In data martedì 23 giugno 2015 13:25:28, Richard W.M. Jones ha scritto:
This allows you to append one file to another:
copy-file-to-file /input.txt /output.txt append:true
will append the contents of /input.txt to /output.txt. --- daemon/copy.c | 38 +++++++++++++++++++++++++++++++------- generator/actions.ml | 29 +++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 15 deletions(-)
diff --git a/daemon/copy.c b/daemon/copy.c index bab00fe..6f3e844 100644 --- a/daemon/copy.c +++ b/daemon/copy.c @@ -30,7 +30,6 @@ #include "actions.h"
/* wrflags */ -#define DEST_FILE_FLAGS O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_CLOEXEC, 0666 #define DEST_DEVICE_FLAGS O_WRONLY|O_CLOEXEC, 0
/* flags */ @@ -210,8 +209,13 @@ copy (const char *src, const char *src_display, int do_copy_device_to_device (const char *src, const char *dest, int64_t srcoffset, int64_t destoffset, int64_t size, - int sparse) + int sparse, int append) { + if ((optargs_bitmask & GUESTFS_COPY_DEVICE_TO_DEVICE_APPEND_BITMASK) && + append) { + reply_with_error ("the append flag cannot be set for this call"); + return -1; + } return copy (src, src, dest, dest, DEST_DEVICE_FLAGS, 0, srcoffset, destoffset, size, sparse); } @@ -219,23 +223,30 @@ do_copy_device_to_device (const char *src, const char *dest, int do_copy_device_to_file (const char *src, const char *dest, int64_t srcoffset, int64_t destoffset, int64_t size, - int sparse) + int sparse, int append) { CLEANUP_FREE char *dest_buf = sysroot_path (dest); + int wrflags = O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC;
Cannot DEST_FILE_FLAGS (without O_TRUNC, of course) be used here (and below) to avoid copying&pasting these attributes?
if (!dest_buf) { reply_with_perror ("malloc"); return -1; }
- return copy (src, src, dest_buf, dest, DEST_FILE_FLAGS, 0, + if ((optargs_bitmask & GUESTFS_COPY_DEVICE_TO_FILE_APPEND_BITMASK) && + append) + wrflags |= O_APPEND; + else + wrflags |= O_TRUNC; + + return copy (src, src, dest_buf, dest, wrflags, 0666, 0, srcoffset, destoffset, size, sparse); }
int do_copy_file_to_device (const char *src, const char *dest, int64_t srcoffset, int64_t destoffset, int64_t size, - int sparse) + int sparse, int append) { CLEANUP_FREE char *src_buf = sysroot_path (src);
@@ -244,6 +255,12 @@ do_copy_file_to_device (const char *src, const char *dest, return -1; }
+ if ((optargs_bitmask & GUESTFS_COPY_FILE_TO_DEVICE_APPEND_BITMASK) && + append) { + reply_with_error ("the append flag cannot be set for this call"); + return -1; + } + return copy (src_buf, src, dest, dest, DEST_DEVICE_FLAGS, 0, srcoffset, destoffset, size, sparse); } @@ -251,9 +268,10 @@ do_copy_file_to_device (const char *src, const char *dest, int do_copy_file_to_file (const char *src, const char *dest, int64_t srcoffset, int64_t destoffset, int64_t size, - int sparse) + int sparse, int append) { CLEANUP_FREE char *src_buf = NULL, *dest_buf = NULL; + int wrflags = O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC;
src_buf = sysroot_path (src); if (!src_buf) { @@ -267,7 +285,13 @@ do_copy_file_to_file (const char *src, const char *dest, return -1; }
- return copy (src_buf, src, dest_buf, dest, DEST_FILE_FLAGS, + if ((optargs_bitmask & GUESTFS_COPY_FILE_TO_FILE_APPEND_BITMASK) && + append) + wrflags |= O_APPEND; + else + wrflags |= O_TRUNC; + + return copy (src_buf, src, dest_buf, dest, wrflags, 0666, COPY_UNLINK_DEST_ON_FAILURE, srcoffset, destoffset, size, sparse); } diff --git a/generator/actions.ml b/generator/actions.ml index d5e5ccf..11b8652 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -9424,7 +9424,7 @@ See also C<guestfs_part_to_dev>." };
{ defaults with name = "copy_device_to_device"; added = (1, 13, 25); - style = RErr, [Device "src"; Device "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"]; + style = RErr, [Device "src"; Device "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"]; proc_nr = Some 294; progress = true; shortdesc = "copy from source device to destination device"; @@ -9448,6 +9448,11 @@ overlapping regions may not be copied correctly. If the destination is a file, it is created if required. If the destination file is not large enough, it is extended.
+If the destination is a file and the C<append> flag is not set, +then the destination file is truncated. If the C<append> flag is +set, then the copy appends to the destination file. The C<append> +flag currently cannot be set for devices. + If the C<sparse> flag is true then the call avoids writing blocks that contain only zeroes, which can help in some situations where the backing disk is thin-provisioned. Note that unless @@ -9456,7 +9461,7 @@ in incorrect copying." };
{ defaults with name = "copy_device_to_file"; added = (1, 13, 25); - style = RErr, [Device "src"; Pathname "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"]; + style = RErr, [Device "src"; Pathname "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"]; proc_nr = Some 295; progress = true; shortdesc = "copy from source device to destination file"; @@ -9466,7 +9471,7 @@ of this call." };
{ defaults with name = "copy_file_to_device"; added = (1, 13, 25); - style = RErr, [Pathname "src"; Device "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"]; + style = RErr, [Pathname "src"; Device "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"]; proc_nr = Some 296; progress = true; shortdesc = "copy from source file to destination device"; @@ -9476,24 +9481,32 @@ of this call." };
{ defaults with name = "copy_file_to_file"; added = (1, 13, 25); - style = RErr, [Pathname "src"; Pathname "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"]; + style = RErr, [Pathname "src"; Pathname "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"]; proc_nr = Some 297; progress = true; tests = [ InitScratchFS, Always, TestResult ( [["mkdir"; "/copyff"]; ["write"; "/copyff/src"; "hello, world"]; - ["copy_file_to_file"; "/copyff/src"; "/copyff/dest"; ""; ""; ""; ""]; + ["copy_file_to_file"; "/copyff/src"; "/copyff/dest"; ""; ""; ""; ""; "false"]; ["read_file"; "/copyff/dest"]], "compare_buffers (ret, size, \"hello, world\", 12) == 0"), []; - let size = 1024 * 1024 in InitScratchFS, Always, TestResultTrue ( + let size = 1024 * 1024 in
This seems unused? Or is it supposed to be used and its usage has been forgotten?
[["mkdir"; "/copyff2"]; ["fill"; "0"; string_of_int size; "/copyff2/src"]; ["touch"; "/copyff2/dest"]; ["truncate_size"; "/copyff2/dest"; string_of_int size]; - ["copy_file_to_file"; "/copyff2/src"; "/copyff2/dest"; ""; ""; ""; "true"]; - ["is_zero"; "/copyff2/dest"]]), [] + ["copy_file_to_file"; "/copyff2/src"; "/copyff2/dest"; ""; ""; ""; "true"; "false"]; + ["is_zero"; "/copyff2/dest"]]), []; + InitScratchFS, Always, TestResult ( + [["mkdir"; "/copyff3"]; + ["write"; "/copyff3/src"; "hello, world"]; + ["copy_file_to_file"; "/copyff3/src"; "/copyff3/dest"; ""; ""; ""; ""; "true"]; + ["copy_file_to_file"; "/copyff3/src"; "/copyff3/dest"; ""; ""; ""; ""; "true"]; + ["copy_file_to_file"; "/copyff3/src"; "/copyff3/dest"; ""; ""; ""; ""; "true"]; + ["read_file"; "/copyff3/dest"]], + "compare_buffers (ret, size, \"hello, worldhello, worldhello, world\", 12*3) == 0"), []; ]; shortdesc = "copy from source file to destination file"; longdesc = "\
It would seem okay for me, although maybe we should decouple the enums for flags, so there's no need to add non-functional append flags to the *_to_device variants. -- Pino Toscano