Richard W.M. Jones
2013-Jun-14  10:06 UTC
[Libguestfs] [PATCH 0/2] Fix inspection of Fedora guests (RHBZ#974489).
Here is a preliminary fix for this bug. I'm running the test suite on this now. Rich.
Richard W.M. Jones
2013-Jun-14  10:06 UTC
[Libguestfs] [PATCH 1/2] Add followsymlinks flag to is-file, is-dir, is-blockdev, is-chardev, is-fifo and is-socket APIs.
From: "Richard W.M. Jones" <rjones@redhat.com>
This adds an extra optional boolean 'followsymlinks' flag to those 6
is-* APIs.  If the flag is true, then symlinks are followed, ie. we
use stat instead of lstat in the test.
For the rationale behind this change, see:
https://bugzilla.redhat.com/show_bug.cgi?id=974489
---
 daemon/is.c                              | 72 +++++++++++++++++++++-------
 generator/actions.ml                     | 82 ++++++++++++++++++++++----------
 gobject/Makefile.inc                     | 12 +++++
 po/POTFILES                              |  6 +++
 sysprep/firstboot.ml                     |  4 +-
 sysprep/sysprep_operation_cron_spool.ml  |  2 +-
 sysprep/sysprep_operation_hostname.ml    |  2 +-
 sysprep/sysprep_operation_random_seed.ml |  2 +-
 8 files changed, 135 insertions(+), 47 deletions(-)
diff --git a/daemon/is.c b/daemon/is.c
index f892ccf..4acdef6 100644
--- a/daemon/is.c
+++ b/daemon/is.c
@@ -1,5 +1,5 @@
 /* libguestfs - the guestfsd daemon
- * Copyright (C) 2010 Red Hat Inc.
+ * Copyright (C) 2010-2013 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
@@ -41,49 +41,79 @@ do_exists (const char *path)
   return r == 0;
 }
 
-static int get_mode (const char *path, mode_t *mode);
+static int get_mode (const char *path, mode_t *mode, int followsymlinks);
 
+/* Takes optional arguments, consult optargs_bitmask. */
 int
-do_is_file (const char *path)
+do_is_file (const char *path, int followsymlinks)
 {
   mode_t mode;
-  int r = get_mode (path, &mode);
+  int r;
+
+  if (!(optargs_bitmask & GUESTFS_IS_FILE_FOLLOWSYMLINKS_BITMASK))
+    followsymlinks = 0;
+
+  r = get_mode (path, &mode, followsymlinks);
   if (r <= 0) return r;
   return S_ISREG (mode);
 }
 
+/* Takes optional arguments, consult optargs_bitmask. */
 int
-do_is_dir (const char *path)
+do_is_dir (const char *path, int followsymlinks)
 {
   mode_t mode;
-  int r = get_mode (path, &mode);
+  int r;
+
+  if (!(optargs_bitmask & GUESTFS_IS_DIR_FOLLOWSYMLINKS_BITMASK))
+    followsymlinks = 0;
+
+  r = get_mode (path, &mode, followsymlinks);
   if (r <= 0) return r;
   return S_ISDIR (mode);
 }
 
+/* Takes optional arguments, consult optargs_bitmask. */
 int
-do_is_chardev (const char *path)
+do_is_chardev (const char *path, int followsymlinks)
 {
   mode_t mode;
-  int r = get_mode (path, &mode);
+  int r;
+
+  if (!(optargs_bitmask & GUESTFS_IS_CHARDEV_FOLLOWSYMLINKS_BITMASK))
+    followsymlinks = 0;
+
+  r = get_mode (path, &mode, followsymlinks);
   if (r <= 0) return r;
   return S_ISCHR (mode);
 }
 
+/* Takes optional arguments, consult optargs_bitmask. */
 int
-do_is_blockdev (const char *path)
+do_is_blockdev (const char *path, int followsymlinks)
 {
   mode_t mode;
-  int r = get_mode (path, &mode);
+  int r;
+
+  if (!(optargs_bitmask & GUESTFS_IS_BLOCKDEV_FOLLOWSYMLINKS_BITMASK))
+    followsymlinks = 0;
+
+  r = get_mode (path, &mode, followsymlinks);
   if (r <= 0) return r;
   return S_ISBLK (mode);
 }
 
+/* Takes optional arguments, consult optargs_bitmask. */
 int
-do_is_fifo (const char *path)
+do_is_fifo (const char *path, int followsymlinks)
 {
   mode_t mode;
-  int r = get_mode (path, &mode);
+  int r;
+
+  if (!(optargs_bitmask & GUESTFS_IS_FIFO_FOLLOWSYMLINKS_BITMASK))
+    followsymlinks = 0;
+
+  r = get_mode (path, &mode, followsymlinks);
   if (r <= 0) return r;
   return S_ISFIFO (mode);
 }
@@ -92,28 +122,36 @@ int
 do_is_symlink (const char *path)
 {
   mode_t mode;
-  int r = get_mode (path, &mode);
+  int r;
+
+  r = get_mode (path, &mode, 0);
   if (r <= 0) return r;
   return S_ISLNK (mode);
 }
 
+/* Takes optional arguments, consult optargs_bitmask. */
 int
-do_is_socket (const char *path)
+do_is_socket (const char *path, int followsymlinks)
 {
   mode_t mode;
-  int r = get_mode (path, &mode);
+  int r;
+
+  if (!(optargs_bitmask & GUESTFS_IS_SOCKET_FOLLOWSYMLINKS_BITMASK))
+    followsymlinks = 0;
+
+  r = get_mode (path, &mode, followsymlinks);
   if (r <= 0) return r;
   return S_ISSOCK (mode);
 }
 
 static int
-get_mode (const char *path, mode_t *mode)
+get_mode (const char *path, mode_t *mode, int followsymlinks)
 {
   int r;
   struct stat buf;
 
   CHROOT_IN;
-  r = lstat (path, &buf);
+  r = (!followsymlinks ? lstat : stat) (path, &buf);
   CHROOT_OUT;
 
   if (r == -1) {
diff --git a/generator/actions.ml b/generator/actions.ml
index 192072b..83a1080 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -3471,7 +3471,7 @@ command." };
     tests = [
       InitScratchFS, Always, TestResultTrue
         [["mkdir"; "/mkdir"];
-         ["is_dir"; "/mkdir"]];
+         ["is_dir"; "/mkdir"; ""]];
       InitScratchFS, Always, TestLastFail
         [["mkdir"; "/mkdir2/foo/bar"]]
     ];
@@ -3486,13 +3486,13 @@ Create a directory named C<path>." };
     tests = [
       InitScratchFS, Always, TestResultTrue
         [["mkdir_p"; "/mkdir_p/foo/bar"];
-         ["is_dir"; "/mkdir_p/foo/bar"]];
+         ["is_dir"; "/mkdir_p/foo/bar"; ""]];
       InitScratchFS, Always, TestResultTrue
         [["mkdir_p"; "/mkdir_p2/foo/bar"];
-         ["is_dir"; "/mkdir_p2/foo"]];
+         ["is_dir"; "/mkdir_p2/foo"; ""]];
       InitScratchFS, Always, TestResultTrue
         [["mkdir_p"; "/mkdir_p3/foo/bar"];
-         ["is_dir"; "/mkdir_p3"]];
+         ["is_dir"; "/mkdir_p3"; ""]];
       (* Regression tests for RHBZ#503133: *)
       InitScratchFS, Always, TestRun
         [["mkdir"; "/mkdir_p4"];
@@ -3554,13 +3554,16 @@ See also C<guestfs_is_file>,
C<guestfs_is_dir>, C<guestfs_stat>." };
 
   { defaults with
     name = "is_file";
-    style = RBool "fileflag", [Pathname "path"], [];
+    style = RBool "fileflag", [Pathname "path"], [OBool
"followsymlinks"];
     proc_nr = Some 37;
+    once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResultTrue (
-        [["is_file"; "/known-1"]]);
+        [["is_file"; "/known-1"; ""]]);
       InitISOFS, Always, TestResultFalse (
-        [["is_file"; "/directory"]])
+        [["is_file"; "/directory"; ""]]);
+      InitISOFS, Always, TestResultTrue (
+        [["is_file"; "/abssymlink"; "true"]])
     ];
     shortdesc = "test if a regular file";
     longdesc = "\
@@ -3568,17 +3571,22 @@ This returns C<true> if and only if there is a
regular file
 with the given C<path> name.  Note that it returns false for
 other objects like directories.
 
