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 <jam@daterainc.com>
This commit is contained in:
Jacob Malevich 2014-12-09 18:03:47 -08:00
parent 52789b5673
commit 8389c1f5da
3 changed files with 170 additions and 25 deletions

View File

@ -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");

View File

@ -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 *);

View File

@ -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},
@ -403,8 +398,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) {
@ -428,6 +425,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;
@ -597,6 +670,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"),