Cleanup, rip out more code, fix compiler warnings

Change-Id: I76b410dc700a917d2717b1ceda0df061a1599144
This commit is contained in:
Kent Overstreet 2015-01-27 13:45:02 -08:00
parent 112aacfeff
commit 5730e47b6f
12 changed files with 83 additions and 566 deletions

3
.gitignore vendored
View File

@ -1,8 +1,5 @@
bcache-super-show
make-bcache
bcacheadm bcacheadm
probe-bcache probe-bcache
bcachectl
.* .*
*.o *.o
tags tags

View File

@ -3,40 +3,30 @@ PREFIX=/usr
UDEVLIBDIR=/lib/udev UDEVLIBDIR=/lib/udev
DRACUTLIBDIR=/lib/dracut DRACUTLIBDIR=/lib/dracut
INSTALL=install INSTALL=install
CFLAGS+=-O2 -Wall -Werror -g -I. CFLAGS+=-std=gnu99 -O2 -Wall -Werror -g -I.
all: bcacheadm make-bcache probe-bcache bcachectl all: bcacheadm probe-bcache
install: bcacheadm make-bcache probe-bcache install: bcacheadm probe-bcache
$(INSTALL) -m0755 bcacheadm bcachectl $(DESTDIR)${PREFIX}/sbin/ $(INSTALL) -m0755 bcacheadm $(DESTDIR)${PREFIX}/sbin/
$(INSTALL) -m0755 make-bcache bcachectl $(DESTDIR)${PREFIX}/sbin/
$(INSTALL) -m0755 probe-bcache bcache-register $(DESTDIR)$(UDEVLIBDIR)/ $(INSTALL) -m0755 probe-bcache bcache-register $(DESTDIR)$(UDEVLIBDIR)/
$(INSTALL) -m0644 69-bcache.rules $(DESTDIR)$(UDEVLIBDIR)/rules.d/ $(INSTALL) -m0644 69-bcache.rules $(DESTDIR)$(UDEVLIBDIR)/rules.d/
#-$(INSTALL) -T -m0755 initramfs/hook $(DESTDIR)/usr/share/initramfs-tools/hooks/bcache #-$(INSTALL) -T -m0755 initramfs/hook $(DESTDIR)/usr/share/initramfs-tools/hooks/bcache
if [ -d $(DESTDIR)$(DRACUTLIBDIR)/modules.d ]; \ if [ -d $(DESTDIR)$(DRACUTLIBDIR)/modules.d ]; then\
then $(INSTALL) -D -m0755 dracut/module-setup.sh $(DESTDIR)$(DRACUTLIBDIR)/modules.d/90bcache/module-setup.sh; \ $(INSTALL) -D -m0755 dracut/module-setup.sh $(DESTDIR)$(DRACUTLIBDIR)/modules.d/90bcache/module-setup.sh; \
fi fi
$(INSTALL) -m0644 -- *.8 $(DESTDIR)${PREFIX}/share/man/man8/ $(INSTALL) -m0644 -- *.8 $(DESTDIR)${PREFIX}/share/man/man8/
# $(INSTALL) -m0755 bcache-test $(DESTDIR)${PREFIX}/sbin/
clean: clean:
$(RM) -f make-bcache probe-bcache bcache-super-show bcache-test bcachectl *.o $(RM) -f probe-bcache bcacheadm bcache-test *.o
bcache-test: LDLIBS += `pkg-config --libs openssl` bcache.o: CFLAGS += `pkg-config --cflags uuid blkid`
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: CFLAGS += `pkg-config --cflags uuid blkid libnih`
bcacheadm: bcache.o bcacheadm: bcache.o
make-bcache: LDLIBS += `pkg-config --libs uuid blkid` probe-bcache.o: CFLAGS += `pkg-config --cflags uuid blkid`
make-bcache: CFLAGS += `pkg-config --cflags uuid blkid`
make-bcache: bcache.o
probe-bcache: LDLIBS += `pkg-config --libs uuid blkid` probe-bcache: LDLIBS += `pkg-config --libs uuid blkid`
probe-bcache: CFLAGS += `pkg-config --cflags uuid blkid`
bcache-super-show: LDLIBS += `pkg-config --libs uuid` bcache-test: LDLIBS += `pkg-config --libs openssl`
bcache-super-show: CFLAGS += -std=gnu99
bcache-super-show: bcache.o
bcachectl: bcachectl.o

