mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 02:44:41 +03:00
zpool: Add slot power control, print power status
Add `zpool` flags to control the slot power to drives. This assumes
your SAS or NVMe enclosure supports slot power control via sysfs.
The new `--power` flag is added to `zpool offline|online|clear`:
zpool offline --power <pool> <device> Turn off device slot power
zpool online --power <pool> <device> Turn on device slot power
zpool clear --power <pool> [device] Turn on device slot power
If the ZPOOL_AUTO_POWER_ON_SLOT env var is set, then the '--power'
option is automatically implied for `zpool online` and `zpool clear`
and does not need to be passed.
zpool status also gets a --power option to print the slot power status.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Mart Frauenlob <AllKind@fastest.cc>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #15662
This commit is contained in:
@@ -318,6 +318,9 @@ _LIBZFS_H int zpool_vdev_remove_wanted(zpool_handle_t *, const char *);
|
||||
|
||||
_LIBZFS_H int zpool_vdev_fault(zpool_handle_t *, uint64_t, vdev_aux_t);
|
||||
_LIBZFS_H int zpool_vdev_degrade(zpool_handle_t *, uint64_t, vdev_aux_t);
|
||||
_LIBZFS_H int zpool_vdev_set_removed_state(zpool_handle_t *, uint64_t,
|
||||
vdev_aux_t);
|
||||
|
||||
_LIBZFS_H int zpool_vdev_clear(zpool_handle_t *, uint64_t);
|
||||
|
||||
_LIBZFS_H nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *,
|
||||
|
||||
@@ -97,6 +97,7 @@ _LIBZUTIL_H int zpool_find_config(libpc_handle_t *, const char *, nvlist_t **,
|
||||
_LIBZUTIL_H const char * const * zpool_default_search_paths(size_t *count);
|
||||
_LIBZUTIL_H int zpool_read_label(int, nvlist_t **, int *);
|
||||
_LIBZUTIL_H int zpool_label_disk_wait(const char *, int);
|
||||
_LIBZUTIL_H int zpool_disk_wait(const char *);
|
||||
|
||||
struct udev_device;
|
||||
|
||||
@@ -163,6 +164,8 @@ _LIBZUTIL_H void zfs_niceraw(uint64_t, char *, size_t);
|
||||
_LIBZUTIL_H void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *);
|
||||
_LIBZUTIL_H int zpool_history_unpack(char *, uint64_t, uint64_t *, nvlist_t ***,
|
||||
uint_t *);
|
||||
_LIBZUTIL_H void fsleep(float sec);
|
||||
_LIBZUTIL_H int zpool_getenv_int(const char *env, int default_val);
|
||||
|
||||
struct zfs_cmd;
|
||||
|
||||
@@ -205,6 +208,60 @@ _LIBZUTIL_H void zfs_setproctitle(const char *fmt, ...);
|
||||
typedef int (*pool_vdev_iter_f)(void *, nvlist_t *, void *);
|
||||
int for_each_vdev_cb(void *zhp, nvlist_t *nv, pool_vdev_iter_f func,
|
||||
void *data);
|
||||
int for_each_vdev_macro_helper_func(void *zhp_data, nvlist_t *nv, void *data);
|
||||
int for_each_real_leaf_vdev_macro_helper_func(void *zhp_data, nvlist_t *nv,
|
||||
void *data);
|
||||
/*
|
||||
* Often you'll want to iterate over all the vdevs in the pool, but don't want
|
||||
* to use for_each_vdev() since it requires a callback function.
|
||||
*
|
||||
* Instead you can use FOR_EACH_VDEV():
|
||||
*
|
||||
* zpool_handle_t *zhp // Assume this is initialized
|
||||
* nvlist_t *nv
|
||||
* ...
|
||||
* FOR_EACH_VDEV(zhp, nv) {
|
||||
* const char *path = NULL;
|
||||
* nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path);
|
||||
* printf("Looking at vdev %s\n", path);
|
||||
* }
|
||||
*
|
||||
* Note: FOR_EACH_VDEV runs in O(n^2) time where n = number of vdevs. However,
|
||||
* there's an upper limit of 256 vdevs per dRAID top-level vdevs (TLDs), 255 for
|
||||
* raidz2 TLDs, a real world limit of ~500 vdevs for mirrors, so this shouldn't
|
||||
* really be an issue.
|
||||
*
|
||||
* Here are some micro-benchmarks of a complete FOR_EACH_VDEV loop on a RAID0
|
||||
* pool:
|
||||
*
|
||||
* 100 vdevs = 0.7ms
|
||||
* 500 vdevs = 17ms
|
||||
* 750 vdevs = 40ms
|
||||
* 1000 vdevs = 82ms
|
||||
*
|
||||
* The '__nv += 0' at the end of the for() loop gets around a "comma or
|
||||
* semicolon followed by non-blank" checkstyle error. Note on most compliers
|
||||
* the '__nv += 0' can just be replaced with 'NULL', but gcc on Centos 7
|
||||
* will give a 'warning: statement with no effect' error if you do that.
|
||||
*/
|
||||
#define __FOR_EACH_VDEV(__zhp, __nv, __func) { \
|
||||
__nv = zpool_get_config(__zhp, NULL); \
|
||||
VERIFY0(nvlist_lookup_nvlist(__nv, ZPOOL_CONFIG_VDEV_TREE, &__nv)); \
|
||||
} \
|
||||
for (nvlist_t *__root_nv = __nv, *__state = (nvlist_t *)0; \
|
||||
for_each_vdev_cb(&__state, __root_nv, __func, &__nv) == 1; \
|
||||
__nv += 0)
|
||||
|
||||
#define FOR_EACH_VDEV(__zhp, __nv) \
|
||||
__FOR_EACH_VDEV(__zhp, __nv, for_each_vdev_macro_helper_func)
|
||||
|
||||
/*
|
||||
* "real leaf" vdevs are leaf vdevs that are real devices (disks or files).
|
||||
* This excludes leaf vdevs like like draid spares.
|
||||
*/
|
||||
#define FOR_EACH_REAL_LEAF_VDEV(__zhp, __nv) \
|
||||
__FOR_EACH_VDEV(__zhp, __nv, for_each_real_leaf_vdev_macro_helper_func)
|
||||
|
||||
int for_each_vdev_in_nvlist(nvlist_t *nvroot, pool_vdev_iter_f func,
|
||||
void *data);
|
||||
void update_vdevs_config_dev_sysfs_path(nvlist_t *config);
|
||||
|
||||
Reference in New Issue
Block a user