Path: blob/main/sys/contrib/openzfs/include/libzutil.h
48254 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* Common Development and Distribution License (the "License").6* You may not use this file except in compliance with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or https://opensource.org/licenses/CDDL-1.0.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/21/*22* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.23* Copyright (c) 2018, 2024 by Delphix. All rights reserved.24*/2526#ifndef _LIBZUTIL_H27#define _LIBZUTIL_H extern __attribute__((visibility("default")))2829#include <string.h>30#include <pthread.h>31#include <sys/nvpair.h>32#include <sys/fs/zfs.h>3334#ifdef __cplusplus35extern "C" {36#endif3738/*39* Default wait time in milliseconds for a device name to be created.40*/41#define DISK_LABEL_WAIT (30 * 1000) /* 30 seconds */424344/*45* Pool Config Operations46*47* These are specific to the library libzfs or libzpool instance.48*/49typedef nvlist_t *refresh_config_func_t(void *, nvlist_t *);5051typedef int pool_active_func_t(void *, const char *, uint64_t, boolean_t *);5253typedef const struct pool_config_ops {54refresh_config_func_t *pco_refresh_config;55pool_active_func_t *pco_pool_active;56} pool_config_ops_t;5758/*59* An instance of pool_config_ops_t is expected in the caller's binary.60*/61_LIBZUTIL_H pool_config_ops_t libzfs_config_ops;62_LIBZUTIL_H pool_config_ops_t libzpool_config_ops;6364typedef enum lpc_error {65LPC_SUCCESS = 0, /* no error -- success */66LPC_BADCACHE = 2000, /* out of memory */67LPC_BADPATH, /* must be an absolute path */68LPC_NOMEM, /* out of memory */69LPC_EACCESS, /* some devices require root privileges */70LPC_UNKNOWN71} lpc_error_t;7273typedef struct importargs {74char **path; /* a list of paths to search */75int paths; /* number of paths to search */76const char *poolname; /* name of a pool to find */77uint64_t guid; /* guid of a pool to find */78const char *cachefile; /* cachefile to use for import */79boolean_t can_be_active; /* can the pool be active? */80boolean_t scan; /* prefer scanning to libblkid cache */81nvlist_t *policy; /* load policy (max txg, rewind, etc.) */82boolean_t do_destroyed;83boolean_t do_all;84} importargs_t;8586typedef struct libpc_handle {87int lpc_error;88boolean_t lpc_printerr;89boolean_t lpc_open_access_error;90boolean_t lpc_desc_active;91char lpc_desc[1024];92pool_config_ops_t *lpc_ops;93void *lpc_lib_handle;94} libpc_handle_t;9596_LIBZUTIL_H const char *libpc_error_description(libpc_handle_t *);97_LIBZUTIL_H nvlist_t *zpool_search_import(libpc_handle_t *, importargs_t *);98_LIBZUTIL_H int zpool_find_config(libpc_handle_t *, const char *, nvlist_t **,99importargs_t *);100101_LIBZUTIL_H const char * const * zpool_default_search_paths(size_t *count);102_LIBZUTIL_H int zpool_read_label(int, nvlist_t **, int *);103_LIBZUTIL_H int zpool_label_disk_wait(const char *, int);104_LIBZUTIL_H int zpool_disk_wait(const char *);105106struct udev_device;107108_LIBZUTIL_H int zfs_device_get_devid(struct udev_device *, char *, size_t);109_LIBZUTIL_H int zfs_device_get_physical(struct udev_device *, char *, size_t);110111_LIBZUTIL_H void update_vdev_config_dev_strs(nvlist_t *);112113/*114* Default device paths115*/116#define DISK_ROOT "/dev"117#define UDISK_ROOT "/dev/disk"118#define ZVOL_ROOT "/dev/zvol"119120_LIBZUTIL_H int zfs_append_partition(char *path, size_t max_len);121_LIBZUTIL_H int zfs_resolve_shortname(const char *name, char *path,122size_t pathlen);123124_LIBZUTIL_H char *zfs_strip_partition(const char *);125_LIBZUTIL_H const char *zfs_strip_path(const char *);126127_LIBZUTIL_H int zfs_strcmp_pathname(const char *, const char *, int);128129_LIBZUTIL_H boolean_t zfs_dev_is_dm(const char *);130_LIBZUTIL_H boolean_t zfs_dev_is_whole_disk(const char *);131_LIBZUTIL_H int zfs_dev_flush(int);132_LIBZUTIL_H char *zfs_get_underlying_path(const char *);133_LIBZUTIL_H char *zfs_get_enclosure_sysfs_path(const char *);134135_LIBZUTIL_H boolean_t is_mpath_whole_disk(const char *);136137_LIBZUTIL_H boolean_t zfs_isnumber(const char *);138139/*140* Formats for iostat numbers. Examples: "12K", "30ms", "4B", "2321234", "-".141*142* ZFS_NICENUM_1024: Print kilo, mega, tera, peta, exa..143* ZFS_NICENUM_BYTES: Print single bytes ("13B"), kilo, mega, tera...144* ZFS_NICENUM_TIME: Print nanosecs, microsecs, millisecs, seconds...145* ZFS_NICENUM_RAW: Print the raw number without any formatting146* ZFS_NICENUM_RAWTIME: Same as RAW, but print dashes ('-') for zero.147*/148enum zfs_nicenum_format {149ZFS_NICENUM_1024 = 0,150ZFS_NICENUM_BYTES = 1,151ZFS_NICENUM_TIME = 2,152ZFS_NICENUM_RAW = 3,153ZFS_NICENUM_RAWTIME = 4154};155156/*157* Convert a number to a human-readable form.158*/159_LIBZUTIL_H void zfs_nicebytes(uint64_t, char *, size_t);160_LIBZUTIL_H void zfs_nicenum(uint64_t, char *, size_t);161_LIBZUTIL_H void zfs_nicenum_format(uint64_t, char *, size_t,162enum zfs_nicenum_format);163_LIBZUTIL_H void zfs_nicetime(uint64_t, char *, size_t);164_LIBZUTIL_H void zfs_niceraw(uint64_t, char *, size_t);165166#define nicenum(num, buf, size) zfs_nicenum(num, buf, size)167168_LIBZUTIL_H void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *);169_LIBZUTIL_H int zpool_history_unpack(char *, uint64_t, uint64_t *, nvlist_t ***,170uint_t *);171_LIBZUTIL_H void fsleep(float sec);172_LIBZUTIL_H int zpool_getenv_int(const char *env, int default_val);173174struct zfs_cmd;175176/*177* List of colors to use178*/179#define ANSI_BLACK "\033[0;30m"180#define ANSI_RED "\033[0;31m"181#define ANSI_GREEN "\033[0;32m"182#define ANSI_YELLOW "\033[0;33m"183#define ANSI_BLUE "\033[0;34m"184#define ANSI_BOLD_BLUE "\033[1;34m" /* light blue */185#define ANSI_MAGENTA "\033[0;35m"186#define ANSI_CYAN "\033[0;36m"187#define ANSI_GRAY "\033[0;37m"188189#define ANSI_RESET "\033[0m"190#define ANSI_BOLD "\033[1m"191192_LIBZUTIL_H int use_color(void);193_LIBZUTIL_H void color_start(const char *color);194_LIBZUTIL_H void color_end(void);195_LIBZUTIL_H int printf_color(const char *color, const char *format, ...);196197_LIBZUTIL_H const char *zfs_basename(const char *path);198_LIBZUTIL_H ssize_t zfs_dirnamelen(const char *path);199#ifdef __linux__200extern char **environ;201_LIBZUTIL_H void zfs_setproctitle_init(int argc, char *argv[], char *envp[]);202_LIBZUTIL_H void zfs_setproctitle(const char *fmt, ...);203#else204#define zfs_setproctitle(fmt, ...) setproctitle(fmt, ##__VA_ARGS__)205#define zfs_setproctitle_init(x, y, z) ((void)0)206#endif207208/*209* These functions are used by the ZFS libraries and cmd/zpool code, but are210* not exported in the ABI.211*/212typedef int (*pool_vdev_iter_f)(void *, nvlist_t *, void *);213int for_each_vdev_cb(void *zhp, nvlist_t *nv, pool_vdev_iter_f func,214void *data);215int for_each_vdev_macro_helper_func(void *zhp_data, nvlist_t *nv, void *data);216int for_each_real_leaf_vdev_macro_helper_func(void *zhp_data, nvlist_t *nv,217void *data);218/*219* Often you'll want to iterate over all the vdevs in the pool, but don't want220* to use for_each_vdev() since it requires a callback function.221*222* Instead you can use FOR_EACH_VDEV():223*224* zpool_handle_t *zhp // Assume this is initialized225* nvlist_t *nv226* ...227* FOR_EACH_VDEV(zhp, nv) {228* const char *path = NULL;229* nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path);230* printf("Looking at vdev %s\n", path);231* }232*233* Note: FOR_EACH_VDEV runs in O(n^2) time where n = number of vdevs. However,234* there's an upper limit of 256 vdevs per dRAID top-level vdevs (TLDs), 255 for235* raidz2 TLDs, a real world limit of ~500 vdevs for mirrors, so this shouldn't236* really be an issue.237*238* Here are some micro-benchmarks of a complete FOR_EACH_VDEV loop on a RAID0239* pool:240*241* 100 vdevs = 0.7ms242* 500 vdevs = 17ms243* 750 vdevs = 40ms244* 1000 vdevs = 82ms245*246* The '__nv += 0' at the end of the for() loop gets around a "comma or247* semicolon followed by non-blank" checkstyle error. Note on most compliers248* the '__nv += 0' can just be replaced with 'NULL', but gcc on Centos 7249* will give a 'warning: statement with no effect' error if you do that.250*/251#define __FOR_EACH_VDEV(__zhp, __nv, __func) { \252__nv = zpool_get_config(__zhp, NULL); \253VERIFY0(nvlist_lookup_nvlist(__nv, ZPOOL_CONFIG_VDEV_TREE, &__nv)); \254} \255for (nvlist_t *__root_nv = __nv, *__state = (nvlist_t *)0; \256for_each_vdev_cb(&__state, __root_nv, __func, &__nv) == 1; \257__nv += 0)258259#define FOR_EACH_VDEV(__zhp, __nv) \260__FOR_EACH_VDEV(__zhp, __nv, for_each_vdev_macro_helper_func)261262/*263* "real leaf" vdevs are leaf vdevs that are real devices (disks or files).264* This excludes leaf vdevs like like draid spares.265*/266#define FOR_EACH_REAL_LEAF_VDEV(__zhp, __nv) \267__FOR_EACH_VDEV(__zhp, __nv, for_each_real_leaf_vdev_macro_helper_func)268269int for_each_vdev_in_nvlist(nvlist_t *nvroot, pool_vdev_iter_f func,270void *data);271void update_vdevs_config_dev_sysfs_path(nvlist_t *config);272_LIBZUTIL_H void update_vdev_config_dev_sysfs_path(nvlist_t *nv,273const char *path, const char *key);274275/*276* Thread-safe strerror() for use in ZFS libraries277*/278static inline char *zfs_strerror(int errnum) {279static __thread char errbuf[512];280static pthread_mutex_t zfs_strerror_lock = PTHREAD_MUTEX_INITIALIZER;281282(void) pthread_mutex_lock(&zfs_strerror_lock);283(void) strlcpy(errbuf, strerror(errnum), sizeof (errbuf));284(void) pthread_mutex_unlock(&zfs_strerror_lock);285286return (errbuf);287}288289#ifdef __cplusplus290}291#endif292293#endif /* _LIBZUTIL_H */294295296