diff options
Diffstat (limited to 'usr/src/cmd')
-rw-r--r-- | usr/src/cmd/devfsadm/disk_link.c | 8 | ||||
-rw-r--r-- | usr/src/cmd/format/io.c | 54 | ||||
-rw-r--r-- | usr/src/cmd/format/io.h | 8 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/modules/dtrace/dtrace.c | 47 | ||||
-rw-r--r-- | usr/src/cmd/nvmeadm/nvmeadm.c | 17 |
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, §, &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); |