]> sourceware.org Git - lvm2.git/blame - tools/toollib.c
metadata: use lv_hash in segment-specific metadata parsing
[lvm2.git] / tools / toollib.c
CommitLineData
269930c0 1/*
67cdbd7e 2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
b8cd0f48 3 * Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
269930c0 4 *
6606c3ae
AK
5 * This file is part of LVM2.
6 *
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
be684599 9 * of the GNU Lesser General Public License v.2.1.
6606c3ae 10 *
be684599 11 * You should have received a copy of the GNU Lesser General Public License
6606c3ae 12 * along with this program; if not, write to the Free Software Foundation,
fcbef05a 13 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
269930c0
AK
14 */
15
25d42d50 16#include "tools.h"
7f97c7ea 17#include "lib/format_text/format-text.h"
6620dc94 18#include "lib/label/hints.h"
83fe6e72 19#include "lib/device/device_id.h"
f40fd883 20#include "lib/device/online.h"
47f8bda0 21#include "libdm/misc/dm-ioctl.h"
dfe3eb12 22
cc219483 23#include <sys/stat.h>
008c33a2
PR
24#include <signal.h>
25#include <sys/wait.h>
8cdec4c4 26#include <sys/utsname.h>
88e0060a 27#include <mntent.h>
cc219483 28
0ab11877 29#define report_log_ret_code(ret_code) report_current_object_cmdlog(REPORT_OBJECT_CMDLOG_NAME, \
0d0a3397
ZK
30 ((ret_code) == ECMD_PROCESSED) ? REPORT_OBJECT_CMDLOG_SUCCESS \
31 : REPORT_OBJECT_CMDLOG_FAILURE, (ret_code))
0ab11877 32
8a2fc586
AK
33const char *command_name(struct cmd_context *cmd)
34{
35 return cmd->command->name;
36}
37
008c33a2
PR
38static void _sigchld_handler(int sig __attribute__((unused)))
39{
40 while (wait4(-1, NULL, WNOHANG | WUNTRACED, NULL) > 0) ;
41}
42
43/*
44 * returns:
45 * -1 if the fork failed
46 * 0 if the parent
47 * 1 if the child
48 */
49int become_daemon(struct cmd_context *cmd, int skip_lvm)
50{
46669fe9 51 static const char _devnull[] = "/dev/null";
008c33a2
PR
52 int null_fd;
53 pid_t pid;
54 struct sigaction act = {
6c85ea50 55 .sa_handler = _sigchld_handler,
008c33a2
PR
56 .sa_flags = SA_NOCLDSTOP,
57 };
58
c68fb55a 59 log_verbose("Forking background process from command: %s", cmd->cmd_line);
008c33a2 60
1bb30a8c
ZK
61 if (sigaction(SIGCHLD, &act, NULL))
62 log_warn("WARNING: Failed to set SIGCHLD action.");
008c33a2
PR
63
64 if (!skip_lvm)
4c629a52
AK
65 if (!sync_local_dev_names(cmd)) { /* Flush ops and reset dm cookie */
66 log_error("Failed to sync local devices before forking.");
67 return -1;
68 }
008c33a2
PR
69
70 if ((pid = fork()) == -1) {
71 log_error("fork failed: %s", strerror(errno));
72 return -1;
73 }
74
75 /* Parent */
76 if (pid > 0)
77 return 0;
78
79 /* Child */
80 if (setsid() == -1)
81 log_error("Background process failed to setsid: %s",
82 strerror(errno));
83
10a5838a 84/* Set this to avoid discarding output from background process */
ce9a5cc2 85// #define DEBUG_CHILD
10a5838a
AK
86
87#ifndef DEBUG_CHILD
46669fe9
ZK
88 if ((null_fd = open(_devnull, O_RDWR)) == -1) {
89 log_sys_error("open", _devnull);
008c33a2
PR
90 _exit(ECMD_FAILED);
91 }
92
d418fc14 93 /* coverity[leaked_handle] don't care */
008c33a2
PR
94 if ((dup2(null_fd, STDIN_FILENO) < 0) || /* reopen stdin */
95 (dup2(null_fd, STDOUT_FILENO) < 0) || /* reopen stdout */
96 (dup2(null_fd, STDERR_FILENO) < 0)) { /* reopen stderr */
97 log_sys_error("dup2", "redirect");
98 (void) close(null_fd);
99 _exit(ECMD_FAILED);
100 }
101
102 if (null_fd > STDERR_FILENO)
103 (void) close(null_fd);
104
105 init_verbose(VERBOSE_BASE_LEVEL);
10a5838a
AK
106#endif /* DEBUG_CHILD */
107
008c33a2
PR
108 strncpy(*cmd->argv, "(lvm2)", strlen(*cmd->argv));
109
110 if (!skip_lvm) {
111 reset_locking();
fc280bcc 112 lvmcache_destroy(cmd, 1, 1);
c016b573 113 if (!lvmcache_init(cmd))
008c33a2
PR
114 /* FIXME Clean up properly here */
115 _exit(ECMD_FAILED);
116 }
008c33a2 117
1b524519 118 /* coverity[leaked_handle] null_fd does not leak here */
008c33a2
PR
119 return 1;
120}
121
08c060cf
AK
122/*
123 * Strip dev_dir if present
124 */
aec21154 125const char *skip_dev_dir(struct cmd_context *cmd, const char *vg_name,
d5d883d9 126 unsigned *dev_dir_found)
08c060cf 127{
b0dde9e8
ZK
128 size_t devdir_len = strlen(cmd->dev_dir);
129 const char *dmdir = dm_dir() + devdir_len;
9397354a 130 size_t dmdir_len = strlen(dmdir), vglv_sz;
63930f57 131 char *vgname = NULL, *lvname, *layer, *vglv;
08c060cf 132
9397354a 133 /* FIXME Do this properly */
b0dde9e8
ZK
134 if (*vg_name == '/')
135 while (vg_name[1] == '/')
08c060cf 136 vg_name++;
08c060cf 137
b0dde9e8
ZK
138 if (strncmp(vg_name, cmd->dev_dir, devdir_len)) {
139 if (dev_dir_found)
140 *dev_dir_found = 0;
141 } else {
9397354a
AK
142 if (dev_dir_found)
143 *dev_dir_found = 1;
b0dde9e8
ZK
144
145 vg_name += devdir_len;
9397354a
AK
146 while (*vg_name == '/')
147 vg_name++;
148
b0dde9e8 149 /* Reformat string if /dev/mapper found */
4bfdb01f
ZK
150 if (!strncmp(vg_name, dmdir, dmdir_len) && vg_name[dmdir_len] == '/') {
151 vg_name += dmdir_len + 1;
b0dde9e8
ZK
152 while (*vg_name == '/')
153 vg_name++;
154
155 if (!dm_split_lvm_name(cmd->mem, vg_name, &vgname, &lvname, &layer) ||
156 *layer) {
38200c20 157 log_error("skip_dev_dir: Couldn't split up device name %s.",
b0dde9e8
ZK
158 vg_name);
159 return vg_name;
160 }
161 vglv_sz = strlen(vgname) + strlen(lvname) + 2;
162 if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
163 dm_snprintf(vglv, vglv_sz, "%s%s%s", vgname,
164 *lvname ? "/" : "",
165 lvname) < 0) {
38200c20 166 log_error("vg/lv string alloc failed.");
b0dde9e8
ZK
167 return vg_name;
168 }
169 return vglv;
9397354a 170 }
9397354a
AK
171 }
172
aec21154 173 return vg_name;
08c060cf
AK
174}
175
565df4e7
DT
176static int _printed_clustered_vg_advice = 0;
177
baf95bbf 178/*
b622a7fe
DT
179 * Three possible results:
180 * a) return 0, skip 0: take the VG, and cmd will end in success
181 * b) return 0, skip 1: skip the VG, and cmd will end in success
182 * c) return 1, skip *: skip the VG, and cmd will end in failure
183 *
184 * Case b is the special case, and includes the following:
185 * . The VG is inconsistent, and the command allows for inconsistent VGs.
186 * . The VG is clustered, the host cannot access clustered VG's,
187 * and the command option has been used to ignore clustered vgs.
188 *
189 * Case c covers the other errors returned when reading the VG.
5bf74f29 190 * If *skip is 1, it's OK for the caller to read the list of PVs in the VG.
baf95bbf 191 */
ba7ff96f
DT
192static int _ignore_vg(struct cmd_context *cmd,
193 uint32_t error_flags, struct volume_group *error_vg,
194 const char *vg_name, struct dm_list *arg_vgnames,
195 uint32_t read_flags, int *skip, int *notfound)
baf95bbf 196{
ba7ff96f 197 uint32_t read_error = error_flags;
66248338 198
d8923457 199 *skip = 0;
66248338 200 *notfound = 0;
baf95bbf 201
1a74171c 202 if ((read_error & FAILED_NOTFOUND) && (read_flags & READ_OK_NOTFOUND)) {
66248338 203 *notfound = 1;
1a74171c
DT
204 return 0;
205 }
206
428514a0 207 if (read_error & FAILED_CLUSTERED) {
ba7ff96f
DT
208 if (arg_vgnames && str_list_match_item(arg_vgnames, vg_name)) {
209 log_error("Cannot access clustered VG %s.", vg_name);
565df4e7
DT
210 if (!_printed_clustered_vg_advice) {
211 _printed_clustered_vg_advice = 1;
212 log_error("See lvmlockd(8) for changing a clvm/clustered VG to a shared VG.");
213 }
428514a0
DT
214 return 1;
215 } else {
81ef1fd0 216 log_warn("WARNING: Skipping clustered VG %s.", vg_name);
565df4e7
DT
217 if (!_printed_clustered_vg_advice) {
218 _printed_clustered_vg_advice = 1;
219 log_error("See lvmlockd(8) for changing a clvm/clustered VG to a shared VG.");
220 }
428514a0
DT
221 *skip = 1;
222 return 0;
223 }
baf95bbf
AK
224 }
225
b4402bd8
DT
226 if (read_error & FAILED_EXPORTED) {
227 if (arg_vgnames && str_list_match_item(arg_vgnames, vg_name)) {
228 log_error("Volume group %s is exported", vg_name);
229 return 1;
230 } else {
231 read_error &= ~FAILED_EXPORTED; /* Check for other errors */
232 log_verbose("Skipping exported volume group %s", vg_name);
233 *skip = 1;
234 }
235 }
236
8cdec4c4
DT
237 /*
238 * Commands that operate on "all vgs" shouldn't be bothered by
239 * skipping a foreign VG, and the command shouldn't fail when
240 * one is skipped. But, if the command explicitly asked to
241 * operate on a foreign VG and it's skipped, then the command
242 * would expect to fail.
243 */
244 if (read_error & FAILED_SYSTEMID) {
ba7ff96f 245 if (arg_vgnames && str_list_match_item(arg_vgnames, vg_name)) {
3562b5ab 246 log_error("Cannot access VG %s with system ID %s with %slocal system ID%s%s.",
ba7ff96f
DT
247 vg_name,
248 error_vg ? error_vg->system_id : "unknown ",
249 cmd->system_id ? "" : "unknown ",
250 cmd->system_id ? " " : "",
251 cmd->system_id ? cmd->system_id : "");
8cdec4c4
DT
252 return 1;
253 } else {
254 read_error &= ~FAILED_SYSTEMID; /* Check for other errors */
b18feb98 255 log_verbose("Skipping foreign volume group %s", vg_name);
8cdec4c4
DT
256 *skip = 1;
257 }
258 }
259
fe70b03d
DT
260 /*
261 * Accessing a lockd VG when lvmlockd is not used is similar
262 * to accessing a foreign VG.
681f779a
DT
263 * This is also the point where a command fails if it failed
264 * to acquire the necessary lock from lvmlockd.
265 * The two cases are distinguished by FAILED_LOCK_TYPE (the
266 * VG lock_type requires lvmlockd), and FAILED_LOCK_MODE (the
267 * command failed to acquire the necessary lock.)
fe70b03d 268 */
681f779a 269 if (read_error & (FAILED_LOCK_TYPE | FAILED_LOCK_MODE)) {
ba7ff96f 270 if (arg_vgnames && str_list_match_item(arg_vgnames, vg_name)) {
681f779a
DT
271 if (read_error & FAILED_LOCK_TYPE)
272 log_error("Cannot access VG %s with lock type %s that requires lvmlockd.",
ba7ff96f
DT
273 vg_name,
274 error_vg ? error_vg->lock_type : "unknown");
681f779a 275 /* For FAILED_LOCK_MODE, the error is printed in vg_read. */
fe70b03d
DT
276 return 1;
277 } else {
278 read_error &= ~FAILED_LOCK_TYPE; /* Check for other errors */
681f779a 279 read_error &= ~FAILED_LOCK_MODE;
fe70b03d
DT
280 log_verbose("Skipping volume group %s", vg_name);
281 *skip = 1;
282 }
283 }
284
d8923457 285 if (read_error != SUCCESS) {
5bf74f29 286 *skip = 0;
d97f1c89
PR
287 if (is_orphan_vg(vg_name))
288 log_error("Cannot process standalone physical volumes");
289 else
290 log_error("Cannot process volume group %s", vg_name);
d8923457
ZK
291 return 1;
292 }
293
294 return 0;
baf95bbf
AK
295}
296
de273247 297/*
39b7d1ba 298 * This function updates the "selected" arg only if last item processed
de273247
PR
299 * is selected so this implements the "whole structure is selected if
300 * at least one of its items is selected".
301 */
302static void _update_selection_result(struct processing_handle *handle, int *selected)
303{
304 if (!handle || !handle->selection_handle)
305 return;
306
307 if (handle->selection_handle->selected)
308 *selected = 1;
309}
310
311static void _set_final_selection_result(struct processing_handle *handle, int selected)
312{
313 if (!handle || !handle->selection_handle)
314 return;
315
316 handle->selection_handle->selected = selected;
317}
318
68e4adb5
AK
319/*
320 * Metadata iteration functions
321 */
c54a9405
AK
322int process_each_segment_in_pv(struct cmd_context *cmd,
323 struct volume_group *vg,
324 struct physical_volume *pv,
51d96a17 325 struct processing_handle *handle,
6c4f65fe 326 process_single_pvseg_fn_t process_single_pvseg)
c54a9405
AK
327{
328 struct pv_segment *pvseg;
de273247 329 int whole_selected = 0;
3a30d1db 330 int ret_max = ECMD_PROCESSED;
c54a9405 331 int ret;
d66abfb8 332 struct pv_segment _free_pv_segment = { .pv = pv };
223c62e7 333
b622a7fe
DT
334 if (dm_list_empty(&pv->segments)) {
335 ret = process_single_pvseg(cmd, NULL, &_free_pv_segment, handle);
336 if (ret != ECMD_PROCESSED)
337 stack;
338 if (ret > ret_max)
339 ret_max = ret;
340 } else {
d66abfb8 341 dm_list_iterate_items(pvseg, &pv->segments) {
d8923457
ZK
342 if (sigint_caught())
343 return_ECMD_FAILED;
b622a7fe
DT
344
345 ret = process_single_pvseg(cmd, vg, pvseg, handle);
de273247 346 _update_selection_result(handle, &whole_selected);
b622a7fe 347 if (ret != ECMD_PROCESSED)
6f335ffa 348 stack;
d66abfb8
MB
349 if (ret > ret_max)
350 ret_max = ret;
d66abfb8 351 }
b622a7fe 352 }
223c62e7 353
de273247
PR
354 /* the PV is selected if at least one PV segment is selected */
355 _set_final_selection_result(handle, whole_selected);
c54a9405
AK
356 return ret_max;
357}
358
4c64ed4c
AK
359int process_each_segment_in_lv(struct cmd_context *cmd,
360 struct logical_volume *lv,
51d96a17 361 struct processing_handle *handle,
6c4f65fe 362 process_single_seg_fn_t process_single_seg)
4c64ed4c 363{
4c64ed4c 364 struct lv_segment *seg;
de273247 365 int whole_selected = 0;
3a30d1db 366 int ret_max = ECMD_PROCESSED;
4c64ed4c
AK
367 int ret;
368
2c44337b 369 dm_list_iterate_items(seg, &lv->segments) {
b622a7fe
DT
370 if (sigint_caught())
371 return_ECMD_FAILED;
372
373 ret = process_single_seg(cmd, seg, handle);
de273247 374 _update_selection_result(handle, &whole_selected);
b622a7fe 375 if (ret != ECMD_PROCESSED)
d8923457 376 stack;
4c64ed4c
AK
377 if (ret > ret_max)
378 ret_max = ret;
379 }
380
de273247
PR
381 /* the LV is selected if at least one LV segment is selected */
382 _set_final_selection_result(handle, whole_selected);
4c64ed4c
AK
383 return ret_max;
384}
385
911d6efa
ZK
386static const char *_extract_vgname(struct cmd_context *cmd, const char *lv_name,
387 const char **after)
388{
389 const char *vg_name = lv_name;
390 char *st, *pos;
391
392 /* Strip dev_dir (optional) */
393 if (!(vg_name = skip_dev_dir(cmd, vg_name, NULL)))
394 return_0;
395
396 /* Require exactly one set of consecutive slashes */
397 if ((st = pos = strchr(vg_name, '/')))
398 while (*st == '/')
399 st++;
400
401 if (!st || strchr(st, '/')) {
38200c20 402 log_error("\"%s\": Invalid path for Logical Volume.",
911d6efa
ZK
403 lv_name);
404 return 0;
405 }
406
407 if (!(vg_name = dm_pool_strndup(cmd->mem, vg_name, pos - vg_name))) {
408 log_error("Allocation of vg_name failed.");
409 return 0;
410 }
411
412 if (after)
413 *after = st;
414
415 return vg_name;
416}
97b16ec2 417
1115a9ea
AK
418/*
419 * Extract default volume group name from environment
420 */
421static const char *_default_vgname(struct cmd_context *cmd)
422{
423 const char *vg_path;
424
425 /* Take default VG from environment? */
426 vg_path = getenv("LVM_VG_NAME");
427 if (!vg_path)
428 return 0;
429
430 vg_path = skip_dev_dir(cmd, vg_path, NULL);
431
432 if (strchr(vg_path, '/')) {
38200c20
ZK
433 log_error("\"%s\": Invalid environment var LVM_VG_NAME set for Volume Group.",
434 vg_path);
1115a9ea
AK
435 return 0;
436 }
437
438 return dm_pool_strdup(cmd->mem, vg_path);
439}
440
68e4adb5
AK
441/*
442 * Determine volume group name from a logical volume name
443 */
8ef2b021 444const char *extract_vgname(struct cmd_context *cmd, const char *lv_name)
9b7742bb 445{
8ef2b021 446 const char *vg_name = lv_name;
cfd658da
AK
447
448 /* Path supplied? */
642c2e96 449 if (vg_name && strchr(vg_name, '/')) {
911d6efa
ZK
450 if (!(vg_name = _extract_vgname(cmd, lv_name, NULL)))
451 return_NULL;
cf6dd251 452
cfd658da
AK
453 return vg_name;
454 }
642c2e96 455
1115a9ea 456 if (!(vg_name = _default_vgname(cmd))) {
642c2e96 457 if (lv_name)
38200c20 458 log_error("Path required for Logical Volume \"%s\".",
9b7742bb 459 lv_name);
911d6efa 460 return NULL;
642c2e96 461 }
9b7742bb 462
642c2e96
AK
463 return vg_name;
464}
465
ffdceeb9 466static const char _pe_size_may_not_be_negative_msg[] = "Physical extent size may not be negative.";
f0cafc92
PR
467
468int vgcreate_params_set_defaults(struct cmd_context *cmd,
469 struct vgcreate_params *vp_def,
470 struct volume_group *vg)
c6ea6bf5 471{
f0cafc92
PR
472 int64_t extent_size;
473
b18feb98 474 /* Only vgsplit sets vg */
c6ea6bf5
DW
475 if (vg) {
476 vp_def->vg_name = NULL;
477 vp_def->extent_size = vg->extent_size;
478 vp_def->max_pv = vg->max_pv;
479 vp_def->max_lv = vg->max_lv;
480 vp_def->alloc = vg->alloc;
12eadbab 481 vp_def->vgmetadatacopies = vg->mda_copies;
b18feb98 482 vp_def->system_id = vg->system_id; /* No need to clone this */
c6ea6bf5
DW
483 } else {
484 vp_def->vg_name = NULL;
f0cafc92
PR
485 extent_size = find_config_tree_int64(cmd,
486 allocation_physical_extent_size_CFG, NULL) * 2;
487 if (extent_size < 0) {
488 log_error(_pe_size_may_not_be_negative_msg);
489 return 0;
490 }
491 vp_def->extent_size = (uint32_t) extent_size;
c6ea6bf5
DW
492 vp_def->max_pv = DEFAULT_MAX_PV;
493 vp_def->max_lv = DEFAULT_MAX_LV;
494 vp_def->alloc = DEFAULT_ALLOC_POLICY;
12eadbab 495 vp_def->vgmetadatacopies = DEFAULT_VGMETADATACOPIES;
b18feb98 496 vp_def->system_id = cmd->system_id;
c6ea6bf5 497 }
f0cafc92
PR
498
499 return 1;
c6ea6bf5
DW
500}
501
b8daca85 502/*
2a924b3e 503 * Set members of struct vgcreate_params from cmdline arguments.
b8daca85
DW
504 * Do preliminary validation with arg_*() interface.
505 * Further, more generic validation is done in validate_vgcreate_params().
d865615e 506 * This function is to remain in tools directory.
b8daca85 507 */
2a924b3e
DW
508int vgcreate_params_set_from_args(struct cmd_context *cmd,
509 struct vgcreate_params *vp_new,
510 struct vgcreate_params *vp_def)
b8daca85 511{
b18feb98 512 const char *system_id_arg_str;
fe70b03d 513 const char *lock_type = NULL;
fe70b03d 514 int use_lvmlockd;
fe70b03d 515 lock_type_t lock_type_num;
8cdec4c4 516
3e781ea4
DT
517 if (arg_is_set(cmd, clustered_ARG)) {
518 log_error("The clustered option is deprecated, see --shared.");
519 return 0;
520 }
521
2a924b3e 522 vp_new->vg_name = skip_dev_dir(cmd, vp_def->vg_name, NULL);
8868a4ff
DW
523 vp_new->max_lv = arg_uint_value(cmd, maxlogicalvolumes_ARG,
524 vp_def->max_lv);
525 vp_new->max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG,
526 vp_def->max_pv);
f3c17731 527 vp_new->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, vp_def->alloc);
b8daca85
DW
528
529 /* Units of 512-byte sectors */
8868a4ff
DW
530 vp_new->extent_size =
531 arg_uint_value(cmd, physicalextentsize_ARG, vp_def->extent_size);
b8daca85 532
fbf6b89a 533 if (arg_sign_value(cmd, physicalextentsize_ARG, SIGN_NONE) == SIGN_MINUS) {
f0cafc92 534 log_error(_pe_size_may_not_be_negative_msg);
b89963a7 535 return 0;
b8daca85
DW
536 }
537
be3510b2 538 if (arg_uint64_value(cmd, physicalextentsize_ARG, 0) > MAX_EXTENT_SIZE) {
21028a79 539 log_error("Physical extent size must be smaller than %s.",
be3510b2 540 display_size(cmd, (uint64_t) MAX_EXTENT_SIZE));
b89963a7 541 return 0;
be3510b2
MB
542 }
543
fbf6b89a 544 if (arg_sign_value(cmd, maxlogicalvolumes_ARG, SIGN_NONE) == SIGN_MINUS) {
38200c20 545 log_error("Max Logical Volumes may not be negative.");
b89963a7 546 return 0;
b8daca85
DW
547 }
548
fbf6b89a 549 if (arg_sign_value(cmd, maxphysicalvolumes_ARG, SIGN_NONE) == SIGN_MINUS) {
38200c20 550 log_error("Max Physical Volumes may not be negative.");
b89963a7 551 return 0;
b8daca85
DW
552 }
553
1e2420bc 554 if (arg_is_set(cmd, vgmetadatacopies_ARG))
12eadbab 555 vp_new->vgmetadatacopies = arg_int_value(cmd, vgmetadatacopies_ARG,
9e111ef6 556 DEFAULT_VGMETADATACOPIES);
b18feb98 557 else
50bf2c0d 558 vp_new->vgmetadatacopies = find_config_tree_int(cmd, metadata_vgmetadatacopies_CFG, NULL);
9e111ef6 559
fe70b03d 560 if (!(system_id_arg_str = arg_str_value(cmd, systemid_ARG, NULL))) {
8cdec4c4 561 vp_new->system_id = vp_def->system_id;
fe70b03d 562 } else {
b18feb98
AK
563 if (!(vp_new->system_id = system_id_from_string(cmd, system_id_arg_str)))
564 return_0;
8cdec4c4 565
b18feb98 566 /* FIXME Take local/extra_system_ids into account */
8cdec4c4 567 if (vp_new->system_id && cmd->system_id &&
ac6a4cd7
AK
568 strcmp(vp_new->system_id, cmd->system_id)) {
569 if (*vp_new->system_id)
81ef1fd0 570 log_warn("WARNING: VG with system ID %s might become inaccessible as local system ID is %s",
ac6a4cd7
AK
571 vp_new->system_id, cmd->system_id);
572 else
809a5e14 573 log_warn("WARNING: A VG without a system ID allows unsafe access from other hosts.");
ac6a4cd7 574 }
8cdec4c4
DT
575 }
576
fe70b03d
DT
577 if ((system_id_arg_str = arg_str_value(cmd, systemid_ARG, NULL))) {
578 vp_new->system_id = system_id_from_string(cmd, system_id_arg_str);
579 } else {
580 vp_new->system_id = vp_def->system_id;
581 }
582
583 if (system_id_arg_str) {
584 if (!vp_new->system_id || !vp_new->system_id[0])
585 log_warn("WARNING: A VG without a system ID allows unsafe access from other hosts.");
586
587 if (vp_new->system_id && cmd->system_id &&
588 strcmp(vp_new->system_id, cmd->system_id)) {
81ef1fd0 589 log_warn("WARNING: VG with system ID %s might become inaccessible as local system ID is %s",
fe70b03d
DT
590 vp_new->system_id, cmd->system_id);
591 }
592 }
593
594 /*
595 * Locking: what kind of locking should be used for the
596 * new VG, and is it compatible with current lvm.conf settings.
597 *
598 * The end result is to set vp_new->lock_type to:
8b904dc7 599 * none | clvm | dlm | sanlock | idm.
fe70b03d
DT
600 *
601 * If 'vgcreate --lock-type <arg>' is set, the answer is given
8b904dc7 602 * directly by <arg> which is one of none|clvm|dlm|sanlock|idm.
fe70b03d
DT
603 *
604 * 'vgcreate --clustered y' is the way to create clvm VGs.
605 *
606 * 'vgcreate --shared' is the way to create lockd VGs.
8b904dc7 607 * lock_type of sanlock, dlm or idm is selected based on
fe70b03d
DT
608 * which lock manager is running.
609 *
610 *
611 * 1. Using neither clvmd nor lvmlockd.
612 * ------------------------------------------------
613 * lvm.conf:
614 * global/use_lvmlockd = 0
615 * global/locking_type = 1
616 *
617 * - no locking is enabled
618 * - clvmd is not used
619 * - lvmlockd is not used
620 * - VGs with CLUSTERED set are ignored (requires clvmd)
621 * - VGs with lockd type are ignored (requires lvmlockd)
622 * - vgcreate can create new VGs with lock_type none
623 * - 'vgcreate --clustered y' fails
624 * - 'vgcreate --shared' fails
625 * - 'vgcreate' (neither option) creates a local VG
626 *
627 * 2. Using clvmd.
628 * ------------------------------------------------
629 * lvm.conf:
630 * global/use_lvmlockd = 0
631 * global/locking_type = 3
632 *
633 * - locking through clvmd is enabled (traditional clvm config)
634 * - clvmd is used
635 * - lvmlockd is not used
636 * - VGs with CLUSTERED set can be used
637 * - VGs with lockd type are ignored (requires lvmlockd)
638 * - vgcreate can create new VGs with CLUSTERED status flag
639 * - 'vgcreate --clustered y' works
640 * - 'vgcreate --shared' fails
641 * - 'vgcreate' (neither option) creates a clvm VG
642 *
643 * 3. Using lvmlockd.
644 * ------------------------------------------------
645 * lvm.conf:
646 * global/use_lvmlockd = 1
647 * global/locking_type = 1
648 *
649 * - locking through lvmlockd is enabled
650 * - clvmd is not used
651 * - lvmlockd is used
652 * - VGs with CLUSTERED set are ignored (requires clvmd)
653 * - VGs with lockd type can be used
8b904dc7 654 * - vgcreate can create new VGs with lock_type sanlock, dlm or idm
fe70b03d
DT
655 * - 'vgcreate --clustered y' fails
656 * - 'vgcreate --shared' works
657 * - 'vgcreate' (neither option) creates a local VG
658 */
659
fe70b03d 660 use_lvmlockd = find_config_tree_bool(cmd, global_use_lvmlockd_CFG, NULL);
fe70b03d
DT
661
662 if (arg_is_set(cmd, locktype_ARG)) {
fe70b03d
DT
663 lock_type = arg_str_value(cmd, locktype_ARG, "");
664
09981afc 665 if (arg_is_set(cmd, shared_ARG) && !is_lockd_type(lock_type)) {
8b904dc7 666 log_error("The --shared option requires lock type sanlock, dlm or idm.");
09981afc
DT
667 return 0;
668 }
669
fe70b03d 670 } else if (arg_is_set(cmd, shared_ARG)) {
d99dd408
DT
671 int found_multiple = 0;
672
fe70b03d 673 if (use_lvmlockd) {
d99dd408
DT
674 if (!(lock_type = lockd_running_lock_type(cmd, &found_multiple))) {
675 if (found_multiple)
676 log_error("Found multiple lock managers, select one with --lock-type.");
677 else
678 log_error("Failed to detect a running lock manager to select lock type.");
fe70b03d
DT
679 return 0;
680 }
681
fe70b03d 682 } else {
e62a71f3 683 log_error("Using a shared lock type requires lvmlockd (lvm.conf use_lvmlockd.)");
fe70b03d
DT
684 return 0;
685 }
686
687 } else {
3e781ea4 688 lock_type = "none";
fe70b03d
DT
689 }
690
691 /*
692 * Check that the lock_type is recognized, and is being
693 * used with the correct lvm.conf settings.
694 */
695 lock_type_num = get_lock_type_from_string(lock_type);
696
697 switch (lock_type_num) {
698 case LOCK_TYPE_INVALID:
3e781ea4 699 case LOCK_TYPE_CLVM:
fe70b03d
DT
700 log_error("lock_type %s is invalid", lock_type);
701 return 0;
702
703 case LOCK_TYPE_SANLOCK:
704 case LOCK_TYPE_DLM:
8b904dc7 705 case LOCK_TYPE_IDM:
fe70b03d 706 if (!use_lvmlockd) {
268f53ed 707 log_error("Using a shared lock type requires lvmlockd.");
fe70b03d
DT
708 return 0;
709 }
710 break;
fe70b03d
DT
711 case LOCK_TYPE_NONE:
712 break;
713 };
714
715 /*
716 * The vg is not owned by one host/system_id.
717 * Locking coordinates access from multiple hosts.
718 */
3e781ea4 719 if (lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK)
fe70b03d
DT
720 vp_new->system_id = NULL;
721
722 vp_new->lock_type = lock_type;
723
fe70b03d 724 log_debug("Setting lock_type to %s", vp_new->lock_type);
b89963a7 725 return 1;
b8daca85 726}
3ad47d16 727
a81a2406
ZK
728/* Shared code for changing activation state for vgchange/lvchange */
729int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
730 activation_change_t activate)
731{
971ab733 732 int r = 1;
d9e8895a 733 int integrity_recalculate;
f0179fac 734 struct logical_volume *snapshot_lv;
971ab733 735
0b7335f8
ZK
736 if (lv_is_cache_pool(lv)) {
737 if (is_change_activating(activate)) {
738 log_verbose("Skipping activation of cache pool %s.",
739 display_lvname(lv));
740 return 1;
741 }
742 if (!dm_list_empty(&lv->segs_using_this_lv)) {
743 log_verbose("Skipping deactivation of used cache pool %s.",
744 display_lvname(lv));
745 return 1;
746 }
747 /*
748 * Allow to pass only deactivation of unused cache pool.
749 * Useful only for recovery of failed zeroing of metadata LV.
750 */
751 }
752
971ab733
ZK
753 if (lv_is_merging_origin(lv)) {
754 /*
755 * For merging origin, its snapshot must be inactive.
756 * If it's still active and cannot be deactivated
757 * activation or deactivation of origin fails!
758 *
759 * When origin is deactivated and merging snapshot is thin
760 * it allows to deactivate origin, but still report error,
761 * since the thin snapshot remains active.
762 *
763 * User could retry to deactivate it with another
764 * deactivation of origin, which is the only visible LV
765 */
f0179fac
AK
766 snapshot_lv = find_snapshot(lv)->lv;
767 if (lv_is_thin_type(snapshot_lv) && !deactivate_lv(cmd, snapshot_lv)) {
e6fd16f8 768 if (is_change_activating(activate)) {
d1c1f600
ZK
769 log_error("Refusing to activate merging volume %s while "
770 "snapshot volume %s is still active.",
771 display_lvname(lv), display_lvname(snapshot_lv));
971ab733
ZK
772 return 0;
773 }
774
d1c1f600
ZK
775 log_error("Cannot fully deactivate merging origin volume %s while "
776 "snapshot volume %s is still active.",
777 display_lvname(lv), display_lvname(snapshot_lv));
971ab733
ZK
778 r = 0; /* and continue to deactivate origin... */
779 }
780 }
781
8b7a78c7 782 if (is_change_activating(activate) &&
677833ce 783 lvmcache_has_duplicate_devs() &&
8b7a78c7
DT
784 vg_has_duplicate_pvs(lv->vg) &&
785 !find_config_tree_bool(cmd, devices_allow_changes_with_duplicate_pvs_CFG, NULL)) {
786 log_error("Cannot activate LVs in VG %s while PVs appear on duplicate devices.",
787 lv->vg->name);
788 return 0;
789 }
790
d9e8895a
DT
791 if ((integrity_recalculate = lv_has_integrity_recalculate_metadata(lv))) {
792 /* Don't want pvscan to write VG while running from systemd service. */
793 if (!strcmp(cmd->name, "pvscan")) {
794 log_error("Cannot activate uninitialized integrity LV %s from pvscan.",
795 display_lvname(lv));
796 return 0;
797 }
798
799 if (vg_is_shared(lv->vg)) {
800 uint32_t lockd_state = 0;
801 if (!lockd_vg(cmd, lv->vg->name, "ex", 0, &lockd_state)) {
802 log_error("Cannot activate uninitialized integrity LV %s without lock.",
803 display_lvname(lv));
804 return 0;
805 }
806 }
807 }
808
18259d55 809 if (!lv_active_change(cmd, lv, activate))
d2d71330 810 return_0;
a81a2406 811
d9e8895a
DT
812 /* Write VG metadata to clear the integrity recalculate flag. */
813 if (integrity_recalculate && lv_is_active(lv)) {
814 log_print_unless_silent("Updating VG to complete initialization of integrity LV %s.",
815 display_lvname(lv));
816 lv_clear_integrity_recalculate_metadata(lv);
817 }
818
0b6782fa
DT
819 /*
820 * When LVs are deactivated, then autoactivation of the VG is
821 * "re-armed" by removing the vg online file. So, after deactivation
822 * of LVs, if PVs are disconnected and reconnected again, event
823 * activation will trigger autoactivation again. This secondary
824 * autoactivation is somewhat different from, and not as important as
825 * the initial autoactivation during system startup. The secondary
826 * autoactivation will happen to a VG on a running system and may be
827 * mixing with user commands, so the end result is unpredictable.
828 *
39b7d1ba 829 * It's possible that we might want a config setting for users to
0b6782fa
DT
830 * disable secondary autoactivations. Once a system is up, the
831 * user may want to take charge of activation changes to the VG
832 * and not have the system autoactivation interfere.
833 */
ed1651d1
ZK
834 if (!is_change_activating(activate) && cmd->event_activation &&
835 !cmd->online_vg_file_removed) {
836 cmd->online_vg_file_removed = 1;
0b6782fa 837 online_vg_file_remove(lv->vg->name);
ed1651d1 838 }
0b6782fa 839
2d5dc651
DT
840 set_lv_notify(lv->vg->cmd);
841
971ab733 842 return r;
a81a2406
ZK
843}
844
3ad47d16
PR
845int lv_refresh(struct cmd_context *cmd, struct logical_volume *lv)
846{
88c19d5d
ZK
847 struct logical_volume *snapshot_lv;
848
849 if (lv_is_merging_origin(lv)) {
850 snapshot_lv = find_snapshot(lv)->lv;
851 if (lv_is_thin_type(snapshot_lv) && !deactivate_lv(cmd, snapshot_lv))
852 log_print_unless_silent("Delaying merge for origin volume %s since "
853 "snapshot volume %s is still active.",
854 display_lvname(lv), display_lvname(snapshot_lv));
855 }
856
98b41db3 857 if (!lv_refresh_suspend_resume(lv))
e043e03c 858 return_0;
df13cf08 859
df06d9ac
MS
860 /*
861 * check if snapshot merge should be polled
862 * - unfortunately: even though the dev_manager will clear
863 * the lv's merge attributes if a merge is not possible;
864 * it is clearing a different instance of the lv (as
865 * retrieved with lv_from_lvid)
866 * - fortunately: polldaemon will immediately shutdown if the
867 * origin doesn't have a status with a snapshot percentage
868 */
18259d55 869 if (background_polling() && lv_is_merging_origin(lv) && lv_is_active(lv))
df06d9ac
MS
870 lv_spawn_background_polling(cmd, lv);
871
778de22d 872 return 1;
3ad47d16 873}
da1ba4ed
PR
874
875int vg_refresh_visible(struct cmd_context *cmd, struct volume_group *vg)
876{
877 struct lv_list *lvl;
878 int r = 1;
21e094d9 879
41449383
ZK
880 sigint_allow();
881 dm_list_iterate_items(lvl, &vg->lvs) {
6f335ffa
ZK
882 if (sigint_caught()) {
883 r = 0;
884 stack;
885 break;
886 }
41449383 887
94eda42e
ZK
888 if (lv_is_visible(lvl->lv) &&
889 !(lv_is_cow(lvl->lv) && !lv_is_virtual_origin(origin_from_cow(lvl->lv))) &&
890 !lv_refresh(cmd, lvl->lv)) {
6f335ffa
ZK
891 r = 0;
892 stack;
893 }
41449383
ZK
894 }
895
896 sigint_restore();
21e094d9 897
da1ba4ed
PR
898 return r;
899}
93bbc31c
AK
900
901void lv_spawn_background_polling(struct cmd_context *cmd,
902 struct logical_volume *lv)
903{
904 const char *pvname;
b120454b 905 const struct logical_volume *lv_mirr = NULL;
93bbc31c 906
f8d12913
ZK
907 /* Ensure there is nothing waiting on cookie */
908 if (!sync_local_dev_names(cmd))
81ef1fd0 909 log_warn("WARNING: Failed to sync local dev names.");
f8d12913 910
b120454b
OK
911 if (lv_is_pvmove(lv))
912 lv_mirr = lv;
913 else if (lv_is_locked(lv))
914 lv_mirr = find_pvmove_lv_in_lv(lv);
915
916 if (lv_mirr &&
917 (pvname = get_pvmove_pvname_from_lv_mirr(lv_mirr))) {
38200c20 918 log_verbose("Spawning background pvmove process for %s.",
93bbc31c 919 pvname);
76a0dffe 920 pvmove_poll(cmd, pvname, lv_mirr->lvid.s, lv_mirr->vg->name, lv_mirr->name, 1);
93bbc31c
AK
921 }
922
2360ce35 923 if (lv_is_converting(lv) || lv_is_merging(lv)) {
38200c20 924 log_verbose("Spawning background lvconvert process for %s.",
b120454b 925 lv->name);
93bbc31c
AK
926 lvconvert_poll(cmd, lv, 1);
927 }
928}
f900ba63 929
a6bc975a
MS
930int get_activation_monitoring_mode(struct cmd_context *cmd,
931 int *monitoring_mode)
932{
933 *monitoring_mode = DEFAULT_DMEVENTD_MONITOR;
934
7e671e5d
AK
935 if (arg_is_set(cmd, monitor_ARG) &&
936 (arg_is_set(cmd, ignoremonitoring_ARG) ||
937 arg_is_set(cmd, sysinit_ARG))) {
38200c20 938 log_error("--ignoremonitoring or --sysinit option not allowed with --monitor option.");
a6bc975a
MS
939 return 0;
940 }
941
7e671e5d 942 if (arg_is_set(cmd, monitor_ARG))
a6bc975a
MS
943 *monitoring_mode = arg_int_value(cmd, monitor_ARG,
944 DEFAULT_DMEVENTD_MONITOR);
7e671e5d
AK
945 else if (is_static() || arg_is_set(cmd, ignoremonitoring_ARG) ||
946 arg_is_set(cmd, sysinit_ARG) ||
d6a91da4 947 !find_config_tree_bool(cmd, activation_monitoring_CFG, NULL))
a6bc975a 948 *monitoring_mode = DMEVENTD_MONITOR_IGNORE;
b73c1824 949
a6bc975a
MS
950 return 1;
951}
68176be1 952
894eda47
ZK
953/*
954 * Read pool options from cmdline
955 */
24a84549 956int get_pool_params(struct cmd_context *cmd,
894eda47 957 const struct segment_type *segtype,
4ccedcea 958 int *pool_data_vdo,
894eda47
ZK
959 uint64_t *pool_metadata_size,
960 int *pool_metadata_spare,
f4137640
ZK
961 uint32_t *chunk_size,
962 thin_discards_t *discards,
b8cd0f48 963 thin_zero_t *zero_new_blocks)
f4137640 964{
4ccedcea
ZK
965 if ((*pool_data_vdo = arg_int_value(cmd, pooldatavdo_ARG, 0))) {
966 if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_VDO)))
967 return_0;
968
969 if (activation() && segtype->ops->target_present) {
970 if (!segtype->ops->target_present(cmd, NULL, NULL)) {
971 log_error("%s: Required device-mapper target(s) not detected in your kernel.",
972 segtype->name);
973 return_0;
974 }
975 }
976 }
977
978 if (segtype_is_thin_pool(segtype) || segtype_is_thin(segtype) || *pool_data_vdo) {
d574072d 979 if (arg_is_set(cmd, zero_ARG)) {
b8cd0f48
ZK
980 *zero_new_blocks = arg_int_value(cmd, zero_ARG, 0) ? THIN_ZERO_YES : THIN_ZERO_NO;
981 log_very_verbose("%s pool zeroing.",
982 (*zero_new_blocks == THIN_ZERO_YES) ? "Enabling" : "Disabling");
983 } else
984 *zero_new_blocks = THIN_ZERO_UNSELECTED;
985
d574072d 986 if (arg_is_set(cmd, discards_ARG)) {
894eda47 987 *discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, 0);
38200c20 988 log_very_verbose("Setting pool discards to %s.",
894eda47 989 get_pool_discards_name(*discards));
b8cd0f48
ZK
990 } else
991 *discards = THIN_DISCARDS_UNSELECTED;
f4137640 992 }
1ef98310 993
897b0915
ZK
994 if (arg_from_list_is_negative(cmd, "may not be negative",
995 chunksize_ARG,
996 pooldatasize_ARG,
997 poolmetadatasize_ARG,
998 -1))
999 return_0;
1000
1001 if (arg_from_list_is_zero(cmd, "may not be zero",
1002 chunksize_ARG,
1003 pooldatasize_ARG,
1004 poolmetadatasize_ARG,
1005 -1))
1006 return_0;
894eda47 1007
897b0915 1008 if (arg_is_set(cmd, chunksize_ARG)) {
894eda47 1009 *chunk_size = arg_uint_value(cmd, chunksize_ARG, 0);
a0693da9
ZK
1010
1011 if (!validate_pool_chunk_size(cmd, segtype, *chunk_size))
1012 return_0;
1013
38200c20 1014 log_very_verbose("Setting pool chunk size to %s.",
1ef98310 1015 display_size(cmd, *chunk_size));
4d0793f0
ZK
1016 } else
1017 *chunk_size = 0;
e195b522 1018
7e671e5d 1019 if (arg_is_set(cmd, poolmetadatasize_ARG)) {
7e671e5d 1020 if (arg_is_set(cmd, poolmetadata_ARG)) {
894eda47
ZK
1021 log_error("Please specify either metadata logical volume or its size.");
1022 return 0;
1023 }
1024
97098965
ZK
1025 *pool_metadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG,
1026 UINT64_C(0));
4d0793f0
ZK
1027 } else
1028 *pool_metadata_size = 0;
1029
4d0793f0 1030 /* TODO: default in lvm.conf and metadata profile ? */
894eda47
ZK
1031 *pool_metadata_spare = arg_int_value(cmd, poolmetadataspare_ARG,
1032 DEFAULT_POOL_METADATA_SPARE);
1033
f4137640
ZK
1034 return 1;
1035}
1036
68176be1
AK
1037/*
1038 * Generic stripe parameter checks.
1039 */
4ffe15bf
AK
1040static int _validate_stripe_params(struct cmd_context *cmd, const struct segment_type *segtype,
1041 uint32_t *stripes, uint32_t *stripe_size)
68176be1 1042{
34eb082b
ZK
1043 if (*stripes < 1 || *stripes > MAX_STRIPES) {
1044 log_error("Number of stripes (%d) must be between %d and %d.",
1045 *stripes, 1, MAX_STRIPES);
1046 return 0;
1047 }
4ffe15bf 1048
34eb082b
ZK
1049 if (!segtype_supports_stripe_size(segtype)) {
1050 if (*stripe_size) {
1051 log_print_unless_silent("Ignoring stripesize argument for %s devices.",
1052 segtype->name);
1053 *stripe_size = 0;
1054 }
1055 } else if (*stripes == 1) {
114db6f7
AK
1056 if (*stripe_size) {
1057 log_print_unless_silent("Ignoring stripesize argument with single stripe.");
1058 *stripe_size = 0;
1059 }
34eb082b 1060 } else {
4ffe15bf
AK
1061 if (!*stripe_size) {
1062 *stripe_size = find_config_tree_int(cmd, metadata_stripesize_CFG, NULL) * 2;
1063 log_print_unless_silent("Using default stripesize %s.",
1064 display_size(cmd, (uint64_t) *stripe_size));
1065 }
1066
34eb082b
ZK
1067 if (*stripe_size > STRIPE_SIZE_LIMIT * 2) {
1068 log_error("Stripe size cannot be larger than %s.",
1069 display_size(cmd, (uint64_t) STRIPE_SIZE_LIMIT));
1070 return 0;
1071 } else if (*stripe_size < STRIPE_SIZE_MIN || !is_power_of_2(*stripe_size)) {
4ffe15bf
AK
1072 log_error("Invalid stripe size %s.",
1073 display_size(cmd, (uint64_t) *stripe_size));
1074 return 0;
1075 }
68176be1
AK
1076 }
1077
68176be1
AK
1078 return 1;
1079}
1080
1081/*
1082 * The stripe size is limited by the size of a uint32_t, but since the
1083 * value given by the user is doubled, and the final result must be a
1084 * power of 2, we must divide UINT_MAX by four and add 1 (to round it
1085 * up to the power of 2)
1086 */
c1a0a2c7
AK
1087int get_stripe_params(struct cmd_context *cmd, const struct segment_type *segtype,
1088 uint32_t *stripes, uint32_t *stripe_size,
1089 unsigned *stripes_supplied, unsigned *stripe_size_supplied)
68176be1
AK
1090{
1091 /* stripes_long_ARG takes precedence (for lvconvert) */
4ffe15bf 1092 /* FIXME Cope with relative +/- changes for lvconvert. */
34eb082b
ZK
1093 if (arg_is_set(cmd, stripes_long_ARG)) {
1094 *stripes = arg_uint_value(cmd, stripes_long_ARG, 0);
1095 *stripes_supplied = 1;
1096 } else if (arg_is_set(cmd, stripes_ARG)) {
1097 *stripes = arg_uint_value(cmd, stripes_ARG, 0);
1098 *stripes_supplied = 1;
1099 } else {
1100 /*
1101 * FIXME add segtype parameter for min_stripes and remove logic for this
1102 * from all other places
1103 */
1104 if (segtype_is_any_raid6(segtype))
1105 *stripes = 3;
1106 else if (segtype_is_striped_raid(segtype))
1107 *stripes = 2;
1108 else
1109 *stripes = 1;
1110 *stripes_supplied = 0;
1111 }
68176be1 1112
34eb082b 1113 if ((*stripe_size = arg_uint_value(cmd, stripesize_ARG, 0))) {
fbf6b89a 1114 if (arg_sign_value(cmd, stripesize_ARG, SIGN_NONE) == SIGN_MINUS) {
38200c20 1115 log_error("Negative stripesize is invalid.");
68176be1
AK
1116 return 0;
1117 }
68176be1 1118 }
34eb082b 1119 *stripe_size_supplied = arg_is_set(cmd, stripesize_ARG);
68176be1 1120
4ffe15bf 1121 return _validate_stripe_params(cmd, segtype, stripes, stripe_size);
68176be1
AK
1122}
1123
df5fd5ae 1124static int _validate_cachepool_params(const char *policy_name, cache_mode_t cache_mode)
f67e1fad 1125{
df5fd5ae
DT
1126 /*
1127 * FIXME: it might be nice if cmd def rules could check option values,
1128 * then a rule could do this.
1129 */
1130 if ((cache_mode == CACHE_MODE_WRITEBACK) && policy_name && !strcmp(policy_name, "cleaner")) {
1131 log_error("Cache mode \"writeback\" is not compatible with cache policy \"cleaner\".");
1132 return 0;
1133 }
1134
f67e1fad
PR
1135 return 1;
1136}
1137
969ee25a 1138int get_cache_params(struct cmd_context *cmd,
c598e65d 1139 uint32_t *chunk_size,
4d2b1a06 1140 cache_metadata_format_t *cache_metadata_format,
197066c8 1141 cache_mode_t *cache_mode,
969ee25a
ZK
1142 const char **name,
1143 struct dm_config_tree **settings)
f67e1fad
PR
1144{
1145 const char *str;
1146 struct arg_value_group_list *group;
1147 struct dm_config_tree *result = NULL, *prev = NULL, *current = NULL;
089bdc0b 1148 struct dm_config_node *cn;
4b9b8e12 1149 int ok = 0;
f67e1fad 1150
36003df7
ZK
1151 if (arg_is_set(cmd, chunksize_ARG)) {
1152 *chunk_size = arg_uint_value(cmd, chunksize_ARG, 0);
969ee25a 1153
36003df7
ZK
1154 if (!validate_cache_chunk_size(cmd, *chunk_size))
1155 return_0;
969ee25a 1156
36003df7
ZK
1157 log_very_verbose("Setting pool chunk size to %s.",
1158 display_size(cmd, *chunk_size));
1159 }
1160
4d2b1a06
ZK
1161 *cache_metadata_format = (cache_metadata_format_t)
1162 arg_uint_value(cmd, cachemetadataformat_ARG, CACHE_METADATA_FORMAT_UNSELECTED);
1163
36003df7
ZK
1164 *cache_mode = (cache_mode_t) arg_uint_value(cmd, cachemode_ARG, CACHE_MODE_UNSELECTED);
1165
1166 *name = arg_str_value(cmd, cachepolicy_ARG, NULL);
e9e35b01 1167
df5fd5ae
DT
1168 if (!_validate_cachepool_params(*name, *cache_mode))
1169 goto_out;
1170
f67e1fad 1171 dm_list_iterate_items(group, &cmd->arg_value_groups) {
4b9b8e12 1172 if (!grouped_arg_is_set(group->arg_values, cachesettings_ARG))
f67e1fad
PR
1173 continue;
1174
e9e35b01 1175 if (!(current = dm_config_create()))
4b9b8e12 1176 goto_out;
f67e1fad
PR
1177 if (prev)
1178 current->cascade = prev;
1179 prev = current;
1180
1181 if (!(str = grouped_arg_str_value(group->arg_values,
4b9b8e12 1182 cachesettings_ARG,
f67e1fad 1183 NULL)))
4b9b8e12 1184 goto_out;
f67e1fad 1185
e40fbd08 1186 if (!dm_config_parse_without_dup_node_check(current, str, str + strlen(str)))
4b9b8e12 1187 goto_out;
f67e1fad
PR
1188 }
1189
36003df7
ZK
1190 if (current) {
1191 if (!(result = dm_config_flatten(current)))
1192 goto_out;
969ee25a 1193
36003df7
ZK
1194 if (result->root) {
1195 if (!(cn = dm_config_create_node(result, "policy_settings")))
1196 goto_out;
4b9b8e12 1197
36003df7
ZK
1198 cn->child = result->root;
1199 result->root = cn;
1200 }
7d615a3f 1201 }
4b9b8e12 1202
4b9b8e12 1203 ok = 1;
4b9b8e12 1204out:
193f9b26 1205 if (!ok && result) {
f67e1fad
PR
1206 dm_config_destroy(result);
1207 result = NULL;
1208 }
f67e1fad
PR
1209 while (prev) {
1210 current = prev->cascade;
1211 dm_config_destroy(prev);
1212 prev = current;
1213 }
e9e35b01
ZK
1214
1215 *settings = result;
1216
1217 return ok;
f67e1fad
PR
1218}
1219
5e060b8f
ZK
1220/*
1221 * Compare VDO option name, skip any '_' in name
1222 * and also allow to use it without vdo_[use_] prefix
1223 */
1224static int _compare_vdo_option(const char *b1, const char *b2)
1225{
bba96e86
ZK
1226 int use_skipped = 0;
1227
5e060b8f
ZK
1228 if (strncasecmp(b1, "vdo", 3) == 0) // skip vdo prefix
1229 b1 += 3;
1230
5e060b8f
ZK
1231 while (*b1 && *b2) {
1232 if (tolower(*b1) == tolower(*b2)) {
1233 ++b1;
1234 ++b2;
1235 continue; // matching char
1236 }
1237
1238 if (*b1 == '_')
1239 ++b1; // skip to next char
1240 else if (*b2 == '_')
1241 ++b2; // skip to next char
bba96e86
ZK
1242 else {
1243 if (!use_skipped++ && (strncmp(b2, "use_", 4) == 0)) {
1244 b2 += 4; // try again with skipped prefix 'use_'
1245 continue;
1246 }
1247
5e060b8f 1248 break; // mismatch
bba96e86 1249 }
5e060b8f
ZK
1250 }
1251
1252 return (*b1 || *b2) ? 0 : 1;
1253}
1254
1255#define CHECK_AND_SET(var, onoff) \
1256 option = #var;\
1257 if (_compare_vdo_option(cn->key, option)) {\
1258 if (is_lvchange || !cn->v || (cn->v->type != DM_CFG_INT))\
1259 goto err;\
1260 if (vtp->var != cn->v->v.i) {\
1261 vtp->var = cn->v->v.i;\
1262 u |= onoff;\
1263 }\
1264 continue;\
1265 }
1266
1267#define DO_OFFLINE(var) \
1268 CHECK_AND_SET(var, VDO_CHANGE_OFFLINE)
1269
1270#define DO_ONLINE(var) \
1271 CHECK_AND_SET(var, VDO_CHANGE_ONLINE)
1272
1273int get_vdo_settings(struct cmd_context *cmd,
1274 struct dm_vdo_target_params *vtp,
1275 int *updated)
1276{
1277 const char *str, *option = NULL;
1278 struct arg_value_group_list *group;
1279 struct dm_config_tree *result = NULL, *prev = NULL, *current = NULL;
1280 struct dm_config_node *cn;
1281 int r = 0, u = 0, is_lvchange;
1282 int use_compression = vtp->use_compression;
1283 int use_deduplication = vtp->use_deduplication;
1284 int checked_lvchange;
1285
1286 if (updated)
1287 *updated = 0;
1288
1289 // Group all --vdosettings
1290 dm_list_iterate_items(group, &cmd->arg_value_groups) {
1291 if (!grouped_arg_is_set(group->arg_values, vdosettings_ARG))
1292 continue;
1293
1294 if (!(current = dm_config_create()))
1295 goto_out;
1296 if (prev)
1297 current->cascade = prev;
1298 prev = current;
1299
1300 if (!(str = grouped_arg_str_value(group->arg_values,
1301 vdosettings_ARG,
1302 NULL)))
1303 goto_out;
1304
1305 if (!dm_config_parse_without_dup_node_check(current, str, str + strlen(str)))
1306 goto_out;
1307 }
1308
1309 if (current) {
1310 if (!(result = dm_config_flatten(current)))
1311 goto_out;
1312
1313 checked_lvchange = !strcmp(cmd->name, "lvchange");
1314
1315 /* Use all acceptable VDO options */
1316 for (cn = result->root; cn; cn = cn->sib) {
1317 is_lvchange = 0;
1318 DO_OFFLINE(ack_threads);
1319 DO_OFFLINE(bio_rotation);
1320 DO_OFFLINE(bio_threads);
1321 DO_OFFLINE(block_map_cache_size_mb);
1322 DO_OFFLINE(block_map_era_length);
1323 DO_OFFLINE(block_map_period); // alias for block_map_era_length
1324 DO_OFFLINE(cpu_threads);
1325 DO_OFFLINE(hash_zone_threads);
1326 DO_OFFLINE(logical_threads);
1327 DO_OFFLINE(max_discard);
1328 DO_OFFLINE(physical_threads);
1329
1330 // Support also these - even when we have regular opts for them
1331 DO_ONLINE(use_compression);
1332 DO_ONLINE(use_deduplication);
1333
39b7d1ba 1334 // Settings below cannot be changed with lvchange command
5e060b8f
ZK
1335 is_lvchange = checked_lvchange;
1336
5e060b8f
ZK
1337 DO_OFFLINE(index_memory_size_mb);
1338 DO_OFFLINE(minimum_io_size);
1339 DO_OFFLINE(slab_size_mb);
1340 DO_OFFLINE(use_metadata_hints);
1341 DO_OFFLINE(use_sparse_index);
1342
1343 option = "write_policy";
1344 if (_compare_vdo_option(cn->key, option)) {
1345 if (is_lvchange || !cn->v || (cn->v->type != DM_CFG_STRING))
1346 goto err;
1347 if (!set_vdo_write_policy(&vtp->write_policy, cn->v->v.str))
1348 goto_out;
1349 u |= VDO_CHANGE_OFFLINE;
1350 continue;
1351 }
1352
6ff65e67
ZK
1353 if (_compare_vdo_option(cn->key, "check_point_frequency")) {
1354 log_verbose("Ignoring deprecated --vdosettings option \"%s\" and its value.", cn->key);
1355 continue; /* Accept & ignore deprecated option */
1356 }
1357
5e060b8f
ZK
1358 log_error("Unknown VDO setting \"%s\".", cn->key);
1359 goto out;
1360 }
1361 }
1362
1363 if (arg_is_set(cmd, compression_ARG)) {
1364 vtp->use_compression = arg_int_value(cmd, compression_ARG, 0);
1365 if (vtp->use_compression != use_compression)
1366 u |= VDO_CHANGE_ONLINE;
1367 }
1368
1369 if (arg_is_set(cmd, deduplication_ARG)) {
1370 vtp->use_deduplication = arg_int_value(cmd, deduplication_ARG, 0);
1371 if (vtp->use_deduplication != use_deduplication)
1372 u |= VDO_CHANGE_ONLINE;
1373 }
1374
493acb91
ZK
1375 // validation of updated VDO option
1376 if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */))
1377 goto_out;
5e060b8f 1378
493acb91 1379 if (updated)
5e060b8f 1380 *updated = u;
5e060b8f 1381
493acb91
ZK
1382 r = 1; // success
1383 goto out;
1384err:
1385 if (is_lvchange)
1386 log_error("Cannot change VDO setting \"vdo_%s\" in existing VDO pool.",
1387 option);
1388 else
1389 log_error("Invalid argument for VDO setting \"vdo_%s\".",
1390 option);
1391
5e060b8f
ZK
1392out:
1393 if (result)
1394 dm_config_destroy(result);
1395
1396 while (prev) {
1397 current = prev->cascade;
1398 dm_config_destroy(prev);
1399 prev = current;
1400 }
1401
1402 return r;
1403}
1404
ffa07c8e
DT
1405static int _get_one_writecache_setting(struct cmd_context *cmd, struct writecache_settings *settings,
1406 char *key, char *val, uint32_t *block_size_sectors)
1ee42f13 1407{
ffa07c8e 1408 /* special case: block_size is not a setting but is set with the --cachesettings option */
e1fd179d 1409 if (!strncmp(key, "block_size", sizeof("block_size") - 1)) {
ffa07c8e
DT
1410 uint32_t block_size = 0;
1411 if (sscanf(val, "%u", &block_size) != 1)
1412 goto_bad;
1413 if (block_size == 512)
1414 *block_size_sectors = 1;
1415 else if (block_size == 4096)
1416 *block_size_sectors = 8;
1417 else
1418 goto_bad;
1419 return 1;
1420 }
1ee42f13 1421
e1fd179d 1422 if (!strncmp(key, "high_watermark", sizeof("high_watermark") - 1)) {
ffa07c8e
DT
1423 if (sscanf(val, "%llu", (unsigned long long *)&settings->high_watermark) != 1)
1424 goto_bad;
1425 if (settings->high_watermark > 100)
1426 goto_bad;
1427 settings->high_watermark_set = 1;
1428 return 1;
1429 }
a7b2fc8f 1430
e1fd179d 1431 if (!strncmp(key, "low_watermark", sizeof("low_watermark") - 1)) {
ffa07c8e
DT
1432 if (sscanf(val, "%llu", (unsigned long long *)&settings->low_watermark) != 1)
1433 goto_bad;
1434 if (settings->low_watermark > 100)
1435 goto_bad;
1436 settings->low_watermark_set = 1;
1437 return 1;
1438 }
a7b2fc8f 1439
e1fd179d 1440 if (!strncmp(key, "writeback_jobs", sizeof("writeback_jobs") - 1)) {
ffa07c8e
DT
1441 if (sscanf(val, "%llu", (unsigned long long *)&settings->writeback_jobs) != 1)
1442 goto_bad;
1443 settings->writeback_jobs_set = 1;
1444 return 1;
1445 }
1446
e1fd179d 1447 if (!strncmp(key, "autocommit_blocks", sizeof("autocommit_blocks") - 1)) {
ffa07c8e
DT
1448 if (sscanf(val, "%llu", (unsigned long long *)&settings->autocommit_blocks) != 1)
1449 goto_bad;
1450 settings->autocommit_blocks_set = 1;
1451 return 1;
1452 }
1453
e1fd179d 1454 if (!strncmp(key, "autocommit_time", sizeof("autocommit_time") - 1)) {
ffa07c8e
DT
1455 if (sscanf(val, "%llu", (unsigned long long *)&settings->autocommit_time) != 1)
1456 goto_bad;
1457 settings->autocommit_time_set = 1;
1458 return 1;
1459 }
1460
e1fd179d 1461 if (!strncmp(key, "fua", sizeof("fua") - 1)) {
ffa07c8e
DT
1462 if (settings->nofua_set) {
1463 log_error("Setting fua and nofua cannot both be set.");
1464 return 0;
1465 }
1466 if (sscanf(val, "%u", &settings->fua) != 1)
1467 goto_bad;
1468 settings->fua_set = 1;
1469 return 1;
1470 }
1471
e1fd179d 1472 if (!strncmp(key, "nofua", sizeof("nofua") - 1)) {
ffa07c8e
DT
1473 if (settings->fua_set) {
1474 log_error("Setting fua and nofua cannot both be set.");
1475 return 0;
c6639056 1476 }
ffa07c8e
DT
1477 if (sscanf(val, "%u", &settings->nofua) != 1)
1478 goto_bad;
1479 settings->nofua_set = 1;
1480 return 1;
1ee42f13
DT
1481 }
1482
e1fd179d 1483 if (!strncmp(key, "cleaner", sizeof("cleaner") - 1)) {
ffa07c8e
DT
1484 if (sscanf(val, "%u", &settings->cleaner) != 1)
1485 goto_bad;
1486 settings->cleaner_set = 1;
1487 return 1;
1488 }
1489
e1fd179d 1490 if (!strncmp(key, "max_age", sizeof("max_age") - 1)) {
ffa07c8e
DT
1491 if (sscanf(val, "%u", &settings->max_age) != 1)
1492 goto_bad;
1493 settings->max_age_set = 1;
1494 return 1;
1495 }
1496
e1fd179d 1497 if (!strncmp(key, "metadata_only", sizeof("metadata_only") - 1)) {
fa7fe5cb
DT
1498 if (sscanf(val, "%u", &settings->metadata_only) != 1)
1499 goto_bad;
1500 settings->metadata_only_set = 1;
1501 return 1;
1502 }
1503
e1fd179d 1504 if (!strncmp(key, "pause_writeback", sizeof("pause_writeback") - 1)) {
fa7fe5cb
DT
1505 if (sscanf(val, "%u", &settings->pause_writeback) != 1)
1506 goto_bad;
1507 settings->pause_writeback_set = 1;
1508 return 1;
1509 }
1510
ffa07c8e
DT
1511 if (settings->new_key) {
1512 log_error("Setting %s is not recognized. Only one unrecognized setting is allowed.", key);
1ee42f13
DT
1513 return 0;
1514 }
1515
81ef1fd0 1516 log_warn("WARNING: Unrecognized writecache setting \"%s\" may cause activation failure.", key);
ffa07c8e
DT
1517 if (yes_no_prompt("Use unrecognized writecache setting? [y/n]: ") == 'n') {
1518 log_error("Aborting writecache conversion.");
1519 return 0;
1520 }
1521
81ef1fd0 1522 log_warn("WARNING: Using unrecognized writecache setting: %s = %s.", key, val);
ffa07c8e
DT
1523
1524 settings->new_key = dm_pool_strdup(cmd->mem, key);
1525 settings->new_val = dm_pool_strdup(cmd->mem, val);
1ee42f13
DT
1526 return 1;
1527
ffa07c8e
DT
1528 bad:
1529 log_error("Invalid setting: %s", key);
1ee42f13
DT
1530 return 0;
1531}
1532
1533int get_writecache_settings(struct cmd_context *cmd, struct writecache_settings *settings,
1534 uint32_t *block_size_sectors)
1535{
f0cd54a8 1536 const struct dm_config_node *cns, *cn1, *cn2;
1ee42f13
DT
1537 struct arg_value_group_list *group;
1538 const char *str;
ffa07c8e
DT
1539 char key[64];
1540 char val[64];
1541 int num;
5ce236a6 1542 unsigned pos;
f0cd54a8
DT
1543 int rn;
1544 int found = 0;
1ee42f13
DT
1545
1546 /*
1547 * "grouped" means that multiple --cachesettings options can be used.
1548 * Each option is also allowed to contain multiple key = val pairs.
1549 */
1550
1551 dm_list_iterate_items(group, &cmd->arg_value_groups) {
1552 if (!grouped_arg_is_set(group->arg_values, cachesettings_ARG))
1553 continue;
1554
1555 if (!(str = grouped_arg_str_value(group->arg_values, cachesettings_ARG, NULL)))
1556 break;
1557
ffa07c8e 1558 pos = 0;
1ee42f13 1559
ffa07c8e
DT
1560 while (pos < strlen(str)) {
1561 /* scan for "key1=val1 key2 = val2 key3= val3" */
1ee42f13 1562
ffa07c8e
DT
1563 memset(key, 0, sizeof(key));
1564 memset(val, 0, sizeof(val));
1ee42f13 1565
ffa07c8e
DT
1566 if (sscanf(str + pos, " %63[^=]=%63s %n", key, val, &num) != 2) {
1567 log_error("Invalid setting at: %s", str+pos);
1568 return 0;
1569 }
1ee42f13 1570
ffa07c8e
DT
1571 pos += num;
1572
1573 if (!_get_one_writecache_setting(cmd, settings, key, val, block_size_sectors))
1574 return_0;
1ee42f13 1575 }
f0cd54a8 1576 found = 1;
1ee42f13
DT
1577 }
1578
f0cd54a8
DT
1579 if (found)
1580 goto out;
1581
1582 /*
1583 * If there were no settings on the command line, look for settings in
1584 * lvm.conf
1585 *
1586 * TODO: support profiles
1587 */
1588
1589 if (!(cns = find_config_tree_node(cmd, allocation_cache_settings_CFG_SECTION, NULL)))
1590 goto out;
1591
1592 for (cn1 = cns->child; cn1; cn1 = cn1->sib) {
1593 if (!cn1->child)
1594 continue; /* Ignore section without settings */
1595
1596 if (cn1->v || strcmp(cn1->key, "writecache") != 0)
1597 continue; /* Ignore non-matching settings */
1598
1599 cn2 = cn1->child;
1600
1601 for (; cn2; cn2 = cn2->sib) {
1602 memset(val, 0, sizeof(val));
1603
1604 if (cn2->v->type == DM_CFG_INT)
1605 rn = dm_snprintf(val, sizeof(val), FMTd64, cn2->v->v.i);
1606 else if (cn2->v->type == DM_CFG_STRING)
1607 rn = dm_snprintf(val, sizeof(val), "%s", cn2->v->v.str);
1608 else
1609 rn = -1;
1610 if (rn < 0) {
1611 log_error("Invalid lvm.conf writecache setting value for %s.", cn2->key);
1612 return 0;
1613 }
1614
1615 if (!_get_one_writecache_setting(cmd, settings, (char *)cn2->key, val, block_size_sectors))
1616 return_0;
1617 }
1618 }
1619
1620 out:
ffa07c8e
DT
1621 if (settings->high_watermark_set && settings->low_watermark_set &&
1622 (settings->high_watermark <= settings->low_watermark)) {
1623 log_error("High watermark must be greater than low watermark.");
1624 return 0;
1ee42f13
DT
1625 }
1626
ffa07c8e 1627 return 1;
1ee42f13 1628}
d9e8895a 1629
78d14a80
DT
1630static int _get_one_integrity_setting(struct cmd_context *cmd, struct integrity_settings *settings,
1631 char *key, char *val)
1632{
1633 /*
1634 * Some settings handled by other options:
1635 * settings->mode from --raidintegritymode
1636 * settings->block_size from --raidintegrityblocksize
1637 */
1638
1639 /* always set in metadata and on table line */
1640
1641 if (!strncmp(key, "journal_sectors", sizeof("journal_sectors") - 1)) {
1642 uint32_t size_mb;
1643
1644 if (sscanf(val, "%u", &settings->journal_sectors) != 1)
1645 goto_bad;
1646
1647 size_mb = settings->journal_sectors / 2048;
1648 if (size_mb < 4 || size_mb > 1024) {
1649 log_error("Invalid raid integrity journal size %d MiB (use 4-1024 MiB).", size_mb);
1650 goto_bad;
1651 }
1652 settings->journal_sectors_set = 1;
1653 return 1;
1654 }
1655
1656
1657 /* optional, not included in metadata or table line unless set */
1658
1659 if (!strncmp(key, "journal_watermark", sizeof("journal_watermark") - 1)) {
1660 if (sscanf(val, "%u", &settings->journal_watermark) != 1)
1661 goto_bad;
1662 if (settings->journal_watermark > 100)
1663 goto_bad;
1664 settings->journal_watermark_set = 1;
1665 return 1;
1666 }
1667
1668 if (!strncmp(key, "commit_time", sizeof("commit_time") - 1)) {
1669 if (sscanf(val, "%u", &settings->commit_time) != 1)
1670 goto_bad;
1671 settings->commit_time_set = 1;
1672 return 1;
1673 }
1674
1675 if (!strncmp(key, "bitmap_flush_interval", sizeof("bitmap_flush_interval") - 1)) {
1676 if (sscanf(val, "%u", &settings->bitmap_flush_interval) != 1)
1677 goto_bad;
1678 settings->bitmap_flush_interval_set = 1;
1679 return 1;
1680 }
1681
1682 if (!strncmp(key, "allow_discards", sizeof("allow_discards") - 1)) {
1683 if (sscanf(val, "%u", &settings->allow_discards) != 1)
1684 goto_bad;
1685 if (settings->allow_discards != 0 && settings->allow_discards != 1)
1686 goto_bad;
1687 settings->allow_discards_set = 1;
1688 return 1;
1689 }
1690
1691 return 1;
1692
1693 bad:
1694 log_error("Invalid setting: %s", key);
1695 return 0;
1696}
1697
1698int get_integrity_settings(struct cmd_context *cmd, struct integrity_settings *settings)
1699{
1700 struct arg_value_group_list *group;
1701 const char *str;
1702 char key[64];
1703 char val[64];
1704 int num;
1705 unsigned pos;
1706
1707 /*
1708 * "grouped" means that multiple --integritysettings options can be used.
1709 * Each option is also allowed to contain multiple key = val pairs.
1710 */
1711
1712 dm_list_iterate_items(group, &cmd->arg_value_groups) {
1713 if (!grouped_arg_is_set(group->arg_values, integritysettings_ARG))
1714 continue;
1715
1716 if (!(str = grouped_arg_str_value(group->arg_values, integritysettings_ARG, NULL)))
1717 break;
1718
1719 pos = 0;
1720
1721 while (pos < strlen(str)) {
1722 /* scan for "key1=val1 key2 = val2 key3= val3" */
1723
1724 memset(key, 0, sizeof(key));
1725 memset(val, 0, sizeof(val));
1726
1727 if (sscanf(str + pos, " %63[^=]=%63s %n", key, val, &num) != 2) {
1728 log_error("Invalid setting at: %s", str+pos);
1729 return 0;
1730 }
1731
1732 pos += num;
1733
1734 if (!_get_one_integrity_setting(cmd, settings, key, val))
1735 return_0;
1736 }
1737 }
1738
1739 return 1;
1740}
1741
b51cd542
AK
1742/* FIXME move to lib */
1743static int _pv_change_tag(struct physical_volume *pv, const char *tag, int addtag)
1744{
1745 if (addtag) {
1746 if (!str_list_add(pv->fmt->cmd->mem, &pv->tags, tag)) {
38200c20 1747 log_error("Failed to add tag %s to physical volume %s.",
b51cd542
AK
1748 tag, pv_dev_name(pv));
1749 return 0;
1750 }
462835fa
ZK
1751 } else
1752 str_list_del(&pv->tags, tag);
b51cd542
AK
1753
1754 return 1;
1755}
1756
1757/* Set exactly one of VG, LV or PV */
1758int change_tag(struct cmd_context *cmd, struct volume_group *vg,
1759 struct logical_volume *lv, struct physical_volume *pv, int arg)
1760{
1761 const char *tag;
1762 struct arg_value_group_list *current_group;
1763
1764 dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
1765 if (!grouped_arg_is_set(current_group->arg_values, arg))
1766 continue;
1767
1768 if (!(tag = grouped_arg_str_value(current_group->arg_values, arg, NULL))) {
38200c20 1769 log_error("Failed to get tag.");
b51cd542
AK
1770 return 0;
1771 }
1772
1773 if (vg && !vg_change_tag(vg, tag, arg == addtag_ARG))
1774 return_0;
1775 else if (lv && !lv_change_tag(lv, tag, arg == addtag_ARG))
1776 return_0;
1777 else if (pv && !_pv_change_tag(pv, tag, arg == addtag_ARG))
1778 return_0;
1779 }
1780
1781 return 1;
1782}
b18e1fd5 1783
9b6a62f9
DT
1784/*
1785 * FIXME: replace process_each_label() with process_each_vg() which is
1786 * based on performing vg_read(), which provides a correct representation
1787 * of VGs/PVs, that is not provided by lvmcache_label_scan().
1788 */
1789
51d96a17
PR
1790int process_each_label(struct cmd_context *cmd, int argc, char **argv,
1791 struct processing_handle *handle,
1ef2c3c4
PR
1792 process_single_label_fn_t process_single_label)
1793{
a77732c1 1794 log_report_t saved_log_report_state = log_get_report_state();
1ef2c3c4
PR
1795 struct label *label;
1796 struct dev_iter *iter;
1797 struct device *dev;
4343280e
DT
1798 struct lvmcache_info *info;
1799 struct dm_list process_duplicates;
1800 struct device_list *devl;
1ef2c3c4 1801 int ret_max = ECMD_PROCESSED;
a1eda8ea 1802 int ret;
1ef2c3c4
PR
1803 int opt = 0;
1804
4343280e
DT
1805 dm_list_init(&process_duplicates);
1806
a77732c1
PR
1807 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LABEL);
1808
92b4fcf5
DT
1809 if (!lvmcache_label_scan(cmd)) {
1810 ret_max = ECMD_FAILED;
1811 goto_out;
1812 }
4343280e 1813
1ef2c3c4
PR
1814 if (argc) {
1815 for (; opt < argc; opt++) {
56620b90
ZK
1816 if (sigint_caught()) {
1817 log_error("Interrupted.");
1818 ret_max = ECMD_FAILED;
1819 goto out;
1820 }
1821
00c30698 1822 if (!(dev = dev_cache_get_existing(cmd, argv[opt], cmd->filter))) {
1ef2c3c4 1823 log_error("Failed to find device "
38200c20 1824 "\"%s\".", argv[opt]);
1ef2c3c4
PR
1825 ret_max = ECMD_FAILED;
1826 continue;
1827 }
1828
4343280e 1829 if (!(label = lvmcache_get_dev_label(dev))) {
677833ce 1830 if (!lvmcache_dev_is_unused_duplicate(dev)) {
4343280e
DT
1831 log_error("No physical volume label read from %s.", argv[opt]);
1832 ret_max = ECMD_FAILED;
1833 } else {
d5da55ed 1834 if (!(devl = malloc(sizeof(*devl))))
4343280e
DT
1835 return_0;
1836 devl->dev = dev;
1837 dm_list_add(&process_duplicates, &devl->list);
1838 }
1839 continue;
1840 }
1841
a77732c1
PR
1842 log_set_report_object_name_and_id(dev_name(dev), NULL);
1843
4343280e
DT
1844 ret = process_single_label(cmd, label, handle);
1845 report_log_ret_code(ret);
1846
1847 if (ret > ret_max)
1848 ret_max = ret;
1849
1850 log_set_report_object_name_and_id(NULL, NULL);
4343280e
DT
1851 }
1852
1853 dm_list_iterate_items(devl, &process_duplicates) {
56620b90
ZK
1854 if (sigint_caught()) {
1855 log_error("Interrupted.");
1856 ret_max = ECMD_FAILED;
1857 goto out;
1858 }
1b908658 1859 /*
4343280e
DT
1860 * remove the existing dev for this pvid from lvmcache
1861 * so that the duplicate dev can replace it.
1862 */
1863 if ((info = lvmcache_info_from_pvid(devl->dev->pvid, NULL, 0)))
1864 lvmcache_del(info);
1865
1866 /*
1867 * add info to lvmcache from the duplicate dev.
1868 */
c3847354 1869 label_scan_dev(cmd, devl->dev);
4343280e
DT
1870
1871 /*
1872 * the info/label should now be found because
1873 * the label_read should have added it.
1874 */
1875 if (!(label = lvmcache_get_dev_label(devl->dev)))
1ef2c3c4 1876 continue;
4343280e 1877
bdf74794 1878 log_set_report_object_name_and_id(dev_name(devl->dev), NULL);
1ef2c3c4
PR
1879
1880 ret = process_single_label(cmd, label, handle);
a77732c1 1881 report_log_ret_code(ret);
1ef2c3c4
PR
1882
1883 if (ret > ret_max)
1884 ret_max = ret;
1885
a77732c1 1886 log_set_report_object_name_and_id(NULL, NULL);
1ef2c3c4
PR
1887 }
1888
a77732c1 1889 goto out;
1ef2c3c4
PR
1890 }
1891
f8aa073a 1892 if (!(iter = dev_iter_create(cmd->filter, 1))) {
38200c20 1893 log_error("dev_iter creation failed.");
a77732c1
PR
1894 ret_max = ECMD_FAILED;
1895 goto out;
1ef2c3c4
PR
1896 }
1897
56620b90
ZK
1898 while ((dev = dev_iter_get(cmd, iter))) {
1899 if (sigint_caught()) {
1900 log_error("Interrupted.");
1901 ret_max = ECMD_FAILED;
1902 break;
1903 }
1904
4343280e 1905 if (!(label = lvmcache_get_dev_label(dev)))
1ef2c3c4
PR
1906 continue;
1907
a77732c1
PR
1908 log_set_report_object_name_and_id(dev_name(label->dev), NULL);
1909
1ef2c3c4 1910 ret = process_single_label(cmd, label, handle);
a77732c1 1911 report_log_ret_code(ret);
1ef2c3c4
PR
1912
1913 if (ret > ret_max)
1914 ret_max = ret;
1915
a77732c1 1916 log_set_report_object_name_and_id(NULL, NULL);
1ef2c3c4
PR
1917 }
1918
1919 dev_iter_destroy(iter);
a77732c1
PR
1920out:
1921 log_restore_report_state(saved_log_report_state);
1ef2c3c4
PR
1922 return ret_max;
1923}
89e1190e 1924
c7484a13
ZK
1925/*
1926 * Parse persistent major minor parameters.
1927 *
1928 * --persistent is unspecified => state is deduced
1929 * from presence of options --minor or --major.
1930 *
1931 * -Mn => --minor or --major not allowed.
1932 *
1933 * -My => --minor is required (and also --major on <=2.4)
1934 */
89e1190e
ZK
1935int get_and_validate_major_minor(const struct cmd_context *cmd,
1936 const struct format_type *fmt,
1937 int32_t *major, int32_t *minor)
1938{
c7484a13
ZK
1939 if (arg_count(cmd, minor_ARG) > 1) {
1940 log_error("Option --minor may not be repeated.");
1941 return 0;
1942 }
1943
1944 if (arg_count(cmd, major_ARG) > 1) {
1945 log_error("Option -j|--major may not be repeated.");
1946 return 0;
1947 }
1948
1949 /* Check with default 'y' */
1950 if (!arg_int_value(cmd, persistent_ARG, 1)) { /* -Mn */
89e1190e 1951 if (arg_is_set(cmd, minor_ARG) || arg_is_set(cmd, major_ARG)) {
c7484a13 1952 log_error("Options --major and --minor are incompatible with -Mn.");
89e1190e
ZK
1953 return 0;
1954 }
1955 *major = *minor = -1;
1956 return 1;
1957 }
1958
c7484a13
ZK
1959 /* -1 cannot be entered as an argument for --major, --minor */
1960 *major = arg_int_value(cmd, major_ARG, -1);
1961 *minor = arg_int_value(cmd, minor_ARG, -1);
89e1190e 1962
c7484a13
ZK
1963 if (arg_is_set(cmd, persistent_ARG)) { /* -My */
1964 if (*minor == -1) {
1965 log_error("Please specify minor number with --minor when using -My.");
1966 return 0;
1967 }
89e1190e
ZK
1968 }
1969
1970 if (!strncmp(cmd->kernel_vsn, "2.4.", 4)) {
1971 /* Major is required for 2.4 */
c7484a13
ZK
1972 if (arg_is_set(cmd, persistent_ARG) && *major < 0) {
1973 log_error("Please specify major number with --major when using -My.");
89e1190e
ZK
1974 return 0;
1975 }
89e1190e 1976 } else {
c7484a13
ZK
1977 if (*major != -1) {
1978 log_warn("WARNING: Ignoring supplied major number %d - "
89e1190e
ZK
1979 "kernel assigns major numbers dynamically. "
1980 "Using major number %d instead.",
c7484a13 1981 *major, cmd->dev_types->device_mapper_major);
89e1190e 1982 }
c7484a13 1983 /* Stay with dynamic major:minor if minor is not specified. */
5ce236a6 1984 *major = (*minor == -1) ? -1 : (int)cmd->dev_types->device_mapper_major;
89e1190e
ZK
1985 }
1986
c7484a13 1987 if ((*minor != -1) && !validate_major_minor(cmd, fmt, *major, *minor))
89e1190e
ZK
1988 return_0;
1989
1990 return 1;
1991}
0d4baeba
ZK
1992
1993/*
1994 * Validate lvname parameter
1995 *
1996 * If it contains vgname, it is extracted from lvname.
1997 * If there is passed vgname, it is compared whether its the same name.
1998 */
1999int validate_lvname_param(struct cmd_context *cmd, const char **vg_name,
2000 const char **lv_name)
2001{
2002 const char *vgname;
2003 const char *lvname;
2004
2005 if (!lv_name || !*lv_name)
2006 return 1; /* NULL lvname is ok */
2007
2008 /* If contains VG name, extract it. */
2009 if (strchr(*lv_name, (int) '/')) {
2010 if (!(vgname = _extract_vgname(cmd, *lv_name, &lvname)))
2011 return_0;
2012
2013 if (!*vg_name)
2014 *vg_name = vgname;
2015 else if (strcmp(vgname, *vg_name)) {
2016 log_error("Please use a single volume group name "
38200c20 2017 "(\"%s\" or \"%s\").", vgname, *vg_name);
0d4baeba
ZK
2018 return 0;
2019 }
2020
2021 *lv_name = lvname;
2022 }
2023
4e9fbb4b
ZK
2024 if (!validate_name(*lv_name)) {
2025 log_error("Logical volume name \"%s\" is invalid.",
2026 *lv_name);
2027 return 0;
2028 }
2029
0d4baeba
ZK
2030 return 1;
2031}
bfb6a4ec 2032
b59335fb
ZK
2033/*
2034 * Validate lvname parameter
2035 * This name must follow restriction rules on prefixes and suffixes.
2036 *
2037 * If it contains vgname, it is extracted from lvname.
2038 * If there is passed vgname, it is compared whether its the same name.
2039 */
2040int validate_restricted_lvname_param(struct cmd_context *cmd, const char **vg_name,
2041 const char **lv_name)
2042{
2043 if (!validate_lvname_param(cmd, vg_name, lv_name))
2044 return_0;
2045
2046 if (lv_name && *lv_name && !apply_lvname_restrictions(*lv_name))
2047 return_0;
2048
1c212371 2049 return 1;
b59335fb
ZK
2050}
2051
bfb6a4ec
DT
2052/*
2053 * Extract list of VG names and list of tags from command line arguments.
2054 */
2055static int _get_arg_vgnames(struct cmd_context *cmd,
2056 int argc, char **argv,
ea74215f 2057 const char *one_vgname,
55683a65 2058 struct dm_list *use_vgnames,
bfb6a4ec
DT
2059 struct dm_list *arg_vgnames,
2060 struct dm_list *arg_tags)
2061{
2062 int opt = 0;
2063 int ret_max = ECMD_PROCESSED;
2064 const char *vg_name;
2065
ea74215f
DT
2066 if (one_vgname) {
2067 if (!str_list_add(cmd->mem, arg_vgnames,
2068 dm_pool_strdup(cmd->mem, one_vgname))) {
2069 log_error("strlist allocation failed.");
2070 return ECMD_FAILED;
2071 }
2072 return ret_max;
2073 }
2074
55683a65
DT
2075 if (use_vgnames && !dm_list_empty(use_vgnames)) {
2076 dm_list_splice(arg_vgnames, use_vgnames);
2077 return ret_max;
2078 }
2079
bfb6a4ec
DT
2080 for (; opt < argc; opt++) {
2081 vg_name = argv[opt];
f5d06efb 2082
bfb6a4ec
DT
2083 if (*vg_name == '@') {
2084 if (!validate_tag(vg_name + 1)) {
2085 log_error("Skipping invalid tag: %s", vg_name);
2086 if (ret_max < EINVALID_CMD_LINE)
2087 ret_max = EINVALID_CMD_LINE;
2088 continue;
2089 }
f5d06efb 2090
bfb6a4ec
DT
2091 if (!str_list_add(cmd->mem, arg_tags,
2092 dm_pool_strdup(cmd->mem, vg_name + 1))) {
38200c20 2093 log_error("strlist allocation failed.");
bfb6a4ec
DT
2094 return ECMD_FAILED;
2095 }
f5d06efb 2096
bfb6a4ec
DT
2097 continue;
2098 }
2099
2100 vg_name = skip_dev_dir(cmd, vg_name, NULL);
2101 if (strchr(vg_name, '/')) {
38200c20 2102 log_error("Invalid volume group name %s.", vg_name);
bfb6a4ec
DT
2103 if (ret_max < EINVALID_CMD_LINE)
2104 ret_max = EINVALID_CMD_LINE;
2105 continue;
2106 }
f5d06efb 2107
bfb6a4ec
DT
2108 if (!str_list_add(cmd->mem, arg_vgnames,
2109 dm_pool_strdup(cmd->mem, vg_name))) {
38200c20 2110 log_error("strlist allocation failed.");
bfb6a4ec
DT
2111 return ECMD_FAILED;
2112 }
2113 }
2114
2115 return ret_max;
2116}
2117
f752a953 2118struct processing_handle *init_processing_handle(struct cmd_context *cmd, struct processing_handle *parent_handle)
a91bc7a1
PR
2119{
2120 struct processing_handle *handle;
2121
2122 if (!(handle = dm_pool_zalloc(cmd->mem, sizeof(struct processing_handle)))) {
2123 log_error("_init_processing_handle: failed to allocate memory for processing handle");
2124 return NULL;
2125 }
2126
f752a953
PR
2127 handle->parent = parent_handle;
2128
a91bc7a1
PR
2129 /*
2130 * For any reporting tool, the internal_report_for_select is reset to 0
2131 * automatically because the internal reporting/selection is simply not
2132 * needed - the reporting/selection is already a part of the code path
2133 * used there.
2134 *
2135 * *The internal report for select is only needed for non-reporting tools!*
2136 */
2137 handle->internal_report_for_select = arg_is_set(cmd, select_ARG);
f7e0a4cc 2138 handle->include_historical_lvs = cmd->include_historical_lvs;
a91bc7a1 2139
1fde4bf4
PR
2140 if (!parent_handle && !cmd->cmd_report.report_group) {
2141 if (!report_format_init(cmd)) {
f752a953
PR
2142 dm_pool_free(cmd->mem, handle);
2143 return NULL;
2144 }
7d4a15e5 2145 } else
1fde4bf4 2146 cmd->cmd_report.saved_log_report_state = log_get_report_state();
c099f531 2147
6ca28ca4 2148 log_set_report_context(LOG_REPORT_CONTEXT_PROCESSING);
a91bc7a1
PR
2149 return handle;
2150}
2151
7f2eebf5 2152int init_selection_handle(struct cmd_context *cmd, struct processing_handle *handle,
9dfe5ce2 2153 unsigned initial_report_type)
a91bc7a1
PR
2154{
2155 struct selection_handle *sh;
b864a062 2156 const char *selection;
a91bc7a1
PR
2157
2158 if (!(sh = dm_pool_zalloc(cmd->mem, sizeof(struct selection_handle)))) {
2159 log_error("_init_selection_handle: failed to allocate memory for selection handle");
2160 return 0;
2161 }
2162
1b11f09d 2163 if (!report_get_single_selection(cmd, initial_report_type, &selection))
b864a062
PR
2164 return_0;
2165
7f2eebf5 2166 sh->report_type = initial_report_type;
b864a062 2167 if (!(sh->selection_rh = report_init_for_selection(cmd, &sh->report_type, selection))) {
a91bc7a1
PR
2168 dm_pool_free(cmd->mem, sh);
2169 return_0;
2170 }
2171
2172 handle->selection_handle = sh;
2173 return 1;
2174}
2175
969d2bf4 2176void destroy_processing_handle(struct cmd_context *cmd, struct processing_handle *handle)
a91bc7a1
PR
2177{
2178 if (handle) {
2179 if (handle->selection_handle && handle->selection_handle->selection_rh)
2180 dm_report_free(handle->selection_handle->selection_rh);
7d4a15e5 2181
1fde4bf4 2182 log_restore_report_state(cmd->cmd_report.saved_log_report_state);
7d4a15e5 2183
cd14d3fc
PR
2184 /*
2185 * Do not destroy current cmd->report_group and cmd->log_rh
2186 * (the log report) yet if we're running interactively
2187 * (== running in lvm shell) or if there's a parent handle
2188 * (== we're executing nested processing, like it is when
2189 * doing selection for parent's process_each_* processing).
2190 *
2191 * In both cases, there's still possible further processing
2192 * to do outside the processing covered by the handle we are
2193 * destroying here and for which we may still need to access
2194 * the log report to cover the rest of the processing.
2195 *
2196 */
2197 if (!cmd->is_interactive && !handle->parent) {
f21afdde
PR
2198 if (!dm_report_group_destroy(cmd->cmd_report.report_group))
2199 stack;
2200 cmd->cmd_report.report_group = NULL;
2201
2202 if (cmd->cmd_report.log_rh) {
2203 dm_report_free(cmd->cmd_report.log_rh);
2204 cmd->cmd_report.log_rh = NULL;
2205 }
89e2aef6 2206 }
0daf9d7a
OK
2207 /*
2208 * TODO: think about better alternatives:
2209 * handle mempool, dm_alloc for handle memory...
2210 */
2211 memset(handle, 0, sizeof(*handle));
a91bc7a1
PR
2212 }
2213}
2214
2215
c3180c4a 2216int select_match_vg(struct cmd_context *cmd, struct processing_handle *handle,
815f1ee2 2217 struct volume_group *vg)
455ef6f2 2218{
4fb224a5
PR
2219 int r;
2220
815f1ee2 2221 if (!handle->internal_report_for_select)
c3180c4a 2222 return 1;
c3180c4a 2223
815f1ee2 2224 handle->selection_handle->orig_report_type = VGS;
4fb224a5 2225 if (!(r = report_for_selection(cmd, handle, NULL, vg, NULL)))
bc1bb7f8 2226 log_error("Selection failed for VG %s.", vg->name);
815f1ee2 2227 handle->selection_handle->orig_report_type = 0;
984ae7f7 2228
4fb224a5 2229 return r;
455ef6f2
DT
2230}
2231
c3180c4a 2232int select_match_lv(struct cmd_context *cmd, struct processing_handle *handle,
815f1ee2 2233 struct volume_group *vg, struct logical_volume *lv)
455ef6f2 2234{
4fb224a5
PR
2235 int r;
2236
815f1ee2 2237 if (!handle->internal_report_for_select)
c3180c4a 2238 return 1;
c3180c4a 2239
815f1ee2 2240 handle->selection_handle->orig_report_type = LVS;
4fb224a5 2241 if (!(r = report_for_selection(cmd, handle, NULL, vg, lv)))
bc1bb7f8 2242 log_error("Selection failed for LV %s.", lv->name);
815f1ee2 2243 handle->selection_handle->orig_report_type = 0;
984ae7f7 2244
4fb224a5 2245 return r;
455ef6f2
DT
2246}
2247
c3180c4a 2248int select_match_pv(struct cmd_context *cmd, struct processing_handle *handle,
815f1ee2 2249 struct volume_group *vg, struct physical_volume *pv)
455ef6f2 2250{
4fb224a5
PR
2251 int r;
2252
815f1ee2 2253 if (!handle->internal_report_for_select)
c3180c4a 2254 return 1;
c3180c4a 2255
815f1ee2 2256 handle->selection_handle->orig_report_type = PVS;
4fb224a5 2257 if (!(r = report_for_selection(cmd, handle, pv, vg, NULL)))
bc1bb7f8 2258 log_error("Selection failed for PV %s.", dev_name(pv->dev));
815f1ee2 2259 handle->selection_handle->orig_report_type = 0;
984ae7f7 2260
4fb224a5 2261 return r;
455ef6f2
DT
2262}
2263
815f1ee2
PR
2264static int _select_matches(struct processing_handle *handle)
2265{
2266 if (!handle->internal_report_for_select)
2267 return 1;
2268
2269 return handle->selection_handle->selected;
2270}
2271
a4418b34 2272static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
bfb6a4ec
DT
2273 struct dm_list *vgnameids_to_process,
2274 struct dm_list *arg_vgnames,
51d96a17
PR
2275 struct dm_list *arg_tags,
2276 struct processing_handle *handle,
bfb6a4ec
DT
2277 process_single_vg_fn_t process_single_vg)
2278{
6ca28ca4 2279 log_report_t saved_log_report_state = log_get_report_state();
4ff2583d 2280 char uuid[64] __attribute__((aligned(8)));
bfb6a4ec 2281 struct volume_group *vg;
ba7ff96f 2282 struct volume_group *error_vg = NULL;
bfb6a4ec
DT
2283 struct vgnameid_list *vgnl;
2284 const char *vg_name;
2285 const char *vg_uuid;
3ec4813b 2286 uint32_t lockd_state = 0;
ba7ff96f 2287 uint32_t error_flags = 0;
de273247 2288 int whole_selected = 0;
bfb6a4ec 2289 int ret_max = ECMD_PROCESSED;
b622a7fe
DT
2290 int ret;
2291 int skip;
66248338 2292 int notfound;
bf60cb4d 2293 int is_lockd;
bfb6a4ec 2294 int process_all = 0;
0ab11877 2295 int do_report_ret_code = 1;
bfb6a4ec 2296
6ca28ca4
PR
2297 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
2298
bfb6a4ec
DT
2299 /*
2300 * If no VG names or tags were supplied, then process all VGs.
2301 */
2302 if (dm_list_empty(arg_vgnames) && dm_list_empty(arg_tags))
2303 process_all = 1;
2304
f5d06efb 2305 /*
ea74215f 2306 * FIXME If one_vgname, only proceed if exactly one VG matches tags or selection.
f5d06efb 2307 */
bfb6a4ec
DT
2308 dm_list_iterate_items(vgnl, vgnameids_to_process) {
2309 vg_name = vgnl->vg_name;
2310 vg_uuid = vgnl->vgid;
b622a7fe 2311 skip = 0;
66248338 2312 notfound = 0;
bf60cb4d 2313 is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid);
bfb6a4ec 2314
6ca28ca4 2315 uuid[0] = '\0';
cee1aedf
PR
2316 if (is_orphan_vg(vg_name)) {
2317 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_ORPHAN);
2318 log_set_report_object_name_and_id(vg_name + sizeof(VG_ORPHANS), uuid);
2319 } else {
2320 if (vg_uuid && !id_write_format((const struct id*)vg_uuid, uuid, sizeof(uuid)))
2321 stack;
2322 log_set_report_object_name_and_id(vg_name, uuid);
2323 }
6ca28ca4
PR
2324
2325 if (sigint_caught()) {
2326 ret_max = ECMD_FAILED;
2327 goto_out;
2328 }
2329
2330 log_very_verbose("Processing VG %s %s", vg_name, uuid);
bf60cb4d
DT
2331do_lockd:
2332 if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
f4abbafd 2333 stack;
b622a7fe 2334 ret_max = ECMD_FAILED;
0ab11877 2335 report_log_ret_code(ret_max);
b622a7fe
DT
2336 continue;
2337 }
fe70b03d 2338
ba7ff96f
DT
2339 vg = vg_read(cmd, vg_name, vg_uuid, read_flags, lockd_state, &error_flags, &error_vg);
2340 if (_ignore_vg(cmd, error_flags, error_vg, vg_name, arg_vgnames, read_flags, &skip, &notfound)) {
fe70b03d
DT
2341 stack;
2342 ret_max = ECMD_FAILED;
0ab11877 2343 report_log_ret_code(ret_max);
ba7ff96f
DT
2344 if (error_vg)
2345 unlock_and_release_vg(cmd, error_vg, vg_name);
fe70b03d 2346 goto endvg;
d8923457 2347 }
ba7ff96f
DT
2348 if (error_vg)
2349 unlock_and_release_vg(cmd, error_vg, vg_name);
2350
66248338 2351 if (skip || notfound)
fe70b03d 2352 goto endvg;
bfb6a4ec 2353
bf60cb4d
DT
2354 if (!is_lockd && vg_is_shared(vg)) {
2355 /* The lock_type changed since label_scan, won't really occur in practice. */
2356 log_debug("Repeat lock and read for local to shared vg");
2357 unlock_and_release_vg(cmd, vg, vg_name);
2358 is_lockd = 1;
2359 goto do_lockd;
2360 }
2361
b622a7fe 2362 /* Process this VG? */
455ef6f2 2363 if ((process_all ||
b622a7fe 2364 (!dm_list_empty(arg_vgnames) && str_list_match_item(arg_vgnames, vg_name)) ||
455ef6f2 2365 (!dm_list_empty(arg_tags) && str_list_match_list(arg_tags, &vg->tags, NULL))) &&
815f1ee2 2366 select_match_vg(cmd, handle, vg) && _select_matches(handle)) {
4ff2583d 2367
aee27dc7 2368 log_very_verbose("Running command for VG %s %s", vg_name, vg_uuid ? uuid : "");
4ff2583d 2369
b622a7fe 2370 ret = process_single_vg(cmd, vg_name, vg, handle);
de273247 2371 _update_selection_result(handle, &whole_selected);
b622a7fe
DT
2372 if (ret != ECMD_PROCESSED)
2373 stack;
0ab11877 2374 report_log_ret_code(ret);
b622a7fe
DT
2375 if (ret > ret_max)
2376 ret_max = ret;
2377 }
2378
ba7ff96f 2379 unlock_vg(cmd, vg, vg_name);
fe70b03d
DT
2380endvg:
2381 release_vg(vg);
bf60cb4d 2382 if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
ae4db9f3 2383 stack;
6ca28ca4
PR
2384
2385 log_set_report_object_name_and_id(NULL, NULL);
bfb6a4ec 2386 }
de273247
PR
2387 /* the VG is selected if at least one LV is selected */
2388 _set_final_selection_result(handle, whole_selected);
0ab11877 2389 do_report_ret_code = 0;
6ca28ca4 2390out:
0ab11877
PR
2391 if (do_report_ret_code)
2392 report_log_ret_code(ret_max);
6ca28ca4 2393 log_restore_report_state(saved_log_report_state);
bfb6a4ec
DT
2394 return ret_max;
2395}
2396
aa493267
DT
2397/*
2398 * Check if a command line VG name is ambiguous, i.e. there are multiple VGs on
2399 * the system that have the given name. If *one* VG with the given name is
2400 * local and the rest are foreign, then use the local VG (removing foreign VGs
2401 * with the same name from the vgnameids_on_system list). If multiple VGs with
2402 * the given name are local, we don't know which VG is intended, so remove the
2403 * ambiguous name from the list of args.
2404 */
2405static int _resolve_duplicate_vgnames(struct cmd_context *cmd,
2406 struct dm_list *arg_vgnames,
2407 struct dm_list *vgnameids_on_system)
2408{
2409 struct dm_str_list *sl, *sl2;
2410 struct vgnameid_list *vgnl, *vgnl2;
2411 char uuid[64] __attribute__((aligned(8)));
2412 int found;
2413 int ret = ECMD_PROCESSED;
2414
2415 dm_list_iterate_items_safe(sl, sl2, arg_vgnames) {
2416 found = 0;
2417 dm_list_iterate_items(vgnl, vgnameids_on_system) {
2418 if (strcmp(sl->str, vgnl->vg_name))
2419 continue;
2420 found++;
2421 }
2422
2423 if (found < 2)
2424 continue;
2425
2426 /*
2427 * More than one VG match the given name.
2428 * If only one is local, use that one.
2429 */
2430
2431 found = 0;
2432 dm_list_iterate_items_safe(vgnl, vgnl2, vgnameids_on_system) {
2433 if (strcmp(sl->str, vgnl->vg_name))
2434 continue;
2435
2436 /*
117160b2
DT
2437 * label scan has already populated lvmcache vginfo with
2438 * this information.
aa493267
DT
2439 */
2440 if (lvmcache_vg_is_foreign(cmd, vgnl->vg_name, vgnl->vgid)) {
48877e21
PR
2441 if (!id_write_format((const struct id*)vgnl->vgid, uuid, sizeof(uuid)))
2442 stack;
aa493267
DT
2443 dm_list_del(&vgnl->list);
2444 } else {
2445 found++;
2446 }
2447 }
2448
2449 if (found < 2)
2450 continue;
2451
2452 /*
2453 * More than one VG with this name is local so the intended VG
2454 * is unknown.
2455 */
2456 log_error("Multiple VGs found with the same name: skipping %s", sl->str);
3b4e7d16
PR
2457
2458 if (arg_is_valid_for_command(cmd, select_ARG))
2459 log_error("Use --select vg_uuid=<uuid> in place of the VG name.");
2460 else
2461 log_error("Use VG uuid in place of the VG name.");
2462
aa493267
DT
2463 dm_list_del(&sl->list);
2464 ret = ECMD_FAILED;
2465 }
2466
2467 return ret;
2468}
2469
4ff2583d
DT
2470/*
2471 * For each arg_vgname, move the corresponding entry from
2472 * vgnameids_on_system to vgnameids_to_process. If an
2473 * item in arg_vgnames doesn't exist in vgnameids_on_system,
2474 * then add a new entry for it to vgnameids_to_process.
2475 */
2476static void _choose_vgs_to_process(struct cmd_context *cmd,
2477 struct dm_list *arg_vgnames,
2478 struct dm_list *vgnameids_on_system,
2479 struct dm_list *vgnameids_to_process)
2480{
166adf0e 2481 char uuid[64] __attribute__((aligned(8)));
4ff2583d
DT
2482 struct dm_str_list *sl, *sl2;
2483 struct vgnameid_list *vgnl, *vgnl2;
166adf0e 2484 struct id id;
61573bd1 2485 int arg_is_uuid = 0;
4ff2583d
DT
2486 int found;
2487
2488 dm_list_iterate_items_safe(sl, sl2, arg_vgnames) {
2489 found = 0;
2490 dm_list_iterate_items_safe(vgnl, vgnl2, vgnameids_on_system) {
2491 if (strcmp(sl->str, vgnl->vg_name))
2492 continue;
2493
2494 dm_list_del(&vgnl->list);
2495 dm_list_add(vgnameids_to_process, &vgnl->list);
2496 found = 1;
2497 break;
2498 }
166adf0e
DT
2499
2500 /*
2501 * If the VG name arg looks like a UUID, then check if it
61573bd1
DT
2502 * matches the UUID of a VG. (--select should generally
2503 * be used to select a VG by uuid instead.)
166adf0e 2504 */
013c0807 2505 if (!found && (cmd->cname->flags & ALLOW_UUID_AS_NAME))
20483ead 2506 arg_is_uuid = id_read_format_try(&id, sl->str);
166adf0e
DT
2507
2508 if (!found && arg_is_uuid) {
2509 dm_list_iterate_items_safe(vgnl, vgnl2, vgnameids_on_system) {
2510 if (!(id_write_format((const struct id*)vgnl->vgid, uuid, sizeof(uuid))))
2511 continue;
2512
2513 if (strcmp(sl->str, uuid))
2514 continue;
2515
2516 log_print("Processing VG %s because of matching UUID %s",
2517 vgnl->vg_name, uuid);
2518
2519 dm_list_del(&vgnl->list);
2520 dm_list_add(vgnameids_to_process, &vgnl->list);
2521
2522 /* Make the arg_vgnames entry use the actual VG name. */
2523 sl->str = dm_pool_strdup(cmd->mem, vgnl->vg_name);
2524
2525 found = 1;
2526 break;
2527 }
2528 }
1b908658 2529
4ff2583d
DT
2530 /*
2531 * If the name arg was not found in the list of all VGs, then
2532 * it probably doesn't exist, but we want the "VG not found"
2533 * failure to be handled by the existing vg_read() code for
2534 * that error. So, create an entry with just the VG name so
2535 * that the processing loop will attempt to process it and use
2536 * the vg_read() error path.
2537 */
2538 if (!found) {
2539 log_verbose("VG name on command line not found in list of VGs: %s", sl->str);
2540
2541 if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl))))
2542 continue;
2543
2544 vgnl->vgid = NULL;
2545
2546 if (!(vgnl->vg_name = dm_pool_strdup(cmd->mem, sl->str)))
2547 continue;
2548
2549 dm_list_add(vgnameids_to_process, &vgnl->list);
2550 }
2551 }
2552}
2553
bfb6a4ec
DT
2554/*
2555 * Call process_single_vg() for each VG selected by the command line arguments.
55683a65 2556 * If one_vgname is set, process only that VG and ignore argc/argv (which should be 0/NULL).
ea74215f 2557 * If one_vgname is not set, get VG names to process from argc/argv.
bfb6a4ec 2558 */
55683a65
DT
2559int process_each_vg(struct cmd_context *cmd,
2560 int argc, char **argv,
2561 const char *one_vgname,
2562 struct dm_list *use_vgnames,
2563 uint32_t read_flags,
8cfc3854 2564 int include_internal,
ea74215f 2565 struct processing_handle *handle,
bfb6a4ec
DT
2566 process_single_vg_fn_t process_single_vg)
2567{
6ca28ca4 2568 log_report_t saved_log_report_state = log_get_report_state();
56011918 2569 int handle_supplied = handle != NULL;
bfb6a4ec
DT
2570 struct dm_list arg_tags; /* str_list */
2571 struct dm_list arg_vgnames; /* str_list */
2572 struct dm_list vgnameids_on_system; /* vgnameid_list */
2573 struct dm_list vgnameids_to_process; /* vgnameid_list */
013c0807 2574 int enable_all_vgs = (cmd->cname->flags & ALL_VGS_IS_DEFAULT);
4ff2583d
DT
2575 int process_all_vgs_on_system = 0;
2576 int ret_max = ECMD_PROCESSED;
bfb6a4ec
DT
2577 int ret;
2578
6ca28ca4 2579 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
71671778
DT
2580 log_debug("Processing each VG");
2581
fe70b03d
DT
2582 /* Disable error in vg_read so we can print it from ignore_vg. */
2583 cmd->vg_read_print_access_error = 0;
0a19238a 2584
bfb6a4ec
DT
2585 dm_list_init(&arg_tags);
2586 dm_list_init(&arg_vgnames);
2587 dm_list_init(&vgnameids_on_system);
2588 dm_list_init(&vgnameids_to_process);
2589
2590 /*
2591 * Find any VGs or tags explicitly provided on the command line.
2592 */
55683a65 2593 if ((ret = _get_arg_vgnames(cmd, argc, argv, one_vgname, use_vgnames, &arg_vgnames, &arg_tags)) != ECMD_PROCESSED) {
4ff2583d 2594 ret_max = ret;
56011918 2595 goto_out;
4ff2583d 2596 }
bfb6a4ec
DT
2597
2598 /*
4ff2583d
DT
2599 * Process all VGs on the system when:
2600 * . tags are specified and all VGs need to be read to
2601 * look for matching tags.
2602 * . no VG names are specified and the command defaults
2603 * to processing all VGs when none are specified.
bfb6a4ec 2604 */
4ff2583d
DT
2605 if ((dm_list_empty(&arg_vgnames) && enable_all_vgs) || !dm_list_empty(&arg_tags))
2606 process_all_vgs_on_system = 1;
fe70b03d 2607
4ff2583d
DT
2608 /*
2609 * Needed for a current listing of the global VG namespace.
2610 */
8c87dda1 2611 if (process_all_vgs_on_system && !lock_global(cmd, "sh")) {
4ff2583d
DT
2612 ret_max = ECMD_FAILED;
2613 goto_out;
2614 }
2615
796461a9 2616 /*
748f29b4
DT
2617 * Scan all devices to populate lvmcache with initial
2618 * list of PVs and VGs.
796461a9 2619 */
92b4fcf5
DT
2620 if (!(read_flags & PROCESS_SKIP_SCAN)) {
2621 if (!lvmcache_label_scan(cmd)) {
2622 ret_max = ECMD_FAILED;
2623 goto_out;
2624 }
2625 }
2626
796461a9 2627
4ff2583d
DT
2628 /*
2629 * A list of all VGs on the system is needed when:
2630 * . processing all VGs on the system
2631 * . A VG name is specified which may refer to one
2632 * of multiple VGs on the system with that name.
2633 */
6bf0f04a 2634 log_very_verbose("Obtaining the complete list of VGs to process");
4ff2583d 2635
4bb7d3da 2636 if (!lvmcache_get_vgnameids(cmd, &vgnameids_on_system, NULL, include_internal)) {
4ff2583d
DT
2637 ret_max = ECMD_FAILED;
2638 goto_out;
fe70b03d 2639 }
bfb6a4ec 2640
aa493267
DT
2641 if (!dm_list_empty(&arg_vgnames)) {
2642 /* This may remove entries from arg_vgnames or vgnameids_on_system. */
2643 ret = _resolve_duplicate_vgnames(cmd, &arg_vgnames, &vgnameids_on_system);
2644 if (ret > ret_max)
2645 ret_max = ret;
2646 if (dm_list_empty(&arg_vgnames) && dm_list_empty(&arg_tags)) {
2647 ret_max = ECMD_FAILED;
2648 goto out;
2649 }
2650 }
2651
bfb6a4ec 2652 if (dm_list_empty(&arg_vgnames) && dm_list_empty(&vgnameids_on_system)) {
91615603 2653 /* FIXME Should be log_print, but suppressed for reporting cmds */
fd32bb19 2654 log_verbose("No volume groups found.");
4ff2583d 2655 ret_max = ECMD_PROCESSED;
56011918 2656 goto out;
bfb6a4ec
DT
2657 }
2658
a4418b34
DT
2659 if (dm_list_empty(&arg_vgnames))
2660 read_flags |= READ_OK_NOTFOUND;
2661
bfb6a4ec 2662 /*
4ff2583d
DT
2663 * When processing all VGs, vgnameids_on_system simply becomes
2664 * vgnameids_to_process.
2665 * When processing only specified VGs, then for each item in
2666 * arg_vgnames, move the corresponding entry from
2667 * vgnameids_on_system to vgnameids_to_process.
bfb6a4ec 2668 */
4ff2583d 2669 if (process_all_vgs_on_system)
bfb6a4ec 2670 dm_list_splice(&vgnameids_to_process, &vgnameids_on_system);
4ff2583d
DT
2671 else
2672 _choose_vgs_to_process(cmd, &arg_vgnames, &vgnameids_on_system, &vgnameids_to_process);
56011918 2673
f752a953 2674 if (!handle && !(handle = init_processing_handle(cmd, NULL))) {
4ff2583d 2675 ret_max = ECMD_FAILED;
56011918 2676 goto_out;
4ff2583d 2677 }
56011918
PR
2678
2679 if (handle->internal_report_for_select && !handle->selection_handle &&
4ff2583d
DT
2680 !init_selection_handle(cmd, handle, VGS)) {
2681 ret_max = ECMD_FAILED;
56011918 2682 goto_out;
4ff2583d 2683 }
bfb6a4ec 2684
a4418b34 2685 ret = _process_vgnameid_list(cmd, read_flags, &vgnameids_to_process,
56011918 2686 &arg_vgnames, &arg_tags, handle, process_single_vg);
4ff2583d
DT
2687 if (ret > ret_max)
2688 ret_max = ret;
56011918
PR
2689out:
2690 if (!handle_supplied)
969d2bf4 2691 destroy_processing_handle(cmd, handle);
f5d06efb 2692
6ca28ca4 2693 log_restore_report_state(saved_log_report_state);
4ff2583d 2694 return ret_max;
bfb6a4ec 2695}
91615603 2696
2e7a1210
PR
2697static struct dm_str_list *_str_list_match_item_with_prefix(const struct dm_list *sll, const char *prefix, const char *str)
2698{
2699 struct dm_str_list *sl;
2700 size_t prefix_len = strlen(prefix);
2701
2702 dm_list_iterate_items(sl, sll) {
2703 if (!strncmp(prefix, sl->str, prefix_len) &&
2704 !strcmp(sl->str + prefix_len, str))
2705 return sl;
2706 }
2707
2708 return NULL;
2709}
2710
2711/*
2712 * Dummy LV, segment type and segment to represent all historical LVs.
2713 */
2714static struct logical_volume _historical_lv = {
2715 .name = "",
2716 .major = -1,
2717 .minor = -1,
2718 .snapshot_segs = DM_LIST_HEAD_INIT(_historical_lv.snapshot_segs),
2719 .segments = DM_LIST_HEAD_INIT(_historical_lv.segments),
2720 .tags = DM_LIST_HEAD_INIT(_historical_lv.tags),
2721 .segs_using_this_lv = DM_LIST_HEAD_INIT(_historical_lv.segs_using_this_lv),
2722 .indirect_glvs = DM_LIST_HEAD_INIT(_historical_lv.indirect_glvs),
2723 .hostname = "",
2724};
2725
2726static struct segment_type _historical_segment_type = {
2727 .name = "historical",
2728 .flags = SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED,
2729};
2730
2731static struct lv_segment _historical_lv_segment = {
2732 .lv = &_historical_lv,
2733 .segtype = &_historical_segment_type,
2734 .len = 0,
2735 .tags = DM_LIST_HEAD_INIT(_historical_lv_segment.tags),
2736 .origin_list = DM_LIST_HEAD_INIT(_historical_lv_segment.origin_list),
2737};
2738
1c396598 2739int opt_in_list_is_set(struct cmd_context *cmd, const uint16_t *opts, int count,
1e2420bc
DT
2740 int *match_count, int *unmatch_count)
2741{
2742 int match = 0;
2743 int unmatch = 0;
2744 int i;
2745
2746 for (i = 0; i < count; i++) {
2747 if (arg_is_set(cmd, opts[i]))
2748 match++;
2749 else
2750 unmatch++;
2751 }
2752
2753 if (match_count)
2754 *match_count = match;
2755 if (unmatch_count)
2756 *unmatch_count = unmatch;
2757
2758 return match ? 1 : 0;
2759}
1b908658 2760
1c396598 2761void opt_array_to_str(struct cmd_context *cmd, const uint16_t *opts, int count,
1e2420bc
DT
2762 char *buf, int len)
2763{
2764 int pos = 0;
2765 int ret;
2766 int i;
2767
2768 for (i = 0; i < count; i++) {
2769 ret = snprintf(buf + pos, len - pos, "%s ", arg_long_option_name(opts[i]));
2770 if (ret >= len - pos)
2771 break;
2772 pos += ret;
2773 }
2774
2775 buf[len - 1] = '\0';
2776}
2777
f1cc5b12 2778static void _lvp_bits_to_str(uint64_t bits, char *buf, int len)
1e2420bc 2779{
45d9b2c4 2780 const struct lv_prop *prop;
1e2420bc
DT
2781 int lvp_enum;
2782 int pos = 0;
2783 int ret;
2784
2785 for (lvp_enum = 0; lvp_enum < LVP_COUNT; lvp_enum++) {
2786 if (!(prop = get_lv_prop(lvp_enum)))
2787 continue;
2788
2789 if (lvp_bit_is_set(bits, lvp_enum)) {
2790 ret = snprintf(buf + pos, len - pos, "%s ", prop->name);
2791 if (ret >= len - pos)
2792 break;
2793 pos += ret;
2794 }
2795 }
2796 buf[len - 1] = '\0';
2797}
2798
f1cc5b12 2799static void _lvt_bits_to_str(uint64_t bits, char *buf, int len)
1e2420bc 2800{
45d9b2c4 2801 const struct lv_type *type;
1e2420bc
DT
2802 int lvt_enum;
2803 int pos = 0;
2804 int ret;
2805
2806 for (lvt_enum = 0; lvt_enum < LVT_COUNT; lvt_enum++) {
2807 if (!(type = get_lv_type(lvt_enum)))
2808 continue;
2809
2810 if (lvt_bit_is_set(bits, lvt_enum)) {
2811 ret = snprintf(buf + pos, len - pos, "%s ", type->name);
2812 if (ret >= len - pos)
2813 break;
2814 pos += ret;
2815 }
2816 }
2817 buf[len - 1] = '\0';
2818}
2819
2820/*
2821 * This is the lv_prop function pointer used for lv_is_foo() #defines.
2822 * Alternatively, lv_is_foo() could all be turned into functions.
2823 */
2824
2825static int _lv_is_prop(struct cmd_context *cmd, struct logical_volume *lv, int lvp_enum)
2826{
2827 switch (lvp_enum) {
2828 case is_locked_LVP:
2829 return lv_is_locked(lv);
2830 case is_partial_LVP:
2831 return lv_is_partial(lv);
2832 case is_virtual_LVP:
2833 return lv_is_virtual(lv);
2834 case is_merging_LVP:
2835 return lv_is_merging(lv);
2836 case is_merging_origin_LVP:
2837 return lv_is_merging_origin(lv);
2838 case is_converting_LVP:
2839 return lv_is_converting(lv);
2840 case is_external_origin_LVP:
2841 return lv_is_external_origin(lv);
2842 case is_virtual_origin_LVP:
2843 return lv_is_virtual_origin(lv);
2844 case is_not_synced_LVP:
2845 return lv_is_not_synced(lv);
2846 case is_pending_delete_LVP:
2847 return lv_is_pending_delete(lv);
2848 case is_error_when_full_LVP:
2849 return lv_is_error_when_full(lv);
2850 case is_pvmove_LVP:
2851 return lv_is_pvmove(lv);
2852 case is_removed_LVP:
2853 return lv_is_removed(lv);
2f3d8659
ZK
2854 case is_writable_LVP:
2855 return lv_is_writable(lv);
1e2420bc
DT
2856 case is_vg_writable_LVP:
2857 return (lv->vg->status & LVM_WRITE) ? 1 : 0;
2858 case is_thinpool_data_LVP:
2859 return lv_is_thin_pool_data(lv);
2860 case is_thinpool_metadata_LVP:
2861 return lv_is_thin_pool_metadata(lv);
2862 case is_cachepool_data_LVP:
2863 return lv_is_cache_pool_data(lv);
2864 case is_cachepool_metadata_LVP:
2865 return lv_is_cache_pool_metadata(lv);
2866 case is_mirror_image_LVP:
2867 return lv_is_mirror_image(lv);
2868 case is_mirror_log_LVP:
2869 return lv_is_mirror_log(lv);
2870 case is_raid_image_LVP:
2871 return lv_is_raid_image(lv);
2872 case is_raid_metadata_LVP:
2873 return lv_is_raid_metadata(lv);
2874 case is_origin_LVP: /* use lv_is_thick_origin */
2875 return lv_is_origin(lv);
2876 case is_thick_origin_LVP:
2877 return lv_is_thick_origin(lv);
2878 case is_thick_snapshot_LVP:
2879 return lv_is_thick_snapshot(lv);
2880 case is_thin_origin_LVP:
2881 return lv_is_thin_origin(lv, NULL);
2882 case is_thin_snapshot_LVP:
2883 return lv_is_thin_snapshot(lv);
2884 case is_cache_origin_LVP:
2885 return lv_is_cache_origin(lv);
2886 case is_merging_cow_LVP:
2887 return lv_is_merging_cow(lv);
44b07041
ZK
2888 case is_cow_LVP:
2889 return lv_is_cow(lv);
1e2420bc
DT
2890 case is_cow_covering_origin_LVP:
2891 return lv_is_cow_covering_origin(lv);
2892 case is_visible_LVP:
2893 return lv_is_visible(lv);
5175e87f
ZK
2894 case is_error_LVP:
2895 return lv_is_error(lv);
2896 case is_zero_LVP:
2897 return lv_is_zero(lv);
1e2420bc
DT
2898 case is_historical_LVP:
2899 return lv_is_historical(lv);
2900 case is_raid_with_tracking_LVP:
2901 return lv_is_raid_with_tracking(lv);
d9e8895a
DT
2902 case is_raid_with_integrity_LVP:
2903 return lv_raid_has_integrity(lv);
1e2420bc
DT
2904 default:
2905 log_error(INTERNAL_ERROR "unknown lv property value lvp_enum %d", lvp_enum);
2906 }
2907
2908 return 0;
2909}
2910
2911/*
2912 * Check if an LV matches a given LV type enum.
2913 */
2914
2915static int _lv_is_type(struct cmd_context *cmd, struct logical_volume *lv, int lvt_enum)
2916{
2917 struct lv_segment *seg = first_seg(lv);
2918
2919 switch (lvt_enum) {
2920 case striped_LVT:
2921 return seg_is_striped(seg) && !lv_is_cow(lv);
2922 case linear_LVT:
2923 return seg_is_linear(seg) && !lv_is_cow(lv);
2924 case snapshot_LVT:
2925 return lv_is_cow(lv);
2926 case thin_LVT:
2927 return lv_is_thin_volume(lv);
2928 case thinpool_LVT:
2929 return lv_is_thin_pool(lv);
2930 case cache_LVT:
2931 return lv_is_cache(lv);
2932 case cachepool_LVT:
2933 return lv_is_cache_pool(lv);
a821b88a
ZK
2934 case vdo_LVT:
2935 return lv_is_vdo(lv);
2936 case vdopool_LVT:
2937 return lv_is_vdo_pool(lv);
2938 case vdopooldata_LVT:
2939 return lv_is_vdo_pool_data(lv);
1e2420bc
DT
2940 case mirror_LVT:
2941 return lv_is_mirror(lv);
2942 case raid_LVT:
2943 return lv_is_raid(lv);
2944 case raid0_LVT:
2224b6a7 2945 return seg_is_any_raid0(seg);
1e2420bc
DT
2946 case raid1_LVT:
2947 return seg_is_raid1(seg);
2948 case raid4_LVT:
2949 return seg_is_raid4(seg);
1e2420bc 2950 case raid5_LVT:
2224b6a7 2951 return seg_is_any_raid5(seg);
1e2420bc 2952 case raid6_LVT:
2224b6a7 2953 return seg_is_any_raid6(seg);
1e2420bc
DT
2954 case raid10_LVT:
2955 return seg_is_raid10(seg);
3ae55695
DT
2956 case writecache_LVT:
2957 return seg_is_writecache(seg);
d9e8895a
DT
2958 case integrity_LVT:
2959 return seg_is_integrity(seg);
1e2420bc 2960 case error_LVT:
5175e87f 2961 return seg_is_error(seg);
1e2420bc 2962 case zero_LVT:
5175e87f 2963 return seg_is_zero(seg);
1e2420bc
DT
2964 default:
2965 log_error(INTERNAL_ERROR "unknown lv type value lvt_enum %d", lvt_enum);
2966 }
2967
2968 return 0;
2969}
2970
0e3e611a 2971int get_lvt_enum(struct logical_volume *lv)
1e2420bc
DT
2972{
2973 struct lv_segment *seg = first_seg(lv);
2974
2975 /*
2976 * The order these are checked is important, because a snapshot LV has
2977 * a linear seg type.
2978 */
2979
2980 if (lv_is_cow(lv))
2981 return snapshot_LVT;
2982 if (seg_is_linear(seg))
2983 return linear_LVT;
2984 if (seg_is_striped(seg))
2985 return striped_LVT;
2986 if (lv_is_thin_volume(lv))
2987 return thin_LVT;
2988 if (lv_is_thin_pool(lv))
2989 return thinpool_LVT;
2990 if (lv_is_cache(lv))
2991 return cache_LVT;
2992 if (lv_is_cache_pool(lv))
2993 return cachepool_LVT;
a821b88a
ZK
2994 if (lv_is_vdo(lv))
2995 return vdo_LVT;
2996 if (lv_is_vdo_pool(lv))
2997 return vdopool_LVT;
2998 if (lv_is_vdo_pool_data(lv))
2999 return vdopooldata_LVT;
1e2420bc
DT
3000 if (lv_is_mirror(lv))
3001 return mirror_LVT;
3002 if (lv_is_raid(lv))
3003 return raid_LVT;
2224b6a7 3004 if (seg_is_any_raid0(seg))
1e2420bc
DT
3005 return raid0_LVT;
3006 if (seg_is_raid1(seg))
3007 return raid1_LVT;
3008 if (seg_is_raid4(seg))
3009 return raid4_LVT;
2224b6a7 3010 if (seg_is_any_raid5(seg))
1e2420bc 3011 return raid5_LVT;
2224b6a7 3012 if (seg_is_any_raid6(seg))
1e2420bc 3013 return raid6_LVT;
1e2420bc
DT
3014 if (seg_is_raid10(seg))
3015 return raid10_LVT;
3ae55695
DT
3016 if (seg_is_writecache(seg))
3017 return writecache_LVT;
d9e8895a
DT
3018 if (seg_is_integrity(seg))
3019 return integrity_LVT;
1e2420bc 3020
5175e87f 3021 if (seg_is_error(seg))
1e2420bc 3022 return error_LVT;
5175e87f 3023 if (seg_is_zero(seg))
1e2420bc
DT
3024 return zero_LVT;
3025
3026 return 0;
3027}
3028
3029/*
3030 * Call lv_is_<type> for each <type>_LVT bit set in lvt_bits.
3031 * If lv matches one of the specified lv types, then return 1.
3032 */
3033
3034static int _lv_types_match(struct cmd_context *cmd, struct logical_volume *lv, uint64_t lvt_bits,
3035 uint64_t *match_bits, uint64_t *unmatch_bits)
3036{
45d9b2c4 3037 const struct lv_type *type;
1e2420bc
DT
3038 int lvt_enum;
3039 int found_a_match = 0;
3040 int match;
3041
3042 if (match_bits)
3043 *match_bits = 0;
3044 if (unmatch_bits)
3045 *unmatch_bits = 0;
3046
3047 for (lvt_enum = 1; lvt_enum < LVT_COUNT; lvt_enum++) {
3048 if (!lvt_bit_is_set(lvt_bits, lvt_enum))
3049 continue;
3050
3051 if (!(type = get_lv_type(lvt_enum)))
3052 continue;
3053
3054 /*
3055 * All types are currently handled by _lv_is_type()
3056 * because lv_is_type() are #defines and not exposed
3057 * in tools.h
3058 */
3059
5b7e30da 3060 match = _lv_is_type(cmd, lv, lvt_enum);
1e2420bc
DT
3061
3062 if (match)
3063 found_a_match = 1;
3064
3065 if (match_bits && match)
3066 *match_bits |= lvt_enum_to_bit(lvt_enum);
3067
3068 if (unmatch_bits && !match)
3069 *unmatch_bits |= lvt_enum_to_bit(lvt_enum);
3070 }
3071
3072 return found_a_match;
3073}
3074
3075/*
3076 * Call lv_is_<prop> for each <prop>_LVP bit set in lvp_bits.
3077 * If lv matches all of the specified lv properties, then return 1.
3078 */
3079
3080static int _lv_props_match(struct cmd_context *cmd, struct logical_volume *lv, uint64_t lvp_bits,
3081 uint64_t *match_bits, uint64_t *unmatch_bits)
3082{
45d9b2c4 3083 const struct lv_prop *prop;
1e2420bc
DT
3084 int lvp_enum;
3085 int found_a_mismatch = 0;
3086 int match;
3087
3088 if (match_bits)
3089 *match_bits = 0;
3090 if (unmatch_bits)
3091 *unmatch_bits = 0;
3092
3093 for (lvp_enum = 1; lvp_enum < LVP_COUNT; lvp_enum++) {
3094 if (!lvp_bit_is_set(lvp_bits, lvp_enum))
3095 continue;
3096
3097 if (!(prop = get_lv_prop(lvp_enum)))
3098 continue;
3099
429ab45a 3100 match = _lv_is_prop(cmd, lv, lvp_enum);
1e2420bc
DT
3101
3102 if (!match)
3103 found_a_mismatch = 1;
3104
3105 if (match_bits && match)
3106 *match_bits |= lvp_enum_to_bit(lvp_enum);
3107
3108 if (unmatch_bits && !match)
3109 *unmatch_bits |= lvp_enum_to_bit(lvp_enum);
3110 }
3111
3112 return !found_a_mismatch;
3113}
3114
3115static int _check_lv_types(struct cmd_context *cmd, struct logical_volume *lv, int pos)
3116{
0349b6d8 3117 int ret;
1e2420bc
DT
3118
3119 if (!pos)
3120 return 1;
3121
3122 if (!cmd->command->required_pos_args[pos-1].def.lvt_bits)
3123 return 1;
3124
3125 if (!val_bit_is_set(cmd->command->required_pos_args[pos-1].def.val_bits, lv_VAL)) {
c3faa581 3126 log_error(INTERNAL_ERROR "Command %d:%s arg position %d does not permit an LV (%llx)",
bebbb1e6 3127 cmd->command->command_index, command_enum(cmd->command->command_enum),
1e2420bc
DT
3128 pos, (unsigned long long)cmd->command->required_pos_args[pos-1].def.val_bits);
3129 return 0;
3130 }
3131
3132 ret = _lv_types_match(cmd, lv, cmd->command->required_pos_args[pos-1].def.lvt_bits, NULL, NULL);
3133 if (!ret) {
0e3e611a 3134 int lvt_enum = get_lvt_enum(lv);
45d9b2c4 3135 const struct lv_type *type = get_lv_type(lvt_enum);
3ae55695 3136 if (!type) {
81ef1fd0 3137 log_warn("WARNING: Command on LV %s does not accept LV type unknown (%d).",
3ae55695
DT
3138 display_lvname(lv), lvt_enum);
3139 } else {
81ef1fd0 3140 log_warn("WARNING: Command on LV %s does not accept LV type %s.",
3ae55695
DT
3141 display_lvname(lv), type->name);
3142 }
1e2420bc
DT
3143 }
3144
3145 return ret;
3146}
3147
3148/* Check if LV passes each rule specified in command definition. */
3149
3150static int _check_lv_rules(struct cmd_context *cmd, struct logical_volume *lv)
3151{
3152 char buf[64];
45d9b2c4
ZK
3153 const struct cmd_rule *rule;
3154 const struct lv_type *lvtype = NULL;
0c9e3e8d
ZK
3155 uint64_t lv_props_match_bits = 0, lv_props_unmatch_bits = 0;
3156 uint64_t lv_types_match_bits = 0, lv_types_unmatch_bits = 0;
3157 int opts_match_count = 0, opts_unmatch_count = 0;
1e2420bc
DT
3158 int lvt_enum;
3159 int ret = 1;
3160 int i;
3161
0e3e611a 3162 lvt_enum = get_lvt_enum(lv);
1e2420bc
DT
3163 if (lvt_enum)
3164 lvtype = get_lv_type(lvt_enum);
3165
3166 for (i = 0; i < cmd->command->rule_count; i++) {
3167 rule = &cmd->command->rules[i];
3168
3169 /*
3170 * RULE: <conditions> INVALID|REQUIRE <checks>
3171 *
3172 * If all the conditions apply to the command+LV, then
3173 * the checks are performed. If all conditions are zero
3174 * (!opts_count, !lvt_bits, !lvp_bits), then the check
3175 * is always performed.
3176 *
3177 * Conditions:
3178 *
3179 * 1. options (opts): if any of the specified options are set,
3180 * then the checks may apply.
3181 *
3182 * 2. LV types (lvt_bits): if any of the specified LV types
3183 * match the LV, then the checks may apply.
3184 *
3185 * 3. LV properties (lvp_bits): if all of the specified
3186 * LV properties match the LV, then the checks may apply.
3187 *
3188 * If conditions 1, 2, 3 all pass, then the checks apply.
3189 *
3190 * Checks:
3191 *
3192 * 1. options (check_opts):
3193 * INVALID: if any of the specified options are set,
3194 * then the command fails.
3195 * REQUIRE: if any of the specified options are not set,
3196 * then the command fails.
3197 *
3198 * 2. LV types (check_lvt_bits):
3199 * INVALID: if any of the specified LV types match the LV,
3200 * then the command fails.
3201 * REQUIRE: if none of the specified LV types match the LV,
3202 * then the command fails.
3203 *
3204 * 3. LV properties (check_lvp_bits):
3205 * INVALID: if any of the specified LV properties match
3206 * the LV, then the command fails.
3207 * REQUIRE: if any of the specified LV properties do not match
3208 * the LV, then the command fails.
3209 */
3210
3211 if (rule->opts_count && !opt_in_list_is_set(cmd, rule->opts, rule->opts_count, NULL, NULL))
3212 continue;
3213
3214 /* If LV matches one type in lvt_bits, this returns 1. */
3215 if (rule->lvt_bits && !_lv_types_match(cmd, lv, rule->lvt_bits, NULL, NULL))
3216 continue;
3217
3218 /* If LV matches all properties in lvp_bits, this returns 1. */
3219 if (rule->lvp_bits && !_lv_props_match(cmd, lv, rule->lvp_bits, NULL, NULL))
3220 continue;
3221
3222 /*
3223 * Check the options, LV types, LV properties.
3224 */
3225
1c396598 3226 if (rule->check_opts_count)
1e2420bc
DT
3227 opt_in_list_is_set(cmd, rule->check_opts, rule->check_opts_count,
3228 &opts_match_count, &opts_unmatch_count);
3229
3230 if (rule->check_lvt_bits)
3231 _lv_types_match(cmd, lv, rule->check_lvt_bits,
3232 &lv_types_match_bits, &lv_types_unmatch_bits);
3233
3234 if (rule->check_lvp_bits)
3235 _lv_props_match(cmd, lv, rule->check_lvp_bits,
3236 &lv_props_match_bits, &lv_props_unmatch_bits);
1b908658 3237
1e2420bc
DT
3238 /*
3239 * Evaluate if the check results pass based on the rule.
3240 * The options are checked again here because the previous
3241 * option validation (during command matching) does not cover
3242 * cases where the option is combined with conditions of LV types
3243 * or properties.
3244 */
3245
3246 /* Fail if any invalid options are set. */
3247
1c396598 3248 if (rule->check_opts_count && (rule->rule == RULE_INVALID) && opts_match_count) {
1e2420bc
DT
3249 memset(buf, 0, sizeof(buf));
3250 opt_array_to_str(cmd, rule->check_opts, rule->check_opts_count, buf, sizeof(buf));
81ef1fd0 3251 log_warn("WARNING: Command on LV %s has invalid use of option %s.",
a3fdc966 3252 display_lvname(lv), buf);
1e2420bc
DT
3253 ret = 0;
3254 }
3255
3256 /* Fail if any required options are not set. */
3257
1c396598 3258 if (rule->check_opts_count && (rule->rule == RULE_REQUIRE) && opts_unmatch_count) {
1e2420bc
DT
3259 memset(buf, 0, sizeof(buf));
3260 opt_array_to_str(cmd, rule->check_opts, rule->check_opts_count, buf, sizeof(buf));
81ef1fd0 3261 log_warn("WARNING: Command on LV %s requires option %s.",
a3fdc966 3262 display_lvname(lv), buf);
1e2420bc
DT
3263 ret = 0;
3264 }
3265
3266 /* Fail if the LV matches any of the invalid LV types. */
3267
3268 if (rule->check_lvt_bits && (rule->rule == RULE_INVALID) && lv_types_match_bits) {
0ab9e4b6 3269 if (rule->opts_count)
81ef1fd0 3270 log_warn("WARNING: Command on LV %s uses options invalid with LV type %s.",
0ab9e4b6
DT
3271 display_lvname(lv), lvtype ? lvtype->name : "unknown");
3272 else
81ef1fd0 3273 log_warn("WARNING: Command on LV %s with invalid LV type %s.",
0ab9e4b6 3274 display_lvname(lv), lvtype ? lvtype->name : "unknown");
1e2420bc
DT
3275 ret = 0;
3276 }
3277
3278 /* Fail if the LV does not match any of the required LV types. */
3279
3280 if (rule->check_lvt_bits && (rule->rule == RULE_REQUIRE) && !lv_types_match_bits) {
3281 memset(buf, 0, sizeof(buf));
f1cc5b12 3282 _lvt_bits_to_str(rule->check_lvt_bits, buf, sizeof(buf));
0ab9e4b6 3283 if (rule->opts_count)
81ef1fd0 3284 log_warn("WARNING: Command on LV %s uses options that require LV types %s.",
0ab9e4b6
DT
3285 display_lvname(lv), buf);
3286 else
81ef1fd0 3287 log_warn("WARNING: Command on LV %s does not accept LV type %s. Required LV types are %s.",
0ab9e4b6 3288 display_lvname(lv), lvtype ? lvtype->name : "unknown", buf);
1e2420bc
DT
3289 ret = 0;
3290 }
3291
3292 /* Fail if the LV matches any of the invalid LV properties. */
3293
3294 if (rule->check_lvp_bits && (rule->rule == RULE_INVALID) && lv_props_match_bits) {
3295 memset(buf, 0, sizeof(buf));
f1cc5b12 3296 _lvp_bits_to_str(lv_props_match_bits, buf, sizeof(buf));
0ab9e4b6 3297 if (rule->opts_count)
81ef1fd0 3298 log_warn("WARNING: Command on LV %s uses options that are invalid with LV properties: %s.",
0ab9e4b6
DT
3299 display_lvname(lv), buf);
3300 else
81ef1fd0 3301 log_warn("WARNING: Command on LV %s is invalid on LV with properties: %s.",
0ab9e4b6 3302 display_lvname(lv), buf);
1e2420bc
DT
3303 ret = 0;
3304 }
3305
3306 /* Fail if the LV does not match any of the required LV properties. */
3307
3308 if (rule->check_lvp_bits && (rule->rule == RULE_REQUIRE) && lv_props_unmatch_bits) {
3309 memset(buf, 0, sizeof(buf));
f1cc5b12 3310 _lvp_bits_to_str(lv_props_unmatch_bits, buf, sizeof(buf));
0ab9e4b6 3311 if (rule->opts_count)
81ef1fd0 3312 log_warn("WARNING: Command on LV %s uses options that require LV properties: %s.",
0ab9e4b6
DT
3313 display_lvname(lv), buf);
3314 else
81ef1fd0 3315 log_warn("WARNING: Command on LV %s requires LV with properties: %s.",
0ab9e4b6 3316 display_lvname(lv), buf);
1e2420bc
DT
3317 ret = 0;
3318 }
3319 }
3320
3321 return ret;
3322}
3323
3324/*
3325 * Return which arg position the given LV is at,
3326 * where 1 represents the first position arg.
3327 * When the first position arg is repeatable,
3328 * return 1 for all.
3329 *
3330 * Return 0 when the command has no required
3331 * position args. (optional position args are
3332 * not considered.)
3333 */
3334
3335static int _find_lv_arg_position(struct cmd_context *cmd, struct logical_volume *lv)
3336{
3337 const char *sep, *lvname;
3338 int i;
3339
3340 if (cmd->command->rp_count == 0)
3341 return 0;
3342
3343 if (cmd->command->rp_count == 1)
3344 return 1;
3345
3346 for (i = 0; i < cmd->position_argc; i++) {
3347 if (i == cmd->command->rp_count)
3348 break;
3349
3350 if (!val_bit_is_set(cmd->command->required_pos_args[i].def.val_bits, lv_VAL))
3351 continue;
3352
3353 if ((sep = strstr(cmd->position_argv[i], "/")))
3354 lvname = sep + 1;
3355 else
3356 lvname = cmd->position_argv[i];
3357
3358 if (!strcmp(lvname, lv->name))
3359 return i + 1;
3360 }
3361
3362 /*
3363 * If the last position arg is an LV and this
3364 * arg is beyond that position, then the last
3365 * LV position arg is repeatable, so return
3366 * that position.
3367 */
3368 if (i == cmd->command->rp_count) {
3369 int last_pos = cmd->command->rp_count;
3370 if (val_bit_is_set(cmd->command->required_pos_args[last_pos-1].def.val_bits, lv_VAL))
3371 return last_pos;
3372 }
3373
3374 return 0;
3375}
3376
91615603
DT
3377int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
3378 struct dm_list *arg_lvnames, const struct dm_list *tags_in,
f3bb1c01 3379 int stop_on_error,
51d96a17 3380 struct processing_handle *handle,
9c6c55c3 3381 check_single_lv_fn_t check_single_lv,
51d96a17 3382 process_single_lv_fn_t process_single_lv)
91615603 3383{
6ca28ca4
PR
3384 log_report_t saved_log_report_state = log_get_report_state();
3385 char lv_uuid[64] __attribute__((aligned(8)));
3386 char vg_uuid[64] __attribute__((aligned(8)));
91615603
DT
3387 int ret_max = ECMD_PROCESSED;
3388 int ret = 0;
de273247 3389 int whole_selected = 0;
56011918 3390 int handle_supplied = handle != NULL;
455ef6f2 3391 unsigned process_lv;
91615603
DT
3392 unsigned process_all = 0;
3393 unsigned tags_supplied = 0;
3394 unsigned lvargs_supplied = 0;
1e2420bc
DT
3395 int lv_is_named_arg;
3396 int lv_arg_pos;
91615603
DT
3397 struct lv_list *lvl;
3398 struct dm_str_list *sl;
c9f021de
PR
3399 struct dm_list final_lvs;
3400 struct lv_list *final_lvl;
1e2420bc 3401 struct dm_list found_arg_lvnames;
2e7a1210 3402 struct glv_list *glvl, *tglvl;
0ab11877 3403 int do_report_ret_code = 1;
c9f021de 3404
ed1651d1
ZK
3405 cmd->online_vg_file_removed = 0;
3406
6ca28ca4
PR
3407 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LV);
3408
3409 vg_uuid[0] = '\0';
3410 if (!id_write_format(&vg->id, vg_uuid, sizeof(vg_uuid)))
3411 stack;
3412
c9f021de 3413 dm_list_init(&final_lvs);
1e2420bc 3414 dm_list_init(&found_arg_lvnames);
91615603 3415
91615603
DT
3416 if (tags_in && !dm_list_empty(tags_in))
3417 tags_supplied = 1;
3418
3419 if (arg_lvnames && !dm_list_empty(arg_lvnames))
3420 lvargs_supplied = 1;
3421
f752a953 3422 if (!handle && !(handle = init_processing_handle(cmd, NULL))) {
56011918
PR
3423 ret_max = ECMD_FAILED;
3424 goto_out;
3425 }
3426
3427 if (handle->internal_report_for_select && !handle->selection_handle &&
7f2eebf5 3428 !init_selection_handle(cmd, handle, LVS)) {
56011918
PR
3429 ret_max = ECMD_FAILED;
3430 goto_out;
3431 }
3432
1b908658 3433 /* Process all LVs in this VG if no restrictions given
91615603
DT
3434 * or if VG tags match. */
3435 if ((!tags_supplied && !lvargs_supplied) ||
3436 (tags_supplied && str_list_match_list(tags_in, &vg->tags, NULL)))
3437 process_all = 1;
3438
6ca28ca4
PR
3439 log_set_report_object_group_and_group_id(vg->name, vg_uuid);
3440
91615603 3441 dm_list_iterate_items(lvl, &vg->lvs) {
6ca28ca4
PR
3442 lv_uuid[0] = '\0';
3443 if (!id_write_format(&lvl->lv->lvid.id[1], lv_uuid, sizeof(lv_uuid)))
3444 stack;
3445
3446 log_set_report_object_name_and_id(lvl->lv->name, lv_uuid);
3447
56011918
PR
3448 if (sigint_caught()) {
3449 ret_max = ECMD_FAILED;
3450 goto_out;
3451 }
d8923457 3452
a8f5e1f2 3453 if (lv_is_snapshot(lvl->lv))
91615603
DT
3454 continue;
3455
3456 /* Skip availability change for non-virt snaps when processing all LVs */
3457 /* FIXME: pass process_all to process_single_lv() */
94eda42e
ZK
3458 if (process_all &&
3459 (arg_is_set(cmd, activate_ARG) ||
3460 arg_is_set(cmd, refresh_ARG)) &&
91615603
DT
3461 lv_is_cow(lvl->lv) && !lv_is_virtual_origin(origin_from_cow(lvl->lv)))
3462 continue;
3463
7e671e5d 3464 if (lv_is_virtual_origin(lvl->lv) && !arg_is_set(cmd, all_ARG)) {
91615603
DT
3465 if (lvargs_supplied &&
3466 str_list_match_item(arg_lvnames, lvl->lv->name))
3467 log_print_unless_silent("Ignoring virtual origin logical volume %s.",
3468 display_lvname(lvl->lv));
3469 continue;
3470 }
3471
3472 /*
1b908658 3473 * Only let hidden LVs through if --all was used or the LVs
91615603
DT
3474 * were specifically named on the command line.
3475 */
112846ce
ZK
3476 if (!lvargs_supplied && !lv_is_visible(lvl->lv) && !arg_is_set(cmd, all_ARG) &&
3477 (!cmd->process_component_lvs || !lv_is_component(lvl->lv)))
91615603
DT
3478 continue;
3479
143a9d7e
DT
3480 /*
3481 * Only let sanlock LV through if --all was used or if
3482 * it is named on the command line.
3483 */
3484 if (lv_is_lockd_sanlock_lv(lvl->lv)) {
7e671e5d 3485 if (arg_is_set(cmd, all_ARG) ||
143a9d7e
DT
3486 (lvargs_supplied && str_list_match_item(arg_lvnames, lvl->lv->name))) {
3487 log_very_verbose("Processing lockd_sanlock_lv %s/%s.", vg->name, lvl->lv->name);
3488 } else {
3489 continue;
3490 }
3491 }
3492
455ef6f2
DT
3493 /*
3494 * process the LV if one of the following:
3495 * - process_all is set
3496 * - LV name matches a supplied LV name
3497 * - LV tag matches a supplied LV tag
3498 * - LV matches the selection
3499 */
3500
3501 process_lv = process_all;
3502
3503 if (lvargs_supplied && str_list_match_item(arg_lvnames, lvl->lv->name)) {
91615603
DT
3504 /* Remove LV from list of unprocessed LV names */
3505 str_list_del(arg_lvnames, lvl->lv->name);
fd6661df
ZK
3506 if (!str_list_add(cmd->mem, &found_arg_lvnames, lvl->lv->name)) {
3507 log_error("strlist allocation failed.");
3508 ret_max = ECMD_FAILED;
3509 goto out;
3510 }
455ef6f2
DT
3511 process_lv = 1;
3512 }
3513
3514 if (!process_lv && tags_supplied && str_list_match_list(tags_in, &lvl->lv->tags, NULL))
3515 process_lv = 1;
3516
815f1ee2 3517 process_lv = process_lv && select_match_lv(cmd, handle, vg, lvl->lv) && _select_matches(handle);
455ef6f2 3518
455ef6f2 3519 if (!process_lv)
91615603
DT
3520 continue;
3521
2cbe88d6 3522 log_very_verbose("Adding %s to the list of LVs to be processed.", display_lvname(lvl->lv));
c9f021de 3523
c701d9cc 3524 if (!(final_lvl = dm_pool_zalloc(cmd->mem, sizeof(struct lv_list)))) {
c9f021de
PR
3525 log_error("Failed to allocate final LV list item.");
3526 ret_max = ECMD_FAILED;
1d58074d 3527 goto out;
c9f021de
PR
3528 }
3529 final_lvl->lv = lvl->lv;
dac82747
ZK
3530 if (lv_is_thin_pool(lvl->lv)) {
3531 /* Add to the front of the list */
3532 dm_list_add_h(&final_lvs, &final_lvl->list);
3533 } else
3534 dm_list_add(&final_lvs, &final_lvl->list);
c9f021de 3535 }
6ca28ca4 3536 log_set_report_object_name_and_id(NULL, NULL);
c9f021de 3537
34fd818c
DT
3538 /*
3539 * If a PV is stacked on an LV, then the LV is kept open
3540 * in bcache, and needs to be closed so the open fd doesn't
3541 * interfere with processing the LV.
3542 */
04fbffb1 3543 label_scan_invalidate_lvs(cmd, &final_lvs);
34fd818c 3544
c9f021de 3545 dm_list_iterate_items(lvl, &final_lvs) {
6ca28ca4
PR
3546 lv_uuid[0] = '\0';
3547 if (!id_write_format(&lvl->lv->lvid.id[1], lv_uuid, sizeof(lv_uuid)))
3548 stack;
3549
3550 log_set_report_object_name_and_id(lvl->lv->name, lv_uuid);
3551
347575df
ZK
3552 if (sigint_caught()) {
3553 ret_max = ECMD_FAILED;
3554 goto_out;
3555 }
8759f7d7
PR
3556 /*
3557 * FIXME: Once we have index over vg->removed_lvs, check directly
3558 * LV presence there and remove LV_REMOVE flag/lv_is_removed fn
3559 * as they won't be needed anymore.
3560 */
c9f021de
PR
3561 if (lv_is_removed(lvl->lv))
3562 continue;
3563
1e2420bc
DT
3564 lv_is_named_arg = str_list_match_item(&found_arg_lvnames, lvl->lv->name);
3565
3566 lv_arg_pos = _find_lv_arg_position(cmd, lvl->lv);
3567
3568 /*
3569 * The command definition may include restrictions on the
3570 * types and properties of LVs that can be processed.
3571 */
3572
3573 if (!_check_lv_types(cmd, lvl->lv, lv_arg_pos)) {
3574 /* FIXME: include this result in report log? */
3575 if (lv_is_named_arg) {
a3fdc966 3576 log_error("Command not permitted on LV %s.", display_lvname(lvl->lv));
1e2420bc
DT
3577 ret_max = ECMD_FAILED;
3578 }
3579 continue;
3580 }
3581
3582 if (!_check_lv_rules(cmd, lvl->lv)) {
3583 /* FIXME: include this result in report log? */
3584 if (lv_is_named_arg) {
a3fdc966 3585 log_error("Command not permitted on LV %s.", display_lvname(lvl->lv));
1e2420bc 3586 ret_max = ECMD_FAILED;
1b908658 3587 }
1e2420bc
DT
3588 continue;
3589 }
3590
9c6c55c3
DT
3591 if (check_single_lv && !check_single_lv(cmd, lvl->lv, handle, lv_is_named_arg)) {
3592 if (lv_is_named_arg)
3593 ret_max = ECMD_FAILED;
3594 continue;
3595 }
3596
38200c20 3597 log_very_verbose("Processing LV %s in VG %s.", lvl->lv->name, vg->name);
91615603 3598
b622a7fe 3599 ret = process_single_lv(cmd, lvl->lv, handle);
de273247
PR
3600 if (handle_supplied)
3601 _update_selection_result(handle, &whole_selected);
b622a7fe 3602 if (ret != ECMD_PROCESSED)
d8923457 3603 stack;
0ab11877 3604 report_log_ret_code(ret);
91615603
DT
3605 if (ret > ret_max)
3606 ret_max = ret;
f3bb1c01 3607
6ca28ca4 3608 if (stop_on_error && ret != ECMD_PROCESSED) {
0ab11877 3609 do_report_ret_code = 0;
56011918 3610 goto_out;
6ca28ca4 3611 }
91615603 3612 }
6ca28ca4 3613 log_set_report_object_name_and_id(NULL, NULL);
91615603 3614
2e7a1210 3615 if (handle->include_historical_lvs && !tags_supplied) {
3cf97a73 3616 if (dm_list_empty(&_historical_lv.segments))
2e7a1210
PR
3617 dm_list_add(&_historical_lv.segments, &_historical_lv_segment.list);
3618 _historical_lv.vg = vg;
3619
3620 dm_list_iterate_items_safe(glvl, tglvl, &vg->historical_lvs) {
6ca28ca4
PR
3621 lv_uuid[0] = '\0';
3622 if (!id_write_format(&glvl->glv->historical->lvid.id[1], lv_uuid, sizeof(lv_uuid)))
3623 stack;
3624
3625 log_set_report_object_name_and_id(glvl->glv->historical->name, lv_uuid);
3626
56620b90
ZK
3627 if (sigint_caught()) {
3628 ret_max = ECMD_FAILED;
3629 goto_out;
3630 }
3631
90855545
PR
3632 if (glvl->glv->historical->fresh)
3633 continue;
3634
2e7a1210
PR
3635 process_lv = process_all;
3636
3637 if (lvargs_supplied &&
3638 (sl = _str_list_match_item_with_prefix(arg_lvnames, HISTORICAL_LV_PREFIX, glvl->glv->historical->name))) {
3639 str_list_del(arg_lvnames, glvl->glv->historical->name);
3640 dm_list_del(&sl->list);
3641 process_lv = 1;
3642 }
3643
7ec0726c
PR
3644 _historical_lv.this_glv = glvl->glv;
3645 _historical_lv.name = glvl->glv->historical->name;
3646
3647 process_lv = process_lv && select_match_lv(cmd, handle, vg, &_historical_lv) && _select_matches(handle);
2e7a1210 3648
2e7a1210
PR
3649 if (!process_lv)
3650 continue;
3651
2e7a1210
PR
3652 log_very_verbose("Processing historical LV %s in VG %s.", glvl->glv->historical->name, vg->name);
3653
524df486 3654 /* coverity[format_string_injection] lv name is already validated */
2e7a1210
PR
3655 ret = process_single_lv(cmd, &_historical_lv, handle);
3656 if (handle_supplied)
3657 _update_selection_result(handle, &whole_selected);
3658 if (ret != ECMD_PROCESSED)
3659 stack;
0ab11877 3660 report_log_ret_code(ret);
2e7a1210
PR
3661 if (ret > ret_max)
3662 ret_max = ret;
3663
6ca28ca4 3664 if (stop_on_error && ret != ECMD_PROCESSED) {
0ab11877 3665 do_report_ret_code = 0;
2e7a1210 3666 goto_out;
6ca28ca4 3667 }
2e7a1210 3668 }
6ca28ca4 3669 log_set_report_object_name_and_id(NULL, NULL);
2e7a1210
PR
3670 }
3671
a125a3bb
ZK
3672 if (vg->needs_write_and_commit && (ret_max == ECMD_PROCESSED) &&
3673 (!vg_write(vg) || !vg_commit(vg)))
843ee943 3674 ret_max = ECMD_FAILED;
eb1160ee 3675
91615603
DT
3676 if (lvargs_supplied) {
3677 /*
3678 * FIXME: lvm supports removal of LV with all its dependencies
3679 * this leads to miscalculation that depends on the order of args.
3680 */
3681 dm_list_iterate_items(sl, arg_lvnames) {
6ca28ca4 3682 log_set_report_object_name_and_id(sl->str, NULL);
91615603
DT
3683 log_error("Failed to find logical volume \"%s/%s\"",
3684 vg->name, sl->str);
3685 if (ret_max < ECMD_FAILED)
3686 ret_max = ECMD_FAILED;
0ab11877 3687 report_log_ret_code(ret_max);
91615603
DT
3688 }
3689 }
0ab11877 3690 do_report_ret_code = 0;
56011918 3691out:
0ab11877
PR
3692 if (do_report_ret_code)
3693 report_log_ret_code(ret_max);
6ca28ca4
PR
3694 log_set_report_object_name_and_id(NULL, NULL);
3695 log_set_report_object_group_and_group_id(NULL, NULL);
56011918 3696 if (!handle_supplied)
969d2bf4 3697 destroy_processing_handle(cmd, handle);
de273247
PR
3698 else
3699 _set_final_selection_result(handle, whole_selected);
6ca28ca4
PR
3700 log_restore_report_state(saved_log_report_state);
3701
91615603
DT
3702 return ret_max;
3703}
3704
3705/*
3706 * If arg is tag, add it to arg_tags
3707 * else the arg is either vgname or vgname/lvname:
3708 * - add the vgname of each arg to arg_vgnames
3709 * - if arg has no lvname, add just vgname arg_lvnames,
3710 * it represents all lvs in the vg
3711 * - if arg has lvname, add vgname/lvname to arg_lvnames
3712 */
3713static int _get_arg_lvnames(struct cmd_context *cmd,
3714 int argc, char **argv,
2f2b3c91 3715 const char *one_vgname, const char *one_lvname,
91615603
DT
3716 struct dm_list *arg_vgnames,
3717 struct dm_list *arg_lvnames,
3718 struct dm_list *arg_tags)
3719{
3720 int opt = 0;
3721 int ret_max = ECMD_PROCESSED;
3722 char *vglv;
3723 size_t vglv_sz;
3724 const char *vgname;
3725 const char *lv_name;
3726 const char *tmp_lv_name;
1115a9ea 3727 const char *vgname_def;
91615603
DT
3728 unsigned dev_dir_found;
3729
2f2b3c91
DT
3730 if (one_vgname) {
3731 if (!str_list_add(cmd->mem, arg_vgnames,
3732 dm_pool_strdup(cmd->mem, one_vgname))) {
3733 log_error("strlist allocation failed.");
3734 return ECMD_FAILED;
3735 }
3736
3737 if (!one_lvname) {
3738 if (!str_list_add(cmd->mem, arg_lvnames,
3739 dm_pool_strdup(cmd->mem, one_vgname))) {
3740 log_error("strlist allocation failed.");
3741 return ECMD_FAILED;
3742 }
3743 } else {
3744 vglv_sz = strlen(one_vgname) + strlen(one_lvname) + 2;
3745 if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
3746 dm_snprintf(vglv, vglv_sz, "%s/%s", one_vgname, one_lvname) < 0) {
3747 log_error("vg/lv string alloc failed.");
3748 return ECMD_FAILED;
3749 }
3750 if (!str_list_add(cmd->mem, arg_lvnames, vglv)) {
3751 log_error("strlist allocation failed.");
3752 return ECMD_FAILED;
3753 }
3754 }
3755 return ret_max;
3756 }
3757
91615603
DT
3758 for (; opt < argc; opt++) {
3759 lv_name = argv[opt];
3760 dev_dir_found = 0;
3761
3762 /* Do we have a tag or vgname or lvname? */
3763 vgname = lv_name;
3764
3765 if (*vgname == '@') {
3766 if (!validate_tag(vgname + 1)) {
38200c20 3767 log_error("Skipping invalid tag %s.", vgname);
91615603
DT
3768 continue;
3769 }
3770 if (!str_list_add(cmd->mem, arg_tags,
3771 dm_pool_strdup(cmd->mem, vgname + 1))) {
38200c20 3772 log_error("strlist allocation failed.");
91615603
DT
3773 return ECMD_FAILED;
3774 }
3775 continue;
3776 }
3777
3778 /* FIXME Jumbled parsing */
3779 vgname = skip_dev_dir(cmd, vgname, &dev_dir_found);
3780
3781 if (*vgname == '/') {
38200c20 3782 log_error("\"%s\": Invalid path for Logical Volume.",
91615603
DT
3783 argv[opt]);
3784 if (ret_max < ECMD_FAILED)
3785 ret_max = ECMD_FAILED;
3786 continue;
3787 }
3788 lv_name = vgname;
3789 if ((tmp_lv_name = strchr(vgname, '/'))) {
3790 /* Must be an LV */
3791 lv_name = tmp_lv_name;
3792 while (*lv_name == '/')
3793 lv_name++;
3794 if (!(vgname = extract_vgname(cmd, vgname))) {
3795 if (ret_max < ECMD_FAILED) {
3796 stack;
3797 ret_max = ECMD_FAILED;
3798 }
3799 continue;
3800 }
3801 } else if (!dev_dir_found &&
1115a9ea 3802 (vgname_def = _default_vgname(cmd)))
91615603
DT
3803 vgname = vgname_def;
3804 else
3805 lv_name = NULL;
3806
3807 if (!str_list_add(cmd->mem, arg_vgnames,
3808 dm_pool_strdup(cmd->mem, vgname))) {
38200c20 3809 log_error("strlist allocation failed.");
91615603
DT
3810 return ECMD_FAILED;
3811 }
3812
3813 if (!lv_name) {
3814 if (!str_list_add(cmd->mem, arg_lvnames,
3815 dm_pool_strdup(cmd->mem, vgname))) {
38200c20 3816 log_error("strlist allocation failed.");
91615603
DT
3817 return ECMD_FAILED;
3818 }
3819 } else {
3820 vglv_sz = strlen(vgname) + strlen(lv_name) + 2;
3821 if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
3822 dm_snprintf(vglv, vglv_sz, "%s/%s", vgname, lv_name) < 0) {
38200c20 3823 log_error("vg/lv string alloc failed.");
91615603
DT
3824 return ECMD_FAILED;
3825 }
3826 if (!str_list_add(cmd->mem, arg_lvnames, vglv)) {
38200c20 3827 log_error("strlist allocation failed.");
91615603
DT
3828 return ECMD_FAILED;
3829 }
3830 }
3831 }
3832
3833 return ret_max;
3834}
3835
95e38607 3836/*
ea63a38f 3837 * Finding vgname/lvname to process.
95e38607 3838 *
ea63a38f
ZK
3839 * When the position arg is a single name without any '/'
3840 * it is treated as an LV name (leaving the VG unknown).
3841 * Other option values, or env var, must be searched for a VG name.
3842 * If one of the option values contains a vgname/lvname value,
3843 * then the VG name is extracted and used for the LV position arg.
3844 * Or, if the env var has the VG name, that is used.
95e38607
DT
3845 *
3846 * Other option values that are searched for a VG name are:
ea63a38f 3847 * --thinpool, --cachepool, --poolmetadata.
95e38607
DT
3848 *
3849 * . command vg/lv1
3850 * . add vg to arg_vgnames
3851 * . add vg/lv1 to arg_lvnames
3852 *
3853 * command lv1
6a5c9ba3 3854 * . error: no vg name (unless LVM_VG_NAME)
95e38607 3855 *
6a5c9ba3 3856 * command --option=vg/lv1 vg/lv2
95e38607
DT
3857 * . verify both vg names match
3858 * . add vg to arg_vgnames
3859 * . add vg/lv2 to arg_lvnames
3860 *
6a5c9ba3
DT
3861 * command --option=lv1 lv2
3862 * . error: no vg name (unless LVM_VG_NAME)
95e38607 3863 *
6a5c9ba3 3864 * command --option=vg/lv1 lv2
95e38607
DT
3865 * . add vg to arg_vgnames
3866 * . add vg/lv2 to arg_lvnames
3867 *
6a5c9ba3 3868 * command --option=lv1 vg/lv2
95e38607
DT
3869 * . add vg to arg_vgnames
3870 * . add vg/lv2 to arg_lvnames
3871 */
95e38607
DT
3872static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
3873 int argc, char **argv,
3874 struct dm_list *arg_vgnames,
3875 struct dm_list *arg_lvnames,
3876 struct dm_list *arg_tags)
3877{
ea63a38f
ZK
3878 /* Array with args which may provide vgname */
3879 static const unsigned _opts_with_vgname[] = {
3880 cachepool_ARG, poolmetadata_ARG, thinpool_ARG
3881 };
3882 unsigned i;
95e38607
DT
3883 const char *pos_name = NULL;
3884 const char *arg_name = NULL;
3885 const char *pos_vgname = NULL;
3886 const char *opt_vgname = NULL;
3887 const char *pos_lvname = NULL;
3888 const char *use_vgname = NULL;
95e38607
DT
3889 char *vglv;
3890 size_t vglv_sz;
3891
3892 if (argc != 1) {
3893 log_error("One LV position arg is required.");
3894 return ECMD_FAILED;
3895 }
3896
3897 if (!(pos_name = dm_pool_strdup(cmd->mem, argv[0]))) {
3898 log_error("string alloc failed.");
3899 return ECMD_FAILED;
3900 }
3901
3902 if (*pos_name == '@') {
3903 if (!validate_tag(pos_name + 1)) {
3904 log_error("Skipping invalid tag %s.", pos_name);
3905 return ECMD_FAILED;
3906 }
3907 if (!str_list_add(cmd->mem, arg_tags,
3908 dm_pool_strdup(cmd->mem, pos_name + 1))) {
3909 log_error("strlist allocation failed.");
3910 return ECMD_FAILED;
3911 }
3912 return ECMD_PROCESSED;
3913 }
3914
ea63a38f 3915 if (strchr(pos_name, '/')) {
6a5c9ba3
DT
3916 /*
3917 * This splits pos_name 'x/y' into pos_vgname 'x' and pos_lvname 'y'
3918 * It skips repeated '/', e.g. x//y
3919 * It also checks and fails for extra '/', e.g. x/y/z
3920 */
ea63a38f
ZK
3921 if (!(pos_vgname = _extract_vgname(cmd, pos_name, &pos_lvname)))
3922 return_0;
3923 use_vgname = pos_vgname;
3924 } else
95e38607 3925 pos_lvname = pos_name;
95e38607 3926
ea63a38f
ZK
3927 /* Go through the list of options which can provide vgname */
3928 for (i = 0; i < DM_ARRAY_SIZE(_opts_with_vgname); ++i) {
3929 if ((arg_name = arg_str_value(cmd, _opts_with_vgname[i], NULL)) &&
3930 strchr(arg_name, '/')) {
3931 /* Combined VG/LV */
3932 /* Don't care about opt lvname, only extract vgname. */
3933 if (!(opt_vgname = _extract_vgname(cmd, arg_name, NULL)))
3934 return_0;
3935 /* Compare with already known vgname */
3936 if (use_vgname) {
3937 if (strcmp(use_vgname, opt_vgname)) {
3938 log_error("VG name mismatch from %s arg (%s) and option arg (%s).",
3939 pos_vgname ? "position" : "option",
3940 use_vgname, opt_vgname);
3941 return ECMD_FAILED;
3942 }
3943 } else
3944 use_vgname = opt_vgname;
95e38607 3945 }
95e38607
DT
3946 }
3947
ea63a38f
ZK
3948 /* VG not specified as position nor as optional arg, so check for default VG */
3949 if (!use_vgname && !(use_vgname = _default_vgname(cmd))) {
95e38607
DT
3950 log_error("Cannot find VG name for LV %s.", pos_lvname);
3951 return ECMD_FAILED;
3952 }
3953
95e38607
DT
3954 if (!str_list_add(cmd->mem, arg_vgnames, dm_pool_strdup(cmd->mem, use_vgname))) {
3955 log_error("strlist allocation failed.");
3956 return ECMD_FAILED;
3957 }
3958
3959 vglv_sz = strlen(use_vgname) + strlen(pos_lvname) + 2;
3960
3961 if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
3962 dm_snprintf(vglv, vglv_sz, "%s/%s", use_vgname, pos_lvname) < 0) {
3963 log_error("vg/lv string alloc failed.");
3964 return ECMD_FAILED;
3965 }
3966 if (!str_list_add(cmd->mem, arg_lvnames, vglv)) {
3967 log_error("strlist allocation failed.");
3968 return ECMD_FAILED;
3969 }
3970
3971 return ECMD_PROCESSED;
3972}
3973
a4418b34 3974static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
91615603
DT
3975 struct dm_list *vgnameids_to_process,
3976 struct dm_list *arg_vgnames,
3977 struct dm_list *arg_lvnames,
3978 struct dm_list *arg_tags,
51d96a17 3979 struct processing_handle *handle,
9c6c55c3 3980 check_single_lv_fn_t check_single_lv,
91615603
DT
3981 process_single_lv_fn_t process_single_lv)
3982{
6ca28ca4 3983 log_report_t saved_log_report_state = log_get_report_state();
4ff2583d 3984 char uuid[64] __attribute__((aligned(8)));
91615603 3985 struct volume_group *vg;
ba7ff96f 3986 struct volume_group *error_vg = NULL;
97b16ec2 3987 struct vgnameid_list *vgnl;
91615603
DT
3988 struct dm_str_list *sl;
3989 struct dm_list *tags_arg;
3990 struct dm_list lvnames;
3ec4813b 3991 uint32_t lockd_state = 0;
ba7ff96f 3992 uint32_t error_flags = 0;
91615603
DT
3993 const char *vg_name;
3994 const char *vg_uuid;
3995 const char *vgn;
3996 const char *lvn;
3997 int ret_max = ECMD_PROCESSED;
3998 int ret;
d8923457 3999 int skip;
66248338 4000 int notfound;
bf60cb4d 4001 int is_lockd;
0ab11877 4002 int do_report_ret_code = 1;
91615603 4003
6ca28ca4 4004 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
d8923457 4005
6ca28ca4 4006 dm_list_iterate_items(vgnl, vgnameids_to_process) {
97b16ec2
AK
4007 vg_name = vgnl->vg_name;
4008 vg_uuid = vgnl->vgid;
b622a7fe 4009 skip = 0;
66248338 4010 notfound = 0;
bf60cb4d 4011 is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid);
91615603 4012
6ca28ca4
PR
4013 uuid[0] = '\0';
4014 if (vg_uuid && !id_write_format((const struct id*)vg_uuid, uuid, sizeof(uuid)))
4015 stack;
4016
4017 log_set_report_object_name_and_id(vg_name, uuid);
4018
4019 if (sigint_caught()) {
4020 ret_max = ECMD_FAILED;
4021 goto_out;
4022 }
4023
91615603
DT
4024 /*
4025 * arg_lvnames contains some elements that are just "vgname"
4026 * which means process all lvs in the vg. Other elements
4027 * are "vgname/lvname" which means process only the select
4028 * lvs in the vg.
4029 */
4030 tags_arg = arg_tags;
4031 dm_list_init(&lvnames); /* LVs to be processed in this VG */
4032
4033 dm_list_iterate_items(sl, arg_lvnames) {
4034 vgn = sl->str;
4035 lvn = strchr(vgn, '/');
4036
4037 if (!lvn && !strcmp(vgn, vg_name)) {
4038 /* Process all LVs in this VG */
4039 tags_arg = NULL;
4040 dm_list_init(&lvnames);
4041 break;
4042 }
1b908658 4043
91615603
DT
4044 if (lvn && !strncmp(vgn, vg_name, strlen(vg_name)) &&
4045 strlen(vg_name) == (size_t) (lvn - vgn)) {
4046 if (!str_list_add(cmd->mem, &lvnames,
4047 dm_pool_strdup(cmd->mem, lvn + 1))) {
38200c20 4048 log_error("strlist allocation failed.");
6ca28ca4
PR
4049 ret_max = ECMD_FAILED;
4050 goto out;
91615603
DT
4051 }
4052 }
4053 }
4054
4ff2583d
DT
4055 log_very_verbose("Processing VG %s %s", vg_name, vg_uuid ? uuid : "");
4056
bf60cb4d
DT
4057do_lockd:
4058 if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
fe70b03d 4059 ret_max = ECMD_FAILED;
0ab11877 4060 report_log_ret_code(ret_max);
fe70b03d
DT
4061 continue;
4062 }
4063
ba7ff96f
DT
4064 vg = vg_read(cmd, vg_name, vg_uuid, read_flags, lockd_state, &error_flags, &error_vg);
4065 if (_ignore_vg(cmd, error_flags, error_vg, vg_name, arg_vgnames, read_flags, &skip, &notfound)) {
91615603 4066 stack;
b622a7fe 4067 ret_max = ECMD_FAILED;
0ab11877 4068 report_log_ret_code(ret_max);
ba7ff96f
DT
4069 if (error_vg)
4070 unlock_and_release_vg(cmd, error_vg, vg_name);
fe70b03d 4071 goto endvg;
b622a7fe 4072 }
ba7ff96f
DT
4073 if (error_vg)
4074 unlock_and_release_vg(cmd, error_vg, vg_name);
4075
66248338 4076 if (skip || notfound)
fe70b03d 4077 goto endvg;
91615603 4078
bf60cb4d
DT
4079 if (!is_lockd && vg_is_shared(vg)) {
4080 /* The lock_type changed since label_scan, won't really occur in practice. */
4081 log_debug("Repeat lock and read for local to shared vg");
4082 unlock_and_release_vg(cmd, vg, vg_name);
4083 is_lockd = 1;
4084 goto do_lockd;
4085 }
4086
b622a7fe 4087 ret = process_each_lv_in_vg(cmd, vg, &lvnames, tags_arg, 0,
9c6c55c3 4088 handle, check_single_lv, process_single_lv);
b622a7fe
DT
4089 if (ret != ECMD_PROCESSED)
4090 stack;
0ab11877 4091 report_log_ret_code(ret);
91615603
DT
4092 if (ret > ret_max)
4093 ret_max = ret;
b622a7fe 4094
c4153a8d 4095 unlock_vg(cmd, vg, vg_name);
fe70b03d
DT
4096endvg:
4097 release_vg(vg);
bf60cb4d 4098 if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
ae4db9f3 4099 stack;
6ca28ca4 4100 log_set_report_object_name_and_id(NULL, NULL);
91615603 4101 }
0ab11877 4102 do_report_ret_code = 0;
6ca28ca4 4103out:
0ab11877
PR
4104 if (do_report_ret_code)
4105 report_log_ret_code(ret_max);
6ca28ca4 4106 log_restore_report_state(saved_log_report_state);
91615603
DT
4107 return ret_max;
4108}
4109
4110/*
4111 * Call process_single_lv() for each LV selected by the command line arguments.
4112 */
2f2b3c91
DT
4113int process_each_lv(struct cmd_context *cmd,
4114 int argc, char **argv,
4115 const char *one_vgname, const char *one_lvname,
4116 uint32_t read_flags,
4117 struct processing_handle *handle,
9c6c55c3 4118 check_single_lv_fn_t check_single_lv,
2f2b3c91 4119 process_single_lv_fn_t process_single_lv)
91615603 4120{
6ca28ca4 4121 log_report_t saved_log_report_state = log_get_report_state();
56011918 4122 int handle_supplied = handle != NULL;
91615603
DT
4123 struct dm_list arg_tags; /* str_list */
4124 struct dm_list arg_vgnames; /* str_list */
4125 struct dm_list arg_lvnames; /* str_list */
4126 struct dm_list vgnameids_on_system; /* vgnameid_list */
4127 struct dm_list vgnameids_to_process; /* vgnameid_list */
013c0807 4128 int enable_all_vgs = (cmd->cname->flags & ALL_VGS_IS_DEFAULT);
4ff2583d
DT
4129 int process_all_vgs_on_system = 0;
4130 int ret_max = ECMD_PROCESSED;
91615603
DT
4131 int ret;
4132
6ca28ca4
PR
4133 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LV);
4134
fe70b03d
DT
4135 /* Disable error in vg_read so we can print it from ignore_vg. */
4136 cmd->vg_read_print_access_error = 0;
0a19238a 4137
91615603
DT
4138 dm_list_init(&arg_tags);
4139 dm_list_init(&arg_vgnames);
4140 dm_list_init(&arg_lvnames);
4141 dm_list_init(&vgnameids_on_system);
4142 dm_list_init(&vgnameids_to_process);
4143
4144 /*
4145 * Find any LVs, VGs or tags explicitly provided on the command line.
4146 */
ecabdf68 4147 if (cmd->get_vgname_from_options)
95e38607
DT
4148 ret = _get_arg_lvnames_using_options(cmd, argc, argv, &arg_vgnames, &arg_lvnames, &arg_tags);
4149 else
4150 ret = _get_arg_lvnames(cmd, argc, argv, one_vgname, one_lvname, &arg_vgnames, &arg_lvnames, &arg_tags);
4151
4152 if (ret != ECMD_PROCESSED) {
4ff2583d 4153 ret_max = ret;
56011918 4154 goto_out;
4ff2583d 4155 }
56011918 4156
f752a953 4157 if (!handle && !(handle = init_processing_handle(cmd, NULL))) {
4ff2583d 4158 ret_max = ECMD_FAILED;
56011918 4159 goto_out;
4ff2583d 4160 }
56011918
PR
4161
4162 if (handle->internal_report_for_select && !handle->selection_handle &&
4ff2583d
DT
4163 !init_selection_handle(cmd, handle, LVS)) {
4164 ret_max = ECMD_FAILED;
56011918 4165 goto_out;
4ff2583d 4166 }
91615603
DT
4167
4168 /*
4ff2583d
DT
4169 * Process all VGs on the system when:
4170 * . tags are specified and all VGs need to be read to
4171 * look for matching tags.
4172 * . no VG names are specified and the command defaults
4173 * to processing all VGs when none are specified.
4174 * . no VG names are specified and the select option needs
4175 * resolving.
4176 */
8e509b5d 4177 if (!dm_list_empty(&arg_tags))
4ff2583d 4178 process_all_vgs_on_system = 1;
8e509b5d 4179 else if (dm_list_empty(&arg_vgnames) && enable_all_vgs)
4ff2583d 4180 process_all_vgs_on_system = 1;
8e509b5d 4181 else if (dm_list_empty(&arg_vgnames) && handle->internal_report_for_select)
4ff2583d 4182 process_all_vgs_on_system = 1;
8e509b5d 4183
4ff2583d
DT
4184 /*
4185 * Needed for a current listing of the global VG namespace.
4186 */
8c87dda1 4187 if (process_all_vgs_on_system && !lock_global(cmd, "sh")) {
4ff2583d
DT
4188 ret_max = ECMD_FAILED;
4189 goto_out;
4190 }
fe70b03d 4191
748f29b4
DT
4192 /*
4193 * Scan all devices to populate lvmcache with initial
4194 * list of PVs and VGs.
4195 */
92b4fcf5
DT
4196 if (!lvmcache_label_scan(cmd)) {
4197 ret_max = ECMD_FAILED;
4198 goto_out;
4199 }
748f29b4 4200
4ff2583d
DT
4201 /*
4202 * A list of all VGs on the system is needed when:
4203 * . processing all VGs on the system
4204 * . A VG name is specified which may refer to one
4205 * of multiple VGs on the system with that name.
4206 */
6bf0f04a 4207 log_very_verbose("Obtaining the complete list of VGs before processing their LVs");
4ff2583d 4208
4bb7d3da 4209 if (!lvmcache_get_vgnameids(cmd, &vgnameids_on_system, NULL, 0)) {
4ff2583d
DT
4210 ret_max = ECMD_FAILED;
4211 goto_out;
fe70b03d 4212 }
91615603 4213
aa493267
DT
4214 if (!dm_list_empty(&arg_vgnames)) {
4215 /* This may remove entries from arg_vgnames or vgnameids_on_system. */
4216 ret = _resolve_duplicate_vgnames(cmd, &arg_vgnames, &vgnameids_on_system);
4217 if (ret > ret_max)
4218 ret_max = ret;
4219 if (dm_list_empty(&arg_vgnames) && dm_list_empty(&arg_tags)) {
4220 ret_max = ECMD_FAILED;
cc03a872 4221 goto_out;
aa493267
DT
4222 }
4223 }
4224
91615603
DT
4225 if (dm_list_empty(&arg_vgnames) && dm_list_empty(&vgnameids_on_system)) {
4226 /* FIXME Should be log_print, but suppressed for reporting cmds */
fd32bb19 4227 log_verbose("No volume groups found.");
4ff2583d 4228 ret_max = ECMD_PROCESSED;
56011918 4229 goto out;
91615603
DT
4230 }
4231
a4418b34
DT
4232 if (dm_list_empty(&arg_vgnames))
4233 read_flags |= READ_OK_NOTFOUND;
4234
91615603 4235 /*
4ff2583d
DT
4236 * When processing all VGs, vgnameids_on_system simply becomes
4237 * vgnameids_to_process.
4238 * When processing only specified VGs, then for each item in
4239 * arg_vgnames, move the corresponding entry from
4240 * vgnameids_on_system to vgnameids_to_process.
91615603 4241 */
4ff2583d 4242 if (process_all_vgs_on_system)
91615603 4243 dm_list_splice(&vgnameids_to_process, &vgnameids_on_system);
4ff2583d
DT
4244 else
4245 _choose_vgs_to_process(cmd, &arg_vgnames, &vgnameids_on_system, &vgnameids_to_process);
91615603 4246
a4418b34 4247 ret = _process_lv_vgnameid_list(cmd, read_flags, &vgnameids_to_process, &arg_vgnames, &arg_lvnames,
9c6c55c3 4248 &arg_tags, handle, check_single_lv, process_single_lv);
4ff2583d
DT
4249
4250 if (ret > ret_max)
4251 ret_max = ret;
56011918
PR
4252out:
4253 if (!handle_supplied)
969d2bf4 4254 destroy_processing_handle(cmd, handle);
4ff2583d 4255
6ca28ca4 4256 log_restore_report_state(saved_log_report_state);
4ff2583d 4257 return ret_max;
91615603 4258}
97b16ec2 4259
f1a000a4
DT
4260static int _get_arg_pvnames(struct cmd_context *cmd,
4261 int argc, char **argv,
4262 struct dm_list *arg_pvnames,
4263 struct dm_list *arg_tags)
97b16ec2 4264{
f1a000a4
DT
4265 int opt = 0;
4266 char *at_sign, *tagname;
4267 char *arg_name;
97b16ec2 4268 int ret_max = ECMD_PROCESSED;
97b16ec2 4269
f1a000a4
DT
4270 for (; opt < argc; opt++) {
4271 arg_name = argv[opt];
4272
4273 dm_unescape_colons_and_at_signs(arg_name, NULL, &at_sign);
4274 if (at_sign && (at_sign == arg_name)) {
4275 tagname = at_sign + 1;
4276
4277 if (!validate_tag(tagname)) {
38200c20 4278 log_error("Skipping invalid tag %s.", tagname);
f1a000a4
DT
4279 if (ret_max < EINVALID_CMD_LINE)
4280 ret_max = EINVALID_CMD_LINE;
4281 continue;
4282 }
4283 if (!str_list_add(cmd->mem, arg_tags,
4284 dm_pool_strdup(cmd->mem, tagname))) {
38200c20 4285 log_error("strlist allocation failed.");
f1a000a4
DT
4286 return ECMD_FAILED;
4287 }
97b16ec2
AK
4288 continue;
4289 }
f1a000a4
DT
4290
4291 if (!str_list_add(cmd->mem, arg_pvnames,
4292 dm_pool_strdup(cmd->mem, arg_name))) {
38200c20 4293 log_error("strlist allocation failed.");
f1a000a4
DT
4294 return ECMD_FAILED;
4295 }
97b16ec2
AK
4296 }
4297
4298 return ret_max;
4299}
4300
1e4a4d48
DT
4301static int _get_arg_devices(struct cmd_context *cmd,
4302 struct dm_list *arg_pvnames,
4303 struct dm_list *arg_devices)
4304{
4305 struct dm_str_list *sl;
c1f246fe 4306 struct device_id_list *dil;
1e4a4d48
DT
4307 int ret_max = ECMD_PROCESSED;
4308
4309 dm_list_iterate_items(sl, arg_pvnames) {
96b77716 4310 if (!(dil = dm_pool_zalloc(cmd->mem, sizeof(*dil)))) {
c1f246fe 4311 log_error("device_id_list alloc failed.");
1e4a4d48
DT
4312 return ECMD_FAILED;
4313 }
4314
00c30698 4315 if (!(dil->dev = dev_cache_get_existing(cmd, sl->str, cmd->filter))) {
f8aa073a 4316 log_error("Cannot use %s: %s", sl->str, devname_error_reason(sl->str));
d86e943b 4317 ret_max = EINIT_FAILED;
1e4a4d48 4318 } else {
96b77716 4319 memcpy(dil->pvid, dil->dev->pvid, ID_LEN);
c1f246fe 4320 dm_list_add(arg_devices, &dil->list);
1e4a4d48
DT
4321 }
4322 }
4323
4324 return ret_max;
4325}
4326
6fb497ef
DT
4327/* Process devices that are not PVs. */
4328
4329static int _process_other_devices(struct cmd_context *cmd,
51d96a17
PR
4330 struct processing_handle *handle,
4331 process_single_pv_fn_t process_single_pv)
f1a000a4 4332{
6fb497ef 4333 struct dev_iter *iter;
f1a000a4
DT
4334 struct physical_volume pv_dummy;
4335 struct physical_volume *pv;
6fb497ef
DT
4336 struct device *dev;
4337 int failed = 0;
4338 int ret;
f1a000a4 4339
71671778
DT
4340 log_debug("Processing devices that are not PVs");
4341
f1a000a4 4342 /*
6fb497ef
DT
4343 * We want devices here that passed filters during
4344 * label_scan but were found to not be PVs.
4345 *
4346 * No filtering used in iter, DEV_SCAN_FOUND_NOLABEL
4347 * was set by label_scan which did filtering.
f1a000a4 4348 */
6fb497ef 4349
f8aa073a 4350 if (!(iter = dev_iter_create(NULL, 0)))
6fb497ef
DT
4351 return_0;
4352
4353 while ((dev = dev_iter_get(cmd, iter))) {
4354 if (sigint_caught()) {
4355 failed = 1;
4356 break;
4357 }
4358
4359 if (!(dev->flags & DEV_SCAN_FOUND_NOLABEL))
4360 continue;
4361
4362 /*
4363 * Pretend that each device is a PV with dummy values.
39b7d1ba 4364 * FIXME Formalize this extension or find an alternative.
6fb497ef 4365 */
d8923457 4366
97b16ec2
AK
4367 memset(&pv_dummy, 0, sizeof(pv_dummy));
4368 dm_list_init(&pv_dummy.tags);
4369 dm_list_init(&pv_dummy.segments);
6fb497ef 4370 pv_dummy.dev = dev;
97b16ec2
AK
4371 pv = &pv_dummy;
4372
6fb497ef 4373 log_very_verbose("Processing device %s.", dev_name(dev));
97b16ec2
AK
4374
4375 ret = process_single_pv(cmd, NULL, pv, handle);
6fb497ef
DT
4376 if (ret != ECMD_PROCESSED)
4377 failed = 1;
97b16ec2 4378 }
6fb497ef 4379 dev_iter_destroy(iter);
97b16ec2 4380
6fb497ef 4381 return failed ? 0 : 1;
f1a000a4
DT
4382}
4383
d3d13e13 4384static int _process_duplicate_pvs(struct cmd_context *cmd,
d3d13e13 4385 struct dm_list *arg_devices,
6fb497ef 4386 int process_other_devices,
d3d13e13
DT
4387 struct processing_handle *handle,
4388 process_single_pv_fn_t process_single_pv)
4389{
d3d13e13
DT
4390 struct device_id_list *dil;
4391 struct device_list *devl;
4392 struct dm_list unused_duplicate_devs;
4393 struct lvmcache_info *info;
e329da17
DT
4394 const char *vgname;
4395 const char *vgid;
6fb497ef
DT
4396 int failed = 0;
4397 int ret;
d3d13e13 4398
e329da17 4399 struct physical_volume dummy_pv = {
ece80cd0 4400 .pe_size = 1,
e329da17
DT
4401 .tags = DM_LIST_HEAD_INIT(dummy_pv.tags),
4402 .segments= DM_LIST_HEAD_INIT(dummy_pv.segments),
4403 };
4404
4405 struct format_instance dummy_fid = {
4406 .metadata_areas_in_use = DM_LIST_HEAD_INIT(dummy_fid.metadata_areas_in_use),
4407 .metadata_areas_ignored = DM_LIST_HEAD_INIT(dummy_fid.metadata_areas_ignored),
4408 };
4409
4410 struct volume_group dummy_vg = {
f5f1cdfa
ZK
4411 .cmd = cmd,
4412 .vgmem = cmd->mem,
6097dfb9 4413 .extent_size = 1,
e329da17
DT
4414 .fid = &dummy_fid,
4415 .name = "",
4416 .system_id = (char *) "",
e329da17
DT
4417 .pvs = DM_LIST_HEAD_INIT(dummy_vg.pvs),
4418 .lvs = DM_LIST_HEAD_INIT(dummy_vg.lvs),
4419 .historical_lvs = DM_LIST_HEAD_INIT(dummy_vg.historical_lvs),
4420 .tags = DM_LIST_HEAD_INIT(dummy_vg.tags),
4421 };
4422
d3d13e13
DT
4423 dm_list_init(&unused_duplicate_devs);
4424
677833ce 4425 if (!lvmcache_get_unused_duplicates(cmd, &unused_duplicate_devs))
6fb497ef 4426 return_0;
d3d13e13
DT
4427
4428 dm_list_iterate_items(devl, &unused_duplicate_devs) {
4429 /* Duplicates are displayed if -a is used or the dev is named as an arg. */
4430
c98617c5
DT
4431 if ((dil = device_id_list_find_dev(arg_devices, devl->dev)))
4432 device_id_list_remove(arg_devices, devl->dev);
d3d13e13 4433
6fb497ef 4434 if (!process_other_devices && !dil)
d3d13e13
DT
4435 continue;
4436
013c0807 4437 if (!(cmd->cname->flags & ENABLE_DUPLICATE_DEVS))
d3d13e13
DT
4438 continue;
4439
4440 /*
4441 * Use the cached VG from the preferred device for the PV,
4442 * the vg is only used to display the VG name.
4443 *
4444 * This VG from lvmcache was not read from the duplicate
4445 * dev being processed here, but from the preferred dev
4446 * in lvmcache.
4447 *
4448 * When a duplicate PV is displayed, the reporting fields
4449 * that come from the VG metadata are not shown, because
4450 * the dev is not a part of the VG, the dev for the
4451 * preferred PV is (also the VG metadata in lvmcache is
4452 * not from the duplicate dev, but from the preferred dev).
4453 */
4454
4455 log_very_verbose("Processing duplicate device %s.", dev_name(devl->dev));
4456
01156de6
DT
4457 /*
4458 * Don't pass dev to lvmcache_info_from_pvid because we looking
4459 * for the chosen/preferred dev for this pvid.
4460 */
bf5d0a26
DT
4461 if (!(info = lvmcache_info_from_pvid(devl->dev->pvid, NULL, 0))) {
4462 log_error(INTERNAL_ERROR "No info for pvid");
6fb497ef 4463 return 0;
bf5d0a26
DT
4464 }
4465
4466 vgname = lvmcache_vgname_from_info(info);
e329da17 4467 vgid = vgname ? lvmcache_vgid_from_vgname(cmd, vgname) : NULL;
d3d13e13 4468
e329da17
DT
4469 dummy_pv.dev = devl->dev;
4470 dummy_pv.fmt = lvmcache_fmt_from_info(info);
4471 dummy_vg.name = vgname ?: "";
d3d13e13 4472
e329da17
DT
4473 if (vgid)
4474 memcpy(&dummy_vg.id, vgid, ID_LEN);
4475 else
4476 memset(&dummy_vg.id, 0, sizeof(dummy_vg.id));
d3d13e13 4477
e329da17 4478 ret = process_single_pv(cmd, &dummy_vg, &dummy_pv, handle);
6fb497ef
DT
4479 if (ret != ECMD_PROCESSED)
4480 failed = 1;
d3d13e13
DT
4481
4482 if (sigint_caught())
6fb497ef 4483 return_0;
d3d13e13
DT
4484 }
4485
6fb497ef 4486 return failed ? 0 : 1;
d3d13e13
DT
4487}
4488
f1a000a4
DT
4489static int _process_pvs_in_vg(struct cmd_context *cmd,
4490 struct volume_group *vg,
1e4a4d48 4491 struct dm_list *arg_devices,
f1a000a4 4492 struct dm_list *arg_tags,
3a7c47af 4493 int process_all_pvs,
f1a000a4 4494 int skip,
b4402bd8 4495 uint32_t error_flags,
51d96a17 4496 struct processing_handle *handle,
f1a000a4
DT
4497 process_single_pv_fn_t process_single_pv)
4498{
6ca28ca4
PR
4499 log_report_t saved_log_report_state = log_get_report_state();
4500 char pv_uuid[64] __attribute__((aligned(8)));
4501 char vg_uuid[64] __attribute__((aligned(8)));
56011918 4502 int handle_supplied = handle != NULL;
f1a000a4
DT
4503 struct physical_volume *pv;
4504 struct pv_list *pvl;
c1f246fe 4505 struct device_id_list *dil;
f1a000a4
DT
4506 const char *pv_name;
4507 int process_pv;
0ab11877 4508 int do_report_ret_code = 1;
f1a000a4
DT
4509 int ret_max = ECMD_PROCESSED;
4510 int ret = 0;
4511
6ca28ca4
PR
4512 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_PV);
4513
4514 vg_uuid[0] = '\0';
4515 if (!id_write_format(&vg->id, vg_uuid, sizeof(vg_uuid)))
4516 stack;
4517
f752a953 4518 if (!handle && (!(handle = init_processing_handle(cmd, NULL)))) {
56011918
PR
4519 ret_max = ECMD_FAILED;
4520 goto_out;
4521 }
4522
4523 if (handle->internal_report_for_select && !handle->selection_handle &&
7f2eebf5 4524 !init_selection_handle(cmd, handle, PVS)) {
56011918
PR
4525 ret_max = ECMD_FAILED;
4526 goto_out;
4527 }
4528
cee1aedf
PR
4529 if (!is_orphan_vg(vg->name))
4530 log_set_report_object_group_and_group_id(vg->name, vg_uuid);
6ca28ca4 4531
f1a000a4 4532 dm_list_iterate_items(pvl, &vg->pvs) {
6ca28ca4
PR
4533 pv = pvl->pv;
4534 pv_name = pv_dev_name(pv);
4535 pv_uuid[0]='\0';
4536 if (!id_write_format(&pv->id, pv_uuid, sizeof(pv_uuid)))
4537 stack;
4538
4539 log_set_report_object_name_and_id(pv_name, pv_uuid);
4540
56011918
PR
4541 if (sigint_caught()) {
4542 ret_max = ECMD_FAILED;
4543 goto_out;
4544 }
d8923457 4545
3a7c47af 4546 process_pv = process_all_pvs;
b4402bd8 4547 dil = NULL;
f1a000a4 4548
1e4a4d48
DT
4549 /* Remove each arg_devices entry as it is processed. */
4550
b4402bd8 4551 if (arg_devices && !dm_list_empty(arg_devices)) {
c98617c5
DT
4552 if ((dil = device_id_list_find_dev(arg_devices, pv->dev)))
4553 device_id_list_remove(arg_devices, dil->dev);
c1f246fe
DT
4554 }
4555
b4402bd8
DT
4556 if (!process_pv && dil)
4557 process_pv = 1;
4558
f1a000a4
DT
4559 if (!process_pv && !dm_list_empty(arg_tags) &&
4560 str_list_match_list(arg_tags, &pv->tags, NULL))
4561 process_pv = 1;
4562
815f1ee2 4563 process_pv = process_pv && select_match_pv(cmd, handle, vg, pv) && _select_matches(handle);
455ef6f2 4564
b4402bd8
DT
4565 /*
4566 * The command has asked to process a specific PV
4567 * named on the command line, but the VG containing
4568 * that PV cannot be accessed. In this case report
4569 * and return an error. If the inaccessible PV is
4570 * not explicitly named on the command line, it is
4571 * silently skipped.
4572 */
4573 if (process_pv && skip && dil && error_flags) {
4574 if (error_flags & FAILED_EXPORTED)
4575 log_error("Cannot use PV %s in exported VG %s.", pv_name, vg->name);
4576 if (error_flags & FAILED_SYSTEMID)
4577 log_error("Cannot use PV %s in foreign VG %s.", pv_name, vg->name);
4578 if (error_flags & (FAILED_LOCK_TYPE | FAILED_LOCK_MODE))
4579 log_error("Cannot use PV %s in shared VG %s.", pv_name, vg->name);
4580 ret_max = ECMD_FAILED;
4581 }
4582
f1a000a4
DT
4583 if (process_pv) {
4584 if (skip)
38200c20 4585 log_verbose("Skipping PV %s in VG %s.", pv_name, vg->name);
f1a000a4 4586 else
38200c20 4587 log_very_verbose("Processing PV %s in VG %s.", pv_name, vg->name);
f1a000a4 4588
d8923457 4589 if (!skip) {
b622a7fe
DT
4590 ret = process_single_pv(cmd, vg, pv, handle);
4591 if (ret != ECMD_PROCESSED)
d8923457 4592 stack;
0ab11877 4593 report_log_ret_code(ret);
d8923457
ZK
4594 if (ret > ret_max)
4595 ret_max = ret;
4596 }
f1a000a4
DT
4597 }
4598
f1a000a4 4599 /*
1e4a4d48 4600 * When processing only specific PVs, we can quit once they've all been found.
f1a000a4 4601 */
82e6b820
ZK
4602 if (!process_all_pvs && dm_list_empty(arg_tags) &&
4603 (!arg_devices || dm_list_empty(arg_devices)))
f1a000a4 4604 break;
6ca28ca4 4605 log_set_report_object_name_and_id(NULL, NULL);
f1a000a4 4606 }
89914a54 4607
0ab11877 4608 do_report_ret_code = 0;
56011918 4609out:
0ab11877
PR
4610 if (do_report_ret_code)
4611 report_log_ret_code(ret_max);
6ca28ca4
PR
4612 log_set_report_object_name_and_id(NULL, NULL);
4613 log_set_report_object_group_and_group_id(NULL, NULL);
56011918 4614 if (!handle_supplied)
969d2bf4 4615 destroy_processing_handle(cmd, handle);
6ca28ca4
PR
4616 log_restore_report_state(saved_log_report_state);
4617
97b16ec2
AK
4618 return ret_max;
4619}
4620
4621/*
f1a000a4 4622 * Iterate through all PVs in each listed VG. Process a PV if
1e4a4d48
DT
4623 * its dev or tag matches arg_devices or arg_tags. If both
4624 * arg_devices and arg_tags are empty, then process all PVs.
f1a000a4
DT
4625 * No PV should be processed more than once.
4626 *
6fb497ef
DT
4627 * Each PV is removed from arg_devices when it is processed.
4628 * Any names remaining in arg_devices were not found, and
4629 * should produce an error.
97b16ec2 4630 */
1a74171c 4631static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
f1a000a4 4632 struct dm_list *all_vgnameids,
1e4a4d48 4633 struct dm_list *arg_devices,
f1a000a4 4634 struct dm_list *arg_tags,
3a7c47af 4635 int process_all_pvs,
51d96a17 4636 struct processing_handle *handle,
f1a000a4 4637 process_single_pv_fn_t process_single_pv)
97b16ec2 4638{
6ca28ca4
PR
4639 log_report_t saved_log_report_state = log_get_report_state();
4640 char uuid[64] __attribute__((aligned(8)));
f1a000a4 4641 struct volume_group *vg;
ba7ff96f 4642 struct volume_group *error_vg;
f1a000a4 4643 struct vgnameid_list *vgnl;
f1a000a4
DT
4644 const char *vg_name;
4645 const char *vg_uuid;
3ec4813b 4646 uint32_t lockd_state = 0;
ba7ff96f 4647 uint32_t error_flags = 0;
97b16ec2
AK
4648 int ret_max = ECMD_PROCESSED;
4649 int ret;
b622a7fe 4650 int skip;
66248338 4651 int notfound;
bf60cb4d 4652 int is_lockd;
f0768f63 4653 int do_report_ret_code = 1;
97b16ec2 4654
6ca28ca4 4655 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
d8923457 4656
6ca28ca4 4657 dm_list_iterate_items(vgnl, all_vgnameids) {
f1a000a4
DT
4658 vg_name = vgnl->vg_name;
4659 vg_uuid = vgnl->vgid;
b622a7fe 4660 skip = 0;
66248338 4661 notfound = 0;
bf60cb4d 4662 is_lockd = lvmcache_vg_is_lockd_type(cmd, vg_name, vg_uuid);
97b16ec2 4663
6ca28ca4 4664 uuid[0] = '\0';
cee1aedf
PR
4665 if (is_orphan_vg(vg_name)) {
4666 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_ORPHAN);
4667 log_set_report_object_name_and_id(vg_name + sizeof(VG_ORPHANS), uuid);
4668 } else {
4669 if (vg_uuid && !id_write_format((const struct id*)vg_uuid, uuid, sizeof(uuid)))
4670 stack;
4671 log_set_report_object_name_and_id(vg_name, uuid);
4672 }
6ca28ca4
PR
4673
4674 if (sigint_caught()) {
4675 ret_max = ECMD_FAILED;
4676 goto_out;
4677 }
bf60cb4d
DT
4678do_lockd:
4679 if (is_lockd && !lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) {
fe70b03d 4680 ret_max = ECMD_FAILED;
0ab11877 4681 report_log_ret_code(ret_max);
fe70b03d
DT
4682 continue;
4683 }
4684
71671778
DT
4685 log_debug("Processing PVs in VG %s", vg_name);
4686
b4402bd8
DT
4687 error_flags = 0;
4688
ba7ff96f 4689 vg = vg_read(cmd, vg_name, vg_uuid, read_flags, lockd_state, &error_flags, &error_vg);
fae0ed8f
ZK
4690 if (_ignore_vg(cmd, error_flags, error_vg, vg_name, NULL, read_flags, &skip, &notfound) ||
4691 (!vg && !error_vg)) {
d8923457 4692 stack;
aaa6205d 4693 ret_max = ECMD_FAILED;
0ab11877 4694 report_log_ret_code(ret_max);
f27388b5 4695 if (!skip || (!vg && !error_vg))
fe70b03d 4696 goto endvg;
b4402bd8 4697 /* Drop through to eliminate unmpermitted PVs from the devices list */
b622a7fe 4698 }
66248338
DT
4699 if (notfound)
4700 goto endvg;
fae0ed8f 4701
bf60cb4d
DT
4702 if (vg && !is_lockd && vg_is_shared(vg)) {
4703 /* The lock_type changed since label_scan, won't really occur in practice. */
4704 log_debug("Repeat lock and read for local to shared vg");
4705 unlock_and_release_vg(cmd, vg, vg_name);
4706 is_lockd = 1;
4707 goto do_lockd;
4708 }
4709
aaa6205d 4710 /*
ba7ff96f
DT
4711 * Don't call "continue" when skip is set, because we need to remove
4712 * error_vg->pvs entries from devices list.
aaa6205d 4713 */
1b908658 4714
6fb497ef
DT
4715 ret = _process_pvs_in_vg(cmd, vg ? vg : error_vg, arg_devices, arg_tags,
4716 process_all_pvs, skip, error_flags,
3a7c47af 4717 handle, process_single_pv);
b622a7fe
DT
4718 if (ret != ECMD_PROCESSED)
4719 stack;
ba7ff96f 4720
0ab11877 4721 report_log_ret_code(ret);
ba7ff96f 4722
aaa6205d 4723 if (ret > ret_max)
f1a000a4
DT
4724 ret_max = ret;
4725
0d9f3dbd 4726 if (!skip && vg)
a7c45ddc 4727 unlock_vg(cmd, vg, vg->name);
fe70b03d 4728endvg:
ba7ff96f
DT
4729 if (error_vg)
4730 unlock_and_release_vg(cmd, error_vg, vg_name);
fe70b03d 4731 release_vg(vg);
bf60cb4d 4732 if (is_lockd && !lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
ae4db9f3 4733 stack;
b622a7fe 4734
f1a000a4 4735 /* Quit early when possible. */
0ab11877
PR
4736 if (!process_all_pvs && dm_list_empty(arg_tags) && dm_list_empty(arg_devices)) {
4737 do_report_ret_code = 0;
1ac7fde6 4738 goto out;
0ab11877 4739 }
97b16ec2 4740
6ca28ca4
PR
4741 log_set_report_object_name_and_id(NULL, NULL);
4742 }
0ab11877 4743 do_report_ret_code = 0;
6ca28ca4 4744out:
0ab11877
PR
4745 if (do_report_ret_code)
4746 report_log_ret_code(ret_max);
6ca28ca4 4747 log_restore_report_state(saved_log_report_state);
f1a000a4
DT
4748 return ret_max;
4749}
97b16ec2 4750
f1a000a4 4751int process_each_pv(struct cmd_context *cmd,
71671778
DT
4752 int argc, char **argv, const char *only_this_vgname,
4753 int all_is_set, uint32_t read_flags,
51d96a17 4754 struct processing_handle *handle,
f1a000a4
DT
4755 process_single_pv_fn_t process_single_pv)
4756{
6ca28ca4 4757 log_report_t saved_log_report_state = log_get_report_state();
e458fc9a
DT
4758 struct dm_list arg_tags; /* str_list */
4759 struct dm_list arg_pvnames; /* str_list */
c1f246fe 4760 struct dm_list arg_devices; /* device_id_list */
e458fc9a 4761 struct dm_list all_vgnameids; /* vgnameid_list */
c1f246fe 4762 struct device_id_list *dil;
f1a000a4 4763 int process_all_pvs;
6fb497ef 4764 int process_other_devices;
b622a7fe 4765 int ret_max = ECMD_PROCESSED;
f1a000a4 4766 int ret;
97b16ec2 4767
6ca28ca4 4768 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_PV);
71671778
DT
4769 log_debug("Processing each PV");
4770
1a74171c
DT
4771 /*
4772 * When processing a specific VG name, warn if it's inconsistent and
4773 * print an error if it's not found. Otherwise we're processing all
39b7d1ba 4774 * VGs, in which case the command doesn't care if the VG is inconsistent
1a74171c
DT
4775 * or not found; it just wants to skip that VG. (It may be not found
4776 * if it was removed between creating the list of all VGs and then
4777 * processing each VG.
4778 */
4779 if (only_this_vgname)
4780 read_flags |= READ_WARN_INCONSISTENT;
4781 else
4782 read_flags |= READ_OK_NOTFOUND;
4783
fe70b03d
DT
4784 /* Disable error in vg_read so we can print it from ignore_vg. */
4785 cmd->vg_read_print_access_error = 0;
0a19238a 4786
f1a000a4
DT
4787 dm_list_init(&arg_tags);
4788 dm_list_init(&arg_pvnames);
1e4a4d48 4789 dm_list_init(&arg_devices);
f1a000a4 4790 dm_list_init(&all_vgnameids);
97b16ec2 4791
f1a000a4
DT
4792 /*
4793 * Create two lists from argv:
4794 * arg_pvnames: pvs explicitly named in argv
4795 * arg_tags: tags explicitly named in argv
1e4a4d48
DT
4796 *
4797 * Then convert arg_pvnames, which are free-form, user-specified,
4798 * names/paths into arg_devices which can be used to match below.
f1a000a4 4799 */
1e4a4d48 4800 if ((ret = _get_arg_pvnames(cmd, argc, argv, &arg_pvnames, &arg_tags)) != ECMD_PROCESSED) {
6ca28ca4
PR
4801 ret_max = ret;
4802 goto_out;
1e4a4d48 4803 }
97b16ec2 4804
013c0807 4805 if ((cmd->cname->flags & DISALLOW_TAG_ARGS) && !dm_list_empty(&arg_tags)) {
b321d2b1
DT
4806 log_error("Tags cannot be used with this command.");
4807 return ECMD_FAILED;
4808 }
4809
f1a000a4 4810 process_all_pvs = dm_list_empty(&arg_pvnames) && dm_list_empty(&arg_tags);
97b16ec2 4811
6fb497ef 4812 process_other_devices = process_all_pvs && (cmd->cname->flags & ENABLE_ALL_DEVS) && all_is_set;
1e4a4d48 4813
fe70b03d 4814 /* Needed for a current listing of the global VG namespace. */
8c87dda1 4815 if (!only_this_vgname && !lock_global(cmd, "sh")) {
6ca28ca4
PR
4816 ret_max = ECMD_FAILED;
4817 goto_out;
4818 }
fe70b03d 4819
92b4fcf5
DT
4820 if (!(read_flags & PROCESS_SKIP_SCAN)) {
4821 if (!lvmcache_label_scan(cmd)) {
4822 ret_max = ECMD_FAILED;
4823 goto_out;
4824 }
4825 }
92e14227 4826
4bb7d3da 4827 if (!lvmcache_get_vgnameids(cmd, &all_vgnameids, only_this_vgname, 1)) {
6ca28ca4
PR
4828 ret_max = ret;
4829 goto_out;
0d0d5018
DT
4830 }
4831
d86e943b
ZK
4832 if ((ret = _get_arg_devices(cmd, &arg_pvnames, &arg_devices)) != ECMD_PROCESSED) {
4833 /* get_arg_devices reports EINIT_FAILED for any PV names not found. */
4834 ret_max = ret;
4835 if (ret_max == ECMD_FAILED)
4836 goto_out;
236a45df 4837 ret_max = ECMD_FAILED; /* but ATM we've returned FAILED for all cases */
d86e943b 4838 }
19c3851d 4839
6fb497ef
DT
4840 ret = _process_pvs_in_vgs(cmd, read_flags, &all_vgnameids,
4841 &arg_devices, &arg_tags, process_all_pvs,
b622a7fe
DT
4842 handle, process_single_pv);
4843 if (ret != ECMD_PROCESSED)
d3d13e13
DT
4844 stack;
4845 if (ret > ret_max)
4846 ret_max = ret;
4847
4848 /*
6fb497ef
DT
4849 * Process the list of unused duplicate devs to display duplicate PVs
4850 * in two cases: 1. pvs -a (which has traditionally included duplicate
4851 * PVs in addition to the expected non-PV devices), 2. pvs <devname>
4852 * (duplicate dev is named on the command line.)
d3d13e13 4853 */
6fb497ef
DT
4854 if (process_other_devices || !dm_list_empty(&arg_devices)) {
4855 if (!_process_duplicate_pvs(cmd, &arg_devices, process_other_devices, handle, process_single_pv))
4856 ret_max = ECMD_FAILED;
4857 }
f1a000a4 4858
c1f246fe
DT
4859 dm_list_iterate_items(dil, &arg_devices) {
4860 log_error("Failed to find physical volume \"%s\".", dev_name(dil->dev));
1e4a4d48
DT
4861 ret_max = ECMD_FAILED;
4862 }
4863
6fb497ef
DT
4864 /*
4865 * pvs -a and pvdisplay -a want to show devices that are not PVs.
4866 */
4867 if (process_other_devices) {
4868 if (!_process_other_devices(cmd, handle, process_single_pv))
4869 ret_max = ECMD_FAILED;
4870 }
f1a000a4 4871
b622a7fe 4872out:
6ca28ca4 4873 log_restore_report_state(saved_log_report_state);
97b16ec2 4874 return ret_max;
f1a000a4
DT
4875}
4876
4877int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
51d96a17
PR
4878 struct processing_handle *handle,
4879 process_single_pv_fn_t process_single_pv)
f1a000a4 4880{
6ca28ca4
PR
4881 log_report_t saved_log_report_state = log_get_report_state();
4882 char pv_uuid[64] __attribute__((aligned(8)));
4883 char vg_uuid[64] __attribute__((aligned(8)));
de273247 4884 int whole_selected = 0;
f1a000a4
DT
4885 int ret_max = ECMD_PROCESSED;
4886 int ret;
0ab11877 4887 int do_report_ret_code = 1;
f1a000a4 4888 struct pv_list *pvl;
97b16ec2 4889
6ca28ca4
PR
4890 log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_PV);
4891
4892 vg_uuid[0] = '\0';
4893 if (!id_write_format(&vg->id, vg_uuid, sizeof(vg_uuid)))
4894 stack;
4895
cee1aedf
PR
4896 if (!is_orphan_vg(vg->name))
4897 log_set_report_object_group_and_group_id(vg->name, vg_uuid);
6ca28ca4 4898
f1a000a4 4899 dm_list_iterate_items(pvl, &vg->pvs) {
6ca28ca4
PR
4900 pv_uuid[0] = '\0';
4901 if (!id_write_format(&pvl->pv->id, pv_uuid, sizeof(pv_uuid)))
4902 stack;
4903
4904 log_set_report_object_name_and_id(pv_dev_name(pvl->pv), pv_uuid);
4905
4906 if (sigint_caught()) {
4907 ret_max = ECMD_FAILED;
4908 goto_out;
4909 }
513105c6 4910
b622a7fe 4911 ret = process_single_pv(cmd, vg, pvl->pv, handle);
de273247 4912 _update_selection_result(handle, &whole_selected);
b622a7fe
DT
4913 if (ret != ECMD_PROCESSED)
4914 stack;
0ab11877 4915 report_log_ret_code(ret);
513105c6 4916 if (ret > ret_max)
f1a000a4 4917 ret_max = ret;
6ca28ca4
PR
4918
4919 log_set_report_object_name_and_id(NULL, NULL);
f1a000a4
DT
4920 }
4921
de273247 4922 _set_final_selection_result(handle, whole_selected);
0ab11877 4923 do_report_ret_code = 0;
6ca28ca4 4924out:
0ab11877
PR
4925 if (do_report_ret_code)
4926 report_log_ret_code(ret_max);
6ca28ca4 4927 log_restore_report_state(saved_log_report_state);
f1a000a4 4928 return ret_max;
97b16ec2 4929}
f3bb1c01
AK
4930
4931int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
47f8bda0 4932 struct processing_handle *handle)
f3bb1c01 4933{
80fa3511 4934 struct lvremove_params *lp = (handle) ? (struct lvremove_params *) handle->custom_handle : NULL;
47f8bda0 4935
f3bb1c01
AK
4936 /*
4937 * Single force is equivalent to single --yes
4938 * Even multiple --yes are equivalent to single --force
4939 * When we require -ff it cannot be replaced with -f -y
4940 */
4941 force_t force = (force_t) arg_count(cmd, force_ARG)
4942 ? : (arg_is_set(cmd, yes_ARG) ? DONT_PROMPT : PROMPT);
4943
4944 if (!lv_remove_with_dependencies(cmd, lv, force, 0))
4945 return_ECMD_FAILED;
4946
91502446
ZK
4947 if (cmd->scan_lvs && cmd->enable_devices_file && lp)
4948 /* save for removal */
4949 if (!str_list_add(cmd->mem, &lp->removed_uuids,
4950 dm_build_dm_uuid(cmd->mem, UUID_PREFIX, lv->lvid.s, NULL)))
4951 stack;
47f8bda0 4952
f3bb1c01
AK
4953 return ECMD_PROCESSED;
4954}
71671778 4955
a77ded30 4956int pvcreate_params_from_args(struct cmd_context *cmd, struct pvcreate_params *pp)
71671778
DT
4957{
4958 pp->yes = arg_count(cmd, yes_ARG);
4959 pp->force = (force_t) arg_count(cmd, force_ARG);
4960
4961 if (arg_int_value(cmd, labelsector_ARG, 0) >= LABEL_SCAN_SECTORS) {
4962 log_error("labelsector must be less than %lu.",
4963 LABEL_SCAN_SECTORS);
4964 return 0;
71671778
DT
4965 }
4966
0bf836aa
ZK
4967 pp->pva.label_sector = arg_int64_value(cmd, labelsector_ARG,
4968 DEFAULT_LABELSECTOR);
4969
7e671e5d 4970 if (arg_is_set(cmd, metadataignore_ARG))
4de6caf5 4971 pp->pva.metadataignore = arg_int_value(cmd, metadataignore_ARG,
71671778
DT
4972 DEFAULT_PVMETADATAIGNORE);
4973 else
4de6caf5 4974 pp->pva.metadataignore = find_config_tree_bool(cmd, metadata_pvmetadataignore_CFG, NULL);
71671778 4975
7e671e5d 4976 if (arg_is_set(cmd, pvmetadatacopies_ARG) &&
71671778 4977 !arg_int_value(cmd, pvmetadatacopies_ARG, -1) &&
4de6caf5 4978 pp->pva.metadataignore) {
cc03a872 4979 log_error("metadataignore only applies to metadatacopies > 0.");
71671778
DT
4980 return 0;
4981 }
4982
4983 pp->zero = arg_int_value(cmd, zero_ARG, 1);
4984
4985 if (arg_sign_value(cmd, dataalignment_ARG, SIGN_NONE) == SIGN_MINUS) {
4986 log_error("Physical volume data alignment may not be negative.");
4987 return 0;
4988 }
4de6caf5 4989 pp->pva.data_alignment = arg_uint64_value(cmd, dataalignment_ARG, UINT64_C(0));
71671778 4990
4de6caf5 4991 if (pp->pva.data_alignment > UINT32_MAX) {
71671778
DT
4992 log_error("Physical volume data alignment is too big.");
4993 return 0;
4994 }
4995
4996 if (arg_sign_value(cmd, dataalignmentoffset_ARG, SIGN_NONE) == SIGN_MINUS) {
cc03a872 4997 log_error("Physical volume data alignment offset may not be negative.");
71671778
DT
4998 return 0;
4999 }
4de6caf5 5000 pp->pva.data_alignment_offset = arg_uint64_value(cmd, dataalignmentoffset_ARG, UINT64_C(0));
71671778 5001
4de6caf5 5002 if (pp->pva.data_alignment_offset > UINT32_MAX) {
71671778
DT
5003 log_error("Physical volume data alignment offset is too big.");
5004 return 0;
5005 }
5006
4de6caf5
DT
5007 if ((pp->pva.data_alignment + pp->pva.data_alignment_offset) &&
5008 (pp->pva.pe_start != PV_PE_START_CALC)) {
5009 if ((pp->pva.data_alignment ? pp->pva.pe_start % pp->pva.data_alignment : pp->pva.pe_start) != pp->pva.data_alignment_offset) {
71671778 5010 log_warn("WARNING: Ignoring data alignment %s"
cc03a872 5011 " incompatible with restored pe_start value %s.",
4de6caf5
DT
5012 display_size(cmd, pp->pva.data_alignment + pp->pva.data_alignment_offset),
5013 display_size(cmd, pp->pva.pe_start));
5014 pp->pva.data_alignment = 0;
5015 pp->pva.data_alignment_offset = 0;
71671778
DT
5016 }
5017 }
5018
5019 if (arg_sign_value(cmd, metadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
5020 log_error("Metadata size may not be negative.");
5021 return 0;
5022 }
5023
5024 if (arg_sign_value(cmd, bootloaderareasize_ARG, SIGN_NONE) == SIGN_MINUS) {
5025 log_error("Bootloader area size may not be negative.");
5026 return 0;
5027 }
5028
4de6caf5 5029 pp->pva.pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, UINT64_C(0));
904e1e3d 5030 if (!pp->pva.pvmetadatasize) {
4de6caf5 5031 pp->pva.pvmetadatasize = find_config_tree_int(cmd, metadata_pvmetadatasize_CFG, NULL);
904e1e3d
DT
5032 if (!pp->pva.pvmetadatasize)
5033 pp->pva.pvmetadatasize = get_default_pvmetadatasize_sectors();
5034 }
71671778 5035
4de6caf5
DT
5036 pp->pva.pvmetadatacopies = arg_int_value(cmd, pvmetadatacopies_ARG, -1);
5037 if (pp->pva.pvmetadatacopies < 0)
5038 pp->pva.pvmetadatacopies = find_config_tree_int(cmd, metadata_pvmetadatacopies_CFG, NULL);
71671778 5039
4de6caf5 5040 pp->pva.ba_size = arg_uint64_value(cmd, bootloaderareasize_ARG, pp->pva.ba_size);
71671778
DT
5041
5042 return 1;
5043}
5044
5045enum {
5046 PROMPT_PVCREATE_PV_IN_VG = 1,
04d34da7 5047 PROMPT_PVREMOVE_PV_IN_VG = 2,
4f9ff145 5048 PROMPT_PVCREATE_DEV_SIZE = 4,
71671778
DT
5049};
5050
5051enum {
5052 PROMPT_ANSWER_NO = 1,
5053 PROMPT_ANSWER_YES = 2
5054};
5055
5056/*
5057 * When a prompt entry is created, save any strings or info
5058 * in this struct that are needed for the prompt messages.
5059 * The VG/PV structs are not be available when the prompt
5060 * is run.
5061 */
5062struct pvcreate_prompt {
5063 struct dm_list list;
5064 uint32_t type;
4f9ff145
DT
5065 uint64_t size;
5066 uint64_t new_size;
71671778
DT
5067 const char *pv_name;
5068 const char *vg_name;
5069 struct device *dev;
5070 int answer;
5071 unsigned abort_command : 1;
5072 unsigned vg_name_unknown : 1;
5073};
5074
5075struct pvcreate_device {
5076 struct dm_list list;
5077 const char *name;
5078 struct device *dev;
5079 char pvid[ID_LEN + 1];
5080 const char *vg_name;
5081 int wiped;
5082 unsigned is_not_pv : 1; /* device is not a PV */
5083 unsigned is_orphan_pv : 1; /* device is an orphan PV */
5084 unsigned is_vg_pv : 1; /* device is a PV used in a VG */
5085 unsigned is_used_unknown_pv : 1; /* device is a PV used in an unknown VG */
5086};
5087
04d34da7
DT
5088/*
5089 * If a PV is in a VG, and pvcreate or pvremove is run on it:
5090 *
5091 * pvcreate|pvremove -f : fails
5092 * pvcreate|pvremove -y : fails
5093 * pvcreate|pvremove -f -y : fails
5094 * pvcreate|pvremove -ff : get y/n prompt
5095 * pvcreate|pvremove -ff -y : succeeds
5096 *
5097 * FIXME: there are a lot of various phrasings used depending on the
5098 * command and specific case. Find some similar way to phrase these.
5099 */
5100
71671778 5101static void _check_pvcreate_prompt(struct cmd_context *cmd,
a77ded30 5102 struct pvcreate_params *pp,
71671778
DT
5103 struct pvcreate_prompt *prompt,
5104 int ask)
5105{
04d34da7
DT
5106 const char *vgname = prompt->vg_name ? prompt->vg_name : "<unknown>";
5107 const char *pvname = prompt->pv_name;
4f9ff145
DT
5108 int answer_yes = 0;
5109 int answer_no = 0;
04d34da7
DT
5110
5111 /* The VG name can be unknown when the PV is used but metadata is not available */
5112
4f9ff145 5113 if (prompt->type & PROMPT_PVCREATE_PV_IN_VG) {
71671778 5114 if (pp->force != DONT_PROMPT_OVERRIDE) {
4f9ff145 5115 answer_no = 1;
71671778 5116
71671778 5117 if (prompt->vg_name_unknown) {
172bad0d 5118 log_error("PV %s is used by a VG but its metadata is missing.", pvname);
04d34da7 5119 log_error("Can't initialize PV '%s' without -ff.", pvname);
71671778 5120 } else if (!strcmp(command_name(cmd), "pvcreate")) {
04d34da7 5121 log_error("Can't initialize physical volume \"%s\" of volume group \"%s\" without -ff", pvname, vgname);
71671778 5122 } else {
04d34da7
DT
5123 log_error("Physical volume '%s' is already in volume group '%s'", pvname, vgname);
5124 log_error("Unable to add physical volume '%s' to volume group '%s'", pvname, vgname);
71671778
DT
5125 }
5126 } else if (pp->yes) {
4f9ff145 5127 answer_yes = 1;
71671778 5128 } else if (ask) {
04d34da7 5129 if (yes_no_prompt("Really INITIALIZE physical volume \"%s\" of volume group \"%s\" [y/n]? ", pvname, vgname) == 'n') {
4f9ff145 5130 answer_no = 1;
04d34da7 5131 } else {
4f9ff145 5132 answer_yes = 1;
04d34da7
DT
5133 log_warn("WARNING: Forcing physical volume creation on %s of volume group \"%s\"", pvname, vgname);
5134 }
5135 }
71671778 5136
4f9ff145
DT
5137 }
5138
5139 if (prompt->type & PROMPT_PVCREATE_DEV_SIZE) {
5140 if (pp->yes) {
5141 log_warn("WARNING: Faking size of PV %s. Don't write outside real device.", pvname);
5142 answer_yes = 1;
5143 } else if (ask) {
5144 if (prompt->new_size != prompt->size) {
5145 if (yes_no_prompt("WARNING: %s: device size %s does not match requested size %s. Proceed? [y/n]: ", pvname,
48ce8c7a
ZK
5146 display_size(cmd, prompt->size),
5147 display_size(cmd, prompt->new_size)) == 'n') {
4f9ff145
DT
5148 answer_no = 1;
5149 } else {
5150 answer_yes = 1;
5151 log_warn("WARNING: Faking size of PV %s. Don't write outside real device.", pvname);
5152 }
5153 }
5154 }
5155 }
1b908658 5156
4f9ff145 5157 if (prompt->type & PROMPT_PVREMOVE_PV_IN_VG) {
04d34da7 5158 if (pp->force != DONT_PROMPT_OVERRIDE) {
4f9ff145 5159 answer_no = 1;
04d34da7
DT
5160
5161 if (prompt->vg_name_unknown)
172bad0d 5162 log_error("PV %s is used by a VG but its metadata is missing.", pvname);
04d34da7 5163 else
172bad0d 5164 log_error("PV %s is used by VG %s so please use vgreduce first.", pvname, vgname);
04d34da7
DT
5165 log_error("(If you are certain you need pvremove, then confirm by using --force twice.)");
5166 } else if (pp->yes) {
cc03a872 5167 log_warn("WARNING: PV %s is used by VG %s.", pvname, vgname);
4f9ff145 5168 answer_yes = 1;
04d34da7 5169 } else if (ask) {
cc03a872 5170 log_warn("WARNING: PV %s is used by VG %s.", pvname, vgname);
4f9ff145
DT
5171 if (yes_no_prompt("Really WIPE LABELS from physical volume \"%s\" of volume group \"%s\" [y/n]? ", pvname, vgname) == 'n')
5172 answer_no = 1;
5173 else
5174 answer_yes = 1;
71671778 5175 }
4f9ff145 5176 }
04d34da7 5177
4f9ff145 5178 if (answer_yes && answer_no) {
01d5e4d1 5179 log_warn("WARNING: prompt answer yes is overridden by prompt answer no.");
4f9ff145 5180 answer_yes = 0;
71671778 5181 }
4f9ff145
DT
5182
5183 /*
5184 * no answer is valid when not asking the user.
5185 * the caller uses this to check if all the prompts
5186 * can be answered automatically without prompts.
5187 */
5188 if (!ask && !answer_yes && !answer_no)
5189 return;
5190
5191 if (answer_no)
5192 prompt->answer = PROMPT_ANSWER_NO;
5193 else if (answer_yes)
5194 prompt->answer = PROMPT_ANSWER_YES;
5195
5196 /*
5197 * Mostly historical messages. Other messages above could be moved
5198 * here to separate the answer logic from the messages.
5199 */
5200
5201 if ((prompt->type & (PROMPT_PVCREATE_DEV_SIZE | PROMPT_PVCREATE_PV_IN_VG)) &&
5202 (prompt->answer == PROMPT_ANSWER_NO))
5203 log_error("%s: physical volume not initialized.", pvname);
5204
5205 if ((prompt->type & PROMPT_PVREMOVE_PV_IN_VG) &&
5206 (prompt->answer == PROMPT_ANSWER_NO))
5207 log_error("%s: physical volume label not removed.", pvname);
5208
5209 if ((prompt->type & PROMPT_PVREMOVE_PV_IN_VG) &&
5210 (prompt->answer == PROMPT_ANSWER_YES) &&
5211 (pp->force == DONT_PROMPT_OVERRIDE))
5212 log_warn("WARNING: Wiping physical volume label from %s of volume group \"%s\".", pvname, vgname);
71671778
DT
5213}
5214
5215static struct pvcreate_device *_pvcreate_list_find_dev(struct dm_list *devices, struct device *dev)
5216{
5217 struct pvcreate_device *pd;
5218
5219 dm_list_iterate_items(pd, devices) {
5220 if (pd->dev == dev)
5221 return pd;
5222 }
5223
5224 return NULL;
5225}
5226
5227static struct pvcreate_device *_pvcreate_list_find_name(struct dm_list *devices, const char *name)
5228{
5229 struct pvcreate_device *pd;
5230
5231 dm_list_iterate_items(pd, devices) {
5232 if (!strcmp(pd->name, name))
5233 return pd;
5234 }
5235
5236 return NULL;
5237}
5238
d1b7438c
DT
5239static int _pvcreate_check_used(struct cmd_context *cmd,
5240 struct pvcreate_params *pp,
5241 struct pvcreate_device *pd)
71671778 5242{
71671778 5243 struct pvcreate_prompt *prompt;
4f9ff145
DT
5244 uint64_t size = 0;
5245 uint64_t new_size = 0;
5246 int need_size_prompt = 0;
5247 int need_vg_prompt = 0;
d1b7438c
DT
5248 struct lvmcache_info *info;
5249 const char *vgname;
71671778 5250
d1b7438c
DT
5251 log_debug("Checking %s for pvcreate %.32s.",
5252 dev_name(pd->dev), pd->dev->pvid[0] ? pd->dev->pvid : "");
71671778 5253
d1b7438c
DT
5254 if (!pd->dev->pvid[0]) {
5255 log_debug("Check pvcreate arg %s no PVID found", dev_name(pd->dev));
5256 pd->is_not_pv = 1;
5257 return 1;
71671778
DT
5258 }
5259
5260 /*
d1b7438c 5261 * Don't allow using a device with duplicates.
71671778 5262 */
d1b7438c
DT
5263 if (lvmcache_pvid_in_unused_duplicates(pd->dev->pvid)) {
5264 log_error("Cannot use device %s with duplicates.", dev_name(pd->dev));
5265 dm_list_move(&pp->arg_fail, &pd->list);
71671778
DT
5266 return 0;
5267 }
5268
d1b7438c
DT
5269 if (!(info = lvmcache_info_from_pvid(pd->dev->pvid, pd->dev, 0))) {
5270 log_error("Failed to read lvm info for %s PVID %s.", dev_name(pd->dev), pd->dev->pvid);
86f92714 5271 dm_list_move(&pp->arg_fail, &pd->list);
d1b7438c 5272 return 0;
86f92714
DT
5273 }
5274
d1b7438c
DT
5275 vgname = lvmcache_vgname_from_info(info);
5276
71671778
DT
5277 /*
5278 * What kind of device is this: an orphan PV, an uninitialized/unused
5279 * device, a PV used in a VG.
5280 */
d1b7438c 5281 if (vgname && !is_orphan_vg(vgname)) {
71671778 5282 /* Device is a PV used in a VG. */
d1b7438c 5283 log_debug("Check pvcreate arg %s found vg %s.", dev_name(pd->dev), vgname);
71671778 5284 pd->is_vg_pv = 1;
d1b7438c
DT
5285 pd->vg_name = dm_pool_strdup(cmd->mem, vgname);
5286 } else if (!vgname || (vgname && is_orphan_vg(vgname))) {
5287 uint32_t ext_flags = lvmcache_ext_flags(info);
5288 if (ext_flags & PV_EXT_USED) {
71671778 5289 /* Device is used in an unknown VG. */
d1b7438c 5290 log_debug("Check pvcreate arg %s found EXT_USED flag.", dev_name(pd->dev));
71671778
DT
5291 pd->is_used_unknown_pv = 1;
5292 } else {
5293 /* Device is an orphan PV. */
d1b7438c 5294 log_debug("Check pvcreate arg %s is orphan.", dev_name(pd->dev));
71671778
DT
5295 pd->is_orphan_pv = 1;
5296 }
c1cd18f2 5297 pp->orphan_vg_name = FMT_TEXT_ORPHAN_VG_NAME;
71671778
DT
5298 }
5299
4f9ff145
DT
5300 if (arg_is_set(cmd, setphysicalvolumesize_ARG)) {
5301 new_size = arg_uint64_value(cmd, setphysicalvolumesize_ARG, UINT64_C(0));
5302
d1b7438c
DT
5303 if (!dev_get_size(pd->dev, &size)) {
5304 log_error("Can't get device size of %s.", dev_name(pd->dev));
4f9ff145 5305 dm_list_move(&pp->arg_fail, &pd->list);
d1b7438c 5306 return 0;
0bf836aa
ZK
5307 }
5308
5309 if (new_size != size)
4f9ff145
DT
5310 need_size_prompt = 1;
5311 }
5312
71671778
DT
5313 /*
5314 * pvcreate is being run on this device, and it's not a PV,
5315 * or is an orphan PV. Neither case requires a prompt.
4f9ff145
DT
5316 * Or, pvcreate is being run on this device, but the device
5317 * is already a PV in a VG. A prompt or force option is required
5318 * to use it.
71671778 5319 */
4f9ff145
DT
5320 if (pd->is_orphan_pv || pd->is_not_pv)
5321 need_vg_prompt = 0;
5322 else
5323 need_vg_prompt = 1;
5324
d1b7438c 5325 if (!need_size_prompt && !need_vg_prompt)
71671778 5326 return 1;
71671778 5327
71671778 5328 if (!(prompt = dm_pool_zalloc(cmd->mem, sizeof(*prompt)))) {
d1b7438c
DT
5329 dm_list_move(&pp->arg_fail, &pd->list);
5330 return_0;
71671778
DT
5331 }
5332 prompt->dev = pd->dev;
d1b7438c 5333 prompt->pv_name = dm_pool_strdup(cmd->mem, dev_name(pd->dev));
4f9ff145
DT
5334 prompt->size = size;
5335 prompt->new_size = new_size;
872d5922 5336
71671778
DT
5337 if (pd->is_used_unknown_pv)
5338 prompt->vg_name_unknown = 1;
4f9ff145 5339 else if (need_vg_prompt)
d1b7438c 5340 prompt->vg_name = dm_pool_strdup(cmd->mem, vgname);
71671778 5341
4f9ff145
DT
5342 if (need_size_prompt)
5343 prompt->type |= PROMPT_PVCREATE_DEV_SIZE;
5344
5345 if (need_vg_prompt)
5346 prompt->type |= PROMPT_PVCREATE_PV_IN_VG;
5347
5348 dm_list_add(&pp->prompts, &prompt->list);
872d5922 5349
71671778
DT
5350 return 1;
5351}
5352
d1b7438c
DT
5353static int _pvremove_check_used(struct cmd_context *cmd,
5354 struct pvcreate_params *pp,
5355 struct pvcreate_device *pd)
71671778 5356{
04d34da7 5357 struct pvcreate_prompt *prompt;
d1b7438c
DT
5358 struct lvmcache_info *info;
5359 const char *vgname = NULL;
04d34da7 5360
d1b7438c
DT
5361 log_debug("Checking %s for pvremove %.32s.",
5362 dev_name(pd->dev), pd->dev->pvid[0] ? pd->dev->pvid : "");
04d34da7
DT
5363
5364 /*
d1b7438c
DT
5365 * Is there a pv here already?
5366 * If not, this is an error unless you used -f.
04d34da7 5367 */
04d34da7 5368
d1b7438c
DT
5369 if (!pd->dev->pvid[0]) {
5370 log_debug("Check pvremove arg %s no PVID found", dev_name(pd->dev));
5371 if (pp->force)
5372 return 1;
5373 pd->is_not_pv = 1;
04d34da7
DT
5374 }
5375
d1b7438c
DT
5376 if (!(info = lvmcache_info_from_pvid(pd->dev->pvid, pd->dev, 0))) {
5377 if (pp->force)
04d34da7 5378 return 1;
2419345b 5379 log_error("No PV found on device %s.", dev_name(pd->dev));
d1b7438c
DT
5380 dm_list_move(&pp->arg_fail, &pd->list);
5381 return 0;
04d34da7
DT
5382 }
5383
d1b7438c
DT
5384 if (info)
5385 vgname = lvmcache_vgname_from_info(info);
5386
04d34da7
DT
5387 /*
5388 * What kind of device is this: an orphan PV, an uninitialized/unused
5389 * device, a PV used in a VG.
5390 */
5391
f17c2cf7
DT
5392 if (pd->is_not_pv) {
5393 /* Device is not a PV. */
d1b7438c 5394 log_debug("Check pvremove arg %s device is not a PV.", dev_name(pd->dev));
f17c2cf7 5395
d1b7438c 5396 } else if (vgname && !is_orphan_vg(vgname)) {
04d34da7 5397 /* Device is a PV used in a VG. */
d1b7438c 5398 log_debug("Check pvremove arg %s found vg %s.", dev_name(pd->dev), vgname);
04d34da7 5399 pd->is_vg_pv = 1;
d1b7438c 5400 pd->vg_name = dm_pool_strdup(cmd->mem, vgname);
04d34da7 5401
d1b7438c
DT
5402 } else if (info && (!vgname || (vgname && is_orphan_vg(vgname)))) {
5403 uint32_t ext_flags = lvmcache_ext_flags(info);
5404 if (ext_flags & PV_EXT_USED) {
04d34da7 5405 /* Device is used in an unknown VG. */
d1b7438c 5406 log_debug("Check pvremove arg %s found EXT_USED flag.", dev_name(pd->dev));
04d34da7
DT
5407 pd->is_used_unknown_pv = 1;
5408 } else {
5409 /* Device is an orphan PV. */
d1b7438c 5410 log_debug("Check pvremove arg %s is orphan.", dev_name(pd->dev));
04d34da7
DT
5411 pd->is_orphan_pv = 1;
5412 }
c1cd18f2 5413 pp->orphan_vg_name = FMT_TEXT_ORPHAN_VG_NAME;
04d34da7
DT
5414 }
5415
5416 if (pd->is_not_pv) {
d1b7438c 5417 log_error("No PV found on device %s.", dev_name(pd->dev));
04d34da7 5418 dm_list_move(&pp->arg_fail, &pd->list);
d1b7438c 5419 return 0;
04d34da7
DT
5420 }
5421
5422 /*
5423 * pvremove is being run on this device, and it's not a PV,
5424 * or is an orphan PV. Neither case requires a prompt.
5425 */
d1b7438c 5426 if (pd->is_orphan_pv)
04d34da7 5427 return 1;
04d34da7
DT
5428
5429 /*
5430 * pvremove is being run on this device, but the device is in a VG.
5431 * A prompt or force option is required to use it.
5432 */
5433
5434 if (!(prompt = dm_pool_zalloc(cmd->mem, sizeof(*prompt)))) {
d1b7438c
DT
5435 dm_list_move(&pp->arg_fail, &pd->list);
5436 return_0;
04d34da7
DT
5437 }
5438 prompt->dev = pd->dev;
d1b7438c 5439 prompt->pv_name = dm_pool_strdup(cmd->mem, dev_name(pd->dev));
04d34da7
DT
5440 if (pd->is_used_unknown_pv)
5441 prompt->vg_name_unknown = 1;
5442 else
d1b7438c 5443 prompt->vg_name = dm_pool_strdup(cmd->mem, vgname);
4f9ff145 5444 prompt->type |= PROMPT_PVREMOVE_PV_IN_VG;
04d34da7
DT
5445 dm_list_add(&pp->prompts, &prompt->list);
5446
d1b7438c
DT
5447 return 1;
5448}
5449
5450static int _confirm_check_used(struct cmd_context *cmd,
5451 struct pvcreate_params *pp,
5452 struct pvcreate_device *pd)
5453{
5454 struct lvmcache_info *info = NULL;
5455 const char *vgname = NULL;
5456 int is_not_pv = 0;
5457
5458 log_debug("Checking %s to confirm %.32s.",
5459 dev_name(pd->dev), pd->dev->pvid[0] ? pd->dev->pvid : "");
5460
5461 if (!pd->dev->pvid[0]) {
5462 log_debug("Check confirm arg %s no PVID found", dev_name(pd->dev));
5463 is_not_pv = 1;
5464 }
5465
5466 if (!(info = lvmcache_info_from_pvid(pd->dev->pvid, pd->dev, 0))) {
5467 log_debug("Check confirm arg %s no info.", dev_name(pd->dev));
5468 is_not_pv = 1;
5469 }
5470
5471 if (info)
5472 vgname = lvmcache_vgname_from_info(info);
5473
5474
5475 /*
5476 * What kind of device is this: an orphan PV, an uninitialized/unused
5477 * device, a PV used in a VG.
5478 */
5479 if (vgname && !is_orphan_vg(vgname)) {
5480 /* Device is a PV used in a VG. */
5481
5482 if (pd->is_orphan_pv || pd->is_not_pv || pd->is_used_unknown_pv) {
5483 /* In first check it was an orphan or unused. */
5484 goto fail;
5485 }
5486
5487 if (pd->is_vg_pv && pd->vg_name && strcmp(pd->vg_name, vgname)) {
5488 /* In first check it was in a different VG. */
5489 goto fail;
5490 }
5491 } else if (info && (!vgname || is_orphan_vg(vgname))) {
5492 uint32_t ext_flags = lvmcache_ext_flags(info);
5493
5494 /* Device is an orphan PV. */
5495
5496 if (pd->is_not_pv) {
5497 /* In first check it was not a PV. */
5498 goto fail;
5499 }
5500
5501 if (pd->is_vg_pv) {
5502 /* In first check it was in a VG. */
5503 goto fail;
5504 }
5505
5506 if ((ext_flags & PV_EXT_USED) && !pd->is_used_unknown_pv) {
5507 /* In first check it was different. */
5508 goto fail;
5509 }
5510
5511 if (!(ext_flags & PV_EXT_USED) && pd->is_used_unknown_pv) {
5512 /* In first check it was different. */
5513 goto fail;
5514 }
5515 } else if (is_not_pv) {
5516 /* Device is not a PV. */
5517 if (pd->is_orphan_pv || pd->is_used_unknown_pv) {
5518 /* In first check it was an orphan PV. */
5519 goto fail;
5520 }
5521
5522 if (pd->is_vg_pv) {
5523 /* In first check it was in a VG. */
5524 goto fail;
5525 }
5526 }
5527
5528 return 1;
afae3355 5529
d1b7438c
DT
5530fail:
5531 log_error("Cannot use device %s: it changed during prompt.", dev_name(pd->dev));
5532 dm_list_move(&pp->arg_fail, &pd->list);
04d34da7
DT
5533 return 1;
5534}
5535
71671778
DT
5536/*
5537 * This can be used by pvcreate, vgcreate and vgextend to create PVs. The
5538 * callers need to set up the pvcreate_each_params structure based on command
5539 * line args. This includes the pv_names field which specifies the devices to
5540 * create PVs on.
5541 *
71671778
DT
5542 * This function returns 0 (failed) if the caller requires all specified
5543 * devices to be created, and any of those devices are not found, or any of
5544 * them cannot be created.
5545 *
5546 * This function returns 1 (success) if the caller requires all specified
5547 * devices to be created, and all are created, or if the caller does not
5548 * require all specified devices to be created and one or more were created.
2c319398
DT
5549 *
5550 * Process of opening, scanning and filtering:
5551 *
5552 * - label scan and filter all devs
5553 * . open ro
5554 * . standard label scan at the start of command
5555 * . done prior to this function
5556 *
5557 * - label scan and filter dev args
5558 * . label_scan_devs(&scan_devs) in this function
5559 * . open ro
5560 * . uses full md component check
5561 * . typically the first scan and filter of pvcreate devs
5562 *
5563 * - close and reopen dev args
5564 * . open rw and excl
5565 * . done by label_scan_devs_excl
5566 *
5567 * - repeat label scan and filter dev args
5568 * . using reopened rw excl fd
5569 * . since something could have used dev
5570 * in the small window between close and reopen
5571 *
5572 * - wipe and write new headers
5573 * . using reopened rw excl fd
71671778
DT
5574 */
5575
5576int pvcreate_each_device(struct cmd_context *cmd,
5577 struct processing_handle *handle,
a77ded30 5578 struct pvcreate_params *pp)
71671778 5579{
71671778
DT
5580 struct pvcreate_device *pd, *pd2;
5581 struct pvcreate_prompt *prompt, *prompt2;
5582 struct physical_volume *pv;
5583 struct volume_group *orphan_vg;
ba9b7b69 5584 struct dm_list remove_duplicates;
71671778 5585 struct dm_list arg_sort;
2c319398 5586 struct dm_list scan_devs;
6c67c755 5587 struct dm_list rescan_devs;
71671778
DT
5588 struct pv_list *pvl;
5589 struct pv_list *vgpvl;
6c67c755 5590 struct device_list *devl;
96b77716 5591 char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
71671778 5592 const char *pv_name;
0404539e
DT
5593 unsigned int physical_block_size, logical_block_size;
5594 unsigned int prev_pbs = 0, prev_lbs = 0;
013c0807 5595 int must_use_all = (cmd->cname->flags & MUST_USE_ALL_ARGS);
d1b7438c 5596 int unlocked_for_prompts = 0;
71671778 5597 int found;
a3579aaf 5598 unsigned i;
71671778 5599
2d5dc651
DT
5600 set_pv_notify(cmd);
5601
ba9b7b69 5602 dm_list_init(&remove_duplicates);
71671778 5603 dm_list_init(&arg_sort);
2c319398 5604 dm_list_init(&scan_devs);
6c67c755 5605 dm_list_init(&rescan_devs);
71671778
DT
5606
5607 handle->custom_handle = pp;
5608
5609 /*
5610 * Create a list entry for each name arg.
5611 */
5612 for (i = 0; i < pp->pv_count; i++) {
5613 dm_unescape_colons_and_at_signs(pp->pv_names[i], NULL, NULL);
5614
5615 pv_name = pp->pv_names[i];
5616
c65d3797
PR
5617 if (_pvcreate_list_find_name(&pp->arg_devices, pv_name)) {
5618 log_error("Duplicate device name found on input: %s.", pv_name);
5619 return 0;
5620 }
5621
71671778 5622 if (!(pd = dm_pool_zalloc(cmd->mem, sizeof(*pd)))) {
872d5922 5623 log_error("alloc failed.");
71671778
DT
5624 return 0;
5625 }
5626
5627 if (!(pd->name = dm_pool_strdup(cmd->mem, pv_name))) {
872d5922 5628 log_error("strdup failed.");
71671778
DT
5629 return 0;
5630 }
5631
5632 dm_list_add(&pp->arg_devices, &pd->list);
5633 }
5634
1df6769a
DT
5635 /*
5636 * Translate arg names into struct device's.
2c319398
DT
5637 *
5638 * lvmcache_label_scan has already been run by the caller.
5639 * It has likely found and filtered pvremove args, but often
5640 * not pvcreate args, since pvcreate args are not typically PVs
5641 * yet (but may be.)
5642 *
5643 * We call label_scan_devs on the args, using the full
5644 * md filter (the previous scan likely did not use the
5645 * full md filter - we really only need to check the
5646 * command args to ensure they are not md components.)
5647 */
5648
5649 dm_list_iterate_items_safe(pd, pd2, &pp->arg_devices) {
5650 struct device *dev;
5651
5652 /* No filter used here */
00c30698 5653 if (!(dev = dev_cache_get_existing(cmd, pd->name, NULL))) {
2c319398
DT
5654 log_error("No device found for %s.", pd->name);
5655 dm_list_del(&pd->list);
5656 dm_list_add(&pp->arg_fail, &pd->list);
5657 continue;
5658 }
5659
5660 if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
5661 goto bad;
5662
5663 devl->dev = dev;
5664 pd->dev = dev;
5665
5666 dm_list_add(&scan_devs, &devl->list);
5667 }
5668
5669 if (dm_list_empty(&pp->arg_devices))
5670 goto_bad;
5671
5672 /*
5673 * Clear the filtering results from lvmcache_label_scan because we are
5674 * going to rerun the filters and don't want to get the results saved
5675 * by the prior filtering. The filtering in label scan will use full
5676 * md filter.
83fe6e72
DT
5677 *
5678 * We allow pvcreate to look outside devices file here to find
5679 * the target device, in case the user has not added the device
5680 * being pvcreated to the devices file.
2c319398
DT
5681 */
5682 dm_list_iterate_items(devl, &scan_devs)
5683 cmd->filter->wipe(cmd, cmd->filter, devl->dev, NULL);
5684
5685 cmd->use_full_md_check = 1;
5686
350f8845 5687 if (cmd->enable_devices_file && !pp->is_remove)
83fe6e72
DT
5688 cmd->filter_deviceid_skip = 1;
5689
5690 log_debug("Scanning and filtering device args (%u).", dm_list_size(&scan_devs));
2c319398
DT
5691 label_scan_devs(cmd, cmd->filter, &scan_devs);
5692
5693 /*
5694 * Check if the filtering done by label scan excluded any devices.
1df6769a 5695 */
d1b7438c 5696 dm_list_iterate_items_safe(pd, pd2, &pp->arg_devices) {
2c319398 5697 if (!cmd->filter->passes_filter(cmd, cmd->filter, pd->dev, NULL)) {
f8aa073a 5698 log_error("Cannot use %s: %s", pd->name, devname_error_reason(pd->name));
d1b7438c
DT
5699 dm_list_del(&pd->list);
5700 dm_list_add(&pp->arg_fail, &pd->list);
5701 }
5702 }
83fe6e72 5703 cmd->filter_deviceid_skip = 0;
d1b7438c
DT
5704
5705 /*
5706 * Can the command continue if some specified devices were not found?
5707 */
5708 if (must_use_all && !dm_list_empty(&pp->arg_fail)) {
5709 log_error("Command requires all devices to be found.");
5f7a7af7 5710 return 0;
d1b7438c 5711 }
1df6769a 5712
0404539e
DT
5713 /*
5714 * Check for consistent block sizes.
5715 */
5716 if (pp->check_consistent_block_size) {
5717 dm_list_iterate_items(pd, &pp->arg_devices) {
0404539e
DT
5718 logical_block_size = 0;
5719 physical_block_size = 0;
5720
5721 if (!dev_get_direct_block_sizes(pd->dev, &physical_block_size, &logical_block_size)) {
5722 log_warn("WARNING: Unknown block size for device %s.", dev_name(pd->dev));
5723 continue;
5724 }
5725
5726 if (!logical_block_size) {
5727 log_warn("WARNING: Unknown logical_block_size for device %s.", dev_name(pd->dev));
5728 continue;
5729 }
5730
5731 if (!prev_lbs) {
5732 prev_lbs = logical_block_size;
5733 prev_pbs = physical_block_size;
5734 continue;
5735 }
5736
5737 if (prev_lbs == logical_block_size) {
5738 /* Require lbs to match, just warn about unmatching pbs. */
5739 if (!cmd->allow_mixed_block_sizes && prev_pbs && physical_block_size &&
5740 (prev_pbs != physical_block_size))
5741 log_warn("WARNING: Devices have inconsistent physical block sizes (%u and %u).",
5742 prev_pbs, physical_block_size);
5743 continue;
5744 }
5745
5746 if (!cmd->allow_mixed_block_sizes) {
5747 log_error("Devices have inconsistent logical block sizes (%u and %u).",
5748 prev_lbs, logical_block_size);
5749 log_print("See lvm.conf allow_mixed_block_sizes.");
5750 return 0;
5751 }
5752 }
5753 }
5754
d1b7438c
DT
5755 /* check_used moves pd entries into the arg_fail list if pvcreate/pvremove is disallowed */
5756 dm_list_iterate_items_safe(pd, pd2, &pp->arg_devices) {
5757 if (pp->is_remove)
5758 _pvremove_check_used(cmd, pp, pd);
5759 else
5760 _pvcreate_check_used(cmd, pp, pd);
5761 }
71671778
DT
5762
5763 /*
d1b7438c
DT
5764 * If the user specified a uuid for the new PV, check
5765 * if a PV on another dev is already using that uuid.
71671778 5766 */
d1b7438c
DT
5767 if (!pp->is_remove && pp->uuid_str) {
5768 struct device *dev;
96b77716 5769 if ((dev = lvmcache_device_from_pv_id(cmd, &pp->pva.id, NULL))) {
d1b7438c
DT
5770 dm_list_iterate_items_safe(pd, pd2, &pp->arg_devices) {
5771 if (pd->dev != dev) {
5772 log_error("UUID %s already in use on \"%s\".", pp->uuid_str, dev_name(dev));
5773 dm_list_move(&pp->arg_fail, &pd->list);
5774 }
5775 }
5776 }
5777 }
71671778 5778
ba9b7b69
DT
5779 /*
5780 * Special case: pvremove -ff is allowed to clear a duplicate device in
d1b7438c 5781 * the unchosen duplicates list. We save them here and erase them below.
ba9b7b69
DT
5782 */
5783 if (pp->is_remove && (pp->force == DONT_PROMPT_OVERRIDE) &&
677833ce 5784 !dm_list_empty(&pp->arg_devices) && lvmcache_has_duplicate_devs()) {
ba9b7b69 5785 dm_list_iterate_items_safe(pd, pd2, &pp->arg_devices) {
677833ce 5786 if (lvmcache_dev_is_unused_duplicate(pd->dev)) {
d1b7438c 5787 log_debug("Check pvremove arg %s device is a duplicate.", dev_name(pd->dev));
ba9b7b69
DT
5788 dm_list_move(&remove_duplicates, &pd->list);
5789 }
5790 }
5791 }
5792
71671778 5793 /*
d1b7438c 5794 * Any devices not moved to arg_fail can be processed.
71671778 5795 */
d1b7438c 5796 dm_list_splice(&pp->arg_process, &pp->arg_devices);
71671778
DT
5797
5798 /*
5799 * Can the command continue if some specified devices cannot be used?
5800 */
5801 if (!dm_list_empty(&pp->arg_fail) && must_use_all)
5802 goto_bad;
5803
5804 /*
ba9b7b69 5805 * The command cannot continue if there are no devices to process.
71671778 5806 */
ba9b7b69 5807 if (dm_list_empty(&pp->arg_process) && dm_list_empty(&remove_duplicates)) {
04d34da7 5808 log_debug("No devices to process.");
afae3355 5809 goto bad;
71671778
DT
5810 }
5811
5812 /*
1b908658 5813 * Clear any prompts that have answers without asking the user.
71671778
DT
5814 */
5815 dm_list_iterate_items_safe(prompt, prompt2, &pp->prompts) {
5816 _check_pvcreate_prompt(cmd, pp, prompt, 0);
5817
5818 switch (prompt->answer) {
5819 case PROMPT_ANSWER_YES:
5820 /* The PV can be used, leave it on arg_process. */
5821 dm_list_del(&prompt->list);
5822 break;
5823 case PROMPT_ANSWER_NO:
5824 /* The PV cannot be used, remove it from arg_process. */
5825 if ((pd = _pvcreate_list_find_dev(&pp->arg_process, prompt->dev)))
5826 dm_list_move(&pp->arg_fail, &pd->list);
5827 dm_list_del(&prompt->list);
5828 break;
5829 }
5830 }
5831
5832 if (!dm_list_empty(&pp->arg_fail) && must_use_all)
5833 goto_bad;
5834
5835 /*
5836 * If no remaining prompts need a user response, then keep orphans
1b908658 5837 * locked and go directly to the create steps.
71671778
DT
5838 */
5839 if (dm_list_empty(&pp->prompts))
5840 goto do_command;
5841
5842 /*
c4153a8d
DT
5843 * Prompts require asking the user and make take some time, during
5844 * which we don't want to block other commands. So, release the lock
5845 * to prevent blocking other commands while we wait. After a response
5846 * from the user, reacquire the lock, verify that the PVs were not used
5847 * during the wait, then do the create steps.
71671778 5848 */
8c87dda1
DT
5849
5850 lockf_global(cmd, "un");
71671778 5851
d1b7438c
DT
5852 unlocked_for_prompts = 1;
5853
71671778 5854 /*
d1b7438c 5855 * Process prompts that require asking the user. The global lock is
71671778
DT
5856 * not held, so there's no harm in waiting for a user to respond.
5857 */
5858 dm_list_iterate_items_safe(prompt, prompt2, &pp->prompts) {
5859 _check_pvcreate_prompt(cmd, pp, prompt, 1);
5860
5861 switch (prompt->answer) {
5862 case PROMPT_ANSWER_YES:
5863 /* The PV can be used, leave it on arg_process. */
5864 dm_list_del(&prompt->list);
5865 break;
5866 case PROMPT_ANSWER_NO:
5867 /* The PV cannot be used, remove it from arg_process. */
5868 if ((pd = _pvcreate_list_find_dev(&pp->arg_process, prompt->dev)))
5869 dm_list_move(&pp->arg_fail, &pd->list);
5870 dm_list_del(&prompt->list);
5871 break;
5872 }
5873
5874 if (!dm_list_empty(&pp->arg_fail) && must_use_all)
ee6519f8 5875 goto_bad;
71671778
DT
5876
5877 if (sigint_caught())
ee6519f8 5878 goto_bad;
71671778
DT
5879
5880 if (prompt->abort_command)
ee6519f8 5881 goto_bad;
71671778
DT
5882 }
5883
5884 /*
c4153a8d 5885 * Reacquire the lock that was released above before waiting, then
d1b7438c 5886 * check again that the devices can still be used. If the second check
c4153a8d 5887 * finds them changed, or can't find them any more, then they aren't
20374760
DT
5888 * used. Use a non-blocking request when reacquiring to avoid
5889 * potential deadlock since this is not the normal locking sequence.
71671778 5890 */
8c87dda1 5891
20374760 5892 if (!lockf_global_nonblock(cmd, "ex")) {
8c87dda1 5893 log_error("Failed to reacquire global lock after prompt.");
ee6519f8 5894 goto bad;
71671778
DT
5895 }
5896
71671778
DT
5897do_command:
5898
6c67c755
DT
5899 dm_list_iterate_items(pd, &pp->arg_process) {
5900 if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
5901 goto bad;
5902 devl->dev = pd->dev;
5903 dm_list_add(&rescan_devs, &devl->list);
5904 }
5905
2c319398
DT
5906 /*
5907 * We want label_scan excl to repeat the filter check in case something
5908 * changed to filter out a dev before we were able to get exclusive.
5909 */
5910 dm_list_iterate_items(devl, &rescan_devs)
5911 cmd->filter->wipe(cmd, cmd->filter, devl->dev, NULL);
5912
350f8845 5913 if (cmd->enable_devices_file && !pp->is_remove)
83fe6e72
DT
5914 cmd->filter_deviceid_skip = 1;
5915
2c319398
DT
5916 log_debug("Rescanning and filtering device args with exclusive open");
5917 if (!label_scan_devs_excl(cmd, cmd->filter, &rescan_devs)) {
6c67c755
DT
5918 log_debug("Failed to rescan devs excl");
5919 goto bad;
5920 }
5921
2c319398
DT
5922 dm_list_iterate_items_safe(pd, pd2, &pp->arg_process) {
5923 if (!cmd->filter->passes_filter(cmd, cmd->filter, pd->dev, NULL)) {
f8aa073a 5924 log_error("Cannot use %s: %s", pd->name, devname_error_reason(pd->name));
2c319398
DT
5925 dm_list_del(&pd->list);
5926 dm_list_add(&pp->arg_fail, &pd->list);
5927 }
5928 }
83fe6e72 5929 cmd->filter_deviceid_skip = 0;
2c319398
DT
5930
5931 if (dm_list_empty(&pp->arg_process) && dm_list_empty(&remove_duplicates)) {
5932 log_debug("No devices to process.");
5933 goto bad;
5934 }
5935
5936 if (!dm_list_empty(&pp->arg_fail) && must_use_all)
5937 goto_bad;
5938
d1b7438c
DT
5939 /*
5940 * If the global lock was unlocked to wait for prompts, then
5941 * devs could have changed while unlocked, so confirm that
5942 * the devs are unchanged since check_used.
5943 * Changed pd entries are moved to arg_fail.
5944 */
5945 if (unlocked_for_prompts) {
5946 dm_list_iterate_items_safe(pd, pd2, &pp->arg_process)
5947 _confirm_check_used(cmd, pp, pd);
5948
5949 if (!dm_list_empty(&pp->arg_fail) && must_use_all)
5950 goto_bad;
5951 }
5952
5953 if (dm_list_empty(&pp->arg_process)) {
5954 log_debug("No devices to process.");
5955 goto bad;
5956 }
5957
71671778
DT
5958 /*
5959 * Reorder arg_process entries to match the original order of args.
5960 */
5961 dm_list_splice(&arg_sort, &pp->arg_process);
5962 for (i = 0; i < pp->pv_count; i++) {
5963 if ((pd = _pvcreate_list_find_name(&arg_sort, pp->pv_names[i])))
5964 dm_list_move(&pp->arg_process, &pd->list);
5965 }
5966
04d34da7
DT
5967 if (pp->is_remove)
5968 dm_list_splice(&pp->arg_remove, &pp->arg_process);
5969 else
5970 dm_list_splice(&pp->arg_create, &pp->arg_process);
71671778
DT
5971
5972 /*
5973 * Wipe signatures on devices being created.
5974 */
5975 dm_list_iterate_items_safe(pd, pd2, &pp->arg_create) {
872d5922 5976 log_verbose("Wiping signatures on new PV %s.", pd->name);
71671778
DT
5977
5978 if (!wipe_known_signatures(cmd, pd->dev, pd->name, TYPE_LVM1_MEMBER | TYPE_LVM2_MEMBER,
5979 0, pp->yes, pp->force, &pd->wiped)) {
5980 dm_list_move(&pp->arg_fail, &pd->list);
5981 }
5982
5983 if (sigint_caught())
5984 goto_bad;
5985 }
5986
5987 if (!dm_list_empty(&pp->arg_fail) && must_use_all)
5988 goto_bad;
5989
5990 /*
5991 * Find existing orphan PVs that vgcreate or vgextend want to use.
5992 * "preserve_existing" means that the command wants to use existing PVs
5993 * and not recreate a new PV on top of an existing PV.
5994 */
5995 if (pp->preserve_existing && pp->orphan_vg_name) {
872d5922 5996 log_debug("Using existing orphan PVs in %s.", pp->orphan_vg_name);
71671778 5997
ba7ff96f 5998 if (!(orphan_vg = vg_read_orphans(cmd, pp->orphan_vg_name))) {
872d5922 5999 log_error("Cannot read orphans VG %s.", pp->orphan_vg_name);
1d58074d 6000 goto bad;
71671778
DT
6001 }
6002
6003 dm_list_iterate_items_safe(pd, pd2, &pp->arg_create) {
6004 if (!pd->is_orphan_pv)
6005 continue;
6006
6007 if (!(pvl = dm_pool_alloc(cmd->mem, sizeof(*pvl)))) {
872d5922 6008 log_error("alloc pvl failed.");
71671778
DT
6009 dm_list_move(&pp->arg_fail, &pd->list);
6010 continue;
6011 }
6012
6013 found = 0;
6014 dm_list_iterate_items(vgpvl, &orphan_vg->pvs) {
6015 if (vgpvl->pv->dev == pd->dev) {
6016 found = 1;
6017 break;
6018 }
6019 }
6020
6021 if (found) {
872d5922 6022 log_debug("Using existing orphan PV %s.", pv_dev_name(vgpvl->pv));
71671778
DT
6023 pvl->pv = vgpvl->pv;
6024 dm_list_add(&pp->pvs, &pvl->list);
83fe6e72
DT
6025
6026 /* allow deviceidtype_ARG/deviceid_ARG ? */
96b77716 6027 memcpy(pvid, &pvl->pv->id.uuid, ID_LEN);
13c63f0c 6028 device_id_add(cmd, pd->dev, pvid, NULL, NULL, 0);
83fe6e72 6029
71671778
DT
6030 } else {
6031 log_error("Failed to find PV %s", pd->name);
6032 dm_list_move(&pp->arg_fail, &pd->list);
6033 }
6034 }
6035 }
6036
6037 /*
6038 * Create PVs on devices. Either create a new PV on top of an existing
6039 * one (e.g. for pvcreate), or create a new PV on a device that is not
6040 * a PV.
6041 */
6042 dm_list_iterate_items_safe(pd, pd2, &pp->arg_create) {
6043 /* Using existing orphan PVs is covered above. */
6044 if (pp->preserve_existing && pd->is_orphan_pv)
6045 continue;
6046
6047 if (!dm_list_empty(&pp->arg_fail) && must_use_all)
6048 break;
6049
6050 if (!(pvl = dm_pool_alloc(cmd->mem, sizeof(*pvl)))) {
872d5922 6051 log_error("alloc pvl failed.");
71671778 6052 dm_list_move(&pp->arg_fail, &pd->list);
8173c2ff 6053 continue;
71671778
DT
6054 }
6055
6056 pv_name = pd->name;
6057
872d5922 6058 log_debug("Creating a new PV on %s.", pv_name);
71671778 6059
4de6caf5 6060 if (!(pv = pv_create(cmd, pd->dev, &pp->pva))) {
872d5922 6061 log_error("Failed to setup physical volume \"%s\".", pv_name);
71671778
DT
6062 dm_list_move(&pp->arg_fail, &pd->list);
6063 continue;
6064 }
6065
83fe6e72 6066 /* allow deviceidtype_ARG/deviceid_ARG ? */
96b77716 6067 memcpy(pvid, &pv->id.uuid, ID_LEN);
13c63f0c 6068 device_id_add(cmd, pd->dev, pvid, NULL, NULL, 0);
83fe6e72 6069
71671778 6070 log_verbose("Set up physical volume for \"%s\" with %" PRIu64
872d5922 6071 " available sectors.", pv_name, pv_size(pv));
71671778
DT
6072
6073 if (!label_remove(pv->dev)) {
872d5922 6074 log_error("Failed to wipe existing label on %s.", pv_name);
71671778
DT
6075 dm_list_move(&pp->arg_fail, &pd->list);
6076 continue;
6077 }
6078
6079 if (pp->zero) {
872d5922 6080 log_verbose("Zeroing start of device %s.", pv_name);
71671778 6081
e49b114f 6082 if (!dev_write_zeros(pv->dev, 0, 2048)) {
872d5922 6083 log_error("%s not wiped: aborting.", pv_name);
71671778
DT
6084 dm_list_move(&pp->arg_fail, &pd->list);
6085 continue;
872d5922 6086 }
71671778
DT
6087 }
6088
872d5922 6089 log_verbose("Writing physical volume data to disk \"%s\".", pv_name);
71671778
DT
6090
6091 if (!pv_write(cmd, pv, 0)) {
872d5922 6092 log_error("Failed to write physical volume \"%s\".", pv_name);
71671778 6093 dm_list_move(&pp->arg_fail, &pd->list);
045d086a 6094 continue;
71671778
DT
6095 }
6096
872d5922
ZK
6097 log_print_unless_silent("Physical volume \"%s\" successfully created.",
6098 pv_name);
71671778
DT
6099
6100 pvl->pv = pv;
6101 dm_list_add(&pp->pvs, &pvl->list);
6102 }
6103
04d34da7
DT
6104 /*
6105 * Remove PVs from devices for pvremove.
6106 */
6107 dm_list_iterate_items_safe(pd, pd2, &pp->arg_remove) {
04d34da7 6108 if (!label_remove(pd->dev)) {
872d5922 6109 log_error("Failed to wipe existing label(s) on %s.", pd->name);
04d34da7
DT
6110 dm_list_move(&pp->arg_fail, &pd->list);
6111 continue;
6112 }
6113
83fe6e72
DT
6114 device_id_pvremove(cmd, pd->dev);
6115
872d5922 6116 log_print_unless_silent("Labels on physical volume \"%s\" successfully wiped.",
04d34da7
DT
6117 pd->name);
6118 }
71671778 6119
ba9b7b69
DT
6120 /*
6121 * Special case: pvremove duplicate PVs (also see above).
6122 */
6123 dm_list_iterate_items_safe(pd, pd2, &remove_duplicates) {
6124 if (!label_remove(pd->dev)) {
6125 log_error("Failed to wipe existing label(s) on %s.", pd->name);
6126 dm_list_move(&pp->arg_fail, &pd->list);
6127 continue;
6128 }
6129
677833ce 6130 lvmcache_del_dev_from_duplicates(pd->dev);
ba9b7b69 6131
83fe6e72
DT
6132 device_id_pvremove(cmd, pd->dev);
6133
ba9b7b69
DT
6134 log_print_unless_silent("Labels on physical volume \"%s\" successfully wiped.",
6135 pd->name);
6136 }
6137
83fe6e72 6138 /* TODO: when vgcreate uses only existing PVs this doesn't change and can be skipped */
75037bee
ZK
6139 if (!device_ids_write(cmd))
6140 stack;
83fe6e72 6141
76321961
DT
6142 /*
6143 * Don't keep devs open excl in bcache because the excl will prevent
6144 * using that dev elsewhere.
6145 */
6146 dm_list_iterate_items(devl, &rescan_devs)
6147 label_scan_invalidate(devl->dev);
6148
71671778 6149 dm_list_iterate_items(pd, &pp->arg_fail)
872d5922
ZK
6150 log_debug("%s: command failed for %s.",
6151 cmd->command->name, pd->name);
71671778
DT
6152
6153 if (!dm_list_empty(&pp->arg_fail))
ee6519f8 6154 goto_bad;
71671778 6155
71671778 6156 return 1;
71671778 6157bad:
71671778
DT
6158 return 0;
6159}
88e0060a
ZK
6160
6161int get_rootvg_dev_uuid(struct cmd_context *cmd, char **dm_uuid_out)
6162{
6163 char dm_uuid[DM_UUID_LEN];
6164 struct stat info;
6165 FILE *fme = NULL;
6166 struct mntent *me;
6167 int found = 0;
6168
6169 if (!(fme = setmntent("/etc/mtab", "r")))
6170 return_0;
6171
6172 while ((me = getmntent(fme))) {
6173 if ((me->mnt_dir[0] == '/') && (me->mnt_dir[1] == '\0')) {
6174 found = 1;
6175 break;
6176 }
6177 }
6178 endmntent(fme);
6179
6180 if (!found)
6181 return_0;
6182
6183 if (stat(me->mnt_dir, &info) < 0)
6184 return_0;
6185
990f4f7c 6186 if (!devno_dm_uuid(cmd, MAJOR(info.st_dev), MINOR(info.st_dev), dm_uuid, sizeof(dm_uuid)))
88e0060a
ZK
6187 return_0;
6188
6189 log_debug("Found root dm_uuid %s", dm_uuid);
6190
6191 /* UUID_PREFIX = "LVM-" */
6192 if (strncmp(dm_uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1))
6193 return_0;
6194
6195 if (strlen(dm_uuid) < sizeof(UUID_PREFIX) - 1 + ID_LEN)
6196 return_0;
6197
6198 *dm_uuid_out = dm_pool_strdup(cmd->mem, dm_uuid);
6199
6200 return 1;
6201}
This page took 1.171536 seconds and 6 git commands to generate.