Skip to content

Commit ac26dbe

Browse files
committed
zed: misc vdev_enc_sysfs_path fixes
There have been rare cases where the VDEV_ENC_SYSFS_PATH value that zed gets passed is stale. To mitigate this, dynamically check the sysfs path at the time of zed event processing, and use the dynamic value if possible. Note that there will be other times when we can not dynamically detect the sysfs path (like if a disk disappears) and have to rely on the old value for things like turning on the fault LED. That is to say, we can't just blindly use the dynamic path in every case. Also: - Add enclosure sysfs entry when running 'zpool add' - Fix 'slot' and 'enc' zpool.d scripts for nvme Signed-off-by: Tony Hutter <[email protected]>
1 parent 05c4710 commit ac26dbe

File tree

7 files changed

+71
-8
lines changed

7 files changed

+71
-8
lines changed

cmd/zed/agents/zfs_mod.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,12 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
233233
}
234234

235235
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_PHYS_PATH, &physpath);
236+
237+
update_vdev_config_dev_sysfs_path(vdev, path,
238+
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
236239
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
237240
&enc_sysfs_path);
241+
238242
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
239243
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_OFFLINE, &offline);
240244
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_FAULTED, &faulted);

cmd/zed/zed_event.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "zed_strings.h"
3636

3737
#include "agents/zfs_agents.h"
38+
#include <libzutil.h>
3839

3940
#define MAXBUF 4096
4041

@@ -922,6 +923,25 @@ _zed_event_add_time_strings(uint64_t eid, zed_strings_t *zsp, int64_t etime[])
922923
}
923924
}
924925

926+
927+
static void
928+
_zed_event_update_enc_sysfs_path(nvlist_t *nvl)
929+
{
930+
const char *vdev_path;
931+
932+
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_PATH,
933+
&vdev_path) != 0) {
934+
return; /* some other kind of event, ignore it */
935+
}
936+
937+
if (vdev_path == NULL) {
938+
return;
939+
}
940+
941+
update_vdev_config_dev_sysfs_path(nvl, vdev_path,
942+
FM_EREPORT_PAYLOAD_ZFS_VDEV_ENC_SYSFS_PATH);
943+
}
944+
925945
/*
926946
* Service the next zevent, blocking until one is available.
927947
*/
@@ -969,6 +989,17 @@ zed_event_service(struct zed_conf *zcp)
969989
zed_log_msg(LOG_WARNING,
970990
"Failed to lookup zevent class (eid=%llu)", eid);
971991
} else {
992+
/*
993+
* Special case: If we can dynamically detect an enclosure sysfs
994+
* path, then use that value rather than the one stored in the
995+
* vd->vdev_enc_sysfs_path. There have been rare cases where
996+
* vd->vdev_enc_sysfs_path becomes outdated. However, there
997+
* will be other times when we can not dynamically detect the
998+
* sysfs path (like if a disk disappears) and have to rely on the
999+
* old value for things like turning on the fault LED.
1000+
*/
1001+
_zed_event_update_enc_sysfs_path(nvl);
1002+
9721003
/* let internal modules see this event first */
9731004
zfs_agent_post_event(class, NULL, nvl);
9741005

cmd/zpool/zpool.d/ses

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,18 @@ for i in $scripts ; do
3333
val=""
3434
case $i in
3535
enc)
36-
val=$(ls "$VDEV_ENC_SYSFS_PATH/../../" 2>/dev/null)
36+
if echo "$VDEV_ENC_SYSFS_PATH" | grep -q '/sys/bus/pci/slots' ; then
37+
val="$VDEV_ENC_SYSFS_PATH"
38+
else
39+
val=$(ls "$VDEV_ENC_SYSFS_PATH/../../" 2>/dev/null)
40+
fi
3741
;;
3842
slot)
39-
val=$(cat "$VDEV_ENC_SYSFS_PATH/slot" 2>/dev/null)
43+
if echo "$VDEV_ENC_SYSFS_PATH" | grep -q '/sys/bus/pci/slots' ; then
44+
val="$(basename $VDEV_ENC_SYSFS_PATH)"
45+
else
46+
val=$(cat "$VDEV_ENC_SYSFS_PATH/slot" 2>/dev/null)
47+
fi
4048
;;
4149
encdev)
4250
val=$(ls "$VDEV_ENC_SYSFS_PATH/../device/scsi_generic" 2>/dev/null)

