Richard W.M. Jones
2010-Sep-26 18:53 UTC
[Libguestfs] [PATCH 0/2] Add pwrite-device API call
These two very simple patches add a pwrite-device API call. I have been conservative and not yet added the equivalent pread-device call, although that could be added in future. The motivation for this is in virt-resize: We need a way to zap the partition table cleanly[1], and obviously parted isn't working out for us[2]. Using this call we can zap MBR and GPT partition tables by overwriting them with zeroes (or zeroes + signature), and I have shown that this works at least for MBR. Although the semantics of pwrite and pwrite-device are not guaranteed full write, they almost certainly do this now and we could add this extra constraint in future. Rich. [1] https://bugzilla.redhat.com/show_bug.cgi?id=633766 [2] http://lists.alioth.debian.org/pipermail/parted-devel/2010-September/003748.html -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://et.redhat.com/~rjones/virt-df/
Richard W.M. Jones
2010-Sep-26 18:54 UTC
[Libguestfs] [PATCH 1/2] pwrite: Check offset is not negative.
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming blog: http://rwmj.wordpress.com Fedora now supports 80 OCaml packages (the OPEN alternative to F#) http://cocan.org/getting_started_with_ocaml_on_red_hat_and_fedora -------------- next part -------------->From 24d1ce5ed269a0d3b03565643b9958948a63e9c5 Mon Sep 17 00:00:00 2001From: Richard W.M. Jones <rjones at redhat.com> Date: Sun, 26 Sep 2010 17:59:50 +0100 Subject: [PATCH 1/2] pwrite: Check offset is not negative. --- daemon/file.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/daemon/file.c b/daemon/file.c index 476f445..0849456 100644 --- a/daemon/file.c +++ b/daemon/file.c @@ -469,6 +469,11 @@ do_pwrite (const char *path, const char *content, size_t size, int64_t offset) int fd; ssize_t r; + if (offset < 0) { + reply_with_error ("offset is negative"); + return -1; + } + CHROOT_IN; fd = open (path, O_WRONLY); CHROOT_OUT; -- 1.7.3
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones New in Fedora 11: Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 70 libraries supprt'd http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw -------------- next part -------------->From d0eca2641b2157e08b53f9059e6cbd0b2462969f Mon Sep 17 00:00:00 2001From: Richard W.M. Jones <rjones at redhat.com> Date: Sun, 26 Sep 2010 18:00:11 +0100 Subject: [PATCH 2/2] New API: pwrite-device This is the same as the existing 'pwrite' API call, but allows you to write to a device. --- daemon/file.c | 44 +++++++++++++++++++++++++++++++-------- generator/generator_actions.ml | 19 ++++++++++++++++- src/MAX_PROC_NR | 2 +- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/daemon/file.c b/daemon/file.c index 0849456..9403100 100644 --- a/daemon/file.c +++ b/daemon/file.c @@ -463,11 +463,32 @@ do_pread (const char *path, int count, int64_t offset, size_t *size_r) return buf; } +static int +pwrite_fd (int fd, const char *content, size_t size, int64_t offset, + const char *display_path) +{ + ssize_t r; + + r = pwrite (fd, content, size, offset); + if (r == -1) { + reply_with_perror ("pwrite: %s", display_path); + close (fd); + return -1; + } + + if (close (fd) == -1) { + reply_with_perror ("close: %s", display_path); + close (fd); + return -1; + } + + return r; +} + int do_pwrite (const char *path, const char *content, size_t size, int64_t offset) { int fd; - ssize_t r; if (offset < 0) { reply_with_error ("offset is negative"); @@ -483,20 +504,25 @@ do_pwrite (const char *path, const char *content, size_t size, int64_t offset) return -1; } - r = pwrite (fd, content, size, offset); - if (r == -1) { - reply_with_perror ("pwrite: %s", path); - close (fd); + return pwrite_fd (fd, content, size, offset, path); +} + +int +do_pwrite_device (const char *device, const char *content, size_t size, + int64_t offset) +{ + if (offset < 0) { + reply_with_error ("offset is negative"); return -1; } - if (close (fd) == -1) { - reply_with_perror ("close: %s", path); - close (fd); + int fd = open (device, O_WRONLY); + if (fd == -1) { + reply_with_perror ("open: %s", device); return -1; } - return r; + return pwrite_fd (fd, content, size, offset, device); } /* This runs the 'file' command. */ diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index ac8dab2..e94fcbd 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -4812,7 +4812,7 @@ return value is the number of bytes that were actually written to the file. This could even be 0, although short writes are unlikely for regular files in ordinary circumstances. -See also C<guestfs_pread>."); +See also C<guestfs_pread>, C<guestfs_pwrite_device>."); ("resize2fs_size", (RErr, [Device "device"; Int64 "size"]), 248, [], [], @@ -5166,6 +5166,23 @@ error occurs. See also C<guestfs_download>, C<guestfs_pread>."); + ("pwrite_device", (RInt "nbytes", [Device "device"; BufferIn "content"; Int64 "offset"]), 275, [ProtocolLimitWarning], + [InitPartition, Always, TestOutputList ( + [["pwrite_device"; "/dev/sda"; "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"; "446"]; + ["blockdev_rereadpt"; "/dev/sda"]; + ["list_partitions"]], [])], + "write to part of a device", + "\ +This command writes to part of a device. It writes the data +buffer C<content> to C<device> starting at offset C<offset>. + +This command implements the L<pwrite(2)> system call, and like +that system call it may not write the full data requested +(although short writes to disk devices and partitions are +probably impossible with standard Linux kernels). + +See also C<guestfs_pwrite>."); + ] let all_functions = non_daemon_functions @ daemon_functions diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index d4d5a4b..4c738e3 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -274 +275 -- 1.7.3
Possibly Parallel Threads
- [PATCH febootstrap 0/8] Add support for building an ext2-based appliance
- [PATCH 0/5] 5 conservative changes to errno handling
- [PATCH 0/8 v2 DISCUSSION ONLY] Connecting to live virtual machines
- [PATCH 0/9] Enhance virt-resize so it can really expand Linux and Windows guests
- [PATCH 0/7] Add libvirt domain to core API