2 * Copyright (C) 2010 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program 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
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <libvirt/libvirt.h>
28 #include <libvirt/virterror.h>
37 static void try_df (const char *name, const char *uuid, const char *dev, int offset);
38 static int find_dev_in_devices (const char *dev, char **devices);
40 /* Since we want this function to be robust against very bad failure
41 * cases (hello, https://bugzilla.kernel.org/show_bug.cgi?id=18792) it
42 * won't exit on guestfs failures.
45 df_on_handle (const char *name, const char *uuid, char **devices, int offset)
50 int free_devices = 0, is_lv;
53 fprintf (stderr, "df_on_handle %s devices=", name);
56 for (i = 0; devices[i] != NULL; ++i) {
59 fputs (devices[i], stderr);
64 fprintf (stderr, "null");
68 if (devices == NULL) {
69 devices = guestfs_list_devices (g);
74 /* Mask LVM for just the devices in the set. */
75 if (guestfs_lvm_set_filter (g, devices) == -1)
79 /* list-filesystems will return filesystems on every device ... */
80 fses = guestfs_list_filesystems (g);
84 /* ... so we need to filter out only the devices we are interested in. */
85 for (i = 0; fses[i] != NULL; i += 2) {
86 if (STRNEQ (fses[i+1], "") &&
87 STRNEQ (fses[i+1], "swap") &&
88 STRNEQ (fses[i+1], "unknown")) {
89 is_lv = guestfs_is_lv (g, fses[i]);
90 if (is_lv > 0) /* LVs are OK because of the LVM filter */
91 try_df (name, uuid, fses[i], -1);
92 else if (is_lv == 0) {
93 if (find_dev_in_devices (fses[i], devices))
94 try_df (name, uuid, fses[i], offset);
103 for (i = 0; fses[i] != NULL; ++i)
109 for (i = 0; devices[i] != NULL; ++i)
118 find_dev_in_devices (const char *dev, char **devices)
122 for (i = 0; devices[i] != NULL; ++i) {
123 if (STRPREFIX (dev, devices[i]))
131 try_df (const char *name, const char *uuid,
132 const char *dev, int offset)
134 struct guestfs_statvfs *stat = NULL;
135 guestfs_error_handler_cb old_error_cb;
136 void *old_error_data;
139 fprintf (stderr, "try_df %s %s %d\n", name, dev, offset);
141 /* Try mounting and stating the device. This might reasonably fail,
142 * so don't show errors.
144 old_error_cb = guestfs_get_error_handler (g, &old_error_data);
145 guestfs_set_error_handler (g, NULL, NULL);
147 if (guestfs_mount_ro (g, dev, "/") == 0) {
148 stat = guestfs_statvfs (g, "/");
149 guestfs_umount_all (g);
152 guestfs_set_error_handler (g, old_error_cb, old_error_data);
155 print_stat (name, uuid, dev, offset, stat);
156 guestfs_free_statvfs (stat);