diff options
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | daemon/Makefile.am | 1 | ||||
-rw-r--r-- | daemon/dd.c | 71 | ||||
-rw-r--r-- | guestfs.pod | 35 | ||||
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | src/MAX_PROC_NR | 2 | ||||
-rwxr-xr-x | src/generator.ml | 16 |
7 files changed, 125 insertions, 2 deletions
@@ -127,7 +127,6 @@ Ideas for extra commands General glibc / core programs: chgrp - dd (?) more mk*temp calls ext2 properties: diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 7034bbf7..75867cbe 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -51,6 +51,7 @@ guestfsd_SOURCES = \ command.c \ cpmv.c \ daemon.h \ + dd.c \ debug.c \ devsparts.c \ df.c \ diff --git a/daemon/dd.c b/daemon/dd.c new file mode 100644 index 00000000..2402e13e --- /dev/null +++ b/daemon/dd.c @@ -0,0 +1,71 @@ +/* libguestfs - the guestfsd daemon + * Copyright (C) 2009 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "../src/guestfs_protocol.h" +#include "daemon.h" +#include "actions.h" + +int +do_dd (const char *src, const char *dest) +{ + int src_is_dev, dest_is_dev; + char *if_arg, *of_arg; + char *err; + int r; + + src_is_dev = STRPREFIX (src, "/dev/"); + + if (src_is_dev) + r = asprintf (&if_arg, "if=%s", src); + else + r = asprintf (&if_arg, "if=%s%s", sysroot, src); + if (r == -1) { + reply_with_perror ("asprintf"); + return -1; + } + + dest_is_dev = STRPREFIX (dest, "/dev/"); + + if (dest_is_dev) + r = asprintf (&of_arg, "of=%s", dest); + else + r = asprintf (&of_arg, "of=%s%s", sysroot, dest); + if (r == -1) { + reply_with_perror ("asprintf"); + free (if_arg); + return -1; + } + + r = command (NULL, &err, "dd", "bs=1024K", if_arg, of_arg, NULL); + free (if_arg); + free (of_arg); + + if (r == -1) { + reply_with_error ("dd: %s: %s: %s", src, dest, err); + free (err); + return -1; + } + free (err); + + return 0; +} diff --git a/guestfs.pod b/guestfs.pod index 4a477330..7b6a34e3 100644 --- a/guestfs.pod +++ b/guestfs.pod @@ -274,6 +274,41 @@ non-portable between kernel versions, and they don't support labels or UUIDs. If you want to pre-build an image or you need to mount it using a label or UUID, use an ISO image instead. +=head2 COPYING + +There are various different commands for copying between files and +devices and in and out of the guest filesystem. These are summarised +in the table below. + +=over 4 + +=item B<file> to B<file> + +Use L</guestfs_cp> to copy a single file, or +L</guestfs_cp_a> to copy directories recursively. + +=item B<file or device> to B<file or device> + +Use L</guestfs_dd> which efficiently uses L<dd(1)> +to copy between files and devices in the guest. + +Example: duplicate the contents of an LV: + + guestfs_dd (g, "/dev/VG/Original", "/dev/VG/Copy"); + +The destination (C</dev/VG/Copy>) must be at least as large as the +source (C</dev/VG/Original>). + +=item B<file on the host> to B<file or device> + +Use L</guestfs_upload>. See L</UPLOADING> above. + +=item B<file or device> to B<file on the host> + +Use L</guestfs_download>. See L</DOWNLOADING> above. + +=back + =head2 LISTING FILES C<guestfs_ll> is just designed for humans to read (mainly when using diff --git a/po/POTFILES.in b/po/POTFILES.in index 7707811f..afaa33b6 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -6,6 +6,7 @@ daemon/checksum.c daemon/cmp.c daemon/command.c daemon/cpmv.c +daemon/dd.c daemon/debug.c daemon/devsparts.c daemon/df.c diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index a817176f..0ddd619c 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -216 +217 diff --git a/src/generator.ml b/src/generator.ml index 1c533fae..a7135a79 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -4162,6 +4162,22 @@ See also C<guestfs_version>. =back"); + ("dd", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"]), 217, [], + [InitBasicFS, Always, TestOutputBuffer ( + [["write_file"; "/src"; "hello, world"; "0"]; + ["dd"; "/src"; "/dest"]; + ["read_file"; "/dest"]], "hello, world")], + "copy from source to destination using dd", + "\ +This command copies from one source device or file C<src> +to another destination device or file C<dest>. Normally you +would use this to copy to or from a device or partition, for +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."); + ] let all_functions = non_daemon_functions @ daemon_functions |