1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-11-05 16:23:51 +03:00

Compare commits

...

73 Commits

Author SHA1 Message Date
Alasdair Kergon
859fe69083 Update dmsetup man. 2003-11-17 14:24:22 +00:00
Alasdair Kergon
f6f2205ddb Ready for another release. 2003-11-14 23:46:49 +00:00
Alasdair Kergon
0f9a03ef61 lvcreate should close the initialised snapshot device immediately. 2003-11-14 17:55:39 +00:00
Alasdair Kergon
9aa417c084 Add/update some man pages. 2003-11-14 16:17:55 +00:00
Alasdair Kergon
7b70952f5d vgscan --mknodes 2003-11-14 14:03:48 +00:00
Alasdair Kergon
edd3d07b49 Fix dev_zero() offset. 2003-11-13 23:55:03 +00:00
Alasdair Kergon
5293d0a4ec Immediate error on big memory allocations when --enable-debug. 2003-11-13 23:54:02 +00:00
Alasdair Kergon
3c8c7beae1 Missing include. 2003-11-13 18:47:22 +00:00
Alasdair Kergon
9c3ba9fdcd vgmknodes also creates necessary nodes in /dev/mapper 2003-11-13 14:11:41 +00:00
Alasdair Kergon
fb1748fb0f dmsetup mknodes 2003-11-13 13:14:28 +00:00
Alasdair Kergon
0a109fbd03 The LVM2 part of vgmknodes [still to do the non-devfs device-mapper bit]. 2003-11-12 19:16:48 +00:00
Alasdair Kergon
5cf64db74e Accept tables from stdin with dmsetup.
Update autoconf.
2003-11-12 17:30:32 +00:00
Alasdair Kergon
488cc94f36 Exclude v1 compatibility code when configured with --disable-compat
[Use this with 2.6 kernels + device-mapper V4 interface]
CVS ----------------------------------------------------------------------
2003-11-10 21:06:16 +00:00
Alasdair Kergon
e15846bf79 Default to unlimited number of LVs/PVs in lvm2 format. 2003-11-06 20:33:34 +00:00
Alasdair Kergon
752bd00674 Prevent PV allocation bit getting changed for format_text orphans. 2003-11-06 20:15:13 +00:00
Alasdair Kergon
7fadfcbe32 Fix vgremove 'all OK' check 2003-11-06 17:16:22 +00:00
Alasdair Kergon
41141e75bb Configuration-time O_DIRECT setting. 2003-11-06 17:14:06 +00:00
Alasdair Kergon
50f641e627 Add drbd. 2003-11-06 17:10:35 +00:00
Alasdair Kergon
c7883fd093 Fit locking bits into 1 byte. 2003-11-06 17:08:18 +00:00
Alasdair Kergon
4fcb24b2b1 Ban vgcreate -s 0 2003-11-06 17:07:19 +00:00
Alasdair Kergon
5003557935 Fix pvchange segfault with orphans. 2003-11-06 17:06:06 +00:00
Alasdair Kergon
bdf1ba84da Don't trigger error if changing PV allocation to the state it already is. 2003-11-06 17:04:35 +00:00
Alasdair Kergon
b0b4def983 Cope better with LVM1 minor numbers & LV numbers. 2003-11-06 16:58:38 +00:00
Alasdair Kergon
cc184bbe9e Fix exported format1 VG recognition. 2003-10-21 22:21:41 +00:00
Alasdair Kergon
ad30c830aa More consistent error code usage. 2003-10-21 22:06:07 +00:00
Alasdair Kergon
1d791a8af4 Check no fs mounted before deactivating. 2003-10-21 22:00:36 +00:00
Alasdair Kergon
e63c51cd97 Inherit CFLAGS at make time 2003-10-21 21:59:42 +00:00
Alasdair Kergon
f202e32908 Dump active configuration 2003-10-15 20:19:43 +00:00
Alasdair Kergon
26e1a08e82 dumpconfig to dump active configuration 2003-10-15 20:17:19 +00:00
Alasdair Kergon
4d5119d435 relax a scanning restriction 2003-10-15 20:10:11 +00:00
Alasdair Kergon
75e34ea62e Fix >32bit lvcreate size calculation. 2003-10-15 20:07:55 +00:00
Alasdair Kergon
0a183d6274 Prevent creation of MDA bigger than disk. 2003-10-15 20:06:37 +00:00
Alasdair Kergon
21d8060aea Don't forget to set 64-bit arg values too. 2003-10-15 20:05:30 +00:00
Alasdair Kergon
9cbe906f60 more str_list fns 2003-10-15 20:04:29 +00:00
Alasdair Kergon
8ce4137399 macro changes 2003-10-15 20:02:46 +00:00
Alasdair Kergon
5f8a139347 str_list_del 2003-10-15 20:01:12 +00:00
Alasdair Kergon
9bb009a3fe Extract some common functions. 2003-09-17 20:35:57 +00:00
Alasdair Kergon
726d65923f Update to incorporate most of version 4 interface changes. 2003-09-17 13:23:49 +00:00
Alasdair Kergon
8a6be4cb2d Remove incorrect comments. 2003-09-16 16:23:21 +00:00
Alasdair Kergon
10b06beb8e out-of-date 2003-09-16 16:18:50 +00:00
Alasdair Kergon
81318c7968 Update 2003-09-16 16:15:07 +00:00
Alasdair Kergon
47a2c1c6e5 Fix read-only snapshot creation. 2003-09-16 16:08:05 +00:00
Alasdair Kergon
39cee65c6b Make dev_name optional to show details for all devices.
e.g. 'dmsetup info', 'dmsetup status -v', 'dmsetup table'
2003-09-16 14:13:51 +00:00
Alasdair Kergon
8582ec724e Improve segment merge/split code. 2003-09-15 18:22:50 +00:00
Alasdair Kergon
b0139682e8 Don't install the pvdata stub; update built-in mesg. 2003-09-15 15:05:23 +00:00
Alasdair Kergon
d39c475a6d Ensure more args aren't negative. 2003-09-15 15:04:39 +00:00
Alasdair Kergon
48f38354c6 Missing vg_commit() 2003-09-15 15:03:54 +00:00
Alasdair Kergon
cd5a920ed5 vgcfgrestore -l lists backup file too 2003-09-15 15:03:22 +00:00
Alasdair Kergon
71bc1f378d Prevent cmdline flags that take args getting repeated. 2003-09-15 15:02:24 +00:00
Alasdair Kergon
0ee6c31cff Missing ] in pvmove usage display 2003-09-15 15:01:36 +00:00
Alasdair Kergon
af89a9971e Generalise 'invalid chars' error mesg to just say 'invalid' 2003-09-15 15:01:00 +00:00
Alasdair Kergon
c718a8ef72 Correct order of consistency/exists checks. 2003-09-15 15:00:01 +00:00
Alasdair Kergon
8c8ad0faf0 Don't use !# in randomly-generated uuids. 2003-09-15 14:58:43 +00:00
Alasdair Kergon
314d5bbb7f Fix makefile install mesg displayed for man5 2003-09-15 14:57:15 +00:00
Alasdair Kergon
102255757a Additional validation of LV segments read from metadata. [HM] 2003-09-01 19:55:16 +00:00
Alasdair Kergon
914067a0d0 Fix unsafe list iteration in segment merge code. [HM] 2003-08-27 15:30:39 +00:00
Alasdair Kergon
06e3ae2536 Remove unnecessary file. 2003-08-26 21:12:45 +00:00
Alasdair Kergon
7f9b252556 Cope better when format functions are missing. 2003-08-26 21:12:06 +00:00
Alasdair Kergon
3d700e243f Log each command & args. 2003-08-26 21:00:05 +00:00
Alasdair Kergon
bcfc78ce11 Update. 2003-08-20 15:48:46 +00:00
Alasdair Kergon
09241765d5 Some tidyups and minor fixes. 2003-08-20 15:48:27 +00:00
Alasdair Kergon
671c83c265 Remove small hard-coded activation target line parameter limit. 2003-08-20 12:53:57 +00:00
Alasdair Kergon
772d28b766 Also allow pvmove --abort when pvmove mirror not active (e.g. after a reboot). 2003-08-18 17:21:51 +00:00
Alasdair Kergon
c26fcea58d Missing check for inconsistent VG in pvmove. 2003-08-18 13:52:43 +00:00
Alasdair Kergon
1e5e26dbff update 2003-07-18 00:41:04 +00:00
Alasdair Kergon
742fc54864 Accept signed numbers in config file. 2003-07-15 16:32:20 +00:00
Alasdair Kergon
49738f43c0 update 2003-07-15 01:30:18 +00:00
Alasdair Kergon
9f85f61010 Fix vgimport fix to work outside debug mode. 2003-07-15 01:26:24 +00:00
Alasdair Kergon
239f422039 update 2003-07-13 11:07:50 +00:00
Alasdair Kergon
67af3c37be Fix detection of exported LVM1 volume groups. 2003-07-13 11:07:25 +00:00
Alasdair Kergon
a9442385c4 vsn 2.00.02 (rc3) 2003-07-12 12:02:12 +00:00
Alasdair Kergon
8c9cd10b8b Restrict active lvchange -My with -f 2003-07-11 17:10:19 +00:00
Alasdair Kergon
72542059dd Fix inactive snapshot display. 2003-07-11 17:09:21 +00:00
112 changed files with 2100 additions and 924 deletions

2
BUGS
View File

@@ -1,2 +0,0 @@
Snapshots under 2.4.18 can deadlock due to a bug in the VM system.
2.4.19-pre8 is fine.

10
README
View File

@@ -1,13 +1,11 @@
This directory contains a beta release of LVM2, the new version of This directory contains LVM2, the new version of the userland LVM
the userland LVM tools designed for the new device-mapper for tools designed for the new device-mapper for the Linux kernel.
the Linux kernel.
The device-mapper needs to be installed before compiling these LVM2 tools. The device-mapper needs to be installed before compiling these LVM2 tools.
For more information about LVM2 read the WHATS_NEW file. For more information about LVM2 read the WHATS_NEW file.
Installation instructions are in INSTALL. Installation instructions are in INSTALL.
This is beta-quality software, released for testing purposes only.
There is no warranty - see COPYING and COPYING.LIB. There is no warranty - see COPYING and COPYING.LIB.
Tarballs are available from: Tarballs are available from:
@@ -20,6 +18,6 @@ To access the CVS tree use:
cvs -d :pserver:cvs@tech.sistina.com:/data/cvs checkout LVM2 cvs -d :pserver:cvs@tech.sistina.com:/data/cvs checkout LVM2
Mailing list for discussion/bug reports etc. Mailing list for discussion/bug reports etc.
lvm-devel@sistina.com linux-lvm@sistina.com
Subscribe from http://lists.sistina.com/mailman/listinfo/lvm-devel Subscribe from http://lists.sistina.com/mailman/listinfo/linux-lvm

View File

@@ -1 +1 @@
2.00.01-cvs (2003-07-06) 2.00.08-cvs (2003-11-14)

View File

@@ -1,3 +1,19 @@
Friday 14th November 2003
=========================
Some bug fixes & minor enhancements, including:
Backwards compatibility with LVM1 metadata improved.
Missing man pages written.
Tool error codes made more consistent.
vgmknodes written.
O_DIRECT can be turned off if it doesn't work in your kernel.
You need to update libdevmapper before using 'vgmknodes' or 'vgscan --mknodes'.
If your root filesystem is on an LV, you should run one of those two
commands to fix up the special files in /dev in your real root filesystem
after finishing with your initrd. Also, remember you can use
'vgchange --ignorelockingfailure' on your initrd if the tool fails because
it can't write a lock file to a read-only filesystem.
Wednesday 30th April 2003 Wednesday 30th April 2003
========================= =========================
A pvmove implementation is now available for the new metadata format. A pvmove implementation is now available for the new metadata format.
@@ -25,6 +41,7 @@ to provide us with diagnostic information:
log { log {
file="/tmp/lvm2.log" file="/tmp/lvm2.log"
level=7 level=7
activation=1
} }
You should schedule regular backups of your configuration file and You should schedule regular backups of your configuration file and

217
configure vendored
View File

