🧹 move btrfs subvolumes mount logic into gucc

This commit is contained in:
Vladislav Nepogodin 2024-06-27 18:44:17 +04:00
parent 9e011fc276
commit 97be1f3fc4
No known key found for this signature in database
GPG Key ID: B62C3D10C54D5DA9
4 changed files with 41 additions and 18 deletions

View File

@ -1,14 +1,15 @@
#ifndef BTRFS_HPP #ifndef BTRFS_HPP
#define BTRFS_HPP #define BTRFS_HPP
#include <string> // for string
#include <string_view> // for string_view #include <string_view> // for string_view
#include <vector> // for vector #include <vector> // for vector
namespace gucc::fs { namespace gucc::fs {
struct BtrfsSubvolume final { struct BtrfsSubvolume final {
std::string_view subvolume; std::string subvolume;
std::string_view mountpoint; std::string mountpoint;
}; };
// Creates btrfs subvolume // Creates btrfs subvolume
@ -17,6 +18,9 @@ auto btrfs_create_subvol(std::string_view subvolume, std::string_view root_mount
// Creates btrfs subvolumes and mounts them // Creates btrfs subvolumes and mounts them
auto btrfs_create_subvols(const std::vector<BtrfsSubvolume>& subvols, std::string_view device, std::string_view root_mountpoint, std::string_view mount_opts) noexcept -> bool; auto btrfs_create_subvols(const std::vector<BtrfsSubvolume>& subvols, std::string_view device, std::string_view root_mountpoint, std::string_view mount_opts) noexcept -> bool;
// Mounts btrfs subvolumes
auto btrfs_mount_subvols(const std::vector<BtrfsSubvolume>& subvols, std::string_view device, std::string_view root_mountpoint, std::string_view mount_opts) noexcept -> bool;
} // namespace gucc::fs } // namespace gucc::fs
#endif // BTRFS_HPP #endif // BTRFS_HPP

View File

@ -52,9 +52,17 @@ auto btrfs_create_subvols(const std::vector<BtrfsSubvolume>& subvols, std::strin
} }
} }
// TODO(vnepogodin): handle exit code // TODO(vnepogodin): handle exit code
utils::exec(fmt::format(FMT_COMPILE("umount -v {} &>>/tmp/cachyos-install.log"), root_mountpoint)); utils::exec(fmt::format(FMT_COMPILE("umount -v {} &>>/tmp/cachyos-install.log"), root_mountpoint), true);
// Mount subvolumes // Mount subvolumes
if (!fs::btrfs_mount_subvols(subvols, device, root_mountpoint, mount_opts)) {
spdlog::error("Failed to mount btrfs subvolumes");
return false;
}
return true;
}
auto btrfs_mount_subvols(const std::vector<BtrfsSubvolume>& subvols, std::string_view device, std::string_view root_mountpoint, std::string_view mount_opts) noexcept -> bool {
for (const auto& subvol : subvols) { for (const auto& subvol : subvols) {
auto mount_option = fmt::format(FMT_COMPILE("subvol={},{}"), subvol.subvolume, mount_opts); auto mount_option = fmt::format(FMT_COMPILE("subvol={},{}"), subvol.subvolume, mount_opts);
if (subvol.subvolume.empty()) { if (subvol.subvolume.empty()) {

View File

@ -116,7 +116,7 @@ auto get_isa_levels() noexcept -> std::vector<std::string> {
std::vector<std::string> supported_isa_levels; std::vector<std::string> supported_isa_levels;
{ {
struct utsname un{}; struct utsname un { };
uname(&un); uname(&un);
supported_isa_levels.emplace_back(un.machine); supported_isa_levels.emplace_back(un.machine);
} }

View File

@ -20,6 +20,7 @@
#include <fmt/core.h> #include <fmt/core.h>
using namespace std::string_view_literals; using namespace std::string_view_literals;
using namespace std::string_literals;
namespace fs = std::filesystem; namespace fs = std::filesystem;
namespace utils { namespace utils {
@ -81,9 +82,9 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
// Create subvolumes automatically // Create subvolumes automatically
const std::vector<gucc::fs::BtrfsSubvolume> subvolumes{ const std::vector<gucc::fs::BtrfsSubvolume> subvolumes{
gucc::fs::BtrfsSubvolume{.subvolume = "/@"sv, .mountpoint = "/"sv}, gucc::fs::BtrfsSubvolume{.subvolume = "/@"s, .mountpoint = "/"s},
gucc::fs::BtrfsSubvolume{.subvolume = "/@home"sv, .mountpoint = "/home"sv}, gucc::fs::BtrfsSubvolume{.subvolume = "/@home"s, .mountpoint = "/home"s},
gucc::fs::BtrfsSubvolume{.subvolume = "/@cache"sv, .mountpoint = "/var/cache"sv}, gucc::fs::BtrfsSubvolume{.subvolume = "/@cache"s, .mountpoint = "/var/cache"s},
// gucc::fs::BtrfsSubvolume{.subvolume = "/@snapshots"sv, .mountpoint = "/.snapshots"sv}, // gucc::fs::BtrfsSubvolume{.subvolume = "/@snapshots"sv, .mountpoint = "/.snapshots"sv},
}; };
if (!gucc::fs::btrfs_create_subvols(subvolumes, disk.root, root_mountpoint, disk.mount_opts)) { if (!gucc::fs::btrfs_create_subvols(subvolumes, disk.root, root_mountpoint, disk.mount_opts)) {
@ -106,23 +107,33 @@ void mount_existing_subvols(const disk_part& disk) noexcept {
fs_opts = "compress=lzo,noatime,space_cache,ssd,commit=120"sv; fs_opts = "compress=lzo,noatime,space_cache,ssd,commit=120"sv;
} }
#ifdef NDEVENV #ifdef NDEVENV
gucc::utils::exec("btrfs subvolume list /mnt 2>/dev/null | cut -d' ' -f9 > /tmp/.subvols"sv, true); const auto root_mountpoint = "/mnt"sv;
umount("/mnt");
// Mount subvolumes one by one gucc::utils::exec(fmt::format(FMT_COMPILE("btrfs subvolume list {} 2>/dev/null | cut -d' ' -f9 > /tmp/.subvols"), root_mountpoint), true);
for (const auto& subvol : gucc::utils::make_multiline(gucc::utils::exec("cat /tmp/.subvols"sv))) { if (gucc::utils::exec(fmt::format(FMT_COMPILE("umount -v {} &>>/tmp/cachyos-install.log"), root_mountpoint), true) != "0") {
spdlog::error("Failed to unmount {}", root_mountpoint);
}
const auto& subvol_list = gucc::utils::make_multiline(gucc::utils::exec("cat /tmp/.subvols"sv));
// Get mountpoints of subvolumes
std::vector<gucc::fs::BtrfsSubvolume> subvolumes{};
for (auto&& subvol : subvol_list) {
// Ask for mountpoint // Ask for mountpoint
const auto& content = fmt::format(FMT_COMPILE("\nInput mountpoint of\nthe subvolume {}\nas it would appear\nin installed system\n(without prepending /mnt).\n"), subvol); const auto& content = fmt::format(FMT_COMPILE("\nInput mountpoint of\nthe subvolume {}\nas it would appear\nin installed system\n(without prepending {}).\n"), subvol, root_mountpoint);
std::string mountpoint{"/"}; std::string mountpoint{"/"};
if (!tui::detail::inputbox_widget(mountpoint, content, size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) { if (!tui::detail::inputbox_widget(mountpoint, content, size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) {
return; return;
} }
const auto& mount_dir{fmt::format(FMT_COMPILE("/mnt/{}"), mountpoint)};
if (!fs::exists(mount_dir)) { subvolumes.push_back(gucc::fs::BtrfsSubvolume{.subvolume = subvol, .mountpoint = mountpoint});
fs::create_directories(mount_dir); }
}
// Mount the subvolume // TODO(vnepogodin): add confirmation for selected mountpoint for particular subvolume
gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o \"{},subvol={}\" \"{}\" \"{}\""), fs_opts, subvol, disk.root, mount_dir));
// Mount subvolumes
if (!gucc::fs::btrfs_mount_subvols(subvolumes, disk.root, root_mountpoint, fs_opts)) {
spdlog::error("Failed to mount btrfs subvolumes");
} }
#endif #endif
} }