Esempio n. 1
0
/* Use vfs-type to look for a filesystem of some sort on 'dev'.
 * Apart from some types which we ignore, add the result to the
 * 'ret' string list.
 */
static int
check_with_vfs_type (guestfs_h *g, const char *device, struct stringsbuf *sb)
{
  const char *v;
  CLEANUP_FREE char *vfs_type = NULL;

  guestfs_push_error_handler (g, NULL, NULL);
  vfs_type = guestfs_vfs_type (g, device);
  guestfs_pop_error_handler (g);

  if (!vfs_type)
    v = "unknown";
  else if (STREQ (vfs_type, ""))
    v = "unknown";
  else if (STREQ (vfs_type, "btrfs")) {
    CLEANUP_FREE_BTRFSSUBVOLUME_LIST struct guestfs_btrfssubvolume_list *vols =
      guestfs_btrfs_subvolume_list (g, device);

    if (vols == NULL)
      return -1;

    for (size_t i = 0; i < vols->len; i++) {
      struct guestfs_btrfssubvolume *this = &vols->val[i];
      guestfs_int_add_sprintf (g, sb,
			       "btrfsvol:%s/%s",
			       device, this->btrfssubvolume_path);
      guestfs_int_add_string (g, sb, "btrfs");
    }

    v = vfs_type;
  }
Esempio n. 2
0
/* Simple implementation of decryption: look for any crypto_LUKS
 * partitions and decrypt them, then rescan for VGs.  This only works
 * for Fedora whole-disk encryption.  WIP to make this work for other
 * encryption schemes.
 */
void
inspect_do_decrypt (void)
{
  CLEANUP_FREE_STRING_LIST char **partitions = guestfs_list_partitions (g);
  if (partitions == NULL)
    exit (EXIT_FAILURE);

  int need_rescan = 0;
  size_t i;
  for (i = 0; partitions[i] != NULL; ++i) {
    CLEANUP_FREE char *type = guestfs_vfs_type (g, partitions[i]);
    if (type && STREQ (type, "crypto_LUKS")) {
      char mapname[32];
      make_mapname (partitions[i], mapname, sizeof mapname);

      CLEANUP_FREE char *key = read_key (partitions[i]);
      /* XXX Should we call guestfs_luks_open_ro if readonly flag
       * is set?  This might break 'mount_ro'.
       */
      if (guestfs_luks_open (g, partitions[i], key, mapname) == -1)
        exit (EXIT_FAILURE);

      need_rescan = 1;
    }
  }

  if (need_rescan) {
    if (guestfs_vgscan (g) == -1)
      exit (EXIT_FAILURE);
    if (guestfs_vg_activate_all (g, 1) == -1)
      exit (EXIT_FAILURE);
  }
}
Esempio n. 3
0
/* Use vfs-type to look for a filesystem of some sort on 'dev'.
 * Apart from some types which we ignore, add the result to the
 * 'ret' string list.
 */
static void
check_with_vfs_type (guestfs_h *g, const char *device,
                     char ***ret, size_t *ret_size)
{
  char *v;
  char *vfs_type;

  guestfs_push_error_handler (g, NULL, NULL);
  vfs_type = guestfs_vfs_type (g, device);
  guestfs_pop_error_handler (g);

  if (!vfs_type)
    v = safe_strdup (g, "unknown");
  else if (STREQ (vfs_type, "")) {
    v = safe_strdup (g, "unknown");
    free (vfs_type);
  }
  else if (STREQ (vfs_type, "btrfs")) {
    CLEANUP_FREE_BTRFSSUBVOLUME_LIST struct guestfs_btrfssubvolume_list *vols =
      guestfs_btrfs_subvolume_list (g, device);

    for (size_t i = 0; i < vols->len; i++) {
      struct guestfs_btrfssubvolume *this = &vols->val[i];
      char *mountable = safe_asprintf (g, "btrfsvol:%s/%s",
                                       device, this->btrfssubvolume_path);
      add_vfs (g, mountable, safe_strdup (g, "btrfs"), ret, ret_size);
    }

    v = vfs_type;
  }
Esempio n. 4
0
static void
output_filesystems (xmlTextWriterPtr xo, char *root)
{
  char *str;
  size_t i;

  CLEANUP_FREE_STRING_LIST char **filesystems =
    guestfs_inspect_get_filesystems (g, root);
  if (filesystems == NULL)
    exit (EXIT_FAILURE);

  /* Sort by name so the output is stable. */
  qsort (filesystems, guestfs_int_count_strings (filesystems), sizeof (char *),
         compare_keys);

  XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "filesystems"));

  for (i = 0; filesystems[i] != NULL; ++i) {
    str = guestfs_canonical_device_name (g, filesystems[i]);
    if (!str)
      exit (EXIT_FAILURE);

    XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "filesystem"));
    XMLERROR (-1,
              xmlTextWriterWriteAttribute (xo, BAD_CAST "dev", BAD_CAST str));
    free (str);

    guestfs_push_error_handler (g, NULL, NULL);

    str = guestfs_vfs_type (g, filesystems[i]);
    if (str && str[0])
      XMLERROR (-1,
                xmlTextWriterWriteElement (xo, BAD_CAST "type",
                                           BAD_CAST str));
    free (str);

    str = guestfs_vfs_label (g, filesystems[i]);
    if (str && str[0])
      XMLERROR (-1,
                xmlTextWriterWriteElement (xo, BAD_CAST "label",
                                           BAD_CAST str));
    free (str);

    str = guestfs_vfs_uuid (g, filesystems[i]);
    if (str && str[0])
      XMLERROR (-1,
                xmlTextWriterWriteElement (xo, BAD_CAST "uuid",
                                           BAD_CAST str));
    free (str);

    guestfs_pop_error_handler (g);

    XMLERROR (-1, xmlTextWriterEndElement (xo));
  }

  XMLERROR (-1, xmlTextWriterEndElement (xo));
}
Esempio n. 5
0
/* Use vfs-type to look for a filesystem of some sort on 'dev'.
 * Apart from some types which we ignore, add the result to the
 * 'ret' string list.
 */