@@ -30,6 +30,8 @@ ac_help="$ac_help
--enable-debug Enable debugging" --enable-debug Enable debugging"
ac_help="$ac_help ac_help="$ac_help
--disable-devmapper Disable device-mapper interaction" --disable-devmapper Disable device-mapper interaction"
ac_help="$ac_help
--disable-o_direct Disable O_DIRECT"
# Initialize some variables set by options. # Initialize some variables set by options.
# The variables have the same names as the options, with # The variables have the same names as the options, with
@@ -561,12 +563,12 @@ ac_config_sub=$ac_aux_dir/config.sub
ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
for ac_prog in mawk gawk nawk awk for ac_prog in gawk mawk nawk awk
do do
# Extract the first word of "$ac_prog", so it can be a program name with args. # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2 set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:570: checking for $ac_word" >&5 echo "configure:572: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@@ -598,7 +600,7 @@ done
# Extract the first word of "gcc", so it can be a program name with args. # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2 set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:602: checking for $ac_word" >&5 echo "configure:604: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@@ -628,7 +630,7 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args. # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2 set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:632: checking for $ac_word" >&5 echo "configure:634: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@@ -679,7 +681,7 @@ fi
# Extract the first word of "cl", so it can be a program name with args. # Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2 set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:683: checking for $ac_word" >&5 echo "configure:685: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@@ -711,7 +713,7 @@ fi
fi fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:715: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 echo "configure:717: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -722,12 +724,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF cat > conftest.$ac_ext << EOF
#line 726 "configure" #line 728 "configure"
#include "confdefs.h" #include "confdefs.h"
main(){return(0);} main(){return(0);}
EOF EOF
if { (eval echo configure:731: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:733: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler. # If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then if (./conftest; exit) 2>/dev/null; then
@@ -753,12 +755,12 @@ if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
echo "configure:757: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "configure:759: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
echo "configure:762: checking whether we are using GNU C" >&5 echo "configure:764: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@@ -767,7 +769,7 @@ else
yes; yes;
#endif #endif
EOF EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:771: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:773: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes ac_cv_prog_gcc=yes
else else
ac_cv_prog_gcc=no ac_cv_prog_gcc=no
@@ -786,7 +788,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS" ac_save_CFLAGS="$CFLAGS"
CFLAGS= CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:790: checking whether ${CC-cc} accepts -g" >&5 echo "configure:792: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@@ -829,7 +831,7 @@ fi
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh. # ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:833: checking for a BSD compatible install" >&5 echo "configure:835: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
@@ -882,7 +884,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
echo "configure:886: checking whether ln -s works" >&5 echo "configure:888: checking whether ln -s works" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@@ -903,7 +905,7 @@ else
fi fi
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
echo "configure:907: checking whether ${MAKE-make} sets \${MAKE}" >&5 echo "configure:909: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
@@ -932,7 +934,7 @@ fi
# Extract the first word of "ranlib", so it can be a program name with args. # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2 set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:936: checking for $ac_word" >&5 echo "configure:938: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@@ -965,12 +967,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
echo "configure:969: checking for $ac_hdr that defines DIR" >&5 echo "configure:971: checking for $ac_hdr that defines DIR" >&5
if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 974 "configure" #line 976 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#include <$ac_hdr> #include <$ac_hdr>
@@ -978,7 +980,7 @@ int main() {
DIR *dirp = 0; DIR *dirp = 0;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:982: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:984: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_header_dirent_$ac_safe=yes" eval "ac_cv_header_dirent_$ac_safe=yes"
else else
@@ -1003,7 +1005,7 @@ done
# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
if test $ac_header_dirent = dirent.h; then if test $ac_header_dirent = dirent.h; then
echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
echo "configure:1007: checking for opendir in -ldir" >&5 echo "configure:1009: checking for opendir in -ldir" >&5
ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
@@ -1011,7 +1013,7 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-ldir $LIBS" LIBS="-ldir $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1015 "configure" #line 1017 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
@@ -1022,7 +1024,7 @@ int main() {
opendir() opendir()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:1026: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:1028: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
@@ -1044,7 +1046,7 @@ fi
else else
echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
echo "configure:1048: checking for opendir in -lx" >&5 echo "configure:1050: checking for opendir in -lx" >&5
ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
@@ -1052,7 +1054,7 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lx $LIBS" LIBS="-lx $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1056 "configure" #line 1058 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
@@ -1063,7 +1065,7 @@ int main() {
opendir() opendir()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:1067: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:1069: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
@@ -1086,7 +1088,7 @@ fi
fi fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:1090: checking how to run the C preprocessor" >&5 echo "configure:1092: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory. # On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then if test -n "$CPP" && test -d "$CPP"; then
CPP= CPP=
@@ -1101,13 +1103,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser, # On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. # not just through cpp.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1105 "configure" #line 1107 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1111: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:1113: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
@@ -1118,13 +1120,13 @@ else
rm -rf conftest* rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp" CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1122 "configure" #line 1124 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1128: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:1130: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
@@ -1135,13 +1137,13 @@ else
rm -rf conftest* rm -rf conftest*
CPP="${CC-cc} -nologo -E" CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1139 "configure" #line 1141 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1145: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:1147: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
@@ -1166,12 +1168,12 @@ fi
echo "$ac_t""$CPP" 1>&6 echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
echo "configure:1170: checking for ANSI C header files" >&5 echo "configure:1172: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1175 "configure" #line 1177 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
@@ -1179,7 +1181,7 @@ else
#include <float.h> #include <float.h>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1183: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:1185: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
@@ -1196,7 +1198,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI. # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1200 "configure" #line 1202 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <string.h> #include <string.h>
EOF EOF
@@ -1214,7 +1216,7 @@ fi
if test $ac_cv_header_stdc = yes; then if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1218 "configure" #line 1220 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <stdlib.h> #include <stdlib.h>
EOF EOF
@@ -1235,7 +1237,7 @@ if test "$cross_compiling" = yes; then
: :
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1239 "configure" #line 1241 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <ctype.h> #include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1246,7 +1248,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); } exit (0); }
EOF EOF
if { (eval echo configure:1250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null if { (eval echo configure:1252: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then then
: :
else else
@@ -1273,17 +1275,17 @@ for ac_hdr in fcntl.h malloc.h sys/ioctl.h unistd.h
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:1277: checking for $ac_hdr" >&5 echo "configure:1279: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1282 "configure" #line 1284 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1287: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:1289: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
@@ -1311,18 +1313,18 @@ done
echo $ac_n "checking for working const""... $ac_c" 1>&6 echo $ac_n "checking for working const""... $ac_c" 1>&6
echo "configure:1315: checking for working const" >&5 echo "configure:1317: checking for working const" >&5
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1320 "configure" #line 1322 "configure"
#include "confdefs.h" #include "confdefs.h"
int main() { int main() {
/* Ultrix mips cc rejects this. */ /* Ultrix mips cc rejects this. */
typedef int charset[2]; const charset x = {0,0}; typedef int charset[2]; const charset x;
/* SunOS 4.1.1 cc rejects this. */ /* SunOS 4.1.1 cc rejects this. */
char const *const *ccp; char const *const *ccp;
char **p; char **p;
@@ -1365,7 +1367,7 @@ ccp = (char const *const *) p;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:1369: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:1371: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_c_const=yes ac_cv_c_const=yes
else else
@@ -1386,21 +1388,21 @@ EOF
fi fi
echo $ac_n "checking for inline""... $ac_c" 1>&6 echo $ac_n "checking for inline""... $ac_c" 1>&6
echo "configure:1390: checking for inline" >&5 echo "configure:1392: checking for inline" >&5
if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
ac_cv_c_inline=no ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do for ac_kw in inline __inline__ __inline; do
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1397 "configure" #line 1399 "configure"
#include "confdefs.h" #include "confdefs.h"
int main() { int main() {
} int $ac_kw foo() { } $ac_kw foo() {
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:1404: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:1406: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_c_inline=$ac_kw; break ac_cv_c_inline=$ac_kw; break
else else
@@ -1426,12 +1428,12 @@ EOF
esac esac
echo $ac_n "checking for off_t""... $ac_c" 1>&6 echo $ac_n "checking for off_t""... $ac_c" 1>&6
echo "configure:1430: checking for off_t" >&5 echo "configure:1432: checking for off_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1435 "configure" #line 1437 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#if STDC_HEADERS #if STDC_HEADERS
@@ -1459,12 +1461,12 @@ EOF
fi fi
echo $ac_n "checking for pid_t""... $ac_c" 1>&6 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
echo "configure:1463: checking for pid_t" >&5 echo "configure:1465: checking for pid_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1468 "configure" #line 1470 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#if STDC_HEADERS #if STDC_HEADERS
@@ -1492,12 +1494,12 @@ EOF
fi fi
echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo $ac_n "checking for size_t""... $ac_c" 1>&6
echo "configure:1496: checking for size_t" >&5 echo "configure:1498: checking for size_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1501 "configure" #line 1503 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#if STDC_HEADERS #if STDC_HEADERS
@@ -1525,12 +1527,12 @@ EOF
fi fi
echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6 echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
echo "configure:1529: checking for st_rdev in struct stat" >&5 echo "configure:1531: checking for st_rdev in struct stat" >&5
if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1534 "configure" #line 1536 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -1538,7 +1540,7 @@ int main() {
struct stat s; s.st_rdev; struct stat s; s.st_rdev;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:1542: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:1544: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_struct_st_rdev=yes ac_cv_struct_st_rdev=yes
else else
@@ -1559,12 +1561,12 @@ EOF
fi fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
echo "configure:1563: checking whether time.h and sys/time.h may both be included" >&5 echo "configure:1565: checking whether time.h and sys/time.h may both be included" >&5
if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1568 "configure" #line 1570 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
@@ -1573,7 +1575,7 @@ int main() {
struct tm *tp; struct tm *tp;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:1577: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:1579: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_header_time=yes ac_cv_header_time=yes
else else
@@ -1622,7 +1624,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi fi
echo $ac_n "checking host system type""... $ac_c" 1>&6 echo $ac_n "checking host system type""... $ac_c" 1>&6
echo "configure:1626: checking host system type" >&5 echo "configure:1628: checking host system type" >&5
host_alias=$host host_alias=$host
case "$host_alias" in case "$host_alias" in
@@ -1643,7 +1645,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 1>&6 echo "$ac_t""$host" 1>&6
echo $ac_n "checking target system type""... $ac_c" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6
echo "configure:1647: checking target system type" >&5 echo "configure:1649: checking target system type" >&5
target_alias=$target target_alias=$target
case "$target_alias" in case "$target_alias" in
@@ -1661,7 +1663,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$target" 1>&6 echo "$ac_t""$target" 1>&6
echo $ac_n "checking build system type""... $ac_c" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6
echo "configure:1665: checking build system type" >&5 echo "configure:1667: checking build system type" >&5
build_alias=$build build_alias=$build
case "$build_alias" in case "$build_alias" in
@@ -1784,19 +1786,33 @@ if test x$DEVMAPPER = xyes; then
CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT" CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT"
fi fi
# Check whether --enable-o_direct or --disable-o_direct was given.
if test "${enable_o_direct+set}" = set; then
enableval="$enable_o_direct"
\
ODIRECT=no
else
ODIRECT=yes
fi
if test x$ODIRECT = xyes; then
CFLAGS="$CFLAGS -DO_DIRECT_SUPPORT"
fi
if [ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]; if [ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ];
then exec_prefix=""; then exec_prefix="";
fi; fi;
if test $ac_cv_prog_gcc = yes; then if test $ac_cv_prog_gcc = yes; then
echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
echo "configure:1794: checking whether ${CC-cc} needs -traditional" >&5 echo "configure:1810: checking whether ${CC-cc} needs -traditional" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
ac_pattern="Autoconf.*'x'" ac_pattern="Autoconf.*'x'"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1800 "configure" #line 1816 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sgtty.h> #include <sgtty.h>
Autoconf TIOCGETP Autoconf TIOCGETP
@@ -1814,7 +1830,7 @@ rm -f conftest*
if test $ac_cv_prog_gcc_traditional = no; then if test $ac_cv_prog_gcc_traditional = no; then
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1818 "configure" #line 1834 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <termio.h> #include <termio.h>
Autoconf TCGETA Autoconf TCGETA
@@ -1836,12 +1852,12 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
fi fi
echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
echo "configure:1840: checking return type of signal handlers" >&5 echo "configure:1856: checking return type of signal handlers" >&5
if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1845 "configure" #line 1861 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#include <signal.h> #include <signal.h>
@@ -1858,7 +1874,7 @@ int main() {
int i; int i;
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:1862: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:1878: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_type_signal=void ac_cv_type_signal=void
else else
@@ -1877,12 +1893,12 @@ EOF
echo $ac_n "checking for vprintf""... $ac_c" 1>&6 echo $ac_n "checking for vprintf""... $ac_c" 1>&6
echo "configure:1881: checking for vprintf" >&5 echo "configure:1897: checking for vprintf" >&5
if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1886 "configure" #line 1902 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vprintf(); below. */ which can conflict with char vprintf(); below. */
@@ -1905,7 +1921,7 @@ vprintf();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:1909: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:1925: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_vprintf=yes" eval "ac_cv_func_vprintf=yes"
else else
@@ -1929,12 +1945,12 @@ fi
if test "$ac_cv_func_vprintf" != yes; then if test "$ac_cv_func_vprintf" != yes; then
echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
echo "configure:1933: checking for _doprnt" >&5 echo "configure:1949: checking for _doprnt" >&5
if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1938 "configure" #line 1954 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char _doprnt(); below. */ which can conflict with char _doprnt(); below. */
@@ -1957,7 +1973,7 @@ _doprnt();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:1961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:1977: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func__doprnt=yes" eval "ac_cv_func__doprnt=yes"
else else
@@ -1984,12 +2000,12 @@ fi
for ac_func in mkdir rmdir uname for ac_func in mkdir rmdir uname
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:1988: checking for $ac_func" >&5 echo "configure:2004: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1993 "configure" #line 2009 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */ which can conflict with char $ac_func(); below. */
@@ -2012,7 +2028,7 @@ $ac_func();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2016: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2032: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_$ac_func=yes" eval "ac_cv_func_$ac_func=yes"
else else
@@ -2040,14 +2056,14 @@ done
if test x$READLINE = xyes; then if test x$READLINE = xyes; then
echo $ac_n "checking for library containing tgetent""... $ac_c" 1>&6 echo $ac_n "checking for library containing tgetent""... $ac_c" 1>&6
echo "configure:2044: checking for library containing tgetent" >&5 echo "configure:2060: checking for library containing tgetent" >&5
if eval "test \"`echo '$''{'ac_cv_search_tgetent'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_search_tgetent'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
ac_func_search_save_LIBS="$LIBS" ac_func_search_save_LIBS="$LIBS"
ac_cv_search_tgetent="no" ac_cv_search_tgetent="no"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2051 "configure" #line 2067 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
@@ -2058,7 +2074,7 @@ int main() {
tgetent() tgetent()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2062: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2078: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
ac_cv_search_tgetent="none required" ac_cv_search_tgetent="none required"
else else
@@ -2069,7 +2085,7 @@ rm -f conftest*
test "$ac_cv_search_tgetent" = "no" && for i in ncurses curses termcap termlib; do test "$ac_cv_search_tgetent" = "no" && for i in ncurses curses termcap termlib; do
LIBS="-l$i $ac_func_search_save_LIBS" LIBS="-l$i $ac_func_search_save_LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2073 "configure" #line 2089 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
@@ -2080,7 +2096,7 @@ int main() {
tgetent() tgetent()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2084: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
ac_cv_search_tgetent="-l$i" ac_cv_search_tgetent="-l$i"
break break
@@ -2113,7 +2129,7 @@ fi
fi fi
echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
echo "configure:2117: checking for dlopen in -ldl" >&5 echo "configure:2133: checking for dlopen in -ldl" >&5
ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
@@ -2121,7 +2137,7 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-ldl $LIBS" LIBS="-ldl $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2125 "configure" #line 2141 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
@@ -2132,7 +2148,7 @@ int main() {
dlopen() dlopen()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2136: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2152: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
@@ -2163,17 +2179,17 @@ for ac_hdr in getopt.h
do do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:2167: checking for $ac_hdr" >&5 echo "configure:2183: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2172 "configure" #line 2188 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <$ac_hdr> #include <$ac_hdr>
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2177: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:2193: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
rm -rf conftest* rm -rf conftest*
@@ -2202,7 +2218,7 @@ done
if test x$READLINE = xyes; then if test x$READLINE = xyes; then
echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6 echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
echo "configure:2206: checking for readline in -lreadline" >&5 echo "configure:2222: checking for readline in -lreadline" >&5
ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'` ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
@@ -2210,7 +2226,7 @@ else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lreadline $LIBS" LIBS="-lreadline $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2214 "configure" #line 2230 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2 /* We use char because int might match the return type of a gcc2
@@ -2221,7 +2237,7 @@ int main() {
readline() readline()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2225: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2241: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
@@ -2258,12 +2274,12 @@ package as well (which may be called readline-devel or something similar).
fi fi
echo $ac_n "checking for rl_completion_matches""... $ac_c" 1>&6 echo $ac_n "checking for rl_completion_matches""... $ac_c" 1>&6
echo "configure:2262: checking for rl_completion_matches" >&5 echo "configure:2278: checking for rl_completion_matches" >&5
if eval "test \"`echo '$''{'ac_cv_func_rl_completion_matches'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_func_rl_completion_matches'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2267 "configure" #line 2283 "configure"
#include "confdefs.h" #include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes, /* System header to define __stub macros and hopefully few prototypes,
which can conflict with char rl_completion_matches(); below. */ which can conflict with char rl_completion_matches(); below. */
@@ -2286,7 +2302,7 @@ rl_completion_matches();
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:2290: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:2306: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_func_rl_completion_matches=yes" eval "ac_cv_func_rl_completion_matches=yes"
else else
@@ -2643,3 +2659,10 @@ chmod +x $CONFIG_STATUS
rm -fr confdefs* $ac_clean_files rm -fr confdefs* $ac_clean_files
test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
if test x$ODIRECT != xyes; then
echo
echo Warning: O_DIRECT disabled.
echo Use of pvmove may cause machine to lock up under low memory conditions.
echo
fi

View File

@@ -113,6 +113,14 @@ if test x$DEVMAPPER = xyes; then
CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT" CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT"
fi fi
dnl Disable O_DIRECT
AC_ARG_ENABLE(o_direct, [ --disable-o_direct Disable O_DIRECT], \
ODIRECT=no, ODIRECT=yes)
if test x$ODIRECT = xyes; then
CFLAGS="$CFLAGS -DO_DIRECT_SUPPORT"
fi
dnl Mess with default exec_prefix dnl Mess with default exec_prefix
if [[ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]]; if [[ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]];
then exec_prefix=""; then exec_prefix="";
@@ -203,3 +211,10 @@ test/format1/Makefile \
test/regex/Makefile \ test/regex/Makefile \
test/filters/Makefile \ test/filters/Makefile \
) )
if test x$ODIRECT != xyes; then
echo
echo Warning: O_DIRECT disabled.
echo Use of pvmove may cause machine to lock up under low memory conditions.
echo
fi

View File

@@ -9,6 +9,7 @@
../lib/datastruct/hash.h ../lib/datastruct/hash.h
../lib/datastruct/list.h ../lib/datastruct/list.h
../lib/datastruct/lvm-types.h ../lib/datastruct/lvm-types.h
../lib/datastruct/str_list.h
../lib/device/dev-cache.h ../lib/device/dev-cache.h
../lib/device/device.h ../lib/device/device.h
../lib/display/display.h ../lib/display/display.h
@@ -17,11 +18,11 @@
../lib/filters/filter-regex.h ../lib/filters/filter-regex.h
../lib/filters/filter.h ../lib/filters/filter.h
../lib/format1/format1.h ../lib/format1/format1.h
../lib/format1/lvm1-label.h
../lib/format_text/format-text.h ../lib/format_text/format-text.h
../lib/label/label.h ../lib/label/label.h
../lib/locking/locking.h ../lib/locking/locking.h
../lib/log/log.h ../lib/log/log.h
../lib/metadata/lv_alloc.h
../lib/metadata/metadata.h ../lib/metadata/metadata.h
../lib/mm/dbg_malloc.h ../lib/mm/dbg_malloc.h
../lib/mm/memlock.h ../lib/mm/memlock.h

View File

@@ -20,6 +20,7 @@ SOURCES=\
datastruct/bitset.c \ datastruct/bitset.c \
datastruct/btree.c \ datastruct/btree.c \
datastruct/hash.c \ datastruct/hash.c \
datastruct/str_list.c \
device/dev-cache.c \ device/dev-cache.c \
device/dev-io.c \ device/dev-io.c \
device/device.c \ device/device.c \

View File

@@ -77,6 +77,12 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s)
{ {
return 1; return 1;
} }
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
{
return 1;
}
void activation_exit(void) void activation_exit(void)
{ {
return; return;
@@ -146,7 +152,8 @@ int driver_version(char *version, size_t size)
/* /*
* Returns 1 if info structure populated, else 0 on failure. * Returns 1 if info structure populated, else 0 on failure.
*/ */
int lv_info(const struct logical_volume *lv, struct lvinfo *info) static int _lv_info(const struct logical_volume *lv, int mknodes,
struct lvinfo *info)
{ {
int r; int r;
struct dev_manager *dm; struct dev_manager *dm;
@@ -160,7 +167,7 @@ int lv_info(const struct logical_volume *lv, struct lvinfo *info)
return 0; return 0;
} }
if (!(r = dev_manager_info(dm, lv, &dminfo))) if (!(r = dev_manager_info(dm, lv, mknodes, &dminfo)))
stack; stack;
info->exists = dminfo.exists; info->exists = dminfo.exists;
@@ -174,6 +181,11 @@ int lv_info(const struct logical_volume *lv, struct lvinfo *info)
return r; return r;
} }
int lv_info(const struct logical_volume *lv, struct lvinfo *info)
{
return _lv_info(lv, 0, info);
}
/* /*
* Returns 1 if percent set, else 0 on failure. * Returns 1 if percent set, else 0 on failure.
*/ */
@@ -428,6 +440,12 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
if (!info.exists) if (!info.exists)
return 1; return 1;
if (info.open_count) {
log_error("LV %s/%s in use: not removing", lv->vg->name,
lv->name);
return 0;
}
memlock_inc(); memlock_inc();
r = _lv_deactivate(lv); r = _lv_deactivate(lv);
memlock_dec(); memlock_dec();
@@ -469,6 +487,26 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s)
return r; return r;
} }
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
{
struct lvinfo info;
int r = 1;
if (!_lv_info(lv, 1, &info)) {
stack;
return 0;
}
if (info.exists)
r = dev_manager_mknodes(lv);
else
r = dev_manager_rmnodes(lv);
fs_unlock();
return r;
}
void activation_exit(void) void activation_exit(void)
{ {
dev_manager_exit(); dev_manager_exit();

View File

@@ -35,6 +35,8 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s);
int lv_activate(struct cmd_context *cmd, const char *lvid_s); int lv_activate(struct cmd_context *cmd, const char *lvid_s);
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s); int lv_deactivate(struct cmd_context *cmd, const char *lvid_s);
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
/* /*
* Returns 1 if info structure has been populated, else 0. * Returns 1 if info structure has been populated, else 0.
*/ */

View File

@@ -5,12 +5,14 @@
*/ */
#include "lib.h" #include "lib.h"
#include "str_list.h"
#include "dev_manager.h" #include "dev_manager.h"
#include "pool.h" #include "pool.h"
#include "hash.h" #include "hash.h"
#include "lvm-string.h" #include "lvm-string.h"
#include "fs.h" #include "fs.h"
#include "defaults.h" #include "defaults.h"
#include "toolcontext.h"
#include <libdevmapper.h> #include <libdevmapper.h>
#include <limits.h> #include <limits.h>
@@ -41,6 +43,8 @@
* *
*/ */
#define MAX_TARGET_PARAMSIZE 50000
enum { enum {
ACTIVE = 0, ACTIVE = 0,
RELOAD = 1, RELOAD = 1,
@@ -153,33 +157,6 @@ static inline void _clear_flag(struct dev_layer *dl, int bit)
dl->flags &= ~(1 << bit); dl->flags &= ~(1 << bit);
} }
static int _pre_list_add(struct pool *mem, struct list *pl, const char *str)
{
struct str_list *sl;
struct list *plh;
if (!str) {
stack;
return 0;
}
/* Already in list? */
list_iterate(plh, pl) {
if (!strcmp(str, list_item(plh, struct str_list)->str))
return 1;
}
if (!(sl = pool_alloc(mem, sizeof(*sl)))) {
stack;
return 0;
}
sl->str = str;
list_add(pl, &sl->list);
return 1;
}
/* /*
* Device layer names are all of the form <vg>-<lv>-<layer>, any * Device layer names are all of the form <vg>-<lv>-<layer>, any
* other hyphens that appear in these names are quoted with yet * other hyphens that appear in these names are quoted with yet
@@ -309,13 +286,16 @@ static struct dm_task *_setup_task(const char *name, const char *uuid,
} }
static int _info_run(const char *name, const char *uuid, struct dm_info *info, static int _info_run(const char *name, const char *uuid, struct dm_info *info,
struct pool *mem, char **uuid_out) int mknodes, struct pool *mem, char **uuid_out)
{ {
int r = 0; int r = 0;
struct dm_task *dmt; struct dm_task *dmt;
const char *u; const char *u;
int dmtask;
if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_INFO))) { dmtask = mknodes ? DM_DEVICE_MKNODES : DM_DEVICE_INFO;
if (!(dmt = _setup_task(name, uuid, 0, dmtask))) {
stack; stack;
return 0; return 0;
} }
@@ -344,15 +324,15 @@ static int _info_run(const char *name, const char *uuid, struct dm_info *info,
return r; return r;
} }
static int _info(const char *name, const char *uuid, struct dm_info *info, static int _info(const char *name, const char *uuid, int mknodes,
struct pool *mem, char **uuid_out) struct dm_info *info, struct pool *mem, char **uuid_out)
{ {
if (uuid && *uuid && _info_run(NULL, uuid, info, mem, uuid_out) if (!mknodes && uuid && *uuid &&
&& info->exists) _info_run(NULL, uuid, info, 0, mem, uuid_out) && info->exists)
return 1; return 1;
if (name) if (name)
return _info_run(name, NULL, info, mem, uuid_out); return _info_run(name, NULL, info, mknodes, mem, uuid_out);
return 0; return 0;
} }
@@ -529,7 +509,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
else else
*percent = 100; *percent = 100;
log_debug("Mirror percent: %f", *percent); log_debug("LV percent: %f", *percent);
r = 1; r = 1;
out: out:
@@ -765,10 +745,10 @@ static int _resume(struct dev_layer *dl)
* Emit a target for a given segment. * Emit a target for a given segment.
* FIXME: tidy this function. * FIXME: tidy this function.
*/ */
static int _emit_target(struct dev_manager *dm, struct dm_task *dmt, static int _emit_target_line(struct dev_manager *dm, struct dm_task *dmt,
struct lv_segment *seg) struct lv_segment *seg, char *params,
size_t paramsize)
{ {
char params[1024];
uint64_t esize = seg->lv->vg->extent_size; uint64_t esize = seg->lv->vg->extent_size;
uint32_t s, start_area = 0u, areas = seg->area_count; uint32_t s, start_area = 0u, areas = seg->area_count;
int w = 0, tw = 0; int w = 0, tw = 0;
@@ -794,7 +774,7 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
target = "linear"; target = "linear";
else if (areas > 1) { else if (areas > 1) {
target = "striped"; target = "striped";
if ((tw = lvm_snprintf(params, sizeof(params), "%u %u ", if ((tw = lvm_snprintf(params, paramsize, "%u %u ",
areas, seg->stripe_size)) < 0) areas, seg->stripe_size)) < 0)
goto error; goto error;
w = tw; w = tw;
@@ -820,8 +800,7 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
break; break;
} }
target = "mirror"; target = "mirror";
if ((tw = lvm_snprintf(params, sizeof(params), if ((tw = lvm_snprintf(params, paramsize, "core 1 %u %u ",
"core 1 %u %u ",
dm->mirror_region_size, areas)) < 0) dm->mirror_region_size, areas)) < 0)
goto error; goto error;
w = tw; w = tw;
@@ -833,11 +812,11 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
if ((seg->area[s].type == AREA_PV && if ((seg->area[s].type == AREA_PV &&
(!seg->area[s].u.pv.pv || !seg->area[s].u.pv.pv->dev)) || (!seg->area[s].u.pv.pv || !seg->area[s].u.pv.pv->dev)) ||
(seg->area[s].type == AREA_LV && !seg->area[s].u.lv.lv)) (seg->area[s].type == AREA_LV && !seg->area[s].u.lv.lv))
tw = lvm_snprintf(params + w, sizeof(params) - w, tw = lvm_snprintf(params + w, paramsize - w,
"%s 0%s", dm->stripe_filler, "%s 0%s", dm->stripe_filler,
trailing_space); trailing_space);
else if (seg->area[s].type == AREA_PV) else if (seg->area[s].type == AREA_PV)
tw = lvm_snprintf(params + w, sizeof(params) - w, tw = lvm_snprintf(params + w, paramsize - w,
"%s %" PRIu64 "%s", "%s %" PRIu64 "%s",
dev_name(seg->area[s].u.pv.pv->dev), dev_name(seg->area[s].u.pv.pv->dev),
(seg->area[s].u.pv.pv->pe_start + (seg->area[s].u.pv.pv->pe_start +
@@ -855,7 +834,7 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
dl->info.major, dl->info.minor); dl->info.major, dl->info.minor);
return 0; return 0;
} }
tw = lvm_snprintf(params + w, sizeof(params) - w, tw = lvm_snprintf(params + w, paramsize - w,
"%s %" PRIu64 "%s", devbuf, "%s %" PRIu64 "%s", devbuf,
esize * seg->area[s].u.lv.le, esize * seg->area[s].u.lv.le,
trailing_space); trailing_space);
@@ -877,7 +856,37 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
return 1; return 1;
error: error:
log_error("Insufficient space in params[] to write target parameters."); log_debug("Insufficient space in params[%" PRIsize_t "] for target "
"parameters.", paramsize);
return -1;
}
static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
struct lv_segment *seg)
{
char *params;
size_t paramsize = 4096;
int ret;
do {
if (!(params = dbg_malloc(paramsize))) {
log_error("Insufficient space for target parameters.");
return 0;
}
ret = _emit_target_line(dm, dmt, seg, params, paramsize);
dbg_free(params);
if (!ret)
stack;
if (ret >= 0)
return ret;
paramsize *= 2;
} while (paramsize < MAX_TARGET_PARAMSIZE);
log_error("Target parameter size too big. Aborting.");
return 0; return 0;
} }
@@ -985,8 +994,8 @@ static int _populate_snapshot(struct dev_manager *dm,
return 0; return 0;
} }
if (snprintf(params, sizeof(params), "%s %s P %d", if (lvm_snprintf(params, sizeof(params), "%s %s P %d",
devbufo, devbufc, s->chunk_size) == -1) { devbufo, devbufc, s->chunk_size) == -1) {
stack; stack;
return 0; return 0;
} }
@@ -1067,7 +1076,7 @@ void dev_manager_destroy(struct dev_manager *dm)
} }
int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv, int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
struct dm_info *info) int mknodes, struct dm_info *info)
{ {
char *name; char *name;
@@ -1083,7 +1092,7 @@ int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
* Try and get some info on this device. * Try and get some info on this device.
*/ */
log_debug("Getting device info for %s", name); log_debug("Getting device info for %s", name);
if (!_info(name, lv->lvid.s, info, NULL, NULL)) { if (!_info(name, lv->lvid.s, mknodes, info, NULL, NULL)) {
stack; stack;
return 0; return 0;
} }
@@ -1162,7 +1171,7 @@ static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
dl->name = name; dl->name = name;
log_debug("Getting device info for %s", dl->name); log_debug("Getting device info for %s", dl->name);
if (!_info(dl->name, dlid, &dl->info, dm->mem, &uuid)) { if (!_info(dl->name, dlid, 0, &dl->info, dm->mem, &uuid)) {
stack; stack;
return NULL; return NULL;
} }
@@ -1270,10 +1279,10 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
for (s = 0; s < seg->area_count; s++) { for (s = 0; s < seg->area_count; s++) {
if (seg->area[s].type != AREA_LV) if (seg->area[s].type != AREA_LV)
continue; continue;
if (!_pre_list_add(dm->mem, &dl->pre_create, if (!str_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem, _build_dlid(dm->mem,
seg->area[s].u.lv. seg->area[s].u.lv.
lv->lvid.s, NULL))) { lv->lvid.s, NULL))) {
stack; stack;
return 0; return 0;
} }
@@ -1296,8 +1305,8 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
_set_flag(dlr, REMOVE); _set_flag(dlr, REMOVE);
/* add the dependency on the real device */ /* add the dependency on the real device */
if (!_pre_list_add(dm->mem, &dl->pre_create, if (!str_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, dlr->dlid))) { pool_strdup(dm->mem, dlr->dlid))) {
stack; stack;
return 0; return 0;
} }
@@ -1330,8 +1339,8 @@ static int _expand_origin_real(struct dev_manager *dm,
_set_flag(dl, TOPLEVEL); _set_flag(dl, TOPLEVEL);
/* add the dependency on the real device */ /* add the dependency on the real device */
if (!_pre_list_add(dm->mem, &dl->pre_create, if (!str_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, real_dlid))) { pool_strdup(dm->mem, real_dlid))) {
stack; stack;
return 0; return 0;
} }
@@ -1378,6 +1387,7 @@ static int _expand_snapshot(struct dev_manager *dm, struct logical_volume *lv,
dl->populate = _populate_vanilla; dl->populate = _populate_vanilla;
_clear_flag(dl, VISIBLE); _clear_flag(dl, VISIBLE);
_clear_flag(dl, TOPLEVEL); _clear_flag(dl, TOPLEVEL);
_set_flag(dl, READWRITE);
cow_dlid = dl->dlid; cow_dlid = dl->dlid;
@@ -1390,21 +1400,21 @@ static int _expand_snapshot(struct dev_manager *dm, struct logical_volume *lv,
_set_flag(dl, TOPLEVEL); _set_flag(dl, TOPLEVEL);
/* add the dependency on the cow device */ /* add the dependency on the cow device */
if (!_pre_list_add(dm->mem, &dl->pre_create, if (!str_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, cow_dlid))) { pool_strdup(dm->mem, cow_dlid))) {
stack; stack;
return 0; return 0;
} }
/* add the dependency on the real origin device */ /* add the dependency on the real origin device */
if (!_pre_list_add(dm->mem, &dl->pre_create, if (!str_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem, s->origin->lvid.s, "real"))) { _build_dlid(dm->mem, s->origin->lvid.s, "real"))) {
stack; stack;
return 0; return 0;
} }
/* add the dependency on the visible origin device */ /* add the dependency on the visible origin device */
if (!_pre_list_add(dm->mem, &dl->pre_suspend, s->origin->lvid.s)) { if (!str_list_add(dm->mem, &dl->pre_suspend, s->origin->lvid.s)) {
stack; stack;
return 0; return 0;
} }
@@ -1589,8 +1599,7 @@ static int _resume_with_deps(struct dev_manager *dm, struct dev_layer *dl)
} }
} }
if (dl->info.exists & !_get_flag(dl, SUSPENDED) && if (dl->info.exists & !_get_flag(dl, SUSPENDED) && !_resume(dl)) {
!_resume(dl)) {
stack; stack;
return 0; return 0;
} }
@@ -1739,8 +1748,8 @@ static int _populate_pre_suspend_lists(struct dev_manager *dm)
continue; continue;
} }
if (!_pre_list_add(dm->mem, &dep->pre_create, if (!str_list_add(dm->mem, &dep->pre_create,
dl->dlid)) { dl->dlid)) {
stack; stack;
return 0; return 0;
} }
@@ -1756,8 +1765,8 @@ static int _populate_pre_suspend_lists(struct dev_manager *dm)
continue; continue;
} }
if (!_pre_list_add(dm->mem, &dep->pre_suspend, if (!str_list_add(dm->mem, &dep->pre_suspend,
dl->dlid)) { dl->dlid)) {
stack; stack;
return 0; return 0;
} }
@@ -2175,6 +2184,24 @@ int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv)
return _action(dm, lv, SUSPEND); return _action(dm, lv, SUSPEND);
} }
int dev_manager_mknodes(const struct logical_volume *lv)
{
char *name;
if (!(name = _build_name(lv->vg->cmd->mem, lv->vg->name,
lv->name, NULL))) {
stack;
return 0;
}
return fs_add_lv(lv, name);
}
int dev_manager_rmnodes(const struct logical_volume *lv)
{
return fs_del_lv(lv);
}
void dev_manager_exit(void) void dev_manager_exit(void)
{ {
dm_lib_exit(); dm_lib_exit();

View File

@@ -28,7 +28,7 @@ void dev_manager_exit(void);
* unsuspended until the snapshot is also created.) * unsuspended until the snapshot is also created.)
*/ */
int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv, int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
struct dm_info *info); int mknodes, struct dm_info *info);
int dev_manager_snapshot_percent(struct dev_manager *dm, int dev_manager_snapshot_percent(struct dev_manager *dm,
struct logical_volume *lv, float *percent); struct logical_volume *lv, float *percent);
int dev_manager_mirror_percent(struct dev_manager *dm, int dev_manager_mirror_percent(struct dev_manager *dm,
@@ -38,6 +38,9 @@ int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv); int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv); int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_mknodes(const struct logical_volume *lv);
int dev_manager_rmnodes(const struct logical_volume *lv);
/* /*
* Put the desired changes into effect. * Put the desired changes into effect.
*/ */

View File

