[Libguestfs] [PATCH 1/2] New API: guestfs_copy_size to copy a fixed number of bytes.

Richard W.M. Jones rjones at redhat.com
Mon Mar 22 18:41:50 UTC 2010


-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines.  Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://et.redhat.com/~rjones/virt-top
-------------- next part --------------
>From 4dcb8e5e52d423d1d31d4a4086788e11790c7632 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones at redhat.com>
Date: Mon, 22 Mar 2010 18:36:16 +0000
Subject: [PATCH 1/2] New API: guestfs_copy_size to copy a fixed number of bytes.

This is similar to 'guestfs_dd', but it copies just a fixed
number of bytes from the source to the destination.  It's an
error if the source is too short or if the destination is too
small.
---
 daemon/dd.c      |   81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/MAX_PROC_NR  |    2 +-
 src/generator.ml |   15 +++++++++-
 3 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/daemon/dd.c b/daemon/dd.c
index d92dac0..2bbe855 100644
--- a/daemon/dd.c
+++ b/daemon/dd.c
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <fcntl.h>
 
 #include "../src/guestfs_protocol.h"
 #include "daemon.h"
@@ -70,3 +71,83 @@ do_dd (const char *src, const char *dest)
 
   return 0;
 }
+
+int
+do_copy_size (const char *src, const char *dest, int64_t size)
+{
+  char *buf;
+  int src_fd, dest_fd;
+
+  if (STRPREFIX (src, "/dev/"))
+    src_fd = open (src, O_RDONLY);
+  else {
+    buf = sysroot_path (src);
+    if (!buf) {
+      reply_with_perror ("malloc");
+      return -1;
+    }
+    src_fd = open (buf, O_RDONLY);
+    free (buf);
+  }
+  if (src_fd == -1) {
+    reply_with_perror ("%s", src);
+    return -1;
+  }
+
+  if (STRPREFIX (dest, "/dev/"))
+    dest_fd = open (dest, O_WRONLY);
+  else {
+    buf = sysroot_path (dest);
+    if (!buf) {
+      reply_with_perror ("malloc");
+      close (src_fd);
+      return -1;
+    }
+    dest_fd = open (buf, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666);
+    free (buf);
+  }
+  if (dest_fd == -1) {
+    reply_with_perror ("%s", dest);
+    close (src_fd);
+    return -1;
+  }
+
+  while (size > 0) {
+    char buf[1024*1024];
+    size_t n = size > (int64_t) (sizeof buf) ? sizeof buf : (size_t) size;
+    ssize_t r = read (src_fd, buf, n);
+    if (r == -1) {
+      reply_with_perror ("%s: read", src);
+      close (src_fd);
+      close (dest_fd);
+      return -1;
+    }
+    if (r == 0) {
+      reply_with_error ("%s: input file too short", src);
+      close (src_fd);
+      close (dest_fd);
+      return -1;
+    }
+
+    if (xwrite (dest_fd, buf, r) == -1) {
+      reply_with_perror ("%s: write", dest);
+      close (src_fd);
+      close (dest_fd);
+      return -1;
+    }
+
+    size -= r;
+  }
+
+  if (close (src_fd) == -1) {
+    reply_with_perror ("%s: close", src);
+    close (dest_fd);
+    return -1;
+  }
+  if (close (dest_fd) == -1) {
+    reply_with_perror ("%s: close", dest);
+    return -1;
+  }
+
+  return 0;
+}
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index f414671..2c36bbd 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-226
+227
diff --git a/src/generator.ml b/src/generator.ml
index fdd228e..c4e3d6d 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -4239,7 +4239,7 @@ example to duplicate a filesystem.
 
 If the destination is a device, it must be as large or larger
 than the source file or device, otherwise the copy will fail.
-This command cannot do partial copies.");
+This command cannot do partial copies (see C<guestfs_copy_size>).");
 
   ("filesize", (RInt64 "size", [Pathname "file"]), 218, [],
    [InitBasicFS, Always, TestOutputInt (
@@ -4332,6 +4332,19 @@ calls to associate logical volumes and volume groups.
 
 See also C<guestfs_vgpvuuids>.");
 
+  ("copy_size", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"; Int64 "size"]), 227, [],
+   [InitBasicFS, Always, TestOutputBuffer (
+      [["write_file"; "/src"; "hello, world"; "0"];
+       ["copy_size"; "/src"; "/dest"; "5"];
+       ["read_file"; "/dest"]], "hello")],
+   "copy size bytes from source to destination using dd",
+   "\
+This command copies exactly C<size> bytes from one source device
+or file C<src> to another destination device or file C<dest>.
+
+Note this will fail if the source is too short or if the destination
+is not large enough.");
+
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions
-- 
1.6.5.2



More information about the Libguestfs mailing list