diff options
-rw-r--r-- | daemon/zero.c | 75 | ||||
-rw-r--r-- | generator/generator_actions.ml | 28 | ||||
-rw-r--r-- | src/MAX_PROC_NR | 2 |
3 files changed, 101 insertions, 4 deletions
diff --git a/daemon/zero.c b/daemon/zero.c index 8fbd963d..c8e79ae9 100644 --- a/daemon/zero.c +++ b/daemon/zero.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * Copyright (C) 2009-2011 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 @@ -105,3 +105,76 @@ do_zero_device (const char *device) return 0; } + +static char zero[BUFSIZ]; + +int +do_is_zero (const char *path) +{ + int fd; + char buf[BUFSIZ]; + ssize_t r; + + CHROOT_IN; + fd = open (path, O_RDONLY); + CHROOT_OUT; + + if (fd == -1) { + reply_with_perror ("open: %s", path); + return -1; + } + + while ((r = read (fd, buf, sizeof buf)) > 0) { + if (memcmp (buf, zero, r) != 0) { + close (fd); + return 0; + } + } + + if (r == -1) { + reply_with_perror ("read: %s", path); + close (fd); + return -1; + } + + if (close (fd) == -1) { + reply_with_perror ("close: %s", path); + return -1; + } + + return 1; +} + +int +do_is_zero_device (const char *device) +{ + int fd; + char buf[BUFSIZ]; + ssize_t r; + + fd = open (device, O_RDONLY); + if (fd == -1) { + reply_with_perror ("open: %s", device); + return -1; + } + + while ((r = read (fd, buf, sizeof buf)) > 0) { + if (memcmp (buf, zero, r) != 0) { + close (fd); + return 0; + } + } + + if (r == -1) { + reply_with_perror ("read: %s", device); + close (fd); + return -1; + } + + if (close (fd) == -1) { + reply_with_perror ("close: %s", device); + return -1; + } + + return 1; +} diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index 44f47df1..d0aac875 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -2273,7 +2273,7 @@ command and it can change in future in ways beyond our control. In other words, the output is not guaranteed by the ABI. See also: L<file(1)>, C<guestfs_vfs_type>, C<guestfs_lstat>, -C<guestfs_is_file>, C<guestfs_is_blockdev> (etc)."); +C<guestfs_is_file>, C<guestfs_is_blockdev> (etc), C<guestfs_is_zero>."); ("command", (RString "output", [StringList "arguments"], []), 50, [ProtocolLimitWarning], [InitScratchFS, Always, TestOutput ( @@ -2979,7 +2979,8 @@ How many blocks are zeroed isn't specified (but it's I<not> enough to securely wipe the device). It should be sufficient to remove any partition tables, filesystem superblocks and so on. -See also: C<guestfs_zero_device>, C<guestfs_scrub_device>."); +See also: C<guestfs_zero_device>, C<guestfs_scrub_device>, +C<guestfs_is_zero_device>"); ("grub_install", (RErr, [Pathname "root"; Device "device"], []), 86, [], (* See: @@ -5937,6 +5938,29 @@ Instead, use the autosync flag (C<guestfs_set_autosync>) to control whether or not this operation is performed when the handle is closed."); + ("is_zero", (RBool "zeroflag", [Pathname "path"], []), 283, [], + [InitISOFS, Always, TestOutputTrue ( + [["is_zero"; "/100kallzeroes"]]); + InitISOFS, Always, TestOutputFalse ( + [["is_zero"; "/100kallspaces"]])], + "test if a file contains all zero bytes", + "\ +This returns true iff the file exists and the file is empty or +it contains all zero bytes."); + + ("is_zero_device", (RBool "zeroflag", [Device "device"], []), 284, [], + [InitBasicFS, Always, TestOutputTrue ( + [["umount"; "/dev/sda1"]; + ["zero_device"; "/dev/sda1"]; + ["is_zero_device"; "/dev/sda1"]]); + InitBasicFS, Always, TestOutputFalse ( + [["is_zero_device"; "/dev/sda1"]])], + "test if a device contains all zero bytes", + "\ +This returns true iff the device exists and contains all zero bytes. + +Note that for large devices this can take a long time to run."); + ] let all_functions = non_daemon_functions @ daemon_functions diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index e01062f1..c9716b72 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -282 +284 |