+If the optional flag C<followsymlinks> is true, then a symlink
+(or chain of symlinks) that ends with a file also causes the
+function to return true.
+
 See also C<guestfs_stat>." };
 
   { defaults with
     name = "is_dir";
-    style = RBool "dirflag", [Pathname "path"], [];
+    style = RBool "dirflag", [Pathname "path"], [OBool
"followsymlinks"];
     proc_nr = Some 38;
+    once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResultFalse (
-        [["is_dir"; "/known-3"]]);
+        [["is_dir"; "/known-3"; ""]]);
       InitISOFS, Always, TestResultTrue (
-        [["is_dir"; "/directory"]])
+        [["is_dir"; "/directory"; ""]])
     ];
     shortdesc = "test if a directory";
     longdesc = "\
@@ -3586,6 +3594,10 @@ This returns C<true> if and only if there is a
directory
 with the given C<path> name.  Note that it returns false for
 other objects like files.
 
+If the optional flag C<followsymlinks> is true, then a symlink
+(or chain of symlinks) that ends with a directory also causes the
+function to return true.
+
 See also C<guestfs_stat>." };
 
   { defaults with
@@ -4796,7 +4808,7 @@ C<guestfs_is_zero_device>" };
         [["mkdir_p"; "/boot/grub"];
          ["write"; "/boot/grub/device.map"; "(hd0)
/dev/sda"];
          ["grub_install"; "/"; "/dev/sda"];
-         ["is_dir"; "/boot"]])
+         ["is_dir"; "/boot"; ""]])
     ];
     shortdesc = "install GRUB 1";
     longdesc = "\
@@ -4850,7 +4862,7 @@ replacing C</dev/vda> with the name of the
installation device.
         [["mkdir"; "/cp2"];
          ["write"; "/cp2/old"; "file content"];
          ["cp"; "/cp2/old"; "/cp2/new"];
-         ["is_file"; "/cp2/old"]]);
+         ["is_file"; "/cp2/old"; ""]]);
       InitScratchFS, Always, TestResultString (
         [["mkdir"; "/cp3"];
          ["write"; "/cp3/old"; "file content"];
@@ -4894,7 +4906,7 @@ recursively using the C<cp -a> command." };
         [["mkdir"; "/mv2"];
          ["write"; "/mv2/old"; "file content"];
          ["mv"; "/mv2/old"; "/mv2/new"];
-         ["is_file"; "/mv2/old"]])
+         ["is_file"; "/mv2/old"; ""]])
     ];
     shortdesc = "move a file";
     longdesc = "\
@@ -8373,56 +8385,71 @@ To find the label of a filesystem, use
C<guestfs_vfs_label>." };
 
   { defaults with
     name = "is_chardev";
-    style = RBool "flag", [Pathname "path"], [];
+    style = RBool "flag", [Pathname "path"], [OBool
"followsymlinks"];
     proc_nr = Some 267;
+    once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResultFalse (
-        [["is_chardev"; "/directory"]]);
+        [["is_chardev"; "/directory"; ""]]);
       InitScratchFS, Always, TestResultTrue (
         [["mknod_c"; "0o777"; "99";
"66"; "/is_chardev"];
-         ["is_chardev"; "/is_chardev"]])
+         ["is_chardev"; "/is_chardev"; ""]])
     ];
     shortdesc = "test if character device";
     longdesc = "\
 This returns C<true> if and only if there is a character device
 with the given C<path> name.
 