@@ -182,7 +182,9 @@ static int _rm_link(const char *dev_dir, const char *vg_name,
} }
if (lstat(lv_path, &buf) || !S_ISLNK(buf.st_mode)) { if (lstat(lv_path, &buf) || !S_ISLNK(buf.st_mode)) {
log_error("%s not symbolic link - not removing", lv_path); if (errno != ENOENT)
log_error("%s not symbolic link - not removing",
lv_path);
return 0; return 0;
} }
@@ -309,13 +311,13 @@ static int _fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
return _do_fs_op(type, dev_dir, vg_name, lv_name, dev, old_lv_name); return _do_fs_op(type, dev_dir, vg_name, lv_name, dev, old_lv_name);
} }
int fs_add_lv(struct logical_volume *lv, const char *dev) int fs_add_lv(const struct logical_volume *lv, const char *dev)
{ {
return _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name, return _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, ""); dev, "");
} }
int fs_del_lv(struct logical_volume *lv) int fs_del_lv(const struct logical_volume *lv)
{ {
return _fs_op(FS_DEL, lv->vg->cmd->dev_dir, lv->vg->name, lv->name, return _fs_op(FS_DEL, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
"", ""); "", "");

View File

@@ -14,8 +14,8 @@
* up the volume group directory in /dev and the * up the volume group directory in /dev and the
* symbolic links to the dm device. * symbolic links to the dm device.
*/ */
int fs_add_lv(struct logical_volume *lv, const char *dev); int fs_add_lv(const struct logical_volume *lv, const char *dev);
int fs_del_lv(struct logical_volume *lv); int fs_del_lv(const struct logical_volume *lv);
int fs_rename_lv(struct logical_volume *lv, int fs_rename_lv(struct logical_volume *lv,
const char *dev, const char *old_name); const char *dev, const char *old_name);
void fs_unlock(void); void fs_unlock(void);

22
lib/cache/lvmcache.c vendored
View File

@@ -13,6 +13,7 @@
#include "metadata.h" #include "metadata.h"
#include "filter.h" #include "filter.h"
#include "memlock.h" #include "memlock.h"
#include "str_list.h"
static struct hash_table *_pvid_hash = NULL; static struct hash_table *_pvid_hash = NULL;
static struct hash_table *_vgid_hash = NULL; static struct hash_table *_vgid_hash = NULL;
@@ -207,31 +208,22 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan) struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
{ {
struct list *vgih, *vgnames; struct list *vgnames;
struct str_list *sl; struct lvmcache_vginfo *vgi;
lvmcache_label_scan(cmd, full_scan); lvmcache_label_scan(cmd, full_scan);
if (!(vgnames = pool_alloc(cmd->mem, sizeof(struct list)))) { if (!(vgnames = str_list_create(cmd->mem))) {
log_error("vgnames list allocation failed"); log_error("vgnames list allocation failed");
return NULL; return NULL;
} }
list_init(vgnames); list_iterate_items(vgi, &_vginfos) {
if (!str_list_add(cmd->mem, vgnames,
list_iterate(vgih, &_vginfos) { pool_strdup(cmd->mem, vgi->vgname))) {
if (!(sl = pool_alloc(cmd->mem, sizeof(*sl)))) {
log_error("strlist allocation failed"); log_error("strlist allocation failed");
return NULL; return NULL;
} }
if (!(sl->str = pool_strdup(cmd->mem,
list_item(vgih,
struct lvmcache_vginfo)->
vgname))) {
log_error("vgname allocation failed");
return NULL;
}
list_add(vgnames, &sl->list);
} }
return vgnames; return vgnames;

View File

@@ -7,9 +7,9 @@
#ifndef _LVM_ERRORS_H #ifndef _LVM_ERRORS_H
#define _LVM_ERRORS_H #define _LVM_ERRORS_H
#define EINVALID_CMD_LINE 1 #define ECMD_PROCESSED 1
#define ENO_SUCH_CMD 3 #define ENO_SUCH_CMD 2
#define ECMD_PROCESSED 4 #define EINVALID_CMD_LINE 3
#define ECMD_FAILED 5 #define ECMD_FAILED 5
#endif #endif

View File

@@ -385,17 +385,25 @@ static int _write_config(struct config_node *n, FILE *fp, int level)
int write_config_file(struct config_tree *cf, const char *file) int write_config_file(struct config_tree *cf, const char *file)
{ {
int r = 1; int r = 1;
FILE *fp = fopen(file, "w"); FILE *fp;
if (!fp) {
if (!file) {
fp = stdout;
file = "stdout";
} else if (!(fp = fopen(file, "w"))) {
log_sys_error("open", file); log_sys_error("open", file);
return 0; return 0;
} }
log_verbose("Dumping configuration to %s", file);
if (!_write_config(cf->root, fp, 0)) { if (!_write_config(cf->root, fp, 0)) {
stack; log_error("Failure while writing configuration");
r = 0; r = 0;
} }
fclose(fp);
if (fp != stdout)
fclose(fp);
return r; return r;
} }
@@ -502,7 +510,7 @@ static struct config_value *_value(struct parser *p)
static struct config_value *_type(struct parser *p) static struct config_value *_type(struct parser *p)
{ {
/* [0-9]+ | [0-9]*\.[0-9]* | ".*" */ /* [+-]{0,1}[0-9]+ | [0-9]*\.[0-9]* | ".*" */
struct config_value *v = _create_value(p); struct config_value *v = _create_value(p);
if (!v) if (!v)
@@ -637,6 +645,8 @@ static void _get_token(struct parser *p, int tok_prev)
case '7': case '7':
case '8': case '8':
case '9': case '9':
case '+':
case '-':
if (values_allowed) { if (values_allowed) {
p->te++; p->te++;
while ((p->te != p->fe) && (*p->te)) { while ((p->te != p->fe) && (*p->te)) {

View File

@@ -63,26 +63,6 @@ static inline struct list *list_next(struct list *head, struct list *elem)
return (list_end(head, elem) ? NULL : elem->n); return (list_end(head, elem) ? NULL : elem->n);
} }
#define list_iterate(v, head) \
for (v = (head)->n; v != head; v = v->n)
#define list_uniterate(v, head, start) \
for (v = (start)->p; v != head; v = v->p)
#define list_iterate_safe(v, t, head) \
for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
static inline unsigned int list_size(const struct list *head)
{
unsigned int s = 0;
const struct list *v;
list_iterate(v, head)
s++;
return s;
}
#define list_item(v, t) \ #define list_item(v, t) \
((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list)) ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list))
@@ -96,4 +76,28 @@ static inline unsigned int list_size(const struct list *head)
/* Given a known element in a known structure, locate the list head */ /* Given a known element in a known structure, locate the list head */
#define list_head(v, t, e) struct_field(v, t, e, list) #define list_head(v, t, e) struct_field(v, t, e, list)
#define list_iterate(v, head) \
for (v = (head)->n; v != head; v = v->n)
#define list_uniterate(v, head, start) \
for (v = (start)->p; v != head; v = v->p)
#define list_iterate_safe(v, t, head) \
for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
#define list_iterate_items(v, head) \
for (v = list_item((head)->n, typeof(*v)); &v->list != (head); \
v = list_item(v->list.n, typeof(*v)))
static inline unsigned int list_size(const struct list *head)
{
unsigned int s = 0;
const struct list *v;
list_iterate(v, head)
s++;
return s;
}
#endif #endif

80
lib/datastruct/str_list.c Normal file
View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2003 Sistina Software
*
* This file is released under the LGPL.
*/
#include "lib.h"
#include "str_list.h"
struct list *str_list_create(struct pool *mem)
{
struct list *sl;
if (!(sl = pool_alloc(mem, sizeof(struct list)))) {
stack;
return NULL;
}
list_init(sl);
return sl;
}
int str_list_add(struct pool *mem, struct list *sll, const char *str)
{
struct str_list *sln;
if (!str) {
stack;
return 0;
}
/* Already in list? */
if (str_list_match_item(sll, str))
return 1;
if (!(sln = pool_alloc(mem, sizeof(*sln)))) {
stack;
return 0;
}
sln->str = str;
list_add(sll, &sln->list);
return 1;
}
int str_list_del(struct list *sll, const char *str)
{
struct list *slh, *slht;
list_iterate_safe(slh, slht, sll) {
if (!strcmp(str, list_item(slh, struct str_list)->str))
list_del(slh);
}
return 1;
}
int str_list_match_item(struct list *sll, const char *str)
{
struct str_list *sl;
list_iterate_items(sl, sll)
if (!strcmp(str, sl->str))
return 1;
return 0;
}
int str_list_match_list(struct list *sll, struct list *sll2)
{
struct str_list *sl;
list_iterate_items(sl, sll)
if (str_list_match_item(sll2, sl->str))
return 1;
return 0;
}

18
lib/datastruct/str_list.h Normal file
View File

@@ -0,0 +1,18 @@
/*
* Copyright (C) 2003 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*/
#ifndef _LVM_STR_LIST_H
#define _LVM_STR_LIST_H
#include "pool.h"
struct list *str_list_create(struct pool *mem);
int str_list_add(struct pool *mem, struct list *sll, const char *str);
int str_list_del(struct list *sll, const char *str);
int str_list_match_item(struct list *sll, const char *str);
int str_list_match_list(struct list *sll, struct list *sll2);
#endif

View File

@@ -406,11 +406,22 @@ static inline void _check_for_open_devices(void)
void dev_cache_exit(void) void dev_cache_exit(void)
{ {
_check_for_open_devices();
pool_destroy(_cache.mem);
if (_cache.names) if (_cache.names)
_check_for_open_devices();
if (_cache.mem) {
pool_destroy(_cache.mem);
_cache.mem = NULL;
}
if (_cache.names) {
hash_destroy(_cache.names); hash_destroy(_cache.names);
_cache.names = NULL;
}
_cache.devices = NULL;
_cache.has_scanned = 0;
list_init(&_cache.dirs);
} }
int dev_cache_add_dir(const char *path) int dev_cache_add_dir(const char *path)

View File

@@ -30,11 +30,15 @@
# define BLKGETSIZE64 DKIOCGETBLOCKCOUNT # define BLKGETSIZE64 DKIOCGETBLOCKCOUNT
# define BLKFLSBUF DKIOCSYNCHRONIZECACHE # define BLKFLSBUF DKIOCSYNCHRONIZECACHE
# define BLKSIZE_SHIFT 0 # define BLKSIZE_SHIFT 0
#endif
#ifdef O_DIRECT_SUPPORT
# ifndef O_DIRECT # ifndef O_DIRECT
# define O_DIRECT 0 # error O_DIRECT support configured but O_DIRECT definition not found in headers
# endif # endif
#endif #endif
/* FIXME Use _llseek for 64-bit /* FIXME Use _llseek for 64-bit
_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh); _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh);
if (_llseek((unsigned) fd, (ulong) (offset >> 32), (ulong) (offset & 0xFFFFFFFF), &pos, SEEK_SET) < 0) { if (_llseek((unsigned) fd, (ulong) (offset >> 32), (ulong) (offset & 0xFFFFFFFF), &pos, SEEK_SET) < 0) {
@@ -151,7 +155,7 @@ static int _aligned_io(struct device_area *where, void *buffer,
} }
if (!block_size) if (!block_size)
block_size = SECTOR_SIZE * 2; block_size = getpagesize();
_widen_region(block_size, where, &widened); _widen_region(block_size, where, &widened);
@@ -284,8 +288,10 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
return 0; return 0;
} }
#ifdef O_DIRECT_SUPPORT
if (direct) if (direct)
flags |= O_DIRECT; flags |= O_DIRECT;
#endif
if ((dev->fd = open(name, flags, 0777)) < 0) { if ((dev->fd = open(name, flags, 0777)) < 0) {
log_sys_error("open", name); log_sys_error("open", name);
@@ -302,7 +308,8 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
dev->fd = -1; dev->fd = -1;
return 0; return 0;
} }
#if !O_DIRECT
#ifndef O_DIRECT_SUPPORT
if (!(dev->flags & DEV_REGULAR)) if (!(dev->flags & DEV_REGULAR))
dev_flush(dev); dev_flush(dev);
#endif #endif
@@ -346,25 +353,36 @@ static void _close(struct device *dev)
} }
} }
int dev_close(struct device *dev) static int _dev_close(struct device *dev, int immediate)
{ {
if (dev->fd < 0) { if (dev->fd < 0) {
log_error("Attempt to close device '%s' " log_error("Attempt to close device '%s' "
"which is not open.", dev_name(dev)); "which is not open.", dev_name(dev));
return 0; return 0;
} }
#if !O_DIRECT
#ifndef O_DIRECT_SUPPORT
if (dev->flags & DEV_ACCESSED_W) if (dev->flags & DEV_ACCESSED_W)
dev_flush(dev); dev_flush(dev);
#endif #endif
/* FIXME lookup device in cache to get vgname and see if it's locked? */ /* FIXME lookup device in cache to get vgname and see if it's locked? */
if (--dev->open_count < 1 && !vgs_locked()) if (--dev->open_count < 1 && (immediate || !vgs_locked()))
_close(dev); _close(dev);
return 1; return 1;
} }
int dev_close(struct device *dev)
{
return _dev_close(dev, 0);
}
int dev_close_immediate(struct device *dev)
{
return _dev_close(dev, 1);
}
void dev_close_all(void) void dev_close_all(void)
{ {
struct list *doh, *doht; struct list *doh, *doht;
@@ -406,7 +424,7 @@ int dev_append(struct device *dev, size_t len, void *buffer)
r = dev_write(dev, dev->end, len, buffer); r = dev_write(dev, dev->end, len, buffer);
dev->end += (uint64_t) len; dev->end += (uint64_t) len;
#if !O_DIRECT #ifndef O_DIRECT_SUPPORT
dev_flush(dev); dev_flush(dev);
#endif #endif
return r; return r;
@@ -455,6 +473,8 @@ int dev_zero(struct device *dev, uint64_t offset, size_t len)
len -= s; len -= s;
if (!len) if (!len)
break; break;
offset += s;
} }
dev->flags |= DEV_ACCESSED_W; dev->flags |= DEV_ACCESSED_W;

View File

@@ -54,6 +54,7 @@ int dev_open(struct device *dev);
int dev_open_quiet(struct device *dev); int dev_open_quiet(struct device *dev);
int dev_open_flags(struct device *dev, int flags, int append, int quiet); int dev_open_flags(struct device *dev, int flags, int append, int quiet);
int dev_close(struct device *dev); int dev_close(struct device *dev);
int dev_close_immediate(struct device *dev);
void dev_close_all(void); void dev_close_all(void);
static inline int dev_fd(struct device *dev) static inline int dev_fd(struct device *dev)

View File

@@ -390,6 +390,9 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
snap = list_item(slh, struct snapshot_list)->snapshot; snap = list_item(slh, struct snapshot_list)->snapshot;
snap_active = lv_snapshot_percent(snap->cow, snap_active = lv_snapshot_percent(snap->cow,
&snap_percent); &snap_percent);
if (!snap_active || snap_percent < 0 ||
snap_percent >= 100)
snap_active = 0;
log_print(" %s%s/%s [%s]", log_print(" %s%s/%s [%s]",
lv->vg->cmd->dev_dir, lv->vg->name, lv->vg->cmd->dev_dir, lv->vg->name,
snap->cow->name, snap->cow->name,
@@ -398,6 +401,8 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
snap = NULL; snap = NULL;
} else if ((snap = find_cow(lv))) { } else if ((snap = find_cow(lv))) {
snap_active = lv_snapshot_percent(lv, &snap_percent); snap_active = lv_snapshot_percent(lv, &snap_percent);
if (!snap_active || snap_percent < 0 || snap_percent >= 100)
snap_active = 0;
log_print("LV snapshot status %s destination for %s%s/%s", log_print("LV snapshot status %s destination for %s%s/%s",
(snap_active > 0) ? "active" : "INACTIVE", (snap_active > 0) ? "active" : "INACTIVE",
lv->vg->cmd->dev_dir, lv->vg->name, lv->vg->cmd->dev_dir, lv->vg->name,

View File

@@ -57,6 +57,7 @@ static const device_info_t device_info[] = {
{"cciss", 16}, /* Compaq CCISS array */ {"cciss", 16}, /* Compaq CCISS array */
{"ubd", 16}, /* User-mode virtual block device */ {"ubd", 16}, /* User-mode virtual block device */
{"ataraid", 16}, /* ATA Raid */ {"ataraid", 16}, /* ATA Raid */
{"drbd", 16}, /* Distributed Replicated Block Device */
{NULL, 0} {NULL, 0}
}; };

View File

@@ -22,7 +22,7 @@ TARGETS=liblvm2format1.so
include ../../make.tmpl include ../../make.tmpl
install: libformat1.so install: liblvm2format1.so
$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \ $(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/liblvm2format1.so.$(LIB_VERSION) $(libdir)/liblvm2format1.so.$(LIB_VERSION)
$(LN_S) -f liblvm2format1.so.$(LIB_VERSION) $(libdir)/liblvm2format1.so $(LN_S) -f liblvm2format1.so.$(LIB_VERSION) $(libdir)/liblvm2format1.so

View File

@@ -255,21 +255,21 @@ static int _read_extents(struct disk_list *data)
/* /*
* If exported, remove "PV_EXP" from end of VG name * If exported, remove "PV_EXP" from end of VG name
*/ */
static void _munge_exported_vg(struct disk_list *data) void munge_exported_vg(struct pv_disk *pvd)
{ {
int l; int l;
size_t s; size_t s;
/* Return if PV not in a VG or VG not exported */ /* Return if PV not in a VG */
if ((!*data->pvd.vg_name) || !(data->vgd.vg_status & VG_EXPORTED)) if ((!*pvd->vg_name))
return; return;
l = strlen(data->pvd.vg_name); l = strlen(pvd->vg_name);
s = sizeof(EXPORTED_TAG); s = sizeof(EXPORTED_TAG);
if (!strncmp(data->pvd.vg_name + l - s + 1, EXPORTED_TAG, s)) if (!strncmp(pvd->vg_name + l - s + 1, EXPORTED_TAG, s)) {
data->pvd.vg_name[l - s + 1] = '\0'; pvd->vg_name[l - s + 1] = '\0';
pvd->pv_status |= VG_EXPORTED;
data->pvd.pv_status |= VG_EXPORTED; }
} }
static struct disk_list *__read_disk(const struct format_type *fmt, static struct disk_list *__read_disk(const struct format_type *fmt,
@@ -295,6 +295,9 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
goto bad; goto bad;
} }
/* If VG is exported, set VG name back to the real name */
munge_exported_vg(&dl->pvd);
if (!(info = lvmcache_add(fmt->labeller, dl->pvd.pv_uuid, dev, if (!(info = lvmcache_add(fmt->labeller, dl->pvd.pv_uuid, dev,
dl->pvd.vg_name, NULL))) dl->pvd.vg_name, NULL)))
stack; stack;
@@ -321,9 +324,6 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
goto bad; goto bad;
} }
/* If VG is exported, set VG name back to the real name */
_munge_exported_vg(dl);
/* Update VG cache with what we found */ /* Update VG cache with what we found */
/* vgcache_add(dl->pvd.vg_name, dl->vgd.vg_uuid, dev, fmt); */ /* vgcache_add(dl->pvd.vg_name, dl->vgd.vg_uuid, dev, fmt); */

View File

@@ -15,6 +15,8 @@
#define MAX_LV 256 #define MAX_LV 256
#define MAX_VG 99 #define MAX_VG 99
#define LVM_BLK_MAJOR 58
#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */ #define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */
#define MIN_PE_SIZE (8192L >> SECTOR_SHIFT) /* 8 KB in sectors */ #define MIN_PE_SIZE (8192L >> SECTOR_SHIFT) /* 8 KB in sectors */
#define MAX_PE_SIZE (16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L) #define MAX_PE_SIZE (16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L)
@@ -224,6 +226,7 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg);
void export_numbers(struct list *pvds, struct volume_group *vg); void export_numbers(struct list *pvds, struct volume_group *vg);
void export_pv_act(struct list *pvds); void export_pv_act(struct list *pvds);
void munge_exported_vg(struct pv_disk *pvd);
/* blech */ /* blech */
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter, int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,

View File

@@ -16,6 +16,8 @@
#include "lvm1-label.h" #include "lvm1-label.h"
#include "format1.h" #include "format1.h"
#define FMT_LVM1_NAME "lvm1"
/* VG consistency checks */ /* VG consistency checks */
static int _check_vgs(struct list *pvs, int *partial) static int _check_vgs(struct list *pvs, int *partial)
{ {
@@ -75,9 +77,9 @@ static int _check_vgs(struct list *pvs, int *partial)
} }
/* On entry to fn, list known to be non-empty */ /* On entry to fn, list known to be non-empty */
if (pv_count != dl->vgd.pv_cur) { if (pv_count != first->vgd.pv_cur) {
log_error("%d PV(s) found for VG %s: expected %d", log_error("%d PV(s) found for VG %s: expected %d",
pv_count, dl->pvd.vg_name, dl->vgd.pv_cur); pv_count, first->pvd.vg_name, first->vgd.pv_cur);
if (!partial_mode()) if (!partial_mode())
return 0; return 0;
*partial = 1; *partial = 1;
@@ -332,32 +334,12 @@ static int _pv_setup(const struct format_type *fmt,
return 1; return 1;
} }
static uint32_t _find_free_lvnum(struct logical_volume *lv)
{
int lvnum_used[MAX_LV];
uint32_t i = 0;
struct list *lvh;
struct lv_list *lvl;
memset(&lvnum_used, 0, sizeof(lvnum_used));
list_iterate(lvh, &lv->vg->lvs) {
lvl = list_item(lvh, struct lv_list);
lvnum_used[lvnum_from_lvid(&lvl->lv->lvid)] = 1;
}
while (lvnum_used[i])
i++;
return i;
}
static int _lv_setup(struct format_instance *fid, struct logical_volume *lv) static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
{ {
uint64_t max_size = UINT_MAX; uint64_t max_size = UINT_MAX;
if (!*lv->lvid.s) if (!*lv->lvid.s)
lvid_from_lvnum(&lv->lvid, &lv->vg->id, _find_free_lvnum(lv)); lvid_from_lvnum(&lv->lvid, &lv->vg->id, find_free_lvnum(lv));
if (lv->le_count > MAX_LE_TOTAL) { if (lv->le_count > MAX_LE_TOTAL) {
log_error("logical volumes cannot contain more than " log_error("logical volumes cannot contain more than "
@@ -440,10 +422,10 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
static int _vg_setup(struct format_instance *fid, struct volume_group *vg) static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
{ {
/* just check max_pv and max_lv */ /* just check max_pv and max_lv */
if (vg->max_lv >= MAX_LV) if (!vg->max_lv || vg->max_lv >= MAX_LV)
vg->max_lv = MAX_LV - 1; vg->max_lv = MAX_LV - 1;
if (vg->max_pv >= MAX_PV) if (!vg->max_pv || vg->max_pv >= MAX_PV)
vg->max_pv = MAX_PV - 1; vg->max_pv = MAX_PV - 1;
if (vg->extent_size > MAX_PE_SIZE || vg->extent_size < MIN_PE_SIZE) { if (vg->extent_size > MAX_PE_SIZE || vg->extent_size < MIN_PE_SIZE) {
@@ -548,7 +530,7 @@ struct format_type *init_format(struct cmd_context *cmd)
fmt->ops = &_format1_ops; fmt->ops = &_format1_ops;
fmt->name = FMT_LVM1_NAME; fmt->name = FMT_LVM1_NAME;
fmt->alias = NULL; fmt->alias = NULL;
fmt->features = 0; fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE;
fmt->private = NULL; fmt->private = NULL;
if (!(fmt->labeller = lvm1_labeller_create(fmt))) { if (!(fmt->labeller = lvm1_labeller_create(fmt))) {

View File

@@ -9,8 +9,6 @@
#include "metadata.h" #include "metadata.h"
#define FMT_LVM1_NAME "lvm1"
#ifdef LVM1_INTERNAL #ifdef LVM1_INTERNAL
struct format_type *init_lvm1_format(struct cmd_context *cmd); struct format_type *init_lvm1_format(struct cmd_context *cmd);
#endif #endif

View File

@@ -339,6 +339,8 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
if (lv->status & FIXED_MINOR) { if (lv->status & FIXED_MINOR) {
lvd->lv_status |= LV_PERSISTENT_MINOR; lvd->lv_status |= LV_PERSISTENT_MINOR;
lvd->lv_dev = MKDEV(lv->major, lv->minor); lvd->lv_dev = MKDEV(lv->major, lv->minor);
} else {
lvd->lv_dev = MKDEV(LVM_BLK_MAJOR, lvnum_from_lvid(&lv->lvid));
} }
lvd->lv_read_ahead = lv->read_ahead; lvd->lv_read_ahead = lv->read_ahead;

View File

@@ -9,6 +9,7 @@
#include "hash.h" #include "hash.h"
#include "pool.h" #include "pool.h"
#include "disk-rep.h" #include "disk-rep.h"
#include "lv_alloc.h"
/* /*
* After much thought I have decided it is easier, * After much thought I have decided it is easier,
@@ -191,26 +192,13 @@ static int _check_maps_are_complete(struct hash_table *maps)
return 1; return 1;
} }
static struct lv_segment *_alloc_seg(struct pool *mem, uint32_t stripes)
{
struct lv_segment *seg;
uint32_t len = sizeof(*seg) + (stripes * sizeof(seg->area[0]));
if (!(seg = pool_zalloc(mem, len))) {
stack;
return NULL;
}
return seg;
}
static int _read_linear(struct pool *mem, struct lv_map *lvm) static int _read_linear(struct pool *mem, struct lv_map *lvm)
{ {
uint32_t le = 0; uint32_t le = 0;
struct lv_segment *seg; struct lv_segment *seg;
while (le < lvm->lv->le_count) { while (le < lvm->lv->le_count) {
seg = _alloc_seg(mem, 1); seg = alloc_lv_segment(mem, 1);
seg->lv = lvm->lv; seg->lv = lvm->lv;
seg->type = SEG_STRIPED; seg->type = SEG_STRIPED;
@@ -276,7 +264,7 @@ static int _read_stripes(struct pool *mem, struct lv_map *lvm)
len = lvm->lv->le_count / lvm->stripes; len = lvm->lv->le_count / lvm->stripes;
while (le < len) { while (le < len) {
if (!(seg = _alloc_seg(mem, lvm->stripes))) { if (!(seg = alloc_lv_segment(mem, lvm->stripes))) {
stack; stack;
return 0; return 0;
} }

View File

@@ -51,8 +51,11 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
struct pv_disk *pvd = (struct pv_disk *) buf; struct pv_disk *pvd = (struct pv_disk *) buf;
struct lvmcache_info *info; struct lvmcache_info *info;
if (!(info = lvmcache_add(l, pvd->pv_uuid, dev, pvd->vg_name, NULL))) munge_exported_vg(pvd);
if (!(info = lvmcache_add(l, pvd->pv_uuid, dev, pvd->vg_name, NULL))) {
stack;
return 0; return 0;
}
*label = info->label; *label = info->label;
info->device_size = xlate32(pvd->pv_size) << SECTOR_SHIFT; info->device_size = xlate32(pvd->pv_size) << SECTOR_SHIFT;

View File

@@ -50,7 +50,7 @@ struct archive_file {
/* /*
* Extract vg name and version number from a filename. * Extract vg name and version number from a filename.
*/ */
static int _split_vg(const char *filename, char *vg, size_t vg_size, static int _split_vg(const char *filename, char *vgname, size_t vg_size,
uint32_t *ix) uint32_t *ix)
{ {
size_t len, vg_len; size_t len, vg_len;
@@ -74,8 +74,8 @@ static int _split_vg(const char *filename, char *vg, size_t vg_size,
if (vg_len + 1 > vg_size) if (vg_len + 1 > vg_size)
return 0; return 0;
strncpy(vg, filename, vg_len); strncpy(vgname, filename, vg_len);
vg[vg_len] = '\0'; vgname[vg_len] = '\0';
return 1; return 1;
} }
@@ -121,10 +121,10 @@ static char *_join(struct pool *mem, const char *dir, const char *name)
* Returns a list of archive_files. * Returns a list of archive_files.
*/ */
static struct list *_scan_archive(struct pool *mem, static struct list *_scan_archive(struct pool *mem,
const char *vg, const char *dir) const char *vgname, const char *dir)
{ {
int i, count, ix; int i, count, ix;
char vg_name[64], *path; char vgname_found[64], *path;
struct dirent **dirent; struct dirent **dirent;
struct archive_file *af; struct archive_file *af;
struct list *results; struct list *results;
@@ -148,12 +148,12 @@ static struct list *_scan_archive(struct pool *mem,
continue; continue;
/* check the name is the correct format */ /* check the name is the correct format */
if (!_split_vg(dirent[i]->d_name, vg_name, sizeof(vg_name), if (!_split_vg(dirent[i]->d_name, vgname_found,
&ix)) sizeof(vgname_found), &ix))
continue; continue;
/* is it the vg we're interested in ? */ /* is it the vg we're interested in ? */
if (strcmp(vg, vg_name)) if (strcmp(vgname, vgname_found))
continue; continue;
if (!(path = _join(mem, dir, dirent[i]->d_name))) { if (!(path = _join(mem, dir, dirent[i]->d_name))) {
@@ -304,7 +304,8 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
char *desc; char *desc;
void *context; void *context;
log_print("path:\t\t%s", af->path); log_print(" ");
log_print("File:\t\t%s", af->path);
if (!(context = create_text_context(cmd, af->path, NULL)) || if (!(context = create_text_context(cmd, af->path, NULL)) ||
!(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL, !(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
@@ -324,34 +325,50 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
return; return;
} }
log_print("description:\t%s", desc ? desc : "<No description>"); log_print("VG name: \t%s", vg->name);
log_print("time:\t\t%s", ctime(&when)); log_print("Description:\t%s", desc ? desc : "<No description>");
log_print("Backup Time:\t%s", ctime(&when));
pool_free(cmd->mem, vg); pool_free(cmd->mem, vg);
tf->fmt->ops->destroy_instance(tf); tf->fmt->ops->destroy_instance(tf);
} }
int archive_list(struct cmd_context *cmd, const char *dir, const char *vg) int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
{ {
struct list *archives, *ah; struct list *archives, *ah;
struct archive_file *af; struct archive_file *af;
if (!(archives = _scan_archive(cmd->mem, vg, dir))) { if (!(archives = _scan_archive(cmd->mem, vgname, dir))) {
log_err("Couldn't scan the archive directory (%s).", dir); log_err("Couldn't scan the archive directory (%s).", dir);
return 0; return 0;
} }
if (list_empty(archives)) if (list_empty(archives))
log_print("No archives found."); log_print("No archives found in %s.", dir);
list_iterate(ah, archives) { list_iterate(ah, archives) {
af = list_item(ah, struct archive_file); af = list_item(ah, struct archive_file);
_display_archive(cmd, af); _display_archive(cmd, af);
log_print(" ");
} }
pool_free(cmd->mem, archives); pool_free(cmd->mem, archives);
return 1; return 1;
} }
int backup_list(struct cmd_context *cmd, const char *dir, const char *vgname)
{
struct archive_file af;
if (!(af.path = _join(cmd->mem, dir, vgname))) {
stack;
return 0;
}
if (path_exists(af.path))
_display_archive(cmd, &af);
return 1;
}

View File

@@ -321,7 +321,6 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
_inc_indent(f); _inc_indent(f);
list_iterate(pvh, &vg->pvs) { list_iterate(pvh, &vg->pvs) {
pv = list_item(pvh, struct pv_list)->pv; pv = list_item(pvh, struct pv_list)->pv;
if (!(name = _get_pv_name(f, pv))) { if (!(name = _get_pv_name(f, pv))) {
@@ -522,7 +521,7 @@ static int _print_snapshots(struct formatter *f, struct volume_group *vg)
static int _print_lvs(struct formatter *f, struct volume_group *vg) static int _print_lvs(struct formatter *f, struct volume_group *vg)
{ {
struct list *lvh, *segh; struct list *lvh;
struct logical_volume *lv; struct logical_volume *lv;
struct lv_segment *seg; struct lv_segment *seg;
char buffer[256]; char buffer[256];
@@ -571,9 +570,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
f->nl(f); f->nl(f);
seg_count = 1; seg_count = 1;
list_iterate(segh, &lv->segments) { list_iterate_items(seg, &lv->segments) {
seg = list_item(segh, struct lv_segment);
if (!_print_segment(f, vg, seg_count++, seg)) { if (!_print_segment(f, vg, seg_count++, seg)) {
stack; stack;
return 0; return 0;

View File

@@ -63,23 +63,6 @@ static struct flag *_get_flags(int type)
return NULL; return NULL;
} }
static int _emit(char **buffer, size_t *size, const char *fmt, ...)
{
int n;
va_list ap;
va_start(ap, fmt);
n = vsnprintf(*buffer, *size, fmt, ap);
va_end(ap);
if (n < 0 || (n == *size))
return 0;
*buffer += n;
*size -= n;
return 1;
}
/* /*
* Converts a bitset to an array of string values, * Converts a bitset to an array of string values,
* using one of the tables defined at the top of * using one of the tables defined at the top of
@@ -95,27 +78,27 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size)
return 0; return 0;
} }
if (!_emit(&buffer, &size, "[")) if (!emit_to_buffer(&buffer, &size, "["))
return 0; return 0;
for (f = 0; flags[f].mask; f++) { for (f = 0; flags[f].mask; f++) {
if (status & flags[f].mask) { if (status & flags[f].mask) {
if (!first) { if (!first) {
if (!_emit(&buffer, &size, ", ")) if (!emit_to_buffer(&buffer, &size, ", "))
return 0; return 0;
} else } else
first = 0; first = 0;
if (!_emit(&buffer, &size, "\"%s\"", if (!emit_to_buffer(&buffer, &size, "\"%s\"",
flags[f].description)) flags[f].description))
return 0; return 0;
status &= ~flags[f].mask; status &= ~flags[f].mask;
} }
} }
if (!_emit(&buffer, &size, "]")) if (!emit_to_buffer(&buffer, &size, "]"))
return 0; return 0;
if (status) if (status)

View File

@@ -28,6 +28,9 @@
#include <dirent.h> #include <dirent.h>
#include <ctype.h> #include <ctype.h>
#define FMT_TEXT_NAME "lvm2"
#define FMT_TEXT_ALIAS "text"
static struct format_instance *_create_text_instance(const struct format_type static struct format_instance *_create_text_instance(const struct format_type
*fmt, const char *vgname, *fmt, const char *vgname,
void *context); void *context);
@@ -889,6 +892,17 @@ static int _mda_setup(const struct format_type *fmt,
/* Place mda straight after label area at start of disk */ /* Place mda straight after label area at start of disk */
start1 = LABEL_SCAN_SIZE; start1 = LABEL_SCAN_SIZE;
/* Ensure it's not going to be bigger than the disk! */
if (mda_size1 > disk_size) {
log_print("Warning: metadata area fills disk %s",
dev_name(pv->dev));
/* Leave some free space for rounding */
/* Avoid empty data area as could cause tools problems */
mda_size1 = disk_size - start1 - alignment * 2;
/* Only have 1 mda in this case */
pvmetadatacopies = 1;
}
/* Round up to PE_ALIGN boundary */ /* Round up to PE_ALIGN boundary */
mda_adjustment = (mda_size1 + start1) % alignment; mda_adjustment = (mda_size1 + start1) % alignment;
if (mda_adjustment) if (mda_adjustment)

View File

@@ -11,9 +11,6 @@
#include "metadata.h" #include "metadata.h"
#include "pool.h" #include "pool.h"
#define FMT_TEXT_NAME "lvm2"
#define FMT_TEXT_ALIAS "text"
/* /*
* Archives a vg config. 'retain_days' is the minimum number of * Archives a vg config. 'retain_days' is the minimum number of
* days that an archive file must be held for. 'min_archives' is * days that an archive file must be held for. 'min_archives' is
@@ -27,7 +24,8 @@ int archive_vg(struct volume_group *vg,
/* /*
* Displays a list of vg backups in a particular archive directory. * Displays a list of vg backups in a particular archive directory.
*/ */
int archive_list(struct cmd_context *cmd, const char *dir, const char *vg); int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname);
int backup_list(struct cmd_context *cmd, const char *dir, const char *vgname);
/* /*
* The text format can read and write a volume_group to a file. * The text format can read and write a volume_group to a file.

View File

@@ -12,6 +12,7 @@
#include "hash.h" #include "hash.h"
#include "toolcontext.h" #include "toolcontext.h"
#include "lvmcache.h" #include "lvmcache.h"
#include "lv_alloc.h"
typedef int (*section_fn) (struct format_instance * fid, struct pool * mem, typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
struct volume_group * vg, struct config_node * pvn, struct volume_group * vg, struct config_node * pvn,
@@ -279,9 +280,8 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
} }
} }
if (!(seg = pool_zalloc(mem, sizeof(*seg) + if (!(seg = alloc_lv_segment(mem, area_count))) {
(sizeof(seg->area[0]) * area_count)))) { log_error("Segment allocation failed");
stack;
return 0; return 0;
} }

View File

@@ -56,8 +56,8 @@ static int _write(struct label *label, char *buf)
} }
/* NULL-termination */ /* NULL-termination */
pvh_dlocn_xl->offset = xlate64(0); pvh_dlocn_xl->offset = xlate64(UINT64_C(0));
pvh_dlocn_xl->size = xlate64(0); pvh_dlocn_xl->size = xlate64(UINT64_C(0));
pvh_dlocn_xl++; pvh_dlocn_xl++;
/* List of metadata area header locations */ /* List of metadata area header locations */
@@ -74,8 +74,8 @@ static int _write(struct label *label, char *buf)
} }
/* NULL-termination */ /* NULL-termination */
pvh_dlocn_xl->offset = xlate64(0); pvh_dlocn_xl->offset = xlate64(UINT64_C(0));
pvh_dlocn_xl->size = xlate64(0); pvh_dlocn_xl->size = xlate64(UINT64_C(0));
return 1; return 1;
} }

View File

@@ -280,6 +280,11 @@ int label_write(struct device *dev, struct label *label)
struct label_header *lh = (struct label_header *) buf; struct label_header *lh = (struct label_header *) buf;
int r = 1; int r = 1;
if (!label->labeller->ops->write) {
log_err("Label handler does not support label writes");
return 0;
}
if ((LABEL_SIZE + (label->sector << SECTOR_SHIFT)) > LABEL_SCAN_SIZE) { if ((LABEL_SIZE + (label->sector << SECTOR_SHIFT)) > LABEL_SCAN_SIZE) {
log_error("Label sector %" PRIu64 " beyond range (%ld)", log_error("Label sector %" PRIu64 " beyond range (%ld)",
label->sector, LABEL_SCAN_SECTORS); label->sector, LABEL_SCAN_SECTORS);
@@ -292,8 +297,10 @@ int label_write(struct device *dev, struct label *label)
lh->sector_xl = xlate64(label->sector); lh->sector_xl = xlate64(label->sector);
lh->offset_xl = xlate32(sizeof(*lh)); lh->offset_xl = xlate32(sizeof(*lh));
if (!label->labeller->ops->write(label, buf)) if (!label->labeller->ops->write(label, buf)) {
stack;
return 0; return 0;
}
lh->crc_xl = xlate32(calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE - lh->crc_xl = xlate32(calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE -
((void *) &lh->offset_xl - (void *) lh))); ((void *) &lh->offset_xl - (void *) lh)));
@@ -327,7 +334,7 @@ int label_verify(struct device *dev)
return 0; return 0;
} }
return l->ops->verify(l, buf, sector); return ((l->ops->verify) ? l->ops->verify(l, buf, sector) : 1);
} }
void label_destroy(struct label *label) void label_destroy(struct label *label)

View File

@@ -33,7 +33,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
/* /*
* Lock type - these numbers are the same as VMS and the IBM DLM * Lock type - these numbers are the same as VMS and the IBM DLM
*/ */
#define LCK_TYPE_MASK 0x000000FF #define LCK_TYPE_MASK 0x00000007
#define LCK_NULL 0x00000000 /* LCK$_NLMODE */ #define LCK_NULL 0x00000000 /* LCK$_NLMODE */
#define LCK_READ 0x00000001 /* LCK$_CRMODE */ #define LCK_READ 0x00000001 /* LCK$_CRMODE */
@@ -41,20 +41,20 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
/* LCK$_PRMODE */ /* LCK$_PRMODE */
#define LCK_WRITE 0x00000004 /* LCK$_PWMODE */ #define LCK_WRITE 0x00000004 /* LCK$_PWMODE */
#define LCK_EXCL 0x00000005 /* LCK$_EXMODE */ #define LCK_EXCL 0x00000005 /* LCK$_EXMODE */
#define LCK_UNLOCK 0x00000010 /* This is ours */ #define LCK_UNLOCK 0x00000006 /* This is ours */
/* /*
* Lock scope * Lock scope
*/ */
#define LCK_SCOPE_MASK 0x0000FF00 #define LCK_SCOPE_MASK 0x00000008
#define LCK_VG 0x00000000 #define LCK_VG 0x00000000
#define LCK_LV 0x00000100 #define LCK_LV 0x00000008
/* /*
* Lock bits * Lock bits
*/ */
#define LCK_NONBLOCK 0x00010000 /* Don't block waiting for lock? */ #define LCK_NONBLOCK 0x00000010 /* Don't block waiting for lock? */
#define LCK_HOLD 0x00020000 /* Hold lock when lock_vol returns? */ #define LCK_HOLD 0x00000020 /* Hold lock when lock_vol returns? */
/* /*
* Common combinations * Common combinations

11
lib/metadata/lv_alloc.h Normal file
View File

@@ -0,0 +1,11 @@
/*
* Copyright (C) 2003 Sistina Software (UK) Limited.
*
* This file is released under the LGPL.
*/
#ifndef _LVM_LV_ALLOC_H
#include "pool.h"
struct lv_segment *alloc_lv_segment(struct pool *mem, uint32_t stripes);
#endif

View File

@@ -10,6 +10,7 @@
#include "pv_map.h" #include "pv_map.h"
#include "lvm-string.h" #include "lvm-string.h"
#include "toolcontext.h" #include "toolcontext.h"
#include "lv_alloc.h"
/* /*
* These functions adjust the pe counts in pv's * These functions adjust the pe counts in pv's
@@ -49,7 +50,7 @@ static void _put_extents(struct lv_segment *seg)
} }
} }
static struct lv_segment *_alloc_segment(struct pool *mem, uint32_t stripes) struct lv_segment *alloc_lv_segment(struct pool *mem, uint32_t stripes)
{ {
struct lv_segment *seg; struct lv_segment *seg;
uint32_t len = sizeof(*seg) + (stripes * sizeof(seg->area[0])); uint32_t len = sizeof(*seg) + (stripes * sizeof(seg->area[0]));
@@ -75,7 +76,7 @@ static int _alloc_stripe_area(struct logical_volume *lv, uint32_t stripes,
if (smallest < area_len) if (smallest < area_len)
area_len = smallest; area_len = smallest;
if (!(seg = _alloc_segment(lv->vg->cmd->mem, stripes))) { if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, stripes))) {
log_err("Couldn't allocate new stripe segment."); log_err("Couldn't allocate new stripe segment.");
return 0; return 0;
} }
@@ -188,7 +189,7 @@ static int _alloc_linear_area(struct logical_volume *lv, uint32_t *ix,
if (count > remaining) if (count > remaining)
count = remaining; count = remaining;
if (!(seg = _alloc_segment(lv->vg->cmd->mem, 1))) { if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 1))) {
log_err("Couldn't allocate new stripe segment."); log_err("Couldn't allocate new stripe segment.");
return 0; return 0;
} }
@@ -224,7 +225,7 @@ static int _alloc_mirrored_area(struct logical_volume *lv, uint32_t *ix,
if (count > remaining) if (count > remaining)
count = remaining; count = remaining;
if (!(seg = _alloc_segment(lv->vg->cmd->mem, 2))) { if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 2))) {
log_err("Couldn't allocate new mirrored segment."); log_err("Couldn't allocate new mirrored segment.");
return 0; return 0;
} }
@@ -477,7 +478,7 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
struct logical_volume *lv; struct logical_volume *lv;
char dname[32]; char dname[32];
if (vg->max_lv == vg->lv_count) { if (vg->max_lv && (vg->max_lv == vg->lv_count)) {
log_error("Maximum number of logical volumes (%u) reached " log_error("Maximum number of logical volumes (%u) reached "
"in volume group %s", vg->max_lv, vg->name); "in volume group %s", vg->max_lv, vg->name);
return NULL; return NULL;
@@ -731,11 +732,37 @@ int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags)
lv = list_item(lvh, struct lv_list)->lv; lv = list_item(lvh, struct lv_list)->lv;
if (!lock_vol(cmd, lv->lvid.s, flags)) { if (!lock_vol(cmd, lv->lvid.s, flags)) {
log_error("Failed to lock %s", lv->name); log_error("Failed to lock %s", lv->name);
/* FIXME Only unlock the locked ones */ list_uniterate(lvh, lvs, lvh) {
unlock_lvs(cmd, lvs); lv = list_item(lvh, struct lv_list)->lv;
unlock_lv(cmd, lv->lvid.s);
}
return 0; return 0;
} }
} }
return 1; return 1;
} }
uint32_t find_free_lvnum(struct logical_volume *lv)
{
int lvnum_used[MAX_RESTRICTED_LVS + 1];
uint32_t i = 0;
struct list *lvh;
struct lv_list *lvl;
int lvnum;
memset(&lvnum_used, 0, sizeof(lvnum_used));
list_iterate(lvh, &lv->vg->lvs) {
lvl = list_item(lvh, struct lv_list);
lvnum = lvnum_from_lvid(&lvl->lv->lvid);
if (lvnum <= MAX_RESTRICTED_LVS)
lvnum_used[lvnum] = 1;
}
while (lvnum_used[i])
i++;
return i;
}

View File

@@ -6,38 +6,55 @@
#include "lib.h" #include "lib.h"
#include "metadata.h" #include "metadata.h"
#include "toolcontext.h"
#include "lv_alloc.h"
/* /*
* Returns success if the segments were * Test whether two segments could be merged by the current merging code
* successfully merged. If the do merge, 'first'
* will be adjusted to contain both areas.
*/ */
static int _merge(struct lv_segment *first, struct lv_segment *second) static int _segments_compatible(struct lv_segment *first,
struct lv_segment *second)
{ {
unsigned int s;
uint32_t width; uint32_t width;
unsigned s;
if (!first || /* FIXME Relax the seg type restriction */
(first->type != SEG_STRIPED) || if (!first || !second ||
(first->type != second->type) || (first->type != SEG_STRIPED) || (second->type != first->type) ||
(first->area_count != second->area_count) || (first->area_count != second->area_count) ||
(first->stripe_size != second->stripe_size)) (first->stripe_size != second->stripe_size))
return 0; return 0;
for (s = 0; s < first->area_count; s++) { for (s = 0; s < first->area_count; s++) {
width = first->area_len;
/* FIXME Relax this to first type != second type ? */ /* FIXME Relax this to first area type != second area type */
if (first->area[s].type != AREA_PV || /* plus the additional AREA_LV checks needed */
second->area[s].type != AREA_PV) if ((first->area[s].type != AREA_PV) ||
(second->area[s].type != AREA_PV))
return 0; return 0;
width = first->area_len;
if ((first->area[s].u.pv.pv != second->area[s].u.pv.pv) || if ((first->area[s].u.pv.pv != second->area[s].u.pv.pv) ||
(first->area[s].u.pv.pe + width != second->area[s].u.pv.pe)) (first->area[s].u.pv.pe + width != second->area[s].u.pv.pe))
return 0; return 0;
} }
/* we should merge */ return 1;
}
/*
* Attempt to merge two adjacent segments.
* Currently only supports SEG_STRIPED on AREA_PV.
* Returns success if successful, in which case 'first'
* gets adjusted to contain both areas.
*/
static int _merge(struct lv_segment *first, struct lv_segment *second)
{
if (!_segments_compatible(first, second))
return 0;
first->len += second->len; first->len += second->len;
first->area_len += second->area_len; first->area_len += second->area_len;
@@ -46,10 +63,10 @@ static int _merge(struct lv_segment *first, struct lv_segment *second)
int lv_merge_segments(struct logical_volume *lv) int lv_merge_segments(struct logical_volume *lv)
{ {
struct list *segh; struct list *segh, *t;
struct lv_segment *current, *prev = NULL; struct lv_segment *current, *prev = NULL;
list_iterate(segh, &lv->segments) { list_iterate_safe(segh, t, &lv->segments) {
current = list_item(segh, struct lv_segment); current = list_item(segh, struct lv_segment);
if (_merge(prev, current)) if (_merge(prev, current))
@@ -61,7 +78,113 @@ int lv_merge_segments(struct logical_volume *lv)
return 1; return 1;
} }
/*
* Verify that an LV's segments are consecutive, complete and don't overlap.
*/
int lv_check_segments(struct logical_volume *lv) int lv_check_segments(struct logical_volume *lv)
{ {
struct lv_segment *seg;
uint32_t le = 0;
unsigned seg_count = 0;
list_iterate_items(seg, &lv->segments) {
seg_count++;
if (seg->le != le) {
log_error("LV %s invalid: segment %u should begin at "
"LE %" PRIu32 " (found %" PRIu32 ").",
lv->name, seg_count, le, seg->le);
return 0;
}
le += seg->len;
}
return 1; return 1;
} }
/*
* Split the supplied segment at the supplied logical extent
*/
static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
uint32_t le)
{
size_t len;
struct lv_segment *split_seg;
uint32_t s;
uint32_t offset = le - seg->le;
if (seg->type == SEG_SNAPSHOT) {
log_error("Unable to split the snapshot segment at LE %" PRIu32
" in LV %s", le, lv->name);
return 0;
}
/* Clone the existing segment */
if (!(split_seg = alloc_lv_segment(lv->vg->cmd->mem,
seg->area_count))) {
log_error("Couldn't allocate new LV segment.");
return 0;
}
len = sizeof(*seg) + (seg->area_count * sizeof(seg->area[0]));
memcpy(split_seg, seg, len);
/* In case of a striped segment, the offset has to be / stripes */
if (seg->type == SEG_STRIPED)
offset /= seg->area_count;
/* Adjust the PV mapping */
for (s = 0; s < seg->area_count; s++) {
/* Split area at the offset */
switch (seg->area[s].type) {
case AREA_LV:
split_seg->area[s].u.lv.le =
seg->area[s].u.lv.le + offset;
break;
case AREA_PV:
split_seg->area[s].u.pv.pe =
seg->area[s].u.pv.pe + offset;
break;
default:
log_error("Unrecognised segment type %u",
seg->area[s].type);
return 0;
}
}
split_seg->area_len = seg->area_len - offset;
seg->area_len = offset;
/* Add split off segment to the list _after_ the original one */
list_add_h(&seg->list, &split_seg->list);
return 1;
}
/*
* Ensure there's a segment boundary at the given logical extent
*/
int lv_split_segment(struct logical_volume *lv, uint32_t le)
{
struct lv_segment *seg;
if (!(seg = find_seg_by_le(lv, le))) {
log_error("Segment with extent %" PRIu32 " in LV %s not found",
le, lv->name);
return 0;
}
/* This is a segment start already */
if (le == seg->le)
return 1;
if (!_lv_split_segment(lv, seg, le)) {
stack;
return 0;
}
return 1;
}

View File

@@ -83,7 +83,7 @@ static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
return 0; return 0;
} }
if (vg->pv_count == vg->max_pv) { if (vg->pv_count && (vg->pv_count == vg->max_pv)) {
log_error("No space for '%s' - volume group '%s' " log_error("No space for '%s' - volume group '%s' "
"holds max %d physical volume(s).", pv_name, "holds max %d physical volume(s).", pv_name,
vg->name, vg->max_pv); vg->name, vg->max_pv);
@@ -217,7 +217,8 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
goto bad; goto bad;
} }
if (!vg->fid->fmt->ops->vg_setup(vg->fid, vg)) { if (vg->fid->fmt->ops->vg_setup &&
!vg->fid->fmt->ops->vg_setup(vg->fid, vg)) {
log_error("Format specific setup of volume group '%s' failed.", log_error("Format specific setup of volume group '%s' failed.",
vg_name); vg_name);
goto bad; goto bad;
@@ -463,6 +464,19 @@ int vg_write(struct volume_group *vg)
/* Write to each copy of the metadata area */ /* Write to each copy of the metadata area */
list_iterate(mdah, &vg->fid->metadata_areas) { list_iterate(mdah, &vg->fid->metadata_areas) {
mda = list_item(mdah, struct metadata_area); mda = list_item(mdah, struct metadata_area);
if(!mda->ops->vg_write) {
log_error("Format does not support writing volume"
"group metadata areas");
/* Revert */
list_uniterate(mdah2, &vg->fid->metadata_areas, mdah) {
mda = list_item(mdah2, struct metadata_area);
if (mda->ops->vg_revert &&
!mda->ops->vg_revert(vg->fid, vg, mda)) {
stack;
}
}
return 0;
}
if (!mda->ops->vg_write(vg->fid, vg, mda)) { if (!mda->ops->vg_write(vg->fid, vg, mda)) {
stack; stack;
/* Revert */ /* Revert */
@@ -666,7 +680,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
if ((correct_vg->status & PVMOVE) && !pvmove_mode()) { if ((correct_vg->status & PVMOVE) && !pvmove_mode()) {
log_error("WARNING: Interrupted pvmove detected in " log_error("WARNING: Interrupted pvmove detected in "
"volume group %s", vg->name); "volume group %s", correct_vg->name);
log_error("Please restore the metadata by running " log_error("Please restore the metadata by running "
"vgcfgrestore."); "vgcfgrestore.");
return NULL; return NULL;
@@ -682,8 +696,8 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
*/ */
struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid) struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
{ {
// const char *vgname; const char *vgname;
// struct list *vgnames, *slh; struct list *vgnames, *slh;
struct volume_group *vg; struct volume_group *vg;
struct lvmcache_vginfo *vginfo; struct lvmcache_vginfo *vginfo;
int consistent = 0; int consistent = 0;
@@ -702,13 +716,14 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
} }
} }
return NULL; /* Mustn't scan if memory locked: ensure cache gets pre-populated! */
if (memlock())
return NULL;
/* FIXME Need a genuine read by ID here - don't vg_read by name! */ /* FIXME Need a genuine read by ID here - don't vg_read by name! */
/* FIXME Disabled vgrenames while active for now because we aren't /* FIXME Disabled vgrenames while active for now because we aren't
* allowed to do a full scan here any more. */ * allowed to do a full scan here any more. */
/*** FIXME Cope with vgrename here
// The slow way - full scan required to cope with vgrename // The slow way - full scan required to cope with vgrename
if (!(vgnames = get_vgs(cmd, 1))) { if (!(vgnames = get_vgs(cmd, 1))) {
log_error("vg_read_by_vgid: get_vgs failed"); log_error("vg_read_by_vgid: get_vgs failed");
@@ -732,7 +747,6 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
} }
return NULL; return NULL;
***/
} }
/* Only called by activate.c */ /* Only called by activate.c */
@@ -869,6 +883,11 @@ struct list *get_pvs(struct cmd_context *cmd)
int pv_write(struct cmd_context *cmd, struct physical_volume *pv, int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
struct list *mdas, int64_t label_sector) struct list *mdas, int64_t label_sector)
{ {
if (!pv->fmt->ops->pv_write) {
log_error("Format does not support writing physical volumes");
return 0;
}
if (*pv->vg_name || pv->pe_alloc_count) { if (*pv->vg_name || pv->pe_alloc_count) {
log_error("Assertion failed: can't _pv_write non-orphan PV " log_error("Assertion failed: can't _pv_write non-orphan PV "
"(in VG %s)", pv->vg_name); "(in VG %s)", pv->vg_name);

View File

@@ -22,6 +22,7 @@
#define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */ #define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */ #define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */ #define PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
/* Various flags */ /* Various flags */
/* Note that the bits no longer necessarily correspond to LVM1 disk format */ /* Note that the bits no longer necessarily correspond to LVM1 disk format */
@@ -50,7 +51,11 @@
/* Format features flags */ /* Format features flags */
#define FMT_SEGMENTS 0x00000001 /* Arbitrary segment params? */ #define FMT_SEGMENTS 0x00000001 /* Arbitrary segment params? */
#define FMT_MDAS 0x00000002 /* Proper metadata areas? */ #define FMT_MDAS 0x00000002 /* Proper metadata areas? */
#define FMT_TAGS 0x00000004 /* Tagging? */
#define FMT_UNLIMITED_VOLS 0x00000008 /* Unlimited PVs/LVs? */
#define FMT_RESTRICTED_LVIDS 0x00000010 /* LVID <= 255 */
#define FMT_ORPHAN_ALLOCATABLE 0x00000020 /* Orphan PV allocatable? */
typedef enum { typedef enum {
ALLOC_DEFAULT, ALLOC_DEFAULT,
ALLOC_NEXT_FREE, ALLOC_NEXT_FREE,
@@ -468,6 +473,11 @@ int lv_check_segments(struct logical_volume *lv);
*/ */
int lv_merge_segments(struct logical_volume *lv); int lv_merge_segments(struct logical_volume *lv);
/*
* Ensure there's a segment boundary at a given LE, splitting if necessary
*/
int lv_split_segment(struct logical_volume *lv, uint32_t le);
/* /*
* Useful functions for managing snapshots. * Useful functions for managing snapshots.
*/ */
@@ -506,6 +516,8 @@ float pvmove_percent(struct logical_volume *lv_mirr);
struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg, struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv); struct logical_volume *lv);
uint32_t find_free_lvnum(struct logical_volume *lv);
static inline int validate_name(const char *n) static inline int validate_name(const char *n)
{ {
register char c; register char c;

View File

@@ -29,3 +29,20 @@ int lvm_snprintf(char *buf, size_t bufsize, const char *format, ...)
return n; return n;
} }
int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
{
int n;
va_list ap;
va_start(ap, fmt);
n = vsnprintf(*buffer, *size, fmt, ap);
va_end(ap);
if (n < 0 || (n == *size))
return 0;
*buffer += n;
*size -= n;
return 1;
}

View File

@@ -19,4 +19,6 @@
*/ */
int lvm_snprintf(char *buf, size_t bufsize, const char *format, ...); int lvm_snprintf(char *buf, size_t bufsize, const char *format, ...);
int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...);
#endif #endif

View File

@@ -34,6 +34,12 @@ void *malloc_aux(size_t s, const char *file, int line)
struct memblock *nb; struct memblock *nb;
size_t tsize = s + sizeof(*nb) + sizeof(unsigned long); size_t tsize = s + sizeof(*nb) + sizeof(unsigned long);
if (s > 50000000) {
log_error("Huge memory allocation (size %" PRIuPTR
") rejected - bug?", s);
return 0;
}
if (!(nb = malloc(tsize))) { if (!(nb = malloc(tsize))) {
log_error("couldn't allocate any memory, size = %" PRIuPTR, s); log_error("couldn't allocate any memory, size = %" PRIuPTR, s);
return 0; return 0;

View File

@@ -30,6 +30,10 @@ int memlock(void)
{ {
return 0; return 0;
} }
void memlock_init(struct cmd_context *cmd)
{
return;
}
#else /* DEVMAPPER_SUPPORT */ #else /* DEVMAPPER_SUPPORT */

View File

@@ -13,31 +13,43 @@
# define xlate16(x) __cpu_to_le16((x)) # define xlate16(x) __cpu_to_le16((x))
# define xlate32(x) __cpu_to_le32((x)) # define xlate32(x) __cpu_to_le32((x))
# define xlate64(x) __cpu_to_le64((x)) # define xlate64(x) __cpu_to_le64((x))
# define xlate16_be(x) __cpu_to_be16((x))
# define xlate32_be(x) __cpu_to_be32((x))
# define xlate64_be(x) __cpu_to_be64((x))
#else #else
# include <machine/endian.h> # include <machine/endian.h>
# if !defined(BYTE_ORDER) || \ # if !defined(BYTE_ORDER) || \
(BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN) (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN)
# error "Undefined or unrecognised BYTE_ORDER"; # error "Undefined or unrecognised BYTE_ORDER";
# endif # endif
# define __xlate16(x) (((x) & 0x00ffU) << 8 | \
((x) & 0xff00U) >> 8)
# define __xlate32(x) (((x) & 0x000000ffU) << 24 | \
((x) & 0xff000000U) >> 24 | \
((x) & 0x0000ff00U) << 8 | \
((x) & 0x00ff0000U) >> 8)
# define __xlate64(x) (((x) & 0x00000000000000ffU) << 56 | \
((x) & 0xff00000000000000U) >> 56 | \
((x) & 0x000000000000ff00U) << 40 | \
((x) & 0x00ff000000000000U) >> 40 | \
((x) & 0x0000000000ff0000U) << 24 | \
((x) & 0x0000ff0000000000U) >> 24 | \
((x) & 0x00000000ff000000U) << 8 | \
((x) & 0x000000ff00000000U) >> 8)
# if BYTE_ORDER == LITTLE_ENDIAN # if BYTE_ORDER == LITTLE_ENDIAN
# define xlate16(x) (x) # define xlate16(x) (x)
# define xlate32(x) (x) # define xlate32(x) (x)
# define xlate64(x) (x) # define xlate64(x) (x)
# define xlate16_be(x) __xlate16(x)
# define xlate32_be(x) __xlate32(x)
# define xlate64_be(x) __xlate64(x)
# else # else
# define xlate16(x) (((x) & 0x00ffU) << 8 | \ # define xlate16(x) __xlate16(x)
((x) & 0xff00U) >> 8) # define xlate32(x) __xlate32(x)
# define xlate32(x) (((x) & 0x000000ffU) << 24 | \ # define xlate64(x) __xlate64(x)
((x) & 0xff000000U) >> 24 | \ # define xlate16_be(x) (x)
((x) & 0x0000ff00U) << 8 | \ # define xlate32_be(x) (x)
((x) & 0x00ff0000U) >> 8) # define xlate64_be(x) (x)
# define xlate64(x) (((x) & 0x00000000000000ffU) << 56 | \
((x) & 0xff00000000000000U) >> 56 | \
((x) & 0x000000000000ff00U) << 40 | \
((x) & 0x00ff000000000000U) >> 40 | \
((x) & 0x0000000000ff0000U) << 24 | \
((x) & 0x0000ff0000000000U) >> 24 | \
((x) & 0x00000000ff000000U) << 8 | \
((x) & 0x000000ff00000000U) >> 8)
# endif # endif
#endif #endif

View File

@@ -12,7 +12,7 @@
#include <unistd.h> #include <unistd.h>
static unsigned char _c[] = static unsigned char _c[] =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#";
static int _built_inverse; static int _built_inverse;
static unsigned char _inverse_c[256]; static unsigned char _inverse_c[256];
@@ -73,8 +73,12 @@ int id_create(struct id *id)
} }
close(randomfile); close(randomfile);
/*
* Skip out the last 2 chars in randomized creation for LVM1
* backwards compatibility.
*/
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
id->uuid[i] = _c[id->uuid[i] % (sizeof(_c) - 1)]; id->uuid[i] = _c[id->uuid[i] % (sizeof(_c) - 3)];
return 1; return 1;
} }

View File

@@ -63,26 +63,6 @@ static inline struct list *list_next(struct list *head, struct list *elem)
return (list_end(head, elem) ? NULL : elem->n); return (list_end(head, elem) ? NULL : elem->n);
} }
#define list_iterate(v, head) \
for (v = (head)->n; v != head; v = v->n)
#define list_uniterate(v, head, start) \
for (v = (start)->p; v != head; v = v->p)
#define list_iterate_safe(v, t, head) \
for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
static inline unsigned int list_size(const struct list *head)
{
unsigned int s = 0;
const struct list *v;
list_iterate(v, head)
s++;
return s;
}
#define list_item(v, t) \ #define list_item(v, t) \
((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list)) ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list))
@@ -96,4 +76,28 @@ static inline unsigned int list_size(const struct list *head)
/* Given a known element in a known structure, locate the list head */ /* Given a known element in a known structure, locate the list head */
#define list_head(v, t, e) struct_field(v, t, e, list) #define list_head(v, t, e) struct_field(v, t, e, list)
#define list_iterate(v, head) \
for (v = (head)->n; v != head; v = v->n)
#define list_uniterate(v, head, start) \
for (v = (start)->p; v != head; v = v->p)
#define list_iterate_safe(v, t, head) \
for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
#define list_iterate_items(v, head) \
for (v = list_item((head)->n, typeof(*v)); &v->list != (head); \
v = list_item(v->list.n, typeof(*v)))
static inline unsigned int list_size(const struct list *head)
{
unsigned int s = 0;
const struct list *v;
list_iterate(v, head)
s++;
return s;
}
#endif #endif

View File

@@ -6,7 +6,10 @@
#include "libdm-targets.h" #include "libdm-targets.h"
#include "libdm-common.h" #include "libdm-common.h"
#include "libdm-compat.h"
#ifdef DM_COMPAT
# include "libdm-compat.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -16,8 +19,18 @@
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h>
#include <limits.h> #include <limits.h>
#include <linux/limits.h>
#ifdef linux
# include <linux/limits.h>
# include <linux/kdev_t.h>
# include <linux/dm-ioctl.h>
#else
# define MAJOR(x) major((x))
# define MINOR(x) minor((x))
# define MKDEV(x,y) makedev((x),(y))
#endif
/* /*
* Ensure build compatibility. * Ensure build compatibility.
@@ -66,6 +79,7 @@ static struct cmd_data _cmd_data_v4[] = {
{"waitevent", DM_DEV_WAIT, {4, 0, 0}}, {"waitevent", DM_DEV_WAIT, {4, 0, 0}},
{"names", DM_LIST_DEVICES, {4, 0, 0}}, {"names", DM_LIST_DEVICES, {4, 0, 0}},
{"clear", DM_TABLE_CLEAR, {4, 0, 0}}, {"clear", DM_TABLE_CLEAR, {4, 0, 0}},
{"mknodes", DM_DEV_STATUS, {4, 0, 0}},
}; };
/* *INDENT-ON* */ /* *INDENT-ON* */
@@ -84,6 +98,56 @@ static void *_align(void *ptr, unsigned int a)
return (void *) (((unsigned long) ptr + agn) & ~agn); return (void *) (((unsigned long) ptr + agn) & ~agn);
} }
static int _open_control(void)
{
char control[PATH_MAX];
if (_control_fd != -1)
return 1;
snprintf(control, sizeof(control), "%s/control", dm_dir());
if ((_control_fd = open(control, O_RDWR)) < 0) {
log_error("%s: open failed: %s", control, strerror(errno));
log_error("Is device-mapper driver missing from kernel?");
return 0;
}
return 1;
}
void dm_task_destroy(struct dm_task *dmt)
{
struct target *t, *n;
for (t = dmt->head; t; t = n) {
n = t->next;
free(t->params);
free(t->type);
free(t);
}
if (dmt->dev_name)
free(dmt->dev_name);
if (dmt->newname)
free(dmt->newname);
if (dmt->dmi.v4)
free(dmt->dmi.v4);
if (dmt->uuid)
free(dmt->uuid);
free(dmt);
}
/*
* Protocol Version 1 compatibility functions.
*/
#ifdef DM_COMPAT
static int _dm_task_get_driver_version_v1(struct dm_task *dmt, char *version, static int _dm_task_get_driver_version_v1(struct dm_task *dmt, char *version,
size_t size) size_t size)
{ {
@@ -122,7 +186,8 @@ static int _unmarshal_status_v1(struct dm_task *dmt, struct dm_ioctl_v1 *dmi)
return 1; return 1;
} }
static int _dm_format_dev_v1(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor) static int _dm_format_dev_v1(char *buf, int bufsize, uint32_t dev_major,
uint32_t dev_minor)
{ {
int r; int r;
@@ -365,24 +430,6 @@ static int _dm_names_v1(struct dm_ioctl_v1 *dmi)
return r; return r;
} }
static int _open_control(void)
{
char control[PATH_MAX];
if (_control_fd != -1)
return 1;
snprintf(control, sizeof(control), "%s/control", dm_dir());
if ((_control_fd = open(control, O_RDWR)) < 0) {
log_error("%s: open failed: %s", control, strerror(errno));
log_error("Is device-mapper driver missing from kernel?");
return 0;
}
return 1;
}
static int _dm_task_run_v1(struct dm_task *dmt) static int _dm_task_run_v1(struct dm_task *dmt)
{ {
struct dm_ioctl_v1 *dmi; struct dm_ioctl_v1 *dmi;
@@ -437,6 +484,14 @@ static int _dm_task_run_v1(struct dm_task *dmt)
rename_dev_node(dmt->dev_name, dmt->newname); rename_dev_node(dmt->dev_name, dmt->newname);
break; break;
case DM_DEVICE_MKNODES:
if (dmi->flags & DM_EXISTS_FLAG)
add_dev_node(dmt->dev_name, MAJOR(dmi->dev),
MINOR(dmi->dev));
else
rm_dev_node(dmt->dev_name);
break;
case DM_DEVICE_STATUS: case DM_DEVICE_STATUS:
case DM_DEVICE_TABLE: case DM_DEVICE_TABLE:
if (!_unmarshal_status_v1(dmt, dmi)) if (!_unmarshal_status_v1(dmt, dmi))
@@ -460,38 +515,20 @@ static int _dm_task_run_v1(struct dm_task *dmt)
return 0; return 0;
} }
void dm_task_destroy(struct dm_task *dmt) #endif
{
struct target *t, *n;
for (t = dmt->head; t; t = n) { /*
n = t->next; * Protocol Version 4 functions.
free(t->params); */
free(t->type);
free(t);
}
if (dmt->dev_name)
free(dmt->dev_name);
if (dmt->newname)
free(dmt->newname);
if (dmt->dmi.v4)
free(dmt->dmi.v4);
if (dmt->uuid)
free(dmt->uuid);
free(dmt);
}
int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size) int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size)
{ {
unsigned int *v; unsigned int *v;
#ifdef DM_COMPAT
if (_dm_version == 1) if (_dm_version == 1)
return _dm_task_get_driver_version_v1(dmt, version, size); return _dm_task_get_driver_version_v1(dmt, version, size);
#endif
if (!dmt->dmi.v4) { if (!dmt->dmi.v4) {
version[0] = '\0'; version[0] = '\0';
@@ -607,12 +644,15 @@ static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi)
return 1; return 1;
} }
int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor) int dm_format_dev(char *buf, int bufsize, uint32_t dev_major,
uint32_t dev_minor)
{ {
int r; int r;
#ifdef DM_COMPAT
if (_dm_version == 1) if (_dm_version == 1)
return _dm_format_dev_v1(buf, bufsize, dev_major, dev_minor); return _dm_format_dev_v1(buf, bufsize, dev_major, dev_minor);
#endif
if (bufsize < 8) if (bufsize < 8)
return 0; return 0;
@@ -626,8 +666,10 @@ int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor
int dm_task_get_info(struct dm_task *dmt, struct dm_info *info) int dm_task_get_info(struct dm_task *dmt, struct dm_info *info)
{ {
#ifdef DM_COMPAT
if (_dm_version == 1) if (_dm_version == 1)
return _dm_task_get_info_v1(dmt, info); return _dm_task_get_info_v1(dmt, info);
#endif
if (!dmt->dmi.v4) if (!dmt->dmi.v4)
return 0; return 0;
@@ -654,24 +696,30 @@ int dm_task_get_info(struct dm_task *dmt, struct dm_info *info)
const char *dm_task_get_name(struct dm_task *dmt) const char *dm_task_get_name(struct dm_task *dmt)
{ {
#ifdef DM_COMPAT
if (_dm_version == 1) if (_dm_version == 1)
return _dm_task_get_name_v1(dmt); return _dm_task_get_name_v1(dmt);
#endif
return (dmt->dmi.v4->name); return (dmt->dmi.v4->name);
} }
const char *dm_task_get_uuid(struct dm_task *dmt) const char *dm_task_get_uuid(struct dm_task *dmt)
{ {
#ifdef DM_COMPAT
if (_dm_version == 1) if (_dm_version == 1)
return _dm_task_get_uuid_v1(dmt); return _dm_task_get_uuid_v1(dmt);
#endif
return (dmt->dmi.v4->uuid); return (dmt->dmi.v4->uuid);
} }
struct dm_deps *dm_task_get_deps(struct dm_task *dmt) struct dm_deps *dm_task_get_deps(struct dm_task *dmt)
{ {
#ifdef DM_COMPAT
if (_dm_version == 1) if (_dm_version == 1)
return _dm_task_get_deps_v1(dmt); return _dm_task_get_deps_v1(dmt);
#endif
return (struct dm_deps *) (((void *) dmt->dmi.v4) + return (struct dm_deps *) (((void *) dmt->dmi.v4) +
dmt->dmi.v4->data_start); dmt->dmi.v4->data_start);
@@ -679,8 +727,10 @@ struct dm_deps *dm_task_get_deps(struct dm_task *dmt)
struct dm_names *dm_task_get_names(struct dm_task *dmt) struct dm_names *dm_task_get_names(struct dm_task *dmt)
{ {
#ifdef DM_COMPAT
if (_dm_version == 1) if (_dm_version == 1)
return _dm_task_get_names_v1(dmt); return _dm_task_get_names_v1(dmt);
#endif
return (struct dm_names *) (((void *) dmt->dmi.v4) + return (struct dm_names *) (((void *) dmt->dmi.v4) +
dmt->dmi.v4->data_start); dmt->dmi.v4->data_start);
@@ -933,11 +983,13 @@ static int _create_and_load_v4(struct dm_task *dmt)
int dm_task_run(struct dm_task *dmt) int dm_task_run(struct dm_task *dmt)
{ {
struct dm_ioctl *dmi; struct dm_ioctl *dmi = NULL;
unsigned int command; unsigned int command;
#ifdef DM_COMPAT
if (_dm_version == 1) if (_dm_version == 1)
return _dm_task_run_v1(dmt); return _dm_task_run_v1(dmt);
#endif
if ((unsigned) dmt->type >= if ((unsigned) dmt->type >=
(sizeof(_cmd_data_v4) / sizeof(*_cmd_data_v4))) { (sizeof(_cmd_data_v4) / sizeof(*_cmd_data_v4))) {
@@ -968,7 +1020,8 @@ int dm_task_run(struct dm_task *dmt)
log_debug("dm %s %s %s %s", _cmd_data_v4[dmt->type].name, dmi->name, log_debug("dm %s %s %s %s", _cmd_data_v4[dmt->type].name, dmi->name,
dmi->uuid, dmt->newname ? dmt->newname : ""); dmi->uuid, dmt->newname ? dmt->newname : "");
if (ioctl(_control_fd, command, dmi) < 0) { if (ioctl(_control_fd, command, dmi) < 0) {
if (errno == ENXIO && dmt->type == DM_DEVICE_INFO) { if (errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) ||
(dmt->type == DM_DEVICE_MKNODES))) {
dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */ dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */
goto ignore_error; goto ignore_error;
} }
@@ -995,6 +1048,14 @@ int dm_task_run(struct dm_task *dmt)
rename_dev_node(dmt->dev_name, dmt->newname); rename_dev_node(dmt->dev_name, dmt->newname);
break; break;
case DM_DEVICE_MKNODES:
if (dmi->flags & DM_EXISTS_FLAG)
add_dev_node(dmt->dev_name, MAJOR(dmi->dev),
MINOR(dmi->dev));
else
rm_dev_node(dmt->dev_name);
break;
case DM_DEVICE_STATUS: case DM_DEVICE_STATUS:
case DM_DEVICE_TABLE: case DM_DEVICE_TABLE:
case DM_DEVICE_WAITEVENT: case DM_DEVICE_WAITEVENT:

View File

@@ -102,7 +102,9 @@ static struct cmd_data _cmd_data_v1[] = {
{ "status", DM_TARGET_STATUS_V1, {1, 0, 0} }, { "status", DM_TARGET_STATUS_V1, {1, 0, 0} },
{ "table", DM_TARGET_STATUS_V1, {1, 0, 0} }, { "table", DM_TARGET_STATUS_V1, {1, 0, 0} },
{ "waitevent", DM_TARGET_WAIT_V1, {1, 0, 0} }, { "waitevent", DM_TARGET_WAIT_V1, {1, 0, 0} },
{ "names", 0, {4, 0, 0} } { "names", 0, {4, 0, 0} },
{ "clear", 0, {4, 0, 0} },
{ "mknodes", 0, {4, 0, 0} },
}; };
/* *INDENT-ON* */ /* *INDENT-ON* */

View File

@@ -9,7 +9,10 @@
#include <inttypes.h> #include <inttypes.h>
#include <sys/types.h> #include <sys/types.h>
#include <linux/types.h>
#ifdef linux
# include <linux/types.h>
#endif
/* /*
* Since it is quite laborious to build the ioctl * Since it is quite laborious to build the ioctl
@@ -52,7 +55,9 @@ enum {
DM_DEVICE_LIST, DM_DEVICE_LIST,
DM_DEVICE_CLEAR DM_DEVICE_CLEAR,
DM_DEVICE_MKNODES
}; };
struct dm_task; struct dm_task;

View File

@@ -27,7 +27,7 @@ SHELL = /bin/sh
INSTALL = @INSTALL@ INSTALL = @INSTALL@
LN_S = @LN_S@ LN_S = @LN_S@
LIBS = @LIBS@ LIBS = @LIBS@
CFLAGS = @CFLAGS@ CFLAGS += @CFLAGS@
# Setup directory variables # Setup directory variables
prefix = $(DESTDIR)@prefix@ prefix = $(DESTDIR)@prefix@

View File

@@ -22,11 +22,12 @@ VPATH = @srcdir@
MAN5=lvm.conf.5 MAN5=lvm.conf.5
MAN8=lvchange.8 lvcreate.8 lvdisplay.8 lvextend.8 lvm.8 lvmchange.8 \ MAN8=lvchange.8 lvcreate.8 lvdisplay.8 lvextend.8 lvm.8 lvmchange.8 \
lvreduce.8 lvremove.8 lvrename.8 lvs.8 lvscan.8 pvchange.8 \ lvmdiskscan.8 lvreduce.8 lvremove.8 lvrename.8 lvresize.8 lvs.8 \
pvcreate.8 pvdisplay.8 pvmove.8 pvremove.8 pvs.8 pvscan.8 \ lvscan.8 pvchange.8 pvcreate.8 pvdisplay.8 pvmove.8 pvremove.8 pvs.8 \
vgcfgbackup.8 vgcfgrestore.8 vgchange.8 vgck.8 vgcreate.8 \ pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 vgck.8 vgcreate.8 \
vgconvert.8 vgdisplay.8 vgextend.8 vgmerge.8 vgreduce.8 vgremove.8 \ vgconvert.8 vgdisplay.8 vgexport.8 vgextend.8 vgimport.8 \
vgrename.8 vgs.8 vgscan.8 vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 vgrename.8 \
vgs.8 vgscan.8 vgsplit.8
MAN5DIR=${mandir}/man5 MAN5DIR=${mandir}/man5
MAN8DIR=${mandir}/man8 MAN8DIR=${mandir}/man8
@@ -40,7 +41,7 @@ install:
@INSTALL@ -D -o $(OWNER) -g $(GROUP) -m 444 $$f $(MAN8DIR)/$$f; \ @INSTALL@ -D -o $(OWNER) -g $(GROUP) -m 444 $$f $(MAN8DIR)/$$f; \
done done
@echo "Installing $(MAN5) in $(MAN8DIR)" @echo "Installing $(MAN5) in $(MAN5DIR)"
@for f in $(MAN5); \ @for f in $(MAN5); \
do \ do \
$(RM) $(MAN5DIR)/$$f; \ $(RM) $(MAN5DIR)/$$f; \

View File

@@ -1,16 +1,19 @@
.TH DMSETUP 8 "Nov 29 2001" "Linux" "MAINTENTANCE COMMANDS" .TH DMSETUP 8 "Sep 17 2003" "Linux" "MAINTENTANCE COMMANDS"
.SH NAME .SH NAME
dmsetup \- low level logical volume management dmsetup \- low level logical volume management
.SH SYNOPSIS .SH SYNOPSIS
.ad l .ad l
.B dmsetup create .B dmsetup create
.I device_name table_file [uuid] .I device_name [-u uuid] [--notable] [table_file]
.br .br
.B dmsetup remove .B dmsetup remove
.I device_name .I device_name
.br .br
.B dmsetup rename .B dmsetup load
.I device_name new_name .I device_name [table_file]
.br
.B dmsetup clear
.I device_name
.br .br
.B dmsetup suspend .B dmsetup suspend
.I device_name .I device_name
@@ -19,25 +22,32 @@ dmsetup \- low level logical volume management
.I device_name .I device_name
.br .br
.B dmsetup reload .B dmsetup reload
.I device_name table_file .I device_name [table_file]
.br
.B dmsetup rename
.I device_name new_name
.br
.B dmsetup ls
.br .br
.B dmsetup info .B dmsetup info
.I device_name .I [device_name]
.br .br
.B dmsetup deps .B dmsetup deps
.I device_name .I [device_name]
.br
.B dmsetup mknodes
.I [device_name]
.br .br
.B dmsetup status .B dmsetup status
.I device_name .I [device_name]
.br .br
.B dmsetup table .B dmsetup table
.I device_name .I [device_name]
.br .br
.B dmsetup wait .B dmsetup wait
.I device_name .I device_name
.br .br
.B dmsetup remove_all .B dmsetup remove_all
.I device_name
.br .br
.B dmsetup version .B dmsetup version
.ad b .ad b
@@ -48,77 +58,107 @@ each sector in the logical device.
The first argument to dmsetup is a command. The first argument to dmsetup is a command.
The second argument is the logical device name or uuid. The second argument is the logical device name or uuid.
.SH OPTIONS
.IP \fB-j|--major\ \fImajor
.br
Specify the major number to use on creation.
.IP \fB-j|--minor\ \fIminor
.br
Specify the minor number to use on creation.
.IP \fB-r|--readonly
.br
Set the table being loaded read-only.
.IP \fB-v|--verbose [-v|--verbose]
.br
Produce additional output.
.IP \fB--version
.br
Display the library and kernel driver version.
.SH COMMANDS .SH COMMANDS
.IP \fBcreate .IP \fBcreate
.I device_name table_file [uuid] .I device_name [-u uuid] [--notable] [table_file]
.br .br
Attempts to create a device using the table file given. Creates a device with the given name.
If table_file is supplied, the table is loaded and made live.
Otherwise a table is read from standard input unless --notable is used.
The optional uuid can be used in place of The optional uuid can be used in place of
device_name in subsequent dmsetup commands. If device_name in subsequent dmsetup commands.
successful a device will appear as If successful a device will appear as
/dev/device-mapper/<device-name>. See below for information /dev/device-mapper/<device-name>.
on the table file format. See below for information on the table format.
.IP \fBdeps
.I device_name
.br
Outputs a list of (major, minor) pairs for devices referenced by the
live table for the specified device.
.IP \fBinfo
.I device_name
.br
Outputs some brief information about the device in the form:
.br
State: SUSPENDED|ACTIVE, READ-ONLY
.br
Tables present: LIVE and/or INACTIVE
.br
Open reference count
.br
Last event sequence number (used by \fBwait\fP)
.br
Major and minor device number
.br
Number of targets in the live table
.br
UUID
.IP \fBls
.br
List device names.
.IP \fBload|reload
.I device_name [table_file]
.br
Loads table_file into the inactive table slot for device_name.
If table_file is not supplied, reads a table from standard input.
.IP \fBremove .IP \fBremove
.I device_name .I device_name
.br .br
Removes a device Removes a device. It will no longer be visible to dmsetup and
will be deleted when its open_count is zero.
.IP \fBremove_all
.br
Attempts to remove all device definitions i.e. reset the driver.
Use with care!
.IP \fBrename .IP \fBrename
.I device_name new_name .I device_name new_name
.br .br
Renames a device Renames a device.
.IP \fBresume
.I device_name
.br
Un-suspends a device.
If an inactive table has been loaded, it becomes live.
Postponed I/O then gets re-queued for processing.
.IP \fBstatus
.I device_name
.br
Outputs status information for each of the device's targets.
.IP \fBsuspend .IP \fBsuspend
.I device_name .I device_name
.br .br
Suspends a device. Any I/O that has already been mapped by the device Suspends a device. Any I/O that has already been mapped by the device
but has not yet completed will be flushed. Any further I/O to that but has not yet completed will be flushed. Any further I/O to that
device will be postponed for as long as the device is suspended. device will be postponed for as long as the device is suspended.
.IP \fBresume
.I device_name
.br
Un-suspends a device. Postponed I/O now gets re-queued for processing.
.IP \fBreload
.I device_name table_file
.br
This command will only work if a device is in the suspended state.
It changes the mapping table for an existing device.
.IP \fBinfo
.I device_name
.br
Outputs some brief information about the device in the form:
.br
SUSPENDED|ACTIVE
.br
open_count
.br
major,minor
.br
target_count
.IP \fBdeps
.I device_name
.br
Outputs a list of (major, minor) pairs for devices referenced by the
specified device.
.IP \fBstatus
.I device_name
.br
Outputs status information for each of the device's targets.
.IP \fBtable .IP \fBtable
.I device_name .I device_name
.br .br
Outputs the current table for the device in a format than can be fed Outputs the current table for the device in a format that can be fed
back in using the create or reload commands. back in using the create or load commands.
.IP \fBwait
.I device_name
.br
Sleeps until an event is triggered against a device.
.IP \fBremove_all
.br
Attempts to remove all device definitions i.e. reset the driver.
Use with care!
.IP \fBversion .IP \fBversion
.I device_name .I device_name
.br .br
Outputs version information. Outputs version information.
.IP \fBwait
.I device_name
.br
Sleeps until an event is triggered against a device.
.SH TABLE FORMAT .SH TABLE FORMAT
Each line of the table specifies a single target and is of the form: Each line of the table specifies a single target and is of the form:
.br .br
@@ -151,16 +191,13 @@ will map the first chunk (16k) as follows:
.br .br
etc. etc.
.IP \fBerror
.IP \fBio-err
.br .br
Errors any I/O that goes to this area. Useful for testing or Errors any I/O that goes to this area. Useful for testing or
for creating devices with holes in them. for creating devices with holes in them.
.SH EXAMPLES .SH EXAMPLES
# A table to join two disks together # A table to join two disks together
.br .br
.br .br
@@ -169,7 +206,6 @@ for creating devices with holes in them.
1028160 3903762 linear /dev/hdb 0 1028160 3903762 linear /dev/hdb 0
# A table to stripe across the two disks, # A table to stripe across the two disks,
.br .br
# and add the spare space from # and add the spare space from

View File

@@ -13,7 +13,7 @@ lvextend \- extend the size of a logical volume
lvextend allows you to extend the size of a logical volume. lvextend allows you to extend the size of a logical volume.
Extension of snapshot logical volumes (see Extension of snapshot logical volumes (see
.B lvcreate(8) .B lvcreate(8)
for information to create snapshots) is supprted as well. for information to create snapshots) is supported as well.
.SH OPTIONS .SH OPTIONS
See \fBlvm\fP for common options. See \fBlvm\fP for common options.
.TP .TP
@@ -30,13 +30,13 @@ of the logical volume and without it, the value is taken as an absolute one.
.TP .TP
.I \-i, \-\-stripes Stripes .I \-i, \-\-stripes Stripes
Gives the number of stripes for the extension. Gives the number of stripes for the extension.
Not applicable to PVs using the original metadata LVM format. Not applicable to LVs using the original metadata LVM format, which must
This is equal to the number of physical volumes to scatter use a single value throughout.
the logical volume.
.TP .TP
.I \-I, \-\-stripesize StripeSize .I \-I, \-\-stripesize StripeSize
Gives the number of kilobytes for the granularity of the stripes. Gives the number of kilobytes for the granularity of the stripes.
Not applicable to PVs using the original metadata LVM format. Not applicable to LVs using the original metadata LVM format, which must
use a single value throughout.
.br .br
StripeSize must be 2^n (n = 2 to 9) StripeSize must be 2^n (n = 2 to 9)
.SH Examples .SH Examples
@@ -48,4 +48,5 @@ there are enough free physical extents in it.
.BR lvm (8), .BR lvm (8),
.BR lvcreate (8), .BR lvcreate (8),
.BR lvreduce (8), .BR lvreduce (8),
.BR lvresize (8),
.BR lvchange (8) .BR lvchange (8)

24
man/lvmdiskscan.8 Normal file
View File

@@ -0,0 +1,24 @@
.TH LVMDISKSCAN 8 "LVM TOOLS" "Sistina Software UK" \" -*- nroff -*-
.SH NAME
lvmdiskscan \- scan for all devices visible to LVM2
.SH SYNOPSIS
.B lvmdiskscan
[\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-l/\-\-lvmpartition]
[\-v/\-\-verbose]
.SH DESCRIPTION
vgscan scans all SCSI, (E)IDE disks, multiple devices and a bunch
of other block devices in the system looking for LVM physical volumes.
The size reported is the real device size.
Define a filter in \fBlvm.conf\fP(5) to restrict
the scan to avoid a CD ROM, for example.
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
.I \-l, \-\-lvmpartition
Only reports Physical Volumes.
.SH SEE ALSO
.BR lvm (8),
.BR lvm.conf (5),
.BR pvscan (8),
.BR vgscan (8)

View File

@@ -13,7 +13,7 @@ lvreduce allows you to reduce the size of a logical volume.
Be careful when reducing a logical volume's size, because data in the Be careful when reducing a logical volume's size, because data in the
reduced part is lost!!! reduced part is lost!!!
.br .br
You should therefore ensure that the (eg) filesystem on the volume is You should therefore ensure that any filesystem on the volume is
resized resized
.i before .i before
running lvreduce so that the extents that are to be removed are not in use. running lvreduce so that the extents that are to be removed are not in use.
@@ -38,7 +38,7 @@ Reduce or set the logical volume size in units of megabyte by default.
A size suffix of k for kilobyte, m for megabyte, g for gigabyte or A size suffix of k for kilobyte, m for megabyte, g for gigabyte or
t for terabyte is optional. t for terabyte is optional.
With the - sign the value will be subtracted from With the - sign the value will be subtracted from
the logical volume's actual size and without it the will be taken as the logical volume's actual size and without it it will be taken as
an absolute size. an absolute size.
.SH Example .SH Example
"lvreduce -l -3 /dev/vg00/lvol1" reduces the size of logical volume lvol1 "lvreduce -l -3 /dev/vg00/lvol1" reduces the size of logical volume lvol1
@@ -47,4 +47,5 @@ in volume group vg00 by 3 logical extents.
.BR lvm (8), .BR lvm (8),
.BR lvcreate (8), .BR lvcreate (8),
.BR lvextend (8), .BR lvextend (8),
.BR lvresize (8),
.BR lvchange (8) .BR lvchange (8)

53
man/lvresize.8 Normal file
View File

@@ -0,0 +1,53 @@
.TH LVRESIZE 8 "LVM TOOLS" "Sistina Software UK" \" -*- nroff -*-
.SH NAME
lvresize \- resize a logical volume
.SH SYNOPSIS
.B lvresize
[\-A/\-\-autobackup y/n] [\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-i/\-\-stripes Stripes [\-I/\-\-stripesize StripeSize]]
{\-l/\-\-extents [+]LogicalExtentsNumber |
\-L/\-\-size [+]LogicalVolumeSize[kKmMgGtT]}
[\-t/\-\-test]
[\-v/\-\-verbose] LogicalVolumePath [PhysicalVolumePath...]
.SH DESCRIPTION
lvresize allows you to resize a logical volume.
Be careful when reducing a logical volume's size, because data in the reduced
part is lost!!!
You should therefore ensure that any filesystem on the volume is
shrunk first so that the extents that are to be removed are not in use.
Resizing snapshot logical volumes (see
.B lvcreate(8)
for information about creating snapshots) is supported as well.
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
.I \-l, \-\-extents [+/-]LogicalExtentsNumber
Change or set the logical volume size in units of logical extents.
With the + or - sign the value is added to or subtracted from the actual size
of the logical volume and without it, the value is taken as an absolute one.
.TP
.I \-L, \-\-size [+/-]LogicalVolumeSize[kKmMgGtT]
Change or set the logical volume size in units in units of megabytes.
A size suffix of M for megabytes, G for gigabytes or T for terabytes is
optional. With the + or - sign the value is added to or subtracted from
the actual size of the logical volume and without it, the value is taken as an
absolute one.
.TP
.I \-i, \-\-stripes Stripes
Gives the number of stripes to use when extending a Logical Volume.
Defaults to whatever the last segment of the Logical Volume uses.
Not applicable to LVs using the original metadata LVM format, which must
use a single value throughout.
.TP
.I \-I, \-\-stripesize StripeSize
Gives the number of kilobytes for the granularity of the stripes.
Defaults to whatever the last segment of the Logical Volume uses.
Not applicable to LVs using the original metadata LVM format, which
must use a single value throughout.
.br
StripeSize must be 2^n (n = 2 to 9)
.SH SEE ALSO
.BR lvm (8),
.BR lvcreate (8),
.BR lvreduce (8),
.BR lvchange (8)

View File

@@ -3,9 +3,10 @@
pvmove \- move physical extents pvmove \- move physical extents
.SH SYNOPSIS .SH SYNOPSIS
.B pvmove .B pvmove
[\-\-abort]
[\-d/\-\-debug] [\-h/\-\-help] [\-i/\-\-interval Seconds] [\-v/\-\-verbose] [\-d/\-\-debug] [\-h/\-\-help] [\-i/\-\-interval Seconds] [\-v/\-\-verbose]
[\-n/\-\-name LogicalVolume] SourcePhysicalVolume [\-n/\-\-name LogicalVolume]
[DestinationPhysicalVolume[:PE[-PE]...]...] [SourcePhysicalVolume [DestinationPhysicalVolume[:PE[-PE]...]...]]
.SH DESCRIPTION .SH DESCRIPTION
.B pvmove .B pvmove
allows you to move the allocated physical extents (PEs) on allows you to move the allocated physical extents (PEs) on
@@ -20,15 +21,16 @@ If no
.I DestinationPhysicalVolume .I DestinationPhysicalVolume
is specifed, the normal allocation rules for the volume group are used. is specifed, the normal allocation rules for the volume group are used.
If \fBpvmove\fP gets interrupted for any reason, it will probably be If \fBpvmove\fP gets interrupted for any reason (e.g. the machine crashes)
necessary to run \fBvgcfgrestore\fP to restore the volume group's metadata to then run \fBpvmove\fP again without any PhysicalVolume arguments to
the state it was before the \fBpvmove\fP began. continue with any moves that were in progress or use \fBpvmove --abort\fP to
abort them.
\fBpvmove\fP locks the volume group and other LVM2 commands can't access
the volume group metadata until \fBpvmove\fP has completed.
.SH OPTIONS .SH OPTIONS
.TP .TP
.I \-\-abort
Abort any moves currently in progress.
.TP
.I \-i, \-\-interval Seconds .I \-i, \-\-interval Seconds
Report progress as a percentage at regular intervals. Report progress as a percentage at regular intervals.
.TP .TP

27
man/vgexport.8 Normal file
View File

@@ -0,0 +1,27 @@
.TH VGEXPORT 8 "LVM TOOLS" "Sistina Software UK" \" -*- nroff -*-
.SH NAME
vgexport \- make volume groups unknown to the system
.SH SYNOPSIS
.B vgexport
[\-a/\-\-all]
[\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-v/\-\-verbose]
VolumeGroupName [VolumeGroupName...]
.SH DESCRIPTION
vgexport allows you to make the inactive
.IR VolumeGroupName (s)
unknown to the system.
You can then move all the Physical Volumes in that Volume Group to
a different system for later
.BR vgimport (8).
Most LVM2 tools ignore exported Volume Groups.
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
.I \-a, \-\-all
Export all inactive Volume Groups.
.SH SEE ALSO
.BR lvm (8),
.BR pvscan (8),
.BR vgimport (8),
.BR vgscan (8)

25
man/vgimport.8 Normal file
View File

@@ -0,0 +1,25 @@
.TH VGIMPORT 8 "LVM TOOLS" "Sistina Software UK" \" -*- nroff -*-
.SH NAME
vgimport \- make exported volume groups known to the system
.SH SYNOPSIS
.B vgimport
[\-a/\-\-all]
[\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-v/\-\-verbose]
VolumeGroupName [VolumeGroupName...]
.SH DESCRIPTION
.B vgimport
allows you to make a Volume Group that was previously exported using
.BR vgexport (8)
known to the system again, perhaps after moving its Physical Volumes
from a different machine.
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
.I \-a, \-\-all
Import all exported Volume Groups.
.SH SEE ALSO
.BR lvm (8),
.BR pvscan (8),
.BR vgexport (8),
.BR vgscan (8)

17
man/vgmknodes.8 Normal file
View File

@@ -0,0 +1,17 @@
.TH VGMKNODES 8 "LVM TOOLS" "Sistina Software UK" \" -*- nroff -*-
.SH NAME
vgmknodes \- recreate volume group directory and logical volume special files
.SH SYNOPSIS
.B vgmknodes
[\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-v/\-\-verbose]
[[VolumeGroupName | LogicalVolumePath]...]
.SH DESCRIPTION
Checks the LVM2 special files in /dev that are needed for active
logical volumes and creates any missing ones and removes unused ones.
.SH OPTIONS
See \fBlvm\fP for common options.
.SH SEE ALSO
.BR lvm (8),
.BR vgscan (8),
.BR dmsetup (8)

View File

@@ -5,6 +5,7 @@ vgscan \- scan all disks for volume groups and rebuild caches
.B vgscan .B vgscan
[\-d/\-\-debug] [\-h/\-?/\-\-help] [\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-\-ignorelockingfailure] [\-\-ignorelockingfailure]
[\-\-mknodes]
[\-P/\-\-partial] [\-P/\-\-partial]
[\-v/\-\-verbose] [\-v/\-\-verbose]
.SH DESCRIPTION .SH DESCRIPTION
@@ -14,9 +15,13 @@ and volume groups. Define a filter in \fBlvm.conf\fP(8) to restrict
the scan to avoid a CD ROM, for example. the scan to avoid a CD ROM, for example.
.LP .LP
In LVM2, vgscans take place automatically; but you might still need to In LVM2, vgscans take place automatically; but you might still need to
run one explicitly after changing hardware or filters. run one explicitly after changing hardware.
.SH OPTIONS .SH OPTIONS
See \fBlvm\fP for common options. See \fBlvm\fP for common options.
.TP
.I \-\-mknodes
Also checks the LVM special files in /dev that are needed for active
logical volumes and creates any missing ones and removes unused ones.
.SH SEE ALSO .SH SEE ALSO
.BR lvm (8), .BR lvm (8),
.BR vgcreate (8), .BR vgcreate (8),

34
man/vgsplit.8 Normal file
View File

@@ -0,0 +1,34 @@
.TH VGMERGE 8 "LVM TOOLS" "Sistina Software UK" \" -*- nroff -*-
.SH NAME
vgsplit \- split a volume group into two
.SH SYNOPSIS
.B vgsplit
[\-A/\-\-autobackup y/n]
[\-d/\-\-debug]
[\-h/\-?/\-\-help]
[\-l/\-\-list]
[\-M/\-\-metadatatype 1/2]
[\-t/\-\-test]
[\-v/\-\-verbose]
ExistingVolumeGroupName NewVolumeGroupName
PhysicalVolumePath [PhysicalVolumePath...]
.SH DESCRIPTION
.B vgsplit
creates
.I NewVolumeGroupName
and moves
.IR PhysicalVolumePath (s)
from
.I ExistingVolumeGroupName
into it.
Logical Volumes cannot be split between Volume Groups.
Each existing Logical Volumes must be entirely on the Physical Volumes forming
either the old or the new Volume Group.
.SH OPTIONS
See \fBlvm\fP for common options.
.SH SEE ALSO
.BR lvm (8),
.BR vgcreate (8),
.BR vgextend (8),
.BR vgreduce (8),
.BR vgmerge (8)

View File

@@ -22,6 +22,7 @@ VPATH = @srcdir@
SOURCES=\ SOURCES=\
archive.c \ archive.c \
dumpconfig.c \
lvchange.c \ lvchange.c \
lvcreate.c \ lvcreate.c \
lvdisplay.c \ lvdisplay.c \
@@ -53,6 +54,7 @@ SOURCES=\
vgextend.c \ vgextend.c \
vgimport.c \ vgimport.c \
vgmerge.c \ vgmerge.c \
vgmknodes.c \
vgreduce.c \ vgreduce.c \
vgremove.c \ vgremove.c \
vgrename.c \ vgrename.c \
@@ -81,7 +83,7 @@ lvm: $(OBJECTS) $(top_srcdir)/lib/liblvm.a
.commands: commands.h cmdnames.h Makefile .commands: commands.h cmdnames.h Makefile
$(CC) -E -P cmdnames.h 2> /dev/null | \ $(CC) -E -P cmdnames.h 2> /dev/null | \
egrep -v '^ *(|#.*|help|version) *$$' > .commands egrep -v '^ *(|#.*|dumpconfig|help|pvdata|version) *$$' > .commands
install: $(TARGETS) install: $(TARGETS)
$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) lvm \ $(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) lvm \

View File

@@ -14,6 +14,12 @@ static struct {
} _archive_params; } _archive_params;
static struct {
int enabled;
char *dir;
} _backup_params;
int archive_init(const char *dir, unsigned int keep_days, unsigned int keep_min) int archive_init(const char *dir, unsigned int keep_days, unsigned int keep_min)
{ {
_archive_params.dir = NULL; _archive_params.dir = NULL;
@@ -103,15 +109,16 @@ int archive(struct volume_group *vg)
int archive_display(struct cmd_context *cmd, const char *vg_name) int archive_display(struct cmd_context *cmd, const char *vg_name)
{ {
return archive_list(cmd, _archive_params.dir, vg_name); int r1, r2;
init_partial(1);
r1 = archive_list(cmd, _archive_params.dir, vg_name);
r2 = backup_list(cmd, _backup_params.dir, vg_name);
init_partial(0);
return r1 && r2;
} }
static struct {
int enabled;
char *dir;
} _backup_params;
int backup_init(const char *dir) int backup_init(const char *dir)
{ {
_backup_params.dir = NULL; _backup_params.dir = NULL;
@@ -206,7 +213,6 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
{ {
struct volume_group *vg = NULL; struct volume_group *vg = NULL;
struct format_instance *tf; struct format_instance *tf;
struct list *mdah;
struct metadata_area *mda; struct metadata_area *mda;
void *context; void *context;
@@ -218,8 +224,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
return NULL; return NULL;
} }
list_iterate(mdah, &tf->metadata_areas) { list_iterate_items(mda, &tf->metadata_areas) {
mda = list_item(mdah, struct metadata_area);
if (!(vg = mda->ops->vg_read(tf, vg_name, mda))) if (!(vg = mda->ops->vg_read(tf, vg_name, mda)))
stack; stack;
break; break;
@@ -232,7 +237,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
/* ORPHAN and VG locks held before calling this */ /* ORPHAN and VG locks held before calling this */
int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg) int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
{ {
struct list *pvh; struct pv_list *pvl;
struct physical_volume *pv; struct physical_volume *pv;
struct lvmcache_info *info; struct lvmcache_info *info;
@@ -249,8 +254,8 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
} }
/* Add any metadata areas on the PVs */ /* Add any metadata areas on the PVs */
list_iterate(pvh, &vg->pvs) { list_iterate_items(pvl, &vg->pvs) {
pv = list_item(pvh, struct pv_list)->pv; pv = pvl->pv;
if (!(info = info_from_pvid(pv->dev->pvid))) { if (!(info = info_from_pvid(pv->dev->pvid))) {
log_error("PV %s missing from cache", log_error("PV %s missing from cache",
dev_name(pv->dev)); dev_name(pv->dev));
@@ -312,7 +317,6 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)
{ {
int r = 0; int r = 0;
struct format_instance *tf; struct format_instance *tf;
struct list *mdah;
struct metadata_area *mda; struct metadata_area *mda;
void *context; void *context;
struct cmd_context *cmd; struct cmd_context *cmd;
@@ -327,8 +331,7 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)
} }
/* Write and commit the metadata area */ /* Write and commit the metadata area */
list_iterate(mdah, &tf->metadata_areas) { list_iterate_items(mda, &tf->metadata_areas) {
mda = list_item(mdah, struct metadata_area);
if (!(r = mda->ops->vg_write(tf, vg, mda))) { if (!(r = mda->ops->vg_write(tf, vg, mda))) {
stack; stack;
continue; continue;

View File

@@ -26,6 +26,7 @@ arg(units_ARG, '\0', "units", string_arg)
arg(nosuffix_ARG, '\0', "nosuffix", NULL) arg(nosuffix_ARG, '\0', "nosuffix", NULL)
arg(removemissing_ARG, '\0', "removemissing", NULL) arg(removemissing_ARG, '\0', "removemissing", NULL)
arg(abort_ARG, '\0', "abort", NULL) arg(abort_ARG, '\0', "abort", NULL)
arg(mknodes_ARG, '\0', "mknodes", NULL)
/* Allow some variations */ /* Allow some variations */
arg(resizable_ARG, '\0', "resizable", yes_no_arg) arg(resizable_ARG, '\0', "resizable", yes_no_arg)

View File

@@ -33,6 +33,10 @@ xx(e2fsadm,
extents_ARG, size_ARG, nofsck_ARG, test_ARG) extents_ARG, size_ARG, nofsck_ARG, test_ARG)
*********/ *********/
xx(dumpconfig,
"Dump active configuration",
"dumpconfig <filename>\n")
xx(help, xx(help,
"Display help for commands", "Display help for commands",
"help <command>" "\n") "help <command>" "\n")
@@ -54,6 +58,7 @@ xx(lvchange,
"\t[-a|--available y|n]\n" "\t[-a|--available y|n]\n"
"\t[-C|--contiguous y|n]\n" "\t[-C|--contiguous y|n]\n"
"\t[-d|--debug]\n" "\t[-d|--debug]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n" "\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n" "\t[--ignorelockingfailure]\n"
"\t[-M|--persistent y|n] [--major major] [--minor minor]\n" "\t[-M|--persistent y|n] [--major major] [--minor minor]\n"
@@ -65,7 +70,7 @@ xx(lvchange,
"\t[--version]" "\n" "\t[--version]" "\n"
"\tLogicalVolume[Path] [LogicalVolume[Path]...]\n", "\tLogicalVolume[Path] [LogicalVolume[Path]...]\n",
autobackup_ARG, available_ARG, contiguous_ARG, autobackup_ARG, available_ARG, contiguous_ARG, force_ARG,
ignorelockingfailure_ARG, major_ARG, minor_ARG, partial_ARG, permission_ARG, ignorelockingfailure_ARG, major_ARG, minor_ARG, partial_ARG, permission_ARG,
persistent_ARG, readahead_ARG, test_ARG) persistent_ARG, readahead_ARG, test_ARG)
@@ -411,7 +416,7 @@ xx(pvmove,
"\t[-t|--test]\n " "\t[-t|--test]\n "
"\t[-v|--verbose]\n " "\t[-v|--verbose]\n "
"\t[--version]\n" "\t[--version]\n"
"\t[{-n|--name} LogicalVolume\n" "\t[{-n|--name} LogicalVolume]\n"
/* "\t[{-n|--name} LogicalVolume[:LogicalExtent[-LogicalExtent]...]]\n" */ /* "\t[{-n|--name} LogicalVolume[:LogicalExtent[-LogicalExtent]...]]\n" */
"\tSourcePhysicalVolume\n" "\tSourcePhysicalVolume\n"
/* "\tSourcePhysicalVolume[:PhysicalExtent[-PhysicalExtent]...]}\n" */ /* "\tSourcePhysicalVolume[:PhysicalExtent[-PhysicalExtent]...]}\n" */
@@ -747,11 +752,12 @@ xx(vgscan,
"\t[-d|--debug]\n" "\t[-d|--debug]\n"
"\t[-h|--help]\n" "\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n" "\t[--ignorelockingfailure]\n"
"\t[--mknodes]\n"
"\t[-P|--partial] " "\n" "\t[-P|--partial] " "\n"
"\t[-v|--verbose]\n" "\t[-v|--verbose]\n"
"\t[--version]" "\n", "\t[--version]" "\n",
ignorelockingfailure_ARG, partial_ARG) ignorelockingfailure_ARG, mknodes_ARG, partial_ARG)
xx(vgsplit, xx(vgsplit,
"Move physical volumes into a new volume group", "Move physical volumes into a new volume group",

View File

@@ -10,8 +10,30 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <getopt.h> #include <dirent.h>
#include <linux/kdev_t.h> #include <errno.h>
#include <unistd.h>
#ifdef HAVE_GETOPTLONG
# include <getopt.h>
# define GETOPTLONG_FN(a, b, c, d, e) getopt_long((a), (b), (c), (d), (e))
# define OPTIND_INIT 0
#else
struct option {
};
extern int optind;
extern char *optarg;
# define GETOPTLONG_FN(a, b, c, d, e) getopt((a), (b), (c))
# define OPTIND_INIT 1
#endif
#ifdef linux
# include <linux/kdev_t.h>
#else
# define MAJOR(x) major((x))
# define MINOR(x) minor((x))
# define MKDEV(x,y) makedev((x),(y))
#endif
#define LINE_SIZE 1024 #define LINE_SIZE 1024
@@ -24,6 +46,8 @@ enum {
READ_ONLY = 0, READ_ONLY = 0,
MAJOR_ARG, MAJOR_ARG,
MINOR_ARG, MINOR_ARG,
NOTABLE_ARG,
UUID_ARG,
VERBOSE_ARG, VERBOSE_ARG,
VERSION_ARG, VERSION_ARG,
NUM_SWITCHES NUM_SWITCHES
@@ -31,6 +55,7 @@ enum {
static int _switches[NUM_SWITCHES]; static int _switches[NUM_SWITCHES];
static int _values[NUM_SWITCHES]; static int _values[NUM_SWITCHES];
static char *_uuid;
/* /*
* Commands * Commands
@@ -38,14 +63,19 @@ static int _values[NUM_SWITCHES];
static int _parse_file(struct dm_task *dmt, const char *file) static int _parse_file(struct dm_task *dmt, const char *file)
{ {
char buffer[LINE_SIZE], *ttype, *ptr, *comment; char buffer[LINE_SIZE], *ttype, *ptr, *comment;
FILE *fp = fopen(file, "r"); FILE *fp;
unsigned long long start, size; unsigned long long start, size;
int r = 0, n, line = 0; int r = 0, n, line = 0;
if (!fp) { /* OK for empty stdin */
err("Couldn't open '%s' for reading", file);
return 0; if (file) {
} if (!(fp = fopen(file, "r"))) {
err("Couldn't open '%s' for reading", file);
return 0;
}
} else
fp = stdin;
while (fgets(buffer, sizeof(buffer), fp)) { while (fgets(buffer, sizeof(buffer), fp)) {
line++; line++;
@@ -81,7 +111,8 @@ static int _parse_file(struct dm_task *dmt, const char *file)
r = 1; r = 1;
out: out:
fclose(fp); if (file)
fclose(fp);
return r; return r;
} }
@@ -141,7 +172,7 @@ static int _load(int task, const char *name, const char *file, const char *uuid)
if (uuid && !dm_task_set_uuid(dmt, uuid)) if (uuid && !dm_task_set_uuid(dmt, uuid))
goto out; goto out;
if (file && !_parse_file(dmt, file)) if (!_switches[NOTABLE_ARG] && !_parse_file(dmt, file))
goto out; goto out;
if (_switches[READ_ONLY] && !dm_task_set_ro(dmt)) if (_switches[READ_ONLY] && !dm_task_set_ro(dmt))
@@ -167,21 +198,24 @@ static int _load(int task, const char *name, const char *file, const char *uuid)
return r; return r;
} }
static int _create(int argc, char **argv) static int _create(int argc, char **argv, void *data)
{ {
if (argc == 1) return _load(DM_DEVICE_CREATE, argv[1], (argc == 3) ? argv[2] : NULL,
return _load(DM_DEVICE_CREATE, argv[1], NULL, NULL); _switches[UUID_ARG] ? _uuid : NULL);
return _load(DM_DEVICE_CREATE, argv[1], argv[2],
(argc == 3) ? argv[3] : NULL);
} }
static int _reload(int argc, char **argv) static int _reload(int argc, char **argv, void *data)
{ {
return _load(DM_DEVICE_RELOAD, argv[1], argv[2], NULL); if (_switches[NOTABLE_ARG]) {
err("--notable only available when creating new device\n");
return 0;
}
return _load(DM_DEVICE_RELOAD, argv[1],
(argc == 3) ? argv[2] : NULL, NULL);
} }
static int _rename(int argc, char **argv) static int _rename(int argc, char **argv, void *data)
{ {
int r = 0; int r = 0;
struct dm_task *dmt; struct dm_task *dmt;
@@ -206,7 +240,7 @@ static int _rename(int argc, char **argv)
return r; return r;
} }
static int _version(int argc, char **argv) static int _version(int argc, char **argv, void *data)
{ {
int r = 0; int r = 0;
struct dm_task *dmt; struct dm_task *dmt;
@@ -258,37 +292,113 @@ static int _simple(int task, const char *name, int display)
return r; return r;
} }
static int _remove_all(int argc, char **argv) static int _remove_all(int argc, char **argv, void *data)
{ {
return _simple(DM_DEVICE_REMOVE_ALL, "", 0); return _simple(DM_DEVICE_REMOVE_ALL, "", 0);
} }
static int _remove(int argc, char **argv) static int _remove(int argc, char **argv, void *data)
{ {
return _simple(DM_DEVICE_REMOVE, argv[1], 0); return _simple(DM_DEVICE_REMOVE, argv[1], 0);
} }
static int _suspend(int argc, char **argv) static int _suspend(int argc, char **argv, void *data)
{ {
return _simple(DM_DEVICE_SUSPEND, argv[1], 1); return _simple(DM_DEVICE_SUSPEND, argv[1], 1);
} }
static int _resume(int argc, char **argv) static int _resume(int argc, char **argv, void *data)
{ {
return _simple(DM_DEVICE_RESUME, argv[1], 1); return _simple(DM_DEVICE_RESUME, argv[1], 1);
} }
static int _clear(int argc, char **argv) static int _clear(int argc, char **argv, void *data)
{ {
return _simple(DM_DEVICE_CLEAR, argv[1], 1); return _simple(DM_DEVICE_CLEAR, argv[1], 1);
} }
static int _wait(int argc, char **argv) static int _wait(int argc, char **argv, void *data)
{ {
return _simple(DM_DEVICE_WAITEVENT, argv[1], 2); return _simple(DM_DEVICE_WAITEVENT, argv[1], 2);
} }
static int _status(int argc, char **argv) static int _process_mapper_dir(int argc, char **argv,
int (*fn) (int argc, char **argv, void *data))
{
struct dirent *dirent;
struct dm_names *names;
DIR *d;
const char *dir;
int r = 1;
dir = dm_dir();
if (!(d = opendir(dir))) {
fprintf(stderr, "opendir %s: %s", dir, strerror(errno));
return 0;
}
while ((dirent = readdir(d))) {
if (!strcmp(dirent->d_name, ".") ||
!strcmp(dirent->d_name, "..") ||
!strcmp(dirent->d_name, "control"))
continue;
/* Set up names->name for _info */
names = (void *) dirent->d_name -
((void *) &names->name - (void *) &names->dev);
if (!fn(argc, argv, names))
r = 0;
}
if (closedir(d)) {
fprintf(stderr, "closedir %s: %s", dir, strerror(errno));
}
return r;
}
static int _process_all(int argc, char **argv,
int (*fn) (int argc, char **argv, void *data))
{
int r = 1;
struct dm_names *names;
unsigned next = 0;
struct dm_task *dmt;
if (!strcmp(argv[0], "mknodes"))
r = _process_mapper_dir(argc, argv, fn);
if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
return 0;
if (!dm_task_run(dmt)) {
r = 0;
goto out;
}
if (!(names = dm_task_get_names(dmt))) {
r = 0;
goto out;
}
if (!names->dev) {
printf("No devices found\n");
goto out;
}
do {
names = (void *) names + next;
if (!fn(argc, argv, (void *) names))
r = 0;
next = names->next;
} while (next);
out:
dm_task_destroy(dmt);
return r;
}
static int _status(int argc, char **argv, void *data)
{ {
int r = 0; int r = 0;
struct dm_task *dmt; struct dm_task *dmt;
@@ -297,16 +407,26 @@ static int _status(int argc, char **argv)
char *target_type = NULL; char *target_type = NULL;
char *params; char *params;
int cmd; int cmd;
struct dm_names *names = (struct dm_names *) data;
char *name;
if (!strcmp(argv[0], "status")) if (argc == 1 && !data)
cmd = DM_DEVICE_STATUS; return _process_all(argc, argv, _status);
if (data)
name = names->name;
else else
name = argv[1];
if (!strcmp(argv[0], "table"))
cmd = DM_DEVICE_TABLE; cmd = DM_DEVICE_TABLE;
else
cmd = DM_DEVICE_STATUS;
if (!(dmt = dm_task_create(cmd))) if (!(dmt = dm_task_create(cmd)))
return 0; return 0;
if (!dm_task_set_name(dmt, argv[1])) if (!dm_task_set_name(dmt, name))
goto out; goto out;
if (!dm_task_run(dmt)) if (!dm_task_run(dmt))
@@ -319,12 +439,17 @@ static int _status(int argc, char **argv)
do { do {
next = dm_get_next_target(dmt, next, &start, &length, next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params); &target_type, &params);
if (data && !_switches[VERBOSE_ARG])
printf("%s: ", name);
if (target_type) { if (target_type) {
printf("%" PRIu64 " %" PRIu64 " %s %s\n", printf("%" PRIu64 " %" PRIu64 " %s %s\n",
start, length, target_type, params); start, length, target_type, params);
} }
} while (next); } while (next);
if (data && _switches[VERBOSE_ARG])
printf("\n");
r = 1; r = 1;
out: out:
@@ -333,23 +458,40 @@ static int _status(int argc, char **argv)
} }
static int _info(int argc, char **argv) static int _info(int argc, char **argv, void *data)
{ {
int r = 0; int r = 0;
/* remove <dev_name> */
struct dm_task *dmt; struct dm_task *dmt;
struct dm_names *names = (struct dm_names *) data;
char *name;
int taskno;
if (!(dmt = dm_task_create(DM_DEVICE_INFO))) if (argc == 1 && !data)
return _process_all(argc, argv, _info);
if (data)
name = names->name;
else
name = argv[1];
if (!strcmp(argv[0], "mknodes"))
taskno = DM_DEVICE_MKNODES;
else
taskno = DM_DEVICE_INFO;
if (!(dmt = dm_task_create(taskno)))
return 0; return 0;
if (!dm_task_set_name(dmt, argv[1])) if (!dm_task_set_name(dmt, name))
goto out; goto out;
if (!dm_task_run(dmt)) if (!dm_task_run(dmt))
goto out; goto out;
_display_info(dmt); if (taskno == DM_DEVICE_INFO)
_display_info(dmt);
r = 1; r = 1;
out: out:
@@ -357,20 +499,28 @@ static int _info(int argc, char **argv)
return r; return r;
} }
static int _deps(int argc, char **argv) static int _deps(int argc, char **argv, void *data)
{ {
int r = 0; int r = 0;
uint32_t i; uint32_t i;
struct dm_deps *deps; struct dm_deps *deps;
/* remove <dev_name> */
struct dm_task *dmt; struct dm_task *dmt;
struct dm_info info; struct dm_info info;
struct dm_names *names = (struct dm_names *) data;
char *name;
if (argc == 1 && !data)
return _process_all(argc, argv, _deps);
if (data)
name = names->name;
else
name = argv[1];
if (!(dmt = dm_task_create(DM_DEVICE_DEPS))) if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
return 0; return 0;
if (!dm_task_set_name(dmt, argv[1])) if (!dm_task_set_name(dmt, name))
goto out; goto out;
if (!dm_task_run(dmt)) if (!dm_task_run(dmt))
@@ -391,6 +541,8 @@ static int _deps(int argc, char **argv)
if (_switches[VERBOSE_ARG]) if (_switches[VERBOSE_ARG])
_display_info(dmt); _display_info(dmt);
if (data && !_switches[VERBOSE_ARG])
printf("%s: ", name);
printf("%d dependencies\t:", deps->count); printf("%d dependencies\t:", deps->count);
for (i = 0; i < deps->count; i++) for (i = 0; i < deps->count; i++)
@@ -399,6 +551,9 @@ static int _deps(int argc, char **argv)
(int) MINOR(deps->device[i])); (int) MINOR(deps->device[i]));
printf("\n"); printf("\n");
if (data && _switches[VERBOSE_ARG])
printf("\n");
r = 1; r = 1;
out: out:
@@ -406,45 +561,25 @@ static int _deps(int argc, char **argv)
return r; return r;
} }
static int _ls(int argc, char **argv) static int _display_name(int argc, char **argv, void *data)
{ {
int r = 0; struct dm_names *names = (struct dm_names *) data;
struct dm_names *names;
unsigned next = 0;
struct dm_task *dmt; printf("%s\t(%d, %d)\n", names->name,
(int) MAJOR(names->dev), (int) MINOR(names->dev));
if (!(dmt = dm_task_create(DM_DEVICE_LIST))) return 1;
return 0; }
if (!dm_task_run(dmt)) static int _ls(int argc, char **argv, void *data)
goto out; {
return _process_all(argc, argv, _display_name);
if (!(names = dm_task_get_names(dmt)))
goto out;
r = 1;
if (!names->dev) {
printf("No devices found\n");
goto out;
}
do {
names = (void *) names + next;
printf("%s\t(%d, %d)\n", names->name,
(int) MAJOR(names->dev), (int) MINOR(names->dev));
next = names->next;
} while (next);
out:
dm_task_destroy(dmt);
return r;
} }
/* /*
* dispatch table * dispatch table
*/ */
typedef int (*command_fn) (int argc, char **argv); typedef int (*command_fn) (int argc, char **argv, void *data);
struct command { struct command {
const char *name; const char *name;
@@ -455,20 +590,22 @@ struct command {
}; };
static struct command _commands[] = { static struct command _commands[] = {
{"create", "<dev_name> <table_file> [<uuid>]", 1, 3, _create}, {"create", "<dev_name> [-u <uuid>] [--notable] [<table_file>]",
1, 2, _create},
{"remove", "<dev_name>", 1, 1, _remove}, {"remove", "<dev_name>", 1, 1, _remove},
{"remove_all", "", 0, 0, _remove_all}, {"remove_all", "", 0, 0, _remove_all},
{"suspend", "<dev_name>", 1, 1, _suspend}, {"suspend", "<dev_name>", 1, 1, _suspend},
{"resume", "<dev_name>", 1, 1, _resume}, {"resume", "<dev_name>", 1, 1, _resume},
{"load", "<dev_name> <table_file>", 2, 2, _reload}, {"load", "<dev_name> [<table_file>]", 1, 2, _reload},
{"clear", "<dev_name>", 1, 1, _clear}, {"clear", "<dev_name>", 1, 1, _clear},
{"reload", "<dev_name> <table_file>", 2, 2, _reload}, {"reload", "<dev_name> [<table_file>]", 1, 2, _reload},
{"rename", "<dev_name> <new_name>", 2, 2, _rename}, {"rename", "<dev_name> <new_name>", 2, 2, _rename},
{"ls", "", 0, 0, _ls}, {"ls", "", 0, 0, _ls},
{"info", "<dev_name>", 1, 1, _info}, {"info", "[<dev_name>]", 0, 1, _info},
{"deps", "<dev_name>", 1, 1, _deps}, {"deps", "[<dev_name>]", 0, 1, _deps},
{"status", "<dev_name>", 1, 1, _status}, {"mknodes", "[<dev_name>]", 0, 1, _info},
{"table", "<dev_name>", 1, 1, _status}, {"status", "[<dev_name>]", 0, 1, _status},
{"table", "[<dev_name>]", 0, 1, _status},
{"wait", "<dev_name>", 1, 1, _wait}, {"wait", "<dev_name>", 1, 1, _wait},
{"version", "", 0, 0, _version}, {"version", "", 0, 0, _version},
{NULL, NULL, 0, 0, NULL} {NULL, NULL, 0, 0, NULL}
@@ -480,7 +617,8 @@ static void _usage(FILE *out)
fprintf(out, "Usage:\n\n"); fprintf(out, "Usage:\n\n");
fprintf(out, "dmsetup [--version] [-v|--verbose [-v|--verbose ...]]\n" fprintf(out, "dmsetup [--version] [-v|--verbose [-v|--verbose ...]]\n"
" [-r|--readonly] [-j|--major <major>] [-m|--minor <minor>]\n\n"); " [-r|--readonly] [-j|--major <major>] "
"[-m|--minor <minor>]\n\n");
for (i = 0; _commands[i].name; i++) for (i = 0; _commands[i].name; i++)
fprintf(out, "\t%s %s\n", _commands[i].name, _commands[i].help); fprintf(out, "\t%s %s\n", _commands[i].name, _commands[i].help);
return; return;
@@ -502,14 +640,20 @@ static int _process_switches(int *argc, char ***argv)
int ind; int ind;
int c; int c;
#ifdef HAVE_GETOPTLONG
static struct option long_options[] = { static struct option long_options[] = {
{"readonly", 0, NULL, READ_ONLY}, {"readonly", 0, NULL, READ_ONLY},
{"major", 1, NULL, MAJOR_ARG}, {"major", 1, NULL, MAJOR_ARG},
{"minor", 1, NULL, MINOR_ARG}, {"minor", 1, NULL, MINOR_ARG},
{"notable", 0, NULL, NOTABLE_ARG},
{"uuid", 1, NULL, UUID_ARG},
{"verbose", 1, NULL, VERBOSE_ARG}, {"verbose", 1, NULL, VERBOSE_ARG},
{"version", 0, NULL, VERSION_ARG}, {"version", 0, NULL, VERSION_ARG},
{"", 0, NULL, 0} {"", 0, NULL, 0}
}; };
#else
struct option long_options;
#endif
/* /*
* Zero all the index counts. * Zero all the index counts.
@@ -517,8 +661,10 @@ static int _process_switches(int *argc, char ***argv)
memset(&_switches, 0, sizeof(_switches)); memset(&_switches, 0, sizeof(_switches));
memset(&_values, 0, sizeof(_values)); memset(&_values, 0, sizeof(_values));
while ((c = getopt_long(*argc, *argv, "j:m:rv", optarg = 0;
long_options, &ind)) != -1) { optind = OPTIND_INIT;
while ((c = GETOPTLONG_FN(*argc, *argv, "j:m:nru:v",
long_options, &ind)) != -1) {
if (c == 'r' || ind == READ_ONLY) if (c == 'r' || ind == READ_ONLY)
_switches[READ_ONLY]++; _switches[READ_ONLY]++;
if (c == 'j' || ind == MAJOR_ARG) { if (c == 'j' || ind == MAJOR_ARG) {
@@ -529,8 +675,14 @@ static int _process_switches(int *argc, char ***argv)
_switches[MINOR_ARG]++; _switches[MINOR_ARG]++;
_values[MINOR_ARG] = atoi(optarg); _values[MINOR_ARG] = atoi(optarg);
} }
if (c == 'n' || ind == NOTABLE_ARG)
_switches[NOTABLE_ARG]++;
if (c == 'v' || ind == VERBOSE_ARG) if (c == 'v' || ind == VERBOSE_ARG)
_switches[VERBOSE_ARG]++; _switches[VERBOSE_ARG]++;
if (c == 'u' || ind == UUID_ARG) {
_switches[UUID_ARG]++;
_uuid = optarg;
}
if ((ind == VERSION_ARG)) if ((ind == VERSION_ARG))
_switches[VERSION_ARG]++; _switches[VERSION_ARG]++;
} }
@@ -575,7 +727,7 @@ int main(int argc, char **argv)
} }
doit: doit:
if (!c->fn(argc, argv)) { if (!c->fn(argc, argv, NULL)) {
fprintf(stderr, "Command failed\n"); fprintf(stderr, "Command failed\n");
exit(1); exit(1);
} }

39
tools/dumpconfig.c Normal file
View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2003 Sistina Software
*
* LVM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* LVM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LVM; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "tools.h"
int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
{
const char *file = NULL;
if (argc == 1)
file = argv[0];
if (argc > 1) {
log_error("Please specify one file for output");
return EINVALID_CMD_LINE;
}
if (!write_config_file(cmd->cf, file))
return ECMD_FAILED;
return ECMD_PROCESSED;
}

View File

@@ -227,6 +227,7 @@ static int lvchange_readahead(struct cmd_context *cmd,
static int lvchange_persistent(struct cmd_context *cmd, static int lvchange_persistent(struct cmd_context *cmd,
struct logical_volume *lv) struct logical_volume *lv)
{ {
struct lvinfo info;
if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "n")) { if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "n")) {
if (!(lv->status & FIXED_MINOR)) { if (!(lv->status & FIXED_MINOR)) {
@@ -248,8 +249,19 @@ static int lvchange_persistent(struct cmd_context *cmd,
log_error("Major number must be specified with -My"); log_error("Major number must be specified with -My");
return 0; return 0;
} }
log_verbose("Ensuring %s is inactive. Reactivate with -ay.", if (lv_info(lv, &info) && info.exists &&
lv->name); !arg_count(cmd, force_ARG)) {
if (yes_no_prompt("Logical volume %s will be "
"deactivated first. "
"Continue? [y/n]: ",
lv->name) == 'n') {
log_print("%s device number not changed.",
lv->name);
return 0;
}
}
log_print("Ensuring %s is inactive. "
"(Reactivate using lvchange -ay.)", lv->name);
if (!lock_vol(cmd, lv->lvid.s, LCK_LV_DEACTIVATE)) { if (!lock_vol(cmd, lv->lvid.s, LCK_LV_DEACTIVATE)) {
log_error("%s: deactivation failed", lv->name); log_error("%s: deactivation failed", lv->name);
return 0; return 0;
@@ -364,7 +376,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!lvchange_availability(cmd, lv)) if (!lvchange_availability(cmd, lv))
return ECMD_FAILED; return ECMD_FAILED;
return 0; return ECMD_PROCESSED;
} }
int lvchange(struct cmd_context *cmd, int argc, char **argv) int lvchange(struct cmd_context *cmd, int argc, char **argv)

View File

@@ -119,8 +119,8 @@ static int _read_name_params(struct lvcreate_params *lp,
} }
if (!validate_name(lp->lv_name)) { if (!validate_name(lp->lv_name)) {
log_error("Logical volume name \"%s\" has invalid " log_error("Logical volume name \"%s\" is invalid",
"characters", lp->lv_name); lp->lv_name);
return 0; return 0;
} }
} }
@@ -148,12 +148,22 @@ static int _read_size_params(struct lvcreate_params *lp,
return 0; return 0;
} }
if (arg_count(cmd, extents_ARG)) if (arg_count(cmd, extents_ARG)) {
if (arg_sign_value(cmd, extents_ARG, 0) == SIGN_MINUS) {
log_error("Negative number of extents is invalid");
return 0;
}
lp->extents = arg_uint_value(cmd, extents_ARG, 0); lp->extents = arg_uint_value(cmd, extents_ARG, 0);
}
/* Size returned in kilobyte units; held in sectors */ /* Size returned in kilobyte units; held in sectors */
if (arg_count(cmd, size_ARG)) if (arg_count(cmd, size_ARG)) {
if (arg_sign_value(cmd, size_ARG, 0) == SIGN_MINUS) {
log_error("Negative size is invalid");
return 0;
}
lp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0)) * 2; lp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0)) * 2;
}
return 1; return 1;
} }
@@ -172,8 +182,13 @@ static int _read_stripe_params(struct lvcreate_params *lp,
log_print("Redundant stripes argument: default is 1"); log_print("Redundant stripes argument: default is 1");
} }
if (arg_count(cmd, stripesize_ARG)) if (arg_count(cmd, stripesize_ARG)) {
if (arg_sign_value(cmd, stripesize_ARG, 0) == SIGN_MINUS) {
log_error("Negative stripesize is invalid");
return 0;
}
lp->stripe_size = 2 * arg_uint_value(cmd, stripesize_ARG, 0); lp->stripe_size = 2 * arg_uint_value(cmd, stripesize_ARG, 0);
}
if (lp->stripes == 1 && lp->stripe_size) { if (lp->stripes == 1 && lp->stripe_size) {
log_print("Ignoring stripesize argument with single stripe"); log_print("Ignoring stripesize argument with single stripe");
@@ -222,6 +237,10 @@ static int _read_params(struct lvcreate_params *lp, struct cmd_context *cmd,
log_error("-s and -Z are incompatible"); log_error("-s and -Z are incompatible");
return 0; return 0;
} }
if (arg_sign_value(cmd, chunksize_ARG, 0) == SIGN_MINUS) {
log_error("Negative chunk size is invalid");
return 0;
}
lp->chunk_size = 2 * arg_uint_value(cmd, chunksize_ARG, 8); lp->chunk_size = 2 * arg_uint_value(cmd, chunksize_ARG, 8);
log_verbose("Setting chunksize to %d sectors.", lp->chunk_size); log_verbose("Setting chunksize to %d sectors.", lp->chunk_size);
} else { } else {
@@ -328,7 +347,7 @@ static int _zero_lv(struct cmd_context *cmd, struct logical_volume *lv)
return 0; return 0;
dev_zero(dev, UINT64_C(0), (size_t) 4096); dev_zero(dev, UINT64_C(0), (size_t) 4096);
dev_close(dev); dev_close_immediate(dev);
return 1; return 1;
} }
@@ -337,6 +356,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
{ {
uint32_t size_rest; uint32_t size_rest;
uint32_t status = 0; uint32_t status = 0;
uint64_t tmp_size;
alloc_policy_t alloc = ALLOC_DEFAULT; alloc_policy_t alloc = ALLOC_DEFAULT;
struct volume_group *vg; struct volume_group *vg;
struct logical_volume *lv, *org = NULL; struct logical_volume *lv, *org = NULL;
@@ -393,17 +413,16 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
if (lp->size) { if (lp->size) {
/* No of 512-byte sectors */ /* No of 512-byte sectors */
lp->extents = lp->size; tmp_size = lp->size;
if (lp->extents % vg->extent_size) { if (tmp_size % vg->extent_size) {
lp->extents += vg->extent_size - lp->extents % tmp_size += vg->extent_size - tmp_size %
vg->extent_size; vg->extent_size;
log_print("Rounding up size to full physical extent %s", log_print("Rounding up size to full physical extent %s",
display_size(cmd, (uint64_t) lp->extents / 2, display_size(cmd, tmp_size / 2, SIZE_SHORT));
SIZE_SHORT));
} }
lp->extents /= vg->extent_size; lp->extents = tmp_size / vg->extent_size;
} }
if ((size_rest = lp->extents % lp->stripes)) { if ((size_rest = lp->extents % lp->stripes)) {
@@ -434,6 +453,8 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
"supported yet"); "supported yet");
return 0; return 0;
} }
/* Must zero cow */
status |= LVM_WRITE;
} }
if (!(lv = lv_create(vg->fid, lp->lv_name, status, alloc, if (!(lv = lv_create(vg->fid, lp->lv_name, status, alloc,
@@ -493,6 +514,9 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
} }
if (lp->snapshot) { if (lp->snapshot) {
/* Reset permission after zeroing */
if (!(lp->permission & LVM_WRITE))
lv->status &= ~LVM_WRITE;
if (!lock_vol(cmd, lv->lvid.s, LCK_LV_DEACTIVATE)) { if (!lock_vol(cmd, lv->lvid.s, LCK_LV_DEACTIVATE)) {
log_err("Couldn't unlock snapshot."); log_err("Couldn't unlock snapshot.");
return 0; return 0;
@@ -539,11 +563,11 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv)
memset(&lp, 0, sizeof(lp)); memset(&lp, 0, sizeof(lp));
if (!_read_params(&lp, cmd, argc, argv)) if (!_read_params(&lp, cmd, argc, argv))
return -EINVALID_CMD_LINE; return EINVALID_CMD_LINE;
if (!lock_vol(cmd, lp.vg_name, LCK_VG_WRITE)) { if (!lock_vol(cmd, lp.vg_name, LCK_VG_WRITE)) {
log_error("Can't get lock for %s", lp.vg_name); log_error("Can't get lock for %s", lp.vg_name);
return 0; return ECMD_FAILED;
} }
if (!_lvcreate(cmd, &lp)) { if (!_lvcreate(cmd, &lp)) {
@@ -551,7 +575,7 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv)
goto out; goto out;
} }
r = 0; r = ECMD_PROCESSED;
out: out:
unlock_vg(cmd, lp.vg_name); unlock_vg(cmd, lp.vg_name);

View File

@@ -31,7 +31,7 @@ static int _lvdisplay_single(struct cmd_context *cmd, struct logical_volume *lv,
lvdisplay_segments(lv); lvdisplay_segments(lv);
} }
return 0; return ECMD_PROCESSED;
} }
int lvdisplay(struct cmd_context *cmd, int argc, char **argv) int lvdisplay(struct cmd_context *cmd, int argc, char **argv)

View File

@@ -77,14 +77,11 @@ int yes_no_arg(struct cmd_context *cmd, struct arg *a)
int metadatatype_arg(struct cmd_context *cmd, struct arg *a) int metadatatype_arg(struct cmd_context *cmd, struct arg *a)
{ {
struct format_type *fmt; struct format_type *fmt;
struct list *fmth;
char *format; char *format;
format = a->value; format = a->value;
list_iterate(fmth, &cmd->formats) { list_iterate_items(fmt, &cmd->formats) {
fmt = list_item(fmth, struct format_type);
if (!strcasecmp(fmt->name, format) || if (!strcasecmp(fmt->name, format) ||
!strcasecmp(fmt->name + 3, format) || !strcasecmp(fmt->name + 3, format) ||
(fmt->alias && !strcasecmp(fmt->alias, format))) { (fmt->alias && !strcasecmp(fmt->alias, format))) {
@@ -125,6 +122,8 @@ static int _get_int_arg(struct arg *a, char **ptr)
a->i_value = (int32_t) v; a->i_value = (int32_t) v;
a->ui_value = (uint32_t) v; a->ui_value = (uint32_t) v;
a->i64_value = (int64_t) v;
a->ui64_value = (uint64_t) v;
return 1; return 1;
} }
@@ -485,6 +484,15 @@ static int _process_command_line(struct cmd_context *cmd, int *argc,
} }
if (a->fn) { if (a->fn) {
if (a->count) {
log_error("Option%s%c%s%s may not be repeated",
a->short_arg ? " -" : "",
a->short_arg ? : ' ',
(a->short_arg && a->long_arg) ?
"/" : "",
a->long_arg ? : "");
return 0;
}
if (!optarg) { if (!optarg) {
log_error("Option requires argument."); log_error("Option requires argument.");
@@ -714,6 +722,8 @@ static int _run_command(struct cmd_context *cmd, int argc, char **argv)
if (!(cmd->cmd_line = _copy_command_line(cmd, argc, argv))) if (!(cmd->cmd_line = _copy_command_line(cmd, argc, argv)))
return ECMD_FAILED; return ECMD_FAILED;
log_debug("Processing: %s", cmd->cmd_line);
if (!(cmd->command = _find_command(argv[0]))) if (!(cmd->command = _find_command(argv[0])))
return ENO_SUCH_CMD; return ENO_SUCH_CMD;

View File

@@ -22,6 +22,6 @@
int lvmchange(struct cmd_context *cmd, int argc, char **argv) int lvmchange(struct cmd_context *cmd, int argc, char **argv)
{ {
log_print("With the device mapper, this program is obsolete."); log_print("With LVM2 and the device mapper, this program is obsolete.");
return 0; return ECMD_FAILED;
} }

View File

@@ -97,7 +97,7 @@ int lvmdiskscan(struct cmd_context *cmd, int argc, char **argv)
if (!(iter = dev_iter_create(cmd->filter))) { if (!(iter = dev_iter_create(cmd->filter))) {
log_error("dev_iter_create failed"); log_error("dev_iter_create failed");
return 0; return ECMD_FAILED;
} }
/* Do scan */ /* Do scan */
@@ -135,5 +135,5 @@ int lvmdiskscan(struct cmd_context *cmd, int argc, char **argv)
log_print("%d LVM physical volume%s", log_print("%d LVM physical volume%s",
pv_parts_found, pv_parts_found == 1 ? "" : "s"); pv_parts_found, pv_parts_found == 1 ? "" : "s");
return 0; return ECMD_PROCESSED;
} }

View File

@@ -59,7 +59,7 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
lv->name) == 'n') { lv->name) == 'n') {
log_print("Logical volume \"%s\" not removed", log_print("Logical volume \"%s\" not removed",
lv->name); lv->name);
return 0; return ECMD_FAILED;
} }
} }
} }
@@ -97,7 +97,7 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_FAILED; return ECMD_FAILED;
log_print("Logical volume \"%s\" successfully removed", lv->name); log_print("Logical volume \"%s\" successfully removed", lv->name);
return 0; return ECMD_PROCESSED;
} }
int lvremove(struct cmd_context *cmd, int argc, char **argv) int lvremove(struct cmd_context *cmd, int argc, char **argv)

View File

@@ -96,8 +96,7 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
} }
if (!validate_name(lv_name_new)) { if (!validate_name(lv_name_new)) {
log_error log_error("New logical volume name \"%s\" is invalid",
("New logical volume name \"%s\" has invalid characters",
lv_name_new); lv_name_new);
return EINVALID_CMD_LINE; return EINVALID_CMD_LINE;
} }
@@ -185,7 +184,7 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
log_print("Renamed \"%s\" to \"%s\" in volume group \"%s\"", log_print("Renamed \"%s\" to \"%s\" in volume group \"%s\"",
lv_name_old, lv_name_new, vg_name); lv_name_old, lv_name_new, vg_name);
return 0; return ECMD_PROCESSED;
error: error:
unlock_vg(cmd, vg_name); unlock_vg(cmd, vg_name);

View File

@@ -37,10 +37,13 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
const char *vg_name; const char *vg_name;
char *st, *lock_lvid; char *st, *lock_lvid;
const char *cmd_name; const char *cmd_name;
struct list *pvh, *segh; struct list *pvh;
struct lv_list *lvl; struct lv_list *lvl;
int opt = 0; int opt = 0;
int consistent = 1; int consistent = 1;
struct lv_segment *seg;
uint32_t seg_extents;
uint32_t sz, str;
enum { enum {
LV_ANY = 0, LV_ANY = 0,
@@ -133,6 +136,10 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
} }
if (arg_count(cmd, stripesize_ARG)) { if (arg_count(cmd, stripesize_ARG)) {
if (arg_sign_value(cmd, stripesize_ARG, 0) == SIGN_MINUS) {
log_error("Stripesize may not be negative.");
goto error;
}
if (vg->fid->fmt->features & FMT_SEGMENTS) if (vg->fid->fmt->features & FMT_SEGMENTS)
ssize = 2 * arg_uint_value(cmd, stripesize_ARG, 0); ssize = 2 * arg_uint_value(cmd, stripesize_ARG, 0);
else else
@@ -193,12 +200,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
/* If extending, find stripes, stripesize & size of last segment */ /* If extending, find stripes, stripesize & size of last segment */
if (extents > lv->le_count && !(stripes == 1 || (stripes > 1 && ssize))) { if (extents > lv->le_count && !(stripes == 1 || (stripes > 1 && ssize))) {
list_iterate(segh, &lv->segments) { list_iterate_items(seg, &lv->segments) {
struct lv_segment *seg;
uint32_t sz, str;
seg = list_item(segh, struct lv_segment);
if (seg->type != SEG_STRIPED) if (seg->type != SEG_STRIPED)
continue; continue;
@@ -244,12 +246,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
log_error("Ignoring stripes and stripesize arguments " log_error("Ignoring stripes and stripesize arguments "
"when reducing"); "when reducing");
list_iterate(segh, &lv->segments) { list_iterate_items(seg, &lv->segments) {
struct lv_segment *seg;
uint32_t seg_extents;
seg = list_item(segh, struct lv_segment);
seg_extents = seg->len; seg_extents = seg->len;
if (seg->type == SEG_STRIPED) { if (seg->type == SEG_STRIPED) {
@@ -404,7 +401,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
log_print("Logical volume %s successfully resized", lv_name); log_print("Logical volume %s successfully resized", lv_name);
return 0; return ECMD_PROCESSED;
error: error:
unlock_vg(cmd, vg_name); unlock_vg(cmd, vg_name);

View File

@@ -51,7 +51,7 @@ static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv,
lv_capacity_total += lv->size; lv_capacity_total += lv->size;
return 0; return ECMD_PROCESSED;
} }
int lvscan(struct cmd_context *cmd, int argc, char **argv) int lvscan(struct cmd_context *cmd, int argc, char **argv)

View File

@@ -89,6 +89,14 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
} }
if (!*pv->vg_name &&
!(pv->fmt->features & FMT_ORPHAN_ALLOCATABLE)) {
log_error("Allocatability not supported by orphan "
"%s format PV %s", pv->fmt->name, pv_name);
unlock_vg(cmd, ORPHAN);
return 0;
}
/* change allocatability for a PV */ /* change allocatability for a PV */
if (allocatable && (pv->status & ALLOCATABLE_PV)) { if (allocatable && (pv->status & ALLOCATABLE_PV)) {
log_error("Physical volume \"%s\" is already allocatable", log_error("Physical volume \"%s\" is already allocatable",
@@ -97,7 +105,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
unlock_vg(cmd, pv->vg_name); unlock_vg(cmd, pv->vg_name);
else else
unlock_vg(cmd, ORPHAN); unlock_vg(cmd, ORPHAN);
return 0; return 1;
} }
if (!allocatable && !(pv->status & ALLOCATABLE_PV)) { if (!allocatable && !(pv->status & ALLOCATABLE_PV)) {
@@ -107,7 +115,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
unlock_vg(cmd, pv->vg_name); unlock_vg(cmd, pv->vg_name);
else else
unlock_vg(cmd, ORPHAN); unlock_vg(cmd, ORPHAN);
return 0; return 1;
} }
if (allocatable) { if (allocatable) {
@@ -131,7 +139,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
backup(vg); backup(vg);
unlock_vg(cmd, pv->vg_name); unlock_vg(cmd, pv->vg_name);
} else { } else {
if (!(pv_write(cmd, pv, &mdas, (int64_t) sector))) { if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
unlock_vg(cmd, ORPHAN); unlock_vg(cmd, ORPHAN);
log_error("Failed to store physical volume \"%s\"", log_error("Failed to store physical volume \"%s\"",
pv_name); pv_name);
@@ -154,7 +162,8 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
struct physical_volume *pv; struct physical_volume *pv;
char *pv_name; char *pv_name;
struct list *pvh, *pvslist; struct pv_list *pvl;
struct list *pvslist;
struct list mdas; struct list mdas;
list_init(&mdas); list_init(&mdas);
@@ -194,12 +203,9 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED; return ECMD_FAILED;
} }
list_iterate(pvh, pvslist) { list_iterate_items(pvl, pvslist) {
total++; total++;
done += _pvchange_single(cmd, done += _pvchange_single(cmd, pvl->pv, NULL);
list_item(pvh,
struct pv_list)->pv,
NULL);
} }
} }
@@ -208,5 +214,5 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
done, done > 1 ? "s" : "", done, done > 1 ? "s" : "",
total - done, total - done > 1 ? "s" : ""); total - done, total - done > 1 ? "s" : "");
return 0; return (total == done) ? ECMD_PROCESSED : ECMD_FAILED;
} }

View File

@@ -73,8 +73,8 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
return 1; return 1;
} }
static void pvcreate_single(struct cmd_context *cmd, const char *pv_name, static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
void *handle) void *handle)
{ {
struct physical_volume *pv, *existing_pv; struct physical_volume *pv, *existing_pv;
struct id id, *idp = NULL; struct id id, *idp = NULL;
@@ -92,12 +92,12 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name,
if (arg_count(cmd, uuidstr_ARG)) { if (arg_count(cmd, uuidstr_ARG)) {
uuid = arg_str_value(cmd, uuidstr_ARG, ""); uuid = arg_str_value(cmd, uuidstr_ARG, "");
if (!id_read_format(&id, uuid)) if (!id_read_format(&id, uuid))
return; return EINVALID_CMD_LINE;
if ((dev = device_from_pvid(cmd, &id)) && if ((dev = device_from_pvid(cmd, &id)) &&
(dev != dev_cache_get(pv_name, cmd->filter))) { (dev != dev_cache_get(pv_name, cmd->filter))) {
log_error("uuid %s already in use on \"%s\"", uuid, log_error("uuid %s already in use on \"%s\"", uuid,
dev_name(dev)); dev_name(dev));
return; return ECMD_FAILED;
} }
idp = &id; idp = &id;
} }
@@ -109,13 +109,13 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name,
if (!(vg = backup_read_vg(cmd, NULL, restorefile))) { if (!(vg = backup_read_vg(cmd, NULL, restorefile))) {
log_error("Unable to read volume group from %s", log_error("Unable to read volume group from %s",
restorefile); restorefile);
return; return ECMD_FAILED;
} }
init_partial(0); init_partial(0);
if (!(existing_pv = find_pv_in_vg_by_uuid(vg, idp))) { if (!(existing_pv = find_pv_in_vg_by_uuid(vg, idp))) {
log_error("Can't find uuid %s in backup file %s", log_error("Can't find uuid %s in backup file %s",
uuid, restorefile); uuid, restorefile);
return; return ECMD_FAILED;
} }
pe_start = existing_pv->pe_start; pe_start = existing_pv->pe_start;
extent_size = existing_pv->pe_size; extent_size = existing_pv->pe_size;
@@ -124,14 +124,22 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name,
if (!lock_vol(cmd, "", LCK_VG_WRITE)) { if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs"); log_error("Can't get lock for orphan PVs");
return; return ECMD_FAILED;
} }
if (!pvcreate_check(cmd, pv_name)) if (!pvcreate_check(cmd, pv_name))
goto error; 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)) * 2; size = arg_uint64_value(cmd, physicalvolumesize_ARG, UINT64_C(0)) * 2;
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)) pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, UINT64_C(0))
* 2; * 2;
if (!pvmetadatasize) if (!pvmetadatasize)
@@ -178,14 +186,18 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name,
log_print("Physical volume \"%s\" successfully created", pv_name); log_print("Physical volume \"%s\" successfully created", pv_name);
unlock_vg(cmd, "");
return ECMD_PROCESSED;
error: error:
unlock_vg(cmd, ""); unlock_vg(cmd, "");
return; return ECMD_FAILED;
} }
int pvcreate(struct cmd_context *cmd, int argc, char **argv) int pvcreate(struct cmd_context *cmd, int argc, char **argv)
{ {
int i; int i, r;
int ret = ECMD_PROCESSED;
if (!argc) { if (!argc) {
log_error("Please enter a physical volume path"); log_error("Please enter a physical volume path");
@@ -227,9 +239,10 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv)
} }
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
pvcreate_single(cmd, argv[i], NULL); r = pvcreate_single(cmd, argv[i], NULL);
pool_empty(cmd->mem); if (r > ret)
ret = r;
} }
return 0; return ret;
} }

