Sync usage with man page.
[netbsd-mini2440.git] / external / gpl2 / lvm2 / dist / test / api / test.c
blob5e1bb58a52b3e293636c2ce7a7c60b3a2b9a014f
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
9 * This copyrighted material is made available to anyone wishing to use,
10 * modify, copy, or redistribute it subject to the terms and conditions
11 * of the GNU Lesser General Public License v.2.1.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <readline/readline.h>
22 #include "lvm2app.h"
24 #define MAX_ARGS 64
26 static int lvm_split(char *str, int *argc, char **argv, int max)
28 char *b = str, *e;
29 *argc = 0;
31 while (*b) {
32 while (*b && isspace(*b))
33 b++;
35 if ((!*b) || ((*argc == 0)&&(*b == '#')))
36 break;
38 e = b;
39 while (*e && !isspace(*e))
40 e++;
42 argv[(*argc)++] = b;
43 if (!*e)
44 break;
45 *e++ = '\0';
46 b = e;
47 if (*argc == max)
48 break;
51 return *argc;
54 static void _show_help(void)
56 printf("'lv_activate vgname lvname: "
57 "Activate an LV\n");
58 printf("'lv_deactivate vgname lvname: "
59 "Deactivate an LV\n");
60 printf("'vg_remove_lv vgname lvname': "
61 "Remove a LV\n");
62 printf("'vg_create_lv_linear vgname lvname size_in_bytes': "
63 "Create a linear LV\n");
64 printf("'scan_vgs': "
65 "Scan the system for LVM metadata\n");
66 printf("'list_vg_names': "
67 "List the names of the VGs that exist in the system\n");
68 printf("'list_vg_ids': "
69 "List the uuids of the VGs that exist in the system\n");
70 printf("'vg_list_pvs vgname': "
71 "List the PVs that exist in VG vgname\n");
72 printf("'vg_list_lvs vgname': "
73 "List the LVs that exist in VG vgname\n");
74 printf("'vgs_open': "
75 "List the VGs that are currently open\n");
76 printf("'vgs': "
77 "List all VGs known to the system\n");
78 printf("'vg_extend vgname device: "
79 "Issue a lvm_vg_extend() API call on VG 'vgname'\n");
80 printf("'vg_reduce vgname device: "
81 "Issue a lvm_vg_reduce() API call on VG 'vgname'\n");
82 printf("'vg_open vgname ['r' | 'w']': "
83 "Issue a lvm_vg_open() API call on VG 'vgname'\n");
84 printf("'vg_close vgname': "
85 "Issue a lvm_vg_close() API call on VG 'vgname'\n");
86 printf("'vg_create vgname: "
87 "Issue a lvm_vg_create() to create VG 'vgname'\n");
88 printf("'vg_remove vgname: "
89 "Issue a lvm_vg_remove() to remove VG 'vgname'\n");
90 printf("'config_reload': "
91 "Issue a lvm_config_reload() API to reload LVM config\n");
92 printf("'config_override' device: "
93 "Issue a lvm_config_override() with accept device filter\n");
94 printf("'quit': exit the program\n");
97 static struct dm_hash_table *_vgid_hash = NULL;
98 static struct dm_hash_table *_vgname_hash = NULL;
99 static struct dm_hash_table *_pvname_hash = NULL;
100 static struct dm_hash_table *_lvname_hash = NULL;
102 static void _hash_destroy_single(struct dm_hash_table **htable)
104 if (htable && *htable) {
105 dm_hash_destroy(*htable);
106 *htable = NULL;
110 static void _hash_destroy(void)
112 _hash_destroy_single(&_vgname_hash);
113 _hash_destroy_single(&_vgid_hash);
114 _hash_destroy_single(&_pvname_hash);
115 _hash_destroy_single(&_lvname_hash);
118 static int _hash_create(void)
120 if (!(_vgname_hash = dm_hash_create(128)))
121 return 0;
122 if (!(_pvname_hash = dm_hash_create(128))) {
123 _hash_destroy_single(&_vgname_hash);
124 return 0;
126 if (!(_lvname_hash = dm_hash_create(128))) {
127 _hash_destroy_single(&_vgname_hash);
128 _hash_destroy_single(&_pvname_hash);
129 return 0;
131 if (!(_vgid_hash = dm_hash_create(128))) {
132 _hash_destroy_single(&_vgname_hash);
133 _hash_destroy_single(&_pvname_hash);
134 _hash_destroy_single(&_lvname_hash);
135 return 0;
137 return 1;
140 /* FIXME: this should be per vg */
141 static lv_t _lookup_lv_by_name(const char *name)
143 lv_t lv;
145 if (!name) {
146 printf ("Invalid LV name\n");
147 return NULL;
149 if (!(lv = dm_hash_lookup(_lvname_hash, name))) {
150 printf ("Can't find %s in LVs - run vg_create_lv first\n",
151 name);
152 return NULL;
154 return lv;
157 static vg_t _lookup_vg_by_name(char **argv, int argc)
159 vg_t vg;
161 if (argc < 2) {
162 printf ("Please enter vg_name\n");
163 return NULL;
165 if (!(vg = dm_hash_lookup(_vgid_hash, argv[1])) &&
166 !(vg = dm_hash_lookup(_vgname_hash, argv[1]))) {
167 printf ("Can't find %s in open VGs - run vg_open first\n",
168 argv[1]);
169 return NULL;
171 return vg;
173 static void _add_lvs_to_lvname_hash(struct dm_list *lvs)
175 struct lvm_lv_list *lvl;
176 dm_list_iterate_items(lvl, lvs) {
177 /* Concatenate VG name with LV name */
178 dm_hash_insert(_lvname_hash, lvm_lv_get_name(lvl->lv), lvl->lv);
182 static void _add_pvs_to_pvname_hash(struct dm_list *pvs)
184 struct lvm_pv_list *pvl;
185 dm_list_iterate_items(pvl, pvs) {
186 dm_hash_insert(_pvname_hash, lvm_pv_get_name(pvl->pv), pvl->pv);
190 static void _remove_device_from_pvname_hash(struct dm_list *pvs, const char *name)
192 struct lvm_pv_list *pvl;
193 dm_list_iterate_items(pvl, pvs) {
194 if (!strncmp(lvm_pv_get_name(pvl->pv), name, strlen(name)))
195 dm_hash_remove(_pvname_hash, name);
198 static void _add_device_to_pvname_hash(struct dm_list *pvs, const char *name)
200 struct lvm_pv_list *pvl;
201 dm_list_iterate_items(pvl, pvs) {
202 if (!strncmp(lvm_pv_get_name(pvl->pv), name, strlen(name)))
203 dm_hash_insert(_pvname_hash, name, pvl->pv);
206 static void _vg_reduce(char **argv, int argc, lvm_t libh)
208 vg_t vg;
209 struct dm_list *pvs;
211 if (argc < 2) {
212 printf ("Please enter vg_name\n");
213 return;
215 if (!(vg = dm_hash_lookup(_vgid_hash, argv[1])) &&
216 !(vg = dm_hash_lookup(_vgname_hash, argv[1]))) {
217 printf ("VG not open\n");
218 return;
220 if (lvm_vg_reduce(vg, argv[2])) {
221 printf("Error reducing %s by %s\n", argv[1], argv[2]);
222 return;
225 printf("Success reducing vg %s by %s\n", argv[1], argv[2]);
228 * Add the device into the hashes for lookups
230 pvs = lvm_vg_list_pvs(vg);
231 if (pvs && !dm_list_empty(pvs))
232 _remove_device_from_pvname_hash(pvs, argv[2]);
235 /* Print "Error" or "Success" depending on lvm status */
236 static int _lvm_status_to_pass_fail(int rc)
238 if (rc)
239 printf("Error ");
240 else
241 printf("Success ");
242 return rc;
244 static void _config_override(char **argv, int argc, lvm_t libh)
246 int rc;
247 char tmp[64];
249 if (argc < 2) {
250 printf ("Please enter device\n");
251 return;
253 snprintf(tmp, 63, "devices{filter=[\"a|%s|\", \"r|.*|\"]}", argv[1]);
254 rc = lvm_config_override(libh, tmp);
255 _lvm_status_to_pass_fail(rc);
256 printf("overriding LVM configuration\n");
259 static void _config_reload(char **argv, int argc, lvm_t libh)
261 int rc;
262 rc = lvm_config_reload(libh);
263 _lvm_status_to_pass_fail(rc);
264 printf("reloading LVM configuration\n");
267 static void _vg_extend(char **argv, int argc, lvm_t libh)
269 vg_t vg;
270 struct dm_list *pvs;
272 if (argc < 2) {
273 printf ("Please enter vg_name\n");
274 return;
276 if (!(vg = dm_hash_lookup(_vgid_hash, argv[1])) &&
277 !(vg = dm_hash_lookup(_vgname_hash, argv[1]))) {
278 printf ("VG not open\n");
279 return;
281 if (lvm_vg_extend(vg, argv[2])) {
282 printf("Error extending %s with %s\n", argv[1], argv[2]);
283 return;
286 printf("Success extending vg %s with %s\n", argv[1], argv[2]);
289 * Add the device into the hashes for lookups
291 pvs = lvm_vg_list_pvs(vg);
292 if (pvs && !dm_list_empty(pvs))
293 _add_device_to_pvname_hash(pvs, argv[2]);
296 static void _vg_open(char **argv, int argc, lvm_t libh)
298 vg_t vg;
299 struct dm_list *lvs;
300 struct dm_list *pvs;
302 if (argc < 2) {
303 printf ("Please enter vg_name\n");
304 return;
306 if ((vg = dm_hash_lookup(_vgid_hash, argv[1])) ||
307 (vg = dm_hash_lookup(_vgname_hash, argv[1]))) {
308 printf ("VG already open\n");
309 return;
311 if (argc < 3)
312 vg = lvm_vg_open(libh, argv[1], "r", 0);
313 else
314 vg = lvm_vg_open(libh, argv[1], argv[2], 0);
315 if (!vg || !lvm_vg_get_name(vg)) {
316 printf("Error opening %s\n", argv[1]);
317 return;
320 printf("Success opening vg %s\n", argv[1]);
321 dm_hash_insert(_vgname_hash, lvm_vg_get_name(vg), vg);
322 dm_hash_insert(_vgid_hash, lvm_vg_get_uuid(vg), vg);
325 * Add the LVs and PVs into the hashes for lookups
327 lvs = lvm_vg_list_lvs(vg);
328 if (lvs && !dm_list_empty(lvs))
329 _add_lvs_to_lvname_hash(lvs);
330 pvs = lvm_vg_list_pvs(vg);
331 if (pvs && !dm_list_empty(pvs))
332 _add_pvs_to_pvname_hash(pvs);
334 /* Lookup the vg and remove it from the vgname and vgid hashes */
335 static vg_t _lookup_and_remove_vg(const char *vgname)
337 vg_t vg=NULL;
339 if ((vg = dm_hash_lookup(_vgname_hash, vgname))) {
340 dm_hash_remove(_vgid_hash, lvm_vg_get_uuid(vg));
341 dm_hash_remove(_vgname_hash, lvm_vg_get_name(vg));
343 if (!vg && (vg = dm_hash_lookup(_vgid_hash, vgname))) {
344 dm_hash_remove(_vgid_hash, lvm_vg_get_uuid(vg));
345 dm_hash_remove(_vgname_hash, lvm_vg_get_name(vg));
347 return vg;
350 static void _vg_write(char **argv, int argc)
352 vg_t vg;
353 int rc = 0;
355 if (argc < 2) {
356 printf ("Please enter vg_name\n");
357 return;
359 vg = _lookup_vg_by_name(argv, argc);
360 if (!vg) {
361 printf("Can't find vg_name %s\n", argv[1]);
362 return;
364 rc = lvm_vg_write(vg);
365 _lvm_status_to_pass_fail(rc);
366 printf("writing VG %s\n", lvm_vg_get_name(vg));
369 static void _vg_create(char **argv, int argc, lvm_t libh)
371 vg_t vg;
373 if (argc < 2) {
374 printf ("Please enter vg_name\n");
375 return;
377 vg = lvm_vg_create(libh, argv[1]);
378 if (!vg || !lvm_vg_get_name(vg)) {
379 printf("Error creating %s\n", argv[1]);
380 return;
383 printf("Success creating vg %s\n", argv[1]);
384 dm_hash_insert(_vgname_hash, lvm_vg_get_name(vg), vg);
385 dm_hash_insert(_vgid_hash, lvm_vg_get_uuid(vg), vg);
388 static void _vg_remove(char **argv, int argc)
390 vg_t vg;
391 int rc = 0;
393 if (argc < 2) {
394 printf ("Please enter vg_name\n");
395 return;
397 vg = _lookup_vg_by_name(argv, argc);
398 if (!vg) {
399 printf("Can't find vg_name %s\n", argv[1]);
400 return;
402 rc = lvm_vg_remove(vg);
403 _lvm_status_to_pass_fail(rc);
404 printf("removing VG\n");
407 static void _vg_close(char **argv, int argc)
409 vg_t vg;
410 int rc = 0;
412 if (argc < 2) {
413 printf ("Please enter vg_name\n");
414 return;
416 vg = _lookup_and_remove_vg(argv[1]);
417 if (!vg) {
418 printf("Can't find vg_name %s\n", argv[1]);
419 return;
421 rc = lvm_vg_close(vg);
422 _lvm_status_to_pass_fail(rc);
423 printf("closing VG\n");
426 static void _show_one_vg(vg_t vg)
428 printf("%s (%s): sz=%"PRIu64", free=%"PRIu64", #pv=%"PRIu64
429 ", seq#=%"PRIu64"\n",
430 lvm_vg_get_name(vg), lvm_vg_get_uuid(vg),
431 lvm_vg_get_size(vg), lvm_vg_get_free_size(vg),
432 lvm_vg_get_pv_count(vg), lvm_vg_get_seqno(vg));
435 static void _list_open_vgs(void)
437 dm_hash_iter(_vgid_hash, (dm_hash_iterate_fn) _show_one_vg);
440 static void _pvs_in_vg(char **argv, int argc)
442 struct dm_list *pvs;
443 struct lvm_pv_list *pvl;
444 vg_t vg;
446 if (!(vg = _lookup_vg_by_name(argv, argc)))
447 return;
448 pvs = lvm_vg_list_pvs(vg);
449 if (!pvs || dm_list_empty(pvs)) {
450 printf("No PVs in VG %s\n", lvm_vg_get_name(vg));
451 return;
453 printf("PVs in VG %s:\n", lvm_vg_get_name(vg));
454 dm_list_iterate_items(pvl, pvs) {
455 printf("%s (%s): mda_count=%"PRIu64"\n",
456 lvm_pv_get_name(pvl->pv), lvm_pv_get_uuid(pvl->pv),
457 lvm_pv_get_mda_count(pvl->pv));
461 static void _scan_vgs(lvm_t libh)
463 lvm_scan(libh);
466 static void _list_vg_names(lvm_t libh)
468 struct dm_list *list;
469 struct lvm_str_list *strl;
470 const char *tmp;
472 list = lvm_list_vg_names(libh);
473 printf("VG names:\n");
474 dm_list_iterate_items(strl, list) {
475 tmp = strl->str;
476 printf("%s\n", tmp);
480 static void _list_vg_ids(lvm_t libh)
482 struct dm_list *list;
483 struct lvm_str_list *strl;
484 const char *tmp;
486 list = lvm_list_vg_uuids(libh);
487 printf("VG uuids:\n");
488 dm_list_iterate_items(strl, list) {
489 tmp = strl->str;
490 printf("%s\n", tmp);
495 static void _lvs_in_vg(char **argv, int argc)
497 struct dm_list *lvs;
498 struct lvm_lv_list *lvl;
499 vg_t vg;
501 if (!(vg = _lookup_vg_by_name(argv, argc)))
502 return;
503 lvs = lvm_vg_list_lvs(vg);
504 if (!lvs || dm_list_empty(lvs)) {
505 printf("No LVs in VG %s\n", lvm_vg_get_name(vg));
506 return;
508 printf("LVs in VG %s:\n", lvm_vg_get_name(vg));
509 dm_list_iterate_items(lvl, lvs) {
510 printf("%s/%s (%s): size=%"PRIu64", %sACTIVE / %sSUSPENDED\n",
511 lvm_vg_get_name(vg),
512 lvm_lv_get_name(lvl->lv), lvm_lv_get_uuid(lvl->lv),
513 lvm_lv_get_size(lvl->lv),
514 lvm_lv_is_active(lvl->lv) ? "" : "IN",
515 lvm_lv_is_suspended(lvl->lv) ? "" : "NOT ");
519 static void _lv_deactivate(char **argv, int argc)
521 lv_t lv;
522 int rc=0;
524 if (argc < 3) {
525 printf("Please enter vgname, lvname\n");
526 return;
528 if (!(lv = _lookup_lv_by_name(argv[2])))
529 return;
530 rc = lvm_lv_deactivate(lv);
531 _lvm_status_to_pass_fail(rc);
532 printf("De-activating LV %s in VG %s\n",
533 argv[2], argv[1]);
535 static void _lv_activate(char **argv, int argc)
537 lv_t lv;
538 int rc=0;
540 if (argc < 3) {
541 printf("Please enter vgname, lvname\n");
542 return;
544 if (!(lv = _lookup_lv_by_name(argv[2])))
545 return;
546 rc = lvm_lv_activate(lv);
547 _lvm_status_to_pass_fail(rc);
548 printf("activating LV %s in VG %s\n",
549 argv[2], argv[1]);
551 static void _vg_remove_lv(char **argv, int argc)
553 lv_t lv;
555 if (argc < 3) {
556 printf("Please enter vgname, lvname\n");
557 return;
559 if (!(lv = _lookup_lv_by_name(argv[2])))
560 return;
561 if (lvm_vg_remove_lv(lv))
562 printf("Error ");
563 else {
564 printf("Success ");
565 dm_hash_remove(_lvname_hash, argv[2]);
567 printf("removing LV %s in VG %s\n",
568 argv[2], argv[1]);
571 static void _vg_create_lv_linear(char **argv, int argc)
573 vg_t vg;
574 lv_t lv;
576 if (argc < 4) {
577 printf("Please enter vgname, lvname, and size\n");
578 return;
580 if (!(vg = _lookup_vg_by_name(argv, argc)))
581 return;
582 lv = lvm_vg_create_lv_linear(vg, argv[2], atol(argv[3]));
583 if (!lv)
584 printf("Error ");
585 else {
586 printf("Success ");
587 dm_hash_insert(_lvname_hash, argv[2], lv);
589 printf("creating LV %s in VG %s\n",
590 argv[2], argv[1]);
593 static int lvmapi_test_shell(lvm_t libh)
595 int argc;
596 char *input = NULL, *args[MAX_ARGS], **argv;
598 _hash_create();
599 argc=0;
600 while (1) {
601 free(input);
602 input = readline("liblvm> ");
604 /* EOF */
605 if (!input) {
606 printf("\n");
607 break;
610 /* empty line */
611 if (!*input)
612 continue;
614 argv = args;
616 if (lvm_split(input, &argc, argv, MAX_ARGS) == MAX_ARGS) {
617 printf("Too many arguments, sorry.");
618 continue;
621 if (!strcmp(argv[0], "lvm")) {
622 argv++;
623 argc--;
626 if (!argc)
627 continue;
629 if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "exit")) {
630 printf("Exiting.\n");
631 break;
632 } else if (!strcmp(argv[0], "?") || !strcmp(argv[0], "help")) {
633 _show_help();
634 } else if (!strcmp(argv[0], "config_reload")) {
635 _config_reload(argv, argc, libh);
636 } else if (!strcmp(argv[0], "config_override")) {
637 _config_override(argv, argc, libh);
638 } else if (!strcmp(argv[0], "vg_extend")) {
639 _vg_extend(argv, argc, libh);
640 } else if (!strcmp(argv[0], "vg_reduce")) {
641 _vg_reduce(argv, argc, libh);
642 } else if (!strcmp(argv[0], "vg_write")) {
643 _vg_write(argv, argc);
644 } else if (!strcmp(argv[0], "vg_open")) {
645 _vg_open(argv, argc, libh);
646 } else if (!strcmp(argv[0], "vg_close")) {
647 _vg_close(argv, argc);
648 } else if (!strcmp(argv[0], "vg_create")) {
649 _vg_create(argv, argc, libh);
650 } else if (!strcmp(argv[0], "vg_remove")) {
651 _vg_remove(argv, argc);
652 } else if (!strcmp(argv[0], "lv_activate")) {
653 _lv_activate(argv, argc);
654 } else if (!strcmp(argv[0], "lv_deactivate")) {
655 _lv_deactivate(argv, argc);
656 } else if (!strcmp(argv[0], "vg_remove_lv")) {
657 _vg_remove_lv(argv, argc);
658 } else if (!strcmp(argv[0], "vgs_open")) {
659 _list_open_vgs();
660 } else if (!strcmp(argv[0], "vg_list_pvs")) {
661 _pvs_in_vg(argv, argc);
662 } else if (!strcmp(argv[0], "vg_list_lvs")) {
663 _lvs_in_vg(argv, argc);
664 } else if (!strcmp(argv[0], "list_vg_names")) {
665 _list_vg_names(libh);
666 } else if (!strcmp(argv[0], "list_vg_ids")) {
667 _list_vg_ids(libh);
668 } else if (!strcmp(argv[0], "scan_vgs")) {
669 _scan_vgs(libh);
670 } else if (!strcmp(argv[0], "vg_create_lv_linear")) {
671 _vg_create_lv_linear(argv, argc);
672 } else {
673 printf ("Unrecognized command %s\n", argv[0]);
677 dm_hash_iter(_vgname_hash, (dm_hash_iterate_fn) lvm_vg_close);
678 _hash_destroy();
679 free(input);
680 return 0;
683 int main (int argc, char *argv[])
685 lvm_t libh;
687 libh = lvm_init(NULL);
688 if (!libh) {
689 printf("Unable to open lvm library instance\n");
690 return 1;
693 printf("Library version: %s\n", lvm_library_get_version());
694 lvmapi_test_shell(libh);
696 lvm_quit(libh);
697 return 0;