From patchwork Thu Nov 4 09:05:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Michael Tremer X-Patchwork-Id: 4833 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4HlJJy5cpBz3wcC for ; Thu, 4 Nov 2021 09:30:26 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "R3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 4HlJJn3Pqsz2Db; Thu, 4 Nov 2021 09:30:17 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4HlJJn0mLCz2yxv; Thu, 4 Nov 2021 09:30:17 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4HlJJm0v9fz2yVC for ; Thu, 4 Nov 2021 09:30:16 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by mail01.ipfire.org (Postfix) with ESMTPSA id 4HlJJj3Xqtz1Ds; Thu, 4 Nov 2021 09:30:13 +0000 (UTC) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1636018213; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qf6FhdBUlTpiUS+TGhTG5nmwDK6D2GDbMaLu06aMROI=; b=HQQmMamtdHAxZxkPWxEZFTHb47WzbTv2An0m6nKTw6tmeE4UXuvXZiIrEWfCJVcRBf31Nt FZeCobfA7hOj7GCA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1636018213; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qf6FhdBUlTpiUS+TGhTG5nmwDK6D2GDbMaLu06aMROI=; b=bfr6uzvxW4HaT7svGu6bVBbAZ0yGmc/nmN8/cGSxtTdAGNSCsmQP4SGN1DVP1WjpLGafke 30O+MlNsKI1huDrovcfYkQc9TIRApfSlIHFMtDCsugxU05gXlp+e0u90j9fcczEFTxBQse cirQc2vQW7FusFjAVAxKiixglVyrSDzy67DDdkLjZOO2cDcacqTSWKIXDvZHmN0P5gXpMx ZUF6Qaqvz2GzhsXl5giuYs6DCl+2m5N7isxn2dO3RsNla30sCC+HuRYbxjCMag2w8/4acH oRxcJgx6DSa8fMu0U3bSs6OxDOyb0URRFwsOoPjO16M0KCNb/zhMf9JQhfxuFg== From: Michael Tremer To: development@lists.ipfire.org Subject: [PATCH 3/3] installer: Bind-mount /sys/firmware/efi/efivars into chroot Date: Thu, 4 Nov 2021 09:05:54 +0000 Message-Id: <20211104090554.6510-3-michael.tremer@ipfire.org> In-Reply-To: <20211104090554.6510-1-michael.tremer@ipfire.org> References: <20211104090554.6510-1-michael.tremer@ipfire.org> MIME-Version: 1.0 X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michael Tremer Errors-To: development-bounces@lists.ipfire.org Sender: "Development" Signed-off-by: Michael Tremer Acked-by: Peter Müller --- src/installer/hw.c | 113 +++++++++++++++++++++++++++++-------------- src/installer/hw.h | 2 +- src/installer/main.c | 2 +- 3 files changed, 78 insertions(+), 39 deletions(-) diff --git a/src/installer/hw.c b/src/installer/hw.c index 71a1f1cce..265df2d8c 100644 --- a/src/installer/hw.c +++ b/src/installer/hw.c @@ -46,13 +46,6 @@ #include "hw.h" -const char* other_filesystems[] = { - "/dev", - "/proc", - "/sys", - NULL -}; - static int system_chroot(const char* output, const char* path, const char* cmd) { char chroot_cmd[STRING_SIZE]; @@ -149,14 +142,53 @@ int hw_mount(const char* source, const char* target, const char* fs, int flags) return mount(source, target, fs, flags, NULL); } -int hw_umount(const char* target) { - int r = umount2(target, 0); +static int hw_bind_mount(const char* source, const char* prefix) { + if (!source || !prefix) { + errno = EINVAL; + return 1; + } - if (r && errno == EBUSY) { - // Give it a moment to settle - sleep(1); + char target[PATH_MAX]; + int r; + + // Format target + r = snprintf(target, sizeof(target) - 1, "%s/%s", prefix, source); + if (r < 0) + return 1; - r = umount2(target, MNT_FORCE); + // Ensure target exists + mkdir(target, S_IRWXU|S_IRWXG|S_IRWXO); + + return hw_mount(source, target, NULL, MS_BIND); +} + +int hw_umount(const char* source, const char* prefix) { + char target[PATH_MAX]; + int r; + + if (prefix) + r = snprintf(target, sizeof(target) - 1, "%s/%s", prefix, source); + else + r = snprintf(target, sizeof(target) - 1, "%s", source); + if (r < 0) + return r; + + // Perform umount + r = umount2(target, 0); + if (r) { + switch (errno) { + // Try again with force if umount wasn't successful + case EBUSY: + sleep(1); + + r = umount2(target, MNT_FORCE); + break; + + // target wasn't a mountpoint. Ignore. + case EINVAL: + r = 0; + break; + } } return r; @@ -174,7 +206,7 @@ static int hw_test_source_medium(const char* path) { ret = access(SOURCE_TEST_FILE, R_OK); // Umount the test device. - hw_umount(SOURCE_MOUNT_PATH); + hw_umount(SOURCE_MOUNT_PATH, NULL); return ret; } @@ -881,20 +913,21 @@ int hw_mount_filesystems(struct hw_destination* dest, const char* prefix) { } // bind-mount misc filesystems - char** otherfs = other_filesystems; - while (*otherfs) { - snprintf(target, sizeof(target), "%s%s", prefix, *otherfs); + r = hw_bind_mount("/dev", prefix); + if (r) + return r; - mkdir(target, S_IRWXU|S_IRWXG|S_IRWXO); - r = hw_mount(*otherfs, target, NULL, MS_BIND); - if (r) { - hw_umount_filesystems(dest, prefix); + r = hw_bind_mount("/proc", prefix); + if (r) + return r; - return r; - } + r = hw_bind_mount("/sys", prefix); + if (r) + return r; - otherfs++; - } + r = hw_bind_mount("/sys/firmware/efi/efivars", prefix); + if (r && errno != ENOENT) + return r; return 0; } @@ -908,16 +941,14 @@ int hw_umount_filesystems(struct hw_destination* dest, const char* prefix) { // ESP if (*dest->part_boot_efi) { - snprintf(target, sizeof(target), "%s%s", prefix, HW_PATH_BOOT_EFI); - r = hw_umount(target); + r = hw_umount(HW_PATH_BOOT_EFI, prefix); if (r) return -1; } // boot if (*dest->part_boot) { - snprintf(target, sizeof(target), "%s%s", prefix, HW_PATH_BOOT); - r = hw_umount(target); + r = hw_umount(HW_PATH_BOOT, prefix); if (r) return -1; } @@ -928,16 +959,24 @@ int hw_umount_filesystems(struct hw_destination* dest, const char* prefix) { } // misc filesystems - char** otherfs = other_filesystems; - while (*otherfs) { - snprintf(target, sizeof(target), "%s%s", prefix, *otherfs++); - r = hw_umount(target); - if (r) - return -1; - } + r = hw_umount("/sys/firmware/efi/efivars", prefix); + if (r) + return -1; + + r = hw_umount("/sys", prefix); + if (r) + return -1; + + r = hw_umount("/proc", prefix); + if (r) + return -1; + + r = hw_umount("/dev", prefix); + if (r) + return -1; // root - r = hw_umount(prefix); + r = hw_umount(prefix, NULL); if (r) return -1; diff --git a/src/installer/hw.h b/src/installer/hw.h index 9fe69271e..b11dfa48f 100644 --- a/src/installer/hw.h +++ b/src/installer/hw.h @@ -108,7 +108,7 @@ struct hw* hw_init(); void hw_free(struct hw* hw); int hw_mount(const char* source, const char* target, const char* fs, int flags); -int hw_umount(const char* target); +int hw_umount(const char* source, const char* prefix); char* hw_find_source_medium(struct hw* hw); diff --git a/src/installer/main.c b/src/installer/main.c index bc0fdaa67..fabc0ef52 100644 --- a/src/installer/main.c +++ b/src/installer/main.c @@ -909,7 +909,7 @@ int main(int argc, char *argv[]) { } // Umount source drive and eject - hw_umount(SOURCE_MOUNT_PATH); + hw_umount(SOURCE_MOUNT_PATH, NULL); // Free downloaded ISO image if (strcmp(sourcedrive, SOURCE_TEMPFILE) == 0) {