diff options
Diffstat (limited to 'sys/contrib/openzfs/cmd')
23 files changed, 393 insertions, 180 deletions
diff --git a/sys/contrib/openzfs/cmd/Makefile.am b/sys/contrib/openzfs/cmd/Makefile.am index 3994d1434e99..68f1e892d3f4 100644 --- a/sys/contrib/openzfs/cmd/Makefile.am +++ b/sys/contrib/openzfs/cmd/Makefile.am @@ -9,7 +9,6 @@ CPPCHECKDIRS += raidz_test zfs_ids_to_path zpool_influxdb # TODO: #12084: SHELLCHECKDIRS += vdev_id SHELLCHECKDIRS = fsck_zfs zed zpool zvol_wait -SHELLCHECK_OPTS = --enable=all if USING_PYTHON SUBDIRS += arcstat arc_summary dbufstat diff --git a/sys/contrib/openzfs/cmd/fsck_zfs/Makefile.am b/sys/contrib/openzfs/cmd/fsck_zfs/Makefile.am index d86ea1f786f4..ec955c7c7ff9 100644 --- a/sys/contrib/openzfs/cmd/fsck_zfs/Makefile.am +++ b/sys/contrib/openzfs/cmd/fsck_zfs/Makefile.am @@ -5,4 +5,3 @@ dist_sbin_SCRIPTS = fsck.zfs SUBSTFILES += $(dist_sbin_SCRIPTS) -SHELLCHECK_OPTS = --enable=all diff --git a/sys/contrib/openzfs/cmd/mount_zfs/mount_zfs.c b/sys/contrib/openzfs/cmd/mount_zfs/mount_zfs.c index 434d53cbad04..669ed88f91c4 100644 --- a/sys/contrib/openzfs/cmd/mount_zfs/mount_zfs.c +++ b/sys/contrib/openzfs/cmd/mount_zfs/mount_zfs.c @@ -246,13 +246,6 @@ main(int argc, char **argv) } } - if (verbose) - (void) fprintf(stdout, gettext("mount.zfs:\n" - " dataset: \"%s\"\n mountpoint: \"%s\"\n" - " mountflags: 0x%lx\n zfsflags: 0x%lx\n" - " mountopts: \"%s\"\n mtabopts: \"%s\"\n"), - dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt); - if (mntflags & MS_REMOUNT) { nomtab = 1; remount = 1; @@ -275,7 +268,10 @@ main(int argc, char **argv) return (MOUNT_USAGE); } - zfs_adjust_mount_options(zhp, mntpoint, mntopts, mtabopt); + if (!zfsutil || sloppy || + libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) { + zfs_adjust_mount_options(zhp, mntpoint, mntopts, mtabopt); + } /* treat all snapshots as legacy mount points */ if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) @@ -293,12 +289,11 @@ main(int argc, char **argv) if (zfs_version == 0) { fprintf(stderr, gettext("unable to fetch " "ZFS version for filesystem '%s'\n"), dataset); + zfs_close(zhp); + libzfs_fini(g_zfs); return (MOUNT_SYSERR); } - zfs_close(zhp); - libzfs_fini(g_zfs); - /* * Legacy mount points may only be mounted using 'mount', never using * 'zfs mount'. However, since 'zfs mount' actually invokes 'mount' @@ -316,6 +311,8 @@ main(int argc, char **argv) "Use 'zfs set mountpoint=%s' or 'mount -t zfs %s %s'.\n" "See zfs(8) for more information.\n"), dataset, mntpoint, dataset, mntpoint); + zfs_close(zhp); + libzfs_fini(g_zfs); return (MOUNT_USAGE); } @@ -326,14 +323,38 @@ main(int argc, char **argv) "Use 'zfs set mountpoint=%s' or 'zfs mount %s'.\n" "See zfs(8) for more information.\n"), dataset, "legacy", dataset); + zfs_close(zhp); + libzfs_fini(g_zfs); return (MOUNT_USAGE); } + if (verbose) + (void) fprintf(stdout, gettext("mount.zfs:\n" + " dataset: \"%s\"\n mountpoint: \"%s\"\n" + " mountflags: 0x%lx\n zfsflags: 0x%lx\n" + " mountopts: \"%s\"\n mtabopts: \"%s\"\n"), + dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt); + if (!fake) { - error = mount(dataset, mntpoint, MNTTYPE_ZFS, - mntflags, mntopts); + if (zfsutil && !sloppy && + !libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) { + error = zfs_mount_at(zhp, mntopts, mntflags, mntpoint); + if (error) { + (void) fprintf(stderr, "zfs_mount_at() failed: " + "%s", libzfs_error_description(g_zfs)); + zfs_close(zhp); + libzfs_fini(g_zfs); + return (MOUNT_SYSERR); + } + } else { + error = mount(dataset, mntpoint, MNTTYPE_ZFS, + mntflags, mntopts); + } } + zfs_close(zhp); + libzfs_fini(g_zfs); + if (error) { switch (errno) { case ENOENT: @@ -369,7 +390,7 @@ main(int argc, char **argv) return (MOUNT_SYSERR); } #endif - fallthrough; + zfs_fallthrough; default: (void) fprintf(stderr, gettext("filesystem " "'%s' can not be mounted: %s\n"), dataset, diff --git a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c index b177105ee63b..8bb38f2f72c7 100644 --- a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c +++ b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c @@ -71,12 +71,13 @@ static void print_opts(raidz_test_opts_t *opts, boolean_t force) { char *verbose; switch (opts->rto_v) { - case 0: + case D_ALL: verbose = "no"; break; - case 1: + case D_INFO: verbose = "info"; break; + case D_DEBUG: default: verbose = "debug"; break; @@ -119,7 +120,7 @@ static void usage(boolean_t requested) "\t[-B benchmark all raidz implementations]\n" "\t[-e use expanded raidz map (default: %s)]\n" "\t[-r expanded raidz map reflow offset (default: %llx)]\n" - "\t[-v increase verbosity (default: %zu)]\n" + "\t[-v increase verbosity (default: %d)]\n" "\t[-h (print help)]\n" "\t[-T test the test, see if failure would be detected]\n" "\t[-D debug (attach gdb on SIGSEGV)]\n" @@ -131,7 +132,7 @@ static void usage(boolean_t requested) rto_opts.rto_sweep ? "yes" : "no", /* -S */ rto_opts.rto_expand ? "yes" : "no", /* -e */ (u_longlong_t)o->rto_expand_offset, /* -r */ - o->rto_v); /* -d */ + o->rto_v); /* -v */ exit(requested ? 0 : 1); } @@ -839,7 +840,7 @@ static kcondvar_t sem_cv; static int max_free_slots; static int free_slots; -static void +static _Noreturn void sweep_thread(void *arg) { int err = 0; diff --git a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.h b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.h index 0f7f4cee3eb6..40a8a85e5f6f 100644 --- a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.h +++ b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.h @@ -28,7 +28,7 @@ #include <sys/spa.h> -static const char *raidz_impl_names[] = { +static const char *const raidz_impl_names[] = { "original", "scalar", "sse2", @@ -42,12 +42,18 @@ static const char *raidz_impl_names[] = { NULL }; +enum raidz_verbosity { + D_ALL, + D_INFO, + D_DEBUG, +}; + typedef struct raidz_test_opts { size_t rto_ashift; uint64_t rto_offset; size_t rto_dcols; size_t rto_dsize; - size_t rto_v; + enum raidz_verbosity rto_v; size_t rto_sweep; size_t rto_sweep_timeout; size_t rto_benchmark; @@ -68,7 +74,7 @@ static const raidz_test_opts_t rto_opts_defaults = { .rto_offset = 1ULL << 0, .rto_dcols = 8, .rto_dsize = 1<<19, - .rto_v = 0, + .rto_v = D_ALL, .rto_sweep = 0, .rto_benchmark = 0, .rto_expand = 0, @@ -86,10 +92,6 @@ static inline size_t ilog2(size_t a) } -#define D_ALL 0 -#define D_INFO 1 -#define D_DEBUG 2 - #define LOG(lvl, a...) \ { \ if (rto_opts.rto_v >= lvl) \ diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c index c0b1a62a3182..3fbe7510693a 100644 --- a/sys/contrib/openzfs/cmd/zdb/zdb.c +++ b/sys/contrib/openzfs/cmd/zdb/zdb.c @@ -1228,9 +1228,9 @@ dump_bpobj(objset_t *os, uint64_t object, void *data, size_t size) char bytes[32], comp[32], uncomp[32]; /* make sure the output won't get truncated */ - CTASSERT(sizeof (bytes) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (comp) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (uncomp) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (bytes) >= NN_NUMBUF_SZ, "bytes truncated"); + _Static_assert(sizeof (comp) >= NN_NUMBUF_SZ, "comp truncated"); + _Static_assert(sizeof (uncomp) >= NN_NUMBUF_SZ, "uncomp truncated"); if (bpop == NULL) return; @@ -1655,7 +1655,7 @@ dump_metaslab_stats(metaslab_t *msp) int free_pct = range_tree_space(rt) * 100 / msp->ms_size; /* max sure nicenum has enough space */ - CTASSERT(sizeof (maxbuf) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (maxbuf) >= NN_NUMBUF_SZ, "maxbuf truncated"); zdb_nicenum(metaslab_largest_allocatable(msp), maxbuf, sizeof (maxbuf)); @@ -2490,7 +2490,7 @@ dump_dsl_dir(objset_t *os, uint64_t object, void *data, size_t size) char nice[32]; /* make sure nicenum has enough space */ - CTASSERT(sizeof (nice) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (nice) >= NN_NUMBUF_SZ, "nice truncated"); if (dd == NULL) return; @@ -2548,10 +2548,12 @@ dump_dsl_dataset(objset_t *os, uint64_t object, void *data, size_t size) char blkbuf[BP_SPRINTF_LEN]; /* make sure nicenum has enough space */ - CTASSERT(sizeof (used) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (compressed) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (uncompressed) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (unique) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (used) >= NN_NUMBUF_SZ, "used truncated"); + _Static_assert(sizeof (compressed) >= NN_NUMBUF_SZ, + "compressed truncated"); + _Static_assert(sizeof (uncompressed) >= NN_NUMBUF_SZ, + "uncompressed truncated"); + _Static_assert(sizeof (unique) >= NN_NUMBUF_SZ, "unique truncated"); if (ds == NULL) return; @@ -2622,7 +2624,7 @@ dump_bptree(objset_t *os, uint64_t obj, const char *name) dmu_buf_t *db; /* make sure nicenum has enough space */ - CTASSERT(sizeof (bytes) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (bytes) >= NN_NUMBUF_SZ, "bytes truncated"); if (dump_opt['d'] < 3) return; @@ -2663,9 +2665,9 @@ dump_full_bpobj(bpobj_t *bpo, const char *name, int indent) uint64_t i; /* make sure nicenum has enough space */ - CTASSERT(sizeof (bytes) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (comp) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (uncomp) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (bytes) >= NN_NUMBUF_SZ, "bytes truncated"); + _Static_assert(sizeof (comp) >= NN_NUMBUF_SZ, "comp truncated"); + _Static_assert(sizeof (uncomp) >= NN_NUMBUF_SZ, "uncomp truncated"); if (dump_opt['d'] < 3) return; @@ -2941,10 +2943,10 @@ dump_blkptr_list(dsl_deadlist_t *dl, char *name) } /* make sure nicenum has enough space */ - CTASSERT(sizeof (bytes) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (comp) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (uncomp) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (entries) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (bytes) >= NN_NUMBUF_SZ, "bytes truncated"); + _Static_assert(sizeof (comp) >= NN_NUMBUF_SZ, "comp truncated"); + _Static_assert(sizeof (uncomp) >= NN_NUMBUF_SZ, "uncomp truncated"); + _Static_assert(sizeof (entries) >= NN_NUMBUF_SZ, "entries truncated"); if (dump_opt['d'] < 3) return; @@ -3428,11 +3430,12 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int error; /* make sure nicenum has enough space */ - CTASSERT(sizeof (iblk) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (dblk) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (lsize) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (asize) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (bonus_size) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (iblk) >= NN_NUMBUF_SZ, "iblk truncated"); + _Static_assert(sizeof (dblk) >= NN_NUMBUF_SZ, "dblk truncated"); + _Static_assert(sizeof (lsize) >= NN_NUMBUF_SZ, "lsize truncated"); + _Static_assert(sizeof (asize) >= NN_NUMBUF_SZ, "asize truncated"); + _Static_assert(sizeof (bonus_size) >= NN_NUMBUF_SZ, + "bonus_size truncated"); if (*print_header) { (void) printf("\n%10s %3s %5s %5s %5s %6s %5s %6s %s\n", @@ -3581,7 +3584,8 @@ dump_object(objset_t *os, uint64_t object, int verbosity, for (;;) { char segsize[32]; /* make sure nicenum has enough space */ - CTASSERT(sizeof (segsize) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (segsize) >= NN_NUMBUF_SZ, + "segsize truncated"); error = dnode_next_offset(dn, 0, &start, minlvl, blkfill, 0); if (error) @@ -3770,7 +3774,7 @@ dump_objset(objset_t *os) uint64_t flags; /* make sure nicenum has enough space */ - CTASSERT(sizeof (numbuf) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (numbuf) >= NN_NUMBUF_SZ, "numbuf truncated"); dsl_pool_config_enter(dmu_objset_pool(os), FTAG); dmu_objset_fast_stat(os, &dds); @@ -4651,7 +4655,7 @@ dump_path_impl(objset_t *os, uint64_t obj, char *name, uint64_t *retobj) case DMU_OT_DIRECTORY_CONTENTS: if (s != NULL && *(s + 1) != '\0') return (dump_path_impl(os, child_obj, s + 1, retobj)); - fallthrough; + zfs_fallthrough; case DMU_OT_PLAIN_FILE_CONTENTS: if (retobj != NULL) { *retobj = child_obj; @@ -5542,7 +5546,7 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, (zcb->zcb_totalasize - bytes) / 1024 / kb_per_sec; /* make sure nicenum has enough space */ - CTASSERT(sizeof (buf) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (buf) >= NN_NUMBUF_SZ, "buf truncated"); zfs_nicebytes(bytes, buf, sizeof (buf)); (void) fprintf(stderr, @@ -6651,12 +6655,18 @@ dump_block_stats(spa_t *spa) const char *typename; /* make sure nicenum has enough space */ - CTASSERT(sizeof (csize) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (lsize) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (psize) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (asize) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (avg) >= NN_NUMBUF_SZ); - CTASSERT(sizeof (gang) >= NN_NUMBUF_SZ); + _Static_assert(sizeof (csize) >= NN_NUMBUF_SZ, + "csize truncated"); + _Static_assert(sizeof (lsize) >= NN_NUMBUF_SZ, + "lsize truncated"); + _Static_assert(sizeof (psize) >= NN_NUMBUF_SZ, + "psize truncated"); + _Static_assert(sizeof (asize) >= NN_NUMBUF_SZ, + "asize truncated"); + _Static_assert(sizeof (avg) >= NN_NUMBUF_SZ, + "avg truncated"); + _Static_assert(sizeof (gang) >= NN_NUMBUF_SZ, + "gang truncated"); if (t < DMU_OT_NUMTYPES) typename = dmu_ot[t].ot_name; @@ -8644,7 +8654,7 @@ main(int argc, char **argv) dump_opt[c] += verbose; } - libspl_assert_ok = (dump_opt['A'] == 1) || (dump_opt['A'] > 2); + libspl_set_assert_ok((dump_opt['A'] == 1) || (dump_opt['A'] > 2)); zfs_recover = (dump_opt['A'] > 1); argc -= optind; diff --git a/sys/contrib/openzfs/cmd/zdb/zdb_il.c b/sys/contrib/openzfs/cmd/zdb/zdb_il.c index d6f588d8316e..76b1d64d76dc 100644 --- a/sys/contrib/openzfs/cmd/zdb/zdb_il.c +++ b/sys/contrib/openzfs/cmd/zdb/zdb_il.c @@ -266,6 +266,29 @@ zil_prt_rec_setattr(zilog_t *zilog, int txtype, const void *arg) } static void +zil_prt_rec_setsaxattr(zilog_t *zilog, int txtype, const void *arg) +{ + (void) zilog, (void) txtype; + const lr_setsaxattr_t *lr = arg; + + char *name = (char *)(lr + 1); + (void) printf("%sfoid %llu\n", tab_prefix, + (u_longlong_t)lr->lr_foid); + + (void) printf("%sXAT_NAME %s\n", tab_prefix, name); + if (lr->lr_size == 0) { + (void) printf("%sXAT_VALUE NULL\n", tab_prefix); + } else { + (void) printf("%sXAT_VALUE ", tab_prefix); + char *val = name + (strlen(name) + 1); + for (int i = 0; i < lr->lr_size; i++) { + (void) printf("%c", *val); + val++; + } + } +} + +static void zil_prt_rec_acl(zilog_t *zilog, int txtype, const void *arg) { (void) zilog, (void) txtype; @@ -304,6 +327,8 @@ static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = { {.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ATTR "}, {.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ACL_ATTR "}, {.zri_print = zil_prt_rec_write, .zri_name = "TX_WRITE2 "}, + {.zri_print = zil_prt_rec_setsaxattr, + .zri_name = "TX_SETSAXATTR "}, }; static int diff --git a/sys/contrib/openzfs/cmd/zed/Makefile.am b/sys/contrib/openzfs/cmd/zed/Makefile.am index 1492123e1696..7b662994d1c6 100644 --- a/sys/contrib/openzfs/cmd/zed/Makefile.am +++ b/sys/contrib/openzfs/cmd/zed/Makefile.am @@ -5,7 +5,6 @@ AM_CFLAGS += $(LIBUDEV_CFLAGS) $(LIBUUID_CFLAGS) SUBDIRS = zed.d SHELLCHECKDIRS = $(SUBDIRS) -SHELLCHECK_OPTS = --enable=all sbin_PROGRAMS = zed diff --git a/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c b/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c index c62a976c2e3f..59d8182c0b2e 100644 --- a/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c +++ b/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c @@ -183,14 +183,14 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled) nvlist_t *nvroot, *newvd; pendingdev_t *device; uint64_t wholedisk = 0ULL; - uint64_t offline = 0ULL; + uint64_t offline = 0ULL, faulted = 0ULL; uint64_t guid = 0ULL; char *physpath = NULL, *new_devid = NULL, *enc_sysfs_path = NULL; char rawpath[PATH_MAX], fullpath[PATH_MAX]; char devpath[PATH_MAX]; int ret; - boolean_t is_dm = B_FALSE; boolean_t is_sd = B_FALSE; + boolean_t is_mpath_wholedisk = B_FALSE; uint_t c; vdev_stat_t *vs; @@ -211,15 +211,73 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled) &enc_sysfs_path); (void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk); (void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_OFFLINE, &offline); + (void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_FAULTED, &faulted); + (void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_GUID, &guid); - if (offline) - return; /* don't intervene if it was taken offline */ + /* + * Special case: + * + * We've seen times where a disk won't have a ZPOOL_CONFIG_PHYS_PATH + * entry in their config. For example, on this force-faulted disk: + * + * children[0]: + * type: 'disk' + * id: 0 + * guid: 14309659774640089719 + * path: '/dev/disk/by-vdev/L28' + * whole_disk: 0 + * DTL: 654 + * create_txg: 4 + * com.delphix:vdev_zap_leaf: 1161 + * faulted: 1 + * aux_state: 'external' + * children[1]: + * type: 'disk' + * id: 1 + * guid: 16002508084177980912 + * path: '/dev/disk/by-vdev/L29' + * devid: 'dm-uuid-mpath-35000c500a61d68a3' + * phys_path: 'L29' + * vdev_enc_sysfs_path: '/sys/class/enclosure/0:0:1:0/SLOT 30 32' + * whole_disk: 0 + * DTL: 1028 + * create_txg: 4 + * com.delphix:vdev_zap_leaf: 131 + * + * If the disk's path is a /dev/disk/by-vdev/ path, then we can infer + * the ZPOOL_CONFIG_PHYS_PATH from the by-vdev disk name. + */ + if (physpath == NULL && path != NULL) { + /* If path begins with "/dev/disk/by-vdev/" ... */ + if (strncmp(path, DEV_BYVDEV_PATH, + strlen(DEV_BYVDEV_PATH)) == 0) { + /* Set physpath to the char after "/dev/disk/by-vdev" */ + physpath = &path[strlen(DEV_BYVDEV_PATH)]; + } + } + + /* + * We don't want to autoreplace offlined disks. However, we do want to + * replace force-faulted disks (`zpool offline -f`). Force-faulted + * disks have both offline=1 and faulted=1 in the nvlist. + */ + if (offline && !faulted) { + zed_log_msg(LOG_INFO, "%s: %s is offline, skip autoreplace", + __func__, path); + return; + } - is_dm = zfs_dev_is_dm(path); + is_mpath_wholedisk = is_mpath_whole_disk(path); zed_log_msg(LOG_INFO, "zfs_process_add: pool '%s' vdev '%s', phys '%s'" - " wholedisk %d, %s dm (guid %llu)", zpool_get_name(zhp), path, - physpath ? physpath : "NULL", wholedisk, is_dm ? "is" : "not", + " %s blank disk, %s mpath blank disk, %s labeled, enc sysfs '%s', " + "(guid %llu)", + zpool_get_name(zhp), path, + physpath ? physpath : "NULL", + wholedisk ? "is" : "not", + is_mpath_wholedisk? "is" : "not", + labeled ? "is" : "not", + enc_sysfs_path, (long long unsigned int)guid); /* @@ -253,8 +311,9 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled) ZFS_ONLINE_CHECKREMOVE | ZFS_ONLINE_UNSPARE, &newstate) == 0 && (newstate == VDEV_STATE_HEALTHY || newstate == VDEV_STATE_DEGRADED)) { - zed_log_msg(LOG_INFO, " zpool_vdev_online: vdev %s is %s", - fullpath, (newstate == VDEV_STATE_HEALTHY) ? + zed_log_msg(LOG_INFO, + " zpool_vdev_online: vdev '%s' ('%s') is " + "%s", fullpath, physpath, (newstate == VDEV_STATE_HEALTHY) ? "HEALTHY" : "DEGRADED"); return; } @@ -271,11 +330,12 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled) * vdev online to trigger a FMA fault by posting an ereport. */ if (!zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOREPLACE, NULL) || - !(wholedisk || is_dm) || (physpath == NULL)) { + !(wholedisk || is_mpath_wholedisk) || (physpath == NULL)) { (void) zpool_vdev_online(zhp, fullpath, ZFS_ONLINE_FORCEFAULT, &newstate); zed_log_msg(LOG_INFO, "Pool's autoreplace is not enabled or " - "not a whole disk for '%s'", fullpath); + "not a blank disk for '%s' ('%s')", fullpath, + physpath); return; } @@ -287,7 +347,7 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled) (void) snprintf(rawpath, sizeof (rawpath), "%s%s", is_sd ? DEV_BYVDEV_PATH : DEV_BYPATH_PATH, physpath); - if (realpath(rawpath, devpath) == NULL && !is_dm) { + if (realpath(rawpath, devpath) == NULL && !is_mpath_wholedisk) { zed_log_msg(LOG_INFO, " realpath: %s failed (%s)", rawpath, strerror(errno)); @@ -303,12 +363,14 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled) if ((vs->vs_state != VDEV_STATE_DEGRADED) && (vs->vs_state != VDEV_STATE_FAULTED) && (vs->vs_state != VDEV_STATE_CANT_OPEN)) { + zed_log_msg(LOG_INFO, " not autoreplacing since disk isn't in " + "a bad state (currently %d)", vs->vs_state); return; } nvlist_lookup_string(vdev, "new_devid", &new_devid); - if (is_dm) { + if (is_mpath_wholedisk) { /* Don't label device mapper or multipath disks. */ } else if (!labeled) { /* @@ -522,8 +584,11 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data) * the dp->dd_compare value. */ if (nvlist_lookup_string(nvl, dp->dd_prop, &path) != 0 || - strcmp(dp->dd_compare, path) != 0) + strcmp(dp->dd_compare, path) != 0) { + zed_log_msg(LOG_INFO, " %s: no match (%s != vdev %s)", + __func__, dp->dd_compare, path); return; + } zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched %s on %s", dp->dd_prop, path); @@ -571,6 +636,8 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data) ZPOOL_CONFIG_VDEV_TREE, &nvl); zfs_iter_vdev(zhp, nvl, data); } + } else { + zed_log_msg(LOG_INFO, "%s: no config\n", __func__); } /* @@ -620,6 +687,72 @@ devphys_iter(const char *physical, const char *devid, zfs_process_func_t func, } /* + * Given a device identifier, find any vdevs with a matching by-vdev + * path. Normally we shouldn't need this as the comparison would be + * made earlier in the devphys_iter(). For example, if we were replacing + * /dev/disk/by-vdev/L28, normally devphys_iter() would match the + * ZPOOL_CONFIG_PHYS_PATH of "L28" from the old disk config to "L28" + * of the new disk config. However, we've seen cases where + * ZPOOL_CONFIG_PHYS_PATH was not in the config for the old disk. Here's + * an example of a real 2-disk mirror pool where one disk was force + * faulted: + * + * com.delphix:vdev_zap_top: 129 + * children[0]: + * type: 'disk' + * id: 0 + * guid: 14309659774640089719 + * path: '/dev/disk/by-vdev/L28' + * whole_disk: 0 + * DTL: 654 + * create_txg: 4 + * com.delphix:vdev_zap_leaf: 1161 + * faulted: 1 + * aux_state: 'external' + * children[1]: + * type: 'disk' + * id: 1 + * guid: 16002508084177980912 + * path: '/dev/disk/by-vdev/L29' + * devid: 'dm-uuid-mpath-35000c500a61d68a3' + * phys_path: 'L29' + * vdev_enc_sysfs_path: '/sys/class/enclosure/0:0:1:0/SLOT 30 32' + * whole_disk: 0 + * DTL: 1028 + * create_txg: 4 + * com.delphix:vdev_zap_leaf: 131 + * + * So in the case above, the only thing we could compare is the path. + * + * We can do this because we assume by-vdev paths are authoritative as physical + * paths. We could not assume this for normal paths like /dev/sda since the + * physical location /dev/sda points to could change over time. + */ +static boolean_t +by_vdev_path_iter(const char *by_vdev_path, const char *devid, + zfs_process_func_t func, boolean_t is_slice) +{ + dev_data_t data = { 0 }; + + data.dd_compare = by_vdev_path; + data.dd_func = func; + data.dd_prop = ZPOOL_CONFIG_PATH; + data.dd_found = B_FALSE; + data.dd_islabeled = is_slice; + data.dd_new_devid = devid; + + if (strncmp(by_vdev_path, DEV_BYVDEV_PATH, + strlen(DEV_BYVDEV_PATH)) != 0) { + /* by_vdev_path doesn't start with "/dev/disk/by-vdev/" */ + return (B_FALSE); + } + + (void) zpool_iter(g_zfshdl, zfs_iter_pool, &data); + + return (data.dd_found); +} + +/* * Given a device identifier, find any vdevs with a matching devid. * On Linux we can match devid directly which is always a whole disk. */ @@ -683,15 +816,17 @@ guid_iter(uint64_t pool_guid, uint64_t vdev_guid, const char *devid, static int zfs_deliver_add(nvlist_t *nvl) { - char *devpath = NULL, *devid; + char *devpath = NULL, *devid = NULL; uint64_t pool_guid = 0, vdev_guid = 0; boolean_t is_slice; /* * Expecting a devid string and an optional physical location and guid */ - if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid) != 0) + if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid) != 0) { + zed_log_msg(LOG_INFO, "%s: no dev identifier\n", __func__); return (-1); + } (void) nvlist_lookup_string(nvl, DEV_PHYS_PATH, &devpath); (void) nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &pool_guid); @@ -707,6 +842,8 @@ zfs_deliver_add(nvlist_t *nvl) * 1. ZPOOL_CONFIG_DEVID (identifies the unique disk) * 2. ZPOOL_CONFIG_PHYS_PATH (identifies disk physical location). * 3. ZPOOL_CONFIG_GUID (identifies unique vdev). + * 4. ZPOOL_CONFIG_PATH for /dev/disk/by-vdev devices only (since + * by-vdev paths represent physical paths). */ if (devid_iter(devid, zfs_process_add, is_slice)) return (0); @@ -717,6 +854,16 @@ zfs_deliver_add(nvlist_t *nvl) (void) guid_iter(pool_guid, vdev_guid, devid, zfs_process_add, is_slice); + if (devpath != NULL) { + /* Can we match a /dev/disk/by-vdev/ path? */ + char by_vdev_path[MAXPATHLEN]; + snprintf(by_vdev_path, sizeof (by_vdev_path), + "/dev/disk/by-vdev/%s", devpath); + if (by_vdev_path_iter(by_vdev_path, devid, zfs_process_add, + is_slice)) + return (0); + } + return (0); } diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am b/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am index 24efaa74f154..3c0f5c3dd1b2 100644 --- a/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am +++ b/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am @@ -11,8 +11,7 @@ dist_zedconf_DATA = \ zed.rc SHELLCHECKSCRIPTS = zed-functions.sh zed.rc -SHELLCHECK_OPTS = --enable=all -SHELLCHECK_SHELL = dash +SHELLCHECK_SHELL = sh zedexecdir = $(zfsexecdir)/zed.d diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh b/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh index bbff9c008bd1..e6d3ce9ecc49 100644 --- a/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh +++ b/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh @@ -417,7 +417,7 @@ zed_notify_slack_webhook() # Construct the JSON message for posting. # - msg_json="$(printf '{"text": "*%s*\n%s"}' "${subject}" "${msg_body}" )" + msg_json="$(printf '{"text": "*%s*\\n%s"}' "${subject}" "${msg_body}" )" # Send the POST request and check for errors. # diff --git a/sys/contrib/openzfs/cmd/zed/zed_disk_event.c b/sys/contrib/openzfs/cmd/zed/zed_disk_event.c index 94e24236063c..52b80d8c4c93 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_disk_event.c +++ b/sys/contrib/openzfs/cmd/zed/zed_disk_event.c @@ -215,6 +215,11 @@ zed_udev_monitor(void *arg) if (type != NULL && type[0] != '\0' && strcmp(type, "disk") == 0 && part != NULL && part[0] != '\0') { + zed_log_msg(LOG_INFO, + "%s: skip %s since it has a %s partition already", + __func__, + udev_device_get_property_value(dev, "DEVNAME"), + part); /* skip and wait for partition event */ udev_device_unref(dev); continue; @@ -229,6 +234,11 @@ zed_udev_monitor(void *arg) sectors = udev_device_get_sysattr_value(dev, "size"); if (sectors != NULL && strtoull(sectors, NULL, 10) < MINIMUM_SECTORS) { + zed_log_msg(LOG_INFO, + "%s: %s sectors %s < %llu (minimum)", + __func__, + udev_device_get_property_value(dev, "DEVNAME"), + sectors, MINIMUM_SECTORS); udev_device_unref(dev); continue; } diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_iter.c b/sys/contrib/openzfs/cmd/zfs/zfs_iter.c index 69b802f77a78..8b6a49a79290 100644 --- a/sys/contrib/openzfs/cmd/zfs/zfs_iter.c +++ b/sys/contrib/openzfs/cmd/zfs/zfs_iter.c @@ -453,23 +453,21 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types, cb.cb_flags |= ZFS_ITER_RECURSE; ret = zfs_iter_root(g_zfs, zfs_callback, &cb); } else { - int i; - zfs_handle_t *zhp; - zfs_type_t argtype; + zfs_handle_t *zhp = NULL; + zfs_type_t argtype = types; /* * If we're recursive, then we always allow filesystems as * arguments. If we also are interested in snapshots or * bookmarks, then we can take volumes as well. */ - argtype = types; if (flags & ZFS_ITER_RECURSE) { argtype |= ZFS_TYPE_FILESYSTEM; if (types & (ZFS_TYPE_SNAPSHOT | ZFS_TYPE_BOOKMARK)) argtype |= ZFS_TYPE_VOLUME; } - for (i = 0; i < argc; i++) { + for (int i = 0; i < argc; i++) { if (flags & ZFS_ITER_ARGS_CAN_BE_PATHS) { zhp = zfs_path_to_zhandle(g_zfs, argv[i], argtype); diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_main.c b/sys/contrib/openzfs/cmd/zfs/zfs_main.c index 5aa2508c382f..42e4d6f7e195 100644 --- a/sys/contrib/openzfs/cmd/zfs/zfs_main.c +++ b/sys/contrib/openzfs/cmd/zfs/zfs_main.c @@ -575,8 +575,9 @@ usage(boolean_t requested) (void) fprintf(fp, gettext("\nSizes are specified in bytes " "with standard units such as K, M, G, etc.\n")); - (void) fprintf(fp, gettext("\nUser-defined properties can " - "be specified by using a name containing a colon (:).\n")); + (void) fprintf(fp, "%s", gettext("\nUser-defined properties " + "can be specified by using a name containing a colon " + "(:).\n")); (void) fprintf(fp, gettext("\nThe {user|group|project}" "[obj]{used|quota}@ properties must be appended with\n" "a user|group|project specifier of one of these forms:\n" @@ -727,32 +728,6 @@ finish_progress(char *done) pt_header = NULL; } -/* This function checks if the passed fd refers to /dev/null or /dev/zero */ -#ifdef __linux__ -static boolean_t -is_dev_nullzero(int fd) -{ - struct stat st; - fstat(fd, &st); - return (major(st.st_rdev) == 1 && (minor(st.st_rdev) == 3 /* null */ || - minor(st.st_rdev) == 5 /* zero */)); -} -#endif - -static void -note_dev_error(int err, int fd) -{ -#ifdef __linux__ - if (err == EINVAL && is_dev_nullzero(fd)) { - (void) fprintf(stderr, - gettext("Error: Writing directly to /dev/{null,zero} files" - " on certain kernels is not currently implemented.\n" - "(As a workaround, " - "try \"zfs send [...] | cat > /dev/null\")\n")); - } -#endif -} - static int zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type) { @@ -4594,16 +4569,11 @@ zfs_do_send(int argc, char **argv) err = zfs_send_saved(zhp, &flags, STDOUT_FILENO, resume_token); - if (err != 0) - note_dev_error(errno, STDOUT_FILENO); zfs_close(zhp); return (err != 0); } else if (resume_token != NULL) { - err = zfs_send_resume(g_zfs, &flags, STDOUT_FILENO, - resume_token); - if (err != 0) - note_dev_error(errno, STDOUT_FILENO); - return (err); + return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO, + resume_token)); } if (flags.skipmissing && !flags.replicate) { @@ -4654,8 +4624,6 @@ zfs_do_send(int argc, char **argv) err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags, redactbook); zfs_close(zhp); - if (err != 0) - note_dev_error(errno, STDOUT_FILENO); return (err != 0); } @@ -4732,7 +4700,6 @@ zfs_do_send(int argc, char **argv) nvlist_free(dbgnv); } zfs_close(zhp); - note_dev_error(errno, STDOUT_FILENO); return (err != 0); } diff --git a/sys/contrib/openzfs/cmd/zgenhostid/zgenhostid.c b/sys/contrib/openzfs/cmd/zgenhostid/zgenhostid.c index 853931c6ad6e..6c8f7c6127a1 100644 --- a/sys/contrib/openzfs/cmd/zgenhostid/zgenhostid.c +++ b/sys/contrib/openzfs/cmd/zgenhostid/zgenhostid.c @@ -36,7 +36,7 @@ #include <time.h> #include <unistd.h> -static __attribute__((noreturn)) void +static _Noreturn void usage(void) { (void) fprintf(stderr, diff --git a/sys/contrib/openzfs/cmd/zhack/zhack.c b/sys/contrib/openzfs/cmd/zhack/zhack.c index 73ce888c0b1d..92d20d753aed 100644 --- a/sys/contrib/openzfs/cmd/zhack/zhack.c +++ b/sys/contrib/openzfs/cmd/zhack/zhack.c @@ -57,7 +57,7 @@ static importargs_t g_importargs; static char *g_pool; static boolean_t g_readonly; -static __attribute__((noreturn)) void +static _Noreturn void usage(void) { (void) fprintf(stderr, @@ -87,7 +87,7 @@ usage(void) } -static __attribute__((noreturn)) __attribute__((format(printf, 3, 4))) void +static __attribute__((format(printf, 3, 4))) _Noreturn void fatal(spa_t *spa, void *tag, const char *fmt, ...) { va_list ap; diff --git a/sys/contrib/openzfs/cmd/zpool/Makefile.am b/sys/contrib/openzfs/cmd/zpool/Makefile.am index b89b5db85800..7ea7c5fc3f3e 100644 --- a/sys/contrib/openzfs/cmd/zpool/Makefile.am +++ b/sys/contrib/openzfs/cmd/zpool/Makefile.am @@ -5,7 +5,6 @@ AM_CFLAGS += $(LIBBLKID_CFLAGS) $(LIBUUID_CFLAGS) DEFAULT_INCLUDES += -I$(srcdir) -SHELLCHECK_OPTS = --enable=all sbin_PROGRAMS = zpool diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c index d7cce73d3dff..717d8b806d79 100644 --- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c +++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c @@ -1760,17 +1760,19 @@ zpool_do_create(int argc, char **argv) "feature@%s", feat->fi_uname); if (!nvlist_lookup_string(props, propname, &propval)) { - if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0) + if (strcmp(propval, + ZFS_FEATURE_DISABLED) == 0) { (void) nvlist_remove_all(props, propname); - if (strcmp(propval, + } else if (strcmp(propval, ZFS_FEATURE_ENABLED) == 0 && - !requested_features[i]) + !requested_features[i]) { (void) fprintf(stderr, gettext( "Warning: feature \"%s\" enabled " "but is not in specified " "'compatibility' feature set.\n"), feat->fi_uname); + } } else if ( enable_pool_features && feat->fi_zfs_mod_supported && @@ -3039,9 +3041,8 @@ show_import(nvlist_t *config, boolean_t report_error) ZPOOL_CONFIG_MMP_HOSTID); (void) printf(gettext(" action: The pool must be " - "exported from %s (hostid=%lx)\n\tbefore it " - "can be safely imported.\n"), hostname, - (unsigned long) hostid); + "exported from %s (hostid=%"PRIx64")\n\tbefore it " + "can be safely imported.\n"), hostname, hostid); break; case ZPOOL_STATUS_HOSTID_REQUIRED: (void) printf(gettext(" action: Set a unique system " @@ -3136,7 +3137,7 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, { int ret = 0; zpool_handle_t *zhp; - char *name; + const char *name; uint64_t version; name = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME); @@ -3157,7 +3158,7 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, ZPOOL_CONFIG_MMP_STATE); if (mmp_state == MMP_STATE_ACTIVE) { - char *hostname = "<unknown>"; + const char *hostname = "<unknown>"; uint64_t hostid = 0; if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME)) @@ -3170,17 +3171,17 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, (void) fprintf(stderr, gettext("cannot import '%s': " "pool is imported on %s (hostid: " - "0x%lx)\nExport the pool on the other system, " - "then run 'zpool import'.\n"), - name, hostname, (unsigned long) hostid); + "0x%"PRIx64")\nExport the pool on the other " + "system, then run 'zpool import'.\n"), + name, hostname, hostid); } else if (mmp_state == MMP_STATE_NO_HOSTID) { (void) fprintf(stderr, gettext("Cannot import '%s': " "pool has the multihost property on and the\n" "system's hostid is not set. Set a unique hostid " "with the zgenhostid(8) command.\n"), name); } else { - char *hostname = "<unknown>"; - uint64_t timestamp = 0; + const char *hostname = "<unknown>"; + time_t timestamp = 0; uint64_t hostid = 0; if (nvlist_exists(config, ZPOOL_CONFIG_HOSTNAME)) @@ -3197,10 +3198,10 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, (void) fprintf(stderr, gettext("cannot import '%s': " "pool was previously in use from another system.\n" - "Last accessed by %s (hostid=%lx) at %s" + "Last accessed by %s (hostid=%"PRIx64") at %s" "The pool can be imported, use 'zpool import -f' " "to import the pool.\n"), name, hostname, - (unsigned long)hostid, ctime((time_t *)×tamp)); + hostid, ctime(×tamp)); } return (1); @@ -3210,7 +3211,7 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, return (1); if (newname != NULL) - name = (char *)newname; + name = newname; if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL) return (1); @@ -3219,11 +3220,9 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, * Loading keys is best effort. We don't want to return immediately * if it fails but we do want to give the error to the caller. */ - if (flags & ZFS_IMPORT_LOAD_KEYS) { - ret = zfs_crypto_attempt_load_keys(g_zfs, name); - if (ret != 0) + if (flags & ZFS_IMPORT_LOAD_KEYS && + zfs_crypto_attempt_load_keys(g_zfs, name) != 0) ret = 1; - } if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && !(flags & ZFS_IMPORT_ONLY) && @@ -3273,7 +3272,7 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags, if (first) first = B_FALSE; else if (!do_all) - (void) printf("\n"); + (void) putchar('\n'); if (do_all) { err |= do_import(config, NULL, mntopts, @@ -3724,9 +3723,8 @@ zpool_do_import(int argc, char **argv) if (argc == 0 && geteuid() != 0) { (void) fprintf(stderr, gettext("cannot " "discover pools: permission denied\n")); - if (searchdirs != NULL) - free(searchdirs); + free(searchdirs); nvlist_free(props); nvlist_free(policy); return (1); @@ -4690,7 +4688,7 @@ print_iostat_default(vdev_stat_t *vs, iostat_cbdata_t *cb, double scale) format, column_width, cb->cb_scripted); } -static const char *class_name[] = { +static const char *const class_name[] = { VDEV_ALLOC_BIAS_DEDUP, VDEV_ALLOC_BIAS_SPECIAL, VDEV_ALLOC_CLASS_LOGS @@ -4850,7 +4848,7 @@ children: continue; vname = zpool_vdev_name(g_zfs, zhp, newchild[c], - cb->cb_vdevs.cb_name_flags); + cb->cb_vdevs.cb_name_flags | VDEV_NAME_TYPE_ID); ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, newchild[c], cb, depth + 2); free(vname); @@ -4859,7 +4857,7 @@ children: /* * print all other top-level devices */ - for (uint_t n = 0; n < 3; n++) { + for (uint_t n = 0; n < ARRAY_SIZE(class_name); n++) { boolean_t printed = B_FALSE; for (c = 0; c < children; c++) { @@ -4894,7 +4892,7 @@ children: } vname = zpool_vdev_name(g_zfs, zhp, newchild[c], - cb->cb_vdevs.cb_name_flags); + cb->cb_vdevs.cb_name_flags | VDEV_NAME_TYPE_ID); ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, newchild[c], cb, depth + 2); free(vname); @@ -5024,7 +5022,7 @@ get_namewidth(zpool_handle_t *zhp, int min_width, int flags, boolean_t verbose) if ((config = zpool_get_config(zhp, NULL)) != NULL) { verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); - unsigned int poolname_len = strlen(zpool_get_name(zhp)); + size_t poolname_len = strlen(zpool_get_name(zhp)); if (verbose == B_FALSE) { width = MAX(poolname_len, min_width); } else { @@ -5963,7 +5961,7 @@ print_header(list_cbdata_t *cb) } if (!first) - (void) printf(" "); + (void) fputs(" ", stdout); else first = B_FALSE; @@ -5981,14 +5979,14 @@ print_header(list_cbdata_t *cb) } if (pl->pl_next == NULL && !right_justify) - (void) printf("%s", header); + (void) fputs(header, stdout); else if (right_justify) (void) printf("%*s", (int)width, header); else (void) printf("%-*s", (int)width, header); } - (void) printf("\n"); + (void) fputc('\n', stdout); } /* @@ -6018,9 +6016,9 @@ print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) if (!first) { if (cb->cb_scripted) - (void) printf("\t"); + (void) fputc('\t', stdout); else - (void) printf(" "); + (void) fputs(" ", stdout); } else { first = B_FALSE; } @@ -6050,14 +6048,14 @@ print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) * format specifier. */ if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify)) - (void) printf("%s", propstr); + (void) fputs(propstr, stdout); else if (right_justify) (void) printf("%*s", (int)width, propstr); else (void) printf("%-*s", (int)width, propstr); } - (void) printf("\n"); + (void) fputc('\n', stdout); } static void @@ -6130,8 +6128,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, char *vname; boolean_t scripted = cb->cb_scripted; uint64_t islog = B_FALSE; - char *dashes = "%-*s - - - - " - "- - - - -\n"; + const char *dashes = "%-*s - - - - " + "- - - - -\n"; verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &c) == 0); @@ -6193,7 +6191,7 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, } print_one_column(ZPOOL_PROP_HEALTH, 0, state, scripted, B_TRUE, format); - (void) printf("\n"); + (void) fputc('\n', stdout); } if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, @@ -6216,13 +6214,13 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, continue; vname = zpool_vdev_name(g_zfs, zhp, child[c], - cb->cb_name_flags); + cb->cb_name_flags | VDEV_NAME_TYPE_ID); print_list_stats(zhp, vname, child[c], cb, depth + 2, B_FALSE); free(vname); } /* list the classes: 'logs', 'dedup', and 'special' */ - for (uint_t n = 0; n < 3; n++) { + for (uint_t n = 0; n < ARRAY_SIZE(class_name); n++) { boolean_t printed = B_FALSE; for (c = 0; c < children; c++) { @@ -6250,7 +6248,7 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, printed = B_TRUE; } vname = zpool_vdev_name(g_zfs, zhp, child[c], - cb->cb_name_flags); + cb->cb_name_flags | VDEV_NAME_TYPE_ID); print_list_stats(zhp, vname, child[c], cb, depth + 2, B_FALSE); free(vname); @@ -9214,7 +9212,7 @@ zpool_do_upgrade(int argc, char **argv) } } - (void) printf(gettext("This system supports ZFS pool feature " + (void) printf("%s", gettext("This system supports ZFS pool feature " "flags.\n\n")); if (showversions) { int i; diff --git a/sys/contrib/openzfs/cmd/zpool_influxdb/zpool_influxdb.c b/sys/contrib/openzfs/cmd/zpool_influxdb/zpool_influxdb.c index f326b0420ee8..57bb2ee7bf0c 100644 --- a/sys/contrib/openzfs/cmd/zpool_influxdb/zpool_influxdb.c +++ b/sys/contrib/openzfs/cmd/zpool_influxdb/zpool_influxdb.c @@ -118,7 +118,7 @@ escape_string(const char *s) case '=': case '\\': *d++ = '\\'; - fallthrough; + zfs_fallthrough; default: *d = *c; } @@ -278,7 +278,7 @@ get_vdev_name(nvlist_t *nvroot, const char *parent_name) vdev_type); } else { (void) snprintf(vdev_name, sizeof (vdev_name), - "%s/%s-%llu", + "%.220s/%s-%llu", parent_name, vdev_type, (u_longlong_t)vdev_id); } return (vdev_name); @@ -818,7 +818,7 @@ main(int argc, char *argv[]) break; case 't': tagslen = strlen(optarg) + 2; - tags = calloc(tagslen, 1); + tags = calloc(1, tagslen); if (tags == NULL) { fprintf(stderr, "error: cannot allocate memory " diff --git a/sys/contrib/openzfs/cmd/zstream/zstream_dump.c b/sys/contrib/openzfs/cmd/zstream/zstream_dump.c index 45cf7b97a147..04a4986b45d8 100644 --- a/sys/contrib/openzfs/cmd/zstream/zstream_dump.c +++ b/sys/contrib/openzfs/cmd/zstream/zstream_dump.c @@ -297,6 +297,7 @@ zstream_do_dump(int argc, char *argv[]) fletcher_4_init(); while (read_hdr(drr, &zc)) { + uint64_t featureflags = 0; /* * If this is the first DMU record being processed, check for @@ -362,6 +363,9 @@ zstream_do_dump(int argc, char *argv[]) BSWAP_64(drrb->drr_fromguid); } + featureflags = + DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo); + (void) printf("BEGIN record\n"); (void) printf("\thdrtype = %lld\n", DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo)); @@ -461,6 +465,15 @@ zstream_do_dump(int argc, char *argv[]) BSWAP_64(drro->drr_maxblkid); } + if (featureflags & DMU_BACKUP_FEATURE_RAW && + drro->drr_bonuslen > drro->drr_raw_bonuslen) { + (void) fprintf(stderr, + "Warning: Object %llu has bonuslen = " + "%u > raw_bonuslen = %u\n\n", + (u_longlong_t)drro->drr_object, + drro->drr_bonuslen, drro->drr_raw_bonuslen); + } + payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro); if (verbose) { diff --git a/sys/contrib/openzfs/cmd/ztest/ztest.c b/sys/contrib/openzfs/cmd/ztest/ztest.c index bb2f14298279..292493584bf7 100644 --- a/sys/contrib/openzfs/cmd/ztest/ztest.c +++ b/sys/contrib/openzfs/cmd/ztest/ztest.c @@ -558,7 +558,7 @@ enum ztest_object { ZTEST_OBJECTS }; -static void usage(boolean_t) __NORETURN; +static _Noreturn void usage(boolean_t); static int ztest_scrub_impl(spa_t *spa); /* @@ -622,7 +622,7 @@ static void sig_handler(int signo) char *fatal_msg; -static __attribute__((noreturn)) __attribute__((format(printf, 2, 3))) void +static __attribute__((format(printf, 2, 3))) _Noreturn void fatal(int do_perror, char *message, ...) { va_list args; @@ -631,6 +631,8 @@ fatal(int do_perror, char *message, ...) (void) fflush(stdout); buf = umem_alloc(FATAL_MSG_SZ, UMEM_NOFAIL); + if (buf == NULL) + goto out; va_start(args, message); (void) sprintf(buf, "ztest: "); @@ -644,6 +646,7 @@ fatal(int do_perror, char *message, ...) (void) fprintf(stderr, "%s\n", buf); fatal_msg = buf; /* to ease debugging */ +out: if (ztest_dump_core) abort(); else @@ -2383,6 +2386,7 @@ zil_replay_func_t *ztest_replay_vector[TX_MAX_TYPE] = { NULL, /* TX_MKDIR_ATTR */ NULL, /* TX_MKDIR_ACL_ATTR */ NULL, /* TX_WRITE2 */ + NULL, /* TX_SETSAXATTR */ }; /* @@ -4269,7 +4273,15 @@ ztest_objset_destroy_cb(const char *name, void *arg) * Destroy the dataset. */ if (strchr(name, '@') != NULL) { - VERIFY0(dsl_destroy_snapshot(name, B_TRUE)); + error = dsl_destroy_snapshot(name, B_TRUE); + if (error != ECHRNG) { + /* + * The program was executed, but encountered a runtime + * error, such as insufficient slop, or a hold on the + * dataset. + */ + ASSERT0(error); + } } else { error = dsl_destroy_head(name); if (error == ENOSPC) { @@ -6981,7 +6993,7 @@ ztest_resume(spa_t *spa) (void) zio_resume(spa); } -static void +static _Noreturn void ztest_resume_thread(void *arg) { spa_t *spa = arg; @@ -7007,7 +7019,7 @@ ztest_resume_thread(void *arg) thread_exit(); } -static void +static _Noreturn void ztest_deadman_thread(void *arg) { ztest_shared_t *zs = arg; @@ -7085,7 +7097,7 @@ ztest_execute(int test, ztest_info_t *zi, uint64_t id) (double)functime / NANOSEC, zi->zi_funcname); } -static void +static _Noreturn void ztest_thread(void *arg) { int rand; diff --git a/sys/contrib/openzfs/cmd/zvol_id/zvol_id_main.c b/sys/contrib/openzfs/cmd/zvol_id/zvol_id_main.c index 22f2e848cba1..929a1a6e794d 100644 --- a/sys/contrib/openzfs/cmd/zvol_id/zvol_id_main.c +++ b/sys/contrib/openzfs/cmd/zvol_id/zvol_id_main.c @@ -35,6 +35,21 @@ #include <sys/zfs_znode.h> #include <sys/fs/zfs.h> +#if defined(ZFS_ASAN_ENABLED) +/* + * zvol_id is invoked by udev with the help of ptrace() + * making sanitized binary with leak detection croak + * because of tracing mechanisms collision + */ +extern const char *__asan_default_options(void); + +const char *__asan_default_options(void) { + return ("abort_on_error=true:halt_on_error=true:" + "allocator_may_return_null=true:disable_coredump=false:" + "detect_stack_use_after_return=true:detect_leaks=false"); +} +#endif + static int ioctl_get_msg(char *var, int fd) { diff --git a/sys/contrib/openzfs/cmd/zvol_wait/Makefile.am b/sys/contrib/openzfs/cmd/zvol_wait/Makefile.am index ee66d51de96f..e8b546a60659 100644 --- a/sys/contrib/openzfs/cmd/zvol_wait/Makefile.am +++ b/sys/contrib/openzfs/cmd/zvol_wait/Makefile.am @@ -2,4 +2,3 @@ include $(top_srcdir)/config/Shellcheck.am dist_bin_SCRIPTS = zvol_wait -SHELLCHECK_OPTS = --enable=all |