mirror of
git://sourceware.org/git/lvm2.git
synced 2025-12-24 16:23:50 +03:00
Compare commits
93 Commits
old-dm_v1_
...
dm_v1_02_2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc633e03aa | ||
|
|
797d0f1ef1 | ||
|
|
1be3e86aa0 | ||
|
|
e56dd38021 | ||
|
|
410904bef1 | ||
|
|
026cc120e7 | ||
|
|
ef2fda05cf | ||
|
|
92277e3ae2 | ||
|
|
fbc34d70b0 | ||
|
|
91dcddbdf7 | ||
|
|
874f42ad6c | ||
|
|
1989ef4ebc | ||
|
|
4f4c72c065 | ||
|
|
666cc72661 | ||
|
|
4524e8f5c9 | ||
|
|
bd07a29886 | ||
|
|
a0d865492e | ||
|
|
de27790de8 | ||
|
|
9c910b7be2 | ||
|
|
7f23ab94e2 | ||
|
|
77dc036c8f | ||
|
|
aa6e8d82ce | ||
|
|
3010285bb3 | ||
|
|
aaad3252f8 | ||
|
|
9065f534d8 | ||
|
|
52361c94e5 | ||
|
|
798be60fef | ||
|
|
6294154b15 | ||
|
|
6594fe077d | ||
|
|
582706cde6 | ||
|
|
6537cbdc17 | ||
|
|
53959459bb | ||
|
|
22d6121099 | ||
|
|
48d7f6f2f4 | ||
|
|
9fd4ddc490 | ||
|
|
a4d2fddbb2 | ||
|
|
c54a3f2721 | ||
|
|
04c0dba697 | ||
|
|
5406e3b7c5 | ||
|
|
6b624b7d00 | ||
|
|
2d364d4d80 | ||
|
|
1f27bf3774 | ||
|
|
d30a2653b5 | ||
|
|
3086822cd2 | ||
|
|
2c08336490 | ||
|
|
5936ac58c2 | ||
|
|
ded77e3f5c | ||
|
|
8a29df0a6c | ||
|
|
9db22babaf | ||
|
|
c318c5ed61 | ||
|
|
61243c65cd | ||
|
|
4a5d5cb462 | ||
|
|
cbf1447ebd | ||
|
|
30104441bf | ||
|
|
b4a70804f0 | ||
|
|
74f6707bde | ||
|
|
223eb8c84d | ||
|
|
107d000606 | ||
|
|
43e05607af | ||
|
|
55793452d5 | ||
|
|
686ba37255 | ||
|
|
03ed19dad5 | ||
|
|
ad2b6e5de1 | ||
|
|
767676d6ff | ||
|
|
bc7a54c615 | ||
|
|
1bda393678 | ||
|
|
bb5495c6bd | ||
|
|
484f905749 | ||
|
|
e0d61a4336 | ||
|
|
e643a16ba5 | ||
|
|
98fadec2b6 | ||
|
|
14f464ecb0 | ||
|
|
2ecdaf9bd4 | ||
|
|
707c898f66 | ||
|
|
69e4400774 | ||
|
|
695efde68d | ||
|
|
0c4b769011 | ||
|
|
e53eff0634 | ||
|
|
6c75243a06 | ||
|
|
efde37880b | ||
|
|
7d8f6381be | ||
|
|
3c361e3393 | ||
|
|
8440ecef5e | ||
|
|
6401f1b1c9 | ||
|
|
7487a7c988 | ||
|
|
f44584fa10 | ||
|
|
7b32165614 | ||
|
|
b0dc94d187 | ||
|
|
0383c4e1d8 | ||
|
|
a8c5758222 | ||
|
|
a7fabfd8cb | ||
|
|
5d5b575d16 | ||
|
|
ac1373653c |
34
Makefile.in
34
Makefile.in
@@ -39,6 +39,7 @@ ifeq ($(MAKECMDGOALS),distclean)
|
||||
test \
|
||||
po
|
||||
DISTCLEAN_TARGETS += lib/misc/configure.h
|
||||
DISTCLEAN_DIRS += lcov_reports*
|
||||
endif
|
||||
|
||||
include make.tmpl
|
||||
@@ -71,3 +72,36 @@ endif
|
||||
|
||||
check: all
|
||||
$(MAKE) -C test all
|
||||
|
||||
ifneq ("@LCOV@", "")
|
||||
.PHONY: lcov-reset lcov lcov-dated
|
||||
|
||||
ifeq ($(MAKECMDGOALS),lcov-dated)
|
||||
LCOV_REPORTS_DIR=$(top_srcdir)/lcov_reports-$(shell date +%Y%m%d%k%M%S)
|
||||
else
|
||||
LCOV_REPORTS_DIR=$(top_srcdir)/lcov_reports
|
||||
endif
|
||||
|
||||
lcov-reset:
|
||||
$(LCOV) -d $(top_srcdir)/dmeventd --zerocounters
|
||||
$(LCOV) -d $(top_srcdir)/lib --zerocounters
|
||||
$(LCOV) -d $(top_srcdir)/tools --zerocounters
|
||||
|
||||
lcov: all
|
||||
$(RM) -rf $(LCOV_REPORTS_DIR)
|
||||
$(MKDIR_P) $(LCOV_REPORTS_DIR)
|
||||
$(LCOV) -b $(top_srcdir)/lib -d $(top_srcdir)/lib -c -o $(LCOV_REPORTS_DIR)/lib.info
|
||||
$(LCOV) -b $(top_srcdir)/tools -d $(top_srcdir)/tools -c -o $(LCOV_REPORTS_DIR)/tools.info
|
||||
DMEVENTD_INFO="$(LCOV_REPORTS_DIR)/dmeventd.info" ;\
|
||||
DMEVENTD_INFO_A="-a $$DMEVENTDINFO" ;\
|
||||
$(LCOV) -b $(top_srcdir)/dmeventd -d $(top_srcdir)/dmeventd -c -o $$DMEVENTD_INFO || DMEVENTD_INFO_A="" ;\
|
||||
$(LCOV) $$DMEVENTD_INFO_A -a $(LCOV_REPORTS_DIR)/lib.info \
|
||||
-a $(LCOV_REPORTS_DIR)/tools.info \
|
||||
-o $(LCOV_REPORTS_DIR)/lvm.info
|
||||
ifneq ("@GENHTML@", "")
|
||||
$(GENHTML) -o $(LCOV_REPORTS_DIR) -p $(top_srcdir) $(LCOV_REPORTS_DIR)/lvm.info
|
||||
endif
|
||||
|
||||
lcov-dated: lcov
|
||||
|
||||
endif
|
||||
|
||||
45
WHATS_NEW
45
WHATS_NEW
@@ -1,5 +1,44 @@
|
||||
Version 2.02.39 -
|
||||
Version 2.02.40 -
|
||||
================================
|
||||
Avoid shuffling remaining mirror images when removing one, retaining primary.
|
||||
Add missing LV error target activation in _remove_mirror_images.
|
||||
Prevent resizing an LV while lvconvert is using it.
|
||||
Avoid repeatedly wiping cache while VG_GLOBAL is held in vgscan & pvscan.
|
||||
Fix pvresize to not allow resize if PV has two metadata areas.
|
||||
Fix setting of volume limit count if converting to lvm1 format.
|
||||
Fix vgconvert logical volume id metadata validation.
|
||||
Fix lvmdump metadata gather option (-m) to work correctly.
|
||||
Fix allocation bug in text metadata format write error path.
|
||||
Fix vgcfgbackup to properly check filename if template is used.
|
||||
configure aborts if lcov or genhtml are missing with --enable-profiling
|
||||
vgremove tries to remove lv snapshot first.
|
||||
Added function lv_remove_with_dependencies().
|
||||
Improve file descriptor leak detection to display likely culprit and filename.
|
||||
Change clustered mirror kernel module name from cmirror to dm-log-clustered.
|
||||
Avoid looping forever in _pv_analyze_mda_raw used by pvck.
|
||||
Change lvchange exit status to indicate if any part of the operation failed.
|
||||
Fix pvchange and pvremove to handle PVs without mdas.
|
||||
Refactor _text_pv_read and always return mda list if requested.
|
||||
Fix configure to work w/o readline unless --enable-readline used. (2.02.39)
|
||||
Remove is_lvm_partition template which has not yet been coded.
|
||||
Refactor pvcreate to separate parameter parsing from validation logic.
|
||||
Check for label_write() failure in _text_pv_write().
|
||||
Add pvcreate tests and update vgsplit tests to handle lvm1 and lvm2 metadata.
|
||||
Fix pvchange -M1 -u to preserve existing extent locations when there's a VG.
|
||||
Cease recognising snapshot-in-use percentages returned by early devt kernels.
|
||||
Add backward-compatible flags field to on-disk format_text metadata.
|
||||
Fix dmeventd monitoring libraries to link against liblvm2cmd again. (2.02.39)
|
||||
|
||||
Version 2.02.39 - 27th June 2008
|
||||
================================
|
||||
Enable readline by default if available.
|
||||
Update autoconf to 2008-01-16.
|
||||
Add $DISTCLEAN_DIRS to make.tmpl.in.
|
||||
Create coverage reports with --enable-profiling and make lcov or lcov-dated.
|
||||
Fix up cache for PVs without mdas after consistent VG metadata is processed.
|
||||
Update validation of safe mirror log type conversions in lvconvert.
|
||||
Fix lvconvert to disallow snapshot and mirror combinations.
|
||||
Fix reporting of LV fields alongside unallocated PV segments.
|
||||
Add --unquoted and --rows to reporting tools.
|
||||
Add and use uninitialized_var() macro to suppress invalid compiler warnings.
|
||||
Introduce enum for md minor sb version to suppress compiler warning.
|
||||
@@ -9,12 +48,12 @@ Version 2.02.39 -
|
||||
Fix and improve readahead 'auto' calculation for stripe_size.
|
||||
Fix lvchange output for -r auto setting if auto is already set.
|
||||
Add test case for readahead.
|
||||
Fix ambiguous use of identifier error_message_produced.
|
||||
Avoid ambiguous use of identifier error_message_produced.
|
||||
Begin syncing configure.in for merge/unification with device-mapper.
|
||||
Fix add_mirror_images not to dereference uninitialized log_lv upon failure.
|
||||
Don't call openlog for every debug line output by clvmd.
|
||||
Add --force to lvextend and lvresize.
|
||||
Fix vgchange to not activate mirror leg and log volumes directly.
|
||||
Fix vgchange not to activate component mirror volumes directly.
|
||||
Fix test directory clean up in make distclean.
|
||||
|
||||
Version 2.02.38 - 11th June 2008
|
||||
|
||||
10
WHATS_NEW_DM
10
WHATS_NEW_DM
@@ -1,3 +1,13 @@
|
||||
Version 1.02.29 -
|
||||
=====================================
|
||||
|
||||
Version 1.02.28 - 18th September 2008
|
||||
=====================================
|
||||
Only resume devices in dm_tree_preload_children if size changes.
|
||||
Extend deptree buffers so the largest possible device numbers fit.
|
||||
Generate versioned libdevmapper-event.so.
|
||||
Underline longer report help text headings.
|
||||
|
||||
Version 1.02.27 - 25th June 2008
|
||||
================================
|
||||
Align struct memblock in dbg_malloc for sparc.
|
||||
|
||||
60
autoconf/config.guess
vendored
60
autoconf/config.guess
vendored
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2006-07-02'
|
||||
timestamp='2008-01-23'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -56,8 +56,8 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -161,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
arm*) machine=arm-unknown ;;
|
||||
sh3el) machine=shl-unknown ;;
|
||||
sh3eb) machine=sh-unknown ;;
|
||||
sh5el) machine=sh5le-unknown ;;
|
||||
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||
esac
|
||||
# The Operating System including object format, if it has switched
|
||||
@@ -329,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
i86pc:SunOS:5.*:*)
|
||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
@@ -531,7 +532,7 @@ EOF
|
||||
echo rs6000-ibm-aix3.2
|
||||
fi
|
||||
exit ;;
|
||||
*:AIX:*:[45])
|
||||
*:AIX:*:[456])
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
||||
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
@@ -780,7 +781,7 @@ EOF
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
exit ;;
|
||||
i*:MINGW*:*)
|
||||
*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
i*:windows32*:*)
|
||||
@@ -790,12 +791,18 @@ EOF
|
||||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit ;;
|
||||
x86:Interix*:[3456]*)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T:Interix*:[3456]*)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:Interix*:[3456]*)
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T | authenticamd)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
IA64)
|
||||
echo ia64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
esac ;;
|
||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
exit ;;
|
||||
@@ -829,7 +836,14 @@ EOF
|
||||
echo ${UNAME_MACHINE}-pc-minix
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||||
fi
|
||||
exit ;;
|
||||
avr32*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
@@ -950,6 +964,9 @@ EOF
|
||||
x86_64:Linux:*:*)
|
||||
echo x86_64-unknown-linux-gnu
|
||||
exit ;;
|
||||
xtensa*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us. cd to the root directory to prevent
|
||||
@@ -1208,6 +1225,15 @@ EOF
|
||||
SX-6:SUPER-UX:*:*)
|
||||
echo sx6-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-7:SUPER-UX:*:*)
|
||||
echo sx7-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-8:SUPER-UX:*:*)
|
||||
echo sx8-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-8R:SUPER-UX:*:*)
|
||||
echo sx8r-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
Power*:Rhapsody:*:*)
|
||||
echo powerpc-apple-rhapsody${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1458,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize
|
||||
the operating system you are using. It is advised that you
|
||||
download the most up to date version of the config scripts from
|
||||
|
||||
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
and
|
||||
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
|
||||
If the version you run ($0) is already up to date, please
|
||||
send the following data and any information you think might be
|
||||
|
||||
66
autoconf/config.sub
vendored
66
autoconf/config.sub
vendored
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2006-09-20'
|
||||
timestamp='2008-01-16'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -72,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -245,12 +245,12 @@ case $basic_machine in
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fr30 | frv \
|
||||
| fido | fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore \
|
||||
| maxq | mb | microblaze | mcore | mep \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
@@ -324,7 +324,7 @@ case $basic_machine in
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
@@ -369,10 +369,14 @@ case $basic_machine in
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| xstormy16-* | xtensa-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
| ymp-* \
|
||||
| z8k-*)
|
||||
;;
|
||||
# Recognize the basic CPU types without company name, with glob match.
|
||||
xtensa*)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
386bsd)
|
||||
@@ -443,6 +447,14 @@ case $basic_machine in
|
||||
basic_machine=ns32k-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
blackfin)
|
||||
basic_machine=bfin-unknown
|
||||
os=-linux
|
||||
;;
|
||||
blackfin-*)
|
||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
@@ -475,8 +487,8 @@ case $basic_machine in
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16c)
|
||||
basic_machine=cr16c-unknown
|
||||
cr16)
|
||||
basic_machine=cr16-unknown
|
||||
os=-elf
|
||||
;;
|
||||
crds | unos)
|
||||
@@ -668,6 +680,14 @@ case $basic_machine in
|
||||
basic_machine=m68k-isi
|
||||
os=-sysv
|
||||
;;
|
||||
m68knommu)
|
||||
basic_machine=m68k-unknown
|
||||
os=-linux
|
||||
;;
|
||||
m68knommu-*)
|
||||
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
m88k-omron*)
|
||||
basic_machine=m88k-omron
|
||||
;;
|
||||
@@ -683,6 +703,10 @@ case $basic_machine in
|
||||
basic_machine=i386-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
mingw32ce)
|
||||
basic_machine=arm-unknown
|
||||
os=-mingw32ce
|
||||
;;
|
||||
miniframe)
|
||||
basic_machine=m68000-convergent
|
||||
;;
|
||||
@@ -809,6 +833,14 @@ case $basic_machine in
|
||||
basic_machine=i860-intel
|
||||
os=-osf
|
||||
;;
|
||||
parisc)
|
||||
basic_machine=hppa-unknown
|
||||
os=-linux
|
||||
;;
|
||||
parisc-*)
|
||||
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
pbd)
|
||||
basic_machine=sparc-tti
|
||||
;;
|
||||
@@ -925,6 +957,9 @@ case $basic_machine in
|
||||
basic_machine=sh-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
sh5el)
|
||||
basic_machine=sh5le-unknown
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
@@ -1014,6 +1049,10 @@ case $basic_machine in
|
||||
basic_machine=tic6x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tile*)
|
||||
basic_machine=tile-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
tx39)
|
||||
basic_machine=mipstx39-unknown
|
||||
;;
|
||||
@@ -1219,7 +1258,7 @@ case $os in
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1414,6 +1453,9 @@ case $basic_machine in
|
||||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mep-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-cisco)
|
||||
os=-elf
|
||||
;;
|
||||
|
||||
70
configure.in
70
configure.in
@@ -70,6 +70,7 @@ AC_PROG_GCC_TRADITIONAL
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_MKDIR_P
|
||||
AC_PROG_RANLIB
|
||||
AC_PATH_PROG(CFLOW_CMD, cflow)
|
||||
AC_PATH_PROG(CSCOPE_CMD, cscope)
|
||||
@@ -268,11 +269,11 @@ if test x$MIRRORS = xinternal; then
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable readline
|
||||
dnl -- Disable readline
|
||||
AC_MSG_CHECKING(whether to enable readline)
|
||||
AC_ARG_ENABLE([readline],
|
||||
[ --enable-readline Enable readline support],
|
||||
[READLINE=$enableval], [READLINE=no])
|
||||
[ --disable-readline Disable readline support],
|
||||
[READLINE=$enableval], [READLINE=maybe])
|
||||
AC_MSG_RESULT($READLINE)
|
||||
|
||||
################################################################################
|
||||
@@ -322,6 +323,23 @@ AC_ARG_WITH(optimisation,
|
||||
[ COPTIMISE_FLAG="$withval" ])
|
||||
AC_MSG_RESULT($COPTIMISE_FLAG)
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable profiling
|
||||
AC_MSG_CHECKING(whether to gather gcov profiling data)
|
||||
AC_ARG_ENABLE(profiling,
|
||||
AC_HELP_STRING(--enable-profiling, [Gather gcov profiling data]),
|
||||
PROFILING=$enableval, PROFILING=no)
|
||||
AC_MSG_RESULT($PROFILING)
|
||||
|
||||
if test "x$PROFILING" = xyes; then
|
||||
COPTIMISE_FLAG="$COPTIMISE_FLAG -fprofile-arcs -ftest-coverage"
|
||||
AC_PATH_PROG(LCOV, lcov, no)
|
||||
AC_PATH_PROG(GENHTML, genhtml, no)
|
||||
if test "$LCOV" = no -o "$GENHTML" = no ; then
|
||||
AC_MSG_ERROR([lcov and genhtml are required for profiling])
|
||||
fi
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable devmapper
|
||||
AC_MSG_CHECKING(whether to use device-mapper)
|
||||
@@ -351,10 +369,11 @@ AC_ARG_ENABLE(cmdlib, [ --enable-cmdlib Build shared command library],
|
||||
CMDLIB=$enableval, CMDLIB=no)
|
||||
AC_MSG_RESULT($CMDLIB)
|
||||
AC_SUBST([LVM2CMD_LIB])
|
||||
test $CMDLIB=yes \
|
||||
test x$CMDLIB = xyes \
|
||||
&& LVM2CMD_LIB=-llvm2cmd \
|
||||
|| LVM2CMD_LIB=
|
||||
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable fsadm
|
||||
AC_MSG_CHECKING(whether to install fsadm)
|
||||
@@ -370,10 +389,17 @@ DMEVENTD=$enableval)
|
||||
AC_MSG_RESULT($DMEVENTD)
|
||||
|
||||
dnl -- dmeventd currently requires internal mirror support
|
||||
if test x$DMEVENTD = xyes && test x$MIRRORS != xinternal; then
|
||||
AC_MSG_ERROR(
|
||||
--enable-dmeventd currently requires --with-mirrors=internal
|
||||
)
|
||||
if test x$DMEVENTD = xyes; then
|
||||
if test x$MIRRORS != xinternal; then
|
||||
AC_MSG_ERROR(
|
||||
--enable-dmeventd currently requires --with-mirrors=internal
|
||||
)
|
||||
fi
|
||||
if test x$CMDLIB = xno; then
|
||||
AC_MSG_ERROR(
|
||||
--enable-dmeventd requires --enable-cmdlib to be used as well
|
||||
)
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$DMEVENTD = xyes; then
|
||||
@@ -387,9 +413,11 @@ fi;
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for termcap (Shamelessly copied from parted 1.4.17)
|
||||
if test x$READLINE = xyes; then
|
||||
AC_SEARCH_LIBS(tgetent, ncurses curses termcap termlib, ,
|
||||
AC_MSG_ERROR(
|
||||
if test x$READLINE != xno; then
|
||||
AC_SEARCH_LIBS([tgetent], [ncurses curses termcap termlib],
|
||||
[tg_found=yes], [tg_found=no])
|
||||
test x$READLINE:$tg_found = xyes:no &&
|
||||
AC_MSG_ERROR(
|
||||
termcap could not be found which is required for the
|
||||
--enable-readline option (which is enabled by default). Either disable readline
|
||||
support with --disable-readline or download and install termcap from:
|
||||
@@ -399,7 +427,6 @@ Note: if you are using precompiled packages you will also need the development
|
||||
Note: (n)curses also seems to work as a substitute for termcap. This was
|
||||
not found either - but you could try installing that as well.
|
||||
)
|
||||
)
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
@@ -491,9 +518,11 @@ AC_CHECK_HEADERS(getopt.h, AC_DEFINE([HAVE_GETOPTLONG], 1, [Define to 1 if getop
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for readline (Shamelessly copied from parted 1.4.17)
|
||||
if test x$READLINE = xyes; then
|
||||
AC_CHECK_LIB(readline, readline, ,
|
||||
AC_MSG_ERROR(
|
||||
if test x$READLINE != xno; then
|
||||
rl_found=yes
|
||||
AC_CHECK_LIB([readline], [readline], , [rl_found=no])
|
||||
test x$READLINE:$rl_found = xyes:no &&
|
||||
AC_MSG_ERROR(
|
||||
GNU Readline could not be found which is required for the
|
||||
--enable-readline option (which is enabled by default). Either disable readline
|
||||
support with --disable-readline or download and install readline from:
|
||||
@@ -501,12 +530,11 @@ support with --disable-readline or download and install readline from:
|
||||
Note: if you are using precompiled packages you will also need the development
|
||||
package as well (which may be called readline-devel or something similar).
|
||||
)
|
||||
)
|
||||
AC_CHECK_FUNC([rl_completion_matches],
|
||||
AC_DEFINE([HAVE_RL_COMPLETION_MATCHES], 1,
|
||||
[Define to 1 if rl_completion_matches() is available.]))
|
||||
AC_DEFINE([READLINE_SUPPORT], 1,
|
||||
[Define to 1 to include the LVM readline shell.])
|
||||
if test $rl_found = yes; then
|
||||
AC_CHECK_FUNCS([rl_completion_matches])
|
||||
AC_DEFINE([READLINE_SUPPORT], 1,
|
||||
[Define to 1 to include the LVM readline shell.])
|
||||
fi
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -23,6 +23,7 @@ ifeq ("@LIB_SUFFIX@","dylib")
|
||||
LIB_SHARED = libdevmapper-event.dylib
|
||||
else
|
||||
LIB_SHARED = libdevmapper-event.so
|
||||
VERSIONED_SHLIB = $(LIB_SHARED).$(LIB_VERSION)
|
||||
endif
|
||||
|
||||
TARGETS = dmeventd
|
||||
@@ -33,7 +34,7 @@ include ../make.tmpl
|
||||
LDFLAGS += -ldl -ldevmapper -lpthread
|
||||
CLDFLAGS += -ldl -ldevmapper -lpthread
|
||||
|
||||
dmeventd: $(LIB_SHARED) dmeventd.o
|
||||
dmeventd: $(LIB_SHARED) $(VERSIONED_SHLIB) dmeventd.o
|
||||
$(CC) -o $@ dmeventd.o $(CFLAGS) $(LDFLAGS) \
|
||||
-L. -ldevmapper-event $(LIBS) -rdynamic
|
||||
|
||||
@@ -74,6 +75,10 @@ install_static: libdevmapper-event.a
|
||||
$(libdir)/libdevmapper-event.a.$(LIB_VERSION)
|
||||
$(LN_S) -f libdevmapper-event.a.$(LIB_VERSION) $(libdir)/libdevmapper-event.a
|
||||
|
||||
$(VERSIONED_SHLIB): $(LIB_SHARED)
|
||||
$(RM) -f $@
|
||||
$(LN_S) $(LIB_SHARED) $@
|
||||
|
||||
.PHONY: distclean_lib distclean
|
||||
|
||||
distclean_lib:
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <arpa/inet.h> /* for htonl, ntohl */
|
||||
|
||||
#ifdef linux
|
||||
|
||||
@@ -17,7 +17,7 @@ top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
INCLUDES += -I${top_srcdir}/tools
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper $(LVM2CMD_LIB)
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper @LVM2CMD_LIB@
|
||||
|
||||
SOURCES = dmeventd_mirror.c
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
INCLUDES += -I${top_srcdir}/tools
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper $(LVM2CMD_LIB)
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper @LVM2CMD_LIB@
|
||||
|
||||
SOURCES = dmeventd_snapshot.c
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
INCLUDES += -I${top_srcdir}/tools
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper $(LVM2CMD_LIB)
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper @LVM2CMD_LIB@
|
||||
|
||||
SOURCES = dmeventd_mirror.c
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
INCLUDES += -I${top_srcdir}/tools
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper $(LVM2CMD_LIB)
|
||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper @LVM2CMD_LIB@
|
||||
|
||||
SOURCES = dmeventd_snapshot.c
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ SOURCES =\
|
||||
format_text/import_vsn1.c \
|
||||
format_text/tags.c \
|
||||
format_text/text_label.c \
|
||||
freeseg/freeseg.c \
|
||||
label/label.c \
|
||||
locking/file_locking.c \
|
||||
locking/locking.c \
|
||||
|
||||
@@ -379,8 +379,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
!segtype->ops->target_percent(&dm->target_state, dm->mem,
|
||||
dm->cmd, seg, params,
|
||||
&total_numerator,
|
||||
&total_denominator,
|
||||
percent))
|
||||
&total_denominator))
|
||||
goto_out;
|
||||
|
||||
} while (next);
|
||||
@@ -393,7 +392,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
|
||||
if (total_denominator)
|
||||
*percent = (float) total_numerator *100 / total_denominator;
|
||||
else if (*percent < 0)
|
||||
else
|
||||
*percent = 100;
|
||||
|
||||
log_debug("LV percent: %f", *percent);
|
||||
|
||||
29
lib/cache/lvmcache.c
vendored
29
lib/cache/lvmcache.c
vendored
@@ -97,9 +97,10 @@ static void _update_cache_info_lock_state(struct lvmcache_info *info,
|
||||
int was_locked = (info->status & CACHE_LOCKED) ? 1 : 0;
|
||||
|
||||
/*
|
||||
* Cache becomes invalid whenever lock state changes
|
||||
* Cache becomes invalid whenever lock state changes unless
|
||||
* exclusive VG_GLOBAL is held (i.e. while scanning).
|
||||
*/
|
||||
if (was_locked != locked) {
|
||||
if (!vgname_is_locked(VG_GLOBAL) && (was_locked != locked)) {
|
||||
info->status |= CACHE_INVALID;
|
||||
*cached_vgmetadata_valid = 0;
|
||||
}
|
||||
@@ -166,7 +167,7 @@ void lvmcache_drop_metadata(const char *vgname)
|
||||
|
||||
/* Indicate that PVs could now be missing from the cache */
|
||||
init_full_scan_done(0);
|
||||
} else
|
||||
} else if (!vgname_is_locked(VG_GLOBAL))
|
||||
_drop_metadata(vgname);
|
||||
}
|
||||
|
||||
@@ -845,6 +846,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo, *primary_vginfo, *orphan_vginfo;
|
||||
struct lvmcache_info *info2, *info3;
|
||||
char mdabuf[32];
|
||||
// struct lvmcache_vginfo *old_vginfo, *next;
|
||||
|
||||
if (!vgname || (info && info->vginfo && !strcmp(info->vginfo->vgname, vgname)))
|
||||
@@ -914,11 +916,16 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
orphan_vginfo = vginfo_from_vgname(primary_vginfo->fmt->orphan_vg_name, NULL);
|
||||
_drop_vginfo(info2, primary_vginfo);
|
||||
_vginfo_attach_info(orphan_vginfo, info2);
|
||||
log_debug("lvmcache: %s: now in VG %s%s%s%s",
|
||||
if (info2->mdas.n)
|
||||
sprintf(mdabuf, " with %u mdas",
|
||||
list_size(&info2->mdas));
|
||||
else
|
||||
mdabuf[0] = '\0';
|
||||
log_debug("lvmcache: %s: now in VG %s%s%s%s%s",
|
||||
dev_name(info2->dev),
|
||||
vgname, orphan_vginfo->vgid[0] ? " (" : "",
|
||||
orphan_vginfo->vgid[0] ? orphan_vginfo->vgid : "",
|
||||
orphan_vginfo->vgid[0] ? ")" : "");
|
||||
orphan_vginfo->vgid[0] ? ")" : "", mdabuf);
|
||||
}
|
||||
|
||||
if (!_insert_vginfo(vginfo, vgid, vgstatus, creation_host,
|
||||
@@ -947,13 +954,17 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
/* FIXME Check consistency of list! */
|
||||
vginfo->fmt = fmt;
|
||||
|
||||
if (info)
|
||||
log_debug("lvmcache: %s: now in VG %s%s%s%s",
|
||||
if (info) {
|
||||
if (info->mdas.n)
|
||||
sprintf(mdabuf, " with %u mdas", list_size(&info->mdas));
|
||||
else
|
||||
mdabuf[0] = '\0';
|
||||
log_debug("lvmcache: %s: now in VG %s%s%s%s%s",
|
||||
dev_name(info->dev),
|
||||
vgname, vginfo->vgid[0] ? " (" : "",
|
||||
vginfo->vgid[0] ? vginfo->vgid : "",
|
||||
vginfo->vgid[0] ? ")" : "");
|
||||
else
|
||||
vginfo->vgid[0] ? ")" : "", mdabuf);
|
||||
} else
|
||||
log_debug("lvmcache: initialised VG %s", vgname);
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -755,6 +755,11 @@ static int _init_segtypes(struct cmd_context *cmd)
|
||||
segtype->library = NULL;
|
||||
list_add(&cmd->segtypes, &segtype->list);
|
||||
|
||||
if (!(segtype = init_free_segtype(cmd)))
|
||||
return 0;
|
||||
segtype->library = NULL;
|
||||
list_add(&cmd->segtypes, &segtype->list);
|
||||
|
||||
#ifdef SNAPSHOT_INTERNAL
|
||||
if (!(segtype = init_snapshot_segtype(cmd)))
|
||||
return 0;
|
||||
|
||||
@@ -1011,7 +1011,7 @@ float find_config_tree_float(struct cmd_context *cmd, const char *path,
|
||||
return _find_config_float(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail);
|
||||
}
|
||||
|
||||
static int _str_in_array(const char *str, const char *values[])
|
||||
static int _str_in_array(const char *str, const char * const values[])
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1024,9 +1024,8 @@ static int _str_in_array(const char *str, const char *values[])
|
||||
|
||||
static int _str_to_bool(const char *str, int fail)
|
||||
{
|
||||
static const char *_true_values[] = { "y", "yes", "on", "true", NULL };
|
||||
static const char *_false_values[] =
|
||||
{ "n", "no", "off", "false", NULL };
|
||||
const char * const _true_values[] = { "y", "yes", "on", "true", NULL };
|
||||
const char * const _false_values[] = { "n", "no", "off", "false", NULL };
|
||||
|
||||
if (_str_in_array(str, _true_values))
|
||||
return 1;
|
||||
@@ -1276,7 +1275,7 @@ unsigned maybe_config_section(const char *str, unsigned len)
|
||||
begin_count = _count_tokens(str, len, TOK_SECTION_B);
|
||||
end_count = _count_tokens(str, len, TOK_SECTION_E);
|
||||
|
||||
if (begin_count && end_count && (begin_count - end_count == 0))
|
||||
if (begin_count && end_count && (begin_count == end_count))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
/* Define some portable printing types */
|
||||
#define PRIsize_t "zu"
|
||||
#define PRIptrdiff_t "td"
|
||||
#define PRIpid_t PRId32
|
||||
|
||||
struct str_list {
|
||||
struct list list;
|
||||
|
||||
@@ -94,11 +94,6 @@ const char *dev_name_confirmed(struct device *dev, int quiet);
|
||||
/* Does device contain md superblock? If so, where? */
|
||||
int dev_is_md(struct device *dev, uint64_t *sb);
|
||||
|
||||
/* FIXME Check partition type if appropriate */
|
||||
|
||||
#define is_lvm_partition(a) 1
|
||||
/* int is_lvm_partition(const char *name); */
|
||||
|
||||
int is_partitioned_dev(struct device *dev);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
typedef enum { SIZE_LONG = 0, SIZE_SHORT = 1, SIZE_UNIT = 2 } size_len_t;
|
||||
|
||||
static struct {
|
||||
static const struct {
|
||||
alloc_policy_t alloc;
|
||||
const char *str;
|
||||
const char str[12]; /* must be changed when size extends 11 chars */
|
||||
} _policies[] = {
|
||||
{
|
||||
ALLOC_CONTIGUOUS, "contiguous"}, {
|
||||
@@ -36,7 +36,7 @@ static struct {
|
||||
ALLOC_INHERIT, "inherit"}
|
||||
};
|
||||
|
||||
static int _num_policies = sizeof(_policies) / sizeof(*_policies);
|
||||
static const int _num_policies = sizeof(_policies) / sizeof(*_policies);
|
||||
|
||||
uint64_t units_to_bytes(const char *units, char *unit_type)
|
||||
{
|
||||
@@ -155,7 +155,7 @@ static const char *_display_size(const struct cmd_context *cmd,
|
||||
uint64_t byte = UINT64_C(0);
|
||||
uint64_t units = UINT64_C(1024);
|
||||
char *size_buf = NULL;
|
||||
const char *size_str[][3] = {
|
||||
const char * const size_str[][3] = {
|
||||
{" Exabyte", " EB", "E"},
|
||||
{" Petabyte", " PB", "P"},
|
||||
{" Terabyte", " TB", "T"},
|
||||
|
||||
@@ -356,7 +356,7 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
|
||||
list_init(&dl->lvds);
|
||||
|
||||
if (!_read_pvd(dev, &dl->pvd))
|
||||
goto_bad;
|
||||
goto bad;
|
||||
|
||||
/*
|
||||
* is it an orphan ?
|
||||
|
||||
@@ -321,6 +321,20 @@ static int _print_header(struct formatter *f,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _print_flag_config(struct formatter *f, int status, int type)
|
||||
{
|
||||
char buffer[4096];
|
||||
if (!print_flags(status, type | STATUS_FLAG, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
outf(f, "status = %s", buffer);
|
||||
|
||||
if (!print_flags(status, type, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
outf(f, "flags = %s", buffer);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _print_vg(struct formatter *f, struct volume_group *vg)
|
||||
{
|
||||
char buffer[4096];
|
||||
@@ -332,9 +346,8 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
|
||||
|
||||
outf(f, "seqno = %u", vg->seqno);
|
||||
|
||||
if (!print_flags(vg->status, VG_FLAGS, buffer, sizeof(buffer)))
|
||||
if (!_print_flag_config(f, vg->status, VG_FLAGS))
|
||||
return_0;
|
||||
outf(f, "status = %s", buffer);
|
||||
|
||||
if (!list_empty(&vg->tags)) {
|
||||
if (!print_tags(&vg->tags, buffer, sizeof(buffer)))
|
||||
@@ -408,9 +421,8 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||
return_0;
|
||||
outnl(f);
|
||||
|
||||
if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer)))
|
||||
if (!_print_flag_config(f, pv->status, PV_FLAGS))
|
||||
return_0;
|
||||
outf(f, "status = %s", buffer);
|
||||
|
||||
if (!list_empty(&pv->tags)) {
|
||||
if (!print_tags(&pv->tags, buffer, sizeof(buffer)))
|
||||
@@ -520,9 +532,8 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
|
||||
|
||||
outf(f, "id = \"%s\"", buffer);
|
||||
|
||||
if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer)))
|
||||
if (!_print_flag_config(f, lv->status, LV_FLAGS))
|
||||
return_0;
|
||||
outf(f, "status = %s", buffer);
|
||||
|
||||
if (!list_empty(&lv->tags)) {
|
||||
if (!print_tags(&lv->tags, buffer, sizeof(buffer)))
|
||||
|
||||
@@ -25,48 +25,49 @@
|
||||
struct flag {
|
||||
const int mask;
|
||||
const char *description;
|
||||
int kind;
|
||||
};
|
||||
|
||||
static struct flag _vg_flags[] = {
|
||||
{EXPORTED_VG, "EXPORTED"},
|
||||
{RESIZEABLE_VG, "RESIZEABLE"},
|
||||
{PARTIAL_VG, "PARTIAL"},
|
||||
{PVMOVE, "PVMOVE"},
|
||||
{LVM_READ, "READ"},
|
||||
{LVM_WRITE, "WRITE"},
|
||||
{CLUSTERED, "CLUSTERED"},
|
||||
{SHARED, "SHARED"},
|
||||
{PRECOMMITTED, NULL},
|
||||
{0, NULL}
|
||||
{EXPORTED_VG, "EXPORTED", STATUS_FLAG},
|
||||
{RESIZEABLE_VG, "RESIZEABLE", STATUS_FLAG},
|
||||
{PARTIAL_VG, "PARTIAL", STATUS_FLAG},
|
||||
{PVMOVE, "PVMOVE", STATUS_FLAG},
|
||||
{LVM_READ, "READ", STATUS_FLAG},
|
||||
{LVM_WRITE, "WRITE", STATUS_FLAG},
|
||||
{CLUSTERED, "CLUSTERED", STATUS_FLAG},
|
||||
{SHARED, "SHARED", STATUS_FLAG},
|
||||
{PRECOMMITTED, NULL, 0},
|
||||
{0, NULL, 0}
|
||||
};
|
||||
|
||||
static struct flag _pv_flags[] = {
|
||||
{ALLOCATABLE_PV, "ALLOCATABLE"},
|
||||
{EXPORTED_VG, "EXPORTED"},
|
||||
{0, NULL}
|
||||
{ALLOCATABLE_PV, "ALLOCATABLE", STATUS_FLAG},
|
||||
{EXPORTED_VG, "EXPORTED", STATUS_FLAG},
|
||||
{0, NULL, 0}
|
||||
};
|
||||
|
||||
static struct flag _lv_flags[] = {
|
||||
{LVM_READ, "READ"},
|
||||
{LVM_WRITE, "WRITE"},
|
||||
{FIXED_MINOR, "FIXED_MINOR"},
|
||||
{VISIBLE_LV, "VISIBLE"},
|
||||
{PVMOVE, "PVMOVE"},
|
||||
{LOCKED, "LOCKED"},
|
||||
{MIRROR_NOTSYNCED, "NOTSYNCED"},
|
||||
{MIRROR_IMAGE, NULL},
|
||||
{MIRROR_LOG, NULL},
|
||||
{MIRRORED, NULL},
|
||||
{VIRTUAL, NULL},
|
||||
{SNAPSHOT, NULL},
|
||||
{ACTIVATE_EXCL, NULL},
|
||||
{CONVERTING, NULL},
|
||||
{0, NULL}
|
||||
{LVM_READ, "READ", STATUS_FLAG},
|
||||
{LVM_WRITE, "WRITE", STATUS_FLAG},
|
||||
{FIXED_MINOR, "FIXED_MINOR", STATUS_FLAG},
|
||||
{VISIBLE_LV, "VISIBLE", STATUS_FLAG},
|
||||
{PVMOVE, "PVMOVE", STATUS_FLAG},
|
||||
{LOCKED, "LOCKED", STATUS_FLAG},
|
||||
{MIRROR_NOTSYNCED, "NOTSYNCED", STATUS_FLAG},
|
||||
{MIRROR_IMAGE, NULL, 0},
|
||||
{MIRROR_LOG, NULL, 0},
|
||||
{MIRRORED, NULL, 0},
|
||||
{VIRTUAL, NULL, 0},
|
||||
{SNAPSHOT, NULL, 0},
|
||||
{ACTIVATE_EXCL, NULL, 0},
|
||||
{CONVERTING, NULL, 0},
|
||||
{0, NULL, 0}
|
||||
};
|
||||
|
||||
static struct flag *_get_flags(int type)
|
||||
{
|
||||
switch (type) {
|
||||
switch (type & ~STATUS_FLAG) {
|
||||
case VG_FLAGS:
|
||||
return _vg_flags;
|
||||
|
||||
@@ -101,6 +102,9 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size)
|
||||
if (status & flags[f].mask) {
|
||||
status &= ~flags[f].mask;
|
||||
|
||||
if ((type & STATUS_FLAG) != flags[f].kind)
|
||||
continue;
|
||||
|
||||
/* Internal-only flag? */
|
||||
if (!flags[f].description)
|
||||
continue;
|
||||
@@ -151,7 +155,7 @@ int read_flags(uint32_t *status, int type, struct config_value *cv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!flags[f].description) {
|
||||
if (!flags[f].description && (type & STATUS_FLAG)) {
|
||||
log_err("Unknown status flag '%s'.", cv->v.str);
|
||||
return 0;
|
||||
}
|
||||
@@ -160,6 +164,6 @@ int read_flags(uint32_t *status, int type, struct config_value *cv)
|
||||
}
|
||||
|
||||
out:
|
||||
*status = s;
|
||||
*status |= s;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
|
||||
struct raw_locn *rlocn;
|
||||
uint64_t area_start;
|
||||
uint64_t area_size;
|
||||
uint64_t prev_sector;
|
||||
uint64_t prev_sector, prev_sector2;
|
||||
uint64_t latest_mrec_offset;
|
||||
int i;
|
||||
uint64_t offset;
|
||||
@@ -184,8 +184,11 @@ static int _pv_analyze_mda_raw (const struct format_type * fmt,
|
||||
offset2 = size2 = 0;
|
||||
i = 0;
|
||||
while (prev_sector != latest_mrec_offset) {
|
||||
prev_sector2 = prev_sector;
|
||||
prev_sector = _get_prev_sector_circular(area_start, area_size,
|
||||
prev_sector);
|
||||
if (prev_sector > prev_sector2)
|
||||
goto_out;
|
||||
/*
|
||||
* FIXME: for some reason, the whole metadata region from
|
||||
* area->start to area->start+area->size is not used.
|
||||
@@ -343,10 +346,8 @@ static int _raw_write_mda_header(const struct format_type *fmt,
|
||||
MDA_HEADER_SIZE -
|
||||
sizeof(mdah->checksum_xl)));
|
||||
|
||||
if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) {
|
||||
dm_pool_free(fmt->cmd->mem, mdah);
|
||||
if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah))
|
||||
return_0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -667,6 +668,7 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
||||
|
||||
if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
|
||||
mdah)) {
|
||||
dm_pool_free(fid->fmt->cmd->mem, mdah);
|
||||
log_error("Failed to write metadata area header");
|
||||
goto out;
|
||||
}
|
||||
@@ -749,6 +751,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
|
||||
if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
|
||||
mdah)) {
|
||||
dm_pool_free(fid->fmt->cmd->mem, mdah);
|
||||
log_error("Failed to write metadata area header");
|
||||
goto out;
|
||||
}
|
||||
@@ -1363,7 +1366,10 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
|
||||
}
|
||||
}
|
||||
|
||||
label_write(pv->dev, label);
|
||||
if (!label_write(pv->dev, label)) {
|
||||
dev_close(pv->dev);
|
||||
return_0;
|
||||
}
|
||||
|
||||
if (!dev_close(pv->dev))
|
||||
return_0;
|
||||
@@ -1393,43 +1399,33 @@ static int _add_raw(struct list *raw_list, struct device_area *dev_area)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
struct physical_volume *pv, struct list *mdas)
|
||||
static int _get_pv_if_in_vg(struct lvmcache_info *info,
|
||||
struct physical_volume *pv)
|
||||
{
|
||||
struct label *label;
|
||||
struct device *dev;
|
||||
struct lvmcache_info *info;
|
||||
struct metadata_area *mda, *mda_new;
|
||||
struct mda_context *mdac, *mdac_new;
|
||||
struct data_area_list *da;
|
||||
|
||||
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
|
||||
return_0;
|
||||
|
||||
/* FIXME Optimise out repeated reading when cache lock held */
|
||||
if (!(label_read(dev, &label, UINT64_C(0))))
|
||||
return_0;
|
||||
info = (struct lvmcache_info *) label->info;
|
||||
|
||||
/* Have we already cached vgname? */
|
||||
if (info->vginfo && info->vginfo->vgname &&
|
||||
!is_orphan_vg(info->vginfo->vgname) &&
|
||||
get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
|
||||
info->vginfo->vgid, info->dev->pvid, pv)) {
|
||||
info->vginfo->vgid, info->dev->pvid, pv))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _populate_pv_fields(struct lvmcache_info *info,
|
||||
struct physical_volume *pv)
|
||||
{
|
||||
struct data_area_list *da;
|
||||
|
||||
/* Have we already cached vgname? */
|
||||
if (_get_pv_if_in_vg(info, pv))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Perform full scan (just the first time) and try again */
|
||||
if (!memlock() && !full_scan_done()) {
|
||||
lvmcache_label_scan(fmt->cmd, 2);
|
||||
lvmcache_label_scan(info->fmt->cmd, 2);
|
||||
|
||||
if (info->vginfo && info->vginfo->vgname &&
|
||||
!is_orphan_vg(info->vginfo->vgname) &&
|
||||
get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
|
||||
info->vginfo->vgid,
|
||||
info->dev->pvid, pv)) {
|
||||
if (_get_pv_if_in_vg(info, pv))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Orphan */
|
||||
@@ -1442,13 +1438,35 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
/* Currently only support exactly one data area */
|
||||
if (list_size(&info->das) != 1) {
|
||||
log_error("Must be exactly one data area (found %d) on PV %s",
|
||||
list_size(&info->das), dev_name(dev));
|
||||
list_size(&info->das), dev_name(info->dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_iterate_items(da, &info->das)
|
||||
pv->pe_start = da->disk_locn.offset >> SECTOR_SHIFT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
struct physical_volume *pv, struct list *mdas)
|
||||
{
|
||||
struct label *label;
|
||||
struct device *dev;
|
||||
struct lvmcache_info *info;
|
||||
struct metadata_area *mda, *mda_new;
|
||||
struct mda_context *mdac, *mdac_new;
|
||||
|
||||
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
|
||||
return_0;
|
||||
|
||||
if (!(label_read(dev, &label, UINT64_C(0))))
|
||||
return_0;
|
||||
info = (struct lvmcache_info *) label->info;
|
||||
|
||||
if (!_populate_pv_fields(info, pv))
|
||||
return 0;
|
||||
|
||||
if (!mdas)
|
||||
return 1;
|
||||
|
||||
|
||||
@@ -36,9 +36,11 @@
|
||||
* common code for reading and writing them.
|
||||
*/
|
||||
enum {
|
||||
COMPATIBLE_FLAG = 0x0,
|
||||
VG_FLAGS,
|
||||
PV_FLAGS,
|
||||
LV_FLAGS
|
||||
LV_FLAGS,
|
||||
STATUS_FLAG = 0x8,
|
||||
};
|
||||
|
||||
struct text_vg_version_ops {
|
||||
|
||||
@@ -125,6 +125,31 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_flag_config(struct config_node *n, uint32_t *status, int type)
|
||||
{
|
||||
struct config_node *cn;
|
||||
*status = 0;
|
||||
|
||||
if (!(cn = find_config_node(n, "status"))) {
|
||||
log_error("Could not find status flags.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(read_flags(status, type | STATUS_FLAG, cn->v))) {
|
||||
log_error("Could not read status flags.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((cn = find_config_node(n, "flags"))) {
|
||||
if (!(read_flags(status, type, cn->v))) {
|
||||
log_error("Could not read flags.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *pvn,
|
||||
struct config_node *vgn __attribute((unused)),
|
||||
@@ -181,12 +206,7 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
|
||||
|
||||
memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
|
||||
|
||||
if (!(cn = find_config_node(pvn, "status"))) {
|
||||
log_error("Couldn't find status flags for physical volume.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(read_flags(&pv->status, PV_FLAGS, cn->v))) {
|
||||
if (!_read_flag_config(pvn, &pv->status, PV_FLAGS)) {
|
||||
log_error("Couldn't read status flags for physical volume.");
|
||||
return 0;
|
||||
}
|
||||
@@ -493,13 +513,9 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cn = find_config_node(lvn, "status"))) {
|
||||
log_error("Couldn't find status flags for logical volume.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(read_flags(&lv->status, LV_FLAGS, cn->v))) {
|
||||
log_error("Couldn't read status flags for logical volume.");
|
||||
if (!_read_flag_config(lvn, &lv->status, LV_FLAGS)) {
|
||||
log_error("Couldn't read status flags for logical volume %s.",
|
||||
lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -692,14 +708,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(cn = find_config_node(vgn, "status"))) {
|
||||
log_error("Couldn't find status flags for volume group %s.",
|
||||
vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(read_flags(&vg->status, VG_FLAGS, cn->v))) {
|
||||
log_error("Couldn't read status flags for volume group %s.",
|
||||
if (!_read_flag_config(vgn, &vg->status, VG_FLAGS)) {
|
||||
log_error("Error reading flags of volume group %s.",
|
||||
vg->name);
|
||||
goto bad;
|
||||
}
|
||||
@@ -826,7 +836,7 @@ static const char *_read_vgname(const struct format_type *fmt,
|
||||
struct config_tree *cft, struct id *vgid,
|
||||
uint32_t *vgstatus, char **creation_host)
|
||||
{
|
||||
struct config_node *vgn, *cn;
|
||||
struct config_node *vgn;
|
||||
struct dm_pool *mem = fmt->cmd->mem;
|
||||
char *vgname;
|
||||
int old_suppress;
|
||||
@@ -855,18 +865,12 @@ static const char *_read_vgname(const struct format_type *fmt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cn = find_config_node(vgn, "status"))) {
|
||||
if (!_read_flag_config(vgn, vgstatus, VG_FLAGS)) {
|
||||
log_error("Couldn't find status flags for volume group %s.",
|
||||
vgname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(read_flags(vgstatus, VG_FLAGS, cn->v))) {
|
||||
log_error("Couldn't read status flags for volume group %s.",
|
||||
vgname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return vgname;
|
||||
}
|
||||
|
||||
|
||||
60
lib/freeseg/freeseg.c
Normal file
60
lib/freeseg/freeseg.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
* 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 Lesser General Public License v.2.1.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser 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
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "toolcontext.h"
|
||||
#include "segtype.h"
|
||||
#include "display.h"
|
||||
#include "text_export.h"
|
||||
#include "text_import.h"
|
||||
#include "config.h"
|
||||
#include "str_list.h"
|
||||
#include "targets.h"
|
||||
#include "lvm-string.h"
|
||||
#include "activate.h"
|
||||
#include "str_list.h"
|
||||
#include "metadata.h"
|
||||
|
||||
static const char *_freeseg_name(const struct lv_segment *seg)
|
||||
{
|
||||
return seg->segtype->name;
|
||||
}
|
||||
|
||||
static void _freeseg_destroy(const struct segment_type *segtype)
|
||||
{
|
||||
dm_free((void *)segtype);
|
||||
}
|
||||
|
||||
static struct segtype_handler _freeseg_ops = {
|
||||
.name = _freeseg_name,
|
||||
.destroy = _freeseg_destroy,
|
||||
};
|
||||
|
||||
struct segment_type *init_free_segtype(struct cmd_context *cmd)
|
||||
{
|
||||
struct segment_type *segtype = dm_malloc(sizeof(*segtype));
|
||||
|
||||
if (!segtype)
|
||||
return_NULL;
|
||||
|
||||
segtype->cmd = cmd;
|
||||
segtype->ops = &_freeseg_ops;
|
||||
segtype->name = "free";
|
||||
segtype->private = NULL;
|
||||
segtype->flags = SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
|
||||
|
||||
log_very_verbose("Initialised segtype: %s", segtype->name);
|
||||
|
||||
return segtype;
|
||||
}
|
||||
@@ -284,7 +284,7 @@ int label_read(struct device *dev, struct label **result,
|
||||
}
|
||||
|
||||
if (!(l = _find_labeller(dev, buf, §or, scan_sector)))
|
||||
goto_out;
|
||||
goto out;
|
||||
|
||||
if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result)
|
||||
(*result)->sector = sector;
|
||||
@@ -361,7 +361,7 @@ int label_verify(struct device *dev)
|
||||
}
|
||||
|
||||
if (!(l = _find_labeller(dev, buf, §or, UINT64_C(0))))
|
||||
goto_out;
|
||||
goto out;
|
||||
|
||||
r = l->ops->verify ? l->ops->verify(l, buf, sector) : 1;
|
||||
|
||||
|
||||
@@ -292,6 +292,10 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
|
||||
if (is_orphan_vg(vgname))
|
||||
return 1;
|
||||
|
||||
/* LVM1 is only present in 2.4 kernels. */
|
||||
if (strncmp(cmd->kernel_vsn, "2.4.", 4))
|
||||
return 1;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir,
|
||||
vgname) < 0) {
|
||||
log_error("LVM1 proc VG pathname too long for %s", vgname);
|
||||
|
||||
@@ -2048,6 +2048,27 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* remove LVs with its dependencies - LV leaf nodes should be removed first
|
||||
*/
|
||||
int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
const force_t force)
|
||||
{
|
||||
struct list *snh, *snht;
|
||||
|
||||
if (lv_is_origin(lv)) {
|
||||
/* remove snapshot LVs first */
|
||||
list_iterate_safe(snh, snht, &lv->snapshot_segs) {
|
||||
if (!lv_remove_with_dependencies(cmd, list_struct_base(snh, struct lv_segment,
|
||||
origin_list)->cow,
|
||||
force))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return lv_remove_single(cmd, lv, force);
|
||||
}
|
||||
|
||||
/*
|
||||
* insert_layer_for_segments_on_pv() inserts a layer segment for a segment area.
|
||||
* However, layer modification could split the underlying layer segment.
|
||||
|
||||
@@ -416,6 +416,9 @@ int lv_remove(struct logical_volume *lv);
|
||||
int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
force_t force);
|
||||
|
||||
int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
force_t force);
|
||||
|
||||
int lv_rename(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
const char *new_name);
|
||||
|
||||
@@ -529,6 +532,7 @@ int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
struct list *removable_pvs, unsigned remove_log);
|
||||
int collapse_mirrored_lv(struct logical_volume *lv);
|
||||
int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage);
|
||||
|
||||
struct logical_volume *find_pvmove_lv(struct volume_group *vg,
|
||||
struct device *dev, uint32_t lv_type);
|
||||
|
||||
@@ -296,11 +296,14 @@ static int remove_lvs_in_vg(struct cmd_context *cmd,
|
||||
struct volume_group *vg,
|
||||
force_t force)
|
||||
{
|
||||
struct list *lst;
|
||||
struct lv_list *lvl;
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs)
|
||||
if (!lv_remove_single(cmd, lvl->lv, force))
|
||||
return 0;
|
||||
while ((lst = list_first(&vg->lvs))) {
|
||||
lvl = list_item(lst, struct lv_list);
|
||||
if (!lv_remove_with_dependencies(cmd, lvl->lv, force))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1252,6 +1255,13 @@ int vg_validate(struct volume_group *vg)
|
||||
}
|
||||
}
|
||||
|
||||
if (!(vg->fid->fmt->features & FMT_UNLIMITED_VOLS) &&
|
||||
(!vg->max_lv || !vg->max_pv)) {
|
||||
log_error("Internal error: Volume group %s has limited PV/LV count"
|
||||
" but limit is not set.", vg->name);
|
||||
r = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1488,8 +1498,10 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
const struct format_type *fmt;
|
||||
struct volume_group *vg, *correct_vg = NULL;
|
||||
struct metadata_area *mda;
|
||||
struct lvmcache_info *info;
|
||||
int inconsistent = 0;
|
||||
int inconsistent_vgid = 0;
|
||||
int inconsistent_pvs = 0;
|
||||
unsigned use_precommitted = precommitted;
|
||||
struct list *pvids;
|
||||
struct pv_list *pvl, *pvl2;
|
||||
@@ -1564,6 +1576,44 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
|
||||
/* Ensure every PV in the VG was in the cache */
|
||||
if (correct_vg) {
|
||||
/*
|
||||
* If the VG has PVs without mdas, they may still be
|
||||
* orphans in the cache: update the cache state here.
|
||||
*/
|
||||
if (!inconsistent &&
|
||||
list_size(&correct_vg->pvs) > list_size(pvids)) {
|
||||
list_iterate_items(pvl, &correct_vg->pvs) {
|
||||
if (!pvl->pv->dev) {
|
||||
inconsistent_pvs = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (str_list_match_item(pvids, pvl->pv->dev->pvid))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* PV not marked as belonging to this VG in cache.
|
||||
* Check it's an orphan without metadata area.
|
||||
*/
|
||||
if (!(info = info_from_pvid(pvl->pv->dev->pvid, 1)) ||
|
||||
!info->vginfo || !is_orphan_vg(info->vginfo->vgname) ||
|
||||
list_size(&info->mdas)) {
|
||||
inconsistent_pvs = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the check passed, let's update VG and recalculate pvids */
|
||||
if (!inconsistent_pvs) {
|
||||
log_debug("Updating cache for PVs without mdas "
|
||||
"in VG %s.", vgname);
|
||||
lvmcache_update_vg(correct_vg, use_precommitted);
|
||||
|
||||
if (!(pvids = lvmcache_get_pvids(cmd, vgname, vgid)))
|
||||
return_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (list_size(&correct_vg->pvs) != list_size(pvids)) {
|
||||
log_debug("Cached VG %s had incorrect PV list",
|
||||
vgname);
|
||||
|
||||
@@ -135,6 +135,53 @@ uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
|
||||
return region_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* shift_mirror_images
|
||||
* @mirrored_seg
|
||||
* @mimage: The position (index) of the image to move to the end
|
||||
*
|
||||
* When dealing with removal of legs, we often move a 'removable leg'
|
||||
* to the back of the 'areas' array. It is critically important not
|
||||
* to simply swap it for the last area in the array. This would have
|
||||
* the affect of reordering the remaining legs - altering position of
|
||||
* the primary. So, we must shuffle all of the areas in the array
|
||||
* to maintain their relative position before moving the 'removable
|
||||
* leg' to the end.
|
||||
*
|
||||
* Short illustration of the problem:
|
||||
* - Mirror consists of legs A, B, C and we want to remove A
|
||||
* - We swap A and C and then remove A, leaving C, B
|
||||
* This scenario is problematic in failure cases where A dies, because
|
||||
* B becomes the primary. If the above happens, we effectively throw
|
||||
* away any changes made between the time of failure and the time of
|
||||
* restructuring the mirror.
|
||||
*
|
||||
* So, any time we want to move areas to the end to be removed, use
|
||||
* this function.
|
||||
*/
|
||||
int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage)
|
||||
{
|
||||
int i;
|
||||
struct lv_segment_area area;
|
||||
|
||||
if (mimage >= mirrored_seg->area_count) {
|
||||
log_error("Invalid index (%u) of mirror image supplied "
|
||||
"to shift_mirror_images()", mimage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
area = mirrored_seg->areas[mimage];
|
||||
|
||||
/* Shift remaining images down to fill the hole */
|
||||
for (i = mimage + 1; i < mirrored_seg->area_count; i++)
|
||||
mirrored_seg->areas[i-1] = mirrored_seg->areas[i];
|
||||
|
||||
/* Place this one at the end */
|
||||
mirrored_seg->areas[i-1] = area;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function writes a new header to the mirror log header to the lv
|
||||
*
|
||||
@@ -469,13 +516,12 @@ static int _remove_mirror_images(struct logical_volume *lv,
|
||||
for (s = 0; s < mirrored_seg->area_count &&
|
||||
old_area_count - new_area_count < num_removed; s++) {
|
||||
sub_lv = seg_lv(mirrored_seg, s);
|
||||
|
||||
if (!is_temporary_mirror_layer(sub_lv) &&
|
||||
_is_mirror_image_removable(sub_lv, removable_pvs)) {
|
||||
/* Swap segment to end */
|
||||
if (!shift_mirror_images(mirrored_seg, s))
|
||||
return_0;
|
||||
new_area_count--;
|
||||
area = mirrored_seg->areas[new_area_count];
|
||||
mirrored_seg->areas[new_area_count] = mirrored_seg->areas[s];
|
||||
mirrored_seg->areas[s] = area;
|
||||
}
|
||||
}
|
||||
if (num_removed && old_area_count == new_area_count)
|
||||
@@ -552,6 +598,17 @@ static int _remove_mirror_images(struct logical_volume *lv,
|
||||
|
||||
log_very_verbose("Updating \"%s\" in kernel", mirrored_seg->lv->name);
|
||||
|
||||
/*
|
||||
* Avoid having same mirror target loaded twice simultaneouly by first
|
||||
* activating the removed LV which now contains an error segment.
|
||||
* As it's now detached from mirrored_seg->lv we must activate it
|
||||
* explicitly.
|
||||
*/
|
||||
if (lv1 && !activate_lv(lv1->vg->cmd, lv1)) {
|
||||
log_error("Problem reactivating removed %s", lv1->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
|
||||
log_error("Problem reactivating %s", mirrored_seg->lv->name);
|
||||
return 0;
|
||||
@@ -1140,6 +1197,8 @@ int remove_mirror_log(struct cmd_context *cmd,
|
||||
struct list *removable_pvs)
|
||||
{
|
||||
float sync_percent;
|
||||
struct lvinfo info;
|
||||
struct volume_group *vg = lv->vg;
|
||||
|
||||
/* Unimplemented features */
|
||||
if (list_size(&lv->segments) != 1) {
|
||||
@@ -1148,10 +1207,21 @@ int remove_mirror_log(struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
/* Had disk log, switch to core. */
|
||||
if (!lv_mirror_percent(cmd, lv, 0, &sync_percent, NULL)) {
|
||||
log_error("Unable to determine mirror sync status.");
|
||||
if (lv_info(cmd, lv, &info, 0, 0) && info.exists) {
|
||||
if (!lv_mirror_percent(cmd, lv, 0, &sync_percent, NULL)) {
|
||||
log_error("Unable to determine mirror sync status.");
|
||||
return 0;
|
||||
}
|
||||
} else if (vg_is_clustered(vg)) {
|
||||
log_error("Unable to convert the log of inactive "
|
||||
"cluster mirror %s", lv->name);
|
||||
return 0;
|
||||
} else if (yes_no_prompt("Full resync required to convert "
|
||||
"inactive mirror %s to core log. "
|
||||
"Proceed? [y/n]: "))
|
||||
sync_percent = 0;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sync_percent >= 100.0)
|
||||
init_mirror_in_sync(1);
|
||||
@@ -1269,12 +1339,9 @@ int attach_mirror_log(struct lv_segment *seg, struct logical_volume *log_lv)
|
||||
return add_seg_to_segs_using_this_lv(log_lv, seg);
|
||||
}
|
||||
|
||||
int add_mirror_log(struct cmd_context *cmd,
|
||||
struct logical_volume *lv,
|
||||
uint32_t log_count,
|
||||
uint32_t region_size,
|
||||
struct list *allocatable_pvs,
|
||||
alloc_policy_t alloc)
|
||||
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
uint32_t log_count, uint32_t region_size,
|
||||
struct list *allocatable_pvs, alloc_policy_t alloc)
|
||||
{
|
||||
struct alloc_handle *ah;
|
||||
const struct segment_type *segtype;
|
||||
@@ -1282,17 +1349,31 @@ int add_mirror_log(struct cmd_context *cmd,
|
||||
float sync_percent;
|
||||
int in_sync;
|
||||
struct logical_volume *log_lv;
|
||||
struct lvinfo info;
|
||||
|
||||
/* Unimplemented features */
|
||||
if (log_count > 1) {
|
||||
log_error("log_count > 1 is not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (list_size(&lv->segments) != 1) {
|
||||
log_error("Multiple-segment mirror is not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are unable to convert the log of inactive cluster mirrors
|
||||
* due to the inability to detect whether the mirror is active
|
||||
* on remote nodes (even though it is inactive on this node)
|
||||
*/
|
||||
if (vg_is_clustered(lv->vg) &&
|
||||
!(lv_info(cmd, lv, &info, 0, 0) && info.exists)) {
|
||||
log_error("Unable to convert the log of inactive "
|
||||
"cluster mirror %s", lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv)))
|
||||
return_0;
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ struct segtype_handler {
|
||||
struct cmd_context *cmd,
|
||||
struct lv_segment *seg, char *params,
|
||||
uint64_t *total_numerator,
|
||||
uint64_t *total_denominator, float *percent);
|
||||
uint64_t *total_denominator);
|
||||
int (*target_present) (const struct lv_segment *seg,
|
||||
unsigned *attributes);
|
||||
int (*modules_needed) (struct dm_pool *mem,
|
||||
@@ -95,6 +95,7 @@ struct segment_type *get_segtype_from_string(struct cmd_context *cmd,
|
||||
struct segment_type *init_striped_segtype(struct cmd_context *cmd);
|
||||
struct segment_type *init_zero_segtype(struct cmd_context *cmd);
|
||||
struct segment_type *init_error_segtype(struct cmd_context *cmd);
|
||||
struct segment_type *init_free_segtype(struct cmd_context *cmd);
|
||||
|
||||
#ifdef SNAPSHOT_INTERNAL
|
||||
struct segment_type *init_snapshot_segtype(struct cmd_context *cmd);
|
||||
|
||||
@@ -176,8 +176,7 @@ static struct mirror_state *_mirrored_init_target(struct dm_pool *mem,
|
||||
static int _mirrored_target_percent(void **target_state, struct dm_pool *mem,
|
||||
struct cmd_context *cmd, struct lv_segment *seg,
|
||||
char *params, uint64_t *total_numerator,
|
||||
uint64_t *total_denominator,
|
||||
float *percent __attribute((unused)))
|
||||
uint64_t *total_denominator)
|
||||
{
|
||||
struct mirror_state *mirr_state;
|
||||
uint64_t numerator, denominator;
|
||||
@@ -376,7 +375,7 @@ static int _mirrored_target_present(const struct lv_segment *seg __attribute((un
|
||||
* FIXME: Fails incorrectly if cmirror was built into kernel.
|
||||
*/
|
||||
if (attributes) {
|
||||
if (!_mirror_attributes && module_present("cmirror"))
|
||||
if (!_mirror_attributes && module_present("log-clustered"))
|
||||
_mirror_attributes |= MIRROR_LOG_CLUSTERED;
|
||||
*attributes = _mirror_attributes;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
|
||||
static inline char *last_path_component(char const *name)
|
||||
{
|
||||
char const *slash = strrchr (name, '/');
|
||||
char const *slash = strrchr(name, '/');
|
||||
char const *res = slash ? slash + 1 : name;
|
||||
return (char *) res;
|
||||
|
||||
return (char *)res;
|
||||
}
|
||||
|
||||
@@ -303,6 +303,10 @@ static int _lvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Blank if this is a "free space" LV. */
|
||||
if (!*lv->name)
|
||||
goto out;
|
||||
|
||||
if (lv->status & PVMOVE)
|
||||
repstr[0] = 'p';
|
||||
else if (lv->status & CONVERTING)
|
||||
@@ -332,8 +336,10 @@ static int _lvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_
|
||||
repstr[1] = '-';
|
||||
else if (lv->status & LVM_WRITE)
|
||||
repstr[1] = 'w';
|
||||
else
|
||||
else if (lv->status & LVM_READ)
|
||||
repstr[1] = 'r';
|
||||
else
|
||||
repstr[1] = '-';
|
||||
|
||||
repstr[2] = _alloc_policy_char(lv->alloc);
|
||||
|
||||
@@ -375,6 +381,7 @@ static int _lvstatus_disp(struct dm_report *rh __attribute((unused)), struct dm_
|
||||
repstr[5] = '-';
|
||||
}
|
||||
|
||||
out:
|
||||
dm_report_field_set_value(field, repstr, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -95,20 +95,14 @@ static int _snap_target_percent(void **target_state __attribute((unused)),
|
||||
struct cmd_context *cmd __attribute((unused)),
|
||||
struct lv_segment *seg __attribute((unused)),
|
||||
char *params, uint64_t *total_numerator,
|
||||
uint64_t *total_denominator, float *percent)
|
||||
uint64_t *total_denominator)
|
||||
{
|
||||
float percent2;
|
||||
uint64_t numerator, denominator;
|
||||
|
||||
if (strchr(params, '/')) {
|
||||
if (sscanf(params, "%" PRIu64 "/%" PRIu64,
|
||||
&numerator, &denominator) == 2) {
|
||||
*total_numerator += numerator;
|
||||
*total_denominator += denominator;
|
||||
}
|
||||
} else if (sscanf(params, "%f", &percent2) == 1) {
|
||||
*percent += percent2;
|
||||
*percent /= 2;
|
||||
if (sscanf(params, "%" PRIu64 "/%" PRIu64,
|
||||
&numerator, &denominator) == 2) {
|
||||
*total_numerator += numerator;
|
||||
*total_denominator += denominator;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static char _c[] =
|
||||
static const char _c[] =
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#";
|
||||
|
||||
static int _built_inverse;
|
||||
@@ -67,11 +68,29 @@ int lvnum_from_lvid(union lvid *lvid)
|
||||
lv_num *= sizeof(_c) - 1;
|
||||
if ((c = strchr(_c, lvid->id[1].uuid[i])))
|
||||
lv_num += (int) (c - _c);
|
||||
if (lv_num < 0)
|
||||
lv_num = 0;
|
||||
}
|
||||
|
||||
return lv_num;
|
||||
}
|
||||
|
||||
int lvid_in_restricted_range(union lvid *lvid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ID_LEN - 3; i++)
|
||||
if (lvid->id[1].uuid[i] != '0')
|
||||
return 0;
|
||||
|
||||
for (i = ID_LEN - 3; i < ID_LEN; i++)
|
||||
if (!isdigit(lvid->id[1].uuid[i]))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int id_create(struct id *id)
|
||||
{
|
||||
int randomfile;
|
||||
@@ -110,7 +129,7 @@ int id_create(struct id *id)
|
||||
*/
|
||||
static void _build_inverse(void)
|
||||
{
|
||||
char *ptr;
|
||||
const char *ptr;
|
||||
|
||||
if (_built_inverse)
|
||||
return;
|
||||
|
||||
@@ -34,6 +34,7 @@ union lvid {
|
||||
|
||||
int lvid_from_lvnum(union lvid *lvid, struct id *vgid, uint32_t lv_num);
|
||||
int lvnum_from_lvid(union lvid *lvid);
|
||||
int lvid_in_restricted_range(union lvid *lvid);
|
||||
|
||||
void uuid_from_num(char *uuid, uint32_t num);
|
||||
|
||||
|
||||
@@ -1501,6 +1501,11 @@ static int _create_and_load_v4(struct dm_task *dmt)
|
||||
return r;
|
||||
}
|
||||
|
||||
uint64_t dm_task_get_existing_table_size(struct dm_task *dmt)
|
||||
{
|
||||
return dmt->existing_table_size;
|
||||
}
|
||||
|
||||
static int _reload_with_suppression_v4(struct dm_task *dmt)
|
||||
{
|
||||
struct dm_task *task;
|
||||
@@ -1534,6 +1539,12 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Store existing table size */
|
||||
t2 = task->head;
|
||||
while (t2 && t2->next)
|
||||
t2 = t2->next;
|
||||
dmt->existing_table_size = t2 ? t2->start + t2->length : 0;
|
||||
|
||||
if ((task->dmi.v4->flags & DM_READONLY_FLAG) ? 1 : 0 != dmt->read_only)
|
||||
goto no_match;
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ struct dm_task {
|
||||
int no_open_count;
|
||||
int skip_lockfs;
|
||||
int suppress_identical_reload;
|
||||
uint64_t existing_table_size;
|
||||
|
||||
char *uuid;
|
||||
};
|
||||
@@ -69,5 +70,6 @@ struct cmd_data {
|
||||
};
|
||||
|
||||
int dm_check_version(void);
|
||||
uint64_t dm_task_get_existing_table_size(struct dm_task *dmt);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -181,8 +181,9 @@ int dm_task_add_target(struct dm_task *dmt,
|
||||
uint64_t size, const char *ttype, const char *params);
|
||||
|
||||
/*
|
||||
* Format major/minor numbers correctly for input to driver
|
||||
* Format major/minor numbers correctly for input to driver.
|
||||
*/
|
||||
#define DM_FORMAT_DEV_BUFSIZE 13 /* Minimum bufsize to handle worst case. */
|
||||
int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor);
|
||||
|
||||
/* Use this to retrive target information returned from a STATUS call */
|
||||
|
||||
@@ -99,6 +99,7 @@ struct load_properties {
|
||||
uint32_t read_ahead_flags;
|
||||
|
||||
unsigned segment_count;
|
||||
unsigned size_changed;
|
||||
struct list segs;
|
||||
|
||||
const char *new_name;
|
||||
@@ -603,6 +604,7 @@ struct dm_tree_node *dm_tree_add_new_dev(struct dm_tree *dtree,
|
||||
dnode->props.major = major;
|
||||
dnode->props.minor = minor;
|
||||
dnode->props.new_name = NULL;
|
||||
dnode->props.size_changed = 0;
|
||||
} else if (strcmp(name, dnode->name)) {
|
||||
/* Do we need to rename node? */
|
||||
if (!(dnode->props.new_name = dm_pool_strdup(dtree->mem, name))) {
|
||||
@@ -1243,7 +1245,7 @@ static int _emit_areas_line(struct dm_task *dmt __attribute((unused)),
|
||||
size_t paramsize, int *pos)
|
||||
{
|
||||
struct seg_area *area;
|
||||
char devbuf[10];
|
||||
char devbuf[DM_FORMAT_DEV_BUFSIZE];
|
||||
int tw;
|
||||
const char *prefix = "";
|
||||
|
||||
@@ -1270,7 +1272,8 @@ static int _emit_segment_line(struct dm_task *dmt, struct load_segment *seg, uin
|
||||
int pos = 0;
|
||||
int tw;
|
||||
int r;
|
||||
char originbuf[10], cowbuf[10], logbuf[10];
|
||||
char originbuf[DM_FORMAT_DEV_BUFSIZE], cowbuf[DM_FORMAT_DEV_BUFSIZE];
|
||||
char logbuf[DM_FORMAT_DEV_BUFSIZE];
|
||||
const char *logtype;
|
||||
|
||||
switch(seg->type) {
|
||||
@@ -1493,6 +1496,13 @@ static int _load_node(struct dm_tree_node *dnode)
|
||||
if (r && !dnode->info.inactive_table)
|
||||
log_verbose("Suppressed %s identical table reload.",
|
||||
dnode->name);
|
||||
|
||||
if ((dnode->props.size_changed =
|
||||
(dm_task_get_existing_table_size(dmt) == seg_start) ? 0 : 1))
|
||||
log_debug("Table size changed from %" PRIu64 " to %"
|
||||
PRIu64 " for %s",
|
||||
dm_task_get_existing_table_size(dmt),
|
||||
seg_start, dnode->name);
|
||||
}
|
||||
|
||||
dnode->props.segment_count = 0;
|
||||
@@ -1504,8 +1514,8 @@ out:
|
||||
}
|
||||
|
||||
int dm_tree_preload_children(struct dm_tree_node *dnode,
|
||||
const char *uuid_prefix,
|
||||
size_t uuid_prefix_len)
|
||||
const char *uuid_prefix,
|
||||
size_t uuid_prefix_len)
|
||||
{
|
||||
void *handle = NULL;
|
||||
struct dm_tree_node *child;
|
||||
@@ -1540,8 +1550,8 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
|
||||
}
|
||||
}
|
||||
|
||||
/* Resume device immediately if it has parents */
|
||||
if (!dm_tree_node_num_children(child, 1))
|
||||
/* Resume device immediately if it has parents and its size changed */
|
||||
if (!dm_tree_node_num_children(child, 1) || !child->props.size_changed)
|
||||
continue;
|
||||
|
||||
if (!child->info.inactive_table && !child->info.suspended)
|
||||
|
||||
@@ -267,8 +267,7 @@ static void _display_fields(struct dm_report *rh)
|
||||
log_warn("%s Fields", desc);
|
||||
log_warn("%*.*s", (int) strlen(desc) + 7,
|
||||
(int) strlen(desc) + 7,
|
||||
"------------------------------------------");
|
||||
|
||||
"-------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
/* FIXME Add line-wrapping at terminal width (or 80 cols) */
|
||||
|
||||
13
make.tmpl.in
13
make.tmpl.in
@@ -21,7 +21,10 @@ CC = @CC@
|
||||
RANLIB = @RANLIB@
|
||||
SHELL = /bin/sh
|
||||
INSTALL = @INSTALL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
MSGFMT = @MSGFMT@
|
||||
LCOV = @LCOV@
|
||||
GENHTML = @GENHTML@
|
||||
LN_S = @LN_S@
|
||||
LIBS = @LIBS@
|
||||
DEFS += @DEFS@
|
||||
@@ -204,11 +207,15 @@ $(LIB_STATIC): $(OBJECTS)
|
||||
|
||||
clean: $(SUBDIRS.clean)
|
||||
$(RM) $(OBJECTS) $(TARGETS) $(CLEAN_TARGETS) $(SOURCES:%.c=%.d) \
|
||||
$(SOURCES:%.c=%.pot) $(LDDEPS)
|
||||
$(SOURCES:%.c=%.pot) $(SOURCES:%.c=%.gcno) \
|
||||
$(SOURCES:%.c=%.gcda) $(LDDEPS)
|
||||
|
||||
distclean: $(SUBDIRS.distclean)
|
||||
$(RM) $(OBJECTS) $(TARGETS) $(CLEAN_TARGETS) $(DISTCLEAN_TARGETS) \
|
||||
$(SOURCES:%.c=%.d) $(SOURCES:%.c=%.pot) $(LDDEPS) \
|
||||
$(RM) -rf $(DISTCLEAN_DIRS)
|
||||
$(RM) $(DISTCLEAN_TARGETS) \
|
||||
$(OBJECTS) $(TARGETS) $(CLEAN_TARGETS) $(SOURCES:%.c=%.d) \
|
||||
$(SOURCES:%.c=%.pot) $(SOURCES:%.c=%.gcno) \
|
||||
$(SOURCES:%.c=%.gcda) $(LDDEPS) \
|
||||
config.cache config.log config.status \
|
||||
Makefile make.tmpl core \
|
||||
version.h lvm2.po
|
||||
|
||||
@@ -126,5 +126,5 @@ SCSI disk for later use by LVM:
|
||||
.sp
|
||||
.SH SEE ALSO
|
||||
.BR lvm "(8), " vgcreate "(8), " vgextend "(8), " lvcreate "(8), "
|
||||
.BR cfdisk "(8), " fdisk "(8), " losetup "(8), " mdadd "(8), "
|
||||
.BR cfdisk "(8), " fdisk "(8), " losetup "(8), " mdadm "(8), "
|
||||
.BR vgcfgrestore "(8), " vgconvert "(8)"
|
||||
|
||||
@@ -206,7 +206,7 @@ if (( $metadata )); then
|
||||
|
||||
pvs="$("$LVM" pvs --separator , --noheadings --units s --nosuffix -o \
|
||||
name,pe_start 2>> "$log" | $SED -e 's/^ *//')"
|
||||
for line in "$pvs"
|
||||
for line in $pvs
|
||||
do
|
||||
test -z "$line" && continue
|
||||
pv="$(echo $line | $CUT -d, -f1)"
|
||||
|
||||
@@ -48,7 +48,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
|
||||
$(T): init.sh
|
||||
@echo "*** $@ ***"; '$(SHELL_PATH_SQ)' \
|
||||
$(TESTS_ENVIRONMENT) $@ $(GIT_TEST_OPTS)
|
||||
$(TESTS_ENVIRONMENT) $@ $(LVM_TEST_OPTS)
|
||||
|
||||
.bin-dir-stamp: lvm-wrapper
|
||||
rm -rf bin
|
||||
@@ -63,7 +63,7 @@ lvm-wrapper: Makefile
|
||||
rm -f $@-t $@
|
||||
echo '#!/bin/sh' > $@-t
|
||||
test -n "@DMDIR@" \
|
||||
&& echo 'export LD_LIBRARY_PATH="@DMDIR@/lib"' >> $@-t
|
||||
&& echo 'export LD_LIBRARY_PATH="@DMDIR@/lib:@DMDIR@/dmeventd"' >> $@-t
|
||||
echo 'cmd=$$(echo ./$$0|sed "s,.*/,,")' >> $@-t
|
||||
echo 'test "$$cmd" = lvm &&' >> $@-t
|
||||
echo 'exec "$(abs_top_builddir)/tools/lvm" "$$@"' >> $@-t
|
||||
@@ -74,6 +74,8 @@ lvm-wrapper: Makefile
|
||||
clean:
|
||||
rm -rf init.sh lvm-wrapper bin .bin-dir-stamp
|
||||
|
||||
distclean: clean
|
||||
|
||||
all: $(T)
|
||||
.PHONY: $(T) clean
|
||||
.PHONY: $(T) clean distclean
|
||||
.NOTPARALLEL:
|
||||
|
||||
@@ -52,38 +52,64 @@ loop_setup_()
|
||||
|
||||
compare_vg_field_()
|
||||
{
|
||||
local vg1=$1;
|
||||
local vg2=$2;
|
||||
local field=$3;
|
||||
local val1;
|
||||
local val2;
|
||||
|
||||
val1=$(vgs --noheadings -o $field $vg1)
|
||||
val2=$(vgs --noheadings -o $field $vg2)
|
||||
if test "$verbose" = "t"
|
||||
then
|
||||
echo "compare_vg_field_ VG1: `vgs --noheadings -o $3 $1` VG2: `vgs --noheadings -o $3 $2`"
|
||||
echo "compare_vg_field_ VG1: $val1 VG2: $val2"
|
||||
fi
|
||||
return $(test $(vgs --noheadings -o $3 $1) == $(vgs --noheadings -o $3 $2) )
|
||||
return $(test $val1 == $val2 )
|
||||
}
|
||||
|
||||
check_vg_field_()
|
||||
{
|
||||
local vg=$1;
|
||||
local field=$2;
|
||||
local expected=$3;
|
||||
local actual;
|
||||
|
||||
actual=$(vgs --noheadings -o $field $vg)
|
||||
if test "$verbose" = "t"
|
||||
then
|
||||
echo "check_vg_field_ VG=$1, field=$2, actual=`vgs --noheadings -o $2 $1`, expected=$3"
|
||||
echo "check_vg_field_ VG=$vg, field=$field, actual=$actual, expected=$expected"
|
||||
fi
|
||||
return $(test $(vgs --noheadings -o $2 $1) == $3)
|
||||
return $(test $actual == $expected)
|
||||
}
|
||||
|
||||
check_pv_field_()
|
||||
{
|
||||
local pv=$1;
|
||||
local field=$2;
|
||||
local expected=$3;
|
||||
local actual;
|
||||
|
||||
actual=$(pvs --noheadings -o $field $pv)
|
||||
if test "$verbose" = "t"
|
||||
then
|
||||
echo "check_pv_field_ PV=$1, field=$2, actual=`pvs --noheadings -o $2 $1`, expected=$3"
|
||||
echo "check_pv_field_ PV=$pv, field=$field, actual=$actual, expected=$expected"
|
||||
fi
|
||||
return $(test $(pvs --noheadings -o $2 $1) == $3)
|
||||
return $(test $actual == $expected)
|
||||
}
|
||||
|
||||
check_lv_field_()
|
||||
{
|
||||
local lv=$1;
|
||||
local field=$2;
|
||||
local expected=$3;
|
||||
local actual;
|
||||
|
||||
actual=$(lvs --noheadings -o $field $lv)
|
||||
if test "$verbose" = "t"
|
||||
then
|
||||
echo "check_lv_field_ LV=$1, field=$2, actual=`lvs --noheadings -o $2 $1`, expected=$3"
|
||||
echo "check_lv_field_ LV=$lv, field=$field, actual=$actual, expected=$expected"
|
||||
fi
|
||||
return $(test $(lvs --noheadings -o $2 $1) == $3)
|
||||
return $(test $actual == $expected)
|
||||
}
|
||||
|
||||
vg_validate_pvlv_counts_()
|
||||
@@ -122,10 +148,20 @@ init_root_dir_()
|
||||
export DM_DEV_DIR=$G_dev_
|
||||
|
||||
# Only the first caller does anything.
|
||||
mkdir -p $G_root_/etc $G_dev_ $G_dev_/mapper
|
||||
mkdir -p $G_root_/etc $G_dev_ $G_dev_/mapper $G_root_/lib
|
||||
for i in 0 1 2 3 4 5 6 7; do
|
||||
mknod $G_root_/dev/loop$i b 7 $i
|
||||
done
|
||||
for i in $abs_top_builddir/dmeventd/mirror/*.so $abs_top_builddir/dmeventd/snapshot/*.so
|
||||
do
|
||||
# NOTE: This check is necessary because the loop above will give us the value
|
||||
# "$abs_top_builddir/dmeventd/mirror/*.so" if no files ending in 'so' exist.
|
||||
# This is the best way I could quickly determine to skip over this bogus value.
|
||||
if [ -f $i ]; then
|
||||
echo Setting up symlink from $i to $G_root_/lib
|
||||
ln -s $i $G_root_/lib
|
||||
fi
|
||||
done
|
||||
cat > $G_root_/etc/lvm.conf <<-EOF
|
||||
devices {
|
||||
dir = "$G_dev_"
|
||||
@@ -134,6 +170,18 @@ init_root_dir_()
|
||||
cache_dir = "$G_root_/etc"
|
||||
sysfs_scan = 0
|
||||
}
|
||||
log {
|
||||
verbose = $verboselevel
|
||||
syslog = 0
|
||||
indent = 1
|
||||
}
|
||||
backup {
|
||||
backup = 0
|
||||
archive = 0
|
||||
}
|
||||
global {
|
||||
library_dir = "$G_root_/lib"
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
@@ -32,4 +32,9 @@ test_expect_success \
|
||||
'ensure they are the same' \
|
||||
'diff -u actual expected'
|
||||
|
||||
# Need mdadm for some pvcreate tests
|
||||
test_expect_success \
|
||||
'verify mdadm is installed and in path (needed for pvcreate tests)' \
|
||||
'which mdadm'
|
||||
|
||||
test_done
|
||||
|
||||
99
test/t-covercmd.sh
Executable file
99
test/t-covercmd.sh
Executable file
@@ -0,0 +1,99 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2007 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
|
||||
|
||||
#
|
||||
# tests basic functionality of read-ahead and ra regressions
|
||||
#
|
||||
|
||||
test_description='Test coverage'
|
||||
privileges_required_=1
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
cleanup_()
|
||||
{
|
||||
vgremove -f "$vg" 2>/dev/null || true
|
||||
test -n "$d1" && losetup -d "$d1"
|
||||
test -n "$d2" && losetup -d "$d2"
|
||||
test -n "$d3" && losetup -d "$d3"
|
||||
test -n "$d4" && losetup -d "$d4"
|
||||
test -n "$d5" && losetup -d "$d5"
|
||||
rm -f "$f1" "$f2" "$f3" "$f4" "$f5"
|
||||
}
|
||||
|
||||
get_lvs_()
|
||||
{
|
||||
case $(lvs --units s --nosuffix --noheadings -o $1_read_ahead "$vg"/"$lv") in
|
||||
*$2) true ;;
|
||||
*) false ;;
|
||||
esac
|
||||
}
|
||||
|
||||
test_expect_success "set up temp files, loopback devices" \
|
||||
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
|
||||
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
|
||||
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
|
||||
f4=$(pwd)/4 && d4=$(loop_setup_ "$f4") &&
|
||||
f5=$(pwd)/5 && d5=$(loop_setup_ "$f5") &&
|
||||
vg=$(this_test_)-test-vg-$$ &&
|
||||
lv=$(this_test_)-test-lv-$$
|
||||
pvcreate "$d1" &&
|
||||
pvcreate --metadatacopies 0 "$d2" &&
|
||||
pvcreate --metadatacopies 0 "$d3" &&
|
||||
pvcreate "$d4" &&
|
||||
pvcreate --metadatacopies 0 "$d5" &&
|
||||
vgcreate -c n "$vg" "$d1" "$d2" "$d3" "$d4" "$d5" &&
|
||||
lvcreate -n "$lv" -l 1%FREE -i5 -I256 "$vg"'
|
||||
|
||||
test_expect_success "test *scan and *display tools" \
|
||||
'pvscan &&
|
||||
vgscan &&
|
||||
lvscan &&
|
||||
lvmdiskscan &&
|
||||
vgdisplay --units k &&
|
||||
lvdisplay --units g &&
|
||||
for i in b k m g t p e H B K M G T P E ; do \
|
||||
pvdisplay --units "$i" "$d1" || return $? ; done'
|
||||
|
||||
test_expect_success "test vgexport vgimport tools" \
|
||||
'vgchange -an "$vg" &&
|
||||
vgexport "$vg" &&
|
||||
vgimport "$vg" &&
|
||||
vgchange -ay "$vg"'
|
||||
|
||||
# "-persistent y --major 254 --minor 20"
|
||||
# "-persistent n"
|
||||
test_expect_success "test various lvm utils" \
|
||||
'for i in dumpconfig formats segtypes
|
||||
do lvm "$i" || return $? ; done &&
|
||||
for i in pr "p rw" an ay "-monitor y" "-monitor n" \
|
||||
-resync -refresh "-addtag MYTAG" "-deltag MYETAG"
|
||||
do lvchange -$i "$vg"/"$lv" || return $? ; done &&
|
||||
pvck "$d1" &&
|
||||
vgck "$vg" &&
|
||||
lvrename "$vg" "$lv" "$lv-rename" &&
|
||||
vgcfgbackup -f "$(pwd)/backup.$$" "$vg" &&
|
||||
vgchange -an "$vg" &&
|
||||
vgcfgrestore -f "$(pwd)/backup.$$" "$vg" &&
|
||||
vgremove -f "$vg" &&
|
||||
pvresize --setphysicalvolumesize 10M "$d1"'
|
||||
|
||||
test_expect_failure "test various errors and obsoleted tools" \
|
||||
'lvmchange ||
|
||||
lvrename "$vg" ||
|
||||
lvrename "$vg-xxx" ||
|
||||
lvrename "$vg" "$vg"/"$lv-rename" "$vg"/"$lv"'
|
||||
|
||||
test_done
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
@@ -36,6 +36,15 @@ test_expect_success \
|
||||
|
||||
lv=lvcreate-usage-$$
|
||||
|
||||
test_expect_success \
|
||||
"lvcreate rejects repeated invocation (run 2 times)" '
|
||||
lvcreate -n $lv -l 4 $vg &&
|
||||
{ lvcreate -n $lv -l 4 $vg;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
lvremove -ff $vg/$lv
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
'lvcreate rejects a negative stripe_size' \
|
||||
'lvcreate -L 64M -n $lv -i2 --stripesize -4 $vg 2>err;
|
||||
|
||||
68
test/t-metadata.sh
Executable file
68
test/t-metadata.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2007 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
|
||||
|
||||
#
|
||||
# tests basic functionality of read-ahead and ra regressions
|
||||
#
|
||||
|
||||
test_description='Test --metadatatype 1'
|
||||
privileges_required_=1
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
cleanup_()
|
||||
{
|
||||
vgremove -f "$vg"
|
||||
test -n "$d1" && losetup -d "$d1"
|
||||
test -n "$d2" && losetup -d "$d2"
|
||||
test -n "$d3" && losetup -d "$d3"
|
||||
test -n "$d4" && losetup -d "$d4"
|
||||
test -n "$d5" && losetup -d "$d5"
|
||||
rm -f "$f1" "$f2" "$f3" "$f4" "$f5"
|
||||
}
|
||||
|
||||
test_expect_success "set up temp files, loopback devices" \
|
||||
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
|
||||
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
|
||||
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
|
||||
f4=$(pwd)/4 && d4=$(loop_setup_ "$f4") &&
|
||||
f5=$(pwd)/5 && d5=$(loop_setup_ "$f5") &&
|
||||
vg=$(this_test_)-test-vg-$$ &&
|
||||
lv=$(this_test_)-test-lv-$$
|
||||
pvcreate "$d1" &&
|
||||
pvcreate --metadatacopies 0 "$d2" &&
|
||||
pvcreate --metadatacopies 0 "$d3" &&
|
||||
pvcreate "$d4" &&
|
||||
pvcreate --metadatacopies 0 "$d5" &&
|
||||
vgcreate -c n "$vg" "$d1" "$d2" "$d3" "$d4" "$d5" &&
|
||||
lvcreate -n "$lv" -l 1%FREE -i5 -I256 "$vg"'
|
||||
|
||||
test_expect_success "test medatasize 0" \
|
||||
'pvchange -x n "$d1" &&
|
||||
pvchange -x y "$d1" &&
|
||||
vgchange -a n "$vg" &&
|
||||
pvchange --uuid "$d1" &&
|
||||
pvchange --uuid "$d2" &&
|
||||
vgremove -f "$vg"'
|
||||
|
||||
|
||||
test_expect_success "test metadatatype 1" \
|
||||
'pvcreate -M1 "$d1" &&
|
||||
pvcreate -M1 "$d2" &&
|
||||
pvcreate -M1 "$d3" &&
|
||||
vgcreate -M1 "$vg" "$d1" "$d2" "$d3" &&
|
||||
pvchange --uuid "$d1"'
|
||||
|
||||
test_done
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
49
test/t-pool-labels.sh
Executable file
49
test/t-pool-labels.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2007 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='Test lvm functionality with GFS pool labels'
|
||||
privileges_required_=1
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
cleanup_()
|
||||
{
|
||||
test -n "$d1" && losetup -d "$d1"
|
||||
rm -f "$f1" "$f2"
|
||||
}
|
||||
|
||||
# create the old GFS pool labeled linear devices
|
||||
create_pool_label_()
|
||||
{
|
||||
echo -en "\x01\x16\x70\x06\x5f\xcf\xff\xb9\xf8\x24\x8apool1" | dd of=$2 bs=5 seek=1 conv=notrunc
|
||||
echo -en "\x04\x01\x03\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x0$1\x68\x01\x16\x70\x00\x00\x00\x00\x00\x06\x5f\xd0" | dd of=$2 bs=273 seek=1 conv=notrunc
|
||||
}
|
||||
|
||||
test_expect_success "set up temp files, loopback devices, pool labels" \
|
||||
'f1=$(pwd)/0 && d1=$(loop_setup_ "$f1") &&
|
||||
f2=$(pwd)/1 && d2=$(loop_setup_ "$f2") &&
|
||||
create_pool_label_ 0 "$d1" &&
|
||||
create_pool_label_ 1 "$d2"'
|
||||
|
||||
test_expect_failure "check that pvcreate fails without -ff on the pool device" \
|
||||
'pvcreate "$d1"'
|
||||
|
||||
test_expect_success "check that vgdisplay and pvcreate -ff works with the pool device" \
|
||||
'vgdisplay &&
|
||||
test -n "$d2" && losetup -d "$d2" &&
|
||||
vgdisplay &&
|
||||
pvcreate -ff -y "$d1"'
|
||||
|
||||
test_done
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
104
test/t-pvchange-usage.sh
Executable file
104
test/t-pvchange-usage.sh
Executable file
@@ -0,0 +1,104 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2008 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='Test pvchange option values'
|
||||
privileges_required_=1
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
cleanup_()
|
||||
{
|
||||
test -n "$d1" && losetup -d "$d1"
|
||||
test -n "$d2" && losetup -d "$d2"
|
||||
test -n "$d3" && losetup -d "$d3"
|
||||
test -n "$d4" && losetup -d "$d4"
|
||||
rm -f "$f1" "$f2" "$f3" "$f4"
|
||||
}
|
||||
|
||||
test_expect_success \
|
||||
'set up temp files, loopback devices, PVs, vgname' \
|
||||
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
|
||||
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
|
||||
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
|
||||
f4=$(pwd)/4 && d4=$(loop_setup_ "$f4") &&
|
||||
vg1=$(this_test_)-test-vg1-$$ &&
|
||||
lv=$(this_test_)-test-lv-$$'
|
||||
|
||||
for mda in 0 1 2
|
||||
do
|
||||
test_expect_success \
|
||||
"setup pv with metadatacopies = $mda" '
|
||||
pvcreate $d4 &&
|
||||
pvcreate --metadatacopies $mda $d1 &&
|
||||
vgcreate $vg1 $d1 $d4
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"pvchange adds/dels tag to pvs with metadatacopies = $mda " '
|
||||
pvchange $d1 --addtag test$mda &&
|
||||
check_pv_field_ $d1 pv_tags test$mda &&
|
||||
pvchange $d1 --deltag test$mda &&
|
||||
check_pv_field_ $d1 pv_tags " "
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"vgchange disable/enable allocation for pvs with metadatacopies = $mda (bz452982)" '
|
||||
pvchange $d1 -x n &&
|
||||
check_pv_field_ $d1 pv_attr -- &&
|
||||
pvchange $d1 -x y &&
|
||||
check_pv_field_ $d1 pv_attr a-
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
'remove pv' '
|
||||
vgremove $vg1 &&
|
||||
pvremove $d1 $d4
|
||||
'
|
||||
done
|
||||
|
||||
test_expect_success \
|
||||
"pvchange uuid" "
|
||||
pvcreate --metadatacopies 0 $d1 &&
|
||||
pvcreate --metadatacopies 2 $d2 &&
|
||||
vgcreate $vg1 $d1 $d2 &&
|
||||
pvchange -u $d1 &&
|
||||
pvchange -u $d2 &&
|
||||
vg_validate_pvlv_counts_ $vg1 2 0 0
|
||||
"
|
||||
test_expect_success \
|
||||
"pvchange rejects uuid change under an active lv" '
|
||||
lvcreate -l 16 -i 2 -n $lv --alloc anywhere $vg1 &&
|
||||
vg_validate_pvlv_counts_ $vg1 2 1 0 &&
|
||||
{ pvchange -u $d1;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
lvchange -an "$vg1"/"$lv" &&
|
||||
pvchange -u $d1
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"cleanup" '
|
||||
lvremove -f "$vg1"/"$lv" &&
|
||||
vgremove $vg1
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"pvchange reject --addtag to lvm1 pv" '
|
||||
pvcreate -M1 $d1 &&
|
||||
{ pvchange $d1 --addtag test;
|
||||
status=$?; echo status=$status; test $status != 0
|
||||
}
|
||||
'
|
||||
|
||||
test_done
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
49
test/t-pvcreate-metadata0.sh
Executable file
49
test/t-pvcreate-metadata0.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2007 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
|
||||
|
||||
#
|
||||
# Testcase for bugzilla #450651
|
||||
# also checks that vgremove properly removes all lv devices in the right order
|
||||
#
|
||||
test_description='Test pvcreate without metadata on all pvs'
|
||||
privileges_required_=1
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
cleanup_()
|
||||
{
|
||||
test -n "$d1" && losetup -d "$d1"
|
||||
test -n "$d2" && losetup -d "$d2"
|
||||
rm -f "$f1" "$f2"
|
||||
}
|
||||
|
||||
test_expect_success "set up temp files, loopback devices" \
|
||||
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
|
||||
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
|
||||
vg=$(this_test_)-test-vg-$$ &&
|
||||
lv=$(this_test_)-test-lv-$$ &&
|
||||
lv_snap=$(this_test_)-test-lv-snap-$$ &&
|
||||
pvcreate "$d1" &&
|
||||
pvcreate --metadatacopies 0 "$d2"'
|
||||
|
||||
test_expect_success "check lv snapshot" \
|
||||
'vgcreate -c n "$vg" "$d1" "$d2" &&
|
||||
lvcreate -n "$lv" -l 60%FREE "$vg" &&
|
||||
lvcreate -s -n "$lv_snap" -l 10%FREE "$vg"/"$lv" &&
|
||||
pvdisplay &&
|
||||
lvdisplay &&
|
||||
vgremove -f "$vg"'
|
||||
|
||||
test_done
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
142
test/t-pvcreate-operation.sh
Executable file
142
test/t-pvcreate-operation.sh
Executable file
@@ -0,0 +1,142 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2007 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='Test pvcreate logic operation'
|
||||
privileges_required_=1
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
cleanup_()
|
||||
{
|
||||
test -n "$d1" && losetup -d "$d1"
|
||||
test -n "$d2" && losetup -d "$d2"
|
||||
test -n "$d3" && losetup -d "$d3"
|
||||
test -n "$d4" && losetup -d "$d4"
|
||||
rm -f "$f1" "$f2" "$f3" "$f4"
|
||||
}
|
||||
|
||||
test_expect_success \
|
||||
'set up temp files, loopback devices, PVs, vgname' \
|
||||
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
|
||||
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
|
||||
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
|
||||
f4=$(pwd)/4 && d4=$(loop_setup_ "$f4") &&
|
||||
vg1=$(this_test_)-test-vg1-$$'
|
||||
|
||||
for mdatype in 1 2
|
||||
do
|
||||
|
||||
test_expect_success \
|
||||
"pvcreate (lvm$mdatype) succeeds when run repeatedly (pv not in a vg)" '
|
||||
pvcreate -M$mdatype $d1 &&
|
||||
pvcreate -M$mdatype $d1 &&
|
||||
pvremove -f $d1
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"pvcreate (lvm$mdatype) fails when PV belongs to VG" \
|
||||
'pvcreate -M$mdatype $d1 &&
|
||||
vgcreate -M$mdatype $vg1 $d1 &&
|
||||
pvcreate -M$mdatype $d1;
|
||||
status=$?; echo status=$status; test $status != 0 &&
|
||||
vgremove -f $vg1 &&
|
||||
pvremove -f $d1'
|
||||
|
||||
test_expect_success \
|
||||
"pvcreate (lvm$mdatype) fails when PV1 does and PV2 does not belong to VG" \
|
||||
'pvcreate -M$mdatype $d1 &&
|
||||
pvcreate -M$mdatype $d2 &&
|
||||
vgcreate -M$mdatype $vg1 $d1 &&
|
||||
echo pvcreate a second time on $d2 and $d1 &&
|
||||
pvcreate -M$mdatype $d2 $d1;
|
||||
status=$?; echo status=$status; test $status != 0 &&
|
||||
vgremove -f $vg1 &&
|
||||
pvremove -f $d2 &&
|
||||
pvremove -f $d1'
|
||||
|
||||
# NOTE: Force pvcreate after test completion to ensure clean device
|
||||
#test_expect_success \
|
||||
# "pvcreate (lvm$mdatype) fails on md component device" \
|
||||
# 'mdadm -C -l raid0 -n 2 /dev/md0 $d1 $d2 &&
|
||||
# pvcreate -M$mdatype $d1;
|
||||
# status=$?; echo status=$status; test $status != 0 &&
|
||||
# mdadm --stop /dev/md0 &&
|
||||
# pvcreate -ff -y -M$mdatype $d1 $d2 &&
|
||||
# pvremove -f $d1 $d2'
|
||||
done
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate (lvm2) fails without -ff when PV with metadatacopies=0 belongs to VG' \
|
||||
'pvcreate --metadatacopies 0 $d1 &&
|
||||
pvcreate --metadatacopies 1 $d2 &&
|
||||
vgcreate $vg1 $d1 $d2 &&
|
||||
pvcreate $d1;
|
||||
status=$?; echo status=$status; test $status != 0 &&
|
||||
vgremove -f $vg1 &&
|
||||
pvremove -f $d2 &&
|
||||
pvremove -f $d1'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate (lvm2) succeeds with -ff when PV with metadatacopies=0 belongs to VG' \
|
||||
'pvcreate --metadatacopies 0 $d1 &&
|
||||
pvcreate --metadatacopies 1 $d2 &&
|
||||
vgcreate $vg1 $d1 $d2 &&
|
||||
pvcreate -ff -y $d1 &&
|
||||
vgreduce --removemissing $vg1 &&
|
||||
vgremove -ff $vg1 &&
|
||||
pvremove -f $d2 &&
|
||||
pvremove -f $d1'
|
||||
|
||||
for i in 0 1 2 3
|
||||
do
|
||||
test_expect_success \
|
||||
"pvcreate (lvm2) succeeds writing LVM label at sector $i" \
|
||||
'pvcreate --labelsector $i $d1 &&
|
||||
dd if=$d1 bs=512 skip=$i count=1 status=noxfer 2>&1 | strings | grep -q LABELONE;
|
||||
test $? == 0 &&
|
||||
pvremove -f $d1'
|
||||
done
|
||||
|
||||
test_expect_failure \
|
||||
"pvcreate (lvm2) fails writing LVM label at sector 4" \
|
||||
'pvcreate --labelsector 4 $d1'
|
||||
|
||||
backupfile=mybackupfile-$(this_test_)
|
||||
uuid1=freddy-fred-fred-fred-fred-fred-freddy
|
||||
uuid2=freddy-fred-fred-fred-fred-fred-fredie
|
||||
bogusuuid=fred
|
||||
|
||||
test_expect_failure \
|
||||
'pvcreate rejects uuid option with less than 32 characters' \
|
||||
'pvcreate --uuid $bogusuuid $d1'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate rejects uuid already in use' \
|
||||
'pvcreate --uuid $uuid1 $d1 &&
|
||||
pvcreate --uuid $uuid1 $d2;
|
||||
status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate rejects non-existent file given with restorefile' \
|
||||
'pvcreate --uuid $uuid1 --restorefile $backupfile $d1;
|
||||
status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate rejects restorefile with uuid not found in file' \
|
||||
'pvcreate --uuid $uuid1 $d1 &&
|
||||
vgcfgbackup -f $backupfile &&
|
||||
pvcreate --uuid $uuid2 --restorefile $backupfile $d2;
|
||||
status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
test_done
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
110
test/t-pvcreate-usage.sh
Executable file
110
test/t-pvcreate-usage.sh
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2007 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='Test pvcreate option values'
|
||||
privileges_required_=1
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
cleanup_()
|
||||
{
|
||||
test -n "$d1" && losetup -d "$d1"
|
||||
test -n "$d2" && losetup -d "$d2"
|
||||
test -n "$d3" && losetup -d "$d3"
|
||||
test -n "$d4" && losetup -d "$d4"
|
||||
rm -f "$f1" "$f2" "$f3" "$f4"
|
||||
}
|
||||
|
||||
test_expect_success \
|
||||
'set up temp files, loopback devices, PVs, vgname' \
|
||||
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
|
||||
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
|
||||
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
|
||||
f4=$(pwd)/4 && d4=$(loop_setup_ "$f4") &&
|
||||
vg1=$(this_test_)-test-vg1-$$'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate rejects negative setphysicalvolumesize' \
|
||||
'pvcreate --setphysicalvolumesize -1024 $d1;
|
||||
status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate rejects negative metadatasize' \
|
||||
'pvcreate --metadatasize -1024 $d1;
|
||||
status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
# x. metadatasize 0, defaults to 255
|
||||
# FIXME: unable to check default value, not in reporting cmds
|
||||
# should default to 255 according to code
|
||||
# check_pv_field_ pv_mda_size 255 &&
|
||||
test_expect_success \
|
||||
'pvcreate accepts metadatasize 0' \
|
||||
'pvcreate --metadatasize 0 $d1 &&
|
||||
pvremove $d1'
|
||||
|
||||
# x. metadatasize too large
|
||||
# For some reason we allow this, even though there's no room for data?
|
||||
#test_expect_success \
|
||||
# 'pvcreate rejects metadatasize too large' \
|
||||
# 'pvcreate --metadatasize 100000000000000 $d1;
|
||||
# status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate rejects metadatacopies < 0' \
|
||||
'pvcreate --metadatacopies -1 $d1;
|
||||
status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate accepts metadatacopies = 0, 1, 2' \
|
||||
'pvcreate --metadatacopies 0 $d1 &&
|
||||
pvcreate --metadatacopies 1 $d2 &&
|
||||
pvcreate --metadatacopies 2 $d3 &&
|
||||
check_pv_field_ $d1 pv_mda_count 0 &&
|
||||
check_pv_field_ $d2 pv_mda_count 1 &&
|
||||
check_pv_field_ $d3 pv_mda_count 2 &&
|
||||
pvremove $d1 &&
|
||||
pvremove $d2 &&
|
||||
pvremove $d3'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate rejects metadatacopies > 2' \
|
||||
'pvcreate --metadatacopies 3 $d1;
|
||||
status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate rejects invalid device' \
|
||||
'pvcreate $d1bogus;
|
||||
status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate rejects labelsector < 0' \
|
||||
'pvcreate --labelsector -1 $d1;
|
||||
status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
test_expect_success \
|
||||
'pvcreate rejects labelsector > 1000000000000' \
|
||||
'pvcreate --labelsector 1000000000000 $d1;
|
||||
status=$?; echo status=$status; test $status != 0'
|
||||
|
||||
# other possibilites based on code inspection (not sure how hard)
|
||||
# x. device too small (min of 512 * 1024 KB)
|
||||
# x. device filtered out
|
||||
# x. unable to open /dev/urandom RDONLY
|
||||
# x. device too large (pe_count > UINT32_MAX)
|
||||
# x. device read-only
|
||||
# x. unable to open device readonly
|
||||
# x. BLKGETSIZE64 fails
|
||||
# x. set size to value inconsistent with device / PE size
|
||||
|
||||
test_done
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
111
test/t-pvremove-usage.sh
Executable file
111
test/t-pvremove-usage.sh
Executable file
@@ -0,0 +1,111 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2008 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='Test pvremove'
|
||||
privileges_required_=1
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
cleanup_()
|
||||
{
|
||||
test -n "$d1" && losetup -d "$d1"
|
||||
test -n "$d2" && losetup -d "$d2"
|
||||
test -n "$d3" && losetup -d "$d3"
|
||||
rm -f "$f1" "$f2"
|
||||
}
|
||||
|
||||
test_expect_success "set up temp files, loopback devices" \
|
||||
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
|
||||
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
|
||||
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
|
||||
vg=$(this_test_)-test-vg-$$ &&
|
||||
pvcreate "$d1" &&
|
||||
pvcreate --metadatacopies 0 "$d2" &&
|
||||
pvcreate --metadatacopies 2 "$d3"
|
||||
'
|
||||
|
||||
test_expect_success "check pvremove fails when bogus pv given" '
|
||||
pvremove "$d2" bogus;
|
||||
status=$?; echo $status; test $status != 0
|
||||
'
|
||||
|
||||
#failing, but still removing everything what can be removed
|
||||
#is somewhat odd as default, what do we have -f for?
|
||||
test_expect_failure "but still removes the valid pv that was given too :-/" '
|
||||
pvs | grep "$d2"; status=$?;
|
||||
pvcreate --metadatacopies 0 "$d2";
|
||||
echo $status; test $status = 0
|
||||
'
|
||||
|
||||
test_expect_success "check pvremove refuses to remove pv in a vg" '
|
||||
vgcreate -c n "$vg" "$d1" "$d2" &&
|
||||
{ pvremove "$d2" "$d3";
|
||||
status=$?; echo $status; test $status != 0
|
||||
}
|
||||
'
|
||||
|
||||
for mdacp in 0 1 2; do
|
||||
test_expect_success \
|
||||
"check pvremove truly wipes the label (pvscan wont find) (---metadatacopies $mdacp)" '
|
||||
pvcreate --metadatacopies $mdacp "$d3" &&
|
||||
pvremove "$d3" &&
|
||||
{ pvscan |grep "$d3";
|
||||
status=$?; echo $status; test $status != 0
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success "reset setup" '
|
||||
vgremove -ff $vg &&
|
||||
pvcreate --metadatacopies $mdacp "$d1" &&
|
||||
pvcreate "$d2" &&
|
||||
vgcreate $vg $d1 $d2
|
||||
'
|
||||
test_expect_success "pvremove -f fails when pv in a vg (---metadatacopies $mdacp)" '
|
||||
pvremove -f $d1;
|
||||
status=$?; echo $status; test $status != 0 &&
|
||||
pvs $d1
|
||||
'
|
||||
test_expect_success \
|
||||
"pvremove -ff fails without confirmation when pv in a vg (---metadatacopies $mdacp)" '
|
||||
echo n|eval pvremove -ff $d1;
|
||||
status=$?; echo $status; test $status != 0
|
||||
'
|
||||
test_expect_success \
|
||||
"pvremove -ff succeds with confirmation when pv in a vg (---metadatacopies $mdacp)" '
|
||||
yes | pvremove -ff $d1 &&
|
||||
pvs $d1;
|
||||
status=$?; echo $status; test $status != 0
|
||||
'
|
||||
test_expect_success "cleanup & setup" '
|
||||
vgreduce --removemissing $vg &&
|
||||
pvcreate --metadatacopies $mdacp "$d1" &&
|
||||
vgextend $vg $d1
|
||||
'
|
||||
test_expect_success \
|
||||
"pvremove -ff -y is sufficient when pv in a vg (---metadatacopies $mdacp)" '
|
||||
echo n | pvremove -ff -y $d1
|
||||
'
|
||||
test_expect_success "cleanup & setup" '
|
||||
vgreduce --removemissing $vg &&
|
||||
pvcreate --metadatacopies $mdacp "$d1" &&
|
||||
vgextend $vg $d1
|
||||
'
|
||||
done
|
||||
|
||||
test_expect_success "cleanup" '
|
||||
vgremove -ff "$vg"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
@@ -54,7 +54,7 @@ test_expect_success "test various read ahead settings" \
|
||||
vgcreate -c n "$vg" "$d1" "$d2" "$d3" "$d4" "$d5" &&
|
||||
lvcreate -n "$lv" -l 100%FREE -i5 -I256 "$vg" &&
|
||||
lvdisplay "$vg"/"$lv" &&
|
||||
lvchange -r auto "$vg"/"$lv" || true | grep auto &&
|
||||
lvchange -r auto "$vg"/"$lv" 2>&1 | grep auto &&
|
||||
get_lvs_ lv auto &&
|
||||
get_lvs_ lv_kernel 5120 &&
|
||||
lvchange -r 400 "$vg/$lv" &&
|
||||
|
||||
@@ -18,15 +18,19 @@ cleanup_()
|
||||
{
|
||||
test -n "$d1" && losetup -d "$d1"
|
||||
test -n "$d2" && losetup -d "$d2"
|
||||
rm -f "$f1" "$f2"
|
||||
test -n "$d3" && losetup -d "$d3"
|
||||
rm -f "$f1" "$f2" "$f3"
|
||||
}
|
||||
|
||||
test_expect_success \
|
||||
'set up temp files, loopback devices, PVs, vgname' \
|
||||
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
|
||||
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
|
||||
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
|
||||
vg=$(this_test_)-test-vg-$$ &&
|
||||
pvcreate $d1 $d2'
|
||||
pvcreate $d1 $d2 &&
|
||||
pvcreate --metadatacopies 0 $d3
|
||||
'
|
||||
|
||||
lv=vgcreate-usage-$$
|
||||
|
||||
@@ -79,13 +83,31 @@ test_expect_success \
|
||||
status=$?; echo status=$status; test $status = 3 &&
|
||||
grep "New volume group name \"$vg\" is invalid\$" err'
|
||||
|
||||
# FIXME: Not sure why this fails
|
||||
#test_expect_success \
|
||||
# 'vgcreate rejects MaxLogicalVolumes > 255' \
|
||||
# 'vgcreate --metadatatype 1 --maxlogicalvolumes 1024 $vg $d1 $d2 2>err;
|
||||
# cp err save;
|
||||
# status=$?; echo status=$status; test $status = 3 &&
|
||||
# grep "^ Number of volumes may not exceed 255\$" err'
|
||||
test_expect_success \
|
||||
'cleanup vg name' '
|
||||
vg=$(this_test_)-test-vg-$$
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"vgcreate rejects repeated invocation (run 2 times)" '
|
||||
vgcreate $vg $d1 $d2 && {
|
||||
vgcreate $vg $d1 $d2;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
vgremove -ff $vg
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
'vgcreate rejects MaxLogicalVolumes > 255' \
|
||||
'vgcreate --metadatatype 1 --maxlogicalvolumes 1024 $vg $d1 $d2 2>err;
|
||||
status=$?; echo status=$status; test $status = 3 &&
|
||||
grep "^ Number of volumes may not exceed 255\$" err'
|
||||
|
||||
test_expect_success \
|
||||
"vgcreate fails when the only pv has --metadatacopies 0" '
|
||||
vgcreate $vg $d3;
|
||||
status=$?; echo status=$status; test $status = 5
|
||||
'
|
||||
|
||||
test_done
|
||||
# Local Variables:
|
||||
|
||||
101
test/t-vgreduce-usage.sh
Executable file
101
test/t-vgreduce-usage.sh
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2008 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='Test vgreduce command options for validity'
|
||||
privileges_required_=1
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
cleanup_()
|
||||
{
|
||||
test -n "$d1" && losetup -d "$d1"
|
||||
test -n "$d2" && losetup -d "$d2"
|
||||
test -n "$d3" && losetup -d "$d3"
|
||||
test -n "$d4" && losetup -d "$d4"
|
||||
rm -f "$f1" "$f2" "$f3" "$f4"
|
||||
}
|
||||
|
||||
test_expect_success \
|
||||
'set up temp files, loopback devices, PVs, vgnames' \
|
||||
'f1=$(pwd)/1 && d1=$(loop_setup_ "$f1") &&
|
||||
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
|
||||
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
|
||||
f4=$(pwd)/4 && d4=$(loop_setup_ "$f4") &&
|
||||
vg1=$(this_test_)-test-vg1-$$ &&
|
||||
vg2=$(this_test_)-test-vg2-$$ &&
|
||||
lv1=$(this_test_)-test-lv1-$$ &&
|
||||
lv2=$(this_test_)-test-lv2-$$ &&
|
||||
lv3=$(this_test_)-test-lv3-$$'
|
||||
|
||||
#TODO --removemissing (+ -- mirrorsonly)
|
||||
|
||||
for mdatype in 1 2
|
||||
do
|
||||
test_expect_success \
|
||||
"(lvm$mdatype) setup PVs" '
|
||||
pvcreate -M$mdatype $d1 $d2
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"(lvm$mdatype) vgreduce removes only the specified pv from vg (bz427382)" '
|
||||
vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
vgreduce $vg1 $d1 &&
|
||||
check_pv_field_ $d2 vg_name $vg1 &&
|
||||
vgremove -f $vg1
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"(lvm$mdatype) vgreduce rejects removing the last pv (--all)" '
|
||||
vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
{ vgreduce --all $vg1;
|
||||
status=$?; echo status=$status; test $status != 0 &&
|
||||
vgremove -f $vg1
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"(lvm$mdatype) vgreduce rejects removing the last pv" '
|
||||
vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
{ vgreduce $vg1 $d1 $d2;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
vgremove -f $vg1
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"(lvm$mdatype) remove PVs " '
|
||||
pvremove -ff $d1 $d2
|
||||
'
|
||||
done
|
||||
|
||||
for mdatype in 2
|
||||
do
|
||||
test_expect_success \
|
||||
"(lvm$mdatype) setup PVs (--metadatacopies 0)" '
|
||||
pvcreate -M$mdatype $d1 $d2 &&
|
||||
pvcreate --metadatacopies 0 -M$mdatype $d3 $d4
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
"(lvm$mdatype) vgreduce rejects removing pv with the last mda copy" '
|
||||
vgcreate -M$mdatype $vg1 $d1 $d3 &&
|
||||
{ vgreduce $vg1 $d1;
|
||||
status=$?; echo status=$status; test $status != 0 &&
|
||||
vgremove -f $vg1
|
||||
}
|
||||
'
|
||||
done
|
||||
|
||||
|
||||
test_done
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
@@ -31,7 +31,8 @@ test_expect_success \
|
||||
f4=$(pwd)/4 && d4=$(loop_setup_ "$f4") &&
|
||||
vg1=$(this_test_)-1-$$ &&
|
||||
vg2=$(this_test_)-2-$$ &&
|
||||
pvcreate $d1 $d2 $d3 $d4'
|
||||
pvcreate $d1 $d2 &&
|
||||
pvcreate --metadatacopies 0 $d3 $d4'
|
||||
|
||||
test_expect_success \
|
||||
'vgrename normal operation - rename vg1 to vg2' \
|
||||
@@ -40,6 +41,16 @@ test_expect_success \
|
||||
check_vg_field_ $vg2 vg_name $vg2 &&
|
||||
vgremove $vg2'
|
||||
|
||||
test_expect_success \
|
||||
"vgrename by uuid (bz231187)" '
|
||||
vgcreate $vg1 $d1 $d3 &&
|
||||
UUID=$(vgs --noheading -o vg_uuid $vg1) &&
|
||||
check_vg_field_ $vg1 vg_uuid $UUID &&
|
||||
vgrename $UUID $vg2 &&
|
||||
check_vg_field_ $vg2 vg_name $vg2 &&
|
||||
vgremove $vg2
|
||||
'
|
||||
|
||||
test_done
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
|
||||
@@ -20,7 +20,8 @@ cleanup_()
|
||||
test -n "$d2" && losetup -d "$d2"
|
||||
test -n "$d3" && losetup -d "$d3"
|
||||
test -n "$d4" && losetup -d "$d4"
|
||||
rm -f "$f1" "$f2" "$f3" "$f4"
|
||||
test -n "$d5" && losetup -d "$d5"
|
||||
rm -f "$f1" "$f2" "$f3" "$f4" "$f5"
|
||||
}
|
||||
|
||||
# FIXME: paramaterize lvm1 vs lvm2 metadata; most of these tests should run
|
||||
@@ -32,16 +33,22 @@ test_expect_success \
|
||||
f2=$(pwd)/2 && d2=$(loop_setup_ "$f2") &&
|
||||
f3=$(pwd)/3 && d3=$(loop_setup_ "$f3") &&
|
||||
f4=$(pwd)/4 && d4=$(loop_setup_ "$f4") &&
|
||||
f5=$(pwd)/5 && d5=$(loop_setup_ "$f5") &&
|
||||
vg1=$(this_test_)-test-vg1-$$ &&
|
||||
vg2=$(this_test_)-test-vg2-$$ &&
|
||||
lv1=$(this_test_)-test-lv1-$$ &&
|
||||
lv2=$(this_test_)-test-lv2-$$ &&
|
||||
lv3=$(this_test_)-test-lv3-$$ &&
|
||||
pvcreate $d1 $d2 $d3 $d4'
|
||||
lv3=$(this_test_)-test-lv3-$$'
|
||||
|
||||
for mdatype in 1 2
|
||||
do
|
||||
test_expect_success \
|
||||
"(lvm$mdatype) setup PVs" \
|
||||
'pvcreate -M$mdatype $d1 $d2 $d3 $d4'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit accepts new vg as destination of split' \
|
||||
'vgcreate $vg1 $d1 $d2 &&
|
||||
"(lvm$mdatype) vgsplit accepts new vg as destination of split" \
|
||||
'vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
vgsplit $vg1 $vg2 $d1 1>err;
|
||||
status=$?; echo status=$status; test $status = 0 &&
|
||||
grep "New volume group \"$vg2\" successfully split from \"$vg1\"" err &&
|
||||
@@ -49,9 +56,9 @@ test_expect_success \
|
||||
vgremove $vg2'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit accepts existing vg as destination of split' \
|
||||
'vgcreate $vg1 $d1 $d2 &&
|
||||
vgcreate $vg2 $d3 $d4 &&
|
||||
"(lvm$mdatype) vgsplit accepts existing vg as destination of split" \
|
||||
'vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
vgcreate -M$mdatype $vg2 $d3 $d4 &&
|
||||
vgsplit $vg1 $vg2 $d1 1>err;
|
||||
status=$?; echo status=$status; test $status = 0 &&
|
||||
grep "Existing volume group \"$vg2\" successfully split from \"$vg1\"" err &&
|
||||
@@ -59,25 +66,25 @@ test_expect_success \
|
||||
vgremove $vg2'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit accepts --maxphysicalvolumes 128 on new VG' \
|
||||
'vgcreate $vg1 $d1 $d2 &&
|
||||
"(lvm$mdatype) vgsplit accepts --maxphysicalvolumes 128 on new VG" \
|
||||
'vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
vgsplit --maxphysicalvolumes 128 $vg1 $vg2 $d1 &&
|
||||
check_vg_field_ $vg2 max_pv 128 &&
|
||||
vgremove $vg1 &&
|
||||
vgremove $vg2'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit accepts --maxlogicalvolumes 128 on new VG' \
|
||||
'vgcreate $vg1 $d1 $d2 &&
|
||||
"(lvm$mdatype) vgsplit accepts --maxlogicalvolumes 128 on new VG" \
|
||||
'vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
vgsplit --maxlogicalvolumes 128 $vg1 $vg2 $d1 &&
|
||||
check_vg_field_ $vg2 max_lv 128 &&
|
||||
vgremove $vg1 &&
|
||||
vgremove $vg2'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit rejects split because max_pv of destination would be exceeded' \
|
||||
'vgcreate --maxphysicalvolumes 2 $vg1 $d1 $d2 &&
|
||||
vgcreate --maxphysicalvolumes 2 $vg2 $d3 $d4 &&
|
||||
"(lvm$mdatype) vgsplit rejects split because max_pv of destination would be exceeded" \
|
||||
'vgcreate -M$mdatype --maxphysicalvolumes 2 $vg1 $d1 $d2 &&
|
||||
vgcreate -M$mdatype --maxphysicalvolumes 2 $vg2 $d3 $d4 &&
|
||||
vgsplit $vg1 $vg2 $d1 2>err;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
grep "^ Maximum number of physical volumes (2) exceeded" err &&
|
||||
@@ -85,9 +92,9 @@ test_expect_success \
|
||||
vgremove $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit rejects split because maxphysicalvolumes given with existing vg' \
|
||||
'vgcreate --maxphysicalvolumes 2 $vg1 $d1 $d2 &&
|
||||
vgcreate --maxphysicalvolumes 2 $vg2 $d3 $d4 &&
|
||||
"(lvm$mdatype) vgsplit rejects split because maxphysicalvolumes given with existing vg" \
|
||||
'vgcreate -M$mdatype --maxphysicalvolumes 2 $vg1 $d1 $d2 &&
|
||||
vgcreate -M$mdatype --maxphysicalvolumes 2 $vg2 $d3 $d4 &&
|
||||
vgsplit --maxphysicalvolumes 2 $vg1 $vg2 $d1 2>err;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
grep "^ Volume group \"$vg2\" exists, but new VG option specified" err &&
|
||||
@@ -95,9 +102,9 @@ test_expect_success \
|
||||
vgremove $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit rejects split because maxlogicalvolumes given with existing vg' \
|
||||
'vgcreate --maxlogicalvolumes 2 $vg1 $d1 $d2 &&
|
||||
vgcreate --maxlogicalvolumes 2 $vg2 $d3 $d4 &&
|
||||
"(lvm$mdatype) vgsplit rejects split because maxlogicalvolumes given with existing vg" \
|
||||
'vgcreate -M$mdatype --maxlogicalvolumes 2 $vg1 $d1 $d2 &&
|
||||
vgcreate -M$mdatype --maxlogicalvolumes 2 $vg2 $d3 $d4 &&
|
||||
vgsplit --maxlogicalvolumes 2 $vg1 $vg2 $d1 2>err;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
grep "^ Volume group \"$vg2\" exists, but new VG option specified" err &&
|
||||
@@ -105,9 +112,9 @@ test_expect_success \
|
||||
vgremove $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit rejects split because alloc given with existing vg' \
|
||||
'vgcreate --alloc cling $vg1 $d1 $d2 &&
|
||||
vgcreate --alloc cling $vg2 $d3 $d4 &&
|
||||
"(lvm$mdatype) vgsplit rejects split because alloc given with existing vg" \
|
||||
'vgcreate -M$mdatype --alloc cling $vg1 $d1 $d2 &&
|
||||
vgcreate -M$mdatype --alloc cling $vg2 $d3 $d4 &&
|
||||
vgsplit --alloc cling $vg1 $vg2 $d1 2>err;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
grep "^ Volume group \"$vg2\" exists, but new VG option specified" err &&
|
||||
@@ -115,9 +122,9 @@ test_expect_success \
|
||||
vgremove $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit rejects split because clustered given with existing vg' \
|
||||
'vgcreate --clustered n $vg1 $d1 $d2 &&
|
||||
vgcreate --clustered n $vg2 $d3 $d4 &&
|
||||
"(lvm$mdatype) vgsplit rejects split because clustered given with existing vg" \
|
||||
'vgcreate -M$mdatype --clustered n $vg1 $d1 $d2 &&
|
||||
vgcreate -M$mdatype --clustered n $vg2 $d3 $d4 &&
|
||||
vgsplit --clustered n $vg1 $vg2 $d1 2>err;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
grep "^ Volume group \"$vg2\" exists, but new VG option specified" err &&
|
||||
@@ -125,22 +132,10 @@ test_expect_success \
|
||||
vgremove $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit rejects split because metadata types differ' \
|
||||
'pvcreate -ff -M1 $d3 $d4 &&
|
||||
pvcreate -ff -M2 $d1 $d2 &&
|
||||
vgcreate -M1 $vg1 $d3 $d4 &&
|
||||
vgcreate -M2 $vg2 $d1 $d2 &&
|
||||
vgsplit $vg1 $vg2 $d3 2>err;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
grep "^ Metadata types differ" err &&
|
||||
vgremove $vg2 &&
|
||||
vgremove $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit rejects vg with active lv' \
|
||||
'pvcreate -ff -M2 $d3 $d4 &&
|
||||
vgcreate $vg1 $d1 $d2 &&
|
||||
vgcreate $vg2 $d3 $d4 &&
|
||||
"(lvm$mdatype) vgsplit rejects vg with active lv" \
|
||||
'pvcreate -ff -M$mdatype $d3 $d4 &&
|
||||
vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
vgcreate -M$mdatype $vg2 $d3 $d4 &&
|
||||
lvcreate -l 4 -n $lv1 $vg1 &&
|
||||
vgsplit $vg1 $vg2 $d1 2>err;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
@@ -149,9 +144,9 @@ test_expect_success \
|
||||
vgremove -f $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit rejects split because max_lv is exceeded' \
|
||||
'vgcreate --maxlogicalvolumes 2 $vg1 $d1 $d2 &&
|
||||
vgcreate --maxlogicalvolumes 2 $vg2 $d3 $d4 &&
|
||||
"(lvm$mdatype) vgsplit rejects split because max_lv is exceeded" \
|
||||
'vgcreate -M$mdatype --maxlogicalvolumes 2 $vg1 $d1 $d2 &&
|
||||
vgcreate -M$mdatype --maxlogicalvolumes 2 $vg2 $d3 $d4 &&
|
||||
lvcreate -l 4 -n $lv1 $vg1 &&
|
||||
lvcreate -l 4 -n $lv2 $vg1 &&
|
||||
lvcreate -l 4 -n $lv3 $vg2 &&
|
||||
@@ -164,8 +159,8 @@ test_expect_success \
|
||||
vgremove -f $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'verify default - max_lv attribute from new VG is same as source VG' \
|
||||
'vgcreate $vg1 $d1 $d2 &&
|
||||
"(lvm$mdatype) vgsplit verify default - max_lv attribute from new VG is same as source VG" \
|
||||
'vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
lvcreate -l 4 -n $lv1 $vg1 &&
|
||||
vgchange -an $vg1 &&
|
||||
vgsplit $vg1 $vg2 $d1 &&
|
||||
@@ -174,8 +169,8 @@ test_expect_success \
|
||||
vgremove -f $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'verify default - max_pv attribute from new VG is same as source VG' \
|
||||
'vgcreate $vg1 $d1 $d2 &&
|
||||
"(lvm$mdatype) vgsplit verify default - max_pv attribute from new VG is same as source VG" \
|
||||
'vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
lvcreate -l 4 -n $lv1 $vg1 &&
|
||||
vgchange -an $vg1 &&
|
||||
vgsplit $vg1 $vg2 $d1 &&
|
||||
@@ -184,8 +179,8 @@ test_expect_success \
|
||||
vgremove -f $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'verify default - vg_fmt attribute from new VG is same as source VG' \
|
||||
'vgcreate $vg1 $d1 $d2 &&
|
||||
"(lvm$mdatype) vgsplit verify default - vg_fmt attribute from new VG is same as source VG" \
|
||||
'vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
lvcreate -l 4 -n $lv1 $vg1 &&
|
||||
vgchange -an $vg1 &&
|
||||
vgsplit $vg1 $vg2 $d1 &&
|
||||
@@ -194,9 +189,9 @@ test_expect_success \
|
||||
vgremove -f $vg1'
|
||||
|
||||
test_expect_success \
|
||||
'vgsplit rejects split because PV not in VG' \
|
||||
'vgcreate $vg1 $d1 $d2 &&
|
||||
vgcreate $vg2 $d3 $d4 &&
|
||||
"(lvm$mdatype) vgsplit rejects split because PV not in VG" \
|
||||
'vgcreate -M$mdatype $vg1 $d1 $d2 &&
|
||||
vgcreate -M$mdatype $vg2 $d3 $d4 &&
|
||||
lvcreate -l 4 -n $lv1 $vg1 &&
|
||||
lvcreate -l 4 -n $lv2 $vg1 &&
|
||||
vgchange -an $vg1 &&
|
||||
@@ -204,6 +199,36 @@ test_expect_success \
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
vgremove -f $vg2 &&
|
||||
vgremove -f $vg1'
|
||||
done
|
||||
|
||||
test_expect_success \
|
||||
"(lvm2) setup PVs" '
|
||||
pvcreate -M$mdatype --metadatacopies 0 $d5'
|
||||
|
||||
test_expect_success \
|
||||
"(lvm2) vgsplit rejects to give away pv with the last mda copy" '
|
||||
vgcreate -M2 $vg1 $d5 $d2 &&
|
||||
lvcreate -l 10 -n $lv1 $vg1 &&
|
||||
lvchange -an $vg1/$lv1 &&
|
||||
vg_validate_pvlv_counts_ $vg1 2 1 0 &&
|
||||
{ vgsplit $vg1 $vg2 $d5;
|
||||
status=$?; echo status=$status; test $status != 0 &&
|
||||
vg_validate_pvlv_counts_ $vg1 2 1 0 &&
|
||||
vgremove -ff $vg1
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
'(lvm2) vgsplit rejects split because metadata types differ' \
|
||||
'pvcreate -ff -M1 $d3 $d4 &&
|
||||
pvcreate -ff -M2 $d1 $d2 &&
|
||||
vgcreate -M1 $vg1 $d3 $d4 &&
|
||||
vgcreate -M2 $vg2 $d1 $d2 &&
|
||||
vgsplit $vg1 $vg2 $d3 2>err;
|
||||
status=$?; echo status=$status; test $status = 5 &&
|
||||
grep "^ Metadata types differ" err &&
|
||||
vgremove $vg2 &&
|
||||
vgremove $vg1'
|
||||
|
||||
test_done
|
||||
# Local Variables:
|
||||
|
||||
@@ -42,19 +42,28 @@ this_test_() { expr "./$0" : '.*/t-\([^/]*\)\.sh$'; }
|
||||
test "${test_description}" != "" ||
|
||||
error "Test script did not set test_description."
|
||||
|
||||
verboselevel=0
|
||||
while test "$#" -ne 0
|
||||
do
|
||||
case "$1" in
|
||||
-d|--d|--de|--deb|--debu|--debug)
|
||||
debug=t; shift ;;
|
||||
debug=t ;;
|
||||
-i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
|
||||
immediate=t; shift ;;
|
||||
immediate=t ;;
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "$test_description"
|
||||
exit 0 ;;
|
||||
-v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
|
||||
verbose=t; shift ;;
|
||||
verbose=t ;;
|
||||
-vv|-vvv|-vvvv)
|
||||
verboselevel=${#1}
|
||||
verboselevel=$(($verboselevel - 1))
|
||||
verbose=t ;;
|
||||
*)
|
||||
echo "$0: unsupported option $1"
|
||||
exit 0 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
exec 5>&1
|
||||
|
||||
@@ -545,7 +545,7 @@ static int lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
void *handle __attribute((unused)))
|
||||
{
|
||||
int doit = 0;
|
||||
int doit = 0, docmds = 0;
|
||||
int archived = 0;
|
||||
|
||||
if (!(lv->vg->status & LVM_WRITE) &&
|
||||
@@ -606,6 +606,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return ECMD_FAILED;
|
||||
archived = 1;
|
||||
doit += lvchange_permission(cmd, lv);
|
||||
docmds++;
|
||||
}
|
||||
|
||||
/* allocation policy change */
|
||||
@@ -614,6 +615,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return ECMD_FAILED;
|
||||
archived = 1;
|
||||
doit += lvchange_alloc(cmd, lv);
|
||||
docmds++;
|
||||
}
|
||||
|
||||
/* read ahead sector change */
|
||||
@@ -622,6 +624,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return ECMD_FAILED;
|
||||
archived = 1;
|
||||
doit += lvchange_readahead(cmd, lv);
|
||||
docmds++;
|
||||
}
|
||||
|
||||
/* read ahead sector change */
|
||||
@@ -630,6 +633,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return ECMD_FAILED;
|
||||
archived = 1;
|
||||
doit += lvchange_persistent(cmd, lv);
|
||||
docmds++;
|
||||
if (sigint_caught())
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
@@ -640,6 +644,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return ECMD_FAILED;
|
||||
archived = 1;
|
||||
doit += lvchange_tag(cmd, lv, addtag_ARG);
|
||||
docmds++;
|
||||
}
|
||||
|
||||
/* del tag */
|
||||
@@ -648,6 +653,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return ECMD_FAILED;
|
||||
archived = 1;
|
||||
doit += lvchange_tag(cmd, lv, deltag_ARG);
|
||||
docmds++;
|
||||
}
|
||||
|
||||
if (doit)
|
||||
@@ -674,6 +680,9 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (doit != docmds)
|
||||
return ECMD_FAILED;
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
|
||||
@@ -508,6 +508,9 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
|
||||
}
|
||||
|
||||
if (lp->mirrors == existing_mirrors) {
|
||||
/*
|
||||
* Convert Mirror log type
|
||||
*/
|
||||
original_lv = _original_lv(lv);
|
||||
if (!first_seg(original_lv)->log_lv && !corelog) {
|
||||
if (!add_mirror_log(cmd, original_lv, 1,
|
||||
@@ -629,10 +632,12 @@ static int lvconvert_snapshot(struct cmd_context *cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (org->status & (LOCKED|PVMOVE) || lv_is_cow(org)) {
|
||||
if (org->status & (LOCKED|PVMOVE|MIRRORED) || lv_is_cow(org)) {
|
||||
log_error("Unable to create a snapshot of a %s LV.",
|
||||
org->status & LOCKED ? "locked" :
|
||||
org->status & PVMOVE ? "pvmove" : "snapshot");
|
||||
org->status & PVMOVE ? "pvmove" :
|
||||
org->status & MIRRORED ? "mirrored" :
|
||||
"snapshot");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -707,16 +712,20 @@ static int lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (arg_count(cmd, mirrors_ARG) || (lv->status & MIRRORED)) {
|
||||
if (!archive(lv->vg))
|
||||
if (lp->snapshot) {
|
||||
if (lv->status & MIRRORED) {
|
||||
log_error("Unable to convert mirrored LV \"%s\" into a snapshot.", lv->name);
|
||||
return ECMD_FAILED;
|
||||
if (!lvconvert_mirrors(cmd, lv, lp))
|
||||
return ECMD_FAILED;
|
||||
} else if (lp->snapshot) {
|
||||
}
|
||||
if (!archive(lv->vg))
|
||||
return ECMD_FAILED;
|
||||
if (!lvconvert_snapshot(cmd, lv, lp))
|
||||
return ECMD_FAILED;
|
||||
} else if (arg_count(cmd, mirrors_ARG) || (lv->status & MIRRORED)) {
|
||||
if (!archive(lv->vg))
|
||||
return ECMD_FAILED;
|
||||
if (!lvconvert_mirrors(cmd, lv, lp))
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
|
||||
@@ -523,8 +523,6 @@ static int _lvcreate(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct lvinfo info;
|
||||
uint32_t pv_extent_count;
|
||||
|
||||
status |= lp->permission | VISIBLE_LV;
|
||||
|
||||
if (lp->lv_name && find_lv_in_vg(vg, lp->lv_name)) {
|
||||
log_error("Logical volume \"%s\" already exists in "
|
||||
"volume group \"%s\"", lp->lv_name, lp->vg_name);
|
||||
@@ -544,16 +542,6 @@ static int _lvcreate(struct cmd_context *cmd, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the pv list.
|
||||
*/
|
||||
if (lp->pv_count) {
|
||||
if (!(pvh = create_pv_list(cmd->mem, vg,
|
||||
lp->pv_count, lp->pvs, 1)))
|
||||
return_0;
|
||||
} else
|
||||
pvh = &vg->pvs;
|
||||
|
||||
if (lp->stripe_size > vg->extent_size) {
|
||||
log_error("Reducing requested stripe size %s to maximum, "
|
||||
"physical extent size %s",
|
||||
@@ -594,6 +582,16 @@ static int _lvcreate(struct cmd_context *cmd, struct volume_group *vg,
|
||||
lp->extents = (uint64_t) tmp_size / vg->extent_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the pv list.
|
||||
*/
|
||||
if (lp->pv_count) {
|
||||
if (!(pvh = create_pv_list(cmd->mem, vg,
|
||||
lp->pv_count, lp->pvs, 1)))
|
||||
return_0;
|
||||
} else
|
||||
pvh = &vg->pvs;
|
||||
|
||||
switch(lp->percent) {
|
||||
case PERCENT_VG:
|
||||
lp->extents = lp->extents * vg->extent_count / 100;
|
||||
@@ -631,6 +629,8 @@ static int _lvcreate(struct cmd_context *cmd, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
status |= lp->permission | VISIBLE_LV;
|
||||
|
||||
if (lp->snapshot) {
|
||||
if (!activation()) {
|
||||
log_error("Can't create snapshot without using "
|
||||
|
||||
@@ -1001,11 +1001,76 @@ static void _init_rand(void)
|
||||
srand((unsigned) time(NULL) + (unsigned) getpid());
|
||||
}
|
||||
|
||||
static void _close_stray_fds(void)
|
||||
static const char *_get_cmdline(pid_t pid)
|
||||
{
|
||||
static char _proc_cmdline[32];
|
||||
char buf[256];
|
||||
int fd;
|
||||
|
||||
snprintf(buf, sizeof(buf), DEFAULT_PROC_DIR "/%u/cmdline", pid);
|
||||
if ((fd = open(buf, O_RDONLY)) > 0) {
|
||||
read(fd, _proc_cmdline, sizeof(_proc_cmdline) - 1);
|
||||
_proc_cmdline[sizeof(_proc_cmdline) - 1] = '\0';
|
||||
close(fd);
|
||||
} else
|
||||
_proc_cmdline[0] = '\0';
|
||||
|
||||
return _proc_cmdline;
|
||||
}
|
||||
|
||||
static const char *_get_filename(int fd)
|
||||
{
|
||||
static char filename[PATH_MAX];
|
||||
char buf[32]; /* Assumes short DEFAULT_PROC_DIR */
|
||||
int size;
|
||||
|
||||
snprintf(buf, sizeof(buf), DEFAULT_PROC_DIR "/self/fd/%u", fd);
|
||||
|
||||
if ((size = readlink(buf, filename, sizeof(filename) - 1)) == -1)
|
||||
filename[0] = '\0';
|
||||
else
|
||||
filename[size] = '\0';
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
static void _close_descriptor(int fd, unsigned suppress_warnings,
|
||||
const char *command, pid_t ppid,
|
||||
const char *parent_cmdline)
|
||||
{
|
||||
int r;
|
||||
const char *filename;
|
||||
|
||||
/* Ignore bad file descriptors */
|
||||
if (fcntl(fd, F_GETFD) == -1 && errno == EBADF)
|
||||
return;
|
||||
|
||||
if (!suppress_warnings)
|
||||
filename = _get_filename(fd);
|
||||
|
||||
r = close(fd);
|
||||
if (suppress_warnings)
|
||||
return;
|
||||
|
||||
if (!r)
|
||||
fprintf(stderr, "File descriptor %d (%s) leaked on "
|
||||
"%s invocation.", fd, filename, command);
|
||||
else if (errno == EBADF)
|
||||
return;
|
||||
else
|
||||
fprintf(stderr, "Close failed on stray file descriptor "
|
||||
"%d (%s): %s", fd, filename, strerror(errno));
|
||||
|
||||
fprintf(stderr, " Parent PID %" PRIpid_t ": %s\n", ppid, parent_cmdline);
|
||||
}
|
||||
|
||||
static void _close_stray_fds(const char *command)
|
||||
{
|
||||
struct rlimit rlim;
|
||||
int fd;
|
||||
int suppress_warnings = 0;
|
||||
unsigned suppress_warnings = 0;
|
||||
pid_t ppid = getppid();
|
||||
const char *parent_cmdline = _get_cmdline(ppid);
|
||||
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
|
||||
fprintf(stderr, "getrlimit(RLIMIT_NOFILE) failed: %s\n",
|
||||
@@ -1016,15 +1081,9 @@ static void _close_stray_fds(void)
|
||||
if (getenv("LVM_SUPPRESS_FD_WARNINGS"))
|
||||
suppress_warnings = 1;
|
||||
|
||||
for (fd = 3; fd < rlim.rlim_cur; fd++) {
|
||||
if (suppress_warnings)
|
||||
close(fd);
|
||||
else if (!close(fd))
|
||||
fprintf(stderr, "File descriptor %d left open\n", fd);
|
||||
else if (errno != EBADF)
|
||||
fprintf(stderr, "Close failed on stray file "
|
||||
"descriptor %d: %s\n", fd, strerror(errno));
|
||||
}
|
||||
for (fd = 3; fd < rlim.rlim_cur; fd++)
|
||||
_close_descriptor(fd, suppress_warnings, command, ppid,
|
||||
parent_cmdline);
|
||||
}
|
||||
|
||||
struct cmd_context *init_lvm(unsigned is_static)
|
||||
@@ -1162,15 +1221,13 @@ int lvm2_main(int argc, char **argv, unsigned is_static)
|
||||
int ret, alias = 0;
|
||||
struct cmd_context *cmd;
|
||||
|
||||
_close_stray_fds();
|
||||
|
||||
base = last_path_component(argv[0]);
|
||||
while (*base == '/')
|
||||
base++;
|
||||
if (strcmp(base, "lvm") && strcmp(base, "lvm.static") &&
|
||||
strcmp(base, "initrd-lvm"))
|
||||
alias = 1;
|
||||
|
||||
_close_stray_fds(base);
|
||||
|
||||
if (is_static && strcmp(base, "lvm.static") &&
|
||||
path_exists(LVM_SHARED_PATH) &&
|
||||
!getenv("LVM_DID_EXEC")) {
|
||||
|
||||
@@ -308,6 +308,11 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (lv->status & CONVERTING) {
|
||||
log_error("Can't resize %s while lvconvert in progress", lv->name);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
alloc = arg_uint_value(cmd, alloc_ARG, lv->alloc);
|
||||
|
||||
if (lp->size) {
|
||||
|
||||
@@ -23,9 +23,11 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
struct volume_group *vg = NULL;
|
||||
const char *vg_name = NULL;
|
||||
struct pv_list *pvl;
|
||||
struct list mdas;
|
||||
uint64_t sector;
|
||||
uint32_t orig_pe_alloc_count;
|
||||
/* FIXME Next three only required for format1. */
|
||||
uint32_t orig_pe_count, orig_pe_size;
|
||||
uint64_t orig_pe_start;
|
||||
|
||||
const char *pv_name = pv_dev_name(pv);
|
||||
const char *tag = NULL;
|
||||
@@ -35,8 +37,6 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
int allocatable = 0;
|
||||
int tagarg = 0;
|
||||
|
||||
list_init(&mdas);
|
||||
|
||||
if (arg_count(cmd, addtag_ARG))
|
||||
tagarg = addtag_ARG;
|
||||
else if (arg_count(cmd, deltag_ARG))
|
||||
@@ -51,7 +51,6 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
}
|
||||
|
||||
/* If in a VG, must change using volume group. */
|
||||
/* FIXME: handle PVs with no MDAs */
|
||||
if (!is_orphan(pv)) {
|
||||
vg_name = pv_vg_name(pv);
|
||||
|
||||
@@ -98,7 +97,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pv = pv_read(cmd, pv_name, &mdas, §or, 1))) {
|
||||
if (!(pv = pv_read(cmd, pv_name, NULL, §or, 1))) {
|
||||
unlock_vg(cmd, vg_name);
|
||||
log_error("Unable to read PV \"%s\"", pv_name);
|
||||
return 0;
|
||||
@@ -171,6 +170,12 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
if (!is_orphan(pv)) {
|
||||
orig_vg_name = pv_vg_name(pv);
|
||||
orig_pe_alloc_count = pv_pe_alloc_count(pv);
|
||||
|
||||
/* FIXME format1 pv_write doesn't preserve these. */
|
||||
orig_pe_size = pv_pe_size(pv);
|
||||
orig_pe_start = pv_pe_start(pv);
|
||||
orig_pe_count = pv_pe_count(pv);
|
||||
|
||||
pv->vg_name = pv->fmt->orphan_vg_name;
|
||||
pv->pe_alloc_count = 0;
|
||||
if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
|
||||
@@ -181,6 +186,10 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
}
|
||||
pv->vg_name = orig_vg_name;
|
||||
pv->pe_alloc_count = orig_pe_alloc_count;
|
||||
|
||||
pv->pe_size = orig_pe_size;
|
||||
pv->pe_start = orig_pe_start;
|
||||
pv->pe_count = orig_pe_count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,8 +229,6 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
|
||||
struct list *pvslist;
|
||||
struct list mdas;
|
||||
|
||||
list_init(&mdas);
|
||||
|
||||
if (arg_count(cmd, allocatable_ARG) + arg_count(cmd, addtag_ARG) +
|
||||
arg_count(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) != 1) {
|
||||
log_error("Please give exactly one option of -x, -uuid, "
|
||||
@@ -243,12 +250,34 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
|
||||
log_verbose("Using physical volume(s) on command line");
|
||||
for (; opt < argc; opt++) {
|
||||
pv_name = argv[opt];
|
||||
/* FIXME Read VG instead - pv_read will fail */
|
||||
list_init(&mdas);
|
||||
if (!(pv = pv_read(cmd, pv_name, &mdas, NULL, 1))) {
|
||||
log_error("Failed to read physical volume %s",
|
||||
pv_name);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* If a PV has no MDAs it may appear to be an
|
||||
* orphan until the metadata is read off
|
||||
* another PV in the same VG. Detecting this
|
||||
* means checking every VG by scanning every
|
||||
* PV on the system.
|
||||
*/
|
||||
if (is_orphan(pv) && !list_size(&mdas)) {
|
||||
if (!scan_vgs_for_pvs(cmd)) {
|
||||
log_error("Rescan for PVs without "
|
||||
"metadata areas failed.");
|
||||
continue;
|
||||
}
|
||||
if (!(pv = pv_read(cmd, pv_name,
|
||||
NULL, NULL, 1))) {
|
||||
log_error("Failed to read "
|
||||
"physical volume %s",
|
||||
pv_name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
total++;
|
||||
done += _pvchange_single(cmd, pv, NULL);
|
||||
}
|
||||
|
||||
236
tools/pvcreate.c
236
tools/pvcreate.c
@@ -18,6 +18,18 @@
|
||||
|
||||
struct pvcreate_params {
|
||||
int zero;
|
||||
uint64_t size;
|
||||
int pvmetadatacopies;
|
||||
uint64_t pvmetadatasize;
|
||||
int64_t labelsector;
|
||||
struct id id; /* FIXME: redundant */
|
||||
struct id *idp; /* 0 if no --uuid option */
|
||||
uint64_t pe_start;
|
||||
uint32_t extent_count;
|
||||
uint32_t extent_size;
|
||||
const char *restorefile; /* 0 if no --restorefile option */
|
||||
force_t force;
|
||||
unsigned yes;
|
||||
};
|
||||
|
||||
const char _really_init[] =
|
||||
@@ -27,18 +39,14 @@ const char _really_init[] =
|
||||
* See if we may pvcreate on this device.
|
||||
* 0 indicates we may not.
|
||||
*/
|
||||
static int pvcreate_check(struct cmd_context *cmd, const char *name)
|
||||
static int pvcreate_check(struct cmd_context *cmd, const char *name,
|
||||
struct pvcreate_params *pp)
|
||||
{
|
||||
struct physical_volume *pv;
|
||||
struct device *dev;
|
||||
uint64_t md_superblock;
|
||||
|
||||
/* is the partition type set correctly ? */
|
||||
if ((arg_count(cmd, force_ARG) < 1) && !is_lvm_partition(name)) {
|
||||
log_error("%s: Not LVM partition type: use -f to override",
|
||||
name);
|
||||
return 0;
|
||||
}
|
||||
/* FIXME Check partition type is LVM unless --force is given */
|
||||
|
||||
/* Is there a pv here already? */
|
||||
/* FIXME Use partial mode here? */
|
||||
@@ -58,14 +66,14 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
|
||||
|
||||
/* Allow partial & exported VGs to be destroyed. */
|
||||
/* We must have -ff to overwrite a non orphan */
|
||||
if (pv && !is_orphan(pv) && arg_count(cmd, force_ARG) != 2) {
|
||||
if (pv && !is_orphan(pv) && pp->force != DONT_PROMPT_OVERRIDE) {
|
||||
log_error("Can't initialize physical volume \"%s\" of "
|
||||
"volume group \"%s\" without -ff", name, pv_vg_name(pv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* prompt */
|
||||
if (pv && !is_orphan(pv) && !arg_count(cmd, yes_ARG) &&
|
||||
if (pv && !is_orphan(pv) && !pp->yes &&
|
||||
yes_no_prompt(_really_init, name, pv_vg_name(pv)) == 'n') {
|
||||
log_print("%s: physical volume not initialized", name);
|
||||
return 0;
|
||||
@@ -98,6 +106,9 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This test will fail if the device belongs to an MD array.
|
||||
*/
|
||||
if (!dev_test_excl(dev)) {
|
||||
/* FIXME Detect whether device-mapper itself is still using it */
|
||||
log_error("Can't open %s exclusively. Mounted filesystem?",
|
||||
@@ -107,9 +118,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
|
||||
|
||||
/* Wipe superblock? */
|
||||
if (dev_is_md(dev, &md_superblock) &&
|
||||
((!arg_count(cmd, uuidstr_ARG) &&
|
||||
!arg_count(cmd, restorefile_ARG)) ||
|
||||
arg_count(cmd, yes_ARG) ||
|
||||
((!pp->idp && !pp->restorefile) || pp->yes ||
|
||||
(yes_no_prompt("Software RAID md superblock "
|
||||
"detected on %s. Wipe it? [y/n] ", name) == 'y'))) {
|
||||
log_print("Wiping software RAID md superblock on %s", name);
|
||||
@@ -123,7 +132,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
|
||||
if (sigint_caught())
|
||||
return 0;
|
||||
|
||||
if (pv && !is_orphan(pv) && arg_count(cmd, force_ARG)) {
|
||||
if (pv && !is_orphan(pv) && pp->force) {
|
||||
log_warn("WARNING: Forcing physical volume creation on "
|
||||
"%s%s%s%s", name,
|
||||
!is_orphan(pv) ? " of volume group \"" : "",
|
||||
@@ -139,85 +148,29 @@ static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
|
||||
{
|
||||
struct pvcreate_params *pp = (struct pvcreate_params *) handle;
|
||||
void *pv;
|
||||
void *existing_pv;
|
||||
struct id id, *idp = NULL;
|
||||
const char *uuid = NULL;
|
||||
uint64_t size = 0;
|
||||
struct device *dev;
|
||||
struct list mdas;
|
||||
int pvmetadatacopies;
|
||||
uint64_t pvmetadatasize;
|
||||
struct volume_group *vg;
|
||||
const char *restorefile;
|
||||
uint64_t pe_start = 0;
|
||||
uint32_t extent_count = 0, extent_size = 0;
|
||||
|
||||
if (arg_count(cmd, uuidstr_ARG)) {
|
||||
uuid = arg_str_value(cmd, uuidstr_ARG, "");
|
||||
if (!id_read_format(&id, uuid))
|
||||
return EINVALID_CMD_LINE;
|
||||
if ((dev = device_from_pvid(cmd, &id)) &&
|
||||
if (pp->idp) {
|
||||
if ((dev = device_from_pvid(cmd, pp->idp)) &&
|
||||
(dev != dev_cache_get(pv_name, cmd->filter))) {
|
||||
log_error("uuid %s already in use on \"%s\"", uuid,
|
||||
dev_name(dev));
|
||||
return ECMD_FAILED;
|
||||
log_error("uuid %s already in use on \"%s\"",
|
||||
pp->idp->uuid, dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
idp = &id;
|
||||
}
|
||||
|
||||
if (arg_count(cmd, restorefile_ARG)) {
|
||||
restorefile = arg_str_value(cmd, restorefile_ARG, "");
|
||||
/* The uuid won't already exist */
|
||||
init_partial(1);
|
||||
if (!(vg = backup_read_vg(cmd, NULL, restorefile))) {
|
||||
log_error("Unable to read volume group from %s",
|
||||
restorefile);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
init_partial(0);
|
||||
if (!(existing_pv = find_pv_in_vg_by_uuid(vg, idp))) {
|
||||
log_error("Can't find uuid %s in backup file %s",
|
||||
uuid, restorefile);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
pe_start = pv_pe_start(existing_pv);
|
||||
extent_size = pv_pe_size(existing_pv);
|
||||
extent_count = pv_pe_count(existing_pv);
|
||||
}
|
||||
|
||||
if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) {
|
||||
log_error("Can't get lock for orphan PVs");
|
||||
return ECMD_FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pvcreate_check(cmd, pv_name))
|
||||
if (!pvcreate_check(cmd, pv_name, pp))
|
||||
goto error;
|
||||
|
||||
if (sigint_caught())
|
||||
goto error;
|
||||
|
||||
if (arg_sign_value(cmd, physicalvolumesize_ARG, 0) == SIGN_MINUS) {
|
||||
log_error("Physical volume size may not be negative");
|
||||
goto error;
|
||||
}
|
||||
size = arg_uint64_value(cmd, physicalvolumesize_ARG, UINT64_C(0));
|
||||
|
||||
if (arg_sign_value(cmd, metadatasize_ARG, 0) == SIGN_MINUS) {
|
||||
log_error("Metadata size may not be negative");
|
||||
goto error;
|
||||
}
|
||||
pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, UINT64_C(0));
|
||||
if (!pvmetadatasize)
|
||||
pvmetadatasize = find_config_tree_int(cmd,
|
||||
"metadata/pvmetadatasize",
|
||||
DEFAULT_PVMETADATASIZE);
|
||||
|
||||
pvmetadatacopies = arg_int_value(cmd, metadatacopies_ARG, -1);
|
||||
if (pvmetadatacopies < 0)
|
||||
pvmetadatacopies = find_config_tree_int(cmd,
|
||||
"metadata/pvmetadatacopies",
|
||||
DEFAULT_PVMETADATACOPIES);
|
||||
|
||||
if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
|
||||
log_error("%s: Couldn't find device. Check your filters?",
|
||||
pv_name);
|
||||
@@ -225,9 +178,10 @@ static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
|
||||
}
|
||||
|
||||
list_init(&mdas);
|
||||
if (!(pv = pv_create(cmd, dev, idp, size, pe_start,
|
||||
extent_count, extent_size,
|
||||
pvmetadatacopies, pvmetadatasize, &mdas))) {
|
||||
if (!(pv = pv_create(cmd, dev, pp->idp, pp->size, pp->pe_start,
|
||||
pp->extent_count, pp->extent_size,
|
||||
pp->pvmetadatacopies,
|
||||
pp->pvmetadatasize,&mdas))) {
|
||||
log_error("Failed to setup physical volume \"%s\"", pv_name);
|
||||
goto error;
|
||||
}
|
||||
@@ -259,8 +213,7 @@ static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
|
||||
log_very_verbose("Writing physical volume data to disk \"%s\"",
|
||||
pv_name);
|
||||
if (!(pv_write(cmd, (struct physical_volume *)pv, &mdas,
|
||||
arg_int64_value(cmd, labelsector_ARG,
|
||||
DEFAULT_LABELSECTOR)))) {
|
||||
pp->labelsector))) {
|
||||
log_error("Failed to write physical volume \"%s\"", pv_name);
|
||||
goto error;
|
||||
}
|
||||
@@ -268,69 +221,152 @@ static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
|
||||
log_print("Physical volume \"%s\" successfully created", pv_name);
|
||||
|
||||
unlock_vg(cmd, VG_ORPHANS);
|
||||
return ECMD_PROCESSED;
|
||||
return 1;
|
||||
|
||||
error:
|
||||
unlock_vg(cmd, VG_ORPHANS);
|
||||
return ECMD_FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pvcreate(struct cmd_context *cmd, int argc, char **argv)
|
||||
/*
|
||||
* Intial sanity checking of command-line arguments and fill in 'pp' fields.
|
||||
*
|
||||
* Input arguments:
|
||||
* cmd, argc, argv
|
||||
*
|
||||
* Output arguments:
|
||||
* pp: structure allocated by caller, fields written / validated here
|
||||
*/
|
||||
static int pvcreate_validate_params(struct cmd_context *cmd,
|
||||
int argc, char **argv,
|
||||
struct pvcreate_params *pp)
|
||||
{
|
||||
int i, r;
|
||||
int ret = ECMD_PROCESSED;
|
||||
struct pvcreate_params pp;
|
||||
const char *uuid = NULL;
|
||||
void *existing_pv;
|
||||
struct volume_group *vg;
|
||||
|
||||
memset(pp, 0, sizeof(*pp));
|
||||
|
||||
if (!argc) {
|
||||
log_error("Please enter a physical volume path");
|
||||
return EINVALID_CMD_LINE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg_count(cmd, restorefile_ARG) && !arg_count(cmd, uuidstr_ARG)) {
|
||||
log_error("--uuid is required with --restorefile");
|
||||
return EINVALID_CMD_LINE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg_count(cmd, uuidstr_ARG) && argc != 1) {
|
||||
log_error("Can only set uuid on one volume at once");
|
||||
return EINVALID_CMD_LINE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg_count(cmd, uuidstr_ARG)) {
|
||||
uuid = arg_str_value(cmd, uuidstr_ARG, "");
|
||||
if (!id_read_format(&pp->id, uuid))
|
||||
return 0;
|
||||
pp->idp = &pp->id;
|
||||
}
|
||||
|
||||
if (arg_count(cmd, restorefile_ARG)) {
|
||||
pp->restorefile = arg_str_value(cmd, restorefile_ARG, "");
|
||||
/* The uuid won't already exist */
|
||||
init_partial(1);
|
||||
if (!(vg = backup_read_vg(cmd, NULL, pp->restorefile))) {
|
||||
log_error("Unable to read volume group from %s",
|
||||
pp->restorefile);
|
||||
return 0;
|
||||
}
|
||||
init_partial(0);
|
||||
if (!(existing_pv = find_pv_in_vg_by_uuid(vg, pp->idp))) {
|
||||
log_error("Can't find uuid %s in backup file %s",
|
||||
uuid, pp->restorefile);
|
||||
return 0;
|
||||
}
|
||||
pp->pe_start = pv_pe_start(existing_pv);
|
||||
pp->extent_size = pv_pe_size(existing_pv);
|
||||
pp->extent_count = pv_pe_count(existing_pv);
|
||||
}
|
||||
|
||||
if (arg_count(cmd, yes_ARG) && !arg_count(cmd, force_ARG)) {
|
||||
log_error("Option y can only be given with option f");
|
||||
return EINVALID_CMD_LINE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp->yes = arg_count(cmd, yes_ARG);
|
||||
pp->force = arg_count(cmd, force_ARG);
|
||||
|
||||
if (arg_int_value(cmd, labelsector_ARG, 0) >= LABEL_SCAN_SECTORS) {
|
||||
log_error("labelsector must be less than %lu",
|
||||
LABEL_SCAN_SECTORS);
|
||||
return EINVALID_CMD_LINE;
|
||||
return 0;
|
||||
} else {
|
||||
pp->labelsector = arg_int64_value(cmd, labelsector_ARG,
|
||||
DEFAULT_LABELSECTOR);
|
||||
}
|
||||
|
||||
if (!(cmd->fmt->features & FMT_MDAS) &&
|
||||
(arg_count(cmd, metadatacopies_ARG) ||
|
||||
arg_count(cmd, metadatasize_ARG))) {
|
||||
log_error("Metadata parameters only apply to text format");
|
||||
return EINVALID_CMD_LINE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg_count(cmd, metadatacopies_ARG) &&
|
||||
arg_int_value(cmd, metadatacopies_ARG, -1) > 2) {
|
||||
log_error("Metadatacopies may only be 0, 1 or 2");
|
||||
return EINVALID_CMD_LINE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg_count(cmd, zero_ARG))
|
||||
pp.zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n");
|
||||
pp->zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n");
|
||||
else if (arg_count(cmd, restorefile_ARG) || arg_count(cmd, uuidstr_ARG))
|
||||
pp.zero = 0;
|
||||
pp->zero = 0;
|
||||
else
|
||||
pp.zero = 1;
|
||||
pp->zero = 1;
|
||||
|
||||
if (arg_sign_value(cmd, physicalvolumesize_ARG, 0) == SIGN_MINUS) {
|
||||
log_error("Physical volume size may not be negative");
|
||||
return 0;
|
||||
}
|
||||
pp->size = arg_uint64_value(cmd, physicalvolumesize_ARG, UINT64_C(0));
|
||||
|
||||
if (arg_sign_value(cmd, metadatasize_ARG, 0) == SIGN_MINUS) {
|
||||
log_error("Metadata size may not be negative");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp->pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, UINT64_C(0));
|
||||
if (!pp->pvmetadatasize)
|
||||
pp->pvmetadatasize = find_config_tree_int(cmd,
|
||||
"metadata/pvmetadatasize",
|
||||
DEFAULT_PVMETADATASIZE);
|
||||
|
||||
pp->pvmetadatacopies = arg_int_value(cmd, metadatacopies_ARG, -1);
|
||||
if (pp->pvmetadatacopies < 0)
|
||||
pp->pvmetadatacopies = find_config_tree_int(cmd,
|
||||
"metadata/pvmetadatacopies",
|
||||
DEFAULT_PVMETADATACOPIES);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int pvcreate(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int ret = ECMD_PROCESSED;
|
||||
struct pvcreate_params pp;
|
||||
|
||||
if (!pvcreate_validate_params(cmd, argc, argv, &pp)) {
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
r = pvcreate_single(cmd, argv[i], &pp);
|
||||
if (r > ret)
|
||||
ret = r;
|
||||
if (!pvcreate_single(cmd, argv[i], &pp))
|
||||
ret = ECMD_FAILED;
|
||||
|
||||
if (sigint_caught())
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -25,23 +25,40 @@ const char _really_wipe[] =
|
||||
static int pvremove_check(struct cmd_context *cmd, const char *name)
|
||||
{
|
||||
struct physical_volume *pv;
|
||||
struct list mdas;
|
||||
|
||||
/* is the partition type set correctly ? */
|
||||
if ((arg_count(cmd, force_ARG) < 1) && !is_lvm_partition(name)) {
|
||||
log_error("%s: Not LVM partition type: use -f to override",
|
||||
name);
|
||||
return 0;
|
||||
}
|
||||
list_init(&mdas);
|
||||
|
||||
/* FIXME Check partition type is LVM unless --force is given */
|
||||
|
||||
/* Is there a pv here already? */
|
||||
/* If not, this is an error unless you used -f. */
|
||||
if (!(pv = pv_read(cmd, name, NULL, NULL, 1))) {
|
||||
if (!(pv = pv_read(cmd, name, &mdas, NULL, 1))) {
|
||||
if (arg_count(cmd, force_ARG))
|
||||
return 1;
|
||||
log_error("Physical Volume %s not found", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a PV has no MDAs it may appear to be an
|
||||
* orphan until the metadata is read off
|
||||
* another PV in the same VG. Detecting this
|
||||
* means checking every VG by scanning every
|
||||
* PV on the system.
|
||||
*/
|
||||
if (is_orphan(pv) && !list_size(&mdas)) {
|
||||
if (!scan_vgs_for_pvs(cmd)) {
|
||||
log_error("Rescan for PVs without metadata areas "
|
||||
"failed.");
|
||||
return 0;
|
||||
}
|
||||
if (!(pv = pv_read(cmd, name, NULL, NULL, 1))) {
|
||||
log_error("Failed to read physical volume %s", name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* orphan ? */
|
||||
if (is_orphan(pv))
|
||||
return 1;
|
||||
|
||||
@@ -35,6 +35,8 @@ static int _pv_resize_single(struct cmd_context *cmd,
|
||||
struct list mdas;
|
||||
const char *pv_name = pv_dev_name(pv);
|
||||
const char *vg_name;
|
||||
struct lvmcache_info *info;
|
||||
int mda_count = 0;
|
||||
|
||||
list_init(&mdas);
|
||||
|
||||
@@ -51,13 +53,7 @@ static int _pv_resize_single(struct cmd_context *cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME Create function to test compatibility properly */
|
||||
if (list_size(&mdas) > 1) {
|
||||
log_error("%s: too many metadata areas for pvresize",
|
||||
pv_name);
|
||||
unlock_vg(cmd, vg_name);
|
||||
return 0;
|
||||
}
|
||||
mda_count = list_size(&mdas);
|
||||
} else {
|
||||
vg_name = pv_vg_name(pv);
|
||||
|
||||
@@ -87,10 +83,26 @@ static int _pv_resize_single(struct cmd_context *cmd,
|
||||
|
||||
pv = pvl->pv;
|
||||
|
||||
if (!(info = info_from_pvid(pv->dev->pvid, 0))) {
|
||||
unlock_vg(cmd, vg_name);
|
||||
log_error("Can't get info for PV %s in volume group %s",
|
||||
pv_name, vg->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mda_count = list_size(&info->mdas);
|
||||
|
||||
if (!archive(vg))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME Create function to test compatibility properly */
|
||||
if (mda_count > 1) {
|
||||
log_error("%s: too many metadata areas for pvresize", pv_name);
|
||||
unlock_vg(cmd, vg_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pv->fmt->features & FMT_RESIZE_PV)) {
|
||||
log_error("Physical volume %s format does not support resizing.",
|
||||
pv_name);
|
||||
|
||||
@@ -61,8 +61,39 @@ static int _pvsegs_sub_single(struct cmd_context *cmd __attribute((unused)),
|
||||
int ret = ECMD_PROCESSED;
|
||||
struct lv_segment *seg = pvseg->lvseg;
|
||||
|
||||
if (!report_object(handle, vg, seg ? seg->lv : NULL, pvseg->pv, seg,
|
||||
pvseg))
|
||||
struct logical_volume _free_logical_volume = {
|
||||
.vg = vg,
|
||||
.name = (char *) "",
|
||||
.snapshot = NULL,
|
||||
.status = VISIBLE_LV,
|
||||
.major = -1,
|
||||
.minor = -1,
|
||||
};
|
||||
|
||||
struct lv_segment _free_lv_segment = {
|
||||
.lv = &_free_logical_volume,
|
||||
.le = 0,
|
||||
.status = 0,
|
||||
.stripe_size = 0,
|
||||
.area_count = 0,
|
||||
.area_len = 0,
|
||||
.origin = NULL,
|
||||
.cow = NULL,
|
||||
.chunk_size = 0,
|
||||
.region_size = 0,
|
||||
.extents_copied = 0,
|
||||
.log_lv = NULL,
|
||||
.areas = NULL,
|
||||
};
|
||||
|
||||
_free_lv_segment.segtype = get_segtype_from_string(cmd, "free");
|
||||
_free_lv_segment.len = pvseg->len;
|
||||
list_init(&_free_logical_volume.tags);
|
||||
list_init(&_free_logical_volume.segments);
|
||||
list_init(&_free_logical_volume.segs_using_this_lv);
|
||||
|
||||
if (!report_object(handle, vg, seg ? seg->lv : &_free_logical_volume, pvseg->pv,
|
||||
seg ? : &_free_lv_segment, pvseg))
|
||||
ret = ECMD_FAILED;
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -34,8 +34,7 @@ static char *_expand_filename(const char *template, const char *vg_name,
|
||||
dm_free(filename);
|
||||
return NULL;
|
||||
}
|
||||
if (*last_filename && !strncmp(*last_filename, filename,
|
||||
strlen(template))) {
|
||||
if (*last_filename && !strncmp(*last_filename, filename, PATH_MAX)) {
|
||||
log_error("VGs must be backed up into different files. "
|
||||
"Use %%s in filename for VG name.");
|
||||
dm_free(filename);
|
||||
@@ -70,7 +69,8 @@ static int vg_backup_single(struct cmd_context *cmd, const char *vg_name,
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
backup_to_file(filename, vg->cmd->cmd_line, vg);
|
||||
if (!backup_to_file(filename, vg->cmd->cmd_line, vg))
|
||||
return ECMD_FAILED;
|
||||
} else {
|
||||
if (!consistent) {
|
||||
log_error("No backup taken: specify filename with -f "
|
||||
|
||||
@@ -81,6 +81,26 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
/* Set PV/LV limit if converting from unlimited metadata format */
|
||||
if (vg->fid->fmt->features & FMT_UNLIMITED_VOLS &&
|
||||
!(cmd->fmt->features & FMT_UNLIMITED_VOLS)) {
|
||||
if (!vg->max_lv)
|
||||
vg->max_lv = 255;
|
||||
if (!vg->max_pv)
|
||||
vg->max_pv = 255;
|
||||
}
|
||||
|
||||
/* If converting to restricted lvid, check if lvid is compatible */
|
||||
if (!(vg->fid->fmt->features & FMT_RESTRICTED_LVIDS) &&
|
||||
cmd->fmt->features & FMT_RESTRICTED_LVIDS)
|
||||
list_iterate_items(lvl, &vg->lvs)
|
||||
if (!lvid_in_restricted_range(&lvl->lv->lvid)) {
|
||||
log_error("Logical volume %s lvid format is"
|
||||
" incompatible with requested"
|
||||
" metadata format.", lvl->lv->name);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
/* Attempt to change any LVIDs that are too big */
|
||||
if (cmd->fmt->features & FMT_RESTRICTED_LVIDS) {
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
|
||||
@@ -250,9 +250,8 @@ static int _make_vg_consistent(struct cmd_context *cmd, struct volume_group *vg)
|
||||
lvl2->lv != seg_lv(mirrored_seg, s))
|
||||
continue;
|
||||
list_del(&lvl2->list);
|
||||
area = mirrored_seg->areas[mimages - 1];
|
||||
mirrored_seg->areas[mimages - 1] = mirrored_seg->areas[s];
|
||||
mirrored_seg->areas[s] = area;
|
||||
if (!shift_mirror_images(mirrored_seg, s))
|
||||
return_0;
|
||||
mimages--; /* FIXME Assumes uniqueness */
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user