From 3f0612b4ada4a895f29613a46acfe57a5de92418 Mon Sep 17 00:00:00 2001 From: Chrysostomus Date: Mon, 7 Dec 2020 22:30:57 +0200 Subject: [PATCH 1/6] Use different location for swapfile on btrfs root --- src/modules/fstab/main.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/modules/fstab/main.py b/src/modules/fstab/main.py index 6c2168a8e..8b5deecb1 100644 --- a/src/modules/fstab/main.py +++ b/src/modules/fstab/main.py @@ -319,14 +319,19 @@ def create_swapfile(root_mount_point, root_btrfs): The swapfile-creation covers progress from 0.2 to 0.5 """ libcalamares.job.setprogress(0.2) - swapfile_path = os.path.join(root_mount_point, "swapfile") - with open(swapfile_path, "wb") as f: - pass if root_btrfs: + # btrfs swapfiles must reside on a subvolume that is not snapshotted to prevent file system corruption + swapfile_path = os.path.join(root_mount_point, "swap/swapfile") + with open(swapfile_path, "wb") as f: + pass o = subprocess.check_output(["chattr", "+C", swapfile_path]) libcalamares.utils.debug("swapfile attributes: {!s}".format(o)) o = subprocess.check_output(["btrfs", "property", "set", swapfile_path, "compression", "none"]) libcalamares.utils.debug("swapfile compression: {!s}".format(o)) + else: + swapfile_path = os.path.join(root_mount_point, "swapfile") + with open(swapfile_path, "wb") as f: + pass # Create the swapfile; swapfiles are small-ish zeroes = bytes(16384) with open(swapfile_path, "wb") as f: From 80a538665e3837fd16cdf6b9ac667d2850dd49fc Mon Sep 17 00:00:00 2001 From: Chrysostomus Date: Mon, 7 Dec 2020 22:39:21 +0200 Subject: [PATCH 2/6] Generate entry for subvolume @swap --- src/modules/fstab/main.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/modules/fstab/main.py b/src/modules/fstab/main.py index 8b5deecb1..9827198ce 100644 --- a/src/modules/fstab/main.py +++ b/src/modules/fstab/main.py @@ -183,7 +183,7 @@ class FstabGenerator(object): print(FSTAB_HEADER, file=fstab_file) for partition in self.partitions: - # Special treatment for a btrfs root with @ and @home + # Special treatment for a btrfs root with @, @home and @swap # subvolumes if (partition["fs"] == "btrfs" and partition["mountPoint"] == "/"): @@ -206,6 +206,13 @@ class FstabGenerator(object): dct = self.generate_fstab_line_info(home_entry) if dct: self.print_fstab_line(dct, file=fstab_file) + elif line.endswith(b'path @swap'): + swap_part_entry = partition + swap_part_entry["mountPoint"] = "/swap" + swap_part_entry["subvol"] = "@swap" + dct = self.generate_fstab_line_info(swap_part_entry) + if dct: + self.print_fstab_line(dct, file=fstab_file) else: dct = self.generate_fstab_line_info(partition) From 97eb32bf5c9e6521780dc95fa9e17c203fb58dcb Mon Sep 17 00:00:00 2001 From: Chrysostomus Date: Mon, 7 Dec 2020 22:47:32 +0200 Subject: [PATCH 3/6] Correct the path of swapfile on btrfs --- src/modules/fstab/main.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/modules/fstab/main.py b/src/modules/fstab/main.py index 9827198ce..6977ccad1 100644 --- a/src/modules/fstab/main.py +++ b/src/modules/fstab/main.py @@ -386,7 +386,12 @@ def run(): swap_choice = swap_choice.get( "swap", None ) if swap_choice and swap_choice == "file": # There's no formatted partition for it, so we'll sneak in an entry - partitions.append( dict(fs="swap", mountPoint=None, claimed=True, device="/swapfile", uuid=None) ) + root_partitions = [ p["fs"].lower() for p in partitions if p["mountPoint"] == "/" ] + root_btrfs = (root_partitions[0] == "btrfs") if root_partitions else False + if root_btrfs: + partitions.append( dict(fs="swap", mountPoint=None, claimed=True, device="/swap/swapfile", uuid=None) ) + else: + partitions.append( dict(fs="swap", mountPoint=None, claimed=True, device="/swapfile", uuid=None) ) else: swap_choice = None From b180cbd47d88379d9002956fe678e0c2d2278e19 Mon Sep 17 00:00:00 2001 From: Chrysostomus Date: Mon, 7 Dec 2020 22:52:39 +0200 Subject: [PATCH 4/6] Generate a subvolume for swap if swapfile is used --- src/modules/mount/main.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index 1313fca49..8e7dce7ba 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -77,6 +77,7 @@ def mount_partition(root_mount_point, partition, partitions): # for the root mount point. # If a separate /home partition isn't defined, we also create # a subvolume "@home". + # If a swapfile is used, we also create a subvolume "@swap". # Finally we remount all of the above on the correct paths. if fstype == "btrfs" and partition["mountPoint"] == '/': has_home_mount_point = False @@ -94,6 +95,13 @@ def mount_partition(root_mount_point, partition, partitions): subprocess.check_call(['btrfs', 'subvolume', 'create', root_mount_point + '/@home']) + swap_choice = global_storage.value( "partitionChoices" ) + if swap_choice: + swap_choice = swap_choice.get( "swap", None ) + if swap_choice and swap_choice == "file": + subprocess.check_call(['btrfs', 'subvolume', 'create', + root_mount_point + '/@swap']) + subprocess.check_call(["umount", "-v", root_mount_point]) device = partition["device"] From 727f7859b7a1399144664c429cc832f7be9fb30c Mon Sep 17 00:00:00 2001 From: Chrysostomus Date: Mon, 7 Dec 2020 22:59:29 +0200 Subject: [PATCH 5/6] Mount @swap to /swap when needed --- src/modules/mount/main.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index 8e7dce7ba..89e1328eb 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -87,6 +87,12 @@ def mount_partition(root_mount_point, partition, partitions): if p["mountPoint"] == "/home": has_home_mount_point = True break + needs_swap_subvolume = False + swap_choice = global_storage.value( "partitionChoices" ) + if swap_choice: + swap_choice = swap_choice.get( "swap", None ) + if swap_choice and swap_choice == "file": + needs_swap_subvolume = True subprocess.check_call(['btrfs', 'subvolume', 'create', root_mount_point + '/@']) @@ -94,12 +100,8 @@ def mount_partition(root_mount_point, partition, partitions): if not has_home_mount_point: subprocess.check_call(['btrfs', 'subvolume', 'create', root_mount_point + '/@home']) - - swap_choice = global_storage.value( "partitionChoices" ) - if swap_choice: - swap_choice = swap_choice.get( "swap", None ) - if swap_choice and swap_choice == "file": - subprocess.check_call(['btrfs', 'subvolume', 'create', + if needs_swap_subvolume: + subprocess.check_call(['btrfs', 'subvolume', 'create', root_mount_point + '/@swap']) subprocess.check_call(["umount", "-v", root_mount_point]) @@ -121,6 +123,13 @@ def mount_partition(root_mount_point, partition, partitions): fstype, ",".join(["subvol=@home", partition.get("options", "")])) != 0: libcalamares.utils.warning("Cannot mount {}".format(device)) + + if needs_swap_subvolume: + if libcalamares.utils.mount(device, + root_mount_point + "/swap", + fstype, + ",".join(["subvol=@swap", partition.get("options", "")])) != 0: + libcalamares.utils.warning("Cannot mount {}".format(device)) def run(): From 271122865faf4885f226092ce1267ce3270f9e37 Mon Sep 17 00:00:00 2001 From: Chrysostomus Date: Sun, 20 Dec 2020 01:27:45 +0200 Subject: [PATCH 6/6] define global storage --- src/modules/mount/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index 89e1328eb..3982176df 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -38,6 +38,7 @@ def mount_partition(root_mount_point, partition, partitions): """ # Create mount point with `+` rather than `os.path.join()` because # `partition["mountPoint"]` starts with a '/'. + global_storage = libcalamares.globalstorage raw_mount_point = partition["mountPoint"] if not raw_mount_point: return