View File

@ -2,42 +2,21 @@
AUTOMAKE_OPTIONS=subdir-objects AUTOMAKE_OPTIONS=subdir-objects
PREFIX=/usr PREFIX=/usr
AM_CFLAGS=-std=gnu99 `pkg-config --cflags uuid blkid` AM_CFLAGS=-std=gnu99 -O2 -Wall -Werror -g
AM_LDFLAGS=`pkg-config --libs uuid blkid` -L$(top_builddir)
bin_PROGRAMS=bcacheadm probe-bcache
bin_PROGRAMS=make-bcache \ bcache.o: CFLAGS += `pkg-config --cflags uuid blkid`
probe-bcache \
bcache-super-show \
bcachectl \
bcacheadm
noinst_PROGRAMS=bcache-test
lib_LIBRARIES=libbcache.a
libbcache_a_SOURCES=bcache.c
bcache_LDADD=libbcache.a
make_bcache_SOURCES=make-bcache.c
make_bcache_LDADD=libbcache.a
probe_bcache_SOURCES=probe-bcache.c
probe_bcache_LDADD=libbcache.a
bcache_super_show_SOURCES=bcache-super-show.c
bcache_super_show_LDADD=libbcache.a
bcachectl_SOURCES=bcachectl.c
bcache_test_SOURCES=bcache-test.c
bcache_test_LDFLAGS=-lm `pkg-config --libs openssl`
bcache_test_CFLAGS=$(AM_CFLAGS) `pkg-config --cflags openssl`
bcacheadm_SOURCES=bcacheadm.c bcacheadm_SOURCES=bcacheadm.c
bcacheadm_CFLAGS=$(AM_CFLAGS) -g bcacheadm_CFLAGS=$(AM_CFLAGS) `pkg-config --cflags uuid blkid libnih`
bcacheadm_LDFLAGS=$(AM_LDFLAGS) -lnih bcacheadm_LDFLAGS=`pkg-config --libs uuid blkid libnih`
bcacheadm_LDADD=libbcache.a bcacheadm_LDADD=bcache.o
probe_bcache_SOURCES=probe-bcache.c
probe_bcache_CFLAGS=$(AM_CFLAGS) `pkg-config --cflags uuid blkid`
probe_bcache_LDFLAGS=`pkg-config --libs uuid blkid`
probe_bcache_LDADD=bcache.o
udevrule_DATA=69-bcache.rules udevrule_DATA=69-bcache.rules
udevruledir=$(prefix)/lib/udev/rules.d udevruledir=$(prefix)/lib/udev/rules.d
@ -48,10 +27,7 @@ udevrdir=$(prefix)/lib/udev/
initramfs_SCRIPTS=initramfs/bcache initramfs_SCRIPTS=initramfs/bcache
initramfsdir=$(prefix)/etc/initramfs-tools/hooks/ initramfsdir=$(prefix)/etc/initramfs-tools/hooks/
man8_MANS= bcache-super-show.8 \ man8_MANS=bcacheadm.8 probe-bcache.8
make-bcache.8 \
probe-bcache.8 \
bcacheadm.8
include ../../../../../../../../../../usr/share/DateraContainer/Makefile.rpm include ../../../../../../../../../../usr/share/DateraContainer/Makefile.rpm
# some version of automake don't like absolute path names for included makefiles # some version of automake don't like absolute path names for included makefiles

View File

@ -1,11 +0,0 @@
.TH bcache-super-show 8
.SH NAME
bcache-super-show \- Print the bcache superblock
.SH SYNOPSIS
.B bcache-super-show
[\fB \-f]
.I device
.SH OPTIONS
.TP
.BR \-f
Keep going if the superblock crc is invalid

View File

@ -1,89 +0,0 @@
/*
* Author: Gabriel de Perthuis <g2p.code@gmail.com>
*
* GPLv2
*/
#define _FILE_OFFSET_BITS 64
#define __USE_FILE_OFFSET64
#define _XOPEN_SOURCE 500
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <linux/fs.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <uuid/uuid.h>
#include "bcache.h"
void usage()
{
fprintf(stderr, "Usage: bcache-super-show [-f] <device>\n");
}
int main(int argc, char **argv)
{
int o;
extern char *optarg;
struct cache_sb sb_stack, *sb = &sb_stack;
size_t bytes = sizeof(*sb);
bool force_csum = false;
while ((o = getopt(argc, argv, "f")) != EOF)
switch (o) {
case 'f':
force_csum = 1;
break;
default:
usage();
exit(1);
}
argv += optind;
argc -= optind;
if (argc != 1) {
usage();
exit(1);
}
int fd = open(argv[0], O_RDONLY);
if (fd < 0) {
printf("Can't open dev %s: %s\n", argv[0], strerror(errno));
exit(2);
}
if (pread(fd, sb, bytes, SB_START) != bytes) {
fprintf(stderr, "Couldn't read\n");
exit(2);
}
if (sb->u64s) {
bytes = sizeof(*sb) + sb->u64s * 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;
}

View File

@ -20,11 +20,7 @@ make DESTDIR=%buildroot INSTALL=/usr/bin/install -C /bld/$RPM_PACKAGE_NAME insta
%files %files
%_bindir/bcacheadm %_bindir/bcacheadm
%_bindir/bcachectl
%_bindir/make-bcache
%_bindir/probe-bcache %_bindir/probe-bcache
%_bindir/bcache-super-show
%_libdir/libbcache.a
%_mandir/man8/*.gz %_mandir/man8/*.gz
%exclude %_prefix/etc/initramfs-tools/hooks/bcache %exclude %_prefix/etc/initramfs-tools/hooks/bcache
%exclude %_prefix/lib/udev/bcache-register %exclude %_prefix/lib/udev/bcache-register

View File

@ -64,6 +64,42 @@ const char * const bdev_state[] = {
NULL NULL
}; };
const char * const set_attrs[] = {
"btree_flush_delay",
"btree_scan_ratelimit",
"bucket_reserve_percent",
"cache_reserve_percent",
"checksum_type",
"congested_read_threshold_us",
"congested_write_threshold_us",
"data_replicas",
"errors",
"foreground_target_percent",
"gc_sector_percent",
"journal_delay_ms",
"meta_replicas",
"sector_reserve_percent",
"tiering_percent",
NULL
};
const char * const cache_attrs[] = {
"cache_replacement_policy",
"discard",
"state",
"tier",
NULL
};
const char * const internal_attrs[] = {
"btree_shrinker_disabled",
"copy_gc_enabled",
"foreground_write_rate",
"tiering_enabled",
"tiering_rate",
NULL
};
char *skip_spaces(const char *str) char *skip_spaces(const char *str)
{ {
while (isspace(*str)) while (isspace(*str))
@ -583,8 +619,8 @@ void write_cache_sbs(int *fds, struct cache_sb *sb,
m->bucket_size = bucket_sizes[0]; m->bucket_size = bucket_sizes[0];
} else { } else {
if (!bucket_sizes[i]) { if (!bucket_sizes[i]) {
printf("No bucket size specified for cache %d," printf("No bucket size specified for cache %zu,"
" using the default of %d", " using the default of %u",
i, bucket_sizes[0]); i, bucket_sizes[0]);
m->bucket_size = bucket_sizes[0]; m->bucket_size = bucket_sizes[0];
} else { } else {
@ -821,11 +857,6 @@ void show_super_backingdev(struct cache_sb *sb, bool force_csum)
bdev_state[BDEV_STATE(sb)]); bdev_state[BDEV_STATE(sb)]);
} }
static void show_cache_member(struct cache_sb *sb, unsigned i)
{
}
void show_super_cache(struct cache_sb *sb, bool force_csum) void show_super_cache(struct cache_sb *sb, bool force_csum)
{ {
struct cache_member *m = sb->members + sb->nr_this_dev; struct cache_member *m = sb->members + sb->nr_this_dev;
@ -866,16 +897,16 @@ void show_super_cache(struct cache_sb *sb, bool force_csum)
printf("cache.discard\t%llu\n", CACHE_DISCARD(m)); printf("cache.discard\t%llu\n", CACHE_DISCARD(m));
} }
static int __sysfs_attr_type(char *attr, const char **attr_arr) { static int __sysfs_attr_type(const char *attr, const char * const *attr_arr)
int i, j; {
for(i = 0; attr_arr[i] != NULL; i++) for (unsigned i = 0; attr_arr[i] != NULL; i++)
if(!strcmp(attr, attr_arr[i])) if(!strcmp(attr, attr_arr[i]))
return 1; return 1;
return 0; return 0;
} }
enum sysfs_attr sysfs_attr_type(char *attr) { enum sysfs_attr sysfs_attr_type(const char *attr)
int ret; {
if(__sysfs_attr_type(attr, set_attrs)) if(__sysfs_attr_type(attr, set_attrs))
return SET_ATTR; return SET_ATTR;
if(__sysfs_attr_type(attr, cache_attrs)) if(__sysfs_attr_type(attr, cache_attrs))
@ -888,13 +919,14 @@ enum sysfs_attr sysfs_attr_type(char *attr) {
return -1; return -1;
} }
static void __sysfs_attr_list(const char **attr_arr) { static void __sysfs_attr_list(const char * const *attr_arr)
int i, j; {
for (i = 0; attr_arr[i] != NULL; i++) for (unsigned i = 0; attr_arr[i] != NULL; i++)
printf("%s\n", attr_arr[i]); printf("%s\n", attr_arr[i]);
} }
void sysfs_attr_list() { void sysfs_attr_list()
{
__sysfs_attr_list(set_attrs); __sysfs_attr_list(set_attrs);
__sysfs_attr_list(cache_attrs); __sysfs_attr_list(cache_attrs);
__sysfs_attr_list(internal_attrs); __sysfs_attr_list(internal_attrs);
@ -968,8 +1000,8 @@ 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) { static void list_cacheset_devs(char *cset_dir, char *cset_name, bool parse_dev_name)
int i = 0; {
DIR *cachedir, *dir; DIR *cachedir, *dir;
struct stat cache_stat; struct stat cache_stat;
char entry[MAX_PATH]; char entry[MAX_PATH];
@ -1017,7 +1049,8 @@ static void list_cacheset_devs(char *cset_dir, char *cset_name, bool parse_dev_n
} }
} }
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
* repeat on each dev until we find a matching one * repeat on each dev until we find a matching one
* append that cache# to subdir and return * append that cache# to subdir and return
@ -1338,7 +1371,6 @@ char *read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, char *ret)
} }
if (S_ISREG(statbuf.st_mode)) { if (S_ISREG(statbuf.st_mode)) {
char buf[MAX_PATH];
FILE *fp = NULL; FILE *fp = NULL;
fp = fopen(entry, "r"); fp = fopen(entry, "r");
@ -1373,7 +1405,6 @@ char *bcache_get_capacity(const char *cset_dir, const char *capacity_uuid,
double total_cap = 0, total_free = 0; double total_cap = 0, total_free = 0;
int precision = 2; int precision = 2;
snprintf(intbuf, 4, "%d", i);
snprintf(bucket_size_path, MAX_PATH, "%s/%s/%s/%s", cset_dir, snprintf(bucket_size_path, MAX_PATH, "%s/%s/%s/%s", cset_dir,
capacity_uuid, "cache0", "bucket_size_bytes"); capacity_uuid, "cache0", "bucket_size_bytes");
snprintf(nbuckets_path, MAX_PATH, "%s/%s/%s/%s", cset_dir, snprintf(nbuckets_path, MAX_PATH, "%s/%s/%s/%s", cset_dir,
@ -1383,7 +1414,7 @@ char *bcache_get_capacity(const char *cset_dir, const char *capacity_uuid,
snprintf(cache_path, MAX_PATH, "%s/%s/%s", cset_dir, capacity_uuid, snprintf(cache_path, MAX_PATH, "%s/%s/%s", cset_dir, capacity_uuid,
"cache0"); "cache0");
while(true) { while (true) {
char buf[MAX_PATH]; char buf[MAX_PATH];
int len; int len;
DIR *cache_dir; DIR *cache_dir;
@ -1417,6 +1448,8 @@ char *bcache_get_capacity(const char *cset_dir, const char *capacity_uuid,
dev_names[dev_count] = dev_name(buf); dev_names[dev_count] = dev_name(buf);
} }
snprintf(intbuf, 4, "%d", dev_count);
/* remove i/stat and append i++/stat */ /* remove i/stat and append i++/stat */
bucket_size_path[strlen(cache_path) - strlen(intbuf)] = 0; bucket_size_path[strlen(cache_path) - strlen(intbuf)] = 0;
nbuckets_path[strlen(cache_path) - strlen(intbuf)] = 0; nbuckets_path[strlen(cache_path) - strlen(intbuf)] = 0;
@ -1425,7 +1458,6 @@ char *bcache_get_capacity(const char *cset_dir, const char *capacity_uuid,
dev_count++; dev_count++;
snprintf(intbuf, 4, "%d", dev_count);
strcat(cache_path, intbuf); strcat(cache_path, intbuf);
strcat(bucket_size_path, intbuf); strcat(bucket_size_path, intbuf);
strcat(nbuckets_path, intbuf); strcat(nbuckets_path, intbuf);

View File

@ -50,6 +50,9 @@ extern const char * const replacement_policies[];
extern const char * const csum_types[]; extern const char * const csum_types[];
extern const char * const bdev_cache_mode[]; extern const char * const bdev_cache_mode[];
extern const char * const bdev_state[]; extern const char * const bdev_state[];
extern const char * const set_attr[];
extern const char * const cache_attrs[];
extern const char * const internal_attrs[];
ssize_t read_string_list(const char *, const char * const[]); ssize_t read_string_list(const char *, const char * const[]);
ssize_t read_string_list_or_die(const char *, const char * const[], ssize_t read_string_list_or_die(const char *, const char * const[],
@ -74,43 +77,7 @@ void show_super_cache(struct cache_sb *, bool);
enum sysfs_attr {SET_ATTR, CACHE_ATTR, INTERNAL_ATTR}; enum sysfs_attr {SET_ATTR, CACHE_ATTR, INTERNAL_ATTR};
static const char *set_attrs[] = { enum sysfs_attr sysfs_attr_type(const char *attr);
"btree_flush_delay",
"btree_scan_ratelimit",
"bucket_reserve_percent",
"cache_reserve_percent",
"checksum_type",
"congested_read_threshold_us",
"congested_write_threshold_us",
"data_replicas",
"errors",
"foreground_target_percent",
"gc_sector_percent",
"journal_delay_ms",
"meta_replicas",
"sector_reserve_percent",
"tiering_percent",
NULL
};
static const char *cache_attrs[] = {
"cache_replacement_policy",
"discard",
"state",
"tier",
NULL
};
static const char *internal_attrs[] = {
"btree_shrinker_disabled",
"copy_gc_enabled",
"foreground_write_rate",
"tiering_enabled",
"tiering_rate",
NULL
};
enum sysfs_attr sysfs_attr_type(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);

View File

@ -477,8 +477,6 @@ int bcache_modify(NihCommand *command, char *const *args)
{ {
char *err; char *err;
char path[MAX_PATH]; char path[MAX_PATH];
DIR *path_dir;
struct stat cache_stat;
char *attr = args[0]; char *attr = args[0];
char *val = NULL; char *val = NULL;
int fd = -1; int fd = -1;
@ -604,7 +602,7 @@ int bcache_query_devs(NihCommand *command, char *const *args)
int bcache_status(NihCommand *command, char *const *args) int bcache_status(NihCommand *command, char *const *args)
{ {
int i, dev_count = 0, seq, nr_in_set = 0; int i, dev_count = 0, seq;
struct cache_sb *seq_sb = NULL; struct cache_sb *seq_sb = NULL;
char cache_path[MAX_PATH]; char cache_path[MAX_PATH];
char *dev_names[MAX_DEVS]; char *dev_names[MAX_DEVS];
@ -624,7 +622,6 @@ int bcache_status(NihCommand *command, char *const *args)
if (!seq_sb || sb->seq > seq) { if (!seq_sb || sb->seq > seq) {
seq = sb->seq; seq = sb->seq;
seq_sb = sb; seq_sb = sb;
nr_in_set = sb->nr_in_set;
} else } else
free(sb); free(sb);
} }
@ -825,7 +822,6 @@ err:
int bcache_set_failed(NihCommand *command, char *const *args) int bcache_set_failed(NihCommand *command, char *const *args)
{ {
int i;
char *err = NULL; char *err = NULL;
if (!dev_failed_uuid) { if (!dev_failed_uuid) {

View File

@ -1,52 +0,0 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#define __KERNEL__
#include <linux/bcache-ioctl.h>
#undef __KERNEL__
int bcachefd;
static int register_devices(int argc, char *argv[])
{
int ret;
ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, argv);
if (ret < 0) {
fprintf(stderr, "ioctl error %d", ret);
exit(EXIT_FAILURE);
}
return 0;
}
int main(int argc, char *argv[])
{
char *ioctl = argv[1];
if (argc < 3) {
fprintf(stderr, " <Usage> %s <action> <space separated list of devices>", argv[0]);
fprintf(stderr, "\n <Help> Possible actions are: \n");
fprintf(stderr, " \t 1. register_devices\n");
exit(EXIT_FAILURE);
}
bcachefd = open("/dev/bcache", O_RDWR);
if (bcachefd < 0) {
perror("Can't open bcache device");
exit(EXIT_FAILURE);
}
argc -= 2;
argv += 2;
if (!strcmp(ioctl, "register"))
return register_devices(argc, argv);
else {
fprintf(stderr, "Unknown ioctl\n");
exit(EXIT_FAILURE);
}
return 0;
}

View File

@ -1,26 +0,0 @@
.TH make-bcache 8
.SH NAME
make-bcache \- create a cache device
.SH SYNOPSIS
.B make-bcache
[\fB \-U\ \fIUUID\fR ]
[\fB \-b\ \fIbucket-size\fR ]
.I device
.SH OPTIONS
.TP
.BR \-C
Create a cache
.TP
.BR \-B
Create a backing device (kernel functionality not yet implemented)
.TP
.BR \-U\ \fIUUID
Create a cache device with the specified UUID
.TP
.BR \-b\ \fIbucket-size
Spcifies the bucket size. Allocation is done in terms of buckets, and cache
hits are counted per bucket; thus a smaller bucket size will give better cache
utilization, but poorer write performance. The bucket size is intended to be
equal to the size of your SSD's erase blocks, which seems to be 128k-512k for
most SSDs. Must be a power of two; accepts human readable units. Defaults to
128k.

View File

@ -1,259 +0,0 @@
/*
* Author: Kent Overstreet <kmo@daterainc.com>
*
* GPLv2
*/
#define _FILE_OFFSET_BITS 64
#define __USE_FILE_OFFSET 64
#define _XOPEN_SOURCE 600
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <linux/fs.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <uuid/uuid.h>
#include "bcache.h"
void usage()
{
fprintf(stderr,
"Usage: make-bcache [options] device\n"
" -C, --cache Format a cache device\n"
" -B, --bdev Format a backing device\n"
" --wipe-bcache destroy existing bcache data if present\n"
" -l, --label label\n"
" --cset-uuid UUID for the cache set\n"
" --csum-type One of (none|crc32c|crc64)\n"
" -b, --bucket bucket size\n"
" -w, --block block size (hard sector size of SSD, often 2k)\n"
" --replication-set replication set of subsequent devices\n"
" --meta-replicas number of metadata replicas\n"
" --data-replicas number of data replicas\n"
" --tier tier of subsequent devices\n"
" --cache_replacement_policy one of (lru|fifo|random)\n"
" --discard enable discards\n"
" --writeback enable writeback\n"
" -o, --data-offset data offset in sectors\n"
" -h, --help display this help and exit\n");
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
int c, bdev = -1;
size_t i, nr_backing_devices = 0;
unsigned block_size = 0;
unsigned bucket_sizes[argc];
int num_bucket_sizes = 0;
int writeback = 0, discard = 0, wipe_bcache = 0;
unsigned replication_set = 0, tier = 0, replacement_policy = 0;
uint64_t data_offset = BDEV_DATA_START_DEFAULT;
char *label = NULL;
const char *cache_devices[argc];
int cache_dev_fd[argc];
const char *backing_devices[argc];
int backing_dev_fd[argc];
const char *backing_dev_labels[argc];
enum long_opts {
CACHE_SET_UUID = 256,
CSUM_TYPE,
REPLICATION_SET,
META_REPLICAS,
DATA_REPLICAS,
};
const struct option opts[] = {
{ "cache", 0, NULL, 'C' },
{ "bdev", 0, NULL, 'B' },
{ "wipe-bcache", 0, &wipe_bcache, 1 },
{ "label", 1, NULL, 'l' },
{ "cset-uuid", 1, NULL, CACHE_SET_UUID },
{ "csum-type", 1, NULL, CSUM_TYPE },
{ "bucket", 1, NULL, 'b' },
{ "block", 1, NULL, 'w' },
{ "replication-set", 1, NULL, REPLICATION_SET },
{ "meta-replicas", 1, NULL, META_REPLICAS},
{ "data-replicas", 1, NULL, DATA_REPLICAS },
{ "tier", 1, NULL, 't' },
{ "cache_replacement_policy", 1, NULL, 'p' },
{ "discard", 0, &discard, 1 },
{ "writeback", 0, &writeback, 1 },
{ "data_offset", 1, NULL, 'o' },
{ "help", 0, NULL, 'h' },
{ NULL, 0, NULL, 0 },
};
struct cache_sb *cache_set_sb = calloc(1, sizeof(*cache_set_sb) +
sizeof(struct cache_member) * argc);
uuid_generate(cache_set_sb->set_uuid.b);
SET_CACHE_PREFERRED_CSUM_TYPE(cache_set_sb, BCH_CSUM_CRC32C);
SET_CACHE_SET_META_REPLICAS_WANT(cache_set_sb, 1);
SET_CACHE_SET_DATA_REPLICAS_WANT(cache_set_sb, 1);
bucket_sizes[0] = 1024;
while ((c = getopt_long(argc, argv,
"-hCBU:w:b:l:",
opts, NULL)) != -1) {
switch (c) {
case 'C':
bdev = 0;
break;
case 'B':
bdev = 1;
break;
case 'l':
label = optarg;
memcpy(cache_set_sb->label, label,
sizeof(cache_set_sb->label));
break;
case CACHE_SET_UUID:
if (uuid_parse(optarg, cache_set_sb->set_uuid.b)) {
fprintf(stderr, "Bad uuid\n");
exit(EXIT_FAILURE);
}
break;
case CSUM_TYPE:
SET_CACHE_PREFERRED_CSUM_TYPE(cache_set_sb,
read_string_list_or_die(optarg, csum_types,
"csum type"));
break;
case 'b':
bucket_sizes[num_bucket_sizes] = hatoi_validate(optarg, "bucket size");
num_bucket_sizes++;
break;
case 'w':
block_size = hatoi_validate(optarg, "block size");
break;
case REPLICATION_SET:
replication_set = strtoul_or_die(optarg,
CACHE_REPLICATION_SET_MAX,
"replication set");
break;
case META_REPLICAS:
SET_CACHE_SET_META_REPLICAS_WANT(cache_set_sb,
strtoul_or_die(optarg,
CACHE_SET_META_REPLICAS_WANT_MAX,
"meta replicas"));
break;
case DATA_REPLICAS:
SET_CACHE_SET_DATA_REPLICAS_WANT(cache_set_sb,
strtoul_or_die(optarg,
CACHE_SET_DATA_REPLICAS_WANT_MAX,
"data replicas"));
break;
case 't':
tier = strtoul_or_die(optarg, CACHE_TIERS, "tier");
break;
case 'p':
replacement_policy = read_string_list_or_die(optarg,
replacement_policies,
"cache replacement policy");
break;
case 'o':
data_offset = atoll(optarg);
if (data_offset < BDEV_DATA_START_DEFAULT) {
fprintf(stderr, "Bad data offset; minimum %d sectors\n",
BDEV_DATA_START_DEFAULT);
exit(EXIT_FAILURE);
}
break;
case 'h':
usage();
break;
case 1:
if (bdev == -1) {
fprintf(stderr, "Please specify -C or -B\n");
exit(EXIT_FAILURE);
}
if (bdev) {
backing_dev_labels[nr_backing_devices] = label;
backing_devices[nr_backing_devices++] = optarg;
} else {
cache_devices[cache_set_sb->nr_in_set] = optarg;
next_cache_device(cache_set_sb,
replication_set,
tier,
replacement_policy,
discard);
}
break;
}
}
if (!cache_set_sb->nr_in_set && !nr_backing_devices) {
fprintf(stderr, "Please supply a device\n");
usage();
}
i = 0;
do {
if (bucket_sizes[i] < block_size) {
fprintf(stderr, "Bucket size cannot be smaller than block size\n");
exit(EXIT_FAILURE);
}
i++;
} while (i < num_bucket_sizes);
if (!block_size) {
for (i = 0; i < cache_set_sb->nr_in_set; i++)
block_size = max(block_size,
get_blocksize(cache_devices[i]));
for (i = 0; i < nr_backing_devices; i++)
block_size = max(block_size,
get_blocksize(backing_devices[i]));
}
for (i = 0; i < cache_set_sb->nr_in_set; i++)
cache_dev_fd[i] = dev_open(cache_devices[i], wipe_bcache);
for (i = 0; i < nr_backing_devices; i++)
backing_dev_fd[i] = dev_open(backing_devices[i], wipe_bcache);
write_cache_sbs(cache_dev_fd, cache_set_sb, block_size,
bucket_sizes, num_bucket_sizes);
for (i = 0; i < nr_backing_devices; i++)
write_backingdev_sb(backing_dev_fd[i],
block_size, bucket_sizes,
writeback
? CACHE_MODE_WRITEBACK
: CACHE_MODE_WRITETHROUGH,
data_offset,
backing_dev_labels[i],
cache_set_sb->user_uuid,
cache_set_sb->set_uuid);
return 0;
}