summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--69-bcache.rules (renamed from 61-bcache.rules)18
-rw-r--r--Makefile30
-rw-r--r--bcache-register4
-rw-r--r--bcache-super-show.c56
-rw-r--r--bcache.h2
-rw-r--r--dracut/module-setup.sh34
-rwxr-xr-xinitramfs/bcache4
-rw-r--r--make-bcache.c77
-rw-r--r--probe-bcache.c16
9 files changed, 193 insertions, 48 deletions
diff --git a/61-bcache.rules b/69-bcache.rules
index dd85e69a..b83f6bc4 100644
--- a/61-bcache.rules
+++ b/69-bcache.rules
@@ -4,15 +4,19 @@
SUBSYSTEM!="block", GOTO="bcache_end"
ACTION=="remove", GOTO="bcache_end"
-# Backing devices: scan, symlink, register
-IMPORT{program}="/sbin/blkid -o udev $tempnode"
-# blkid and probe-bcache can disagree, in which case don't register
-ENV{ID_FS_TYPE}=="?*", ENV{ID_FS_TYPE}!="bcache", GOTO="bcache_backing_end"
+# blkid was run by the standard udev rules
+# It recognised bcache (util-linux 2.24+)
+ENV{ID_FS_TYPE}=="bcache", GOTO="bcache_backing_found"
+# It recognised something else; bail
+ENV{ID_FS_TYPE}=="?*", GOTO="bcache_backing_end"
-IMPORT{program}="/sbin/probe-bcache -o udev $tempnode"
+# Backing devices: scan, symlink, register
+IMPORT{program}="probe-bcache -o udev $tempnode"
+ENV{ID_FS_TYPE}!="bcache", GOTO="bcache_backing_end"
ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
-SUBSYSTEM=="block", ACTION=="add|change", ENV{ID_FS_TYPE}=="bcache", \
- RUN+="bcache-register $tempnode"
+
+LABEL="bcache_backing_found"
+RUN+="bcache-register $tempnode"
LABEL="bcache_backing_end"
# Cached devices: symlink
diff --git a/Makefile b/Makefile
index 10ec79c6..4f9f7c54 100644
--- a/Makefile
+++ b/Makefile
@@ -1,24 +1,32 @@
PREFIX=/usr
+UDEVLIBDIR=/lib/udev
+DRACUTLIBDIR=/lib/dracut
+INSTALL=install
CFLAGS+=-O2 -Wall -g
all: make-bcache probe-bcache bcache-super-show
install: make-bcache probe-bcache bcache-super-show
- install -m0755 make-bcache bcache-super-show $(DESTDIR)${PREFIX}/sbin/
- install -m0755 probe-bcache $(DESTDIR)/sbin/
- install -m0644 61-bcache.rules $(DESTDIR)/lib/udev/rules.d/
- install -m0755 bcache-register $(DESTDIR)/lib/udev/
- -install -m0755 initramfs/hook $(DESTDIR)/etc/initramfs-tools/hooks/bcache
- install -m0644 -- *.8 $(DESTDIR)${PREFIX}/share/man/man8
-# install -m0755 bcache-test $(DESTDIR)${PREFIX}/sbin/
+ $(INSTALL) -m0755 make-bcache bcache-super-show $(DESTDIR)${PREFIX}/sbin/
+ $(INSTALL) -m0755 probe-bcache bcache-register $(DESTDIR)$(UDEVLIBDIR)/
+ $(INSTALL) -m0644 69-bcache.rules $(DESTDIR)$(UDEVLIBDIR)/rules.d/
+ -$(INSTALL) -T -m0755 initramfs/hook $(DESTDIR)/usr/share/initramfs-tools/hooks/bcache
+ if [ -d $(DESTDIR)$(DRACUTLIBDIR)/modules.d ]; \
+ then $(INSTALL) -D -m0755 dracut/module-setup.sh $(DESTDIR)$(DRACUTLIBDIR)/modules.d/90bcache/module-setup.sh; \
+ fi
+ $(INSTALL) -m0644 -- *.8 $(DESTDIR)${PREFIX}/share/man/man8/
+# $(INSTALL) -m0755 bcache-test $(DESTDIR)${PREFIX}/sbin/
clean:
$(RM) -f make-bcache probe-bcache bcache-super-show bcache-test *.o
-bcache-test: LDLIBS += -lm -lssl -lcrypto
-make-bcache: LDLIBS += -luuid
+bcache-test: LDLIBS += `pkg-config --libs openssl`
+make-bcache: LDLIBS += `pkg-config --libs uuid blkid`
+make-bcache: CFLAGS += `pkg-config --cflags uuid blkid`
make-bcache: bcache.o
-probe-bcache: LDLIBS += -luuid
-bcache-super-show: LDLIBS += -luuid
+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-super-show: CFLAGS += -std=gnu99
bcache-super-show: bcache.o
diff --git a/bcache-register b/bcache-register
index bf93c7f9..9b592bcd 100644
--- a/bcache-register
+++ b/bcache-register
@@ -1,4 +1,4 @@
#!/bin/sh
-modprobe -qba bcache
-test -f /sys/fs/bcache/register && echo "$1" > /sys/fs/bcache/register
+/sbin/modprobe -qba bcache
+test -f /sys/fs/bcache/register_quiet && echo "$1" > /sys/fs/bcache/register_quiet
diff --git a/bcache-super-show.c b/bcache-super-show.c
index fab5e810..26cc40ed 100644
--- a/bcache-super-show.c
+++ b/bcache-super-show.c
@@ -4,6 +4,7 @@
* GPLv2
*/
+
#define _FILE_OFFSET_BITS 64
#define __USE_FILE_OFFSET64
#define _XOPEN_SOURCE 500
@@ -32,6 +33,29 @@ static void usage()
}
+static bool accepted_char(char c)
+{
+ if ('0' <= c && c <= '9')
+ return true;
+ if ('A' <= c && c <= 'Z')
+ return true;
+ if ('a' <= c && c <= 'z')
+ return true;
+ if (strchr(".-_", c))
+ return true;
+ return false;
+}
+
+static void print_encode(char* in)
+{
+ for (char* pos = in; *pos; pos++)
+ if (accepted_char(*pos))
+ putchar(*pos);
+ else
+ printf("%%%x", *pos);
+}
+
+
int main(int argc, char **argv)
{
bool force_csum = false;
@@ -123,6 +147,16 @@ int main(int argc, char **argv)
putchar('\n');
+ char label[SB_LABEL_SIZE + 1];
+ strncpy(label, (char*)sb.label, SB_LABEL_SIZE);
+ label[SB_LABEL_SIZE] = '\0';
+ printf("dev.label\t\t");
+ if (*label)
+ print_encode(label);
+ else
+ printf("(empty)");
+ putchar('\n');
+
uuid_unparse(sb.uuid, uuid);
printf("dev.uuid\t\t%s\n", uuid);
@@ -136,13 +170,31 @@ int main(int argc, char **argv)
printf("dev.cache.first_sector\t%u\n"
"dev.cache.cache_sectors\t%ju\n"
"dev.cache.total_sectors\t%ju\n"
+ "dev.cache.ordered\t%s\n"
"dev.cache.discard\t%s\n"
- "dev.cache.pos\t\t%u\n",
+ "dev.cache.pos\t\t%u\n"
+ "dev.cache.replacement\t%ju",
sb.bucket_size * sb.first_bucket,
sb.bucket_size * (sb.nbuckets - sb.first_bucket),
sb.bucket_size * sb.nbuckets,
+ CACHE_SYNC(&sb) ? "yes" : "no",
CACHE_DISCARD(&sb) ? "yes" : "no",
- sb.nr_this_dev);
+ sb.nr_this_dev,
+ CACHE_REPLACEMENT(&sb));
+ switch (CACHE_REPLACEMENT(&sb)) {
+ case CACHE_REPLACEMENT_LRU:
+ printf(" [lru]\n");
+ break;
+ case CACHE_REPLACEMENT_FIFO:
+ printf(" [fifo]\n");
+ break;
+ case CACHE_REPLACEMENT_RANDOM:
+ printf(" [random]\n");
+ break;
+ default:
+ putchar('\n');
+ }
+
} else {
uint64_t first_sector;
if (sb.version == BCACHE_SB_VERSION_BDEV) {
diff --git a/bcache.h b/bcache.h
index 1d78da3b..61e42524 100644
--- a/bcache.h
+++ b/bcache.h
@@ -115,7 +115,7 @@ BITMASK(BDEV_STATE, struct cache_sb, flags, 61, 2);
#define BDEV_STATE_DIRTY 2U
#define BDEV_STATE_STALE 3U
-inline uint64_t crc64(const void *_data, size_t len);
+uint64_t crc64(const void *_data, size_t len);
#define node(i, j) ((void *) ((i)->d + (j)))
#define end(i) node(i, (i)->keys)
diff --git a/dracut/module-setup.sh b/dracut/module-setup.sh
new file mode 100644
index 00000000..5a067cb0
--- /dev/null
+++ b/dracut/module-setup.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+
+#
+# At some point (util-linux v2.24) blkid will be able to identify bcache
+# but until every system has this version of util-linux, probe-bcache is
+# provided as an alternative.
+#
+
+check() {
+ if [[ $hostonly ]] || [[ $mount_needs ]]
+ then
+ for fs in "${host_fs_types[@]}"; do
+ [[ $fs = "bcache" ]] && return 0
+ done
+ return 255
+ fi
+
+ return 0
+}
+
+depends() {
+ return 0
+}
+
+installkernel() {
+ instmods bcache
+}
+
+install() {
+ inst_multiple ${udevdir}/probe-bcache ${udevdir}/bcache-register
+ inst_rules 69-bcache.rules
+}
diff --git a/initramfs/bcache b/initramfs/bcache
index ce328f3a..e618e1a5 100755
--- a/initramfs/bcache
+++ b/initramfs/bcache
@@ -16,7 +16,7 @@ esac
. /usr/share/initramfs-tools/hook-functions
-cp -pt "${DESTDIR}/lib/udev/rules.d" /lib/udev/rules.d/61-bcache.rules
+cp -pt "${DESTDIR}/lib/udev/rules.d" /lib/udev/rules.d/69-bcache.rules
copy_exec /lib/udev/bcache-register
-copy_exec /sbin/probe-bcache
+copy_exec /lib/udev/probe-bcache
manual_add_modules bcache
diff --git a/make-bcache.c b/make-bcache.c
index 30b49638..9e55fac1 100644
--- a/make-bcache.c
+++ b/make-bcache.c
@@ -8,6 +8,7 @@
#define __USE_FILE_OFFSET64
#define _XOPEN_SOURCE 600
+#include <blkid.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -76,19 +77,19 @@ unsigned hatoi_validate(const char *s, const char *msg)
uint64_t v = hatoi(s);
if (v & (v - 1)) {
- printf("%s must be a power of two\n", msg);
+ fprintf(stderr, "%s must be a power of two\n", msg);
exit(EXIT_FAILURE);
}
v /= 512;
if (v > USHRT_MAX) {
- printf("%s too large\n", msg);
+ fprintf(stderr, "%s too large\n", msg);
exit(EXIT_FAILURE);
}
if (!v) {
- printf("%s too small\n", msg);
+ fprintf(stderr, "%s too small\n", msg);
exit(EXIT_FAILURE);
}
@@ -143,7 +144,8 @@ ssize_t read_string_list(const char *buf, const char * const list[])
void usage()
{
- printf("Usage: make-bcache [options] device\n"
+ fprintf(stderr,
+ "Usage: make-bcache [options] device\n"
" -C, --cache Format a cache device\n"
" -B, --bdev Format a backing device\n"
" -b, --bucket bucket size\n"
@@ -166,18 +168,42 @@ const char * const cache_replacement_policies[] = {
};
static void write_sb(char *dev, unsigned block_size, unsigned bucket_size,
- bool writeback, bool discard,
+ bool writeback, bool discard, bool wipe_bcache,
unsigned cache_replacement_policy,
uint64_t data_offset,
uuid_t set_uuid, bool bdev,
uint16_t nr_in_set, uint16_t nr_this_dev)
{
int fd;
- char uuid_str[40], set_uuid_str[40];
+ char uuid_str[40], set_uuid_str[40], zeroes[SB_START] = {0};
struct cache_sb sb;
+ blkid_probe pr;
if ((fd = open(dev, O_RDWR|O_EXCL)) == -1) {
- printf("Can't open dev %s: %s\n", dev, strerror(errno));
+ fprintf(stderr, "Can't open dev %s: %s\n", dev, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb))
+ exit(EXIT_FAILURE);
+
+ if (!memcmp(sb.magic, bcache_magic, 16) && !wipe_bcache) {
+ fprintf(stderr, "Already a bcache device on %s, "
+ "overwrite with --wipe-bcache\n", dev);
+ exit(EXIT_FAILURE);
+ }
+
+ if (!(pr = blkid_new_probe()))
+ exit(EXIT_FAILURE);
+ if (blkid_probe_set_device(pr, fd, 0, 0))
+ exit(EXIT_FAILURE);
+ /* enable ptable probing; superblock probing is enabled by default */
+ if (blkid_probe_enable_partitions(pr, true))
+ exit(EXIT_FAILURE);
+ if (!blkid_do_probe(pr)) {
+ /* XXX wipefs doesn't know how to remove partition tables */
+ fprintf(stderr, "Device %s already has a non-bcache superblock, "
+ "remove it using wipefs and wipefs -a\n", dev);
exit(EXIT_FAILURE);
}
@@ -223,7 +249,7 @@ static void write_sb(char *dev, unsigned block_size, unsigned bucket_size,
sb.first_bucket = (23 / sb.bucket_size) + 1;
if (sb.nbuckets < 1 << 7) {
- printf("Not enough buckets: %ju, need %u\n",
+ fprintf(stderr, "Not enough buckets: %ju, need %u\n",
sb.nbuckets, 1 << 7);
exit(EXIT_FAILURE);
}
@@ -252,7 +278,13 @@ static void write_sb(char *dev, unsigned block_size, unsigned bucket_size,
sb.csum = csum_set(&sb);
- if (pwrite(fd, &sb, sizeof(sb), SB_SECTOR << 9) != sizeof(sb)) {
+ /* Zero start of disk */
+ if (pwrite(fd, zeroes, SB_START, 0) != SB_START) {
+ perror("write error\n");
+ exit(EXIT_FAILURE);
+ }
+ /* Write superblock */
+ if (pwrite(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
perror("write error\n");
exit(EXIT_FAILURE);
}
@@ -313,7 +345,7 @@ int main(int argc, char **argv)
char *backing_devices[argc];
unsigned block_size = 0, bucket_size = 1024;
- int writeback = 0, discard = 0;
+ int writeback = 0, discard = 0, wipe_bcache = 0;
unsigned cache_replacement_policy = 0;
uint64_t data_offset = BDEV_DATA_START_DEFAULT;
uuid_t set_uuid;
@@ -326,6 +358,7 @@ int main(int argc, char **argv)
{ "bucket", 1, NULL, 'b' },
{ "block", 1, NULL, 'w' },
{ "writeback", 0, &writeback, 1 },
+ { "wipe-bcache", 0, &wipe_bcache, 1 },
{ "discard", 0, &discard, 1 },
{ "cache_replacement_policy", 1, NULL, 'p' },
{ "data_offset", 1, NULL, 'o' },
@@ -353,7 +386,7 @@ int main(int argc, char **argv)
#if 0
case 'U':
if (uuid_parse(optarg, sb.uuid)) {
- printf("Bad uuid\n");
+ fprintf(stderr, "Bad uuid\n");
exit(EXIT_FAILURE);
}
break;
@@ -365,14 +398,14 @@ int main(int argc, char **argv)
case 'o':
data_offset = atoll(optarg);
if (data_offset < BDEV_DATA_START_DEFAULT) {
- printf("Bad data offset; minimum %d sectors\n",
+ fprintf(stderr, "Bad data offset; minimum %d sectors\n",
BDEV_DATA_START_DEFAULT);
exit(EXIT_FAILURE);
}
break;
case 'u':
if (uuid_parse(optarg, set_uuid)) {
- printf("Bad uuid\n");
+ fprintf(stderr, "Bad uuid\n");
exit(EXIT_FAILURE);
}
break;
@@ -381,7 +414,7 @@ int main(int argc, char **argv)
break;
case 1:
if (bdev == -1) {
- printf("Please specify -C or -B\n");
+ fprintf(stderr, "Please specify -C or -B\n");
exit(EXIT_FAILURE);
}
@@ -393,12 +426,12 @@ int main(int argc, char **argv)
}
if (!ncache_devices && !nbacking_devices) {
- printf("Please supply a device\n");
+ fprintf(stderr, "Please supply a device\n");
usage();
}
if (bucket_size < block_size) {
- printf("Bucket size cannot be smaller than block size\n");
+ fprintf(stderr, "Bucket size cannot be smaller than block size\n");
exit(EXIT_FAILURE);
}
@@ -414,15 +447,15 @@ int main(int argc, char **argv)
for (i = 0; i < ncache_devices; i++)
write_sb(cache_devices[i], block_size, bucket_size,
- writeback, discard, cache_replacement_policy,
- data_offset, set_uuid, false,
- ncache_devices, i);
+ writeback, discard, wipe_bcache,
+ cache_replacement_policy, data_offset,
+ set_uuid, false, ncache_devices, i);
for (i = 0; i < nbacking_devices; i++)
write_sb(backing_devices[i], block_size, bucket_size,
- writeback, discard, cache_replacement_policy,
- data_offset, set_uuid, true,
- nbacking_devices, i);
+ writeback, discard, wipe_bcache,
+ cache_replacement_policy, data_offset,
+ set_uuid, true, nbacking_devices, i);
return 0;
}
diff --git a/probe-bcache.c b/probe-bcache.c
index caff7b65..c94c9722 100644
--- a/probe-bcache.c
+++ b/probe-bcache.c
@@ -8,6 +8,7 @@
#define __USE_FILE_OFFSET64
#define _XOPEN_SOURCE 500
+#include <blkid.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <stdbool.h>
@@ -30,6 +31,7 @@ int main(int argc, char **argv)
extern char *optarg;
struct cache_sb sb;
char uuid[40];
+ blkid_probe pr;
while ((o = getopt(argc, argv, "o:")) != EOF)
switch (o) {
@@ -51,8 +53,20 @@ int main(int argc, char **argv)
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), 4096) != sizeof(sb))
+ if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb))
continue;
if (memcmp(sb.magic, bcache_magic, 16))