master - cleanup: unneeded initialization
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2941cffd2c6bf6...
Commit: 2941cffd2c6bf67ea2b47696e0ad111f07cf921d
Parent: 65b3fe9b058862c09994b98c246faaf7e0c0e0aa
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 20 20:10:29 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 20 21:50:28 2014 +0200
cleanup: unneeded initialization
Move or drop initialization where it is not needed.
---
tools/lvconvert.c | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 2200ba2..03cd42d 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1054,13 +1054,10 @@ static void _lvconvert_mirrors_repair_ask(struct cmd_context *cmd,
int failed_log, int failed_mirrors,
int *replace_log, int *replace_mirrors)
{
- const char *leg_policy = NULL, *log_policy = NULL;
-
+ const char *leg_policy, *log_policy;
int force = arg_count(cmd, force_ARG);
int yes = arg_count(cmd, yes_ARG);
- *replace_log = *replace_mirrors = 1;
-
if (arg_count(cmd, use_policies_ARG)) {
leg_policy = find_config_tree_str(cmd, activation_mirror_image_fault_policy_CFG, NULL);
log_policy = find_config_tree_str(cmd, activation_mirror_log_fault_policy_CFG, NULL);
@@ -1074,6 +1071,8 @@ static void _lvconvert_mirrors_repair_ask(struct cmd_context *cmd,
return;
}
+ *replace_log = *replace_mirrors = 1;
+
if (yes)
return;
@@ -1616,8 +1615,8 @@ static int _lvconvert_mirrors_repair(struct cmd_context *cmd,
struct logical_volume *lv,
struct lvconvert_params *lp)
{
- int failed_logs = 0;
- int failed_mimages = 0;
+ int failed_logs;
+ int failed_mimages;
int replace_logs = 0;
int replace_mimages = 0;
uint32_t log_count;
9 years, 11 months
master - man: cleanup style
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=65b3fe9b058862...
Commit: 65b3fe9b058862c09994b98c246faaf7e0c0e0aa
Parent: 9fd0be2a8507e1134bf1f5d0e84dd80b765a6b19
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 20 12:54:19 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 20 21:50:28 2014 +0200
man: cleanup style
---
man/lvconvert.8.in | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/man/lvconvert.8.in b/man/lvconvert.8.in
index 8c3479f..91c5bee 100644
--- a/man/lvconvert.8.in
+++ b/man/lvconvert.8.in
@@ -227,7 +227,7 @@ in the background. You should only use this if udev is not running
or has rules that ignore the devices LVM2 creates.
.TP
.B \-\-splitmirrors \fIImages
-The number of redundant Images of a mirror to be split off and used
+The number of redundant \fIImages\fP of a mirror to be split off and used
to form a new logical volume. A name must be supplied for the
newly-split-off logical volume using the \fB\-\-name\fP argument, unless
the \fB\-\-trackchanges\fP argument is given.
@@ -246,11 +246,11 @@ Please note that this feature is only supported with the new md-based mirror
implementation and not with the original device-mapper mirror implementation.
.TP
.B \-\-splitsnapshot
-Separates SnapshotLogicalVolume from its origin.
+Separates \fISnapshotLogicalVolume\fP from its origin.
The volume that is split off contains the chunks that differ from the origin
along with the metadata describing them. This volume can be wiped and then
destroyed with lvremove.
-The inverse of \-\-snapshot.
+The inverse of \fB\-\-snapshot\fP.
.TP
.B \-s, \-\-snapshot
Recreates a snapshot from constituent logical volumes (or copies of them) after
9 years, 11 months
master - debug: fix backtracing
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9fd0be2a8507e1...
Commit: 9fd0be2a8507e1134bf1f5d0e84dd80b765a6b19
Parent: c70c100cce6cdd1f3723203c2cec4427eba7a464
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 20 12:53:51 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 20 21:50:28 2014 +0200
debug: fix backtracing
---
lib/metadata/mirror.c | 2 +-
tools/lvconvert.c | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index 86ec4ca..9a413e8 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -2156,7 +2156,7 @@ int lv_split_mirror_images(struct logical_volume *lv, const char *split_name,
*/
r = _split_mirror_images(lv, split_name, split_count, removable_pvs);
if (!r)
- return 0;
+ return_0;
return 1;
}
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 3c20257..2200ba2 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1001,7 +1001,7 @@ static struct dm_list *_failed_pv_list(struct volume_group *vg)
if (!(failed_pvs = dm_pool_alloc(vg->vgmem, sizeof(*failed_pvs)))) {
log_error("Allocation of list of failed_pvs failed.");
- return_NULL;
+ return NULL;
}
dm_list_init(failed_pvs);
@@ -1022,7 +1022,7 @@ static struct dm_list *_failed_pv_list(struct volume_group *vg)
if (!(new_pvl = dm_pool_alloc(vg->vgmem, sizeof(*new_pvl)))) {
log_error("Allocation of failed_pvs list entry failed.");
- return_NULL;
+ return NULL;
}
new_pvl->pv = pvl->pv;
dm_list_add(failed_pvs, &new_pvl->list);
@@ -1539,7 +1539,7 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
}
if (!lv_split_mirror_images(lv, lp->lv_split_name,
nmc, operable_pvs))
- return 0;
+ return_0;
} else if (!lv_remove_mirrors(cmd, lv, nmc, nlc,
is_mirror_image_removable, operable_pvs, 0))
return_0;
@@ -1584,17 +1584,17 @@ int mirror_remove_missing(struct cmd_context *cmd,
* will get stuck during a suspend.
*/
if (!_lv_update_mirrored_log(lv, failed_pvs, log_count))
- return 0;
+ return_0;
if (_failed_mirrors_count(lv) > 0 &&
!lv_remove_mirrors(cmd, lv, _failed_mirrors_count(lv),
log_count ? 0U : 1U,
_is_partial_lv, NULL, 0))
- return 0;
+ return_0;
if (lv_is_mirrored(lv) &&
!_lv_update_log_type(cmd, NULL, lv, failed_pvs, log_count))
- return 0;
+ return_0;
if (!_reload_lv(cmd, lv->vg, lv))
return_0;
9 years, 11 months
master - lvconvert: check ret code of mirror_remove_missing
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c70c100cce6cdd...
Commit: c70c100cce6cdd1f3723203c2cec4427eba7a464
Parent: bbf4b2c1c9da174c607daee9f920f32517d48e6a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 20 12:57:42 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 20 21:49:42 2014 +0200
lvconvert: check ret code of mirror_remove_missing
When mirror_remove_missing() fails, stop repairing mirror.
---
WHATS_NEW | 1 +
tools/lvconvert.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 5e13c04..86ed3bc 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.107 -
==================================
+ Check for failing mirror_remove_missing() function.
Prompt before converting volumes to thin pool and thin pool metadata.
Add dumpconfig --type profilable-{metadata,command} to select profile type.
Exit immediately with error if command profile is found invalid.
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 79a78a4..3c20257 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1639,7 +1639,8 @@ static int _lvconvert_mirrors_repair(struct cmd_context *cmd,
failed_mimages = _failed_mirrors_count(lv);
failed_logs = _failed_logs_count(lv);
- mirror_remove_missing(cmd, lv, 0);
+ if (!mirror_remove_missing(cmd, lv, 0))
+ return_0;
if (failed_mimages)
log_error("Mirror status: %d of %d images failed.",
9 years, 11 months
master - thin: lvconvert warn before conversion
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=bbf4b2c1c9da17...
Commit: bbf4b2c1c9da174c607daee9f920f32517d48e6a
Parent: 83f468be4e8ff6189523eae7de8a087ab42021be
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 20 16:21:14 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 20 21:48:47 2014 +0200
thin: lvconvert warn before conversion
Warn user before converting volume to different type.
WARNING: Converting vg/lvol0 logical volume to pool's meta/data volume.
THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
Since the content of volume is lost we have to query user to confirm
such operation. If user is 100% sure, he may use '--yes' to avoid prompts.
---
WHATS_NEW | 1 +
tools/lvconvert.c | 22 ++++++++++++++++++++++
2 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 51249ed..5e13c04 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.107 -
==================================
+ Prompt before converting volumes to thin pool and thin pool metadata.
Add dumpconfig --type profilable-{metadata,command} to select profile type.
Exit immediately with error if command profile is found invalid.
Separate --profile cmd line arg into --commandprofile and --metadataprofile.
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 94d870a..79a78a4 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2718,6 +2718,17 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
return 0;
}
+ log_warn("WARNING: Converting \"%s/%s\" logical volume to pool's data volume.",
+ pool_lv->vg->name, pool_lv->name);
+ log_warn("THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)");
+
+ if (!lp->yes &&
+ yes_no_prompt("Do you really want to convert \"%s/%s\"? [y|n]: ",
+ pool_lv->vg->name, pool_lv->name) == 'n') {
+ log_error("Conversion aborted.");
+ return 0;
+ }
+
if ((dm_snprintf(metadata_name, sizeof(metadata_name), "%s%s",
pool_lv->name,
(segtype_is_cache_pool(lp->segtype)) ?
@@ -2825,6 +2836,17 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
return 0;
}
+ log_warn("WARNING: Converting \"%s/%s\" logical volume to pool's metadata volume.",
+ metadata_lv->vg->name, metadata_lv->name);
+ log_warn("THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)");
+
+ if (!lp->yes &&
+ yes_no_prompt("Do you really want to convert \"%s/%s\"? [y|n]: ",
+ metadata_lv->vg->name, metadata_lv->name) == 'n') {
+ log_error("Conversion aborted.");
+ return 0;
+ }
+
lp->poolmetadata_size = metadata_lv->size;
max_metadata_size = (segtype_is_cache_pool(lp->segtype)) ?
DEFAULT_CACHE_POOL_MAX_METADATA_SIZE * 2 :
9 years, 11 months
master - tests: update profiles.sh test for latest changes
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=83f468be4e8ff6...
Commit: 83f468be4e8ff6189523eae7de8a087ab42021be
Parent: 9c937e7d54221a783d294768efbaad12473a0265
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue May 20 14:50:42 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue May 20 16:27:09 2014 +0200
tests: update profiles.sh test for latest changes
---
test/shell/profiles.sh | 130 +++++++++++++++++++++++++++---------------------
1 files changed, 73 insertions(+), 57 deletions(-)
diff --git a/test/shell/profiles.sh b/test/shell/profiles.sh
index bae13d6..49b8b9c 100644
--- a/test/shell/profiles.sh
+++ b/test/shell/profiles.sh
@@ -15,12 +15,16 @@
. lib/test
-MSG_FAILED_TO_APPLY_PROFILE="Failed to apply configuration profile"
-MSG_IGNORING_INVALID_PROFILE="Ignoring invalid configuration profile"
+MSG_FAILED_TO_APPLY_CMD_PROFILE="Failed to apply command profile"
+MSG_IGNORING_INVALID_CMD_PROFILE="Ignoring invalid command profile"
+MSG_FAILED_TO_APPLY_MDA_PROFILE="Failed to apply metadata profile"
+MSG_IGNORING_INVALID_MDA_PROFILE="Ignoring invalid metadata profile"
MSG_NOT_PROFILABLE="not customizable by a profile"
+MSG_CMD_PROFILABLE_ONLY="customizable by command profile only, not metadata profile"
+MSG_MDA_PROFILABLE_ONLY="customizable by metadata profile only, not command profile"
# fail if the profile requested by --profile cmdline option is not present
-not pvs --profile nonexistent 2>&1 | grep "$MSG_FAILED_TO_APPLY_PROFILE"
+not pvs --profile nonexistent 2>&1 | grep "$MSG_FAILED_TO_APPLY_CMD_PROFILE"
# config/checks=1: warning message about setting not being profilable +
# summary error message about invalid profile
@@ -28,58 +32,68 @@ not pvs --profile nonexistent 2>&1 | grep "$MSG_FAILED_TO_APPLY_PROFILE"
aux profileconf invalid 'log/prefix=" "'
aux lvmconf 'config/checks = 0'
-pvs --profile invalid 2>msg
+not pvs --profile invalid 2>msg
not grep "$MSG_NOT_PROFILABLE" msg
-grep "$MSG_IGNORING_INVALID_PROFILE" msg
+grep "$MSG_IGNORING_INVALID_CMD_PROFILE" msg
+grep "$MSG_FAILED_TO_APPLY_CMD_PROFILE" msg
aux lvmconf 'config/checks = 1'
-pvs --profile invalid 2>msg
+not pvs --profile invalid 2>msg
grep "$MSG_NOT_PROFILABLE" msg
-grep "$MSG_IGNORING_INVALID_PROFILE" msg
+grep "$MSG_IGNORING_INVALID_CMD_PROFILE" msg
+grep "$MSG_FAILED_TO_APPLY_CMD_PROFILE" msg
aux lvmconf 'allocation/thin_pool_zero = 1'
# all profilable items listed here - should pass
-aux profileconf valid 'allocation/thin_pool_zero = 0' \
- 'allocation/thin_pool_discards = "passdown"' \
- 'allocation/thin_pool_chunk_size = 64'\
- 'activation/thin_pool_autoextend_threshold = 100' \
- 'activation/thin_pool_autoextend_percent = 20' \
- 'global/units = "h"' \
- 'global/si_unit_consistency = 1' \
- 'global/suffix = 1' \
- 'global/lvdisplay_shows_full_device_path = 0' \
- 'report/aligned = 1' \
- 'report/buffered = 1' \
- 'report/headings = 1' \
- 'report/separator = " "' \
- 'report/prefixes = 0' \
- 'report/quoted = 1' \
- 'report/colums_as_rows = 0' \
- 'report/devtypes_sort = "devtype_name"' \
- 'report/devtypes_cols = "devtype_name,devtype_max_partitions,devtype_description"' \
- 'report/devtypes_cols_verbose = "devtype_name,devtype_max_partitions,devtype_description"' \
- 'report/lvs_sort = "vg_name,lv_name"' \
- 'report/lvs_cols = "lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,move_pv,mirror_log,copy_percent,convert_lv"' \
- 'report/lvs_cols_verbose = "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,pool_lv,origin,data_percent,metadata_percent,move_pv,copy_percent,mirror_log,convert_lv,lv_uuid,lv_profile"' \
- 'report/vgs_sort = "vg_name"' \
- 'report/vgs_cols = "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"' \
- 'report/vgs_cols_verbose = "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid,vg_profile"' \
- 'report/pvs_sort = "pv_name"' \
- 'report/pvs_cols = "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"' \
- 'report/pvs_cols_verbose = "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"' \
- 'report/segs_sort = "vg_name,lv_name,seg_start"' \
- 'report/segs_cols = "lv_name,vg_name,lv_attr,stripes,segtype,seg_size"' \
- 'report/segs_cols_verbose = "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"' \
- 'report/pvsegs_sort = "pv_name,pvseg_start"' \
- 'report/pvsegs_cols = "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"' \
- 'report/pvsegs_cols_verbose = "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"'
-
-aux profileconf extra 'allocation/thin_pool_chunk_size = 128'
-
-pvs --profile valid 2>msg
+aux profileconf valid_cmd_profile 'global/units = "h"' \
+ 'global/si_unit_consistency = 1' \
+ 'global/suffix = 1' \
+ 'global/lvdisplay_shows_full_device_path = 0' \
+ 'report/aligned = 1' \
+ 'report/buffered = 1' \
+ 'report/headings = 1' \
+ 'report/separator = " "' \
+ 'report/prefixes = 0' \
+ 'report/quoted = 1' \
+ 'report/colums_as_rows = 0' \
+ 'report/devtypes_sort = "devtype_name"' \
+ 'report/devtypes_cols = "devtype_name,devtype_max_partitions,devtype_description"' \
+ 'report/devtypes_cols_verbose = "devtype_name,devtype_max_partitions,devtype_description"' \
+ 'report/lvs_sort = "vg_name,lv_name"' \
+ 'report/lvs_cols = "lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,move_pv,mirror_log,copy_percent,convert_lv"' \
+ 'report/lvs_cols_verbose = "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,pool_lv,origin,data_percent,metadata_percent,move_pv,copy_percent,mirror_log,convert_lv,lv_uuid,lv_profile"' \
+ 'report/vgs_sort = "vg_name"' \
+ 'report/vgs_cols = "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"' \
+ 'report/vgs_cols_verbose = "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid,vg_profile"' \
+ 'report/pvs_sort = "pv_name"' \
+ 'report/pvs_cols = "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"' \
+ 'report/pvs_cols_verbose = "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"' \
+ 'report/segs_sort = "vg_name,lv_name,seg_start"' \
+ 'report/segs_cols = "lv_name,vg_name,lv_attr,stripes,segtype,seg_size"' \
+ 'report/segs_cols_verbose = "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"' \
+ 'report/pvsegs_sort = "pv_name,pvseg_start"' \
+ 'report/pvsegs_cols = "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"' \
+ 'report/pvsegs_cols_verbose = "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"'
+
+aux profileconf valid_mda_profile 'allocation/thin_pool_zero = 0' \
+ 'allocation/thin_pool_discards = "passdown"' \
+ 'allocation/thin_pool_chunk_size = 64'\
+ 'activation/thin_pool_autoextend_threshold = 100' \
+ 'activation/thin_pool_autoextend_percent = 20' \
+
+
+aux profileconf extra_mda_profile 'allocation/thin_pool_chunk_size = 128'
+
+pvs --profile valid_cmd_profile 2>msg
not grep "$MSG_NOT_PROFILABLE" msg
-not grep "$MSG_IGNORING_INVALID_PROFILE" msg
+not grep "$MSG_IGNORING_INVALID_CMD_PROFILE" msg
+not grep "$MSG_IGNORING_INVALID_MDA_PROFILE" msg
+
+not pvs --profile valid_mda_profile 2>msg
+grep "$MSG_MDA_PROFILABLE_ONLY" msg
+grep "$MSG_IGNORING_INVALID_CMD_PROFILE" msg
+not grep "$MSG_IGNORING_INVALID_MDA_PROFILE" msg
# attaching/detaching profiles to VG/LV
aux prepare_pvs 1 8
@@ -88,27 +102,29 @@ vgcreate $vg1 "$dev1"
check vg_field $vg1 vg_profile ""
lvcreate -l 1 -n $lv1 $vg1
check lv_field $vg1/$lv1 lv_profile ""
-vgchange --profile valid $vg1
-check vg_field $vg1 vg_profile valid
+vgchange --profile valid_mda_profile $vg1
+check vg_field $vg1 vg_profile valid_mda_profile
check lv_field $vg1/$lv1 lv_profile ""
-lvchange --profile extra $vg1/$lv1
-check vg_field $vg1 vg_profile valid
-check lv_field $vg1/$lv1 lv_profile extra
+lvchange --profile extra_mda_profile $vg1/$lv1
+check vg_field $vg1 vg_profile valid_mda_profile
+check lv_field $vg1/$lv1 lv_profile extra_mda_profile
vgchange --detachprofile $vg1
check vg_field $vg1 vg_profile ""
-check lv_field $vg1/$lv1 lv_profile extra
+check lv_field $vg1/$lv1 lv_profile extra_mda_profile
lvchange --detachprofile $vg1/$lv1
check vg_field $vg1 vg_profile ""
check lv_field $vg1/$lv1 lv_profile ""
# dumpconfig and merged lvm.conf + profile
+aux lvmconf 'global/units="m"'
+aux profileconf extra_cmd_profile 'global/units="h"'
lvm dumpconfig &>out
-grep 'thin_pool_zero=1' out
-lvm dumpconfig --profile valid --mergedconfig >out
-grep 'thin_pool_zero=0' out
+grep 'units="m"' out
+lvm dumpconfig --profile extra_cmd_profile --mergedconfig >out
+grep 'units="h"' out
# dumpconfig --profilable output must be usable as a profile
-lvm dumpconfig --type profilable --file etc/profile/generated.profile
+lvm dumpconfig --type profilable-command --file etc/profile/generated.profile
pvs --profile generated &> msg
not grep "$MSG_NOT_PROFILABLE" msg
-not grep "$MSG_IGNORING_INVALID_PROFILE" msg
+not grep "$MSG_IGNORING_INVALID_CMD_PROFILE" msg
9 years, 11 months
master - dumpconfig: add --type profilable-command/profilable-metadata, --metadataprofile/--commandprofile
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9c937e7d54221a...
Commit: 9c937e7d54221a783d294768efbaad12473a0265
Parent: 9e3e4d69944f072742fd13c5ac74d68e41a3db55
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue May 20 14:45:20 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue May 20 16:27:07 2014 +0200
dumpconfig: add --type profilable-command/profilable-metadata, --metadataprofile/--commandprofile
The dumpconfig now understands --commandprofile/--profile/--metadataprofile
The --commandprofile and --profile functionality is almost the same
with only one difference and that is that the --profile is just used
for dumping the content, it's not applied for the command itself
(while the --commandprofile profile is applied like it is done for
any other LVM command).
We also allow --metadataprofile for dumpconfig - dumpconfig *does not*
touch VG/LV and metadata in any way so it's OK to use it here (just for
dumping the content, checking the profile validity etc.).
The validity of the profile can be checked with:
dumpconfig --commandprofile/--profile/--metadataprofile --validate
...depending on the profile type.
Also, mention --config in the dumpconfig help string so users know
that dumpconfig handles this too (it did even before, but it was not
documented in the help string).
---
WHATS_NEW | 1 +
lib/config/config.c | 11 +++++++++++
lib/config/config.h | 2 ++
tools/commands.h | 10 +++++++---
tools/dumpconfig.c | 26 +++++++++++++++++++++++++-
5 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index b57a1c3..51249ed 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.107 -
==================================
+ Add dumpconfig --type profilable-{metadata,command} to select profile type.
Exit immediately with error if command profile is found invalid.
Separate --profile cmd line arg into --commandprofile and --metadataprofile.
Strictly separate command profiles and per-VG/LV profiles referenced in mda.
diff --git a/lib/config/config.c b/lib/config/config.c
index 4fbee66..ecb674e 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -1622,6 +1622,7 @@ static struct dm_config_node *_add_def_node(struct dm_config_tree *cft,
static int _should_skip_def_node(struct config_def_tree_spec *spec, int section_id, int id)
{
cfg_def_item_t *def = cfg_def_get_item_p(id);
+ uint16_t flags;
if ((def->parent != section_id) ||
(spec->ignoreadvanced && def->flags & CFG_ADVANCED) ||
@@ -1645,9 +1646,19 @@ static int _should_skip_def_node(struct config_def_tree_spec *spec, int section_
return 1;
break;
case CFG_DEF_TREE_PROFILABLE:
+ case CFG_DEF_TREE_PROFILABLE_CMD:
+ case CFG_DEF_TREE_PROFILABLE_MDA:
if (!(def->flags & CFG_PROFILABLE) ||
(def->since_version > spec->version))
return 1;
+ flags = def->flags & ~CFG_PROFILABLE;
+ if (spec->type == CFG_DEF_TREE_PROFILABLE_CMD) {
+ if (flags & CFG_PROFILABLE_METADATA)
+ return 1;
+ } else if (spec->type == CFG_DEF_TREE_PROFILABLE_MDA) {
+ if (!(flags & CFG_PROFILABLE_METADATA))
+ return 1;
+ }
break;
default:
if (def->since_version > spec->version)
diff --git a/lib/config/config.h b/lib/config/config.h
index 0618045..7b1d5b6 100644
--- a/lib/config/config.h
+++ b/lib/config/config.h
@@ -129,6 +129,8 @@ typedef enum {
CFG_DEF_TREE_DEFAULT, /* tree of all possible config nodes with default values */
CFG_DEF_TREE_NEW, /* tree of all new nodes that appeared in given version */
CFG_DEF_TREE_PROFILABLE, /* tree of all nodes that are customizable by profiles */
+ CFG_DEF_TREE_PROFILABLE_CMD, /* tree of all nodes that are customizable by command profiles (subset of PROFILABLE) */
+ CFG_DEF_TREE_PROFILABLE_MDA, /* tree of all nodes that are customizable by metadata profiles (subset of PROFILABLE) */
CFG_DEF_TREE_DIFF, /* tree of all nodes that differ from defaults */
} cfg_def_tree_t;
diff --git a/tools/commands.h b/tools/commands.h
index 6ed4f8d..50db8eb 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -59,18 +59,22 @@ xx(dumpconfig,
"dumpconfig\n"
"\t[--commandprofile ProfileName]\n"
"\t[-f|--file filename] \n"
- "\t[--type {current|default|diff|missing|new|profilable} \n"
+ "\t[--type {current|default|diff|missing|new|profilable|profilable-command|profilable-metadata} \n"
"\t[--atversion version]] \n"
"\t[--ignoreadvanced] \n"
"\t[--ignoreunsupported] \n"
+ "\t[--config ConfigurationString] \n"
+ "\t[--commandprofile ProfileName] \n"
+ "\t[--profile ProfileName] \n"
+ "\t[--metadataprofile ProfileName] \n"
"\t[--mergedconfig] \n"
"\t[--validate]\n"
"\t[--withcomments] \n"
"\t[--withversions] \n"
"\t[ConfigurationNode...]\n",
atversion_ARG, configtype_ARG, file_ARG, ignoreadvanced_ARG,
- ignoreunsupported_ARG, mergedconfig_ARG, validate_ARG,
- withcomments_ARG, withversions_ARG)
+ ignoreunsupported_ARG, mergedconfig_ARG, metadataprofile_ARG,
+ validate_ARG, withcomments_ARG, withversions_ARG)
xx(formats,
"List available metadata formats",
diff --git a/tools/dumpconfig.c b/tools/dumpconfig.c
index 141a030..09f2119 100644
--- a/tools/dumpconfig.c
+++ b/tools/dumpconfig.c
@@ -92,6 +92,7 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
struct config_def_tree_spec tree_spec = {0};
struct dm_config_tree *cft = NULL;
struct cft_check_handle *cft_check_handle = NULL;
+ struct profile *profile = NULL;
int r = ECMD_PROCESSED;
tree_spec.cmd = cmd;
@@ -132,6 +133,18 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
/*
+ * The profile specified by --profile cmd arg is like --commandprofile,
+ * but it is used just for dumping the profile content and not for
+ * application.
+ */
+ if (arg_count(cmd, profile_ARG) &&
+ (!(profile = add_profile(cmd, arg_str_value(cmd, profile_ARG, NULL), CONFIG_PROFILE_COMMAND)) ||
+ !override_config_tree_from_profile(cmd, profile))) {
+ log_error("Failed to load profile %s.", arg_str_value(cmd, profile_ARG, NULL));
+ return ECMD_FAILED;
+ }
+
+ /*
* Set the 'cft' to work with based on whether we need the plain
* config tree or merged config tree cascade if --mergedconfig is used.
*/
@@ -188,9 +201,18 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
tree_spec.type = CFG_DEF_TREE_PROFILABLE;
/* profilable type does not require check status */
}
+ else if (!strcmp(type, "profilable-command")) {
+ tree_spec.type = CFG_DEF_TREE_PROFILABLE_CMD;
+ /* profilable-command type does not require check status */
+ }
+ else if (!strcmp(type, "profilable-metadata")) {
+ tree_spec.type = CFG_DEF_TREE_PROFILABLE_MDA;
+ /* profilable-metadata type does not require check status */
+ }
else {
log_error("Incorrect type of configuration specified. "
- "Expected one of: current, default, missing, new, profilable.");
+ "Expected one of: current, default, missing, new, "
+ "profilable, profilable-command, profilable-metadata.");
r = EINVALID_CMD_LINE;
goto out;
}
@@ -218,6 +240,8 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
out:
if (cft && (cft != cmd->cft))
dm_pool_destroy(cft->mem);
+ else if (profile)
+ remove_config_tree_by_source(cmd, CONFIG_PROFILE_COMMAND);
/*
* The cmd->cft (the "current" tree) is destroyed
9 years, 11 months
master - config: differentiate command and metadata profiles and consolidate profile handling code
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9e3e4d69944f07...
Commit: 9e3e4d69944f072742fd13c5ac74d68e41a3db55
Parent: c5fbd2c59f1248b1315aae71dee032878d8476f8
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue May 20 14:13:10 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue May 20 16:21:48 2014 +0200
config: differentiate command and metadata profiles and consolidate profile handling code
- When defining configuration source, the code now uses separate
CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers
(before, it was just CONFIG_PROFILE that did not make the
difference between the two). This helps when checking the
configuration if it contains correct set of options which
are all in either command-profilable or metadata-profilable
group without mixing these groups together - so it's a firm
distinction. The "command profile" can't contain
"metadata profile" and vice versa! This is strictly checked
and if the settings are mixed, such profile is rejected and
it's not used. So in the end, the CONFIG_PROFILE_COMMAND
set of options and CONFIG_PROFILE_METADATA are mutually exclusive
sets.
- Marking configuration with one or the other marker will also
determine the way these configuration sources are positioned
in the configuration cascade which is now:
CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES
- Marking configuration with one or the other marker will also make
it possible to issue a command context refresh (will be probably
a part of a future patch) if needed for settings in global profile
set. For settings in metadata profile set this is impossible since
we can't refresh cmd context in the middle of reading VG/LV metadata
and for each VG/LV separately because each VG/LV can have a different
metadata profile assinged and it's not possible to change these
settings at this level.
- When command profile is incorrect, it's rejected *and also* the
command exits immediately - the profile *must* be correct for the
command that was run with a profile to be executed. Before this
patch, when the profile was found incorrect, there was just the
warning message and the command continued without profile applied.
But it's more correct to exit immediately in this case.
- When metadata profile is incorrect, we reject it during command
runtime (as we know the profile name from metadata and not early
from command line as it is in case of command profiles) and we
*do continue* with the command as we're in the middle of operation.
Also, the metadata profile is applied directly and on the fly on
find_config_tree_* fn call and even if the metadata profile is
found incorrect, we still need to return the non-profiled value
as found in the other configuration provided or default value.
To exit immediately even in this case, we'd need to refactor
existing find_config_tree_* fns so they can return error. Currently,
these fns return only config values (which end up with default
values in the end if the config is not found).
- To check the profile validity before use to be sure it's correct,
one can use :
lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate
(the --commandprofile/--metadataprofile for dumpconfig will come
as part of the subsequent patch)
- This patch also adds a reference to --commandprofile and
--metadataprofile in the cmd help string (which was missing before
for the --profile for some commands). We do not mention --profile
now as people should use --commandprofile or --metadataprofile
directly. However, the --profile is still supported for backward
compatibility and it's translated as:
--profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange
(as these commands are able to attach profile to metadata)
--profile == --commandprofile for all the other commands
(--metadataprofile is not allowed there as it makes no sense)
- This patch also contains some cleanups to make the code handling
the profiles more readable...
---
WHATS_NEW | 3 +
lib/commands/toolcontext.c | 20 ++-
lib/config/config.c | 322 ++++++++++++++++++++++++++++++-----------
lib/config/config.h | 15 +-
lib/format_text/import_vsn1.c | 4 +-
lib/metadata/lv_manip.c | 2 +-
lib/mm/memlock.c | 2 +-
tools/args.h | 2 +
tools/commands.h | 101 ++++++++++---
tools/lvchange.c | 22 ++-
tools/lvmcmdline.c | 141 ++++++++++++++++---
tools/vgchange.c | 14 ++-
tools/vgcreate.c | 2 +-
13 files changed, 495 insertions(+), 155 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 6cbd622..b57a1c3 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,8 @@
Version 2.02.107 -
==================================
+ Exit immediately with error if command profile is found invalid.
+ Separate --profile cmd line arg into --commandprofile and --metadataprofile.
+ Strictly separate command profiles and per-VG/LV profiles referenced in mda.
Fix dumpconfig --type diff when run as second and later cmd in lvm shell.
Fix wrong profile reuse from previous run if another cmd is run in lvm shell.
Move cache description from lvm(8) to lvmcache(7) man page.
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 904ae83..519d36a 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -717,7 +717,8 @@ static void _destroy_config(struct cmd_context *cmd)
/* CONFIG_PROFILE */
if (cmd->profile_params) {
- remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ remove_config_tree_by_source(cmd, CONFIG_PROFILE_COMMAND);
+ remove_config_tree_by_source(cmd, CONFIG_PROFILE_METADATA);
/*
* Destroy config trees for any loaded profiles and
* move these profiles to profile_to_load list.
@@ -1605,7 +1606,7 @@ int refresh_filters(struct cmd_context *cmd)
int refresh_toolcontext(struct cmd_context *cmd)
{
struct dm_config_tree *cft_cmdline, *cft_tmp;
- const char *profile_name;
+ const char *profile_command_name, *profile_metadata_name;
struct profile *profile;
log_verbose("Reloading config files");
@@ -1633,8 +1634,10 @@ int refresh_toolcontext(struct cmd_context *cmd)
cft_cmdline = remove_config_tree_by_source(cmd, CONFIG_STRING);
/* save the global profile name used */
- profile_name = cmd->profile_params->global_profile ?
- cmd->profile_params->global_profile->name : NULL;
+ profile_command_name = cmd->profile_params->global_command_profile ?
+ cmd->profile_params->global_command_profile->name : NULL;
+ profile_metadata_name = cmd->profile_params->global_metadata_profile ?
+ cmd->profile_params->global_metadata_profile->name : NULL;
_destroy_config(cmd);
@@ -1653,8 +1656,13 @@ int refresh_toolcontext(struct cmd_context *cmd)
cmd->cft = dm_config_insert_cascaded_tree(cft_cmdline, cft_tmp);
/* Reload the global profile. */
- if (profile_name) {
- if (!(profile = add_profile(cmd, profile_name)) ||
+ if (profile_command_name) {
+ if (!(profile = add_profile(cmd, profile_command_name, CONFIG_PROFILE_COMMAND)) ||
+ !override_config_tree_from_profile(cmd, profile))
+ return_0;
+ }
+ if (profile_metadata_name) {
+ if (!(profile = add_profile(cmd, profile_metadata_name, CONFIG_PROFILE_METADATA)) ||
!override_config_tree_from_profile(cmd, profile))
return_0;
}
diff --git a/lib/config/config.c b/lib/config/config.c
index 4b5c18c..4fbee66 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -38,7 +38,8 @@ static const char *_config_source_names[] = {
[CONFIG_FILE] = "file",
[CONFIG_MERGED_FILES] = "merged files",
[CONFIG_STRING] = "string",
- [CONFIG_PROFILE] = "profile",
+ [CONFIG_PROFILE_COMMAND] = "command profile",
+ [CONFIG_PROFILE_METADATA] = "metadata profile",
[CONFIG_FILE_SPECIAL] = "special purpose"
};
@@ -83,6 +84,19 @@ config_source_t config_get_source_type(struct dm_config_tree *cft)
return cs ? cs->type : CONFIG_UNDEFINED;
}
+static inline int _is_profile_based_config_source(config_source_t source)
+{
+ return (source == CONFIG_PROFILE_COMMAND) ||
+ (source == CONFIG_PROFILE_METADATA);
+}
+
+static inline int _is_file_based_config_source(config_source_t source)
+{
+ return (source == CONFIG_FILE) ||
+ (source == CONFIG_FILE_SPECIAL) ||
+ _is_profile_based_config_source(source);
+}
+
/*
* public interface
*/
@@ -102,9 +116,7 @@ struct dm_config_tree *config_open(config_source_t source,
goto fail;
}
- if ((source == CONFIG_FILE) ||
- (source == CONFIG_FILE_SPECIAL) ||
- (source == CONFIG_PROFILE)) {
+ if (_is_file_based_config_source(source)) {
if (!(cf = dm_pool_zalloc(cft->mem, sizeof(struct config_file)))) {
log_error("Failed to allocate config file.");
goto fail;
@@ -137,9 +149,7 @@ int config_file_check(struct dm_config_tree *cft, const char **filename, struct
struct config_file *cf;
struct stat _info;
- if ((cs->type != CONFIG_FILE) &&
- (cs->type != CONFIG_PROFILE) &&
- (cs->type != CONFIG_FILE_SPECIAL)) {
+ if (!_is_file_based_config_source(cs->type)) {
log_error(INTERNAL_ERROR "config_file_check: expected file, special file or "
"profile config source, found %s config source.",
_config_source_names[cs->type]);
@@ -234,9 +244,7 @@ void config_destroy(struct dm_config_tree *cft)
cs = dm_config_get_custom(cft);
- if ((cs->type == CONFIG_FILE) ||
- (cs->type == CONFIG_PROFILE) ||
- (cs->type == CONFIG_FILE_SPECIAL)) {
+ if (_is_file_based_config_source(cs->type)) {
cf = cs->source.file;
if (cf && cf->dev)
if (!dev_close(cf->dev))
@@ -261,7 +269,7 @@ struct dm_config_tree *config_file_open_and_read(const char *config_file,
/* Is there a config file? */
if (stat(config_file, &info) == -1) {
/* Profile file must be present! */
- if (errno == ENOENT && (source != CONFIG_PROFILE))
+ if (errno == ENOENT && (!_is_profile_based_config_source(source)))
return cft;
log_sys_error("stat", config_file);
goto bad;
@@ -360,7 +368,7 @@ int override_config_tree_from_string(struct cmd_context *cmd,
/*
* Follow this sequence:
- * CONFIG_STRING -> CONFIG_PROFILE -> CONFIG_FILE/CONFIG_MERGED_FILES
+ * CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES
*/
if (cs->type == CONFIG_STRING) {
@@ -388,39 +396,89 @@ int override_config_tree_from_string(struct cmd_context *cmd,
return 1;
}
-int override_config_tree_from_profile(struct cmd_context *cmd,
- struct profile *profile)
+static int _override_config_tree_from_command_profile(struct cmd_context *cmd,
+ struct profile *profile)
{
- struct dm_config_tree *cft = cmd->cft, *cft_string = NULL;
+ struct dm_config_tree *cft = cmd->cft, *cft_previous = NULL;
struct config_source *cs = dm_config_get_custom(cft);
- /*
- * Follow this sequence:
- * CONFIG_STRING -> CONFIG_PROFILE -> CONFIG_FILE/CONFIG_MERGED_FILES
- */
+ if (cs->type == CONFIG_STRING) {
+ cft_previous = cft;
+ cft = cft->cascade;
+ cs = dm_config_get_custom(cft);
+ }
- if (!profile->cft && !load_profile(cmd, profile))
- return_0;
+ if (cs->type == CONFIG_PROFILE_COMMAND) {
+ log_error(INTERNAL_ERROR "_override_config_tree_from_command_profile: "
+ "config cascade already contains a command profile config.");
+ return 0;
+ }
+
+ if (cft_previous)
+ dm_config_insert_cascaded_tree(cft_previous, profile->cft);
+ else
+ cmd->cft = profile->cft;
+
+ dm_config_insert_cascaded_tree(profile->cft, cft);
+
+ return 1;
+}
+
+static int _override_config_tree_from_metadata_profile(struct cmd_context *cmd,
+ struct profile *profile)
+{
+ struct dm_config_tree *cft = cmd->cft, *cft_previous = NULL;
+ struct config_source *cs = dm_config_get_custom(cft);
if (cs->type == CONFIG_STRING) {
- cft_string = cft;
+ cft_previous = cft;
+ cft = cft->cascade;
+ }
+
+ if (cs->type == CONFIG_PROFILE_COMMAND) {
+ cft_previous = cft;
cft = cft->cascade;
cs = dm_config_get_custom(cft);
- if (cs->type == CONFIG_PROFILE) {
- log_error(INTERNAL_ERROR "override_config_tree_from_profile: "
- "config cascade already contains a profile config.");
- return 0;
- }
- dm_config_insert_cascaded_tree(cft_string, profile->cft);
}
- cmd->cft = dm_config_insert_cascaded_tree(profile->cft, cft);
+ cs = dm_config_get_custom(cft);
+
+ if (cs->type == CONFIG_PROFILE_METADATA) {
+ log_error(INTERNAL_ERROR "_override_config_tree_from_metadata_profile: "
+ "config cascade already contains a metadata profile config.");
+ return 0;
+ }
+
+ if (cft_previous)
+ dm_config_insert_cascaded_tree(cft_previous, profile->cft);
+ else
+ cmd->cft = profile->cft;
- cmd->cft = cft_string ? : profile->cft;
+ dm_config_insert_cascaded_tree(profile->cft, cft);
return 1;
}
+int override_config_tree_from_profile(struct cmd_context *cmd,
+ struct profile *profile)
+{
+ /*
+ * Follow this sequence:
+ * CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES
+ */
+
+ if (!profile->cft && !load_profile(cmd, profile))
+ return_0;
+
+ if (profile->source == CONFIG_PROFILE_COMMAND)
+ return _override_config_tree_from_command_profile(cmd, profile);
+ else if (profile->source == CONFIG_PROFILE_METADATA)
+ return _override_config_tree_from_metadata_profile(cmd, profile);
+
+ log_error(INTERNAL_ERROR "override_config_tree_from_profile: incorrect profile source type");
+ return 0;
+}
+
int config_file_read_fd(struct dm_config_tree *cft, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum)
@@ -432,9 +490,7 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev,
char *buf = NULL;
struct config_source *cs = dm_config_get_custom(cft);
- if ((cs->type != CONFIG_FILE) &&
- (cs->type != CONFIG_PROFILE) &&
- (cs->type != CONFIG_FILE_SPECIAL)) {
+ if (!_is_file_based_config_source(cs->type)) {
log_error(INTERNAL_ERROR "config_file_read_fd: expected file, special file "
"or profile config source, found %s config source.",
_config_source_names[cs->type]);
@@ -850,6 +906,48 @@ static int _config_def_check_node_value(struct cft_check_handle *handle,
return 1;
}
+static int _config_def_check_node_is_profilable(struct cft_check_handle *handle,
+ const char *rp, struct dm_config_node *cn,
+ const cfg_def_item_t *def)
+{
+ uint16_t flags;
+
+ if (!(def->flags & CFG_PROFILABLE)) {
+ log_warn_suppress(handle->suppress_messages,
+ "Configuration %s \"%s\" is not customizable by "
+ "a profile.", cn->v ? "option" : "section", rp);
+ return 0;
+ }
+
+ flags = def->flags & ~CFG_PROFILABLE;
+
+ /*
+ * Make sure there is no metadata profilable config in the command profile!
+ */
+ if ((handle->source == CONFIG_PROFILE_COMMAND) && (flags & CFG_PROFILABLE_METADATA)) {
+ log_warn_suppress(handle->suppress_messages,
+ "Configuration %s \"%s\" is customizable by "
+ "metadata profile only, not command profile.",
+ cn->v ? "option" : "section", rp);
+ return 0;
+ }
+
+ /*
+ * Make sure there is no command profilable config in the metadata profile!
+ * (sections do not need to be flagged with CFG_PROFILABLE_METADATA, the
+ * CFG_PROFILABLE is enough as sections may contain both types inside)
+ */
+ if ((handle->source == CONFIG_PROFILE_METADATA) && cn->v && !(flags & CFG_PROFILABLE_METADATA)) {
+ log_warn_suppress(handle->suppress_messages,
+ "Configuration %s \"%s\" is customizable by "
+ "command profile only, not metadata profile.",
+ cn->v ? "option" : "section", rp);
+ return 0;
+ }
+
+ return 1;
+}
+
static int _config_def_check_node(struct cft_check_handle *handle,
const char *vp, char *pvp, char *rp, char *prp,
size_t buf_size, struct dm_config_node *cn)
@@ -896,13 +994,9 @@ static int _config_def_check_node(struct cft_check_handle *handle,
* in certain types of configuration trees as in some
* the use of configuration is restricted, e.g. profiles...
*/
- if (handle->source == CONFIG_PROFILE &&
- !(def->flags & CFG_PROFILABLE)) {
- log_warn_suppress(handle->suppress_messages,
- "Configuration %s \"%s\" is not customizable by "
- "a profile.", cn->v ? "option" : "section", rp);
- return 0;
- }
+ if (_is_profile_based_config_source(handle->source) &&
+ !_config_def_check_node_is_profilable(handle, rp, cn, def))
+ return_0;
handle->status[def->id] |= CFG_VALID;
return 1;
@@ -1028,6 +1122,23 @@ out:
return r;
}
+static int _apply_local_profile(struct cmd_context *cmd, struct profile *profile)
+{
+ if (!profile)
+ return 0;
+
+ /*
+ * Global metadata profile overrides the local one.
+ * This simply means the "--metadataprofile" arg
+ * overrides any profile attached to VG/LV.
+ */
+ if ((profile->source == CONFIG_PROFILE_METADATA) &&
+ cmd->profile_params->global_metadata_profile)
+ return 0;
+
+ return override_config_tree_from_profile(cmd, profile);
+}
+
const struct dm_config_node *find_config_tree_node(struct cmd_context *cmd, int id, struct profile *profile)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
@@ -1035,14 +1146,13 @@ const struct dm_config_node *find_config_tree_node(struct cmd_context *cmd, int
int profile_applied = 0;
const struct dm_config_node *cn;
- if (profile && !cmd->profile_params->global_profile)
- profile_applied = override_config_tree_from_profile(cmd, profile);
-
+ profile_applied = _apply_local_profile(cmd, profile);
_cfg_def_make_path(path, sizeof(path), item->id, item, 0);
+
cn = dm_config_tree_find_node(cmd->cft, path);
if (profile_applied)
- remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ remove_config_tree_by_source(cmd, profile->source);
return cn;
}
@@ -1054,9 +1164,7 @@ const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile
int profile_applied = 0;
const char *str;
- if (profile && !cmd->profile_params->global_profile)
- profile_applied = override_config_tree_from_profile(cmd, profile);
-
+ profile_applied = _apply_local_profile(cmd, profile);
_cfg_def_make_path(path, sizeof(path), item->id, item, 0);
if (item->type != CFG_TYPE_STRING)
@@ -1065,7 +1173,7 @@ const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile
str = dm_config_tree_find_str(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_STRING, profile));
if (profile_applied)
- remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ remove_config_tree_by_source(cmd, profile->source);
return str;
}
@@ -1077,9 +1185,7 @@ const char *find_config_tree_str_allow_empty(struct cmd_context *cmd, int id, st
int profile_applied = 0;
const char *str;
- if (profile && !cmd->profile_params->global_profile)
- profile_applied = override_config_tree_from_profile(cmd, profile);
-
+ profile_applied = _apply_local_profile(cmd, profile);
_cfg_def_make_path(path, sizeof(path), item->id, item, 0);
if (item->type != CFG_TYPE_STRING)
@@ -1090,7 +1196,7 @@ const char *find_config_tree_str_allow_empty(struct cmd_context *cmd, int id, st
str = dm_config_tree_find_str_allow_empty(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_STRING, profile));
if (profile_applied)
- remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ remove_config_tree_by_source(cmd, profile->source);
return str;
}
@@ -1102,9 +1208,7 @@ int find_config_tree_int(struct cmd_context *cmd, int id, struct profile *profil
int profile_applied = 0;
int i;
- if (profile && !cmd->profile_params->global_profile)
- profile_applied = override_config_tree_from_profile(cmd, profile);
-
+ profile_applied = _apply_local_profile(cmd, profile);
_cfg_def_make_path(path, sizeof(path), item->id, item, 0);
if (item->type != CFG_TYPE_INT)
@@ -1113,7 +1217,7 @@ int find_config_tree_int(struct cmd_context *cmd, int id, struct profile *profil
i = dm_config_tree_find_int(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_INT, profile));
if (profile_applied)
- remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ remove_config_tree_by_source(cmd, profile->source);
return i;
}
@@ -1125,9 +1229,7 @@ int64_t find_config_tree_int64(struct cmd_context *cmd, int id, struct profile *
int profile_applied = 0;
int i64;
- if (profile && !cmd->profile_params->global_profile)
- profile_applied = override_config_tree_from_profile(cmd, profile);
-
+ profile_applied = _apply_local_profile(cmd, profile);
_cfg_def_make_path(path, sizeof(path), item->id, item, 0);
if (item->type != CFG_TYPE_INT)
@@ -1136,7 +1238,7 @@ int64_t find_config_tree_int64(struct cmd_context *cmd, int id, struct profile *
i64 = dm_config_tree_find_int64(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_INT, profile));
if (profile_applied)
- remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ remove_config_tree_by_source(cmd, profile->source);
return i64;
}
@@ -1148,9 +1250,7 @@ float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *pr
int profile_applied = 0;
float f;
- if (profile && !cmd->profile_params->global_profile)
- profile_applied = override_config_tree_from_profile(cmd, profile);
-
+ profile_applied = _apply_local_profile(cmd, profile);
_cfg_def_make_path(path, sizeof(path), item->id, item, 0);
if (item->type != CFG_TYPE_FLOAT)
@@ -1159,7 +1259,7 @@ float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *pr
f = dm_config_tree_find_float(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_FLOAT, profile));
if (profile_applied)
- remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ remove_config_tree_by_source(cmd, profile->source);
return f;
}
@@ -1171,9 +1271,7 @@ int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profi
int profile_applied = 0;
int b;
- if (profile && !cmd->profile_params->global_profile)
- profile_applied = override_config_tree_from_profile(cmd, profile);
-
+ profile_applied = _apply_local_profile(cmd, profile);
_cfg_def_make_path(path, sizeof(path), item->id, item, 0);
if (item->type != CFG_TYPE_BOOL)
@@ -1182,7 +1280,7 @@ int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profi
b = dm_config_tree_find_bool(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_BOOL, profile));
if (profile_applied)
- remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ remove_config_tree_by_source(cmd, profile->source);
return b;
}
@@ -1627,7 +1725,7 @@ static int _check_profile(struct cmd_context *cmd, struct profile *profile)
handle->cmd = cmd;
handle->cft = profile->cft;
- handle->source = CONFIG_PROFILE;
+ handle->source = profile->source;
/* the check is compulsory - allow only profilable items in a profile config! */
handle->force_check = 1;
/* provide warning messages only if config/checks=1 */
@@ -1639,11 +1737,44 @@ static int _check_profile(struct cmd_context *cmd, struct profile *profile)
return r;
}
-struct profile *add_profile(struct cmd_context *cmd, const char *profile_name)
+static int _get_profile_from_list(struct dm_list *list, const char *profile_name,
+ config_source_t source, struct profile **profile_found)
+{
+ struct profile *profile;
+
+ dm_list_iterate_items(profile, list) {
+ if (!strcmp(profile->name, profile_name)) {
+ if (profile->source == source) {
+ *profile_found = profile;
+ return 1;
+ }
+ log_error(INTERNAL_ERROR "Profile %s already added as "
+ "%s type, but requested type is %s.",
+ profile_name,
+ _config_source_names[profile->source],
+ _config_source_names[source]);
+ return 0;
+ }
+ }
+
+ *profile_found = NULL;
+ return 1;
+}
+
+struct profile *add_profile(struct cmd_context *cmd, const char *profile_name, config_source_t source)
{
struct profile *profile;
/* Do some sanity checks first. */
+ if (!_is_profile_based_config_source(source)) {
+ log_error(INTERNAL_ERROR "add_profile: incorrect configuration "
+ "source, expected %s or %s but %s requested",
+ _config_source_names[CONFIG_PROFILE_COMMAND],
+ _config_source_names[CONFIG_PROFILE_METADATA],
+ _config_source_names[source]);
+ return NULL;
+ }
+
if (!profile_name || !*profile_name) {
log_error("Undefined profile name.");
return NULL;
@@ -1654,14 +1785,29 @@ struct profile *add_profile(struct cmd_context *cmd, const char *profile_name)
return NULL;
}
- /* Check if the profile is added already... */
- dm_list_iterate_items(profile, &cmd->profile_params->profiles_to_load) {
- if (!strcmp(profile->name, profile_name))
- return profile;
- }
- dm_list_iterate_items(profile, &cmd->profile_params->profiles) {
- if (!strcmp(profile->name, profile_name))
- return profile;
+ /*
+ * Check if the profile is on the list of profiles to be loaded or if
+ * not found there, if it's on the list of already loaded profiles.
+ */
+ if (!_get_profile_from_list(&cmd->profile_params->profiles_to_load,
+ profile_name, source, &profile))
+ return_NULL;
+
+ if (profile)
+ profile->source = source;
+ else if (!_get_profile_from_list(&cmd->profile_params->profiles,
+ profile_name, source, &profile))
+ return_NULL;
+
+ if (profile) {
+ if (profile->source != source) {
+ log_error(INTERNAL_ERROR "add_profile: loaded profile "
+ "has incorrect type, expected %s but %s found",
+ _config_source_names[source],
+ _config_source_names[profile->source]);
+ return NULL;
+ }
+ return profile;
}
if (!(profile = dm_pool_zalloc(cmd->libmem, sizeof(*profile)))) {
@@ -1669,6 +1815,7 @@ struct profile *add_profile(struct cmd_context *cmd, const char *profile_name)
return NULL;
}
+ profile->source = source;
profile->name = dm_pool_strdup(cmd->libmem, profile_name);
dm_list_add(&cmd->profile_params->profiles_to_load, &profile->list);
@@ -1693,11 +1840,9 @@ int load_profile(struct cmd_context *cmd, struct profile *profile) {
return 0;
}
- if (!(profile->cft = config_file_open_and_read(profile_path, CONFIG_PROFILE, cmd)))
+ if (!(profile->cft = config_file_open_and_read(profile_path, profile->source, cmd)))
return 0;
- dm_list_move(&cmd->profile_params->profiles, &profile->list);
-
/*
* *Profile must be valid* otherwise we'd end up with incorrect config!
* If there were config items present that are not supposed to be
@@ -1708,25 +1853,28 @@ int load_profile(struct cmd_context *cmd, struct profile *profile) {
* for profiles!
*/
if (!_check_profile(cmd, profile)) {
- log_error("Ignoring invalid configuration profile %s.", profile->name);
- /* if invalid, cut the whole tree and leave it empty */
- dm_pool_free(profile->cft->mem, profile->cft->root);
- profile->cft->root = NULL;
+ log_error("Ignoring invalid %s %s.",
+ _config_source_names[profile->source], profile->name);
+ config_destroy(profile->cft);
+ profile->cft = NULL;
+ return 0;
}
+ dm_list_move(&cmd->profile_params->profiles, &profile->list);
return 1;
}
int load_pending_profiles(struct cmd_context *cmd)
{
struct profile *profile, *temp_profile;
+ int r = 1;
dm_list_iterate_items_safe(profile, temp_profile, &cmd->profile_params->profiles_to_load) {
if (!load_profile(cmd, profile))
- return 0;
+ r = 0;
}
- return 1;
+ return r;
}
const char *get_default_devices_cache_dir_CFG(struct cmd_context *cmd, struct profile *profile)
diff --git a/lib/config/config.h b/lib/config/config.h
index f06fb68..0618045 100644
--- a/lib/config/config.h
+++ b/lib/config/config.h
@@ -30,21 +30,24 @@ typedef enum {
CONFIG_FILE, /* one file config */
CONFIG_MERGED_FILES, /* config that is a result of merging more config files */
CONFIG_STRING, /* config string typed on cmdline using '--config' arg */
- CONFIG_PROFILE, /* profile config */
+ CONFIG_PROFILE_COMMAND, /* command profile config */
+ CONFIG_PROFILE_METADATA,/* metadata profile config */
CONFIG_FILE_SPECIAL /* special purpose file config (e.g. metadata, persistent filter...) */
} config_source_t;
struct profile {
struct dm_list list;
+ config_source_t source; /* either CONFIG_PROFILE_COMMAND or CONFIG_PROFILE_METADATA */
const char *name;
struct dm_config_tree *cft;
};
struct profile_params {
- char dir[PATH_MAX]; /* subdir in LVM_SYSTEM_DIR where LVM looks for profiles */
- struct profile *global_profile; /* profile that overrides any other VG/LV-based profile ('--profile' cmd line arg) */
- struct dm_list profiles_to_load;/* list of profiles which are only added, but still need to be loaded for any use */
- struct dm_list profiles; /* list of profiles which are loaded already and which are ready for use */
+ char dir[PATH_MAX]; /* subdir in LVM_SYSTEM_DIR where LVM looks for profiles */
+ struct profile *global_command_profile; /* profile (as given by --commandprofile cmd arg) used as global command profile */
+ struct profile *global_metadata_profile; /* profile (as given by --metadataprofile cmd arg) that overrides any other VG/LV-based profile */
+ struct dm_list profiles_to_load; /* list of profiles which are only added, but still need to be loaded for any use */
+ struct dm_list profiles; /* list of profiles which are loaded already and which are ready for use */
};
#define CFG_PATH_MAX_LEN 64
@@ -166,7 +169,7 @@ enum {
#undef cfg_array_runtime
};
-struct profile *add_profile(struct cmd_context *cmd, const char *profile_name);
+struct profile *add_profile(struct cmd_context *cmd, const char *profile_name, config_source_t source);
int load_profile(struct cmd_context *cmd, struct profile *profile);
int load_pending_profiles(struct cmd_context *cmd);
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index 59603bb..7d4304e 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -576,7 +576,7 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
if (dm_config_get_str(lvn, "profile", &str)) {
log_debug_metadata("Adding profile configuration %s for LV %s/%s.",
str, vg->name, lv->name);
- lv->profile = add_profile(vg->cmd, str);
+ lv->profile = add_profile(vg->cmd, str, CONFIG_PROFILE_METADATA);
if (!lv->profile) {
log_error("Failed to add configuration profile %s for LV %s/%s",
str, vg->name, lv->name);
@@ -814,7 +814,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
if (dm_config_get_str(vgn, "profile", &str)) {
log_debug_metadata("Adding profile configuration %s for VG %s.", str, vg->name);
- vg->profile = add_profile(vg->cmd, str);
+ vg->profile = add_profile(vg->cmd, str, CONFIG_PROFILE_METADATA);
if (!vg->profile) {
log_error("Failed to add configuration profile %s for VG %s", str, vg->name);
goto bad;
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 0eaa719..91a15f2 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4525,7 +4525,7 @@ struct logical_volume *lv_create_empty(const char *name,
goto_bad;
if (vg->fid->fmt->features & FMT_CONFIG_PROFILE)
- lv->profile = vg->cmd->profile_params->global_profile;
+ lv->profile = vg->cmd->profile_params->global_metadata_profile;
return lv;
bad:
diff --git a/lib/mm/memlock.c b/lib/mm/memlock.c
index 5382b69..84b93db 100644
--- a/lib/mm/memlock.c
+++ b/lib/mm/memlock.c
@@ -417,7 +417,7 @@ void critical_section_inc(struct cmd_context *cmd, const char *reason)
* entering the critical section all needed profiles are
* loaded to avoid the disk access later.
*/
- load_pending_profiles(cmd);
+ (void) load_pending_profiles(cmd);
if (!_critical_section) {
_critical_section = 1;
diff --git a/tools/args.h b/tools/args.h
index 2e63adb..6a594c3 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -99,6 +99,8 @@ arg(minrecoveryrate_ARG, '\0', "minrecoveryrate", size_kb_arg, 0)
arg(raidminrecoveryrate_ARG, '\0', "raidminrecoveryrate", size_kb_arg, 0)
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", size_kb_arg, 0)
arg(raidmaxrecoveryrate_ARG, '\0', "raidmaxrecoveryrate", size_kb_arg, 0)
+arg(commandprofile_ARG, '\0', "commandprofile", string_arg, 0)
+arg(metadataprofile_ARG, '\0', "metadataprofile", string_arg, 0)
arg(profile_ARG, '\0', "profile", string_arg, 0)
arg(detachprofile_ARG, '\0', "detachprofile", NULL, 0)
arg(mergedconfig_ARG, '\0', "mergedconfig", NULL, 0)
diff --git a/tools/commands.h b/tools/commands.h
index 5a69e44..6ed4f8d 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -33,6 +33,7 @@ xx(devtypes,
PERMITTED_READ_ONLY,
"devtypes" "\n"
"\t[--aligned]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--nameprefixes]\n"
@@ -56,6 +57,7 @@ xx(dumpconfig,
"Dump configuration",
PERMITTED_READ_ONLY,
"dumpconfig\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-f|--file filename] \n"
"\t[--type {current|default|diff|missing|new|profilable} \n"
"\t[--atversion version]] \n"
@@ -99,6 +101,7 @@ xx(lvchange,
"\t[--addtag Tag]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-C|--contiguous y|n]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[--deltag Tag]\n"
"\t[--detachprofile]\n"
@@ -114,9 +117,9 @@ xx(lvchange,
"\t[--poll {y|n}]\n"
"\t[--noudevsync]\n"
"\t[-M|--persistent y|n] [--major major] [--minor minor]\n"
+ "\t[--metadataprofile ProfileName]\n"
"\t[-P|--partial] " "\n"
"\t[-p|--permission r|rw]\n"
- "\t[--profile ProfileName\n"
"\t[--[raid]minrecoveryrate Rate]\n"
"\t[--[raid]maxrecoveryrate Rate]\n"
"\t[--[raid]syncaction {check|repair}\n"
@@ -136,9 +139,9 @@ xx(lvchange,
addtag_ARG, alloc_ARG, autobackup_ARG, activate_ARG, available_ARG,
contiguous_ARG, deltag_ARG, discards_ARG, detachprofile_ARG, force_ARG,
ignorelockingfailure_ARG, ignoremonitoring_ARG, ignoreactivationskip_ARG,
- ignoreskippedcluster_ARG,
- major_ARG, minor_ARG, monitor_ARG, minrecoveryrate_ARG, maxrecoveryrate_ARG,
- noudevsync_ARG, partial_ARG, permission_ARG, persistent_ARG, poll_ARG,
+ ignoreskippedcluster_ARG, major_ARG, metadataprofile_ARG, minor_ARG,
+ monitor_ARG, minrecoveryrate_ARG, maxrecoveryrate_ARG, noudevsync_ARG,
+ partial_ARG, permission_ARG, persistent_ARG, poll_ARG,
raidminrecoveryrate_ARG, raidmaxrecoveryrate_ARG, raidsyncaction_ARG,
raidwritebehind_ARG, raidwritemostly_ARG, readahead_ARG, resync_ARG,
refresh_ARG, setactivationskip_ARG, syncaction_ARG, sysinit_ARG, test_ARG,
@@ -155,6 +158,7 @@ xx(lvconvert,
"\t[-R|--regionsize MirrorLogRegionSize]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-b|--background]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|-?|--help]\n"
@@ -169,10 +173,12 @@ xx(lvconvert,
"lvconvert "
"[--splitmirrors Images --trackchanges]\n"
"[--splitmirrors Images --name SplitLogicalVolumeName]\n"
+ "\t[--commandprofile ProfileName]\n"
"\tLogicalVolume[Path] [SplittablePhysicalVolume[Path]...]\n\n"
"lvconvert "
"--splitsnapshot\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|-?|--help]\n"
"\t[--noudevsync]\n"
@@ -183,6 +189,7 @@ xx(lvconvert,
"lvconvert "
"[-s|--snapshot]\n"
"\t[-c|--chunksize]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|-?|--help]\n"
"\t[--noudevsync]\n"
@@ -195,6 +202,7 @@ xx(lvconvert,
"--merge\n"
"\t[-b|--background]\n"
"\t[-i|--interval seconds]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|-?|--help]\n"
"\t[-v|--verbose]\n"
@@ -212,6 +220,7 @@ xx(lvconvert,
"\t[-T|--thin ExternalLogicalVolume[Path]\n"
"\t [--originname NewExternalOriginVolumeName]]\n"
"\t[-Z|--zero {y|n}]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] [-h|-?|--help] [-v|--verbose]\n\n"
"lvconvert "
@@ -221,11 +230,13 @@ xx(lvconvert,
"\t[--poolmetadata CacheMetadataLogicalVolume[Path] |\n"
"\t [--poolmetadatasize size]\n"
"\t [--poolmetadataspare {y|n}]]\n"
+ "\t[--commandprofile ProfileName]\n"
"\tCacheDataLogicalVolume[Path]\n\n"
"lvconvert "
"--type cache\n"
"\t--cachepool CachePoolLogicalVolume[Path]\n"
+ "\t[--commandprofile ProfileName]\n"
"\tLogicalVolume[Path]\n\n",
alloc_ARG, background_ARG, cachemode_ARG, cachepool_ARG, chunksize_ARG,
@@ -246,6 +257,7 @@ xx(lvcreate,
"\t[--alloc AllocationPolicy]\n"
"\t[--cachemode CacheMode]\n"
"\t[-C|--contiguous {y|n}]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|-?|--help]\n"
"\t[--ignoremonitoring]\n"
@@ -256,6 +268,7 @@ xx(lvcreate,
"\t{-l|--extents LogicalExtentsNumber[%{VG|PVS|FREE}] |\n"
"\t -L|--size LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
+ "\t[--metadataprofile ProfileName]\n"
"\t[-m|--mirrors Mirrors [--nosync] [{--mirrorlog {disk|core|mirrored}|--corelog}]]\n"
"\t[-n|--name LogicalVolumeName]\n"
"\t[--noudevsync]\n"
@@ -287,6 +300,7 @@ xx(lvcreate,
"\t[--addtag Tag]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-C|--contiguous {y|n}]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[--discards {ignore|nopassdown|passdown}]\n"
"\t[-h|-?|--help]\n"
@@ -299,6 +313,7 @@ xx(lvcreate,
"\t -L|--size LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
"\t[--poolmetadatasize MetadataVolumeSize[bBsSkKmMgG]]\n"
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
+ "\t[--metadataprofile ProfileName]\n"
"\t[-n|--name LogicalVolumeName]\n"
"\t[--noudevsync]\n"
"\t[-p|--permission {r|rw}]\n"
@@ -313,14 +328,13 @@ xx(lvcreate,
addtag_ARG, alloc_ARG, autobackup_ARG, activate_ARG, available_ARG,
cachemode_ARG, chunksize_ARG, contiguous_ARG, corelog_ARG, discards_ARG,
extents_ARG, ignoreactivationskip_ARG, ignoremonitoring_ARG, major_ARG,
- minor_ARG, mirrorlog_ARG, mirrors_ARG, monitor_ARG, minrecoveryrate_ARG,
- maxrecoveryrate_ARG, name_ARG, nosync_ARG, noudevsync_ARG,
- permission_ARG, persistent_ARG, poolmetadatasize_ARG, poolmetadataspare_ARG,
- raidminrecoveryrate_ARG, raidmaxrecoveryrate_ARG, readahead_ARG,
- regionsize_ARG, setactivationskip_ARG, size_ARG, snapshot_ARG, stripes_ARG,
- stripesize_ARG, test_ARG, thin_ARG, thinpool_ARG,
- type_ARG, virtualoriginsize_ARG, virtualsize_ARG,
- wipesignatures_ARG, zero_ARG)
+ metadataprofile_ARG, minor_ARG, mirrorlog_ARG, mirrors_ARG, monitor_ARG,
+ minrecoveryrate_ARG, maxrecoveryrate_ARG, name_ARG, nosync_ARG,
+ noudevsync_ARG, permission_ARG, persistent_ARG, poolmetadatasize_ARG,
+ poolmetadataspare_ARG, raidminrecoveryrate_ARG, raidmaxrecoveryrate_ARG,
+ readahead_ARG, regionsize_ARG, setactivationskip_ARG, size_ARG, snapshot_ARG,
+ stripes_ARG, stripesize_ARG, test_ARG, thin_ARG, thinpool_ARG, type_ARG,
+ virtualoriginsize_ARG, virtualsize_ARG, wipesignatures_ARG, zero_ARG)
xx(lvdisplay,
"Display information about a logical volume",
@@ -328,6 +342,7 @@ xx(lvdisplay,
"lvdisplay\n"
"\t[-a|--all]\n"
"\t[-c|--colon]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -344,6 +359,7 @@ xx(lvdisplay,
"lvdisplay --columns|-C\n"
"\t[--aligned]\n"
"\t[-a|--all]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -373,6 +389,7 @@ xx(lvextend,
"lvextend\n"
"\t[-A|--autobackup y|n]\n"
"\t[--alloc AllocationPolicy]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
@@ -401,6 +418,7 @@ xx(lvmchange,
"With the device mapper, this is obsolete and does nothing.",
0,
"lvmchange\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[-R|--reset]\n"
@@ -413,6 +431,7 @@ xx(lvmdiskscan,
"List devices that may be used as physical volumes",
PERMITTED_READ_ONLY,
"lvmdiskscan\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[-l|--lvmpartition]\n"
@@ -425,6 +444,7 @@ xx(lvmsadc,
"Collect activity data",
0,
"lvmsadc\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[-v|--verbose]\n"
@@ -435,6 +455,7 @@ xx(lvmsar,
"Create activity report",
0,
"lvmsar\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-f|--full]\n"
"\t[-h|--help]\n"
@@ -450,6 +471,7 @@ xx(lvreduce,
0,
"lvreduce\n"
"\t[-A|--autobackup y|n]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
@@ -472,6 +494,7 @@ xx(lvremove,
0,
"lvremove\n"
"\t[-A|--autobackup y|n]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
@@ -488,6 +511,7 @@ xx(lvrename,
0,
"lvrename\n"
"\t[-A|--autobackup {y|n}] " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-h|-?|--help] " "\n"
"\t[--noudevsync]\n"
@@ -505,6 +529,7 @@ xx(lvresize,
"lvresize\n"
"\t[-A|--autobackup y|n]\n"
"\t[--alloc AllocationPolicy]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
@@ -532,6 +557,7 @@ xx(lvs,
"lvs" "\n"
"\t[-a|--all]\n"
"\t[--aligned]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -567,6 +593,7 @@ xx(lvscan,
"lvscan " "\n"
"\t[-a|--all]\n"
"\t[-b|--blockdevice] " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-h|-?|--help] " "\n"
"\t[--ignorelockingfailure]\n"
@@ -584,6 +611,7 @@ xx(pvchange,
"pvchange\n"
"\t[-a|--all]\n"
"\t[-A|--autobackup y|n]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
@@ -604,6 +632,7 @@ xx(pvresize,
"Resize physical volume(s)",
0,
"pvresize " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]" "\n"
"\t[-h|-?|--help] " "\n"
"\t[--setphysicalvolumesize PhysicalVolumeSize[bBsSkKmMgGtTpPeE]" "\n"
@@ -618,6 +647,7 @@ xx(pvck,
"Check the consistency of physical volume(s)",
0,
"pvck "
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--labelsector sector] " "\n"
@@ -633,6 +663,7 @@ xx(pvcreate,
"pvcreate " "\n"
"\t[--norestorefile]\n"
"\t[--restorefile file]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]" "\n"
"\t[-f[f]|--force [--force]] " "\n"
"\t[-h|-?|--help] " "\n"
@@ -663,6 +694,7 @@ xx(pvdata,
0,
"pvdata " "\n"
"\t[-a|--all] " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-E|--physicalextent] " "\n"
"\t[-h|-?|--help]" "\n"
@@ -682,6 +714,7 @@ xx(pvdisplay,
CACHE_VGMETADATA | PERMITTED_READ_ONLY,
"pvdisplay\n"
"\t[-c|--colon]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -698,6 +731,7 @@ xx(pvdisplay,
"pvdisplay --columns|-C\n"
"\t[--aligned]\n"
"\t[-a|--all]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -727,6 +761,7 @@ xx(pvmove,
"\t[-A|--autobackup {y|n}]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-b|--background]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n "
"\t[-h|-?|--help]\n"
"\t[-i|--interval seconds]\n"
@@ -746,6 +781,7 @@ xx(pvremove,
"Remove LVM label(s) from physical volume(s)",
0,
"pvremove " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]" "\n"
"\t[-f[f]|--force [--force]] " "\n"
"\t[-h|-?|--help] " "\n"
@@ -763,6 +799,7 @@ xx(pvs,
"pvs" "\n"
"\t[-a|--all]\n"
"\t[--aligned]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]" "\n"
"\t[-h|-?|--help] " "\n"
"\t[--ignorelockingfailure]\n"
@@ -796,6 +833,7 @@ xx(pvscan,
"pvscan " "\n"
"\t[-b|--background]\n"
"\t[--cache [-a|--activate ay] [ DevicePath | --major major --minor minor]...]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t{-e|--exported | -n|--novolumegroup} " "\n"
"\t[-h|-?|--help]" "\n"
@@ -825,6 +863,7 @@ xx(vgcfgbackup,
"Backup volume group configuration(s)",
PERMITTED_READ_ONLY,
"vgcfgbackup " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-f|--file filename] " "\n"
"\t[-h|-?|--help] " "\n"
@@ -841,6 +880,7 @@ xx(vgcfgrestore,
"Restore volume group configuration",
0,
"vgcfgrestore " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-f|--file filename] " "\n"
"\t[--force]\n"
@@ -861,6 +901,7 @@ xx(vgchange,
"\t[-A|--autobackup {y|n}] " "\n"
"\t[--alloc AllocationPolicy] " "\n"
"\t[-P|--partial] " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[--detachprofile] " "\n"
"\t[-h|--help] " "\n"
@@ -868,6 +909,7 @@ xx(vgchange,
"\t[--ignoremonitoring]\n"
"\t[--ignoreskippedcluster]\n"
"\t[-K|--ignoreactivationskip] \n"
+ "\t[--metadataprofile ProfileName]\n"
"\t[--monitor {y|n}]\n"
"\t[--[vg]metadatacopies #copies] " "\n"
"\t[--poll {y|n}]\n"
@@ -884,7 +926,6 @@ xx(vgchange,
"\t -l|--logicalvolume MaxLogicalVolumes |" "\n"
"\t -p|--maxphysicalvolumes MaxPhysicalVolumes |" "\n"
"\t -s|--physicalextentsize PhysicalExtentSize[bBsSkKmMgGtTpPeE] |" "\n"
- "\t[--profile ProfileName\n"
"\t --addtag Tag |\n"
"\t --deltag Tag}\n"
"\t[VolumeGroupName...]\n",
@@ -892,16 +933,16 @@ xx(vgchange,
addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG, activate_ARG,
available_ARG, clustered_ARG, deltag_ARG, detachprofile_ARG,
ignoreactivationskip_ARG, ignorelockingfailure_ARG, ignoremonitoring_ARG,
- ignoreskippedcluster_ARG,
- logicalvolume_ARG, maxphysicalvolumes_ARG, monitor_ARG, noudevsync_ARG,
- metadatacopies_ARG, vgmetadatacopies_ARG, partial_ARG,
- physicalextentsize_ARG, poll_ARG, refresh_ARG, resizeable_ARG,
- resizable_ARG, sysinit_ARG, test_ARG, uuid_ARG)
+ ignoreskippedcluster_ARG, logicalvolume_ARG, maxphysicalvolumes_ARG,
+ metadataprofile_ARG, monitor_ARG, noudevsync_ARG, metadatacopies_ARG,
+ vgmetadatacopies_ARG, partial_ARG, physicalextentsize_ARG, poll_ARG,
+ refresh_ARG, resizeable_ARG, resizable_ARG, sysinit_ARG, test_ARG, uuid_ARG)
xx(vgck,
"Check the consistency of volume group(s)",
0,
"vgck "
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[-v|--verbose]\n"
@@ -912,6 +953,7 @@ xx(vgconvert,
"Change volume group metadata format",
0,
"vgconvert " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]" "\n"
"\t[-h|--help] " "\n"
"\t[--labelsector sector] " "\n"
@@ -936,9 +978,11 @@ xx(vgcreate,
"\t[--addtag Tag] " "\n"
"\t[--alloc AllocationPolicy] " "\n"
"\t[-c|--clustered {y|n}] " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]" "\n"
"\t[-h|--help]" "\n"
"\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
+ "\t[--metadataprofile ProfileName]\n"
"\t[-M|--metadatatype 1|2] " "\n"
"\t[--[vg]metadatacopies #copies] " "\n"
"\t[-p|--maxphysicalvolumes MaxPhysicalVolumes] " "\n"
@@ -951,10 +995,10 @@ xx(vgcreate,
"\tVolumeGroupName PhysicalDevicePath [PhysicalDevicePath...]\n",
addtag_ARG, alloc_ARG, autobackup_ARG, clustered_ARG, maxlogicalvolumes_ARG,
- maxphysicalvolumes_ARG, metadatatype_ARG, physicalextentsize_ARG, test_ARG,
- force_ARG, zero_ARG, labelsector_ARG, metadatasize_ARG,
- pvmetadatacopies_ARG, metadatacopies_ARG, vgmetadatacopies_ARG,
- dataalignment_ARG, dataalignmentoffset_ARG)
+ maxphysicalvolumes_ARG, metadataprofile_ARG, metadatatype_ARG,
+ physicalextentsize_ARG, test_ARG, force_ARG, zero_ARG, labelsector_ARG,
+ metadatasize_ARG, pvmetadatacopies_ARG, metadatacopies_ARG,
+ vgmetadatacopies_ARG, dataalignment_ARG, dataalignmentoffset_ARG)
xx(vgdisplay,
"Display volume group information",
@@ -962,6 +1006,7 @@ xx(vgdisplay,
"vgdisplay " "\n"
"\t[-A|--activevolumegroups]" "\n"
"\t[-c|--colon | -s|--short | -v|--verbose]" "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-h|--help] " "\n"
"\t[--ignorelockingfailure]" "\n"
@@ -975,6 +1020,7 @@ xx(vgdisplay,
"\n"
"vgdisplay --columns|-C\n"
"\t[--aligned]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-h|--help] " "\n"
"\t[--ignorelockingfailure]" "\n"
@@ -1002,6 +1048,7 @@ xx(vgexport,
0,
"vgexport " "\n"
"\t[-a|--all] " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-h|--help]" "\n"
"\t[-v|--verbose] " "\n"
@@ -1016,6 +1063,7 @@ xx(vgextend,
"vgextend\n"
"\t[-A|--autobackup y|n]\n"
"\t[--restoremissing]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
@@ -1037,6 +1085,7 @@ xx(vgimport,
0,
"vgimport " "\n"
"\t[-a|--all]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-f|--force] " "\n"
"\t[-h|--help] " "\n"
@@ -1052,6 +1101,7 @@ xx(vgmerge,
0,
"vgmerge\n"
"\t[-A|--autobackup y|n]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[-l|--list]\n"
@@ -1066,6 +1116,7 @@ xx(vgmknodes,
"Create the special files for volume group devices in /dev",
0,
"vgmknodes\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -1082,6 +1133,7 @@ xx(vgreduce,
"vgreduce\n"
"\t[-a|--all]\n"
"\t[-A|--autobackup y|n]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--mirrorsonly]\n"
@@ -1100,6 +1152,7 @@ xx(vgremove,
"Remove volume group(s)",
0,
"vgremove\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
@@ -1116,6 +1169,7 @@ xx(vgrename,
0,
"vgrename\n"
"\t[-A|--autobackup y|n]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[-t|--test]\n"
@@ -1132,6 +1186,7 @@ xx(vgs,
"vgs" "\n"
"\t[--aligned]\n"
"\t[-a|--all]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -1165,6 +1220,7 @@ xx(vgscan,
PERMITTED_READ_ONLY,
"vgscan "
"\t[--cache]\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -1182,6 +1238,7 @@ xx(vgsplit,
"\t[-A|--autobackup {y|n}] " "\n"
"\t[--alloc AllocationPolicy] " "\n"
"\t[-c|--clustered {y|n}] " "\n"
+ "\t[--commandprofile ProfileName]\n"
"\t[-d|--debug] " "\n"
"\t[-h|--help] " "\n"
"\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
diff --git a/tools/lvchange.c b/tools/lvchange.c
index bddc079..48e48d4 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -898,8 +898,11 @@ static int lvchange_profile(struct logical_volume *lv)
new_profile_name = "(inherited)";
lv->profile = NULL;
} else {
- new_profile_name = arg_str_value(lv->vg->cmd, profile_ARG, NULL);
- if (!(new_profile = add_profile(lv->vg->cmd, new_profile_name)))
+ if (arg_count(lv->vg->cmd, metadataprofile_ARG))
+ new_profile_name = arg_str_value(lv->vg->cmd, metadataprofile_ARG, NULL);
+ else
+ new_profile_name = arg_str_value(lv->vg->cmd, profile_ARG, NULL);
+ if (!(new_profile = add_profile(lv->vg->cmd, new_profile_name, CONFIG_PROFILE_METADATA)))
return_0;
lv->profile = new_profile;
}
@@ -944,7 +947,8 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
arg_count(cmd, discards_ARG) || arg_count(cmd, zero_ARG) ||
- arg_count(cmd, alloc_ARG) || arg_count(cmd, profile_ARG))) {
+ arg_count(cmd, alloc_ARG) || arg_count(cmd, profile_ARG) ||
+ arg_count(cmd, metadataprofile_ARG))) {
log_error("Only -a permitted with read-only volume "
"group \"%s\"", lv->vg->name);
return EINVALID_CMD_LINE;
@@ -958,7 +962,8 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lv_is_origin(lv) && !lv_is_thin_volume(lv) &&
(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
- arg_count(cmd, alloc_ARG) || arg_count(cmd, profile_ARG))) {
+ arg_count(cmd, alloc_ARG) || arg_count(cmd, profile_ARG) ||
+ arg_count(cmd, metadataprofile_ARG))) {
log_error("Can't change logical volume \"%s\" under snapshot",
lv->name);
return ECMD_FAILED;
@@ -1108,7 +1113,8 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* change configuration profile */
- if (arg_count(cmd, profile_ARG) || arg_count(cmd, detachprofile_ARG)) {
+ if (arg_count(cmd, profile_ARG) || arg_count(cmd, metadataprofile_ARG) ||
+ arg_count(cmd, detachprofile_ARG)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
doit += lvchange_profile(lv);
@@ -1170,6 +1176,7 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
arg_count(cmd, persistent_ARG) ||
arg_count(cmd, addtag_ARG) ||
arg_count(cmd, deltag_ARG) ||
+ arg_count(cmd, metadataprofile_ARG) ||
arg_count(cmd, profile_ARG) ||
arg_count(cmd, detachprofile_ARG) ||
arg_count(cmd, setactivationskip_ARG);
@@ -1194,8 +1201,9 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, profile_ARG) && arg_count(cmd, detachprofile_ARG)) {
- log_error("Only one of --profile and --detachprofile permitted.");
+ if ((arg_count(cmd, profile_ARG) || arg_count(cmd, metadataprofile_ARG)) &&
+ arg_count(cmd, detachprofile_ARG)) {
+ log_error("Only one of --metadataprofile and --detachprofile permitted.");
return EINVALID_CMD_LINE;
}
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 69e5781..96e478f 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -622,6 +622,7 @@ void lvm_register_commands(void)
version_ARG, verbose_ARG, \
yes_ARG, \
quiet_ARG, config_ARG, \
+ commandprofile_ARG, \
profile_ARG, -1);
#include "commands.h"
#undef xx
@@ -1079,10 +1080,122 @@ static const char *_copy_command_line(struct cmd_context *cmd, int argc, char **
return NULL;
}
-int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
+static int _prepare_profiles(struct cmd_context *cmd)
{
- struct dm_config_tree *config_string_cft, *config_profile_cft;
+ static const char _failed_to_add_profile_msg[] = "Failed to add %s %s.";
+ static const char _failed_to_apply_profile_msg[] = "Failed to apply %s %s.";
+ static const char _command_profile_source_name[] = "command profile";
+ static const char _metadata_profile_source_name[] = "metadata profile";
+ static const char _setting_global_profile_msg[] = "Setting global %s \"%s\".";
+
+ const char *name;
struct profile *profile;
+ config_source_t source;
+ const char *source_name;
+
+ if (arg_count(cmd, profile_ARG)) {
+ /*
+ * If --profile is used with dumpconfig, it's used
+ * to dump the profile without the profile being applied.
+ */
+ if (!strcmp(cmd->command->name, "dumpconfig"))
+ return 1;
+
+ /*
+ * If --profile is used with lvcreate/lvchange/vgchange,
+ * it's recognized as shortcut to --metadataprofile.
+ * The --commandprofile is assumed otherwise.
+ */
+ if (!strcmp(cmd->command->name, "lvcreate") ||
+ !strcmp(cmd->command->name, "vgcreate") ||
+ !strcmp(cmd->command->name, "lvchange") ||
+ !strcmp(cmd->command->name, "vgchange")) {
+ if (arg_count(cmd, metadataprofile_ARG)) {
+ log_error("Only one of --profile or "
+ " --metadataprofile allowed.");
+ return 0;
+ }
+ source = CONFIG_PROFILE_METADATA;
+ source_name = _metadata_profile_source_name;
+ }
+ else {
+ if (arg_count(cmd, commandprofile_ARG)) {
+ log_error("Only one of --profile or "
+ "--commandprofile allowed.");
+ return 0;
+ }
+ source = CONFIG_PROFILE_COMMAND;
+ source_name = _command_profile_source_name;
+ }
+
+ name = arg_str_value(cmd, profile_ARG, NULL);
+
+ if (!(profile = add_profile(cmd, name, source))) {
+ log_error(_failed_to_add_profile_msg, source_name, name);
+ return 0;
+ }
+
+ if (source == CONFIG_PROFILE_COMMAND) {
+ log_debug(_setting_global_profile_msg, _command_profile_source_name, profile->name);
+ cmd->profile_params->global_command_profile = profile;
+ } else if (source == CONFIG_PROFILE_METADATA) {
+ log_debug(_setting_global_profile_msg, _metadata_profile_source_name, profile->name);
+ /* This profile will override any VG/LV-based profile if present */
+ cmd->profile_params->global_metadata_profile = profile;
+ }
+
+ if (!override_config_tree_from_profile(cmd, profile)) {
+ log_error(_failed_to_apply_profile_msg, source_name, name);
+ return 0;
+ }
+
+ }
+
+ if (arg_count(cmd, commandprofile_ARG)) {
+ name = arg_str_value(cmd, commandprofile_ARG, NULL);
+ source_name = _command_profile_source_name;
+
+ if (!(profile = add_profile(cmd, name, CONFIG_PROFILE_COMMAND))) {
+ log_error(_failed_to_add_profile_msg, source_name, name);
+ return 0;
+ }
+ if (!override_config_tree_from_profile(cmd, profile)) {
+ log_error(_failed_to_apply_profile_msg, source_name, name);
+ return 0;
+ }
+
+ log_debug(_setting_global_profile_msg, _command_profile_source_name, profile->name);
+ cmd->profile_params->global_command_profile = profile;
+ }
+
+
+ if (arg_count(cmd, metadataprofile_ARG)) {
+ name = arg_str_value(cmd, metadataprofile_ARG, NULL);
+ source_name = _metadata_profile_source_name;
+
+ if (!(profile = add_profile(cmd, name, CONFIG_PROFILE_METADATA))) {
+ log_error(_failed_to_add_profile_msg, source_name, name);
+ return 0;
+ }
+ if (!override_config_tree_from_profile(cmd, profile)) {
+ log_error(_failed_to_apply_profile_msg, source_name, name);
+ return 0;
+ }
+
+ log_debug(_setting_global_profile_msg, _metadata_profile_source_name, profile->name);
+ cmd->profile_params->global_metadata_profile = profile;
+ }
+
+ if (!process_profilable_config(cmd))
+ return_0;
+
+ return 1;
+}
+
+int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
+{
+ struct dm_config_tree *config_string_cft;
+ struct dm_config_tree *config_profile_command_cft, *config_profile_metadata_cft;
int ret = 0;
int locking_type;
int monitoring;
@@ -1131,19 +1244,10 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
}
}
- if (arg_count(cmd, profile_ARG)) {
- if (!(profile = add_profile(cmd, arg_str_value(cmd, profile_ARG, NULL)))) {
- log_error("Failed to add configuration profile.");
- return ECMD_FAILED;
- }
- log_debug("Setting global configuration profile \"%s\".", profile->name);
- /* This profile will override any VG/LV-based profile if present */
- cmd->profile_params->global_profile = profile;
- if (!override_config_tree_from_profile(cmd, profile)) {
- log_error("Failed to apply configuration profile.");
- return ECMD_FAILED;
- }
- if (!process_profilable_config(cmd))
+ if (arg_count(cmd, profile_ARG) ||
+ arg_count(cmd, commandprofile_ARG) ||
+ arg_count(cmd, metadataprofile_ARG)) {
+ if (!_prepare_profiles(cmd))
return_ECMD_FAILED;
}
@@ -1206,10 +1310,11 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING)))
dm_config_destroy(config_string_cft);
- config_profile_cft = remove_config_tree_by_source(cmd, CONFIG_PROFILE);
- cmd->profile_params->global_profile = NULL;
+ config_profile_command_cft = remove_config_tree_by_source(cmd, CONFIG_PROFILE_COMMAND);
+ config_profile_metadata_cft = remove_config_tree_by_source(cmd, CONFIG_PROFILE_METADATA);
+ cmd->profile_params->global_metadata_profile = NULL;
- if (config_string_cft || config_profile_cft) {
+ if (config_string_cft || config_profile_command_cft || config_profile_metadata_cft) {
/* Move this? */
if (!refresh_toolcontext(cmd))
stack;
diff --git a/tools/vgchange.c b/tools/vgchange.c
index d24b17e..05e7aea 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -441,8 +441,11 @@ static int _vgchange_profile(struct cmd_context *cmd,
new_profile_name = "(no profile)";
vg->profile = NULL;
} else {
- new_profile_name = arg_str_value(cmd, profile_ARG, NULL);
- if (!(new_profile = add_profile(cmd, new_profile_name)))
+ if (arg_count(cmd, metadataprofile_ARG))
+ new_profile_name = arg_str_value(cmd, metadataprofile_ARG, NULL);
+ else
+ new_profile_name = arg_str_value(cmd, profile_ARG, NULL);
+ if (!(new_profile = add_profile(cmd, new_profile_name, CONFIG_PROFILE_METADATA)))
return_0;
vg->profile = new_profile;
}
@@ -473,6 +476,7 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
{ alloc_ARG, &_vgchange_alloc },
{ clustered_ARG, &_vgchange_clustered },
{ vgmetadatacopies_ARG, &_vgchange_metadata_copies },
+ { metadataprofile_ARG, &_vgchange_profile },
{ profile_ARG, &_vgchange_profile},
{ detachprofile_ARG, &_vgchange_profile},
};
@@ -547,6 +551,7 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
int update_partial_safe =
arg_count(cmd, deltag_ARG) ||
arg_count(cmd, addtag_ARG) ||
+ arg_count(cmd, metadataprofile_ARG) ||
arg_count(cmd, profile_ARG) ||
arg_count(cmd, detachprofile_ARG);
int update_partial_unsafe =
@@ -572,8 +577,9 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
- if (arg_count(cmd, profile_ARG) && arg_count(cmd, detachprofile_ARG)) {
- log_error("Only one of --profile and --detachprofile permitted.");
+ if ((arg_count(cmd, profile_ARG) || arg_count(cmd, metadataprofile_ARG)) &&
+ arg_count(cmd, detachprofile_ARG)) {
+ log_error("Only one of --metadataprofile and --detachprofile permitted.");
return EINVALID_CMD_LINE;
}
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index 45f4c04..9d701c8 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -63,7 +63,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
}
if (vg->fid->fmt->features & FMT_CONFIG_PROFILE)
- vg->profile = vg->cmd->profile_params->global_profile;
+ vg->profile = vg->cmd->profile_params->global_metadata_profile;
if (!vg_set_extent_size(vg, vp_new.extent_size) ||
!vg_set_max_lv(vg, vp_new.max_lv) ||
9 years, 11 months
master - config: add CFG_PROFILABLE_METADATA flag
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c5fbd2c59f1248...
Commit: c5fbd2c59f1248b1315aae71dee032878d8476f8
Parent: 22cab9c481c853cb58aef4b5836f74b3ddfd586c
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon May 19 16:29:50 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon May 19 16:31:15 2014 +0200
config: add CFG_PROFILABLE_METADATA flag
Mark profilable settings with a separate CFG_PROFILABLE_METADATA
flag where the profile can be attached to VG/LV. This makes it possible
to differentiate global command-profilable settings (CFG_PROFILABLE flag)
and contextual metadata-profilable (per VG/LV) settings (CFG_PROFILABLE_METADATA flag).
---
lib/config/config.h | 8 ++++++--
lib/config/config_settings.h | 13 +++++++------
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/lib/config/config.h b/lib/config/config.h
index df5841c..f06fb68 100644
--- a/lib/config/config.h
+++ b/lib/config/config.h
@@ -97,10 +97,14 @@ typedef union {
#define CFG_UNSUPPORTED 0x08
/* whether the configuration item is customizable by a profile */
#define CFG_PROFILABLE 0x10
+/* whether the configuration item is customizable by a profile */
+/* and whether it can be attached to VG/LV metadata at the same time
+ * The CFG_PROFILABLE_METADATA flag incorporates CFG_PROFILABLE flag!!! */
+#define CFG_PROFILABLE_METADATA 0x30
/* whether the default value is undefned */
-#define CFG_DEFAULT_UNDEFINED 0x20
+#define CFG_DEFAULT_UNDEFINED 0x40
/* whether the defualt value is calculated during run time */
-#define CFG_DEFAULT_RUN_TIME 0x40
+#define CFG_DEFAULT_RUN_TIME 0x80
/* configuration definition item structure */
typedef struct cfg_def_item {
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 3792238..d277e0e 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -41,6 +41,7 @@
* CFG_ADVANCED - this node belongs to advanced config set
* CFG_UNSUPPORTED - this node belongs to unsupported config set
* CFG_PROFILABLE - this node is customizable by a profile
+ * CFG_PROFILABLE_METADATA - profilable and attachable to VG/LV metadata
* CFG_DEFAULT_UNDEFINED - node's default value is undefined
* type: allowed type for the value of simple configuation setting, one of:
* CFG_TYPE_BOOL
@@ -121,10 +122,10 @@ cfg(allocation_mirror_logs_require_separate_pvs_CFG, "mirror_logs_require_separa
cfg(allocation_cache_pool_metadata_require_separate_pvs_CFG, "cache_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 106), NULL)
cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", allocation_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 106), NULL)
cfg(allocation_thin_pool_metadata_require_separate_pvs_CFG, "thin_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 89), NULL)
-cfg(allocation_thin_pool_zero_CFG, "thin_pool_zero", allocation_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_ZERO, vsn(2, 2, 99), NULL)
-cfg(allocation_thin_pool_discards_CFG, "thin_pool_discards", allocation_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_THIN_POOL_DISCARDS, vsn(2, 2, 99), NULL)
-cfg(allocation_thin_pool_chunk_size_policy_CFG, "thin_pool_chunk_size_policy", allocation_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_THIN_POOL_CHUNK_SIZE_POLICY, vsn(2, 2, 101), NULL)
-cfg_runtime(allocation_thin_pool_chunk_size_CFG, "thin_pool_chunk_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 99), NULL)
+cfg(allocation_thin_pool_zero_CFG, "thin_pool_zero", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_ZERO, vsn(2, 2, 99), NULL)
+cfg(allocation_thin_pool_discards_CFG, "thin_pool_discards", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_STRING, DEFAULT_THIN_POOL_DISCARDS, vsn(2, 2, 99), NULL)
+cfg(allocation_thin_pool_chunk_size_policy_CFG, "thin_pool_chunk_size_policy", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_STRING, DEFAULT_THIN_POOL_CHUNK_SIZE_POLICY, vsn(2, 2, 101), NULL)
+cfg_runtime(allocation_thin_pool_chunk_size_CFG, "thin_pool_chunk_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 99), NULL)
cfg(log_verbose_CFG, "verbose", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_VERBOSE, vsn(1, 0, 0), NULL)
@@ -204,8 +205,8 @@ cfg(activation_mirror_log_fault_policy_CFG, "mirror_log_fault_policy", activatio
cfg_runtime(activation_mirror_image_fault_policy_CFG, "mirror_image_fault_policy", activation_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(2, 2, 57), NULL)
cfg(activation_snapshot_autoextend_threshold_CFG, "snapshot_autoextend_threshold", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_SNAPSHOT_AUTOEXTEND_THRESHOLD, vsn(2, 2, 75), NULL)
cfg(activation_snapshot_autoextend_percent_CFG, "snapshot_autoextend_percent", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_SNAPSHOT_AUTOEXTEND_PERCENT, vsn(2, 2, 75), NULL)
-cfg(activation_thin_pool_autoextend_threshold_CFG, "thin_pool_autoextend_threshold", activation_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_THRESHOLD, vsn(2, 2, 89), NULL)
-cfg(activation_thin_pool_autoextend_percent_CFG, "thin_pool_autoextend_percent", activation_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_PERCENT, vsn(2, 2, 89), NULL)
+cfg(activation_thin_pool_autoextend_threshold_CFG, "thin_pool_autoextend_threshold", activation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_THRESHOLD, vsn(2, 2, 89), NULL)
+cfg(activation_thin_pool_autoextend_percent_CFG, "thin_pool_autoextend_percent", activation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_PERCENT, vsn(2, 2, 89), NULL)
cfg_array(activation_mlock_filter_CFG, "mlock_filter", activation_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 62), NULL)
cfg(activation_use_mlockall_CFG, "use_mlockall", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_USE_MLOCKALL, vsn(2, 2, 62), NULL)
cfg(activation_monitoring_CFG, "monitoring", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DMEVENTD_MONITOR, vsn(2, 2, 63), NULL)
9 years, 11 months
master - commands: do not register profile_ARG for lvcreate/lvchange separetely
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=22cab9c481c853...
Commit: 22cab9c481c853cb58aef4b5836f74b3ddfd586c
Parent: 24f32721a9e6a61943122f3d06d2329f5f81597c
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon May 19 16:29:06 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon May 19 16:30:49 2014 +0200
commands: do not register profile_ARG for lvcreate/lvchange separetely
The --profile is globally available for all commands.
---
tools/commands.h | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tools/commands.h b/tools/commands.h
index 21a2075..5a69e44 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -139,10 +139,10 @@ xx(lvchange,
ignoreskippedcluster_ARG,
major_ARG, minor_ARG, monitor_ARG, minrecoveryrate_ARG, maxrecoveryrate_ARG,
noudevsync_ARG, partial_ARG, permission_ARG, persistent_ARG, poll_ARG,
- profile_ARG, raidminrecoveryrate_ARG, raidmaxrecoveryrate_ARG,
- raidsyncaction_ARG, raidwritebehind_ARG, raidwritemostly_ARG, readahead_ARG,
- resync_ARG, refresh_ARG, setactivationskip_ARG, syncaction_ARG, sysinit_ARG,
- test_ARG, writebehind_ARG, writemostly_ARG, zero_ARG)
+ raidminrecoveryrate_ARG, raidmaxrecoveryrate_ARG, raidsyncaction_ARG,
+ raidwritebehind_ARG, raidwritemostly_ARG, readahead_ARG, resync_ARG,
+ refresh_ARG, setactivationskip_ARG, syncaction_ARG, sysinit_ARG, test_ARG,
+ writebehind_ARG, writemostly_ARG, zero_ARG)
xx(lvconvert,
"Change logical volume layout",
@@ -894,7 +894,7 @@ xx(vgchange,
ignoreactivationskip_ARG, ignorelockingfailure_ARG, ignoremonitoring_ARG,
ignoreskippedcluster_ARG,
logicalvolume_ARG, maxphysicalvolumes_ARG, monitor_ARG, noudevsync_ARG,
- metadatacopies_ARG, vgmetadatacopies_ARG, partial_ARG, profile_ARG,
+ metadatacopies_ARG, vgmetadatacopies_ARG, partial_ARG,
physicalextentsize_ARG, poll_ARG, refresh_ARG, resizeable_ARG,
resizable_ARG, sysinit_ARG, test_ARG, uuid_ARG)
9 years, 11 months