Add basic support for netbsd detection.
[libguestfs.git] / src / inspect_fs.c
index 3fa5c98..25bb492 100644 (file)
@@ -87,8 +87,6 @@ static int check_filesystem (guestfs_h *g, const char *device, int is_block, int
 static void check_package_format (guestfs_h *g, struct inspect_fs *fs);
 static void check_package_management (guestfs_h *g, struct inspect_fs *fs);
 static int extend_fses (guestfs_h *g);
-static int is_file_nocase (guestfs_h *g, const char *);
-static int is_dir_nocase (guestfs_h *g, const char *);
 
 /* Find out if 'device' contains a filesystem.  If it does, add
  * another entry in g->fses.
@@ -122,9 +120,16 @@ guestfs___check_for_filesystem_on (guestfs_h *g, const char *device,
 
   /* Try mounting the device.  As above, ignore errors. */
   g->error_cb = NULL;
-  int r = guestfs_mount_ro (g, device, "/");
-  if (r == -1 && vfs_type && STREQ (vfs_type, "ufs")) /* Hack for the *BSDs. */
+  int r;
+  if (vfs_type && STREQ (vfs_type, "ufs")) { /* Hack for the *BSDs. */
+    /* FreeBSD fs is a variant of ufs called ufs2 ... */
     r = guestfs_mount_vfs (g, "ro,ufstype=ufs2", "ufs", device, "/");
+    if (r == -1)
+      /* while NetBSD and OpenBSD use another variant labeled 44bsd */
+      r = guestfs_mount_vfs (g, "ro,ufstype=44bsd", "ufs", device, "/");
+  } else {
+    r = guestfs_mount_ro (g, device, "/");
+  }
   free (vfs_type);
   g->error_cb = old_error_cb;
   if (r == -1)
@@ -185,6 +190,23 @@ check_filesystem (guestfs_h *g, const char *device,
     if (guestfs___check_freebsd_root (g, fs) == -1)
       return -1;
   }
+  else if (is_dir_etc &&
+           is_dir_bin &&
+           guestfs_is_file (g, "/etc/fstab") > 0 &&
+           guestfs_is_file (g, "/etc/release") > 0) {
+    /* Ignore /dev/sda1 which is a shadow of the real root filesystem
+     * that is probably /dev/sda5 (see:
+     * http://www.freebsd.org/doc/handbook/disk-organization.html)
+     */
+    if (match (g, device, re_first_partition))
+      return 0;
+
+    fs->is_root = 1;
+    fs->content = FS_CONTENT_NETBSD_ROOT;
+    fs->format = OS_FORMAT_INSTALLED;
+    if (guestfs___check_netbsd_root (g, fs) == -1)
+      return -1;
+  }
   /* Linux root? */
   else if (is_dir_etc &&
            is_dir_bin &&
@@ -214,18 +236,8 @@ check_filesystem (guestfs_h *g, const char *device,
            guestfs_is_dir (g, "/run") > 0 &&
            guestfs_is_dir (g, "/spool") > 0)
     fs->content = FS_CONTENT_LINUX_VAR;
-  /* Windows root?
-   * Note that if a Windows guest has multiple disks and applications
-   * are installed on those other disks, then those other disks will
-   * contain "/Program Files" and "/System Volume Information".  Those
-   * would *not* be Windows root disks.  (RHBZ#674130)
-   */
-  else if (is_file_nocase (g, "/AUTOEXEC.BAT") > 0 ||
-           is_dir_nocase (g, "/WINDOWS/SYSTEM32") > 0 ||
-           is_dir_nocase (g, "/WIN32/SYSTEM32") > 0 ||
-           is_dir_nocase (g, "/WINNT/SYSTEM32") > 0 ||
-           is_file_nocase (g, "/boot.ini") > 0 ||
-           is_file_nocase (g, "/ntldr") > 0) {
+  /* Windows root? */
+  else if (guestfs___has_windows_systemroot (g) >= 0) {
     fs->is_root = 1;
     fs->content = FS_CONTENT_WINDOWS_ROOT;
     fs->format = OS_FORMAT_INSTALLED;
@@ -233,11 +245,11 @@ check_filesystem (guestfs_h *g, const char *device,
       return -1;
   }
   /* Windows volume with installed applications (but not root)? */
-  else if (is_dir_nocase (g, "/System Volume Information") > 0 &&
-           is_dir_nocase (g, "/Program Files") > 0)
+  else if (guestfs___is_dir_nocase (g, "/System Volume Information") > 0 &&
+           guestfs___is_dir_nocase (g, "/Program Files") > 0)
     fs->content = FS_CONTENT_WINDOWS_VOLUME_WITH_APPS;
   /* Windows volume (but not root)? */
-  else if (is_dir_nocase (g, "/System Volume Information") > 0)
+  else if (guestfs___is_dir_nocase (g, "/System Volume Information") > 0)
     fs->content = FS_CONTENT_WINDOWS_VOLUME;
   /* Install CD/disk?  Skip these checks if it's not a whole device
    * (eg. CD) or the first partition (eg. bootable USB key).
@@ -286,8 +298,8 @@ extend_fses (guestfs_h *g)
   return 0;
 }
 
-static int
-is_file_nocase (guestfs_h *g, const char *path)
+int
+guestfs___is_file_nocase (guestfs_h *g, const char *path)
 {
   char *p;
   int r;
@@ -300,8 +312,8 @@ is_file_nocase (guestfs_h *g, const char *path)
   return r > 0;
 }
 
-static int
-is_dir_nocase (guestfs_h *g, const char *path)
+int
+guestfs___is_dir_nocase (guestfs_h *g, const char *path)
 {
   char *p;
   int r;
@@ -373,7 +385,9 @@ check_package_format (guestfs_h *g, struct inspect_fs *fs)
   case OS_DISTRO_MEEGO:
   case OS_DISTRO_REDHAT_BASED:
   case OS_DISTRO_RHEL:
+  case OS_DISTRO_MAGEIA:
   case OS_DISTRO_MANDRIVA:
+  case OS_DISTRO_OPENSUSE:
   case OS_DISTRO_CENTOS:
   case OS_DISTRO_SCIENTIFIC_LINUX:
     fs->package_format = OS_PACKAGE_FORMAT_RPM;
@@ -396,6 +410,7 @@ check_package_format (guestfs_h *g, struct inspect_fs *fs)
     break;
 
   case OS_DISTRO_SLACKWARE:
+  case OS_DISTRO_TTYLINUX:
   case OS_DISTRO_WINDOWS:
   case OS_DISTRO_UNKNOWN:
   default:
@@ -438,11 +453,17 @@ check_package_management (guestfs_h *g, struct inspect_fs *fs)
   case OS_DISTRO_PARDUS:
     fs->package_management = OS_PACKAGE_MANAGEMENT_PISI;
     break;
+  case OS_DISTRO_MAGEIA:
   case OS_DISTRO_MANDRIVA:
     fs->package_management = OS_PACKAGE_MANAGEMENT_URPMI;
     break;
 
+  case OS_DISTRO_OPENSUSE:
+    fs->package_management = OS_PACKAGE_MANAGEMENT_ZYPPER;
+    break;
+
   case OS_DISTRO_SLACKWARE:
+  case OS_DISTRO_TTYLINUX:
   case OS_DISTRO_WINDOWS:
   case OS_DISTRO_UNKNOWN:
   default: