From patchwork Sat Mar 23 10:56:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Schantl X-Patchwork-Id: 7664 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 (secp384r1) client-signature ECDSA (secp384r1)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4V1x3M28rdz3wtq for ; Sat, 23 Mar 2024 10:57:03 +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 (secp384r1) client-signature ECDSA (secp384r1)) (Client CN "mail02.haj.ipfire.org", Issuer "R3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 4V1x392YrqzFLr; Sat, 23 Mar 2024 10:56:53 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4V1x363mWmz32vr; Sat, 23 Mar 2024 10:56:50 +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 (secp384r1) client-signature ECDSA (secp384r1)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4V1x2z1pznz32vX for ; Sat, 23 Mar 2024 10:56:43 +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 (secp384r1) server-digest SHA384) (No client certificate requested) by mail01.ipfire.org (Postfix) with ESMTPSA id 4V1x2y6Jwxz4Rt; Sat, 23 Mar 2024 10:56:42 +0000 (UTC) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1711191403; 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=ZwGrJq3MIfge6fO4qmL/rhFzTnFqhoCYZClf3w7drYU=; b=oWtcaWCWSV3LPCvxhW15IDoRb2sbhPC/Mn0CC4vvjOoM3O6zBWt7TCZei8Nkz6QYNDOZLf oJU20iG8Sa6UIeAg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1711191403; 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=ZwGrJq3MIfge6fO4qmL/rhFzTnFqhoCYZClf3w7drYU=; b=tjZ2eSfFTCVybRB8t2h/gw9HHRnbJbrNTDdc626Suel14xkkU9SaB1oPkmLrM+ccfy/9Nh Z+0uU57Jy2L0qGdmZYR4zmP0QpPLunXG6YUNnC0wzZtOcF7gzWcc/I08CpDZXntjFTqpcI jdnsaygGJ3wwLw9r2xQX1Zo2+2Z/ugH6SmYYp4LXq1PYInokoF0Wx4HxArjYQZSC6jHfwM vKzYvpI1yE23k6ncIOOegGEnnNTktOmwMZYiMjxejYnuKh4JoiHv789Bfo3e9tHvAQQuvi jT9OrZU30miEDgvmvmopoGNK6Q38lcqbEdnULk0lbtioj7THE4Y6EsE7yz4qdQ== From: Stefan Schantl To: development@lists.ipfire.org Subject: [PATCHv2 06/12] installer: Add code to create a BTRFS subvolume layout Date: Sat, 23 Mar 2024 11:56:23 +0100 Message-Id: <20240323105629.371511-6-stefan.schantl@ipfire.org> In-Reply-To: <20240323105629.371511-1-stefan.schantl@ipfire.org> References: <20240323105629.371511-1-stefan.schantl@ipfire.org> MIME-Version: 1.0 Message-ID-Hash: OVYQF6BKBOL2SKTRB6RVVQHZVMXBDV7Z X-Message-ID-Hash: OVYQF6BKBOL2SKTRB6RVVQHZVMXBDV7Z X-MailFrom: stefan.schantl@ipfire.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: IPFire development talk Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Signed-off-by: Stefan Schantl --- src/installer/hw.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-- src/installer/hw.h | 20 ++++++++++++ 2 files changed, 98 insertions(+), 2 deletions(-) diff --git a/src/installer/hw.c b/src/installer/hw.c index 11dbcd96d..8396d83cf 100644 --- a/src/installer/hw.c +++ b/src/installer/hw.c @@ -810,6 +810,7 @@ int hw_create_partitions(struct hw_destination* dest, const char* output) { static int hw_format_filesystem(const char* path, int fs, const char* output) { char cmd[STRING_SIZE] = "\0"; + int r; // Swap if (fs == HW_FS_SWAP) { @@ -829,7 +830,9 @@ static int hw_format_filesystem(const char* path, int fs, const char* output) { // BTRFS } else if (fs == HW_FS_BTRFS) { - snprintf(cmd, sizeof(cmd), "/usr/bin/mkfs.btrfs -f %s", path); + r = hw_create_btrfs_layout(path, output); + + return r; // FAT32 } else if (fs == HW_FS_FAT32) { @@ -838,7 +841,7 @@ static int hw_format_filesystem(const char* path, int fs, const char* output) { assert(*cmd); - int r = mysystem(output, cmd); + r = mysystem(output, cmd); return r; } @@ -875,6 +878,59 @@ int hw_create_filesystems(struct hw_destination* dest, const char* output) { return 0; } +int hw_create_btrfs_layout(const char* path, const char* output) { + const struct btrfs_subvolumes* subvolume = NULL; + char cmd[STRING_SIZE]; + char volume[STRING_SIZE]; + int r; + + r = snprintf(cmd, sizeof(cmd), "/usr/bin/mkfs.btrfs -f %s", path); + if (r < 0) { + return r; + } + + // Create the main BTRFS file system. + r = mysystem(output, cmd); + + if (r) { + return r; + } + + + // We need to mount the FS in order to create any subvolumes. + r = hw_mount(path, DESTINATION_MOUNT_PATH, "btrfs", 0); + + if (r) { + return r; + } + + // Loop through the list of subvolumes to create. + for ( subvolume = btrfs_subvolumes; subvolume->name; subvolume++ ) { + r = snprintf(volume, sizeof(volume), "%s", subvolume->name); + + // Abort if snprintf fails. + if (r < 0) { + return r; + } + + // Call function to create the subvolume + r = hw_create_btrfs_subvolume(output, volume); + + if (r) { + return r; + } + } + + // Umount the main BTRFS after subvolume creation. + r = hw_umount(DESTINATION_MOUNT_PATH, 0); + + if (r) { + return r; + } + + return 0; +} + int hw_mount_filesystems(struct hw_destination* dest, const char* prefix) { char target[STRING_SIZE]; @@ -1224,3 +1280,23 @@ int hw_restore_backup(const char* output, const char* backup_path, const char* d return 0; } + +int hw_create_btrfs_subvolume(const char* output, const char* subvolume) { + char command [STRING_SIZE]; + int r; + + // Abort if the command could not be assigned. + r = snprintf(command, sizeof(command), "/usr/bin/btrfs subvolume create %s/%s", DESTINATION_MOUNT_PATH, subvolume); + if (r < 0) { + return r; + } + + // Create the subvolume + r = mysystem(output, command); + + if (r) { + return r; + } + + return 0; +} diff --git a/src/installer/hw.h b/src/installer/hw.h index e5ee65a6d..73a5233e2 100644 --- a/src/installer/hw.h +++ b/src/installer/hw.h @@ -104,6 +104,26 @@ struct hw_destination { unsigned long long size_root; }; +// Struct to define the BTRFS subvolumes layout +static const struct btrfs_subvolumes { + const char* name; + const char* mount_path; +} btrfs_subvolumes[] = { + { "@", "/" }, + { "@snapshots", "/.snapshots" }, + { "@home", "/home" }, + { "@root", "/root" }, + { "@cache", "/var/cache" }, + { "@backups", "/var/ipfire/backup" }, + { "@lib", "/var/lib" }, + { "@logs", "/var/log" }, + { "@mails", "/var/mail" }, + { "@tmp", "/var/tmp" }, + + // Sentinel + { NULL }, +}; + struct hw* hw_init(); void hw_free(struct hw* hw);