+If the optional flag C<followsymlinks> is true, then a symlink
+(or chain of symlinks) that ends with a chardev also causes the
+function to return true.
+
 See also C<guestfs_stat>." };
 
   { defaults with
     name = "is_blockdev";
-    style = RBool "flag", [Pathname "path"], [];
+    style = RBool "flag", [Pathname "path"], [OBool
"followsymlinks"];
     proc_nr = Some 268;
+    once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResultFalse (
-        [["is_blockdev"; "/directory"]]);
+        [["is_blockdev"; "/directory"; ""]]);
       InitScratchFS, Always, TestResultTrue (
         [["mknod_b"; "0o777"; "99";
"66"; "/is_blockdev"];
-         ["is_blockdev"; "/is_blockdev"]])
+         ["is_blockdev"; "/is_blockdev"; ""]])
     ];
     shortdesc = "test if block device";
     longdesc = "\
 This returns C<true> if and only if there is a block device
 with the given C<path> name.
 
+If the optional flag C<followsymlinks> is true, then a symlink
+(or chain of symlinks) that ends with a block device also causes the
+function to return true.
+
 See also C<guestfs_stat>." };
 
   { defaults with
     name = "is_fifo";
-    style = RBool "flag", [Pathname "path"], [];
+    style = RBool "flag", [Pathname "path"], [OBool
"followsymlinks"];
     proc_nr = Some 269;
+    once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResultFalse (
-        [["is_fifo"; "/directory"]]);
+        [["is_fifo"; "/directory"; ""]]);
       InitScratchFS, Always, TestResultTrue (
         [["mkfifo"; "0o777"; "/is_fifo"];
-         ["is_fifo"; "/is_fifo"]])
+         ["is_fifo"; "/is_fifo"; ""]])
     ];
     shortdesc = "test if FIFO (named pipe)";
     longdesc = "\
 This returns C<true> if and only if there is a FIFO (named pipe)
 with the given C<path> name.
 
