This commit is contained in:
Kent Overstreet 2015-05-08 18:13:38 -07:00
parent da1fff8700
commit fb22ceda3e
13 changed files with 729 additions and 985 deletions

View File

@ -25,7 +25,8 @@ bcache.o: CFLAGS += `pkg-config --cflags uuid blkid`
bcacheadm.o: CFLAGS += `pkg-config --cflags uuid blkid libnih` bcacheadm.o: CFLAGS += `pkg-config --cflags uuid blkid libnih`
bcacheadm: LDLIBS += `pkg-config --libs 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.o: CFLAGS += `pkg-config --cflags uuid blkid`
probe-bcache: LDLIBS += `pkg-config --libs uuid blkid` probe-bcache: LDLIBS += `pkg-config --libs uuid blkid`

408
bcache.c
View File

@ -852,55 +852,6 @@ char *dev_name(const char *ugly_path) {
return strdup(buf); 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) char *find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uuid)
{ {
/* Do a query-dev --uuid only to get the uuid /* Do a query-dev --uuid only to get the uuid
@ -973,360 +924,21 @@ char *find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uu
return err; return err;
} }
char *list_cachesets(char *cset_dir, bool list_devs) int bcachectl_open(void)
{ {
struct dirent *ent; int fd = open("/dev/bcache-ctl", O_RDWR);
DIR *dir; if (fd < 0)
char *err = NULL; die("Can't open bcache device: %s", strerror(errno));
dir = opendir(cset_dir); return fd;
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) unsigned nr_args(char *const *args)
{ {
int ret, bcachefd; unsigned i;
char *err = NULL;
bcachefd = open("/dev/bcache", O_RDWR); for (i = 0; args[i]; i++)
if (bcachefd < 0) { ;
err = "Can't open bcache device";
goto err;
}
ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, devs); return i;
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)
{
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;
}
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;
}
char *bcache_get_capacity(const char *cset_dir, const char *capacity_uuid,
bool show_devs)
{
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);
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)");
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;
} }

View File

@ -7,6 +7,7 @@
#ifndef _BCACHE_H #ifndef _BCACHE_H
#define _BCACHE_H #define _BCACHE_H
#include <stdint.h>
#include <linux/bcache.h> #include <linux/bcache.h>
#include <dirent.h> #include <dirent.h>
@ -87,18 +88,13 @@ enum sysfs_attr sysfs_attr_type(const char *attr);
void sysfs_attr_list(); void sysfs_attr_list();
struct cache_sb *query_dev(char *, bool, bool, bool, char *dev_uuid); 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 *parse_array_to_list(char *const *);
char *register_bcache(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 *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 *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) \ #define csum_set(i, type) \
({ \ ({ \

61
bcacheadm-assemble.c Normal file
View File

@ -0,0 +1,61 @@
#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;
}

10
bcacheadm-assemble.h Normal file
View File

@ -0,0 +1,10 @@
#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 */

View File

@ -35,7 +35,7 @@
#include <nih/option.h> #include <nih/option.h>
#include "bcache.h" #include "bcache.h"
#include "bcacheadm.h" #include "bcacheadm-format.h"
static struct cache_opts { static struct cache_opts {
int fd; int fd;
@ -180,7 +180,7 @@ static int set_cache_mode(NihOption *option, const char *arg)
return 0; return 0;
} }
NihOption bcacheadm_format_options[] = { NihOption opts_format[] = {
// { int shortoption, char *longoption, char *help, NihOptionGroup, char *argname, void *value, NihOptionSetter} // { int shortoption, char *longoption, char *help, NihOptionGroup, char *argname, void *value, NihOptionSetter}
{ 'C', "cache", N_("Format a cache device"), { 'C', "cache", N_("Format a cache device"),
@ -259,13 +259,15 @@ static unsigned ilog2(uint64_t n)
return ret; return ret;
} }
int bcacheadm_format(NihCommand *command, char *const *args) static int format_v0(void)
{
return 0;
}
static int format_v1(void)
{ {
struct cache_sb *cache_set_sb; struct cache_sb *cache_set_sb;
if (!nr_cache_devices && !nr_backing_devices)
die("Please supply a device");
if (!block_size) { if (!block_size) {
for (struct cache_opts *i = cache_devices; for (struct cache_opts *i = cache_devices;
i < cache_devices + nr_cache_devices; i < cache_devices + nr_cache_devices;
@ -403,3 +405,11 @@ int bcacheadm_format(NihCommand *command, char *const *args)
return 0; 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();
}

7
bcacheadm-format.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _BCACHEADM_FORMAT_H
#define _BCACHEADM_FORMAT_H
extern NihOption opts_format[];
int cmd_format(NihCommand *, char * const *);
#endif /* _BCACHEADM_FORMAT_H */

361
bcacheadm-query.c Normal file
View File

@ -0,0 +1,361 @@
#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;
}

13
bcacheadm-query.h Normal file
View File

@ -0,0 +1,13 @@
#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 */

153
bcacheadm-run.c Normal file
View File

@ -0,0 +1,153 @@
#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;
}

22
bcacheadm-run.h Normal file
View File

@ -0,0 +1,22 @@
#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 */

View File

@ -29,88 +29,20 @@
#include <dirent.h> #include <dirent.h>
#include "bcache.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_NAME "bcacheadm"
#define PACKAGE_VERSION "1.0" #define PACKAGE_VERSION "1.0"
#define PACKAGE_BUGREPORT "bugreport" #define PACKAGE_BUGREPORT "linux-bcache@vger.kernel.org"
/* rm-dev globals */ #if 0
bool force_remove = false; static bool modify_list_attrs = false;
/* Modify globals */
bool modify_list_attrs = false;
static const char *modify_set_uuid = NULL; static const char *modify_set_uuid = NULL;
static const char *modify_dev_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[] = { static NihOption bcache_modify_options[] = {
{'l', "list", N_("list attributes"), NULL, NULL, &modify_list_attrs, NULL}, {'l', "list", N_("list attributes"), NULL, NULL, &modify_list_attrs, NULL},
{'u', "set", N_("cacheset uuid"), NULL, "UUID", &modify_set_uuid, NULL}, {'u', "set", N_("cacheset uuid"), NULL, "UUID", &modify_set_uuid, NULL},
@ -118,127 +50,6 @@ static NihOption bcache_modify_options[] = {
NIH_OPTION_LAST 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) int bcache_modify(NihCommand *command, char *const *args)
{ {
char *err; char *err;
@ -312,386 +123,80 @@ err:
close(fd); close(fd);
return 0; return 0;
} }
#endif
int bcache_list_cachesets(NihCommand *command, char *const *args) #define CMD(_command, _usage, _synopsis, _help) \
{ { \
char *err = NULL; .command = #_command, \
.usage = _usage, \
if (internal_uuid) { .synopsis = _synopsis, \
char uuid_path[MAX_PATH]; .help = _help, \
DIR *uuid_dir; .group = NULL, \
char buf[MAX_PATH]; .options = opts_##_command, \
.action = cmd_##_command, \
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;
} }
static NihCommand commands[] = { static NihCommand commands[] = {
{"format", N_("format <list of drives>"), CMD(format, N_("<list of devices>"),
"Format one or a list of devices with bcache datastructures." "Create a new bcache volume from one or more devices",
" You need to do this before you create a volume", N_("format drive[s] for bcache")),
N_("format drive[s] with bcache"),
NULL, bcacheadm_format_options, bcacheadm_format}, CMD(assemble, N_("<devices>"),
{"probe", N_("probe <list of devices>"), "Assembles one or more devices into a bcache volume",
"Does a blkid_probe on a device", N_("Registers a list of devices")),
N_("Does a blkid_probe on a device"), CMD(incremental, N_("<device"),
NULL, probe_bcache_options, probe_bcache}, "Incremental assemble bcache volumes",
{"register", N_("register <list of devices>"), N_("Incrementally registers a single device")),
"Registers a list of devices",
N_("Registers a list of devices"), CMD(run, N_("<volume>"),
NULL, bcache_register_options, bcache_register}, "Start a partially assembled volume",
{"unregister", N_("unregister <list of devices>"), N_("Registers a list of devices")),
"Unregisters a list of devices", CMD(stop, N_("<volume>"),
N_("Unregisters a list of devices"), "Stops a running bcache volume",
NULL, bcache_unregister_options, bcache_unregister}, N_("Unregisters a list of devices")),
{"add-devs", N_("add-devs --tier=# <list of devices>"), CMD(add, N_("<volume> <devices>"),
"Adds a list of devices to a cacheset", "Adds a list of devices to a volume",
N_("Adds a list of devices to a cacheset"), N_("Adds a list of devices to a volume")),
NULL, bcache_add_device_options, bcache_add_devices}, CMD(readd, N_("<volume> <devices>"),
{"rm-dev", N_("rm-dev <dev>"), "Adds previously used members of a volume",
"Removes a device from its cacheset", N_("Adds a list of devices to a volume")),
N_("Removes a device from its cacheset"), CMD(remove, N_("<volume> <devices>"),
NULL, bcache_rm_device_options, bcache_rm_device}, "Removes a device from its volume",
{"modify", N_("modify --set=UUID (dev=UUID) name value"), N_("Removes a device from its volume")),
"Modifies attributes related to the cacheset", CMD(fail, N_("<volume> <devices>"),
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", "Sets a device to the FAILED state",
N_("Sets a device to the FAILED state"), N_("Sets a device to the FAILED state")),
NULL, set_failed_options, bcache_set_failed},
#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 NIH_COMMAND_LAST
}; };
static NihOption options[] = {
NIH_OPTION_LAST
};
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int ret = 0; nih_main_init(argv[0]);
nih_main_init (argv[0]); nih_option_set_synopsis(_("Manage bcache devices"));
nih_option_set_help( _("Helps you manage bcache devices"));
nih_option_set_synopsis (_("Manage bcache devices")); int ret = nih_command_parser(NULL, argc, argv, options, commands);
nih_option_set_help (
_("Helps you manage bcache devices"));
ret = nih_command_parser (NULL, argc, argv, options, commands);
if (ret < 0) if (ret < 0)
exit (1); exit(EXIT_FAILURE);
nih_signal_reset(); nih_signal_reset();

View File

@ -1,7 +0,0 @@
#ifndef _BCACHEADM_H
#define _BCACHEADM_H
extern NihOption bcacheadm_format_options[];
int bcacheadm_format(NihCommand *, char * const *);
#endif /* _BCACHEADM_H */