Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / contrib / lvm2 / dist / tools / toollib.c
1 /*      $NetBSD: toollib.c,v 1.1.1.3 2009/12/02 00:25:56 haad Exp $     */
2
3 /*
4  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5  * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
6  *
7  * This file is part of LVM2.
8  *
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.
12  *
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
16  */
17
18 #include "tools.h"
19 #include "lv_alloc.h"
20 #include "xlate.h"
21
22 #include <sys/stat.h>
23 #include <sys/wait.h>
24
25 const char *command_name(struct cmd_context *cmd)
26 {
27         return cmd->command->name;
28 }
29
30 /*
31  * Strip dev_dir if present
32  */
33 char *skip_dev_dir(struct cmd_context *cmd, const char *vg_name,
34                    unsigned *dev_dir_found)
35 {
36         const char *dmdir = dm_dir();
37         size_t dmdir_len = strlen(dmdir), vglv_sz;
38         char *vgname, *lvname, *layer, *vglv;
39
40         /* FIXME Do this properly */
41         if (*vg_name == '/') {
42                 while (*vg_name == '/')
43                         vg_name++;
44                 vg_name--;
45         }
46
47         /* Reformat string if /dev/mapper found */
48         if (!strncmp(vg_name, dmdir, dmdir_len) && vg_name[dmdir_len] == '/') {
49                 if (dev_dir_found)
50                         *dev_dir_found = 1;
51                 vg_name += dmdir_len;
52                 while (*vg_name == '/')
53                         vg_name++;
54
55                 if (!dm_split_lvm_name(cmd->mem, vg_name, &vgname, &lvname, &layer) ||
56                     *layer) {
57                         log_error("skip_dev_dir: Couldn't split up device name %s",
58                                   vg_name);
59                         return (char *) vg_name;
60                 }
61                 vglv_sz = strlen(vgname) + strlen(lvname) + 2;
62                 if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
63                     dm_snprintf(vglv, vglv_sz, "%s%s%s", vgname,
64                                  *lvname ? "/" : "",
65                                  lvname) < 0) {
66                         log_error("vg/lv string alloc failed");
67                         return (char *) vg_name;
68                 }
69                 return vglv;
70         }
71
72         if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir))) {
73                 if (dev_dir_found)
74                         *dev_dir_found = 1;
75                 vg_name += strlen(cmd->dev_dir);
76                 while (*vg_name == '/')
77                         vg_name++;
78         } else if (dev_dir_found)
79                 *dev_dir_found = 0;
80
81         return (char *) vg_name;
82 }
83
84 /*
85  * Metadata iteration functions
86  */
87 int process_each_lv_in_vg(struct cmd_context *cmd,
88                           const struct volume_group *vg,
89                           const struct dm_list *arg_lvnames,
90                           const struct dm_list *tags,
91                           void *handle,
92                           process_single_lv_fn_t process_single)
93 {
94         int ret_max = ECMD_PROCESSED;
95         int ret = 0;
96         unsigned process_all = 0;
97         unsigned process_lv = 0;
98         unsigned tags_supplied = 0;
99         unsigned lvargs_supplied = 0;
100         unsigned lvargs_matched = 0;
101
102         struct lv_list *lvl;
103
104         if (!vg_check_status(vg, EXPORTED_VG))
105                 return ECMD_FAILED;
106
107         if (tags && !dm_list_empty(tags))
108                 tags_supplied = 1;
109
110         if (arg_lvnames && !dm_list_empty(arg_lvnames))
111                 lvargs_supplied = 1;
112
113         /* Process all LVs in this VG if no restrictions given */
114         if (!tags_supplied && !lvargs_supplied)
115                 process_all = 1;
116
117         /* Or if VG tags match */
118         if (!process_lv && tags_supplied &&
119             str_list_match_list(tags, &vg->tags)) {
120                 process_all = 1;
121         }
122
123         dm_list_iterate_items(lvl, &vg->lvs) {
124                 if (lvl->lv->status & SNAPSHOT)
125                         continue;
126
127                 if (lv_is_virtual_origin(lvl->lv) && !arg_count(cmd, all_ARG))
128                         continue;
129
130                 /* Should we process this LV? */
131                 if (process_all)
132                         process_lv = 1;
133                 else
134                         process_lv = 0;
135
136                 /* LV tag match? */
137                 if (!process_lv && tags_supplied &&
138                     str_list_match_list(tags, &lvl->lv->tags)) {
139                         process_lv = 1;
140                 }
141
142                 /* LV name match? */
143                 if (lvargs_supplied &&
144                     str_list_match_item(arg_lvnames, lvl->lv->name)) {
145                         process_lv = 1;
146                         lvargs_matched++;
147                 }
148
149                 if (!process_lv)
150                         continue;
151
152                 ret = process_single(cmd, lvl->lv, handle);
153                 if (ret > ret_max)
154                         ret_max = ret;
155                 if (sigint_caught())
156                         return ret_max;
157         }
158
159         if (lvargs_supplied && lvargs_matched != dm_list_size(arg_lvnames)) {
160                 log_error("One or more specified logical volume(s) not found.");
161                 if (ret_max < ECMD_FAILED)
162                         ret_max = ECMD_FAILED;
163         }
164
165         return ret_max;
166 }
167
168 int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
169                     uint32_t flags, void *handle,
170                     int (*process_single) (struct cmd_context * cmd,
171                                            struct logical_volume * lv,
172                                            void *handle))
173 {
174         int opt = 0;
175         int ret_max = ECMD_PROCESSED;
176         int ret = 0;
177
178         struct dm_list *tags_arg;
179         struct dm_list *vgnames;        /* VGs to process */
180         struct str_list *sll, *strl;
181         struct volume_group *vg;
182         struct dm_list tags, lvnames;
183         struct dm_list arg_lvnames;     /* Cmdline vgname or vgname/lvname */
184         char *vglv;
185         size_t vglv_sz;
186
187         const char *vgname;
188
189         dm_list_init(&tags);
190         dm_list_init(&arg_lvnames);
191
192         if (argc) {
193                 struct dm_list arg_vgnames;
194
195                 log_verbose("Using logical volume(s) on command line");
196                 dm_list_init(&arg_vgnames);
197
198                 for (; opt < argc; opt++) {
199                         const char *lv_name = argv[opt];
200                         char *vgname_def;
201                         unsigned dev_dir_found = 0;
202
203                         /* Do we have a tag or vgname or lvname? */
204                         vgname = lv_name;
205
206                         if (*vgname == '@') {
207                                 if (!validate_name(vgname + 1)) {
208                                         log_error("Skipping invalid tag %s",
209                                                   vgname);
210                                         continue;
211                                 }
212                                 if (!str_list_add(cmd->mem, &tags,
213                                                   dm_pool_strdup(cmd->mem,
214                                                               vgname + 1))) {
215                                         log_error("strlist allocation failed");
216                                         return ECMD_FAILED;
217                                 }
218                                 continue;
219                         }
220
221                         /* FIXME Jumbled parsing */
222                         vgname = skip_dev_dir(cmd, vgname, &dev_dir_found);
223
224                         if (*vgname == '/') {
225                                 log_error("\"%s\": Invalid path for Logical "
226                                           "Volume", argv[opt]);
227                                 if (ret_max < ECMD_FAILED)
228                                         ret_max = ECMD_FAILED;
229                                 continue;
230                         }
231                         lv_name = vgname;
232                         if (strchr(vgname, '/')) {
233                                 /* Must be an LV */
234                                 lv_name = strchr(vgname, '/');
235                                 while (*lv_name == '/')
236                                         lv_name++;
237                                 if (!(vgname = extract_vgname(cmd, vgname))) {
238                                         if (ret_max < ECMD_FAILED)
239                                                 ret_max = ECMD_FAILED;
240                                         continue;
241                                 }
242                         } else if (!dev_dir_found &&
243                                    (vgname_def = default_vgname(cmd))) {
244                                 vgname = vgname_def;
245                         } else
246                                 lv_name = NULL;
247
248                         if (!str_list_add(cmd->mem, &arg_vgnames,
249                                           dm_pool_strdup(cmd->mem, vgname))) {
250                                 log_error("strlist allocation failed");
251                                 return ECMD_FAILED;
252                         }
253
254                         if (!lv_name) {
255                                 if (!str_list_add(cmd->mem, &arg_lvnames,
256                                                   dm_pool_strdup(cmd->mem,
257                                                               vgname))) {
258                                         log_error("strlist allocation failed");
259                                         return ECMD_FAILED;
260                                 }
261                         } else {
262                                 vglv_sz = strlen(vgname) + strlen(lv_name) + 2;
263                                 if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
264                                     dm_snprintf(vglv, vglv_sz, "%s/%s", vgname,
265                                                  lv_name) < 0) {
266                                         log_error("vg/lv string alloc failed");
267                                         return ECMD_FAILED;
268                                 }
269                                 if (!str_list_add(cmd->mem, &arg_lvnames, vglv)) {
270                                         log_error("strlist allocation failed");
271                                         return ECMD_FAILED;
272                                 }
273                         }
274                 }
275                 vgnames = &arg_vgnames;
276         }
277
278         if (!argc || !dm_list_empty(&tags)) {
279                 log_verbose("Finding all logical volumes");
280                 if (!(vgnames = get_vgnames(cmd, 0)) || dm_list_empty(vgnames)) {
281                         log_error("No volume groups found");
282                         return ret_max;
283                 }
284         }
285
286         vg = NULL;
287         dm_list_iterate_items(strl, vgnames) {
288                 vgname = strl->str;
289                 if (is_orphan_vg(vgname))
290                         continue;       /* FIXME Unnecessary? */
291                 vg = vg_read(cmd, vgname, NULL, flags);
292
293                 if (vg_read_error(vg)) {
294                         vg_release(vg);
295                         if (ret_max < ECMD_FAILED) {
296                                 log_error("Skipping volume group %s", vgname);
297                                 ret_max = ECMD_FAILED;
298                         } else
299                                 stack;
300                         continue;
301                 }
302
303                 tags_arg = &tags;
304                 dm_list_init(&lvnames); /* LVs to be processed in this VG */
305                 dm_list_iterate_items(sll, &arg_lvnames) {
306                         const char *vg_name = sll->str;
307                         const char *lv_name = strchr(vg_name, '/');
308
309                         if ((!lv_name && !strcmp(vg_name, vgname))) {
310                                 /* Process all LVs in this VG */
311                                 tags_arg = NULL;
312                                 dm_list_init(&lvnames);
313                                 break;
314                         } else if (!strncmp(vg_name, vgname, strlen(vgname)) &&
315                                    strlen(vgname) == (size_t) (lv_name - vg_name)) {
316                                 if (!str_list_add(cmd->mem, &lvnames,
317                                                   dm_pool_strdup(cmd->mem,
318                                                               lv_name + 1))) {
319                                         log_error("strlist allocation failed");
320                                         vg_release(vg);
321                                         return ECMD_FAILED;
322                                 }
323                         }
324                 }
325
326                 ret = process_each_lv_in_vg(cmd, vg, &lvnames, tags_arg,
327                                             handle, process_single);
328                 unlock_and_release_vg(cmd, vg, vgname);
329                 if (ret > ret_max)
330                         ret_max = ret;
331                 if (sigint_caught())
332                         break;
333         }
334
335         return ret_max;
336 }
337
338 int process_each_segment_in_pv(struct cmd_context *cmd,
339                                struct volume_group *vg,
340                                struct physical_volume *pv,
341                                void *handle,
342                                int (*process_single) (struct cmd_context * cmd,
343                                                       struct volume_group * vg,
344                                                       struct pv_segment * pvseg,
345                                                       void *handle))
346 {
347         struct pv_segment *pvseg;
348         struct pv_list *pvl;
349         const char *vg_name = NULL;
350         int ret_max = ECMD_PROCESSED;
351         int ret;
352         struct volume_group *old_vg = vg;
353         struct pv_segment _free_pv_segment = { .pv = pv };
354
355         if (is_pv(pv) && !vg && !is_orphan(pv)) {
356                 vg_name = pv_vg_name(pv);
357
358                 vg = vg_read(cmd, vg_name, NULL, 0);
359                 if (vg_read_error(vg)) {
360                         vg_release(vg);
361                         log_error("Skipping volume group %s", vg_name);
362                         return ECMD_FAILED;
363                 }
364
365                 /*
366                  * Replace possibly incomplete PV structure with new one
367                  * allocated in vg_read_internal() path.
368                  */
369                 if (!(pvl = find_pv_in_vg(vg, pv_dev_name(pv)))) {
370                          log_error("Unable to find %s in volume group %s",
371                                    pv_dev_name(pv), vg_name);
372                         vg_release(vg);
373                         return ECMD_FAILED;
374                 }
375
376                 pv = pvl->pv;
377         }
378
379         if (dm_list_empty(&pv->segments)) {
380                 ret = process_single(cmd, NULL, &_free_pv_segment, handle);
381                 if (ret > ret_max)
382                         ret_max = ret;
383         } else
384                 dm_list_iterate_items(pvseg, &pv->segments) {
385                         ret = process_single(cmd, vg, pvseg, handle);
386                         if (ret > ret_max)
387                                 ret_max = ret;
388                         if (sigint_caught())
389                                 break;
390                 }
391
392         if (vg_name)
393                 unlock_vg(cmd, vg_name);
394         if (!old_vg)
395                 vg_release(vg);
396
397         return ret_max;
398 }
399
400 int process_each_segment_in_lv(struct cmd_context *cmd,
401                                struct logical_volume *lv,
402                                void *handle,
403                                int (*process_single) (struct cmd_context * cmd,
404                                                       struct lv_segment * seg,
405                                                       void *handle))
406 {
407         struct lv_segment *seg;
408         int ret_max = ECMD_PROCESSED;
409         int ret;
410
411         dm_list_iterate_items(seg, &lv->segments) {
412                 ret = process_single(cmd, seg, handle);
413                 if (ret > ret_max)
414                         ret_max = ret;
415                 if (sigint_caught())
416                         break;
417         }
418
419         return ret_max;
420 }
421
422 static int _process_one_vg(struct cmd_context *cmd, const char *vg_name,
423                            const char *vgid,
424                            struct dm_list *tags, struct dm_list *arg_vgnames,
425                            uint32_t flags, void *handle, int ret_max,
426                            int (*process_single) (struct cmd_context * cmd,
427                                                   const char *vg_name,
428                                                   struct volume_group * vg,
429                                                   void *handle))
430 {
431         struct volume_group *vg;
432         int ret = 0;
433
434         log_verbose("Finding volume group \"%s\"", vg_name);
435
436         vg = vg_read(cmd, vg_name, vgid, flags);
437         /* Allow FAILED_INCONSISTENT through only for vgcfgrestore */
438         if (vg_read_error(vg) &&
439             !((vg_read_error(vg) == FAILED_INCONSISTENT) &&
440               (flags & READ_ALLOW_INCONSISTENT))) {
441                 ret_max = ECMD_FAILED;
442                 goto_out;
443         }
444
445         if (!dm_list_empty(tags)) {
446                 /* Only process if a tag matches or it's on arg_vgnames */
447                 if (!str_list_match_item(arg_vgnames, vg_name) &&
448                     !str_list_match_list(tags, &vg->tags))
449                         goto out;
450         }
451
452         if ((ret = process_single(cmd, vg_name, vg,
453                                   handle)) > ret_max)
454                 ret_max = ret;
455
456 out:
457         if (vg_read_error(vg))
458                 vg_release(vg);
459         else
460                 unlock_and_release_vg(cmd, vg, vg_name);
461         return ret_max;
462 }
463
464 int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
465                     uint32_t flags, void *handle,
466                     int (*process_single) (struct cmd_context * cmd,
467                                            const char *vg_name,
468                                            struct volume_group * vg,
469                                            void *handle))
470 {
471         int opt = 0;
472         int ret_max = ECMD_PROCESSED;
473
474         struct str_list *sl;
475         struct dm_list *vgnames, *vgids;
476         struct dm_list arg_vgnames, tags;
477
478         const char *vg_name, *vgid;
479
480         dm_list_init(&tags);
481         dm_list_init(&arg_vgnames);
482
483         if (argc) {
484                 log_verbose("Using volume group(s) on command line");
485
486                 for (; opt < argc; opt++) {
487                         vg_name = argv[opt];
488                         if (*vg_name == '@') {
489                                 if (!validate_name(vg_name + 1)) {
490                                         log_error("Skipping invalid tag %s",
491                                                   vg_name);
492                                         if (ret_max < EINVALID_CMD_LINE)
493                                                 ret_max = EINVALID_CMD_LINE;
494                                         continue;
495                                 }
496                                 if (!str_list_add(cmd->mem, &tags,
497                                                   dm_pool_strdup(cmd->mem,
498                                                               vg_name + 1))) {
499                                         log_error("strlist allocation failed");
500                                         return ECMD_FAILED;
501                                 }
502                                 continue;
503                         }
504
505                         vg_name = skip_dev_dir(cmd, vg_name, NULL);
506                         if (strchr(vg_name, '/')) {
507                                 log_error("Invalid volume group name: %s",
508                                           vg_name);
509                                 if (ret_max < EINVALID_CMD_LINE)
510                                         ret_max = EINVALID_CMD_LINE;
511                                 continue;
512                         }
513                         if (!str_list_add(cmd->mem, &arg_vgnames,
514                                           dm_pool_strdup(cmd->mem, vg_name))) {
515                                 log_error("strlist allocation failed");
516                                 return ECMD_FAILED;
517                         }
518                 }
519
520                 vgnames = &arg_vgnames;
521         }
522
523         if (!argc || !dm_list_empty(&tags)) {
524                 log_verbose("Finding all volume groups");
525                 if (!(vgids = get_vgids(cmd, 0)) || dm_list_empty(vgids)) {
526                         log_error("No volume groups found");
527                         return ret_max;
528                 }
529                 dm_list_iterate_items(sl, vgids) {
530                         vgid = sl->str;
531                         if (!vgid || !(vg_name = vgname_from_vgid(cmd->mem, vgid)) ||
532                             is_orphan_vg(vg_name))
533                                 continue;
534                         ret_max = _process_one_vg(cmd, vg_name, vgid, &tags,
535                                                   &arg_vgnames,
536                                                   flags, handle,
537                                                   ret_max, process_single);
538                         if (sigint_caught())
539                                 return ret_max;
540                 }
541         } else {
542                 dm_list_iterate_items(sl, vgnames) {
543                         vg_name = sl->str;
544                         if (is_orphan_vg(vg_name))
545                                 continue;       /* FIXME Unnecessary? */
546                         ret_max = _process_one_vg(cmd, vg_name, NULL, &tags,
547                                                   &arg_vgnames,
548                                                   flags, handle,
549                                                   ret_max, process_single);
550                         if (sigint_caught())
551                                 return ret_max;
552                 }
553         }
554
555         return ret_max;
556 }
557
558 int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
559                           const struct dm_list *tags, void *handle,
560                           process_single_pv_fn_t process_single)
561 {
562         int ret_max = ECMD_PROCESSED;
563         int ret = 0;
564         struct pv_list *pvl;
565
566         dm_list_iterate_items(pvl, &vg->pvs) {
567                 if (tags && !dm_list_empty(tags) &&
568                     !str_list_match_list(tags, &pvl->pv->tags)) {
569                         continue;
570                 }
571                 if ((ret = process_single(cmd, vg, pvl->pv, handle)) > ret_max)
572                         ret_max = ret;
573                 if (sigint_caught())
574                         return ret_max;
575         }
576
577         return ret_max;
578 }
579
580 static int _process_all_devs(struct cmd_context *cmd, void *handle,
581                     int (*process_single) (struct cmd_context * cmd,
582                                            struct volume_group * vg,
583                                            struct physical_volume * pv,
584                                            void *handle))
585 {
586         struct physical_volume *pv;
587         struct physical_volume pv_dummy;
588         struct dev_iter *iter;
589         struct device *dev;
590
591         int ret_max = ECMD_PROCESSED;
592         int ret = 0;
593
594         if (!scan_vgs_for_pvs(cmd)) {
595                 stack;
596                 return ECMD_FAILED;
597         }
598
599         if (!(iter = dev_iter_create(cmd->filter, 1))) {
600                 log_error("dev_iter creation failed");
601                 return ECMD_FAILED;
602         }
603
604         while ((dev = dev_iter_get(iter))) {
605                 if (!(pv = pv_read(cmd, dev_name(dev), NULL, NULL, 0, 0))) {
606                         memset(&pv_dummy, 0, sizeof(pv_dummy));
607                         dm_list_init(&pv_dummy.tags);
608                         dm_list_init(&pv_dummy.segments);
609                         pv_dummy.dev = dev;
610                         pv_dummy.fmt = NULL;
611                         pv = &pv_dummy;
612                 }
613                 ret = process_single(cmd, NULL, pv, handle);
614                 if (ret > ret_max)
615                         ret_max = ret;
616                 if (sigint_caught())
617                         break;
618         }
619
620         dev_iter_destroy(iter);
621
622         return ret_max;
623 }
624
625 /*
626  * If the lock_type is LCK_VG_READ (used only in reporting commands),
627  * we lock VG_GLOBAL to enable use of metadata cache.
628  * This can pause alongide pvscan or vgscan process for a while.
629  */
630 int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
631                     struct volume_group *vg, uint32_t flags,
632                     int scan_label_only, void *handle,
633                     int (*process_single) (struct cmd_context * cmd,
634                                            struct volume_group * vg,
635                                            struct physical_volume * pv,
636                                            void *handle))
637 {
638         int opt = 0;
639         int ret_max = ECMD_PROCESSED;
640         int ret = 0;
641         int lock_global = !(flags & READ_WITHOUT_LOCK) && !(flags & READ_FOR_UPDATE);
642
643         struct pv_list *pvl;
644         struct physical_volume *pv;
645         struct dm_list *pvslist, *vgnames;
646         struct dm_list tags;
647         struct str_list *sll;
648         char *tagname;
649         int scanned = 0;
650
651         dm_list_init(&tags);
652
653         if (lock_global && !lock_vol(cmd, VG_GLOBAL, LCK_VG_READ)) {
654                 log_error("Unable to obtain global lock.");
655                 return ECMD_FAILED;
656         }
657
658         if (argc) {
659                 log_verbose("Using physical volume(s) on command line");
660                 for (; opt < argc; opt++) {
661                         if (*argv[opt] == '@') {
662                                 tagname = argv[opt] + 1;
663
664                                 if (!validate_name(tagname)) {
665                                         log_error("Skipping invalid tag %s",
666                                                   tagname);
667                                         if (ret_max < EINVALID_CMD_LINE)
668                                                 ret_max = EINVALID_CMD_LINE;
669                                         continue;
670                                 }
671                                 if (!str_list_add(cmd->mem, &tags,
672                                                   dm_pool_strdup(cmd->mem,
673                                                               tagname))) {
674                                         log_error("strlist allocation failed");
675                                         goto bad;
676                                 }
677                                 continue;
678                         }
679                         if (vg) {
680                                 if (!(pvl = find_pv_in_vg(vg, argv[opt]))) {
681                                         log_error("Physical Volume \"%s\" not "
682                                                   "found in Volume Group "
683                                                   "\"%s\"", argv[opt],
684                                                   vg->name);
685                                         ret_max = ECMD_FAILED;
686                                         continue;
687                                 }
688                                 pv = pvl->pv;
689                         } else {
690                                 if (!(pv = pv_read(cmd, argv[opt], NULL,
691                                                    NULL, 1, scan_label_only))) {
692                                         log_error("Failed to read physical "
693                                                   "volume \"%s\"", argv[opt]);
694                                         ret_max = ECMD_FAILED;
695                                         continue;
696                                 }
697
698                                 /*
699                                  * If a PV has no MDAs it may appear to be an
700                                  * orphan until the metadata is read off
701                                  * another PV in the same VG.  Detecting this
702                                  * means checking every VG by scanning every
703                                  * PV on the system.
704                                  */
705                                 if (!scanned && is_orphan(pv)) {
706                                         if (!scan_label_only &&
707                                             !scan_vgs_for_pvs(cmd)) {
708                                                 stack;
709                                                 ret_max = ECMD_FAILED;
710                                                 continue;
711                                         }
712                                         scanned = 1;
713                                         if (!(pv = pv_read(cmd, argv[opt],
714                                                            NULL, NULL, 1,
715                                                            scan_label_only))) {
716                                                 log_error("Failed to read "
717                                                           "physical volume "
718                                                           "\"%s\"", argv[opt]);
719                                                 ret_max = ECMD_FAILED;
720                                                 continue;
721                                         }
722                                 }
723                         }
724
725                         ret = process_single(cmd, vg, pv, handle);
726                         if (ret > ret_max)
727                                 ret_max = ret;
728                         if (sigint_caught())
729                                 goto out;
730                 }
731                 if (!dm_list_empty(&tags) && (vgnames = get_vgnames(cmd, 0)) &&
732                            !dm_list_empty(vgnames)) {
733                         dm_list_iterate_items(sll, vgnames) {
734                                 vg = vg_read(cmd, sll->str, NULL, flags);
735                                 if (vg_read_error(vg)) {
736                                         ret_max = ECMD_FAILED;
737                                         vg_release(vg);
738                                         stack;
739                                         continue;
740                                 }
741
742                                 ret = process_each_pv_in_vg(cmd, vg, &tags,
743                                                             handle,
744                                                             process_single);
745
746                                 unlock_and_release_vg(cmd, vg, sll->str);
747
748                                 if (ret > ret_max)
749                                         ret_max = ret;
750                                 if (sigint_caught())
751                                         goto out;
752                         }
753                 }
754         } else {
755                 if (vg) {
756                         log_verbose("Using all physical volume(s) in "
757                                     "volume group");
758                         ret = process_each_pv_in_vg(cmd, vg, NULL, handle,
759                                                     process_single);
760                         if (ret > ret_max)
761                                 ret_max = ret;
762                         if (sigint_caught())
763                                 goto out;
764                 } else if (arg_count(cmd, all_ARG)) {
765                         ret = _process_all_devs(cmd, handle, process_single);
766                         if (ret > ret_max)
767                                 ret_max = ret;
768                         if (sigint_caught())
769                                 goto out;
770                 } else {
771                         log_verbose("Scanning for physical volume names");
772
773                         if (!(pvslist = get_pvs(cmd)))
774                                 goto bad;
775
776                         dm_list_iterate_items(pvl, pvslist) {
777                                 ret = process_single(cmd, NULL, pvl->pv,
778                                                      handle);
779                                 if (ret > ret_max)
780                                         ret_max = ret;
781                                 if (sigint_caught())
782                                         goto out;
783                         }
784                 }
785         }
786 out:
787         if (lock_global)
788                 unlock_vg(cmd, VG_GLOBAL);
789         return ret_max;
790 bad:
791         if (lock_global)
792                 unlock_vg(cmd, VG_GLOBAL);
793
794         return ECMD_FAILED;
795 }
796
797 /*
798  * Determine volume group name from a logical volume name
799  */
800 const char *extract_vgname(struct cmd_context *cmd, const char *lv_name)
801 {
802         const char *vg_name = lv_name;
803         char *st;
804         char *dev_dir = cmd->dev_dir;
805         int dev_dir_provided = 0;
806
807         /* Path supplied? */
808         if (vg_name && strchr(vg_name, '/')) {
809                 /* Strip dev_dir (optional) */
810                 if (*vg_name == '/') {
811                         while (*vg_name == '/')
812                                 vg_name++;
813                         vg_name--;
814                 }
815                 if (!strncmp(vg_name, dev_dir, strlen(dev_dir))) {
816                         vg_name += strlen(dev_dir);
817                         dev_dir_provided = 1;
818                         while (*vg_name == '/')
819                                 vg_name++;
820                 }
821                 if (*vg_name == '/') {
822                         log_error("\"%s\": Invalid path for Logical "
823                                   "Volume", lv_name);
824                         return 0;
825                 }
826
827                 /* Require exactly one set of consecutive slashes */
828                 if ((st = strchr(vg_name, '/')))
829                         while (*st == '/')
830                                 st++;
831
832                 if (!strchr(vg_name, '/') || strchr(st, '/')) {
833                         log_error("\"%s\": Invalid path for Logical Volume",
834                                   lv_name);
835                         return 0;
836                 }
837
838                 vg_name = dm_pool_strdup(cmd->mem, vg_name);
839                 if (!vg_name) {
840                         log_error("Allocation of vg_name failed");
841                         return 0;
842                 }
843
844                 *strchr(vg_name, '/') = '\0';
845                 return vg_name;
846         }
847
848         if (!(vg_name = default_vgname(cmd))) {
849                 if (lv_name)
850                         log_error("Path required for Logical Volume \"%s\"",
851                                   lv_name);
852                 return 0;
853         }
854
855         return vg_name;
856 }
857
858 /*
859  * Extract default volume group name from environment
860  */
861 char *default_vgname(struct cmd_context *cmd)
862 {
863         char *vg_path;
864
865         /* Take default VG from environment? */
866         vg_path = getenv("LVM_VG_NAME");
867         if (!vg_path)
868                 return 0;
869
870         vg_path = skip_dev_dir(cmd, vg_path, NULL);
871
872         if (strchr(vg_path, '/')) {
873                 log_error("Environment Volume Group in LVM_VG_NAME invalid: "
874                           "\"%s\"", vg_path);
875                 return 0;
876         }
877
878         return dm_pool_strdup(cmd->mem, vg_path);
879 }
880
881 /*
882  * Process physical extent range specifiers
883  */
884 static int _add_pe_range(struct dm_pool *mem, const char *pvname,
885                          struct dm_list *pe_ranges, uint32_t start, uint32_t count)
886 {
887         struct pe_range *per;
888
889         log_debug("Adding PE range: start PE %" PRIu32 " length %" PRIu32
890                   " on %s", start, count, pvname);
891
892         /* Ensure no overlap with existing areas */
893         dm_list_iterate_items(per, pe_ranges) {
894                 if (((start < per->start) && (start + count - 1 >= per->start))
895                     || ((start >= per->start) &&
896                         (per->start + per->count - 1) >= start)) {
897                         log_error("Overlapping PE ranges specified (%" PRIu32
898                                   "-%" PRIu32 ", %" PRIu32 "-%" PRIu32 ")"
899                                   " on %s",
900                                   start, start + count - 1, per->start,
901                                   per->start + per->count - 1, pvname);
902                         return 0;
903                 }
904         }
905
906         if (!(per = dm_pool_alloc(mem, sizeof(*per)))) {
907                 log_error("Allocation of list failed");
908                 return 0;
909         }
910
911         per->start = start;
912         per->count = count;
913         dm_list_add(pe_ranges, &per->list);
914
915         return 1;
916 }
917
918 static int xstrtouint32(const char *s, char **p, int base, uint32_t *result)
919 {
920         unsigned long ul;
921
922         errno = 0;
923         ul = strtoul(s, p, base);
924         if (errno || *p == s || (uint32_t) ul != ul)
925                 return -1;
926         *result = ul;
927         return 0;
928 }
929
930 static int _parse_pes(struct dm_pool *mem, char *c, struct dm_list *pe_ranges,
931                       const char *pvname, uint32_t size)
932 {
933         char *endptr;
934         uint32_t start, end;
935
936         /* Default to whole PV */
937         if (!c) {
938                 if (!_add_pe_range(mem, pvname, pe_ranges, UINT32_C(0), size))
939                         return_0;
940                 return 1;
941         }
942
943         while (*c) {
944                 if (*c != ':')
945                         goto error;
946
947                 c++;
948
949                 /* Disallow :: and :\0 */
950                 if (*c == ':' || !*c)
951                         goto error;
952
953                 /* Default to whole range */
954                 start = UINT32_C(0);
955                 end = size - 1;
956
957                 /* Start extent given? */
958                 if (isdigit(*c)) {
959                         if (xstrtouint32(c, &endptr, 10, &start))
960                                 goto error;
961                         c = endptr;
962                         /* Just one number given? */
963                         if (!*c || *c == ':')
964                                 end = start;
965                 }
966                 /* Range? */
967                 if (*c == '-') {
968                         c++;
969                         if (isdigit(*c)) {
970                                 if (xstrtouint32(c, &endptr, 10, &end))
971                                         goto error;
972                                 c = endptr;
973                         }
974                 }
975                 if (*c && *c != ':')
976                         goto error;
977
978                 if ((start > end) || (end > size - 1)) {
979                         log_error("PE range error: start extent %" PRIu32 " to "
980                                   "end extent %" PRIu32, start, end);
981                         return 0;
982                 }
983
984                 if (!_add_pe_range(mem, pvname, pe_ranges, start, end - start + 1))
985                         return_0;
986
987         }
988
989         return 1;
990
991       error:
992         log_error("Physical extent parsing error at %s", c);
993         return 0;
994 }
995
996 static int _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl,
997                              char *colon, int allocatable_only, struct dm_list *r)
998 {
999         const char *pvname;
1000         struct pv_list *new_pvl = NULL, *pvl2;
1001         struct dm_list *pe_ranges;
1002
1003         pvname = pv_dev_name(pvl->pv);
1004         if (allocatable_only && !(pvl->pv->status & ALLOCATABLE_PV)) {
1005                 log_error("Physical volume %s not allocatable", pvname);
1006                 return 1;
1007         }
1008
1009         if (allocatable_only && (pvl->pv->status & MISSING_PV)) {
1010                 log_error("Physical volume %s is missing", pvname);
1011                 return 1;
1012         }
1013
1014         if (allocatable_only &&
1015             (pvl->pv->pe_count == pvl->pv->pe_alloc_count)) {
1016                 log_error("No free extents on physical volume \"%s\"", pvname);
1017                 return 1;
1018         }
1019
1020         dm_list_iterate_items(pvl2, r)
1021                 if (pvl->pv->dev == pvl2->pv->dev) {
1022                         new_pvl = pvl2;
1023                         break;
1024                 }
1025
1026         if (!new_pvl) {
1027                 if (!(new_pvl = dm_pool_alloc(mem, sizeof(*new_pvl)))) {
1028                         log_error("Unable to allocate physical volume list.");
1029                         return 0;
1030                 }
1031
1032                 memcpy(new_pvl, pvl, sizeof(*new_pvl));
1033
1034                 if (!(pe_ranges = dm_pool_alloc(mem, sizeof(*pe_ranges)))) {
1035                         log_error("Allocation of pe_ranges list failed");
1036                         return 0;
1037                 }
1038                 dm_list_init(pe_ranges);
1039                 new_pvl->pe_ranges = pe_ranges;
1040                 dm_list_add(r, &new_pvl->list);
1041         }
1042
1043         /* Determine selected physical extents */
1044         if (!_parse_pes(mem, colon, new_pvl->pe_ranges, pv_dev_name(pvl->pv),
1045                         pvl->pv->pe_count))
1046                 return_0;
1047
1048         return 1;
1049 }
1050
1051 struct dm_list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int argc,
1052                             char **argv, int allocatable_only)
1053 {
1054         struct dm_list *r;
1055         struct pv_list *pvl;
1056         struct dm_list tags, arg_pvnames;
1057         const char *pvname = NULL;
1058         char *colon, *tagname;
1059         int i;
1060
1061         /* Build up list of PVs */
1062         if (!(r = dm_pool_alloc(mem, sizeof(*r)))) {
1063                 log_error("Allocation of list failed");
1064                 return NULL;
1065         }
1066         dm_list_init(r);
1067
1068         dm_list_init(&tags);
1069         dm_list_init(&arg_pvnames);
1070
1071         for (i = 0; i < argc; i++) {
1072                 if (*argv[i] == '@') {
1073                         tagname = argv[i] + 1;
1074                         if (!validate_name(tagname)) {
1075                                 log_error("Skipping invalid tag %s", tagname);
1076                                 continue;
1077                         }
1078                         dm_list_iterate_items(pvl, &vg->pvs) {
1079                                 if (str_list_match_item(&pvl->pv->tags,
1080                                                         tagname)) {
1081                                         if (!_create_pv_entry(mem, pvl, NULL,
1082                                                               allocatable_only,
1083                                                               r))
1084                                                 return_NULL;
1085                                 }
1086                         }
1087                         continue;
1088                 }
1089
1090                 pvname = argv[i];
1091
1092                 if ((colon = strchr(pvname, ':'))) {
1093                         if (!(pvname = dm_pool_strndup(mem, pvname,
1094                                                     (unsigned) (colon -
1095                                                                 pvname)))) {
1096                                 log_error("Failed to clone PV name");
1097                                 return NULL;
1098                         }
1099                 }
1100
1101                 if (!(pvl = find_pv_in_vg(vg, pvname))) {
1102                         log_error("Physical Volume \"%s\" not found in "
1103                                   "Volume Group \"%s\"", pvname, vg->name);
1104                         return NULL;
1105                 }
1106                 if (!_create_pv_entry(mem, pvl, colon, allocatable_only, r))
1107                         return_NULL;
1108         }
1109
1110         if (dm_list_empty(r))
1111                 log_error("No specified PVs have space available");
1112
1113         return dm_list_empty(r) ? NULL : r;
1114 }
1115
1116 struct dm_list *clone_pv_list(struct dm_pool *mem, struct dm_list *pvsl)
1117 {
1118         struct dm_list *r;
1119         struct pv_list *pvl, *new_pvl;
1120
1121         /* Build up list of PVs */
1122         if (!(r = dm_pool_alloc(mem, sizeof(*r)))) {
1123                 log_error("Allocation of list failed");
1124                 return NULL;
1125         }
1126         dm_list_init(r);
1127
1128         dm_list_iterate_items(pvl, pvsl) {
1129                 if (!(new_pvl = dm_pool_zalloc(mem, sizeof(*new_pvl)))) {
1130                         log_error("Unable to allocate physical volume list.");
1131                         return NULL;
1132                 }
1133
1134                 memcpy(new_pvl, pvl, sizeof(*new_pvl));
1135                 dm_list_add(r, &new_pvl->list);
1136         }
1137
1138         return r;
1139 }
1140
1141 int apply_lvname_restrictions(const char *name)
1142 {
1143         if (!strncmp(name, "snapshot", 8)) {
1144                 log_error("Names starting \"snapshot\" are reserved. "
1145                           "Please choose a different LV name.");
1146                 return 0;
1147         }
1148
1149         if (!strncmp(name, "pvmove", 6)) {
1150                 log_error("Names starting \"pvmove\" are reserved. "
1151                           "Please choose a different LV name.");
1152                 return 0;
1153         }
1154
1155         if (strstr(name, "_mlog")) {
1156                 log_error("Names including \"_mlog\" are reserved. "
1157                           "Please choose a different LV name.");
1158                 return 0;
1159         }
1160
1161         if (strstr(name, "_mimage")) {
1162                 log_error("Names including \"_mimage\" are reserved. "
1163                           "Please choose a different LV name.");
1164                 return 0;
1165         }
1166
1167         if (strstr(name, "_vorigin")) {
1168                 log_error("Names including \"_vorigin\" are reserved. "
1169                           "Please choose a different LV name.");
1170                 return 0;
1171         }
1172
1173         return 1;
1174 }
1175
1176 int is_reserved_lvname(const char *name)
1177 {
1178         int rc, old_suppress;
1179
1180         old_suppress = log_suppress(2);
1181         rc = !apply_lvname_restrictions(name);
1182         log_suppress(old_suppress);
1183
1184         return rc;
1185 }
1186
1187 void vgcreate_params_set_defaults(struct vgcreate_params *vp_def,
1188                                   struct volume_group *vg)
1189 {
1190         if (vg) {
1191                 vp_def->vg_name = NULL;
1192                 vp_def->extent_size = vg->extent_size;
1193                 vp_def->max_pv = vg->max_pv;
1194                 vp_def->max_lv = vg->max_lv;
1195                 vp_def->alloc = vg->alloc;
1196                 vp_def->clustered = vg_is_clustered(vg);
1197         } else {
1198                 vp_def->vg_name = NULL;
1199                 vp_def->extent_size = DEFAULT_EXTENT_SIZE * 2;
1200                 vp_def->max_pv = DEFAULT_MAX_PV;
1201                 vp_def->max_lv = DEFAULT_MAX_LV;
1202                 vp_def->alloc = DEFAULT_ALLOC_POLICY;
1203                 vp_def->clustered = DEFAULT_CLUSTERED;
1204         }
1205 }
1206
1207 /*
1208  * Set members of struct vgcreate_params from cmdline arguments.
1209  * Do preliminary validation with arg_*() interface.
1210  * Further, more generic validation is done in validate_vgcreate_params().
1211  * This function is to remain in tools directory.
1212  */
1213 int vgcreate_params_set_from_args(struct cmd_context *cmd,
1214                                   struct vgcreate_params *vp_new,
1215                                   struct vgcreate_params *vp_def)
1216 {
1217         vp_new->vg_name = skip_dev_dir(cmd, vp_def->vg_name, NULL);
1218         vp_new->max_lv = arg_uint_value(cmd, maxlogicalvolumes_ARG,
1219                                         vp_def->max_lv);
1220         vp_new->max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG,
1221                                         vp_def->max_pv);
1222         vp_new->alloc = arg_uint_value(cmd, alloc_ARG, vp_def->alloc);
1223
1224         /* Units of 512-byte sectors */
1225         vp_new->extent_size =
1226             arg_uint_value(cmd, physicalextentsize_ARG, vp_def->extent_size);
1227
1228         if (arg_count(cmd, clustered_ARG))
1229                 vp_new->clustered =
1230                         !strcmp(arg_str_value(cmd, clustered_ARG,
1231                                               vp_def->clustered ? "y":"n"), "y");
1232         else
1233                 /* Default depends on current locking type */
1234                 vp_new->clustered = locking_is_clustered();
1235
1236         if (arg_sign_value(cmd, physicalextentsize_ARG, 0) == SIGN_MINUS) {
1237                 log_error("Physical extent size may not be negative");
1238                 return 1;
1239         }
1240
1241         if (arg_sign_value(cmd, maxlogicalvolumes_ARG, 0) == SIGN_MINUS) {
1242                 log_error("Max Logical Volumes may not be negative");
1243                 return 1;
1244         }
1245
1246         if (arg_sign_value(cmd, maxphysicalvolumes_ARG, 0) == SIGN_MINUS) {
1247                 log_error("Max Physical Volumes may not be negative");
1248                 return 1;
1249         }
1250
1251         return 0;
1252 }
1253
1254 int lv_refresh(struct cmd_context *cmd, struct logical_volume *lv)
1255 {
1256         return suspend_lv(cmd, lv) && resume_lv(cmd, lv);
1257 }
1258
1259 int vg_refresh_visible(struct cmd_context *cmd, struct volume_group *vg)
1260 {
1261         struct lv_list *lvl;
1262         int r = 1;
1263
1264         dm_list_iterate_items(lvl, &vg->lvs)
1265                 if (lv_is_visible(lvl->lv))
1266                         if (!lv_refresh(cmd, lvl->lv))
1267                                 r = 0;
1268
1269         return r;
1270 }
1271
1272 void lv_spawn_background_polling(struct cmd_context *cmd,
1273                                  struct logical_volume *lv)
1274 {
1275         const char *pvname;
1276
1277         if ((lv->status & PVMOVE) &&
1278             (pvname = get_pvmove_pvname_from_lv_mirr(lv))) {
1279                 log_verbose("Spawning background pvmove process for %s",
1280                             pvname);
1281                 pvmove_poll(cmd, pvname, 1);
1282         } else if ((lv->status & LOCKED) &&
1283             (pvname = get_pvmove_pvname_from_lv(lv))) {
1284                 log_verbose("Spawning background pvmove process for %s",
1285                             pvname);
1286                 pvmove_poll(cmd, pvname, 1);
1287         }
1288
1289         if (lv->status & CONVERTING) {
1290                 log_verbose("Spawning background lvconvert process for %s",
1291                         lv->name);
1292                 lvconvert_poll(cmd, lv, 1);
1293         }
1294 }
1295
1296 /*
1297  * Intial sanity checking of non-recovery related command-line arguments.
1298  *
1299  * Output arguments:
1300  * pp: structure allocated by caller, fields written / validated here
1301  */
1302 int pvcreate_params_validate(struct cmd_context *cmd,
1303                              int argc, char **argv,
1304                              struct pvcreate_params *pp)
1305 {
1306         if (!argc) {
1307                 log_error("Please enter a physical volume path");
1308                 return 0;
1309         }
1310
1311         if (arg_count(cmd, yes_ARG) && !arg_count(cmd, force_ARG)) {
1312                 log_error("Option y can only be given with option f");
1313                 return 0;
1314         }
1315
1316         pp->yes = arg_count(cmd, yes_ARG);
1317         pp->force = arg_count(cmd, force_ARG);
1318
1319         if (arg_int_value(cmd, labelsector_ARG, 0) >= LABEL_SCAN_SECTORS) {
1320                 log_error("labelsector must be less than %lu",
1321                           LABEL_SCAN_SECTORS);
1322                 return 0;
1323         } else {
1324                 pp->labelsector = arg_int64_value(cmd, labelsector_ARG,
1325                                                   DEFAULT_LABELSECTOR);
1326         }
1327
1328         if (!(cmd->fmt->features & FMT_MDAS) &&
1329             (arg_count(cmd, pvmetadatacopies_ARG) ||
1330              arg_count(cmd, metadatasize_ARG)   ||
1331              arg_count(cmd, dataalignment_ARG)  ||
1332              arg_count(cmd, dataalignmentoffset_ARG))) {
1333                 log_error("Metadata and data alignment parameters only "
1334                           "apply to text format.");
1335                 return 0;
1336         }
1337
1338         if (arg_count(cmd, pvmetadatacopies_ARG) &&
1339             arg_int_value(cmd, pvmetadatacopies_ARG, -1) > 2) {
1340                 log_error("Metadatacopies may only be 0, 1 or 2");
1341                 return 0;
1342         }
1343
1344         if (arg_count(cmd, zero_ARG))
1345                 pp->zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n");
1346
1347         if (arg_sign_value(cmd, dataalignment_ARG, 0) == SIGN_MINUS) {
1348                 log_error("Physical volume data alignment may not be negative");
1349                 return 0;
1350         }
1351         pp->data_alignment = arg_uint64_value(cmd, dataalignment_ARG, UINT64_C(0));
1352
1353         if (pp->data_alignment > ULONG_MAX) {
1354                 log_error("Physical volume data alignment is too big.");
1355                 return 0;
1356         }
1357
1358         if (pp->data_alignment && pp->pe_start) {
1359                 if (pp->pe_start % pp->data_alignment)
1360                         log_warn("WARNING: Ignoring data alignment %" PRIu64
1361                                  " incompatible with --restorefile value (%"
1362                                  PRIu64").", pp->data_alignment, pp->pe_start);
1363                 pp->data_alignment = 0;
1364         }
1365
1366         if (arg_sign_value(cmd, dataalignmentoffset_ARG, 0) == SIGN_MINUS) {
1367                 log_error("Physical volume data alignment offset may not be negative");
1368                 return 0;
1369         }
1370         pp->data_alignment_offset = arg_uint64_value(cmd, dataalignmentoffset_ARG, UINT64_C(0));
1371
1372         if (pp->data_alignment_offset > ULONG_MAX) {
1373                 log_error("Physical volume data alignment offset is too big.");
1374                 return 0;
1375         }
1376
1377         if (pp->data_alignment_offset && pp->pe_start) {
1378                 log_warn("WARNING: Ignoring data alignment offset %" PRIu64
1379                          " incompatible with --restorefile value (%"
1380                          PRIu64").", pp->data_alignment_offset, pp->pe_start);
1381                 pp->data_alignment_offset = 0;
1382         }
1383
1384         if (arg_sign_value(cmd, metadatasize_ARG, 0) == SIGN_MINUS) {
1385                 log_error("Metadata size may not be negative");
1386                 return 0;
1387         }
1388
1389         pp->pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, UINT64_C(0));
1390         if (!pp->pvmetadatasize)
1391                 pp->pvmetadatasize = find_config_tree_int(cmd,
1392                                                  "metadata/pvmetadatasize",
1393                                                  DEFAULT_PVMETADATASIZE);
1394
1395         pp->pvmetadatacopies = arg_int_value(cmd, pvmetadatacopies_ARG, -1);
1396         if (pp->pvmetadatacopies < 0)
1397                 pp->pvmetadatacopies = find_config_tree_int(cmd,
1398                                                    "metadata/pvmetadatacopies",
1399                                                    DEFAULT_PVMETADATACOPIES);
1400
1401         return 1;
1402 }
1403