bcacheadm.o: CFLAGS += `pkg-config --cflags uuid blkid libnih`
bcacheadm: LDLIBS += `pkg-config --libs uuid blkid libnih`
-bcacheadm: bcacheadm.o bcacheadm-format.o bcache.o
+bcacheadm: bcacheadm.o bcacheadm-format.o bcacheadm-assemble.o bcacheadm-run.o\
+ bcacheadm-query.o bcache.o
probe-bcache.o: CFLAGS += `pkg-config --cflags uuid blkid`
probe-bcache: LDLIBS += `pkg-config --libs uuid blkid`
return strdup(buf);
}
-static void list_cacheset_devs(char *cset_dir, char *cset_name, bool parse_dev_name)
-{
- DIR *cachedir, *dir;
- struct stat cache_stat;
- char entry[MAX_PATH];
- struct dirent *ent;
- snprintf(entry, MAX_PATH, "%s/%s", cset_dir, cset_name);
-
- if((dir = opendir(entry)) != NULL) {
- while((ent = readdir(dir)) != NULL) {
- char buf[MAX_PATH];
- int len;
- char *tmp;
-
- /*
- * We are looking for all cache# directories
- * do a strlen < 9 to skip over other entries
- * that also start with "cache"
- */
- if(strncmp(ent->d_name, "cache", 5) ||
- !(strlen(ent->d_name) < 9))
- continue;
-
- snprintf(entry, MAX_PATH, "%s/%s/%s",
- cset_dir,
- cset_name,
- ent->d_name);
-
- if((cachedir = opendir(entry)) == NULL)
- continue;
-
- if(stat(entry, &cache_stat))
- continue;
-
- if((len = readlink(entry, buf, sizeof(buf) - 1)) !=
- -1) {
- buf[len] = '\0';
- if(parse_dev_name) {
- tmp = dev_name(buf);
- printf("/dev%s\n", tmp);
- free(tmp);
- } else {
- printf("\t%s\n", buf);
- }
- }
- }
- }
-}
-
char *find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uuid)
{
/* Do a query-dev --uuid only to get the uuid
return err;
}
-char *list_cachesets(char *cset_dir, bool list_devs)
-{
- struct dirent *ent;
- DIR *dir;
- char *err = NULL;
-
- dir = opendir(cset_dir);
- if (!dir) {
- err = "Failed to open cacheset dir";
- goto err;
- }
-
- while ((ent = readdir(dir)) != NULL) {
- struct stat statbuf;
- char entry[MAX_PATH];
-
- if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
- continue;
-
- snprintf(entry, MAX_PATH, "%s/%s", cset_dir, ent->d_name);
- if(stat(entry, &statbuf) == -1) {
- err = "Failed to stat cacheset subdir";
- goto err;
- }
-
- if (S_ISDIR(statbuf.st_mode)) {
- printf("%s\n", ent->d_name);
-
- if(list_devs) {
- list_cacheset_devs(cset_dir, ent->d_name, true);
- }
- }
- }
-
-err:
- closedir(dir);
- return err;
-}
-
-char *register_bcache(char *const *devs)
-{
- int ret, bcachefd;
- char *err = NULL;
-
- bcachefd = open("/dev/bcache", O_RDWR);
- if (bcachefd < 0) {
- err = "Can't open bcache device";
- goto err;
- }
-
- ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, devs);
- if (ret < 0) {
- char tmp[64];
- snprintf(tmp, 64, "ioctl register error: %s\n",
- strerror(ret));
- err = strdup(tmp);
- goto err;
- }
-
-err:
- if (bcachefd)
- close(bcachefd);
- return err;
-}
-
-char *unregister_bcache(char *const *devs)
-{
- int ret, bcachefd;
- char *err = NULL;
-
- bcachefd = open("/dev/bcache_extent0", O_RDWR);
- if (bcachefd < 0) {
- err = "Can't open bcache device";
- goto err;
- }
-
- ret = ioctl(bcachefd, BCH_IOCTL_STOP);
- if (ret < 0) {
- char tmp[64];
- snprintf(tmp, 64, "ioctl unregister error: %s\n",
- strerror(ret));
- err = strdup(tmp);
- goto err;
- }
-
-err:
- close(bcachefd);
- return err;
-}
-
-char *add_devices(char *const *devs)
-{
- int ret, bcachefd;
- char *err = NULL;
-
- bcachefd = open("/dev/bcache_extent0", O_RDWR);
- if (bcachefd < 0) {
- err = "Can't open bcache device";
- goto err;
- }
-
- struct bch_ioctl_add_disks ia;
- ia.devs = devs;
-
- ret = ioctl(bcachefd, BCH_IOCTL_ADD_DISKS, &ia);
- if (ret < 0) {
- char tmp[128];
- snprintf(tmp, 128, "ioctl add disk error: %s\n",
- strerror(ret));
- err = strdup(tmp);
- }
-
-err:
- close(bcachefd);
- return err;
-}
-
-char *remove_device(const char *dev, bool force)
-{
- int ret, bcachefd;
- char *err = NULL;
-
- bcachefd = open("/dev/bcache_extent0", O_RDWR);
- if (bcachefd < 0) {
- err = "Can't open bcache device";
- goto err;
- }
-
- struct bch_ioctl_rm_disk ir;
- ir.dev = dev;
- ir.force = force ? 1 : 0;
-
- ret = ioctl(bcachefd, BCH_IOCTL_RM_DISK, &ir);
- if (ret < 0) {
- char tmp[128];
- snprintf(tmp, 128, "ioctl add disk error: %s\n",
- strerror(ret));
- err = strdup(tmp);
- }
-
-err:
- close(bcachefd);
- return err;
-}
-
-char *device_set_failed(const char *dev_uuid) {
- int ret, bcachefd;
- char *err = NULL;
- uuid_le dev;
- struct bch_ioctl_disk_failed df;
-
- bcachefd = open("/dev/bcache_extent0", O_RDWR);
- if (bcachefd < 0) {
- err = "Can't open bcache device";
- goto err;
- }
-
- uuid_parse(dev_uuid, dev.b);
- df.dev_uuid = dev;
-
- ret = ioctl(bcachefd, BCH_IOCTL_SET_DISK_FAILED, &df);
- if (ret < 0) {
- char tmp[128];
- snprintf(tmp, 128, "ioctl set disk failed error %s\n",
- strerror(ret));
- err = strdup(tmp);
- }
-
-err:
- close(bcachefd);
- return err;
-}
-
-char *probe(char *dev, int udev)
+int bcachectl_open(void)
{
- struct cache_sb sb;
- char uuid[40];
- blkid_probe pr;
- char *err = NULL;
-
- int fd = open(dev, O_RDONLY);
- if (fd == -1) {
- err = "Got file descriptor -1 trying to open dev";
- goto err;
- }
-
- if (!(pr = blkid_new_probe())) {
- err = "Failed trying to get a blkid for new probe";
- goto err;
- }
-
- if (blkid_probe_set_device(pr, fd, 0, 0)) {
- err = "Failed blkid probe set device";
- goto err;
- }
-
- /* probe partitions too */
- if (blkid_probe_enable_partitions(pr, true)) {
- err = "Enable probe partitions";
- goto err;
- }
-
- /* bail if anything was found
- * probe-bcache isn't needed once blkid recognizes bcache */
- if (!blkid_do_probe(pr)) {
- err = "blkid recognizes bcache";
- goto err;
- }
+ int fd = open("/dev/bcache-ctl", O_RDWR);
+ if (fd < 0)
+ die("Can't open bcache device: %s", strerror(errno));
- if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
- err = "Failed to read superblock";
- goto err;
- }
-
- if (memcmp(&sb.magic, &BCACHE_MAGIC, sizeof(sb.magic))) {
- err = "Bcache magic incorrect";
- goto err;
- }
-
- uuid_unparse(sb.disk_uuid.b, uuid);
-
- if (udev)
- printf("ID_FS_UUID=%s\n"
- "ID_FS_UUID_ENC=%s\n"
- "ID_FS_TYPE=bcache\n",
- uuid, uuid);
- else
- printf("%s: UUID=\"\" TYPE=\"bcache\"\n", uuid);
-
- return 0;
-
-err:
- return err;
-}
-
-char *read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, char *ret)
-{
- struct stat statbuf;
- char entry[MAX_PATH];
- char *err = NULL;
-
- snprintf(entry, MAX_PATH, "%s/%s", stats_dir, stat_name);
- if(stat(entry, &statbuf) == -1) {
- char tmp[MAX_PATH];
- snprintf(tmp, MAX_PATH, "Failed to stat %s\n", entry);
- err = strdup(tmp);
- goto err;
- }
-
- if (S_ISREG(statbuf.st_mode)) {
- FILE *fp = NULL;
-
- fp = fopen(entry, "r");
- if(!fp) {
- /* If we can't open the file, this is probably because
- * of permissions, just move to the next file */
- return NULL;
- }
-
- while(fgets(ret, MAX_PATH, fp));
- fclose(fp);
- }
-err:
- return err;
+ return fd;
}
-char *bcache_get_capacity(const char *cset_dir, const char *capacity_uuid,
- bool show_devs)
+unsigned nr_args(char *const *args)
{
- char *err = NULL;
- char bucket_size_path[MAX_PATH];
- char nbuckets_path[MAX_PATH];
- char avail_buckets_path[MAX_PATH];
- char cache_path[MAX_PATH];
-
- double bucket_sizes[MAX_DEVS];
- double nbuckets[MAX_DEVS];
- double avail_buckets[MAX_DEVS];
- char *dev_names[MAX_DEVS];
- int dev_count = 0, i;
- double total_cap = 0, total_free = 0;
- int precision = 2;
-
-
- while (true) {
- char buf[MAX_PATH];
- int len;
- DIR *cache_dir;
-
- snprintf(bucket_size_path, sizeof(bucket_size_path), "%s/%s/%s%d/%s", cset_dir,
- capacity_uuid, "cache", dev_count, "bucket_size_bytes");
- snprintf(nbuckets_path, sizeof(nbuckets_path), "%s/%s/%s%d/%s", cset_dir,
- capacity_uuid, "cache", dev_count, "nbuckets");
- snprintf(avail_buckets_path, sizeof(avail_buckets_path), "%s/%s/%s%d/%s", cset_dir,
- capacity_uuid, "cache", dev_count, "available_buckets");
- snprintf(cache_path, sizeof(cache_path), "%s/%s/%s%d", cset_dir, capacity_uuid,
- "cache", dev_count);
-
- if((cache_dir = opendir(cache_path)) == NULL)
- break;
-
- err = read_stat_dir(cache_dir, cache_path,
- "bucket_size_bytes", buf);
- if (err)
- goto err;
- else
- bucket_sizes[dev_count] = atof(buf);
+ unsigned i;
- err = read_stat_dir(cache_dir, cache_path,
- "nbuckets", buf);
- if (err)
- goto err;
- else
- nbuckets[dev_count] = atof(buf);
-
- err = read_stat_dir(cache_dir, cache_path,
- "available_buckets", buf);
- if (err)
- goto err;
- else
- avail_buckets[dev_count] = atof(buf);
-
- if((len = readlink(cache_path, buf, sizeof(buf) - 1)) != -1) {
- buf[len] = '\0';
- dev_names[dev_count] = dev_name(buf);
- }
-
- dev_count++;
- }
-
- printf("%-15s%-25s%-25s\n", "Device Name", "Capacity (512 Blocks)", "Free (512 Blocks)");
+ for (i = 0; args[i]; i++)
+ ;
- if (show_devs) {
- for (i = 0; i < dev_count; i++) {
- printf("%s%-11s%-25.*f%-25.*f\n", "/dev", dev_names[i],
- precision,
- (bucket_sizes[i] * nbuckets[i]) / 512,
- precision,
- (bucket_sizes[i] * avail_buckets[i]) / 512);
- }
- }
-
- for (i = 0; i < dev_count; i++) {
- total_cap += (bucket_sizes[i] * nbuckets[i]) / 512;
- total_free += (bucket_sizes[i] * avail_buckets[i]) / 512;
-
- }
-
- printf("%-15s%-25.*f%-25.*f\n", "Total", precision, total_cap,
- precision, total_free);
-
-err:
- for (i = 0; i < dev_count; i++)
- if (dev_names[i])
- free(dev_names[i]);
- return err;
+ return i;
}
#ifndef _BCACHE_H
#define _BCACHE_H
+#include <stdint.h>
#include <linux/bcache.h>
#include <dirent.h>
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 *);
char *register_bcache(char *const *);
-char *unregister_bcache(char *const *);
-char *probe(char *, int);
-char *read_stat_dir(DIR *, char *, char *, char *);
char *find_matching_uuid(char *, char *, const char*);
-char *add_devices(char *const *);
-char *remove_device(const char *, bool);
-char *bcache_get_capacity(const char *, const char *, bool);
char *dev_name(const char *);
-char *device_set_failed(const char *dev_uuid);
+
+int bcachectl_open(void);
+unsigned nr_args(char * const *);
#define csum_set(i, type) \
({ \
--- /dev/null
+
+#include <alloca.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+
+#include <nih/command.h>
+#include <nih/option.h>
+
+#include <linux/bcache-ioctl.h>
+
+#include "bcache.h"
+#include "bcacheadm-assemble.h"
+
+NihOption opts_assemble[] = {
+ NIH_OPTION_LAST
+};
+
+int cmd_assemble(NihCommand *command, char *const *args)
+{
+ unsigned nr_devs = nr_args(args);
+
+ struct bch_ioctl_assemble *assemble =
+ alloca(sizeof(*assemble) + sizeof(__u64) * nr_devs);
+
+ memset(assemble, 0, sizeof(*assemble));
+ assemble->nr_devs = nr_devs;
+
+ for (unsigned i = 0; i < nr_devs; i++)
+ assemble->devs[i] = (__u64) args[i];
+
+ int ret = ioctl(bcachectl_open(), BCH_IOCTL_ASSEMBLE, assemble);
+ if (ret < 0)
+ die("BCH_IOCTL_ASSEMBLE error: %s", strerror(errno));
+
+ return 0;
+}
+
+NihOption opts_incremental[] = {
+ NIH_OPTION_LAST
+};
+
+int cmd_incremental(NihCommand *command, char *const *args)
+{
+ if (nr_args(args) != 1)
+ die("Please supply exactly one device");
+
+ struct bch_ioctl_incremental incremental = {
+ .dev = (__u64) args[0],
+ };
+
+ int ret = ioctl(bcachectl_open(), BCH_IOCTL_INCREMENTAL, &incremental);
+ if (ret < 0)
+ die("BCH_IOCTL_INCREMENTAL error: %s", strerror(errno));
+
+ return 0;
+}
--- /dev/null
+#ifndef _BCACHEADM_ASSEMBLE_H
+#define _BCACHEADM_ASSEMBLE_H
+
+extern NihOption opts_assemble[];
+int cmd_assemble(NihCommand *, char * const *);
+
+extern NihOption opts_incremental[];
+int cmd_incremental(NihCommand *, char * const *);
+
+#endif /* _BCACHEADM_ASSEMBLE_H */
#include <nih/option.h>
#include "bcache.h"
-#include "bcacheadm.h"
+#include "bcacheadm-format.h"
static struct cache_opts {
int fd;
return 0;
}
-NihOption bcacheadm_format_options[] = {
+NihOption opts_format[] = {
// { int shortoption, char *longoption, char *help, NihOptionGroup, char *argname, void *value, NihOptionSetter}
{ 'C', "cache", N_("Format a cache device"),
return ret;
}
-int bcacheadm_format(NihCommand *command, char *const *args)
+static int format_v0(void)
{
- struct cache_sb *cache_set_sb;
+ return 0;
+}
- if (!nr_cache_devices && !nr_backing_devices)
- die("Please supply a device");
+static int format_v1(void)
+{
+ struct cache_sb *cache_set_sb;
if (!block_size) {
for (struct cache_opts *i = cache_devices;
return 0;
}
+
+int cmd_format(NihCommand *command, char *const *args)
+{
+ if (!nr_cache_devices && !nr_backing_devices)
+ die("Please supply a device");
+
+ return format_v1();
+}
--- /dev/null
+#ifndef _BCACHEADM_FORMAT_H
+#define _BCACHEADM_FORMAT_H
+
+extern NihOption opts_format[];
+int cmd_format(NihCommand *, char * const *);
+
+#endif /* _BCACHEADM_FORMAT_H */
--- /dev/null
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <nih/command.h>
+#include <nih/option.h>
+
+#include <linux/bcache-ioctl.h>
+
+#include <uuid/uuid.h>
+
+#include "bcache.h"
+#include "bcacheadm-query.h"
+
+static char *cset_dir = "/sys/fs/bcache";
+static bool list_devs = false;
+static const char *internal_uuid = NULL;
+
+NihOption opts_list[] = {
+ {'d', "dir", N_("directory"), NULL, NULL, &cset_dir, NULL},
+ {0, "list-devs", N_("list all devices in the cache sets as well"), NULL, NULL, &list_devs, NULL},
+ {0, "internal_uuid", N_("Show the internal UUID for the given cacheset UUID"), NULL, "UUID", &internal_uuid, NULL},
+ NIH_OPTION_LAST
+};
+
+static void list_cacheset_devs(char *cset_dir, char *cset_name, bool parse_dev_name)
+{
+ DIR *cachedir, *dir;
+ struct stat cache_stat;
+ char entry[MAX_PATH];
+ struct dirent *ent;
+ snprintf(entry, MAX_PATH, "%s/%s", cset_dir, cset_name);
+
+ if((dir = opendir(entry)) != NULL) {
+ while((ent = readdir(dir)) != NULL) {
+ char buf[MAX_PATH];
+ int len;
+ char *tmp;
+
+ /*
+ * We are looking for all cache# directories
+ * do a strlen < 9 to skip over other entries
+ * that also start with "cache"
+ */
+ if(strncmp(ent->d_name, "cache", 5) ||
+ !(strlen(ent->d_name) < 9))
+ continue;
+
+ snprintf(entry, MAX_PATH, "%s/%s/%s",
+ cset_dir,
+ cset_name,
+ ent->d_name);
+
+ if((cachedir = opendir(entry)) == NULL)
+ continue;
+
+ if(stat(entry, &cache_stat))
+ continue;
+
+ if((len = readlink(entry, buf, sizeof(buf) - 1)) !=
+ -1) {
+ buf[len] = '\0';
+ if(parse_dev_name) {
+ tmp = dev_name(buf);
+ printf("/dev%s\n", tmp);
+ free(tmp);
+ } else {
+ printf("\t%s\n", buf);
+ }
+ }
+ }
+ }
+}
+
+static char *list_cachesets(char *cset_dir, bool list_devs)
+{
+ struct dirent *ent;
+ DIR *dir;
+ char *err = NULL;
+
+ dir = opendir(cset_dir);
+ if (!dir) {
+ err = "Failed to open cacheset dir";
+ goto err;
+ }
+
+ while ((ent = readdir(dir)) != NULL) {
+ struct stat statbuf;
+ char entry[MAX_PATH];
+
+ if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
+ continue;
+
+ snprintf(entry, MAX_PATH, "%s/%s", cset_dir, ent->d_name);
+ if(stat(entry, &statbuf) == -1) {
+ err = "Failed to stat cacheset subdir";
+ goto err;
+ }
+
+ if (S_ISDIR(statbuf.st_mode)) {
+ printf("%s\n", ent->d_name);
+
+ if(list_devs) {
+ list_cacheset_devs(cset_dir, ent->d_name, true);
+ }
+ }
+ }
+
+err:
+ closedir(dir);
+ return err;
+}
+
+static char *read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, char *ret)
+{
+ struct stat statbuf;
+ char entry[MAX_PATH];
+ char *err = NULL;
+
+ snprintf(entry, MAX_PATH, "%s/%s", stats_dir, stat_name);
+ if(stat(entry, &statbuf) == -1) {
+ char tmp[MAX_PATH];
+ snprintf(tmp, MAX_PATH, "Failed to stat %s\n", entry);
+ err = strdup(tmp);
+ goto err;
+ }
+
+ if (S_ISREG(statbuf.st_mode)) {
+ FILE *fp = NULL;
+
+ fp = fopen(entry, "r");
+ if(!fp) {
+ /* If we can't open the file, this is probably because
+ * of permissions, just move to the next file */
+ return NULL;
+ }
+
+ while(fgets(ret, MAX_PATH, fp));
+ fclose(fp);
+ }
+err:
+ return err;
+}
+
+int cmd_list(NihCommand *command, char *const *args)
+{
+ char *err = NULL;
+
+ if (internal_uuid) {
+ char uuid_path[MAX_PATH];
+ DIR *uuid_dir;
+ char buf[MAX_PATH];
+
+ snprintf(uuid_path, MAX_PATH, "%s/%s", cset_dir, internal_uuid);
+
+ err = "uuid does not exist";
+ if((uuid_dir = opendir(uuid_path)) == NULL)
+ goto err;
+
+ err = read_stat_dir(uuid_dir, uuid_path, "/internal/internal_uuid", buf);
+ if (err)
+ goto err;
+ printf("%s", buf);
+ return 0;
+ }
+
+ err = list_cachesets(cset_dir, list_devs);
+ if (err)
+ goto err;
+
+ return 0;
+
+err:
+ printf("bcache_list_cachesets error :%s\n", err);
+ return -1;
+}
+
+static bool force_csum = false;
+static bool uuid_only = false;
+static bool query_brief = false;
+
+NihOption opts_query[] = {
+ {'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},
+ {'b', "brief", N_("only print out the cluster,server,and disk uuids"), NULL, NULL, &query_brief, NULL},
+ NIH_OPTION_LAST
+};
+
+int cmd_query(NihCommand *command, char *const *args)
+{
+ int i;
+
+ if (query_brief)
+ printf("%-10s%-40s%-40s%-40s\n", "dev name", "disk uuid",
+ "server uuid", "cluster uuid");
+
+ for (i = 0; args[i] != NULL; i++) {
+ char dev_uuid[40];
+ struct cache_sb *sb = query_dev(args[i], force_csum,
+ !query_brief, uuid_only, dev_uuid);
+
+ if (!sb) {
+ printf("error opening the superblock for %s\n",
+ args[i]);
+ return -1;
+ }
+
+ if (uuid_only) {
+ printf("%s\n", dev_uuid);
+ } else if (query_brief) {
+ char set_uuid_str[40], dev_uuid_str[40];
+ char *clus_uuid = (char *)sb->label;
+
+ uuid_unparse(sb->user_uuid.b, set_uuid_str);
+ uuid_unparse(sb->disk_uuid.b, dev_uuid_str);
+ if (!strcmp(clus_uuid, ""))
+ clus_uuid = "None";
+
+ printf("%-10s%-40s%-40s%-40s\n", args[i],
+ dev_uuid_str,
+ set_uuid_str,
+ clus_uuid);
+ }
+ free(sb);
+ }
+
+ return 0;
+}
+
+static bool status_all = false;
+
+NihOption opts_status[] = {
+ {'a', "all", N_("all"), NULL, NULL, &status_all, NULL},
+ NIH_OPTION_LAST
+};
+
+int cmd_status(NihCommand *command, char *const *args)
+{
+ int i, dev_count = 0, seq, cache_count = 0;
+ struct cache_sb *seq_sb = NULL;
+ char cache_path[MAX_PATH];
+ char *dev_names[MAX_DEVS];
+ char *dev_uuids[MAX_DEVS];
+ char intbuf[4];
+ char set_uuid[40];
+
+ for (i = 0; args[i] != NULL; i++) {
+ struct cache_sb *sb = query_dev(args[i], false, false,
+ false, NULL);
+
+ if (!sb) {
+ printf("Unable to open superblock, bad path\n");
+ return -1;
+ }
+
+ if (!seq_sb || sb->seq > seq) {
+ seq = sb->seq;
+ seq_sb = sb;
+ } else
+ free(sb);
+ }
+
+ if (!seq_sb) {
+ printf("Unable to find a superblock\n");
+ return -1;
+ } else {
+ uuid_unparse(seq_sb->user_uuid.b, set_uuid);
+ printf("%-50s%-15s%-4s\n", "uuid", "state", "tier");
+ }
+
+ snprintf(intbuf, 4, "%d", i);
+ snprintf(cache_path, MAX_PATH, "%s/%s/%s", cset_dir, set_uuid,
+ "cache0");
+
+ /*
+ * Get a list of all the devices from sysfs first, then
+ * compare it to the list we get back from the most up
+ * to date superblock. If there are any devices in the superblock
+ * that are not in sysfs, print out 'missing'
+ */
+ while (true) {
+ char buf[MAX_PATH];
+ int len;
+ DIR *cache_dir;
+
+ if(((cache_dir = opendir(cache_path)) == NULL) &&
+ cache_count > MAX_DEVS)
+ break;
+
+ if (cache_dir)
+ closedir(cache_dir);
+
+ if((len = readlink(cache_path, buf, sizeof(buf) - 1)) != -1) {
+ struct cache_sb *sb;
+ char dev_uuid[40];
+ char dev_path[32];
+
+ buf[len] = '\0';
+ dev_names[dev_count] = dev_name(buf);
+ snprintf(dev_path, MAX_PATH, "%s/%s", "/dev",
+ dev_names[dev_count]);
+ sb = query_dev(dev_path, false, false,
+ true, dev_uuid);
+ if (!sb) {
+ printf("error reading %s\n", dev_path);
+ return -1;
+ } else
+ free(sb);
+
+ dev_uuids[dev_count] = strdup(dev_uuid);
+ dev_count++;
+ }
+
+ cache_path[strlen(cache_path) - strlen(intbuf)] = 0;
+ cache_count++;
+
+ snprintf(intbuf, 4, "%d", cache_count);
+ strcat(cache_path, intbuf);
+ }
+
+ for (i = 0; i < seq_sb->nr_in_set; i++) {
+ char uuid_str[40];
+ struct cache_member *m = seq_sb->members + i;
+ char dev_state[32];
+ int j;
+
+ uuid_unparse(m->uuid.b, uuid_str);
+ snprintf(dev_state, MAX_PATH, "%s",
+ cache_state[CACHE_STATE(m)]);
+
+ for (j = 0; j < dev_count; j++) {
+ if (!strcmp(uuid_str, dev_uuids[j])) {
+ break;
+ } else if (j == dev_count - 1) {
+ if (!strcmp(cache_state[CACHE_STATE(m)], "active"))
+ snprintf(dev_state, MAX_PATH, "%s", "missing");
+ break;
+ }
+ }
+
+ printf("%-50s%-15s%-4llu\n", uuid_str, dev_state,
+ CACHE_TIER(m));
+ }
+
+ if (seq_sb)
+ free(seq_sb);
+ for (i = 0; i < dev_count; i++) {
+ free(dev_names[i]);
+ free(dev_uuids[i]);
+ }
+
+ return 0;
+}
--- /dev/null
+#ifndef _BCACHEADM_QUERY_H
+#define _BCACHEADM_QUERY_H
+
+extern NihOption opts_list[];
+int cmd_list(NihCommand *, char * const *);
+
+extern NihOption opts_query[];
+int cmd_query(NihCommand *, char * const *);
+
+extern NihOption opts_status[];
+int cmd_status(NihCommand *, char * const *);
+
+#endif /* _BCACHEADM_QUERY_H */
--- /dev/null
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <nih/command.h>
+#include <nih/option.h>
+
+#include <linux/bcache-ioctl.h>
+
+#include <uuid/uuid.h>
+
+#include "bcache.h"
+#include "bcacheadm-run.h"
+
+static bool force_data = false;
+static bool force_metadata = false;
+
+NihOption opts_run[] = {
+ NIH_OPTION_LAST
+};
+
+int cmd_run(NihCommand *command, char *const *args)
+{
+ return 0;
+}
+
+NihOption opts_stop[] = {
+ NIH_OPTION_LAST
+};
+
+int cmd_stop(NihCommand *command, char *const *args)
+{
+ int bcachefd = open("/dev/bcache_extent0", O_RDWR);
+ if (bcachefd < 0)
+ die("Can't open bcache device");
+
+ int ret = ioctl(bcachefd, BCH_IOCTL_STOP);
+ if (ret < 0)
+ die("BCH_IOCTL_STOP error: %s", strerror(errno));
+
+ close(bcachefd);
+ return 0;
+}
+
+NihOption opts_add[] = {
+ NIH_OPTION_LAST
+};
+
+int cmd_add(NihCommand *command, char *const *args)
+{
+ if (nr_args(args) != 1)
+ die("Please supply exactly one device");
+
+ int ret, bcachefd;
+
+ bcachefd = open("/dev/bcache_extent0", O_RDWR);
+ if (bcachefd < 0)
+ die("Can't open bcache device: %s", strerror(errno));
+
+ struct bch_ioctl_disk_add ia = {
+ .dev = (__u64) args[0],
+ };
+
+ ret = ioctl(bcachefd, BCH_IOCTL_DISK_ADD, &ia);
+ if (ret < 0)
+ die("BCH_IOCTL_DISK_ADD error: %s", strerror(ret));
+
+ close(bcachefd);
+ return 0;
+}
+
+NihOption opts_readd[] = {
+ NIH_OPTION_LAST
+};
+
+int cmd_readd(NihCommand *command, char *const *args)
+{
+ if (nr_args(args) != 1)
+ die("Please supply exactly one device");
+
+ return 0;
+}
+
+NihOption opts_remove[] = {
+ {
+ 'f', "force", N_("force if data present"),
+ NULL, NULL, &force_data, NULL
+ },
+ {
+ '\0', "force-metadata", N_("force if metadata present"),
+ NULL, NULL, &force_metadata, NULL},
+ NIH_OPTION_LAST
+};
+
+int cmd_remove(NihCommand *command, char *const *args)
+{
+ if (nr_args(args) != 1)
+ die("Please supply exactly one device");
+
+ int bcachefd = open("/dev/bcache_extent0", O_RDWR);
+ if (bcachefd < 0)
+ die("Can't open bcache device");
+
+ struct bch_ioctl_disk_remove ir = {
+ .dev = (__u64) args[0],
+ };
+
+ if (force_data)
+ ir.flags |= BCH_FORCE_IF_DATA_MISSING;
+ if (force_metadata)
+ ir.flags |= BCH_FORCE_IF_METADATA_MISSING;
+
+ int ret = ioctl(bcachefd, BCH_IOCTL_DISK_REMOVE, &ir);
+ if (ret < 0)
+ die("BCH_IOCTL_DISK_REMOVE error: %s\n", strerror(errno));
+
+ close(bcachefd);
+ return 0;
+}
+
+static const char *dev_failed_uuid = NULL;
+
+NihOption opts_fail[] = {
+ {'d', "dev", N_("dev UUID"), NULL, "UUID", &dev_failed_uuid, NULL},
+ NIH_OPTION_LAST
+};
+
+int cmd_fail(NihCommand *command, char *const *args)
+{
+ if (nr_args(args) != 1)
+ die("Please supply exactly one device");
+
+ int bcachefd = open("/dev/bcache_extent0", O_RDWR);
+ if (bcachefd < 0)
+ die("Can't open bcache device");
+
+ struct bch_ioctl_disk_fail df = {
+ .dev = (__u64) args[0],
+ };
+
+ int ret = ioctl(bcachefd, BCH_IOCTL_DISK_FAIL, &df);
+ if (ret < 0)
+ die("BCH_IOCTL_DISK_FAIL error: %s\n", strerror(errno));
+
+ return 0;
+}
--- /dev/null
+#ifndef _BCACHEADM_RUN_H
+#define _BCACHEADM_RUN_H
+
+extern NihOption opts_run[];
+int cmd_run(NihCommand *, char * const *);
+
+extern NihOption opts_stop[];
+int cmd_stop(NihCommand *, char * const *);
+
+extern NihOption opts_add[];
+int cmd_add(NihCommand *, char * const *);
+
+extern NihOption opts_readd[];
+int cmd_readd(NihCommand *, char * const *);
+
+extern NihOption opts_remove[];
+int cmd_remove(NihCommand *, char * const *);
+
+extern NihOption opts_fail[];
+int cmd_fail(NihCommand *, char * const *);
+
+#endif /* _BCACHEADM_RUN_H */
#include <dirent.h>
#include "bcache.h"
-#include "bcacheadm.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 PACKAGE_BUGREPORT "linux-bcache@vger.kernel.org"
-/* rm-dev globals */
-bool force_remove = false;
-
-/* Modify globals */
-bool modify_list_attrs = false;
+#if 0
+static 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;
-bool query_brief = false;
-
-/* probe globals */
-bool udev = false;
-
-/* list globals */
-char *cset_dir = "/sys/fs/bcache";
-bool list_devs = false;
-static const char *internal_uuid = NULL;
-
-/* status globals */
-bool status_all = false;
-
-/* capacity globals */
-static const char *capacity_uuid = NULL;
-bool capacity_devs = false;
-
-/* stats globals */
-bool stats_all = false;
-bool stats_list = false;
-static const char *stats_uuid = NULL;
-static const char *stats_dev_uuid = NULL;
-static const char *stats_cache_num = NULL;
-bool stats_five_min = false;
-bool stats_hour = false;
-bool stats_day = false;
-bool stats_total = false;
-
-/* set_failed globals */
-static const char *dev_failed_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 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 bcache_unregister_options[] = {
- NIH_OPTION_LAST
-};
-
-static NihOption bcache_add_device_options[] = {
- NIH_OPTION_LAST
-};
-
-static NihOption bcache_rm_device_options[] = {
- {'f', "force", N_("force cache removal"), NULL, NULL, &force_remove, NULL},
- 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},
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},
- {'b', "brief", N_("only print out the cluster,server,and disk uuids"), NULL, NULL, &query_brief, NULL},
- NIH_OPTION_LAST
-};
-
-static NihOption list_cachesets_options[] = {
- {'d', "dir", N_("directory"), NULL, NULL, &cset_dir, NULL},
- {0, "list-devs", N_("list all devices in the cache sets as well"), NULL, NULL, &list_devs, NULL},
- {0, "internal_uuid", N_("Show the internal UUID for the given cacheset UUID"), NULL, "UUID", &internal_uuid, NULL},
- NIH_OPTION_LAST
-};
-
-static NihOption status_options[] = {
- {'a', "all", N_("all"), NULL, NULL, &status_all, NULL},
- NIH_OPTION_LAST
-};
-
-static NihOption capacity_options[] = {
- {'u', "set", N_("cache_set UUID"), NULL, "UUID", &capacity_uuid, NULL},
- {'d', "devs", N_("Individual device capacities"), NULL, NULL, &capacity_devs, NULL},
- NIH_OPTION_LAST
-};
-
-static NihOption stats_options[] = {
- {'a', "all", N_("all"), NULL, NULL, &stats_all, NULL},
- {'l', "list", N_("list"), NULL, NULL, &stats_list, NULL},
- {'u', "set", N_("cache_set UUID"), NULL, "UUID", &stats_uuid, NULL},
- {'d', "dev", N_("dev UUID"), NULL, "UUID", &stats_dev_uuid, NULL},
- {'c', "cache", N_("cache number (starts from 0)"), NULL, "CACHE#", &stats_cache_num, NULL},
- {0, "five-min-stats", N_("stats accumulated in last 5 minutes"), NULL, NULL, &stats_five_min, NULL},
- {0, "hour-stats", N_("stats accumulated in last hour"), NULL, NULL, &stats_hour, NULL},
- {0, "day-stats", N_("stats accumulated in last day"), NULL, NULL, &stats_day, NULL},
- {0, "total-stats", N_("stats accumulated in total"), NULL, NULL, &stats_total, NULL},
- NIH_OPTION_LAST
-};
-
-static NihOption set_failed_options[] = {
- {'d', "dev", N_("dev UUID"), NULL, "UUID", &dev_failed_uuid, NULL},
- NIH_OPTION_LAST
-};
-
-static NihOption options[] = {
- NIH_OPTION_LAST
-};
-
-/* commands */
-int probe_bcache(NihCommand *command, char *const *args)
-{
- int i;
- char *err = NULL;
-
- for (i = 0; args[i] != NULL; i++) {
- err = probe(args[i], udev);
- if(err) {
- printf("probe_bcache error: %s\n", err);
- return -1;
- }
- }
-
- return 0;
-}
-
-int bcache_register(NihCommand *command, char *const *args)
-{
- char *err = NULL;
-
- err = register_bcache(args);
- if (err) {
- printf("bcache_register error: %s\n", err);
- return -1;
- }
-
- return 0;
-}
-
-int bcache_unregister(NihCommand *command, char *const *args)
-{
- char *err = NULL;
-
- err = unregister_bcache(args);
- if (err) {
- printf("bcache_unregister error: %s\n", err);
- return -1;
- }
-
- return 0;
-}
-
-int bcache_add_devices(NihCommand *command, char *const *args)
-{
- char *err;
-
- err = add_devices(args);
- if (err) {
- printf("bcache_add_devices error: %s\n", err);
- return -1;
- }
-
- return 0;
-}
-
-int bcache_rm_device(NihCommand *command, char *const *args)
-{
- char *err;
-
- if (!args[0]) {
- printf("Must provide a device name\n");
- return -1;
- }
-
- err = remove_device(args[0], force_remove);
- if (err) {
- printf("bcache_rm_devices error: %s\n", err);
- return -1;
- }
-
- return 0;
-}
-
int bcache_modify(NihCommand *command, char *const *args)
{
char *err;
close(fd);
return 0;
}
-
-int bcache_list_cachesets(NihCommand *command, char *const *args)
-{
- char *err = NULL;
-
- if (internal_uuid) {
- char uuid_path[MAX_PATH];
- DIR *uuid_dir;
- char buf[MAX_PATH];
-
- snprintf(uuid_path, MAX_PATH, "%s/%s", cset_dir, internal_uuid);
-
- err = "uuid does not exist";
- if((uuid_dir = opendir(uuid_path)) == NULL)
- goto err;
-
- err = read_stat_dir(uuid_dir, uuid_path, "/internal/internal_uuid", buf);
- if (err)
- goto err;
- printf("%s", buf);
- return 0;
- }
-
- err = list_cachesets(cset_dir, list_devs);
- if (err)
- goto err;
-
- return 0;
-
-err:
- printf("bcache_list_cachesets error :%s\n", err);
- return -1;
-}
-
-int bcache_query_devs(NihCommand *command, char *const *args)
-{
- int i;
-
- if (query_brief)
- printf("%-10s%-40s%-40s%-40s\n", "dev name", "disk uuid",
- "server uuid", "cluster uuid");
-
- for (i = 0; args[i] != NULL; i++) {
- char dev_uuid[40];
- struct cache_sb *sb = query_dev(args[i], force_csum,
- !query_brief, uuid_only, dev_uuid);
-
- if (!sb) {
- printf("error opening the superblock for %s\n",
- args[i]);
- return -1;
- }
-
- if (uuid_only) {
- printf("%s\n", dev_uuid);
- } else if (query_brief) {
- char set_uuid_str[40], dev_uuid_str[40];
- char *clus_uuid = (char *)sb->label;
-
- uuid_unparse(sb->user_uuid.b, set_uuid_str);
- uuid_unparse(sb->disk_uuid.b, dev_uuid_str);
- if (!strcmp(clus_uuid, ""))
- clus_uuid = "None";
-
- printf("%-10s%-40s%-40s%-40s\n", args[i],
- dev_uuid_str,
- set_uuid_str,
- clus_uuid);
- }
- free(sb);
- }
-
- return 0;
-}
-
-int bcache_status(NihCommand *command, char *const *args)
-{
- int i, dev_count = 0, seq, cache_count = 0;
- struct cache_sb *seq_sb = NULL;
- char cache_path[MAX_PATH];
- char *dev_names[MAX_DEVS];
- char *dev_uuids[MAX_DEVS];
- char intbuf[4];
- char set_uuid[40];
-
- for (i = 0; args[i] != NULL; i++) {
- struct cache_sb *sb = query_dev(args[i], false, false,
- false, NULL);
-
- if (!sb) {
- printf("Unable to open superblock, bad path\n");
- return -1;
- }
-
- if (!seq_sb || sb->seq > seq) {
- seq = sb->seq;
- seq_sb = sb;
- } else
- free(sb);
- }
-
- if (!seq_sb) {
- printf("Unable to find a superblock\n");
- return -1;
- } else {
- uuid_unparse(seq_sb->user_uuid.b, set_uuid);
- printf("%-50s%-15s%-4s\n", "uuid", "state", "tier");
- }
-
- snprintf(intbuf, 4, "%d", i);
- snprintf(cache_path, MAX_PATH, "%s/%s/%s", cset_dir, set_uuid,
- "cache0");
-
- /*
- * Get a list of all the devices from sysfs first, then
- * compare it to the list we get back from the most up
- * to date superblock. If there are any devices in the superblock
- * that are not in sysfs, print out 'missing'
- */
- while (true) {
- char buf[MAX_PATH];
- int len;
- DIR *cache_dir;
-
- if(((cache_dir = opendir(cache_path)) == NULL) &&
- cache_count > MAX_DEVS)
- break;
-
- if (cache_dir)
- closedir(cache_dir);
-
- if((len = readlink(cache_path, buf, sizeof(buf) - 1)) != -1) {
- struct cache_sb *sb;
- char dev_uuid[40];
- char dev_path[32];
-
- buf[len] = '\0';
- dev_names[dev_count] = dev_name(buf);
- snprintf(dev_path, MAX_PATH, "%s/%s", "/dev",
- dev_names[dev_count]);
- sb = query_dev(dev_path, false, false,
- true, dev_uuid);
- if (!sb) {
- printf("error reading %s\n", dev_path);
- return -1;
- } else
- free(sb);
-
- dev_uuids[dev_count] = strdup(dev_uuid);
- dev_count++;
- }
-
- cache_path[strlen(cache_path) - strlen(intbuf)] = 0;
- cache_count++;
-
- snprintf(intbuf, 4, "%d", cache_count);
- strcat(cache_path, intbuf);
- }
-
- for (i = 0; i < seq_sb->nr_in_set; i++) {
- char uuid_str[40];
- struct cache_member *m = seq_sb->members + i;
- char dev_state[32];
- int j;
-
- uuid_unparse(m->uuid.b, uuid_str);
- snprintf(dev_state, MAX_PATH, "%s",
- cache_state[CACHE_STATE(m)]);
-
- for (j = 0; j < dev_count; j++) {
- if (!strcmp(uuid_str, dev_uuids[j])) {
- break;
- } else if (j == dev_count - 1) {
- if (!strcmp(cache_state[CACHE_STATE(m)], "active"))
- snprintf(dev_state, MAX_PATH, "%s", "missing");
- break;
- }
- }
-
- printf("%-50s%-15s%-4llu\n", uuid_str, dev_state,
- CACHE_TIER(m));
- }
-
- if (seq_sb)
- free(seq_sb);
- for (i = 0; i < dev_count; i++) {
- free(dev_names[i]);
- free(dev_uuids[i]);
- }
-
- return 0;
-}
-
-int bcache_capacity(NihCommand *command, char *const *args)
-{
- char *err = "Must provide a cacheset uuid";
- if(!capacity_uuid)
- goto err;
-
- err = bcache_get_capacity(cset_dir, capacity_uuid, capacity_devs);
- if (err)
- goto err;
-
- return 0;
-
-err:
- printf("bcache_capacity failed with error: %s\n", err);
- return -1;
-
-}
-
-static char *stats_subdir(char* stats_dir)
-{
- char tmp[50] = "/";
- char *err = NULL;
- if(stats_dev_uuid) {
- strcat(tmp, "cache");
- err = find_matching_uuid(stats_dir, tmp, stats_dev_uuid);
- if(err)
- goto err;
- } else if(stats_cache_num) {
- strcat(tmp, "cache");
- strcat(tmp, stats_cache_num);
- } else if (stats_five_min)
- strcat(tmp, "stats_five_minute");
- else if (stats_hour)
- strcat(tmp, "stats_hour");
- else if (stats_day)
- strcat(tmp, "stats_day");
- else if (stats_total)
- strcat(tmp, "stats_total");
- else
- return err;
-
- strcat(stats_dir, tmp);
-
-err:
- return err;
-}
-
-int bcache_stats(NihCommand *command, char *const *args)
-{
- int i;
- char stats_dir[MAX_PATH];
- DIR *dir = NULL;
- struct dirent *ent = NULL;
- char *err = NULL;
- char buf[MAX_PATH];
-
- if (stats_uuid) {
- snprintf(stats_dir, MAX_PATH, "%s/%s", cset_dir, stats_uuid);
- err = stats_subdir(stats_dir);
- if(err)
- goto err;
-
- dir = opendir(stats_dir);
- if (!dir) {
- err = "Failed to open dir";
- goto err;
- }
- } else {
- err = "Must provide a cacheset uuid";
- goto err;
- }
-
- if(stats_list || stats_all) {
- while ((ent = readdir(dir)) != NULL) {
- err = read_stat_dir(dir, stats_dir, ent->d_name, buf);
- if (err)
- goto err;
- if(stats_list)
- printf("%s\n", ent->d_name);
- if(stats_all)
- printf("\t%s\n", buf);
- }
- }
-
- for (i = 0; args[i] != NULL; i++) {
- err = read_stat_dir(dir, stats_dir, args[i], buf);
- if (err)
- goto err;
- printf("%s\n", buf);
- }
-
- closedir(dir);
- return 0;
-
-err:
- closedir(dir);
- printf("bcache_stats error: %s\n", err);
- return -1;
-}
-
-int bcache_set_failed(NihCommand *command, char *const *args)
-{
- char *err = NULL;
-
- if (!dev_failed_uuid) {
- printf("Pass in a dev uuid\n");
- return -1;
- }
-
- err = device_set_failed(dev_failed_uuid);
- if (err) {
- printf("bcache_set_failed_ioctl error: %s\n", err);
- return -1;
- }
-
- return 0;
+#endif
+
+#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 <list of drives>"),
- "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, bcacheadm_format_options, bcacheadm_format},
- {"probe", N_("probe <list of devices>"),
- "Does a blkid_probe on a device",
- N_("Does a blkid_probe on a device"),
- NULL, probe_bcache_options, probe_bcache},
- {"register", N_("register <list of devices>"),
- "Registers a list of devices",
- N_("Registers a list of devices"),
- NULL, bcache_register_options, bcache_register},
- {"unregister", N_("unregister <list of devices>"),
- "Unregisters a list of devices",
- N_("Unregisters a list of devices"),
- NULL, bcache_unregister_options, bcache_unregister},
- {"add-devs", N_("add-devs --tier=# <list of devices>"),
- "Adds a list of devices to a cacheset",
- N_("Adds a list of devices to a cacheset"),
- NULL, bcache_add_device_options, bcache_add_devices},
- {"rm-dev", N_("rm-dev <dev>"),
- "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"),
- NULL, list_cachesets_options, bcache_list_cachesets},
- {"query-devs", N_("query <list of devices>"),
- "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 <list of devices>"),
- "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},
- {"capacity", N_("capacity --set=UUID"),
- "Shows the capacity of the cacheset",
- N_("Shows the capacity of the cacheset"),
- NULL, capacity_options, bcache_capacity},
- {"stats", N_("stats <list of devices>"),
- "List various bcache statistics",
- N_("List various bcache statistics"),
- NULL, stats_options, bcache_stats},
- {"set-failed", N_("set-failed --dev=UUID"),
- "Sets a device to the FAILED state",
- N_("Sets a device to the FAILED state"),
- NULL, set_failed_options, bcache_set_failed},
+ CMD(format, N_("<list of devices>"),
+ "Create a new bcache volume from one or more devices",
+ N_("format drive[s] for bcache")),
+
+ CMD(assemble, N_("<devices>"),
+ "Assembles one or more devices into a bcache volume",
+ N_("Registers a list of devices")),
+ CMD(incremental, N_("<device"),
+ "Incremental assemble bcache volumes",
+ N_("Incrementally registers a single device")),
+
+ CMD(run, N_("<volume>"),
+ "Start a partially assembled volume",
+ N_("Registers a list of devices")),
+ CMD(stop, N_("<volume>"),
+ "Stops a running bcache volume",
+ N_("Unregisters a list of devices")),
+ CMD(add, N_("<volume> <devices>"),
+ "Adds a list of devices to a volume",
+ N_("Adds a list of devices to a volume")),
+ CMD(readd, N_("<volume> <devices>"),
+ "Adds previously used members of a volume",
+ N_("Adds a list of devices to a volume")),
+ CMD(remove, N_("<volume> <devices>"),
+ "Removes a device from its volume",
+ N_("Removes a device from its volume")),
+ CMD(fail, N_("<volume> <devices>"),
+ "Sets a device to the FAILED state",
+ N_("Sets a device to the FAILED state")),
+
+#if 0
+ CMD(modify, N_("<options>"),
+ "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 <list of devices>"),
+ "Gives info about the superblock of a list of devices",
+ N_("show superblock on each of the listed drive")),
+ CMD(status, N_("status <list of devices>"),
+ "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();
+++ /dev/null
-#ifndef _BCACHEADM_H
-#define _BCACHEADM_H
-
-extern NihOption bcacheadm_format_options[];
-int bcacheadm_format(NihCommand *, char * const *);
-
-#endif /* _BCACHEADM_H */