eaa6bcea64e4c7acb39d0061724e02955440654d
[libguestfs.git] / daemon / lvm.c
1 /* libguestfs - the guestfsd daemon
2  * Copyright (C) 2009-2011 Red Hat Inc.
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include <config.h>
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <inttypes.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/stat.h>
27 #include <dirent.h>
28
29 #include "daemon.h"
30 #include "c-ctype.h"
31 #include "actions.h"
32 #include "optgroups.h"
33
34 int
35 optgroup_lvm2_available (void)
36 {
37   return prog_exists ("lvm");
38 }
39
40 /* LVM actions.  Keep an eye on liblvm, although at the time
41  * of writing it hasn't progressed very far.
42  */
43
44 static char **
45 convert_lvm_output (char *out, const char *prefix)
46 {
47   char *p, *pend;
48   char **r = NULL;
49   int size = 0, alloc = 0;
50   int len;
51   char buf[256];
52   char *str;
53
54   p = out;
55   while (p) {
56     pend = strchr (p, '\n');    /* Get the next line of output. */
57     if (pend) {
58       *pend = '\0';
59       pend++;
60     }
61
62     while (*p && c_isspace (*p))        /* Skip any leading whitespace. */
63       p++;
64
65     /* Sigh, skip trailing whitespace too.  "pvs", I'm looking at you. */
66     len = strlen (p)-1;
67     while (*p && c_isspace (p[len]))
68       p[len--] = '\0';
69
70     if (!*p) {                  /* Empty line?  Skip it. */
71       p = pend;
72       continue;
73     }
74
75     /* Prefix? */
76     if (prefix) {
77       snprintf (buf, sizeof buf, "%s%s", prefix, p);
78       str = buf;
79     } else
80       str = p;
81
82     if (add_string (&r, &size, &alloc, str) == -1) {
83       free (out);
84       return NULL;
85     }
86
87     p = pend;
88   }
89
90   free (out);
91
92   if (add_string (&r, &size, &alloc, NULL) == -1)
93     return NULL;
94
95   sort_strings (r, size-1);
96   return r;
97 }
98
99 char **
100 do_pvs (void)
101 {
102   char *out, *err;
103   int r;
104
105   r = command (&out, &err,
106                "lvm", "pvs", "-o", "pv_name", "--noheadings", NULL);
107   if (r == -1) {
108     reply_with_error ("%s", err);
109     free (out);
110     free (err);
111     return NULL;
112   }
113
114   free (err);
115
116   return convert_lvm_output (out, NULL);
117 }
118
119 char **
120 do_vgs (void)
121 {
122   char *out, *err;
123   int r;
124
125   r = command (&out, &err,
126                "lvm", "vgs", "-o", "vg_name", "--noheadings", NULL);
127   if (r == -1) {
128     reply_with_error ("%s", err);
129     free (out);
130     free (err);
131     return NULL;
132   }
133
134   free (err);
135
136   return convert_lvm_output (out, NULL);
137 }
138
139 char **
140 do_lvs (void)
141 {
142   char *out, *err;
143   int r;
144
145   r = command (&out, &err,
146                "lvm", "lvs",
147                "-o", "vg_name,lv_name", "--noheadings",
148                "--separator", "/", NULL);
149   if (r == -1) {
150     reply_with_error ("%s", err);
151     free (out);
152     free (err);
153     return NULL;
154   }
155
156   free (err);
157
158   return convert_lvm_output (out, "/dev/");
159 }
160
161 /* These were so complex to implement that I ended up auto-generating
162  * the code.  That code is in stubs.c, and it is generated as usual
163  * by generator.ml.
164  */
165 guestfs_int_lvm_pv_list *
166 do_pvs_full (void)
167 {
168   return parse_command_line_pvs ();
169 }
170
171 guestfs_int_lvm_vg_list *
172 do_vgs_full (void)
173 {
174   return parse_command_line_vgs ();
175 }
176
177 guestfs_int_lvm_lv_list *
178 do_lvs_full (void)
179 {
180   return parse_command_line_lvs ();
181 }
182
183 int
184 do_pvcreate (const char *device)
185 {
186   char *err;
187   int r;
188
189   r = command (NULL, &err,
190                "lvm", "pvcreate", device, NULL);
191   if (r == -1) {
192     reply_with_error ("%s", err);
193     free (err);
194     return -1;
195   }
196
197   free (err);
198
199   udev_settle ();
200
201   return 0;
202 }
203
204 int
205 do_vgcreate (const char *volgroup, char *const *physvols)
206 {
207   char *err;
208   int r, argc, i;
209   const char **argv;
210
211   argc = count_strings (physvols) + 3;
212   argv = malloc (sizeof (char *) * (argc + 1));
213   if (argv == NULL) {
214     reply_with_perror ("malloc");
215     return -1;
216   }
217   argv[0] = "lvm";
218   argv[1] = "vgcreate";
219   argv[2] = volgroup;
220   for (i = 3; i <= argc; ++i)
221     argv[i] = physvols[i-3];
222
223   r = commandv (NULL, &err, (const char * const*) argv);
224   if (r == -1) {
225     reply_with_error ("%s", err);
226     free (err);
227     free (argv);
228     return -1;
229   }
230
231   free (err);
232   free (argv);
233
234   udev_settle ();
235
236   return 0;
237 }
238
239 int
240 do_lvcreate (const char *logvol, const char *volgroup, int mbytes)
241 {
242   char *err;
243   int r;
244   char size[64];
245
246   snprintf (size, sizeof size, "%d", mbytes);
247
248   r = command (NULL, &err,
249                "lvm", "lvcreate",
250                "-L", size, "-n", logvol, volgroup, NULL);
251   if (r == -1) {
252     reply_with_error ("%s", err);
253     free (err);
254     return -1;
255   }
256
257   free (err);
258
259   udev_settle ();
260
261   return 0;
262 }
263
264 int
265 do_lvresize (const char *logvol, int mbytes)
266 {
267   char *err;
268   int r;
269   char size[64];
270
271   snprintf (size, sizeof size, "%d", mbytes);
272
273   r = command (NULL, &err,
274                "lvm", "lvresize",
275                "--force", "-L", size, logvol, NULL);
276   if (r == -1) {
277     reply_with_error ("%s", err);
278     free (err);
279     return -1;
280   }
281
282   free (err);
283   return 0;
284 }
285
286 int
287 do_lvresize_free (const char *logvol, int percent)
288 {
289   char *err;
290   int r;
291
292   if (percent < 0 || percent > 100) {
293     reply_with_error ("percentage must be [0..100] (was %d)", percent);
294     return -1;
295   }
296
297   char size[64];
298   snprintf (size, sizeof size, "+%d%%FREE", percent);
299
300   r = command (NULL, &err,
301                "lvm", "lvresize", "-l", size, logvol, NULL);
302   if (r == -1) {
303     reply_with_error ("%s", err);
304     free (err);
305     return -1;
306   }
307
308   free (err);
309   return 0;
310 }
311
312 /* Super-dangerous command used for testing.  It removes all
313  * LVs, VGs and PVs permanently.
314  */
315 int
316 do_lvm_remove_all (void)
317 {
318   char **xs;
319   int i, r;
320   char *err;
321
322   /* Remove LVs. */
323   xs = do_lvs ();
324   if (xs == NULL)
325     return -1;
326
327   for (i = 0; xs[i] != NULL; ++i) {
328     /* Deactivate the LV first.  On Ubuntu, lvremove '-f' option
329      * does not remove active LVs reliably.
330      */
331     (void) command (NULL, NULL, "lvm", "lvchange", "-an", xs[i], NULL);
332     udev_settle ();
333
334     r = command (NULL, &err, "lvm", "lvremove", "-f", xs[i], NULL);
335     if (r == -1) {
336       reply_with_error ("lvremove: %s: %s", xs[i], err);
337       free (err);
338       free_strings (xs);
339       return -1;
340     }
341     free (err);
342   }
343   free_strings (xs);
344
345   /* Remove VGs. */
346   xs = do_vgs ();
347   if (xs == NULL)
348     return -1;
349
350   for (i = 0; xs[i] != NULL; ++i) {
351     /* Deactivate the VG first, see note above. */
352     (void) command (NULL, NULL, "lvm", "vgchange", "-an", xs[i], NULL);
353     udev_settle ();
354
355     r = command (NULL, &err, "lvm", "vgremove", "-f", xs[i], NULL);
356     if (r == -1) {
357       reply_with_error ("vgremove: %s: %s", xs[i], err);
358       free (err);
359       free_strings (xs);
360       return -1;
361     }
362     free (err);
363   }
364   free_strings (xs);
365
366   /* Remove PVs. */
367   xs = do_pvs ();
368   if (xs == NULL)
369     return -1;
370
371   for (i = 0; xs[i] != NULL; ++i) {
372     r = command (NULL, &err, "lvm", "pvremove", "-f", xs[i], NULL);
373     if (r == -1) {
374       reply_with_error ("pvremove: %s: %s", xs[i], err);
375       free (err);
376       free_strings (xs);
377       return -1;
378     }
379     free (err);
380   }
381   free_strings (xs);
382
383   udev_settle ();
384
385   /* There, that was easy, sorry about your data. */
386   return 0;
387 }
388
389 int
390 do_lvremove (const char *device)
391 {
392   char *err;
393   int r;
394
395   r = command (NULL, &err,
396                "lvm", "lvremove", "-f", device, NULL);
397   if (r == -1) {
398     reply_with_error ("%s", err);
399     free (err);
400     return -1;
401   }
402
403   free (err);
404
405   udev_settle ();
406
407   return 0;
408 }
409
410 int
411 do_vgremove (const char *device)
412 {
413   char *err;
414   int r;
415
416   r = command (NULL, &err,
417                "lvm", "vgremove", "-f", device, NULL);
418   if (r == -1) {
419     reply_with_error ("%s", err);
420     free (err);
421     return -1;
422   }
423
424   free (err);
425
426   udev_settle ();
427
428   return 0;
429 }
430
431 int
432 do_pvremove (const char *device)
433 {
434   char *err;
435   int r;
436
437   r = command (NULL, &err,
438                "lvm", "pvremove", "-ff", device, NULL);
439   if (r == -1) {
440     reply_with_error ("%s", err);
441     free (err);
442     return -1;
443   }
444
445   free (err);
446
447   udev_settle ();
448
449   return 0;
450 }
451
452 int
453 do_pvresize (const char *device)
454 {
455   char *err;
456   int r;
457
458   r = command (NULL, &err,
459                "lvm", "pvresize", device, NULL);
460   if (r == -1) {
461     reply_with_error ("%s: %s", device, err);
462     free (err);
463     return -1;
464   }
465
466   free (err);
467   return 0;
468 }
469
470 int
471 do_pvresize_size (const char *device, int64_t size)
472 {
473   char *err;
474   int r;
475
476   char buf[32];
477   snprintf (buf, sizeof buf, "%" PRIi64 "b", size);
478
479   r = command (NULL, &err,
480                "lvm", "pvresize",
481                "--setphysicalvolumesize", buf,
482                device, NULL);
483   if (r == -1) {
484     reply_with_error ("%s: %s", device, err);
485     free (err);
486     return -1;
487   }
488
489   free (err);
490   return 0;
491 }
492
493 int
494 do_vg_activate (int activate, char *const *volgroups)
495 {
496   char *err;
497   int r, i, argc;
498   const char **argv;
499
500   argc = count_strings (volgroups) + 4;
501   argv = malloc (sizeof (char *) * (argc+1));
502   if (argv == NULL) {
503     reply_with_perror ("malloc");
504     return -1;
505   }
506
507   argv[0] = "lvm";
508   argv[1] = "vgchange";
509   argv[2] = "-a";
510   argv[3] = activate ? "y" : "n";
511   for (i = 4; i <= argc; ++i)
512     argv[i] = volgroups[i-4];
513
514   r = commandv (NULL, &err, (const char * const*) argv);
515   if (r == -1) {
516     reply_with_error ("vgchange: %s", err);
517     free (err);
518     free (argv);
519     return -1;
520   }
521
522   free (err);
523   free (argv);
524
525   udev_settle ();
526
527   return 0;
528 }
529
530 int
531 do_vg_activate_all (int activate)
532 {
533   char *empty[] = { NULL };
534   return do_vg_activate (activate, empty);
535 }
536
537 int
538 do_lvrename (const char *logvol, const char *newlogvol)
539 {
540   char *err;
541   int r;
542
543   r = command (NULL, &err,
544                "lvm", "lvrename",
545                logvol, newlogvol, NULL);
546   if (r == -1) {
547     reply_with_error ("%s -> %s: %s", logvol, newlogvol, err);
548     free (err);
549     return -1;
550   }
551
552   free (err);
553
554   udev_settle ();
555
556   return 0;
557 }
558
559 int
560 do_vgrename (const char *volgroup, const char *newvolgroup)
561 {
562   char *err;
563   int r;
564
565   r = command (NULL, &err,
566                "lvm", "vgrename",
567                volgroup, newvolgroup, NULL);
568   if (r == -1) {
569     reply_with_error ("%s -> %s: %s", volgroup, newvolgroup, err);
570     free (err);
571     return -1;
572   }
573
574   free (err);
575
576   udev_settle ();
577
578   return 0;
579 }
580
581 static char *
582 get_lvm_field (const char *cmd, const char *field, const char *device)
583 {
584   char *out;
585   char *err;
586   int r = command (&out, &err,
587                    "lvm", cmd,
588                    "--unbuffered", "--noheadings", "-o", field,
589                    device, NULL);
590   if (r == -1) {
591     reply_with_error ("%s: %s", device, err);
592     free (out);
593     free (err);
594     return NULL;
595   }
596
597   free (err);
598
599   trim (out);
600   return out;                   /* Caller frees. */
601 }
602
603 char *
604 do_pvuuid (const char *device)
605 {
606   return get_lvm_field ("pvs", "pv_uuid", device);
607 }
608
609 char *
610 do_vguuid (const char *vgname)
611 {
612   return get_lvm_field ("vgs", "vg_uuid", vgname);
613 }
614
615 char *
616 do_lvuuid (const char *device)
617 {
618   return get_lvm_field ("lvs", "lv_uuid", device);
619 }
620
621 static char **
622 get_lvm_fields (const char *cmd, const char *field, const char *device)
623 {
624   char *out;
625   char *err;
626   int r = command (&out, &err,
627                    "lvm", cmd,
628                    "--unbuffered", "--noheadings", "-o", field,
629                    device, NULL);
630   if (r == -1) {
631     reply_with_error ("%s: %s", device, err);
632     free (out);
633     free (err);
634     return NULL;
635   }
636
637   free (err);
638
639   char **ret = split_lines (out);
640   free (out);
641
642   if (ret == NULL)
643     return NULL;
644
645   size_t i;
646   for (i = 0; ret[i] != NULL; ++i)
647     trim (ret[i]);
648
649   return ret;
650 }
651
652 char **
653 do_vgpvuuids (const char *vgname)
654 {
655   return get_lvm_fields ("vgs", "pv_uuid", vgname);
656 }
657
658 char **
659 do_vglvuuids (const char *vgname)
660 {
661   return get_lvm_fields ("vgs", "lv_uuid", vgname);
662 }
663
664 int
665 do_vgscan (void)
666 {
667   char *err;
668   int r;
669
670   r = command (NULL, &err,
671                "lvm", "vgscan", NULL);
672   if (r == -1) {
673     reply_with_error ("%s", err);
674     free (err);
675     return -1;
676   }
677
678   free (err);
679   return 0;
680 }
681
682 /* Convert a non-canonical LV path like /dev/mapper/vg-lv or /dev/dm-0
683  * to a canonical one.
684  *
685  * This is harder than it should be.  A LV device like /dev/VG/LV is
686  * really a symlink to a device-mapper device like /dev/dm-0.  However
687  * at the device-mapper (kernel) level, nothing is really known about
688  * LVM (a userspace concept).  Therefore we use a convoluted method to
689  * determine this, by listing out known LVs and checking whether the
690  * rdev (major/minor) of the device we are passed matches any of them.
691  *
692  * Note use of 'stat' instead of 'lstat' so that symlinks are fully
693  * resolved.
694  *
695  * Returns:
696  *   1  =  conversion was successful, path is an LV
697  *         '*ret' is set to the updated path if 'ret' is non-NULL.
698  *   0  =  path is not an LV
699  *  -1  =  error, reply_with_* has been called
700  *
701  */
702 int
703 lv_canonical (const char *device, char **ret)
704 {
705   struct stat stat1, stat2;
706
707   int r = stat (device, &stat1);
708   if (r == -1) {
709     reply_with_perror ("stat: %s", device);
710     return -1;
711   }
712
713   char **lvs = do_lvs ();
714   if (lvs == NULL)
715     return -1;
716
717   size_t i;
718   for (i = 0; lvs[i] != NULL; ++i) {
719     r = stat (lvs[i], &stat2);
720     if (r == -1) {
721       reply_with_perror ("stat: %s", lvs[i]);
722       free_strings (lvs);
723       return -1;
724     }
725     if (stat1.st_rdev == stat2.st_rdev) { /* found it */
726       if (ret) {
727         *ret = strdup (lvs[i]);
728         if (*ret == NULL) {
729           reply_with_perror ("strdup");
730           free_strings (lvs);
731           return -1;
732         }
733       }
734       free_strings (lvs);
735       return 1;
736     }
737   }
738
739   /* not found */
740   free_strings (lvs);
741   return 0;
742 }
743
744 /* Test if a device is a logical volume (RHBZ#619793). */
745 int
746 do_is_lv (const char *device)
747 {
748   return lv_canonical (device, NULL);
749 }
750
751 /* Return canonical name of LV to caller (RHBZ#638899). */
752 char *
753 do_lvm_canonical_lv_name (const char *device)
754 {
755   char *canonical;
756   int r = lv_canonical (device, &canonical);
757   if (r == -1)
758     return NULL;
759
760   if (r == 0) {
761     reply_with_error ("%s: not a logical volume", device);
762     return NULL;
763   }
764
765   return canonical;             /* caller frees */
766 }
767
768 /* List everything in /dev/mapper which *isn't* an LV (RHBZ#688062). */
769 char **
770 do_list_dm_devices (void)
771 {
772   char **ret = NULL;
773   int size = 0, alloc = 0;
774   struct dirent *d;
775   DIR *dir;
776   int r;
777
778   dir = opendir ("/dev/mapper");
779   if (!dir) {
780     reply_with_perror ("opendir: /dev/mapper");
781     return NULL;
782   }
783
784   while (1) {
785     errno = 0;
786     d = readdir (dir);
787     if (d == NULL) break;
788
789     /* Ignore . and .. */
790     if (STREQ (d->d_name, ".") || STREQ (d->d_name, ".."))
791       continue;
792
793     /* Ignore /dev/mapper/control which is used internally by dm. */
794     if (STREQ (d->d_name, "control"))
795       continue;
796
797     size_t len = strlen (d->d_name);
798     char devname[len+64];
799
800     snprintf (devname, len+64, "/dev/mapper/%s", d->d_name);
801
802     /* Ignore dm devices which are LVs. */
803     r = lv_canonical (devname, NULL);
804     if (r == -1) {
805       free_stringslen (ret, size);
806       closedir (dir);
807       return NULL;
808     }
809     if (r)
810       continue;
811
812     /* Not an LV, so add it. */
813     if (add_string (&ret, &size, &alloc, devname) == -1) {
814       closedir (dir);
815       return NULL;
816     }
817   }
818
819   /* Did readdir fail? */
820   if (errno != 0) {
821     reply_with_perror ("readdir: /dev/mapper");
822     free_stringslen (ret, size);
823     closedir (dir);
824     return NULL;
825   }
826
827   /* Close the directory handle. */
828   if (closedir (dir) == -1) {
829     reply_with_perror ("closedir: /dev/mapper");
830     free_stringslen (ret, size);
831     return NULL;
832   }
833
834   /* Sort the output (may be empty). */
835   if (ret != NULL)
836     sort_strings (ret, size);
837
838   /* NULL-terminate the list. */
839   if (add_string (&ret, &size, &alloc, NULL) == -1)
840     return NULL;
841
842   return ret;
843 }