mirror of
git://sourceware.org/git/lvm2.git
synced 2025-09-23 17:44:22 +03:00
Compare commits
59 Commits
dev-bmr-dm
...
v2_02_161
Author | SHA1 | Date | |
---|---|---|---|
|
3d717b52c1 | ||
|
c425cdd115 | ||
|
081e569e14 | ||
|
e96d1ad3ef | ||
|
4de7a843eb | ||
|
d2bb19e883 | ||
|
a57bf37cdb | ||
|
12925d8b70 | ||
|
5af311ddd8 | ||
|
07be2b864f | ||
|
4e1bf7acd3 | ||
|
4661c6b6fb | ||
|
bbf574ab90 | ||
|
0b773eecd9 | ||
|
07587c2699 | ||
|
deb6f6a06c | ||
|
e1112227d1 | ||
|
3928c96a37 | ||
|
26f3b321f9 | ||
|
df5021a201 | ||
|
9c27573493 | ||
|
c77c59f3d9 | ||
|
dcbcc65dc2 | ||
|
c32f96f277 | ||
|
4ca55192e0 | ||
|
d5be748341 | ||
|
957480f4b9 | ||
|
1891fa8272 | ||
|
80394ae7cd | ||
|
5254971418 | ||
|
fd53d86eea | ||
|
42e76a1920 | ||
|
9f7e8f22dc | ||
|
c526c327d7 | ||
|
06a9dab730 | ||
|
6336b5dedf | ||
|
8756297a8d | ||
|
34c55d98ee | ||
|
309bdfa224 | ||
|
61cb58e549 | ||
|
feb69966d4 | ||
|
74565e41fc | ||
|
6a77a40501 | ||
|
2d1f03b616 | ||
|
58bfea6a6e | ||
|
7771793a56 | ||
|
3951ca9320 | ||
|
39921284a0 | ||
|
5cd39f1dc4 | ||
|
17cbcc85bd | ||
|
008c57714a | ||
|
6cb0c7bb5c | ||
|
bd1f4987eb | ||
|
db63587ce2 | ||
|
bce1bc4ca3 | ||
|
4bb57341bd | ||
|
c3caf4b80b | ||
|
db73d756e9 | ||
|
ae9cffba52 |
@@ -1 +1 @@
|
||||
1.02.131-git (2016-07-06)
|
||||
1.02.131-git (2016-07-15)
|
||||
|
10
WHATS_NEW
10
WHATS_NEW
@@ -1,5 +1,11 @@
|
||||
Version 2.02.161 -
|
||||
================================
|
||||
Version 2.02.161 - 15th July 2016
|
||||
=================================
|
||||
Prohibit some lvchange/lvresize that were failing on raid0 volumes.
|
||||
Fix segfaults in complex vgsplits. (2.02.159)
|
||||
Reformat unwieldy lvconvert man page.
|
||||
Allow --force to be passed through to pvcreate from vgcreate. (2.02.144)
|
||||
Fix lvresize of filesystem when LV has already right size (2.02.141)
|
||||
New LVM_LOG_FILE_MAX_LINES env var to limit max size of created logs.
|
||||
|
||||
Version 2.02.160 - 6th July 2016
|
||||
================================
|
||||
|
14
WHATS_NEW_DM
14
WHATS_NEW_DM
@@ -1,5 +1,15 @@
|
||||
Version 1.02.131 -
|
||||
================================
|
||||
Version 1.02.131 - 15th July 2016
|
||||
=================================
|
||||
Disable queueing on mpath devs in blk-availability systemd service/initscript.
|
||||
Add new -m|--mpathoption disablequeueing to blkdeactivate.
|
||||
Automatically group regions with 'create --segments' unless --nogroup.
|
||||
Fix resource leak when deleting the first member of a group.
|
||||
Allow --bounds with 'create --filemap' for dmstats.
|
||||
Enable creation of filemap regions with histograms.
|
||||
Enable histogram aggregation for regions with more than one area.
|
||||
Enable histogram aggregation for groups of regions.
|
||||
Add a --filemap option to 'dmstats create' to allow mapping of files.
|
||||
Add dm_stats_create_regions_from_fd() to map file extents to regions.
|
||||
|
||||
Version 1.02.130 - 6th July 2016
|
||||
================================
|
||||
|
2
configure
vendored
2
configure
vendored
@@ -5875,7 +5875,7 @@ fi
|
||||
done
|
||||
|
||||
|
||||
for ac_header in termios.h sys/statvfs.h sys/timerfd.h
|
||||
for ac_header in termios.h sys/statvfs.h sys/timerfd.h linux/magic.h linux/fiemap.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
|
||||
|
@@ -103,7 +103,7 @@ AC_CHECK_HEADERS([assert.h ctype.h dirent.h errno.h fcntl.h float.h \
|
||||
sys/time.h sys/types.h sys/utsname.h sys/wait.h time.h \
|
||||
unistd.h], , [AC_MSG_ERROR(bailing out)])
|
||||
|
||||
AC_CHECK_HEADERS(termios.h sys/statvfs.h sys/timerfd.h)
|
||||
AC_CHECK_HEADERS(termios.h sys/statvfs.h sys/timerfd.h linux/magic.h linux/fiemap.h)
|
||||
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
|
@@ -861,7 +861,7 @@ static int remove_metadata(lvmetad_state *s, const char *vgid, int update_pvids)
|
||||
|
||||
/* update_pvid_to_vgid will clear/free the pvid_to_vgid hash */
|
||||
if (update_pvids && meta_lookup)
|
||||
_update_pvid_to_vgid(s, meta_lookup, "#orphan", 0);
|
||||
(void) _update_pvid_to_vgid(s, meta_lookup, "#orphan", 0);
|
||||
|
||||
/* free the unmapped data */
|
||||
|
||||
|
@@ -264,9 +264,15 @@
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the <linux/fiemap.h> header file. */
|
||||
#undef HAVE_LINUX_FIEMAP_H
|
||||
|
||||
/* Define to 1 if you have the <linux/fs.h> header file. */
|
||||
#undef HAVE_LINUX_FS_H
|
||||
|
||||
/* Define to 1 if you have the <linux/magic.h> header file. */
|
||||
#undef HAVE_LINUX_MAGIC_H
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
|
2
lib/cache/lvmetad.c
vendored
2
lib/cache/lvmetad.c
vendored
@@ -1784,7 +1784,7 @@ static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct vo
|
||||
struct dm_list pvs_scan;
|
||||
struct dm_list pvs_drop;
|
||||
struct dm_list pvs_new;
|
||||
struct lvmcache_info *info;
|
||||
struct lvmcache_info *info = NULL;
|
||||
struct format_instance *fid;
|
||||
struct format_instance_ctx fic = { .type = 0 };
|
||||
struct _lvmetad_pvscan_baton baton;
|
||||
|
@@ -31,6 +31,8 @@ static struct dm_str_list _log_dev_alias;
|
||||
|
||||
static int _syslog = 0;
|
||||
static int _log_to_file = 0;
|
||||
static uint64_t _log_file_max_lines = 0;
|
||||
static uint64_t _log_file_lines = 0;
|
||||
static int _log_direct = 0;
|
||||
static int _log_while_suspended = 0;
|
||||
static int _indent = 1;
|
||||
@@ -111,6 +113,14 @@ void init_log_file(const char *log_file, int append)
|
||||
|
||||
if (st && fclose(st))
|
||||
log_sys_debug("fclose", statfile);
|
||||
|
||||
if ((env = getenv("LVM_LOG_FILE_MAX_LINES"))) {
|
||||
if (sscanf(env, FMTu64, &_log_file_max_lines) != 1) {
|
||||
log_warn("WARNING: Ignoring invalid LVM_LOG_MAX_LINES envvar \"%s\".", env);
|
||||
_log_file_max_lines = 0;
|
||||
}
|
||||
_log_file_lines = 0;
|
||||
}
|
||||
}
|
||||
|
||||
no_epoch:
|
||||
@@ -487,6 +497,9 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
|
||||
|
||||
fputc('\n', _log_file);
|
||||
fflush(_log_file);
|
||||
|
||||
if (_log_file_max_lines && ++_log_file_lines >= _log_file_max_lines)
|
||||
fatal_internal_error = 1;
|
||||
}
|
||||
|
||||
if (_syslog && (_log_while_suspended || !critical_section())) {
|
||||
|
@@ -1140,9 +1140,9 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
|
||||
else if (lv_is_cache_type(lv))
|
||||
repstr[0] = 'C';
|
||||
else if (lv_is_raid(lv))
|
||||
repstr[0] = (lv->status & LV_NOTSYNCED) ? 'R' : 'r';
|
||||
repstr[0] = (lv_is_not_synced(lv)) ? 'R' : 'r';
|
||||
else if (lv_is_mirror(lv))
|
||||
repstr[0] = (lv->status & LV_NOTSYNCED) ? 'M' : 'm';
|
||||
repstr[0] = (lv_is_not_synced(lv)) ? 'M' : 'm';
|
||||
else if (lv_is_thin_volume(lv))
|
||||
repstr[0] = lv_is_merging_origin(lv) ?
|
||||
'O' : (lv_is_merging_thin_snapshot(lv) ? 'S' : 'V');
|
||||
|
@@ -3921,14 +3921,16 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
|
||||
|
||||
/*
|
||||
* The MD bitmap is limited to being able to track 2^21 regions.
|
||||
* The region_size must be adjusted to meet that criteria.
|
||||
* The region_size must be adjusted to meet that criteria
|
||||
* unless raid0/raid0_meta, which doesn't have a bitmap.
|
||||
*/
|
||||
while (seg_is_raid(seg) && (seg->region_size < (lv->size / (1 << 21)))) {
|
||||
seg->region_size *= 2;
|
||||
log_very_verbose("Adjusting RAID region_size from %uS to %uS"
|
||||
" to support large LV size",
|
||||
seg->region_size/2, seg->region_size);
|
||||
}
|
||||
if (seg_is_raid(seg) && !seg_is_any_raid0(seg))
|
||||
while (seg->region_size < (lv->size / (1 << 21))) {
|
||||
seg->region_size *= 2;
|
||||
log_very_verbose("Adjusting RAID region_size from %uS to %uS"
|
||||
" to support large LV size",
|
||||
seg->region_size/2, seg->region_size);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -4025,7 +4027,7 @@ int lv_extend(struct logical_volume *lv,
|
||||
*/
|
||||
if (old_extents &&
|
||||
segtype_is_mirrored(segtype) &&
|
||||
(lv->status & LV_NOTSYNCED)) {
|
||||
(lv_is_not_synced(lv))) {
|
||||
dm_percent_t sync_percent = DM_PERCENT_INVALID;
|
||||
|
||||
if (!lv_is_active_locally(lv)) {
|
||||
@@ -4987,14 +4989,14 @@ static int _lvresize_adjust_extents(struct logical_volume *lv,
|
||||
/* At this point, lp->extents should hold the correct NEW logical size required. */
|
||||
|
||||
if (!lp->extents) {
|
||||
log_error("New size of 0 not permitted");
|
||||
log_error("New size of 0 not permitted.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lp->extents == existing_logical_extents) {
|
||||
if (!lp->resizefs) {
|
||||
log_error("New size (%d extents) matches existing size "
|
||||
"(%d extents)", lp->extents, existing_logical_extents);
|
||||
log_error("New size (%d extents) matches existing size (%d extents).",
|
||||
lp->extents, existing_logical_extents);
|
||||
return 0;
|
||||
}
|
||||
lp->resize = LV_EXTEND; /* lets pretend zero size extension */
|
||||
@@ -5003,7 +5005,7 @@ static int _lvresize_adjust_extents(struct logical_volume *lv,
|
||||
/* Perform any rounding to produce complete stripes. */
|
||||
if (lp->stripes > 1) {
|
||||
if (lp->stripe_size < STRIPE_SIZE_MIN) {
|
||||
log_error("Invalid stripe size %s",
|
||||
log_error("Invalid stripe size %s.",
|
||||
display_size(cmd, (uint64_t) lp->stripe_size));
|
||||
return 0;
|
||||
}
|
||||
@@ -5022,7 +5024,7 @@ static int _lvresize_adjust_extents(struct logical_volume *lv,
|
||||
(vg->free_count >= (lp->extents - existing_logical_extents - size_rest +
|
||||
stripes_extents)))) {
|
||||
log_print_unless_silent("Rounding size (%d extents) up to stripe "
|
||||
"boundary size for segment (%d extents)",
|
||||
"boundary size for segment (%d extents).",
|
||||
lp->extents,
|
||||
lp->extents - size_rest + stripes_extents);
|
||||
lp->extents = lp->extents - size_rest + stripes_extents;
|
||||
@@ -5086,7 +5088,7 @@ static int _lvresize_check_type(const struct logical_volume *lv,
|
||||
|
||||
if (lv_is_active(lv)) {
|
||||
log_error("Snapshot origin volumes can be resized "
|
||||
"only while inactive: try lvchange -an");
|
||||
"only while inactive: try lvchange -an.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -5128,38 +5130,8 @@ static int _lvresize_volume(struct logical_volume *lv,
|
||||
struct volume_group *vg = lv->vg;
|
||||
struct cmd_context *cmd = vg->cmd;
|
||||
uint32_t old_extents;
|
||||
int status;
|
||||
alloc_policy_t alloc = lp->alloc ? : lv->alloc;
|
||||
|
||||
if ((lp->resize == LV_REDUCE) && (pvh != &vg->pvs))
|
||||
log_print_unless_silent("Ignoring PVs on command line when reducing.");
|
||||
|
||||
/* Request confirmation before operations that are often mistakes. */
|
||||
if ((lp->resizefs || (lp->resize == LV_REDUCE)) &&
|
||||
!_request_confirmation(lv, lp))
|
||||
return_0;
|
||||
|
||||
if (lp->resizefs) {
|
||||
if (!lp->nofsck &&
|
||||
!_fsadm_cmd(FSADM_CMD_CHECK, lv, 0, lp->force, &status)) {
|
||||
if (status != FSADM_CHECK_FAILS_FOR_MOUNTED) {
|
||||
log_error("Filesystem check failed.");
|
||||
return 0;
|
||||
}
|
||||
/* some filesystems support online resize */
|
||||
}
|
||||
|
||||
/* FIXME forks here */
|
||||
if ((lp->resize == LV_REDUCE) &&
|
||||
!_fsadm_cmd(FSADM_CMD_RESIZE, lv, lp->extents, lp->force, NULL)) {
|
||||
log_error("Filesystem resize failed.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!archive(vg))
|
||||
return_0;
|
||||
|
||||
old_extents = lv->le_count;
|
||||
log_verbose("%sing logical volume %s to %s%s",
|
||||
(lp->resize == LV_REDUCE) ? "Reduc" : "Extend",
|
||||
@@ -5185,11 +5157,13 @@ static int _lvresize_volume(struct logical_volume *lv,
|
||||
log_print_unless_silent("Size of logical volume %s unchanged from %s (%" PRIu32 " extents).",
|
||||
display_lvname(lv),
|
||||
display_size(cmd, (uint64_t) old_extents * vg->extent_size), old_extents);
|
||||
else
|
||||
else {
|
||||
lp->size_changed = 1;
|
||||
log_print_unless_silent("Size of logical volume %s changed from %s (%" PRIu32 " extents) to %s (%" PRIu32 " extents).",
|
||||
display_lvname(lv),
|
||||
display_size(cmd, (uint64_t) old_extents * vg->extent_size), old_extents,
|
||||
display_size(cmd, (uint64_t) lv->le_count * vg->extent_size), lv->le_count);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -5209,10 +5183,10 @@ static int _lvresize_prepare(struct logical_volume **lv,
|
||||
else if (lp->extents && !_lvresize_extents_from_percent(*lv, lp, pvh))
|
||||
return_0;
|
||||
|
||||
if (lp->extents && !_lvresize_adjust_extents(*lv, lp, pvh))
|
||||
if (!_lvresize_adjust_extents(*lv, lp, pvh))
|
||||
return_0;
|
||||
|
||||
if (lp->extents && !_lvresize_check_type(*lv, lp))
|
||||
if (!_lvresize_check_type(*lv, lp))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
@@ -5244,6 +5218,7 @@ int lv_resize(struct logical_volume *lv,
|
||||
struct lvresize_params aux_lp;
|
||||
int activated = 0;
|
||||
int ret = 0;
|
||||
int status;
|
||||
|
||||
if (!_lvresize_check(lv, lp))
|
||||
return_0;
|
||||
@@ -5269,8 +5244,8 @@ int lv_resize(struct logical_volume *lv,
|
||||
}
|
||||
} else if (lp->poolmetadata_size) {
|
||||
if (!lp->extents && !lp->size) {
|
||||
/* When only --poolmetadatasize give and not --size
|
||||
* swith directly to resize metadata LV */
|
||||
/* When only --poolmetadatasize given and not --size
|
||||
* switch directly to resize metadata LV */
|
||||
lv = first_seg(lv)->metadata_lv;
|
||||
lp->size = lp->poolmetadata_size;
|
||||
lp->sign = lp->poolmetadata_sign;
|
||||
@@ -5285,9 +5260,44 @@ int lv_resize(struct logical_volume *lv,
|
||||
if (aux_lv && !_lvresize_prepare(&aux_lv, &aux_lp, pvh))
|
||||
return_0;
|
||||
|
||||
/* Always should have lp->size or lp->extents */
|
||||
if (!_lvresize_prepare(&lv, lp, pvh))
|
||||
return_0;
|
||||
|
||||
if (((lp->resize == LV_REDUCE) ||
|
||||
(aux_lv && aux_lp.resize == LV_REDUCE)) &&
|
||||
(pvh != &vg->pvs))
|
||||
log_print_unless_silent("Ignoring PVs on command line when reducing.");
|
||||
|
||||
/* Request confirmation before operations that are often mistakes. */
|
||||
/* aux_lv never resize fs */
|
||||
if ((lp->resizefs || (lp->resize == LV_REDUCE)) &&
|
||||
!_request_confirmation(lv, lp))
|
||||
return_0;
|
||||
|
||||
if (lp->resizefs) {
|
||||
if (!lp->nofsck &&
|
||||
!_fsadm_cmd(FSADM_CMD_CHECK, lv, 0, lp->force, &status)) {
|
||||
if (status != FSADM_CHECK_FAILS_FOR_MOUNTED) {
|
||||
log_error("Filesystem check failed.");
|
||||
return 0;
|
||||
}
|
||||
/* some filesystems support online resize */
|
||||
}
|
||||
|
||||
/* FIXME forks here */
|
||||
if ((lp->resize == LV_REDUCE) &&
|
||||
!_fsadm_cmd(FSADM_CMD_RESIZE, lv, lp->extents, lp->force, NULL)) {
|
||||
log_error("Filesystem resize failed.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lp->extents && (!aux_lv || !aux_lp.extents)) {
|
||||
lp->extents = lv->le_count;
|
||||
goto out; /* Nothing to do */
|
||||
}
|
||||
|
||||
if (lv_is_thin_pool(lock_lv) && /* Lock holder is thin-pool */
|
||||
!lv_is_active(lock_lv)) {
|
||||
|
||||
@@ -5320,12 +5330,15 @@ int lv_resize(struct logical_volume *lv,
|
||||
if (!lockd_lv(cmd, lock_lv, "ex", 0))
|
||||
return_0;
|
||||
|
||||
if (!archive(vg))
|
||||
return_0;
|
||||
|
||||
if (aux_lv) {
|
||||
if (!_lvresize_volume(aux_lv, &aux_lp, pvh))
|
||||
goto_bad;
|
||||
|
||||
/* store vg on disk(s) */
|
||||
if (!lv_update_and_reload(lock_lv))
|
||||
if (aux_lp.size_changed && !lv_update_and_reload(lock_lv))
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
@@ -5333,6 +5346,9 @@ int lv_resize(struct logical_volume *lv,
|
||||
goto_bad;
|
||||
|
||||
/* store vg on disk(s) */
|
||||
if (!lp->size_changed)
|
||||
goto out; /* No table reload needed */
|
||||
|
||||
if (!lv_update_and_reload(lock_lv))
|
||||
goto_bad;
|
||||
|
||||
@@ -5347,7 +5363,7 @@ int lv_resize(struct logical_volume *lv,
|
||||
|
||||
backup(vg);
|
||||
}
|
||||
|
||||
out:
|
||||
log_print_unless_silent("Logical volume %s successfully resized.",
|
||||
display_lvname(lv));
|
||||
|
||||
|
@@ -218,6 +218,7 @@
|
||||
#define lv_is_mirror_log(lv) (((lv)->status & MIRROR_LOG) ? 1 : 0)
|
||||
#define lv_is_mirror(lv) (((lv)->status & MIRROR) ? 1 : 0)
|
||||
#define lv_is_mirror_type(lv) (((lv)->status & (MIRROR | MIRROR_LOG | MIRROR_IMAGE)) ? 1 : 0)
|
||||
#define lv_is_not_synced(lv) (((lv)->status & LV_NOTSYNCED) ? 1 : 0)
|
||||
|
||||
#define lv_is_pending_delete(lv) (((lv)->status & LV_PENDING_DELETE) ? 1 : 0)
|
||||
#define lv_is_error_when_full(lv) (((lv)->status & LV_ERROR_WHEN_FULL) ? 1 : 0)
|
||||
@@ -637,6 +638,7 @@ struct lvresize_params {
|
||||
|
||||
int approx_alloc;
|
||||
int extents_are_pes; /* Is 'extents' counting PEs or LEs? */
|
||||
int size_changed; /* Was there actually a size change */
|
||||
};
|
||||
|
||||
void pvcreate_params_set_defaults(struct pvcreate_params *pp);
|
||||
|
@@ -4641,7 +4641,8 @@ static int _check_devs_used_correspond_with_lv(struct dm_pool *mem, struct dm_li
|
||||
dev = dl->dev;
|
||||
if (!(dev->flags & DEV_ASSUMED_FOR_LV)) {
|
||||
if (!found_inconsistent) {
|
||||
dm_pool_begin_object(mem, 32);
|
||||
if (!dm_pool_begin_object(mem, 32))
|
||||
return_0;
|
||||
found_inconsistent = 1;
|
||||
} else {
|
||||
if (!dm_pool_grow_object(mem, DEV_LIST_DELIM, sizeof(DEV_LIST_DELIM) - 1))
|
||||
@@ -4674,7 +4675,8 @@ static int _check_devs_used_correspond_with_lv(struct dm_pool *mem, struct dm_li
|
||||
}
|
||||
if (!(dev->flags & DEV_USED_FOR_LV)) {
|
||||
if (!found_inconsistent) {
|
||||
dm_pool_begin_object(mem, 32);
|
||||
if (!dm_pool_begin_object(mem, 32))
|
||||
return_0;
|
||||
found_inconsistent = 1;
|
||||
} else {
|
||||
if (!dm_pool_grow_object(mem, DEV_LIST_DELIM, sizeof(DEV_LIST_DELIM) - 1))
|
||||
|
@@ -590,7 +590,7 @@ static int _raid_add_images(struct logical_volume *lv,
|
||||
struct lv_list *lvl;
|
||||
struct lv_segment_area *new_areas;
|
||||
|
||||
if (lv->status & LV_NOTSYNCED) {
|
||||
if (lv_is_not_synced(lv)) {
|
||||
log_error("Can't add image to out-of-sync RAID LV:"
|
||||
" use 'lvchange --resync' first.");
|
||||
return 0;
|
||||
@@ -1726,7 +1726,7 @@ static int _raid0_to_striped_retrieve_segments_and_lvs(struct logical_volume *lv
|
||||
struct dm_list *removal_lvs)
|
||||
{
|
||||
uint32_t s, area_le, area_len, le;
|
||||
struct lv_segment *data_seg, *seg, *seg_to;
|
||||
struct lv_segment *data_seg = NULL, *seg, *seg_to;
|
||||
struct dm_list new_segments;
|
||||
|
||||
seg = first_seg(lv);
|
||||
@@ -3090,8 +3090,11 @@ int lv_raid_remove_missing(struct logical_volume *lv)
|
||||
(!seg->meta_areas || !seg_metalv(seg, s) || !lv_is_partial(seg_metalv(seg, s))))
|
||||
continue;
|
||||
|
||||
log_debug("Replacing %s and %s segments with error target",
|
||||
seg_lv(seg, s)->name, seg_metalv(seg, s)->name);
|
||||
log_debug("Replacing %s segments with error target",
|
||||
display_lvname(seg_lv(seg, s)));
|
||||
if (seg->meta_areas && seg_metalv(seg, s))
|
||||
log_debug("Replacing %s segments with error target",
|
||||
display_lvname(seg_metalv(seg, s)));
|
||||
if (!replace_lv_with_error_segment(seg_lv(seg, s))) {
|
||||
log_error("Failed to replace %s's extents with error target.",
|
||||
display_lvname(seg_lv(seg, s)));
|
||||
|
@@ -243,3 +243,19 @@ char *build_dm_uuid(struct dm_pool *mem, const struct logical_volume *lv,
|
||||
|
||||
return dlid;
|
||||
}
|
||||
|
||||
char *first_substring(const char *str, ...)
|
||||
{
|
||||
char *substr, *r = NULL;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, str);
|
||||
|
||||
while ((substr = va_arg(ap, char *)))
|
||||
if ((r = strstr(str, substr)))
|
||||
break;
|
||||
|
||||
va_end(ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@@ -49,4 +49,12 @@ void copy_systemid_chars(const char *src, char *dst);
|
||||
int apply_lvname_restrictions(const char *name);
|
||||
int is_reserved_lvname(const char *name);
|
||||
|
||||
/*
|
||||
* Provided with a NULL-terminated argument list of const char *
|
||||
* substrings that might be contained within the string str, use
|
||||
* strstr() to search str for each in turn and return a pointer to the
|
||||
* first match or else NULL.
|
||||
*/
|
||||
char *first_substring(const char *str, ...);
|
||||
|
||||
#endif
|
||||
|
@@ -3161,7 +3161,7 @@ static int _lvinitialimagesync_disp(struct dm_report *rh, struct dm_pool *mem,
|
||||
int initial_image_sync;
|
||||
|
||||
if (lv_is_raid(lv) || lv_is_mirrored(lv))
|
||||
initial_image_sync = (lv->status & LV_NOTSYNCED) == 0;
|
||||
initial_image_sync = !lv_is_not_synced(lv);
|
||||
else
|
||||
initial_image_sync = 0;
|
||||
|
||||
|
@@ -26,7 +26,7 @@ int buffer_append_f(struct buffer *buf, ...);
|
||||
int buffer_append(struct buffer *buf, const char *string);
|
||||
void buffer_init(struct buffer *buf);
|
||||
void buffer_destroy(struct buffer *buf);
|
||||
int buffer_realloc(struct buffer *buf, int required);
|
||||
int buffer_realloc(struct buffer *buf, int needed);
|
||||
|
||||
int buffer_line(const char *line, void *baton);
|
||||
|
||||
|
@@ -78,7 +78,7 @@ daemon_handle daemon_open(daemon_info i);
|
||||
* be ignored even if non-NULL). If the buffer is NULL, the cft is required to
|
||||
* be a valid pointer, and is used to build up the request.
|
||||
*/
|
||||
daemon_reply daemon_send(daemon_handle h, daemon_request r);
|
||||
daemon_reply daemon_send(daemon_handle h, daemon_request rq);
|
||||
|
||||
/*
|
||||
* A simple interface to daemon_send. This function just takes the command id
|
||||
|
@@ -319,7 +319,7 @@ error:
|
||||
goto out;
|
||||
}
|
||||
|
||||
static void remove_lockfile(const char *file)
|
||||
static void _remove_lockfile(const char *file)
|
||||
{
|
||||
if (unlink(file))
|
||||
perror("unlink failed");
|
||||
@@ -418,7 +418,7 @@ end:
|
||||
return res;
|
||||
}
|
||||
|
||||
static response builtin_handler(daemon_state s, client_handle h, request r)
|
||||
static response _builtin_handler(daemon_state s, client_handle h, request r)
|
||||
{
|
||||
const char *rq = daemon_request_str(r, "request", "NONE");
|
||||
response res = { .error = EPROTO };
|
||||
@@ -432,7 +432,7 @@ static response builtin_handler(daemon_state s, client_handle h, request r)
|
||||
return res;
|
||||
}
|
||||
|
||||
static void *client_thread(void *state)
|
||||
static void *_client_thread(void *state)
|
||||
{
|
||||
thread_state *ts = state;
|
||||
request req;
|
||||
@@ -451,7 +451,7 @@ static void *client_thread(void *state)
|
||||
else
|
||||
daemon_log_cft(ts->s.log, DAEMON_LOG_WIRE, "<- ", req.cft->root);
|
||||
|
||||
res = builtin_handler(ts->s, ts->client, req);
|
||||
res = _builtin_handler(ts->s, ts->client, req);
|
||||
|
||||
if (res.error == EPROTO) /* Not a builtin, delegate to the custom handler. */
|
||||
res = ts->s.handler(ts->s, ts->client, req);
|
||||
@@ -512,7 +512,7 @@ static int handle_connect(daemon_state s)
|
||||
ts->s = s;
|
||||
ts->client = client;
|
||||
|
||||
if (pthread_create(&ts->client.thread_id, NULL, client_thread, ts)) {
|
||||
if (pthread_create(&ts->client.thread_id, NULL, _client_thread, ts)) {
|
||||
ERROR(&s, "Failed to create client thread.");
|
||||
return 0;
|
||||
}
|
||||
@@ -520,7 +520,7 @@ static int handle_connect(daemon_state s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void reap(daemon_state s, int waiting)
|
||||
static void _reap(daemon_state s, int waiting)
|
||||
{
|
||||
thread_state *last = s.threads, *ts = last->next;
|
||||
void *rv;
|
||||
@@ -637,7 +637,7 @@ void daemon_start(daemon_state s)
|
||||
handle_connect(s);
|
||||
}
|
||||
|
||||
reap(s, 0);
|
||||
_reap(s, 0);
|
||||
|
||||
if (_shutdown_requested && !s.threads->next)
|
||||
break;
|
||||
@@ -653,13 +653,17 @@ void daemon_start(daemon_state s)
|
||||
}
|
||||
|
||||
INFO(&s, "%s waiting for client threads to finish", s.name);
|
||||
reap(s, 1);
|
||||
_reap(s, 1);
|
||||
out:
|
||||
/* If activated by systemd, do not unlink the socket - systemd takes care of that! */
|
||||
if (!_systemd_activation && s.socket_fd >= 0)
|
||||
if (unlink(s.socket_path))
|
||||
perror("unlink error");
|
||||
|
||||
if (s.socket_fd >= 0)
|
||||
if (close(s.socket_fd))
|
||||
perror("socket close");
|
||||
|
||||
if (s.daemon_fini)
|
||||
if (!s.daemon_fini(&s))
|
||||
failed = 1;
|
||||
@@ -668,7 +672,7 @@ out:
|
||||
|
||||
closelog(); /* FIXME */
|
||||
if (s.pidfile)
|
||||
remove_lockfile(s.pidfile);
|
||||
_remove_lockfile(s.pidfile);
|
||||
if (failed)
|
||||
exit(1);
|
||||
}
|
||||
|
@@ -21,9 +21,18 @@
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/vfs.h> /* fstatfs */
|
||||
#include <linux/fs.h> /* FS_IOC_FIEMAP */
|
||||
#include <linux/fiemap.h> /* fiemap */
|
||||
#include <linux/magic.h> /* BTRFS_SUPER_MAGIC */
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/fs.h> /* FS_IOC_FIEMAP */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_FIEMAP_H
|
||||
#include <linux/fiemap.h> /* fiemap */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_MAGIC_H
|
||||
#include <linux/magic.h> /* BTRFS_SUPER_MAGIC */
|
||||
#endif
|
||||
|
||||
#define DM_STATS_REGION_NOT_PRESENT UINT64_MAX
|
||||
#define DM_STATS_GROUP_NOT_PRESENT DM_STATS_GROUP_NONE
|
||||
@@ -37,6 +46,9 @@
|
||||
|
||||
#define STATS_ROW_BUF_LEN 4096
|
||||
#define STATS_MSG_BUF_LEN 1024
|
||||
#define STATS_FIE_BUF_LEN 2048
|
||||
|
||||
#define SECTOR_SHIFT 9L
|
||||
|
||||
/* Histogram bin */
|
||||
struct dm_histogram_bin {
|
||||
@@ -85,6 +97,7 @@ struct dm_stats_region {
|
||||
char *aux_data;
|
||||
uint64_t timescale; /* precise_timestamps is per-region */
|
||||
struct dm_histogram *bounds; /* histogram configuration */
|
||||
struct dm_histogram *histogram; /* aggregate cache */
|
||||
struct dm_stats_counters *counters;
|
||||
};
|
||||
|
||||
@@ -92,6 +105,7 @@ struct dm_stats_group {
|
||||
uint64_t group_id;
|
||||
const char *alias;
|
||||
dm_bitset_t regions;
|
||||
struct dm_histogram *histogram;
|
||||
};
|
||||
|
||||
struct dm_stats {
|
||||
@@ -339,6 +353,8 @@ static void _stats_group_destroy(struct dm_stats_group *group)
|
||||
if (!_stats_group_present(group))
|
||||
return;
|
||||
|
||||
group->histogram = NULL;
|
||||
|
||||
if (group->alias) {
|
||||
dm_free((char *) group->alias);
|
||||
group->alias = NULL;
|
||||
@@ -899,6 +915,9 @@ static int _stats_parse_list_region(struct dm_stats *dms,
|
||||
} else
|
||||
region->bounds = NULL;
|
||||
|
||||
/* clear aggregate cache */
|
||||
region->histogram = NULL;
|
||||
|
||||
region->group_id = DM_STATS_GROUP_NOT_PRESENT;
|
||||
|
||||
if (!(region->program_id = dm_strdup(program_id)))
|
||||
@@ -3177,21 +3196,132 @@ int dm_stats_get_current_region_precise_timestamps(const struct dm_stats *dms)
|
||||
* Histogram access methods.
|
||||
*/
|
||||
|
||||
static void _sum_histogram_bins(const struct dm_stats *dms,
|
||||
struct dm_histogram *dmh_aggr,
|
||||
uint64_t region_id, uint64_t area_id)
|
||||
{
|
||||
struct dm_stats_region *region;
|
||||
struct dm_histogram_bin *bins;
|
||||
struct dm_histogram *dmh_cur;
|
||||
uint64_t bin;
|
||||
|
||||
region = &dms->regions[region_id];
|
||||
dmh_cur = region->counters[area_id].histogram;
|
||||
bins = dmh_aggr->bins;
|
||||
|
||||
for (bin = 0; bin < dmh_aggr->nr_bins; bin++)
|
||||
bins[bin].count += dmh_cur->bins[bin].count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an aggregate histogram for a sub-divided region or a group.
|
||||
*/
|
||||
static struct dm_histogram *_aggregate_histogram(const struct dm_stats *dms,
|
||||
uint64_t region_id,
|
||||
uint64_t area_id)
|
||||
{
|
||||
struct dm_histogram *dmh_aggr, *dmh_cur, **dmh_cachep;
|
||||
int bin, nr_bins, group = 1;
|
||||
uint64_t group_id;
|
||||
size_t hist_size;
|
||||
|
||||
if (area_id == DM_STATS_WALK_REGION) {
|
||||
/* region aggregation */
|
||||
group = 0;
|
||||
if (!_stats_region_present(&dms->regions[region_id]))
|
||||
return_NULL;
|
||||
|
||||
if (!dms->regions[region_id].bounds)
|
||||
return_NULL;
|
||||
|
||||
if (!dms->regions[region_id].counters)
|
||||
return dms->regions[region_id].bounds;
|
||||
|
||||
if (dms->regions[region_id].histogram)
|
||||
return dms->regions[region_id].histogram;
|
||||
|
||||
dmh_cur = dms->regions[region_id].counters[0].histogram;
|
||||
dmh_cachep = &dms->regions[region_id].histogram;
|
||||
nr_bins = dms->regions[region_id].bounds->nr_bins;
|
||||
} else {
|
||||
/* group aggregation */
|
||||
group_id = region_id;
|
||||
area_id = DM_STATS_WALK_GROUP;
|
||||
if (!_stats_group_id_present(dms, group_id))
|
||||
return_NULL;
|
||||
|
||||
if (!dms->regions[group_id].bounds)
|
||||
return_NULL;
|
||||
|
||||
if (!dms->regions[group_id].counters)
|
||||
return dms->regions[group_id].bounds;
|
||||
|
||||
if (dms->groups[group_id].histogram)
|
||||
return dms->groups[group_id].histogram;
|
||||
|
||||
dmh_cur = dms->regions[group_id].counters[0].histogram;
|
||||
dmh_cachep = &dms->groups[group_id].histogram;
|
||||
nr_bins = dms->regions[group_id].bounds->nr_bins;
|
||||
}
|
||||
|
||||
hist_size = sizeof(*dmh_aggr)
|
||||
+ nr_bins * sizeof(struct dm_histogram_bin);
|
||||
|
||||
if (!(dmh_aggr = dm_pool_zalloc(dms->hist_mem, hist_size))) {
|
||||
log_error("Could not allocate group histogram");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dmh_aggr->nr_bins = dmh_cur->nr_bins;
|
||||
dmh_aggr->dms = dms;
|
||||
|
||||
if (!group)
|
||||
_foreach_region_area(dms, region_id, area_id) {
|
||||
_sum_histogram_bins(dms, dmh_aggr, region_id, area_id);
|
||||
}
|
||||
else {
|
||||
_foreach_group_area(dms, group_id, region_id, area_id) {
|
||||
_sum_histogram_bins(dms, dmh_aggr, region_id, area_id);
|
||||
}
|
||||
}
|
||||
|
||||
for (bin = 0; bin < nr_bins; bin++) {
|
||||
dmh_aggr->sum += dmh_aggr->bins[bin].count;
|
||||
dmh_aggr->bins[bin].upper = dmh_cur->bins[bin].upper;
|
||||
}
|
||||
|
||||
/* cache aggregate histogram for subsequent access */
|
||||
*dmh_cachep = dmh_aggr;
|
||||
|
||||
return dmh_aggr;
|
||||
}
|
||||
|
||||
struct dm_histogram *dm_stats_get_histogram(const struct dm_stats *dms,
|
||||
uint64_t region_id,
|
||||
uint64_t area_id)
|
||||
{
|
||||
region_id = (region_id == DM_STATS_REGION_CURRENT)
|
||||
? dms->cur_region : region_id ;
|
||||
area_id = (area_id == DM_STATS_AREA_CURRENT)
|
||||
? dms->cur_area : area_id ;
|
||||
int aggr = 0;
|
||||
|
||||
/* FIXME return histogram sum? Requires bounds check at group time */
|
||||
if (region_id & DM_STATS_WALK_GROUP) {
|
||||
log_err_once("Group histogram data is not supported");
|
||||
return NULL;
|
||||
if (region_id == DM_STATS_REGION_CURRENT) {
|
||||
region_id = dms->cur_region;
|
||||
if (region_id & DM_STATS_WALK_GROUP) {
|
||||
region_id = dms->cur_group;
|
||||
aggr = 1;
|
||||
}
|
||||
} else if (region_id & DM_STATS_WALK_GROUP) {
|
||||
region_id &= ~DM_STATS_WALK_GROUP;
|
||||
aggr = 1;
|
||||
}
|
||||
|
||||
area_id = (area_id == DM_STATS_AREA_CURRENT)
|
||||
? dms->cur_area : area_id ;
|
||||
|
||||
if (area_id == DM_STATS_WALK_REGION)
|
||||
aggr = 1;
|
||||
|
||||
if (aggr)
|
||||
return _aggregate_histogram(dms, region_id, area_id);
|
||||
|
||||
if (region_id & DM_STATS_WALK_REGION)
|
||||
region_id &= ~DM_STATS_WALK_REGION;
|
||||
|
||||
@@ -3742,6 +3872,39 @@ merge:
|
||||
return overlap;
|
||||
}
|
||||
|
||||
static void _stats_copy_histogram_bounds(struct dm_histogram *to,
|
||||
struct dm_histogram *from)
|
||||
{
|
||||
uint64_t i;
|
||||
|
||||
to->nr_bins = from->nr_bins;
|
||||
|
||||
for (i = 0; i < to->nr_bins; i++)
|
||||
to->bins[i].upper = from->bins[i].upper;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare histogram bounds h1 and h2, and return 1 if they match (i.e.
|
||||
* have the same number of bins and identical bin boundary values), or 0
|
||||
* otherwise.
|
||||
*/
|
||||
static int _stats_check_histogram_bounds(struct dm_histogram *h1,
|
||||
struct dm_histogram *h2)
|
||||
{
|
||||
uint64_t i;
|
||||
|
||||
if (!h1 || !h2)
|
||||
return 0;
|
||||
|
||||
if (h1->nr_bins != h2->nr_bins)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < h1->nr_bins; i++)
|
||||
if (h1->bins[i].upper != h2->bins[i].upper)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new group in stats handle dms from the group description
|
||||
* passed in group.
|
||||
@@ -3749,6 +3912,7 @@ merge:
|
||||
int dm_stats_create_group(struct dm_stats *dms, const char *members,
|
||||
const char *alias, uint64_t *group_id)
|
||||
{
|
||||
struct dm_histogram *check = NULL, *bounds;
|
||||
int i, count = 0, precise = 0;
|
||||
dm_bitset_t regions;
|
||||
|
||||
@@ -3759,6 +3923,11 @@ int dm_stats_create_group(struct dm_stats *dms, const char *members,
|
||||
|
||||
if (!(regions = dm_bitset_parse_list(members, NULL))) {
|
||||
log_error("Could not parse list: '%s'", members);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(check = dm_pool_zalloc(dms->hist_mem, sizeof(*check)))) {
|
||||
log_error("Could not allocate memory for bounds check");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@@ -3784,14 +3953,20 @@ int dm_stats_create_group(struct dm_stats *dms, const char *members,
|
||||
FMTu64, i, dms->regions[i].group_id);
|
||||
goto bad;
|
||||
}
|
||||
if (dms->regions[i].bounds) {
|
||||
log_error("Region ID %d: grouping regions with "
|
||||
"histograms is not yet supported", i);
|
||||
goto bad;
|
||||
}
|
||||
if (dms->regions[i].timescale == 1)
|
||||
precise++;
|
||||
|
||||
/* check for matching histogram bounds */
|
||||
bounds = dms->regions[i].bounds;
|
||||
if (bounds && !check->nr_bins)
|
||||
_stats_copy_histogram_bounds(check, bounds);
|
||||
else if (bounds) {
|
||||
if (!_stats_check_histogram_bounds(check, bounds)) {
|
||||
log_error("All region histogram bounds "
|
||||
"must match exactly");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
@@ -3805,8 +3980,11 @@ int dm_stats_create_group(struct dm_stats *dms, const char *members,
|
||||
if (!_stats_create_group(dms, regions, alias, group_id))
|
||||
goto bad;
|
||||
|
||||
dm_pool_free(dms->hist_mem, check);
|
||||
return 1;
|
||||
|
||||
bad:
|
||||
dm_pool_free(dms->hist_mem, check);
|
||||
dm_bitset_destroy(regions);
|
||||
return 0;
|
||||
}
|
||||
@@ -3895,6 +4073,7 @@ int dm_stats_get_group_descriptor(const struct dm_stats *dms,
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX_FIEMAP_H
|
||||
/*
|
||||
* Group a table of region_ids corresponding to the extents of a file.
|
||||
*/
|
||||
@@ -3954,8 +4133,8 @@ static int _stats_add_extent(struct dm_pool *mem, struct fiemap_extent *fm_ext,
|
||||
memset(&extent.list, 0, sizeof(extent.list));
|
||||
|
||||
/* convert bytes to dm (512b) sectors */
|
||||
extent.start = fm_ext->fe_physical >> 9;
|
||||
extent.len = fm_ext->fe_length >> 9;
|
||||
extent.start = fm_ext->fe_physical >> SECTOR_SHIFT;
|
||||
extent.len = fm_ext->fe_length >> SECTOR_SHIFT;
|
||||
|
||||
extent.id = id;
|
||||
|
||||
@@ -3968,6 +4147,12 @@ static int _stats_add_extent(struct dm_pool *mem, struct fiemap_extent *fm_ext,
|
||||
|
||||
}
|
||||
|
||||
/* test for the boundary of an extent */
|
||||
#define ext_boundary(ext, exp, exp_dense) \
|
||||
(((ext).fe_logical != 0) && \
|
||||
((ext).fe_physical != (exp)) && \
|
||||
((ext).fe_physical != (exp_dense)))
|
||||
|
||||
/*
|
||||
* Read the extents of an open file descriptor into a table of struct _extent.
|
||||
*
|
||||
@@ -3979,7 +4164,7 @@ static int _stats_add_extent(struct dm_pool *mem, struct fiemap_extent *fm_ext,
|
||||
static struct _extent *_stats_get_extents_for_file(struct dm_pool *mem, int fd,
|
||||
uint64_t *count)
|
||||
{
|
||||
uint64_t buf[2048];
|
||||
uint64_t buf[STATS_FIE_BUF_LEN];
|
||||
struct fiemap *fiemap = (struct fiemap *)buf;
|
||||
struct fiemap_extent *fm_ext = &fiemap->fm_extents[0];
|
||||
struct fiemap_extent fm_last = {0};
|
||||
@@ -4029,13 +4214,11 @@ static struct _extent *_stats_get_extents_for_file(struct dm_pool *mem, int fd,
|
||||
fm_last.fe_length;
|
||||
expected = fm_last.fe_physical +
|
||||
fm_ext[i].fe_logical - fm_last.fe_logical;
|
||||
if ((fm_ext[i].fe_logical != 0)
|
||||
&& (fm_ext[i].fe_physical != expected)
|
||||
&& (fm_ext[i].fe_physical != expected_dense)) {
|
||||
if (ext_boundary(fm_ext[i], expected, expected_dense)) {
|
||||
tot_extents++;
|
||||
if (!_stats_add_extent(mem, fm_ext + i,
|
||||
tot_extents - 1))
|
||||
goto bad;
|
||||
goto_bad;
|
||||
} else {
|
||||
expected = 0;
|
||||
if (!tot_extents)
|
||||
@@ -4043,7 +4226,7 @@ static struct _extent *_stats_get_extents_for_file(struct dm_pool *mem, int fd,
|
||||
if (fm_ext[i].fe_logical == 0)
|
||||
if (!_stats_add_extent(mem, fm_ext + i,
|
||||
tot_extents - 1))
|
||||
goto bad;
|
||||
goto_bad;
|
||||
}
|
||||
num += tot_extents;
|
||||
if (fm_ext[i].fe_flags & FIEMAP_EXTENT_LAST)
|
||||
@@ -4081,9 +4264,11 @@ static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
|
||||
{
|
||||
struct _extent *extents = NULL;
|
||||
uint64_t *regions = NULL, i;
|
||||
char *hist_arg = NULL;
|
||||
struct statfs fsbuf;
|
||||
struct stat buf;
|
||||
|
||||
#ifdef BTRFS_SUPER_MAGIC
|
||||
if (fstatfs(fd, &fsbuf)) {
|
||||
log_error("fstatfs failed for fd %d", fd);
|
||||
return 0;
|
||||
@@ -4094,6 +4279,7 @@ static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
|
||||
"physical FIEMAP extent data.");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fstat(fd, &buf)) {
|
||||
log_error("fstat failed for fd %d", fd);
|
||||
@@ -4113,6 +4299,12 @@ static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
|
||||
if (!(extents = _stats_get_extents_for_file(dms->mem, fd, count)))
|
||||
return_0;
|
||||
|
||||
if (bounds) {
|
||||
/* _build_histogram_arg enables precise if vals < 1ms. */
|
||||
if (!(hist_arg = _build_histogram_arg(bounds, &precise)))
|
||||
goto_out;
|
||||
}
|
||||
|
||||
/* make space for end-of-table marker */
|
||||
if (!(regions = dm_malloc((1 + *count) * sizeof(*regions)))) {
|
||||
log_error("Could not allocate memory for region IDs.");
|
||||
@@ -4120,9 +4312,9 @@ static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
|
||||
}
|
||||
|
||||
for (i = 0; i < *count; i++) {
|
||||
if (!_stats_create_region(dms, regions + i,
|
||||
extents[i].start, extents[i].len, -1,
|
||||
precise, NULL, dms->program_id, "")) {
|
||||
if (!_stats_create_region(dms, regions + i, extents[i].start,
|
||||
extents[i].len, -1, precise, hist_arg,
|
||||
dms->program_id, "")) {
|
||||
log_error("Failed to create region " FMTu64 " of "
|
||||
FMTu64 " at " FMTu64 ".", i, *count,
|
||||
extents[i].start);
|
||||
@@ -4155,12 +4347,6 @@ uint64_t *dm_stats_create_regions_from_fd(struct dm_stats *dms, int fd,
|
||||
{
|
||||
uint64_t *regions, count = 0;
|
||||
|
||||
if (bounds) {
|
||||
log_error("File mapped groups with histograms are not "
|
||||
"yet supported.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (alias && !group) {
|
||||
log_error("Cannot set alias without grouping regions.");
|
||||
return NULL;
|
||||
@@ -4186,6 +4372,17 @@ out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else /* HAVE_LINUX_FIEMAP */
|
||||
uint64_t *dm_stats_create_regions_from_fd(struct dm_stats *dms, int fd,
|
||||
int group, int precise,
|
||||
struct dm_histogram *bounds,
|
||||
const char *alias)
|
||||
{
|
||||
log_error("File mapping requires FIEMAP ioctl support.");
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_LINUX_FIEMAP */
|
||||
|
||||
/*
|
||||
* Backward compatible dm_stats_create_region() implementations.
|
||||
*
|
||||
|
@@ -7,6 +7,7 @@ blkdeactivate \(em utility to deactivate block devices
|
||||
.RB [ \-e ]
|
||||
.RB [ \-h ]
|
||||
.RB [ \-l \ \fIlvm_options\fP ]
|
||||
.RB [ \-m \ \fImpath_options\fP ]
|
||||
.RB [ \-u ]
|
||||
.RB [ \-v ]
|
||||
.RI [ device ]
|
||||
@@ -51,6 +52,16 @@ Deactivating Volume Group as a whole takes less time than deactivating each
|
||||
Logical Volume separately.
|
||||
.RE
|
||||
.TP
|
||||
.BR \-m ", " \-\-mpathoption \ \fImpath_options\fP
|
||||
Comma separated list of device-mapper multipath specific options:
|
||||
.RS
|
||||
.IP \fIdisablequeueing\fP
|
||||
Disable queueing on all multipath devices first before deactivation.
|
||||
This avoids a situation where blkdeactivate may end up waiting if
|
||||
all paths are unavailable for any underlying device-mapper multipath
|
||||
device.
|
||||
.RE
|
||||
.TP
|
||||
.BR \-u ", " \-\-umount
|
||||
Unmount a mounted device before trying to deactivate it.
|
||||
Without this option used, a device that is mounted is not deactivated.
|
||||
@@ -90,4 +101,5 @@ of device-mapper devices in case the deactivation fails and force removal.
|
||||
.BR lsblk (8),
|
||||
.BR lvm (8),
|
||||
.BR mdadm (8),
|
||||
.BR multipathd (8),
|
||||
.BR umount (8)
|
||||
|
@@ -80,15 +80,15 @@ dmstats \(em device-mapper statistics management
|
||||
.de CMD_CREATE
|
||||
. ad l
|
||||
. BR create
|
||||
. IR device_name
|
||||
. RB [ device_name...
|
||||
. RB | file_path... ]
|
||||
. RB [ \-\-alldevices ]
|
||||
. RB [ \-\-areas
|
||||
. IR nr_areas | \fB\-\-areasize
|
||||
. IR area_size ]
|
||||
. RB [ \-\-bounds
|
||||
. IR \%histogram_boundaries ]
|
||||
. RB [ \-\-filemap
|
||||
. IR path ]
|
||||
. RB [ \-\-filemap ]
|
||||
. RB [ \-\-nogroup ]
|
||||
. RB [ \-\-precise ]
|
||||
. RB [ \-\-start
|
||||
@@ -148,8 +148,6 @@ dmstats \(em device-mapper statistics management
|
||||
. RI [ device_name ]
|
||||
. RB [ \-\-histogram ]
|
||||
. OPT_PROGRAMS
|
||||
. RB [ \-\-statstype
|
||||
. IR type_list ]
|
||||
. RB [ \-\-units
|
||||
. IR units ]
|
||||
. OPT_OBJECTS
|
||||
@@ -193,8 +191,6 @@ dmstats \(em device-mapper statistics management
|
||||
. IR sort_fields ]
|
||||
. RB [ \-S | \-\-select
|
||||
. IR selection ]
|
||||
. RB [ \-\-statstype
|
||||
. IR type_list ]
|
||||
. RB [ \-\-units
|
||||
. IR units ]
|
||||
. RB [ \-\-nosuffix ]
|
||||
@@ -303,11 +299,11 @@ results.
|
||||
.
|
||||
.HP
|
||||
.BR \-\-filemap
|
||||
.IR path
|
||||
.br
|
||||
Instead of creating regions specified by command line options, open
|
||||
the file found at \fBpath\fP, and create regions corresponding to the
|
||||
locations of the on-disk extents allocated to the file.
|
||||
Instead of creating regions on a device as specified by command line
|
||||
options, open the file found at each \fBfile_path\fP argument, and
|
||||
create regions corresponding to the locations of the on-disk extents
|
||||
allocated to the file(s).
|
||||
.
|
||||
.HP
|
||||
.BR \-\-groupid
|
||||
@@ -460,23 +456,13 @@ optional suffix selects units of:
|
||||
.HP
|
||||
.BR \-\-segments
|
||||
.br
|
||||
Create a new statistics region for each target contained in the target
|
||||
device. This causes a separate region to be allocated for each segment
|
||||
of the device.
|
||||
.
|
||||
.HP
|
||||
.BR \-\-statstype
|
||||
.IR type_list
|
||||
.br
|
||||
Filter the types of statistics object included in a report or listing
|
||||
according to the provided list. A report may include areas, regions,
|
||||
and user-defined groups of regions that report aggregate data for all
|
||||
group members.
|
||||
When used with \fBcreate\fP, create a new statistics region for each
|
||||
target contained in the given device(s). This causes a separate region
|
||||
to be allocated for each segment of the device.
|
||||
|
||||
The list may be a single object type, a comma separated list of types,
|
||||
or the special value 'all'.
|
||||
|
||||
The currently available object types are 'area', 'region' and 'group'.
|
||||
The newly created regions are automatically placed into a group unless
|
||||
the \fB\-\-nogroup\fP option is given. When grouping is enabled a group
|
||||
alias may be specified using the \fB\-\-alias\fP option.
|
||||
.
|
||||
.HP
|
||||
.BR \-\-units
|
||||
@@ -558,13 +544,13 @@ By default dmstats creates regions with a \fBprogram_id\fP of
|
||||
On success the \fBregion_id\fP of the newly created region is printed
|
||||
to stdout.
|
||||
|
||||
If the \fB\-\-filemap\fP option is given with a regular file as the
|
||||
\fBpath\fP argument, instead of creating regions with parameters
|
||||
specified on the command line, \fBdmstats\fP will open the file located
|
||||
at \fBpath\fP and create regions corresponding to the physical extents
|
||||
allocated to the file. This can be used to monitor statistics for
|
||||
individual files in the file system, for example, virtual machine
|
||||
images, swap areas, or large database files.
|
||||
If the \fB\-\-filemap\fP option is given with a regular file, or list
|
||||
of files, as the \fBfile_path\fP argument, instead of creating regions
|
||||
with parameters specified on the command line, \fBdmstats\fP will open
|
||||
the files located at \fBfile_path\fP and create regions corresponding to
|
||||
the physical extents allocated to the file. This can be used to monitor
|
||||
statistics for individual files in the file system, for example, virtual
|
||||
machine images, swap areas, or large database files.
|
||||
|
||||
To work with the \fB\-\-filemap\fP option, files must be located on a
|
||||
local file system, backed by a device-mapper device, that supports
|
||||
@@ -574,8 +560,8 @@ By default regions that map a file are placed into a group and the
|
||||
group alias is set to the basename of the file. This behaviour can be
|
||||
overridden with the \fB\-\-alias\fP and \fB\-\-nogroup\fP options.
|
||||
|
||||
To display only group information when listing and reporting, use the
|
||||
\fB\-\-statstype\fP option with the 'group' type.
|
||||
Use the \fB\-\-group\fP option to only display information for groups
|
||||
when listing and reporting.
|
||||
.
|
||||
.HP
|
||||
.CMD_DELETE
|
||||
@@ -609,6 +595,9 @@ regions is given as a comma-separated list of region identifiers. A
|
||||
continuous range of identifers spanning from \fBR1\fP to \fBR2\fP may
|
||||
be expressed as '\fBR1\fP-\fBR2\fP'.
|
||||
|
||||
Regions that have a histogram configured can be grouped: in this case
|
||||
the number of histogram bins and their bounds must match exactly.
|
||||
|
||||
On success the group list and newly created \fBgroup_id\fP are
|
||||
printed to stdout.
|
||||
.
|
||||
@@ -628,13 +617,13 @@ regardless of region program ID values.
|
||||
By default only regions and groups are included in list output. If
|
||||
\fB\-v\fP or \fB\-\-verbose\fP is given the report will also include a
|
||||
row of information for each configured group and for each area contained
|
||||
in each region displayed (regions that contain a single area are by
|
||||
default omitted from the verbose list since their properties are
|
||||
identical to the area that they contain - to view all regions regardless
|
||||
of the number of areas they contain use \fB\-\-statstype\fP).
|
||||
in each region displayed.
|
||||
|
||||
Specific combinations of objects may be selected using the
|
||||
\fB\-\-statstype\fP option.
|
||||
Regions that contain a single area are by default omitted from the
|
||||
verbose list since their properties are identical to the area that they
|
||||
contain - to view all regions regardless of the number of areas present
|
||||
use \fB\-\-region\fP). To also view the areas contained within regions
|
||||
use \fB\-\-area\fP.
|
||||
|
||||
If \fB\-\-histogram\fP is given the report will include the bin count
|
||||
and latency boundary values for any configured histograms.
|
||||
@@ -661,8 +650,9 @@ values and latency boundaries.
|
||||
If the \fB\-\-relative\fP is used the default histogram field displays
|
||||
bin values as a percentage of the total number of I/Os.
|
||||
|
||||
Object types (areas, regions and groups) are selected using the
|
||||
\fB\-\-statstype\fP option.
|
||||
Object types (areas, regions and groups) to include in the report are
|
||||
selected using the \fB\-\-area\fP, \fB\-\-region\fP, and \fB\-\-group\fP
|
||||
options.
|
||||
.
|
||||
.HP
|
||||
.CMD_UNGROUP
|
||||
@@ -1055,13 +1045,21 @@ vg00-lvol1: Created new region with 1 area(s) as region ID 1
|
||||
.br
|
||||
vg00-lvol1: Created new region with 1 area(s) as region ID 2
|
||||
.P
|
||||
Create regions mapping the file vm.img and place them into a group with
|
||||
the alias set to the same name as the file.
|
||||
Create regions mapping each file in the directory images/ and place
|
||||
them into separate groups, each named after the corresponding file
|
||||
.br
|
||||
#
|
||||
.B dmstats create --filemap vm.img
|
||||
.B dmstats create --filemap images/*
|
||||
.br
|
||||
vm.img: Created new group with 112 region(s) as group ID 3.
|
||||
images/vm1.qcow2: Created new group with 87 region(s) as group ID 0.
|
||||
.br
|
||||
images/vm1-1.qcow2: Created new group with 8 region(s) as group ID 87.
|
||||
.br
|
||||
images/vm2.qcow2: Created new group with 11 region(s) as group ID 95.
|
||||
.br
|
||||
images/vm2-1.qcow2: Created new group with 1454 region(s) as group ID 106.
|
||||
.br
|
||||
images/vm3.img: Created new group with 2 region(s) as group ID 1560.
|
||||
.P
|
||||
Print raw counters for region 4 on device d0
|
||||
.br
|
||||
|
@@ -8,19 +8,168 @@ lvconvert \(em change LV type and other utilities
|
||||
.RI [ OPTION ]...
|
||||
.IR VolumeGroup / LogicalVolume
|
||||
|
||||
OPTIONS:
|
||||
.br
|
||||
.BR \-b ,
|
||||
.BR \-\-background
|
||||
.br
|
||||
.BR \-\-cachepolicy
|
||||
.IR Policy
|
||||
.br
|
||||
.BR \-\-cachepool
|
||||
.IR CachePoolLogicalVolume { Name | Path }
|
||||
.br
|
||||
.BR \-\-cachesettings
|
||||
.IB Key = Value
|
||||
.br
|
||||
.BR \-c ,
|
||||
.BR \-\-chunksize
|
||||
.BR \fIChunkSize [ b | B | s | S | k | K | m | M | g | G ]
|
||||
.br
|
||||
.BR \-\-corelog
|
||||
.br
|
||||
.BR \-\-discards
|
||||
.RB { ignore | nopassdown | passdown }
|
||||
.br
|
||||
.BR \-i ,
|
||||
.BR \-\-interval
|
||||
.IR Seconds
|
||||
.br
|
||||
.BR \-\-merge
|
||||
.br
|
||||
.BR \-\-mirrorlog
|
||||
.RB { disk | core | mirrored }
|
||||
.br
|
||||
.BR \-m ,
|
||||
.BR \-\-mirrors
|
||||
.IR Number
|
||||
.br
|
||||
.BR \-n ,
|
||||
.BR \-\-name
|
||||
.IR Name
|
||||
.br
|
||||
.BR \-\-noudevsync
|
||||
.br
|
||||
.BR \-\-originname
|
||||
.IR NewExternalOriginVolumeName
|
||||
.br
|
||||
.BR \-\-poolmetadata
|
||||
.IR PoolMetadataLogicalVolume { Name | Path }
|
||||
.br
|
||||
.BR \-\-poolmetadatasize
|
||||
.BR \fIPoolMetadataSize [ b | B | s | S | k | K | m | M | g | G ]
|
||||
.br
|
||||
.BR \-\-poolmetadataspare
|
||||
.RB { y | n }
|
||||
.br
|
||||
.BR \-r ,
|
||||
.BR \-\-readahead
|
||||
.RB { \fIReadAheadSectors | auto | none }
|
||||
.br
|
||||
.BR \-R ,
|
||||
.BR \-\-regionsize
|
||||
.IR MirrorLogRegionSize
|
||||
.br
|
||||
.BR \-\-repair
|
||||
.br
|
||||
.BR \-\-replace
|
||||
.IR PhysicalVolume
|
||||
.br
|
||||
.BR \-\-splitcache
|
||||
.br
|
||||
.BR \-\-splitmirrors
|
||||
.IR Number
|
||||
.br
|
||||
.BR \-\-splitsnapshot
|
||||
.br
|
||||
.BR \-\-stripes
|
||||
.IR Number
|
||||
.br
|
||||
.BR \-I ,
|
||||
.BR \-\-stripesize
|
||||
.IR StripeSize
|
||||
.br
|
||||
.B \-\-type striped
|
||||
.br
|
||||
.B \-\-type snapshot
|
||||
.R |
|
||||
.B \-\-snapshot
|
||||
.R |
|
||||
.B \-s
|
||||
.br
|
||||
.B \-\-type mirror
|
||||
.br
|
||||
.B \-\-type raid*
|
||||
.br
|
||||
.B \-\-type thin
|
||||
.R |
|
||||
.B \-\-thin
|
||||
.R |
|
||||
.B \-T
|
||||
.br
|
||||
.B \-\-type cache
|
||||
.R |
|
||||
.B \-\-cache
|
||||
.R |
|
||||
.B \-H
|
||||
.br
|
||||
.B \-\-type thin\-pool
|
||||
.br
|
||||
.B \-\-type cache\-pool
|
||||
.br
|
||||
.BR \-\-thinpool
|
||||
.IR ThinPoolLogicalVolume { Name | Path }
|
||||
.br
|
||||
.BR \-\-trackchanges
|
||||
.br
|
||||
.BR \-\-uncache
|
||||
.br
|
||||
.BR \-Z ,
|
||||
.BR \-\-zero
|
||||
.RB { y | n }
|
||||
.br
|
||||
|
||||
Common options:
|
||||
.br
|
||||
.BR \-A ,
|
||||
.BR \-\-alloc
|
||||
.IR AllocationPolicy
|
||||
.br
|
||||
.BR \-f ,
|
||||
.BR \-\-force
|
||||
.br
|
||||
.BR \-\-commandprofile
|
||||
.IR ProfileName
|
||||
.br
|
||||
.BR \-h ,
|
||||
.BR \-? ,
|
||||
.BR \-\-help
|
||||
.br
|
||||
.BR \-v ,
|
||||
.BR \-\-verbose
|
||||
.br
|
||||
.BR \-y ,
|
||||
.BR \-\-yes
|
||||
.br
|
||||
.BR \-\-version
|
||||
|
||||
|
||||
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
||||
lvconvert changes the LV type and includes various LV utilities.
|
||||
|
||||
To display the current LV type, run the command:
|
||||
|
||||
.B lvs \-o name,segtype VG/LV
|
||||
.B lvs \-o name,segtype
|
||||
.IR VG / LV
|
||||
|
||||
To change the LV type, run the command:
|
||||
|
||||
.B lvconvert \-\-type
|
||||
.I NewType
|
||||
.B VG/LV
|
||||
.IR VG / LV
|
||||
|
||||
.SS LV types
|
||||
|
||||
@@ -56,9 +205,6 @@ The
|
||||
type refers to one of many raid levels, e.g.
|
||||
.B raid1,
|
||||
.B raid5.
|
||||
See
|
||||
.BR lvmraid (7)
|
||||
for a full list.
|
||||
|
||||
.SS LV layers
|
||||
|
||||
@@ -87,13 +233,16 @@ avoid the direct use of hidden LVs.
|
||||
|
||||
.B lvconvert \-\-merge
|
||||
VG/StripedLV
|
||||
.br
|
||||
\[bu]
|
||||
Merge StripedLV into an LV when it is a previously split mirror
|
||||
.br
|
||||
\[bu]
|
||||
See --splitmirror.
|
||||
./" FIXME: use --merge-mirror
|
||||
.br
|
||||
\[bu]
|
||||
Merge StripedLV into an LV when it is a previously split mirror.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-background, \-\-interval.
|
||||
.br
|
||||
\[bu]
|
||||
See corresponding operation --splitmirrors.
|
||||
|
||||
.B lvconvert \-\-type snapshot
|
||||
VG/StripedLV VG/SnapshotLV
|
||||
@@ -102,7 +251,10 @@ VG/StripedLV VG/SnapshotLV
|
||||
Recombine StripedLV with SnapshotLV which was previously split.
|
||||
.br
|
||||
\[bu]
|
||||
See --splitsnapshot.
|
||||
Options \-\-chunksize, \-\-zero.
|
||||
.br
|
||||
\[bu]
|
||||
See corresponding operation --splitsnapshot.
|
||||
|
||||
.B lvconvert \-\-type thin
|
||||
VG/StripedLV
|
||||
@@ -111,13 +263,13 @@ VG/StripedLV
|
||||
Convert StripedLV to type thin with an external origin.
|
||||
.br
|
||||
\[bu]
|
||||
Also specify a thin pool to use, see \-\-thinpool.
|
||||
.br
|
||||
\[bu]
|
||||
StripedLV becomes a read\-only external origin LV with a new name.
|
||||
.br
|
||||
\[bu]
|
||||
See \-\-originname.
|
||||
Requires \-\-thinpool to specify the thin pool to use.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-originname.
|
||||
|
||||
.B lvconvert \-\-type cache
|
||||
VG/StripedLV
|
||||
@@ -126,19 +278,33 @@ VG/StripedLV
|
||||
Convert StripedLV to type cache.
|
||||
.br
|
||||
\[bu]
|
||||
Also specify a cache pool to use, see \-\-cachepool.
|
||||
Requires \-\-cachepool to specify the cache pool to use.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-cachepolicy, \-\-cachesettings.
|
||||
|
||||
.B lvconvert \-\-type thin\-pool
|
||||
VG/StripedLV
|
||||
.br
|
||||
\[bu]
|
||||
Convert StripedLV to type thin\-pool.
|
||||
.br
|
||||
\[bu]
|
||||
The StripedLV is used for thin pool data.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-chunksize, \-\-discards, \-\-poolmetadata{size,spare},
|
||||
.br
|
||||
\-\-readahead, \-\-zero.
|
||||
|
||||
.B lvconvert \-\-type cache\-pool
|
||||
VG/StripedLV
|
||||
.br
|
||||
\[bu]
|
||||
Convert StripedLV to type cache\-pool.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-chunksize, \-\-poolmetadata{size,spare}.
|
||||
|
||||
.B lvconvert \-\-type mirror
|
||||
VG/StripedLV
|
||||
@@ -147,7 +313,10 @@ VG/StripedLV
|
||||
Convert StripedLV to type mirror.
|
||||
.br
|
||||
\[bu]
|
||||
Also specify the number of mirrors, see \-\-mirrors.
|
||||
Requires \-\-mirrors to specify the number of mirrors to use.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-mirrorlog, \-\-regionsize.
|
||||
|
||||
.B lvconvert \-\-type raid*
|
||||
VG/StripedLV
|
||||
@@ -156,7 +325,7 @@ VG/StripedLV
|
||||
Convert StripedLV to type raid*.
|
||||
.br
|
||||
\[bu]
|
||||
Also specify the number of mirrors, see \-\-mirrors.
|
||||
Required options depend on the raid level.
|
||||
|
||||
.SS Operations on RaidLV with type raid*:
|
||||
|
||||
@@ -167,7 +336,7 @@ Number
|
||||
VG/RaidLV
|
||||
.br
|
||||
\[bu]
|
||||
Change the number of images in a raid1 RaidLV.
|
||||
Change the number of images in raid1 RaidLV.
|
||||
|
||||
.B lvconvert \-\-splitmirrors
|
||||
Number
|
||||
@@ -177,17 +346,20 @@ VG/RaidLV
|
||||
Split images from raid1 RaidLV and use them to create a new LV.
|
||||
.br
|
||||
\[bu]
|
||||
Also specify \-\-name for new LV, or use \-\-trackchanges.
|
||||
Requires \-\-name for the new LV, or the use of \-\-trackchanges.
|
||||
|
||||
.B lvconvert \-\-merge
|
||||
VG/RaidLV
|
||||
./" FIXME: use --merge-mirror
|
||||
.br
|
||||
\[bu]
|
||||
Merge RaidLV into an LV when it is a previously split mirror.
|
||||
.br
|
||||
\[bu]
|
||||
See --splitmirror.
|
||||
./" FIXME: use --merge-mirror
|
||||
Options \-\-background, \-\-interval.
|
||||
.br
|
||||
\[bu]
|
||||
See corresponding operation --splitmirrors.
|
||||
|
||||
.B lvconvert \-\-repair
|
||||
VG/RaidLV
|
||||
@@ -197,16 +369,16 @@ Replace failed PVs in RaidLV.
|
||||
|
||||
.B lvconvert \-\-replace
|
||||
PV
|
||||
.B [\-\-replace
|
||||
PV
|
||||
.B ...]
|
||||
VG/RaidLV
|
||||
.br
|
||||
\[bu]
|
||||
Replace specific PV(s) in a raid* LV with another PV.
|
||||
.br
|
||||
\[bu]
|
||||
The replacement PV can be optionally specified, see below.
|
||||
The new PV(s) to use can be optionally specified after the LV.
|
||||
.br
|
||||
\[bu]
|
||||
Repeat to replace multiple: \-\-replace PV1 \-\-replace PV2 ...
|
||||
|
||||
.B lvconvert \-\-type snapshot
|
||||
VG/RaidLV
|
||||
@@ -216,7 +388,10 @@ VG/SnapshotLV
|
||||
Combine RaidLV with SnapshotLV that was previously split.
|
||||
.br
|
||||
\[bu]
|
||||
See \-\-splitsnapshot.
|
||||
Options \-\-chunksize, \-\-zero.
|
||||
.br
|
||||
\[bu]
|
||||
See corresponding operation \-\-splitsnapshot.
|
||||
|
||||
.B lvconvert \-\-type thin
|
||||
VG/RaidLV
|
||||
@@ -225,13 +400,13 @@ VG/RaidLV
|
||||
Convert RaidLV to type thin with an external origin.
|
||||
.br
|
||||
\[bu]
|
||||
Also specify a thin pool to use, see \-\-thinpool.
|
||||
.br
|
||||
\[bu]
|
||||
RaidLV becomes a read\-only external origin LV with a new name.
|
||||
.br
|
||||
\[bu]
|
||||
See \-\-originname.
|
||||
Requires \-\-thinpool to specify the thin pool to use.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-originname.
|
||||
|
||||
.B lvconvert \-\-type cache
|
||||
VG/RaidLV
|
||||
@@ -240,25 +415,42 @@ VG/RaidLV
|
||||
Convert RaidLV to type cache.
|
||||
.br
|
||||
\[bu]
|
||||
Also specify a cache pool to use, see \-\-cachepool.
|
||||
Requires \-\-cachepool to specify the cache pool to use.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-cachepolicy, \-\-cachesettings.
|
||||
|
||||
.B lvconvert \-\-type thin\-pool
|
||||
VG/RaidLV
|
||||
.br
|
||||
\[bu]
|
||||
Convert RaidLV to type thin\-pool.
|
||||
.br
|
||||
\[bu]
|
||||
The RaidLV is used for thin pool data.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-chunksize, \-\-discards, \-\-poolmetadata{size,spare},
|
||||
.br
|
||||
\-\-readahead, \-\-zero.
|
||||
|
||||
.B lvconvert \-\-type cache\-pool
|
||||
VG/RaidLV
|
||||
.br
|
||||
\[bu]
|
||||
Convert RaidLV to type cache\-pool.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-chunksize, \-\-poolmetadata{size,spare}.
|
||||
|
||||
.B lvconvert \-\-type raid*
|
||||
VG/RaidLV
|
||||
.br
|
||||
\[bu]
|
||||
Convert RaidLV to use a different raid level.
|
||||
.br
|
||||
\[bu]
|
||||
Required options depend on the raid level.
|
||||
|
||||
.B lvconvert \-\-type striped
|
||||
VG/RaidLV
|
||||
@@ -291,7 +483,7 @@ VG/MirrorLV
|
||||
Split images from MirrorLV and use them to create a new LV.
|
||||
.br
|
||||
\[bu]
|
||||
Also specify \-\-name for new LV.
|
||||
Requires \-\-name for the new LV.
|
||||
|
||||
.B lvconvert \-\-mirrorlog
|
||||
LogType
|
||||
@@ -299,9 +491,6 @@ VG/MirrorLV
|
||||
.br
|
||||
\[bu]
|
||||
Change the type of log used by MirrorLV.
|
||||
.br
|
||||
\[bu]
|
||||
See --mirrorlog and --corelog for log types.
|
||||
|
||||
.B lvconvert \-\-repair
|
||||
VG/MirrorLV
|
||||
@@ -322,7 +511,7 @@ VG/MirrorLV
|
||||
Convert MirrorLV to type raid*.
|
||||
.br
|
||||
\[bu]
|
||||
See lvmraid(7) for permitted raid levels.
|
||||
Required options depend on the raid level.
|
||||
|
||||
.SS Operations on CachePoolLV with type cache\-pool:
|
||||
|
||||
@@ -333,6 +522,9 @@ VG/CachePoolLV
|
||||
.br
|
||||
\[bu]
|
||||
Split the cache LV from CachePoolLV.
|
||||
.br
|
||||
\[bu]
|
||||
Equivalent to --splitcache on CacheLV.
|
||||
|
||||
.SS Operations on CacheLV with type cache:
|
||||
|
||||
@@ -361,7 +553,7 @@ Split images from the mirrored origin of CacheLV to create a new LV.
|
||||
Operates on mirror or raid1 sub LV.
|
||||
.br
|
||||
\[bu]
|
||||
Also specify \-\-name for new LV, or use \-\-trackchanges.
|
||||
Requires \-\-name for the new LV, or the use of \-\-trackchanges.
|
||||
|
||||
.B lvconvert \-\-type thin\-pool
|
||||
VG/CacheLV
|
||||
@@ -371,6 +563,11 @@ Convert CacheLV to type thin-pool.
|
||||
.br
|
||||
\[bu]
|
||||
The CacheLV is used for thin pool data.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-chunksize, \-\-discards, \-\-poolmetadata{size,spare},
|
||||
.br
|
||||
\-\-readahead, \-\-zero.
|
||||
|
||||
|
||||
.SS Operations on ThinPoolLV with type thin\-pool:
|
||||
@@ -409,6 +606,9 @@ Convert the data portion of ThinPoolLV to type cache.
|
||||
.br
|
||||
\[bu]
|
||||
Operates on the data sub LV of the thin pool LV.
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-cachepolicy, \-\-cachesettings.
|
||||
|
||||
.B lvconvert \-\-repair
|
||||
VG/ThinPoolLV
|
||||
@@ -422,13 +622,16 @@ Repair ThinPoolLV.
|
||||
|
||||
.B lvconvert \-\-merge
|
||||
VG/ThinLV
|
||||
./" FIXME: use --merge-snapshot
|
||||
.br
|
||||
\[bu]
|
||||
Merge ThinLV into its origin LV.
|
||||
.br
|
||||
\[bu]
|
||||
ThinLV must have been created as a snapshot of another thin LV.
|
||||
./" FIXME: use --merge-snapshot
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-background, \-\-interval.
|
||||
|
||||
.SS Operations on SnapshotLV with type snapshot:
|
||||
|
||||
@@ -442,10 +645,13 @@ Separate COW snapshot SnapshotLV from its origin LV.
|
||||
|
||||
.B lvconvert \-\-merge
|
||||
VG/SnapshotLV
|
||||
./" FIXME: use --merge-snapshot
|
||||
.br
|
||||
\[bu]
|
||||
Merge COW snapshot SnapshotLV into its origin.
|
||||
./" FIXME: use --merge-snapshot
|
||||
.br
|
||||
\[bu]
|
||||
Options \-\-background, \-\-interval.
|
||||
|
||||
.SH OPTIONS
|
||||
.
|
||||
@@ -525,6 +731,18 @@ It is an alias for \fB\-\-mirrorlog core\fP.
|
||||
Specifies if discards will be processed by the thin layer in the
|
||||
kernel and passed down to the Physical Volume. This applies only
|
||||
to thin pools. The default is \fBpassdown\fP.
|
||||
Also see
|
||||
.BR lvmthin (7).
|
||||
.
|
||||
.HP
|
||||
.BR \-H ,
|
||||
.BR \-\-cache
|
||||
.br
|
||||
Alias for
|
||||
.B \-\-type cache.
|
||||
See COMMANDS description for
|
||||
.br
|
||||
.B lvconvert \-\-type cache.
|
||||
.
|
||||
.HP
|
||||
.BR \-i ,
|
||||
@@ -587,8 +805,8 @@ This option is required when converting an LV to a \fBraid1\fP or
|
||||
This option can be used alone to change the number of mirror images in an
|
||||
existing \fBraid1\fP or \fBmirror\fP LV.
|
||||
|
||||
The special case \fB\-\-mirrors 0\fP indicates a linear LV with no mirror
|
||||
images.
|
||||
The special case \fB\-\-mirrors 0\fP has been used historically to
|
||||
indicate a linear LV with no mirror images.
|
||||
.
|
||||
.HP
|
||||
.BR \-n ,
|
||||
@@ -704,38 +922,43 @@ number of problems. Only inactive thin pools can be repaired. There is
|
||||
no validation of metadata between kernel and LVM. This requires further
|
||||
manual work. After successfull repair the old unmodified metadata are
|
||||
still available in "<pool>_meta<n>" LV.
|
||||
Also see
|
||||
.BR lvmthin (7).
|
||||
.
|
||||
.HP
|
||||
.BR \-\-replace
|
||||
.IR PhysicalVolume
|
||||
.br
|
||||
Remove the specified device (\fIPhysicalVolume\fP) and replace it with one
|
||||
Remove the specified device \fIPhysicalVolume\fP and replace it with one
|
||||
that is available in the VG, or from a specific list of PVs specified on
|
||||
the command line following the LV name. This option may be repeated multiple
|
||||
times depending on the RaidLV type. Maxima for raid1 are N-1 mirrors,
|
||||
for raid4/5 1 stripe, for raid6 2 stripes and for raid10 it is the number
|
||||
of stripes, i.e. one mirror in each mirror group. It is recommended to keep
|
||||
resilience whilst replacing PVs whenever possible, i.e. only replace a maximum
|
||||
of N-2 mirrors in a raid1 LV and 1 stripe in a raid6 LV at a time;
|
||||
this is not possible with raid4/5/10 LVs, because any single replaced PV
|
||||
will render the RaidLV non-resilient against another PV failure during replacement.
|
||||
.br
|
||||
(This option only applies to \fBraid*\fP LV types.)
|
||||
times depending on the RaidLV type.
|
||||
.
|
||||
.HP
|
||||
.BR \-s ,
|
||||
.BR \-\-snapshot
|
||||
.br
|
||||
Alias for
|
||||
.B \-\-type snapshot.
|
||||
See COMMANDS description for
|
||||
.br
|
||||
.B lvconvert \-\-type snapshot.
|
||||
.HP
|
||||
.BR \-\-split
|
||||
.br
|
||||
Separates \fISplitableLogicalVolume\fP.
|
||||
This option tries to detect the necessary split operation from its arguments.
|
||||
Avoid using this option and use one of the following instead:
|
||||
.B \-\-splitcache, \-\-splitmirror, \-\-splitsnapshot.
|
||||
.B \-\-splitcache, \-\-splitmirrors, \-\-splitsnapshot.
|
||||
.
|
||||
.HP
|
||||
.BR \-\-splitcache
|
||||
.br
|
||||
Separates a cache pool from a cache LV, and keeps the unused cache pool
|
||||
LV. Before the separation, the cache is flushed. Also see
|
||||
LV. Before the separation, the cache is flushed. See similar option
|
||||
.B \-\-uncache.
|
||||
Also see
|
||||
.BR lvmcache (7).
|
||||
.
|
||||
.HP
|
||||
.BR \-\-splitmirrors
|
||||
@@ -758,7 +981,7 @@ required without \fB\-\-trackchanges\fP).
|
||||
Separates a COW snapshot from its origin LV. The LV that is split off
|
||||
contains the chunks that differ from the origin LV along with metadata
|
||||
describing them. This LV can be wiped and then destroyed with lvremove.
|
||||
Also see
|
||||
See corresponding operation
|
||||
.B lvconvert \-\-type snapshot.
|
||||
.
|
||||
.HP
|
||||
@@ -766,10 +989,10 @@ Also see
|
||||
.IR Number
|
||||
.br
|
||||
Specifies the number of stripes in a striped LV. This is the number of
|
||||
physical volumes (devices) across which to spread a striped LV. Data that
|
||||
appears sequential in the LV is spread (striped) across multiple devices
|
||||
in units of the stripe size (see below). This does not apply to existing
|
||||
allocated space, only newly allocated space can be striped.
|
||||
physical volumes (devices) that a striped LV is spread across. Data that
|
||||
appears sequential in the LV is spread across multiple devices in units of
|
||||
the stripe size (see \fB\-\-stripesize\fP). This does not apply to
|
||||
existing allocated space, only newly allocated space can be striped.
|
||||
.
|
||||
.HP
|
||||
.BR \-I ,
|
||||
@@ -785,7 +1008,8 @@ and cannot exceed the VG physical extent (PE) size.
|
||||
.BR \-\-type
|
||||
.IR SegmentType
|
||||
.br
|
||||
Converts an LV from one segment type to another. See commmands above.
|
||||
Converts an LV from one segment type to another.
|
||||
See COMMANDS section for a description of converting between each type.
|
||||
.
|
||||
.HP
|
||||
.BR \-\-thinpool
|
||||
@@ -808,11 +1032,23 @@ changed data are resynchronized during merge. (This option only applies
|
||||
to the \fBraid1\fP LV type.)
|
||||
.
|
||||
.HP
|
||||
.BR \-T ,
|
||||
.BR \-\-thin
|
||||
.br
|
||||
Alias for
|
||||
.B \-\-type thin.
|
||||
See COMMANDS description for
|
||||
.br
|
||||
.B lvconvert \-\-type thin.
|
||||
.
|
||||
.HP
|
||||
.BR \-\-uncache
|
||||
.br
|
||||
Separates a cache pool from a cache LV, and removes the unused cache pool
|
||||
LV. Before the separation, the cache is flushed. Also see
|
||||
LV. Before the separation, the cache is flushed. See similar option
|
||||
.B \-\-splitcache.
|
||||
Also see
|
||||
.BR lvmcache (7).
|
||||
.
|
||||
.HP
|
||||
.BR \-Z ,
|
||||
@@ -824,28 +1060,10 @@ snapshot. If the LV is read\-only, the snapshot will not be zeroed.
|
||||
|
||||
For thin pools, this controls zeroing of provisioned blocks.
|
||||
Provisioning of large zeroed chunks negatively impacts performance.
|
||||
Also see
|
||||
.BR lvmthin (7).
|
||||
.
|
||||
|
||||
.SS Option aliases
|
||||
|
||||
.B \-\-type cache
|
||||
can be replaced with
|
||||
.B \-H
|
||||
or
|
||||
.B \-\-cache.
|
||||
|
||||
.B \-\-type thin
|
||||
can be replaced with
|
||||
.B \-T
|
||||
or
|
||||
.B \-\-thin.
|
||||
|
||||
.B \-\-type snapshot
|
||||
can be replaced with
|
||||
.B \-s
|
||||
or
|
||||
.B \-\-snapshot.
|
||||
|
||||
.SH Examples
|
||||
.
|
||||
Convert a linear LV to a two-way mirror LV:
|
||||
@@ -934,7 +1152,7 @@ metadata:
|
||||
|
||||
Convert an LV to a cache LV using the specified cache pool and chunk size:
|
||||
.br
|
||||
.B lvconvert \-\-cache \-\-cachepool vg/cpool1 \-c 128 vg/lvol1
|
||||
.B lvconvert \-\-type cache \-\-cachepool vg/cpool1 \-c 128 vg/lvol1
|
||||
|
||||
Detach and keep the cache pool from a cache LV:
|
||||
.br
|
||||
|
@@ -720,16 +720,17 @@ device sizes (GiB), thin provisioning should be used for this case.
|
||||
.BR \-W | \-\-wipesignatures
|
||||
.RB { y | n }
|
||||
.br
|
||||
Controls wiping of detected signatures on newly created Logical Volume.
|
||||
If this option is not specified, then by default signature wiping is done
|
||||
each time the zeroing (
|
||||
.BR \-Z | \-\-zero
|
||||
) is done. This default behaviour
|
||||
Controls detection and subsequent wiping of signatures on newly created
|
||||
Logical Volume. There's a prompt for each signature detected to confirm
|
||||
its wiping (unless \fB--yes\fP is used where LVM assumes 'yes' answer
|
||||
for each prompt automatically). If this option is not specified, then by
|
||||
default \fB-W\fP | \fB--wipesignatures y\fP is assumed each time the
|
||||
zeroing is done (\fB\-Z\fP | \fB\-\-zero y\fP). This default behaviour
|
||||
can be controlled by \fB\%allocation/wipe_signatures_when_zeroing_new_lvs\fP
|
||||
setting found in
|
||||
.BR lvm.conf (5).
|
||||
.br
|
||||
If blkid wiping is used \fBallocation/use_blkid_wiping\fP setting in
|
||||
If blkid wiping is used (\fBallocation/use_blkid_wiping\fP setting in
|
||||
.BR lvm.conf (5))
|
||||
and LVM2 is compiled with blkid wiping support, then \fBblkid\fP(8) library is used
|
||||
to detect the signatures (use \fBblkid \-k\fP command to list the signatures that are recognized).
|
||||
|
@@ -778,6 +778,10 @@ followed by the process ID and a startup timestamp using
|
||||
this format string "_%s_%d_%llu". When set, each process logs to a
|
||||
separate file.
|
||||
.TP
|
||||
.B LVM_LOG_FILE_MAX_LINES
|
||||
If more than this number of lines are sent to the log file, the command gets
|
||||
aborted. Automated tests use this to terminate looping commands.
|
||||
.TP
|
||||
.B LVM_EXPECTED_EXIT_STATUS
|
||||
The status anticipated when the process exits. Use ">N" to match any
|
||||
status greater than N. If the actual exit status matches and a log
|
||||
|
@@ -33,7 +33,7 @@
|
||||
|
||||
sbindir=@sbindir@
|
||||
script=blkdeactivate
|
||||
options="-u -l wholevg"
|
||||
options="-u -l wholevg -m disablequeueing"
|
||||
|
||||
LOCK_FILE="/var/lock/subsys/blk-availability"
|
||||
|
||||
|
@@ -7,7 +7,7 @@ Conflicts=shutdown.target
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/true
|
||||
ExecStop=@sbindir@/blkdeactivate -u -l wholevg
|
||||
ExecStop=@sbindir@/blkdeactivate -u -l wholevg -m disablequeueing
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
|
@@ -38,6 +38,7 @@ UMOUNT="/bin/umount"
|
||||
DMSETUP="@sbindir@/dmsetup"
|
||||
LVM="@sbindir@/lvm"
|
||||
MDADM="@sbindir@/mdadm"
|
||||
MPATHD="/sbin/multipathd"
|
||||
|
||||
if $UMOUNT --help | grep -- "--all-targets" >$DEV_DIR/null; then
|
||||
UMOUNT_OPTS="--all-targets "
|
||||
@@ -49,6 +50,7 @@ fi
|
||||
DMSETUP_OPTS=""
|
||||
LVM_OPTS=""
|
||||
MDADM_OPTS=""
|
||||
MPATHD_OPTS=""
|
||||
|
||||
LSBLK="/bin/lsblk -r --noheadings -o TYPE,KNAME,NAME,MOUNTPOINT"
|
||||
LSBLK_VARS="local devtype local kname local name local mnt"
|
||||
@@ -68,6 +70,9 @@ LVM_DO_WHOLE_VG=0
|
||||
# Do not retry LV deactivation by default.
|
||||
LVM_CONFIG="activation{retry_deactivation=0}"
|
||||
|
||||
# Do not disable queueing if set on multipath devices.
|
||||
MPATHD_DO_DISABLEQUEUEING=0
|
||||
|
||||
#
|
||||
# List of device names and/or VGs to be skipped.
|
||||
# Device name is the KNAME from lsblk output.
|
||||
@@ -107,20 +112,23 @@ usage() {
|
||||
echo " If devices are specified, deactivate only supplied devices and their holders."
|
||||
echo
|
||||
echo " Options:"
|
||||
echo " -e | --errors Show errors reported from tools"
|
||||
echo " -h | --help Show this help message"
|
||||
echo " -d | --dmoption DM_OPTIONS Comma separated DM specific options"
|
||||
echo " -l | --lvmoption LVM_OPTIONS Comma separated LVM specific options"
|
||||
echo " -u | --umount Unmount the device if mounted"
|
||||
echo " -v | --verbose Verbose mode (also implies -e)"
|
||||
echo " -e | --errors Show errors reported from tools"
|
||||
echo " -h | --help Show this help message"
|
||||
echo " -d | --dmoption DM_OPTIONS Comma separated DM specific options"
|
||||
echo " -l | --lvmoption LVM_OPTIONS Comma separated LVM specific options"
|
||||
echo " -m | --mpathoption MPATH_OPTIONS Comma separated DM-multipath specific options"
|
||||
echo " -u | --umount Unmount the device if mounted"
|
||||
echo " -v | --verbose Verbose mode (also implies -e)"
|
||||
echo
|
||||
echo " Device specific options:"
|
||||
echo " DM_OPTIONS:"
|
||||
echo " retry retry removal several times in case of failure"
|
||||
echo " force force device removal"
|
||||
echo " retry retry removal several times in case of failure"
|
||||
echo " force force device removal"
|
||||
echo " LVM_OPTIONS:"
|
||||
echo " retry retry removal several times in case of failure"
|
||||
echo " wholevg deactivate the whole VG when processing an LV"
|
||||
echo " retry retry removal several times in case of failure"
|
||||
echo " wholevg deactivate the whole VG when processing an LV"
|
||||
echo " MPATH_OPTIONS:"
|
||||
echo " disablequeueing disable queueing on all DM-multipath devices first"
|
||||
|
||||
exit
|
||||
}
|
||||
@@ -312,6 +320,11 @@ deactivate_all() {
|
||||
|
||||
echo "Deactivating block devices:"
|
||||
|
||||
test $MPATHD_RUNNING -eq 1 && {
|
||||
echo -n " [DM]: disabling queueing on all multipath devices... "
|
||||
eval $MPATHD $MPATHD_OPTS disablequeueing maps $ERR | grep '^ok$' >$DEV_DIR/null && echo "done" || echo "failed"
|
||||
}
|
||||
|
||||
if test $# -eq 0; then
|
||||
#######################
|
||||
# Process all devices #
|
||||
@@ -406,6 +419,20 @@ get_lvmopts() {
|
||||
IFS=$ORIG_IFS
|
||||
}
|
||||
|
||||
get_mpathopts() {
|
||||
ORIG_IFS=$IFS; IFS=','
|
||||
|
||||
for opt in $1; do
|
||||
case "$opt" in
|
||||
"") ;;
|
||||
"disablequeueing") MPATHD_DO_DISABLEQUEUEING=1 ;;
|
||||
*) echo "$opt: unknown DM-multipath option"
|
||||
esac
|
||||
done
|
||||
|
||||
IFS=$ORIG_IFS
|
||||
}
|
||||
|
||||
set_env() {
|
||||
if test "$ERRORS" -eq "1"; then
|
||||
unset ERR
|
||||
@@ -419,6 +446,7 @@ set_env() {
|
||||
DMSETUP_OPTS+="-vvvv"
|
||||
LVM_OPTS+="-vvvv"
|
||||
MDADM_OPTS+="-vv"
|
||||
MPATHD_OPTS+="-v 3"
|
||||
else
|
||||
OUT="1>$DEV_DIR/null"
|
||||
fi
|
||||
@@ -434,6 +462,15 @@ set_env() {
|
||||
else
|
||||
MDADM_AVAILABLE=0
|
||||
fi
|
||||
|
||||
MPATHD_RUNNING=0
|
||||
test $MPATHD_DO_DISABLEQUEUEING -eq 1 && {
|
||||
if test -f $MPATHD; then
|
||||
if eval $MPATHD show daemon $ERR | grep "running" >$DEVDIR/null; then
|
||||
MPATHD_RUNNING=1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
while test $# -ne 0; do
|
||||
@@ -443,6 +480,7 @@ while test $# -ne 0; do
|
||||
"-h"|"--help") usage ;;
|
||||
"-d"|"--dmoption ") get_dmopts "$2" ; shift ;;
|
||||
"-l"|"--lvmoption ") get_lvmopts "$2" ; shift ;;
|
||||
"-m"|"--mpathoption ") get_mpathopts "$2" ; shift ;;
|
||||
"-u"|"--umount") DO_UMOUNT=1 ;;
|
||||
"-v"|"--verbose") VERBOSE=1 ; ERRORS=1 ;;
|
||||
"-vv") VERBOSE=1 ; ERRORS=1 ; set -x ;;
|
||||
|
@@ -142,10 +142,10 @@ if (( $advanced )); then
|
||||
log "\"$LVM\" pvscan -v >> \"$dir/pvscan\" 2>> \"$log\""
|
||||
|
||||
myecho " lvs..."
|
||||
log "\"$LVM\" lvs -a -H -o +devices >> \"$dir/lvs\" 2>> \"$log\""
|
||||
log "\"$LVM\" lvs -a -H -o +devices,kernel_major,kernel_minor >> \"$dir/lvs\" 2>> \"$log\""
|
||||
|
||||
myecho " pvs..."
|
||||
log "\"$LVM\" pvs -a -v >> \"$dir/pvs\" 2>> \"$log\""
|
||||
log "\"$LVM\" pvs -a -o +major,minor -v >> \"$dir/pvs\" 2>> \"$log\""
|
||||
|
||||
myecho " vgs..."
|
||||
log "\"$LVM\" vgs -v >> \"$dir/vgs\" 2>> \"$log\""
|
||||
|
@@ -906,7 +906,6 @@ class TestLvm(unittest.TestCase):
|
||||
pvmeta_copies = [0, 1, 2]
|
||||
pvmeta_size = [0, 255, 512, 1024]
|
||||
data_alignment = [0, 2048, 4096]
|
||||
data_alignment_offset = [1, 1, 1]
|
||||
zero = [0, 1]
|
||||
|
||||
device_names = TestLvm._get_pv_device_names()
|
||||
@@ -927,27 +926,13 @@ class TestLvm(unittest.TestCase):
|
||||
|
||||
#Try a number of combinations and permutations
|
||||
for s in size:
|
||||
lvm.pvCreate(d, s)
|
||||
lvm.pvRemove(d)
|
||||
for copies in pvmeta_copies:
|
||||
lvm.pvCreate(d, s, copies)
|
||||
lvm.pvRemove(d)
|
||||
for pv_size in pvmeta_size:
|
||||
lvm.pvCreate(d, s, copies, pv_size)
|
||||
lvm.pvRemove(d)
|
||||
for align in data_alignment:
|
||||
lvm.pvCreate(d, s, copies, pv_size, align)
|
||||
lvm.pvRemove(d)
|
||||
for align_offset in data_alignment_offset:
|
||||
lvm.pvCreate(
|
||||
d, s, copies, pv_size, align,
|
||||
align * align_offset)
|
||||
for z in zero:
|
||||
lvm.pvCreate(d, s, copies, pv_size, align,
|
||||
align, z)
|
||||
lvm.pvRemove(d)
|
||||
for z in zero:
|
||||
lvm.pvCreate(
|
||||
d, s, copies, pv_size, align,
|
||||
align * align_offset, z)
|
||||
lvm.pvRemove(d)
|
||||
|
||||
#Restore
|
||||
for d in device_names:
|
||||
|
@@ -169,7 +169,7 @@ prepare_clvmd() {
|
||||
rm -f "$CLVMD_PIDFILE"
|
||||
echo "<======== Starting CLVMD ========>"
|
||||
# lvs is executed from clvmd - use our version
|
||||
LVM_LOG_FILE_EPOCH=CLVMD LVM_BINARY=$(which lvm) $run_valgrind clvmd -Isinglenode -d 1 -f &
|
||||
LVM_LOG_FILE_EPOCH=CLVMD LVM_LOG_FILE_MAX_LINES=1000000 LVM_BINARY=$(which lvm) $run_valgrind clvmd -Isinglenode -d 1 -f &
|
||||
echo $! > LOCAL_CLVMD
|
||||
|
||||
for i in {1..100} ; do
|
||||
|
@@ -58,6 +58,7 @@ RUNNING_DMEVENTD=$(pgrep dmeventd || true)
|
||||
|
||||
export TESTOLDPWD TESTDIR COMMON_PREFIX PREFIX RUNNING_DMEVENTD
|
||||
export LVM_LOG_FILE_EPOCH=DEBUG
|
||||
export LVM_LOG_FILE_MAX_LINES=100000
|
||||
export LVM_EXPECTED_EXIT_STATUS=1
|
||||
|
||||
test -n "$BASH" && trap 'set +vx; STACKTRACE; set -vx' ERR
|
||||
|
@@ -16,7 +16,7 @@ SKIP_WITH_LVMPOLLD=1
|
||||
|
||||
. lib/inittest
|
||||
|
||||
aux have_cache 1 3 0 || skip
|
||||
aux have_cache 1 5 0 || skip
|
||||
|
||||
aux prepare_vg 2
|
||||
|
||||
|
@@ -33,6 +33,10 @@ not lvchange --cachesettings foo=bar $vg/noncache
|
||||
lvchange --cachepolicy cleaner $vg/corigin
|
||||
check lv_field $vg/corigin kernel_cache_policy "cleaner"
|
||||
|
||||
# Skip these test on older cache driver as it shows errors with these lvchanges
|
||||
# device-mapper: space map common: index_check failed: blocknr 17179869216 != wanted 11
|
||||
if aux have_cache 1 5 0 ; then
|
||||
|
||||
lvchange --cachepolicy mq --cachesettings migration_threshold=333 $vg/corigin
|
||||
|
||||
# TODO once mq->smq happens we will get here some 0 for mq settings
|
||||
@@ -86,4 +90,6 @@ else
|
||||
grep 'sequential_threshold=0' out
|
||||
fi
|
||||
|
||||
fi # have_cache 1 5 0
|
||||
|
||||
vgremove -f $vg
|
||||
|
@@ -144,7 +144,7 @@ lvcreate -H -L 4 -n corigin --cachepool $vg/cpool
|
||||
|
||||
# unsupported yet
|
||||
fail lvconvert --repair $vg/cpool 2>&1 | tee out
|
||||
grep "Cannot convert internal LV" out
|
||||
#grep "Cannot convert internal LV" out
|
||||
|
||||
lvremove -f $vg
|
||||
|
||||
|
41
test/shell/lvcreate-cache-fail.sh
Normal file
41
test/shell/lvcreate-cache-fail.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2016 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
# of the GNU General Public License v.2.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# Exercise creation of cache and cache pool volumes and failure path
|
||||
# https://bugzilla.redhat.com/1355923
|
||||
|
||||
SKIP_WITH_LVMLOCKD=1
|
||||
SKIP_WITH_LVMPOLLD=1
|
||||
|
||||
. lib/inittest
|
||||
|
||||
aux have_cache 1 3 0 || skip
|
||||
|
||||
#aux prepare_pvs 1 4707950
|
||||
#vgcreate $vg "$dev1"
|
||||
#lvcreate -L4T -n $lv1 $vg
|
||||
#lvcreate -H -L500G -n cache $vg/$lv1
|
||||
#fail lvcreate -H -l 127999 -n cache $vg/$lv1
|
||||
|
||||
aux prepare_vg 1 20
|
||||
lvcreate -L10 -n $lv1 $vg
|
||||
fail lvcreate -H -L2 -n cache $vg/$lv1
|
||||
|
||||
lvs -a $vg
|
||||
vgs $vg
|
||||
lvdisplay $vg
|
||||
|
||||
#dmsetup table
|
||||
#dmsetup status
|
||||
#time dmsetup suspend ${vg}-${lv1}
|
||||
#time dmsetup resume ${vg}-${lv1}
|
||||
|
||||
vgremove -ff $vg
|
69
test/shell/lvresize-full.sh
Normal file
69
test/shell/lvresize-full.sh
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2016 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
# of the GNU General Public License v.2.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# Excersize resize of filesystem when size of LV already matches
|
||||
# https://bugzilla.redhat.com/1354396
|
||||
|
||||
SKIP_WITH_LVMLOCKD=1
|
||||
SKIP_WITH_LVMPOLLD=1
|
||||
|
||||
. lib/inittest
|
||||
|
||||
FSCK=${FSCK-fsck}
|
||||
MKFS=${MKFS-mkfs.ext3}
|
||||
RESIZEFS=${RESIZEFS-resize2fs}
|
||||
|
||||
which $FSCK || skip
|
||||
which $MKFS || skip
|
||||
which $RESIZEFS || skip
|
||||
|
||||
aux prepare_vg 2 20
|
||||
|
||||
lvcreate -l100%FREE -n $lv1 $vg
|
||||
|
||||
lvdev="$DM_DEV_DIR/$vg/$lv1"
|
||||
|
||||
lvs -a $vg
|
||||
|
||||
"$MKFS" "$lvdev"
|
||||
|
||||
# this should resolve to resize to same actual size
|
||||
lvreduce -r -f -l-100%FREE $vg/$lv1
|
||||
"$FSCK" -n "$lvdev"
|
||||
|
||||
# size should remain the same
|
||||
lvextend -r -f -l+100%FREE $vg/$lv1
|
||||
"$FSCK" -n "$lvdev"
|
||||
|
||||
#lvchange -an $vg/$lv1
|
||||
lvresize -r -f -l+100%FREE $vg/$lv1
|
||||
"$FSCK" -n "$lvdev"
|
||||
|
||||
# Check there is really file system resize happening
|
||||
# even when LV itself has still the same size
|
||||
"$RESIZEFS" -f "$lvdev" 20000
|
||||
"$FSCK" -n "$lvdev" | tee out
|
||||
grep "20000 blocks" out
|
||||
|
||||
SIZE=$(get lv_field $vg/$lv1 size)
|
||||
lvresize -r -f -l-100%FREE $vg/$lv1
|
||||
test "$SIZE" = "$(get lv_field $vg/$lv1 size)"
|
||||
|
||||
"$FSCK" -n "$lvdev" | tee out
|
||||
grep -v "20000 blocks" out
|
||||
|
||||
|
||||
# Also check it fails when the user 'resize' volume without
|
||||
# resizing fs and then retries with '-r'.
|
||||
lvreduce -f -l50%VG $vg/$lv1
|
||||
fail lvresize -r -f -l50%VG $vg/$lv1
|
||||
|
||||
lvremove -ff $vg
|
132
tools/dmsetup.c
132
tools/dmsetup.c
@@ -4768,6 +4768,56 @@ static uint64_t _nr_areas_from_step(uint64_t len, int64_t step)
|
||||
return (len / step) + !!(len % (uint64_t) step);
|
||||
}
|
||||
|
||||
/* maximum length of a string representation of an integer */
|
||||
#define max_int_strlen(i) (strlen(#i))
|
||||
#define MAX_UINT64_STRLEN max_int_strlen(UINT64_MAX)
|
||||
static int _stats_group_segments(struct dm_stats *dms, uint64_t *region_ids,
|
||||
int count, const char *alias)
|
||||
{
|
||||
/* NULL, commas, and count * region_id */
|
||||
size_t bufsize = 1 + count + count * MAX_UINT64_STRLEN;
|
||||
char *this_region, *regions = NULL;
|
||||
uint64_t group_id;
|
||||
int r, i;
|
||||
|
||||
this_region = regions = dm_malloc(bufsize);
|
||||
|
||||
if (!regions) {
|
||||
log_error("Could not allocate memory for region_id table.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
/*
|
||||
* We don't expect large numbers of segments (compared to e.g.
|
||||
* --filemap): use a fixed-size buffer based on the number of
|
||||
* region identifiers and do not collapse continuous ranges
|
||||
* of identifiers in the group descriptor argument.
|
||||
*/
|
||||
r = dm_snprintf(this_region, bufsize, FMTu64 "%s", region_ids[i],
|
||||
(i < (count - 1)) ? "," : "");
|
||||
if (r < 0)
|
||||
goto_bad;
|
||||
this_region += r;
|
||||
bufsize -= r;
|
||||
}
|
||||
|
||||
/* refresh handle */
|
||||
if (!(r = dm_stats_list(dms, NULL)))
|
||||
goto bad;
|
||||
|
||||
if ((r = dm_stats_create_group(dms, regions, alias, &group_id)))
|
||||
printf("Grouped regions %s as group ID " FMTu64 "%s%s\n",
|
||||
regions, group_id, (alias) ? " with alias " : "",
|
||||
(alias) ? : "");
|
||||
else
|
||||
log_error("Failed to create group for regions %s", regions);
|
||||
|
||||
bad:
|
||||
dm_free(regions);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a single region starting at start and spanning len sectors,
|
||||
* or, if the segments argument is no-zero create one region for each
|
||||
@@ -4784,8 +4834,9 @@ static int _do_stats_create_regions(struct dm_stats *dms,
|
||||
{
|
||||
uint64_t this_start = 0, this_len = len, region_id = UINT64_C(0);
|
||||
const char *devname = NULL, *histogram = _string_args[BOUNDS_ARG];
|
||||
int r = 0, precise = _switches[PRECISE_ARG];
|
||||
int r = 0, count = 0, precise = _switches[PRECISE_ARG];
|
||||
struct dm_histogram *bounds = NULL; /* histogram bounds */
|
||||
uint64_t *region_ids = NULL; /* segments */
|
||||
char *target_type, *params; /* unused */
|
||||
struct dm_task *dmt;
|
||||
struct dm_info info;
|
||||
@@ -4794,6 +4845,12 @@ static int _do_stats_create_regions(struct dm_stats *dms,
|
||||
if (histogram && !(bounds = dm_histogram_bounds_from_string(histogram)))
|
||||
return_0;
|
||||
|
||||
if (_switches[ALIAS_ARG] && _switches[NOGROUP_ARG]) {
|
||||
log_error("Cannot set alias with --nogroup.");
|
||||
dm_stats_destroy(dms);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) {
|
||||
dm_histogram_bounds_destroy(bounds);
|
||||
dm_stats_destroy(dms);
|
||||
@@ -4818,6 +4875,11 @@ static int _do_stats_create_regions(struct dm_stats *dms,
|
||||
if (!(devname = dm_task_get_name(dmt)))
|
||||
goto_out;
|
||||
|
||||
if (!segments || (info.target_count == 1))
|
||||
region_ids = ®ion_id;
|
||||
else
|
||||
region_ids = dm_malloc(info.target_count * sizeof(*region_ids));
|
||||
|
||||
do {
|
||||
uint64_t segment_start, segment_len;
|
||||
next = dm_get_next_target(dmt, next, &segment_start, &segment_len,
|
||||
@@ -4838,10 +4900,10 @@ static int _do_stats_create_regions(struct dm_stats *dms,
|
||||
*/
|
||||
this_start = (segments) ? segment_start : start;
|
||||
this_len = (segments) ? segment_len : this_len;
|
||||
if (!dm_stats_create_region(dms, ®ion_id,
|
||||
this_start, this_len, step,
|
||||
precise, bounds,
|
||||
program_id, user_data)) {
|
||||
if (!(r = dm_stats_create_region(dms, ®ion_ids[count],
|
||||
this_start, this_len, step,
|
||||
precise, bounds,
|
||||
program_id, user_data))) {
|
||||
log_error("%s: Could not create statistics region.",
|
||||
devname);
|
||||
goto out;
|
||||
@@ -4849,12 +4911,19 @@ static int _do_stats_create_regions(struct dm_stats *dms,
|
||||
|
||||
printf("%s: Created new region with "FMTu64" area(s) as "
|
||||
"region ID "FMTu64"\n", devname,
|
||||
_nr_areas_from_step(this_len, step), region_id);
|
||||
_nr_areas_from_step(this_len, step),
|
||||
region_ids[count++]);
|
||||
}
|
||||
} while (next);
|
||||
r = 1;
|
||||
|
||||
if (!_switches[NOGROUP_ARG] && segments)
|
||||
r = _stats_group_segments(dms, region_ids, count,
|
||||
_string_args[ALIAS_ARG]);
|
||||
|
||||
out:
|
||||
if (region_ids != ®ion_id)
|
||||
dm_free(region_ids);
|
||||
|
||||
dm_task_destroy(dmt);
|
||||
dm_stats_destroy(dms);
|
||||
dm_histogram_bounds_destroy(bounds);
|
||||
@@ -4882,7 +4951,9 @@ static char *_get_abspath(const char *path)
|
||||
static int _stats_create_file(CMD_ARGS)
|
||||
{
|
||||
const char *alias, *program_id = DM_STATS_PROGRAM_ID;
|
||||
const char *histogram = _string_args[BOUNDS_ARG];
|
||||
uint64_t *regions, *region, count = 0;
|
||||
struct dm_histogram *bounds = NULL;
|
||||
char *path, *abspath = NULL;
|
||||
int group, fd, precise;
|
||||
struct dm_stats *dms;
|
||||
@@ -4907,24 +4978,20 @@ static int _stats_create_file(CMD_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_switches[BOUNDS_ARG]) {
|
||||
log_error("--bounds is not yet supported with --filemap.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* _stats_create_file does not use _process_all() */
|
||||
if (names) {
|
||||
log_error("Device argument not compatible with --filemap.");
|
||||
if (names || !argc) {
|
||||
log_error("--filemap requires a file path argument");
|
||||
return 0;
|
||||
} else {
|
||||
if (argc || _switches[UUID_ARG] || _switches[MAJOR_ARG]) {
|
||||
log_error("--uuid, --major, and device argument are "
|
||||
"incompatible with --filemap.");
|
||||
return 0;
|
||||
}
|
||||
if (_switches[ALL_DEVICES_ARG]) {
|
||||
log_error("--alldevices is incompatible with "
|
||||
"--filemap.");
|
||||
if (argc)
|
||||
path = argv[0];
|
||||
else {
|
||||
if (_switches[UUID_ARG] || _switches[MAJOR_ARG])
|
||||
log_error("--uuid and --major are incompatible "
|
||||
"with --filemap.");
|
||||
if (_switches[ALL_DEVICES_ARG])
|
||||
log_error("--alldevices is incompatible with "
|
||||
"--filemap.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -4945,12 +5012,14 @@ static int _stats_create_file(CMD_ARGS)
|
||||
}
|
||||
}
|
||||
|
||||
if (histogram && !(bounds = dm_histogram_bounds_from_string(histogram)))
|
||||
return_0;
|
||||
|
||||
if (_switches[PROGRAM_ID_ARG])
|
||||
program_id = _string_args[PROGRAM_ID_ARG];
|
||||
if (!strlen(program_id) && !_switches[FORCE_ARG])
|
||||
program_id = DM_STATS_PROGRAM_ID;
|
||||
|
||||
path = _string_args[FILEMAP_ARG];
|
||||
precise = _int_args[PRECISE_ARG];
|
||||
group = !_switches[NOGROUP_ARG];
|
||||
|
||||
@@ -4965,7 +5034,7 @@ static int _stats_create_file(CMD_ARGS)
|
||||
fd = open(abspath, O_RDONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
log_error("Could not open %s for reading", path);
|
||||
log_error("Could not open %s for reading", abspath);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@@ -4988,21 +5057,20 @@ static int _stats_create_file(CMD_ARGS)
|
||||
}
|
||||
|
||||
regions = dm_stats_create_regions_from_fd(dms, fd, group, precise,
|
||||
NULL, alias);
|
||||
bounds, alias);
|
||||
|
||||
if (close(fd))
|
||||
log_error("Error closing %s", path);
|
||||
log_error("Error closing %s", abspath);
|
||||
|
||||
fd = -1;
|
||||
|
||||
if (!regions) {
|
||||
log_error("Could not create regions from file %s", path);
|
||||
log_error("Could not create regions from file %s", abspath);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
for (region = regions; *region != DM_STATS_REGIONS_ALL; region++) {
|
||||
for (region = regions; *region != DM_STATS_REGIONS_ALL; region++)
|
||||
count++;
|
||||
}
|
||||
|
||||
if (group) {
|
||||
printf("%s: Created new group with "FMTu64" region(s) as "
|
||||
@@ -6161,7 +6229,7 @@ static int _process_switches(int *argcp, char ***argvp, const char *dev_dir)
|
||||
{"deferred", 0, &ind, DEFERRED_ARG},
|
||||
{"select", 1, &ind, SELECT_ARG},
|
||||
{"exec", 1, &ind, EXEC_ARG},
|
||||
{"filemap", 1, &ind, FILEMAP_ARG},
|
||||
{"filemap", 0, &ind, FILEMAP_ARG},
|
||||
{"force", 0, &ind, FORCE_ARG},
|
||||
{"gid", 1, &ind, GID_ARG},
|
||||
{"group", 0, &ind, GROUP_ARG},
|
||||
@@ -6326,10 +6394,8 @@ static int _process_switches(int *argcp, char ***argvp, const char *dev_dir)
|
||||
_switches[CLEAR_ARG]++;
|
||||
if (c == 'c' || c == 'C' || ind == COLS_ARG)
|
||||
_switches[COLS_ARG]++;
|
||||
if (ind == FILEMAP_ARG) {
|
||||
if (ind == FILEMAP_ARG)
|
||||
_switches[FILEMAP_ARG]++;
|
||||
_string_args[FILEMAP_ARG] = optarg;
|
||||
}
|
||||
if (c == 'f' || ind == FORCE_ARG)
|
||||
_switches[FORCE_ARG]++;
|
||||
if (c == 'r' || ind == READ_ONLY)
|
||||
|
@@ -20,11 +20,8 @@ static int _get_vsn(struct cmd_context *cmd, uint16_t *version_int)
|
||||
const char *vsn;
|
||||
unsigned int major, minor, patchlevel;
|
||||
|
||||
if (arg_is_set(cmd, atversion_ARG))
|
||||
vsn = arg_str_value(cmd, atversion_ARG, NULL);
|
||||
else if (arg_is_set(cmd, sinceversion_ARG))
|
||||
vsn = arg_str_value(cmd, sinceversion_ARG, NULL);
|
||||
else
|
||||
if (!(vsn = arg_str_value(cmd, atversion_ARG, NULL)) &&
|
||||
!(vsn = arg_str_value(cmd, sinceversion_ARG, NULL)))
|
||||
vsn = LVM_VERSION;
|
||||
|
||||
if (sscanf(vsn, "%u.%u.%u", &major, &minor, &patchlevel) != 3) {
|
||||
|
@@ -326,8 +326,9 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
|
||||
dm_list_init(&device_list);
|
||||
|
||||
if (!seg_is_mirror(seg) && !seg_is_raid(seg)) {
|
||||
log_error("Unable to resync %s. It is not RAID or mirrored.",
|
||||
if (seg_is_any_raid0(seg) ||
|
||||
(!seg_is_mirror(seg) && !seg_is_raid(seg))) {
|
||||
log_error("Unable to resync %s. It is not RAID4/5/6/10 or mirrored.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
@@ -403,7 +404,7 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
* worry about persistent logs.
|
||||
*/
|
||||
if (!seg_is_raid(seg) && !seg->log_lv) {
|
||||
if (lv->status & LV_NOTSYNCED) {
|
||||
if (lv_is_not_synced(lv)) {
|
||||
lv->status &= ~LV_NOTSYNCED;
|
||||
log_very_verbose("Updating logical volume %s on disk(s).",
|
||||
display_lvname(lv));
|
||||
@@ -1179,9 +1180,17 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
!_lvchange_resync(cmd, lv))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
if (arg_is_set(cmd, syncaction_ARG) &&
|
||||
!lv_raid_message(lv, arg_str_value(cmd, syncaction_ARG, NULL)))
|
||||
return_ECMD_FAILED;
|
||||
if (arg_is_set(cmd, syncaction_ARG)) {
|
||||
struct lv_segment *seg = first_seg(lv);
|
||||
|
||||
if (seg_is_any_raid0(seg)) {
|
||||
log_error("Unable to sync raid0 LV %s.", display_lvname(lv));
|
||||
return_ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (!lv_raid_message(lv, arg_str_value(cmd, syncaction_ARG, NULL)))
|
||||
return_ECMD_FAILED;
|
||||
}
|
||||
|
||||
/* activation change */
|
||||
if (arg_is_set(cmd, activate_ARG)) {
|
||||
|
@@ -359,6 +359,7 @@ static int _read_pool_params(struct cmd_context *cmd, int *pargc, char ***pargv,
|
||||
log_error("--cache requires --cachepool.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((lp->cache || cachepool) &&
|
||||
!get_cache_params(cmd, &lp->cache_mode, &lp->policy_name, &lp->policy_settings)) {
|
||||
log_error("Failed to parse cache policy and/or settings.");
|
||||
@@ -636,15 +637,15 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
return_0;
|
||||
} else if (lp->splitsnapshot) /* Destroy snapshot retaining cow as separate LV */
|
||||
;
|
||||
else if (lp->splitcache)
|
||||
else if (lp->splitcache)
|
||||
;
|
||||
else if (lp->split)
|
||||
else if (lp->split)
|
||||
;
|
||||
else if (lp->uncache)
|
||||
else if (lp->uncache)
|
||||
;
|
||||
else if (lp->cache)
|
||||
else if (lp->cache)
|
||||
;
|
||||
else if (lp->thin)
|
||||
else if (lp->thin)
|
||||
;
|
||||
else if (lp->keep_mimages) /* --splitmirrors */
|
||||
;
|
||||
@@ -726,7 +727,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
if (arg_is_set(cmd, regionsize_ARG)) {
|
||||
if (arg_sign_value(cmd, regionsize_ARG, SIGN_NONE) ==
|
||||
SIGN_MINUS) {
|
||||
log_error("Negative regionsize is invalid");
|
||||
log_error("Negative regionsize is invalid.");
|
||||
return 0;
|
||||
}
|
||||
lp->region_size = arg_uint_value(cmd, regionsize_ARG, 0);
|
||||
@@ -734,7 +735,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
region_size = get_default_region_size(cmd);
|
||||
if (region_size < 0) {
|
||||
log_error("Negative regionsize in "
|
||||
"configuration file is invalid");
|
||||
"configuration file is invalid.");
|
||||
return 0;
|
||||
}
|
||||
lp->region_size = region_size;
|
||||
@@ -743,14 +744,14 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
if (lp->region_size % (pagesize >> SECTOR_SHIFT)) {
|
||||
log_error("Region size (%" PRIu32 ") must be "
|
||||
"a multiple of machine memory "
|
||||
"page size (%d)",
|
||||
"page size (%d).",
|
||||
lp->region_size, pagesize >> SECTOR_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!is_power_of_2(lp->region_size)) {
|
||||
log_error("Region size (%" PRIu32
|
||||
") must be a power of 2", lp->region_size);
|
||||
") must be a power of 2.", lp->region_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -773,7 +774,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
/* changing mirror type? */
|
||||
if (!(lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL)))))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
} else if (_raid0_type_requested(cmd, lp->type_str) || _striped_type_requested(cmd, lp->type_str)) { /* striped or linear or raid0 */
|
||||
if (arg_from_list_is_set(cmd, "cannot be used with --type raid0 or --type striped or --type linear",
|
||||
chunksize_ARG, corelog_ARG, mirrors_ARG, mirrorlog_ARG, regionsize_ARG, zero_ARG,
|
||||
@@ -798,7 +799,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
if (activation() && lp->segtype && lp->segtype->ops->target_present &&
|
||||
!lp->segtype->ops->target_present(cmd, NULL, &lp->target_attr)) {
|
||||
log_error("%s: Required device-mapper target(s) not "
|
||||
"detected in your kernel", lp->segtype->name);
|
||||
"detected in your kernel.", lp->segtype->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1171,8 +1172,8 @@ static int _lv_update_log_type(struct cmd_context *cmd,
|
||||
return_0;
|
||||
/*
|
||||
* FIXME: This simple approach won't work in cluster mirrors,
|
||||
* but it doesn't matter because we don't support
|
||||
* mirrored logs in cluster mirrors.
|
||||
* but it doesn't matter because we don't support
|
||||
* mirrored logs in cluster mirrors.
|
||||
*/
|
||||
if (old_log_count &&
|
||||
!lv_update_and_reload(log_lv))
|
||||
@@ -1231,7 +1232,7 @@ static void _remove_missing_empty_pv(struct volume_group *vg, struct dm_list *re
|
||||
* 2) Parses the CLI args to find the new desired values
|
||||
* 3) Adjusts 'lp->mirrors' to the appropriate absolute value.
|
||||
* (Remember, 'lp->mirrors' is specified in terms of the number of "copies"
|
||||
* vs. the number of mimages. It can also be a relative value.)
|
||||
* vs. the number of mimages. It can also be a relative value.)
|
||||
* 4) Sets 'lp->need_polling' if collapsing
|
||||
* 5) Validates other mirror params
|
||||
*
|
||||
@@ -1326,11 +1327,11 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
|
||||
* log daemon is multi-threaded.
|
||||
*/
|
||||
if ((*new_log_count == MIRROR_LOG_MIRRORED) && vg_is_clustered(lv->vg)) {
|
||||
log_error("Log type, \"mirrored\", is unavailable to cluster mirrors");
|
||||
log_error("Log type, \"mirrored\", is unavailable to cluster mirrors.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_verbose("Setting logging type to %s", get_mirror_log_name(*new_log_count));
|
||||
log_verbose("Setting logging type to %s.", get_mirror_log_name(*new_log_count));
|
||||
|
||||
/*
|
||||
* Region size must not change on existing mirrors
|
||||
@@ -1348,14 +1349,13 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
|
||||
*/
|
||||
if (lv_is_mirrored(lv) && dm_list_size(&lv->segments) != 1) {
|
||||
log_error("Logical volume %s has multiple "
|
||||
"mirror segments.", lv->name);
|
||||
"mirror segments.", display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _lvconvert_mirrors_aux
|
||||
*
|
||||
@@ -1378,7 +1378,7 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
|
||||
|
||||
if ((lp->mirrors == 1) && !lv_is_mirrored(lv)) {
|
||||
log_warn("Logical volume %s is already not mirrored.",
|
||||
lv->name);
|
||||
display_lvname(lv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1418,7 +1418,7 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
|
||||
* Up-convert m-way mirror to n-way mirror
|
||||
*/
|
||||
if (new_mimage_count > old_mimage_count) {
|
||||
if (lv->status & LV_NOTSYNCED) {
|
||||
if (lv_is_not_synced(lv)) {
|
||||
log_error("Can't add mirror to out-of-sync mirrored "
|
||||
"LV: use lvchange --resync first.");
|
||||
return 0;
|
||||
@@ -1433,7 +1433,7 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
|
||||
*/
|
||||
if (lv_is_origin(lv)) {
|
||||
log_error("Can't add additional mirror images to "
|
||||
"mirrors that are under snapshots");
|
||||
"mirrors that are under snapshots,");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1443,7 +1443,7 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
|
||||
*/
|
||||
if (find_temporary_mirror(lv) || lv_is_converting(lv)) {
|
||||
log_error("%s is already being converted. Unable to start another conversion.",
|
||||
lv->name);
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1459,7 +1459,7 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
|
||||
/* Insert a temporary layer for syncing,
|
||||
* only if the original lv is using disk log. */
|
||||
if (seg->log_lv && !_insert_lvconvert_layer(cmd, lv)) {
|
||||
log_error("Failed to insert resync layer");
|
||||
log_error("Failed to insert resync layer.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1477,7 +1477,7 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
|
||||
!vg_commit(lv->vg)) {
|
||||
log_error("ABORTING: Failed to remove "
|
||||
"temporary mirror layer %s.",
|
||||
layer_lv->name);
|
||||
display_lvname(layer_lv));
|
||||
log_error("Manual cleanup with vgcfgrestore "
|
||||
"and dmsetup may be required.");
|
||||
return 0;
|
||||
@@ -1505,7 +1505,7 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
|
||||
if (lp->keep_mimages) {
|
||||
if (arg_is_set(cmd, trackchanges_ARG)) {
|
||||
log_error("--trackchanges is not available "
|
||||
"to 'mirror' segment type");
|
||||
"to 'mirror' segment type.");
|
||||
return 0;
|
||||
}
|
||||
if (!lv_split_mirror_images(lv, lp->lv_split_name,
|
||||
@@ -1548,7 +1548,7 @@ int mirror_remove_missing(struct cmd_context *cmd,
|
||||
if (force && _failed_mirrors_count(lv) == (int)lv_mirror_count(lv)) {
|
||||
log_error("No usable images left in %s.", display_lvname(lv));
|
||||
return lv_remove_with_dependencies(cmd, lv, DONT_PROMPT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We must adjust the log first, or the entire mirror
|
||||
@@ -1692,6 +1692,7 @@ static int _lvconvert_validate_thin(struct logical_volume *lv,
|
||||
display_lvname(seg_lv(first_seg(lv), 0)));
|
||||
log_error("For pool metadata volume conversion use %s.",
|
||||
display_lvname(first_seg(lv)->metadata_lv));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1713,7 +1714,7 @@ static int _lvconvert_mirrors(struct cmd_context *cmd,
|
||||
|
||||
if (lp->merge_mirror) {
|
||||
log_error("Unable to merge mirror images"
|
||||
"of segment type 'mirror'");
|
||||
"of segment type 'mirror'.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1750,14 +1751,14 @@ static int _lvconvert_mirrors(struct cmd_context *cmd,
|
||||
&new_mimage_count, &new_log_count))
|
||||
return 0;
|
||||
|
||||
if (((old_mimage_count < new_mimage_count && old_log_count > new_log_count) ||
|
||||
(old_mimage_count > new_mimage_count && old_log_count < new_log_count)) &&
|
||||
lp->pv_count) {
|
||||
if (((old_mimage_count < new_mimage_count && old_log_count > new_log_count) ||
|
||||
(old_mimage_count > new_mimage_count && old_log_count < new_log_count)) &&
|
||||
lp->pv_count) {
|
||||
log_error("Cannot both allocate and free extents when "
|
||||
"specifying physical volumes to use.");
|
||||
log_error("Please specify the operation in two steps.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Nothing to do? (Probably finishing collapse.) */
|
||||
if ((old_mimage_count == new_mimage_count) &&
|
||||
@@ -1772,9 +1773,11 @@ static int _lvconvert_mirrors(struct cmd_context *cmd,
|
||||
return 0;
|
||||
|
||||
if (!lp->need_polling)
|
||||
log_print_unless_silent("Logical volume %s converted.", lv->name);
|
||||
log_print_unless_silent("Logical volume %s converted.",
|
||||
display_lvname(lv));
|
||||
|
||||
backup(lv->vg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1845,7 +1848,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||
|
||||
/* Can only change image count for raid1 and linear */
|
||||
if (lp->mirrors_supplied && !seg_is_mirrored(seg) && !seg_is_linear(seg)) {
|
||||
log_error("'--mirrors/-m' is not compatible with %s",
|
||||
log_error("'--mirrors/-m' is not compatible with %s.",
|
||||
lvseg_name(seg));
|
||||
return 0;
|
||||
}
|
||||
@@ -1854,14 +1857,14 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||
return_0;
|
||||
|
||||
if (!_is_valid_raid_conversion(seg->segtype, lp->segtype)) {
|
||||
log_error("Unable to convert %s/%s from %s to %s",
|
||||
lv->vg->name, lv->name,
|
||||
lvseg_name(seg), lp->segtype->name);
|
||||
log_error("Unable to convert %s from %s to %s.",
|
||||
display_lvname(lv), lvseg_name(seg),
|
||||
lp->segtype->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (seg_is_linear(seg) && !lp->merge_mirror && !lp->mirrors_supplied) {
|
||||
log_error("Raid conversions require -m/--mirrors");
|
||||
log_error("Raid conversions require -m/--mirrors.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1876,7 +1879,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||
image_count = lp->mirrors + 1;
|
||||
|
||||
if (image_count < 1) {
|
||||
log_error("Unable to %s images by specified amount",
|
||||
log_error("Unable to %s images by specified amount.",
|
||||
lp->keep_mimages ? "split" : "reduce");
|
||||
return 0;
|
||||
}
|
||||
@@ -1904,7 +1907,8 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||
}
|
||||
if (!lv_raid_convert(lv, lp->segtype, lp->yes, lp->force, lp->stripes, lp->stripe_size, lp->pvh))
|
||||
return_0;
|
||||
log_print_unless_silent("Logical volume %s successfully converted", display_lvname(lv));
|
||||
log_print_unless_silent("Logical volume %s successfully converted.",
|
||||
display_lvname(lv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1913,8 +1917,8 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||
|
||||
if (lp->repair) {
|
||||
if (!lv_is_active_exclusive_locally(lv_lock_holder(lv))) {
|
||||
log_error("%s/%s must be active %sto perform this"
|
||||
" operation.", lv->vg->name, lv->name,
|
||||
log_error("%s must be active %sto perform this operation.",
|
||||
display_lvname(lv),
|
||||
vg_is_clustered(lv->vg) ?
|
||||
"exclusive locally " : "");
|
||||
return 0;
|
||||
@@ -1922,14 +1926,14 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||
|
||||
if (!seg_is_striped(seg) && !seg_is_any_raid0(seg) &&
|
||||
!lv_raid_percent(lv, &sync_percent)) {
|
||||
log_error("Unable to determine sync status of %s/%s.",
|
||||
lv->vg->name, lv->name);
|
||||
log_error("Unable to determine sync status of %s.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sync_percent != DM_PERCENT_100) {
|
||||
log_warn("WARNING: %s/%s is not in-sync.",
|
||||
lv->vg->name, lv->name);
|
||||
log_warn("WARNING: %s is not in-sync.",
|
||||
display_lvname(lv));
|
||||
log_warn("WARNING: Portions of the array may be unrecoverable.");
|
||||
|
||||
/*
|
||||
@@ -1947,24 +1951,25 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||
return_0;
|
||||
|
||||
if (!lv_raid_replace(lv, failed_pvs, lp->pvh)) {
|
||||
log_error("Failed to replace faulty devices in"
|
||||
" %s/%s.", lv->vg->name, lv->name);
|
||||
log_error("Failed to replace faulty devices in %s.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_print_unless_silent("Faulty devices in %s/%s successfully"
|
||||
" replaced.", lv->vg->name, lv->name);
|
||||
log_print_unless_silent("Faulty devices in %s successfully"
|
||||
" replaced.", display_lvname(lv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* "warn" if policy not set to replace */
|
||||
if (arg_is_set(cmd, usepolicies_ARG))
|
||||
log_warn("Use 'lvconvert --repair %s/%s' to replace "
|
||||
"failed device.", lv->vg->name, lv->name);
|
||||
log_warn("Use 'lvconvert --repair %s' to replace "
|
||||
"failed device.", display_lvname(lv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_error("Conversion operation not yet supported.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2006,7 +2011,7 @@ static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volu
|
||||
|
||||
if (is_lockd_type(vg->lock_type)) {
|
||||
/* FIXME: we need to create a lock for the new LV. */
|
||||
log_error("Unable to split snapshots in VG with lock_type %s", vg->lock_type);
|
||||
log_error("Unable to split snapshots in VG with lock_type %s.", vg->lock_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2213,7 +2218,7 @@ static int _lvconvert_snapshot(struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
if (!lp->zero || !(lv->status & LVM_WRITE))
|
||||
log_warn("WARNING: %s not zeroed", snap_name);
|
||||
log_warn("WARNING: %s not zeroed.", snap_name);
|
||||
else {
|
||||
lv->status |= LV_TEMPORARY;
|
||||
if (!activate_lv_local(cmd, lv) ||
|
||||
@@ -2351,7 +2356,8 @@ static int _lvconvert_merge_old_snapshot(struct cmd_context *cmd,
|
||||
"next activation of %s.",
|
||||
display_lvname(lv), display_lvname(origin));
|
||||
else
|
||||
log_print_unless_silent("Merging of volume %s started.", lv->name);
|
||||
log_print_unless_silent("Merging of volume %s started.",
|
||||
display_lvname(lv));
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -2442,6 +2448,7 @@ out:
|
||||
log_print_unless_silent("Merging of thin snapshot %s will occur on "
|
||||
"next activation of %s.",
|
||||
display_lvname(lv), display_lvname(origin));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -2543,9 +2550,9 @@ static int _lvconvert_thin_pool_repair(struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
if (!(ret = exec_cmd(cmd, (const char * const *)argv, &status, 1))) {
|
||||
log_error("Repair of thin metadata volume of thin pool %s/%s failed (status:%d). "
|
||||
log_error("Repair of thin metadata volume of thin pool %s failed (status:%d). "
|
||||
"Manual repair required!",
|
||||
pool_lv->vg->name, pool_lv->name, status);
|
||||
display_lvname(pool_lv), status);
|
||||
goto deactivate_mlv;
|
||||
}
|
||||
|
||||
@@ -2632,11 +2639,11 @@ deactivate_pmslv:
|
||||
if (!vg_write(pool_lv->vg) || !vg_commit(pool_lv->vg))
|
||||
return_0;
|
||||
|
||||
log_warn("WARNING: If everything works, remove \"%s/%s\".",
|
||||
mlv->vg->name, mlv->name);
|
||||
log_warn("WARNING: If everything works, remove %s volume.",
|
||||
display_lvname(mlv));
|
||||
|
||||
log_warn("WARNING: Use pvmove command to move \"%s/%s\" on the best fitting PV.",
|
||||
pool_lv->vg->name, first_seg(pool_lv)->metadata_lv->name);
|
||||
log_warn("WARNING: Use pvmove command to move %s on the best fitting PV.",
|
||||
display_lvname(first_seg(pool_lv)->metadata_lv));
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -3230,7 +3237,7 @@ mda_write:
|
||||
"provisioning.", display_size(cmd, seg->chunk_size));
|
||||
|
||||
if (activate_pool && !lockd_lv(cmd, pool_lv, "ex", LDLV_PERSISTENT)) {
|
||||
log_error("Failed to lock pool LV %s/%s", vg->name, pool_lv->name);
|
||||
log_error("Failed to lock pool LV %s.", display_lvname(pool_lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -3240,9 +3247,11 @@ mda_write:
|
||||
display_lvname(pool_lv));
|
||||
/* Deactivate subvolumes */
|
||||
if (!deactivate_lv(cmd, seg_lv(seg, 0)))
|
||||
log_error("Failed to deactivate pool data logical volume.");
|
||||
log_error("Failed to deactivate pool data logical volume %s.",
|
||||
display_lvname(seg_lv(seg, 0)));
|
||||
if (!deactivate_lv(cmd, seg->metadata_lv))
|
||||
log_error("Failed to deactivate pool metadata logical volume.");
|
||||
log_error("Failed to deactivate pool metadata logical volume %s.",
|
||||
display_lvname(seg->metadata_lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -3277,7 +3286,7 @@ out:
|
||||
return r;
|
||||
#if 0
|
||||
revert_new_lv:
|
||||
/* TBD */
|
||||
/* TBD */
|
||||
if (!lp->pool_metadata_lv_name) {
|
||||
if (!deactivate_lv(cmd, metadata_lv)) {
|
||||
log_error("Failed to deactivate metadata lv.");
|
||||
@@ -3350,9 +3359,8 @@ static int _lvconvert_cache(struct cmd_context *cmd,
|
||||
* Separate a COW snapshot LV from its origin.
|
||||
* lvconvert --splitsnapshot LV
|
||||
*/
|
||||
|
||||
static int _convert_cow_snapshot_splitsnapshot(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_splitsnapshot(cmd, lv, lp);
|
||||
}
|
||||
@@ -3361,9 +3369,8 @@ static int _convert_cow_snapshot_splitsnapshot(struct cmd_context *cmd, struct l
|
||||
* Merge a COW snapshot LV into its origin.
|
||||
* lvconvert --merge LV
|
||||
*/
|
||||
|
||||
static int _convert_cow_snapshot_merge(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_merge_old_snapshot(cmd, lv, lp);
|
||||
}
|
||||
@@ -3374,7 +3381,7 @@ static int _convert_cow_snapshot_merge(struct cmd_context *cmd, struct logical_v
|
||||
*/
|
||||
|
||||
static int _convert_thin_volume_merge(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_merge_thin_snapshot(cmd, lv, lp);
|
||||
}
|
||||
@@ -3383,9 +3390,8 @@ static int _convert_thin_volume_merge(struct cmd_context *cmd, struct logical_vo
|
||||
* Split and preserve a cache pool from the data portion of a thin pool LV.
|
||||
* lvconvert --splitcache LV
|
||||
*/
|
||||
|
||||
static int _convert_thin_pool_splitcache(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
struct logical_volume *sublv1;
|
||||
|
||||
@@ -3403,7 +3409,6 @@ static int _convert_thin_pool_splitcache(struct cmd_context *cmd, struct logical
|
||||
* Split and remove a cache pool from the data portion of a thin pool LV.
|
||||
* lvconvert --uncache LV
|
||||
*/
|
||||
|
||||
static int _convert_thin_pool_uncache(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
@@ -3423,9 +3428,8 @@ static int _convert_thin_pool_uncache(struct cmd_context *cmd, struct logical_vo
|
||||
* Repair a thin pool LV.
|
||||
* lvconvert --repair LV
|
||||
*/
|
||||
|
||||
static int _convert_thin_pool_repair(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_thin_pool_repair(cmd, lv, lp);
|
||||
}
|
||||
@@ -3443,9 +3447,8 @@ static int _convert_thin_pool_repair(struct cmd_context *cmd, struct logical_vol
|
||||
* Alternate syntax:
|
||||
* lvconvert --cache LV
|
||||
*/
|
||||
|
||||
static int _convert_thin_pool_cache(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
/* lvconvert --type cache includes an implicit conversion of the cachepool arg to type cache-pool. */
|
||||
if (!_lvconvert_pool(cmd, lv, lp)) {
|
||||
@@ -3464,9 +3467,8 @@ static int _convert_thin_pool_cache(struct cmd_context *cmd, struct logical_volu
|
||||
* FIXME: this will change so --swap-poolmetadata defines the operation.
|
||||
* FIXME: should be lvconvert --swap-poolmetadata NewLV LV
|
||||
*/
|
||||
|
||||
static int _convert_thin_pool_swapmetadata(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_pool(cmd, lv, lp);
|
||||
}
|
||||
@@ -3475,9 +3477,8 @@ static int _convert_thin_pool_swapmetadata(struct cmd_context *cmd, struct logic
|
||||
* Split and preserve a cache pool from a cache LV.
|
||||
* lvconvert --splitcache LV
|
||||
*/
|
||||
|
||||
static int _convert_cache_volume_splitcache(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_split_cached(cmd, lv);
|
||||
}
|
||||
@@ -3486,9 +3487,8 @@ static int _convert_cache_volume_splitcache(struct cmd_context *cmd, struct logi
|
||||
* Split and remove a cache pool from a cache LV.
|
||||
* lvconvert --uncache LV
|
||||
*/
|
||||
|
||||
static int _convert_cache_volume_uncache(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_uncache(cmd, lv, lp);
|
||||
}
|
||||
@@ -3500,9 +3500,8 @@ static int _convert_cache_volume_uncache(struct cmd_context *cmd, struct logical
|
||||
* Required options:
|
||||
* --trackchanges | --name Name
|
||||
*/
|
||||
|
||||
static int _convert_cache_volume_splitmirrors(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
struct logical_volume *sublv1;
|
||||
|
||||
@@ -3526,9 +3525,8 @@ static int _convert_cache_volume_splitmirrors(struct cmd_context *cmd, struct lo
|
||||
* This is equivalent to above, but not preferred because it's ambiguous and inconsistent.
|
||||
* lvconvert --thinpool LV
|
||||
*/
|
||||
|
||||
static int _convert_cache_volume_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_pool(cmd, lv, lp);
|
||||
}
|
||||
@@ -3537,7 +3535,6 @@ static int _convert_cache_volume_thin_pool(struct cmd_context *cmd, struct logic
|
||||
* Split a cache volume from a cache pool LV.
|
||||
* lvconvert --splitcache LV
|
||||
*/
|
||||
|
||||
static int _convert_cache_pool_splitcache(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
@@ -3569,9 +3566,8 @@ static int _convert_cache_pool_splitcache(struct cmd_context *cmd, struct logica
|
||||
* FIXME: this will change so --swap-poolmetadata defines the operation.
|
||||
* FIXME: should be lvconvert --swap-poolmetadata NewLV LV
|
||||
*/
|
||||
|
||||
static int _convert_cache_pool_swapmetadata(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_pool(cmd, lv, lp);
|
||||
}
|
||||
@@ -3580,9 +3576,8 @@ static int _convert_cache_pool_swapmetadata(struct cmd_context *cmd, struct logi
|
||||
* Change the number of images in a mirror LV.
|
||||
* lvconvert --mirrors Number LV
|
||||
*/
|
||||
|
||||
static int _convert_mirror_number(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_mirrors(cmd, lv, lp);
|
||||
}
|
||||
@@ -3596,7 +3591,7 @@ static int _convert_mirror_number(struct cmd_context *cmd, struct logical_volume
|
||||
*/
|
||||
|
||||
static int _convert_mirror_splitmirrors(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_mirrors(cmd, lv, lp);
|
||||
}
|
||||
@@ -3605,9 +3600,8 @@ static int _convert_mirror_splitmirrors(struct cmd_context *cmd, struct logical_
|
||||
* Change the type of log used by a mirror LV.
|
||||
* lvconvert --mirrorlog Type LV
|
||||
*/
|
||||
|
||||
static int _convert_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_mirrors(cmd, lv, lp);
|
||||
}
|
||||
@@ -3619,9 +3613,8 @@ static int _convert_mirror_log(struct cmd_context *cmd, struct logical_volume *l
|
||||
* Auxiliary operation:
|
||||
* Removes missing, empty PVs from the VG, like vgreduce.
|
||||
*/
|
||||
|
||||
static int _convert_mirror_repair(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
struct dm_list *failed_pvs;
|
||||
int ret;
|
||||
@@ -3643,9 +3636,8 @@ static int _convert_mirror_repair(struct cmd_context *cmd, struct logical_volume
|
||||
* Alternate syntax:
|
||||
* lvconvert --mirrors 0 LV
|
||||
*/
|
||||
|
||||
static int _convert_mirror_linear(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_mirrors(cmd, lv, lp);
|
||||
}
|
||||
@@ -3653,12 +3645,9 @@ static int _convert_mirror_linear(struct cmd_context *cmd, struct logical_volume
|
||||
/*
|
||||
* Convert mirror LV to raid1 LV.
|
||||
* lvconvert --type raid1 LV
|
||||
*
|
||||
* FIXME: this is not yet implemented in the raid code.
|
||||
*/
|
||||
|
||||
static int _convert_mirror_raid(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_raid(lv, lp);
|
||||
}
|
||||
@@ -3667,9 +3656,8 @@ static int _convert_mirror_raid(struct cmd_context *cmd, struct logical_volume *
|
||||
* Change the number of images in a raid1 LV.
|
||||
* lvconvert --mirrors Number LV
|
||||
*/
|
||||
|
||||
static int _convert_raid_number(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_raid(lv, lp);
|
||||
}
|
||||
@@ -3681,9 +3669,8 @@ static int _convert_raid_number(struct cmd_context *cmd, struct logical_volume *
|
||||
* Required options:
|
||||
* --trackchanges | --name Name
|
||||
*/
|
||||
|
||||
static int _convert_raid_splitmirrors(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
/* FIXME: split the splitmirrors section out of _lvconvert_raid and call it here. */
|
||||
return _lvconvert_raid(lv, lp);
|
||||
@@ -3694,7 +3681,6 @@ static int _convert_raid_splitmirrors(struct cmd_context *cmd, struct logical_vo
|
||||
* previously split from the originalLV using --trackchanges.
|
||||
* lvconvert --merge LV
|
||||
*/
|
||||
|
||||
static int _convert_raid_merge(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
@@ -3709,9 +3695,8 @@ static int _convert_raid_merge(struct cmd_context *cmd, struct logical_volume *l
|
||||
* Auxiliary operation:
|
||||
* Removes missing, empty PVs from the VG, like vgreduce.
|
||||
*/
|
||||
|
||||
static int _convert_raid_repair(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
struct dm_list *failed_pvs;
|
||||
int ret;
|
||||
@@ -3729,11 +3714,10 @@ static int _convert_raid_repair(struct cmd_context *cmd, struct logical_volume *
|
||||
|
||||
/*
|
||||
* Replace a specific PV in a raid* LV with another PV.
|
||||
* lvconvert --replace PV LV
|
||||
* lvconvert --replace PV LV
|
||||
*/
|
||||
|
||||
static int _convert_raid_replace(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
/* FIXME: remove the replace section from _lvconvert_raid */
|
||||
return _lvconvert_raid(lv, lp);
|
||||
@@ -3747,9 +3731,8 @@ static int _convert_raid_replace(struct cmd_context *cmd, struct logical_volume
|
||||
* Alternate syntax:
|
||||
* lvconvert --snapshot LV SnapshotLV
|
||||
*/
|
||||
|
||||
static int _convert_raid_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_snapshot(cmd, lv, lp);
|
||||
}
|
||||
@@ -3767,7 +3750,6 @@ static int _convert_raid_snapshot(struct cmd_context *cmd, struct logical_volume
|
||||
* Alternate syntax:
|
||||
* lvconvert --thin LV
|
||||
*/
|
||||
|
||||
static int _convert_raid_thin(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
@@ -3793,7 +3775,6 @@ static int _convert_raid_thin(struct cmd_context *cmd, struct logical_volume *lv
|
||||
* Alternate syntax:
|
||||
* lvconvert --cache LV
|
||||
*/
|
||||
|
||||
static int _convert_raid_cache(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
@@ -3814,9 +3795,8 @@ static int _convert_raid_cache(struct cmd_context *cmd, struct logical_volume *l
|
||||
* This is equivalent to above, but not preferred because it's ambiguous and inconsistent.
|
||||
* lvconvert --thinpool LV
|
||||
*/
|
||||
|
||||
static int _convert_raid_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_pool(cmd, lv, lp);
|
||||
}
|
||||
@@ -3825,9 +3805,8 @@ static int _convert_raid_thin_pool(struct cmd_context *cmd, struct logical_volum
|
||||
* Convert a raid* LV to cache-pool LV.
|
||||
* lvconvert --type cache-pool LV
|
||||
*/
|
||||
|
||||
static int _convert_raid_cache_pool(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_pool(cmd, lv, lp);
|
||||
}
|
||||
@@ -3836,7 +3815,6 @@ static int _convert_raid_cache_pool(struct cmd_context *cmd, struct logical_volu
|
||||
* Convert a raid* LV to use a different raid level.
|
||||
* lvconvert --type raid* LV
|
||||
*/
|
||||
|
||||
static int _convert_raid_raid(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
@@ -3846,12 +3824,9 @@ static int _convert_raid_raid(struct cmd_context *cmd, struct logical_volume *lv
|
||||
/*
|
||||
* Convert a raid* LV to a striped LV.
|
||||
* lvconvert --type striped LV
|
||||
*
|
||||
* FIXME: this is not yet implemented in the raid code.
|
||||
*/
|
||||
|
||||
static int _convert_raid_striped(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_raid(lv, lp);
|
||||
}
|
||||
@@ -3859,12 +3834,9 @@ static int _convert_raid_striped(struct cmd_context *cmd, struct logical_volume
|
||||
/*
|
||||
* Convert a raid* LV to a linear LV.
|
||||
* lvconvert --type linear LV
|
||||
*
|
||||
* FIXME: this is not yet implemented in the raid code.
|
||||
*/
|
||||
|
||||
static int _convert_raid_linear(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_raid(lv, lp);
|
||||
}
|
||||
@@ -3874,9 +3846,8 @@ static int _convert_raid_linear(struct cmd_context *cmd, struct logical_volume *
|
||||
* previously split from the raid1 LV using --trackchanges.
|
||||
* lvconvert --merge LV
|
||||
*/
|
||||
|
||||
static int _convert_striped_merge(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_raid(lv, lp);
|
||||
}
|
||||
@@ -3889,9 +3860,8 @@ static int _convert_striped_merge(struct cmd_context *cmd, struct logical_volume
|
||||
* Alternate syntax:
|
||||
* lvconvert --snapshot LV SnapshotLV
|
||||
*/
|
||||
|
||||
static int _convert_striped_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_snapshot(cmd, lv, lp);
|
||||
}
|
||||
@@ -3909,9 +3879,8 @@ static int _convert_striped_snapshot(struct cmd_context *cmd, struct logical_vol
|
||||
* Alternate syntax:
|
||||
* lvconvert --thin LV
|
||||
*/
|
||||
|
||||
static int _convert_striped_thin(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
/* lvconvert --thin includes an implicit conversion of the thinpool arg to type thin-pool. */
|
||||
if (!_lvconvert_pool(cmd, lv, lp)) {
|
||||
@@ -3937,7 +3906,7 @@ static int _convert_striped_thin(struct cmd_context *cmd, struct logical_volume
|
||||
*/
|
||||
|
||||
static int _convert_striped_cache(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
/* lvconvert --cache includes an implicit conversion of the cachepool arg to type cache-pool. */
|
||||
if (!_lvconvert_pool(cmd, lv, lp)) {
|
||||
@@ -3956,9 +3925,8 @@ static int _convert_striped_cache(struct cmd_context *cmd, struct logical_volume
|
||||
* This is equivalent to above, but not preferred because it's ambiguous and inconsistent.
|
||||
* lvconvert --thinpool LV
|
||||
*/
|
||||
|
||||
static int _convert_striped_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_pool(cmd, lv, lp);
|
||||
}
|
||||
@@ -3967,9 +3935,8 @@ static int _convert_striped_thin_pool(struct cmd_context *cmd, struct logical_vo
|
||||
* Convert a striped/linear LV to a cache-pool LV.
|
||||
* lvconvert --type cache-pool LV
|
||||
*/
|
||||
|
||||
static int _convert_striped_cache_pool(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_pool(cmd, lv, lp);
|
||||
}
|
||||
@@ -3985,9 +3952,8 @@ static int _convert_striped_cache_pool(struct cmd_context *cmd, struct logical_v
|
||||
* This is equivalent to above when global/mirror_segtype_default="mirror".
|
||||
* lvconvert --mirrors Number LV
|
||||
*/
|
||||
|
||||
static int _convert_striped_mirror(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_mirrors(cmd, lv, lp);
|
||||
}
|
||||
@@ -4003,9 +3969,8 @@ static int _convert_striped_mirror(struct cmd_context *cmd, struct logical_volum
|
||||
* This is equivalent to above when global/mirror_segtype_default="raid1".
|
||||
* lvconvert --mirrors Number LV
|
||||
*/
|
||||
|
||||
static int _convert_striped_raid(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
return _lvconvert_raid(lv, lp);
|
||||
}
|
||||
@@ -4015,9 +3980,8 @@ static int _convert_striped_raid(struct cmd_context *cmd, struct logical_volume
|
||||
*
|
||||
* _convert_<lvtype>
|
||||
*/
|
||||
|
||||
static int _convert_cow_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
if (arg_is_set(cmd, splitsnapshot_ARG))
|
||||
return _convert_cow_snapshot_splitsnapshot(cmd, lv, lp);
|
||||
@@ -4026,7 +3990,7 @@ static int _convert_cow_snapshot(struct cmd_context *cmd, struct logical_volume
|
||||
if (arg_is_set(cmd, merge_ARG))
|
||||
return _convert_cow_snapshot_merge(cmd, lv, lp);
|
||||
|
||||
log_error("Operation not permitted on COW snapshot LV %s", display_lvname(lv));
|
||||
log_error("Operation not permitted on COW snapshot LV %s.", display_lvname(lv));
|
||||
log_error("Operations permitted on a COW snapshot LV are:\n"
|
||||
" --splitsnapshot\n"
|
||||
" --merge\n");
|
||||
@@ -4040,7 +4004,7 @@ static int _convert_thin_volume(struct cmd_context *cmd, struct logical_volume *
|
||||
if (arg_is_set(cmd, merge_ARG))
|
||||
return _convert_thin_volume_merge(cmd, lv, lp);
|
||||
|
||||
log_error("Operation not permitted on thin LV %s", display_lvname(lv));
|
||||
log_error("Operation not permitted on thin LV %s.", display_lvname(lv));
|
||||
log_error("Operations permitted on a thin LV are:\n"
|
||||
" --merge\n");
|
||||
return 0;
|
||||
@@ -4074,17 +4038,17 @@ static int _convert_thin_pool(struct cmd_context *cmd, struct logical_volume *lv
|
||||
|
||||
/* FIXME: add --swapmetadata to list of permitted operations. */
|
||||
|
||||
log_error("Operation not permitted on thin pool LV %s", display_lvname(lv));
|
||||
log_error("Operation not permitted on thin pool LV %s.", display_lvname(lv));
|
||||
log_error("Operations permitted on a thin pool LV are:\n"
|
||||
" --splitcache (operates on cache sub LV)\n"
|
||||
" --uncache (operates on cache sub LV)\n"
|
||||
" --type cache | --cache (operates on data sub LV)\n"
|
||||
" --splitcache (operates on cache sub LV)\n"
|
||||
" --uncache (operates on cache sub LV)\n"
|
||||
" --type cache (operates on data sub LV)\n"
|
||||
" --repair\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _convert_cache_volume(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
const char *new_type = arg_str_value(cmd, type_ARG, NULL);
|
||||
|
||||
@@ -4109,7 +4073,7 @@ static int _convert_cache_volume(struct cmd_context *cmd, struct logical_volume
|
||||
|
||||
/* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
|
||||
|
||||
log_error("Operation not permitted on cache LV %s", display_lvname(lv));
|
||||
log_error("Operation not permitted on cache LV %s.", display_lvname(lv));
|
||||
log_error("Operations permitted on a cache LV are:\n"
|
||||
" --splitcache\n"
|
||||
" --uncache\n"
|
||||
@@ -4135,9 +4099,9 @@ static int _convert_cache_pool(struct cmd_context *cmd, struct logical_volume *l
|
||||
|
||||
/* FIXME: add --swapmetadata to list of permitted operations. */
|
||||
|
||||
log_error("Operation not permitted on cache pool LV %s", display_lvname(lv));
|
||||
log_error("Operation not permitted on cache pool LV %s.", display_lvname(lv));
|
||||
log_error("Operations permitted on a cache pool LV are:\n"
|
||||
" --splitcache (operates on cache LV)\n");
|
||||
" --splitcache (operates on cache LV)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4185,7 +4149,7 @@ static int _convert_mirror(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_error("Operation not permitted on mirror LV %s", display_lvname(lv));
|
||||
log_error("Operation not permitted on mirror LV %s.", display_lvname(lv));
|
||||
log_error("Operations permitted on a mirror LV are:\n"
|
||||
" --mirrors\n"
|
||||
" --splitmirrors\n"
|
||||
@@ -4193,6 +4157,7 @@ static int _convert_mirror(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
" --repair\n"
|
||||
" --type linear\n"
|
||||
" --type raid*\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4248,16 +4213,16 @@ static int _convert_raid(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
|
||||
/* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
|
||||
|
||||
log_error("Operation not permitted on raid LV %s", display_lvname(lv));
|
||||
log_error("Operation not permitted on raid LV %s.", display_lvname(lv));
|
||||
log_error("Operations permitted on a raid LV are:\n"
|
||||
" --mirrors\n"
|
||||
" --splitmirrors\n"
|
||||
" --merge\n"
|
||||
" --repair\n"
|
||||
" --replace\n"
|
||||
" --type snapshot | --snapshot\n"
|
||||
" --type thin | --thin\n"
|
||||
" --type cache | --cache\n"
|
||||
" --type snapshot\n"
|
||||
" --type thin\n"
|
||||
" --type cache\n"
|
||||
" --type thin-pool\n"
|
||||
" --type cache-pool\n"
|
||||
" --type raid*\n"
|
||||
@@ -4313,16 +4278,17 @@ static int _convert_striped(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
|
||||
/* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
|
||||
|
||||
log_error("Operation not permitted on striped or linear LV %s", display_lvname(lv));
|
||||
log_error("Operation not permitted on striped or linear LV %s.", display_lvname(lv));
|
||||
log_error("Operations permitted on a striped or linear LV are:\n"
|
||||
" --merge\n"
|
||||
" --type snapshot | --snapshot\n"
|
||||
" --type thin | --thin\n"
|
||||
" --type cache | --cache\n"
|
||||
" --type snapshot\n"
|
||||
" --type thin\n"
|
||||
" --type cache\n"
|
||||
" --type thin-pool\n"
|
||||
" --type cache-pool\n"
|
||||
" --type mirror | --mirrors\n"
|
||||
" --type raid* | --mirrors\n");
|
||||
" --type mirror\n"
|
||||
" --type raid*\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4338,7 +4304,6 @@ static int _convert_striped(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
* _convert_lvtype_operation();
|
||||
*
|
||||
*/
|
||||
|
||||
static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
@@ -4372,6 +4337,7 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
!lv_is_cache_pool_data(lv) &&
|
||||
!lv_is_thin_pool_metadata(lv) &&
|
||||
!lv_is_thin_pool_data(lv) &&
|
||||
!lv_is_used_cache_pool(lv) &&
|
||||
!lv_is_raid_image(lv)) {
|
||||
log_error("Cannot convert internal LV %s.", display_lvname(lv));
|
||||
ret = 0;
|
||||
@@ -4438,7 +4404,6 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
|
||||
out:
|
||||
return ret ? ECMD_PROCESSED : ECMD_FAILED;
|
||||
|
||||
}
|
||||
|
||||
static struct convert_poll_id_list* _convert_poll_id_list_create(struct cmd_context *cmd,
|
||||
@@ -4493,7 +4458,7 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct volume_group *vg = lv->vg;
|
||||
|
||||
if (test_mode() && is_lockd_type(vg->lock_type)) {
|
||||
log_error("Test mode is not yet supported with lock type %s",
|
||||
log_error("Test mode is not yet supported with lock type %s.",
|
||||
vg->lock_type);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
@@ -35,6 +35,7 @@ static struct dm_list *_lvh_in_vg(struct logical_volume *lv, struct volume_group
|
||||
}
|
||||
|
||||
static int _lv_tree_move(struct dm_list *lvh,
|
||||
struct dm_list **lvht,
|
||||
struct volume_group *vg_from,
|
||||
struct volume_group *vg_to)
|
||||
{
|
||||
@@ -43,6 +44,10 @@ static int _lv_tree_move(struct dm_list *lvh,
|
||||
struct lv_segment *seg = first_seg(lv);
|
||||
struct dm_list *lvh1;
|
||||
|
||||
/* Update the list pointer refering to the item moving to @vg_to. */
|
||||
if (lvh == *lvht)
|
||||
*lvht = dm_list_next(lvh, lvh);
|
||||
|
||||
dm_list_move(&vg_to->lvs, lvh);
|
||||
lv->vg = vg_to;
|
||||
lv->lvid.id[0] = lv->vg->id;
|
||||
@@ -51,7 +56,7 @@ static int _lv_tree_move(struct dm_list *lvh,
|
||||
for (s = 0; s < seg->area_count; s++)
|
||||
if (seg_type(seg, s) == AREA_LV && seg_lv(seg, s)) {
|
||||
if ((lvh1 = _lvh_in_vg(seg_lv(seg, s), vg_from))) {
|
||||
if (!_lv_tree_move(lvh1, vg_from, vg_to))
|
||||
if (!_lv_tree_move(lvh1, lvht, vg_from, vg_to))
|
||||
return 0;
|
||||
} else if (!_lvh_in_vg(seg_lv(seg, s), vg_to))
|
||||
return 0;
|
||||
@@ -62,7 +67,8 @@ static int _lv_tree_move(struct dm_list *lvh,
|
||||
|
||||
static int _move_one_lv(struct volume_group *vg_from,
|
||||
struct volume_group *vg_to,
|
||||
struct dm_list *lvh)
|
||||
struct dm_list *lvh,
|
||||
struct dm_list **lvht)
|
||||
{
|
||||
struct logical_volume *lv = dm_list_item(lvh, struct lv_list)->lv;
|
||||
struct logical_volume *parent_lv;
|
||||
@@ -82,7 +88,7 @@ static int _move_one_lv(struct volume_group *vg_from,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_lv_tree_move(lvh, vg_from, vg_to))
|
||||
if (!_lv_tree_move(lvh, lvht, vg_from, vg_to))
|
||||
return 0;
|
||||
|
||||
/* Moved pool metadata spare LV */
|
||||
@@ -163,7 +169,7 @@ static int _move_lvs(struct volume_group *vg_from, struct volume_group *vg_to)
|
||||
continue;
|
||||
|
||||
/* Move this LV */
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh))
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh, &lvht))
|
||||
return_0;
|
||||
}
|
||||
|
||||
@@ -209,7 +215,7 @@ static int _move_snapshots(struct volume_group *vg_from,
|
||||
*/
|
||||
if (_lv_is_in_vg(vg_to, seg->cow) &&
|
||||
_lv_is_in_vg(vg_to, seg->origin)) {
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh))
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh, &lvht))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
@@ -271,7 +277,7 @@ static int _move_mirrors(struct volume_group *vg_from,
|
||||
}
|
||||
|
||||
if (seg_in == seg->area_count && log_in) {
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh))
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh, &lvht))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
@@ -303,7 +309,7 @@ static int _move_raids(struct volume_group *vg_from,
|
||||
continue;
|
||||
|
||||
/* If allocations are on PVs of @vg_to -> move RAID LV stack across */
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh))
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh, &lvht))
|
||||
return_0;
|
||||
}
|
||||
|
||||
@@ -338,7 +344,7 @@ static int _move_thins(struct volume_group *vg_from,
|
||||
seg->pool_lv->name);
|
||||
return 0;
|
||||
}
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh))
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh, &lvht))
|
||||
return_0;
|
||||
}
|
||||
} else if (lv_is_thin_pool(lv)) {
|
||||
@@ -358,7 +364,7 @@ static int _move_thins(struct volume_group *vg_from,
|
||||
lv->name);
|
||||
return 0;
|
||||
}
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh))
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh, &lvht))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
@@ -439,7 +445,7 @@ static int _move_cache(struct volume_group *vg_from,
|
||||
lv->name, meta->name);
|
||||
return 0;
|
||||
}
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh))
|
||||
if (!_move_one_lv(vg_from, vg_to, lvh, &lvht))
|
||||
return_0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user