static void
check_with_vfs_type (guestfs_h *g, const char *device,
                     char ***ret, size_t *ret_size)
{
  char *v;

  guestfs_error_handler_cb old_error_cb = g->error_cb;
  g->error_cb = NULL;
  char *vfs_type = guestfs_vfs_type (g, device);
  g->error_cb = old_error_cb;

  if (!vfs_type)
    v = safe_strdup (g, "unknown");
  else if (STREQ (vfs_type, "")) {
    free (vfs_type);
    v = safe_strdup (g, "unknown");
  }
  else {
    /* Ignore all "*_member" strings.  In libblkid these are returned
     * for things which are members of some RAID or LVM set, most
     * importantly "LVM2_member" which is a PV.
     */
    size_t n = strlen (vfs_type);
    if (n >= 7 && STREQ (&vfs_type[n-7], "_member")) {
      free (vfs_type);
      return;
    }

    /* Ignore LUKS-encrypted partitions.  These are also containers. */
    if (STREQ (vfs_type, "crypto_LUKS")) {
      free (vfs_type);
      return;
    }

    v = vfs_type;
  }

  /* Extend the return array. */
  size_t i = *ret_size;
  *ret_size += 2;
  *ret = safe_realloc (g, *ret, (*ret_size + 1) * sizeof (char *));
  (*ret)[i] = safe_strdup (g, device);
  (*ret)[i+1] = v;
  (*ret)[i+2] = NULL;
}
Esempio n. 6
0
/* Use vfs-type to look for a filesystem of some sort on 'dev'.
 * Apart from some types which we ignore, add the result to the
 * 'ret' string list.
 */
