From 77c0a660417a046bfab6c8ef58d00c181c0264b3 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Thu, 27 Oct 2022 09:07:04 +0300 Subject: 15128 libnsl: variable is used uninitialized Reviewed by: Andy Fiddaman Reviewed by: Marcel Telka Approved by: Robert Mustacchi --- usr/src/lib/libnsl/ipsec/algs.c | 2 +- usr/src/lib/libnsl/rpc/clnt_generic.c | 88 +++++++++++++++++------------------ 2 files changed, 44 insertions(+), 46 deletions(-) (limited to 'usr/src/lib') diff --git a/usr/src/lib/libnsl/ipsec/algs.c b/usr/src/lib/libnsl/ipsec/algs.c index 6620f02cae..a20473a6da 100644 --- a/usr/src/lib/libnsl/ipsec/algs.c +++ b/usr/src/lib/libnsl/ipsec/algs.c @@ -591,7 +591,7 @@ void _build_internal_algs(ipsec_proto_t **alg_context, int *alg_nums) { FILE *f; - int rc, trash_num; + int rc, trash_num = 0; ipsec_proto_t *new_protos = NULL, *trash; time_t filetime; struct stat statbuf; diff --git a/usr/src/lib/libnsl/rpc/clnt_generic.c b/usr/src/lib/libnsl/rpc/clnt_generic.c index 34deeb1f2c..8801686a96 100644 --- a/usr/src/lib/libnsl/rpc/clnt_generic.c +++ b/usr/src/lib/libnsl/rpc/clnt_generic.c @@ -68,11 +68,11 @@ CLIENT *_clnt_tli_create_timed(int, const struct netconfig *, struct netbuf *, */ CLIENT * clnt_create_vers(const char *hostname, const rpcprog_t prog, - rpcvers_t *vers_out, const rpcvers_t vers_low, - const rpcvers_t vers_high, const char *nettype) + rpcvers_t *vers_out, const rpcvers_t vers_low, + const rpcvers_t vers_high, const char *nettype) { return (clnt_create_vers_timed(hostname, prog, vers_out, vers_low, - vers_high, nettype, NULL)); + vers_high, nettype, NULL)); } /* @@ -102,7 +102,7 @@ clnt_create_vers_timed(const char *hostname, const rpcprog_t prog, to = *tp; rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t)xdr_void, - NULL, (xdrproc_t)xdr_void, NULL, to); + NULL, (xdrproc_t)xdr_void, NULL, to); if (rpc_stat == RPC_SUCCESS) { *vers_out = vers_high; return (clnt); @@ -126,8 +126,7 @@ clnt_create_vers_timed(const char *hostname, const rpcprog_t prog, } CLNT_CONTROL(clnt, CLSET_VERS, (char *)&v_high); rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t)xdr_void, - NULL, (xdrproc_t)xdr_void, - NULL, to); + NULL, (xdrproc_t)xdr_void, NULL, to); if (rpc_stat == RPC_SUCCESS) { *vers_out = v_high; return (clnt); @@ -250,7 +249,7 @@ clnt_create_timed(const char *hostname, const rpcprog_t prog, */ if (rpc_createerr.cf_stat == RPC_SYSTEMERROR) { syslog(LOG_ERR, "clnt_create_timed: " - "RPC_SYSTEMERROR."); + "RPC_SYSTEMERROR."); break; } @@ -267,8 +266,8 @@ clnt_create_timed(const char *hostname, const rpcprog_t prog, * translation failed'' or ``unknown host name'' */ if ((rpc_createerr.cf_stat == RPC_N2AXLATEFAILURE || - rpc_createerr.cf_stat == RPC_UNKNOWNHOST) && - (save_cf_stat != RPC_SUCCESS)) { + rpc_createerr.cf_stat == RPC_UNKNOWNHOST) && + (save_cf_stat != RPC_SUCCESS)) { rpc_createerr.cf_stat = save_cf_stat; rpc_createerr.cf_error = save_cf_error; } @@ -289,9 +288,9 @@ clnt_create_timed(const char *hostname, const rpcprog_t prog, CLIENT * clnt_create_service_timed(const char *host, const char *service, - const rpcprog_t prog, const rpcvers_t vers, - const ushort_t port, const char *netclass, - const struct timeval *tmout) + const rpcprog_t prog, const rpcvers_t vers, + const ushort_t port, const char *netclass, + const struct timeval *tmout) { int fd; void *handle; @@ -399,7 +398,6 @@ clnt_create_service_timed(const char *host, const char *service, __rpc_set_mac_options(fd, nconf, prog); - /* LINTED pointer cast */ if ((tbind = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR)) == NULL) { (void) t_close(fd); @@ -423,18 +421,17 @@ clnt_create_service_timed(const char *host, const char *service, netdir_free((void *)raddrs, ND_ADDRLIST); if (port) { - if (strcmp(nconf->nc_protofmly, NC_INET) == 0) - /* LINTED pointer alignment */ + if (strcmp(nconf->nc_protofmly, NC_INET) == 0) { ((struct sockaddr_in *) - tbind->addr.buf)->sin_port = htons(port); - else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) - /* LINTED pointer alignment */ + tbind->addr.buf)->sin_port = htons(port); + } else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) { ((struct sockaddr_in6 *) - tbind->addr.buf)->sin6_port = htons(port); + tbind->addr.buf)->sin6_port = htons(port); + } } clnt = _clnt_tli_create_timed(fd, nconf, &tbind->addr, - prog, vers, 0, 0, &to); + prog, vers, 0, 0, &to); if (clnt == NULL) { if (tbind) @@ -453,7 +450,7 @@ clnt_create_service_timed(const char *host, const char *service, */ rpc_createerr.cf_stat = clnt_call(clnt, NULLPROC, - xdr_void, 0, xdr_void, 0, to); + xdr_void, 0, xdr_void, 0, to); rpc_createerr.cf_error.re_errno = rpc_callerr.re_status; rpc_createerr.cf_error.re_terrno = 0; @@ -464,8 +461,9 @@ clnt_create_service_timed(const char *host, const char *service, if (tbind) (void) t_free((char *)tbind, T_BIND); continue; - } else + } else { break; + } } __rpc_endconf(handle); @@ -520,15 +518,16 @@ clnt_tp_create_timed(const char *hostname, const rpcprog_t prog, /* * Get the address of the server */ - if ((svcaddr = __rpcb_findaddr_timed(prog, vers, - (struct netconfig *)nconf, (char *)hostname, - &cl, (struct timeval *)tp)) == NULL) { + svcaddr = __rpcb_findaddr_timed(prog, vers, + (struct netconfig *)nconf, (char *)hostname, + &cl, (struct timeval *)tp); + if (svcaddr == NULL) { /* appropriate error number is set by rpcbind libraries */ return (NULL); } if (cl == NULL) { cl = _clnt_tli_create_timed(RPC_ANYFD, nconf, svcaddr, - prog, vers, 0, 0, tp); + prog, vers, 0, 0, tp); } else { /* Reuse the CLIENT handle and change the appropriate fields */ if (CLNT_CONTROL(cl, CLSET_SVC_ADDR, (void *)svcaddr) == TRUE) { @@ -538,8 +537,8 @@ clnt_tp_create_timed(const char *hostname, const rpcprog_t prog, netdir_free((char *)svcaddr, ND_ADDR); rpc_createerr.cf_stat = RPC_SYSTEMERROR; syslog(LOG_ERR, - "clnt_tp_create_timed: " - "strdup failed."); + "clnt_tp_create_timed: " + "strdup failed."); return (NULL); } } @@ -551,8 +550,8 @@ clnt_tp_create_timed(const char *hostname, const rpcprog_t prog, free(cl->cl_netid); rpc_createerr.cf_stat = RPC_SYSTEMERROR; syslog(LOG_ERR, - "clnt_tp_create_timed: " - "strdup failed."); + "clnt_tp_create_timed: " + "strdup failed."); return (NULL); } } @@ -561,7 +560,7 @@ clnt_tp_create_timed(const char *hostname, const rpcprog_t prog, } else { CLNT_DESTROY(cl); cl = _clnt_tli_create_timed(RPC_ANYFD, nconf, svcaddr, - prog, vers, 0, 0, tp); + prog, vers, 0, 0, tp); } } netdir_free((char *)svcaddr, ND_ADDR); @@ -582,7 +581,7 @@ clnt_tli_create(const int fd, const struct netconfig *nconf, const uint_t sendsz, const uint_t recvsz) { return (_clnt_tli_create_timed(fd, nconf, svcaddr, prog, vers, sendsz, - recvsz, NULL)); + recvsz, NULL)); } /* @@ -596,12 +595,12 @@ clnt_tli_create(const int fd, const struct netconfig *nconf, */ CLIENT * _clnt_tli_create_timed(int fd, const struct netconfig *nconf, - struct netbuf *svcaddr, rpcprog_t prog, rpcvers_t vers, uint_t sendsz, - uint_t recvsz, const struct timeval *tp) + struct netbuf *svcaddr, rpcprog_t prog, rpcvers_t vers, uint_t sendsz, + uint_t recvsz, const struct timeval *tp) { CLIENT *cl; /* client handle */ struct t_info tinfo; /* transport info */ - bool_t madefd; /* whether fd opened here */ + bool_t madefd = FALSE; /* whether fd opened here */ t_scalar_t servtype; int retval; @@ -647,13 +646,12 @@ _clnt_tli_create_timed(int fd, const struct netconfig *nconf, (t_getinfo(fd, &tinfo) == -1)) goto err; servtype = tinfo.servtype; - madefd = FALSE; } switch (servtype) { case T_COTS: cl = _clnt_vc_create_timed(fd, svcaddr, prog, vers, sendsz, - recvsz, tp); + recvsz, tp); break; case T_COTS_ORD: if (nconf && ((strcmp(nconf->nc_protofmly, NC_INET) == 0) || @@ -663,7 +661,7 @@ _clnt_tli_create_timed(int fd, const struct netconfig *nconf, goto err; } cl = _clnt_vc_create_timed(fd, svcaddr, prog, vers, sendsz, - recvsz, tp); + recvsz, tp); break; case T_CLTS: cl = clnt_dg_create(fd, svcaddr, prog, vers, sendsz, recvsz); @@ -681,7 +679,7 @@ _clnt_tli_create_timed(int fd, const struct netconfig *nconf, rpc_createerr.cf_error.re_errno = errno; rpc_createerr.cf_error.re_terrno = 0; syslog(LOG_ERR, - "clnt_tli_create: strdup failed"); + "clnt_tli_create: strdup failed"); goto err1; } cl->cl_tp = strdup(nconf->nc_device); @@ -692,7 +690,7 @@ _clnt_tli_create_timed(int fd, const struct netconfig *nconf, rpc_createerr.cf_error.re_errno = errno; rpc_createerr.cf_error.re_terrno = 0; syslog(LOG_ERR, - "clnt_tli_create: strdup failed"); + "clnt_tli_create: strdup failed"); goto err1; } } else { @@ -706,8 +704,8 @@ _clnt_tli_create_timed(int fd, const struct netconfig *nconf, rpc_createerr.cf_error.re_errno = errno; rpc_createerr.cf_error.re_terrno = 0; syslog(LOG_ERR, - "clnt_tli_create: " - "strdup failed"); + "clnt_tli_create: " + "strdup failed"); goto err1; } } @@ -720,8 +718,8 @@ _clnt_tli_create_timed(int fd, const struct netconfig *nconf, rpc_createerr.cf_error.re_errno = errno; rpc_createerr.cf_error.re_terrno = 0; syslog(LOG_ERR, - "clnt_tli_create: " - "strdup failed"); + "clnt_tli_create: " + "strdup failed"); goto err1; } } @@ -770,7 +768,7 @@ __rpc_raise_fd(int fd) if (t_close(fd) == -1) { /* this is okay, we will syslog an error, then use the new fd */ (void) syslog(LOG_ERR, - "could not t_close() fd %d; mem & fd leak", fd); + "could not t_close() fd %d; mem & fd leak", fd); } return (nfd); -- cgit v1.2.3 From b4fb003914e70b41d96dec8011864f6af1faf3ef Mon Sep 17 00:00:00 2001 From: "Joshua M. Clulow" Date: Tue, 8 Nov 2022 12:54:43 -0800 Subject: 14978 ZFS autoexpand property should work for root pools Reviewed by: Andy Fiddaman Reviewed by: Toomas Soome Approved by: Dan McDonald --- usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c | 8 ++ usr/src/lib/libzfs/common/libzfs.h | 2 + usr/src/lib/libzfs/common/libzfs_pool.c | 115 ++++++++++++++---------- usr/src/lib/libzfs/common/mapfile-vers | 1 + usr/src/lib/libzpool/Makefile.com | 2 +- usr/src/uts/common/fs/zfs/spa.c | 16 ++-- usr/src/uts/common/fs/zfs/spa_misc.c | 42 +++++++++ usr/src/uts/common/fs/zfs/sys/spa.h | 1 + usr/src/uts/common/fs/zfs/zvol.c | 10 +-- 9 files changed, 132 insertions(+), 65 deletions(-) (limited to 'usr/src/lib') diff --git a/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c b/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c index 82c296a669..6a25af90f9 100644 --- a/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c +++ b/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c @@ -23,6 +23,7 @@ * Copyright (c) 2012 by Delphix. All rights reserved. * Copyright 2016 Nexenta Systems, Inc. All rights reserved. * Copyright 2022 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 Oxide Computer Company */ /* @@ -564,6 +565,13 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data) char *path, fullpath[MAXPATHLEN]; uint64_t wholedisk = 0ULL; + /* + * If the /dev path of the device is invalid because the disk + * has been moved to a new location, we need to try to refresh + * that path before onlining the device. + */ + zpool_vdev_refresh_path(g_zfshdl, zhp, tgt); + verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path) == 0); verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK, 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 @@ -3959,18 +3960,71 @@ set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path) (void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc); } +/* + * 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 diff --git a/usr/src/uts/common/fs/zfs/spa.c b/usr/src/uts/common/fs/zfs/spa.c index 70d690d587..d390e39195 100644 --- a/usr/src/uts/common/fs/zfs/spa.c +++ b/usr/src/uts/common/fs/zfs/spa.c @@ -32,6 +32,7 @@ * Copyright (c) 2017, Intel Corporation. * Copyright 2020 Joshua M. Clulow * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 Oxide Computer Company */ /* @@ -5593,6 +5594,12 @@ spa_import_rootpool(char *devpath, char *devid, uint64_t pool_guid, goto out; } + /* + * The root disk may have been expanded while the system was offline. + * Kick off an async task to check for and handle expansion. + */ + spa_async_request(spa, SPA_ASYNC_AUTOEXPAND); + error = 0; out: spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); @@ -7517,8 +7524,6 @@ spa_async_probe(spa_t *spa, vdev_t *vd) static void spa_async_autoexpand(spa_t *spa, vdev_t *vd) { - sysevent_id_t eid; - nvlist_t *attr; char *physpath; if (!spa->spa_autoexpand) @@ -7535,13 +7540,8 @@ spa_async_autoexpand(spa_t *spa, vdev_t *vd) physpath = kmem_zalloc(MAXPATHLEN, KM_SLEEP); (void) snprintf(physpath, MAXPATHLEN, "/devices%s", vd->vdev_physpath); - VERIFY(nvlist_alloc(&attr, NV_UNIQUE_NAME, KM_SLEEP) == 0); - VERIFY(nvlist_add_string(attr, DEV_PHYS_PATH, physpath) == 0); - - (void) ddi_log_sysevent(zfs_dip, SUNW_VENDOR, EC_DEV_STATUS, - ESC_DEV_DLE, attr, &eid, DDI_SLEEP); + zfs_post_dle_sysevent(physpath); - nvlist_free(attr); kmem_free(physpath, MAXPATHLEN); } diff --git a/usr/src/uts/common/fs/zfs/spa_misc.c b/usr/src/uts/common/fs/zfs/spa_misc.c index cb59eef824..6e834005a1 100644 --- a/usr/src/uts/common/fs/zfs/spa_misc.c +++ b/usr/src/uts/common/fs/zfs/spa_misc.c @@ -29,6 +29,7 @@ * Copyright 2019 Joyent, Inc. * Copyright (c) 2017, Intel Corporation. * Copyright 2020 Joyent, Inc. + * Copyright 2022 Oxide Computer Company */ #include @@ -2598,3 +2599,44 @@ spa_suspend_async_destroy(spa_t *spa) return (B_FALSE); } + +/* + * Generate a LUN expansion event. This routine does not use + * ddi_log_sysevent() because that would require a dev_info_t, and we may not + * have one available. + */ +void +zfs_post_dle_sysevent(const char *physpath) +{ +#ifdef _KERNEL + sysevent_t *ev = sysevent_alloc(EC_DEV_STATUS, ESC_DEV_DLE, + SUNW_KERN_PUB "zfs", SE_SLEEP); + sysevent_attr_list_t *attr = NULL; + sysevent_id_t eid; + + VERIFY(ev != NULL); + + /* + * The only attribute is the /devices path of the expanding device: + */ + sysevent_value_t value = { + .value_type = SE_DATA_TYPE_STRING, + .value = { + .sv_string = (char *)physpath, + }, + }; + if (sysevent_add_attr(&attr, DEV_PHYS_PATH, &value, SE_SLEEP) != 0) { + sysevent_free(ev); + return; + } + + if (sysevent_attach_attributes(ev, attr) != 0) { + sysevent_free_attr(attr); + sysevent_free(ev); + return; + } + + (void) log_sysevent(ev, SE_SLEEP, &eid); + sysevent_free(ev); +#endif +} diff --git a/usr/src/uts/common/fs/zfs/sys/spa.h b/usr/src/uts/common/fs/zfs/sys/spa.h index af8057be8f..b896d51577 100644 --- a/usr/src/uts/common/fs/zfs/sys/spa.h +++ b/usr/src/uts/common/fs/zfs/sys/spa.h @@ -1104,6 +1104,7 @@ extern sysevent_t *spa_event_create(spa_t *spa, vdev_t *vd, nvlist_t *hist_nvl, const char *name); extern void spa_event_post(sysevent_t *ev); extern void spa_event_discard(sysevent_t *ev); +extern void zfs_post_dle_sysevent(const char *); #ifdef ZFS_DEBUG #define dprintf_bp(bp, fmt, ...) do { \ diff --git a/usr/src/uts/common/fs/zfs/zvol.c b/usr/src/uts/common/fs/zfs/zvol.c index 1de192f87f..2bb311d28d 100644 --- a/usr/src/uts/common/fs/zfs/zvol.c +++ b/usr/src/uts/common/fs/zfs/zvol.c @@ -813,20 +813,12 @@ zvol_update_live_volsize(zvol_state_t *zv, uint64_t volsize) * Generate a LUN expansion event. */ if (error == 0) { - sysevent_id_t eid; - nvlist_t *attr; char *physpath = kmem_zalloc(MAXPATHLEN, KM_SLEEP); (void) snprintf(physpath, MAXPATHLEN, "%s%u", ZVOL_PSEUDO_DEV, zv->zv_minor); - VERIFY(nvlist_alloc(&attr, NV_UNIQUE_NAME, KM_SLEEP) == 0); - VERIFY(nvlist_add_string(attr, DEV_PHYS_PATH, physpath) == 0); - - (void) ddi_log_sysevent(zfs_dip, SUNW_VENDOR, EC_DEV_STATUS, - ESC_DEV_DLE, attr, &eid, DDI_SLEEP); - - nvlist_free(attr); + zfs_post_dle_sysevent(physpath); kmem_free(physpath, MAXPATHLEN); } return (error); -- cgit v1.2.3