master - man: lvconvert update
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4bbfac359c5e7e...
Commit: 4bbfac359c5e7e82a0600fa3d41bf7ea308e485f
Parent: b2988a917af8ca16814b067c1d73f899e871e1d4
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:28:43 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:23 2014 +0200
man: lvconvert update
Update lvconvert doc for conversion of pools
(thin and cache pools and volumes)
Various more cleanups.
---
man/lvconvert.8.in | 178 +++++++++++++++++++++++++++++-----------------------
1 files changed, 99 insertions(+), 79 deletions(-)
diff --git a/man/lvconvert.8.in b/man/lvconvert.8.in
index f96cee2..e038371 100644
--- a/man/lvconvert.8.in
+++ b/man/lvconvert.8.in
@@ -5,26 +5,26 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.B lvconvert
.BR \-m | \-\-mirrors
.I Mirrors
+.RB [ \-\-type
+.IR SegmentType ]
.RB [ \-\-mirrorlog
.RI { disk | core | mirrored }]
.RB [ \-\-corelog ]
.RB [ \-R | \-\-regionsize
.IR MirrorLogRegionSize ]
-.RB [ \-\-type
-.IR SegmentType ]
+.RB [ \-\-stripes
+.I Stripes
+.RB [ \-I | \-\-stripesize
+.IR StripeSize ]]
.RB [ \-A | \-\-alloc
.IR AllocationPolicy ]
.RB [ \-b | \-\-background ]
-.RB [ \-\-commandprofile
-.IR ProfileName ]
.RB [ \-f | \-\-force ]
.RB [ \-i | \-\-interval
.IR Seconds ]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
.RB [ \-h | \-? | \-\-help ]
-.RB [ \-\-stripes
-.I Stripes
-.RB [ \-I | \-\-stripesize
-.IR StripeSize ]]
.RB [ \-\-noudevsync ]
.RB [ \-v | \-\-verbose ]
.RB [ \-y | \-\-yes ]
@@ -33,12 +33,12 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.RI [ PhysicalVolume [ Path ][ :PE [ \-PE ]]...]
.sp
.B lvconvert \-\-splitmirrors \fIImages
-.RB [ \-\-commandprofile
-.IR ProfileName ]
.RB [ \-\-name
.IR SplitLogicalVolumeName ]
.RB [ \-\-trackchanges ]
.IR MirrorLogicalVolume [ Path ]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
.RI [ SplittablePhysicalVolume [ Path ][ :PE [ \-PE ]]...]
.sp
.B lvconvert
@@ -53,38 +53,38 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.sp
.B lvconvert
.BR \-s | \-\-snapshot
-.RB [ \-\-commandprofile
-.IR ProfileName ]
.RB [ \-c | \-\-chunksize
.IR ChunkSize [ bBsSkK ]]
+.RB [ \-Z | \-\-zero
+.RI { y | n }]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-noudevsync ]
.RB [ \-v | \-\-verbose ]
-.RB [ \-Z | \-\-zero
-.RI { y | n }]
.RB [ \-\-version ]
.IR OriginalLogicalVolume [ Path ]
.IR SnapshotLogicalVolume [ Path ]
.sp
.B lvconvert \-\-merge
-.RB [ \-\-commandprofile
-.IR ProfileName ]
.RB [ \-b | \-\-background ]
.RB [ \-i | \-\-interval
.IR Seconds ]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-v | \-\-verbose ]
.RB [ \-\-version ]
.IR LogicalVolume [ Path ]...
.sp
.B lvconvert \-\-repair
-.RB [ \-\-commandprofile
-.IR ProfileName ]
-.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-stripes
.I Stripes
.RB [ \-I | \-\-stripesize
.IR StripeSize ]]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
+.RB [ \-h | \-? | \-\-help ]
.RB [ \-v | \-\-verbose ]
.RB [ \-\-version ]
.IR LogicalVolume [ Path ]
@@ -99,10 +99,12 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.IR LogicalVolume [ Path ]
.RI [ PhysicalVolume [ Path ]...]
.sp
-.B lvconvert \-\-thinpool
+.B lvconvert
+.RB [{ \-\-type \ \fIthin [ \fI\-pool ]| \-T | \-\-thin }
+.RB [ \-\-originname
+.IR NewExternalOriginVolumeName ]]
+.RB [ \-\-thinpool
.IR ThinPoolLogicalVolume { Name | Path }
-.RB [ \-\-commandprofile
-.IR ProfileName ]
.RB [ \-c | \-\-chunksize
.IR ChunkSize [ bBsSkKmMgG ]]
.RB [ \-\-discards
@@ -114,24 +116,22 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
.IR ThinPoolMetadataSize [ bBsSkKmMgG ]}]
.RB [ \-r | \-\-readahead
.RI { ReadAheadSectors | auto | none }]
-.RB [ \-\-stripes
-.I Stripes
-.RB [ \-I | \-\-stripesize
-.IR StripeSize ]]]
-.RB [ \-Z | \-\-zero
-.RI { y | n }]
-.RB [ \-T | \-\-thin
-.IR ExternalOriginLogicalVolume { Name | Path }
-.RB [ \-\-originname
-.IR NewExternalOriginVolumeName ]]
-.RI [ PhysicalVolume [ Path ][ :PE [ \-PE ]]...]
+.RB [ \-\-stripes \ \fIStripes
+.RB [ \-I | \-\-stripesize \ \fIStripeSize ]]]
+.RB [ \-Z | \-\-zero \ { \fIy | \fIn }]]
+.RI [[ ExternalOrigin | ThinPool ] LogicalVolume { Name | Path }]
+.RI [ PhysicalVolume [ Path ][ :PE
+.RI [ \-PE ]]...]
+.RB [ \-\-commandprofile
+.IR ProfileName ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-v | \-\-verbose ]
.RB [ \-\-version ]
.sp
-.B lvconvert \-\-type \fIcache-pool
-.RB [ \-\-commandprofile
-.IR ProfileName ]
+.B lvconvert
+.RB [ \-\-type \ \fIcache [ \fI\-pool ]| \-\-cache ]
+.RB [ \-\-cachepool
+.IR CachePoolLV { Name | Path }]
.RB [ \-c | \-\-chunksize
.IR ChunkSize [ bBsSkKmMgG ]]
.RB [ \-\-cachemode
@@ -141,16 +141,8 @@ lvconvert \(em convert a logical volume from linear to mirror or snapshot
|
.B \-\-poolmetadatasize
.IR CachePoolMetadataSize [ bBsSkKmMgG ]}]
-.IR LogicalVolume [ Path ]
+.IR LogicalVolume { Name | Path }
.RI [ PhysicalVolume [ Path ][ :PE [ \-PE ]]...]
-.RB [ \-h | \-? | \-\-help ]
-.RB [ \-v | \-\-verbose ]
-.RB [ \-\-version ]
-.sp
-.B lvconvert \-\-type \fIcache
-.B \-\-cachepool
-.IR CachePoolLV { Name | Path }
-.IR LogicalVolume [ Path ]
.RB [ \-\-commandprofile
.IR ProfileName ]
.RB [ \-h | \-? | \-\-help ]
@@ -176,6 +168,7 @@ the freed extents come first from the specified PhysicalVolumes.
See \fBlvm\fP(8) for common options.
.br
Exactly one of
+.BR \-\-cache ,
.BR \-\-merge ,
.BR \-\-mirrors ,
.BR \-\-repair ,
@@ -183,8 +176,7 @@ Exactly one of
.BR \-\-splitsnapshot ,
.BR \-\-snapshot ,
.BR \-\-splitmirrors ,
-.BR \-\-thin ,
-.BR \-\-thinpool
+.BR \-\-thin
or
.BR \-\-type
arguments is required.
@@ -192,20 +184,25 @@ arguments is required.
.BR \-b ", " \-\-background
Run the daemon in the background.
.TP
+.BR \-\-cache ", " \-\-type\ \fIcache
+Converts logical volume to a cached LV with the use of cache pool
+specified with \fB\-\-cachepool\fP.
+For more information on cache pool LVs and cache LVs, see \fBlvmcache\fP(8).
+.TP
.BR \-\-cachepool " " \fICachePoolLV
This argument is necessary when converting a logical volume to a cache LV.
-For more information on cache pool LVs and cache LVs, see \fBlvm\fP(8).
+For more information on cache pool LVs and cache LVs, see \fBlvmcache\fP(8).
.TP
.BR \-m ", " \-\-mirrors " " \fIMirrors
Specifies the degree of the mirror you wish to create.
For example, "\fB\-m 1\fP" would convert the original logical
volume to a mirror volume with 2-sides; that is, a
linear volume plus one copy. There are two implementations of mirroring
-which correspond to the "raid1" and "mirror" segment types. The default
-mirroring segment type is "raid1". If the legacy "mirror" segment type
+which correspond to the "\fIraid1\fP" and "\fImirror\fP" segment types. The default
+mirroring segment type is "\fIraid1\fP". If the legacy "\fImirror\fP" segment type
is desired, the \fB\-\-type\fP argument must be used to explicitly
select the desired type. The \fB\-\-mirrorlog\fP and \fB\-\-corelog\fP
-options below are only relevant to the legacy "mirror" segment type.
+options below are only relevant to the legacy "\fImirror\fP" segment type.
.TP
.IR \fB\-\-mirrorlog " {" disk | core | mirrored }
Specifies the type of log to use.
@@ -227,14 +224,19 @@ uses this granularity to track which regions are in sync.
.TP
.B \-\-type \fISegmentType
Used to convert a logical volume to another segment type, like
-.IR cache-pool ,
.IR cache ,
+.IR cache-pool ,
.IR raid1 ,
+.IR snapshot ,
+.IR thin ,
or
.IR thin-pool .
When converting a logical volume to a cache LV, the
.B \-\-cachepool
argument is required.
+When converting a logical volume to a thin LV, the
+.B \-\-thinpool
+argument is required.
See \fBlvmcache\fP(7) for more info about caching support
and \fBlvmthin\fP(7) for thin provisioning support.
.TP
@@ -274,28 +276,30 @@ along with the metadata describing them. This volume can be wiped and then
destroyed with lvremove.
The inverse of \fB\-\-snapshot\fP.
.TP
-.B \-s, \-\-snapshot
+.BR \-s ", " \-\-snapshot ", " \-\-type\ \fIsnapshot
Recreates a snapshot from constituent logical volumes (or copies of them) after
having been separated using \fB\-\-splitsnapshot\fP.
For this to work correctly, no changes may be made to the contents
of either volume after the split.
.TP
.BR \-c ", " \-\-chunksize " " \fIChunkSize [ \fIbBsSkKmMgG ]
-Gives the size of chunk for snapshot and thin pool logical volumes.
+Gives the size of chunk for snapshot, cache pool and thin pool logical volumes.
Default unit is in kilobytes.
-.br
+.sp
For snapshots the value must be power of 2 between 4KiB and 512KiB
and the default value is 4.
-.br
+.sp
+For cache pools the value must be between 32KiB and 1GiB and
+the default value is 64.
+.sp
For thin pools the value must be between 64KiB and
1GiB and the default value starts with 64 and scales
up to fit the pool metadata size within 128MiB,
if the pool metadata size is not specified.
-The value must be a multiple of 64KiB.
+The value must be a multiple of 64KiB.
(Early kernel support until thin target version 1.4 required the value
to be a power of 2. Discards weren't supported for non-power of 2 values
until thin target version 1.5.)
-Default unit is in kilobytes.
.TP
.BR \-\-discards " {" \fIignore | \fInopassdown | \fIpassdown }
Specifies whether or not discards will be processed by the thin layer in the
@@ -306,7 +310,7 @@ Default is \fIpassdown\fP.
Controls zeroing of the first 4KiB of data in the snapshot.
If the volume is read-only the snapshot will not be zeroed.
For thin pool volumes it controls zeroing of provisioned blocks.
-Note: Provisioning of large zeroed chunks impacts performance.
+Note: Provisioning of large zeroed chunks negatively impacts performance.
.TP
.B \-\-merge
Merges a snapshot into its origin volume or merges a raid1 image that has
@@ -327,25 +331,35 @@ be specified on the commandline or a @tag may be used to specify
multiple snapshots be merged to their respective origin.
.TP
.B \-\-originname \fINewExternalOriginVolumeName\fP
-The new name for original logical volume, which becomes external origin volume.
+The new name for original logical volume, which becomes external origin volume
+for a thin logical volume that will use given \fB\-\-thinpool\fP.
.br
-Without this option a default names of "lvol#" will be generated where
-# is the LVM internal number of the logical volume.
+Without this option a default name of "lvol<n>" will be generated where
+<n> is the LVM internal number of the logical volume.
This volume will be read-only and cannot be further modified as long,
-as it is being used as external origin.
+as it is being used as the external origin.
.TP
.BR \-\-poolmetadata " " \fIThinPoolMetadataLogicalVolume { \fIName | \fIPath }
-Specifies thin pool metadata logical volume.
+Specifies cache or thin pool metadata logical volume.
The size should be in between 2MiB and 16GiB.
+Cache pool is specified with the option
+\fB\-\-cachepool\fP.
Thin pool is specified with the option
\fB\-\-thinpool\fP.
-When the specified thin pool already exists,
-the thin pool's metadata volume will be swapped with the given LV.
-Properties of the thin pool like chunk size, discards or zero
+When the specified pool already exists,
+the pool's metadata volume will be swapped with the given LV.
+Pool properties (like chunk size, discards or zero)
are preserved by default in this case.
-It can be useful for thin pool metadata repair or its offline resize,
-since the content of metadata becomes accessible for
-thin provisioning tools \fBthin_dump\fP(8) and \fBthin_restore\fP(8).
+It can be useful for pool metadata repair or its offline resize,
+since the metadata volume is available as regular volume for a user with
+thin provisioning tools
+.BR cache_dump (8),
+.BR cache_repair (8),
+.BR cache_restore (8),
+.BR thin_dump (8),
+.BR thin_repair (8)
+and
+.BR thin_restore (8).
.TP
.BR \-\-poolmetadatasize " " \fIThinPoolMetadataSize [ \fIbBsSkKmMgG ]
Sets the size of thin pool's metadata logical volume,
@@ -380,13 +394,16 @@ Only inactive thin pool volumes can be repaired.
There is no validation of metadata between kernel and lvm2.
This requires further manual work.
After successfull repair the old unmodified metadata are still
-available in \fB<pool>_meta<n>\fP LV.
+available in "<pool>_meta<n>" LV.
.TP
.B \-\-replace \fIPhysicalVolume
Remove the specified device (\fIPhysicalVolume\fP) and replace it with one
that is available in the volume group or from the specific list provided.
This option is only available to RAID segment types
-(e.g. "raid1", "raid5", etc).
+(e.g.
+.IR raid1 ,
+.IR raid5 ,
+etc).
.TP
.BR \-\-stripes " " \fIStripes
Gives the number of stripes.
@@ -401,17 +418,17 @@ StripeSize must be 2^n (n = 2 to 9) for metadata in LVM1 format.
For metadata in LVM2 format, the stripe size may be a larger
power of 2 but must not exceed the physical extent size.
.TP
-.IR \fB\-T ", " \fB\-\-thin " " ExternalOriginLogicalVolume { Name | Path }
+.IR \fB\-T ", " \fB\-\-thin ", " \fB\-\-type " " thin
Converts the logical volume into a thin logical volume of the thin pool
specified with \fB\-\-thinpool\fP. The original logical volume
.I ExternalOriginLogicalVolume
is renamed into a new read-only logical volume.
-The non-default name for this volume use \fB\-\-originname\fP.
+For the non-default name for this volume use \fB\-\-originname\fP.
The volume cannot be further modified as long as it is used as an
external origin volume for unprovisioned areas of any thin logical volume.
.TP
.IR \fB\-\-thinpool " " ThinPoolLogicalVolume { Name | Path }
-Switches logical volume into a thin pool's data volume.
+Specifies or converts logical volume into a thin pool's data volume.
Content of converted volume is lost.
Thin pool's metadata logical volume can be specified with the option
\fB\-\-poolmetadata\fP or allocated with \fB\-\-poolmetadatasize\fP.
@@ -507,14 +524,14 @@ and convert "vg00/lv1" into a thin volume using this pool. Original "vg00/lv1"
is used as an external read-only origin, where all writes to such volume
are stored in the "vg00/lvpool".
.sp
-.B lvconvert \-\-thinpool vg00/lvpool \-c 128 \-T lv1
+.B lvconvert \-\-type thin \-\-thinpool vg00/lvpool \-c 128 lv1
Convert the logical volume "vg00/origin" into a thin volume from the thin pool
"vg00/lvpool". This thin volume will use "vg00/origin" as an external origin
volume for unprovisioned areas in this volume.
For the read-only external origin use the new name "vg00/external".
.sp
-.B lvconvert \-\-thinpool vg00/lvpool \-\-originname external \-T vg00/origin
+.B lvconvert \-T \-\-thinpool vg00/lvpool \-\-originname external vg00/origin
Convert an existing logical volume to a cache pool LV using the
given cache metadata LV.
@@ -526,7 +543,7 @@ given cache metadata LV.
Convert an existing logical volume to a cache LV using the given
cache pool LV.
.sp
-.B lvconvert \-\-type cache \-\-cachepool vg00/lvx_cachepool vg00/lvx
+.B lvconvert \-\-cache \-\-cachepool vg00/lvx_cachepool vg00/lvx
.SH SEE ALSO
.BR lvm (8),
@@ -540,6 +557,9 @@ cache pool LV.
.BR lvrename (8),
.BR lvscan (8),
.BR vgcreate (8),
+.BR cache_dump (8),
+.BR cache_repair (8),
+.BR cache_restore (8),
.BR thin_dump (8),
-.BR thin_repair (8)
+.BR thin_repair (8),
.BR thin_restore (8)
9 years, 8 months
master - lvconvert: update help
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b2988a917af8ca...
Commit: b2988a917af8ca16814b067c1d73f899e871e1d4
Parent: 970989655ff5cd9ca960bf3113b7bfdf6f575d78
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:54:33 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:22 2014 +0200
lvconvert: update help
Extend help for lvconvert.
Use COMMON_OPTS for some common options.
---
tools/commands.h | 68 ++++++++++++++++++-----------------------------------
1 files changed, 23 insertions(+), 45 deletions(-)
diff --git a/tools/commands.h b/tools/commands.h
index 5fae835..1f9d03c 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -47,7 +47,6 @@ xx(devtypes,
"\t[--separator Separator]\n"
"\t[--unbuffered]\n"
"\t[--unquoted]\n"
- "\t[-v|--verbose]\n"
"\t[--version]" "\n",
aligned_ARG, binary_ARG, nameprefixes_ARG,
@@ -154,6 +153,10 @@ xx(lvchange,
refresh_ARG, setactivationskip_ARG, syncaction_ARG, sysinit_ARG, test_ARG,
writebehind_ARG, writemostly_ARG, zero_ARG)
+#define COMMON_OPTS \
+ "\t[--commandprofile ProfileName] [-d|--debug] [-h|-?|--help]\n" \
+ "\t[--noudevsync] [-t|--test] [-v|--verbose] [--version] [-y|--yes]\n"
+
xx(lvconvert,
"Change logical volume layout",
0,
@@ -165,88 +168,64 @@ 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"
"\t[-i|--interval seconds]\n"
"\t[--stripes Stripes [-I|--stripesize StripeSize]]\n"
- "\t[--noudevsync]\n"
- "\t[-v|--verbose]\n"
- "\t[-y|--yes]\n"
- "\t[--version]" "\n"
+ COMMON_OPTS
"\tLogicalVolume[Path] [PhysicalVolume[Path]...]\n\n"
"lvconvert "
"[--splitmirrors Images --trackchanges]\n"
- "[--splitmirrors Images --name SplitLogicalVolumeName]\n"
- "\t[--commandprofile ProfileName]\n"
+ "\t[--splitmirrors Images --name SplitLogicalVolumeName]\n"
+ COMMON_OPTS
"\tLogicalVolume[Path] [SplittablePhysicalVolume[Path]...]\n\n"
"lvconvert "
"--splitsnapshot\n"
- "\t[--commandprofile ProfileName]\n"
- "\t[-d|--debug]\n"
- "\t[-h|-?|--help]\n"
- "\t[--noudevsync]\n"
- "\t[-v|--verbose]\n"
- "\t[--version]" "\n"
+ COMMON_OPTS
"\tSnapshotLogicalVolume[Path]\n\n"
"lvconvert "
- "[-s|--snapshot]\n"
+ "[--type snapshot|-s|--snapshot]\n"
"\t[-c|--chunksize]\n"
- "\t[--commandprofile ProfileName]\n"
- "\t[-d|--debug]\n"
- "\t[-h|-?|--help]\n"
- "\t[--noudevsync]\n"
- "\t[-v|--verbose]\n"
"\t[-Z|--zero {y|n}]\n"
- "\t[--version]" "\n"
+ COMMON_OPTS
"\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n\n"
"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"
+ COMMON_OPTS
"\tLogicalVolume[Path]\n\n"
"lvconvert "
- "--thinpool ThinPoolLogicalVolume[Path]\n"
+ "[--type thin[-pool]|-T|--thin]\n"
+ "\t[--thinpool ThinPoolLogicalVolume[Path]]\n"
"\t[--chunksize size]\n"
"\t[--discards {ignore|nopassdown|passdown}]\n"
+ "\t[--poolmetadataspare {y|n}]\n"
"\t[--poolmetadata ThinMetadataLogicalVolume[Path] |\n"
"\t [--poolmetadatasize size]\n"
- "\t [--poolmetadataspare {y|n}]\n"
"\t [-r|--readahead ReadAheadSectors|auto|none]\n"
"\t [--stripes Stripes [-I|--stripesize StripeSize]]]\n"
- "\t[-T|--thin ExternalLogicalVolume[Path]\n"
- "\t [--originname NewExternalOriginVolumeName]]\n"
+ "\t[--originname NewExternalOriginVolumeName]]\n"
"\t[-Z|--zero {y|n}]\n"
- "\t[--commandprofile ProfileName]\n"
- "\t[-d|--debug] [-h|-?|--help] [-v|--verbose]\n\n"
+ COMMON_OPTS
+ "\t[ExternalOrigin|ThinDataPool]LogicalVolume[Path]\n\n"
"lvconvert "
- "--type cache-pool\n"
+ "[--type cache[-pool]|--cache]\n"
+ "\t[--cachepool CacheDataLogicalVolume[Path]]\n"
"\t[--cachemode CacheMode]\n"
"\t[--chunksize size]\n"
+ "\t[--poolmetadataspare {y|n}]]\n"
"\t[--poolmetadata CacheMetadataLogicalVolume[Path] |\n"
"\t [--poolmetadatasize size]\n"
- "\t [--poolmetadataspare {y|n}]]\n"
- "\t[--commandprofile ProfileName]\n"
- "\tCacheDataLogicalVolume[Path]\n\n"
+ COMMON_OPTS
+ "\t[Cache|CacheDataPool]LogicalVolume[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,
+ alloc_ARG, background_ARG, cache_ARG, cachemode_ARG, cachepool_ARG, chunksize_ARG,
corelog_ARG, discards_ARG, force_ARG, interval_ARG, merge_ARG, mirrorlog_ARG,
mirrors_ARG, name_ARG, noudevsync_ARG, originname_ARG, poolmetadata_ARG,
poolmetadatasize_ARG, poolmetadataspare_ARG, readahead_ARG, regionsize_ARG,
@@ -1278,4 +1257,3 @@ xx(version,
"Display software and driver version information",
PERMITTED_READ_ONLY,
"version\n" )
-
9 years, 8 months
master - lvconvert: update for thin a cache
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=970989655ff5cd...
Commit: 970989655ff5cd9ca960bf3113b7bfdf6f575d78
Parent: fe3ea94e5846f48baf3b00d0f6b913f585b4404e
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 12:15:23 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:22 2014 +0200
lvconvert: update for thin a cache
Major update of lvconvert code to handle cache and thin.
related targets.
Code tries to unify handling of cache and thin pools.
Better supports lvm2 syntax:
lvconvert --type cache --cachepool vg/pool vg/cache
lvconvert --type thin --thinpool vg/pool vg/extorg
lvconvert --type cache-pool vg/pool
lvconvert --type thin-pool vg/pool
as well as:
lvconvert --cache --cachepool vg/pool vg/cache
lvconvert --thin --thinpool vg/pool vg/extorg
lvconvert --cachepool vg/pool
lvconvert --thinpool vg/pool
While catching much more command line errors.
(Yet couple paths still needs more tests)
Detects as much cmdline errors prior opening VG.
Uses single lvconvert_name_params to convert LV names.
Detects as much incompatibilies in VG prior prompting.
Uses single prompt to confirm whole conversion.
TODO: still the code needs fixes...
---
WHATS_NEW | 1 +
tools/lvconvert.c | 992 ++++++++++++++++++++++++++++-------------------------
tools/toollib.c | 22 +-
3 files changed, 539 insertions(+), 476 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 6cbf221..a81fddb 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Enhance lvconvert thin, thinpool, cache and cachepool command line support.
Display 'C' only for cache and cache-pool target types in lvs.
Prompt for confirmation before change LV into a snapshot exception store.
Return proper error codes for some failing lvconvert funtions.
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 8c960f9..9710134 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2013 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2005-2014 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -17,6 +17,7 @@
#include "lv_alloc.h"
struct lvconvert_params {
+ int cache;
int force;
int snapshot;
int splitsnapshot;
@@ -27,8 +28,6 @@ struct lvconvert_params {
int yes;
int zero;
- const char *origin;
- const char *cachepool;
const char *lv_name;
const char *lv_split_name;
const char *lv_name_full;
@@ -64,84 +63,88 @@ struct lvconvert_params {
struct logical_volume *lv_to_poll;
int passed_args;
- uint64_t poolmetadata_size;
+ uint64_t pool_metadata_size;
const char *origin_lv_name;
const char *pool_data_lv_name;
+ struct logical_volume *pool_data_lv;
const char *pool_metadata_lv_name;
+ struct logical_volume *pool_metadata_lv;
thin_discards_t discards;
};
+static int _lvconvert_vg_name(struct lvconvert_params *lp,
+ struct cmd_context *cmd,
+ const char **lv_name)
+{
+ const char *vg_name;
+ const char *tmp_str;
+
+ if (!lv_name || !*lv_name)
+ return 1;
+
+ /* If contains VG name, extract it. */
+ if ((tmp_str = strchr(*lv_name, (int) '/'))) {
+ if (!(vg_name = extract_vgname(cmd, *lv_name)))
+ return_0;
+ if (!lp->vg_name)
+ lp->vg_name = vg_name;
+ else if (strcmp(vg_name, lp->vg_name)) {
+ log_error("Please use a single volume group name "
+ "(\"%s\" or \"%s\")", vg_name, lp->vg_name);
+ return 0;
+ }
+ /* Strip VG from lv_name */
+ *lv_name = tmp_str + 1;
+ }
+
+ if (!apply_lvname_restrictions(*lv_name))
+ return_0;
+
+ return 1;
+}
+
static int _lvconvert_name_params(struct lvconvert_params *lp,
struct cmd_context *cmd,
int *pargc, char ***pargv)
{
char *ptr;
const char *vg_name = NULL;
- const char *tmp_str;
if (lp->merge)
return 1;
- if (lp->snapshot) {
- if (!*pargc) {
+ if (!*pargc) {
+ if (lp->cache) {
+ log_error("Logical volume name for caching is missing.");
+ return 0;
+ }
+ if (lp->thin) {
log_error("Please specify a logical volume to act as "
- "the snapshot origin.");
+ "the external origin.");
return 0;
}
-
- lp->origin = *pargv[0];
- (*pargv)++, (*pargc)--;
- if (!(lp->vg_name = extract_vgname(cmd, lp->origin))) {
- log_error("The origin name should include the "
- "volume group.");
+ if (lp->snapshot) {
+ log_error("Please specify a logical volume to act as "
+ "the snapshot exception store.");
return 0;
}
-
- /* Strip the volume group from the origin */
- if ((ptr = strrchr(lp->origin, (int) '/')))
- lp->origin = ptr + 1;
- }
-
- if (lp->pool_data_lv_name) {
- if (*pargc) {
- if (!lp->thin) {
- log_error("More then one logical volume name specified.");
- return 0;
- }
- } else {
- if (lp->thin) {
- log_error("External thin volume name is missing.");
- return 0;
- }
-
- if (!lp->vg_name || !validate_name(lp->vg_name)) {
- log_error("Please provide a valid volume group name.");
- return 0;
- }
-
- lp->lv_name = lp->pool_data_lv_name;
- return 1;
+ if (!lp->lv_name_full) {
+ log_error("Please provide logical volume path.");
+ return 0;
}
+ } else if (!lp->lv_name_full) {
+ lp->lv_name_full = (*pargv)[0];
+ (*pargv)++, (*pargc)--;
}
- if (lp->origin_lv_name) {
- /* FIXME: Using generic routine */
- if (strchr(lp->origin_lv_name, '/')) {
- if (!(lp->vg_name = extract_vgname(cmd, lp->origin_lv_name)))
- return_0;
- /* Strip VG from origin_lv_name */
- if ((tmp_str = strrchr(lp->origin_lv_name, '/')))
- lp->origin_lv_name = tmp_str + 1;
- }
- }
+ if (!_lvconvert_vg_name(lp, cmd, &lp->pool_metadata_lv_name))
+ return_0;
- if (!*pargc) {
- log_error("Please provide logical volume path");
- return 0;
- }
+ if (!_lvconvert_vg_name(lp, cmd, &lp->pool_data_lv_name))
+ return_0;
- lp->lv_name = lp->lv_name_full = (*pargv)[0];
- (*pargv)++, (*pargc)--;
+ if (!_lvconvert_vg_name(lp, cmd, &lp->origin_lv_name))
+ return_0;
if (strchr(lp->lv_name_full, '/') &&
(vg_name = extract_vgname(cmd, lp->lv_name_full)) &&
@@ -161,6 +164,8 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
if ((ptr = strrchr(lp->lv_name_full, '/')))
lp->lv_name = ptr + 1;
+ else
+ lp->lv_name = lp->lv_name_full;
if (!lp->merge_mirror &&
!strstr(lp->lv_name, "_tdata") &&
@@ -168,19 +173,21 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
!apply_lvname_restrictions(lp->lv_name))
return_0;
- if (*pargc && lp->snapshot) {
- log_error("Too many arguments provided for snapshots");
- return 0;
- }
-
- if (lp->splitsnapshot && *pargc) {
- log_error("Too many arguments provided with --splitsnapshot.");
- return 0;
- }
-
- if (lp->pool_data_lv_name && lp->lv_name && lp->poolmetadata_size) {
- log_error("Please specify either metadata logical volume or its size.");
- return 0;
+ log_error("PAR %d t:%d c:%d m:%s d:%s l:%s", *pargc, lp->thin,lp->cache,
+ lp->pool_metadata_lv_name, lp->pool_data_lv_name, lp->lv_name);
+ if (*pargc) {
+ if (lp->snapshot) {
+ log_error("Too many arguments provided for snapshots.");
+ return 0;
+ }
+ if (lp->splitsnapshot) {
+ log_error("Too many arguments provided with --splitsnapshot.");
+ return 0;
+ }
+ if (lp->pool_data_lv_name && lp->pool_metadata_lv_name) {
+ log_error("Too many arguments provided for pool.");
+ return 0;
+ }
}
return 1;
@@ -219,11 +226,159 @@ static int _mirror_or_raid_type_requested(struct cmd_context *cmd, const char *t
return (arg_count(cmd, mirrors_ARG) || !strncmp(type_str, "raid", 4) || !strcmp(type_str, "mirror"));
}
+static int _read_pool_params(struct lvconvert_params *lp, struct cmd_context *cmd,
+ const char *type_str, int *pargc, char ***pargv)
+{
+ const char *tmp_str;
+ int cachepool = 0;
+ int thinpool = 0;
+
+ if (arg_count(cmd, cachepool_ARG)) {
+ if (type_str[0] &&
+ strcmp(type_str, "cache") &&
+ strcmp(type_str, "cache-pool")) {
+ log_error("--cachepool argument is only valid with "
+ " the cache or cache-pool segment type.");
+ return 0;
+ }
+ if (!(lp->pool_data_lv_name = arg_str_value(cmd, cachepool_ARG, NULL))) {
+ log_error("Missing cache pool logical volume name.");
+ return 0;
+ }
+ cachepool = 1;
+ type_str = "cache-pool";
+ } else if (!strcmp(type_str, "cache-pool"))
+ cachepool = 1;
+
+ if (arg_count(cmd, thinpool_ARG)) {
+ if (type_str[0] &&
+ strcmp(type_str, "thin") &&
+ strcmp(type_str, "thin-pool")) {
+ log_error("--thinpool argument is only valid with "
+ " the thin or thin-pool segment type.");
+ return 0;
+ }
+ if (!(lp->pool_data_lv_name = arg_str_value(cmd, thinpool_ARG, NULL))) {
+ log_error("Missing thin pool logical volume name.");
+ return 0;
+ }
+ thinpool = 1;
+ type_str = "thin-pool";
+ } else if (!strcmp(type_str, "thin-pool"))
+ thinpool = 1;
+
+ if (thinpool) {
+ lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN);
+
+ if (arg_count(cmd, originname_ARG)) {
+ if (!(lp->origin_lv_name = arg_str_value(cmd, originname_ARG, NULL))) {
+ log_error("Missing --originname argument.");
+ return 0;
+ }
+ }
+ } else {
+ if (!arg_is_any_set(cmd, "is valid only with thin pools",
+ discards_ARG, originname_ARG, zero_ARG,
+ -1))
+ return_0;
+ if (lp->thin) {
+ log_error("--thin requires --thinpool.");
+ return 0;
+ }
+ }
+
+ if (cachepool) {
+ if ((tmp_str = arg_str_value(cmd, cachemode_ARG, NULL))) {
+ if (!strcmp(tmp_str, "writeback"))
+ lp->feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
+ else if (!strcmp(tmp_str, "writethrough"))
+ lp->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
+ else {
+ log_error("Unknown cachemode argument");
+ return 0;
+ }
+ }
+ } else {
+ if (!arg_is_any_set(cmd, "is valid only with cache pools",
+ cachemode_ARG, -1))
+ return_0;
+ if (lp->cache) {
+ log_error("--cache requires --cachepool.");
+ return 0;
+ }
+ }
+
+ if (thinpool || cachepool) {
+ if (!arg_is_any_set(cmd, "is invalid with pools",
+ merge_ARG, mirrors_ARG, repair_ARG, snapshot_ARG,
+ splitmirrors_ARG, -1))
+ return_0;
+
+ if (arg_count(cmd, poolmetadatasize_ARG)) {
+ if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
+ log_error("Negative pool metadata size is invalid.");
+ return 0;
+ }
+ if (arg_count(cmd, poolmetadata_ARG)) {
+ log_error("Please specify either metadata logical volume or its size.");
+ return 0;
+ }
+ /* value is read in get_pool_params() */
+ }
+
+ if (arg_count(cmd, poolmetadata_ARG)) {
+ if (arg_count(cmd, stripesize_ARG) || arg_count(cmd, stripes_long_ARG)) {
+ log_error("Can't use --stripes and --stripesize with --poolmetadata.");
+ return 0;
+ }
+
+ if (arg_count(cmd, readahead_ARG)) {
+ log_error("Can't use --readahead with --poolmetadata.");
+ return 0;
+ }
+
+ if (!(lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, NULL))) {
+ log_error("Missing --poolmetadata argument.");
+ return 0;
+ }
+ }
+
+ if (arg_count(cmd, chunksize_ARG) &&
+ (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Negative chunk size is invalid.");
+ return 0;
+ }
+
+ if (!arg_count(cmd, cachepool_ARG) &&
+ !arg_count(cmd, thinpool_ARG)) {
+ if (!*pargc) {
+ log_error("Please specify the pool data LV.");
+ return 0;
+ }
+ lp->pool_data_lv_name = (*pargv)[0];
+ (*pargv)++, (*pargc)--;
+ }
+
+ if (!lp->thin && !lp->cache)
+ lp->lv_name_full = lp->pool_data_lv_name;
+ /* Hmm _read_activation_params */
+ lp->read_ahead = arg_uint_value(cmd, readahead_ARG,
+ cmd->default_settings.read_ahead);
+
+ if (!(lp->segtype = get_segtype_from_string(cmd, type_str)))
+ return_0;
+ } else if (!arg_is_any_set(cmd, "is valid only with pools",
+ poolmetadatasize_ARG, poolmetadataspare_ARG,
+ -1))
+ return_0;
+
+ return 1;
+}
+
static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
int argc, char **argv)
{
int i;
- int cache_pool = 0;
const char *tmp_str;
struct arg_value_group_list *group;
int region_size;
@@ -269,84 +424,45 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
return 0;
}
- if (!strcmp(type_str, "cache-pool")) {
- cache_pool = 1;
- if ((tmp_str = arg_str_value(cmd, cachemode_ARG, NULL))) {
- if (!strcmp(tmp_str, "writeback"))
- lp->feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
- else if (!strcmp(tmp_str, "writethrough"))
- lp->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
- else {
- log_error("Unknown cachemode argument");
- return 0;
- }
- }
- }
+ if (arg_count(cmd, cache_ARG))
+ lp->cache = 1;
- if (!arg_count(cmd, background_ARG))
- lp->wait_completion = 1;
-
- if (_snapshot_type_requested(cmd, type_str))
- lp->snapshot = 1;
-
- if (_snapshot_type_requested(cmd, type_str) && arg_count(cmd, merge_ARG)) {
- log_error("--snapshot and --merge are mutually exclusive");
- return 0;
- }
-
- if (arg_count(cmd, splitmirrors_ARG) && _mirror_or_raid_type_requested(cmd, type_str)) {
- log_error("--mirrors/--type mirror/--type raid* and --splitmirrors are "
- "mutually exclusive");
- return 0;
+ if (!strcmp(type_str, "cache"))
+ lp->cache = 1;
+ else if (lp->cache) {
+ if (type_str[0]) {
+ log_error("--cache is incompatible with --type %s", type_str);
+ return 0;
+ }
+ type_str = "cache";
}
if (arg_count(cmd, thin_ARG))
lp->thin = 1;
- if (arg_count(cmd, cachepool_ARG)) {
- if (strcmp(type_str, "cache")) {
- log_error("--cachepool argument is only valid with "
- " the \"cache\" segment type");
+ if (!strcmp(type_str, "thin"))
+ lp->thin = 1;
+ else if (lp->thin) {
+ if (type_str[0]) {
+ log_error("--thin is incompatible with --type %s", type_str);
return 0;
}
- lp->cachepool = arg_str_value(cmd, cachepool_ARG, NULL);
- } else if (arg_count(cmd, thinpool_ARG) || cache_pool) {
+ type_str = "thin";
+ }
+
+ if (!_read_pool_params(lp, cmd, type_str, &argc, &argv))
+ return_0;
+
+ if (!arg_count(cmd, background_ARG))
+ lp->wait_completion = 1;
+
+ if (_snapshot_type_requested(cmd, type_str)) {
if (arg_count(cmd, merge_ARG)) {
- log_error("--%spool and --merge are mutually exlusive.",
- cache_pool ? "type cache_" : "thin");
+ log_error("--snapshot and --merge are mutually exclusive.");
return 0;
}
- if (_mirror_or_raid_type_requested(cmd, type_str)) {
- log_error("--%spool and --mirrors/--type mirror/--type raid* are mutually exlusive.",
- cache_pool ? "type cache_" : "thin");
- return 0;
- }
- if (arg_count(cmd, repair_ARG)) {
- log_error("--%spool and --repair are mutually exlusive.",
- cache_pool ? "type cache_" : "thin");
- return 0;
- }
- if (_snapshot_type_requested(cmd, type_str)) {
- log_error("--%spool and --snapshot/--type snapshot are mutually exlusive.",
- cache_pool ? "type cache_" : "thin");
- return 0;
- }
- if (arg_count(cmd, splitmirrors_ARG)) {
- log_error("--%spool and --splitmirrors are mutually exlusive.",
- cache_pool ? "type cache_" : "thin");
- return 0;
- }
- if (!cache_pool)
- lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN);
- } else if (lp->thin) {
- log_error("--thin is only valid with --thinpool.");
- return 0;
- } else if (arg_count(cmd, discards_ARG)) {
- log_error("--discards is only valid with --thinpool.");
- return 0;
- } else if (arg_count(cmd, poolmetadataspare_ARG)) {
- log_error("--poolmetadataspare is only valid with --thinpool.");
- return 0;
+
+ lp->snapshot = 1;
}
/*
@@ -356,6 +472,11 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
* discarding it.
*/
if (arg_count(cmd, splitmirrors_ARG)) {
+ if (_mirror_or_raid_type_requested(cmd, type_str)) {
+ log_error("--mirrors/--type mirror/--type raid* and --splitmirrors are "
+ "mutually exclusive.");
+ return 0;
+ }
if (!arg_count(cmd, name_ARG) &&
!arg_count(cmd, trackchanges_ARG)) {
log_error("Please name the new logical volume using '--name'");
@@ -437,6 +558,13 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
} else if (lp->splitsnapshot) /* Destroy snapshot retaining cow as separate LV */
;
else if (lp->snapshot) { /* Snapshot creation from pre-existing cow */
+ if (!argc) {
+ log_error("Please provide logical volume path for snaphost origin.");
+ return 0;
+ }
+ lp->origin_lv_name = argv[0];
+ argv++, argc--;
+
if (arg_count(cmd, regionsize_ARG)) {
log_error("--regionsize is only available with mirrors");
return 0;
@@ -490,65 +618,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
tmp_str)))
return_0;
}
- } else if (arg_count(cmd, thinpool_ARG) || cache_pool) {
- if (cache_pool) {
- if (!argc) {
- log_error("Please specify the pool data LV.");
- return 0;
- }
- lp->pool_data_lv_name = argv[0];
- argv++, argc--;
- } else if (!(lp->pool_data_lv_name = arg_str_value(cmd, thinpool_ARG, NULL))) {
- log_error("Missing pool logical volume name.");
- return 0;
- }
-
- if (arg_count(cmd, poolmetadata_ARG)) {
- if (arg_count(cmd, poolmetadatasize_ARG)) {
- log_error("--poolmetadatasize is invalid with --poolmetadata.");
- return 0;
- }
- if (arg_count(cmd, stripesize_ARG) || arg_count(cmd, stripes_long_ARG)) {
- log_error("Can't use --stripes and --stripesize with --poolmetadata.");
- return 0;
- }
-
- if (arg_count(cmd, readahead_ARG)) {
- log_error("Can't use --readahead with --poolmetadata.");
- return 0;
- }
- lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, "");
- }
-
- /* Hmm _read_activation_params */
- lp->read_ahead = arg_uint_value(cmd, readahead_ARG,
- cmd->default_settings.read_ahead);
-
- /* If pool_data_lv_name contains VG name, extract it. */
- if ((tmp_str = strchr(lp->pool_data_lv_name, (int) '/'))) {
- if (!(lp->vg_name = extract_vgname(cmd, lp->pool_data_lv_name)))
- return 0;
- /* Strip VG from pool */
- lp->pool_data_lv_name = tmp_str + 1;
- }
-
- if (arg_count(cmd, originname_ARG)) {
- if (!(lp->origin_lv_name = arg_str_value(cmd, originname_ARG, NULL))) {
- log_error("--originname is invalid.");
- return 0;
- }
- }
-
- lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, cache_pool ? "cache-pool" : "thin-pool"));
- if (!lp->segtype)
- return_0;
-
- if (arg_count(cmd, chunksize_ARG) &&
- (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
- log_error("Negative chunk size is invalid.");
- return 0;
- }
- } else { /* Mirrors (and some RAID functions) */
+ } else if (_mirror_or_raid_type_requested(cmd, type_str)) { /* Mirrors (and some RAID functions) */
if (arg_count(cmd, chunksize_ARG)) {
log_error("--chunksize is only available with snapshots or pools.");
return 0;
@@ -2046,14 +2116,14 @@ static int _lvconvert_snapshot(struct cmd_context *cmd,
return 0;
}
- if (!(org = find_lv(lv->vg, lp->origin))) {
- log_error("Couldn't find origin volume '%s'.", lp->origin);
+ if (!(org = find_lv(lv->vg, lp->origin_lv_name))) {
+ log_error("Couldn't find origin volume %s.", lp->origin_lv_name);
return 0;
}
if (org == lv) {
- log_error("Unable to use \"%s\" as both snapshot and origin.",
- lv->name);
+ log_error("Unable to use %s as both snapshot and origin.",
+ display_lvname(lv));
return 0;
}
@@ -2327,9 +2397,9 @@ out:
return r;
}
-static int _lvconvert_thinpool_repair(struct cmd_context *cmd,
- struct logical_volume *pool_lv,
- struct lvconvert_params *lp)
+static int _lvconvert_pool_repair(struct cmd_context *cmd,
+ struct logical_volume *pool_lv,
+ struct lvconvert_params *lp)
{
const char *dmdir = dm_dir();
const char *thin_dump =
@@ -2526,12 +2596,12 @@ deactivate_pmslv:
return 1;
}
-static int _lvconvert_thinpool_external(struct cmd_context *cmd,
- struct logical_volume *pool_lv,
- struct logical_volume *external_lv,
- struct lvconvert_params *lp)
+/* Currently converts only to thin volume with external origin */
+static int _lvconvert_thin(struct cmd_context *cmd,
+ struct logical_volume *lv,
+ struct lvconvert_params *lp)
{
- struct logical_volume *torigin_lv;
+ struct logical_volume *torigin_lv, *pool_lv = lp->pool_data_lv;
struct volume_group *vg = pool_lv->vg;
struct lvcreate_params lvc = {
.activate = CHANGE_AE,
@@ -2544,18 +2614,33 @@ static int _lvconvert_thinpool_external(struct cmd_context *cmd,
.pvh = &vg->pvs,
.read_ahead = DM_READ_AHEAD_AUTO,
.stripes = 1,
- .voriginextents = external_lv->le_count,
- .voriginsize = external_lv->size,
+ .voriginextents = lv->le_count,
+ .voriginsize = lv->size,
};
+ if (lv == pool_lv) {
+ log_error("Can't use same LV %s for thin pool and thin volume.",
+ display_lvname(pool_lv));
+ return 0;
+ }
+
+ if (lv_is_thin_pool(lv)) {
+ log_error("Can't use pool %s as external origin.",
+ display_lvname(lv));
+ return 0;
+ }
+
dm_list_init(&lvc.tags);
- if (!pool_supports_external_origin(first_seg(pool_lv), external_lv))
+ if (!pool_supports_external_origin(first_seg(pool_lv), lv))
return_0;
if (!(lvc.segtype = get_segtype_from_string(cmd, "thin")))
return_0;
+ if (!archive(vg))
+ return_0;
+
/* New thin LV needs to be created (all messages sent to pool) */
if (!(torigin_lv = lv_create_single(vg, &lvc)))
return_0;
@@ -2572,15 +2657,15 @@ static int _lvconvert_thinpool_external(struct cmd_context *cmd,
* which could be easily removed by the user after i.e. power-off
*/
- if (!_swap_lv_identifiers(cmd, torigin_lv, external_lv)) {
+ if (!_swap_lv_identifiers(cmd, torigin_lv, lv)) {
stack;
goto revert_new_lv;
}
/* Preserve read-write status of original LV here */
- torigin_lv->status |= (external_lv->status & LVM_WRITE);
+ torigin_lv->status |= (lv->status & LVM_WRITE);
- if (!attach_thin_external_origin(first_seg(torigin_lv), external_lv)) {
+ if (!attach_thin_external_origin(first_seg(torigin_lv), lv)) {
stack;
goto revert_new_lv;
}
@@ -2590,15 +2675,17 @@ static int _lvconvert_thinpool_external(struct cmd_context *cmd,
goto deactivate_and_revert_new_lv;
}
- log_print_unless_silent("Converted \"%s/%s\" to thin volume with "
- "external origin \"%s/%s\".",
- vg->name, torigin_lv->name,
- vg->name, external_lv->name);
+ log_print_unless_silent("Converted %s to thin volume with "
+ "external origin %s.",
+ display_lvname(torigin_lv),
+ display_lvname(lv));
+
+ backup(vg);
return 1;
deactivate_and_revert_new_lv:
- if (!_swap_lv_identifiers(cmd, torigin_lv, external_lv))
+ if (!_swap_lv_identifiers(cmd, torigin_lv, lv))
stack;
if (!deactivate_lv(cmd, torigin_lv)) {
@@ -2632,7 +2719,7 @@ static int _lvconvert_update_pool_params(struct logical_volume *pool_lv,
&lp->thin_chunk_size_calc_policy,
&lp->chunk_size,
&lp->discards,
- &lp->poolmetadata_size,
+ &lp->pool_metadata_size,
&lp->zero);
return update_thin_pool_params(pool_lv->vg, lp->target_attr,
@@ -2642,101 +2729,95 @@ static int _lvconvert_update_pool_params(struct logical_volume *pool_lv,
&lp->thin_chunk_size_calc_policy,
&lp->chunk_size,
&lp->discards,
- &lp->poolmetadata_size,
+ &lp->pool_metadata_size,
&lp->zero);
}
-
-
/*
* Thin lvconvert version which
* rename metadata
* convert/layers thinpool over data
* attach metadata
*/
-static int _lvconvert_to_pool(struct cmd_context *cmd,
- struct logical_volume *pool_lv,
- struct lvconvert_params *lp)
+static int _lvconvert_pool(struct cmd_context *cmd,
+ struct logical_volume *pool_lv,
+ struct lvconvert_params *lp)
{
int r = 0;
- uint64_t min_metadata_size;
- uint64_t max_metadata_size;
const char *old_name;
struct lv_segment *seg;
+ struct volume_group *vg = pool_lv->vg;
struct logical_volume *data_lv;
- struct logical_volume *metadata_lv;
+ struct logical_volume *metadata_lv = NULL;
struct logical_volume *pool_metadata_lv;
- struct logical_volume *external_lv = NULL;
char metadata_name[NAME_LEN], data_name[NAME_LEN];
int activate_pool;
- if (!lv_is_visible(pool_lv)) {
- log_error("Can't convert internal LV %s/%s.",
- pool_lv->vg->name, pool_lv->name);
+ if (lp->pool_data_lv_name &&
+ !(pool_lv = find_lv(vg, lp->pool_data_lv_name))) {
+ log_error("Unknown pool data LV %s.", lp->pool_data_lv_name);
return 0;
}
- if (lv_is_mirrored(pool_lv) && !lv_is_raid_type(pool_lv)) {
- log_error("Mirror logical volumes cannot be used as thinpools.\n"
- "Try \"raid1\" segment type instead.");
- return 0;
- }
-
- if (lp->thin) {
- if (strcmp(pool_lv->name, lp->pool_data_lv_name) == 0) {
- log_error("Can't use same LV %s/%s for thin pool and thin volume.",
- pool_lv->vg->name, pool_lv->name);
+ if (lp->pool_metadata_lv_name) {
+ if (!(lp->pool_metadata_lv = find_lv(vg, lp->pool_metadata_lv_name))) {
+ log_error("Unknown pool metadata LV %s.", lp->pool_metadata_lv_name);
return 0;
}
+ lp->pool_metadata_size = lp->pool_metadata_lv->size;
+ metadata_lv = lp->pool_metadata_lv;
- external_lv = pool_lv;
- if (!(pool_lv = find_lv(external_lv->vg, lp->pool_data_lv_name))) {
- log_error("Can't find pool LV %s/%s.",
- external_lv->vg->name, lp->pool_data_lv_name);
+ if (!lv_is_visible(metadata_lv)) {
+ log_error("Can't convert internal LV %s.",
+ display_lvname(metadata_lv));
return 0;
}
-
- if (lv_is_thin_pool(external_lv)) {
- log_error("Can't convert pool \"%s/%s\" to external origin.",
- external_lv->vg->name, lp->pool_data_lv_name);
+ if (lv_is_mirrored(metadata_lv) && !lv_is_raid_type(metadata_lv)) {
+ log_error("Mirror logical volumes cannot be used "
+ "for pool metadata.");
+ log_error("Try \"raid1\" segment type instead.");
+ return 0;
+ }
+ if (metadata_lv->status & LOCKED) {
+ log_error("Can't convert locked LV %s.",
+ display_lvname(metadata_lv));
+ return 0;
+ }
+ if (metadata_lv == pool_lv) {
+ log_error("Can't use same LV for pool data and metadata LV %s.",
+ display_lvname(metadata_lv));
+ return 0;
+ }
+ if (lv_is_thin_type(metadata_lv) ||
+ lv_is_cache_type(metadata_lv)) {
+ log_error("Can't use %s LV %s for pool metadata.",
+ lv_type_name(metadata_lv), display_lvname(metadata_lv));
return 0;
}
- if (lv_is_thin_pool(pool_lv)) {
- activate_pool = lv_is_active(pool_lv);
- r = 1; /* Already existing thin pool */
- goto out;
+ if (!lv_is_pool(pool_lv)) {
+ if (!_lvconvert_update_pool_params(pool_lv, lp))
+ return_0;
+
+ if (lp->pool_metadata_size > metadata_lv->size) {
+ log_error("Logical volume %s is too small for metadata.",
+ display_lvname(metadata_lv));
+ return 0;
+ }
}
}
- if (lv_is_thin_type(pool_lv) && !lp->pool_metadata_lv_name) {
- log_error("Can't use thin logical volume %s/%s for thin pool data.",
- pool_lv->vg->name, pool_lv->name);
+ if (!lv_is_visible(pool_lv)) {
+ log_error("Can't convert internal LV %s.", display_lvname(pool_lv));
return 0;
}
- if (segtype_is_cache_pool(lp->segtype))
- activate_pool = 0; /* Cannot activate cache pool */
- else
- /* Allow to have only thinpool active and restore it's active state */
- activate_pool = lv_is_active(pool_lv);
-
- /* We are changing target type, so deactivate first */
- if (!deactivate_lv(cmd, pool_lv)) {
- log_error("Aborting. Failed to deactivate logical volume %s/%s.",
- pool_lv->vg->name, pool_lv->name);
+ if (lv_is_mirrored(pool_lv) && !lv_is_raid_type(pool_lv)) {
+ log_error("Mirror logical volumes cannot be used as pools.\n"
+ "Try \"raid1\" segment type instead.");
return 0;
}
- if (lv_is_thin_pool(pool_lv)) {
- if (pool_is_active(pool_lv)) {
- /* If any thin volume is also active - abort here */
- log_error("Cannot convert pool %s/%s with active thin volumes.",
- pool_lv->vg->name, pool_lv->name);
- return 0;
- }
- }
-
if ((dm_snprintf(metadata_name, sizeof(metadata_name), "%s%s",
pool_lv->name,
(segtype_is_cache_pool(lp->segtype)) ?
@@ -2750,149 +2831,144 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
return 0;
}
- if (!lp->pool_metadata_lv_name) {
- if (!_lvconvert_update_pool_params(pool_lv, lp))
- return_0;
-
- if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size))
- return_0;
+ if (lv_is_pool(pool_lv)) {
+ lp->pool_data_lv = pool_lv;
- if (!(metadata_lv = alloc_pool_metadata(pool_lv, metadata_name,
- lp->read_ahead, lp->stripes,
- lp->stripe_size,
- lp->poolmetadata_size,
- lp->alloc, lp->pvh)))
- return_0;
- } else {
- if (!(metadata_lv = find_lv(pool_lv->vg, lp->pool_metadata_lv_name))) {
- log_error("Unknown metadata LV %s.", lp->pool_metadata_lv_name);
- return 0;
- }
- if (!lv_is_visible(metadata_lv)) {
- log_error("Can't convert internal LV %s/%s.",
- metadata_lv->vg->name, metadata_lv->name);
- return 0;
- }
- if (lv_is_mirrored(pool_lv) && !lv_is_raid_type(pool_lv)) {
- log_error("Mirror logical volumes cannot be used"
- " for thinpool metadata.\n"
- "Try \"raid1\" segment type instead.");
- return 0;
- }
- if (metadata_lv->status & LOCKED) {
- log_error("Can't convert locked LV %s/%s.",
- metadata_lv->vg->name, metadata_lv->name);
- return 0;
+ if (!metadata_lv) {
+ if (!arg_is_any_set(cmd, "is invalid with existing pool",
+ cachemode_ARG,chunksize_ARG, discards_ARG,
+ zero_ARG, poolmetadatasize_ARG, -1))
+ return_0;
+ return 1;
}
- if (metadata_lv == pool_lv) {
- log_error("Can't use same LV for thin pool data and metadata LV %s/%s.",
- metadata_lv->vg->name, metadata_lv->name);
+
+ if (lp->thin || lp->cache) {
+ log_error("--%s and pool metadata swap is not supported.",
+ lp->thin ? "thin" : "cache");
return 0;
}
- if (lv_is_thin_type(metadata_lv)) {
- log_error("Can't use thin type LV %s/%s for thin pool metadata.",
- metadata_lv->vg->name, metadata_lv->name);
+
+ /* FIXME cache pool */
+ if (lv_is_thin_pool(pool_lv) && pool_is_active(pool_lv)) {
+ /* If any volume referencing pool active - abort here */
+ log_error("Cannot convert pool %s with active volumes.",
+ display_lvname(pool_lv));
return 0;
}
- /* Swap normal LV with pool's metadata LV ? */
- if (lv_is_thin_pool(pool_lv)) {
- if (!deactivate_lv(cmd, metadata_lv)) {
- log_error("Aborting. Failed to deactivate LV %s/%s.",
- metadata_lv->vg->name, metadata_lv->name);
- return 0;
- }
+ seg = first_seg(pool_lv);
- seg = first_seg(pool_lv);
-
- if (!arg_count(cmd, chunksize_ARG))
- lp->chunk_size = seg->chunk_size;
- else if (lp->chunk_size != seg->chunk_size) {
- if (lp->force == PROMPT) {
- log_error("Chunk size can be only changed with --force. Conversion aborted.");
- return 0;
- }
- /* Ok, user has likely some serious reason for this */
- if (!lp->yes &&
- yes_no_prompt("Do you really want to change chunk size %s to %s "
- "for %s/%s pool volume? [y/n]: ",
- display_size(cmd, seg->chunk_size),
- display_size(cmd, lp->chunk_size),
- pool_lv->vg->name, pool_lv->name) == 'n') {
- log_error("Conversion aborted.");
- return 0;
- }
- log_warn("WARNING: Changing chunk size %s to %s for %s/%s pool volume.",
- display_size(cmd, seg->chunk_size),
- display_size(cmd, lp->chunk_size),
- pool_lv->vg->name, pool_lv->name);
+ /* Normally do NOT change chunk size when swapping */
+ if (arg_count(cmd, chunksize_ARG) &&
+ (lp->chunk_size != seg->chunk_size)) {
+ if (lp->force == PROMPT) {
+ log_error("Chunk size can be only changed with --force. Conversion aborted.");
+ return 0;
}
-
+ log_warn("WARNING: Changing chunk size %s to "
+ "%s for %s pool volume.",
+ display_size(cmd, seg->chunk_size),
+ display_size(cmd, lp->chunk_size),
+ display_lvname(pool_lv));
+ /* Ok, user has likely some serious reason for this */
if (!lp->yes &&
- yes_no_prompt("Do you want to swap metadata of %s/%s pool with "
- "volume %s/%s? [y/n]: ",
- pool_lv->vg->name, pool_lv->name,
- metadata_lv->vg->name, metadata_lv->name) == 'n') {
+ yes_no_prompt("Do you really want to change chunk size "
+ "for %s pool volume? [y/n]: ",
+ display_lvname(pool_lv)) == 'n') {
log_error("Conversion aborted.");
return 0;
}
+ } else
+ lp->chunk_size = seg->chunk_size;
- /* Swap names between old and new metadata LV */
- if (!detach_pool_metadata_lv(seg, &pool_metadata_lv))
- return_0;
- old_name = metadata_lv->name;
- if (!lv_rename_update(cmd, metadata_lv, "pvmove_tmeta", 0))
- return_0;
- if (!lv_rename_update(cmd, pool_metadata_lv, old_name, 0))
- return_0;
+ if (!_lvconvert_update_pool_params(pool_lv, lp))
+ return_0;
- if (!arg_count(cmd, discards_ARG))
- lp->discards = seg->discards;
- if (!arg_count(cmd, zero_ARG))
- lp->zero = seg->zero_new_blocks;
+ if (metadata_lv->size < lp->pool_metadata_size)
+ log_print_unless_silent("Continuing with swap...");
- goto mda_write;
- }
+ if (!arg_count(cmd, discards_ARG))
+ lp->discards = seg->discards;
+ if (!arg_count(cmd, zero_ARG))
+ lp->zero = seg->zero_new_blocks;
- if (!deactivate_lv(cmd, metadata_lv)) {
- log_error("Aborting. Failed to deactivate \"%s/%s\".",
- metadata_lv->vg->name, metadata_lv->name);
+ if (!lp->yes &&
+ yes_no_prompt("Do you want to swap metadata of %s "
+ "pool with %s volume %s? [y/n]: ",
+ display_lvname(pool_lv),
+ lv_type_name(metadata_lv),
+ display_lvname(metadata_lv)) == 'n') {
+ log_error("Conversion aborted.");
return 0;
}
+ } else if (lv_is_thin_type(pool_lv)) {
+ log_error("Can't use %s logical volume %s for thin pool data.",
+ lv_type_name(pool_lv), display_lvname(pool_lv));
+ return 0;
+ } else {
+ log_warn("WARNING: Converting logical volume %s%s%s to pool's data%s.",
+ display_lvname(pool_lv),
+ metadata_lv ? " and " : "",
+ metadata_lv ? display_lvname(metadata_lv) : "",
+ metadata_lv ? " and metadata volumes" : " volume");
+ log_warn("THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)");
- lp->poolmetadata_size = metadata_lv->size;
- max_metadata_size = (segtype_is_cache_pool(lp->segtype)) ?
- DEFAULT_CACHE_POOL_MAX_METADATA_SIZE * 2 :
- DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2;
- min_metadata_size = (segtype_is_cache_pool(lp->segtype)) ?
- DEFAULT_CACHE_POOL_MIN_METADATA_SIZE * 2 :
- DEFAULT_THIN_POOL_MIN_METADATA_SIZE * 2;
-
- if (lp->poolmetadata_size > max_metadata_size) {
- log_warn("WARNING: Maximum size used by metadata is %s, rest is unused.",
- display_size(cmd, max_metadata_size));
- lp->poolmetadata_size = max_metadata_size;
- } else if (lp->poolmetadata_size < min_metadata_size) {
- log_error("Logical volume %s/%s is too small (<%s) for metadata.",
- metadata_lv->vg->name, metadata_lv->name,
- display_size(cmd, min_metadata_size));
+ if (!lp->yes &&
+ yes_no_prompt("Do you really want to convert %s%s%s? [y/n]: ",
+ display_lvname(pool_lv),
+ metadata_lv ? " and " : "",
+ metadata_lv ? display_lvname(metadata_lv) : "") == 'n') {
+ log_error("Conversion aborted.");
return 0;
}
+ }
+ if (segtype_is_cache_pool(lp->segtype))
+ activate_pool = 0; /* Cannot activate cache pool */
+ else
+ /* Allow to have only thinpool active and restore it's active state */
+ activate_pool = lv_is_active(pool_lv);
+
+ if (!metadata_lv) {
if (!_lvconvert_update_pool_params(pool_lv, lp))
return_0;
- log_warn("WARNING: Converting logical volume %s/%s to pool's metadata volume.",
- metadata_lv->vg->name, metadata_lv->name);
- log_warn("THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)");
+ if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size))
+ return_0;
- 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.");
+ if (!archive(vg))
+ return_0;
+
+ if (!(metadata_lv = alloc_pool_metadata(pool_lv, metadata_name,
+ lp->read_ahead, lp->stripes,
+ lp->stripe_size,
+ lp->pool_metadata_size,
+ lp->alloc, lp->pvh)))
+ return_0;
+ } else {
+ if (!deactivate_lv(cmd, metadata_lv)) {
+ log_error("Aborting. Failed to deactivate %s.",
+ display_lvname(metadata_lv));
return 0;
}
+ if (!archive(vg))
+ return_0;
+
+ /* Swap normal LV with pool's metadata LV ? */
+ if (lv_is_pool(pool_lv)) {
+ /* Swap names between old and new metadata LV */
+ if (!detach_pool_metadata_lv(seg, &pool_metadata_lv))
+ return_0;
+ old_name = metadata_lv->name;
+ if (!lv_rename_update(cmd, metadata_lv, "pvmove_tmeta", 0))
+ return_0;
+ if (!lv_rename_update(cmd, pool_metadata_lv, old_name, 0))
+ return_0;
+
+ goto mda_write;
+ }
+
metadata_lv->status |= LV_TEMPORARY;
if (!activate_lv_local(cmd, metadata_lv)) {
log_error("Aborting. Failed to activate metadata lv.");
@@ -2905,27 +2981,17 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
}
}
+ /* We are changing target type, so deactivate first */
if (!deactivate_lv(cmd, metadata_lv)) {
log_error("Aborting. Failed to deactivate metadata lv. "
"Manual intervention required.");
return 0;
}
- if (!handle_pool_metadata_spare(pool_lv->vg, metadata_lv->le_count,
- lp->pvh, lp->poolmetadataspare))
- return_0;
-
- if (!lv_is_thin_pool(pool_lv)) {
- log_warn("WARNING: Converting logical volume %s/%s 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 (!deactivate_lv(cmd, pool_lv)) {
+ log_error("Aborting. Failed to deactivate logical volume %s.",
+ display_lvname(pool_lv));
+ return 0;
}
data_lv = pool_lv;
@@ -2943,12 +3009,12 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
((segtype_is_cache_pool(lp->segtype)) ?
CACHE_POOL : THIN_POOL) |
VISIBLE_LV | LVM_READ | LVM_WRITE,
- ALLOC_INHERIT, data_lv->vg))) {
+ ALLOC_INHERIT, vg))) {
log_error("Creation of pool LV failed.");
return 0;
}
- /* Allocate a new linear segment */
+ /* Allocate a new pool segment */
if (!(seg = alloc_lv_segment(lp->segtype, pool_lv, 0, data_lv->le_count,
pool_lv->status, 0, NULL, NULL, 1,
data_lv->le_count, 0, 0, 0, NULL)))
@@ -2982,13 +3048,22 @@ mda_write:
if (!attach_pool_metadata_lv(seg, metadata_lv))
return_0;
- if (!vg_write(pool_lv->vg) || !vg_commit(pool_lv->vg))
+ if (!handle_pool_metadata_spare(vg, metadata_lv->le_count,
+ lp->pvh, lp->poolmetadataspare))
return_0;
+ if (!vg_write(vg) || !vg_commit(vg))
+ return_0;
+
+ if (seg->zero_new_blocks &&
+ seg->chunk_size >= DEFAULT_THIN_POOL_CHUNK_SIZE_PERFORMANCE * 2)
+ log_warn("WARNING: Pool zeroing and large %s chunk size slows down "
+ "provisioning.", display_size(cmd, seg->chunk_size));
+
if (activate_pool &&
!activate_lv_excl(cmd, pool_lv)) {
- log_error("Failed to activate pool logical volume %s/%s.",
- pool_lv->vg->name, pool_lv->name);
+ log_error("Failed to activate pool logical volume %s.",
+ display_lvname(pool_lv));
/* Deactivate subvolumes */
if (!deactivate_lv(cmd, seg_lv(seg, 0)))
log_error("Failed to deactivate pool data logical volume.");
@@ -2997,53 +3072,68 @@ mda_write:
goto out;
}
- log_print_unless_silent("Converted \"%s/%s\" to %s pool.",
- pool_lv->vg->name, pool_lv->name,
+ log_print_unless_silent("Converted %s to %s pool.",
+ display_lvname(pool_lv),
(segtype_is_cache_pool(lp->segtype)) ?
"cache" : "thin");
r = 1;
-out:
- if (r && external_lv &&
- !(r = _lvconvert_thinpool_external(cmd, pool_lv, external_lv, lp)))
- stack;
- backup(pool_lv->vg);
+ lp->pool_data_lv = pool_lv;
+
+out:
+ backup(vg);
return r;
+#if 0
+revert_new_lv:
+ /* TBD */
+ if (!lp->pool_metadata_lv_name) {
+ if (!deactivate_lv(cmd, metadata_lv)) {
+ log_error("Failed to deactivate metadata lv.");
+ return 0;
+ }
+ if (!lv_remove(metadata_lv) || !vg_write(vg) || !vg_commit(vg))
+ log_error("Manual intervention may be required to remove "
+ "abandoned LV(s) before retrying.");
+ else
+ backup(vg);
+ }
+
+ return 0;
+#endif
}
-static int _lvconvert_cache(struct logical_volume *origin,
+static int _lvconvert_cache(struct cmd_context *cmd,
+ struct logical_volume *origin,
struct lvconvert_params *lp)
{
- struct cmd_context *cmd = origin->vg->cmd;
+ struct logical_volume *pool_lv = lp->pool_data_lv;
struct logical_volume *cache_lv;
- struct logical_volume *cachepool;
- if (!lp->cachepool) {
- log_error("--cachepool argument is required.");
+ if (origin == pool_lv) {
+ log_error("Can't use same LV %s for cache pool and cache volume.",
+ display_lvname(pool_lv));
return 0;
}
- if (!(cachepool = find_lv(origin->vg, lp->cachepool))) {
- log_error("Unable to find cache pool LV, %s", lp->cachepool);
+ if (lv_is_pool(origin) || lv_is_cache_type(origin)) {
+ log_error("Can't cache %s volume %s.",
+ lv_type_name(origin), display_lvname(origin));
return 0;
}
- if (!(cache_lv = lv_cache_create(cachepool, origin)))
+ if (!archive(origin->vg))
return_0;
- if (!vg_write(cache_lv->vg))
- return_0;
- if (!suspend_lv(cmd, cache_lv))
- return_0;
- if (!vg_commit(cache_lv->vg))
+ if (!(cache_lv = lv_cache_create(pool_lv, origin)))
return_0;
- if (!resume_lv(cmd, cache_lv))
+
+ if (!_reload_lv(cmd, cache_lv->vg, cache_lv))
return_0;
- log_print_unless_silent("%s/%s is now cached.",
- cache_lv->vg->name, cache_lv->name);
+ log_print_unless_silent("Logical volume %s is now cached.",
+ display_lvname(cache_lv));
return 1;
}
@@ -3073,8 +3163,8 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lp->splitsnapshot)
return _lvconvert_splitsnapshot(cmd, lv, lp);
- if (arg_count(cmd, repair_ARG) && lv_is_thin_pool(lv)) {
- if (!_lvconvert_thinpool_repair(cmd, lv, lp))
+ if (arg_count(cmd, repair_ARG) && lv_is_pool(lv)) {
+ if (!_lvconvert_pool_repair(cmd, lv, lp))
return_ECMD_FAILED;
return ECMD_PROCESSED;
}
@@ -3112,28 +3202,19 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
} else if (lp->snapshot) {
if (!_lvconvert_snapshot(cmd, lv, lp))
return_ECMD_FAILED;
-
- } else if (segtype_is_cache(lp->segtype)) {
- if (!archive(lv->vg))
+ } else if (segtype_is_pool(lp->segtype) || lp->thin || lp->cache) {
+ if (!get_pool_params(cmd, lv_config_profile(lv),
+ &lp->passed_args, &lp->thin_chunk_size_calc_policy,
+ &lp->chunk_size, &lp->discards,
+ &lp->pool_metadata_size, &lp->zero))
return_ECMD_FAILED;
- if (!_lvconvert_cache(lv, lp))
+ if (!_lvconvert_pool(cmd, lv, lp))
return_ECMD_FAILED;
- } else if (segtype_is_cache_pool(lp->segtype)) {
- if (!archive(lv->vg))
+ if ((lp->thin && !_lvconvert_thin(cmd, lv, lp)) ||
+ (lp->cache && !_lvconvert_cache(cmd, lv, lp)))
return_ECMD_FAILED;
-
- if (!_lvconvert_to_pool(cmd, lv, lp))
- return_ECMD_FAILED;
-
- } else if (arg_count(cmd, thinpool_ARG)) {
- if (!archive(lv->vg))
- return_ECMD_FAILED;
-
- if (!_lvconvert_to_pool(cmd, lv, lp))
- return_ECMD_FAILED;
-
} else if (segtype_is_raid(lp->segtype) ||
(lv->status & RAID) || lp->merge_mirror) {
if (!archive(lv->vg))
@@ -3223,16 +3304,9 @@ static int lvconvert_single(struct cmd_context *cmd, struct lvconvert_params *lp
cmd->handles_missing_pvs = 1;
}
- lv = get_vg_lock_and_logical_volume(cmd, lp->vg_name, lp->lv_name);
- if (!lv)
+ if (!(lv = get_vg_lock_and_logical_volume(cmd, lp->vg_name, lp->lv_name)))
goto_out;
- if (!get_pool_params(cmd, lv_config_profile(lv),
- &lp->passed_args, &lp->thin_chunk_size_calc_policy,
- &lp->chunk_size, &lp->discards,
- &lp->poolmetadata_size, &lp->zero))
- goto_bad;
-
/*
* lp->pvh holds the list of PVs available for allocation or removal
*/
diff --git a/tools/toollib.c b/tools/toollib.c
index b4e02d6..312a76d 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1661,18 +1661,9 @@ int get_pool_params(struct cmd_context *cmd,
{
int cache_pool = 0;
- if (!strcmp("cache-pool", arg_str_value(cmd, type_ARG, "none")))
+ if (!strcmp("cache-pool", arg_str_value(cmd, type_ARG, "")))
cache_pool = 1;
- if (!cache_pool && !arg_count(cmd, thinpool_ARG)) {
- /* Check for arguments that should only go with pools */
- if (arg_count(cmd, poolmetadata_ARG)) {
- log_error("'--poolmetadata' argument is only valid when"
- " converting to pool LVs.");
- return_0;
- }
- }
-
*passed_args = 0;
if (!cache_pool && arg_count(cmd, zero_ARG)) {
*passed_args |= PASS_ARG_ZERO;
@@ -1706,14 +1697,11 @@ int get_pool_params(struct cmd_context *cmd,
return_0;
if (arg_count(cmd, poolmetadatasize_ARG)) {
- if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative pool metadata size is invalid.");
- return 0;
- }
*passed_args |= PASS_ARG_POOL_METADATA_SIZE;
- }
- *pool_metadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG,
- UINT64_C(0));
+ *pool_metadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG,
+ UINT64_C(0));
+ } else if (arg_count(cmd, poolmetadata_ARG))
+ *passed_args |= PASS_ARG_POOL_METADATA_SIZE; /* fixed size */
return 1;
}
9 years, 8 months
master - cleanup: shift detection of chunksize sign
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fe3ea94e5846f4...
Commit: fe3ea94e5846f48baf3b00d0f6b913f585b4404e
Parent: 9955204e0d9d8d50c19564d475ece03995a6e837
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:40:36 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:22 2014 +0200
cleanup: shift detection of chunksize sign
Sign should be checked prior opening of VG.
Since get_pool_params() needs profiles,
we need to move check for sign earlier.
---
tools/lvconvert.c | 15 +++++++++++----
tools/lvcreate.c | 12 +++++++-----
tools/toollib.c | 4 ----
3 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 95ca245..8c960f9 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -447,10 +447,12 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
return 0;
}
- if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative chunk size is invalid");
+ if (arg_count(cmd, chunksize_ARG) &&
+ (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Negative chunk size is invalid.");
return 0;
}
+
lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
(lp->chunk_size & (lp->chunk_size - 1))) {
@@ -540,10 +542,15 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, cache_pool ? "cache-pool" : "thin-pool"));
if (!lp->segtype)
return_0;
+
+ if (arg_count(cmd, chunksize_ARG) &&
+ (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Negative chunk size is invalid.");
+ return 0;
+ }
} else { /* Mirrors (and some RAID functions) */
if (arg_count(cmd, chunksize_ARG)) {
- log_error("--chunksize is only available with "
- "snapshots or thin pools.");
+ log_error("--chunksize is only available with snapshots or pools.");
return 0;
}
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 47459ec..8e45cc1 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -1033,6 +1033,12 @@ static int _lvcreate_params(struct lvcreate_params *lp,
lp->wipe_signatures = 0;
}
+ if (arg_count(cmd, chunksize_ARG) &&
+ (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
+ log_error("Negative chunk size is invalid.");
+ return 0;
+ }
+
if (!_lvcreate_name_params(lp, cmd, &argc, &argv) ||
!_read_size_params(lp, lcp, cmd) ||
!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size) ||
@@ -1047,10 +1053,6 @@ static int _lvcreate_params(struct lvcreate_params *lp,
return_0;
if (lp->snapshot && (lp->extents || lcp->size)) {
- if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative chunk size is invalid.");
- return 0;
- }
lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
(lp->chunk_size & (lp->chunk_size - 1))) {
@@ -1063,7 +1065,7 @@ static int _lvcreate_params(struct lvcreate_params *lp,
if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
return_0;
} else if (!lp->create_pool && arg_count(cmd, chunksize_ARG)) {
- log_error("--chunksize is only available with snapshots and thin pools.");
+ log_error("--chunksize is only available with snapshots and pools.");
return 0;
}
diff --git a/tools/toollib.c b/tools/toollib.c
index 7cd6e60..b4e02d6 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1688,10 +1688,6 @@ int get_pool_params(struct cmd_context *cmd,
}
if (arg_count(cmd, chunksize_ARG)) {
- if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative chunk size is invalid.");
- return 0;
- }
*passed_args |= PASS_ARG_CHUNK_SIZE;
*chunk_size = arg_uint_value(cmd, chunksize_ARG, cache_pool ?
DM_CACHE_MIN_DATA_BLOCK_SIZE :
9 years, 8 months
master - cleanup: reorder code
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9955204e0d9d8d...
Commit: 9955204e0d9d8d50c19564d475ece03995a6e837
Parent: de1ee0bc52255987f3b21819a55c0ef9ddf261bb
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:24:35 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:21 2014 +0200
cleanup: reorder code
Simplify code.
---
lib/metadata/thin_manip.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 33ab31c..28b6bbf 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -474,15 +474,15 @@ int update_thin_pool_params(struct volume_group *vg, unsigned attr,
}
if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) {
+ *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Maximum supported pool metadata size is %s.",
- display_size(cmd, 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE));
- *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
+ display_size(cmd, *pool_metadata_size));
} else if (*pool_metadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) {
+ *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE;
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Minimum supported pool metadata size is %s.",
- display_size(cmd, 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE));
- *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE;
+ display_size(cmd, *pool_metadata_size));
}
log_verbose("Setting pool metadata size to %s.",
9 years, 8 months
master - cleanup: move merge option
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=de1ee0bc522559...
Commit: de1ee0bc52255987f3b21819a55c0ef9ddf261bb
Parent: d5d883d91ba132bd601fb27d44191d3a9c9f64f1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jul 9 17:22:16 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:21 2014 +0200
cleanup: move merge option
Put long --merge option into section with long options.
---
tools/args.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/args.h b/tools/args.h
index 9632478..dc467d2 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -59,6 +59,7 @@ arg(trackchanges_ARG, '\0', "trackchanges", NULL, 0)
arg(replace_ARG, '\0', "replace", string_arg, ARG_GROUPABLE)
arg(repair_ARG, '\0', "repair", NULL, 0)
arg(use_policies_ARG, '\0', "use-policies", NULL, 0)
+arg(merge_ARG, '\0', "merge", NULL, 0)
arg(monitor_ARG, '\0', "monitor", yes_no_arg, 0)
arg(config_ARG, '\0', "config", string_arg, 0)
arg(trustcache_ARG, '\0', "trustcache", NULL, 0)
@@ -152,7 +153,6 @@ arg(list_ARG, 'l', "list", NULL, 0)
arg(size_ARG, 'L', "size", size_mb_arg, 0)
arg(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign, 0)
arg(persistent_ARG, 'M', "persistent", yes_no_arg, 0)
-arg(merge_ARG, '\0', "merge", NULL, 0)
arg(major_ARG, 'j', "major", int_arg, ARG_GROUPABLE)
arg(setactivationskip_ARG, 'k', "setactivationskip", yes_no_arg, 0)
arg(ignoreactivationskip_ARG, 'K', "ignoreactivationskip", NULL, 0)
9 years, 8 months
master - cleanup: indent changes
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d5d883d91ba132...
Commit: d5d883d91ba132bd601fb27d44191d3a9c9f64f1
Parent: f7d661406196568abce68abb66a45b27177b4379
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 12:25:18 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:32:21 2014 +0200
cleanup: indent changes
---
tools/lvconvert.c | 34 +++++++++++++++++-----------------
tools/toollib.c | 4 ++--
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 2892d00..95ca245 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -553,9 +553,9 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
}
/*
- * --regionsize is only valid if converting an LV into a mirror.
- * Checked when we know the state of the LV being converted.
- */
+ * --regionsize is only valid if converting an LV into a mirror.
+ * Checked when we know the state of the LV being converted.
+ */
if (arg_count(cmd, regionsize_ARG)) {
if (arg_sign_value(cmd, regionsize_ARG, SIGN_NONE) ==
@@ -715,7 +715,7 @@ static int _finish_lvconvert_mirror(struct cmd_context *cmd,
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
- if (!(_reload_lv(cmd, vg, lv)))
+ if (!_reload_lv(cmd, vg, lv))
return_0;
log_print_unless_silent("Logical volume %s converted.", lv->name);
@@ -1026,7 +1026,7 @@ static struct dm_list *_failed_pv_list(struct volume_group *vg)
if (!is_missing_pv(pvl->pv))
continue;
- /*
+ /*
* Finally, --repair will remove empty PVs.
* But we only want remove these which are output of repair,
* Do not count these which are already empty here.
@@ -1992,20 +1992,20 @@ static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volu
return ECMD_FAILED;
}
- if (lv_info(cmd, cow, 0, &info, 1, 0)) {
- if (!lv_check_not_in_use(cmd, cow, &info))
+ if (lv_info(cmd, cow, 0, &info, 1, 0)) {
+ if (!lv_check_not_in_use(cmd, cow, &info))
return_ECMD_FAILED;
- if ((lp->force == PROMPT) &&
- lv_is_visible(cow) &&
- lv_is_active(cow)) {
- if (yes_no_prompt("Do you really want to split off active "
- "logical volume %s? [y/n]: ", cow->name) == 'n') {
- log_error("Logical volume %s not split.", cow->name);
- return ECMD_FAILED;
- }
- }
- }
+ if ((lp->force == PROMPT) &&
+ lv_is_visible(cow) &&
+ lv_is_active(cow)) {
+ if (yes_no_prompt("Do you really want to split off active "
+ "logical volume %s? [y/n]: ", cow->name) == 'n') {
+ log_error("Logical volume %s not split.", cow->name);
+ return ECMD_FAILED;
+ }
+ }
+ }
if (!archive(vg))
return_ECMD_FAILED;
diff --git a/tools/toollib.c b/tools/toollib.c
index 34db90c..7cd6e60 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -106,7 +106,7 @@ int become_daemon(struct cmd_context *cmd, int skip_lvm)
* Strip dev_dir if present
*/
const char *skip_dev_dir(struct cmd_context *cmd, const char *vg_name,
- unsigned *dev_dir_found)
+ unsigned *dev_dir_found)
{
const char *dmdir = dm_dir();
size_t dmdir_len = strlen(dmdir), vglv_sz;
@@ -1773,7 +1773,7 @@ int get_stripe_params(struct cmd_context *cmd, uint32_t *stripes, uint32_t *stri
return 0;
}
- if(arg_uint64_value(cmd, stripesize_ARG, 0) > STRIPE_SIZE_LIMIT * 2) {
+ if (arg_uint64_value(cmd, stripesize_ARG, 0) > STRIPE_SIZE_LIMIT * 2) {
log_error("Stripe size cannot be larger than %s",
display_size(cmd, (uint64_t) STRIPE_SIZE_LIMIT));
return 0;
9 years, 8 months
master - cache: warn about metadata size limits
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f7d66140619656...
Commit: f7d661406196568abce68abb66a45b27177b4379
Parent: 04b8e55f2a2a96d2ffbd124fe3c0fc7c452cfb26
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 12:12:51 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 13:31:19 2014 +0200
cache: warn about metadata size limits
Cache pools are similar as with thin pools.
Add (needs %s) - since cache has currently
a bit strange need for extra few kb over
our default 4M extent size so make it more obvious.
---
lib/metadata/cache_manip.c | 17 ++++++++++-------
1 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index 6a0f0f6..e220dd9 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -60,15 +60,18 @@ int update_cache_pool_params(struct volume_group *vg, unsigned attr,
if (!*pool_metadata_size)
*pool_metadata_size = min_meta_size;
- if (*pool_metadata_size < min_meta_size) {
- *pool_metadata_size = min_meta_size;
- log_print("Increasing metadata device size to %"
- PRIu64 " sectors", *pool_metadata_size);
- }
if (*pool_metadata_size > (2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE)) {
*pool_metadata_size = 2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE;
- log_print("Reducing metadata device size to %" PRIu64 " sectors",
- *pool_metadata_size);
+ if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
+ log_warn("WARNING: Maximum supported pool metadata size is %s.",
+ display_size(vg->cmd, *pool_metadata_size));
+ } else if (*pool_metadata_size < min_meta_size) {
+ if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
+ log_warn("WARNING: Minimum supported pool metadata size is %s "
+ "(needs extra %s).",
+ display_size(vg->cmd, min_meta_size),
+ display_size(vg->cmd, min_meta_size - *pool_metadata_size));
+ *pool_metadata_size = min_meta_size;
}
return 1;
9 years, 8 months
master - lvconvert: relocate mirror tests
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=04b8e55f2a2a96...
Commit: 04b8e55f2a2a96d2ffbd124fe3c0fc7c452cfb26
Parent: 1931d1e58e1b7af8251d96ed84694c3ba5c7352e
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 10 22:02:54 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:57:45 2014 +0200
lvconvert: relocate mirror tests
---
tools/lvconvert.c | 25 ++++++++++++-------------
1 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 264b86c..2892d00 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -236,6 +236,18 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
if (!_check_conversion_type(cmd, type_str))
return_0;
+ if (arg_count(cmd, repair_ARG) &&
+ !arg_is_only_set(cmd, "cannot be used with --repair",
+ repair_ARG,
+ stripes_long_ARG, stripesize_ARG,
+ -1))
+ return_0;
+
+ if (arg_is_set(cmd, mirrorlog_ARG) && arg_is_set(cmd, corelog_ARG)) {
+ log_error("--mirrorlog and --corelog are incompatible.");
+ return 0;
+ }
+
if (arg_count(cmd, splitsnapshot_ARG))
lp->splitsnapshot = 1;
@@ -1273,19 +1285,6 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
return 1;
}
- if ((arg_count(cmd, mirrors_ARG) && repair) ||
- (arg_count(cmd, mirrorlog_ARG) && repair) ||
- (arg_count(cmd, corelog_ARG) && repair)) {
- log_error("--repair cannot be used with --mirrors, --mirrorlog,"
- " or --corelog");
- return 0;
- }
-
- if (arg_count(cmd, mirrorlog_ARG) && arg_count(cmd, corelog_ARG)) {
- log_error("--mirrorlog and --corelog are incompatible");
- return 0;
- }
-
/*
* Adjusting mimage count?
*/
9 years, 8 months
master - tools: arg_is_any_set and arg_is_only_set
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1931d1e58e1b7a...
Commit: 1931d1e58e1b7af8251d96ed84694c3ba5c7352e
Parent: c0c1ada88eef8e112515f5415dc4dd89b4191214
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jul 10 22:52:53 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:57:45 2014 +0200
tools: arg_is_any_set and arg_is_only_set
Helpful functions to more easily detect conflicting
set of options.
---
tools/lvmcmdline.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/tools.h | 2 +
2 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index fc51c4a..be7844b 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -68,6 +68,61 @@ unsigned arg_is_set(const struct cmd_context *cmd, int a)
return arg_count(cmd, a) ? 1 : 0;
}
+int arg_is_any_set(const struct cmd_context *cmd, const char *err, ...)
+{
+ int arg;
+ va_list ap;
+
+ va_start(ap, err);
+ while ((arg = va_arg(ap, int)) != -1 && !arg_count(cmd, arg))
+ /* empty */;
+ va_end(ap);
+
+ if (arg != -1) {
+ log_error("%s %s.", arg_long_option_name(arg), err);
+ return 0;
+ }
+
+ return 1;
+}
+
+int arg_is_only_set(const struct cmd_context *cmd, const char *err, ...)
+{
+ int i, arg;
+ va_list ap;
+
+ for (i = 0; i < ARG_COUNT; ++i) {
+ switch (i) {
+ /* skip common options */
+ case commandprofile_ARG:
+ case config_ARG:
+ case debug_ARG:
+ case driverloaded_ARG:
+ case help2_ARG:
+ case help_ARG:
+ case profile_ARG:
+ case quiet_ARG:
+ case verbose_ARG:
+ case version_ARG:
+ case yes_ARG:
+ continue;
+ }
+ if (!arg_count(cmd, i))
+ continue; /* unset */
+ va_start(ap, err);
+ while (((arg = va_arg(ap, int)) != -1) && (arg != i))
+ /* empty */;
+ va_end(ap);
+
+ if (arg != i) {
+ log_error("Option %s %s.", arg_long_option_name(i), err);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
unsigned grouped_arg_is_set(const struct arg_values *av, int a)
{
return grouped_arg_count(av, a) ? 1 : 0;
diff --git a/tools/tools.h b/tools/tools.h
index 2b09f37..a92845a 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -144,6 +144,8 @@ int major_minor_valid(const struct cmd_context * cmd, const struct format_type *
/* we use the enums to access the switches */
unsigned arg_count(const struct cmd_context *cmd, int a);
unsigned arg_is_set(const struct cmd_context *cmd, int a);
+int arg_is_any_set(const struct cmd_context *cmd, const char *err, ...);
+int arg_is_only_set(const struct cmd_context *cmd, const char *err, ...);
const char *arg_long_option_name(int a);
const char *arg_value(struct cmd_context *cmd, int a);
const char *arg_str_value(struct cmd_context *cmd, int a, const char *def);
9 years, 8 months