[Libguestfs] [PATCH 1/4] inspect_os: Add support for detecting OpenBSD

Nikos Skalkotos skalkoto at grnet.gr
Wed Dec 3 14:10:48 UTC 2014


Signed-off-by: Nikos Skalkotos <skalkoto at grnet.gr>
---
 src/guestfs-internal.h |   1 +
 src/inspect-fs-unix.c  | 106 +++++++++++++++++++++++++++++++++++++++++++++++--
 src/inspect-fs.c       |  12 ++++++
 3 files changed, 116 insertions(+), 3 deletions(-)

diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 33d28f5..c8dd084 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -782,6 +782,7 @@ extern void guestfs___check_package_management (guestfs_h *g, struct inspect_fs
 extern int guestfs___check_linux_root (guestfs_h *g, struct inspect_fs *fs);
 extern int guestfs___check_freebsd_root (guestfs_h *g, struct inspect_fs *fs);
 extern int guestfs___check_netbsd_root (guestfs_h *g, struct inspect_fs *fs);
+extern int guestfs___check_openbsd_root (guestfs_h *g, struct inspect_fs *fs);
 extern int guestfs___check_hurd_root (guestfs_h *g, struct inspect_fs *fs);
 extern int guestfs___check_minix_root (guestfs_h *g, struct inspect_fs *fs);
 
diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c
index f55e53b..ab76bc6 100644
--- a/src/inspect-fs-unix.c
+++ b/src/inspect-fs-unix.c
@@ -80,6 +80,9 @@ COMPILE_REGEXP (re_sles_version, "^VERSION = (\\d+)", 0)
 COMPILE_REGEXP (re_sles_patchlevel, "^PATCHLEVEL = (\\d+)", 0)
 COMPILE_REGEXP (re_minix, "^(\\d+)\\.(\\d+)(\\.(\\d+))?", 0)
 COMPILE_REGEXP (re_hurd_dev, "^/dev/(h)d(\\d+)s(\\d+)$", 0)
+COMPILE_REGEXP (re_openbsd, "^OpenBSD (\\d+|\\?)\\.(\\d+|\\?)", 0)
+COMPILE_REGEXP (re_openbsd_duid, "^[0-9a-f]{16}\\.[a-z]", 0)
+COMPILE_REGEXP (re_openbsd_dev, "^/dev/(s|w)d([0-9])([a-z])$", 0)
 
 static void check_architecture (guestfs_h *g, struct inspect_fs *fs);
 static int check_hostname_unix (guestfs_h *g, struct inspect_fs *fs);
@@ -659,6 +662,55 @@ guestfs___check_netbsd_root (guestfs_h *g, struct inspect_fs *fs)
   return 0;
 }
 
+/* The currently mounted device may be an OpenBSD root. */
+int
+guestfs___check_openbsd_root (guestfs_h *g, struct inspect_fs *fs)
+{
+  if (guestfs_is_file_opts (g, "/etc/motd",
+                            GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) > 0) {
+    CLEANUP_FREE char *major = NULL, *minor = NULL;
+
+    /* The first line of this file gets automatically updated at boot. */
+    if (parse_release_file (g, fs, "/etc/motd") == -1)
+      return -1;
+
+    if (match2 (g, fs->product_name, re_openbsd, &major, &minor)) {
+      fs->type = OS_TYPE_OPENBSD;
+      fs->distro = OS_DISTRO_OPENBSD;
+
+      /* Before the first boot, the first line will look like this:
+       *
+       * OpenBSD ?.? (UNKNOWN)
+       */
+      if ((fs->product_name[8] != '?') && (fs->product_name[10] != '?')) {
+        fs->major_version = guestfs___parse_unsigned_int (g, major);
+        if (fs->major_version == -1)
+          return -1;
+
+        fs->minor_version = guestfs___parse_unsigned_int (g, minor);
+        if (fs->minor_version == -1)
+          return -1;
+      }
+    }
+  } else {
+    return -1;
+  }
+
+  /* Determine the architecture. */
+  check_architecture (g, fs);
+
+  /* We already know /etc/fstab exists because it's part of the test above. */
+  const char *configfiles[] = { "/etc/fstab", NULL };
+  if (inspect_with_augeas (g, fs, configfiles, check_fstab) == -1)
+    return -1;
+
+  /* Determine hostname. */
+  if (check_hostname_unix (g, fs) == -1)
+    return -1;
+
+  return 0;
+}
+
 /* The currently mounted device may be a Hurd root.  Hurd has distros
  * just like Linux.
  */
@@ -821,6 +873,18 @@ check_hostname_unix (guestfs_h *g, struct inspect_fs *fs)
     }
     break;
 
+  case OS_TYPE_OPENBSD:
+    if (guestfs_is_file (g, "/etc/myname")) {
+      fs->hostname = guestfs___first_line_of_file (g, "/etc/myname");
+      if (fs->hostname == NULL)
+        return -1;
+      if (STREQ (fs->hostname, "")) {
+        free (fs->hostname);
+        fs->hostname = NULL;
+      }
+    }
+    break;
+
   case OS_TYPE_MINIX:
     if (guestfs_is_file (g, "/etc/hostname.file")) {
       fs->hostname = guestfs___first_line_of_file (g, "/etc/hostname.file");
@@ -835,7 +899,6 @@ check_hostname_unix (guestfs_h *g, struct inspect_fs *fs)
 
   case OS_TYPE_WINDOWS: /* not here, see check_windows_system_registry */
   case OS_TYPE_DOS:
-  case OS_TYPE_OPENBSD:
   case OS_TYPE_UNKNOWN:
     /* nothing */;
   }
