Skip to content

Commit c5c5a29

Browse files
tonyhutterdefaziogiancarlo
authored andcommitted
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 Reviewed-by: Don Brady <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Tony Hutter <[email protected]> Closes openzfs#15462
1 parent 4df6c81 commit c5c5a29

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
@@ -222,8 +222,12 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
222222
}
223223

224224
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_PHYS_PATH, &physpath);
225+
226+
update_vdev_config_dev_sysfs_path(vdev, path,
227+
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
225228
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
226229
&enc_sysfs_path);
230+
227231
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
228232
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_OFFLINE, &offline);
229233
(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

@@ -907,6 +908,25 @@ _zed_event_add_time_strings(uint64_t eid, zed_strings_t *zsp, int64_t etime[])
907908
}
908909
}
909910

911+
912+
static void
913+
_zed_event_update_enc_sysfs_path(nvlist_t *nvl)
914+
{
915+
const char *vdev_path;
916+
917+
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_PATH,
918+
&vdev_path) != 0) {
919+
return; /* some other kind of event, ignore it */
920+
}
921+
922+
if (vdev_path == NULL) {
923+
return;
924+
}
925+
926+
update_vdev_config_dev_sysfs_path(nvl, vdev_path,
927+
FM_EREPORT_PAYLOAD_ZFS_VDEV_ENC_SYSFS_PATH);
928+
}
929+
910930
/*
911931
* Service the next zevent, blocking until one is available.
912932
*/
@@ -954,6 +974,17 @@ zed_event_service(struct zed_conf *zcp)
954974
zed_log_msg(LOG_WARNING,
955975
"Failed to lookup zevent class (eid=%llu)", eid);
956976
} else {
977+
/*
978+
* Special case: If we can dynamically detect an enclosure sysfs
979+
* path, then use that value rather than the one stored in the
980+
* vd->vdev_enc_sysfs_path. There have been rare cases where
981+
* vd->vdev_enc_sysfs_path becomes outdated. However, there
982+
* will be other times when we can not dynamically detect the
983+
* sysfs path (like if a disk disappears) and have to rely on
984+
* the old value for things like turning on the fault LED.
985+
*/
986+
_zed_event_update_enc_sysfs_path(nvl);
987+
957988
/* let internal modules see this event first */
958989
zfs_agent_post_event(class, NULL, nvl);
959990

cmd/zpool/zpool.d/ses

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,18 @@ for i in $scripts ; do
3232
val=""
3333
case $i in
3434
enc)
35-
val=$(ls "$VDEV_ENC_SYSFS_PATH/../../" 2>/dev/null)
35+
if echo "$VDEV_ENC_SYSFS_PATH" | grep -q '/sys/bus/pci/slots' ; then
36+
val="$VDEV_ENC_SYSFS_PATH"
37+
else
38+
val="$(ls """$VDEV_ENC_SYSFS_PATH/../../""" 2>/dev/null)"
39+
fi
3640
;;
3741
slot)
38-
val=$(cat "$VDEV_ENC_SYSFS_PATH/slot" 2>/dev/null)
42+
if echo "$VDEV_ENC_SYSFS_PATH" | grep -q '/sys/bus/pci/slots' ; then
43+
val="$(basename """$VDEV_ENC_SYSFS_PATH""")"
44+
else
45+
val="$(cat """$VDEV_ENC_SYSFS_PATH/slot""" 2>/dev/null)"
46+
fi
3947
;;
4048
encdev)
4149
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
@@ -373,6 +373,10 @@ make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)
373373
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
374374
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
375375

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

include/libzutil.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ int for_each_vdev_cb(void *zhp, nvlist_t *nv, pool_vdev_iter_f func,
187187
int for_each_vdev_in_nvlist(nvlist_t *nvroot, pool_vdev_iter_f func,
188188
void *data);
189189
void update_vdevs_config_dev_sysfs_path(nvlist_t *config);
190+
_LIBZUTIL_H void update_vdev_config_dev_sysfs_path(nvlist_t *nv,
191+
const char *path, const char *key);
190192
#ifdef __cplusplus
191193
}
192194
#endif

lib/libzutil/os/freebsd/zutil_import_os.c

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

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

lib/libzutil/os/linux/zutil_import_os.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -781,9 +781,12 @@ encode_device_strings(const char *path, vdev_dev_strs_t *ds,
781781
* Rescan the enclosure sysfs path for turning on enclosure LEDs and store it
782782
* in the nvlist * (if applicable). Like:
783783
* vdev_enc_sysfs_path: '/sys/class/enclosure/11:0:1:0/SLOT 4'
784+
*
785+
* key: The nvlist_t name (like ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH)
784786
*/
785-
static void
786-
update_vdev_config_dev_sysfs_path(nvlist_t *nv, char *path)
787+
void
788+
update_vdev_config_dev_sysfs_path(nvlist_t *nv, const char *path,
789+
const char *key)
787790
{
788791
char *upath, *spath;
789792

@@ -792,9 +795,9 @@ update_vdev_config_dev_sysfs_path(nvlist_t *nv, char *path)
792795
spath = zfs_get_enclosure_sysfs_path(upath);
793796

794797
if (spath) {
795-
nvlist_add_string(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH, spath);
798+
(void) nvlist_add_string(nv, key, spath);
796799
} else {
797-
nvlist_remove_all(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
800+
(void) nvlist_remove_all(nv, key);
798801
}
799802

800803
free(upath);
@@ -812,7 +815,8 @@ sysfs_path_pool_vdev_iter_f(void *hdl_data, nvlist_t *nv, void *data)
812815
return (1);
813816

814817
/* Rescan our enclosure sysfs path for this vdev */
815-
update_vdev_config_dev_sysfs_path(nv, path);
818+
update_vdev_config_dev_sysfs_path(nv, path,
819+
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
816820
return (0);
817821
}
818822

@@ -901,7 +905,8 @@ update_vdev_config_dev_strs(nvlist_t *nv)
901905
(void) nvlist_add_string(nv, ZPOOL_CONFIG_PHYS_PATH,
902906
vds.vds_devphys);
903907
}
904-
update_vdev_config_dev_sysfs_path(nv, path);
908+
update_vdev_config_dev_sysfs_path(nv, path,
909+
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
905910
} else {
906911
/* Clear out any stale entries. */
907912
(void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID);

0 commit comments

Comments
 (0)