View File

@@ -35,7 +35,7 @@ static int _pvdisplay_single(struct cmd_context *cmd, struct volume_group *vg,
if (arg_count(cmd, short_ARG)) { if (arg_count(cmd, short_ARG)) {
log_print("Device \"%s\" has a capacity of %s", pv_name, log_print("Device \"%s\" has a capacity of %s", pv_name,
display_size(cmd, size / 2, SIZE_SHORT)); display_size(cmd, size / 2, SIZE_SHORT));
return 0; return ECMD_PROCESSED;
} }
if (pv->status & EXPORTED_VG) if (pv->status & EXPORTED_VG)
@@ -48,13 +48,13 @@ static int _pvdisplay_single(struct cmd_context *cmd, struct volume_group *vg,
if (arg_count(cmd, colon_ARG)) { if (arg_count(cmd, colon_ARG)) {
pvdisplay_colons(pv); pvdisplay_colons(pv);
return 0; return ECMD_PROCESSED;
} }
pvdisplay_full(cmd, pv, handle); pvdisplay_full(cmd, pv, handle);
if (!arg_count(cmd, maps_ARG)) if (!arg_count(cmd, maps_ARG))
return 0; return ECMD_PROCESSED;
return 0; return 0;
} }
@@ -82,7 +82,5 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE; return EINVALID_CMD_LINE;
} }
process_each_pv(cmd, argc, argv, NULL, NULL, _pvdisplay_single); return process_each_pv(cmd, argc, argv, NULL, NULL, _pvdisplay_single);
return 0;
} }

