From 22e531bc459309d9a871a845cfacd1396ff5b7e4 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Sun, 22 Nov 2009 19:15:56 +0000 Subject: [PATCH] Implement 'dd' command. --- TODO | 1 - daemon/Makefile.am | 1 + daemon/dd.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ guestfs.pod | 35 +++++++++++++++++++++++++++ po/POTFILES.in | 1 + src/MAX_PROC_NR | 2 +- src/generator.ml | 16 ++++++++++++ 7 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 daemon/dd.c diff --git a/TODO b/TODO index 24c0171..661c137 100644 --- a/TODO +++ b/TODO @@ -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 7034bbf..75867cb 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 0000000..2402e13 --- /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 + +#include +#include + +#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 4a47733..7b6a34e 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 to B + +Use L to copy a single file, or +L to copy directories recursively. + +=item B to B + +Use L which efficiently uses L +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) must be at least as large as the +source (C). + +=item B to B + +Use L. See L above. + +=item B to B + +Use L. See L above. + +=back + =head2 LISTING FILES C is just designed for humans to read (mainly when using diff --git a/po/POTFILES.in b/po/POTFILES.in index 7707811..afaa33b 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 a817176..0ddd619 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 1c533fa..a7135a7 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -4162,6 +4162,22 @@ See also C. =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 +to another destination device or file C. 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 -- 1.8.3.1