/* 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; }
int main (int argc, char *argv[]) { guestfs_h *g; struct guestfs_internal_mountable *mountable; const char *devices[] = { "/dev/VG/LV", NULL }; const char *feature[] = { "btrfs", NULL }; g = guestfs_create (); if (g == NULL) { perror ("could not create handle"); exit (EXIT_FAILURE); } if (guestfs_add_drive_scratch (g, 1024*1024*1024, -1) == -1) { error: guestfs_close (g); exit (EXIT_FAILURE); } if (guestfs_launch (g) == -1) goto error; if (!guestfs_feature_available (g, (char **) feature)) { printf ("skipping test because btrfs is not available\n"); guestfs_close (g); exit (77); } if (!guestfs_filesystem_available (g, "btrfs")) { printf ("skipping test because btrfs filesystem is not available\n"); guestfs_close (g); exit (77); } if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1) goto error; if (guestfs_pvcreate (g, "/dev/sda1") == -1) goto error; const char *pvs[] = { "/dev/sda1", NULL }; if (guestfs_vgcreate (g, "VG", (char **) pvs) == -1) goto error; if (guestfs_lvcreate (g, "LV", "VG", 900) == -1) goto error; if (guestfs_mkfs_btrfs (g, (char * const *)devices, -1) == -1) goto error; if (guestfs_mount (g, "/dev/VG/LV", "/") == -1) goto error; if (guestfs_btrfs_subvolume_create (g, "/sv") == -1) goto error; mountable = guestfs_internal_parse_mountable (g, "/dev/VG/LV"); if (mountable == NULL) goto error; if (mountable->im_type != MOUNTABLE_DEVICE || STRNEQ ("/dev/VG/LV", mountable->im_device)) { fprintf (stderr, "incorrectly parsed /dev/VG/LV: im_device=%s\n", mountable->im_device); goto error; } guestfs_free_internal_mountable (mountable); mountable = guestfs_internal_parse_mountable (g, "btrfsvol:/dev/VG/LV/sv"); if (mountable == NULL) goto error; if (mountable->im_type != MOUNTABLE_BTRFSVOL || STRNEQ ("/dev/VG/LV", mountable->im_device) || STRNEQ ("sv", mountable->im_volume)) { fprintf (stderr, "incorrectly parsed /dev/VG/LV/sv: im_device=%s, im_volume=%s\n", mountable->im_device, mountable->im_volume); goto error; } guestfs_free_internal_mountable (mountable); guestfs_close (g); exit (EXIT_SUCCESS); }