mirror of
git://sourceware.org/git/lvm2.git
synced 2025-09-24 21:44:22 +03:00
Compare commits
9 Commits
dev-dct-cm
...
dev-dct-cm
Author | SHA1 | Date | |
---|---|---|---|
|
c3ce2456b7 | ||
|
7ccbe49876 | ||
|
295bf7baaa | ||
|
fe1d4e6a08 | ||
|
2023297736 | ||
|
c0a356561a | ||
|
4df2157c72 | ||
|
08cf602be1 | ||
|
072ef008ea |
@@ -30,8 +30,8 @@ aux wait_for_sync $vg $lv2
|
||||
lvchange -an $vg/$lv1
|
||||
|
||||
# conversion fails for internal volumes
|
||||
invalid lvconvert --thinpool $vg/${lv1}_rimage_0
|
||||
invalid lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $vg/${lv2}_rimage_0
|
||||
not lvconvert --thinpool $vg/${lv1}_rimage_0
|
||||
not lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $vg/${lv2}_rimage_0
|
||||
|
||||
lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
|
||||
|
@@ -58,13 +58,13 @@ lvchange -an $vg/$lv1
|
||||
# conversion fails for mirror segment type
|
||||
fail lvconvert --thinpool $vg/$lv1
|
||||
# cannot use same LV
|
||||
invalid lvconvert --yes --thinpool $vg/$lv2 --poolmetadata $vg/$lv2
|
||||
not lvconvert --yes --thinpool $vg/$lv2 --poolmetadata $vg/$lv2
|
||||
|
||||
prepare_lvs
|
||||
|
||||
# conversion fails for internal volumes
|
||||
# can't use --readahead with --poolmetadata
|
||||
invalid lvconvert --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 --readahead 512
|
||||
not lvconvert --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 --readahead 512
|
||||
lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
|
||||
prepare_lvs
|
||||
@@ -81,9 +81,9 @@ grep "Pool zeroing and large" err
|
||||
UUID=$(get lv_field $vg/$lv2 uuid)
|
||||
# Fail is pool is active
|
||||
# TODO maybe detect inactive pool and deactivate
|
||||
fail lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $lv2
|
||||
fail lvconvert --swapmetadata --yes --poolmetadata $lv2 $vg/$lv1
|
||||
lvchange -an $vg
|
||||
lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $lv2
|
||||
lvconvert --swapmetadata --yes --poolmetadata $lv2 $vg/$lv1
|
||||
check lv_field $vg/${lv1}_tmeta uuid "$UUID"
|
||||
lvremove -f $vg
|
||||
|
||||
@@ -96,20 +96,20 @@ lvcreate -L1M -n $lv3 $vg
|
||||
# chunk size is bigger then size of thin pool data
|
||||
fail lvconvert --yes -c 1G --thinpool $vg/$lv3
|
||||
# stripes can't be used with poolmetadata
|
||||
invalid lvconvert --stripes 2 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
not lvconvert --stripes 2 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
# too small metadata (<2M)
|
||||
fail lvconvert --yes -c 64 --thinpool $vg/$lv1 --poolmetadata $vg/$lv3
|
||||
# too small chunk size fails
|
||||
invalid lvconvert -c 4 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
not lvconvert -c 4 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
# too big chunk size fails
|
||||
invalid lvconvert -c 2G --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
not lvconvert -c 2G --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
# negative chunk size fails
|
||||
invalid lvconvert -c -256 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
not lvconvert -c -256 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
# non multiple of 64KiB fails
|
||||
invalid lvconvert -c 88 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
not lvconvert -c 88 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2
|
||||
|
||||
# cannot use same LV for pool and convertion
|
||||
invalid lvconvert --yes --thinpool $vg/$lv3 -T $vg/$lv3
|
||||
not lvconvert --yes --thinpool $vg/$lv3 -T $vg/$lv3
|
||||
|
||||
# Warning about smaller then suggested
|
||||
lvconvert --yes -c 256 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 2>&1 | tee err
|
||||
@@ -129,7 +129,7 @@ if test "$TSIZE" = 64T; then
|
||||
lvcreate -L24T -n $lv1 $vg
|
||||
# Warning about bigger then needed (24T data and 16G -> 128K chunk)
|
||||
lvconvert --yes -c 64 --thinpool $vg/$lv1 2>&1 | tee err
|
||||
grep "WARNING: Chunk size is too small" err
|
||||
grep "too small" err
|
||||
lvremove -f $vg
|
||||
fi
|
||||
|
||||
|
@@ -44,7 +44,7 @@ touch mntsnap/test_snap
|
||||
|
||||
lvs -o+tags,thin_id $vg
|
||||
|
||||
lvconvert --merge $vg/snap
|
||||
lvconvert --mergethin $vg/snap
|
||||
|
||||
umount mnt
|
||||
|
||||
@@ -107,7 +107,7 @@ fsck -n "$DM_DEV_DIR/$vg/$lv1"
|
||||
check lv_not_exists $vg oldsnapof_${lv1}
|
||||
# Add old snapshot to thin snapshot
|
||||
lvcreate -s -L10 -n oldsnapof_snap $vg/snap
|
||||
lvconvert --merge $vg/snap
|
||||
lvconvert --mergethin $vg/snap
|
||||
lvremove -f $vg/oldsnapof_snap
|
||||
|
||||
vgremove -ff $vg
|
||||
|
@@ -34,7 +34,7 @@ mount "$DM_DEV_DIR/$vg/$lv1" mnt
|
||||
lvcreate -s -n snap $vg/$lv1
|
||||
check lv_field $vg/snap thin_id "3"
|
||||
|
||||
lvconvert --merge $vg/snap
|
||||
lvconvert --mergethin $vg/snap
|
||||
|
||||
umount mnt
|
||||
vgchange -an $vg
|
||||
|
@@ -60,7 +60,9 @@ arg(locktype_ARG, '\0', "locktype", locktype_VAL, 0, 0)
|
||||
arg(logonly_ARG, '\0', "logonly", 0, 0, 0)
|
||||
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", sizekb_VAL, 0, 0)
|
||||
arg(merge_ARG, '\0', "merge", 0, 0, 0)
|
||||
arg(mergemirrors_ARG, '\0', "mergemirrors", 0, 0, 0)
|
||||
arg(mergesnapshot_ARG, '\0', "mergesnapshot", 0, 0, 0)
|
||||
arg(mergethin_ARG, '\0', "mergethin", 0, 0, 0)
|
||||
arg(mergedconfig_ARG, '\0', "mergedconfig", 0, 0, 0)
|
||||
arg(metadatacopies_ARG, '\0', "metadatacopies", metadatacopies_VAL, 0, 0)
|
||||
arg(metadataignore_ARG, '\0', "metadataignore", bool_VAL, 0, 0)
|
||||
@@ -120,6 +122,7 @@ arg(showdeprecated_ARG, '\0', "showdeprecated", 0, 0, 0)
|
||||
arg(showunsupported_ARG, '\0', "showunsupported", 0, 0, 0)
|
||||
arg(startpoll_ARG, '\0', "startpoll", 0, 0, 0)
|
||||
arg(stripes_long_ARG, '\0', "stripes", number_VAL, 0, 0)
|
||||
arg(swapmetadata_ARG, '\0', "swapmetadata", 0, 0, 0)
|
||||
arg(syncaction_ARG, '\0', "syncaction", syncaction_VAL, 0, 0)
|
||||
arg(sysinit_ARG, '\0', "sysinit", 0, 0, 0)
|
||||
arg(systemid_ARG, '\0', "systemid", string_VAL, 0, 0)
|
||||
|
@@ -373,6 +373,12 @@ OP: PV ...
|
||||
ID: lvconvert_split_mirror_images
|
||||
DESC: Split images from a raid1 LV and track changes to origin.
|
||||
|
||||
lvconvert --mergemirrors LV_linear_raid|VG|Tag ...
|
||||
OO: OO_LVCONVERT
|
||||
ID: lvconvert_merge_mirror_images
|
||||
DESC: Merge LV images that were split from a raid1 LV.
|
||||
RULE: all not lv_is_locked lv_is_pvmove lv_is_merging_origin lv_is_virtual_origin lv_is_external_origin lv_is_merging_cow
|
||||
|
||||
lvconvert --mirrorlog MirrorLog LV_mirror
|
||||
OO: OO_LVCONVERT
|
||||
OP: PV ...
|
||||
@@ -388,6 +394,8 @@ lvconvert --type thin --thinpool LV LV_linear_striped_raid
|
||||
OO: --thin, --originname LV_new, --zero Bool, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
ID: lvconvert_to_thin_with_external
|
||||
DESC: Convert LV to type thin with an external origin.
|
||||
RULE: all and lv_is_visible
|
||||
RULE: all not lv_is_locked
|
||||
|
||||
# alternate form of lvconvert --type thin
|
||||
lvconvert --thin --thinpool LV LV_linear_striped_raid
|
||||
@@ -396,6 +404,8 @@ ID: lvconvert_to_thin_with_external
|
||||
DESC: Convert LV to type thin with an external origin
|
||||
DESC: (variant, infers --type thin).
|
||||
FLAGS: SECONDARY_SYNTAX
|
||||
RULE: all and lv_is_visible
|
||||
RULE: all not lv_is_locked
|
||||
|
||||
---
|
||||
|
||||
@@ -404,6 +414,7 @@ OO: --cache, --cachemode CacheMode, --cachepolicy String,
|
||||
--cachesettings String, --zero Bool, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
ID: lvconvert_to_cache_vol
|
||||
DESC: Convert LV to type cache.
|
||||
RULE: all and lv_is_visible
|
||||
|
||||
# alternate form of lvconvert --type cache
|
||||
lvconvert --cache --cachepool LV LV_linear_striped_raid_thinpool
|
||||
@@ -412,6 +423,7 @@ OO: --type cache, --cachemode CacheMode, --cachepolicy String,
|
||||
ID: lvconvert_to_cache_vol
|
||||
DESC: Convert LV to type cache (variant, infers --type cache).
|
||||
FLAGS: SECONDARY_SYNTAX
|
||||
RULE: all and lv_is_visible
|
||||
|
||||
---
|
||||
|
||||
@@ -421,14 +433,18 @@ OO: --stripes_long Number, --stripesize SizeKB,
|
||||
OP: PV ...
|
||||
ID: lvconvert_to_thinpool
|
||||
DESC: Convert LV to type thin-pool.
|
||||
RULE: all and lv_is_visible
|
||||
RULE: all not lv_is_locked lv_is_origin lv_is_merging_origin lv_is_external_origin lv_is_virtual
|
||||
|
||||
# alternate form of lvconvert --type thin-pool
|
||||
# deprecated because of non-standard syntax (missing positional arg)
|
||||
# Commands in this form are converted to standard form so that
|
||||
# the validation of LV types and rules specified above will apply.
|
||||
lvconvert --thinpool LV_linear_striped_raid_cache
|
||||
OO: --type thin-pool, --stripes_long Number, --stripesize SizeKB,
|
||||
--discards Discards, --zero Bool, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
OP: PV ...
|
||||
ID: lvconvert_to_thinpool
|
||||
ID: lvconvert_to_thinpool_noarg
|
||||
DESC: Convert LV to type thin-pool (variant, use --type thin-pool).
|
||||
FLAGS: SECONDARY_SYNTAX
|
||||
|
||||
@@ -443,10 +459,13 @@ DESC: Convert LV to type cache-pool.
|
||||
|
||||
# alternate form of lvconvert --type cache-pool
|
||||
# deprecated because of non-standard syntax (missing positional arg)
|
||||
# Commands in this form are converted to standard form so that
|
||||
# the validation of LV types and rules specified above will apply.
|
||||
lvconvert --cachepool LV_linear_striped_raid
|
||||
OO: --type cache-pool, OO_LVCONVERT_POOL, OO_LVCONVERT,
|
||||
--cachemode CacheMode, --cachepolicy String, --cachesettings String
|
||||
ID: lvconvert_to_cachepool
|
||||
OP: PV ...
|
||||
ID: lvconvert_to_cachepool_noarg
|
||||
DESC: Convert LV to type cache-pool (variant, use --type cache-pool).
|
||||
FLAGS: SECONDARY_SYNTAX
|
||||
|
||||
@@ -461,52 +480,42 @@ DESC: Separate and keep the cache pool from a cache LV.
|
||||
|
||||
lvconvert --uncache LV_cache_thinpool
|
||||
OO: OO_LVCONVERT
|
||||
ID: lvconvert_split_and_delete_cachepool
|
||||
ID: lvconvert_split_and_remove_cachepool
|
||||
DESC: Separate and delete the cache pool from a cache LV.
|
||||
|
||||
---
|
||||
|
||||
# FIXME: add a new option defining this operation, e.g. --swapmetadata
|
||||
|
||||
lvconvert --poolmetadata LV LV_thinpool_cachepool
|
||||
OO: OO_LVCONVERT
|
||||
lvconvert --swapmetadata --poolmetadata LV LV_thinpool_cachepool
|
||||
OO: --chunksize SizeKB, OO_LVCONVERT
|
||||
ID: lvconvert_swap_pool_metadata
|
||||
DESC: Swap metadata LV in a thin pool or cache pool (temporary command).
|
||||
DESC: Swap metadata LV in a thin pool or cache pool (for repair only).
|
||||
|
||||
# alternate form, does not use explicit command option
|
||||
lvconvert --poolmetadata LV LV_thinpool_cachepool
|
||||
OO: --chunksize SizeKB, OO_LVCONVERT
|
||||
ID: lvconvert_swap_pool_metadata_deprecated
|
||||
DESC: Swap metadata LV in a thin pool or cache pool (variant, use --swapmetadata).
|
||||
FLAGS: SECONDARY_SYNTAX
|
||||
|
||||
---
|
||||
|
||||
# FIXME: lvconvert --merge is an extremely ambiguous command.
|
||||
# lvconvert --merge is an extremely ambiguous command.
|
||||
# It can do very different operations, but which one depends
|
||||
# on knowing the LV type. So, the command doesn't know what
|
||||
# it's actually doing until quite late, when processing a
|
||||
# single LV.
|
||||
#
|
||||
# Use different option names for different merge operations
|
||||
# so that we can have different command definitions,
|
||||
# different behaviors, different optional options, etc:
|
||||
#
|
||||
# lvconvert --merge-mirror LV_linear_striped_raid ...
|
||||
# DESC: Merge LV that was previously split from a mirror.
|
||||
#
|
||||
# lvconvert --merge-thin LV_thin
|
||||
# DESC: Merge thin LV into its origin LV.
|
||||
#
|
||||
# lvconvert --merge-snapshot LV_snapshot
|
||||
# DESC: Merge COW snapshot LV into its origin.
|
||||
#
|
||||
# Then we could add VG|Tag to --merge-mirror arg pos 1, because
|
||||
# "lvconvert --merge VG|Tag" is a terrible command. It will do
|
||||
# different operations on each LV it finds, depending on the
|
||||
# current LV type.
|
||||
# single LV. When passed a VG or tag, it will do different
|
||||
# operations on each LV it finds, depending on the current LV type.
|
||||
|
||||
lvconvert --merge LV_linear_striped_raid_thin_snapshot|VG|Tag ...
|
||||
OO: --background, --interval Number, OO_LVCONVERT
|
||||
ID: lvconvert_merge
|
||||
DESC: Merge LV that was previously split from a mirror.
|
||||
DESC: Merge thin LV into its origin LV.
|
||||
DESC: Merge COW snapshot LV into its origin.
|
||||
DESC: Merge LV that was split from a mirror (variant, use --mergemirrors).
|
||||
DESC: Merge thin LV into its origin LV (variant, use --mergethin).
|
||||
DESC: Merge COW snapshot LV into its origin (variant, use --mergesnapshot).
|
||||
RULE: all not lv_is_locked lv_is_pvmove lv_is_merging_origin lv_is_virtual_origin lv_is_external_origin lv_is_merging_cow
|
||||
FLAGS: SECONDARY_SYNTAX
|
||||
|
||||
---
|
||||
|
||||
@@ -516,7 +525,7 @@ RULE: all not lv_is_locked lv_is_pvmove lv_is_merging_origin lv_is_virtual_origi
|
||||
lvconvert --mergesnapshot LV_snapshot ...
|
||||
OO: --background, --interval Number, OO_LVCONVERT
|
||||
ID: lvconvert_merge_snapshot
|
||||
DESC: Merge LV that was previously split from a mirror.
|
||||
DESC: Merge COW snapshot LV into its origin.
|
||||
RULE: all not lv_is_locked lv_is_pvmove lv_is_merging_origin lv_is_virtual_origin lv_is_external_origin lv_is_merging_cow
|
||||
|
||||
---
|
||||
@@ -873,6 +882,14 @@ DESC: (infers --type thin).
|
||||
|
||||
---
|
||||
|
||||
lvconvert --mergethin LV_thin ...
|
||||
OO: OO_LVCONVERT
|
||||
ID: lvconvert_merge_thin
|
||||
DESC: Merge thin LV into its origin LV.
|
||||
RULE: all not lv_is_locked lv_is_pvmove lv_is_merging_origin lv_is_virtual_origin lv_is_external_origin lv_is_merging_cow
|
||||
|
||||
---
|
||||
|
||||
# stripes option is not intuitive when creating a thin LV,
|
||||
# but here it applies to creating the new thin pool that
|
||||
# is used for the thin LV
|
||||
|
@@ -47,7 +47,7 @@ xx(lvchange,
|
||||
|
||||
xx(lvconvert,
|
||||
"Change logical volume layout",
|
||||
0)
|
||||
GET_VGNAME_FROM_OPTIONS)
|
||||
|
||||
xx(lvcreate,
|
||||
"Create a logical volume",
|
||||
|
2275
tools/lvconvert.c
2275
tools/lvconvert.c
File diff suppressed because it is too large
Load Diff
@@ -134,32 +134,36 @@ struct command_function command_functions[COMMAND_ID_COUNT] = {
|
||||
|
||||
/* lvconvert utility to trigger polling on an LV. */
|
||||
{ lvconvert_start_poll_CMD, lvconvert_start_poll_cmd },
|
||||
};
|
||||
|
||||
/* lvconvert utilities for creating/maintaining thin and cache objects. */
|
||||
{ lvconvert_to_thinpool_CMD, lvconvert_to_pool_cmd },
|
||||
{ lvconvert_to_thinpool_noarg_CMD, lvconvert_to_pool_noarg_cmd },
|
||||
{ lvconvert_to_cachepool_CMD, lvconvert_to_pool_cmd },
|
||||
{ lvconvert_to_cachepool_noarg_CMD, lvconvert_to_pool_noarg_cmd },
|
||||
{ lvconvert_to_thin_with_external_CMD, lvconvert_to_thin_with_external_cmd },
|
||||
{ lvconvert_to_cache_vol_CMD, lvconvert_to_cache_vol_cmd },
|
||||
{ lvconvert_swap_pool_metadata_CMD, lvconvert_swap_pool_metadata_cmd },
|
||||
{ lvconvert_swap_pool_metadata_deprecated_CMD, lvconvert_swap_pool_metadata_cmd },
|
||||
{ lvconvert_merge_thin_CMD, lvconvert_merge_thin_cmd },
|
||||
{ lvconvert_split_and_keep_cachepool_CMD, lvconvert_split_cachepool_cmd },
|
||||
{ lvconvert_split_and_remove_cachepool_CMD, lvconvert_split_cachepool_cmd },
|
||||
|
||||
/* lvconvert utilities for raid/mirror */
|
||||
{ lvconvert_merge_mirror_images_CMD, lvconvert_merge_mirror_images_cmd },
|
||||
#if 0
|
||||
{ lvconvert_split_mirror_images_CMD, lvconvert_split_mirror_images_cmd },
|
||||
{ lvconvert_change_mirrorlog_CMD, lvconvert_change_mirrorlog_cmd },
|
||||
#endif
|
||||
|
||||
/* redirected to merge_snapshot/merge_thin/merge_mirrors */
|
||||
{ lvconvert_merge_CMD, lvconvert_merge_cmd },
|
||||
|
||||
#if 0
|
||||
/* all raid-related type conversions */
|
||||
|
||||
{ lvconvert_raid_types_CMD, lvconvert_raid_types_fn },
|
||||
|
||||
/* raid-related utilities (move into lvconvert_raid_types?) */
|
||||
|
||||
{ lvconvert_split_mirror_images_CMD, lvconvert_split_mirror_images_fn },
|
||||
{ lvconvert_change_mirrorlog_CMD, lvconvert_change_mirrorlog_fn },
|
||||
|
||||
/* utilities for creating/maintaining thin and cache objects. */
|
||||
|
||||
{ lvconvert_to_thin_with_external_CMD, lvconvert_to_thin_with_external_fn },
|
||||
{ lvconvert_to_cache_vol_CMD, lvconvert_to_cache_vol_fn },
|
||||
{ lvconvert_to_thinpool_CMD, lvconvert_to_thinpool_fn },
|
||||
{ lvconvert_to_cachepool_CMD, lvconvert_to_cachepool_fn },
|
||||
{ lvconvert_split_and_keep_cachepool_CMD, lvconvert_split_and_keep_cachepool_fn },
|
||||
{ lvconvert_split_and_delete_cachepool_CMD, lvconvert_split_and_delete_cachepool_fn },
|
||||
{ lvconvert_swap_pool_metadata_CMD, lvconvert_swap_pool_metadata_fn },
|
||||
|
||||
/* other misc. */
|
||||
|
||||
{ lvconvert_merge_CMD, lvconvert_merge_fn },
|
||||
{ lvconvert_raid_types_CMD, lvconvert_raid_types_cmd },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/* Command line args */
|
||||
unsigned arg_count(const struct cmd_context *cmd, int a)
|
||||
@@ -1128,6 +1132,18 @@ struct lv_types *get_lv_type(int lvt_enum)
|
||||
return &_lv_types[lvt_enum];
|
||||
}
|
||||
|
||||
struct command *get_command(int cmd_enum)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < COMMAND_COUNT; i++) {
|
||||
if (commands[i].command_line_enum == cmd_enum)
|
||||
return &commands[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Also see merge_synonym(). The command definitions
|
||||
* are written using just one variation of the option
|
||||
|
167
tools/toollib.c
167
tools/toollib.c
@@ -2498,9 +2498,9 @@ static int _lv_is_type(struct cmd_context *cmd, struct logical_volume *lv, int l
|
||||
|
||||
switch (lvt_enum) {
|
||||
case striped_LVT:
|
||||
return seg_is_striped(seg);
|
||||
return seg_is_striped(seg) && !lv_is_cow(lv);
|
||||
case linear_LVT:
|
||||
return seg_is_linear(seg);
|
||||
return seg_is_linear(seg) && !lv_is_cow(lv);
|
||||
case snapshot_LVT:
|
||||
return lv_is_cow(lv);
|
||||
case thin_LVT:
|
||||
@@ -2540,16 +2540,21 @@ static int _lv_is_type(struct cmd_context *cmd, struct logical_volume *lv, int l
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _get_lvt_enum(struct logical_volume *lv)
|
||||
int get_lvt_enum(struct logical_volume *lv)
|
||||
{
|
||||
struct lv_segment *seg = first_seg(lv);
|
||||
|
||||
if (seg_is_striped(seg))
|
||||
return striped_LVT;
|
||||
if (seg_is_linear(seg))
|
||||
return linear_LVT;
|
||||
/*
|
||||
* The order these are checked is important, because a snapshot LV has
|
||||
* a linear seg type.
|
||||
*/
|
||||
|
||||
if (lv_is_cow(lv))
|
||||
return snapshot_LVT;
|
||||
if (seg_is_linear(seg))
|
||||
return linear_LVT;
|
||||
if (seg_is_striped(seg))
|
||||
return striped_LVT;
|
||||
if (lv_is_thin_volume(lv))
|
||||
return thin_LVT;
|
||||
if (lv_is_thin_pool(lv))
|
||||
@@ -2696,7 +2701,7 @@ static int _check_lv_types(struct cmd_context *cmd, struct logical_volume *lv, i
|
||||
|
||||
ret = _lv_types_match(cmd, lv, cmd->command->required_pos_args[pos-1].def.lvt_bits, NULL, NULL);
|
||||
if (!ret) {
|
||||
int lvt_enum = _get_lvt_enum(lv);
|
||||
int lvt_enum = get_lvt_enum(lv);
|
||||
struct lv_types *type = get_lv_type(lvt_enum);
|
||||
log_warn("Operation on LV %s which has invalid type %s.",
|
||||
display_lvname(lv), type ? type->name : "unknown");
|
||||
@@ -2719,7 +2724,7 @@ static int _check_lv_rules(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
int ret = 1;
|
||||
int i;
|
||||
|
||||
lvt_enum = _get_lvt_enum(lv);
|
||||
lvt_enum = get_lvt_enum(lv);
|
||||
if (lvt_enum)
|
||||
lvtype = get_lv_type(lvt_enum);
|
||||
|
||||
@@ -3360,6 +3365,143 @@ static int _get_arg_lvnames(struct cmd_context *cmd,
|
||||
return ret_max;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a non-standard way of finding vgname/lvname to process. It exists
|
||||
* because an earlier form of lvconvert did not follow the standard form, and
|
||||
* came up with its own inconsistent approach.
|
||||
*
|
||||
* In this case, when the position arg is a single name, it is treated as an LV
|
||||
* name (not a VG name). This leaves the VG unknown. So, other option values
|
||||
* must be searched for a VG name. If one of those option values contains a
|
||||
* vgname/lvname value, then the VG name is extracted and used for the LV
|
||||
* position arg.
|
||||
*
|
||||
* Other option values that are searched for a VG name are:
|
||||
* --thinpool, --cachepool.
|
||||
*
|
||||
* . command vg/lv1
|
||||
* . add vg to arg_vgnames
|
||||
* . add vg/lv1 to arg_lvnames
|
||||
*
|
||||
* command lv1
|
||||
* . error: no vg name
|
||||
*
|
||||
* command --option vg/lv1 vg/lv2
|
||||
* . verify both vg names match
|
||||
* . add vg to arg_vgnames
|
||||
* . add vg/lv2 to arg_lvnames
|
||||
*
|
||||
* command --option lv1 lv2
|
||||
* . error: no vg name
|
||||
*
|
||||
* command --option vg/lv1 lv2
|
||||
* . add vg to arg_vgnames
|
||||
* . add vg/lv2 to arg_lvnames
|
||||
*
|
||||
* command --option lv1 vg/lv2
|
||||
* . add vg to arg_vgnames
|
||||
* . add vg/lv2 to arg_lvnames
|
||||
*/
|
||||
|
||||
static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
|
||||
int argc, char **argv,
|
||||
struct dm_list *arg_vgnames,
|
||||
struct dm_list *arg_lvnames)
|
||||
{
|
||||
const char *pos_name = NULL;
|
||||
const char *arg_name = NULL;
|
||||
const char *pos_vgname = NULL;
|
||||
const char *opt_vgname = NULL;
|
||||
const char *pos_lvname = NULL;
|
||||
const char *use_vgname = NULL;
|
||||
char *tmp_name;
|
||||
char *split;
|
||||
char *vglv;
|
||||
size_t vglv_sz;
|
||||
|
||||
if (argc != 1) {
|
||||
log_error("One LV position arg is required.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (!(pos_name = dm_pool_strdup(cmd->mem, argv[0]))) {
|
||||
log_error("string alloc failed.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if ((split = strchr(pos_name, '/'))) {
|
||||
pos_vgname = pos_name;
|
||||
pos_lvname = split + 1;
|
||||
*split = '\0';
|
||||
} else {
|
||||
pos_lvname = pos_name;
|
||||
pos_vgname = NULL;
|
||||
}
|
||||
|
||||
if (arg_is_set(cmd, thinpool_ARG))
|
||||
arg_name = arg_str_value(cmd, thinpool_ARG, NULL);
|
||||
else if (arg_is_set(cmd, cachepool_ARG))
|
||||
arg_name = arg_str_value(cmd, cachepool_ARG, NULL);
|
||||
|
||||
if (!pos_vgname && !arg_name) {
|
||||
log_error("Cannot find VG name for LV %s.", pos_lvname);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (arg_name && (split = strchr(arg_name, '/'))) {
|
||||
/* combined VG/LV */
|
||||
|
||||
if (!(tmp_name = dm_pool_strdup(cmd->mem, arg_name))) {
|
||||
log_error("string alloc failed.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (!(split = strchr(tmp_name, '/')))
|
||||
return ECMD_FAILED;
|
||||
|
||||
opt_vgname = tmp_name;
|
||||
/* Don't care about opt lvname. */
|
||||
/* opt_lvname = split + 1; */
|
||||
*split = '\0';
|
||||
} else {
|
||||
/* Don't care about opt lvname. */
|
||||
/* opt_lvname = arg_name; */
|
||||
opt_vgname = NULL;
|
||||
}
|
||||
|
||||
if (!pos_vgname && !opt_vgname) {
|
||||
log_error("Cannot find VG name for LV %s.", pos_lvname);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (pos_vgname && opt_vgname && strcmp(pos_vgname, opt_vgname)) {
|
||||
log_error("VG name mismatch from position arg (%s) and option arg (%s).",
|
||||
pos_vgname, opt_vgname);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
use_vgname = pos_vgname ? pos_vgname : opt_vgname;
|
||||
|
||||
if (!str_list_add(cmd->mem, arg_vgnames, dm_pool_strdup(cmd->mem, use_vgname))) {
|
||||
log_error("strlist allocation failed.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
vglv_sz = strlen(use_vgname) + strlen(pos_lvname) + 2;
|
||||
|
||||
if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
|
||||
dm_snprintf(vglv, vglv_sz, "%s/%s", use_vgname, pos_lvname) < 0) {
|
||||
log_error("vg/lv string alloc failed.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
if (!str_list_add(cmd->mem, arg_lvnames, vglv)) {
|
||||
log_error("strlist allocation failed.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
|
||||
struct dm_list *vgnameids_to_process,
|
||||
struct dm_list *arg_vgnames,
|
||||
@@ -3519,7 +3661,12 @@ int process_each_lv(struct cmd_context *cmd,
|
||||
/*
|
||||
* Find any LVs, VGs or tags explicitly provided on the command line.
|
||||
*/
|
||||
if ((ret = _get_arg_lvnames(cmd, argc, argv, one_vgname, one_lvname, &arg_vgnames, &arg_lvnames, &arg_tags) != ECMD_PROCESSED)) {
|
||||
if (cmd->command->flags & GET_VGNAME_FROM_OPTIONS)
|
||||
ret = _get_arg_lvnames_using_options(cmd, argc, argv, &arg_vgnames, &arg_lvnames);
|
||||
else
|
||||
ret = _get_arg_lvnames(cmd, argc, argv, one_vgname, one_lvname, &arg_vgnames, &arg_lvnames, &arg_tags);
|
||||
|
||||
if (ret != ECMD_PROCESSED) {
|
||||
ret_max = ret;
|
||||
goto_out;
|
||||
}
|
||||
|
@@ -240,4 +240,6 @@ int validate_restricted_lvname_param(struct cmd_context *cmd, const char **vg_na
|
||||
int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct processing_handle *handle __attribute__((unused)));
|
||||
|
||||
int get_lvt_enum(struct logical_volume *lv);
|
||||
|
||||
#endif
|
||||
|
@@ -162,6 +162,8 @@ struct lv_types {
|
||||
#define ENABLE_DUPLICATE_DEVS 0x00000400
|
||||
/* Command does not accept tags as args. */
|
||||
#define DISALLOW_TAG_ARGS 0x00000800
|
||||
/* Command may need to find VG name in an option value. */
|
||||
#define GET_VGNAME_FROM_OPTIONS 0x00001000
|
||||
|
||||
void usage(const char *name);
|
||||
|
||||
@@ -240,6 +242,7 @@ int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg
|
||||
|
||||
struct lv_props *get_lv_prop(int lvp_enum);
|
||||
struct lv_types *get_lv_type(int lvt_enum);
|
||||
struct command *get_command(int cmd_enum);
|
||||
|
||||
int lvchange_properties_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvchange_activate_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
@@ -259,4 +262,16 @@ int lvconvert_combine_split_snapshot_cmd(struct cmd_context *cmd, int argc, char
|
||||
|
||||
int lvconvert_start_poll_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
int lvconvert_to_pool_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_to_pool_noarg_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_to_cache_vol_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_to_thin_with_external_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_swap_pool_metadata_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_merge_thin_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_split_cachepool_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
int lvconvert_merge_mirror_images_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
int lvconvert_merge_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user