From 1c113a126b499dea3bbf3b4f93836f60763edff3 Mon Sep 17 00:00:00 2001 From: Jacob Malevich Date: Tue, 9 Dec 2014 18:03:47 -0800 Subject: [PATCH] bcacheadm: add command to modify sysfs attributes for a cache or cacheset bcacheadm modify -u csetuuid -d cacheuuid attr val bcacheadm modify -u csetuuid attr val bcacheadm modify --list Change-Id: I7b8ddfb6a7cd12a7bc71870dcc10787a7d3d9e8d Signed-off-by: Jacob Malevich --- bcache.c | 35 +++++++++++++++- bcache.h | 47 +++++++++++++++++++--- bcacheadm.c | 113 +++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 170 insertions(+), 25 deletions(-) diff --git a/bcache.c b/bcache.c index 1373d1a..ec88ffc 100644 --- a/bcache.c +++ b/bcache.c @@ -868,6 +868,40 @@ void show_super_cache(struct cache_sb *sb, bool force_csum) show_cache_member(sb, sb->nr_this_dev); } +static int __sysfs_attr_type(char *attr, const char **attr_arr) { + int i, j; + for(i = 0; attr_arr[i] != NULL; i++) + if(!strcmp(attr, attr_arr[i])) + return 1; + return 0; +} + +enum sysfs_attr sysfs_attr_type(char *attr) { + int ret; + if(__sysfs_attr_type(attr, set_attrs)) + return SET_ATTR; + if(__sysfs_attr_type(attr, cache_attrs)) + return CACHE_ATTR; + if(__sysfs_attr_type(attr, internal_attrs)) + return INTERNAL_ATTR; + + printf("No attribute called %s, try --list to see options\n", attr); + + return -1; +} + +static void __sysfs_attr_list(const char **attr_arr) { + int i, j; + for (i = 0; attr_arr[i] != NULL; i++) + printf("%s\n", attr_arr[i]); +} + +void sysfs_attr_list() { + __sysfs_attr_list(set_attrs); + __sysfs_attr_list(cache_attrs); + __sysfs_attr_list(internal_attrs); +} + struct cache_sb *query_dev(char *dev, bool force_csum, bool print_sb, bool uuid_only, char *dev_uuid) { @@ -879,7 +913,6 @@ struct cache_sb *query_dev(char *dev, bool force_csum, printf("Can't open dev %s: %s\n", dev, strerror(errno)); exit(2); } - printf("opened sb for %s\n", dev); if (pread(fd, sb, bytes, SB_START) != bytes) { fprintf(stderr, "Couldn't read\n"); diff --git a/bcache.h b/bcache.h index 07e9733..dc79d06 100644 --- a/bcache.h +++ b/bcache.h @@ -30,12 +30,6 @@ typedef __s64 s64; (void) (&_max1 == &_max2); \ _max1 > _max2 ? _max1 : _max2; }) -struct add_msg { - char *const *devs; - char *uuid; - int tier; -}; - extern const char * const cache_state[]; extern const char * const replacement_policies[]; extern const char * const csum_types[]; @@ -63,6 +57,47 @@ long strtoul_or_die(const char *, size_t, const char *); void show_super_backingdev(struct cache_sb *, bool); void show_super_cache(struct cache_sb *, bool); +enum sysfs_attr {SET_ATTR, CACHE_ATTR, INTERNAL_ATTR}; + +static const char *set_attrs[] = { + "btree_flush_delay", + "btree_scan_ratelimit", + "bucket_reserve_percent", + "cache_reserve_percent", + "checksum_type", + "congested_read_threshold_us", + "congested_write_threshold_us", + "data_replicas", + "errors", + "foreground_target_percent", + "gc_sector_percent", + "journal_delay_ms", + "meta_replicas", + "sector_reserve_percent", + "tiering_percent", + NULL +}; + +static const char *cache_attrs[] = { + "cache_replacement_policy", + "discard", + "state", + "tier", + NULL +}; + +static const char *internal_attrs[] = { + "btree_shrinker_disabled", + "copy_gc_enabled", + "foreground_write_rate", + "tiering_enabled", + "tiering_rate", + NULL +}; + +enum sysfs_attr sysfs_attr_type(char *attr); +void sysfs_attr_list(); + struct cache_sb *query_dev(char *, bool, bool, bool, char *dev_uuid); char *list_cachesets(char *, bool); char *parse_array_to_list(char *const *); diff --git a/bcacheadm.c b/bcacheadm.c index a0c9536..67f26b1 100644 --- a/bcacheadm.c +++ b/bcacheadm.c @@ -37,16 +37,6 @@ #define MAX_DEVS MAX_CACHES_PER_SET -/* bcacheadm globals */ -enum exit { - EXIT_OK = 0, /* Ok */ - EXIT_ERROR = 1, /* General/OS error */ - EXIT_SHELL = 2, /* Start maintenance shell */ - EXIT_SHELL_REBOOT = 3, /* Start maintenance shell, reboot when done */ - EXIT_REBOOT = 4, /* System must reboot */ -}; - - /* make-bcache globals */ int bdev = -1; int devs = 0; @@ -63,13 +53,6 @@ unsigned replication_set = 0, replacement_policy = 0; uint64_t data_offset = BDEV_DATA_START_DEFAULT; char *label = NULL; struct cache_sb *cache_set_sb = NULL; -enum long_opts { - CACHE_SET_UUID = 256, - CSUM_TYPE, - REPLICATION_SET, - META_REPLICAS, - DATA_REPLICAS, -}; const char *cache_set_uuid = 0; const char *csum_type = 0; char *metadata_replicas = 0; @@ -82,6 +65,11 @@ char *add_dev_uuid = NULL; /* rm-dev globals */ bool force_remove = false; +/* Modify globals */ +bool modify_list_attrs = false; +static const char *modify_set_uuid = NULL; +static const char *modify_dev_uuid = NULL; + /* query-dev globals */ bool force_csum = false; bool uuid_only = false; @@ -218,6 +206,13 @@ static NihOption bcache_rm_device_options[] = { NIH_OPTION_LAST }; +static NihOption bcache_modify_options[] = { + {'l', "list", N_("list attributes"), NULL, NULL, &modify_list_attrs, NULL}, + {'u', "set", N_("cacheset uuid"), NULL, "UUID", &modify_set_uuid, NULL}, + {'d', "dev", N_("device uuid"), NULL, "UUID", &modify_dev_uuid, NULL}, + NIH_OPTION_LAST +}; + static NihOption query_devs_options[] = { {'f', "force_csum", N_("force_csum"), NULL, NULL, &force_csum, NULL}, {'u', "uuid-only", N_("only print out the uuid for the devices, not the whole superblock"), NULL, NULL, &uuid_only, NULL}, @@ -406,8 +401,10 @@ int bcache_add_devices(NihCommand *command, char *const *args) { char *err; - if (!add_dev_uuid) + if (!add_dev_uuid) { printf("Must specify a cacheset uuid to add the disk to\n"); + return -1; + } err = add_devices(args, add_dev_uuid); if (err) { @@ -431,6 +428,82 @@ int bcache_rm_device(NihCommand *command, char *const *args) return 0; } +int bcache_modify(NihCommand *command, char *const *args) +{ + char *err; + char path[MAX_PATH]; + DIR *path_dir; + struct stat cache_stat; + char *attr = args[0]; + char *val = NULL; + int fd = -1; + + if (modify_list_attrs) { + sysfs_attr_list(); + return 0; + } + + if (!modify_set_uuid) { + printf("Must provide a cacheset uuid\n"); + return -1; + } + + snprintf(path, MAX_PATH, "%s/%s", cset_dir, modify_set_uuid); + + if(!attr) { + printf("Must provide the name of an attribute to modify\n"); + goto err; + } + + enum sysfs_attr type = sysfs_attr_type(attr); + + if (type == -1) + goto err; + else if(type == INTERNAL_ATTR) + strcat(path, "/internal"); + else if(type == CACHE_ATTR) { + if(modify_dev_uuid) { + /* searches all cache# for a matching uuid, + * path gets modified to the correct cache path */ + char subdir[10] = "/cache"; + err = find_matching_uuid(path, subdir, + modify_dev_uuid); + if (err) { + printf("Failed to find " + "matching dev %s\n", err); + goto err; + } else { + strcat(path, subdir); + } + } else { + printf("Must provide a device uuid\n"); + } + } + /* SET_ATTRs are just in the current dir */ + + strcat(path, "/"); + strcat(path, attr); + + val = args[1]; + if (!val) { + printf("Must provide a value to change the attribute to\n"); + goto err; + } + + fd = open(path, O_WRONLY); + if (fd < 0) { + printf("Unable to open modify attr with path %s\n", path); + goto err; + } + + write(fd, val, strlen(val)); + +err: + if(fd) + close(fd); + return 0; +} + int bcache_list_cachesets(NihCommand *command, char *const *args) { char *err = NULL; @@ -600,6 +673,10 @@ static NihCommand commands[] = { "Removes a device from its cacheset", N_("Removes a device from its cacheset"), NULL, bcache_rm_device_options, bcache_rm_device}, + {"modify", N_("modify --set=UUID (dev=UUID) name value"), + "Modifies attributes related to the cacheset", + N_("Modifies attributes related to the cacheset"), + NULL, bcache_modify_options, bcache_modify}, {"list-cachesets", N_("list-cachesets"), "Lists cachesets in /sys/fs/bcache", N_("Lists cachesets in /sys/fs/bcache"), -- 2.39.2