diff options
Diffstat (limited to 'sys/contrib/openzfs/lib')
| -rw-r--r-- | sys/contrib/openzfs/lib/libspl/include/sys/uio.h | 1 | ||||
| -rw-r--r-- | sys/contrib/openzfs/lib/libzfs/libzfs_status.c | 78 | ||||
| -rw-r--r-- | sys/contrib/openzfs/lib/libzpool/kernel.c | 79 | 
3 files changed, 104 insertions, 54 deletions
| diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/uio.h b/sys/contrib/openzfs/lib/libspl/include/sys/uio.h index 93aa4984d734..9ada482be000 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/uio.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/uio.h @@ -41,6 +41,7 @@  #ifndef	_LIBSPL_SYS_UIO_H  #define	_LIBSPL_SYS_UIO_H +#include <sys/sysmacros.h>  #include <sys/types.h>  #include_next <sys/uio.h> diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_status.c b/sys/contrib/openzfs/lib/libzfs/libzfs_status.c index bdddefb92165..a589ca6896f0 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_status.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_status.c @@ -98,57 +98,57 @@ static const char *const zfs_msgid_table[] = {  #define	NMSGID	(sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0]))  static int -vdev_missing(vdev_stat_t *vs, uint_t vsc) +vdev_missing(vdev_stat_t *vs, uint_t vsc, void *arg)  { -	(void) vsc; +	(void) vsc, (void) arg;  	return (vs->vs_state == VDEV_STATE_CANT_OPEN &&  	    vs->vs_aux == VDEV_AUX_OPEN_FAILED);  }  static int -vdev_faulted(vdev_stat_t *vs, uint_t vsc) +vdev_faulted(vdev_stat_t *vs, uint_t vsc, void *arg)  { -	(void) vsc; +	(void) vsc, (void) arg;  	return (vs->vs_state == VDEV_STATE_FAULTED);  }  static int -vdev_errors(vdev_stat_t *vs, uint_t vsc) +vdev_errors(vdev_stat_t *vs, uint_t vsc, void *arg)  { -	(void) vsc; +	(void) vsc, (void) arg;  	return (vs->vs_state == VDEV_STATE_DEGRADED ||  	    vs->vs_read_errors != 0 || vs->vs_write_errors != 0 ||  	    vs->vs_checksum_errors != 0);  }  static int -vdev_broken(vdev_stat_t *vs, uint_t vsc) +vdev_broken(vdev_stat_t *vs, uint_t vsc, void *arg)  { -	(void) vsc; +	(void) vsc, (void) arg;  	return (vs->vs_state == VDEV_STATE_CANT_OPEN);  }  static int -vdev_offlined(vdev_stat_t *vs, uint_t vsc) +vdev_offlined(vdev_stat_t *vs, uint_t vsc, void *arg)  { -	(void) vsc; +	(void) vsc, (void) arg;  	return (vs->vs_state == VDEV_STATE_OFFLINE);  }  static int -vdev_removed(vdev_stat_t *vs, uint_t vsc) +vdev_removed(vdev_stat_t *vs, uint_t vsc, void *arg)  { -	(void) vsc; +	(void) vsc, (void) arg;  	return (vs->vs_state == VDEV_STATE_REMOVED);  }  static int -vdev_non_native_ashift(vdev_stat_t *vs, uint_t vsc) +vdev_non_native_ashift(vdev_stat_t *vs, uint_t vsc, void *arg)  { -	if (getenv("ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE") != NULL) -		return (0); +	uint64_t ashift = *(uint64_t *)arg;  	return (VDEV_STAT_VALID(vs_physical_ashift, vsc) && +	    (ashift == 0 || vs->vs_configured_ashift < ashift) &&  	    vs->vs_configured_ashift < vs->vs_physical_ashift);  } @@ -156,8 +156,8 @@ vdev_non_native_ashift(vdev_stat_t *vs, uint_t vsc)   * Detect if any leaf devices that have seen errors or could not be opened.   */  static boolean_t -find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t), -    boolean_t ignore_replacing) +find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t, void *), +    void *arg, boolean_t ignore_replacing)  {  	nvlist_t **child;  	uint_t c, children; @@ -177,14 +177,16 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),  	if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_CHILDREN, &child,  	    &children) == 0) { -		for (c = 0; c < children; c++) -			if (find_vdev_problem(child[c], func, ignore_replacing)) +		for (c = 0; c < children; c++) { +			if (find_vdev_problem(child[c], func, arg, +			    ignore_replacing))  				return (B_TRUE); +		}  	} else {  		uint_t vsc;  		vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(  		    vdev, ZPOOL_CONFIG_VDEV_STATS, &vsc); -		if (func(vs, vsc) != 0) +		if (func(vs, vsc, arg) != 0)  			return (B_TRUE);  	} @@ -193,9 +195,11 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),  	 */  	if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_L2CACHE, &child,  	    &children) == 0) { -		for (c = 0; c < children; c++) -			if (find_vdev_problem(child[c], func, ignore_replacing)) +		for (c = 0; c < children; c++) { +			if (find_vdev_problem(child[c], func, arg, +			    ignore_replacing))  				return (B_TRUE); +		}  	}  	return (B_FALSE); @@ -220,7 +224,7 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),   */  static zpool_status_t  check_status(nvlist_t *config, boolean_t isimport, -    zpool_errata_t *erratap, const char *compat) +    zpool_errata_t *erratap, const char *compat, uint64_t ashift)  {  	pool_scan_stat_t *ps = NULL;  	uint_t vsc, psc; @@ -371,15 +375,15 @@ check_status(nvlist_t *config, boolean_t isimport,  	 * Bad devices in non-replicated config.  	 */  	if (vs->vs_state == VDEV_STATE_CANT_OPEN && -	    find_vdev_problem(nvroot, vdev_faulted, B_TRUE)) +	    find_vdev_problem(nvroot, vdev_faulted, NULL, B_TRUE))  		return (ZPOOL_STATUS_FAULTED_DEV_NR);  	if (vs->vs_state == VDEV_STATE_CANT_OPEN && -	    find_vdev_problem(nvroot, vdev_missing, B_TRUE)) +	    find_vdev_problem(nvroot, vdev_missing, NULL, B_TRUE))  		return (ZPOOL_STATUS_MISSING_DEV_NR);  	if (vs->vs_state == VDEV_STATE_CANT_OPEN && -	    find_vdev_problem(nvroot, vdev_broken, B_TRUE)) +	    find_vdev_problem(nvroot, vdev_broken, NULL, B_TRUE))  		return (ZPOOL_STATUS_CORRUPT_LABEL_NR);  	/* @@ -402,35 +406,37 @@ check_status(nvlist_t *config, boolean_t isimport,  	/*  	 * Missing devices in a replicated config.  	 */ -	if (find_vdev_problem(nvroot, vdev_faulted, B_TRUE)) +	if (find_vdev_problem(nvroot, vdev_faulted, NULL, B_TRUE))  		return (ZPOOL_STATUS_FAULTED_DEV_R); -	if (find_vdev_problem(nvroot, vdev_missing, B_TRUE)) +	if (find_vdev_problem(nvroot, vdev_missing, NULL, B_TRUE))  		return (ZPOOL_STATUS_MISSING_DEV_R); -	if (find_vdev_problem(nvroot, vdev_broken, B_TRUE)) +	if (find_vdev_problem(nvroot, vdev_broken, NULL, B_TRUE))  		return (ZPOOL_STATUS_CORRUPT_LABEL_R);  	/*  	 * Devices with errors  	 */ -	if (!isimport && find_vdev_problem(nvroot, vdev_errors, B_TRUE)) +	if (!isimport && find_vdev_problem(nvroot, vdev_errors, NULL, B_TRUE))  		return (ZPOOL_STATUS_FAILING_DEV);  	/*  	 * Offlined devices  	 */ -	if (find_vdev_problem(nvroot, vdev_offlined, B_TRUE)) +	if (find_vdev_problem(nvroot, vdev_offlined, NULL, B_TRUE))  		return (ZPOOL_STATUS_OFFLINE_DEV);  	/*  	 * Removed device  	 */ -	if (find_vdev_problem(nvroot, vdev_removed, B_TRUE)) +	if (find_vdev_problem(nvroot, vdev_removed, NULL, B_TRUE))  		return (ZPOOL_STATUS_REMOVED_DEV);  	/*  	 * Suboptimal, but usable, ashift configuration.  	 */ -	if (find_vdev_problem(nvroot, vdev_non_native_ashift, B_FALSE)) +	if (!isimport && +	    getenv("ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE") == NULL && +	    find_vdev_problem(nvroot, vdev_non_native_ashift, &ashift, B_FALSE))  		return (ZPOOL_STATUS_NON_NATIVE_ASHIFT);  	/* @@ -510,8 +516,10 @@ zpool_get_status(zpool_handle_t *zhp, const char **msgid,  	    ZFS_MAXPROPLEN, NULL, B_FALSE) != 0)  		compatibility[0] = '\0'; +	uint64_t ashift = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, NULL); +  	zpool_status_t ret = check_status(zhp->zpool_config, B_FALSE, errata, -	    compatibility); +	    compatibility, ashift);  	if (msgid != NULL) {  		if (ret >= NMSGID) @@ -526,7 +534,7 @@ zpool_status_t  zpool_import_status(nvlist_t *config, const char **msgid,      zpool_errata_t *errata)  { -	zpool_status_t ret = check_status(config, B_TRUE, errata, NULL); +	zpool_status_t ret = check_status(config, B_TRUE, errata, NULL, 0);  	if (ret >= NMSGID)  		*msgid = NULL; diff --git a/sys/contrib/openzfs/lib/libzpool/kernel.c b/sys/contrib/openzfs/lib/libzpool/kernel.c index 8ed374627264..70eba5099119 100644 --- a/sys/contrib/openzfs/lib/libzpool/kernel.c +++ b/sys/contrib/openzfs/lib/libzpool/kernel.c @@ -23,6 +23,7 @@   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.   * Copyright (c) 2012, 2018 by Delphix. All rights reserved.   * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc.   */  #include <assert.h> @@ -645,39 +646,60 @@ __dprintf(boolean_t dprint, const char *file, const char *func,   * cmn_err() and panic()   * =========================================================================   */ -static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" }; -static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" }; -__attribute__((noreturn)) void -vpanic(const char *fmt, va_list adx) +static __attribute__((noreturn)) void +panic_stop_or_abort(void)  { -	(void) fprintf(stderr, "error: "); -	(void) vfprintf(stderr, fmt, adx); -	(void) fprintf(stderr, "\n"); +	const char *stopenv = getenv("LIBZPOOL_PANIC_STOP"); +	if (stopenv != NULL && atoi(stopenv)) { +		fputs("libzpool: LIBZPOOL_PANIC_STOP is set, sending " +		    "SIGSTOP to process group\n", stderr); +		fflush(stderr); + +		kill(0, SIGSTOP); + +		fputs("libzpool: continued after panic stop, " +		    "aborting\n", stderr); +	}  	abort();	/* think of it as a "user-level crash dump" */  } -__attribute__((noreturn)) void -panic(const char *fmt, ...) +static void +vcmn_msg(int ce, const char *fmt, va_list adx)  { -	va_list adx; +	switch (ce) { +	case CE_IGNORE: +		return; +	case CE_CONT: +		break; +	case CE_NOTE: +		fputs("libzpool: NOTICE: ", stderr); +		break; +	case CE_WARN: +		fputs("libzpool: WARNING: ", stderr); +		break; +	case CE_PANIC: +		fputs("libzpool: PANIC: ", stderr); +		break; +	default: +		fputs("libzpool: [unknown severity %d]: ", stderr); +		break; +	} -	va_start(adx, fmt); -	vpanic(fmt, adx); -	va_end(adx); +	vfprintf(stderr, fmt, adx); +	if (ce != CE_CONT) +		fputc('\n', stderr); +	fflush(stderr);  }  void  vcmn_err(int ce, const char *fmt, va_list adx)  { +	vcmn_msg(ce, fmt, adx); +  	if (ce == CE_PANIC) -		vpanic(fmt, adx); -	if (ce != CE_NOTE) {	/* suppress noise in userland stress testing */ -		(void) fprintf(stderr, "%s", ce_prefix[ce]); -		(void) vfprintf(stderr, fmt, adx); -		(void) fprintf(stderr, "%s", ce_suffix[ce]); -	} +		panic_stop_or_abort();  }  void @@ -690,6 +712,25 @@ cmn_err(int ce, const char *fmt, ...)  	va_end(adx);  } +__attribute__((noreturn)) void +panic(const char *fmt, ...) +{ +	va_list adx; + +	va_start(adx, fmt); +	vcmn_msg(CE_PANIC, fmt, adx); +	va_end(adx); + +	panic_stop_or_abort(); +} + +__attribute__((noreturn)) void +vpanic(const char *fmt, va_list adx) +{ +	vcmn_msg(CE_PANIC, fmt, adx); +	panic_stop_or_abort(); +} +  /*   * =========================================================================   * misc routines | 
