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
This commit is contained in:
scottl 2017-01-26 20:08:58 +00:00
parent 4834c2f7b9
commit 5a99de79ab
2 changed files with 51 additions and 39 deletions

View File

@ -3697,33 +3697,14 @@ xpt_path_comp_dev(struct cam_path *path, struct cam_ed *dev)
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

View File

@ -32,11 +32,15 @@
#ifndef _CAM_CAM_XPT_H
#define _CAM_CAM_XPT_H 1
#include <sys/cdefs.h>
#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 *device);
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);