Skip to content

Commit

Permalink
Rescan enclosure sysfs path on import
Browse files Browse the repository at this point in the history
When you create a pool, zfs writes vd->vdev_enc_sysfs_path with the
enclosure sysfs path to the fault LEDs, like:

  vdev_enc_sysfs_path = /sys/class/enclosure/0:0:1:0/SLOT8

However, this enclosure path doesn't get updated on successive imports
even if enclosure path to the disk changes.  This patch fixes the issue.

The largest part of this patch is moving for_each_vdev_vdev() and
associated function from zpool_iter.c to libzutil.  This was needed
to make those functions visible to the cache import codepath for
sysfs path re-scan.  This also updates the .abi files so 'make checkabi'
is happy.

Signed-off-by: Tony Hutter <[email protected]>
Fixes: #11950
  • Loading branch information
tonyhutter committed Aug 5, 2021
1 parent 7eebcd2 commit 70c3e7e
Show file tree
Hide file tree
Showing 16 changed files with 12,868 additions and 6,838 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/checkstyle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:

jobs:
checkstyle:
runs-on: ubuntu-18.04
runs-on: ubuntu-21.04
steps:
- uses: actions/checkout@v2
with:
Expand Down
3 changes: 2 additions & 1 deletion cmd/zpool/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ zpool_LDADD = \
$(abs_top_builddir)/lib/libzfs/libzfs.la \
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
$(abs_top_builddir)/lib/libuutil/libuutil.la
$(abs_top_builddir)/lib/libuutil/libuutil.la \
$(abs_top_builddir)/lib/libzutil/libzutil.la

zpool_LDADD += $(LTLIBINTL)

Expand Down
66 changes: 0 additions & 66 deletions cmd/zpool/zpool_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,72 +264,6 @@ for_each_pool(int argc, char **argv, boolean_t unavail,
return (ret);
}

static int
for_each_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, pool_vdev_iter_f func,
void *data)
{
nvlist_t **child;
uint_t c, children;
int ret = 0;
int i;
char *type;

const char *list[] = {
ZPOOL_CONFIG_SPARES,
ZPOOL_CONFIG_L2CACHE,
ZPOOL_CONFIG_CHILDREN
};

for (i = 0; i < ARRAY_SIZE(list); i++) {
if (nvlist_lookup_nvlist_array(nv, list[i], &child,
&children) == 0) {
for (c = 0; c < children; c++) {
uint64_t ishole = 0;

(void) nvlist_lookup_uint64(child[c],
ZPOOL_CONFIG_IS_HOLE, &ishole);

if (ishole)
continue;

ret |= for_each_vdev_cb(zhp, child[c], func,
data);
}
}
}

if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
return (ret);

/* Don't run our function on root vdevs */
if (strcmp(type, VDEV_TYPE_ROOT) != 0) {
ret |= func(zhp, nv, data);
}

return (ret);
}

/*
* This is the equivalent of for_each_pool() for vdevs. It iterates thorough
* all vdevs in the pool, ignoring root vdevs and holes, calling func() on
* each one.
*
* @zhp: Zpool handle
* @func: Function to call on each vdev
* @data: Custom data to pass to the function
*/
int
for_each_vdev(zpool_handle_t *zhp, pool_vdev_iter_f func, void *data)
{
nvlist_t *config, *nvroot = NULL;

if ((config = zpool_get_config(zhp, NULL)) != NULL) {
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
&nvroot) == 0);
}
return (for_each_vdev_cb(zhp, nvroot, func, data));
}

/*
* Process the vcdl->vdev_cmd_data[] array to figure out all the unique column
* names and their widths. When this function is done, vcdl->uniq_cols,
Expand Down
4 changes: 0 additions & 4 deletions cmd/zpool/zpool_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@ nvlist_t *split_mirror_vdev(zpool_handle_t *zhp, char *newname,
int for_each_pool(int, char **, boolean_t unavail, zprop_list_t **,
boolean_t, zpool_iter_f, void *);

/* Vdev list functions */
typedef int (*pool_vdev_iter_f)(zpool_handle_t *, nvlist_t *, void *);
int for_each_vdev(zpool_handle_t *zhp, pool_vdev_iter_f func, void *data);

typedef struct zpool_list zpool_list_t;

zpool_list_t *pool_list_get(int, char **, zprop_list_t **, boolean_t, int *);
Expand Down
7 changes: 7 additions & 0 deletions include/libzfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,13 @@ _LIBZFS_H boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *,
_LIBZFS_H int zfs_spa_version(zfs_handle_t *, int *);
_LIBZFS_H boolean_t zfs_bookmark_exists(const char *path);

/* Vdev list functions */
typedef int (*pool_vdev_iter_f)(zpool_handle_t *, nvlist_t *, void *);
extern int for_each_vdev(zpool_handle_t *zhp, pool_vdev_iter_f func,
void *data);
extern int for_each_vdev_in_nvlist(nvlist_t *nvroot, pool_vdev_iter_f func,
void *data);

/*
* Mount support functions.
*/
Expand Down
1 change: 1 addition & 0 deletions include/libzutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ struct udev_device;
_LIBZUTIL_H int zfs_device_get_devid(struct udev_device *, char *, size_t);
_LIBZUTIL_H int zfs_device_get_physical(struct udev_device *, char *, size_t);

_LIBZUTIL_H void update_vdevs_config_dev_sysfs_path(nvlist_t *config);
_LIBZUTIL_H void update_vdev_config_dev_strs(nvlist_t *);

/*
Expand Down
3 changes: 2 additions & 1 deletion lib/libzfs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ libzfs_la_LIBADD = \
$(abs_top_builddir)/lib/libshare/libshare.la \
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
$(abs_top_builddir)/lib/libuutil/libuutil.la
$(abs_top_builddir)/lib/libuutil/libuutil.la \
$(abs_top_builddir)/lib/libzutil/libzutil.la

libzfs_la_LIBADD += -lm $(LIBCRYPTO_LIBS) $(ZLIB_LIBS) $(LIBFETCH_LIBS) $(LTLIBINTL)

Expand Down
12,430 changes: 8,413 additions & 4,017 deletions lib/libzfs/libzfs.abi

Large diffs are not rendered by default.

12 changes: 0 additions & 12 deletions lib/libzfs/libzfs_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,18 +212,6 @@ namespace_reload(libzfs_handle_t *hdl)
return (0);
}

/*
* Retrieve the configuration for the given pool. The configuration is an nvlist
* describing the vdevs, as well as the statistics associated with each one.
*/
nvlist_t *
zpool_get_config(zpool_handle_t *zhp, nvlist_t **oldconfig)
{
if (oldconfig)
*oldconfig = zhp->zpool_old_config;
return (zhp->zpool_config);
}

/*
* Retrieves a list of enabled features and their refcounts and caches it in
* the pool handle.
Expand Down
Loading

0 comments on commit 70c3e7e

Please sign in to comment.