mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-02 00:00:03 +03:00
bcache device_show now dumps superblocks
This commit is contained in:
parent
837a476cc1
commit
f3a8d54837
2
Makefile
2
Makefile
@ -6,7 +6,7 @@ LDFLAGS+=-static
|
||||
|
||||
PKGCONFIG_LIBS="blkid uuid libnih"
|
||||
CFLAGS+=`pkg-config --cflags ${PKGCONFIG_LIBS}`
|
||||
LDLIBS+=`pkg-config --libs ${PKGCONFIG_LIBS}` -lscrypt -lsodium -lkeyutils
|
||||
LDLIBS+=`pkg-config --libs ${PKGCONFIG_LIBS}` -lscrypt -lsodium -lkeyutils -lm
|
||||
|
||||
ifeq ($(PREFIX),/usr)
|
||||
ROOT_SBINDIR=/sbin
|
||||
|
@ -16,6 +16,10 @@
|
||||
#include <nih/option.h>
|
||||
|
||||
#include "bcache.h"
|
||||
#include "libbcache.h"
|
||||
|
||||
/* This code belongs under show_fs */
|
||||
#if 0
|
||||
|
||||
struct bcache_dev {
|
||||
unsigned nr;
|
||||
@ -162,6 +166,20 @@ int cmd_device_show(int argc, char *argv[])
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int cmd_device_show(int argc, char *argv[])
|
||||
{
|
||||
struct cache_sb *sb;
|
||||
|
||||
if (argc != 2)
|
||||
die("please supply a single device");
|
||||
|
||||
sb = bcache_super_read(argv[1]);
|
||||
bcache_super_print(sb, HUMAN_READABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_device_add(int argc, char *argv[])
|
||||
{
|
||||
|
12
bcache-key.c
12
bcache-key.c
@ -18,7 +18,7 @@ int cmd_unlock(int argc, char *argv[])
|
||||
|
||||
struct bcache_disk_key disk_key;
|
||||
struct bcache_key key;
|
||||
struct cache_sb sb;
|
||||
struct cache_sb *sb;
|
||||
char *passphrase;
|
||||
char uuid[40];
|
||||
char description[60];
|
||||
@ -26,12 +26,12 @@ int cmd_unlock(int argc, char *argv[])
|
||||
if (!args[0] || args[1])
|
||||
die("please supply a single device");
|
||||
|
||||
bcache_super_read(args[0], &sb);
|
||||
sb = bcache_super_read(args[0]);
|
||||
|
||||
if (!CACHE_SET_ENCRYPTION_KEY(&sb))
|
||||
if (!CACHE_SET_ENCRYPTION_KEY(sb))
|
||||
die("filesystem is not encrypted");
|
||||
|
||||
memcpy(&disk_key, sb.encryption_key, sizeof(disk_key));
|
||||
memcpy(&disk_key, sb->encryption_key, sizeof(disk_key));
|
||||
|
||||
if (!memcmp(&disk_key, bch_key_header, sizeof(bch_key_header)))
|
||||
die("filesystem does not have encryption key");
|
||||
@ -39,12 +39,12 @@ int cmd_unlock(int argc, char *argv[])
|
||||
passphrase = read_passphrase("Enter passphrase: ");
|
||||
|
||||
derive_passphrase(&key, passphrase);
|
||||
disk_key_encrypt(&sb, &disk_key, &key);
|
||||
disk_key_encrypt(sb, &disk_key, &key);
|
||||
|
||||
if (memcmp(&disk_key, bch_key_header, sizeof(bch_key_header)))
|
||||
die("incorrect passphrase");
|
||||
|
||||
uuid_unparse_lower(sb.user_uuid.b, uuid);
|
||||
uuid_unparse_lower(sb->user_uuid.b, uuid);
|
||||
sprintf(description, "bcache:%s", uuid);
|
||||
|
||||
if (add_key("logon", description, &key, sizeof(key),
|
||||
|
@ -670,6 +670,7 @@ LE64_BITMASK(CACHE_STATE, struct cache_member, f1, 0, 4)
|
||||
#define CACHE_RO 1U
|
||||
#define CACHE_FAILED 2U
|
||||
#define CACHE_SPARE 3U
|
||||
#define CACHE_STATE_NR 4U
|
||||
|
||||
LE64_BITMASK(CACHE_TIER, struct cache_member, f1, 4, 8)
|
||||
#define CACHE_TIERS 4U
|
||||
@ -683,6 +684,7 @@ LE64_BITMASK(CACHE_REPLACEMENT, struct cache_member, f1, 26, 30)
|
||||
#define CACHE_REPLACEMENT_LRU 0U
|
||||
#define CACHE_REPLACEMENT_FIFO 1U
|
||||
#define CACHE_REPLACEMENT_RANDOM 2U
|
||||
#define CACHE_REPLACEMENT_NR 3U
|
||||
|
||||
LE64_BITMASK(CACHE_DISCARD, struct cache_member, f1, 30, 31);
|
||||
|
||||
@ -770,18 +772,7 @@ LE64_BITMASK(CACHE_SET_META_CSUM_TYPE,struct cache_sb, flags, 16, 20);
|
||||
#define BCH_CSUM_NONE 0U
|
||||
#define BCH_CSUM_CRC32C 1U
|
||||
#define BCH_CSUM_CRC64 2U
|
||||
#define BCH_CSUM_CHACHA20_POLY1305 3U
|
||||
#define BCH_CSUM_NR 4U
|
||||
|
||||
static inline _Bool bch_csum_type_is_encryption(unsigned type)
|
||||
{
|
||||
switch (type) {
|
||||
case BCH_CSUM_CHACHA20_POLY1305:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#define BCH_CSUM_NR 3U
|
||||
|
||||
LE64_BITMASK(CACHE_SET_BTREE_NODE_SIZE, struct cache_sb, flags, 20, 36);
|
||||
|
||||
@ -816,6 +807,12 @@ LE64_BITMASK(CACHE_SET_GC_RESERVE, struct cache_sb, flags, 57, 63);
|
||||
|
||||
LE64_BITMASK(CACHE_SET_ROOT_RESERVE, struct cache_sb, flags2, 0, 6);
|
||||
|
||||
/*
|
||||
* Did we shut down cleanly? Just a hint, doesn't affect behaviour of
|
||||
* mount/recovery path:
|
||||
*/
|
||||
LE64_BITMASK(CACHE_SET_CLEAN, struct cache_sb, flags2, 6, 7);
|
||||
|
||||
/*
|
||||
* If nonzero, encryption is enabled; overrides DATA/META_CSUM_TYPE. Also
|
||||
* indicates encryption algorithm in use, if/when we get more than one:
|
||||
|
52
bcache.c
52
bcache.c
@ -23,58 +23,6 @@
|
||||
|
||||
#include "bcache.h"
|
||||
|
||||
const char * const cache_state[] = {
|
||||
"active",
|
||||
"ro",
|
||||
"failed",
|
||||
"spare",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const replacement_policies[] = {
|
||||
"lru",
|
||||
"fifo",
|
||||
"random",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const csum_types[] = {
|
||||
"none",
|
||||
"crc32c",
|
||||
"crc64",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const compression_types[] = {
|
||||
"none",
|
||||
"lz4",
|
||||
"gzip",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const error_actions[] = {
|
||||
"continue",
|
||||
"readonly",
|
||||
"panic",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const bdev_cache_mode[] = {
|
||||
"writethrough",
|
||||
"writeback",
|
||||
"writearound",
|
||||
"none",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const bdev_state[] = {
|
||||
"detached",
|
||||
"clean",
|
||||
"dirty",
|
||||
"inconsistent",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
puts("bcache - tool for managing bcache volumes/filesystems\n"
|
||||
|
8
bcache.h
8
bcache.h
@ -9,14 +9,6 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
extern const char * const cache_state[];
|
||||
extern const char * const replacement_policies[];
|
||||
extern const char * const csum_types[];
|
||||
extern const char * const compression_types[];
|
||||
extern const char * const error_actions[];
|
||||
extern const char * const bdev_cache_mode[];
|
||||
extern const char * const bdev_state[];
|
||||
|
||||
int cmd_format(int argc, char *argv[]);
|
||||
|
||||
int cmd_unlock(int argc, char *argv[]);
|
||||
|
223
libbcache.c
223
libbcache.c
@ -17,6 +17,74 @@
|
||||
#include "libbcache.h"
|
||||
#include "crypto.h"
|
||||
|
||||
const char * const cache_state[] = {
|
||||
"active",
|
||||
"ro",
|
||||
"failed",
|
||||
"spare",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const replacement_policies[] = {
|
||||
"lru",
|
||||
"fifo",
|
||||
"random",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const csum_types[] = {
|
||||
"none",
|
||||
"crc32c",
|
||||
"crc64",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const compression_types[] = {
|
||||
"none",
|
||||
"lz4",
|
||||
"gzip",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const str_hash_types[] = {
|
||||
"crc32c",
|
||||
"crc64",
|
||||
"siphash",
|
||||
"sha1",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const error_actions[] = {
|
||||
"continue",
|
||||
"readonly",
|
||||
"panic",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const member_states[] = {
|
||||
"active",
|
||||
"ro",
|
||||
"failed",
|
||||
"spare",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const bdev_cache_mode[] = {
|
||||
"writethrough",
|
||||
"writeback",
|
||||
"writearound",
|
||||
"none",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char * const bdev_state[] = {
|
||||
"detached",
|
||||
"clean",
|
||||
"dirty",
|
||||
"inconsistent",
|
||||
NULL
|
||||
};
|
||||
|
||||
#define BCH_MIN_NR_NBUCKETS (1 << 10)
|
||||
|
||||
/* first bucket should start 1 mb in, in sectors: */
|
||||
@ -187,48 +255,155 @@ void bcache_format(struct dev_opts *devs, size_t nr_devs,
|
||||
|
||||
for (i = devs; i < devs + nr_devs; i++) {
|
||||
struct cache_member *m = sb->members + (i - devs);
|
||||
char uuid_str[40], set_uuid_str[40];
|
||||
|
||||
sb->disk_uuid = m->uuid;
|
||||
sb->nr_this_dev = i - devs;
|
||||
sb->csum = __cpu_to_le64(__csum_set(sb, __le16_to_cpu(sb->u64s),
|
||||
CACHE_SB_CSUM_TYPE(sb)));
|
||||
|
||||
uuid_unparse(sb->disk_uuid.b, uuid_str);
|
||||
uuid_unparse(sb->user_uuid.b, set_uuid_str);
|
||||
printf("UUID: %s\n"
|
||||
"Set UUID: %s\n"
|
||||
"version: %u\n"
|
||||
"nbuckets: %llu\n"
|
||||
"block_size: %u\n"
|
||||
"bucket_size: %u\n"
|
||||
"nr_in_set: %u\n"
|
||||
"nr_this_dev: %u\n"
|
||||
"first_bucket: %u\n",
|
||||
uuid_str, set_uuid_str,
|
||||
(unsigned) sb->version,
|
||||
__le64_to_cpu(m->nbuckets),
|
||||
__le16_to_cpu(sb->block_size),
|
||||
__le16_to_cpu(m->bucket_size),
|
||||
sb->nr_in_set,
|
||||
sb->nr_this_dev,
|
||||
__le16_to_cpu(m->first_bucket));
|
||||
|
||||
do_write_sb(i->fd, sb);
|
||||
}
|
||||
|
||||
bcache_super_print(sb, HUMAN_READABLE);
|
||||
|
||||
free(sb);
|
||||
}
|
||||
|
||||
void bcache_super_read(const char *path, struct cache_sb *sb)
|
||||
void bcache_super_print(struct cache_sb *sb, int units)
|
||||
{
|
||||
unsigned i;
|
||||
char user_uuid_str[40], internal_uuid_str[40], member_uuid_str[40];
|
||||
char label[SB_LABEL_SIZE + 1];
|
||||
|
||||
memset(label, 0, sizeof(label));
|
||||
memcpy(label, sb->label, sizeof(sb->label));
|
||||
uuid_unparse(sb->user_uuid.b, user_uuid_str);
|
||||
uuid_unparse(sb->set_uuid.b, internal_uuid_str);
|
||||
|
||||
printf("External UUID: %s\n"
|
||||
"Internal UUID: %s\n"
|
||||
"Label: %s\n"
|
||||
"Version: %llu\n"
|
||||
"Block_size: %s\n"
|
||||
"Btree node size: %s\n"
|
||||
"Error action: %s\n"
|
||||
"Clean: %llu\n"
|
||||
|
||||
"Metadata replicas: have %llu, want %llu\n"
|
||||
"Data replicas: have %llu, want %llu\n"
|
||||
|
||||
"Metadata checksum type: %s\n"
|
||||
"Data checksum type: %s\n"
|
||||
"Compression type: %s\n"
|
||||
|
||||
"String hash type: %s\n"
|
||||
"32 bit inodes: %llu\n"
|
||||
"GC reserve percentage: %llu%%\n"
|
||||
"Root reserve percentage: %llu%%\n"
|
||||
|
||||
"Devices: %u\n",
|
||||
user_uuid_str,
|
||||
internal_uuid_str,
|
||||
label,
|
||||
le64_to_cpu(sb->version),
|
||||
pr_units(le16_to_cpu(sb->block_size), units).b,
|
||||
pr_units(CACHE_SET_BTREE_NODE_SIZE(sb), units).b,
|
||||
|
||||
CACHE_SET_ERROR_ACTION(sb) < BCH_NR_ERROR_ACTIONS
|
||||
? error_actions[CACHE_SET_ERROR_ACTION(sb)]
|
||||
: "unknown",
|
||||
|
||||
CACHE_SET_CLEAN(sb),
|
||||
|
||||
CACHE_SET_META_REPLICAS_HAVE(sb),
|
||||
CACHE_SET_META_REPLICAS_WANT(sb),
|
||||
CACHE_SET_DATA_REPLICAS_HAVE(sb),
|
||||
CACHE_SET_DATA_REPLICAS_WANT(sb),
|
||||
|
||||
CACHE_SET_META_CSUM_TYPE(sb) < BCH_CSUM_NR
|
||||
? csum_types[CACHE_SET_META_CSUM_TYPE(sb)]
|
||||
: "unknown",
|
||||
|
||||
CACHE_SET_DATA_CSUM_TYPE(sb) < BCH_CSUM_NR
|
||||
? csum_types[CACHE_SET_DATA_CSUM_TYPE(sb)]
|
||||
: "unknown",
|
||||
|
||||
CACHE_SET_COMPRESSION_TYPE(sb) < BCH_COMPRESSION_NR
|
||||
? compression_types[CACHE_SET_COMPRESSION_TYPE(sb)]
|
||||
: "unknown",
|
||||
|
||||
CACHE_SET_STR_HASH_TYPE(sb) < BCH_STR_HASH_NR
|
||||
? str_hash_types[CACHE_SET_STR_HASH_TYPE(sb)]
|
||||
: "unknown",
|
||||
|
||||
CACHE_INODE_32BIT(sb),
|
||||
CACHE_SET_GC_RESERVE(sb),
|
||||
CACHE_SET_ROOT_RESERVE(sb),
|
||||
|
||||
sb->nr_in_set);
|
||||
|
||||
for (i = 0; i < sb->nr_in_set; i++) {
|
||||
struct cache_member *m = sb->members + i;
|
||||
time_t last_mount = le64_to_cpu(m->last_mount);
|
||||
|
||||
uuid_unparse(m->uuid.b, member_uuid_str);
|
||||
|
||||
printf("\n"
|
||||
"Device %u:\n"
|
||||
" UUID: %s\n"
|
||||
" bucket_size: %s\n"
|
||||
" first_bucket: %u\n"
|
||||
" nbuckets: %llu\n"
|
||||
" Last mount: %s\n"
|
||||
" State: %s\n"
|
||||
" Tier: %llu\n"
|
||||
" Has metadata: %llu\n"
|
||||
" Has data: %llu\n"
|
||||
" Replacement policy: %s\n"
|
||||
" Discard: %llu\n",
|
||||
i, member_uuid_str,
|
||||
pr_units(le16_to_cpu(m->bucket_size), units).b,
|
||||
le16_to_cpu(m->first_bucket),
|
||||
le64_to_cpu(m->nbuckets),
|
||||
last_mount ? ctime(&last_mount) : "(never)",
|
||||
|
||||
CACHE_STATE(m) < CACHE_STATE_NR
|
||||
? member_states[CACHE_STATE(m)]
|
||||
: "unknown",
|
||||
|
||||
CACHE_TIER(m),
|
||||
CACHE_HAS_METADATA(m),
|
||||
CACHE_HAS_DATA(m),
|
||||
|
||||
CACHE_REPLACEMENT(m) < CACHE_REPLACEMENT_NR
|
||||
? replacement_policies[CACHE_REPLACEMENT(m)]
|
||||
: "unknown",
|
||||
|
||||
CACHE_DISCARD(m));
|
||||
}
|
||||
}
|
||||
|
||||
struct cache_sb *bcache_super_read(const char *path)
|
||||
{
|
||||
struct cache_sb sb, *ret;
|
||||
size_t bytes;
|
||||
|
||||
int fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
die("couldn't open %s", path);
|
||||
|
||||
if (pread(fd, sb, sizeof(*sb), SB_SECTOR << 9) != sizeof(*sb))
|
||||
if (pread(fd, &sb, sizeof(sb), SB_SECTOR << 9) != sizeof(sb))
|
||||
die("error reading superblock");
|
||||
|
||||
if (memcmp(&sb->magic, &BCACHE_MAGIC, sizeof(sb->magic)))
|
||||
if (memcmp(&sb.magic, &BCACHE_MAGIC, sizeof(sb.magic)))
|
||||
die("not a bcache superblock");
|
||||
|
||||
bytes = sizeof(sb) + le16_to_cpu(sb.u64s) * sizeof(u64);
|
||||
|
||||
ret = calloc(1, bytes);
|
||||
|
||||
if (pread(fd, ret, bytes, SB_SECTOR << 9) != bytes)
|
||||
die("error reading superblock");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
13
libbcache.h
13
libbcache.h
@ -4,6 +4,15 @@
|
||||
#include "util.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
extern const char * const cache_state[];
|
||||
extern const char * const replacement_policies[];
|
||||
extern const char * const csum_types[];
|
||||
extern const char * const compression_types[];
|
||||
extern const char * const str_hash_types[];
|
||||
extern const char * const error_actions[];
|
||||
extern const char * const bdev_cache_mode[];
|
||||
extern const char * const bdev_state[];
|
||||
|
||||
struct dev_opts {
|
||||
int fd;
|
||||
const char *path;
|
||||
@ -29,6 +38,8 @@ void bcache_format(struct dev_opts *devs, size_t nr_devs,
|
||||
char *label,
|
||||
uuid_le uuid);
|
||||
|
||||
void bcache_super_read(const char *, struct cache_sb *);
|
||||
void bcache_super_print(struct cache_sb *, int);
|
||||
|
||||
struct cache_sb *bcache_super_read(const char *);
|
||||
|
||||
#endif /* _LIBBCACHE_H */
|
||||
|
30
util.c
30
util.c
@ -4,6 +4,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <linux/fs.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -69,6 +70,35 @@ char *strim(char *s)
|
||||
return s;
|
||||
}
|
||||
|
||||
struct units_buf pr_units(u64 v, enum units units)
|
||||
{
|
||||
struct units_buf ret;
|
||||
|
||||
switch (units) {
|
||||
case BYTES:
|
||||
snprintf(ret.b, sizeof(ret.b), "%llu", v << 9);
|
||||
break;
|
||||
case SECTORS:
|
||||
snprintf(ret.b, sizeof(ret.b), "%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",
|
||||
v / pow(1024, exp),
|
||||
"KMGTPE"[exp-1]);
|
||||
} else {
|
||||
snprintf(ret.b, sizeof(ret.b), "%llu", v);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Argument parsing stuff: */
|
||||
|
||||
long strtoul_or_die(const char *p, size_t max, const char *msg)
|
||||
|
37
util.h
37
util.h
@ -9,6 +9,7 @@
|
||||
/* linux kernel style types: */
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
typedef __u8 u8;
|
||||
typedef __u16 u16;
|
||||
@ -20,6 +21,29 @@ typedef __s16 s16;
|
||||
typedef __s32 s32;
|
||||
typedef __s64 s64;
|
||||
|
||||
#define cpu_to_le16 __cpu_to_le16
|
||||
#define cpu_to_le32 __cpu_to_le32
|
||||
#define cpu_to_le64 __cpu_to_le64
|
||||
|
||||
#define le16_to_cpu __le16_to_cpu
|
||||
#define le32_to_cpu __le32_to_cpu
|
||||
#define le64_to_cpu __le64_to_cpu
|
||||
|
||||
static inline void le16_add_cpu(__le16 *var, u16 val)
|
||||
{
|
||||
*var = cpu_to_le16(le16_to_cpu(*var) + val);
|
||||
}
|
||||
|
||||
static inline void le32_add_cpu(__le32 *var, u32 val)
|
||||
{
|
||||
*var = cpu_to_le32(le32_to_cpu(*var) + val);
|
||||
}
|
||||
|
||||
static inline void le64_add_cpu(__le64 *var, u64 val)
|
||||
{
|
||||
*var = cpu_to_le64(le64_to_cpu(*var) + val);
|
||||
}
|
||||
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
|
||||
#define min(x, y) ({ \
|
||||
@ -46,7 +70,20 @@ unsigned ilog2(u64);
|
||||
char *skip_spaces(const char *str);
|
||||
char *strim(char *s);
|
||||
|
||||
enum units {
|
||||
BYTES,
|
||||
SECTORS,
|
||||
HUMAN_READABLE,
|
||||
};
|
||||
|
||||
struct units_buf pr_units(u64, enum units);
|
||||
|
||||
struct units_buf {
|
||||
char b[20];
|
||||
};
|
||||
|
||||
long strtoul_or_die(const char *, size_t, const char *);
|
||||
|
||||
u64 hatoi(const char *);
|
||||
unsigned hatoi_validate(const char *, const char *);
|
||||
unsigned nr_args(char * const *);
|
||||
|
Loading…
Reference in New Issue
Block a user