summaryrefslogtreecommitdiff
path: root/cloudinit/config
diff options
context:
space:
mode:
authorRobert Schweikert <rjschwei@suse.com>2023-01-06 18:16:28 -0500
committerGitHub <noreply@github.com>2023-01-06 16:16:28 -0700
commitd1e237d22deeb7dde724bdc5495b5cbbe8914404 (patch)
treecb0b864593f674171727b802e615f2805057f3dd /cloudinit/config
parent8a155c7404aea8728c697f4a4b2d1d24dcf4d0ec (diff)
downloadcloud-init-git-d1e237d22deeb7dde724bdc5495b5cbbe8914404.tar.gz
Use btrfs enquque when available (#1926)
btrfs has operations that are blocking and when we try to resize a btrfs filesystem we may be in a race condition with blocking operations. Use the enqueue feature introduced in btrfs 5.10 to queue our resize request until resize if possible. Before this commit, hitting this race would cause the command to immediately fail. With this change, the resize is queued and the command blocks until resize has completed (event driven, with a poll loop of 1m).
Diffstat (limited to 'cloudinit/config')
-rw-r--r--cloudinit/config/cc_resizefs.py19
1 files changed, 16 insertions, 3 deletions
diff --git a/cloudinit/config/cc_resizefs.py b/cloudinit/config/cc_resizefs.py
index 7a0ecf96..0e6197a2 100644
--- a/cloudinit/config/cc_resizefs.py
+++ b/cloudinit/config/cc_resizefs.py
@@ -60,15 +60,28 @@ def _resize_btrfs(mount_point, devpth):
if not util.mount_is_read_write(mount_point) and os.path.isdir(
"%s/.snapshots" % mount_point
):
- return (
+ cmd = [
"btrfs",
"filesystem",
"resize",
"max",
"%s/.snapshots" % mount_point,
- )
+ ]
else:
- return ("btrfs", "filesystem", "resize", "max", mount_point)
+ cmd = ["btrfs", "filesystem", "resize", "max", mount_point]
+
+ # btrfs has exclusive operations and resize may fail if btrfs is busy
+ # doing one of the operations that prevents resize. As of btrfs 5.10
+ # the resize operation can be queued
+ btrfs_with_queue = util.Version.from_str("5.10")
+ system_btrfs_ver = util.Version.from_str(
+ subp.subp(["btrfs", "--version"])[0].split("v")[-1].strip()
+ )
+ if system_btrfs_ver >= btrfs_with_queue:
+ idx = cmd.index("resize")
+ cmd.insert(idx + 1, "--enqueue")
+
+ return tuple(cmd)
def _resize_ext(mount_point, devpth):