]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
add -c to cmd_unlock, to check if a device needs to be unlocked
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 11 Feb 2018 17:35:15 +0000 (12:35 -0500)
committerKent Overstreet <kent.overstreet@gmail.com>
Sun, 11 Feb 2018 19:25:33 +0000 (14:25 -0500)
Makefile
cmd_key.c
crypto.c
crypto.h
initramfs/hook [new file with mode: 0755]
initramfs/script [new file with mode: 0755]

index 075257b89f1e25a734d90ea6e93295f27c95dc9c..e773b467862ce155e17c6c47c153148d9f7561ea 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -37,8 +37,10 @@ LDLIBS+=`pkg-config --libs   ${PKGCONFIG_LIBS}`              \
 
 ifeq ($(PREFIX),/usr)
        ROOT_SBINDIR=/sbin
+       INITRAMFS_DIR=$(PREFIX)/share/initramfs-tools
 else
        ROOT_SBINDIR=$(PREFIX)/sbin
+       INITRAMFS_DIR=/etc/initramfs-tools
 endif
 
 .PHONY: all
@@ -58,6 +60,9 @@ install: bcachefs
        $(INSTALL) -m0755 bcachefs      $(DESTDIR)$(ROOT_SBINDIR)
        $(INSTALL) -m0755 fsck.bcachefs $(DESTDIR)$(ROOT_SBINDIR)
        $(INSTALL) -m0755 mkfs.bcachefs $(DESTDIR)$(ROOT_SBINDIR)
+       $(INSTALL) -m0755 -D initramfs/hook $(DESTDIR)$(INITRAMFS_DIR)/hooks/bcachefs
+       echo "copy_exec $(ROOT_SBINDIR)/bcachefs /sbin/bcachefs" >> $(DESTDIR)$(INITRAMFS_DIR)/hooks/bcachefs
+       $(INSTALL) -m0755 -D initramfs/script $(DESTDIR)$(INITRAMFS_DIR)/scripts/local-premount/bcachefs
        $(INSTALL) -m0644 bcachefs.8    $(DESTDIR)$(PREFIX)/share/man/man8/
 
 .PHONY: clean
index e670b508a15c02587be1d6abfd113e24bf0a0111..0ca591c50f909e47471643f95ad91b2d717b9b60 100644 (file)
--- a/cmd_key.c
+++ b/cmd_key.c
@@ -7,23 +7,61 @@
 #include "crypto.h"
 #include "libbcachefs.h"
 
+static void unlock_usage(void)
+{
+       puts("bcachefs unlock - unlock an encrypted filesystem so it can be mounted\n"
+            "Usage: bcachefs unlock [OPTION] device\n"
+            "\n"
+            "Options:\n"
+            "  -c                     Check if a device is encrypted\n"
+            "  -h                     Display this help and exit\n"
+            "Report bugs to <linux-bcache@vger.kernel.org>");
+}
+
 int cmd_unlock(int argc, char *argv[])
 {
+       bool check = false;
+       int opt;
+
+       while ((opt = getopt(argc, argv, "ch")) != -1)
+               switch (opt) {
+               case 'c':
+                       check = true;
+                       break;
+               case 'h':
+                       unlock_usage();
+                       exit(EXIT_SUCCESS);
+               }
+       args_shift(optind);
+
+       char *dev = arg_pop();
+       if (!dev)
+               die("Please supply a device");
+
+       if (argc)
+               die("Too many arguments");
+
        struct bch_opts opts = bch2_opts_empty();
-       struct bch_sb_handle sb;
-       char *passphrase;
 
-       if (argc != 2)
-               die("Please supply a single device");
+       opt_set(opts, noexcl, true);
+       opt_set(opts, nochanges, true);
 
-       int ret = bch2_read_super(argv[1], &opts, &sb);
+       struct bch_sb_handle sb;
+       int ret = bch2_read_super(dev, &opts, &sb);
        if (ret)
-               die("Error opening %s: %s", argv[1], strerror(-ret));
+               die("Error opening %s: %s", dev, strerror(-ret));
+
+       if (!bch2_sb_is_encrypted(sb.sb))
+               die("%s is not encrypted", dev);
+
+       if (check)
+               exit(EXIT_SUCCESS);
 
-       passphrase = read_passphrase("Enter passphrase: ");
+       char *passphrase = read_passphrase("Enter passphrase: ");
 
        bch2_add_key(sb.sb, passphrase);
 
+       bch2_free_super(&sb);
        memzero_explicit(passphrase, strlen(passphrase));
        free(passphrase);
        return 0;
@@ -38,6 +76,12 @@ int cmd_set_passphrase(int argc, char *argv[])
                die("Please supply one or more devices");
 
        opt_set(opts, nostart, true);
+
+       /*
+        * we use bch2_fs_open() here, instead of just reading the superblock,
+        * to make sure we're opening and updating every component device:
+        */
+
        c = bch2_fs_open(argv + 1, argc - 1, opts);
        if (IS_ERR(c))
                die("Error opening %s: %s", argv[1], strerror(-PTR_ERR(c)));
index 0e18b36ff81aa6e4f535cea29c8bc6ba52df3db1..7f7fbd5a337ac8d04585f30cfc468720892d6037 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -100,6 +100,14 @@ struct bch_key derive_passphrase(struct bch_sb_field_crypt *crypt,
        return key;
 }
 
+bool bch2_sb_is_encrypted(struct bch_sb *sb)
+{
+       struct bch_sb_field_crypt *crypt;
+
+       return (crypt = bch2_sb_get_crypt(sb)) &&
+               bch2_key_is_encrypted(&crypt->key);
+}
+
 void bch2_passphrase_check(struct bch_sb *sb, const char *passphrase,
                           struct bch_key *passphrase_key,
                           struct bch_encrypted_key *sb_key)
index d6c206190d6e2880597046c522251356818d89f1..7f523c057cbbf3c9ad6a0b8a57b16b2296d95c52 100644 (file)
--- a/crypto.h
+++ b/crypto.h
@@ -12,6 +12,7 @@ char *read_passphrase(const char *);
 char *read_passphrase_twice(const char *);
 
 struct bch_key derive_passphrase(struct bch_sb_field_crypt *, const char *);
+bool bch2_sb_is_encrypted(struct bch_sb *);
 void bch2_passphrase_check(struct bch_sb *, const char *,
                           struct bch_key *, struct bch_encrypted_key *);
 void bch2_add_key(struct bch_sb *, const char *);
diff --git a/initramfs/hook b/initramfs/hook
new file mode 100755 (executable)
index 0000000..aa91469
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+PREREQ=""
+
+prereqs()
+{
+    echo "$PREREQ"
+}
+
+case $1 in
+prereqs)
+    prereqs
+    exit 0
+    ;;
+esac
+
+. /usr/share/initramfs-tools/hook-functions
+
diff --git a/initramfs/script b/initramfs/script
new file mode 100755 (executable)
index 0000000..bd64b41
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+PREREQ=""
+
+prereqs()
+{
+    echo "$PREREQ"
+}
+
+case $1 in
+# get pre-requisites
+prereqs)
+    prereqs
+    exit 0
+    ;;
+esac
+
+# Check if it needs unlocking:
+if bcachefs unlock -c $ROOT >/dev/null 2>&1; then
+    echo "Unlocking $ROOT:"
+
+    while true; do
+       bcachefs unlock $ROOT && break
+    done
+fi