@@ -921,6 +984,9 @@ check_fstab (guestfs_h *g, struct inspect_fs *fs)
   char **entry;
   char augpath[256];
   CLEANUP_HASH_FREE Hash_table *md_map = NULL;
+  bool is_bsd = (fs->type == OS_TYPE_FREEBSD ||
+                 fs->type == OS_TYPE_NETBSD ||
+                 fs->type == OS_TYPE_OPENBSD);
 
   /* Generate a map of MD device paths listed in /etc/mdadm.conf to MD device
    * paths in the guestfs appliance */
@@ -975,12 +1041,31 @@ check_fstab (guestfs_h *g, struct inspect_fs *fs)
     else if (STRPREFIX (spec, "LABEL="))
       mountable = guestfs_findfs_label (g, &spec[6]);
     /* Ignore "/.swap" (Pardus) and pseudo-devices like "tmpfs". */
-    else if (STREQ (spec, "/dev/root"))
-      /* Resolve /dev/root to the current device. */
+    else if (STREQ (spec, "/dev/root") || (is_bsd && STREQ (mp, "/")))
+      /* Resolve /dev/root to the current device.
+       * Do the same for the / partition of the *BSD systems, since the
+       * BSD -> Linux device translation is not straight forward.
+       */
       mountable = safe_strdup (g, fs->mountable);
     else if (STRPREFIX (spec, "/dev/"))
       /* Resolve guest block device names. */
       mountable = resolve_fstab_device (g, spec, md_map);
+    else if (match (g, spec, re_openbsd_duid)) {
+      /* In OpenBSD's fstab you can specify partitions on a disk by appending a
+       * period and a partition letter to a Disklable Unique Identifier. The
+       * DUID is a 16 hex digit field found in the OpenBSD's altered BSD
+       * disklabel. For more info see here:
+       * http://www.openbsd.org/faq/faq14.html#intro
+       */
+       char device[10]; /* /dev/sd[0-9][a-z] */
+       char part = spec[17];
+
+       /* We cannot peep into disklables, we can only assume that this is the
+        * first disk.
+        */
+       snprintf(device, 10, "%s%c", "/dev/sd0", part);
+       mountable = resolve_fstab_device (g, device, md_map);
+    }
 
     /* If we haven't resolved the device successfully by this point,
      * we don't care, just ignore it.
@@ -1542,6 +1627,21 @@ resolve_fstab_device (guestfs_h *g, const char *spec, Hash_table *md_map)
       device = safe_asprintf (g, "/dev/sd%c%d", disk_i + 'a', part_i + 5);
     }
   }
+  else if (match3 (g, spec, re_openbsd_dev, &type, &disk, &part)) {
+    int disk_i = guestfs___parse_unsigned_int (g, disk);
+    int part_i = part[0] - 'a'; /* counting from 0 */
+    free (type);
+    free (disk);
+    free (part);
+
+    if (part_i > 2)
+      /* Partition 'c' is the hard disk itself. Not mapped under Linux */
+      part_i -= 1;
+
+    /* In OpenBSD MAXPARTITIONS is defined to 16 for all architectures */
+    if (disk_i != -1 && part_i >= 0 && part_i < 15)
+      device = safe_asprintf (g, "/dev/sd%c%d", disk_i + 'a', part_i + 5);
+  }
   else if ((part = match1 (g, spec, re_diskbyid)) != NULL) {
     r = resolve_fstab_device_diskbyid (g, part, &device);
     free (part);
diff --git a/src/inspect-fs.c b/src/inspect-fs.c
index fe82132..aaddb49 100644
--- a/src/inspect-fs.c
+++ b/src/inspect-fs.c
@@ -177,6 +177,7 @@ check_filesystem (guestfs_h *g, const char *mountable,
     if (guestfs___check_freebsd_root (g, fs) == -1)
       return -1;
   }
+  /* NetBSD root? */
   else if (is_dir_etc &&
            is_dir_bin &&
            guestfs_is_file (g, "/netbsd") > 0 &&
@@ -187,6 +188,17 @@ check_filesystem (guestfs_h *g, const char *mountable,
     if (guestfs___check_netbsd_root (g, fs) == -1)
       return -1;
   }
+  /* OpenBSD root? */
+  else if (is_dir_etc &&
+           is_dir_bin &&
+           guestfs_is_file (g, "/bsd") > 0 &&
+           guestfs_is_file (g, "/etc/fstab") > 0 &&
+           guestfs_is_file (g, "/etc/motd") > 0) {
+    fs->is_root = 1;
+    fs->format = OS_FORMAT_INSTALLED;
+    if (guestfs___check_openbsd_root (g, fs) == -1)
+      return -1;
+  }
   /* Hurd root? */
   else if (guestfs_is_file (g, "/hurd/console") > 0 &&
            guestfs_is_file (g, "/hurd/hello") > 0 &&
-- 
2.1.3




More information about the Libguestfs mailing list