mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
New API: list-filesystems: list filesystems
This API is a simpler replacement for the guestfish commands list-devices / list-partitions / lvs, in the case where you are just examining a guest by hand to see what it contains. Typical usage and output in guestfish is like this: $ guestfish --ro -a /dev/vg_trick/F13x64 ><fs> run ><fs> list-filesystems /dev/vda1: ext4 /dev/vg_f13x64/lv_root: ext4 /dev/vg_f13x64/lv_swap: swap It can also be used to replace programs that try to mount devices to determine if they are mountable filesystems.
This commit is contained in:
@@ -747,7 +747,9 @@ This function cannot decrypt encrypted disks. The caller
|
||||
must do that first (supplying the necessary keys) if the
|
||||
disk is encrypted.
|
||||
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.");
|
||||
Please read L<guestfs(3)/INSPECTION> for more details.
|
||||
|
||||
See also C<guestfs_list_filesystems>.");
|
||||
|
||||
("inspect_get_type", (RString "name", [Device "root"]), -1, [],
|
||||
[],
|
||||
@@ -955,6 +957,39 @@ it has no effect.");
|
||||
"\
|
||||
This returns the enable network flag.");
|
||||
|
||||
("list_filesystems", (RHashtable "fses", []), -1, [],
|
||||
[],
|
||||
"list filesystems",
|
||||
"\
|
||||
This inspection command looks for filesystems on partitions,
|
||||
block devices and logical volumes, returning a list of devices
|
||||
containing filesystems and their type.
|
||||
|
||||
The return value is a hash, where the keys are the devices
|
||||
containing filesystems, and the values are the filesystem types.
|
||||
For example:
|
||||
|
||||
\"/dev/sda1\" => \"ntfs\"
|
||||
\"/dev/sda2\" => \"ext2\"
|
||||
\"/dev/vg_guest/lv_root\" => \"ext4\"
|
||||
\"/dev/vg_guest/lv_swap\" => \"swap\"
|
||||
|
||||
The value can have the special value \"unknown\", meaning the
|
||||
content of the device is undetermined or empty.
|
||||
\"swap\" means a Linux swap partition.
|
||||
|
||||
This command runs other libguestfs commands, which might include
|
||||
C<guestfs_mount> and C<guestfs_umount>, and therefore you should
|
||||
use this soon after launch and only when nothing is mounted.
|
||||
|
||||
Not all of the filesystems returned will be mountable. In
|
||||
particular, swap partitions are returned in the list. Also
|
||||
this command does not check that each filesystem
|
||||
found is valid and mountable, and some filesystems might
|
||||
be mountable but require special options. Filesystems may
|
||||
not all belong to a single logical operating system
|
||||
(use C<guestfs_inspect_os> to look for OSes).");
|
||||
|
||||
]
|
||||
|
||||
(* daemon_functions are any functions which cause some action
|
||||
@@ -1064,7 +1099,9 @@ should probably use C<guestfs_readdir> instead.");
|
||||
"\
|
||||
List all the block devices.
|
||||
|
||||
The full block device names are returned, eg. C</dev/sda>");
|
||||
The full block device names are returned, eg. C</dev/sda>.
|
||||
|
||||
See also C<guestfs_list_filesystems>.");
|
||||
|
||||
("list_partitions", (RStringList "partitions", []), 8, [],
|
||||
[InitBasicFS, Always, TestOutputListOfDevices (
|
||||
@@ -1079,7 +1116,9 @@ List all the partitions detected on all block devices.
|
||||
The full partition device names are returned, eg. C</dev/sda1>
|
||||
|
||||
This does not return logical volumes. For that you will need to
|
||||
call C<guestfs_lvs>.");
|
||||
call C<guestfs_lvs>.
|
||||
|
||||
See also C<guestfs_list_filesystems>.");
|
||||
|
||||
("pvs", (RStringList "physvols", []), 9, [Optional "lvm2"],
|
||||
[InitBasicFSonLVM, Always, TestOutputListOfDevices (
|
||||
@@ -1143,7 +1182,7 @@ of the L<lvs(8)> command.
|
||||
This returns a list of the logical volume device names
|
||||
(eg. C</dev/VolGroup00/LogVol00>).
|
||||
|
||||
See also C<guestfs_lvs_full>.");
|
||||
See also C<guestfs_lvs_full>, C<guestfs_list_filesystems>.");
|
||||
|
||||
("pvs_full", (RStructList ("physvols", "lvm_pv"), []), 12, [Optional "lvm2"],
|
||||
[], (* XXX how to test? *)
|
||||
|
||||
137
src/inspect.c
137
src/inspect.c
@@ -1295,3 +1295,140 @@ guestfs__inspect_get_filesystems (guestfs_h *g, const char *root)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* List filesystems.
|
||||
*
|
||||
* The current implementation just uses guestfs_vfs_type and doesn't
|
||||
* try mounting anything, but we reserve the right in future to try
|
||||
* mounting filesystems.
|
||||
*/
|
||||
|
||||
static void remove_from_list (char **list, const char *item);
|
||||
static void check_with_vfs_type (guestfs_h *g, const char *dev, char ***ret, size_t *ret_size);
|
||||
|
||||
char **
|
||||
guestfs__list_filesystems (guestfs_h *g)
|
||||
{
|
||||
size_t i;
|
||||
char **ret;
|
||||
size_t ret_size;
|
||||
|
||||
ret = safe_malloc (g, sizeof (char *));
|
||||
ret[0] = NULL;
|
||||
ret_size = 0;
|
||||
|
||||
/* Look to see if any devices directly contain filesystems
|
||||
* (RHBZ#590167). However vfs-type will fail to tell us anything
|
||||
* useful about devices which just contain partitions, so we also
|
||||
* get the list of partitions and exclude the corresponding devices
|
||||
* by using part-to-dev.
|
||||
*/
|
||||
char **devices;
|
||||
devices = guestfs_list_devices (g);
|
||||
if (devices == NULL) {
|
||||
free_string_list (ret);
|
||||
return NULL;
|
||||
}
|
||||
char **partitions;
|
||||
partitions = guestfs_list_partitions (g);
|
||||
if (partitions == NULL) {
|
||||
free_string_list (devices);
|
||||
free_string_list (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; partitions[i] != NULL; ++i) {
|
||||
char *dev = guestfs_part_to_dev (g, partitions[i]);
|
||||
if (dev)
|
||||
remove_from_list (devices, dev);
|
||||
free (dev);
|
||||
}
|
||||
|
||||
/* Use vfs-type to check for filesystems on devices. */
|
||||
for (i = 0; devices[i] != NULL; ++i)
|
||||
check_with_vfs_type (g, devices[i], &ret, &ret_size);
|
||||
free_string_list (devices);
|
||||
|
||||
/* Use vfs-type to check for filesystems on partitions. */
|
||||
for (i = 0; partitions[i] != NULL; ++i)
|
||||
check_with_vfs_type (g, partitions[i], &ret, &ret_size);
|
||||
free_string_list (partitions);
|
||||
|
||||
if (feature_available (g, "lvm2")) {
|
||||
/* Use vfs-type to check for filesystems on LVs. */
|
||||
char **lvs;
|
||||
lvs = guestfs_lvs (g);
|
||||
if (lvs == NULL) {
|
||||
free_string_list (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; lvs[i] != NULL; ++i)
|
||||
check_with_vfs_type (g, lvs[i], &ret, &ret_size);
|
||||
free_string_list (lvs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If 'item' occurs in 'list', remove and free it. */
|
||||
static void
|
||||
remove_from_list (char **list, const char *item)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; list[i] != NULL; ++i)
|
||||
if (STREQ (list[i], item)) {
|
||||
free (list[i]);
|
||||
for (; list[i+1] != NULL; ++i)
|
||||
list[i] = list[i+1];
|
||||
list[i] = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user