master - toollib: validate also name
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4e9fbb4b96ad4b...
Commit: 4e9fbb4b96ad4beed5dd004f221cdbfb874e1094
Parent: 68bf974769ff2491f90620d15fd76c42244190a1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Sep 30 21:45:10 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 6 15:18:05 2014 +0200
toollib: validate also name
In validate_lvname_param() call also validate_name().
---
tools/toollib.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index 721c727..69c1c39 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1539,6 +1539,12 @@ int validate_lvname_param(struct cmd_context *cmd, const char **vg_name,
if (!apply_lvname_restrictions(*lv_name))
return_0;
+ if (!validate_name(*lv_name)) {
+ log_error("Logical volume name \"%s\" is invalid.",
+ *lv_name);
+ return 0;
+ }
+
return 1;
}
9 years, 6 months
master - lvcreate: support --cache and --cachepool
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=68bf974769ff24...
Commit: 68bf974769ff2491f90620d15fd76c42244190a1
Parent: fc77e4291bdae39e1ea9dfdf0c8ef9af493df9cb
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Sep 30 21:46:02 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 6 15:18:05 2014 +0200
lvcreate: support --cache and --cachepool
Enable in cmdline options for cache and cachepool.
---
tools/commands.h | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/tools/commands.h b/tools/commands.h
index 1e3677e..ed911fa 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -241,7 +241,10 @@ xx(lvcreate,
"\t[-a|--activate [a|e|l]{y|n}]\n"
"\t[--addtag Tag]\n"
"\t[--alloc AllocationPolicy]\n"
- "\t[--cachemode CacheMode]\n"
+ "\t[-H|--cache\n"
+ "\t [-c|--chunksize ChunkSize]\n"
+ "\t [--cachemode {writeback|writethrough}]\n"
+ "\t[--cachepool CachePoolLogicalVolume{Name|Path}]\n"
"\t[-C|--contiguous {y|n}]\n"
"\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
@@ -263,10 +266,11 @@ xx(lvcreate,
"\t[--[raid]maxrecoveryrate Rate]\n"
"\t[-r|--readahead ReadAheadSectors|auto|none]\n"
"\t[-R|--regionsize MirrorLogRegionSize]\n"
- "\t[-T|--thin [-c|--chunksize ChunkSize]\n"
+ "\t[-T|--thin\n"
+ "\t [-c|--chunksize ChunkSize]\n"
"\t [--discards {ignore|nopassdown|passdown}]\n"
- "\t [--poolmetadatasize MetadataSize[bBsSkKmMgG]]]\n"
- "\t [--poolmetadataspare {y|n}]\n"
+ "\t [--poolmetadatasize MetadataSize[bBsSkKmMgG]]\n"
+ "\t [--poolmetadataspare {y|n}]]\n"
"\t[--thinpool ThinPoolLogicalVolume{Name|Path}]\n"
"\t[-t|--test]\n"
"\t[--type VolumeType]\n"
@@ -312,7 +316,8 @@ xx(lvcreate,
"\t[PhysicalVolumePath...]\n\n",
addtag_ARG, alloc_ARG, autobackup_ARG, activate_ARG, available_ARG,
- cachemode_ARG, chunksize_ARG, contiguous_ARG, corelog_ARG, discards_ARG,
+ cache_ARG, cachemode_ARG, cachepool_ARG,
+ chunksize_ARG, contiguous_ARG, corelog_ARG, discards_ARG,
extents_ARG, ignoreactivationskip_ARG, ignoremonitoring_ARG, major_ARG,
metadataprofile_ARG, minor_ARG, mirrorlog_ARG, mirrors_ARG, monitor_ARG,
minrecoveryrate_ARG, maxrecoveryrate_ARG, name_ARG, nosync_ARG,
9 years, 6 months
master - commands: support shortcut -H for cache objects
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fc77e4291bdae3...
Commit: fc77e4291bdae39e1ea9dfdf0c8ef9af493df9cb
Parent: 1a6c892864c409724bcc0fdd48e325ae1674ae8b
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Sep 29 20:43:11 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 6 15:18:05 2014 +0200
commands: support shortcut -H for cache objects
Introduce cache_long_ARG for those instancies
where --cache is not related to caching LV.
(pvchange,vg|lv|pvscan).
cache_ARG is now with -H shortcut.
---
WHATS_NEW | 1 +
tools/args.h | 3 ++-
tools/commands.h | 6 +++---
tools/lvscan.c | 4 ++--
tools/pvscan.c | 2 +-
tools/vgscan.c | 2 +-
6 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 1ac7750..9847730 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.112 -
=====================================
+ Option --cache has also shortcut -H (i.e. lvcreate -H).
Refactor lvcreate code and better preserve --type argument.
Refactor process_each_vg in toollib.
Pools cannot be used as external origin.
diff --git a/tools/args.h b/tools/args.h
index dc467d2..c1999bd 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -63,7 +63,7 @@ arg(merge_ARG, '\0', "merge", NULL, 0)
arg(monitor_ARG, '\0', "monitor", yes_no_arg, 0)
arg(config_ARG, '\0', "config", string_arg, 0)
arg(trustcache_ARG, '\0', "trustcache", NULL, 0)
-arg(cache_ARG, '\0', "cache", NULL, 0)
+arg(cache_long_ARG, '\0', "cache", NULL, 0)
arg(cachemode_ARG, '\0', "cachemode", string_arg, 0)
arg(cachepool_ARG, '\0', "cachepool", string_arg, 0)
arg(ignoremonitoring_ARG, '\0', "ignoremonitoring", NULL, 0)
@@ -140,6 +140,7 @@ arg(file_ARG, 'f', "file", string_arg, 0)
arg(force_ARG, 'f', "force", NULL, ARG_COUNTABLE)
arg(full_ARG, 'f', "full", NULL, 0)
arg(help_ARG, 'h', "help", NULL, 0)
+arg(cache_ARG, 'H', "cache", NULL, 0)
arg(help2_ARG, '?', "", NULL, 0)
arg(stripesize_ARG, 'I', "stripesize", size_kb_arg, 0)
arg(stripes_ARG, 'i', "stripes", int_arg, 0)
diff --git a/tools/commands.h b/tools/commands.h
index afdf4c3..1e3677e 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -592,7 +592,7 @@ xx(lvscan,
"\t[--version]\n",
all_ARG, blockdevice_ARG, ignorelockingfailure_ARG, partial_ARG,
- readonly_ARG, cache_ARG)
+ readonly_ARG, cache_long_ARG)
xx(pvchange,
"Change attributes of physical volume(s)",
@@ -839,7 +839,7 @@ xx(pvscan,
"\t[-v|--verbose] " "\n"
"\t[--version]\n",
- activate_ARG, available_ARG, backgroundfork_ARG, cache_ARG,
+ activate_ARG, available_ARG, backgroundfork_ARG, cache_long_ARG,
exported_ARG, ignorelockingfailure_ARG, major_ARG, minor_ARG,
novolumegroup_ARG, partial_ARG, readonly_ARG, short_ARG, uuid_ARG)
@@ -1227,7 +1227,7 @@ xx(vgscan,
"\t[-v|--verbose]\n"
"\t[--version]" "\n",
- cache_ARG, ignorelockingfailure_ARG, mknodes_ARG, partial_ARG)
+ cache_long_ARG, ignorelockingfailure_ARG, mknodes_ARG, partial_ARG)
xx(vgsplit,
"Move physical volumes into a new or existing volume group",
diff --git a/tools/lvscan.c b/tools/lvscan.c
index f05fd50..2d7be07 100644
--- a/tools/lvscan.c
+++ b/tools/lvscan.c
@@ -56,7 +56,7 @@ static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv,
const char *active_str, *snapshot_str;
- if (arg_count(cmd, cache_ARG))
+ if (arg_count(cmd, cache_long_ARG))
return _lvscan_single_lvmetad(cmd, lv);
if (!arg_count(cmd, all_ARG) && !lv_is_visible(lv))
@@ -93,7 +93,7 @@ static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv,
int lvscan(struct cmd_context *cmd, int argc, char **argv)
{
- if (argc && !arg_count(cmd, cache_ARG)) {
+ if (argc && !arg_count(cmd, cache_long_ARG)) {
log_error("No additional command line arguments allowed");
return EINVALID_CMD_LINE;
}
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 10e08ba..3eaf0bb 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -327,7 +327,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
uint64_t size_new = 0;
unsigned len;
- if (arg_count(cmd, cache_ARG))
+ if (arg_count(cmd, cache_long_ARG))
return _pvscan_lvmetad(cmd, argc, argv);
if (argc) {
diff --git a/tools/vgscan.c b/tools/vgscan.c
index fff0e89..bca98cc 100644
--- a/tools/vgscan.c
+++ b/tools/vgscan.c
@@ -46,7 +46,7 @@ int vgscan(struct cmd_context *cmd, int argc, char **argv)
cmd->filter->wipe(cmd->filter);
lvmcache_destroy(cmd, 1, 0);
- if (arg_count(cmd, cache_ARG)) {
+ if (arg_count(cmd, cache_long_ARG)) {
if (lvmetad_active()) {
if (!lvmetad_pvscan_all_devs(cmd, NULL))
return ECMD_FAILED;
9 years, 6 months
master - thin: better thin snapshot error detection
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1a6c892864c409...
Commit: 1a6c892864c409724bcc0fdd48e325ae1674ae8b
Parent: 1ef660be460a6dcd876f8077bac9478aca6df3e5
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Oct 6 13:42:59 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 6 15:18:05 2014 +0200
thin: better thin snapshot error detection
While creating thin snapshot, we cannot use size argument.
---
tools/lvcreate.c | 41 +++++++++++++++++++++++++++--------------
1 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 9e2c85c..a3f07f3 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -233,37 +233,50 @@ static int _lvcreate_name_params(struct lvcreate_params *lp,
* Normal snapshot or thinly-provisioned snapshot?
*/
static int _determine_snapshot_type(struct volume_group *vg,
- struct lvcreate_params *lp)
+ struct lvcreate_params *lp)
{
- struct lv_list *lvl;
+ struct logical_volume *lv, *pool_lv = NULL;
- if (!(lvl = find_lv_in_vg(vg, lp->origin))) {
+ if (!(lv = find_lv(vg, lp->origin))) {
log_error("Snapshot origin LV %s not found in Volume group %s.",
lp->origin, vg->name);
return 0;
}
- if (lv_is_cache(lvl->lv)) {
+ if (lv_is_cache(lv)) {
log_error("Snapshot of cache LV is not yet supported.");
return 0;
}
- if (!arg_count(vg->cmd, extents_ARG) && !arg_count(vg->cmd, size_ARG)) {
- if (seg_is_thin(lp)) {
- if (!(lp->segtype = get_segtype_from_string(vg->cmd, "thin")))
- return_0;
- return 1;
+ if (lp->pool) {
+ if (!(pool_lv = find_lv(vg, lp->pool))) {
+ log_error("Thin pool volume %s not found in Volume group %s.",
+ lp->pool, vg->name);
+ return 0;
}
- if (!lv_is_thin_volume(lvl->lv)) {
- log_error("Please specify either size or extents with snapshots.");
+ if (!lv_is_thin_pool(pool_lv)) {
+ log_error("Logical volume %s is not a thin pool volume.",
+ display_lvname(pool_lv));
return 0;
}
+ }
- if (!(lp->segtype = get_segtype_from_string(vg->cmd, "thin")))
- return_0;
+ if (!arg_count(vg->cmd, extents_ARG) && !arg_count(vg->cmd, size_ARG)) {
+ if (lv_is_thin_volume(lv) && !lp->pool)
+ lp->pool = first_seg(lv)->pool_lv->name;
- lp->pool = first_seg(lvl->lv)->pool_lv->name;
+ if (seg_is_thin(lp) || lp->pool) {
+ if (!(lp->segtype = get_segtype_from_string(vg->cmd, "thin")))
+ return_0;
+ return 1;
+ }
+
+ log_error("Please specify either size or extents with snapshots.");
+ return 0;
+ } else if (lp->pool) {
+ log_error("Cannot specify size with thin pool snapshot.");
+ return 0;
}
return 1;
9 years, 6 months
master - thin: lvcreate improve check of thin params
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1ef660be460a6d...
Commit: 1ef660be460a6dcd876f8077bac9478aca6df3e5
Parent: 487723e0dfbaf23236e7ea1415497a8bb394440d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Oct 6 13:13:01 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 6 14:53:16 2014 +0200
thin: lvcreate improve check of thin params
Use arg_from_list_is_set()
Resolve pool_lv at one single place.
Replace use of find_lv_in_vg() with find_lv().
---
tools/lvcreate.c | 47 +++++++++++++++++++++--------------------------
1 files changed, 21 insertions(+), 26 deletions(-)
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index fe405ea..9e2c85c 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -1059,8 +1059,7 @@ static int _lvcreate_params(struct lvcreate_params *lp,
static int _check_thin_parameters(struct volume_group *vg, struct lvcreate_params *lp,
struct lvcreate_cmdline_params *lcp)
{
- struct lv_list *lvl;
- unsigned i;
+ struct logical_volume *pool_lv = NULL;
if (!lp->thin && !lp->create_pool && !lp->snapshot) {
log_error("Please specify device size(s).");
@@ -1072,26 +1071,22 @@ static int _check_thin_parameters(struct volume_group *vg, struct lvcreate_param
return 0;
}
+ if (lp->pool)
+ pool_lv = find_lv(vg, lp->pool);
+
if (!lp->create_pool) {
- static const int _argname[] = {
- alloc_ARG,
- chunksize_ARG,
- contiguous_ARG,
- discards_ARG,
- poolmetadatasize_ARG,
- poolmetadataspare_ARG,
- stripes_ARG,
- stripesize_ARG,
- zero_ARG
- };
-
- for (i = 0; i < DM_ARRAY_SIZE(_argname); ++i) {
- if (arg_count(vg->cmd, _argname[i])) {
- log_error("%s is only available for thin pool creation.",
- arg_long_option_name(_argname[i]));
- return 0;
- }
- }
+ if (arg_from_list_is_set(vg->cmd, "is only available with thin pool creation",
+ alloc_ARG,
+ chunksize_ARG,
+ contiguous_ARG,
+ discards_ARG,
+ poolmetadatasize_ARG,
+ poolmetadataspare_ARG,
+ stripes_ARG,
+ stripesize_ARG,
+ zero_ARG,
+ -1))
+ return_0;
if (lcp->pv_count) {
log_error("Only specify Physical volumes when allocating the thin pool.");
@@ -1103,17 +1098,17 @@ static int _check_thin_parameters(struct volume_group *vg, struct lvcreate_param
return 0;
}
- if (!(lvl = find_lv_in_vg(vg, lp->pool))) {
+ if (!pool_lv) {
log_error("Thin pool %s not found in Volume group %s.", lp->pool, vg->name);
return 0;
}
- if (!lv_is_thin_pool(lvl->lv)) {
- log_error("Logical volume %s is not a thin pool.", lp->pool);
+ if (!lv_is_thin_pool(pool_lv)) {
+ log_error("Logical volume %s is not a thin pool.", display_lvname(pool_lv));
return 0;
}
- } else if (lp->pool && find_lv_in_vg(vg, lp->pool)) {
- log_error("Thin pool %s already exists in Volume group %s.", lp->pool, vg->name);
+ } else if (pool_lv) {
+ log_error("Logical volume %s already exists in Volume group %s.", lp->pool, vg->name);
return 0;
}
9 years, 6 months
master - lvcreate: refactor code
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=487723e0dfbaf2...
Commit: 487723e0dfbaf23236e7ea1415497a8bb394440d
Parent: 072e25a965afdd76145248edea18c3b9e36967df
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Sep 28 22:31:30 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 6 14:52:16 2014 +0200
lvcreate: refactor code
Over the time lvcreate code has accumulated various hacks.
So try to move that code in right places.
Detect all types early in _lvcreate_params() so functions like
_read_size_params() do not need to change volume types.
Also ultimately respect give volume --type, that its shortcut
(-T, H, -m, -s) and after that options which do type estimation.
(i.e. --cachepool, --thinpool)
Avoid repeative tests - if we know all types are decode at once
place we can 'optimize' number of validations.
---
WHATS_NEW | 1 +
tools/lvcreate.c | 163 ++++++++++++++++++++++++++++--------------------------
2 files changed, 86 insertions(+), 78 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index ad7bafb..1ac7750 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.112 -
=====================================
+ Refactor lvcreate code and better preserve --type argument.
Refactor process_each_vg in toollib.
Pools cannot be used as external origin.
Use lv_update_and_reload() for snapshot reload.
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index bb3892d..fe405ea 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -460,6 +460,12 @@ static int _update_extents_params(struct volume_group *vg,
return 1;
}
+/*
+ * Validate various common size arguments
+ *
+ * Note: at this place all volume types needs to be already
+ * identified, do not change them here.
+ */
static int _read_size_params(struct lvcreate_params *lp,
struct lvcreate_cmdline_params *lcp,
struct cmd_context *cmd)
@@ -474,6 +480,12 @@ static int _read_size_params(struct lvcreate_params *lp,
return 0;
}
+ /* poolmetadatasize_ARG is parsed in get_pool_params() */
+ if (!lp->create_pool && arg_count(cmd, poolmetadatasize_ARG)) {
+ log_error("--poolmetadatasize may only be specified when creating pools.");
+ return 0;
+ }
+
if (arg_count(cmd, extents_ARG)) {
if (arg_sign_value(cmd, extents_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error("Negative number of extents is invalid");
@@ -493,38 +505,21 @@ static int _read_size_params(struct lvcreate_params *lp,
lcp->percent = PERCENT_NONE;
}
- /* If size/extents given with thin, then we are creating a thin pool */
- if (seg_is_thin(lp) && (arg_count(cmd, size_ARG) || arg_count(cmd, extents_ARG)))
- lp->create_pool = 1;
-
- if (!lp->create_pool && arg_count(cmd, poolmetadatasize_ARG)) {
- log_error("--poolmetadatasize may only be specified when allocating the pool.");
- return 0;
- }
-
if (arg_count(cmd, virtualsize_ARG)) {
- if (seg_is_thin_pool(lp)) {
- log_error("Virtual size in incompatible with thin_pool segment type.");
+ if (!lp->thin && !lp->snapshot) {
+ log_error("--virtualsize may only be specified when creating thins or virtual snapshots.");
return 0;
}
if (arg_sign_value(cmd, virtualsize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative virtual origin size is invalid");
+ log_error("Negative virtual origin size is invalid.");
return 0;
}
/* Size returned in kilobyte units; held in sectors */
- lp->voriginsize = arg_uint64_value(cmd, virtualsize_ARG,
- UINT64_C(0));
- if (!lp->voriginsize) {
- log_error("Virtual origin size may not be zero");
+ if (!(lp->voriginsize = arg_uint64_value(cmd, virtualsize_ARG,
+ UINT64_C(0)))) {
+ log_error("Virtual origin size may not be zero.");
return 0;
}
- } else {
- /* No virtual size given and no snapshot, so no thin LV to create. */
- if (seg_is_thin_volume(lp) && !lp->snapshot &&
- !(lp->segtype = get_segtype_from_string(cmd, "thin-pool")))
- return_0;
-
- lp->thin = 0;
}
return 1;
@@ -814,15 +809,6 @@ static int _lvcreate_params(struct lvcreate_params *lp,
dm_list_init(&lp->tags);
lp->target_attr = ~0;
- /*
- * Check selected options are compatible and determine segtype
- */
- if ((arg_count(cmd, thin_ARG) || arg_count(cmd, thinpool_ARG)) &&
- arg_count(cmd,mirrors_ARG)) {
- log_error("--thin, --thinpool and --mirrors are incompatible.");
- return 0;
- }
-
/* Set default segtype - remember, '-m 0' implies stripe. */
if (arg_count(cmd, mirrors_ARG) &&
arg_uint_value(cmd, mirrors_ARG, 0))
@@ -832,10 +818,17 @@ static int _lvcreate_params(struct lvcreate_params *lp,
} else {
segtype_str = find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL);
}
- else if (arg_count(cmd, thin_ARG) || arg_count(cmd, thinpool_ARG))
+ else if (arg_count(cmd, snapshot_ARG))
+ segtype_str = "snapshot";
+ else if (arg_count(cmd, cache_ARG))
+ segtype_str = "cache";
+ else if (arg_count(cmd, thin_ARG))
segtype_str = "thin";
- else if (arg_count(cmd, cache_ARG) || arg_count(cmd, cachepool_ARG))
+ /* estimations after valid shortcuts */
+ else if (arg_count(cmd, cachepool_ARG))
segtype_str = "cache";
+ else if (arg_count(cmd, thinpool_ARG))
+ segtype_str = "thin";
else
segtype_str = "striped";
@@ -849,32 +842,74 @@ static int _lvcreate_params(struct lvcreate_params *lp,
return 0;
}
- if ((arg_count(cmd, snapshot_ARG) || seg_is_snapshot(lp)) &&
- arg_count(cmd, thin_ARG)) {
- log_error("--thin and --snapshot are incompatible.");
- return 0;
- }
+ if (seg_is_snapshot(lp) ||
+ (!seg_is_thin(lp) && arg_count(cmd, virtualsize_ARG))) {
+ if (arg_from_list_is_set(cmd, "is unsupported with snapshots",
+ cache_ARG, cachepool_ARG,
+ mirrors_ARG,
+ thin_ARG,
+ zero_ARG,
+ -1))
+ return_0;
+
+ if (seg_is_pool(lp)) {
+ log_error("Snapshots are incompatible with pool segment types.");
+ return 0;
+ }
+
+ if (arg_is_set(cmd, thinpool_ARG) &&
+ (arg_is_set(cmd, extents_ARG) || arg_is_set(cmd, size_ARG))) {
+ log_error("Cannot specify snapshot size and thin pool.");
+ return 0;
+ }
- if (arg_count(cmd, snapshot_ARG) || seg_is_snapshot(lp) ||
- (!seg_is_thin(lp) && arg_count(cmd, virtualsize_ARG)))
lp->snapshot = 1;
+ }
- if (seg_is_pool(lp)) {
- if (lp->snapshot) {
- log_error("Snapshots are incompatible with pool segment_type.");
+ if (seg_is_thin_volume(lp)) {
+ if (arg_is_set(cmd, virtualsize_ARG))
+ lp->thin = 1;
+ else if (arg_is_set(cmd, name_ARG)) {
+ log_error("Missing --virtualsize when specified --name of thin volume.");
return 0;
+ /* When no virtual size -> create thin-pool only */
+ } else if (!(lp->segtype = get_segtype_from_string(cmd, "thin-pool")))
+ return_0;
+
+ /* If size/extents given with thin, then we are creating a thin pool */
+ if (arg_count(cmd, size_ARG) || arg_count(cmd, extents_ARG)) {
+ if (lp->snapshot &&
+ (arg_is_set(cmd, cachepool_ARG) || arg_is_set(cmd, thinpool_ARG))) {
+ log_error("Size or extents cannot be specified with pool name.");
+ return 0;
+ }
+ lp->create_pool = 1;
}
+ } else if (seg_is_pool(lp)) {
+ if (arg_from_list_is_set(cmd, "is unsupported with pool segment type",
+ cache_ARG, mirrors_ARG, snapshot_ARG, thin_ARG,
+ virtualsize_ARG,
+ -1))
+ return_0;
lp->create_pool = 1;
}
- if (seg_is_thin_volume(lp))
- lp->thin = 1;
-
- lp->mirrors = 1;
+ if (seg_is_mirrored(lp) || seg_is_raid(lp)) {
+ /* Note: snapshots have snapshot_ARG or virtualsize_ARG */
+ if (arg_from_list_is_set(cmd, "is unsupported with mirrored segment type",
+ cache_ARG, cachepool_ARG,
+ snapshot_ARG,
+ thin_ARG, thinpool_ARG,
+ virtualsize_ARG,
+ -1))
+ return_0;
+ } else if (arg_from_list_is_set(cmd, "is unsupported without mirrored segment type",
+ corelog_ARG, mirrorlog_ARG, nosync_ARG,
+ -1))
+ return_0;
/* Default to 2 mirrored areas if '--type mirror|raid1|raid10' */
- if (segtype_is_mirrored(lp->segtype))
- lp->mirrors = 2;
+ lp->mirrors = segtype_is_mirrored(lp->segtype) ? 2 : 1;
if (arg_count(cmd, mirrors_ARG)) {
if (arg_sign_value(cmd, mirrors_ARG, SIGN_NONE) == SIGN_MINUS) {
@@ -910,34 +945,6 @@ static int _lvcreate_params(struct lvcreate_params *lp,
}
}
- if (lp->snapshot && arg_count(cmd, zero_ARG)) {
- log_error("-Z is incompatible with snapshots");
- return 0;
- }
-
- if (segtype_is_mirrored(lp->segtype) || segtype_is_raid(lp->segtype)) {
- if (lp->snapshot) {
- log_error("mirrors and snapshots are currently "
- "incompatible");
- return 0;
- }
- } else {
- if (arg_count(cmd, corelog_ARG)) {
- log_error("--corelog is only available with mirrors");
- return 0;
- }
-
- if (arg_count(cmd, mirrorlog_ARG)) {
- log_error("--mirrorlog is only available with mirrors");
- return 0;
- }
-
- if (arg_count(cmd, nosync_ARG)) {
- log_error("--nosync is only available with mirrors");
- return 0;
- }
- }
-
if (activation() && lp->segtype->ops->target_present) {
if (!lp->segtype->ops->target_present(cmd, NULL, &lp->target_attr)) {
log_error("%s: Required device-mapper target(s) not detected in your kernel.",
9 years, 6 months
master - test: Show an activation bug in lvcreate of a cache over raid.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=072e25a965afdd...
Commit: 072e25a965afdd76145248edea18c3b9e36967df
Parent: d2f901f04f76cca110475395272e70c83bea816d
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Mon Oct 6 08:11:42 2014 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Mon Oct 6 08:11:42 2014 +0200
test: Show an activation bug in lvcreate of a cache over raid.
---
test/shell/lvcreate-cache.sh | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/test/shell/lvcreate-cache.sh b/test/shell/lvcreate-cache.sh
index 03ff214..84c9c88 100644
--- a/test/shell/lvcreate-cache.sh
+++ b/test/shell/lvcreate-cache.sh
@@ -104,11 +104,19 @@ done
lvcreate -aey -l 1 -n $lv1 $vg
not lvcreate --type cache -l 2 $vg/$lv1
-
# Option testing
# --chunksize
# --cachepolicy
# --poolmetadatasize
# --poolmetadataspare
+# TODO: creating a cache on top of active RAID appears to be broken
+lvremove -f $vg
+lvcreate -n corigin -m 1 --type raid1 -l 10 $vg
+lvcreate -n cpool --type cache $vg/corigin -l 10
+should check active $vg corigin_corig
+dmsetup table | grep ^$PREFIX | should grep corigin_corig
+lvchange --refresh $vg
+dmsetup table | grep ^$PREFIX | grep corigin_corig
+
vgremove -ff $vg
9 years, 6 months
master - lvconvert: Forward --splitmirror to a cache origin when applicable.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d2f901f04f76cc...
Commit: d2f901f04f76cca110475395272e70c83bea816d
Parent: 91615603cdc7974047103c4c6f6af7e56f97437b
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Mon Oct 6 08:11:06 2014 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Mon Oct 6 08:11:06 2014 +0200
lvconvert: Forward --splitmirror to a cache origin when applicable.
---
test/shell/lvconvert-cache.sh | 14 ++++++++++++++
tools/lvconvert.c | 10 ++++++++++
2 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/test/shell/lvconvert-cache.sh b/test/shell/lvconvert-cache.sh
index 6c2acd9..5979912 100644
--- a/test/shell/lvconvert-cache.sh
+++ b/test/shell/lvconvert-cache.sh
@@ -81,4 +81,18 @@ lvs -a $vg/${lv1}_corig_rimage_0 # ensure images are properly renamed
dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
lvremove -ff $vg
+lvcreate -n corigin -l 10 $vg
+lvcreate -n pool -l 10 $vg
+lvs -a -o +devices
+echo n | not lvconvert --type cache --cachepool $vg/pool $vg/corigin
+lvconvert -y --type cache --cachepool $vg/pool $vg/corigin
+
+lvremove -ff $vg
+
+# TODO: creating a cache on top of active RAID appears to be broken
+lvcreate -n corigin -m 1 --type raid1 -l 10 $vg
+lvcreate -n cpool --type cache $vg/corigin -l 10
+lvchange --refresh $vg # fix up DM tables
+lvconvert --splitmirrors 1 --name split $vg/corigin $dev1
+
vgremove -f $vg
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 09257e3..0d800ec 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -3064,6 +3064,7 @@ static int _lvconvert_cache(struct cmd_context *cmd,
static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
+ struct logical_volume *origin = NULL;
struct lvconvert_params *lp = handle;
struct dm_list *failed_pvs;
@@ -3102,6 +3103,15 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
}
}
+ /* forward splitmirror operations to the cache origin, which may be raid
+ * or old-style mirror */
+ if (arg_count(cmd, splitmirrors_ARG) && lv_is_cache_type(lv)
+ && (origin = seg_lv(first_seg(lv), 0)) && lv_is_cache_origin(origin)) {
+ log_warn("WARNING: Selected operation does not work with cache-type LVs.");
+ log_warn("Proceeding using the cache origin LV %s instead", origin->name);
+ lv = origin;
+ }
+
if (!lp->segtype) {
/* segtype not explicitly set in _read_params */
lp->segtype = first_seg(lv)->segtype;
9 years, 6 months
master - toollib: Rewrite process_each_lv.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=91615603cdc797...
Commit: 91615603cdc7974047103c4c6f6af7e56f97437b
Parent: bfb6a4ecc6ad7bb06649ffd026d9c997443dd684
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Oct 3 23:37:49 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Fri Oct 3 23:37:49 2014 +0100
toollib: Rewrite process_each_lv.
Copy the same form as the new process_each_vg.
Replace unused struct cmd_vg and cmd_vg_read() replicator
code with struct vg and vg_read() directly.
The failed_lvnames arg is no longer used since the
cmd_vg replicator wrapper was removed.
[Committed by agk with cosmetic changes and tweaks.]
---
tools/toollib.c | 643 ++++++++++++++++++++++++++++-------------------------
tools/toollib.h | 3 +-
tools/vgdisplay.c | 2 +-
3 files changed, 340 insertions(+), 308 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index 8049b1f..721c727 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -184,308 +184,6 @@ int ignore_vg(struct volume_group *vg, const char *vg_name, int allow_inconsiste
/*
* Metadata iteration functions
*/
-int process_each_lv_in_vg(struct cmd_context *cmd,
- struct volume_group *vg,
- const struct dm_list *arg_lvnames,
- const struct dm_list *tagsl,
- struct dm_list *failed_lvnames,
- void *handle,
- process_single_lv_fn_t process_single_lv)
-{
- int ret_max = ECMD_PROCESSED;
- int ret;
- unsigned process_all = 0;
- unsigned tags_supplied = 0;
- unsigned lvargs_supplied = 0;
- unsigned lvargs_matched = 0;
- char *lv_name;
- struct lv_list *lvl;
-
- if (!vg_check_status(vg, EXPORTED_VG))
- return ECMD_FAILED;
-
- if (tagsl && !dm_list_empty(tagsl))
- tags_supplied = 1;
-
- if (arg_lvnames && !dm_list_empty(arg_lvnames))
- lvargs_supplied = 1;
-
- /* Process all LVs in this VG if no restrictions given */
- if (!tags_supplied && !lvargs_supplied)
- process_all = 1;
- /* Or if VG tags match */
- else if (tags_supplied &&
- str_list_match_list(tagsl, &vg->tags, NULL))
- process_all = 1;
-
- /*
- * FIXME: In case of remove it goes through deleted entries,
- * but it works since entries are allocated from vg mem pool.
- */
- dm_list_iterate_items(lvl, &vg->lvs) {
- if (lvl->lv->status & SNAPSHOT)
- continue;
-
- /* Skip availability change for non-virt snaps when processing all LVs */
- /* FIXME: pass process_all to process_single_lv() */
- if (process_all && arg_count(cmd, activate_ARG) &&
- lv_is_cow(lvl->lv) && !lv_is_virtual_origin(origin_from_cow(lvl->lv)))
- continue;
-
- if (lv_is_virtual_origin(lvl->lv) && !arg_count(cmd, all_ARG)) {
- if (lvargs_supplied &&
- str_list_match_item(arg_lvnames, lvl->lv->name))
- log_print_unless_silent("Ignoring virtual origin logical volume %s.",
- display_lvname(lvl->lv));
- continue;
- }
-
- /*
- * Only let hidden LVs through it --all was used or the LVs
- * were specifically named on the command line.
- */
- if (!lvargs_supplied && !lv_is_visible(lvl->lv) && !arg_count(cmd, all_ARG))
- continue;
-
- /* LV name match? */
- if (lvargs_supplied &&
- str_list_match_item(arg_lvnames, lvl->lv->name))
- /* Check even when process_all for counter */
- lvargs_matched++;
- /* LV tag match? skip test, when process_all */
- else if (!process_all &&
- (!tags_supplied ||
- !str_list_match_list(tagsl, &lvl->lv->tags, NULL)))
- continue;
-
- if (sigint_caught())
- return_ECMD_FAILED;
-
- lvl->lv->vg->cmd_missing_vgs = 0;
- ret = process_single_lv(cmd, lvl->lv, handle);
- if (ret != ECMD_PROCESSED && failed_lvnames) {
- lv_name = dm_pool_strdup(cmd->mem, lvl->lv->name);
- if (!lv_name ||
- !str_list_add(cmd->mem, failed_lvnames, lv_name)) {
- log_error("Allocation failed for str_list.");
- return ECMD_FAILED;
- }
- if (lvl->lv->vg->cmd_missing_vgs)
- ret = ECMD_PROCESSED;
- }
- if (ret > ret_max)
- ret_max = ret;
- }
-
- if (lvargs_supplied && lvargs_matched != dm_list_size(arg_lvnames)) {
- /*
- * FIXME: lvm supports removal of LV with all its dependencies
- * this leads to miscalculation that depends on the order of args.
- */
- log_error("One or more specified logical volume(s) not found.");
- if (ret_max < ECMD_FAILED)
- ret_max = ECMD_FAILED;
- }
-
- return ret_max;
-}
-
-int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
- uint32_t flags, void *handle,
- process_single_lv_fn_t process_single_lv)
-{
- int opt = 0;
- int ret_max = ECMD_PROCESSED;
- int ret;
-
- struct dm_list *tags_arg;
- struct dm_list *vgnames; /* VGs to process */
- struct dm_str_list *sll, *strl;
- struct cmd_vg *cvl_vg;
- struct dm_list cmd_vgs;
- struct dm_list failed_lvnames;
- struct dm_list tagsl, lvnames;
- struct dm_list arg_lvnames; /* Cmdline vgname or vgname/lvname */
- struct dm_list arg_vgnames;
- char *vglv;
- size_t vglv_sz;
-
- const char *vgname;
-
- dm_list_init(&tagsl);
- dm_list_init(&arg_lvnames);
- dm_list_init(&failed_lvnames);
-
- if (argc) {
- log_verbose("Using logical volume(s) on command line");
- dm_list_init(&arg_vgnames);
-
- for (; opt < argc; opt++) {
- const char *lv_name = argv[opt];
- const char *tmp_lv_name;
- char *vgname_def;
- unsigned dev_dir_found = 0;
-
- /* Do we have a tag or vgname or lvname? */
- vgname = lv_name;
-
- if (*vgname == '@') {
- if (!validate_tag(vgname + 1)) {
- log_error("Skipping invalid tag %s",
- vgname);
- continue;
- }
- if (!str_list_add(cmd->mem, &tagsl,
- dm_pool_strdup(cmd->mem,
- vgname + 1))) {
- log_error("strlist allocation failed");
- return ECMD_FAILED;
- }
- continue;
- }
-
- /* FIXME Jumbled parsing */
- vgname = skip_dev_dir(cmd, vgname, &dev_dir_found);
-
- if (*vgname == '/') {
- log_error("\"%s\": Invalid path for Logical "
- "Volume", argv[opt]);
- if (ret_max < ECMD_FAILED)
- ret_max = ECMD_FAILED;
- continue;
- }
- lv_name = vgname;
- if ((tmp_lv_name = strchr(vgname, '/'))) {
- /* Must be an LV */
- lv_name = tmp_lv_name;
- while (*lv_name == '/')
- lv_name++;
- if (!(vgname = extract_vgname(cmd, vgname))) {
- if (ret_max < ECMD_FAILED) {
- stack;
- ret_max = ECMD_FAILED;
- }
- continue;
- }
- } else if (!dev_dir_found &&
- (vgname_def = default_vgname(cmd))) {
- vgname = vgname_def;
- } else
- lv_name = NULL;
-
- if (!str_list_add(cmd->mem, &arg_vgnames,
- dm_pool_strdup(cmd->mem, vgname))) {
- log_error("strlist allocation failed");
- return ECMD_FAILED;
- }
-
- if (!lv_name) {
- if (!str_list_add(cmd->mem, &arg_lvnames,
- dm_pool_strdup(cmd->mem,
- vgname))) {
- log_error("strlist allocation failed");
- return ECMD_FAILED;
- }
- } else {
- vglv_sz = strlen(vgname) + strlen(lv_name) + 2;
- if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
- dm_snprintf(vglv, vglv_sz, "%s/%s", vgname,
- lv_name) < 0) {
- log_error("vg/lv string alloc failed");
- return ECMD_FAILED;
- }
- if (!str_list_add(cmd->mem, &arg_lvnames, vglv)) {
- log_error("strlist allocation failed");
- return ECMD_FAILED;
- }
- }
- }
- vgnames = &arg_vgnames;
- }
-
- if (!argc || !dm_list_empty(&tagsl)) {
- log_verbose("Finding all logical volumes");
- if (!lvmetad_vg_list_to_lvmcache(cmd))
- stack;
- if (!(vgnames = get_vgnames(cmd, 0)) || dm_list_empty(vgnames)) {
- log_error("No volume groups found");
- return ret_max;
- }
- }
-
- dm_list_iterate_items(strl, vgnames) {
- vgname = strl->str;
- dm_list_init(&cmd_vgs);
- if (!(cvl_vg = cmd_vg_add(cmd->mem, &cmd_vgs,
- vgname, NULL, flags)))
- return_ECMD_FAILED;
-
- if (!cmd_vg_read(cmd, &cmd_vgs)) {
- if (ignore_vg(cvl_vg->vg, vgname, 0, &ret_max))
- stack;
-
- free_cmd_vgs(&cmd_vgs);
- continue;
- }
-
- tags_arg = &tagsl;
- dm_list_init(&lvnames); /* LVs to be processed in this VG */
- dm_list_iterate_items(sll, &arg_lvnames) {
- const char *vg_name = sll->str;
- const char *lv_name = strchr(vg_name, '/');
-
- if ((!lv_name && !strcmp(vg_name, vgname))) {
- /* Process all LVs in this VG */
- tags_arg = NULL;
- dm_list_init(&lvnames);
- break;
- } else if (!strncmp(vg_name, vgname, strlen(vgname)) && lv_name &&
- strlen(vgname) == (size_t) (lv_name - vg_name)) {
- if (!str_list_add(cmd->mem, &lvnames,
- dm_pool_strdup(cmd->mem,
- lv_name + 1))) {
- log_error("strlist allocation failed");
- free_cmd_vgs(&cmd_vgs);
- return ECMD_FAILED;
- }
- }
- }
-
- for (;;) {
- if (sigint_caught())
- return_ECMD_FAILED;
-
- ret = process_each_lv_in_vg(cmd, cvl_vg->vg, &lvnames,
- tags_arg, &failed_lvnames,
- handle, process_single_lv);
- if (ret != ECMD_PROCESSED) {
- stack;
- break;
- }
-
- if (dm_list_empty(&failed_lvnames))
- break;
-
- /* Try again with failed LVs in this VG */
- dm_list_init(&lvnames);
- dm_list_splice(&lvnames, &failed_lvnames);
-
- free_cmd_vgs(&cmd_vgs);
- if (!cmd_vg_read(cmd, &cmd_vgs)) {
- stack;
- ret = ECMD_FAILED; /* break */
- break;
- }
- }
- if (ret > ret_max)
- ret_max = ret;
-
- free_cmd_vgs(&cmd_vgs);
- }
-
- return ret_max;
-}
-
int process_each_segment_in_pv(struct cmd_context *cmd,
struct volume_group *vg,
struct physical_volume *pv,
@@ -2002,8 +1700,8 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t flags,
* Copy the contents of a str_list of VG names to a name list, filling
* in the vgid with NULL (unknown).
*/
-static int _copy_str_to_name_list(struct cmd_context *cmd, struct dm_list *sll,
- struct dm_list *vgnll)
+static int _copy_str_to_vgnameid_list(struct cmd_context *cmd, struct dm_list *sll,
+ struct dm_list *vgnll)
{
const char *vgname;
struct dm_str_list *sl;
@@ -2067,6 +1765,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
}
if (dm_list_empty(&arg_vgnames) && dm_list_empty(&vgnameids_on_system)) {
+ /* FIXME Should be log_print, but suppressed for reporting cmds */
log_error("No volume groups found");
return ECMD_PROCESSED;
}
@@ -2077,7 +1776,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
*/
if (!dm_list_empty(&vgnameids_on_system))
dm_list_splice(&vgnameids_to_process, &vgnameids_on_system);
- else if ((ret = _copy_str_to_name_list(cmd, &arg_vgnames, &vgnameids_to_process)) != ECMD_PROCESSED) {
+ else if ((ret = _copy_str_to_vgnameid_list(cmd, &arg_vgnames, &vgnameids_to_process)) != ECMD_PROCESSED) {
stack;
return ret;
}
@@ -2085,3 +1784,337 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
return _process_vgnameid_list(cmd, flags, &vgnameids_to_process,
&arg_vgnames, &arg_tags, handle, process_single_vg);
}
+
+int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
+ struct dm_list *arg_lvnames, const struct dm_list *tags_in,
+ void *handle, process_single_lv_fn_t process_single_lv)
+{
+ int ret_max = ECMD_PROCESSED;
+ int ret = 0;
+ unsigned process_all = 0;
+ unsigned tags_supplied = 0;
+ unsigned lvargs_supplied = 0;
+ struct lv_list *lvl;
+ struct dm_str_list *sl;
+
+ if (!vg_check_status(vg, EXPORTED_VG))
+ return_ECMD_FAILED;
+
+ if (tags_in && !dm_list_empty(tags_in))
+ tags_supplied = 1;
+
+ if (arg_lvnames && !dm_list_empty(arg_lvnames))
+ lvargs_supplied = 1;
+
+ /* Process all LVs in this VG if no restrictions given
+ * or if VG tags match. */
+ if ((!tags_supplied && !lvargs_supplied) ||
+ (tags_supplied && str_list_match_list(tags_in, &vg->tags, NULL)))
+ process_all = 1;
+
+ /*
+ * FIXME: In case of remove it goes through deleted entries,
+ * but it works since entries are allocated from vg mem pool.
+ */
+ dm_list_iterate_items(lvl, &vg->lvs) {
+ if (lvl->lv->status & SNAPSHOT)
+ continue;
+
+ /* Skip availability change for non-virt snaps when processing all LVs */
+ /* FIXME: pass process_all to process_single_lv() */
+ if (process_all && arg_count(cmd, activate_ARG) &&
+ lv_is_cow(lvl->lv) && !lv_is_virtual_origin(origin_from_cow(lvl->lv)))
+ continue;
+
+ if (lv_is_virtual_origin(lvl->lv) && !arg_count(cmd, all_ARG)) {
+ if (lvargs_supplied &&
+ str_list_match_item(arg_lvnames, lvl->lv->name))
+ log_print_unless_silent("Ignoring virtual origin logical volume %s.",
+ display_lvname(lvl->lv));
+ continue;
+ }
+
+ /*
+ * Only let hidden LVs through it --all was used or the LVs
+ * were specifically named on the command line.
+ */
+ if (!lvargs_supplied && !lv_is_visible(lvl->lv) && !arg_count(cmd, all_ARG))
+ continue;
+
+ /* Only process the LV if the name matches or process_all is set or if an LV tag matches */
+ if (lvargs_supplied && str_list_match_item(arg_lvnames, lvl->lv->name))
+ /* Remove LV from list of unprocessed LV names */
+ str_list_del(arg_lvnames, lvl->lv->name);
+ else if (!process_all &&
+ (!tags_supplied || !str_list_match_list(tags_in, &lvl->lv->tags, NULL)))
+ continue;
+
+ if (sigint_caught())
+ return_ECMD_FAILED;
+
+ log_very_verbose("Processing LV %s in VG %s", lvl->lv->name, vg->name);
+
+ ret = process_single_lv(cmd, lvl->lv, handle);
+
+ if (ret > ret_max)
+ ret_max = ret;
+ }
+
+ if (lvargs_supplied) {
+ /*
+ * FIXME: lvm supports removal of LV with all its dependencies
+ * this leads to miscalculation that depends on the order of args.
+ */
+ dm_list_iterate_items(sl, arg_lvnames) {
+ log_error("Failed to find logical volume \"%s/%s\"",
+ vg->name, sl->str);
+ if (ret_max < ECMD_FAILED)
+ ret_max = ECMD_FAILED;
+ }
+ }
+
+ return ret_max;
+}
+
+/*
+ * If arg is tag, add it to arg_tags
+ * else the arg is either vgname or vgname/lvname:
+ * - add the vgname of each arg to arg_vgnames
+ * - if arg has no lvname, add just vgname arg_lvnames,
+ * it represents all lvs in the vg
+ * - if arg has lvname, add vgname/lvname to arg_lvnames
+ */
+static int _get_arg_lvnames(struct cmd_context *cmd,
+ int argc, char **argv,
+ struct dm_list *arg_vgnames,
+ struct dm_list *arg_lvnames,
+ struct dm_list *arg_tags)
+{
+ int opt = 0;
+ int ret_max = ECMD_PROCESSED;
+ char *vglv;
+ size_t vglv_sz;
+ const char *vgname;
+ const char *lv_name;
+ const char *tmp_lv_name;
+ char *vgname_def;
+ unsigned dev_dir_found;
+
+ log_verbose("Using logical volume(s) on command line");
+
+ for (; opt < argc; opt++) {
+ lv_name = argv[opt];
+ dev_dir_found = 0;
+
+ /* Do we have a tag or vgname or lvname? */
+ vgname = lv_name;
+
+ if (*vgname == '@') {
+ if (!validate_tag(vgname + 1)) {
+ log_error("Skipping invalid tag %s", vgname);
+ continue;
+ }
+ if (!str_list_add(cmd->mem, arg_tags,
+ dm_pool_strdup(cmd->mem, vgname + 1))) {
+ log_error("strlist allocation failed");
+ return ECMD_FAILED;
+ }
+ continue;
+ }
+
+ /* FIXME Jumbled parsing */
+ vgname = skip_dev_dir(cmd, vgname, &dev_dir_found);
+
+ if (*vgname == '/') {
+ log_error("\"%s\": Invalid path for Logical Volume",
+ argv[opt]);
+ if (ret_max < ECMD_FAILED)
+ ret_max = ECMD_FAILED;
+ continue;
+ }
+ lv_name = vgname;
+ if ((tmp_lv_name = strchr(vgname, '/'))) {
+ /* Must be an LV */
+ lv_name = tmp_lv_name;
+ while (*lv_name == '/')
+ lv_name++;
+ if (!(vgname = extract_vgname(cmd, vgname))) {
+ if (ret_max < ECMD_FAILED) {
+ stack;
+ ret_max = ECMD_FAILED;
+ }
+ continue;
+ }
+ } else if (!dev_dir_found &&
+ (vgname_def = default_vgname(cmd)))
+ vgname = vgname_def;
+ else
+ lv_name = NULL;
+
+ if (!str_list_add(cmd->mem, arg_vgnames,
+ dm_pool_strdup(cmd->mem, vgname))) {
+ log_error("strlist allocation failed");
+ return ECMD_FAILED;
+ }
+
+ if (!lv_name) {
+ if (!str_list_add(cmd->mem, arg_lvnames,
+ dm_pool_strdup(cmd->mem, vgname))) {
+ log_error("strlist allocation failed");
+ return ECMD_FAILED;
+ }
+ } else {
+ vglv_sz = strlen(vgname) + strlen(lv_name) + 2;
+ if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
+ dm_snprintf(vglv, vglv_sz, "%s/%s", vgname, lv_name) < 0) {
+ log_error("vg/lv string alloc failed");
+ return ECMD_FAILED;
+ }
+ if (!str_list_add(cmd->mem, arg_lvnames, vglv)) {
+ log_error("strlist allocation failed");
+ return ECMD_FAILED;
+ }
+ }
+ }
+
+ return ret_max;
+}
+
+static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t flags,
+ struct dm_list *vgnameids_to_process,
+ struct dm_list *arg_vgnames,
+ struct dm_list *arg_lvnames,
+ struct dm_list *arg_tags,
+ void *handle,
+ process_single_lv_fn_t process_single_lv)
+{
+ struct volume_group *vg;
+ struct vgnameid_list *nl;
+ struct dm_str_list *sl;
+ struct dm_list *tags_arg;
+ struct dm_list lvnames;
+ const char *vg_name;
+ const char *vg_uuid;
+ const char *vgn;
+ const char *lvn;
+ int ret_max = ECMD_PROCESSED;
+ int ret;
+
+ dm_list_iterate_items(nl, vgnameids_to_process) {
+ vg_name = nl->vg_name;
+ vg_uuid = nl->vgid;
+ ret = 0;
+
+ /*
+ * arg_lvnames contains some elements that are just "vgname"
+ * which means process all lvs in the vg. Other elements
+ * are "vgname/lvname" which means process only the select
+ * lvs in the vg.
+ */
+ tags_arg = arg_tags;
+ dm_list_init(&lvnames); /* LVs to be processed in this VG */
+
+ dm_list_iterate_items(sl, arg_lvnames) {
+ vgn = sl->str;
+ lvn = strchr(vgn, '/');
+
+ if (!lvn && !strcmp(vgn, vg_name)) {
+ /* Process all LVs in this VG */
+ tags_arg = NULL;
+ dm_list_init(&lvnames);
+ break;
+ }
+
+ if (lvn && !strncmp(vgn, vg_name, strlen(vg_name)) &&
+ strlen(vg_name) == (size_t) (lvn - vgn)) {
+ if (!str_list_add(cmd->mem, &lvnames,
+ dm_pool_strdup(cmd->mem, lvn + 1))) {
+ log_error("strlist allocation failed");
+ return ECMD_FAILED;
+ }
+ }
+ }
+
+ vg = vg_read(cmd, vg_name, vg_uuid, flags);
+ if (ignore_vg(vg, vg_name, flags & READ_ALLOW_INCONSISTENT, &ret)) {
+ if (ret > ret_max)
+ ret_max = ret;
+ release_vg(vg);
+ stack;
+ continue;
+ }
+
+ ret = process_each_lv_in_vg(cmd, vg, &lvnames, tags_arg,
+ handle, process_single_lv);
+ unlock_and_release_vg(cmd, vg, vg_name);
+
+ if (ret > ret_max)
+ ret_max = ret;
+
+ if (sigint_caught())
+ break;
+ }
+
+ return ret_max;
+}
+
+/*
+ * Call process_single_lv() for each LV selected by the command line arguments.
+ */
+int process_each_lv(struct cmd_context *cmd, int argc, char **argv, uint32_t flags,
+ void *handle, process_single_lv_fn_t process_single_lv)
+{
+ struct dm_list arg_tags; /* str_list */
+ struct dm_list arg_vgnames; /* str_list */
+ struct dm_list arg_lvnames; /* str_list */
+ struct dm_list vgnameids_on_system; /* vgnameid_list */
+ struct dm_list vgnameids_to_process; /* vgnameid_list */
+
+ int enable_all_vgs = (cmd->command->flags & ALL_VGS_IS_DEFAULT);
+ int ret;
+
+ dm_list_init(&arg_tags);
+ dm_list_init(&arg_vgnames);
+ dm_list_init(&arg_lvnames);
+ dm_list_init(&vgnameids_on_system);
+ dm_list_init(&vgnameids_to_process);
+
+ /*
+ * Find any LVs, VGs or tags explicitly provided on the command line.
+ */
+ if ((ret = _get_arg_lvnames(cmd, argc, argv, &arg_vgnames, &arg_lvnames, &arg_tags) != ECMD_PROCESSED)) {
+ stack;
+ return ret;
+ }
+
+ /*
+ * Obtain the complete list of VGs present on the system if it is needed because:
+ * any tags were supplied and need resolving; or
+ * no VG names were given and the command defaults to processing all VGs.
+ */
+ if (((dm_list_empty(&arg_vgnames) && enable_all_vgs) || !dm_list_empty(&arg_tags)) &&
+ (ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system) != ECMD_PROCESSED)) {
+ stack;
+ return ret;
+ }
+
+ if (dm_list_empty(&arg_vgnames) && dm_list_empty(&vgnameids_on_system)) {
+ /* FIXME Should be log_print, but suppressed for reporting cmds */
+ log_error("No volume groups found");
+ return ECMD_PROCESSED;
+ }
+
+ /*
+ * If we obtained a full list of VGs on the system, we need to work through them all;
+ * otherwise we can merely work through the VG names provided.
+ */
+ if (!dm_list_empty(&vgnameids_on_system))
+ dm_list_splice(&vgnameids_to_process, &vgnameids_on_system);
+ else if ((ret = _copy_str_to_vgnameid_list(cmd, &arg_vgnames, &vgnameids_to_process)) != ECMD_PROCESSED) {
+ stack;
+ return ret;
+ }
+
+ return _process_lv_vgnameid_list(cmd, flags, &vgnameids_to_process, &arg_vgnames, &arg_lvnames,
+ &arg_tags, handle, process_single_lv);
+}
diff --git a/tools/toollib.h b/tools/toollib.h
index 8aa82e0..1a14d60 100644
--- a/tools/toollib.h
+++ b/tools/toollib.h
@@ -86,9 +86,8 @@ int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
int process_each_lv_in_vg(struct cmd_context *cmd,
struct volume_group *vg,
- const struct dm_list *arg_lvnames,
+ struct dm_list *arg_lvnames,
const struct dm_list *tagsl,
- struct dm_list *failed_lvnames,
void *handle,
process_single_lv_fn_t process_single_lv);
diff --git a/tools/vgdisplay.c b/tools/vgdisplay.c
index a739d11..39cdaf3 100644
--- a/tools/vgdisplay.c
+++ b/tools/vgdisplay.c
@@ -39,7 +39,7 @@ static int vgdisplay_single(struct cmd_context *cmd, const char *vg_name,
if (arg_count(cmd, verbose_ARG)) {
vgdisplay_extents(vg);
- process_each_lv_in_vg(cmd, vg, NULL, NULL, NULL, NULL,
+ process_each_lv_in_vg(cmd, vg, NULL, NULL, NULL,
(process_single_lv_fn_t)lvdisplay_full);
log_print("--- Physical volumes ---");
9 years, 6 months
master - toollib: Rewrite process_each_vg.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=bfb6a4ecc6ad7b...
Commit: bfb6a4ecc6ad7bb06649ffd026d9c997443dd684
Parent: 91198ac13e61c66b65884660410311ffc8b8c24e
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Oct 3 20:47:19 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Fri Oct 3 20:47:19 2014 +0100
toollib: Rewrite process_each_vg.
Split VG argument collection from processing.
This allows the two different loops through VGs to
be replaced by a single loop.
Replace unused struct cmd_vg and cmd_vg_read() replicator
code with struct vg and vg_read() directly.
[Committed by agk with cosmetic changes and tweaks.]
---
WHATS_NEW | 1 +
tools/toollib.c | 391 ++++++++++++++++++++++++++++++++++---------------------
2 files changed, 246 insertions(+), 146 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index a94edc6..ad7bafb 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.112 -
=====================================
+ Refactor process_each_vg in toollib.
Pools cannot be used as external origin.
Use lv_update_and_reload() for snapshot reload.
Don't print message in adjusted_mirror_region_size() in activation.
diff --git a/tools/toollib.c b/tools/toollib.c
index c5395ba..8049b1f 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -169,7 +169,9 @@ int ignore_vg(struct volume_group *vg, const char *vg_name, int allow_inconsiste
if ((read_error == FAILED_INCONSISTENT) && allow_inconsistent)
return 0;
- if (read_error == FAILED_CLUSTERED && vg->cmd->ignore_clustered_vgs)
+ if (read_error == FAILED_NOTFOUND)
+ *ret = ECMD_FAILED;
+ else if (read_error == FAILED_CLUSTERED && vg->cmd->ignore_clustered_vgs)
log_verbose("Skipping volume group %s", vg_name);
else {
log_error("Skipping volume group %s", vg_name);
@@ -566,151 +568,6 @@ int process_each_segment_in_lv(struct cmd_context *cmd,
return ret_max;
}
-static int _process_one_vg(struct cmd_context *cmd, const char *vg_name,
- const char *vgid,
- struct dm_list *tagsl, struct dm_list *arg_vgnames,
- uint32_t flags, void *handle, int ret_max,
- process_single_vg_fn_t process_single_vg)
-{
- struct dm_list cmd_vgs;
- struct cmd_vg *cvl_vg;
- int ret = ECMD_PROCESSED;
-
- log_verbose("Finding volume group \"%s\"", vg_name);
-
- dm_list_init(&cmd_vgs);
- if (!(cvl_vg = cmd_vg_add(cmd->mem, &cmd_vgs, vg_name, vgid, flags)))
- return_ECMD_FAILED;
-
- for (;;) {
- if (sigint_caught()) {
- ret = ECMD_FAILED;
- stack;
- break;
- }
-
- if (!cmd_vg_read(cmd, &cmd_vgs)) {
- /* Allow FAILED_INCONSISTENT through only for vgcfgrestore */
- if (ignore_vg(cvl_vg->vg, vg_name, flags & READ_ALLOW_INCONSISTENT, &ret)) {
- stack;
- break;
- }
- }
-
- if (!dm_list_empty(tagsl) &&
- /* Only process if a tag matches or it's on arg_vgnames */
- !str_list_match_item(arg_vgnames, vg_name) &&
- !str_list_match_list(tagsl, &cvl_vg->vg->tags, NULL))
- break;
-
- ret = process_single_vg(cmd, vg_name, cvl_vg->vg, handle);
-
- if (vg_read_error(cvl_vg->vg)) /* FAILED_INCONSISTENT */
- break;
-
- if (!cvl_vg->vg->cmd_missing_vgs)
- break;
-
- free_cmd_vgs(&cmd_vgs);
- }
-
- free_cmd_vgs(&cmd_vgs);
-
- return (ret > ret_max) ? ret : ret_max;
-}
-
-int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
- uint32_t flags, void *handle,
- process_single_vg_fn_t process_single_vg)
-{
- int opt = 0;
- int ret_max = ECMD_PROCESSED;
-
- struct dm_str_list *sl;
- struct dm_list *vgnames, *vgids;
- struct dm_list arg_vgnames, tagsl;
-
- const char *vg_name, *vgid;
-
- dm_list_init(&tagsl);
- dm_list_init(&arg_vgnames);
-
- if (argc) {
- log_verbose("Using volume group(s) on command line");
-
- for (; opt < argc; opt++) {
- vg_name = argv[opt];
- if (*vg_name == '@') {
- if (!validate_tag(vg_name + 1)) {
- log_error("Skipping invalid tag %s",
- vg_name);
- if (ret_max < EINVALID_CMD_LINE)
- ret_max = EINVALID_CMD_LINE;
- continue;
- }
- if (!str_list_add(cmd->mem, &tagsl,
- dm_pool_strdup(cmd->mem,
- vg_name + 1))) {
- log_error("strlist allocation failed");
- return ECMD_FAILED;
- }
- continue;
- }
-
- vg_name = skip_dev_dir(cmd, vg_name, NULL);
- if (strchr(vg_name, '/')) {
- log_error("Invalid volume group name: %s",
- vg_name);
- if (ret_max < EINVALID_CMD_LINE)
- ret_max = EINVALID_CMD_LINE;
- continue;
- }
- if (!str_list_add(cmd->mem, &arg_vgnames,
- dm_pool_strdup(cmd->mem, vg_name))) {
- log_error("strlist allocation failed");
- return ECMD_FAILED;
- }
- }
-
- vgnames = &arg_vgnames;
- }
-
- if (!argc || !dm_list_empty(&tagsl)) {
- log_verbose("Finding all volume groups");
- if (!lvmetad_vg_list_to_lvmcache(cmd))
- stack;
- if (!(vgids = get_vgids(cmd, 0)) || dm_list_empty(vgids)) {
- log_error("No volume groups found");
- return ret_max;
- }
- dm_list_iterate_items(sl, vgids) {
- if (sigint_caught())
- return_ECMD_FAILED;
- vgid = sl->str;
- if (!vgid || !(vg_name = lvmcache_vgname_from_vgid(cmd->mem, vgid)))
- continue;
- ret_max = _process_one_vg(cmd, vg_name, vgid, &tagsl,
- &arg_vgnames,
- flags, handle,
- ret_max, process_single_vg);
- }
- } else {
- dm_list_iterate_items(sl, vgnames) {
- if (sigint_caught())
- return_ECMD_FAILED;
- vg_name = sl->str;
- if (is_orphan_vg(vg_name))
- continue; /* FIXME Unnecessary? */
- ret_max = _process_one_vg(cmd, vg_name, NULL, &tagsl,
- &arg_vgnames,
- flags, handle,
- ret_max, process_single_vg);
- }
- }
-
- return ret_max;
-}
-
int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
const struct dm_list *tagsl, void *handle,
process_single_pv_fn_t process_single_pv)
@@ -1986,3 +1843,245 @@ int validate_lvname_param(struct cmd_context *cmd, const char **vg_name,
return 1;
}
+
+struct vgnameid_list {
+ struct dm_list list;
+ const char *vg_name;
+ const char *vgid;
+};
+
+/*
+ * Extract list of VG names and list of tags from command line arguments.
+ */
+static int _get_arg_vgnames(struct cmd_context *cmd,
+ int argc, char **argv,
+ struct dm_list *arg_vgnames,
+ struct dm_list *arg_tags)
+{
+ int opt = 0;
+ int ret_max = ECMD_PROCESSED;
+ const char *vg_name;
+
+ log_verbose("Using volume group(s) on command line");
+
+ for (; opt < argc; opt++) {
+ vg_name = argv[opt];
+ if (*vg_name == '@') {
+ if (!validate_tag(vg_name + 1)) {
+ log_error("Skipping invalid tag: %s", vg_name);
+ if (ret_max < EINVALID_CMD_LINE)
+ ret_max = EINVALID_CMD_LINE;
+ continue;
+ }
+ if (!str_list_add(cmd->mem, arg_tags,
+ dm_pool_strdup(cmd->mem, vg_name + 1))) {
+ log_error("strlist allocation failed");
+ return ECMD_FAILED;
+ }
+ continue;
+ }
+
+ vg_name = skip_dev_dir(cmd, vg_name, NULL);
+ if (strchr(vg_name, '/')) {
+ log_error("Invalid volume group name: %s", vg_name);
+ if (ret_max < EINVALID_CMD_LINE)
+ ret_max = EINVALID_CMD_LINE;
+ continue;
+ }
+ if (!str_list_add(cmd->mem, arg_vgnames,
+ dm_pool_strdup(cmd->mem, vg_name))) {
+ log_error("strlist allocation failed");
+ return ECMD_FAILED;
+ }
+ }
+
+ return ret_max;
+}
+
+/*
+ * FIXME Add arg to include (or not) entries with duplicate vg names?
+ *
+ * Obtain complete list of VG name/vgid pairs known on the system.
+ */
+static int _get_vgnameids_on_system(struct cmd_context *cmd,
+ struct dm_list *vgnameids_on_system)
+{
+ struct vgnameid_list *vgnl;
+ struct dm_list *vgids;
+ struct dm_str_list *sl;
+ const char *vgid;
+
+ log_verbose("Finding all volume groups");
+
+ if (!lvmetad_vg_list_to_lvmcache(cmd))
+ stack;
+
+ /*
+ * Start with complete vgid list because multiple VGs might have same name.
+ */
+ vgids = get_vgids(cmd, 0);
+ if (!vgids || dm_list_empty(vgids)) {
+ stack;
+ return ECMD_PROCESSED;
+ }
+
+ /* FIXME get_vgids() should provide these pairings directly */
+ dm_list_iterate_items(sl, vgids) {
+ if (!(vgid = sl->str))
+ continue;
+
+ if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
+ log_error("vgnameid_list allocation failed");
+ return ECMD_FAILED;
+ }
+
+ vgnl->vgid = dm_pool_strdup(cmd->mem, vgid);
+ vgnl->vg_name = lvmcache_vgname_from_vgid(cmd->mem, vgid);
+
+ dm_list_add(vgnameids_on_system, &vgnl->list);
+ }
+
+ return ECMD_PROCESSED;
+}
+
+static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t flags,
+ struct dm_list *vgnameids_to_process,
+ struct dm_list *arg_vgnames,
+ struct dm_list *arg_tags, void *handle,
+ process_single_vg_fn_t process_single_vg)
+{
+ struct volume_group *vg;
+ struct vgnameid_list *vgnl;
+ const char *vg_name;
+ const char *vg_uuid;
+ int ret_max = ECMD_PROCESSED;
+ int ret;
+ int process_all = 0;
+
+ /*
+ * If no VG names or tags were supplied, then process all VGs.
+ */
+ if (dm_list_empty(arg_vgnames) && dm_list_empty(arg_tags))
+ process_all = 1;
+
+ dm_list_iterate_items(vgnl, vgnameids_to_process) {
+ vg_name = vgnl->vg_name;
+ vg_uuid = vgnl->vgid;
+ ret = 0;
+
+ vg = vg_read(cmd, vg_name, vg_uuid, flags);
+ if (ignore_vg(vg, vg_name, flags & READ_ALLOW_INCONSISTENT, &ret)) {
+ if (ret > ret_max)
+ ret_max = ret;
+ release_vg(vg);
+ stack;
+ continue;
+ }
+
+ /* Process this VG? */
+ if (process_all ||
+ (!dm_list_empty(arg_vgnames) && str_list_match_item(arg_vgnames, vg_name)) ||
+ (!dm_list_empty(arg_tags) && str_list_match_list(arg_tags, &vg->tags, NULL)))
+ ret = process_single_vg(cmd, vg_name, vg, handle);
+
+ if (vg_read_error(vg))
+ release_vg(vg);
+ else
+ unlock_and_release_vg(cmd, vg, vg_name);
+
+ if (ret > ret_max)
+ ret_max = ret;
+ if (sigint_caught())
+ break;
+ }
+
+ return ret_max;
+}
+
+/*
+ * Copy the contents of a str_list of VG names to a name list, filling
+ * in the vgid with NULL (unknown).
+ */
+static int _copy_str_to_name_list(struct cmd_context *cmd, struct dm_list *sll,
+ struct dm_list *vgnll)
+{
+ const char *vgname;
+ struct dm_str_list *sl;
+ struct vgnameid_list *vgnl;
+
+ dm_list_iterate_items(sl, sll) {
+ vgname = sl->str;
+
+ vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl));
+ if (!vgnl) {
+ log_error("vgnameid_list allocation failed");
+ return ECMD_FAILED;
+ }
+
+ vgnl->vgid = NULL;
+ vgnl->vg_name = dm_pool_strdup(cmd->mem, vgname);
+
+ dm_list_add(vgnll, &vgnl->list);
+ }
+
+ return ECMD_PROCESSED;
+}
+
+/*
+ * Call process_single_vg() for each VG selected by the command line arguments.
+ */
+int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
+ uint32_t flags, void *handle,
+ process_single_vg_fn_t process_single_vg)
+{
+ struct dm_list arg_tags; /* str_list */
+ struct dm_list arg_vgnames; /* str_list */
+ struct dm_list vgnameids_on_system; /* vgnameid_list */
+ struct dm_list vgnameids_to_process; /* vgnameid_list */
+
+ int enable_all_vgs = (cmd->command->flags & ALL_VGS_IS_DEFAULT);
+ int ret;
+
+ dm_list_init(&arg_tags);
+ dm_list_init(&arg_vgnames);
+ dm_list_init(&vgnameids_on_system);
+ dm_list_init(&vgnameids_to_process);
+
+ /*
+ * Find any VGs or tags explicitly provided on the command line.
+ */
+ if ((ret = _get_arg_vgnames(cmd, argc, argv, &arg_vgnames, &arg_tags)) != ECMD_PROCESSED) {
+ stack;
+ return ret;
+ }
+
+ /*
+ * Obtain the complete list of VGs present on the system if it is needed because:
+ * any tags were supplied and need resolving; or
+ * no VG names were given and the command defaults to processing all VGs.
+ */
+ if (((dm_list_empty(&arg_vgnames) && enable_all_vgs) || !dm_list_empty(&arg_tags)) &&
+ ((ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system)) != ECMD_PROCESSED)) {
+ stack;
+ return ret;
+ }
+
+ if (dm_list_empty(&arg_vgnames) && dm_list_empty(&vgnameids_on_system)) {
+ log_error("No volume groups found");
+ return ECMD_PROCESSED;
+ }
+
+ /*
+ * If we obtained a full list of VGs on the system, we need to work through them all;
+ * otherwise we can merely work through the VG names provided.
+ */
+ if (!dm_list_empty(&vgnameids_on_system))
+ dm_list_splice(&vgnameids_to_process, &vgnameids_on_system);
+ else if ((ret = _copy_str_to_name_list(cmd, &arg_vgnames, &vgnameids_to_process)) != ECMD_PROCESSED) {
+ stack;
+ return ret;
+ }
+
+ return _process_vgnameid_list(cmd, flags, &vgnameids_to_process,
+ &arg_vgnames, &arg_tags, handle, process_single_vg);
+}
9 years, 6 months