cmd/zpool/zpool_vdev.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)
372372
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
373373
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
374374

375+
/* Lookup and add the enclosure sysfs path (if exists) */
376+
update_vdev_config_dev_sysfs_path(vdev, path,
377+
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
378+
375379
if (strcmp(type, VDEV_TYPE_DISK) == 0)
376380
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
377381
(uint64_t)wholedisk) == 0);

include/libzutil.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ int for_each_vdev_cb(void *zhp, nvlist_t *nv, pool_vdev_iter_f func,
208208
int for_each_vdev_in_nvlist(nvlist_t *nvroot, pool_vdev_iter_f func,
209209
void *data);
210210
void update_vdevs_config_dev_sysfs_path(nvlist_t *config);
211+
_LIBZUTIL_H void update_vdev_config_dev_sysfs_path(nvlist_t *nv,
212+
const char *path, const char *key);
211213
#ifdef __cplusplus
212214
}
213215
#endif

lib/libzutil/os/freebsd/zutil_import_os.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,15 @@ zfs_dev_flush(int fd)
249249
return (0);
250250
}
251251

252+
void
253+
update_vdev_config_dev_sysfs_path(nvlist_t *nv, const char *path, const char
254+
*key)
255+
{
256+
(void) nv;
257+
(void) path;
258+
(void) key;
259+
}
260+
252261
void
253262
update_vdevs_config_dev_sysfs_path(nvlist_t *config)
254263
{

lib/libzutil/os/linux/zutil_import_os.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -766,9 +766,12 @@ encode_device_strings(const char *path, vdev_dev_strs_t *ds,
766766
* Rescan the enclosure sysfs path for turning on enclosure LEDs and store it
767767
* in the nvlist * (if applicable). Like:
768768
* vdev_enc_sysfs_path: '/sys/class/enclosure/11:0:1:0/SLOT 4'
769+
*
770+
* key: The nvlist_t name (like ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH)
769771
*/
770-
static void
771-
update_vdev_config_dev_sysfs_path(nvlist_t *nv, const char *path)
772+
void
773+
update_vdev_config_dev_sysfs_path(nvlist_t *nv, const char *path, const char
774+
*key)
772775
{
773776
char *upath, *spath;
774777

@@ -777,9 +780,9 @@ update_vdev_config_dev_sysfs_path(nvlist_t *nv, const char *path)
777780
spath = zfs_get_enclosure_sysfs_path(upath);
778781

779782
if (spath) {
780-
nvlist_add_string(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH, spath);
783+
(void) nvlist_add_string(nv, key, spath);
781784
} else {
782-
nvlist_remove_all(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
785+
(void) nvlist_remove_all(nv, key);
783786
}
784787

785788
free(upath);
@@ -799,7 +802,8 @@ sysfs_path_pool_vdev_iter_f(void *hdl_data, nvlist_t *nv, void *data)
799802
return (1);
800803

801804
/* Rescan our enclosure sysfs path for this vdev */
802-
update_vdev_config_dev_sysfs_path(nv, path);
805+
update_vdev_config_dev_sysfs_path(nv, path,
806+
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
803807
return (0);
804808
}
805809

@@ -888,7 +892,8 @@ update_vdev_config_dev_strs(nvlist_t *nv)
888892
(void) nvlist_add_string(nv, ZPOOL_CONFIG_PHYS_PATH,
889893
vds.vds_devphys);
890894
}
891-
update_vdev_config_dev_sysfs_path(nv, path);
895+
update_vdev_config_dev_sysfs_path(nv, path,
896+
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
892897
} else {
893898
/* Clear out any stale entries. */
894899
(void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID);

0 commit comments

Comments
 (0)