From b75724ce4b0e79df48994f42ebf31b861b2a3a33 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Wed, 25 Nov 2015 12:40:47 +0000 Subject: main/mkinitfs: fix cryptsetup on lvm fixes #4863 --- main/mkinitfs/APKBUILD | 14 +-- main/mkinitfs/git.patch | 268 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 224 insertions(+), 58 deletions(-) (limited to 'main/mkinitfs') diff --git a/main/mkinitfs/APKBUILD b/main/mkinitfs/APKBUILD index eefd14f194..36c069a784 100644 --- a/main/mkinitfs/APKBUILD +++ b/main/mkinitfs/APKBUILD @@ -1,11 +1,11 @@ # Maintainer: Natanael Copa pkgname=mkinitfs -pkgver=2.8.0_git20151024 +pkgver=2.8.0_git20151025 _ver=${pkgver%_git*} -pkgrel=2 +pkgrel=0 pkgdesc="Tool to generate initramfs images for Alpine" -url=http://git.alpinelinux.org/cgit/mkinitfs -makedepends="kmod-dev util-linux-dev linux-headers" +url="http://git.alpinelinux.org/cgit/mkinitfs" +makedepends="kmod-dev util-linux-dev cryptsetup-dev linux-headers" depends="acct busybox apk-tools>=2.0 lddtree>=1.25" install="$pkgname.pre-upgrade $pkgname.post-install $pkgname.post-upgrade" triggers="$pkgname.trigger=/usr/share/kernel/*" @@ -37,8 +37,8 @@ package() { make install DESTDIR="$pkgdir" || return 1 } md5sums="1a321336d97b22257349ddd36884ec34 mkinitfs-2.8.0.tar.xz -960550bde89e96cc6f9583fb47f05bea git.patch" +141a0411c74ac7533162b8a4007e2004 git.patch" sha256sums="5ffe4c5ec9e0ff4581e5b24301fd30d0964120d6b30ee78ea79f31ff48eeab73 mkinitfs-2.8.0.tar.xz -2cda01897e16116e8dc10e8a76dbb64721f8a5764854b89a944773463f5d28b7 git.patch" +525507c490490fd622b4f8760d212f2552570bebcdb974641d3aff65181854e5 git.patch" sha512sums="c103003f95c7d7d94daa41d0a81b210a0208c93d77203978554fb127a21e2f143b56990865fc53e2c5c732ef663603b297da63d31f915b1e3a3e0f3818aa8f2e mkinitfs-2.8.0.tar.xz -204ce7710ee4b807b1f6ef0a117f01a24b6edc90b0bc47c8b83827716f27f1491bb350e2ac36fd2aa4efffeb797edf331362c29fca2d2be966c0abe7fa09a427 git.patch" +bdd182ef4fcd82c99f658e53c9c406bb7ad16ad6c19d3a11397699ed57c52d3e05e9d927807e02fd8980b5948fc5c37d184303a6d22b075e6b23aa5b8567af11 git.patch" diff --git a/main/mkinitfs/git.patch b/main/mkinitfs/git.patch index 7c51287287..a1ba95cbe0 100644 --- a/main/mkinitfs/git.patch +++ b/main/mkinitfs/git.patch @@ -1,5 +1,5 @@ diff --git a/Makefile b/Makefile -index aaa553e..a62c294 100644 +index aaa553e..5ce1962 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ sysconfdir ?= /etc/mkinitfs @@ -11,7 +11,14 @@ index aaa553e..a62c294 100644 SHARE_FILES := initramfs-init fstab passwd group CONF_FILES := mkinitfs.conf \ features.d/ata.modules \ -@@ -32,6 +32,7 @@ CONF_FILES := mkinitfs.conf \ +@@ -25,13 +25,13 @@ CONF_FILES := mkinitfs.conf \ + features.d/gfs2.modules \ + features.d/jfs.modules \ + features.d/keymap.files \ +- features.d/kms.files \ + features.d/kms.modules \ + features.d/lvm.files \ + features.d/lvm.modules \ features.d/network.files \ features.d/network.modules \ features.d/ocfs2.modules \ @@ -19,7 +26,7 @@ index aaa553e..a62c294 100644 features.d/raid.modules \ features.d/reiserfs.modules \ features.d/scsi.modules \ -@@ -41,7 +42,7 @@ CONF_FILES := mkinitfs.conf \ +@@ -41,7 +41,7 @@ CONF_FILES := mkinitfs.conf \ features.d/virtio.modules \ features.d/xfs.modules @@ -28,7 +35,7 @@ index aaa553e..a62c294 100644 IN_FILES := $(addsuffix .in,$(SCRIPTS)) GIT_REV := $(shell test -d .git && git describe || echo exported) -@@ -62,7 +63,8 @@ SED_REPLACE := -e 's:@VERSION@:$(FULL_VERSION):g' \ +@@ -62,7 +62,8 @@ SED_REPLACE := -e 's:@VERSION@:$(FULL_VERSION):g' \ -e 's:@datadir@:$(datadir):g' @@ -38,7 +45,7 @@ index aaa553e..a62c294 100644 clean: rm -f $(SCRIPTS) -@@ -71,6 +73,24 @@ help: +@@ -71,6 +72,26 @@ help: @echo mkinitfs $(VERSION) @echo "usage: make install [DESTDIR=]" @@ -50,9 +57,11 @@ index aaa553e..a62c294 100644 +BLKID_LIBS := $(shell $(PKGCONF) --libs blkid) +LIBKMOD_CFLAGS := $(shell $(PKGCONF) --cflags libkmod) +LIBKMOD_LIBS := $(shell $(PKGCONF) --libs libkmod) ++CRYPTSETUP_CFLAGS := $(shell $(PKGCONF) --cflags libcryptsetup) ++CRYPTSETUP_LIBS := $(shell $(PKGCONF) --libs libcryptsetup) + -+CFLAGS += $(BLKID_CFLAGS) $(LIBKMOD_CFLAGS) -+LIBS = $(BLKID_LIBS) $(LIBKMOD_LIBS) ++CFLAGS += $(BLKID_CFLAGS) $(LIBKMOD_CFLAGS) $(CRYPTSETUP_CFLAGS) ++LIBS = $(BLKID_LIBS) $(LIBKMOD_LIBS) $(CRYPTSETUP_LIBS) + +%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< @@ -199,6 +208,13 @@ index 8adf4df..6f28294 100644 /usr/sbin/accton /usr/sbin/sa - +diff --git a/features.d/kms.files b/features.d/kms.files +deleted file mode 100644 +index 9d198b2..0000000 +--- a/features.d/kms.files ++++ /dev/null +@@ -1 +0,0 @@ +-lib/firmware/radeon/*.bin diff --git a/features.d/lvm.modules b/features.d/lvm.modules index 92f0721..3af8ef9 100644 --- a/features.d/lvm.modules @@ -796,7 +812,7 @@ index 35cc96a..67a5444 100644 -features="ata base bootchart cdrom cramfs ext2 ext3 ext4 floppy keymap kms raid scsi usb virtio" +features="ata base cdrom ext2 ext3 ext4 keymap kms mmc raid scsi usb virtio" diff --git a/mkinitfs.in b/mkinitfs.in -index 04dc99c..14c728f 100755 +index 04dc99c..c5f6434 100755 --- a/mkinitfs.in +++ b/mkinitfs.in @@ -36,7 +36,7 @@ feature_files() { @@ -808,7 +824,7 @@ index 04dc99c..14c728f 100755 etc/apk media/floppy media/usb newroot; do dirs="$dirs $tmpdir/$i" done -@@ -115,6 +115,11 @@ initfs_kmods() { +@@ -115,10 +115,24 @@ initfs_kmods() { for file in $(find_kmods); do echo "${file#/}" done | sort -u | cpio -pdm "$tmpdir" || return 1 @@ -820,7 +836,20 @@ index 04dc99c..14c728f 100755 depmod $kernel -b "$tmpdir" cd "$oldpwd" } -@@ -179,7 +184,7 @@ done + ++initfs_firmware() { ++ rm -rf "$tmpdir"/lib/firmware ++ mkdir -p "$tmpdir"/lib/firmware ++ find "$tmpdir"/lib/modules -type f -name "*.ko" | xargs modinfo -F firmware | sort -u | while read FW; do ++ [ -e "${basedir}/lib/firmware/${FW}" ] && install -pD "${basedir}/lib/firmware/${FW}" "$tmpdir"/lib/firmware/$FW ++ done ++ return 0 ++} ++ + initfs_apk_keys() { + mkdir -p "$tmpdir"/etc/apk/keys + cp "${basedir}etc/apk/keys/"* "$tmpdir"/etc/apk/keys/ +@@ -179,7 +193,7 @@ done shift $(( $OPTIND - 1 )) . $(readlink -f "$config") @@ -829,12 +858,20 @@ index 04dc99c..14c728f 100755 [ -n "$myfeatures" ] && features="$myfeatures" if [ -n "$list_features" ]; then +@@ -232,6 +246,7 @@ fi + + initfs_base \ + && initfs_kmods \ ++ && initfs_firmware \ + && initfs_apk_keys \ + && initfs_cpio + rc=$? diff --git a/nlplug-findfs.c b/nlplug-findfs.c new file mode 100644 -index 0000000..5f6dc5e +index 0000000..27b9ce2 --- /dev/null +++ b/nlplug-findfs.c -@@ -0,0 +1,888 @@ +@@ -0,0 +1,1017 @@ + +/* + * Copy me if you can. @@ -857,6 +894,7 @@ index 0000000..5f6dc5e +#include +#include +#include ++#include +#include + +#include @@ -872,6 +910,7 @@ index 0000000..5f6dc5e + +#include +#include ++#include + +#include "arg.h" + @@ -882,9 +921,16 @@ index 0000000..5f6dc5e +#define FOUND_BOOTREPO 0x2 +#define FOUND_APKOVL 0x4 + ++#define TRIGGER_THREAD 0x1 ++#define CRYPTSETUP_THREAD 0x2 ++ ++#define LVM_PATH "/sbin/lvm" ++#define MDADM_PATH "/sbin/mdadm" ++ +static int dodebug; +static char *default_envp[2]; +char *argv0; ++static int use_mdadm, use_lvm; + +#if defined(DEBUG) +#include @@ -1025,12 +1071,17 @@ index 0000000..5f6dc5e + char *search_device; + char *crypt_device; + char *crypt_name; ++ char crypt_devnode[256]; + char *subsystem_filter; + int modalias_count; + int fork_count; + char *bootrepos; + char *apkovls; + int timeout; ++ int efd; ++ unsigned running_threads; ++ pthread_t cryptsetup_tid; ++ pthread_mutex_t cryptsetup_mutex; +}; + + @@ -1139,33 +1190,111 @@ index 0000000..5f6dc5e +static void start_mdadm(char *devnode) +{ + char *mdadm_argv[] = { -+ "/sbin/mdadm", ++ MDADM_PATH, + "--incremental", + "--quiet", + devnode, + NULL + }; -+ spawn_command(&spawnmgr, mdadm_argv, 0); ++ if (use_mdadm) ++ spawn_command(&spawnmgr, mdadm_argv, 0); +} + +static void start_lvm2(char *devnode) +{ + char *lvm2_argv[] = { -+ "/sbin/lvm", "vgchange", -+ "--activate" , "ay", "--noudevsync", "--sysinit", ++ LVM_PATH, "vgchange", ++ "--activate" , "ay", "--noudevsync", "--sysinit", "-q", "-q", + NULL + }; -+ spawn_command(&spawnmgr, lvm2_argv, 0); ++ if (use_lvm) ++ spawn_command(&spawnmgr, lvm2_argv, 0); +} + -+static void start_cryptsetup(char *devnode, char *cryptdm) ++ ++static int read_pass(char *pass, size_t pass_size) +{ -+ char *cryptsetup_argv[] = { -+ "/sbin/cryptsetup", "luksOpen", -+ devnode, cryptdm ? cryptdm : "crypdm", NULL -+ }; ++ struct termios old_flags, new_flags; ++ int r; ++ ++ tcgetattr(STDIN_FILENO, &old_flags); ++ new_flags = old_flags; ++ new_flags.c_lflag &= ~ECHO; ++ new_flags.c_lflag |= ECHONL; ++ ++ r = tcsetattr(STDIN_FILENO, TCSANOW, &new_flags); ++ if (r < 0) { ++ warn("tcsetattr"); ++ return r; ++ } ++ ++ if (fgets(pass, pass_size, stdin) == NULL) { ++ warn("fgets"); ++ return -1; ++ } ++ pass[strlen(pass) - 1] = '\0'; ++ ++ if (tcsetattr(STDIN_FILENO, TCSANOW, &old_flags) < 0) { ++ warn("tcsetattr"); ++ return r; ++ } ++ ++ return 0; ++} ++ ++static void *cryptsetup_thread(void *data) ++{ ++ struct ueventconf *c = (struct ueventconf *)data; ++ uint64_t ok = CRYPTSETUP_THREAD; ++ struct crypt_device *cd; ++ int r, passwd_tries = 5; ++ ++ r = crypt_init(&cd, c->crypt_devnode); ++ if (r < 0) { ++ warnx("crypt_init(%s)", c->crypt_devnode); ++ goto notify_out; ++ } ++ ++ r = crypt_load(cd , CRYPT_LUKS1, NULL); ++ if (r < 0) { ++ warnx("crypt_load(%s)", c->crypt_devnode); ++ goto free_out; ++ } ++ ++ while (passwd_tries > 0) { ++ char pass[1024]; ++ ++ printf("Enter passphrase for %s: ", c->crypt_devnode); ++ fflush(stdout); ++ ++ if (read_pass(pass, sizeof(pass)) < 0) ++ goto free_out; ++ passwd_tries--; ++ ++ pthread_mutex_lock(&c->cryptsetup_mutex); ++ r = crypt_activate_by_passphrase(cd, c->crypt_name, ++ CRYPT_ANY_SLOT, ++ pass, strlen(pass), 0); ++ pthread_mutex_unlock(&c->cryptsetup_mutex); ++ ++ if (r == 0) ++ break; ++ printf("No key available with this passphrase.\n"); ++ } ++ ++free_out: ++ crypt_free(cd); ++notify_out: ++ write(c->efd, &ok, sizeof(ok)); ++ return NULL; ++} ++ ++static void start_cryptsetup(struct ueventconf *conf) ++{ ++ dbg("starting cryptsetup %s -> %s", conf->crypt_devnode, conf->crypt_name); + load_kmod("dm-crypt"); -+ spawn_command(&spawnmgr, cryptsetup_argv, 0); ++ pthread_create(&conf->cryptsetup_tid, NULL, cryptsetup_thread, conf); ++ conf->running_threads |= CRYPTSETUP_THREAD; +} + +static int is_mounted(const char *devnode) { @@ -1343,35 +1472,50 @@ index 0000000..5f6dc5e + return rc; +} + -+static int searchdev(char *devname, const char *searchdev, char *bootrepos, ++static int is_same_device(const struct uevent *ev, const char *nodepath) ++{ ++ struct stat st; ++ unsigned int maj, min; ++ if (stat(nodepath, &st) < 0) ++ return 0; ++ ++ if (ev->major == NULL || ev->minor == NULL) ++ return 0; ++ ++ maj = atoi(ev->major); ++ min = atoi(ev->minor); ++ return S_ISBLK(st.st_mode) && makedev(maj, min) == st.st_rdev; ++} ++ ++ ++static int searchdev(struct uevent *ev, const char *searchdev, char *bootrepos, + const char *apkovls) +{ + static blkid_cache cache = NULL; + char *type = NULL, *label = NULL, *uuid = NULL; -+ char devnode[256]; + int rc = 0; + + if (searchdev == NULL && bootrepos == NULL && apkovls == NULL) + return 0; + -+ snprintf(devnode, sizeof(devnode), "/dev/%s", devname); -+ if (searchdev && (strcmp(devname, searchdev) == 0 -+ || strcmp(devnode, searchdev) == 0)) { ++ if (searchdev && (strcmp(ev->devname, searchdev) == 0 ++ || strcmp(ev->devnode, searchdev) == 0 ++ || is_same_device(ev, searchdev))) { + return FOUND_DEVICE; + } + + if (cache == NULL) + blkid_get_cache(&cache, NULL); + -+ type = blkid_get_tag_value(cache, "TYPE", devnode); ++ type = blkid_get_tag_value(cache, "TYPE", ev->devnode); + + if (searchdev != NULL) { + if (strncmp("LABEL=", searchdev, 6) == 0) { -+ label = blkid_get_tag_value(cache, "LABEL", devnode); ++ label = blkid_get_tag_value(cache, "LABEL", ev->devnode); + if (label && strcmp(label, searchdev+6) == 0) + rc = FOUND_DEVICE; + } else if (strncmp("UUID=", searchdev, 5) == 0) { -+ uuid = blkid_get_tag_value(cache, "UUID", devnode); ++ uuid = blkid_get_tag_value(cache, "UUID", ev->devnode); + if (uuid && strcmp(uuid, searchdev+5) == 0) + rc = FOUND_DEVICE; + } @@ -1381,7 +1525,7 @@ index 0000000..5f6dc5e + dbg("%s:\n" + "\ttype='%s'\n" + "\tlabel='%s'\n" -+ "\tuuid='%s'\n", devnode, ++ "\tuuid='%s'\n", ev->devnode, + type ? type : NULL, + label ? label : NULL, + uuid ? uuid : NULL); @@ -1389,11 +1533,11 @@ index 0000000..5f6dc5e + + if (!rc && type) { + if (strcmp("linux_raid_member", type) == 0) { -+ start_mdadm(devnode); ++ start_mdadm(ev->devnode); + } else if (strcmp("LVM2_member", type) == 0) { -+ start_lvm2(devnode); ++ start_lvm2(ev->devnode); + } else if (bootrepos) { -+ rc = find_bootrepos(devnode, type, bootrepos, apkovls); ++ rc = find_bootrepos(ev->devnode, type, bootrepos, apkovls); + } + } + @@ -1441,14 +1585,19 @@ index 0000000..5f6dc5e + + snprintf(ev->devnode, sizeof(ev->devnode), "/dev/%s", + ev->devname); -+ rc = searchdev(ev->devname, conf->search_device, ++ pthread_mutex_lock(&conf->cryptsetup_mutex); ++ rc = searchdev(ev, conf->search_device, + conf->bootrepos, conf->apkovls); ++ pthread_mutex_unlock(&conf->cryptsetup_mutex); + if (rc) + return rc; + -+ if (searchdev(ev->devname, conf->crypt_device, NULL, -+ NULL)) -+ start_cryptsetup(ev->devnode, conf->crypt_name); ++ if (searchdev(ev, conf->crypt_device, NULL, NULL)) { ++ strncpy(conf->crypt_devnode, ++ conf->crypt_device[0] == '/' ? conf->crypt_device : ev->devnode, ++ sizeof(conf->crypt_devnode)); ++ start_cryptsetup(conf); ++ } + } + } + return 0; @@ -1517,7 +1666,7 @@ index 0000000..5f6dc5e +static void *trigger_thread(void *data) +{ + int fd = *(int *)data; -+ uint64_t ok = 1; ++ uint64_t ok = TRIGGER_THREAD; + struct recurse_opts opts = { + .searchname = "uevent", + .callback = trigger_uevent_cb, @@ -1560,7 +1709,7 @@ index 0000000..5f6dc5e + struct ueventconf conf; + int event_count = 0; + size_t total_bytes = 0; -+ int found = 0, trigger_running = 0; ++ int found = 0; + char *program_argv[2] = {0,0}; + pthread_t tid; + sigset_t sigchldmask; @@ -1573,6 +1722,9 @@ index 0000000..5f6dc5e + memset(&conf, 0, sizeof(conf)); + conf.program_argv = program_argv; + conf.timeout = DEFAULT_EVENT_TIMEOUT; ++ use_lvm = access(LVM_PATH, X_OK) == 0; ++ use_mdadm = access(MDADM_PATH, X_OK) == 0; ++ + argv0 = strrchr(argv[0], '/'); + if (argv0++ == NULL) + argv0 = argv[0]; @@ -1612,6 +1764,10 @@ index 0000000..5f6dc5e + if (argc > 0) + conf.search_device = argv[0]; + ++ r = pthread_mutex_init(&conf.cryptsetup_mutex, NULL); ++ if (r < 0) ++ err(1, "pthread_mutex_init"); ++ + initsignals(); + sigemptyset(&sigchldmask); + sigaddset(&sigchldmask, SIGCHLD); @@ -1625,18 +1781,19 @@ index 0000000..5f6dc5e + + fds[2].fd = eventfd(0, EFD_CLOEXEC); + fds[2].events = POLLIN; ++ conf.efd = fds[2].fd; + pthread_create(&tid, NULL, trigger_thread, &fds[2].fd); -+ trigger_running = 1; ++ conf.running_threads |= TRIGGER_THREAD; + + while (1) { -+ r = poll(fds, numfds, (spawn_active(&spawnmgr) || trigger_running) ? -1 : conf.timeout); ++ r = poll(fds, numfds, (spawn_active(&spawnmgr) || conf.running_threads) ? -1 : conf.timeout); + if (r == -1) { + if (errno == EINTR || errno == ERESTART) + continue; + err(1, "poll"); + } + if (r == 0) { -+ dbg("exit due to timeout"); ++ dbg("exit due to timeout (%i)", conf.timeout); + break; + } + @@ -1685,7 +1842,8 @@ index 0000000..5f6dc5e + if ((found & FOUND_DEVICE) + || ((found & FOUND_BOOTREPO) && + (found & FOUND_APKOVL))) { -+ dbg("setting timeout to 0"); ++ if (conf.timeout) ++ dbg("FOUND! setting timeout to 0"); + conf.timeout = 0; + } + } @@ -1707,14 +1865,22 @@ index 0000000..5f6dc5e + } + + if (fds[2].revents & POLLIN) { -+ close(fds[2].fd); -+ fds[2].fd = -1; -+ fds[2].revents = 0; -+ numfds--; -+ trigger_running = 0; -+ pthread_join(tid, NULL); ++ uint64_t tmask = 0; ++ if (read(fds[2].fd, &tmask, sizeof(tmask)) < 0) ++ warn("eventfd"); ++ if (tmask & TRIGGER_THREAD) { ++ dbg("terminating trigger thread"); ++ pthread_join(tid, NULL); ++ } ++ if (tmask & CRYPTSETUP_THREAD) { ++ dbg("terminating cryptsetup thread"); ++ pthread_join(conf.cryptsetup_tid, NULL); ++ } ++ conf.running_threads &= ~tmask; + } + } ++ close(fds[2].fd); ++ pthread_mutex_destroy(&conf.cryptsetup_mutex); + + dbg("modaliases: %i, forks: %i, events: %i, total bufsize: %zu", + conf.modalias_count, -- cgit v1.2.3