diff --git a/common/utils.c b/common/utils.c index b05e4ccd..967094c2 100644 --- a/common/utils.c +++ b/common/utils.c @@ -1925,3 +1925,53 @@ int sysfs_read_file(int fd, char *buf, size_t size) memset(buf, 0, size); return read(fd, buf, size); } + +static const char exclop_def[][16] = { + [BTRFS_EXCLOP_NONE] "none", + [BTRFS_EXCLOP_BALANCE] "balance", + [BTRFS_EXCLOP_DEV_ADD] "device add", + [BTRFS_EXCLOP_DEV_REMOVE] "device remove", + [BTRFS_EXCLOP_DEV_REPLACE] "device replace", + [BTRFS_EXCLOP_RESIZE] "resize", + [BTRFS_EXCLOP_SWAP_ACTIVATE] "swap activate", +}; + +/* + * Read currently running exclusive operation from sysfs. If this is not + * available, return BTRFS_EXCLOP_UNKNOWN + */ +int get_fs_exclop(int fd) +{ + int sysfs_fd; + char buf[32]; + int ret; + int i; + + sysfs_fd = sysfs_open_fsid_file(fd, "exclusive_operation"); + if (sysfs_fd < 0) + return BTRFS_EXCLOP_UNKNOWN; + + memset(buf, 0, sizeof(buf)); + ret = sysfs_read_file(sysfs_fd, buf, sizeof(buf)); + close(sysfs_fd); + if (ret <= 0) + return BTRFS_EXCLOP_UNKNOWN; + + i = strlen(buf) - 1; + while (i > 0 && isspace(buf[i])) i--; + if (i > 0) + buf[i + 1] = 0; + for (i = 0; i < ARRAY_SIZE(exclop_def); i++) { + if (strcmp(exclop_def[i], buf) == 0) + return i; + } + + return BTRFS_EXCLOP_UNKNOWN; +} + +const char *get_fs_exclop_name(int op) +{ + if (0 <= op && op <= ARRAY_SIZE(exclop_def)) + return exclop_def[op]; + return "UNKNOWN"; +} diff --git a/common/utils.h b/common/utils.h index 2fa4033d..2dd1ccd0 100644 --- a/common/utils.h +++ b/common/utils.h @@ -52,6 +52,17 @@ #define UNITS_HUMAN (UNITS_HUMAN_BINARY) #define UNITS_DEFAULT (UNITS_HUMAN) +enum exclusive_operation { + BTRFS_EXCLOP_NONE, + BTRFS_EXCLOP_BALANCE, + BTRFS_EXCLOP_DEV_ADD, + BTRFS_EXCLOP_DEV_REMOVE, + BTRFS_EXCLOP_DEV_REPLACE, + BTRFS_EXCLOP_RESIZE, + BTRFS_EXCLOP_SWAP_ACTIVATE, + BTRFS_EXCLOP_UNKNOWN = -1, +}; + void units_set_mode(unsigned *units, unsigned mode); void units_set_base(unsigned *units, unsigned base); @@ -76,6 +87,8 @@ int get_fs_info(const char *path, struct btrfs_ioctl_fs_info_args *fi_args, struct btrfs_ioctl_dev_info_args **di_ret); int get_fsid(const char *path, u8 *fsid, int silent); int get_fsid_fd(int fd, u8 *fsid); +int get_fs_exclop(int fd); +const char *get_fs_exclop_name(int op); int get_label(const char *btrfs_dev, char *label); int set_label(const char *btrfs_dev, const char *label);