X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=bcacheadm.c;h=efe9065b265ca154557cd29b1bf4f458295673bb;hb=074caf716a816d3c4c62bce28503e512d0ef4169;hp=d9a9c46244dfb5844bf40c9fb72985678adb183c;hpb=637b614630affe6125efea65d7202aecd513fab9;p=bcachefs-tools-debian diff --git a/bcacheadm.c b/bcacheadm.c index d9a9c46..efe9065 100644 --- a/bcacheadm.c +++ b/bcacheadm.c @@ -22,371 +22,183 @@ #include #include #include -#include #include #include #include #include -#include //libbcache +#include + +#include "bcache.h" +#include "bcacheadm-format.h" +#include "bcacheadm-assemble.h" +#include "bcacheadm-run.h" +#include "bcacheadm-query.h" #define PACKAGE_NAME "bcacheadm" #define PACKAGE_VERSION "1.0" -#define PACKAGE_BUGREPORT "bugreport" - -#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; -const char *cache_devices[MAX_DEVS]; -const char *backing_devices[MAX_DEVS]; -const char *backing_dev_labels[MAX_DEVS]; -size_t i, nr_backing_devices = 0; -unsigned block_size = 0; -unsigned bucket_sizes[MAX_DEVS]; -int num_bucket_sizes = 0; -int writeback = 0, discard = 0, wipe_bcache = 0; -unsigned replication_set = 0, tier = 0, replacement_policy = 0; -uint64_t data_offset = BDEV_DATA_START_DEFAULT; -char *label = NULL; -struct cache_sb *cache_set_sb; -enum long_opts { - CACHE_SET_UUID = 256, - CSUM_TYPE, - REPLICATION_SET, - META_REPLICAS, - DATA_REPLICAS, -}; - - -/* super-show globals */ -bool force_csum = false; - -/* probe globals */ -bool udev = false; - -/* list globals */ -char *cset_dir = "/sys/fs/bcache"; - -/* make-bcache option setters */ -static int set_CACHE_SET_UUID(NihOption *option, const char *arg) -{ - if(uuid_parse(arg, cache_set_sb->set_uuid.b)){ - fprintf(stderr, "Bad uuid\n"); - return -1; - } - return 0; -} -static int set_CSUM_TYPE(NihOption *option, const char *arg) -{ - SET_CACHE_PREFERRED_CSUM_TYPE(cache_set_sb, - read_string_list_or_die(arg, csum_types, - "csum type")); - return 0; -} -static int set_REPLICATION_SET(NihOption *option, const char *arg) -{ - replication_set = strtoul_or_die(arg, - CACHE_REPLICATION_SET_MAX, - "replication set"); - return 0; -} -static int set_META_REPLICAS(NihOption *option, const char *arg) -{ - SET_CACHE_SET_META_REPLICAS_WANT(cache_set_sb, - strtoul_or_die(arg, - CACHE_SET_META_REPLICAS_WANT_MAX, - "meta replicas")); - return 0; -} -static int set_DATA_REPLICAS(NihOption *option, const char *arg) -{ - SET_CACHE_SET_DATA_REPLICAS_WANT(cache_set_sb, - strtoul_or_die(arg, - CACHE_SET_DATA_REPLICAS_WANT_MAX, - "data replicas")); - return 0; -} -static int set_cache(NihOption *option, const char *arg) -{ - bdev=0; - cache_devices[cache_set_sb->nr_in_set] = arg; - next_cache_device(cache_set_sb, - replication_set, - tier, - replacement_policy, - discard); - devs++; - return 0; -} -static int set_bdev(NihOption *option, const char *arg) -{ - bdev=1; - backing_dev_labels[nr_backing_devices]=label; - backing_devices[nr_backing_devices++]=arg; - devs++; - return 0; -} -static int set_bucket_sizes(NihOption *option, const char *arg) -{ - bucket_sizes[num_bucket_sizes]=hatoi_validate(arg, "bucket size"); - num_bucket_sizes++; - return 0; -} +#define PACKAGE_BUGREPORT "linux-bcache@vger.kernel.org" +#if 0 +static bool modify_list_attrs = false; +static const char *modify_set_uuid = NULL; +static const char *modify_dev_uuid = NULL; -/* probe setters */ -static int set_udev(NihOption *option, const char *arg) -{ - if (strcmp("udev", arg)) { - printf("Invalid output format %s\n", arg); - exit(EXIT_FAILURE); - } - udev = true; - return 0; -} - - -/* options */ -static NihOption make_bcache_options[] = { -// {int shortoption, char* longoption, char* help, NihOptionGroup, char* argname, void *value, NihOptionSetter} - {'C', "cache", N_("Format a cache device"), NULL, NULL, NULL, set_cache}, - {'B', "bdev", N_("Format a backing device"), NULL, NULL, NULL, set_bdev}, - {'l', "label", N_("label"), NULL, NULL, &label, NULL}, - //Only one bucket_size supported until a list of bucket sizes is parsed correctly - {'b', "bucket", N_("bucket size"), NULL, NULL, NULL, set_bucket_sizes}, - //Does the default setter automatically convert strings to an int? - {'w', "block", N_("block size (hard sector size of SSD, often 2k"), NULL,NULL, &block_size, NULL}, - {'t', "tier", N_("tier of subsequent devices"), NULL,NULL, &tier, NULL}, - {'p', "cache_replacement_policy", N_("one of (lru|fifo|random)"), NULL,NULL, &replacement_policy, NULL}, - {'o', "data_offset", N_("data offset in sectors"), NULL,NULL, &data_offset, NULL}, - - {0, "cset-uuid", N_("UUID for the cache set"), NULL, NULL, NULL, set_CACHE_SET_UUID }, - {0, "csum-type", N_("One of (none|crc32c|crc64)"), NULL, NULL, NULL, set_CSUM_TYPE }, - {0, "replication-set",N_("replication set of subsequent devices"), NULL, NULL, NULL, set_REPLICATION_SET }, - {0, "meta-replicas",N_("number of metadata replicas"), NULL, NULL, NULL, set_META_REPLICAS}, - {0, "data-replicas",N_("number of data replicas"), NULL, NULL, NULL, set_DATA_REPLICAS }, - - {0, "wipe-bcache", N_("destroy existing bcache data if present"), NULL, NULL, &wipe_bcache, NULL}, - {0, "discard", N_("enable discards"), NULL, NULL, &discard, NULL}, - {0, "writeback", N_("enable writeback"), NULL, NULL, &writeback, NULL}, - - NIH_OPTION_LAST -}; - -static NihOption probe_bcache_options[] = { - {'o', "udev", N_("udev"), NULL, NULL, NULL, set_udev}, - NIH_OPTION_LAST -}; - -static NihOption bcache_register_options[] = { - NIH_OPTION_LAST -}; - -static NihOption query_devs_options[] = { - {'f', "force_csum", N_("force_csum"), NULL, NULL, &force_csum, NULL}, +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 list_cachesets_options[] = { - {'d', "dir", N_("directory"), NULL, NULL, &cset_dir, NULL}, - NIH_OPTION_LAST -}; - -static NihOption status_options[] = { - NIH_OPTION_LAST -}; - -static NihOption options[] = { - NIH_OPTION_LAST -}; - - -/* commands */ -int make_bcache (NihCommand *command, char *const *args) +int bcache_modify(NihCommand *command, char *const *args) { - int cache_dev_fd[devs]; - - int backing_dev_fd[devs]; - - cache_set_sb = calloc(1, sizeof(*cache_set_sb) + - sizeof(struct cache_member) * devs); - - uuid_generate(cache_set_sb->set_uuid.b); - SET_CACHE_PREFERRED_CSUM_TYPE(cache_set_sb, BCH_CSUM_CRC32C); - SET_CACHE_SET_META_REPLICAS_WANT(cache_set_sb, 1); - SET_CACHE_SET_DATA_REPLICAS_WANT(cache_set_sb, 1); - - if(!bucket_sizes[0]) bucket_sizes[0] = 1024; + char *err; + char path[MAX_PATH]; + char *attr = args[0]; + char *val = NULL; + int fd = -1; - if (bdev == -1) { - fprintf(stderr, "Please specify -C or -B\n"); - exit(EXIT_FAILURE); + if (modify_list_attrs) { + sysfs_attr_list(); + return 0; } - if (!cache_set_sb->nr_in_set && !nr_backing_devices) { - fprintf(stderr, "Please supply a device\n"); - exit(EXIT_FAILURE); + if (!modify_set_uuid) { + printf("Must provide a cacheset uuid\n"); + return -1; } - i = 0; - do { - if (bucket_sizes[i] < block_size) { - fprintf(stderr, "Bucket size cannot be smaller than block size\n"); - exit(EXIT_FAILURE); - } - i++; - } while (i < num_bucket_sizes); + snprintf(path, MAX_PATH, "%s/%s", cset_dir, modify_set_uuid); - if (!block_size) { - for (i = 0; i < cache_set_sb->nr_in_set; i++) - block_size = max(block_size, - get_blocksize(cache_devices[i])); - - for (i = 0; i < nr_backing_devices; i++) - block_size = max(block_size, - get_blocksize(backing_devices[i])); + if(!attr) { + printf("Must provide the name of an attribute to modify\n"); + goto err; } - for (i = 0; i < cache_set_sb->nr_in_set; i++) - cache_dev_fd[i] = dev_open(cache_devices[i], wipe_bcache); - - for (i = 0; i < nr_backing_devices; i++) - backing_dev_fd[i] = dev_open(backing_devices[i], wipe_bcache); - - write_cache_sbs(cache_dev_fd, cache_set_sb, block_size, - bucket_sizes, num_bucket_sizes); - - for (i = 0; i < nr_backing_devices; i++) - write_backingdev_sb(backing_dev_fd[i], - block_size, bucket_sizes, - writeback, data_offset, - backing_dev_labels[i], - cache_set_sb->set_uuid); - - - return 0; -} - -int probe_bcache (NihCommand *command, char *const *args) -{ - int i; - - for (i = 0; args[i] != NULL; i++) { - probe(args[i], udev); + 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 */ - return 0; -} - -int bcache_register (NihCommand *command, char *const *args) -{ - int ret; - char *arg_list = parse_array_to_list(args); + strcat(path, "/"); + strcat(path, attr); - if(arg_list) { - ret = register_bcache(arg_list); - free(arg_list); + val = args[1]; + if (!val) { + printf("Must provide a value to change the attribute to\n"); + goto err; } - return ret; -} - -int bcache_list_cachesets (NihCommand *command, char *const *args) -{ - return list_cachesets(cset_dir); -} - -int bcache_query_devs (NihCommand *command, char *const *args) -{ - int i; - - for (i = 0; args[i] != NULL; i++) { - struct cache_sb *sb = query_dev(args[i], false); - print_dev_info(sb, force_csum); + fd = open(path, O_WRONLY); + if (fd < 0) { + printf("Unable to open modify attr with path %s\n", path); + goto err; } -} -int bcache_status (NihCommand *command, char *const *args) -{ - int i; - struct cache_sb *sb_tier0 = NULL, *sb_tier1 = NULL; - char *dev0 = NULL, *dev1 = NULL; + write(fd, val, strlen(val)); - for (i = 0; args[i] != NULL; i++) { - struct cache_sb *sb = query_dev(args[i], false); - struct cache_member *m = ((struct cache_member *) sb->d) + - sb->nr_this_dev; - long long unsigned cache_tier = CACHE_TIER(m); +err: + if(fd) + close(fd); + return 0; +} +#endif - if (!cache_tier) - if (!sb_tier0 || sb->seq > sb_tier0->seq) { - sb_tier0 = sb; - dev0 = args[i]; - } - else if (cache_tier == 1) - if (!sb_tier1 || sb->seq > sb_tier1->seq) { - sb_tier1 = sb; - dev1 = args[i]; - } - } - if (sb_tier0) sb_state(sb_tier0, dev0); - if (sb_tier1) sb_state(sb_tier1, dev1); +#define CMD(_command, _usage, _synopsis, _help) \ +{ \ + .command = #_command, \ + .usage = _usage, \ + .synopsis = _synopsis, \ + .help = _help, \ + .group = NULL, \ + .options = opts_##_command, \ + .action = cmd_##_command, \ } static NihCommand commands[] = { - {"format", N_("format "), - "Format one or a list of devices with bcache datastructures." - " You need to do this before you create a volume", - N_("format drive[s] with bcache"), - NULL, make_bcache_options, make_bcache}, - {"probe", N_("probe "), - "Does a blkid_probe on a device", - N_("Does a blkid_probe on a device"), - NULL, probe_bcache_options, probe_bcache}, - {"register", N_("register "), - "Registers a list of devices", - N_("Registers a list of devices"), - NULL, bcache_register_options, bcache_register}, - {"list-cachesets", N_("list-cachesets"), - "Lists cachesets in /sys/fs/bcache", - N_("Lists cachesets in /sys/fs/bcache"), - NULL, list_cachesets_options, bcache_list_cachesets}, - {"query-devs", N_("query "), - "Gives info about the superblock of a list of devices", - N_("show superblock on each of the listed drive"), - NULL, query_devs_options, bcache_query_devs}, - {"status", N_("status "), - "Finds the status of the most up to date superblock", - N_("Finds the status of the most up to date superblock"), - NULL, status_options, bcache_status}, + CMD(format, N_(""), + "Create a new bcache volume from one or more devices", + N_("format drive[s] for bcache")), + + CMD(assemble, N_(""), + "Assembles one or more devices into a bcache volume", + N_("Registers a list of devices")), + CMD(incremental, N_(""), + "Start a partially assembled volume", + N_("Registers a list of devices")), + CMD(stop, N_(""), + "Stops a running bcache volume", + N_("Unregisters a list of devices")), + CMD(add, N_(" "), + "Adds a list of devices to a volume", + N_("Adds a list of devices to a volume")), + CMD(readd, N_(" "), + "Adds previously used members of a volume", + N_("Adds a list of devices to a volume")), + CMD(remove, N_(" "), + "Removes a device from its volume", + N_("Removes a device from its volume")), + CMD(fail, N_(" "), + "Sets a device to the FAILED state", + N_("Sets a device to the FAILED state")), + +#if 0 + CMD(modify, N_(""), + "Modifies attributes related to the volume", + N_("Modifies attributes related to the volume")), +#endif + CMD(list, N_("list-cachesets"), + "Lists cachesets in /sys/fs/bcache", + N_("Lists cachesets in /sys/fs/bcache")), + CMD(query, N_("query "), + "Gives info about the superblock of a list of devices", + N_("show superblock on each of the listed drive")), + CMD(status, N_("status "), + "Finds the status of the most up to date superblock", + N_("Finds the status of the most up to date superblock")), NIH_COMMAND_LAST }; +static NihOption options[] = { + NIH_OPTION_LAST +}; int main(int argc, char *argv[]) { - int ret = 0; - nih_main_init (argv[0]); - - nih_option_set_synopsis (_("Manage bcache devices")); - nih_option_set_help ( - _("Helps you manage bcache devices")); + nih_main_init(argv[0]); + nih_option_set_synopsis(_("Manage bcache devices")); + nih_option_set_help( _("Helps you manage bcache devices")); - ret = nih_command_parser (NULL, argc, argv, options, commands); + int ret = nih_command_parser(NULL, argc, argv, options, commands); if (ret < 0) - exit (1); + exit(EXIT_FAILURE); nih_signal_reset(); + + return 0; }