mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-22 00:00:03 +03:00
Add bcachefs fs usage
This commit is contained in:
parent
14117dcdfb
commit
30caf69540
@ -42,8 +42,7 @@ static void usage(void)
|
||||
" stop Stop a running filesystem\n"
|
||||
"\n"
|
||||
"Commands for managing a running filesystem:\n"
|
||||
" fs show Show various information about a filesystem\n"
|
||||
" fs set Modify filesystem options\n"
|
||||
" fs usage Show disk usage\n"
|
||||
"\n"
|
||||
"Commands for managing devices within a running filesystem:\n"
|
||||
" device add Add a new device to an existing filesystem\n"
|
||||
@ -90,10 +89,8 @@ static int fs_cmds(int argc, char *argv[])
|
||||
{
|
||||
char *cmd = pop_cmd(&argc, argv);
|
||||
|
||||
if (!strcmp(cmd, "show"))
|
||||
return cmd_fs_show(argc, argv);
|
||||
if (!strcmp(cmd, "set"))
|
||||
return cmd_fs_set(argc, argv);
|
||||
if (!strcmp(cmd, "usage"))
|
||||
return cmd_fs_usage(argc, argv);
|
||||
|
||||
usage();
|
||||
return 0;
|
||||
|
146
cmd_fs.c
146
cmd_fs.c
@ -1,43 +1,125 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "libbcachefs/bcachefs_ioctl.h"
|
||||
#include "libbcachefs/opts.h"
|
||||
|
||||
#include "cmds.h"
|
||||
|
||||
struct bcache_fs {
|
||||
/* options... */
|
||||
|
||||
u64 capacity;
|
||||
|
||||
/* XXX: dirty != used, it doesn't count metadata */
|
||||
u64 bytes_dirty;
|
||||
};
|
||||
|
||||
#if 0
|
||||
static struct bcache_fs fill_fs(struct bcache_handle fs)
|
||||
static inline int printf_pad(unsigned pad, const char * fmt, ...)
|
||||
{
|
||||
return (struct bcache_fs) {
|
||||
};
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, fmt);
|
||||
ret = vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
while (ret++ < pad)
|
||||
putchar(' ');
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int cmd_fs_show(int argc, char *argv[])
|
||||
static void print_fs_usage(const char *path, enum units units)
|
||||
{
|
||||
if (argc != 2)
|
||||
die("Please supply a filesystem");
|
||||
unsigned i, j, nr_devices = 4;
|
||||
struct bcache_handle fs = bcache_fs_open(path);
|
||||
struct bch_ioctl_usage *u = NULL;
|
||||
char uuid[40];
|
||||
|
||||
#if 0
|
||||
struct bcache_handle fs = bcache_fs_open(argv[1]);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_fs_set(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
die("Please supply a filesystem");
|
||||
|
||||
#if 0
|
||||
struct bcache_handle fs = bcache_fs_open(argv[1]);
|
||||
#endif
|
||||
while (1) {
|
||||
u = xrealloc(u, sizeof(*u) + sizeof(u->devs[0]) * nr_devices);
|
||||
u->nr_devices = nr_devices;
|
||||
|
||||
if (!ioctl(fs.ioctl_fd, BCH_IOCTL_USAGE, u))
|
||||
break;
|
||||
if (errno != ENOSPC)
|
||||
die("BCH_IOCTL_USAGE error: %m");
|
||||
nr_devices *= 2;
|
||||
}
|
||||
|
||||
uuid_unparse(fs.uuid.b, uuid);
|
||||
printf("Filesystem %s:\n", uuid);
|
||||
|
||||
printf("%-20s%12s\n", "Size:", pr_units(u->fs.capacity, units));
|
||||
printf("%-20s%12s\n", "Used:", pr_units(u->fs.used, units));
|
||||
|
||||
printf("%-20s%12s%12s%12s%12s\n",
|
||||
"By replicas:", "1x", "2x", "3x", "4x");
|
||||
|
||||
for (j = BCH_DATA_BTREE; j < BCH_DATA_NR; j++) {
|
||||
printf_pad(20, " %s:", bch2_data_types[j]);
|
||||
|
||||
for (i = 0; i < BCH_REPLICAS_MAX; i++)
|
||||
printf("%12s", pr_units(u->fs.sectors[j][i], units));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf_pad(20, " %s:", "reserved");
|
||||
for (i = 0; i < BCH_REPLICAS_MAX; i++)
|
||||
printf("%12s", pr_units(u->fs.persistent_reserved[i], units));
|
||||
printf("\n");
|
||||
|
||||
printf("%-20s%12s\n", " online reserved:", pr_units(u->fs.online_reserved, units));
|
||||
|
||||
for (i = 0; i < u->nr_devices; i++) {
|
||||
struct bch_ioctl_dev_usage *d = u->devs + i;
|
||||
char *name = NULL;
|
||||
|
||||
if (!d->alive)
|
||||
continue;
|
||||
|
||||
printf("\n");
|
||||
printf_pad(20, "Device %u usage:", i);
|
||||
name = !d->dev ? strdup("(offline)")
|
||||
: dev_to_path(d->dev)
|
||||
?: strdup("(device not found)");
|
||||
|
||||
printf("%24s%12s\n", name, bch2_dev_state[d->state]);
|
||||
free(name);
|
||||
|
||||
printf("%-20s%12s%12s%12s\n",
|
||||
"", "data", "buckets", "fragmented");
|
||||
|
||||
for (j = BCH_DATA_SB; j < BCH_DATA_NR; j++) {
|
||||
u64 frag = max((s64) d->buckets[j] * d->bucket_size -
|
||||
(s64) d->sectors[j], 0LL);
|
||||
|
||||
printf_pad(20, " %s:", bch2_data_types[j]);
|
||||
printf("%12s%12llu%12s\n",
|
||||
pr_units(d->sectors[j], units),
|
||||
d->buckets[j],
|
||||
pr_units(frag, units));
|
||||
}
|
||||
}
|
||||
|
||||
free(u);
|
||||
bcache_fs_close(fs);
|
||||
}
|
||||
|
||||
int cmd_fs_usage(int argc, char *argv[])
|
||||
{
|
||||
enum units units = BYTES;
|
||||
unsigned i;
|
||||
int opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, "h")) != -1)
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
units = HUMAN_READABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (argc - optind < 1) {
|
||||
print_fs_usage(".", units);
|
||||
} else {
|
||||
for (i = optind; i < argc; i++)
|
||||
print_fs_usage(argv[i], units);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
3
cmds.h
3
cmds.h
@ -17,8 +17,7 @@ int cmd_incremental(int argc, char *argv[]);
|
||||
int cmd_run(int argc, char *argv[]);
|
||||
int cmd_stop(int argc, char *argv[]);
|
||||
|
||||
int cmd_fs_show(int argc, char *argv[]);
|
||||
int cmd_fs_set(int argc, char *argv[]);
|
||||
int cmd_fs_usage(int argc, char *argv[]);
|
||||
|
||||
int cmd_device_add(int argc, char *argv[]);
|
||||
int cmd_device_remove(int argc, char *argv[]);
|
||||
|
67
tools-util.c
67
tools-util.c
@ -10,6 +10,7 @@
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -70,6 +71,15 @@ void *xmalloc(size_t size)
|
||||
return p;
|
||||
}
|
||||
|
||||
void *xrealloc(void *p, size_t size)
|
||||
{
|
||||
p = realloc(p, size);
|
||||
if (!p)
|
||||
die("insufficient memory");
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void xpread(int fd, void *buf, size_t count, off_t offset)
|
||||
{
|
||||
ssize_t r = pread(fd, buf, count, offset);
|
||||
@ -104,27 +114,34 @@ struct stat xfstat(int fd)
|
||||
|
||||
/* Integer stuff: */
|
||||
|
||||
struct units_buf __pr_units(u64 v, enum units units)
|
||||
struct units_buf __pr_units(s64 _v, enum units units)
|
||||
{
|
||||
struct units_buf ret;
|
||||
char *out = ret.b, *end = out + sizeof(ret.b);
|
||||
u64 v = _v;
|
||||
|
||||
if (_v < 0) {
|
||||
out += scnprintf(out, end - out, "-");
|
||||
v = -_v;
|
||||
}
|
||||
|
||||
switch (units) {
|
||||
case BYTES:
|
||||
snprintf(ret.b, sizeof(ret.b), "%llu", v << 9);
|
||||
snprintf(out, end - out, "%llu", v << 9);
|
||||
break;
|
||||
case SECTORS:
|
||||
snprintf(ret.b, sizeof(ret.b), "%llu", v);
|
||||
snprintf(out, end - out, "%llu", v);
|
||||
break;
|
||||
case HUMAN_READABLE:
|
||||
v <<= 9;
|
||||
|
||||
if (v >= 1024) {
|
||||
int exp = log(v) / log(1024);
|
||||
snprintf(ret.b, sizeof(ret.b), "%.1f%c",
|
||||
snprintf(out, end - out, "%.1f%c",
|
||||
v / pow(1024, exp),
|
||||
"KMGTPE"[exp-1]);
|
||||
} else {
|
||||
snprintf(ret.b, sizeof(ret.b), "%llu", v);
|
||||
snprintf(out, end - out, "%llu", v);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -255,12 +272,17 @@ int bcachectl_open(void)
|
||||
|
||||
#define SYSFS_BASE "/sys/fs/bcachefs/"
|
||||
|
||||
void bcache_fs_close(struct bcache_handle fs)
|
||||
{
|
||||
close(fs.ioctl_fd);
|
||||
close(fs.sysfs_fd);
|
||||
}
|
||||
|
||||
struct bcache_handle bcache_fs_open(const char *path)
|
||||
{
|
||||
struct bcache_handle ret;
|
||||
uuid_t tmp;
|
||||
|
||||
if (!uuid_parse(path, tmp)) {
|
||||
if (!uuid_parse(path, ret.uuid.b)) {
|
||||
/* It's a UUID, look it up in sysfs: */
|
||||
char *sysfs = mprintf("%s%s", SYSFS_BASE, path);
|
||||
ret.sysfs_fd = xopen(sysfs, O_RDONLY);
|
||||
@ -279,6 +301,8 @@ struct bcache_handle bcache_fs_open(const char *path)
|
||||
struct bch_ioctl_query_uuid uuid;
|
||||
xioctl(ret.ioctl_fd, BCH_IOCTL_QUERY_UUID, &uuid);
|
||||
|
||||
ret.uuid = uuid.uuid;
|
||||
|
||||
char uuid_str[40];
|
||||
uuid_unparse(uuid.uuid.b, uuid_str);
|
||||
|
||||
@ -562,4 +586,33 @@ u32 crc32c(u32 crc, const void *buf, size_t size)
|
||||
|
||||
#endif /* HAVE_WORKING_IFUNC */
|
||||
|
||||
char *dev_to_path(dev_t dev)
|
||||
{
|
||||
char *line = NULL, *name = NULL, *path = NULL;
|
||||
size_t n = 0;
|
||||
|
||||
FILE *f = fopen("/proc/partitions", "r");
|
||||
if (!f)
|
||||
die("error opening /proc/partitions: %m");
|
||||
|
||||
while (getline(&line, &n, f) != -1) {
|
||||
unsigned ma, mi;
|
||||
u64 sectors;
|
||||
|
||||
name = realloc(name, n + 1);
|
||||
|
||||
if (sscanf(line, " %u %u %llu %s", &ma, &mi, §ors, name) == 4 &&
|
||||
ma == major(dev) && mi == minor(dev)) {
|
||||
path = mprintf("/dev/%s", name);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
free(line);
|
||||
free(name);
|
||||
return path;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -15,12 +15,14 @@
|
||||
#include <linux/log2.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/uuid.h>
|
||||
#include "ccan/darray/darray.h"
|
||||
|
||||
void die(const char *, ...);
|
||||
char *mprintf(const char *, ...);
|
||||
void *xcalloc(size_t, size_t);
|
||||
void *xmalloc(size_t);
|
||||
void *xrealloc(void *, size_t);
|
||||
void xpread(int, void *, size_t, off_t);
|
||||
void xpwrite(int, const void *, size_t, off_t);
|
||||
struct stat xfstatat(int, const char *, int);
|
||||
@ -48,7 +50,7 @@ enum units {
|
||||
HUMAN_READABLE,
|
||||
};
|
||||
|
||||
struct units_buf __pr_units(u64, enum units);
|
||||
struct units_buf __pr_units(s64, enum units);
|
||||
|
||||
struct units_buf {
|
||||
char b[20];
|
||||
@ -69,10 +71,12 @@ int open_for_format(const char *, bool);
|
||||
int bcachectl_open(void);
|
||||
|
||||
struct bcache_handle {
|
||||
uuid_le uuid;
|
||||
int ioctl_fd;
|
||||
int sysfs_fd;
|
||||
};
|
||||
|
||||
void bcache_fs_close(struct bcache_handle);
|
||||
struct bcache_handle bcache_fs_open(const char *);
|
||||
|
||||
bool ask_yn(void);
|
||||
@ -151,4 +155,6 @@ unsigned hatoi_validate(const char *, const char *);
|
||||
|
||||
u32 crc32c(u32, const void *, size_t);
|
||||
|
||||
char *dev_to_path(dev_t);
|
||||
|
||||
#endif /* _TOOLS_UTIL_H */
|
||||
|
Loading…
Reference in New Issue
Block a user