+If the optional flag C<followsymlinks> is true, then a symlink
+(or chain of symlinks) that ends with a FIFO also causes the
+function to return true.
+
 See also C<guestfs_stat>." };
 
   { defaults with
@@ -8444,18 +8471,23 @@ See also C<guestfs_stat>." };
 
   { defaults with
     name = "is_socket";
-    style = RBool "flag", [Pathname "path"], [];
+    style = RBool "flag", [Pathname "path"], [OBool
"followsymlinks"];
     proc_nr = Some 271;
+    once_had_no_optargs = true;
     (* XXX Need a positive test for sockets. *)
     tests = [
       InitISOFS, Always, TestResultFalse (
-        [["is_socket"; "/directory"]])
+        [["is_socket"; "/directory"; ""]])
     ];
     shortdesc = "test if socket";
     longdesc = "\
 This returns C<true> if and only if there is a Unix domain socket
 with the given C<path> name.
 
+If the optional flag C<followsymlinks> is true, then a symlink
+(or chain of symlinks) that ends with a socket also causes the
+function to return true.
+
 See also C<guestfs_stat>." };
 
   { defaults with
@@ -11039,7 +11071,7 @@ for other partition types." };
         [["mkdir"; "/rename"];
          ["write"; "/rename/old"; "file
content"];
          ["rename"; "/rename/old";
"/rename/new"];
-         ["is_file"; "/rename/old"]])
+         ["is_file"; "/rename/old"; ""]])
     ];
     shortdesc = "rename a file on the same filesystem";
     longdesc = "\
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index f7d45fc..28727b6 100644
--- a/gobject/Makefile.inc
+++ b/gobject/Makefile.inc
@@ -51,11 +51,17 @@ guestfs_gobject_headers= \
   include/guestfs-gobject/optargs-inspect_get_icon.h \
   include/guestfs-gobject/optargs-mount_local.h \
   include/guestfs-gobject/optargs-umount_local.h \
