From owner-svn-src-head@freebsd.org Thu Jan 26 20:09:00 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 07044CC3031; Thu, 26 Jan 2017 20:09:00 +0000 (UTC) (envelope-from scottl@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B961490D; Thu, 26 Jan 2017 20:08:59 +0000 (UTC) (envelope-from scottl@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v0QK8wf0081445; Thu, 26 Jan 2017 20:08:58 GMT (envelope-from scottl@FreeBSD.org) Received: (from scottl@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v0QK8wWl081443; Thu, 26 Jan 2017 20:08:58 GMT (envelope-from scottl@FreeBSD.org) Message-Id: <201701262008.v0QK8wWl081443@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: scottl set sender to scottl@FreeBSD.org using -f From: Scott Long Date: Thu, 26 Jan 2017 20:08:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r312827 - head/sys/cam X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Jan 2017 20:09:00 -0000 Author: scottl Date: Thu Jan 26 20:08:58 2017 New Revision: 312827 URL: https://svnweb.freebsd.org/changeset/base/312827 Log: Refactor xpt_print_path, xpt_print, and xpt_path_string. Implement all of them in terms of an sbuf-based back-end, xpt_path_sbuf. This unifies the implementation, but more importantly it stops the output fropm being split between 4 or more invocations of printf. The multiple invocations cause interleaving of the messages on the console during boot, making the output of disk discovery often unintelligible. This change helps a lot, but more work is needed. Reviewed by: ken, mav Sponsored by: Netflix Modified: head/sys/cam/cam_xpt.c head/sys/cam/cam_xpt.h Modified: head/sys/cam/cam_xpt.c ============================================================================== --- head/sys/cam/cam_xpt.c Thu Jan 26 19:14:14 2017 (r312826) +++ head/sys/cam/cam_xpt.c Thu Jan 26 20:08:58 2017 (r312827) @@ -3697,33 +3697,14 @@ xpt_path_comp_dev(struct cam_path *path, void xpt_print_path(struct cam_path *path) { + struct sbuf sb; + char buffer[XPT_PRINT_LEN]; - if (path == NULL) - printf("(nopath): "); - else { - if (path->periph != NULL) - printf("(%s%d:", path->periph->periph_name, - path->periph->unit_number); - else - printf("(noperiph:"); - - if (path->bus != NULL) - printf("%s%d:%d:", path->bus->sim->sim_name, - path->bus->sim->unit_number, - path->bus->sim->bus_id); - else - printf("nobus:"); - - if (path->target != NULL) - printf("%d:", path->target->target_id); - else - printf("X:"); - - if (path->device != NULL) - printf("%jx): ", (uintmax_t)path->device->lun_id); - else - printf("X): "); - } + sbuf_new(&sb, buffer, XPT_PRINT_LEN, SBUF_FIXEDLEN); + xpt_path_sbuf(path, &sb); + sbuf_finish(&sb); + printf("%s", sbuf_data(&sb)); + sbuf_delete(&sb); } void @@ -3745,49 +3726,66 @@ void xpt_print(struct cam_path *path, const char *fmt, ...) { va_list ap; - xpt_print_path(path); + struct sbuf sb; + char buffer[XPT_PRINT_MAXLEN]; + + sbuf_new(&sb, buffer, XPT_PRINT_MAXLEN, SBUF_FIXEDLEN); + + xpt_path_sbuf(path, &sb); va_start(ap, fmt); - vprintf(fmt, ap); + sbuf_vprintf(&sb, fmt, ap); va_end(ap); + + sbuf_finish(&sb); + printf("%s", sbuf_data(&sb)); + sbuf_delete(&sb); } int xpt_path_string(struct cam_path *path, char *str, size_t str_len) { struct sbuf sb; + int len; sbuf_new(&sb, str, str_len, 0); + len = xpt_path_sbuf(path, &sb); + sbuf_finish(&sb); + return (len); +} + +int +xpt_path_sbuf(struct cam_path *path, struct sbuf *sb) +{ if (path == NULL) - sbuf_printf(&sb, "(nopath): "); + sbuf_printf(sb, "(nopath): "); else { if (path->periph != NULL) - sbuf_printf(&sb, "(%s%d:", path->periph->periph_name, + sbuf_printf(sb, "(%s%d:", path->periph->periph_name, path->periph->unit_number); else - sbuf_printf(&sb, "(noperiph:"); + sbuf_printf(sb, "(noperiph:"); if (path->bus != NULL) - sbuf_printf(&sb, "%s%d:%d:", path->bus->sim->sim_name, + sbuf_printf(sb, "%s%d:%d:", path->bus->sim->sim_name, path->bus->sim->unit_number, path->bus->sim->bus_id); else - sbuf_printf(&sb, "nobus:"); + sbuf_printf(sb, "nobus:"); if (path->target != NULL) - sbuf_printf(&sb, "%d:", path->target->target_id); + sbuf_printf(sb, "%d:", path->target->target_id); else - sbuf_printf(&sb, "X:"); + sbuf_printf(sb, "X:"); if (path->device != NULL) - sbuf_printf(&sb, "%jx): ", + sbuf_printf(sb, "%jx): ", (uintmax_t)path->device->lun_id); else - sbuf_printf(&sb, "X): "); + sbuf_printf(sb, "X): "); } - sbuf_finish(&sb); - return(sbuf_len(&sb)); + return(sbuf_len(sb)); } path_id_t Modified: head/sys/cam/cam_xpt.h ============================================================================== --- head/sys/cam/cam_xpt.h Thu Jan 26 19:14:14 2017 (r312826) +++ head/sys/cam/cam_xpt.h Thu Jan 26 20:08:58 2017 (r312827) @@ -32,11 +32,15 @@ #ifndef _CAM_CAM_XPT_H #define _CAM_CAM_XPT_H 1 +#include +#include "opt_printf.h" + /* Forward Declarations */ union ccb; struct cam_periph; struct cam_ed; struct cam_sim; +struct sbuf; /* * Definition of a CAM path. Paths are created from bus, target, and lun ids @@ -49,6 +53,15 @@ struct cam_path; #ifdef _KERNEL +/* Wild guess based on not wanting to grow the stack too much */ +#define XPT_PRINT_MAXLEN 512 +#ifdef PRINTF_BUFR_SIZE +#define XPT_PRINT_LEN PRINTF_BUFR_SIZE +#else +#define XPT_PRINT_LEN 128 +#endif +_Static_assert(XPT_PRINT_LEN <= XPT_PRINT_MAXLEN, "XPT_PRINT_LEN is too large"); + /* * Definition of an async handler callback block. These are used to add * SIMs and peripherals to the async callback lists. @@ -102,6 +115,7 @@ void xpt_print_device(struct cam_ed *d void xpt_print(struct cam_path *path, const char *fmt, ...); int xpt_path_string(struct cam_path *path, char *str, size_t str_len); +int xpt_path_sbuf(struct cam_path *path, struct sbuf *sb); path_id_t xpt_path_path_id(struct cam_path *path); target_id_t xpt_path_target_id(struct cam_path *path); lun_id_t xpt_path_lun_id(struct cam_path *path);