1 /* libguestfs - the guestfsd daemon
2 * Copyright (C) 2009 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.
30 /* LVM actions. Keep an eye on liblvm, although at the time
31 * of writing it hasn't progressed very far.
35 convert_lvm_output (char *out, char *prefix)
39 int size = 0, alloc = 0;
46 pend = strchr (p, '\n'); /* Get the next line of output. */
52 while (*p && isspace (*p)) /* Skip any leading whitespace. */
55 /* Sigh, skip trailing whitespace too. "pvs", I'm looking at you. */
57 while (*p && isspace (p[len]))
60 if (!*p) { /* Empty line? Skip it. */
67 snprintf (buf, sizeof buf, "%s%s", prefix, p);
72 if (add_string (&r, &size, &alloc, str) == -1) {
82 if (add_string (&r, &size, &alloc, NULL) == -1)
85 sort_strings (r, size-1);
95 r = command (&out, &err,
96 "/sbin/lvm", "pvs", "-o", "pv_name", "--noheadings", NULL);
98 reply_with_error ("%s", err);
106 return convert_lvm_output (out, NULL);
115 r = command (&out, &err,
116 "/sbin/lvm", "vgs", "-o", "vg_name", "--noheadings", NULL);
118 reply_with_error ("%s", err);
126 return convert_lvm_output (out, NULL);
135 r = command (&out, &err,
137 "-o", "vg_name,lv_name", "--noheadings",
138 "--separator", "/", NULL);
140 reply_with_error ("%s", err);
148 return convert_lvm_output (out, "/dev/");
151 /* These were so complex to implement that I ended up auto-generating
152 * the code. That code is in stubs.c, and it is generated as usual
155 guestfs_lvm_int_pv_list *
158 return parse_command_line_pvs ();
161 guestfs_lvm_int_vg_list *
164 return parse_command_line_vgs ();
167 guestfs_lvm_int_lv_list *
170 return parse_command_line_lvs ();
174 do_pvcreate (const char *device)
179 IS_DEVICE (device, -1);
181 r = command (NULL, &err,
182 "/sbin/lvm", "pvcreate", device, NULL);
184 reply_with_error ("%s", err);
194 do_vgcreate (const char *volgroup, char * const* const physvols)
202 argc = count_strings (physvols) + 3;
203 argv = malloc (sizeof (char *) * (argc + 1));
205 reply_with_perror ("malloc");
208 argv[0] = "/sbin/lvm";
209 argv[1] = "vgcreate";
211 for (i = 3; i <= argc; ++i)
212 argv[i] = physvols[i-3];
214 r = commandv (NULL, &err, argv);
216 reply_with_error ("%s", err);
226 do_lvcreate (const char *logvol, const char *volgroup, int mbytes)
232 snprintf (size, sizeof size, "%d", mbytes);
234 r = command (NULL, &err,
235 "/sbin/lvm", "lvcreate",
236 "-L", size, "-n", logvol, volgroup, NULL);
238 reply_with_error ("%s", err);
248 do_lvresize (const char *logvol, int mbytes)
254 IS_DEVICE (logvol, -1);
256 snprintf (size, sizeof size, "%d", mbytes);
258 r = command (NULL, &err,
259 "/sbin/lvm", "lvresize",
260 "-L", size, logvol, NULL);
262 reply_with_error ("lvresize: %s", err);
271 /* Super-dangerous command used for testing. It removes all
272 * LVs, VGs and PVs permanently.
275 do_lvm_remove_all (void)
286 for (i = 0; xs[i] != NULL; ++i) {
287 r = command (NULL, &err, "/sbin/lvm", "lvremove", "-f", xs[i], NULL);
289 reply_with_error ("lvremove: %s: %s", xs[i], err);
303 for (i = 0; xs[i] != NULL; ++i) {
304 r = command (NULL, &err, "/sbin/lvm", "vgremove", "-f", xs[i], NULL);
306 reply_with_error ("vgremove: %s: %s", xs[i], err);
320 for (i = 0; xs[i] != NULL; ++i) {
321 r = command (NULL, &err, "/sbin/lvm", "pvremove", "-f", xs[i], NULL);
323 reply_with_error ("pvremove: %s: %s", xs[i], err);
332 /* There, that was easy, sorry about your data. */
337 do_lvremove (const char *device)
342 IS_DEVICE (device, -1);
344 r = command (NULL, &err,
345 "/sbin/lvm", "lvremove", "-f", device, NULL);
347 reply_with_error ("%s", err);
357 do_vgremove (const char *device)
362 IS_DEVICE (device, -1);
364 r = command (NULL, &err,
365 "/sbin/lvm", "vgremove", "-f", device, NULL);
367 reply_with_error ("%s", err);
377 do_pvremove (const char *device)
382 IS_DEVICE (device, -1);
384 r = command (NULL, &err,
385 "/sbin/lvm", "pvremove", "-ff", device, NULL);
387 reply_with_error ("%s", err);
397 do_pvresize (const char *device)
402 IS_DEVICE (device, -1);
404 r = command (NULL, &err,
405 "/sbin/lvm", "pvresize", device, NULL);
407 reply_with_error ("pvresize: %s: %s", device, err);
417 do_vg_activate (int activate, char * const* const volgroups)
423 argc = count_strings (volgroups) + 4;
424 argv = malloc (sizeof (char *) * (argc+1));
426 reply_with_perror ("malloc");
430 argv[0] = "/sbin/lvm";
431 argv[1] = "vgchange";
433 argv[3] = activate ? "y" : "n";
434 for (i = 4; i <= argc; ++i)
435 argv[i] = volgroups[i-4];
437 r = commandv (NULL, &err, argv);
439 reply_with_error ("vgchange: %s", err);
449 do_vg_activate_all (int activate)
451 char *empty[] = { NULL };
452 return do_vg_activate (activate, empty);