+  include/guestfs-gobject/optargs-is_file.h \
+  include/guestfs-gobject/optargs-is_dir.h \
   include/guestfs-gobject/optargs-umount.h \
   include/guestfs-gobject/optargs-tar_in.h \
   include/guestfs-gobject/optargs-tar_out.h \
   include/guestfs-gobject/optargs-mkswap.h \
   include/guestfs-gobject/optargs-grep.h \
+  include/guestfs-gobject/optargs-is_chardev.h \
+  include/guestfs-gobject/optargs-is_blockdev.h \
+  include/guestfs-gobject/optargs-is_fifo.h \
+  include/guestfs-gobject/optargs-is_socket.h \
   include/guestfs-gobject/optargs-mkfs.h \
   include/guestfs-gobject/optargs-mount_9p.h \
   include/guestfs-gobject/optargs-ntfsresize.h \
@@ -118,11 +124,17 @@ guestfs_gobject_sources= \
   src/optargs-inspect_get_icon.c \
   src/optargs-mount_local.c \
   src/optargs-umount_local.c \
+  src/optargs-is_file.c \
+  src/optargs-is_dir.c \
   src/optargs-umount.c \
   src/optargs-tar_in.c \
   src/optargs-tar_out.c \
   src/optargs-mkswap.c \
   src/optargs-grep.c \
+  src/optargs-is_chardev.c \
+  src/optargs-is_blockdev.c \
+  src/optargs-is_fifo.c \
+  src/optargs-is_socket.c \
   src/optargs-mkfs.c \
   src/optargs-mount_9p.c \
   src/optargs-ntfsresize.c \
diff --git a/po/POTFILES b/po/POTFILES
index 327fc20..bc8fbdd 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -165,6 +165,12 @@ gobject/src/optargs-inspect_get_icon.c
 gobject/src/optargs-internal_test.c
 gobject/src/optargs-internal_test_63_optargs.c
 gobject/src/optargs-internal_test_only_optargs.c
+gobject/src/optargs-is_blockdev.c
+gobject/src/optargs-is_chardev.c
+gobject/src/optargs-is_dir.c
+gobject/src/optargs-is_fifo.c
+gobject/src/optargs-is_file.c
+gobject/src/optargs-is_socket.c
 gobject/src/optargs-md_create.c
 gobject/src/optargs-mke2fs.c
 gobject/src/optargs-mkfs.c
