From 598484729632d1207dc3e1493f27499de18d2242 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 17 May 2011 22:06:00 +0100 Subject: [PATCH] New APIs: is-zero and is-zero-device, to test if file or device is all zeroes. --- daemon/zero.c | 75 +++++++++++++++++++++++++++++++++++++++++- generator/generator_actions.ml | 28 ++++++++++++++-- src/MAX_PROC_NR | 2 +- 3 files changed, 101 insertions(+), 4 deletions(-) diff --git a/daemon/zero.c b/daemon/zero.c index 8fbd963..c8e79ae 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 44f47df..d0aac87 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, C, C, -C, C (etc)."); +C, C (etc), C."); ("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 enough to securely wipe the device). It should be sufficient to remove any partition tables, filesystem superblocks and so on. -See also: C, C."); +See also: C, C, +C"); ("grub_install", (RErr, [Pathname "root"; Device "device"], []), 86, [], (* See: @@ -5937,6 +5938,29 @@ Instead, use the autosync flag (C) 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 e01062f..c9716b7 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -282 +284 -- 1.8.3.1