mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-12-11 00:00:12 +03:00
bcacheadm add list-cachesets and query-devs
Change-Id: Ie2bc7ba8293d1d493c0a215119456e4bb9e659aa Signed-off-by: Jacob Malevich <jam@daterainc.com>
This commit is contained in:
parent
82ac2a0338
commit
bc69c8fe04
155
bcache.c
155
bcache.c
@ -15,12 +15,17 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <uuid/uuid.h>
|
#include <uuid/uuid.h>
|
||||||
#include <blkid.h>
|
#include <blkid.h>
|
||||||
|
|
||||||
#include "bcache.h"
|
#include "bcache.h"
|
||||||
|
|
||||||
|
#define __KERNEL__
|
||||||
|
#include <linux/bcache-ioctl.h>
|
||||||
|
#undef __KERNEL__
|
||||||
|
|
||||||
const char * const cache_state[] = {
|
const char * const cache_state[] = {
|
||||||
"active",
|
"active",
|
||||||
"ro",
|
"ro",
|
||||||
@ -802,7 +807,7 @@ void show_super_backingdev(struct cache_sb *sb, bool force_csum)
|
|||||||
bdev_state[BDEV_STATE(sb)]);
|
bdev_state[BDEV_STATE(sb)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_cache_member(struct cache_sb *sb, unsigned i)
|
static void show_cache_member(struct cache_sb *sb, unsigned i)
|
||||||
{
|
{
|
||||||
struct cache_member *m = ((struct cache_member *) sb->d) + i;
|
struct cache_member *m = ((struct cache_member *) sb->d) + i;
|
||||||
|
|
||||||
@ -845,3 +850,151 @@ void show_super_cache(struct cache_sb *sb, bool force_csum)
|
|||||||
|
|
||||||
show_cache_member(sb, sb->nr_this_dev);
|
show_cache_member(sb, sb->nr_this_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void query_dev(char *dev, bool force_csum)
|
||||||
|
{
|
||||||
|
struct cache_sb sb_stack, *sb = &sb_stack;
|
||||||
|
size_t bytes = sizeof(*sb);
|
||||||
|
|
||||||
|
int fd = open(dev, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
printf("Can't open dev %s: %s\n", dev, strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pread(fd, sb, bytes, SB_START) != bytes) {
|
||||||
|
fprintf(stderr, "Couldn't read\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sb->keys) {
|
||||||
|
bytes = sizeof(*sb) + sb->keys * sizeof(uint64_t);
|
||||||
|
sb = malloc(bytes);
|
||||||
|
|
||||||
|
if (pread(fd, sb, bytes, SB_START) != bytes) {
|
||||||
|
fprintf(stderr, "Couldn't read\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SB_IS_BDEV(sb))
|
||||||
|
show_super_cache(sb, force_csum);
|
||||||
|
else
|
||||||
|
show_super_backingdev(sb, force_csum);
|
||||||
|
}
|
||||||
|
|
||||||
|
int list_cachesets(char *cset_dir)
|
||||||
|
{
|
||||||
|
struct dirent *ent;
|
||||||
|
DIR *dir = opendir(cset_dir);
|
||||||
|
if (!dir) {
|
||||||
|
fprintf(stderr, "Failed to open dir %s\n", cset_dir);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((ent = readdir(dir)) != NULL) {
|
||||||
|
struct stat statbuf;
|
||||||
|
char entry[100];
|
||||||
|
|
||||||
|
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
strcpy(entry, cset_dir);
|
||||||
|
strcat(entry, "/");
|
||||||
|
strcat(entry, ent->d_name);
|
||||||
|
if(stat(entry, &statbuf) == -1) {
|
||||||
|
fprintf(stderr, "Failed to stat %s\n", entry);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (S_ISDIR(statbuf.st_mode)) {
|
||||||
|
printf("%s\n", ent->d_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *parse_array_to_list(char *const *args)
|
||||||
|
{
|
||||||
|
int i, len = 0;
|
||||||
|
char *space = " ";
|
||||||
|
for(i=0; args[i] != NULL; i++) {
|
||||||
|
len+=strlen(args[i]) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *arg_list = (char*)malloc(sizeof(char)*len);
|
||||||
|
strcpy(arg_list, args[0]);
|
||||||
|
strcat(arg_list, space);
|
||||||
|
|
||||||
|
for(i=1; args[i] != NULL; i++) {
|
||||||
|
strcat(arg_list, args[i]);
|
||||||
|
strcat(arg_list, space);
|
||||||
|
}
|
||||||
|
|
||||||
|
return arg_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
int register_bcache(char *devs)
|
||||||
|
{
|
||||||
|
int ret, bcachefd;
|
||||||
|
|
||||||
|
bcachefd = open("/dev/bcache", O_RDWR);
|
||||||
|
if (bcachefd < 0) {
|
||||||
|
perror("Can't open bcache device");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, devs);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "ioctl error %d", ret);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int probe(char *dev, int udev)
|
||||||
|
{
|
||||||
|
struct cache_sb sb;
|
||||||
|
char uuid[40];
|
||||||
|
blkid_probe pr;
|
||||||
|
|
||||||
|
int fd = open(dev, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!(pr = blkid_new_probe()))
|
||||||
|
return -1;
|
||||||
|
if (blkid_probe_set_device(pr, fd, 0, 0))
|
||||||
|
return -1;
|
||||||
|
/* probe partitions too */
|
||||||
|
if (blkid_probe_enable_partitions(pr, true))
|
||||||
|
return -1;
|
||||||
|
/* bail if anything was found
|
||||||
|
* probe-bcache isn't needed once blkid recognizes bcache */
|
||||||
|
if (!blkid_do_probe(pr)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (memcmp(&sb.magic, &BCACHE_MAGIC, sizeof(sb.magic)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uuid_unparse(sb.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
9
bcache.h
9
bcache.h
@ -54,9 +54,16 @@ unsigned get_blocksize(const char *);
|
|||||||
long strtoul_or_die(const char *, size_t, const char *);
|
long strtoul_or_die(const char *, size_t, const char *);
|
||||||
|
|
||||||
void show_super_backingdev(struct cache_sb *, bool);
|
void show_super_backingdev(struct cache_sb *, bool);
|
||||||
void show_cache_member(struct cache_sb *, unsigned);
|
|
||||||
void show_super_cache(struct cache_sb *, bool);
|
void show_super_cache(struct cache_sb *, bool);
|
||||||
|
|
||||||
|
void query_dev(char *dev, bool force_csum);
|
||||||
|
int list_cachesets(char *cset_dir);
|
||||||
|
char *parse_array_to_list(char *const *args);
|
||||||
|
int register_bcache();
|
||||||
|
int probe(char *dev, int udev);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define csum_set(i, type) \
|
#define csum_set(i, type) \
|
||||||
({ \
|
({ \
|
||||||
void *start = ((void *) (i)) + sizeof(uint64_t); \
|
void *start = ((void *) (i)) + sizeof(uint64_t); \
|
||||||
|
|||||||
133
bcacheadm.c
133
bcacheadm.c
@ -28,9 +28,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <uuid/uuid.h>
|
#include <uuid/uuid.h>
|
||||||
#include <bcache.h> //libbcache
|
#include <bcache.h> //libbcache
|
||||||
#define __KERNEL__
|
|
||||||
#include <linux/bcache-ioctl.h>
|
|
||||||
#undef __KERNEL__
|
|
||||||
|
|
||||||
#define PACKAGE_NAME "bcacheadm"
|
#define PACKAGE_NAME "bcacheadm"
|
||||||
#define PACKAGE_VERSION "1.0"
|
#define PACKAGE_VERSION "1.0"
|
||||||
@ -77,14 +74,12 @@ enum long_opts {
|
|||||||
|
|
||||||
/* super-show globals */
|
/* super-show globals */
|
||||||
bool force_csum = false;
|
bool force_csum = false;
|
||||||
char *show_dev = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
/* probe globals */
|
/* probe globals */
|
||||||
bool udev = false;
|
bool udev = false;
|
||||||
|
|
||||||
/* register globals */
|
/* list globals */
|
||||||
int bcachefd;
|
char *cset_dir = "/sys/fs/bcache";
|
||||||
|
|
||||||
/* make-bcache option setters */
|
/* make-bcache option setters */
|
||||||
static int set_CACHE_SET_UUID(NihOption *option, const char *arg)
|
static int set_CACHE_SET_UUID(NihOption *option, const char *arg)
|
||||||
@ -178,7 +173,6 @@ static NihOption make_bcache_options[] = {
|
|||||||
{'t', "tier", N_("tier of subsequent devices"), NULL,NULL, &tier, 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},
|
{'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},
|
{'o', "data_offset", N_("data offset in sectors"), NULL,NULL, &data_offset, NULL},
|
||||||
{'h', "help", N_("display this help and exit"), NULL,NULL, NULL, NULL},
|
|
||||||
|
|
||||||
{0, "cset-uuid", N_("UUID for the cache set"), NULL, NULL, NULL, set_CACHE_SET_UUID },
|
{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, "csum-type", N_("One of (none|crc32c|crc64)"), NULL, NULL, NULL, set_CSUM_TYPE },
|
||||||
@ -193,13 +187,6 @@ static NihOption make_bcache_options[] = {
|
|||||||
NIH_OPTION_LAST
|
NIH_OPTION_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
static NihOption super_show_options[] = {
|
|
||||||
{'f', "force_csum", N_("force_csum"), NULL, NULL, &force_csum, NULL},
|
|
||||||
{0, "dev", N_("dev"), NULL, NULL, &show_dev, NULL},
|
|
||||||
NIH_OPTION_LAST
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static NihOption probe_bcache_options[] = {
|
static NihOption probe_bcache_options[] = {
|
||||||
{'o', "udev", N_("udev"), NULL, NULL, NULL, set_udev},
|
{'o', "udev", N_("udev"), NULL, NULL, NULL, set_udev},
|
||||||
NIH_OPTION_LAST
|
NIH_OPTION_LAST
|
||||||
@ -209,6 +196,16 @@ static NihOption bcache_register_options[] = {
|
|||||||
NIH_OPTION_LAST
|
NIH_OPTION_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static NihOption query_devs_options[] = {
|
||||||
|
{'f', "force_csum", N_("force_csum"), NULL, NULL, &force_csum, NULL},
|
||||||
|
NIH_OPTION_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
static NihOption list_cachesets_options[] = {
|
||||||
|
{'d', "dir", N_("directory"), NULL, NULL, &cset_dir, NULL},
|
||||||
|
NIH_OPTION_LAST
|
||||||
|
};
|
||||||
|
|
||||||
static NihOption options[] = {
|
static NihOption options[] = {
|
||||||
NIH_OPTION_LAST
|
NIH_OPTION_LAST
|
||||||
};
|
};
|
||||||
@ -280,80 +277,12 @@ int make_bcache (NihCommand *command, char *const *args)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int super_show (NihCommand *command, char *const *args)
|
|
||||||
{
|
|
||||||
struct cache_sb sb_stack, *sb = &sb_stack;
|
|
||||||
size_t bytes = sizeof(*sb);
|
|
||||||
|
|
||||||
int fd = open(show_dev, O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
printf("Can't open dev %s: %s\n", show_dev, strerror(errno));
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pread(fd, sb, bytes, SB_START) != bytes) {
|
|
||||||
fprintf(stderr, "Couldn't read\n");
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sb->keys) {
|
|
||||||
bytes = sizeof(*sb) + sb->keys * sizeof(uint64_t);
|
|
||||||
sb = malloc(bytes);
|
|
||||||
|
|
||||||
if (pread(fd, sb, bytes, SB_START) != bytes) {
|
|
||||||
fprintf(stderr, "Couldn't read\n");
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SB_IS_BDEV(sb))
|
|
||||||
show_super_cache(sb, force_csum);
|
|
||||||
else
|
|
||||||
show_super_backingdev(sb, force_csum);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int probe_bcache (NihCommand *command, char *const *args)
|
int probe_bcache (NihCommand *command, char *const *args)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct cache_sb sb;
|
|
||||||
char uuid[40];
|
|
||||||
blkid_probe pr;
|
|
||||||
|
|
||||||
for (i = 0; args[i]!=NULL; i++) {
|
for (i = 0; args[i] != NULL; i++) {
|
||||||
int fd = open(args[i], O_RDONLY);
|
probe(args[i], udev);
|
||||||
if (fd == -1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(pr = blkid_new_probe()))
|
|
||||||
continue;
|
|
||||||
if (blkid_probe_set_device(pr, fd, 0, 0))
|
|
||||||
continue;
|
|
||||||
/* probe partitions too */
|
|
||||||
if (blkid_probe_enable_partitions(pr, true))
|
|
||||||
continue;
|
|
||||||
/* bail if anything was found
|
|
||||||
* probe-bcache isn't needed once blkid recognizes bcache */
|
|
||||||
if (!blkid_do_probe(pr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (memcmp(&sb.magic, &BCACHE_MAGIC, sizeof(sb.magic)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
uuid_unparse(sb.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;
|
return 0;
|
||||||
@ -362,26 +291,36 @@ int probe_bcache (NihCommand *command, char *const *args)
|
|||||||
int bcache_register (NihCommand *command, char *const *args)
|
int bcache_register (NihCommand *command, char *const *args)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
char *arg_list = parse_array_to_list(args);
|
||||||
|
|
||||||
bcachefd = open("/dev/bcache", O_RDWR);
|
if(arg_list) {
|
||||||
if (bcachefd < 0) {
|
ret = register_bcache(arg_list);
|
||||||
perror("Can't open bcache device");
|
free(arg_list);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, args);
|
return ret;
|
||||||
if (ret < 0) {
|
}
|
||||||
fprintf(stderr, "ioctl error %d", ret);
|
|
||||||
exit(EXIT_FAILURE);
|
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++) {
|
||||||
|
query_dev(args[i], false);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static NihCommand commands[] = {
|
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, make_bcache_options, make_bcache},
|
{"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, make_bcache_options, make_bcache},
|
||||||
{"show-sb", N_("show-sb <list of drives>"), "View a superblock on one or a list of bcache formated devices", N_("show superblock on each of the listed drive"), NULL, super_show_options, super_show},
|
{"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},
|
||||||
{"probe", N_("probe <list of drives>"), NULL, NULL, 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},
|
||||||
{"register", N_("register <list of devices>"), NULL, NULL, 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 <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},
|
||||||
NIH_COMMAND_LAST
|
NIH_COMMAND_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user