master - add comment about PV in-use repair
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=7a0f46e2f87f28e17c0...
Commit: 7a0f46e2f87f28e17c0ea6b6d58ffd90b37bc6f0
Parent: 4d261cd719eb5c5f8b6d96adcb954c2e36c7c3ec
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue May 23 16:59:46 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue May 23 16:59:46 2017 -0500
add comment about PV in-use repair
copied from commit message for
d97f1c89deb9a75452059cd62ebb20cf7d2d6bfa
---
lib/metadata/metadata.c | 30 ++++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 36bb0e4..c5a41fe 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3711,6 +3711,36 @@ struct _vg_read_orphan_baton {
int repair;
};
+/*
+ * If we know that the PV is orphan, meaning there's at least one MDA on
+ * that PV which does not reference any VG and at the same time there's
+ * PV_EXT_USED flag set, we're certainly in an inconsistent state and we
+ * need to fix this.
+ *
+ * For example, such situation can happen during vgremove/vgreduce if we
+ * removed/reduced the VG, but we haven't written PV headers yet because
+ * vgremove stopped abruptly for whatever reason just before writing new
+ * PV headers with updated state, including PV extension flags (and so the
+ * PV_EXT_USED flag).
+ *
+ * However, in case the PV has no MDAs at all, we can't double-check
+ * whether the PV_EXT_USED is correct or not - if that PV is marked
+ * as used, it's either:
+ * - really used (but other disks with MDAs are missing)
+ * - or the error state as described above is hit
+ *
+ * User needs to overwrite the PV header directly if it's really clear
+ * the PV having no MDAs does not belong to any VG and at the same time
+ * it's still marked as being in use (pvcreate -ff <dev_name> will fix this).
+ *
+ * Note that the above doesn't account for the case where the PV has
+ * VG metadata that fails to be parsed. In that case, the PV looks
+ * like an in-use orphan, and is auto-repaired here. A PV with
+ * unparsable metadata should be kept on a special list of devices
+ * (like duplicate PVs) that are not auto-repaired, cannot be used
+ * by pvcreate, and are displayed with a special flag by 'pvs'.
+ */
+
static int _check_or_repair_orphan_pv_ext(struct physical_volume *pv,
struct lvmcache_info *info,
struct _vg_read_orphan_baton *b)
6 years, 11 months
master - man lvmsystemid: change some wording
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4d261cd719eb5c5f8b6...
Commit: 4d261cd719eb5c5f8b6d96adcb954c2e36c7c3ec
Parent: 5e8beb4023642eb3aabee0b9f9e54047044b0cb8
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue May 23 10:50:08 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue May 23 10:50:41 2017 -0500
man lvmsystemid: change some wording
Clarify the wording in a couple cases.
---
man/lvmsystemid.7_main | 19 +++++++++----------
1 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/man/lvmsystemid.7_main b/man/lvmsystemid.7_main
index 8c57042..9b36dc3 100644
--- a/man/lvmsystemid.7_main
+++ b/man/lvmsystemid.7_main
@@ -94,19 +94,18 @@ corrupting the PVs. See the
section for more information.
.IP \[bu] 2
-The system ID does not protect devices in VG from programs other than LVM.
+The system ID does not protect devices in a VG from programs other than LVM.
.IP \[bu] 2
-A host using an old version of LVM without the system ID feature will not
-recognize a system ID in VGs from other hosts. Even though the old
-version of LVM is not blocked from reading a VG with a system ID, it is
-blocked from writing to the VG (or its LVs). The system ID feature
-changes the write mode of a VG, making it appear read-only to previous
-versions of LVM.
-
-This also means that if a host downgrades its version of LVM, it would
+A host using an old LVM version (without the system ID feature) will not
+recognize a system ID set in VGs. The old LVM can read a VG with a
+system ID, but is prevented from writing to the VG (or its LVs).
+The system ID feature changes the write mode of a VG, making it appear
+read-only to previous versions of LVM.
+
+This also means that if a host downgrades to the old LVM version, it would
lose access to any VGs it had created with a system ID. To avoid this,
-the system ID should be removed from VGs before downgrading to an LVM
+the system ID should be removed from local VGs before downgrading LVM to a
version without the system ID feature.
6 years, 11 months
master - tests: fix test for fsadm
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=5e8beb4023642eb3aab...
Commit: 5e8beb4023642eb3aabee0b9f9e54047044b0cb8
Parent: 1fe4f80e45a6bfcceed5aaab97fc0e27dfcf2b88
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 23 13:59:29 2017 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 23 14:02:43 2017 +0200
tests: fix test for fsadm
Avoid mountinfo
Pass 'y' - since ATM lvresize cannot pass --yes to fsadm.
---
test/shell/fsadm-renamed.sh | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/test/shell/fsadm-renamed.sh b/test/shell/fsadm-renamed.sh
index b2c3e0f..3444840 100644
--- a/test/shell/fsadm-renamed.sh
+++ b/test/shell/fsadm-renamed.sh
@@ -73,7 +73,7 @@ mount | grep $vg
# fails on renamed LV
fail lvresize -L+10M -r $vg_lv_ren
-# fials on unknown mountpoint (FIXME: umount)
+# fails on unknown mountpoint (FIXME: umount)
not umount "$dev_vg_lv"
lvcreate -L20 -n $lv1 $vg
@@ -81,13 +81,14 @@ lvcreate -L20 -n $lv1 $vg
mount "$dev_vg_lv" "$mount_dolar_dir"
-cat /proc/self/mountinfo
+mount | grep $vg
not lvresize -L+10M -r $vg_lv_ren
umount "$mount_dir"
-lvresize -L+10M -r $vg_lv
+# FIXME: lvresize CANNOT handle/propagage '--yes' to fsadm
+echo y | lvresize -L+10M -vvvv -r $vg_lv
umount "$mount_dolar_dir"
6 years, 11 months
master - fsadm: avoid hidden --yes
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1fe4f80e45a6bfcceed...
Commit: 1fe4f80e45a6bfcceed5aaab97fc0e27dfcf2b88
Parent: 57492a609410c39809960a6f32bf67e1eddb7064
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 23 13:58:12 2017 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 23 14:02:41 2017 +0200
fsadm: avoid hidden --yes
When 'fsadm' was running without terminal (i.e. pipe), it's been
automatically working like in '--yes'.
Detect terminal and only accept empty "" input in this mode.
---
WHATS_NEW | 1 +
scripts/fsadm.sh | 9 +++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 82397a9..f38c23c 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.172 -
===============================
+ Stop using '--yes' mode when fsadm runs without terminal.
Extend validation of filesystems resized by fsadm.
Enhance lvconvert automatic settings of possible (raid) LV types.
Allow lvchange to change properties on a thin pool data sub LV.
diff --git a/scripts/fsadm.sh b/scripts/fsadm.sh
index bd54a26..ea14efe 100755
--- a/scripts/fsadm.sh
+++ b/scripts/fsadm.sh
@@ -401,10 +401,15 @@ yes_no() {
while read -r -s -n 1 ANS ; do
case "$ANS" in
- "y" | "Y" | "") echo y ; return 0 ;;
- "n" | "N") echo n ; return 1 ;;
+ "y" | "Y" ) echo y ; return 0 ;;
+ "" ) if [ -t 1 ] ; then
+ echo y ; return 0
+ fi ;;
esac
done
+
+ echo n
+ return 1
}
try_umount() {
6 years, 11 months
master - raid: Drop unnecessary/incorrect use of dm_pool_free
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=57492a609410c398099...
Commit: 57492a609410c39809960a6f32bf67e1eddb7064
Parent: fbe7464df5018d8ab85dd312fae8c13796eca59d
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Tue May 23 01:51:04 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue May 23 01:51:04 2017 +0100
raid: Drop unnecessary/incorrect use of dm_pool_free
---
lib/metadata/raid_manip.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 005075c..e0e988c 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -4781,9 +4781,6 @@ static int _rename_area_lvs(struct logical_volume *lv, const char *suffix)
return_0;
}
- for (s = 0; s < SLV_COUNT; s++)
- dm_pool_free(lv->vg->cmd->mem, sfx[s]);
-
return 1;
}
6 years, 11 months
master - metadata: Unlock VG on more _vg_make_handle error paths
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=fbe7464df5018d8ab85...
Commit: fbe7464df5018d8ab85dd312fae8c13796eca59d
Parent: d1ddfc408535b9c4df432273657f952c59f16232
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Tue May 23 01:37:14 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue May 23 01:38:02 2017 +0100
metadata: Unlock VG on more _vg_make_handle error paths
Internal error: VG lock vg0 must be requested before vg3, not after.
Internal error: 3 device(s) were left open and have been closed.
---
lib/metadata/metadata.c | 26 +++++++++++++++++++-------
1 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index a95b9e3..36bb0e4 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1089,8 +1089,7 @@ static struct volume_group *_vg_make_handle(struct cmd_context *cmd,
if (!vg && !(vg = alloc_vg("vg_make_handle", cmd, NULL)))
return_NULL;
- if (vg->read_status != failure)
- vg->read_status = failure;
+ vg->read_status = failure;
if (vg->fid && !_vg_update_vg_committed(vg))
vg->read_status |= FAILED_ALLOCATION;
@@ -1122,6 +1121,7 @@ int vg_has_unknown_segments(const struct volume_group *vg)
struct volume_group *vg_lock_and_create(struct cmd_context *cmd, const char *vg_name)
{
uint32_t rc;
+ struct volume_group *vg;
if (!validate_name(vg_name)) {
log_error("Invalid vg name %s", vg_name);
@@ -1134,7 +1134,11 @@ struct volume_group *vg_lock_and_create(struct cmd_context *cmd, const char *vg_
/* NOTE: let caller decide - this may be check for existence */
return _vg_make_handle(cmd, NULL, rc);
- return vg_create(cmd, vg_name);
+ vg = vg_create(cmd, vg_name);
+ if (!vg || vg_read_error(vg))
+ unlock_vg(cmd, NULL, vg_name);
+
+ return vg;
}
/*
@@ -5877,7 +5881,11 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
if (failure)
goto_bad;
- return _vg_make_handle(cmd, vg, failure);
+ if (!(vg = _vg_make_handle(cmd, vg, failure)) || vg_read_error(vg))
+ if (!already_locked)
+ unlock_vg(cmd, vg, vg_name);
+
+ return vg;
bad:
if (!already_locked)
@@ -5938,7 +5946,12 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name,
struct volume_group *vg_read_for_update(struct cmd_context *cmd, const char *vg_name,
const char *vgid, uint32_t read_flags, uint32_t lockd_state)
{
- return vg_read(cmd, vg_name, vgid, read_flags | READ_FOR_UPDATE, lockd_state);
+ struct volume_group *vg = vg_read(cmd, vg_name, vgid, read_flags | READ_FOR_UPDATE, lockd_state);
+
+ if (!vg || vg_read_error(vg))
+ stack;
+
+ return vg;
}
/*
@@ -5967,9 +5980,8 @@ uint32_t vg_read_error(struct volume_group *vg_handle)
*/
uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)
{
- if (!lock_vol(cmd, vgname, LCK_VG_WRITE, NULL)) {
+ if (!lock_vol(cmd, vgname, LCK_VG_WRITE, NULL))
return FAILED_LOCKING;
- }
/* Find the vgname in the cache */
/* If it's not there we must do full scan to be completely sure */
6 years, 11 months
master - format_text: More internal errors if given invalid internal metadata
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=d1ddfc408535b9c4df4...
Commit: d1ddfc408535b9c4df432273657f952c59f16232
Parent: ca241964914fc151a9a2f370b1567b4a1ef5cb48
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Mon May 22 23:30:34 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Mon May 22 23:30:34 2017 +0100
format_text: More internal errors if given invalid internal metadata
Three more messages to ensure each failure in out_areas() results in a
low-level message instead of sometimes just <backtrace>.
---
lib/format_text/export.c | 19 +++++++++++++++++--
1 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/lib/format_text/export.c b/lib/format_text/export.c
index 473275d..f530ec9 100644
--- a/lib/format_text/export.c
+++ b/lib/format_text/export.c
@@ -501,7 +501,13 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
*/
static const char *_get_pv_name_from_uuid(struct formatter *f, char *uuid)
{
- return dm_hash_lookup(f->pv_names, uuid);
+ const char *pv_name = dm_hash_lookup(f->pv_names, uuid);
+
+ if (!pv_name)
+ log_error(INTERNAL_ERROR "PV name for uuid %s missing from text metadata export hash table.",
+ uuid);
+
+ return pv_name;
}
static const char *_get_pv_name(struct formatter *f, struct physical_volume *pv)
@@ -607,6 +613,7 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
{
const char *name;
unsigned int s;
+ struct physical_volume *pv;
outnl(f);
@@ -616,7 +623,13 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
for (s = 0; s < seg->area_count; s++) {
switch (seg_type(seg, s)) {
case AREA_PV:
- if (!(name = _get_pv_name(f, seg_pv(seg, s))))
+ if (!(pv = seg_pv(seg, s))) {
+ log_error(INTERNAL_ERROR "Missing PV for area %" PRIu32 " of %s segment of LV %s.",
+ s, type, display_lvname(seg->lv));
+ return 0;
+ }
+
+ if (!(name = _get_pv_name(f, pv)))
return_0;
outf(f, "\"%s\", %u%s", name,
@@ -650,6 +663,8 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
break;
case AREA_UNASSIGNED:
+ log_error(INTERNAL_ERROR "Invalid type for area %" PRIu32 " of %s segment of LV %s.",
+ s, type, display_lvname(seg->lv));
return 0;
}
}
6 years, 11 months
master - man lvmraid: add more indirect conversion info
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ca241964914fc151a9a...
Commit: ca241964914fc151a9a2f370b1567b4a1ef5cb48
Parent: 3877ef0e43a8dec17b35ede5824b561a13f6db46
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon May 22 14:28:04 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon May 22 14:28:24 2017 -0500
man lvmraid: add more indirect conversion info
---
man/lvmraid.7_main | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/man/lvmraid.7_main b/man/lvmraid.7_main
index 6e0287a..c27f1fa 100644
--- a/man/lvmraid.7_main
+++ b/man/lvmraid.7_main
@@ -948,6 +948,50 @@ potential write/recovery performance reduction in raid6_ls_6 because of
the dedicated parity device. raid6_zr rotates data and parity blocks to
avoid this.
+.B linear to striped
+
+To convert an LV from linear to striped:
+.br
+1. convert to raid1 with two images
+.br
+2. convert to raid5_n
+.br
+3. convert to raid5_n with five 128k stripes (reshape)
+.br
+4. convert raid5_n to striped
+
+The commands to perform the steps above are:
+.br
+1. lvconvert --type raid1 --mirrors 1 LV
+.br
+2. lvconvert --type raid5_n LV
+.br
+3. lvconvert --stripes 5 --stripesize 128k LV
+.br
+4. lvconvert --type striped LV
+
+The raid5_n type in step 2 is used because it has dedicated parity SubLVs
+at the end, and can be converted to striped directly. The stripe size is
+increased in step 3 to add extra space for the conversion process. This
+step grows the LV size by a factor of five. After conversion, this extra
+space can be reduced (or used to grow the file system using the LV).
+
+Reversing these steps will convert a striped LV to linear.
+
+.B raid6 to striped
+
+To convert an LV from raid6_nr to striped:
+.br
+1. convert to raid6_n_6
+.br
+2. convert to striped
+
+The commands to perform the steps above are:
+.br
+1. lvconvert --type raid6_n_6 LV
+.br
+2. lvconvert --type striped LV
+
.SS Examples
@@ -1316,7 +1360,7 @@ In case the RaidLV should be converted to striped:
.nf
# lvconvert --type striped vg/lv
Unable to convert LV vg/lv from raid6_nr to striped.
- Converting vg/lv from raid6_nr is directly possible to the \
+ Converting vg/lv from raid6_nr is directly possible to the \\
following layouts:
raid6_nc
raid6_zr
@@ -1620,7 +1664,9 @@ RAID6 last parity devices
.br
\[bu]
Fixed dedicated last devices (P-Syndrome N-1 and Q-Syndrome N)
+.RS 2
with striped data used for striped/raid0 conversions
+.RE
.br
\[bu]
Used for RAID Takeover
@@ -1631,7 +1677,10 @@ raid6_{ls,rs,la,ra}_6
RAID6 last parity device
.br
\[bu]
-Dedicated last parity device used for conversions from/to raid5_{ls,rs,la,ra}
+Dedicated last parity device used for conversions from/to
+.RS 2
+raid5_{ls,rs,la,ra}
+.RE
raid6_ls_6
.br
6 years, 11 months
master - tests: catch some fsadm tricky paths
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=3877ef0e43a8dec17b3...
Commit: 3877ef0e43a8dec17b35ede5824b561a13f6db46
Parent: 9e04e0483f033d131f52a86b7f28300a761c3634
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon May 22 14:43:30 2017 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon May 22 15:12:31 2017 +0200
tests: catch some fsadm tricky paths
When user is renaming a device, we are getting into troubles.
We needs to recognize which case is actually supportable by fsadm.
---
test/shell/fsadm-renamed.sh | 98 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 98 insertions(+), 0 deletions(-)
diff --git a/test/shell/fsadm-renamed.sh b/test/shell/fsadm-renamed.sh
new file mode 100644
index 0000000..b2c3e0f
--- /dev/null
+++ b/test/shell/fsadm-renamed.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+# Copyright (C) 2017 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+test_description='Exercise fsadm operation on renamed device'
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux prepare_vg 1 80
+
+vg_lv=$vg/$lv1
+vg_lv_ren=${vg_lv}_renamed
+
+dev_vg_lv="$DM_DEV_DIR/$vg_lv"
+dev_vg_lv_ren="$DM_DEV_DIR/$vg_lv_ren"
+
+mount_dir="mnt"
+mount_space_dir="mnt space dir"
+mount_dolar_dir="mnt \$SPACE dir"
+# for recursive call
+export LVM_BINARY=$(which lvm)
+
+test ! -d "$mount_dir" && mkdir "$mount_dir"
+test ! -d "$mount_space_dir" && mkdir "$mount_space_dir"
+test ! -d "$mount_dolar_dir" && mkdir "$mount_dolar_dir"
+
+cleanup_mounted_and_teardown()
+{
+ umount "$mount_dir" || true
+ umount "$mount_space_dir" || true
+ umount "$mount_dolar_dir" || true
+ aux teardown
+}
+
+# Test for block sizes != 1024 (rhbz #480022)
+trap 'cleanup_mounted_and_teardown' EXIT
+
+# Iterate over supported filesystems
+for i in mkfs.ext3 mkfs.xfs mkfs.reiserfs
+do
+
+if not which "$i" ; then
+ echo "Skipping tests for missing $i"
+ continue
+fi
+
+lvcreate -n $lv1 -L20M $vg
+
+case "$i" in
+*ext3) MKFS_ARGS="-b1024 -j" ;;
+*xfs) MKFS_ARGS="-l internal,size=1000b -f" ;;
+*reiserfs) MKFS_ARGS="-s 513 -f" ;;
+esac
+
+echo "$i"
+"$i" $MKFS_ARGS "$dev_vg_lv"
+
+mount "$dev_vg_lv" "$mount_dir"
+
+lvrename $vg_lv $vg_lv_ren
+
+mount | grep $vg
+
+# fails on renamed LV
+fail lvresize -L+10M -r $vg_lv_ren
+
+# fials on unknown mountpoint (FIXME: umount)
+not umount "$dev_vg_lv"
+
+lvcreate -L20 -n $lv1 $vg
+"$i" $MKFS_ARGS "$dev_vg_lv"
+
+mount "$dev_vg_lv" "$mount_dolar_dir"
+
+cat /proc/self/mountinfo
+
+not lvresize -L+10M -r $vg_lv_ren
+
+umount "$mount_dir"
+
+lvresize -L+10M -r $vg_lv
+
+umount "$mount_dolar_dir"
+
+lvremove -ff $vg
+
+done
+
+vgremove -ff $vg
6 years, 11 months
master - fsadm: enhance detection of already mounted volumes
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=9e04e0483f033d131f5...
Commit: 9e04e0483f033d131f52a86b7f28300a761c3634
Parent: 2b7ac2bfb3461073486a7b296a76ef26b0d5d733
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed May 10 15:32:48 2017 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon May 22 15:11:21 2017 +0200
fsadm: enhance detection of already mounted volumes
Add more validation to catch mainly renamed devices, where
filesystem utils are not able to handle devices properly,
as they are not addressed by major:minor by rather via some
symbolic path names which can change over time via rename operation.
---
WHATS_NEW | 1 +
scripts/fsadm.sh | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 112 insertions(+), 8 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 07c2602..82397a9 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.172 -
===============================
+ Extend validation of filesystems resized by fsadm.
Enhance lvconvert automatic settings of possible (raid) LV types.
Allow lvchange to change properties on a thin pool data sub LV.
Fix lvcreate extent percentage calculation for mirrors.
diff --git a/scripts/fsadm.sh b/scripts/fsadm.sh
index 831b3ca..bd54a26 100755
--- a/scripts/fsadm.sh
+++ b/scripts/fsadm.sh
@@ -75,8 +75,9 @@ BLOCKCOUNT=
MOUNTPOINT=
MOUNTED=
REMOUNT=
-PROCMOUNTS="/proc/mounts"
-PROCSELFMOUNTINFO="/proc/self/mountinfo"
+PROCDIR="/proc"
+PROCMOUNTS="$PROCDIR/mounts"
+PROCSELFMOUNTINFO="$PROCDIR/self/mountinfo"
NULL="$DM_DEV_DIR/null"
IFS_OLD=$IFS
@@ -113,8 +114,11 @@ verbose() {
test -n "$VERB" && echo "$TOOL: $@" || true
}
+# Support multi-line error messages
error() {
- echo "$TOOL: $@" >&2
+ for i in "$@" ; do
+ echo "$TOOL: $i" >&2
+ done
cleanup 1
}
@@ -178,6 +182,17 @@ decode_size() {
fi
}
+decode_major_minor() {
+ # 0x00000fff00 mask MAJOR
+ # 0xfffff000ff mask MINOR
+
+ #MINOR=$(( $1 / 1048576 ))
+ #MAJOR=$(( ($1 - ${MINOR} * 1048576) / 256 ))
+ #MINOR=$(( $1 - ${MINOR} * 1048576 - ${MAJOR} * 256 + ${MINOR} * 256))
+
+ echo "$(( ( $1 >> 8 ) & 4095 )):$(( ( ( $1 >> 12 ) & 268435200 ) | ( $1 & 255 ) ))"
+}
+
# detect filesystem on the given device
# dereference device name if it is symbolic link
detect_fs() {
@@ -210,23 +225,92 @@ detect_fs() {
verbose "\"$FSTYPE\" filesystem found on \"$VOLUME\"."
}
-detect_mounted_with_proc_self_mountinfo() {
- MOUNTED=$("$GREP" "^[0-9]* [0-9]* $MAJORMINOR " "$PROCSELFMOUNTINFO")
- # extract 5th field which is mount point
+# Check that passed mounted MAJOR:MINOR is not matching $MAJOR:MINOR of resized $VOLUME
+validate_mounted_major_minor() {
+ test "$1" = "$MAJORMINOR" || {
+ local REFNAME=$(dmsetup info -c -j "${1%%:*}" -m "${1##*:}" -o name --noheadings 2>/dev/null)
+ local CURNAME=$(dmsetup info -c -j "$MAJOR" -m "$MINOR" -o name --noheadings 2>/dev/null)
+ error "Cannot ${CHECK+CHECK}${RESIZE+RESIZE} device \"$VOLUME\" without umounting filesystem $MOUNTED first." \
+ "Mounted filesystem is using device $CURNAME, but referenced device is $REFNAME." \
+ "Filesystem utilities currently do not support renamed devices."
+ }
+}
+
+# ATM fsresize & fsck tools are not able to work properly
+# when mounted device has changed its name.
+# So whenever such device no longer exists with original name
+# abort further command processing
+check_valid_mounted_device() {
+ local MOUNTEDMAJORMINOR
+ local VOL=$("$READLINK" $READLINK_E "$1")
+ local CURNAME=$(dmsetup info -c -j "$MAJOR" -m "$MINOR" -o name --noheadings)
+ local SUGGEST="Possibly device \"$1\" has been renamed to \"$CURNAME\"?"
+
+ # more confused, device is not DM....
+ test -n "$CURNAME" || SUGGEST="Mounted volume is not a device mapper device???"
+
+ test -n "$VOL" ||
+ error "Cannot access device \"$1\" referenced by mounted filesystem \"$MOUNTED\"." \
+ "$SUGGEST" \
+ "Filesystem utilities currently do not support renamed devices."
+
+ case "$VOL" in
+ # hardcoded /dev since udev does not create these entries elsewhere
+ /dev/dm-[0-9]*)
+ read </sys/block/${VOL#/dev/}/dev MOUNTEDMAJORMINOR 2>&1 || error "Cannot get major:minor for \"$VOLUME\"."
+ ;;
+ *)
+ STAT=$(stat --format "MOUNTEDMAJORMINOR=\$((0x%t)):\$((0x%T))" "$VOL")
+ test -n "$STAT" || error "Cannot get major:minor for \"$VOLUME\"."
+ eval "$STAT"
+ ;;
+ esac
+
+ validate_mounted_major_minor "$MOUNTEDMAJORMINOR"
+}
+
+detect_mounted_with_proc_self_mountinfo() {
+ # Check self mountinfo
+ # grab major:minor mounted_device mount_point
+ MOUNTED=$("$GREP" "^[0-9]* [0-9]* $MAJORMINOR " "$PROCSELFMOUNTINFO" 2>/dev/null | head -1)
+
+ # If device is opened and not yet found as self mounted
+ # check all other mountinfos (since it can be mounted in cgroups)
+ # Use 'find' to not fail on to long list of args with too many pids
+ # only 1st. line is needed
+ test -z "$MOUNTED" &&
+ test $(dmsetup info -c --noheading -o open -j "$MAJOR" -m "$MINOR") -gt 0 &&
+ MOUNTED=$(find "$PROCDIR" -maxdepth 2 -name mountinfo -print0 | xargs -0 "$GREP" "^[0-9]* [0-9]* $MAJORMINOR " 2>/dev/null | head -1 2>/dev/null)
+
+ # TODO: for performance compare with sed and stop with 1st. match:
+ # sed -n "/$MAJORMINOR/ {;p;q;}"
+
+ # extract 2nd field after ' - ' separator as mouted device
+ MOUNTDEV=$(echo ${MOUNTED##* - } | cut -d ' ' -f 2)
+ MOUNTDEV=$(echo -n -e ${MOUNTDEV})
+
+ # extract 5th field as mount point
# echo -e translates \040 to spaces
- MOUNTED=$(echo ${MOUNTED} | cut -d " " -f 5)
+ MOUNTED=$(echo ${MOUNTED} | cut -d ' ' -f 5)
MOUNTED=$(echo -n -e ${MOUNTED})
- test -n "$MOUNTED"
+ test -n "$MOUNTED" || return 1 # Not seen mounted anywhere
+
+ check_valid_mounted_device "$MOUNTDEV"
}
+# With older systems without /proc/*/mountinfo we may need to check
+# every mount point as cannot easily depend on the name of mounted
+# device (which could have been renamed).
+# We need to visit every mount point and check it's major minor
detect_mounted_with_proc_mounts() {
MOUNTED=$("$GREP" "^$VOLUME[ \t]" "$PROCMOUNTS")
# for empty string try again with real volume name
test -z "$MOUNTED" && MOUNTED=$("$GREP" "^$RVOLUME[ \t]" "$PROCMOUNTS")
+ MOUNTDEV=$(echo -n -e ${MOUNTED%% *})
# cut device name prefix and trim everything past mountpoint
# echo translates \040 to spaces
MOUNTED=${MOUNTED#* }
@@ -234,13 +318,32 @@ detect_mounted_with_proc_mounts() {
# for systems with different device names - check also mount output
if test -z "$MOUNTED" ; then
+ # will not work with spaces in paths
MOUNTED=$(LC_ALL=C "$MOUNT" | "$GREP" "^$VOLUME[ \t]")
test -z "$MOUNTED" && MOUNTED=$(LC_ALL=C "$MOUNT" | "$GREP" "^$RVOLUME[ \t]")
+ MOUNTDEV=${MOUNTED%% on *}
MOUNTED=${MOUNTED##* on }
MOUNTED=${MOUNTED% type *} # allow type in the mount name
fi
- test -n "$MOUNTED"
+ if test -n "$MOUNTED" ; then
+ check_valid_mounted_device "$MOUNTDEV"
+ return 0 # mounted
+ fi
+
+ # If still nothing found and volume is in use
+ # check every known mount point against MAJOR:MINOR
+ if test $(dmsetup info -c --noheading -o open -j "$MAJOR" -m "$MINOR") -gt 0 ; then
+ while IFS=$'\n' read -r i ; do
+ MOUNTDEV=$(echo -n -e ${i%% *})
+ MOUNTED=${i#* }
+ MOUNTED=$(echo -n -e ${MOUNTED%% *})
+ STAT=$(stat --format "%d" $MOUNTED)
+ validate_mounted_major_minor $(decode_major_minor "$STAT")
+ done < "$PROCMOUNTS"
+ fi
+
+ return 1 # nothing is mounted
}
# check if the given device is already mounted and where
6 years, 11 months