diff --git a/sysprep/firstboot.ml b/sysprep/firstboot.ml
index 7d49379..16e9212 100644
--- a/sysprep/firstboot.ml
+++ b/sysprep/firstboot.ml
@@ -77,7 +77,7 @@ WantedBy=default.target
 let failed fs    ksprintf (fun msg -> failwith (s_"firstboot: failed:
" ^ msg)) fs
 
-let rec install_service g distro +let rec install_service (g : Guestfs.guestfs)
distro    g#mkdir_p firstboot_dir;
   g#mkdir_p (sprintf "%s/scripts" firstboot_dir);
   g#write (sprintf "%s/firstboot.sh" firstboot_dir) firstboot_sh;
@@ -145,7 +145,7 @@ and install_sysvinit_debian g    g#ln_sf
"/etc/init.d/virt-sysprep-firstboot"
     "/etc/rc5.d/S99virt-sysprep-firstboot"
 
-let add_firstboot_script g root id content +let add_firstboot_script (g :
Guestfs.guestfs) root id content    let typ = g#inspect_get_type root in
   let distro = g#inspect_get_distro root in
   match typ, distro with
diff --git a/sysprep/sysprep_operation_cron_spool.ml
b/sysprep/sysprep_operation_cron_spool.ml
index 90eea03..f61769d 100644
--- a/sysprep/sysprep_operation_cron_spool.ml
+++ b/sysprep/sysprep_operation_cron_spool.ml
@@ -21,7 +21,7 @@ open Common_gettext.Gettext
 
 module G = Guestfs
 
-let cron_spool_perform g root +let cron_spool_perform (g : Guestfs.guestfs)
root    Array.iter g#rm_rf (g#glob_expand "/var/spool/cron/*");
   Array.iter g#rm (g#glob_expand "/var/spool/atjobs/*");
   Array.iter g#rm (g#glob_expand "/var/spool/atjobs/.SEQ");
diff --git a/sysprep/sysprep_operation_hostname.ml
b/sysprep/sysprep_operation_hostname.ml
index d38335e..e8767f3 100644
--- a/sysprep/sysprep_operation_hostname.ml
+++ b/sysprep/sysprep_operation_hostname.ml
@@ -26,7 +26,7 @@ module G = Guestfs
 
 let hostname = ref "localhost.localdomain"
 
-let hostname_perform g root +let hostname_perform (g : Guestfs.guestfs) root   
let typ = g#inspect_get_type root in
   let distro = g#inspect_get_distro root in
   let major_version = g#inspect_get_major_version root in
diff --git a/sysprep/sysprep_operation_random_seed.ml
b/sysprep/sysprep_operation_random_seed.ml
index 6beb16f..c3d0dc5 100644
--- a/sysprep/sysprep_operation_random_seed.ml
+++ b/sysprep/sysprep_operation_random_seed.ml
@@ -21,7 +21,7 @@ open Common_gettext.Gettext
 
 module G = Guestfs
 
-let random_seed_perform g root +let random_seed_perform (g : Guestfs.guestfs)
root    let typ = g#inspect_get_type root in
   if typ = "linux" then (
     let files = [
-- 
1.8.2.1
Richard W.M. Jones
2013-Jun-14  10:06 UTC
[Libguestfs] [PATCH 2/2] inspection: Fix inspection of Fedora guests (RHBZ#974489).
From: "Richard W.M. Jones" <rjones@redhat.com>
Commit e71b2c11f59b3f8ae0c4b31c4ab5b0d1bfcdf181 broke inspection of
Fedora guests because guestfs_is_file returns false for
/etc/redhat-release (it's a symlink to a file, not a file).
We fix this by using the new followsymlinks flag added in the
previous commit.  Thus guestfs_is_file becomes
guestfs_is_file_opts (g, filename, GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1)
which checks if it's a file or a symlink to a file.
This fixes commit e71b2c11f59b3f8ae0c4b31c4ab5b0d1bfcdf181.
---
 src/inspect-fs-unix.c | 49 +++++++++++++++++++++++++++++++++----------------
 src/inspect-icon.c    |  6 ++++--
 2 files changed, 37 insertions(+), 18 deletions(-)
diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c
index a90f45e..9c0b310 100644
--- a/src/inspect-fs-unix.c
+++ b/src/inspect-fs-unix.c
@@ -404,7 +404,8 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs
*fs)
 
   fs->type = OS_TYPE_LINUX;
 
-  if (guestfs_is_file (g, "/etc/lsb-release") > 0) {
+  if (guestfs_is_file_opts (g, "/etc/lsb-release",
+                            GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) > 0)
{
     r = parse_lsb_release (g, fs);
     if (r == -1)        /* error */
       return -1;
@@ -412,7 +413,8 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs
*fs)
       goto skip_release_checks;
   }
 
-  if (guestfs_is_file (g, "/etc/redhat-release") > 0) {
+  if (guestfs_is_file_opts (g, "/etc/redhat-release",
+                            GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) > 0)
{
     fs->distro = OS_DISTRO_REDHAT_BASED; /* Something generic Red Hat-like.
*/
 
     if (parse_release_file (g, fs, "/etc/redhat-release") == -1)
@@ -493,7 +495,8 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs
*fs)
       fs->minor_version = 0;
     }
   }
-  else if (guestfs_is_file (g, "/etc/debian_version") > 0) {
+  else if (guestfs_is_file_opts (g, "/etc/debian_version",
+                                 GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1)
> 0) {
     fs->distro = OS_DISTRO_DEBIAN;
 
     if (parse_release_file (g, fs, "/etc/debian_version") == -1)
@@ -502,7 +505,8 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs
*fs)
     if (guestfs___parse_major_minor (g, fs) == -1)
       return -1;
   }
-  else if (guestfs_is_file (g, "/etc/pardus-release") > 0) {
+  else if (guestfs_is_file_opts (g, "/etc/pardus-release",
+                                 GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1)
> 0) {
     fs->distro = OS_DISTRO_PARDUS;
 
     if (parse_release_file (g, fs, "/etc/pardus-release") == -1)
@@ -511,14 +515,16 @@ guestfs___check_linux_root (guestfs_h *g, struct
inspect_fs *fs)
     if (guestfs___parse_major_minor (g, fs) == -1)
       return -1;
   }
-  else if (guestfs_is_file (g, "/etc/arch-release") > 0) {
+  else if (guestfs_is_file_opts (g, "/etc/arch-release",
+                                 GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1)
> 0) {
     fs->distro = OS_DISTRO_ARCHLINUX;
 
     /* /etc/arch-release file is empty and I can't see a way to
      * determine the actual release or product string.
      */
   }
-  else if (guestfs_is_file (g, "/etc/gentoo-release") > 0) {
+  else if (guestfs_is_file_opts (g, "/etc/gentoo-release",
+                                 GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1)
> 0) {
     fs->distro = OS_DISTRO_GENTOO;
 
     if (parse_release_file (g, fs, "/etc/gentoo-release") == -1)
@@ -527,7 +533,8 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs
*fs)
     if (guestfs___parse_major_minor (g, fs) == -1)
       return -1;
   }
-  else if (guestfs_is_file (g, "/etc/meego-release") > 0) {
+  else if (guestfs_is_file_opts (g, "/etc/meego-release",
+                                 GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1)
> 0) {
     fs->distro = OS_DISTRO_MEEGO;
 
     if (parse_release_file (g, fs, "/etc/meego-release") == -1)
@@ -536,7 +543,8 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs
*fs)
     if (guestfs___parse_major_minor (g, fs) == -1)
       return -1;
   }
-  else if (guestfs_is_file (g, "/etc/slackware-version") > 0) {
+  else if (guestfs_is_file_opts (g, "/etc/slackware-version",
+                                 GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1)
> 0) {
     fs->distro = OS_DISTRO_SLACKWARE;
 
     if (parse_release_file (g, fs, "/etc/slackware-version") == -1)
@@ -545,7 +553,8 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs
*fs)
     if (guestfs___parse_major_minor (g, fs) == -1)
       return -1;
   }
-  else if (guestfs_is_file (g, "/etc/ttylinux-target") > 0) {
+  else if (guestfs_is_file_opts (g, "/etc/ttylinux-target",
+                                 GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1)
> 0) {
     fs->distro = OS_DISTRO_TTYLINUX;
 
     if (parse_release_file (g, fs, "/etc/ttylinux-target") == -1)
@@ -554,7 +563,8 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs
*fs)
     if (guestfs___parse_major_minor (g, fs) == -1)
       return -1;
   }
-  else if (guestfs_is_file (g, "/etc/SuSE-release") > 0) {
+  else if (guestfs_is_file_opts (g, "/etc/SuSE-release",
+                                 GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1)
> 0) {
     fs->distro = OS_DISTRO_SUSE_BASED;
 
     if (parse_suse_release (g, fs, "/etc/SuSE-release") == -1)
@@ -564,8 +574,10 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs
*fs)
   /* Buildroot (http://buildroot.net) is an embedded Linux distro
    * toolkit.  It is used by specific distros such as Cirros.
    */
-  else if (guestfs_is_file (g, "/etc/br-version") > 0) {
-    if (guestfs_is_file (g, "/usr/share/cirros/logo") > 0)
+  else if (guestfs_is_file_opts (g, "/etc/br-version",
+                                 GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1)
> 0) {
+    if (guestfs_is_file_opts (g, "/usr/share/cirros/logo",
+                              GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) >
0)
       fs->distro = OS_DISTRO_CIRROS;
     else
       fs->distro = OS_DISTRO_BUILDROOT;
@@ -610,7 +622,8 @@ guestfs___check_freebsd_root (guestfs_h *g, struct
inspect_fs *fs)
    * we'll use that anyway.
    */
 
-  if (guestfs_is_file (g, "/etc/motd") > 0) {
+  if (guestfs_is_file_opts (g, "/etc/motd",
+                            GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) > 0)
{
     if (parse_release_file (g, fs, "/etc/motd") == -1)
       return -1;
 
@@ -638,7 +651,8 @@ int
 guestfs___check_netbsd_root (guestfs_h *g, struct inspect_fs *fs)
 {
 
-  if (guestfs_is_file (g, "/etc/release") > 0) {
+  if (guestfs_is_file_opts (g, "/etc/release",
+                            GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) > 0)
{
     char *major, *minor;
     if (parse_release_file (g, fs, "/etc/release") == -1)
       return -1;
@@ -683,7 +697,8 @@ guestfs___check_hurd_root (guestfs_h *g, struct inspect_fs
*fs)
 {
   fs->type = OS_TYPE_HURD;
 
-  if (guestfs_is_file (g, "/etc/debian_version") > 0) {
+  if (guestfs_is_file_opts (g, "/etc/debian_version",
+                            GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) > 0)
{
     fs->distro = OS_DISTRO_DEBIAN;
 
     if (parse_release_file (g, fs, "/etc/debian_version") == -1)
@@ -1495,7 +1510,9 @@ inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs,
 {
   /* Security: Refuse to do this if a config file is too large. */
   for (const char **i = configfiles; *i != NULL; i++) {
-    if (guestfs_is_file (g, *i) == 0) continue;
+    if (guestfs_is_file_opts (g, *i,
+                              GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) == 0)
+      continue;
 
     int64_t size = guestfs_filesize (g, *i);
     if (size == -1)
diff --git a/src/inspect-icon.c b/src/inspect-icon.c
index 728ee68..9ddba64 100644
--- a/src/inspect-icon.c
+++ b/src/inspect-icon.c
@@ -225,7 +225,8 @@ get_png (guestfs_h *g, struct inspect_fs *fs, const char
*filename,
   CLEANUP_FREE char *local = NULL;
   int r, w, h;
 
-  r = guestfs_is_file (g, filename);
+  r = guestfs_is_file_opts (g, filename,
+                            GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1);
   if (r == -1)
     return NULL; /* a real error */
   if (r == 0)
@@ -367,7 +368,8 @@ icon_cirros (guestfs_h *g, struct inspect_fs *fs, size_t
*size_r)
   CLEANUP_CMD_CLOSE struct command *cmd = guestfs___new_command (g);
   int r;
 
-  r = guestfs_is_file (g, CIRROS_LOGO);
+  r = guestfs_is_file_opts (g, CIRROS_LOGO,
+                            GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1);
   if (r == -1)
     return NULL; /* a real error */
   if (r == 0)
-- 
1.8.2.1
Richard W.M. Jones
2013-Jun-14  11:39 UTC
Re: [Libguestfs] [PATCH 0/2] Fix inspection of Fedora guests (RHBZ#974489).
On Fri, Jun 14, 2013 at 11:06:22AM +0100, Richard W.M. Jones wrote:> Here is a preliminary fix for this bug. > > I'm running the test suite on this now.The tests (check-release) all pass and it fixes the obvious bug with inspecting Fedora VMs. Therefore I have pushed this. Rich. -- 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#)
Reasonably Related Threads
- [PATCH] inspect: fix detection of newer CirrOS versions (RHBZ#1045450).
- [PATCH v10 00/10] Reimplement inspection in the daemon.
- [PATCH v9 00/11] Reimplement inspection in the daemon.
- [PATCH v12 00/11] Reimplement inspection in the daemon.
- [PATCH v11 00/10] Reimplement inspection in the daemon.