diff options
author | Joshua M. Clulow <josh@sysmgr.org> | 2022-11-08 12:54:43 -0800 |
---|---|---|
committer | Joshua M. Clulow <josh@sysmgr.org> | 2022-11-08 12:54:43 -0800 |
commit | b4fb003914e70b41d96dec8011864f6af1faf3ef (patch) | |
tree | f64867f9ae24b071f386b0c2fe24a47bd97bce79 /usr/src/lib | |
parent | 77c0a660417a046bfab6c8ef58d00c181c0264b3 (diff) | |
download | illumos-joyent-b4fb003914e70b41d96dec8011864f6af1faf3ef.tar.gz |
14978 ZFS autoexpand property should work for root pools
Reviewed by: Andy Fiddaman <illumos@fiddaman.net>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@mnx.io>
Diffstat (limited to 'usr/src/lib')
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs.h | 2 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_pool.c | 115 | ||||
-rw-r--r-- | usr/src/lib/libzfs/common/mapfile-vers | 1 | ||||
-rw-r--r-- | usr/src/lib/libzpool/Makefile.com | 2 |
4 files changed, 72 insertions, 48 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs.h b/usr/src/lib/libzfs/common/libzfs.h index 0516845d24..df89daf19a 100644 --- a/usr/src/lib/libzfs/common/libzfs.h +++ b/usr/src/lib/libzfs/common/libzfs.h @@ -316,6 +316,8 @@ extern nvlist_t *zpool_find_vdev_by_physpath(zpool_handle_t *, const char *, boolean_t *, boolean_t *, boolean_t *); extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, const char *, zpool_boot_label_t, uint64_t, int *); +extern void zpool_vdev_refresh_path(libzfs_handle_t *, zpool_handle_t *, + nvlist_t *); /* * Functions to manage pool properties diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c index 6e634a81cb..6f072e4935 100644 --- a/usr/src/lib/libzfs/common/libzfs_pool.c +++ b/usr/src/lib/libzfs/common/libzfs_pool.c @@ -28,6 +28,7 @@ * Copyright (c) 2017 Datto Inc. * Copyright (c) 2017, Intel Corporation. * Copyright 2022 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 Oxide Computer Company */ #include <ctype.h> @@ -3960,17 +3961,70 @@ set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path) } /* + * This routine is responsible for identifying when disks have been + * reconfigured in a new location. The kernel will have opened the device by + * devid, but the path will still refer to the old location. To catch this, we + * first do a path -> devid translation (which is fast for the common case). + * If the devid matches, we're done. If not, we do a reverse devid -> path + * translation and issue the appropriate ioctl() to update the path of the + * vdev. + */ +void +zpool_vdev_refresh_path(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv) +{ + char *path = NULL; + char *newpath = NULL; + char *physpath = NULL; + char *devid = NULL; + + if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0) { + return; + } + + if (nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) { + /* + * This vdev has a devid. We can use it to check the current + * path. + */ + char *newdevid = path_to_devid(path); + + if (newdevid == NULL || strcmp(devid, newdevid) != 0) { + newpath = devid_to_path(devid); + } + + if (newdevid != NULL) { + devid_str_free(newdevid); + } + + } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PHYS_PATH, + &physpath) == 0) { + /* + * This vdev does not have a devid, but it does have a physical + * path. Attempt to translate this to a /dev path. + */ + newpath = path_from_physpath(hdl, path, physpath); + } + + if (newpath == NULL) { + /* + * No path update is required. + */ + return; + } + + set_path(zhp, nv, newpath); + fnvlist_add_string(nv, ZPOOL_CONFIG_PATH, newpath); + + free(newpath); +} + +/* * Given a vdev, return the name to display in iostat. If the vdev has a path, * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type. - * We also check if this is a whole disk, in which case we strip off the - * trailing 's0' slice name. + * We will confirm that the path and name of the vdev are current, and update + * them if not. We also check if this is a whole disk, in which case we strip + * off the trailing 's0' slice name. * - * This routine is also responsible for identifying when disks have been - * reconfigured in a new location. The kernel will have opened the device by - * devid, but the path will still refer to the old location. To catch this, we - * first do a path -> devid translation (which is fast for the common case). If - * the devid matches, we're done. If not, we do a reverse devid -> path - * translation and issue the appropriate ioctl() to update the path of the vdev. * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any * of these checks. */ @@ -4013,9 +4067,6 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv, } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { vdev_stat_t *vs; uint_t vsc; - char *newpath = NULL; - char *physpath = NULL; - char *devid = NULL; /* * If the device is dead (faulted, offline, etc) then don't @@ -4030,42 +4081,12 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv, goto after_open; } - if (nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) { - /* - * This vdev has a devid. We can use it to check the - * current path. - */ - char *newdevid = path_to_devid(path); - - if (newdevid == NULL || strcmp(devid, newdevid) != 0) { - newpath = devid_to_path(devid); - } - - if (newdevid != NULL) - devid_str_free(newdevid); - - } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PHYS_PATH, - &physpath) == 0) { - /* - * This vdev does not have a devid, but it does have a - * physical path. Attempt to translate this to a /dev - * path. - */ - newpath = path_from_physpath(hdl, path, physpath); - } - - if (newpath != NULL) { - /* - * Update the path appropriately. - */ - set_path(zhp, nv, newpath); - if (nvlist_add_string(nv, ZPOOL_CONFIG_PATH, - newpath) == 0) { - verify(nvlist_lookup_string(nv, - ZPOOL_CONFIG_PATH, &path) == 0); - } - free(newpath); - } + /* + * Refresh the /dev path for this vdev if required, then ensure + * we're using the latest path value: + */ + zpool_vdev_refresh_path(hdl, zhp, nv); + path = fnvlist_lookup_string(nv, ZPOOL_CONFIG_PATH); if (name_flags & VDEV_NAME_FOLLOW_LINKS) { char *rp = realpath(path, NULL); diff --git a/usr/src/lib/libzfs/common/mapfile-vers b/usr/src/lib/libzfs/common/mapfile-vers index 196751b44c..4c2c6e67fe 100644 --- a/usr/src/lib/libzfs/common/mapfile-vers +++ b/usr/src/lib/libzfs/common/mapfile-vers @@ -279,6 +279,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zpool_vdev_name; zpool_vdev_offline; zpool_vdev_online; + zpool_vdev_refresh_path; zpool_vdev_remove; zpool_vdev_remove_cancel; zpool_vdev_split; diff --git a/usr/src/lib/libzpool/Makefile.com b/usr/src/lib/libzpool/Makefile.com index d52d56b1ff..47ff1d0b76 100644 --- a/usr/src/lib/libzpool/Makefile.com +++ b/usr/src/lib/libzpool/Makefile.com @@ -68,7 +68,7 @@ CSTD= $(CSTD_GNU99) CFLAGS += $(CCGDEBUG) $(CCVERBOSE) $(CNOGLOBAL) CFLAGS64 += $(CCGDEBUG) $(CCVERBOSE) $(CNOGLOBAL) -LDLIBS += -lcmdutils -lumem -lavl -lnvpair -lz -lc -lsysevent -lmd \ +LDLIBS += -lcmdutils -lumem -lavl -lnvpair -lz -lc -lmd \ -lfakekernel -lzutil NATIVE_LIBS += libz.so CPPFLAGS.first = -I$(SRC)/lib/libfakekernel/common |