New APIs: is-zero and is-zero-device, to test if file or device is all zeroes.
authorRichard W.M. Jones <rjones@redhat.com>
Tue, 17 May 2011 21:06:00 +0000 (22:06 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Tue, 17 May 2011 21:06:00 +0000 (22:06 +0100)
daemon/zero.c
generator/generator_actions.ml
src/MAX_PROC_NR

index 8fbd963..c8e79ae 100644 (file)
@@ -1,5 +1,5 @@
 /* libguestfs - the guestfsd daemon
 /* 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
  *
  * 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;
 }
 
   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;
+}
index 44f47df..d0aac87 100644 (file)
@@ -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>,
 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 (
 
   ("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.
 
 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:
 
   ("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.");
 
 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
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions
index e01062f..c9716b7 100644 (file)
@@ -1 +1 @@
-282
+284