View File

@@ -182,7 +182,7 @@ static struct list *_get_allocatable_pvs(struct cmd_context *cmd, int argc,
pvl = list_item(pvh, struct pv_list); pvl = list_item(pvh, struct pv_list);
if ((pvl->pv->dev == pv->dev) || if ((pvl->pv->dev == pv->dev) ||
(pvl->pv->pe_count == pvl->pv->pe_alloc_count)) (pvl->pv->pe_count == pvl->pv->pe_alloc_count))
list_del(&pvl->list); list_del(&pvl->list);
} }
if (list_empty(allocatable_pvs)) { if (list_empty(allocatable_pvs)) {
@@ -202,7 +202,7 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
struct list **lvs_changed) struct list **lvs_changed)
{ {
struct logical_volume *lv_mirr, *lv; struct logical_volume *lv_mirr, *lv;
struct list *lvh; struct lv_list *lvl;
/* FIXME Cope with non-contiguous => splitting existing segments */ /* FIXME Cope with non-contiguous => splitting existing segments */
if (!(lv_mirr = lv_create_empty(vg->fid, NULL, "pvmove%d", if (!(lv_mirr = lv_create_empty(vg->fid, NULL, "pvmove%d",
@@ -222,8 +222,8 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
list_init(*lvs_changed); list_init(*lvs_changed);
/* Find segments to be moved and set up mirrors */ /* Find segments to be moved and set up mirrors */
list_iterate(lvh, &vg->lvs) { list_iterate_items(lvl, &vg->lvs) {
lv = list_item(lvh, struct lv_list)->lv; lv = lvl->lv;
if ((lv == lv_mirr) || (lv_name && strcmp(lv->name, lv_name))) if ((lv == lv_mirr) || (lv_name && strcmp(lv->name, lv_name)))
continue; continue;
if (lv_is_origin(lv) || lv_is_cow(lv)) { if (lv_is_origin(lv) || lv_is_cow(lv)) {
@@ -483,6 +483,16 @@ static int _check_pvmove_status(struct cmd_context *cmd,
*finished = 1; *finished = 1;
if (parms->aborting) {
if (!(lvs_changed = lvs_using_lv(cmd, vg, lv_mirr))) {
log_error("Failed to generate list of moved LVs: "
"can't abort.");
return 0;
}
_finish_pvmove(cmd, vg, lv_mirr, lvs_changed);
return 0;
}
if (!lv_mirror_percent(lv_mirr, !parms->interval, &segment_percent, if (!lv_mirror_percent(lv_mirr, !parms->interval, &segment_percent,
&event_nr)) { &event_nr)) {
log_error("ABORTING: Mirror percentage check failed."); log_error("ABORTING: Mirror percentage check failed.");
@@ -495,7 +505,7 @@ static int _check_pvmove_status(struct cmd_context *cmd,
else else
log_verbose("%s: Moved: %.1f%%", pv_name, overall_percent); log_verbose("%s: Moved: %.1f%%", pv_name, overall_percent);
if (segment_percent < 100.0 && !parms->aborting) { if (segment_percent < 100.0) {
*finished = 0; *finished = 0;
return 1; return 1;
} }
@@ -505,11 +515,6 @@ static int _check_pvmove_status(struct cmd_context *cmd,
return 0; return 0;
} }
if (parms->aborting) {
_finish_pvmove(cmd, vg, lv_mirr, lvs_changed);
return 0;
}
if (overall_percent >= 100.0) { if (overall_percent >= 100.0) {
if (!_finish_pvmove(cmd, vg, lv_mirr, lvs_changed)) if (!_finish_pvmove(cmd, vg, lv_mirr, lvs_changed))
return 0; return 0;
@@ -571,18 +576,29 @@ static int _poll_pvmove_vgs(struct cmd_context *cmd, const char *vgname,
void *handle) void *handle)
{ {
struct pvmove_parms *parms = (struct pvmove_parms *) handle; struct pvmove_parms *parms = (struct pvmove_parms *) handle;
struct list *lvh; struct lv_list *lvl;
struct logical_volume *lv_mirr; struct logical_volume *lv_mirr;
struct physical_volume *pv; struct physical_volume *pv;
int finished; int finished;
if (!vg) {
log_error("Couldn't read volume group %s", vgname);
return ECMD_FAILED;
}
if (!consistent) {
log_error("Volume Group %s inconsistent - skipping", vgname);
/* FIXME Should we silently recover it here or not? */
return ECMD_FAILED;
}
if (vg->status & EXPORTED_VG) { if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg->name); log_error("Volume group \"%s\" is exported", vg->name);
return ECMD_FAILED; return ECMD_FAILED;
} }
list_iterate(lvh, &vg->lvs) { list_iterate_items(lvl, &vg->lvs) {
lv_mirr = list_item(lvh, struct lv_list)->lv; lv_mirr = lvl->lv;
if (!(lv_mirr->status & PVMOVE)) if (!(lv_mirr->status & PVMOVE))
continue; continue;
if (!(pv = get_pvmove_pv_from_lv_mirr(lv_mirr))) if (!(pv = get_pvmove_pv_from_lv_mirr(lv_mirr)))
@@ -623,9 +639,11 @@ int pvmove_poll(struct cmd_context *cmd, const char *pv_name,
log_verbose("Checking progress every %u seconds", log_verbose("Checking progress every %u seconds",
parms.interval); parms.interval);
if (parms.interval == 0) { if (!parms.interval) {
parms.interval = DEFAULT_INTERVAL;
parms.progress_display = 0; parms.progress_display = 0;
if (!pv_name)
parms.interval = DEFAULT_INTERVAL;
} }
if (parms.background) { if (parms.background) {
@@ -653,8 +671,9 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv)
argc--; argc--;
argv++; argv++;
if ((ret = _set_up_pvmove(cmd, pv_name, argc, argv)) != if (!arg_count(cmd, abort_ARG) &&
ECMD_PROCESSED) { (ret = _set_up_pvmove(cmd, pv_name, argc, argv)) !=
ECMD_PROCESSED) {
stack; stack;
return ret; return ret;
} }

View File

@@ -72,14 +72,14 @@ static int pvremove_check(struct cmd_context *cmd, const char *name)
return 1; return 1;
} }
static void pvremove_single(struct cmd_context *cmd, const char *pv_name, static int pvremove_single(struct cmd_context *cmd, const char *pv_name,
void *handle) void *handle)
{ {
struct device *dev; struct device *dev;
if (!lock_vol(cmd, "", LCK_VG_WRITE)) { if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs"); log_error("Can't get lock for orphan PVs");
return; return ECMD_FAILED;
} }
if (!pvremove_check(cmd, pv_name)) if (!pvremove_check(cmd, pv_name))
@@ -99,14 +99,18 @@ static void pvremove_single(struct cmd_context *cmd, const char *pv_name,
log_print("Labels on physical volume \"%s\" successfully wiped", log_print("Labels on physical volume \"%s\" successfully wiped",
pv_name); pv_name);
unlock_vg(cmd, "");
return ECMD_PROCESSED;
error: error:
unlock_vg(cmd, ""); unlock_vg(cmd, "");
return; return ECMD_FAILED;
} }
int pvremove(struct cmd_context *cmd, int argc, char **argv) int pvremove(struct cmd_context *cmd, int argc, char **argv)
{ {
int i; int i, r;
int ret = ECMD_PROCESSED;
if (!argc) { if (!argc) {
log_error("Please enter a physical volume path"); log_error("Please enter a physical volume path");
@@ -119,9 +123,10 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv)
} }
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
pvremove_single(cmd, argv[i], NULL); r = pvremove_single(cmd, argv[i], NULL);
pool_empty(cmd->mem); if (r > ret)
ret = r;
} }
return 0; return ret;
} }

View File

@@ -109,7 +109,6 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
int pvs_found = 0; int pvs_found = 0;
struct list *pvslist; struct list *pvslist;
struct list *pvh;
struct pv_list *pvl; struct pv_list *pvl;
struct physical_volume *pv; struct physical_volume *pv;
@@ -141,8 +140,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED; return ECMD_FAILED;
/* eliminate exported/new if required */ /* eliminate exported/new if required */
list_iterate(pvh, pvslist) { list_iterate_items(pvl, pvslist) {
pvl = list_item(pvh, struct pv_list);
pv = pvl->pv; pv = pvl->pv;
if ((arg_count(cmd, exported_ARG) if ((arg_count(cmd, exported_ARG)
@@ -175,8 +173,8 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
/* find maximum pv name length */ /* find maximum pv name length */
pv_max_name_len = vg_max_name_len = 0; pv_max_name_len = vg_max_name_len = 0;
list_iterate(pvh, pvslist) { list_iterate_items(pvl, pvslist) {
pv = list_item(pvh, struct pv_list)->pv; pv = pvl->pv;
len = strlen(dev_name(pv->dev)); len = strlen(dev_name(pv->dev));
if (pv_max_name_len < len) if (pv_max_name_len < len)
pv_max_name_len = len; pv_max_name_len = len;
@@ -187,13 +185,12 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
pv_max_name_len += 2; pv_max_name_len += 2;
vg_max_name_len += 2; vg_max_name_len += 2;
list_iterate(pvh, pvslist) list_iterate_items(pvl, pvslist)
_pvscan_display_single(cmd, list_item(pvh, struct pv_list)->pv, _pvscan_display_single(cmd, pvl->pv, NULL);
NULL);
if (!pvs_found) { if (!pvs_found) {
log_print("No matching physical volumes found"); log_print("No matching physical volumes found");
return 0; return ECMD_PROCESSED;
} }
log_print("Total: %d [%s] / in use: %d [%s] / in no VG: %d [%s]", log_print("Total: %d [%s] / in use: %d [%s] / in no VG: %d [%s]",
@@ -203,5 +200,5 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
display_size(cmd, (size_total - size_new) / 2, SIZE_SHORT), display_size(cmd, (size_total - size_new) / 2, SIZE_SHORT),
new_pvs_found, display_size(cmd, size_new / 2, SIZE_SHORT)); new_pvs_found, display_size(cmd, size_new / 2, SIZE_SHORT));
return 0; return ECMD_PROCESSED;
} }

View File

@@ -32,7 +32,7 @@ static int _vgs_single(struct cmd_context *cmd, const char *vg_name,
if (!report_object(handle, vg, NULL, NULL, NULL)) if (!report_object(handle, vg, NULL, NULL, NULL))
return ECMD_FAILED; return ECMD_FAILED;
return 0; return ECMD_PROCESSED;
} }
static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv, static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv,
@@ -41,7 +41,7 @@ static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!report_object(handle, lv->vg, lv, NULL, NULL)) if (!report_object(handle, lv->vg, lv, NULL, NULL))
return ECMD_FAILED; return ECMD_FAILED;
return 0; return ECMD_PROCESSED;
} }
static int _segs_single(struct cmd_context *cmd, struct lv_segment *seg, static int _segs_single(struct cmd_context *cmd, struct lv_segment *seg,
@@ -50,7 +50,7 @@ static int _segs_single(struct cmd_context *cmd, struct lv_segment *seg,
if (!report_object(handle, seg->lv->vg, seg->lv, NULL, seg)) if (!report_object(handle, seg->lv->vg, seg->lv, NULL, seg))
return ECMD_FAILED; return ECMD_FAILED;
return 0; return ECMD_PROCESSED;
} }
static int _lvsegs_single(struct cmd_context *cmd, struct logical_volume *lv, static int _lvsegs_single(struct cmd_context *cmd, struct logical_volume *lv,
@@ -66,12 +66,12 @@ static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg,
if (!lock_vol(cmd, pv->vg_name, LCK_VG_READ)) { if (!lock_vol(cmd, pv->vg_name, LCK_VG_READ)) {
log_error("Can't lock %s: skipping", pv->vg_name); log_error("Can't lock %s: skipping", pv->vg_name);
return 0; return ECMD_FAILED;
} }
if (!(vg = vg_read(cmd, pv->vg_name, &consistent))) { if (!(vg = vg_read(cmd, pv->vg_name, &consistent))) {
log_error("Can't read %s: skipping", pv->vg_name); log_error("Can't read %s: skipping", pv->vg_name);
unlock_vg(cmd, pv->vg_name); unlock_vg(cmd, pv->vg_name);
return 0; return ECMD_FAILED;
} }
if (!report_object(handle, vg, NULL, pv, NULL)) if (!report_object(handle, vg, NULL, pv, NULL))
@@ -79,7 +79,7 @@ static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg,
unlock_vg(cmd, pv->vg_name); unlock_vg(cmd, pv->vg_name);
return 0; return ECMD_PROCESSED;
} }
static int _report(struct cmd_context *cmd, int argc, char **argv, static int _report(struct cmd_context *cmd, int argc, char **argv,
@@ -89,6 +89,7 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
const char *opts; const char *opts;
char *str; char *str;
const char *keys = NULL, *options = NULL, *separator; const char *keys = NULL, *options = NULL, *separator;
int r = ECMD_PROCESSED;
int aligned, buffered, headings; int aligned, buffered, headings;
@@ -192,27 +193,27 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
switch (report_type) { switch (report_type) {
case LVS: case LVS:
process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle, r = process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle,
&_lvs_single); &_lvs_single);
break; break;
case VGS: case VGS:
process_each_vg(cmd, argc, argv, LCK_VG_READ, 0, report_handle, r = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0,
&_vgs_single); report_handle, &_vgs_single);
break; break;
case PVS: case PVS:
process_each_pv(cmd, argc, argv, NULL, report_handle, r = process_each_pv(cmd, argc, argv, NULL, report_handle,
&_pvs_single); &_pvs_single);
break; break;
case SEGS: case SEGS:
process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle, r = process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle,
&_lvsegs_single); &_lvsegs_single);
break; break;
} }
report_output(report_handle); report_output(report_handle);
report_free(report_handle); report_free(report_handle);
return ECMD_PROCESSED; return r;
} }
int lvs(struct cmd_context *cmd, int argc, char **argv) int lvs(struct cmd_context *cmd, int argc, char **argv)

View File

@@ -6,9 +6,16 @@
#define unimplemented \ #define unimplemented \
{ log_error("Command not implemented yet."); return ECMD_FAILED;} { log_error("Command not implemented yet."); return ECMD_FAILED;}
/*int e2fsadm(struct cmd_context *cmd, int argc, char **argv) unimplemented*/ /*int e2fsadm(struct cmd_context *cmd, int argc, char **argv) unimplemented*/
int lvmsadc(struct cmd_context *cmd, int argc, char **argv) unimplemented int lvmsadc(struct cmd_context *cmd, int argc, char **argv) unimplemented
int lvmsar(struct cmd_context *cmd, int argc, char **argv) unimplemented int lvmsar(struct cmd_context *cmd, int argc, char **argv) unimplemented
int pvdata(struct cmd_context *cmd, int argc, char **argv) unimplemented
int pvresize(struct cmd_context *cmd, int argc, char **argv) unimplemented int pvresize(struct cmd_context *cmd, int argc, char **argv) unimplemented
int vgmknodes(struct cmd_context *cmd, int argc, char **argv) unimplemented
int pvdata(struct cmd_context *cmd, int argc, char **argv) {
log_error("There's no 'pvdata' command in LVM2.");
log_error("Use lvs, pvs, vgs instead; or use vgcfgbackup and read the text file backup.");
log_error("Metadata in LVM1 format can still be displayed using LVM1's pvdata command.");
return ECMD_FAILED;
}

View File

@@ -17,17 +17,15 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
int ret_max = 0; int ret_max = 0;
int ret = 0; int ret = 0;
struct list *lvh; struct lv_list *lvl;
struct logical_volume *lv;
if (vg->status & EXPORTED_VG) { if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg->name); log_error("Volume group \"%s\" is exported", vg->name);
return ECMD_FAILED; return ECMD_FAILED;
} }
list_iterate(lvh, &vg->lvs) { list_iterate_items(lvl, &vg->lvs) {
lv = list_item(lvh, struct lv_list)->lv; ret = process_single(cmd, lvl->lv, handle);
ret = process_single(cmd, lv, handle);
if (ret > ret_max) if (ret > ret_max)
ret_max = ret; ret_max = ret;
} }
@@ -233,13 +231,11 @@ int process_each_segment_in_lv(struct cmd_context *cmd,
struct lv_segment * seg, struct lv_segment * seg,
void *handle)) void *handle))
{ {
struct list *segh;
struct lv_segment *seg; struct lv_segment *seg;
int ret_max = 0; int ret_max = 0;
int ret; int ret;
list_iterate(segh, &lv->segments) { list_iterate_items(seg, &lv->segments) {
seg = list_item(segh, struct lv_segment);
ret = process_single(cmd, seg, handle); ret = process_single(cmd, seg, handle);
if (ret > ret_max) if (ret > ret_max)
ret_max = ret; ret_max = ret;
@@ -328,15 +324,11 @@ int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
{ {
int ret_max = 0; int ret_max = 0;
int ret = 0; int ret = 0;
struct list *pvh; struct pv_list *pvl;
struct physical_volume *pv;
list_iterate(pvh, &vg->pvs) { list_iterate_items(pvl, &vg->pvs)
pv = list_item(pvh, struct pv_list)->pv; if ((ret = process_single(cmd, vg, pvl->pv, handle)) > ret_max)
if ((ret = process_single(cmd, vg, pv, handle)) > ret_max)
ret_max = ret; ret_max = ret;
}
return ret_max; return ret_max;
} }
@@ -354,7 +346,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
struct pv_list *pvl; struct pv_list *pvl;
struct physical_volume *pv; struct physical_volume *pv;
struct list *pvslist, *pvh; struct list *pvslist;
if (argc) { if (argc) {
log_verbose("Using physical volume(s) on command line"); log_verbose("Using physical volume(s) on command line");
@@ -365,6 +357,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
"found in Volume Group " "found in Volume Group "
"\"%s\"", argv[opt], "\"%s\"", argv[opt],
vg->name); vg->name);
ret_max = ECMD_FAILED;
continue; continue;
} }
pv = pvl->pv; pv = pvl->pv;
@@ -372,6 +365,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
if (!(pv = pv_read(cmd, argv[opt], NULL, NULL))) { if (!(pv = pv_read(cmd, argv[opt], NULL, NULL))) {
log_error("Failed to read physical " log_error("Failed to read physical "
"volume \"%s\"", argv[opt]); "volume \"%s\"", argv[opt]);
ret_max = ECMD_FAILED;
continue; continue;
} }
} }
@@ -384,15 +378,17 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
if (vg) { if (vg) {
log_verbose("Using all physical volume(s) in " log_verbose("Using all physical volume(s) in "
"volume group"); "volume group");
process_each_pv_in_vg(cmd, vg, handle, process_single); ret = process_each_pv_in_vg(cmd, vg, handle, process_single);
if (ret > ret_max)
ret_max = ret;
} else { } else {
log_verbose("Scanning for physical volume names"); log_verbose("Scanning for physical volume names");
if (!(pvslist = get_pvs(cmd))) if (!(pvslist = get_pvs(cmd)))
return ECMD_FAILED; return ECMD_FAILED;
list_iterate(pvh, pvslist) { list_iterate_items(pvl, pvslist) {
pv = list_item(pvh, struct pv_list)->pv; ret = process_single(cmd, NULL, pvl->pv,
ret = process_single(cmd, NULL, pv, handle); handle);
if (ret > ret_max) if (ret > ret_max)
ret_max = ret; ret_max = ret;
} }
@@ -492,14 +488,12 @@ static int _add_alloc_area(struct pool *mem, struct list *alloc_areas,
uint32_t start, uint32_t count) uint32_t start, uint32_t count)
{ {
struct alloc_area *aa; struct alloc_area *aa;
struct list *aah;
log_debug("Adding alloc area: start PE %" PRIu32 " length %" PRIu32, log_debug("Adding alloc area: start PE %" PRIu32 " length %" PRIu32,
start, count); start, count);
/* Ensure no overlap with existing areas */ /* Ensure no overlap with existing areas */
list_iterate(aah, alloc_areas) { list_iterate_items(aa, alloc_areas) {
aa = list_item(aah, struct alloc_area);
if (((start < aa->start) && (start + count - 1 >= aa->start)) || if (((start < aa->start) && (start + count - 1 >= aa->start)) ||
((start >= aa->start) && ((start >= aa->start) &&
(aa->start + aa->count - 1) >= start)) { (aa->start + aa->count - 1) >= start)) {
@@ -666,7 +660,7 @@ struct list *create_pv_list(struct pool *mem,
struct list *clone_pv_list(struct pool *mem, struct list *pvsl) struct list *clone_pv_list(struct pool *mem, struct list *pvsl)
{ {
struct list *r, *pvh; struct list *r;
struct pv_list *pvl, *new_pvl; struct pv_list *pvl, *new_pvl;
/* Build up list of PVs */ /* Build up list of PVs */
@@ -676,9 +670,7 @@ struct list *clone_pv_list(struct pool *mem, struct list *pvsl)
} }
list_init(r); list_init(r);
list_iterate(pvh, pvsl) { list_iterate_items(pvl, pvsl) {
pvl = list_item(pvh, struct pv_list);
if (!(new_pvl = pool_zalloc(mem, sizeof(*new_pvl)))) { if (!(new_pvl = pool_zalloc(mem, sizeof(*new_pvl)))) {
log_error("Unable to allocate physical volume list."); log_error("Unable to allocate physical volume list.");
return NULL; return NULL;

View File

@@ -38,7 +38,7 @@ static int vg_backup_single(struct cmd_context *cmd, const char *vg_name,
} }
log_print("Volume group \"%s\" successfully backed up.", vg_name); log_print("Volume group \"%s\" successfully backed up.", vg_name);
return 0; return ECMD_PROCESSED;
} }
int vgcfgbackup(struct cmd_context *cmd, int argc, char **argv) int vgcfgbackup(struct cmd_context *cmd, int argc, char **argv)

View File

@@ -21,8 +21,7 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
vg_name += strlen(cmd->dev_dir); vg_name += strlen(cmd->dev_dir);
if (!validate_name(vg_name)) { if (!validate_name(vg_name)) {
log_error("Volume group name \"%s\" has invalid characters", log_error("Volume group name \"%s\" is invalid", vg_name);
vg_name);
return ECMD_FAILED; return ECMD_FAILED;
} }
@@ -34,7 +33,7 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
if (!archive_display(cmd, vg_name)) if (!archive_display(cmd, vg_name))
return ECMD_FAILED; return ECMD_FAILED;
return 0; return ECMD_PROCESSED;
} }
if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) { if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) {
@@ -62,5 +61,5 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
unlock_vg(cmd, vg_name); unlock_vg(cmd, vg_name);
unlock_vg(cmd, ORPHAN); unlock_vg(cmd, ORPHAN);
return 0; return ECMD_PROCESSED;
} }

View File

@@ -23,13 +23,13 @@
static int _activate_lvs_in_vg(struct cmd_context *cmd, static int _activate_lvs_in_vg(struct cmd_context *cmd,
struct volume_group *vg, int lock) struct volume_group *vg, int lock)
{ {
struct list *lvh; struct lv_list *lvl;
struct logical_volume *lv; struct logical_volume *lv;
struct physical_volume *pv; struct physical_volume *pv;
int count = 0; int count = 0;
list_iterate(lvh, &vg->lvs) { list_iterate_items(lvl, &vg->lvs) {
lv = list_item(lvh, struct lv_list)->lv; lv = lvl->lv;
/* Only request activation of snapshot origin devices */ /* Only request activation of snapshot origin devices */
if (lv_is_cow(lv)) if (lv_is_cow(lv))
@@ -56,8 +56,8 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd,
return count; return count;
} }
static void _vgchange_available(struct cmd_context *cmd, static int _vgchange_available(struct cmd_context *cmd,
struct volume_group *vg) struct volume_group *vg)
{ {
int lv_open, active; int lv_open, active;
int available = !strcmp(arg_str_value(cmd, available_ARG, "n"), "y"); int available = !strcmp(arg_str_value(cmd, available_ARG, "n"), "y");
@@ -66,7 +66,7 @@ static void _vgchange_available(struct cmd_context *cmd,
if (!available && (lv_open = lvs_in_vg_opened(vg))) { if (!available && (lv_open = lvs_in_vg_opened(vg))) {
log_error("Can't deactivate volume group \"%s\" with %d open " log_error("Can't deactivate volume group \"%s\" with %d open "
"logical volume(s)", vg->name, lv_open); "logical volume(s)", vg->name, lv_open);
return; return ECMD_FAILED;
} }
if (available && (active = lvs_in_vg_activated(vg))) if (available && (active = lvs_in_vg_activated(vg)))
@@ -83,28 +83,28 @@ static void _vgchange_available(struct cmd_context *cmd,
log_print("%d logical volume(s) in volume group \"%s\" now active", log_print("%d logical volume(s) in volume group \"%s\" now active",
lvs_in_vg_activated(vg), vg->name); lvs_in_vg_activated(vg), vg->name);
return; return ECMD_PROCESSED;
} }
static void _vgchange_resizeable(struct cmd_context *cmd, static int _vgchange_resizeable(struct cmd_context *cmd,
struct volume_group *vg) struct volume_group *vg)
{ {
int resizeable = !strcmp(arg_str_value(cmd, resizeable_ARG, "n"), "y"); int resizeable = !strcmp(arg_str_value(cmd, resizeable_ARG, "n"), "y");
if (resizeable && (vg->status & RESIZEABLE_VG)) { if (resizeable && (vg->status & RESIZEABLE_VG)) {
log_error("Volume group \"%s\" is already resizeable", log_error("Volume group \"%s\" is already resizeable",
vg->name); vg->name);
return; return ECMD_FAILED;
} }
if (!resizeable && !(vg->status & RESIZEABLE_VG)) { if (!resizeable && !(vg->status & RESIZEABLE_VG)) {
log_error("Volume group \"%s\" is already not resizeable", log_error("Volume group \"%s\" is already not resizeable",
vg->name); vg->name);
return; return ECMD_FAILED;
} }
if (!archive(vg)) if (!archive(vg))
return; return ECMD_FAILED;
if (resizeable) if (resizeable)
vg->status |= RESIZEABLE_VG; vg->status |= RESIZEABLE_VG;
@@ -112,52 +112,63 @@ static void _vgchange_resizeable(struct cmd_context *cmd,
vg->status &= ~RESIZEABLE_VG; vg->status &= ~RESIZEABLE_VG;
if (!vg_write(vg) || !vg_commit(vg)) if (!vg_write(vg) || !vg_commit(vg))
return; return ECMD_FAILED;
backup(vg); backup(vg);
log_print("Volume group \"%s\" successfully changed", vg->name); log_print("Volume group \"%s\" successfully changed", vg->name);
return; return ECMD_PROCESSED;
} }
static void _vgchange_logicalvolume(struct cmd_context *cmd, static int _vgchange_logicalvolume(struct cmd_context *cmd,
struct volume_group *vg) struct volume_group *vg)
{ {
uint32_t max_lv = arg_uint_value(cmd, logicalvolume_ARG, 0); uint32_t max_lv = arg_uint_value(cmd, logicalvolume_ARG, 0);
if (!(vg->status & RESIZEABLE_VG)) { if (!(vg->status & RESIZEABLE_VG)) {
log_error("Volume group \"%s\" must be resizeable " log_error("Volume group \"%s\" must be resizeable "
"to change MaxLogicalVolume", vg->name); "to change MaxLogicalVolume", vg->name);
return; return ECMD_FAILED;
} }
if (max_lv < vg->lv_count) { if (!(vg->fid->fmt->features & FMT_UNLIMITED_VOLS)) {
if (!max_lv)
max_lv = 255;
else if (max_lv > 255) {
log_error("MaxLogicalVolume limit is 255");
return ECMD_FAILED;
}
}
if (max_lv && max_lv < vg->lv_count) {
log_error("MaxLogicalVolume is less than the current number " log_error("MaxLogicalVolume is less than the current number "
"%d of logical volume(s) for \"%s\"", vg->lv_count, "%d of logical volume(s) for \"%s\"", vg->lv_count,
vg->name); vg->name);
return; return ECMD_FAILED;
} }
if (!archive(vg)) if (!archive(vg))
return; return ECMD_FAILED;
vg->max_lv = max_lv; vg->max_lv = max_lv;
if (!vg_write(vg) || !vg_commit(vg)) if (!vg_write(vg) || !vg_commit(vg))
return; return ECMD_FAILED;
backup(vg); backup(vg);
log_print("Volume group \"%s\" successfully changed", vg->name); log_print("Volume group \"%s\" successfully changed", vg->name);
return; return ECMD_PROCESSED;
} }
static int vgchange_single(struct cmd_context *cmd, const char *vg_name, static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
struct volume_group *vg, int consistent, struct volume_group *vg, int consistent,
void *handle) void *handle)
{ {
int r = 0;
if (!vg) { if (!vg) {
log_error("Unable to find volume group \"%s\"", vg_name); log_error("Unable to find volume group \"%s\"", vg_name);
return ECMD_FAILED; return ECMD_FAILED;
@@ -181,15 +192,15 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
} }
if (arg_count(cmd, available_ARG)) if (arg_count(cmd, available_ARG))
_vgchange_available(cmd, vg); r = _vgchange_available(cmd, vg);
if (arg_count(cmd, resizeable_ARG)) else if (arg_count(cmd, resizeable_ARG))
_vgchange_resizeable(cmd, vg); r = _vgchange_resizeable(cmd, vg);
if (arg_count(cmd, logicalvolume_ARG)) else if (arg_count(cmd, logicalvolume_ARG))
_vgchange_logicalvolume(cmd, vg); r = _vgchange_logicalvolume(cmd, vg);
return 0; return r;
} }
int vgchange(struct cmd_context *cmd, int argc, char **argv) int vgchange(struct cmd_context *cmd, int argc, char **argv)

View File

@@ -23,13 +23,13 @@
static int vgck_single(struct cmd_context *cmd, const char *vg_name, static int vgck_single(struct cmd_context *cmd, const char *vg_name,
struct volume_group *vg, int consistent, void *handle) struct volume_group *vg, int consistent, void *handle)
{ {
if (!consistent) { if (!vg) {
log_error("Volume group \"%s\" inconsistent", vg_name); log_error("Volume group \"%s\" not found", vg_name);
return ECMD_FAILED; return ECMD_FAILED;
} }
if (!vg) { if (!consistent) {
log_error("Volume group \"%s\" not found", vg_name); log_error("Volume group \"%s\" inconsistent", vg_name);
return ECMD_FAILED; return ECMD_FAILED;
} }
@@ -38,8 +38,7 @@ static int vgck_single(struct cmd_context *cmd, const char *vg_name,
return ECMD_FAILED; return ECMD_FAILED;
} }
/* FIXME: free */ return ECMD_PROCESSED;
return 0;
} }
int vgck(struct cmd_context *cmd, int argc, char **argv) int vgck(struct cmd_context *cmd, int argc, char **argv)

View File

@@ -25,13 +25,17 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
void *handle) void *handle)
{ {
struct physical_volume *pv, *existing_pv; struct physical_volume *pv, *existing_pv;
struct logical_volume *lv;
struct lv_list *lvl;
uint64_t size = 0; uint64_t size = 0;
struct list mdas; struct list mdas;
int pvmetadatacopies = 0; int pvmetadatacopies = 0;
uint64_t pvmetadatasize = 0; uint64_t pvmetadatasize = 0;
uint64_t pe_end = 0, pe_start = 0; uint64_t pe_end = 0, pe_start = 0;
struct list *pvh; struct pv_list *pvl;
int change_made = 0; int change_made = 0;
struct lvinfo info;
int active = 0;
if (!vg) { if (!vg) {
log_error("Unable to find volume group \"%s\"", vg_name); log_error("Unable to find volume group \"%s\"", vg_name);
@@ -62,6 +66,11 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
} }
if (cmd->fmt->features & FMT_MDAS) { if (cmd->fmt->features & FMT_MDAS) {
if (arg_sign_value(cmd, metadatasize_ARG, 0) == SIGN_MINUS) {
log_error("Metadata size may not be negative");
return EINVALID_CMD_LINE;
}
pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG,
UINT64_C(0)) * 2; UINT64_C(0)) * 2;
if (!pvmetadatasize) if (!pvmetadatasize)
@@ -83,8 +92,29 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
return ECMD_FAILED; return ECMD_FAILED;
} }
list_iterate(pvh, &vg->pvs) { /* Attempt to change any LVIDs that are too big */
existing_pv = list_item(pvh, struct pv_list)->pv; if (cmd->fmt->features & FMT_RESTRICTED_LVIDS) {
list_iterate_items(lvl, &vg->lvs) {
lv = lvl->lv;
if (lvnum_from_lvid(&lv->lvid) < MAX_RESTRICTED_LVS)
continue;
if (lv_info(lv, &info) && info.exists) {
log_error("Logical volume %s must be "
"deactivated before conversion.",
lv->name);
active++;
continue;
}
lvid_from_lvnum(&lv->lvid, &lv->vg->id, find_free_lvnum(lv));
}
}
if (active)
return ECMD_FAILED;
list_iterate_items(pvl, &vg->pvs) {
existing_pv = pvl->pv;
pe_start = existing_pv->pe_start; pe_start = existing_pv->pe_start;
pe_end = existing_pv->pe_count * existing_pv->pe_size pe_end = existing_pv->pe_count * existing_pv->pe_size
@@ -148,7 +178,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
if (test_mode()) { if (test_mode()) {
log_verbose("Test mode: Skipping metadata writing for VG %s in" log_verbose("Test mode: Skipping metadata writing for VG %s in"
" format %s", vg_name, cmd->fmt->name); " format %s", vg_name, cmd->fmt->name);
return 0; return ECMD_PROCESSED;
} }
log_verbose("Writing metadata for VG %s using format %s", vg_name, log_verbose("Writing metadata for VG %s using format %s", vg_name,
@@ -163,7 +193,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
backup(vg); backup(vg);
return 0; return ECMD_PROCESSED;
} }
int vgconvert(struct cmd_context *cmd, int argc, char **argv) int vgconvert(struct cmd_context *cmd, int argc, char **argv)

Some files were not shown because too many files have changed in this diff Show More