2 * Copyright (C) 2010 Red Hat Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "guestfs-internal.h"
31 #include "guestfs-internal-actions.h"
32 #include "guestfs_protocol.h"
36 * The current implementation just uses guestfs_vfs_type and doesn't
37 * try mounting anything, but we reserve the right in future to try
38 * mounting filesystems.
41 static void remove_from_list (char **list, const char *item);
42 static void check_with_vfs_type (guestfs_h *g, const char *dev, char ***ret, size_t *ret_size);
45 guestfs__list_filesystems (guestfs_h *g)
51 char **devices = NULL;
52 char **partitions = NULL;
56 /* Look to see if any devices directly contain filesystems
57 * (RHBZ#590167). However vfs-type will fail to tell us anything
58 * useful about devices which just contain partitions, so we also
59 * get the list of partitions and exclude the corresponding devices
60 * by using part-to-dev.
62 devices = guestfs_list_devices (g);
63 if (devices == NULL) goto error;
64 partitions = guestfs_list_partitions (g);
65 if (partitions == NULL) goto error;
66 mds = guestfs_list_md_devices (g);
67 if (mds == NULL) goto error;
69 for (i = 0; partitions[i] != NULL; ++i) {
70 char *dev = guestfs_part_to_dev (g, partitions[i]);
72 remove_from_list (devices, dev);
76 /* Use vfs-type to check for filesystems on devices. */
77 for (i = 0; devices[i] != NULL; ++i)
78 check_with_vfs_type (g, devices[i], &ret, &ret_size);
80 /* Use vfs-type to check for filesystems on partitions. */
81 for (i = 0; partitions[i] != NULL; ++i)
82 check_with_vfs_type (g, partitions[i], &ret, &ret_size);
84 /* Use vfs-type to check for filesystems on md devices. */
85 for (i = 0; mds[i] != NULL; ++i)
86 check_with_vfs_type (g, mds[i], &ret, &ret_size);
88 if (guestfs___feature_available (g, "lvm2")) {
89 /* Use vfs-type to check for filesystems on LVs. */
90 lvs = guestfs_lvs (g);
91 if (lvs == NULL) goto error;
93 for (i = 0; lvs[i] != NULL; ++i)
94 check_with_vfs_type (g, lvs[i], &ret, &ret_size);
97 guestfs___free_string_list (devices);
98 guestfs___free_string_list (partitions);
99 guestfs___free_string_list (mds);
100 if (lvs) guestfs___free_string_list (lvs);
104 if (devices) guestfs___free_string_list (devices);
105 if (partitions) guestfs___free_string_list (partitions);
106 if (mds) guestfs___free_string_list (mds);
107 if (lvs) guestfs___free_string_list (lvs);
108 if (ret) guestfs___free_string_list (ret);
112 /* If 'item' occurs in 'list', remove and free it. */
114 remove_from_list (char **list, const char *item)
118 for (i = 0; list[i] != NULL; ++i)
119 if (STREQ (list[i], item)) {
121 for (; list[i+1] != NULL; ++i)
128 /* Use vfs-type to look for a filesystem of some sort on 'dev'.
129 * Apart from some types which we ignore, add the result to the
133 check_with_vfs_type (guestfs_h *g, const char *device,
134 char ***ret, size_t *ret_size)
138 guestfs_error_handler_cb old_error_cb = g->error_cb;
140 char *vfs_type = guestfs_vfs_type (g, device);
141 g->error_cb = old_error_cb;
144 v = safe_strdup (g, "unknown");
145 else if (STREQ (vfs_type, "")) {
147 v = safe_strdup (g, "unknown");
150 /* Ignore all "*_member" strings. In libblkid these are returned
151 * for things which are members of some RAID or LVM set, most
152 * importantly "LVM2_member" which is a PV.
154 size_t n = strlen (vfs_type);
155 if (n >= 7 && STREQ (&vfs_type[n-7], "_member")) {
160 /* Ignore LUKS-encrypted partitions. These are also containers. */
161 if (STREQ (vfs_type, "crypto_LUKS")) {
169 /* Extend the return array. */
170 size_t i = *ret_size;
172 *ret = safe_realloc (g, *ret, (*ret_size + 1) * sizeof (char *));
173 (*ret)[i] = safe_strdup (g, device);