summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/devfsadm/disk_link.c8
-rw-r--r--usr/src/cmd/format/io.c54
-rw-r--r--usr/src/cmd/format/io.h8
-rw-r--r--usr/src/cmd/mdb/common/modules/dtrace/dtrace.c47
-rw-r--r--usr/src/cmd/nvmeadm/nvmeadm.c17
5 files changed, 102 insertions, 32 deletions
diff --git a/usr/src/cmd/devfsadm/disk_link.c b/usr/src/cmd/devfsadm/disk_link.c
index ade81417c6..5e68c6c67f 100644
--- a/usr/src/cmd/devfsadm/disk_link.c
+++ b/usr/src/cmd/devfsadm/disk_link.c
@@ -21,7 +21,7 @@
/*
* Copyright 2016 Toomas Soome <tsoome@me.com>
- * Copyright 2017 Nexenta Systems, Inc.
+ * Copyright 2022 Tintri by DDN, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -226,12 +226,12 @@ disk_callback_blkdev(di_minor_t minor, di_node_t node)
{
char *addr;
char disk[DISK_SUBPATH_MAX];
- uint64_t eui64;
+ char guid[50];
uint_t lun = 0;
addr = di_bus_addr(node);
- (void) sscanf(addr, "w%016"PRIx64",%X", &eui64, &lun);
- (void) snprintf(disk, DISK_SUBPATH_MAX, "t%016"PRIX64"d%d", eui64, lun);
+ (void) sscanf(addr, "w%49[0-9A-F],%X", &guid, &lun);
+ (void) snprintf(disk, DISK_SUBPATH_MAX, "t%sd%d", guid, lun);
disk_common(minor, node, disk, RM_STALE);
return (DEVFSADM_CONTINUE);
}
diff --git a/usr/src/cmd/format/io.c b/usr/src/cmd/format/io.c
index 06342e975e..673e968424 100644
--- a/usr/src/cmd/format/io.c
+++ b/usr/src/cmd/format/io.c
@@ -367,7 +367,8 @@ getbn(char *str, diskaddr_t *iptr)
if (geti(buf, &cyl, &wild))
return (-1);
if ((cyl < 0) || (cyl >= (ncyl + acyl))) {
- err_print("`%d' is out of range.\n", cyl);
+ err_print("`%d' is out of range [0-%u].\n", cyl,
+ ncyl + acyl - 1);
return (-1);
}
/*
@@ -378,7 +379,7 @@ getbn(char *str, diskaddr_t *iptr)
if (geti(buf, &head, &wild))
return (-1);
if ((head < 0) || (head >= nhead)) {
- err_print("`%d' is out of range.\n", head);
+ err_print("`%d' is out of range [0-%u].\n", head, nhead - 1);
return (-1);
}
/*
@@ -389,7 +390,8 @@ getbn(char *str, diskaddr_t *iptr)
if (geti(buf, &sect, &wild))
return (-1);
if ((sect < 0) || (sect >= sectors(head))) {
- err_print("`%d' is out of range.\n", sect);
+ err_print("`%d' is out of range [0-%u].\n", sect,
+ sectors(head) - 1);
return (-1);
}
/*
@@ -784,7 +786,8 @@ reprompt:
if ((bn64 < bounds->lower) || (bn64 > bounds->upper)) {
err_print("`");
pr_dblock(err_print, bn64);
- err_print("' is out of range.\n");
+ err_print("' is out of range [%llu-%llu].\n",
+ bounds->lower, bounds->upper);
break;
}
/*
@@ -817,7 +820,8 @@ reprompt:
* Check to be sure it is within the legal bounds.
*/
if ((bn < bounds->lower) || (bn > bounds->upper)) {
- err_print("`%lu' is out of range.\n", bn);
+ err_print("`%lu' is out of range [%llu-%llu].\n", bn,
+ bounds->lower, bounds->upper);
break;
}
/*
@@ -848,7 +852,8 @@ reprompt:
* Check to be sure it is within the legal bounds.
*/
if ((bn64 < bounds->lower) || (bn64 > bounds->upper)) {
- err_print("`%llu' is out of range.\n", bn64);
+ err_print("`%llu' is out of range [%llu-%llu].\n",
+ bn64, bounds->lower, bounds->upper);
break;
}
/*
@@ -881,7 +886,8 @@ reprompt:
* Check to be sure it is within the legal bounds.
*/
if ((bn < bounds->lower) || (bn > bounds->upper)) {
- err_print("`%lu' is out of range.\n", bn);
+ err_print("`%lu' is out of range [%llu-%llu].\n", bn,
+ bounds->lower, bounds->upper);
break;
}
/*
@@ -1150,8 +1156,9 @@ reprompt:
/*
* Check the bounds - cyls is number of cylinders
*/
- if (cyls > (bounds->upper/spc())) {
- err_print("`%dc' is out of range\n", cyls);
+ if (cyls > (bounds->upper / spc())) {
+ err_print("`%dc' is out of range [0-%llu]\n",
+ cyls, bounds->upper / spc());
break;
}
/*
@@ -1171,7 +1178,8 @@ reprompt:
* Check the bounds
*/
if (nmegs > bn2mb(bounds->upper)) {
- err_print("`%1.2fmb' is out of range\n", nmegs);
+ err_print("`%1.2fmb' is out of range "
+ "[0-%1.2f]\n", nmegs, bn2mb(bounds->upper));
break;
}
/*
@@ -1197,7 +1205,8 @@ reprompt:
* Check the bounds
*/
if (ngigs > bn2gb(bounds->upper)) {
- err_print("`%1.2fgb' is out of range\n", ngigs);
+ err_print("`%1.2fgb' is out of range "
+ "[0-%1.2f]\n", ngigs, bn2gb(bounds->upper));
break;
}
/*
@@ -1384,8 +1393,9 @@ or g(gigabytes)\n");
* Check the bounds - cyls is number of
* cylinders
*/
- if (cyls > (bounds->upper/spc())) {
- err_print("`%dc' is out of range\n", cyls);
+ if (cyls > (bounds->upper / spc())) {
+ err_print("`%dc' is out of range [0-%llu]\n",
+ cyls, bounds->upper / spc());
break;
}
@@ -1410,7 +1420,8 @@ or g(gigabytes)\n");
* Check the bounds
*/
if (nmegs > bn2mb(bounds->upper)) {
- err_print("`%1.2fmb' is out of range\n", nmegs);
+ err_print("`%1.2fmb' is out of range "
+ "[0-%1.2f]\n", nmegs, bn2mb(bounds->upper));
break;
}
@@ -1441,7 +1452,8 @@ or g(gigabytes)\n");
* Check the bounds
*/
if (ngigs > bn2gb(bounds->upper)) {
- err_print("`%1.2fgb' is out of range\n", ngigs);
+ err_print("`%1.2fgb' is out of range "
+ "[0-%1.2f]\n", ngigs, bn2gb(bounds->upper));
break;
}
@@ -1608,7 +1620,9 @@ or g(gigabytes)\n");
* Check the bounds
*/
if (nmegs > bn2mb(bounds->upper - bounds->lower)) {
- err_print("`%1.2fmb' is out of range\n", nmegs);
+ err_print("`%1.2fmb' is out of range "
+ "[0-%1.2f]\n", nmegs,
+ bn2mb(bounds->upper - bounds->lower));
break;
}
@@ -1621,7 +1635,9 @@ or g(gigabytes)\n");
break;
}
if (nmegs > bn2gb(bounds->upper - bounds->lower)) {
- err_print("`%1.2fgb' is out of range\n", nmegs);
+ err_print("`%1.2fgb' is out of range "
+ "[0-%1.2f]\n", nmegs,
+ bn2gb(bounds->upper - bounds->lower));
break;
}
@@ -1634,7 +1650,9 @@ or g(gigabytes)\n");
break;
}
if (nmegs > bn2tb(bounds->upper - bounds->lower)) {
- err_print("`%1.2ftb' is out of range\n", nmegs);
+ err_print("`%1.2ftb' is out of range "
+ "[0-%1.2f]\n", nmegs,
+ bn2tb(bounds->upper - bounds->lower));
break;
}
return (uint64_t)((float)nmegs * 1024.0 *
diff --git a/usr/src/cmd/format/io.h b/usr/src/cmd/format/io.h
index e20c719c02..7450a37a0f 100644
--- a/usr/src/cmd/format/io.h
+++ b/usr/src/cmd/format/io.h
@@ -106,10 +106,10 @@ int geti(char *str, int *iptr, int *wild);
uint64_t input(int, char *, int, u_ioparam_t *, int *, int);
int find_value(slist_t *slist, char *match_str, int *match_value);
char *find_string(slist_t *slist, int match_value);
-void fmt_print(char *format, ...);
-void nolog_print(char *format, ...);
-void log_print(char *format, ...);
-void err_print(char *format, ...);
+void fmt_print(char *format, ...) __PRINTFLIKE(1);
+void nolog_print(char *format, ...) __PRINTFLIKE(1);
+void log_print(char *format, ...) __PRINTFLIKE(1);
+void err_print(char *format, ...) __PRINTFLIKE(1);
void print_buf(char *buf, int nbytes);
void pr_diskline(struct disk_info *disk, int num);
void pr_dblock(void (*func)(char *, ...), diskaddr_t bn);
diff --git a/usr/src/cmd/mdb/common/modules/dtrace/dtrace.c b/usr/src/cmd/mdb/common/modules/dtrace/dtrace.c
index aaf430f82d..ec1523dd28 100644
--- a/usr/src/cmd/mdb/common/modules/dtrace/dtrace.c
+++ b/usr/src/cmd/mdb/common/modules/dtrace/dtrace.c
@@ -23,6 +23,7 @@
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright 2019 Joyent, Inc.
+ * Copyright 2022 Racktop Systems, Inc.
*/
/*
@@ -354,6 +355,8 @@ dtracemdb_aggdesc(dtrace_state_t *state, dtrace_aggdesc_t *agd)
static int
dtracemdb_bufsnap(dtrace_buffer_t *which, dtrace_bufdesc_t *desc)
{
+ static hrtime_t hr_offset = 0;
+ static boolean_t offset_set = B_FALSE;
uintptr_t addr;
size_t bufsize;
dtrace_buffer_t buf;
@@ -430,10 +433,52 @@ dtracemdb_bufsnap(dtrace_buffer_t *which, dtrace_bufdesc_t *desc)
desc->dtbd_oldest = 0;
}
+ /*
+ * On a live system, dtbd_timestamp is set to gethrtime() when the
+ * DTRACEIOC_BUFSNAP ioctl is called. The effect of this is that the
+ * timestamps of all the enabled probe records in the buf will always
+ * be less than dtbd_timestamp. dtrace_consume() relies on this
+ * invariant to determine when it needs to retrieve more dtrace bufs
+ * from the kernel.
+ *
+ * However when mdb is reading a crash dump, the value of
+ * gethrtime() on the system running mdb may smaller than the
+ * enabled probe records in the crash dump, violating the invariant
+ * dtrace_consume() is relying on. This can cause dtrace_consume()
+ * to prematurely stop processing records.
+ *
+ * To preserve the invariant dtrace_consume() requires, we simply
+ * add the value of panic_hrtime to gethrtime() when setting
+ * dtdb_timestamp. On a live system, panic_hrtime will be 0, and
+ * the invariant will be preserved by virtue of being running on
+ * a live system. On a crash dump, no valid probe record can have a
+ * timestamp greater than panic_hrtime, so adding this to the value
+ * of gethrtime() will guarantee the invariant expected by
+ * dtrace_consume() is preserved.
+ */
+ if (!offset_set) {
+ hrtime_t panic_hrtime;
+
+ /*
+ * We could be slightly more clever and only set hr_offset
+ * if gethrtime() in mdb is < panic_hrtime, but it doesn't
+ * seem necessary. If for some reason, we cannot read
+ * panic_hrtime, we'll try to continue -- ::dtrace may
+ * still succeed, so we just warn and continue.
+ */
+ if (mdb_readvar(&panic_hrtime, "panic_hrtime") == -1) {
+ mdb_warn("failed to read 'panic_hrtime' -- "
+ "some dtrace data may not be displayed");
+ } else {
+ hr_offset = panic_hrtime;
+ }
+ offset_set = B_TRUE;
+ }
+
desc->dtbd_size = bufsize;
desc->dtbd_drops = buf.dtb_drops;
desc->dtbd_errors = buf.dtb_errors;
- desc->dtbd_timestamp = gethrtime();
+ desc->dtbd_timestamp = gethrtime() + hr_offset;
return (0);
}
diff --git a/usr/src/cmd/nvmeadm/nvmeadm.c b/usr/src/cmd/nvmeadm/nvmeadm.c
index 3de4fa0b00..d78c7fe9ee 100644
--- a/usr/src/cmd/nvmeadm/nvmeadm.c
+++ b/usr/src/cmd/nvmeadm/nvmeadm.c
@@ -472,6 +472,8 @@ nvme_dskname(const nvme_process_arg_t *npa)
di_node_t child;
di_dim_t dim;
char *addr;
+ char *disk_ctd;
+ char *diskname = NULL;
dim = di_dim_init();
@@ -501,19 +503,23 @@ nvme_dskname(const nvme_process_arg_t *npa)
/* Chop off 's0' and get everything past the last '/' */
path[strlen(path) - 2] = '\0';
- path = strrchr(path, '/');
- if (path == NULL)
+ disk_ctd = strrchr(path, '/');
+ if (disk_ctd == NULL)
+ goto fail;
+ diskname = strdup(++disk_ctd);
+ if (diskname == NULL)
goto fail;
- path++;
+ free(path);
break;
}
di_dim_fini(dim);
- return (path);
+ return (diskname);
fail:
+ free(path);
err(-1, "nvme_dskname");
}
@@ -561,14 +567,15 @@ nvme_process(di_node_t node, di_minor_t minor, void *arg)
out:
di_devfs_path_free(npa->npa_path);
- free(npa->npa_dsk);
free(npa->npa_version);
free(npa->npa_idctl);
free(npa->npa_idns);
+ free(npa->npa_dsk);
npa->npa_version = NULL;
npa->npa_idctl = NULL;
npa->npa_idns = NULL;
+ npa->npa_dsk = NULL;
nvme_close(fd);