static int
check_with_vfs_type (guestfs_h *g, const char *device, struct stringsbuf *sb)
{
  const char *v;
  CLEANUP_FREE char *vfs_type = NULL;

  guestfs_push_error_handler (g, NULL, NULL);
  vfs_type = guestfs_vfs_type (g, device);
  guestfs_pop_error_handler (g);

  if (!vfs_type)
    v = "unknown";
  else if (STREQ (vfs_type, ""))
    v = "unknown";
  else if (STREQ (vfs_type, "btrfs")) {
    CLEANUP_FREE_BTRFSSUBVOLUME_LIST struct guestfs_btrfssubvolume_list *vols =
      guestfs_btrfs_subvolume_list (g, device);

    if (vols == NULL)
      return -1;

    int64_t default_volume = guestfs_btrfs_subvolume_get_default (g, device);

    for (size_t i = 0; i < vols->len; i++) {
      struct guestfs_btrfssubvolume *this = &vols->val[i];

      /* Ignore the default subvolume.  We get it by simply mounting
       * the whole device of this btrfs filesystem.
       */
      if (this->btrfssubvolume_id == (uint64_t) default_volume)
        continue;

      guestfs_int_add_sprintf (g, sb,
			       "btrfsvol:%s/%s",
			       device, this->btrfssubvolume_path);
      guestfs_int_add_string (g, sb, "btrfs");
    }

    v = vfs_type;
  }
Esempio n. 7
0
/* Find out if 'device' contains a filesystem.  If it does, add
 * another entry in g->fses.
 */
int
guestfs_int_check_for_filesystem_on (guestfs_h *g, const char *mountable)
{
  CLEANUP_FREE char *vfs_type = NULL;
  int is_swap, r;
  struct inspect_fs *fs;
  CLEANUP_FREE_INTERNAL_MOUNTABLE struct guestfs_internal_mountable *m = NULL;
  int whole_device = 0;

  /* Get vfs-type in order to check if it's a Linux(?) swap device.
   * If there's an error we should ignore it, so to do that we have to
   * temporarily replace the error handler with a null one.
   */
  guestfs_push_error_handler (g, NULL, NULL);
  vfs_type = guestfs_vfs_type (g, mountable);
  guestfs_pop_error_handler (g);

  is_swap = vfs_type && STREQ (vfs_type, "swap");
  debug (g, "check_for_filesystem_on: %s (%s)",
         mountable, vfs_type ? vfs_type : "failed to get vfs type");

  if (is_swap) {
    extend_fses (g);
    fs = &g->fses[g->nr_fses-1];
    fs->mountable = safe_strdup (g, mountable);
    return 0;
  }

  m = guestfs_internal_parse_mountable (g, mountable);
  if (m == NULL)
    return -1;

  /* If it's a whole device, see if it is an install ISO. */
  if (m->im_type == MOUNTABLE_DEVICE) {
    whole_device = guestfs_is_whole_device (g, m->im_device);
    if (whole_device == -1) {
      return -1;
    }
  }

  if (whole_device) {
    extend_fses (g);
    fs = &g->fses[g->nr_fses-1];

    r = guestfs_int_check_installer_iso (g, fs, m->im_device);
    if (r == -1) {              /* Fatal error. */
      g->nr_fses--;
      return -1;
    }
    if (r > 0)                  /* Found something. */
      return 0;

    /* Didn't find anything.  Fall through ... */
    g->nr_fses--;
  }

  /* Try mounting the device.  As above, ignore errors. */
  guestfs_push_error_handler (g, NULL, NULL);
  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", mountable, "/");
    if (r == -1)
      /* while NetBSD and OpenBSD use another variant labeled 44bsd */
      r = guestfs_mount_vfs (g, "ro,ufstype=44bsd", "ufs", mountable, "/");
  } else {
    r = guestfs_mount_ro (g, mountable, "/");
  }
  guestfs_pop_error_handler (g);
  if (r == -1)
    return 0;

  /* Do the rest of the checks. */
  r = check_filesystem (g, mountable, m, whole_device);

  /* Unmount the filesystem. */
  if (guestfs_umount_all (g) == -1)
    return -1;

  return r;
}