]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
mkosi: make -i mode snappier on reflink-capable file systems 206/head
authorLennart Poettering <lennart@poettering.net>
Wed, 29 Nov 2017 11:20:24 +0000 (12:20 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 5 Jan 2018 19:06:47 +0000 (20:06 +0100)
Let's start out with a reflink copy, even if we don't actually want CoW
for disk images ultimately.

mkosi

diff --git a/mkosi b/mkosi
index 919f303ab5143a6be9d12137cd274cacd58eddf2..eeb38438a77147649f4785bc8afb645f8fef9f4f 100755 (executable)
--- a/mkosi
+++ b/mkosi
@@ -183,6 +183,14 @@ def copy_fd(oldfd, newfd):
         shutil.copyfileobj(open(oldfd, 'rb', closefd=False),
                            open(newfd, 'wb', closefd=False))
 
+def copy_file_object(oldobject, newobject):
+    try:
+        _reflink(oldobject.fileno(), newobject.fileno())
+    except OSError as e:
+        if e.errno not in {errno.EXDEV, errno.EOPNOTSUPP}:
+            raise
+        shutil.copyfileobj(oldobject, newobject)
+
 def copy_file(oldpath, newpath):
     with open_close(oldpath, os.O_RDONLY) as oldfd:
         st = os.stat(oldfd)
@@ -415,8 +423,17 @@ def reuse_cache_image(args, workspace, run_build_script, for_cache):
         with source:
             f = tempfile.NamedTemporaryFile(dir = os.path.dirname(args.output), prefix='.mkosi-')
             output.append(f)
+
+            # So on one hand we want CoW off, since this stuff will
+            # have a lot of random write accesses. On the other we
+            # want the copy to be snappy, hence we do want CoW. Let's
+            # ask for both, and let the kernel figure things out:
+            # let's turn off CoW on the file, but start with a CoW
+            # copy. On btrfs that works: the initial copy is made as
+            # CoW but later changes do not result in CoW anymore.
+
             disable_cow(f.name)
-            shutil.copyfileobj(source, f)
+            copy_file_object(source, f)
 
         table, run_sfdisk = determine_partition_table(args)
         args.ran_sfdisk = run_sfdisk