1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-20 05:44:20 +03:00

Compare commits

...

68 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
111 changed files with 2076 additions and 920 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
the userland LVM tools designed for the new device-mapper for
the Linux kernel.
This directory contains LVM2, the new version of the userland LVM
tools designed for the new device-mapper for the Linux kernel.
The device-mapper needs to be installed before compiling these LVM2 tools.
For more information about LVM2 read the WHATS_NEW file.
Installation instructions are in INSTALL.
This is beta-quality software, released for testing purposes only.
There is no warranty - see COPYING and COPYING.LIB.
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
Mailing list for discussion/bug reports etc.
lvm-devel@sistina.com
Subscribe from http://lists.sistina.com/mailman/listinfo/lvm-devel
linux-lvm@sistina.com
Subscribe from http://lists.sistina.com/mailman/listinfo/linux-lvm

View File

@@ -1 +1 @@
2.00.03-cvs (2003-07-13)
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
=========================
A pvmove implementation is now available for the new metadata format.
@@ -25,6 +41,7 @@ to provide us with diagnostic information:
log {
file="/tmp/lvm2.log"
level=7
activation=1
}
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"
ac_help="$ac_help
--disable-devmapper Disable device-mapper interaction"
ac_help="$ac_help
--disable-o_direct Disable O_DIRECT"
# Initialize some variables set by options.
# 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.
for ac_prog in mawk gawk nawk awk
for ac_prog in gawk mawk nawk awk
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
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
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -598,7 +600,7 @@ done
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
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
echo $ac_n "(cached) $ac_c" 1>&6
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.
set dummy cc; ac_word=$2
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
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -679,7 +681,7 @@ fi
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
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
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -711,7 +713,7 @@ fi
fi
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
# 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
#line 726 "configure"
#line 728 "configure"
#include "confdefs.h"
main(){return(0);}
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
# If we can't run a trivial program, we are probably using a cross compiler.
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; }
fi
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
cross_compiling=$ac_cv_prog_cc_cross
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
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -767,7 +769,7 @@ else
yes;
#endif
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
else
ac_cv_prog_gcc=no
@@ -786,7 +788,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
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
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -829,7 +831,7 @@ fi
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./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 "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 eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
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'
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
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -903,7 +905,7 @@ else
fi
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_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
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.
set dummy ranlib; ac_word=$2
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
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -965,12 +967,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 974 "configure"
#line 976 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_hdr>
@@ -978,7 +980,7 @@ int main() {
DIR *dirp = 0;
; return 0; }
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*
eval "ac_cv_header_dirent_$ac_safe=yes"
else
@@ -1003,7 +1005,7 @@ done
# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
if test $ac_header_dirent = dirent.h; then
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_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1011,7 +1013,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldir $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1015 "configure"
#line 1017 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1022,7 +1024,7 @@ int main() {
opendir()
; return 0; }
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*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1044,7 +1046,7 @@ fi
else
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_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1052,7 +1054,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lx $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1056 "configure"
#line 1058 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1063,7 +1065,7 @@ int main() {
opendir()
; return 0; }
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*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1086,7 +1088,7 @@ fi
fi
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.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -1101,13 +1103,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
#line 1105 "configure"
#line 1107 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
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}\$"`
if test -z "$ac_err"; then
:
@@ -1118,13 +1120,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
#line 1122 "configure"
#line 1124 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
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}\$"`
if test -z "$ac_err"; then
:
@@ -1135,13 +1137,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
#line 1139 "configure"
#line 1141 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
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}\$"`
if test -z "$ac_err"; then
:
@@ -1166,12 +1168,12 @@ fi
echo "$ac_t""$CPP" 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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1175 "configure"
#line 1177 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1179,7 +1181,7 @@ else
#include <float.h>
EOF
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}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1196,7 +1198,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
#line 1200 "configure"
#line 1202 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1214,7 +1216,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
#line 1218 "configure"
#line 1220 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1235,7 +1237,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
#line 1239 "configure"
#line 1241 "configure"
#include "confdefs.h"
#include <ctype.h>
#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); }
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
:
else
@@ -1273,17 +1275,17 @@ for ac_hdr in fcntl.h malloc.h sys/ioctl.h unistd.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1282 "configure"
#line 1284 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
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}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1311,18 +1313,18 @@ done
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1320 "configure"
#line 1322 "configure"
#include "confdefs.h"
int main() {
/* 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. */
char const *const *ccp;
char **p;
@@ -1365,7 +1367,7 @@ ccp = (char const *const *) p;
; return 0; }
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*
ac_cv_c_const=yes
else
@@ -1386,21 +1388,21 @@ EOF
fi
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
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
cat > conftest.$ac_ext <<EOF
#line 1397 "configure"
#line 1399 "configure"
#include "confdefs.h"
int main() {
} int $ac_kw foo() {
} $ac_kw foo() {
; return 0; }
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*
ac_cv_c_inline=$ac_kw; break
else
@@ -1426,12 +1428,12 @@ EOF
esac
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1435 "configure"
#line 1437 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1459,12 +1461,12 @@ EOF
fi
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1468 "configure"
#line 1470 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1492,12 +1494,12 @@ EOF
fi
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1501 "configure"
#line 1503 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1525,12 +1527,12 @@ EOF
fi
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1534 "configure"
#line 1536 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -1538,7 +1540,7 @@ int main() {
struct stat s; s.st_rdev;
; return 0; }
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*
ac_cv_struct_st_rdev=yes
else
@@ -1559,12 +1561,12 @@ EOF
fi
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1568 "configure"
#line 1570 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
@@ -1573,7 +1575,7 @@ int main() {
struct tm *tp;
; return 0; }
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*
ac_cv_header_time=yes
else
@@ -1622,7 +1624,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
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
case "$host_alias" in
@@ -1643,7 +1645,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 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
case "$target_alias" in
@@ -1661,7 +1663,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$target" 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
case "$build_alias" in
@@ -1784,19 +1786,33 @@ if test x$DEVMAPPER = xyes; then
CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT"
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 ];
then exec_prefix="";
fi;
if test $ac_cv_prog_gcc = yes; then
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
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_pattern="Autoconf.*'x'"
cat > conftest.$ac_ext <<EOF
#line 1800 "configure"
#line 1816 "configure"
#include "confdefs.h"
#include <sgtty.h>
Autoconf TIOCGETP
@@ -1814,7 +1830,7 @@ rm -f conftest*
if test $ac_cv_prog_gcc_traditional = no; then
cat > conftest.$ac_ext <<EOF
#line 1818 "configure"
#line 1834 "configure"
#include "confdefs.h"
#include <termio.h>
Autoconf TCGETA
@@ -1836,12 +1852,12 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
fi
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1845 "configure"
#line 1861 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
@@ -1858,7 +1874,7 @@ int main() {
int i;
; return 0; }
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*
ac_cv_type_signal=void
else
@@ -1877,12 +1893,12 @@ EOF
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1886 "configure"
#line 1902 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vprintf(); below. */
@@ -1905,7 +1921,7 @@ vprintf();
; return 0; }
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*
eval "ac_cv_func_vprintf=yes"
else
@@ -1929,12 +1945,12 @@ fi
if test "$ac_cv_func_vprintf" != yes; then
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1938 "configure"
#line 1954 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char _doprnt(); below. */
@@ -1957,7 +1973,7 @@ _doprnt();
; return 0; }
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*
eval "ac_cv_func__doprnt=yes"
else
@@ -1984,12 +2000,12 @@ fi
for ac_func in mkdir rmdir uname
do
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1993 "configure"
#line 2009 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2012,7 +2028,7 @@ $ac_func();
; return 0; }
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*
eval "ac_cv_func_$ac_func=yes"
else
@@ -2040,14 +2056,14 @@ done
if test x$READLINE = xyes; then
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
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_func_search_save_LIBS="$LIBS"
ac_cv_search_tgetent="no"
cat > conftest.$ac_ext <<EOF
#line 2051 "configure"
#line 2067 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2058,7 +2074,7 @@ int main() {
tgetent()
; return 0; }
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*
ac_cv_search_tgetent="none required"
else
@@ -2069,7 +2085,7 @@ rm -f conftest*
test "$ac_cv_search_tgetent" = "no" && for i in ncurses curses termcap termlib; do
LIBS="-l$i $ac_func_search_save_LIBS"
cat > conftest.$ac_ext <<EOF
#line 2073 "configure"
#line 2089 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2080,7 +2096,7 @@ int main() {
tgetent()
; return 0; }
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*
ac_cv_search_tgetent="-l$i"
break
@@ -2113,7 +2129,7 @@ fi
fi
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_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2121,7 +2137,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldl $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2125 "configure"
#line 2141 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2132,7 +2148,7 @@ int main() {
dlopen()
; return 0; }
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*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2163,17 +2179,17 @@ for ac_hdr in getopt.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2172 "configure"
#line 2188 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
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}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -2202,7 +2218,7 @@ done
if test x$READLINE = xyes; then
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_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2210,7 +2226,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lreadline $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2214 "configure"
#line 2230 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2221,7 +2237,7 @@ int main() {
readline()
; return 0; }
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*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2258,12 +2274,12 @@ package as well (which may be called readline-devel or something similar).
fi
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
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2267 "configure"
#line 2283 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char rl_completion_matches(); below. */
@@ -2286,7 +2302,7 @@ rl_completion_matches();
; return 0; }
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*
eval "ac_cv_func_rl_completion_matches=yes"
else
@@ -2643,3 +2659,10 @@ chmod +x $CONFIG_STATUS
rm -fr confdefs* $ac_clean_files
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"
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
if [[ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]];
then exec_prefix="";
@@ -203,3 +211,10 @@ test/format1/Makefile \
test/regex/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/list.h
../lib/datastruct/lvm-types.h
../lib/datastruct/str_list.h
../lib/device/dev-cache.h
../lib/device/device.h
../lib/display/display.h
@@ -17,11 +18,11 @@
../lib/filters/filter-regex.h
../lib/filters/filter.h
../lib/format1/format1.h
../lib/format1/lvm1-label.h
../lib/format_text/format-text.h
../lib/label/label.h
../lib/locking/locking.h
../lib/log/log.h
../lib/metadata/lv_alloc.h
../lib/metadata/metadata.h
../lib/mm/dbg_malloc.h
../lib/mm/memlock.h

View File

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

View File

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

View File

@@ -5,12 +5,14 @@
*/
#include "lib.h"
#include "str_list.h"
#include "dev_manager.h"
#include "pool.h"
#include "hash.h"
#include "lvm-string.h"
#include "fs.h"
#include "defaults.h"
#include "toolcontext.h"
#include <libdevmapper.h>
#include <limits.h>
@@ -41,6 +43,8 @@
*
*/
#define MAX_TARGET_PARAMSIZE 50000
enum {
ACTIVE = 0,
RELOAD = 1,
@@ -153,33 +157,6 @@ static inline void _clear_flag(struct dev_layer *dl, int 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
* 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,
struct pool *mem, char **uuid_out)
int mknodes, struct pool *mem, char **uuid_out)
{
int r = 0;
struct dm_task *dmt;
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;
return 0;
}
@@ -344,15 +324,15 @@ static int _info_run(const char *name, const char *uuid, struct dm_info *info,
return r;
}
static int _info(const char *name, const char *uuid, struct dm_info *info,
struct pool *mem, char **uuid_out)
static int _info(const char *name, const char *uuid, int mknodes,
struct dm_info *info, struct pool *mem, char **uuid_out)
{
if (uuid && *uuid && _info_run(NULL, uuid, info, mem, uuid_out)
&& info->exists)
if (!mknodes && uuid && *uuid &&
_info_run(NULL, uuid, info, 0, mem, uuid_out) && info->exists)
return 1;
if (name)
return _info_run(name, NULL, info, mem, uuid_out);
return _info_run(name, NULL, info, mknodes, mem, uuid_out);
return 0;
}
@@ -529,7 +509,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
else
*percent = 100;
log_debug("Mirror percent: %f", *percent);
log_debug("LV percent: %f", *percent);
r = 1;
out:
@@ -765,10 +745,10 @@ static int _resume(struct dev_layer *dl)
* Emit a target for a given segment.
* FIXME: tidy this function.
*/
static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
struct lv_segment *seg)
static int _emit_target_line(struct dev_manager *dm, struct dm_task *dmt,
struct lv_segment *seg, char *params,
size_t paramsize)
{
char params[1024];
uint64_t esize = seg->lv->vg->extent_size;
uint32_t s, start_area = 0u, areas = seg->area_count;
int w = 0, tw = 0;
@@ -794,7 +774,7 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
target = "linear";
else if (areas > 1) {
target = "striped";
if ((tw = lvm_snprintf(params, sizeof(params), "%u %u ",
if ((tw = lvm_snprintf(params, paramsize, "%u %u ",
areas, seg->stripe_size)) < 0)
goto error;
w = tw;
@@ -820,8 +800,7 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
break;
}
target = "mirror";
if ((tw = lvm_snprintf(params, sizeof(params),
"core 1 %u %u ",
if ((tw = lvm_snprintf(params, paramsize, "core 1 %u %u ",
dm->mirror_region_size, areas)) < 0)
goto error;
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 &&
(!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))
tw = lvm_snprintf(params + w, sizeof(params) - w,
tw = lvm_snprintf(params + w, paramsize - w,
"%s 0%s", dm->stripe_filler,
trailing_space);
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",
dev_name(seg->area[s].u.pv.pv->dev),
(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);
return 0;
}
tw = lvm_snprintf(params + w, sizeof(params) - w,
tw = lvm_snprintf(params + w, paramsize - w,
"%s %" PRIu64 "%s", devbuf,
esize * seg->area[s].u.lv.le,
trailing_space);
@@ -877,7 +856,37 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
return 1;
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;
}
@@ -985,8 +994,8 @@ static int _populate_snapshot(struct dev_manager *dm,
return 0;
}
if (snprintf(params, sizeof(params), "%s %s P %d",
devbufo, devbufc, s->chunk_size) == -1) {
if (lvm_snprintf(params, sizeof(params), "%s %s P %d",
devbufo, devbufc, s->chunk_size) == -1) {
stack;
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,
struct dm_info *info)
int mknodes, struct dm_info *info)
{
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.
*/
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;
return 0;
}
@@ -1162,7 +1171,7 @@ static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
dl->name = 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;
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++) {
if (seg->area[s].type != AREA_LV)
continue;
if (!_pre_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem,
seg->area[s].u.lv.
lv->lvid.s, NULL))) {
if (!str_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem,
seg->area[s].u.lv.
lv->lvid.s, NULL))) {
stack;
return 0;
}
@@ -1296,8 +1305,8 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
_set_flag(dlr, REMOVE);
/* add the dependency on the real device */
if (!_pre_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, dlr->dlid))) {
if (!str_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, dlr->dlid))) {
stack;
return 0;
}
@@ -1330,8 +1339,8 @@ static int _expand_origin_real(struct dev_manager *dm,
_set_flag(dl, TOPLEVEL);
/* add the dependency on the real device */
if (!_pre_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, real_dlid))) {
if (!str_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, real_dlid))) {
stack;
return 0;
}
@@ -1378,6 +1387,7 @@ static int _expand_snapshot(struct dev_manager *dm, struct logical_volume *lv,
dl->populate = _populate_vanilla;
_clear_flag(dl, VISIBLE);
_clear_flag(dl, TOPLEVEL);
_set_flag(dl, READWRITE);
cow_dlid = dl->dlid;
@@ -1390,21 +1400,21 @@ static int _expand_snapshot(struct dev_manager *dm, struct logical_volume *lv,
_set_flag(dl, TOPLEVEL);
/* add the dependency on the cow device */
if (!_pre_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, cow_dlid))) {
if (!str_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, cow_dlid))) {
stack;
return 0;
}
/* add the dependency on the real origin device */
if (!_pre_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem, s->origin->lvid.s, "real"))) {
if (!str_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem, s->origin->lvid.s, "real"))) {
stack;
return 0;
}
/* 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;
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) &&
!_resume(dl)) {
if (dl->info.exists & !_get_flag(dl, SUSPENDED) && !_resume(dl)) {
stack;
return 0;
}
@@ -1739,8 +1748,8 @@ static int _populate_pre_suspend_lists(struct dev_manager *dm)
continue;
}
if (!_pre_list_add(dm->mem, &dep->pre_create,
dl->dlid)) {
if (!str_list_add(dm->mem, &dep->pre_create,
dl->dlid)) {
stack;
return 0;
}
@@ -1756,8 +1765,8 @@ static int _populate_pre_suspend_lists(struct dev_manager *dm)
continue;
}
if (!_pre_list_add(dm->mem, &dep->pre_suspend,
dl->dlid)) {
if (!str_list_add(dm->mem, &dep->pre_suspend,
dl->dlid)) {
stack;
return 0;
}
@@ -2175,6 +2184,24 @@ int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv)
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)
{
dm_lib_exit();

View File

@@ -28,7 +28,7 @@ void dev_manager_exit(void);
* unsuspended until the snapshot is also created.)
*/
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,
struct logical_volume *lv, float *percent);
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_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.
*/

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)) {
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;
}
@@ -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);
}
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,
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,
"", "");

View File

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

22
lib/cache/lvmcache.c vendored
View File

@@ -13,6 +13,7 @@
#include "metadata.h"
#include "filter.h"
#include "memlock.h"
#include "str_list.h"
static struct hash_table *_pvid_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 *vgih, *vgnames;
struct str_list *sl;
struct list *vgnames;
struct lvmcache_vginfo *vgi;
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");
return NULL;
}
list_init(vgnames);
list_iterate(vgih, &_vginfos) {
if (!(sl = pool_alloc(cmd->mem, sizeof(*sl)))) {
list_iterate_items(vgi, &_vginfos) {
if (!str_list_add(cmd->mem, vgnames,
pool_strdup(cmd->mem, vgi->vgname))) {
log_error("strlist allocation failed");
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;

View File

@@ -7,9 +7,9 @@
#ifndef _LVM_ERRORS_H
#define _LVM_ERRORS_H
#define EINVALID_CMD_LINE 1
#define ENO_SUCH_CMD 3
#define ECMD_PROCESSED 4
#define ECMD_PROCESSED 1
#define ENO_SUCH_CMD 2
#define EINVALID_CMD_LINE 3
#define ECMD_FAILED 5
#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 r = 1;
FILE *fp = fopen(file, "w");
if (!fp) {
FILE *fp;
if (!file) {
fp = stdout;
file = "stdout";
} else if (!(fp = fopen(file, "w"))) {
log_sys_error("open", file);
return 0;
}
log_verbose("Dumping configuration to %s", file);
if (!_write_config(cf->root, fp, 0)) {
stack;
log_error("Failure while writing configuration");
r = 0;
}
fclose(fp);
if (fp != stdout)
fclose(fp);
return r;
}
@@ -502,7 +510,7 @@ static struct config_value *_value(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);
if (!v)
@@ -637,6 +645,8 @@ static void _get_token(struct parser *p, int tok_prev)
case '7':
case '8':
case '9':
case '+':
case '-':
if (values_allowed) {
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);
}
#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) \
((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 */
#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

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)
{
_check_for_open_devices();
pool_destroy(_cache.mem);
if (_cache.names)
_check_for_open_devices();
if (_cache.mem) {
pool_destroy(_cache.mem);
_cache.mem = NULL;
}
if (_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)

View File

@@ -30,11 +30,15 @@
# define BLKGETSIZE64 DKIOCGETBLOCKCOUNT
# define BLKFLSBUF DKIOCSYNCHRONIZECACHE
# define BLKSIZE_SHIFT 0
#endif
#ifdef O_DIRECT_SUPPORT
# ifndef O_DIRECT
# define O_DIRECT 0
# error O_DIRECT support configured but O_DIRECT definition not found in headers
# endif
#endif
/* FIXME Use _llseek for 64-bit
_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) {
@@ -151,7 +155,7 @@ static int _aligned_io(struct device_area *where, void *buffer,
}
if (!block_size)
block_size = SECTOR_SIZE * 2;
block_size = getpagesize();
_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;
}
#ifdef O_DIRECT_SUPPORT
if (direct)
flags |= O_DIRECT;
#endif
if ((dev->fd = open(name, flags, 0777)) < 0) {
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;
return 0;
}
#if !O_DIRECT
#ifndef O_DIRECT_SUPPORT
if (!(dev->flags & DEV_REGULAR))
dev_flush(dev);
#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) {
log_error("Attempt to close device '%s' "
"which is not open.", dev_name(dev));
return 0;
}
#if !O_DIRECT
#ifndef O_DIRECT_SUPPORT
if (dev->flags & DEV_ACCESSED_W)
dev_flush(dev);
#endif
/* 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);
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)
{
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);
dev->end += (uint64_t) len;
#if !O_DIRECT
#ifndef O_DIRECT_SUPPORT
dev_flush(dev);
#endif
return r;
@@ -455,6 +473,8 @@ int dev_zero(struct device *dev, uint64_t offset, size_t len)
len -= s;
if (!len)
break;
offset += s;
}
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_flags(struct device *dev, int flags, int append, int quiet);
int dev_close(struct device *dev);
int dev_close_immediate(struct device *dev);
void dev_close_all(void);
static inline int dev_fd(struct device *dev)

View File

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

View File

@@ -22,7 +22,7 @@ TARGETS=liblvm2format1.so
include ../../make.tmpl
install: libformat1.so
install: liblvm2format1.so
$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/liblvm2format1.so.$(LIB_VERSION)
$(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
*/
void munge_exported_vg(struct pv_disk *pvd, struct vg_disk *vgd)
void munge_exported_vg(struct pv_disk *pvd)
{
int l;
size_t s;
/* Return if PV not in a VG or VG not exported */
if ((!*pvd->vg_name) || (vgd && !(vgd->vg_status & VG_EXPORTED)))
/* Return if PV not in a VG */
if ((!*pvd->vg_name))
return;
l = strlen(pvd->vg_name);
s = sizeof(EXPORTED_TAG);
if (!strncmp(pvd->vg_name + l - s + 1, EXPORTED_TAG, s))
pvd->vg_name[l - s + 1] = '\0';
pvd->pv_status |= VG_EXPORTED;
if (!strncmp(pvd->vg_name + l - s + 1, EXPORTED_TAG, s)) {
pvd->vg_name[l - s + 1] = '\0';
pvd->pv_status |= VG_EXPORTED;
}
}
static struct disk_list *__read_disk(const struct format_type *fmt,
@@ -296,7 +296,7 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
}
/* If VG is exported, set VG name back to the real name */
munge_exported_vg(&dl->pvd, &dl->vgd);
munge_exported_vg(&dl->pvd);
if (!(info = lvmcache_add(fmt->labeller, dl->pvd.pv_uuid, dev,
dl->pvd.vg_name, NULL)))

View File

@@ -15,6 +15,8 @@
#define MAX_LV 256
#define MAX_VG 99
#define LVM_BLK_MAJOR 58
#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */
#define MIN_PE_SIZE (8192L >> SECTOR_SHIFT) /* 8 KB in sectors */
#define MAX_PE_SIZE (16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L)
@@ -224,7 +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_pv_act(struct list *pvds);
void munge_exported_vg(struct pv_disk *pvd, struct vg_disk *vgd);
void munge_exported_vg(struct pv_disk *pvd);
/* blech */
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,

View File

@@ -16,6 +16,8 @@
#include "lvm1-label.h"
#include "format1.h"
#define FMT_LVM1_NAME "lvm1"
/* VG consistency checks */
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 */
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",
pv_count, dl->pvd.vg_name, dl->vgd.pv_cur);
pv_count, first->pvd.vg_name, first->vgd.pv_cur);
if (!partial_mode())
return 0;
*partial = 1;
@@ -332,32 +334,12 @@ static int _pv_setup(const struct format_type *fmt,
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)
{
uint64_t max_size = UINT_MAX;
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) {
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)
{
/* 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;
if (vg->max_pv >= MAX_PV)
if (!vg->max_pv || vg->max_pv >= MAX_PV)
vg->max_pv = MAX_PV - 1;
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->name = FMT_LVM1_NAME;
fmt->alias = NULL;
fmt->features = 0;
fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE;
fmt->private = NULL;
if (!(fmt->labeller = lvm1_labeller_create(fmt))) {

View File

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

View File

@@ -339,6 +339,8 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
if (lv->status & FIXED_MINOR) {
lvd->lv_status |= LV_PERSISTENT_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;

View File

@@ -9,6 +9,7 @@
#include "hash.h"
#include "pool.h"
#include "disk-rep.h"
#include "lv_alloc.h"
/*
* 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;
}
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)
{
uint32_t le = 0;
struct lv_segment *seg;
while (le < lvm->lv->le_count) {
seg = _alloc_seg(mem, 1);
seg = alloc_lv_segment(mem, 1);
seg->lv = lvm->lv;
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;
while (le < len) {
if (!(seg = _alloc_seg(mem, lvm->stripes))) {
if (!(seg = alloc_lv_segment(mem, lvm->stripes))) {
stack;
return 0;
}

View File

@@ -51,9 +51,11 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
struct pv_disk *pvd = (struct pv_disk *) buf;
struct lvmcache_info *info;
munge_exported_vg(pvd, NULL);
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;
}
*label = info->label;
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.
*/
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)
{
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)
return 0;
strncpy(vg, filename, vg_len);
vg[vg_len] = '\0';
strncpy(vgname, filename, vg_len);
vgname[vg_len] = '\0';
return 1;
}
@@ -121,10 +121,10 @@ static char *_join(struct pool *mem, const char *dir, const char *name)
* Returns a list of archive_files.
*/
static struct list *_scan_archive(struct pool *mem,
const char *vg, const char *dir)
const char *vgname, const char *dir)
{
int i, count, ix;
char vg_name[64], *path;
char vgname_found[64], *path;
struct dirent **dirent;
struct archive_file *af;
struct list *results;
@@ -148,12 +148,12 @@ static struct list *_scan_archive(struct pool *mem,
continue;
/* check the name is the correct format */
if (!_split_vg(dirent[i]->d_name, vg_name, sizeof(vg_name),
&ix))
if (!_split_vg(dirent[i]->d_name, vgname_found,
sizeof(vgname_found), &ix))
continue;
/* is it the vg we're interested in ? */
if (strcmp(vg, vg_name))
if (strcmp(vgname, vgname_found))
continue;
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;
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)) ||
!(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;
}
log_print("description:\t%s", desc ? desc : "<No description>");
log_print("time:\t\t%s", ctime(&when));
log_print("VG name: \t%s", vg->name);
log_print("Description:\t%s", desc ? desc : "<No description>");
log_print("Backup Time:\t%s", ctime(&when));
pool_free(cmd->mem, vg);
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 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);
return 0;
}
if (list_empty(archives))
log_print("No archives found.");
log_print("No archives found in %s.", dir);
list_iterate(ah, archives) {
af = list_item(ah, struct archive_file);
_display_archive(cmd, af);
log_print(" ");
}
pool_free(cmd->mem, archives);
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);
list_iterate(pvh, &vg->pvs) {
pv = list_item(pvh, struct pv_list)->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)
{
struct list *lvh, *segh;
struct list *lvh;
struct logical_volume *lv;
struct lv_segment *seg;
char buffer[256];
@@ -571,9 +570,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
f->nl(f);
seg_count = 1;
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct lv_segment);
list_iterate_items(seg, &lv->segments) {
if (!_print_segment(f, vg, seg_count++, seg)) {
stack;
return 0;

View File

@@ -63,23 +63,6 @@ static struct flag *_get_flags(int type)
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,
* 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;
}
if (!_emit(&buffer, &size, "["))
if (!emit_to_buffer(&buffer, &size, "["))
return 0;
for (f = 0; flags[f].mask; f++) {
if (status & flags[f].mask) {
if (!first) {
if (!_emit(&buffer, &size, ", "))
if (!emit_to_buffer(&buffer, &size, ", "))
return 0;
} else
first = 0;
if (!_emit(&buffer, &size, "\"%s\"",
flags[f].description))
if (!emit_to_buffer(&buffer, &size, "\"%s\"",
flags[f].description))
return 0;
status &= ~flags[f].mask;
}
}
if (!_emit(&buffer, &size, "]"))
if (!emit_to_buffer(&buffer, &size, "]"))
return 0;
if (status)

View File

@@ -28,6 +28,9 @@
#include <dirent.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
*fmt, const char *vgname,
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 */
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 */
mda_adjustment = (mda_size1 + start1) % alignment;
if (mda_adjustment)

View File

@@ -11,9 +11,6 @@
#include "metadata.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
* 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.
*/
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.

View File

@@ -12,6 +12,7 @@
#include "hash.h"
#include "toolcontext.h"
#include "lvmcache.h"
#include "lv_alloc.h"
typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
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) +
(sizeof(seg->area[0]) * area_count)))) {
stack;
if (!(seg = alloc_lv_segment(mem, area_count))) {
log_error("Segment allocation failed");
return 0;
}

View File

@@ -56,8 +56,8 @@ static int _write(struct label *label, char *buf)
}
/* NULL-termination */
pvh_dlocn_xl->offset = xlate64(0);
pvh_dlocn_xl->size = xlate64(0);
pvh_dlocn_xl->offset = xlate64(UINT64_C(0));
pvh_dlocn_xl->size = xlate64(UINT64_C(0));
pvh_dlocn_xl++;
/* List of metadata area header locations */
@@ -74,8 +74,8 @@ static int _write(struct label *label, char *buf)
}
/* NULL-termination */
pvh_dlocn_xl->offset = xlate64(0);
pvh_dlocn_xl->size = xlate64(0);
pvh_dlocn_xl->offset = xlate64(UINT64_C(0));
pvh_dlocn_xl->size = xlate64(UINT64_C(0));
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;
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) {
log_error("Label sector %" PRIu64 " beyond range (%ld)",
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->offset_xl = xlate32(sizeof(*lh));
if (!label->labeller->ops->write(label, buf))
if (!label->labeller->ops->write(label, buf)) {
stack;
return 0;
}
lh->crc_xl = xlate32(calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE -
((void *) &lh->offset_xl - (void *) lh)));
@@ -327,7 +334,7 @@ int label_verify(struct device *dev)
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)

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
*/
#define LCK_TYPE_MASK 0x000000FF
#define LCK_TYPE_MASK 0x00000007
#define LCK_NULL 0x00000000 /* LCK$_NLMODE */
#define LCK_READ 0x00000001 /* LCK$_CRMODE */
@@ -41,20 +41,20 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
/* LCK$_PRMODE */
#define LCK_WRITE 0x00000004 /* LCK$_PWMODE */
#define LCK_EXCL 0x00000005 /* LCK$_EXMODE */
#define LCK_UNLOCK 0x00000010 /* This is ours */
#define LCK_UNLOCK 0x00000006 /* This is ours */
/*
* Lock scope
*/
#define LCK_SCOPE_MASK 0x0000FF00
#define LCK_SCOPE_MASK 0x00000008
#define LCK_VG 0x00000000
#define LCK_LV 0x00000100
#define LCK_LV 0x00000008
/*
* Lock bits
*/
#define LCK_NONBLOCK 0x00010000 /* Don't block waiting for lock? */
#define LCK_HOLD 0x00020000 /* Hold lock when lock_vol returns? */
#define LCK_NONBLOCK 0x00000010 /* Don't block waiting for lock? */
#define LCK_HOLD 0x00000020 /* Hold lock when lock_vol returns? */
/*
* 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 "lvm-string.h"
#include "toolcontext.h"
#include "lv_alloc.h"
/*
* 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;
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)
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.");
return 0;
}
@@ -188,7 +189,7 @@ static int _alloc_linear_area(struct logical_volume *lv, uint32_t *ix,
if (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.");
return 0;
}
@@ -224,7 +225,7 @@ static int _alloc_mirrored_area(struct logical_volume *lv, uint32_t *ix,
if (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.");
return 0;
}
@@ -477,7 +478,7 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
struct logical_volume *lv;
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 "
"in volume group %s", vg->max_lv, vg->name);
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;
if (!lock_vol(cmd, lv->lvid.s, flags)) {
log_error("Failed to lock %s", lv->name);
/* FIXME Only unlock the locked ones */
unlock_lvs(cmd, lvs);
list_uniterate(lvh, lvs, lvh) {
lv = list_item(lvh, struct lv_list)->lv;
unlock_lv(cmd, lv->lvid.s);
}
return 0;
}
}
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 "metadata.h"
#include "toolcontext.h"
#include "lv_alloc.h"
/*
* Returns success if the segments were
* successfully merged. If the do merge, 'first'
* will be adjusted to contain both areas.
* Test whether two segments could be merged by the current merging code
*/
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;
unsigned s;
if (!first ||
(first->type != SEG_STRIPED) ||
(first->type != second->type) ||
/* FIXME Relax the seg type restriction */
if (!first || !second ||
(first->type != SEG_STRIPED) || (second->type != first->type) ||
(first->area_count != second->area_count) ||
(first->stripe_size != second->stripe_size))
return 0;
for (s = 0; s < first->area_count; s++) {
width = first->area_len;
/* FIXME Relax this to first type != second type ? */
if (first->area[s].type != AREA_PV ||
second->area[s].type != AREA_PV)
/* FIXME Relax this to first area type != second area type */
/* plus the additional AREA_LV checks needed */
if ((first->area[s].type != AREA_PV) ||
(second->area[s].type != AREA_PV))
return 0;
width = first->area_len;
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))
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->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)
{
struct list *segh;
struct list *segh, *t;
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);
if (_merge(prev, current))
@@ -61,7 +78,113 @@ int lv_merge_segments(struct logical_volume *lv)
return 1;
}
/*
* Verify that an LV's segments are consecutive, complete and don't overlap.
*/
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;
}
/*
* 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;
}
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' "
"holds max %d physical volume(s).", pv_name,
vg->name, vg->max_pv);
@@ -217,7 +217,8 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
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.",
vg_name);
goto bad;
@@ -463,6 +464,19 @@ int vg_write(struct volume_group *vg)
/* Write to each copy of the metadata area */
list_iterate(mdah, &vg->fid->metadata_areas) {
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)) {
stack;
/* Revert */
@@ -666,7 +680,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
if ((correct_vg->status & PVMOVE) && !pvmove_mode()) {
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 "
"vgcfgrestore.");
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)
{
// const char *vgname;
// struct list *vgnames, *slh;
const char *vgname;
struct list *vgnames, *slh;
struct volume_group *vg;
struct lvmcache_vginfo *vginfo;
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 Disabled vgrenames while active for now because we aren't
* allowed to do a full scan here any more. */
/*** FIXME Cope with vgrename here
// The slow way - full scan required to cope with vgrename
if (!(vgnames = get_vgs(cmd, 1))) {
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;
***/
}
/* 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,
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) {
log_error("Assertion failed: can't _pv_write non-orphan PV "
"(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 PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
/* Various flags */
/* Note that the bits no longer necessarily correspond to LVM1 disk format */
@@ -50,7 +51,11 @@
/* Format features flags */
#define FMT_SEGMENTS 0x00000001 /* Arbitrary segment params? */
#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 {
ALLOC_DEFAULT,
ALLOC_NEXT_FREE,
@@ -468,6 +473,11 @@ int lv_check_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.
*/
@@ -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 logical_volume *lv);
uint32_t find_free_lvnum(struct logical_volume *lv);
static inline int validate_name(const char *n)
{
register char c;

View File

@@ -29,3 +29,20 @@ int lvm_snprintf(char *buf, size_t bufsize, const char *format, ...)
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 emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...);
#endif

View File

@@ -34,6 +34,12 @@ void *malloc_aux(size_t s, const char *file, int line)
struct memblock *nb;
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))) {
log_error("couldn't allocate any memory, size = %" PRIuPTR, s);
return 0;

View File

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

View File

@@ -13,31 +13,43 @@
# define xlate16(x) __cpu_to_le16((x))
# define xlate32(x) __cpu_to_le32((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
# include <machine/endian.h>
# if !defined(BYTE_ORDER) || \
(BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN)
# error "Undefined or unrecognised BYTE_ORDER";
# 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
# define xlate16(x) (x)
# define xlate32(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
# 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)
# define xlate16(x) __xlate16(x)
# define xlate32(x) __xlate32(x)
# define xlate64(x) __xlate64(x)
# define xlate16_be(x) (x)
# define xlate32_be(x) (x)
# define xlate64_be(x) (x)
# endif
#endif

View File

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

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);
}
#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) \
((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 */
#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

View File

@@ -6,7 +6,10 @@
#include "libdm-targets.h"
#include "libdm-common.h"
#include "libdm-compat.h"
#ifdef DM_COMPAT
# include "libdm-compat.h"
#endif
#include <stdio.h>
#include <stdlib.h>
@@ -16,8 +19,18 @@
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.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.
@@ -66,6 +79,7 @@ static struct cmd_data _cmd_data_v4[] = {
{"waitevent", DM_DEV_WAIT, {4, 0, 0}},
{"names", DM_LIST_DEVICES, {4, 0, 0}},
{"clear", DM_TABLE_CLEAR, {4, 0, 0}},
{"mknodes", DM_DEV_STATUS, {4, 0, 0}},
};
/* *INDENT-ON* */
@@ -84,6 +98,56 @@ static void *_align(void *ptr, unsigned int a)
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,
size_t size)
{
@@ -122,7 +186,8 @@ static int _unmarshal_status_v1(struct dm_task *dmt, struct dm_ioctl_v1 *dmi)
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;
@@ -365,24 +430,6 @@ static int _dm_names_v1(struct dm_ioctl_v1 *dmi)
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)
{
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);
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_TABLE:
if (!_unmarshal_status_v1(dmt, dmi))
@@ -460,38 +515,20 @@ static int _dm_task_run_v1(struct dm_task *dmt)
return 0;
}
void dm_task_destroy(struct dm_task *dmt)
{
struct target *t, *n;
#endif
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 4 functions.
*/
int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size)
{
unsigned int *v;
#ifdef DM_COMPAT
if (_dm_version == 1)
return _dm_task_get_driver_version_v1(dmt, version, size);
#endif
if (!dmt->dmi.v4) {
version[0] = '\0';
@@ -607,12 +644,15 @@ static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi)
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;
#ifdef DM_COMPAT
if (_dm_version == 1)
return _dm_format_dev_v1(buf, bufsize, dev_major, dev_minor);
#endif
if (bufsize < 8)
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)
{
#ifdef DM_COMPAT
if (_dm_version == 1)
return _dm_task_get_info_v1(dmt, info);
#endif
if (!dmt->dmi.v4)
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)
{
#ifdef DM_COMPAT
if (_dm_version == 1)
return _dm_task_get_name_v1(dmt);
#endif
return (dmt->dmi.v4->name);
}
const char *dm_task_get_uuid(struct dm_task *dmt)
{
#ifdef DM_COMPAT
if (_dm_version == 1)
return _dm_task_get_uuid_v1(dmt);
#endif
return (dmt->dmi.v4->uuid);
}
struct dm_deps *dm_task_get_deps(struct dm_task *dmt)
{
#ifdef DM_COMPAT
if (_dm_version == 1)
return _dm_task_get_deps_v1(dmt);
#endif
return (struct dm_deps *) (((void *) dmt->dmi.v4) +
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)
{
#ifdef DM_COMPAT
if (_dm_version == 1)
return _dm_task_get_names_v1(dmt);
#endif
return (struct dm_names *) (((void *) dmt->dmi.v4) +
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)
{
struct dm_ioctl *dmi;
struct dm_ioctl *dmi = NULL;
unsigned int command;
#ifdef DM_COMPAT
if (_dm_version == 1)
return _dm_task_run_v1(dmt);
#endif
if ((unsigned) dmt->type >=
(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,
dmi->uuid, dmt->newname ? dmt->newname : "");
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 */
goto ignore_error;
}
@@ -995,6 +1048,14 @@ int dm_task_run(struct dm_task *dmt)
rename_dev_node(dmt->dev_name, dmt->newname);
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_TABLE:
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} },
{ "table", DM_TARGET_STATUS_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* */

View File

@@ -9,7 +9,10 @@
#include <inttypes.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
@@ -52,7 +55,9 @@ enum {
DM_DEVICE_LIST,
DM_DEVICE_CLEAR
DM_DEVICE_CLEAR,
DM_DEVICE_MKNODES
};
struct dm_task;

View File

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

View File

@@ -22,11 +22,12 @@ VPATH = @srcdir@
MAN5=lvm.conf.5
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 \
pvcreate.8 pvdisplay.8 pvmove.8 pvremove.8 pvs.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 \
vgrename.8 vgs.8 vgscan.8
lvmdiskscan.8 lvreduce.8 lvremove.8 lvrename.8 lvresize.8 lvs.8 \
lvscan.8 pvchange.8 pvcreate.8 pvdisplay.8 pvmove.8 pvremove.8 pvs.8 \
pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 vgck.8 vgcreate.8 \
vgconvert.8 vgdisplay.8 vgexport.8 vgextend.8 vgimport.8 \
vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 vgrename.8 \
vgs.8 vgscan.8 vgsplit.8
MAN5DIR=${mandir}/man5
MAN8DIR=${mandir}/man8
@@ -40,7 +41,7 @@ install:
@INSTALL@ -D -o $(OWNER) -g $(GROUP) -m 444 $$f $(MAN8DIR)/$$f; \
done
@echo "Installing $(MAN5) in $(MAN8DIR)"
@echo "Installing $(MAN5) in $(MAN5DIR)"
@for f in $(MAN5); \
do \
$(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
dmsetup \- low level logical volume management
.SH SYNOPSIS
.ad l
.B dmsetup create
.I device_name table_file [uuid]
.B dmsetup create
.I device_name [-u uuid] [--notable] [table_file]
.br
.B dmsetup remove
.I device_name
.br
.B dmsetup rename
.I device_name new_name
.B dmsetup load
.I device_name [table_file]
.br
.B dmsetup clear
.I device_name
.br
.B dmsetup suspend
.I device_name
@@ -19,25 +22,32 @@ dmsetup \- low level logical volume management
.I device_name
.br
.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
.B dmsetup info
.I device_name
.I [device_name]
.br
.B dmsetup deps
.I device_name
.I [device_name]
.br
.B dmsetup mknodes
.I [device_name]
.br
.B dmsetup status
.I device_name
.I [device_name]
.br
.B dmsetup table
.I device_name
.I [device_name]
.br
.B dmsetup wait
.I device_name
.br
.B dmsetup remove_all
.I device_name
.br
.B dmsetup version
.ad b
@@ -48,77 +58,107 @@ each sector in the logical device.
The first argument to dmsetup is a command.
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
.IP \fBcreate
.I device_name table_file [uuid]
.I device_name [-u uuid] [--notable] [table_file]
.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
device_name in subsequent dmsetup commands. If
successful a device will appear as
/dev/device-mapper/<device-name>. See below for information
on the table file format.
device_name in subsequent dmsetup commands.
If successful a device will appear as
/dev/device-mapper/<device-name>.
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
.I device_name
.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
.I device_name new_name
.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
.I device_name
.br
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
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
.I device_name
.br
Outputs the current table for the device in a format than can be fed
back in using the create or reload 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!
Outputs the current table for the device in a format that can be fed
back in using the create or load commands.
.IP \fBversion
.I device_name
.br
Outputs version information.
.IP \fBwait
.I device_name
.br
Sleeps until an event is triggered against a device.
.SH TABLE FORMAT
Each line of the table specifies a single target and is of the form:
.br
@@ -151,16 +191,13 @@ will map the first chunk (16k) as follows:
.br
etc.
.IP \fBio-err
.IP \fBerror
.br
Errors any I/O that goes to this area. Useful for testing or
for creating devices with holes in them.
.SH EXAMPLES
# A table to join two disks together
.br
.br
@@ -169,7 +206,6 @@ for creating devices with holes in them.
1028160 3903762 linear /dev/hdb 0
# A table to stripe across the two disks,
.br
# 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.
Extension of snapshot logical volumes (see
.B lvcreate(8)
for information to create snapshots) is supprted as well.
for information to create snapshots) is supported as well.
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
@@ -30,13 +30,13 @@ 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 for the extension.
Not applicable to PVs using the original metadata LVM format.
This is equal to the number of physical volumes to scatter
the logical volume.
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.
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
StripeSize must be 2^n (n = 2 to 9)
.SH Examples
@@ -48,4 +48,5 @@ there are enough free physical extents in it.
.BR lvm (8),
.BR lvcreate (8),
.BR lvreduce (8),
.BR lvresize (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
reduced part is lost!!!
.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
.i before
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
t for terabyte is optional.
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.
.SH Example
"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 lvcreate (8),
.BR lvextend (8),
.BR lvresize (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
.SH SYNOPSIS
.B pvmove
[\-\-abort]
[\-d/\-\-debug] [\-h/\-\-help] [\-i/\-\-interval Seconds] [\-v/\-\-verbose]
[\-n/\-\-name LogicalVolume] SourcePhysicalVolume
[DestinationPhysicalVolume[:PE[-PE]...]...]
[\-n/\-\-name LogicalVolume]
[SourcePhysicalVolume [DestinationPhysicalVolume[:PE[-PE]...]...]]
.SH DESCRIPTION
.B pvmove
allows you to move the allocated physical extents (PEs) on
@@ -20,15 +21,16 @@ If no
.I DestinationPhysicalVolume
is specifed, the normal allocation rules for the volume group are used.
If \fBpvmove\fP gets interrupted for any reason, it will probably be
necessary to run \fBvgcfgrestore\fP to restore the volume group's metadata to
the state it was before the \fBpvmove\fP began.
\fBpvmove\fP locks the volume group and other LVM2 commands can't access
the volume group metadata until \fBpvmove\fP has completed.
If \fBpvmove\fP gets interrupted for any reason (e.g. the machine crashes)
then run \fBpvmove\fP again without any PhysicalVolume arguments to
continue with any moves that were in progress or use \fBpvmove --abort\fP to
abort them.
.SH OPTIONS
.TP
.I \-\-abort
Abort any moves currently in progress.
.TP
.I \-i, \-\-interval Seconds
Report progress as a percentage at regular intervals.
.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
[\-d/\-\-debug] [\-h/\-?/\-\-help]
[\-\-ignorelockingfailure]
[\-\-mknodes]
[\-P/\-\-partial]
[\-v/\-\-verbose]
.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.
.LP
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
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
.BR lvm (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=\
archive.c \
dumpconfig.c \
lvchange.c \
lvcreate.c \
lvdisplay.c \
@@ -53,6 +54,7 @@ SOURCES=\
vgextend.c \
vgimport.c \
vgmerge.c \
vgmknodes.c \
vgreduce.c \
vgremove.c \
vgrename.c \
@@ -81,7 +83,7 @@ lvm: $(OBJECTS) $(top_srcdir)/lib/liblvm.a
.commands: commands.h cmdnames.h Makefile
$(CC) -E -P cmdnames.h 2> /dev/null | \
egrep -v '^ *(|#.*|help|version) *$$' > .commands
egrep -v '^ *(|#.*|dumpconfig|help|pvdata|version) *$$' > .commands
install: $(TARGETS)
$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) lvm \

View File

@@ -14,6 +14,12 @@ static struct {
} _archive_params;
static struct {
int enabled;
char *dir;
} _backup_params;
int archive_init(const char *dir, unsigned int keep_days, unsigned int keep_min)
{
_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)
{
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)
{
_backup_params.dir = NULL;
@@ -206,7 +213,6 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
{
struct volume_group *vg = NULL;
struct format_instance *tf;
struct list *mdah;
struct metadata_area *mda;
void *context;
@@ -218,8 +224,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
return NULL;
}
list_iterate(mdah, &tf->metadata_areas) {
mda = list_item(mdah, struct metadata_area);
list_iterate_items(mda, &tf->metadata_areas) {
if (!(vg = mda->ops->vg_read(tf, vg_name, mda)))
stack;
break;
@@ -232,7 +237,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
/* ORPHAN and VG locks held before calling this */
int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
{
struct list *pvh;
struct pv_list *pvl;
struct physical_volume *pv;
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 */
list_iterate(pvh, &vg->pvs) {
pv = list_item(pvh, struct pv_list)->pv;
list_iterate_items(pvl, &vg->pvs) {
pv = pvl->pv;
if (!(info = info_from_pvid(pv->dev->pvid))) {
log_error("PV %s missing from cache",
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;
struct format_instance *tf;
struct list *mdah;
struct metadata_area *mda;
void *context;
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 */
list_iterate(mdah, &tf->metadata_areas) {
mda = list_item(mdah, struct metadata_area);
list_iterate_items(mda, &tf->metadata_areas) {
if (!(r = mda->ops->vg_write(tf, vg, mda))) {
stack;
continue;

View File

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

View File

@@ -33,6 +33,10 @@ xx(e2fsadm,
extents_ARG, size_ARG, nofsck_ARG, test_ARG)
*********/
xx(dumpconfig,
"Dump active configuration",
"dumpconfig <filename>\n")
xx(help,
"Display help for commands",
"help <command>" "\n")
@@ -412,7 +416,7 @@ xx(pvmove,
"\t[-t|--test]\n "
"\t[-v|--verbose]\n "
"\t[--version]\n"
"\t[{-n|--name} LogicalVolume\n"
"\t[{-n|--name} LogicalVolume]\n"
/* "\t[{-n|--name} LogicalVolume[:LogicalExtent[-LogicalExtent]...]]\n" */
"\tSourcePhysicalVolume\n"
/* "\tSourcePhysicalVolume[:PhysicalExtent[-PhysicalExtent]...]}\n" */
@@ -748,11 +752,12 @@ xx(vgscan,
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
"\t[--mknodes]\n"
"\t[-P|--partial] " "\n"
"\t[-v|--verbose]\n"
"\t[--version]" "\n",
ignorelockingfailure_ARG, partial_ARG)
ignorelockingfailure_ARG, mknodes_ARG, partial_ARG)
xx(vgsplit,
"Move physical volumes into a new volume group",

View File

@@ -10,8 +10,30 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <getopt.h>
#include <linux/kdev_t.h>
#include <dirent.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
@@ -24,6 +46,8 @@ enum {
READ_ONLY = 0,
MAJOR_ARG,
MINOR_ARG,
NOTABLE_ARG,
UUID_ARG,
VERBOSE_ARG,
VERSION_ARG,
NUM_SWITCHES
@@ -31,6 +55,7 @@ enum {
static int _switches[NUM_SWITCHES];
static int _values[NUM_SWITCHES];
static char *_uuid;
/*
* Commands
@@ -38,14 +63,19 @@ static int _values[NUM_SWITCHES];
static int _parse_file(struct dm_task *dmt, const char *file)
{
char buffer[LINE_SIZE], *ttype, *ptr, *comment;
FILE *fp = fopen(file, "r");
FILE *fp;
unsigned long long start, size;
int r = 0, n, line = 0;
if (!fp) {
err("Couldn't open '%s' for reading", file);
return 0;
}
/* OK for empty stdin */
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)) {
line++;
@@ -81,7 +111,8 @@ static int _parse_file(struct dm_task *dmt, const char *file)
r = 1;
out:
fclose(fp);
if (file)
fclose(fp);
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))
goto out;
if (file && !_parse_file(dmt, file))
if (!_switches[NOTABLE_ARG] && !_parse_file(dmt, file))
goto out;
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;
}
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], NULL, NULL);
return _load(DM_DEVICE_CREATE, argv[1], argv[2],
(argc == 3) ? argv[3] : NULL);
return _load(DM_DEVICE_CREATE, argv[1], (argc == 3) ? argv[2] : NULL,
_switches[UUID_ARG] ? _uuid : 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;
struct dm_task *dmt;
@@ -206,7 +240,7 @@ static int _rename(int argc, char **argv)
return r;
}
static int _version(int argc, char **argv)
static int _version(int argc, char **argv, void *data)
{
int r = 0;
struct dm_task *dmt;
@@ -258,37 +292,113 @@ static int _simple(int task, const char *name, int display)
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);
}
static int _remove(int argc, char **argv)
static int _remove(int argc, char **argv, void *data)
{
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);
}
static int _resume(int argc, char **argv)
static int _resume(int argc, char **argv, void *data)
{
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);
}
static int _wait(int argc, char **argv)
static int _wait(int argc, char **argv, void *data)
{
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;
struct dm_task *dmt;
@@ -297,16 +407,26 @@ static int _status(int argc, char **argv)
char *target_type = NULL;
char *params;
int cmd;
struct dm_names *names = (struct dm_names *) data;
char *name;
if (!strcmp(argv[0], "status"))
cmd = DM_DEVICE_STATUS;
if (argc == 1 && !data)
return _process_all(argc, argv, _status);
if (data)
name = names->name;
else
name = argv[1];
if (!strcmp(argv[0], "table"))
cmd = DM_DEVICE_TABLE;
else
cmd = DM_DEVICE_STATUS;
if (!(dmt = dm_task_create(cmd)))
return 0;
if (!dm_task_set_name(dmt, argv[1]))
if (!dm_task_set_name(dmt, name))
goto out;
if (!dm_task_run(dmt))
@@ -319,12 +439,17 @@ static int _status(int argc, char **argv)
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (data && !_switches[VERBOSE_ARG])
printf("%s: ", name);
if (target_type) {
printf("%" PRIu64 " %" PRIu64 " %s %s\n",
start, length, target_type, params);
}
} while (next);
if (data && _switches[VERBOSE_ARG])
printf("\n");
r = 1;
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;
/* remove <dev_name> */
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;
if (!dm_task_set_name(dmt, argv[1]))
if (!dm_task_set_name(dmt, name))
goto out;
if (!dm_task_run(dmt))
goto out;
_display_info(dmt);
if (taskno == DM_DEVICE_INFO)
_display_info(dmt);
r = 1;
out:
@@ -357,20 +499,28 @@ static int _info(int argc, char **argv)
return r;
}
static int _deps(int argc, char **argv)
static int _deps(int argc, char **argv, void *data)
{
int r = 0;
uint32_t i;
struct dm_deps *deps;
/* remove <dev_name> */
struct dm_task *dmt;
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)))
return 0;
if (!dm_task_set_name(dmt, argv[1]))
if (!dm_task_set_name(dmt, name))
goto out;
if (!dm_task_run(dmt))
@@ -391,6 +541,8 @@ static int _deps(int argc, char **argv)
if (_switches[VERBOSE_ARG])
_display_info(dmt);
if (data && !_switches[VERBOSE_ARG])
printf("%s: ", name);
printf("%d dependencies\t:", deps->count);
for (i = 0; i < deps->count; i++)
@@ -399,6 +551,9 @@ static int _deps(int argc, char **argv)
(int) MINOR(deps->device[i]));
printf("\n");
if (data && _switches[VERBOSE_ARG])
printf("\n");
r = 1;
out:
@@ -406,45 +561,25 @@ static int _deps(int argc, char **argv)
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;
unsigned next = 0;
struct dm_names *names = (struct dm_names *) data;
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 0;
return 1;
}
if (!dm_task_run(dmt))
goto out;
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;
static int _ls(int argc, char **argv, void *data)
{
return _process_all(argc, argv, _display_name);
}
/*
* dispatch table
*/
typedef int (*command_fn) (int argc, char **argv);
typedef int (*command_fn) (int argc, char **argv, void *data);
struct command {
const char *name;
@@ -455,20 +590,22 @@ struct command {
};
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_all", "", 0, 0, _remove_all},
{"suspend", "<dev_name>", 1, 1, _suspend},
{"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},
{"reload", "<dev_name> <table_file>", 2, 2, _reload},
{"reload", "<dev_name> [<table_file>]", 1, 2, _reload},
{"rename", "<dev_name> <new_name>", 2, 2, _rename},
{"ls", "", 0, 0, _ls},
{"info", "<dev_name>", 1, 1, _info},
{"deps", "<dev_name>", 1, 1, _deps},
{"status", "<dev_name>", 1, 1, _status},
{"table", "<dev_name>", 1, 1, _status},
{"info", "[<dev_name>]", 0, 1, _info},
{"deps", "[<dev_name>]", 0, 1, _deps},
{"mknodes", "[<dev_name>]", 0, 1, _info},
{"status", "[<dev_name>]", 0, 1, _status},
{"table", "[<dev_name>]", 0, 1, _status},
{"wait", "<dev_name>", 1, 1, _wait},
{"version", "", 0, 0, _version},
{NULL, NULL, 0, 0, NULL}
@@ -480,7 +617,8 @@ static void _usage(FILE *out)
fprintf(out, "Usage:\n\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++)
fprintf(out, "\t%s %s\n", _commands[i].name, _commands[i].help);
return;
@@ -502,14 +640,20 @@ static int _process_switches(int *argc, char ***argv)
int ind;
int c;
#ifdef HAVE_GETOPTLONG
static struct option long_options[] = {
{"readonly", 0, NULL, READ_ONLY},
{"major", 1, NULL, MAJOR_ARG},
{"minor", 1, NULL, MINOR_ARG},
{"notable", 0, NULL, NOTABLE_ARG},
{"uuid", 1, NULL, UUID_ARG},
{"verbose", 1, NULL, VERBOSE_ARG},
{"version", 0, NULL, VERSION_ARG},
{"", 0, NULL, 0}
};
#else
struct option long_options;
#endif
/*
* Zero all the index counts.
@@ -517,8 +661,10 @@ static int _process_switches(int *argc, char ***argv)
memset(&_switches, 0, sizeof(_switches));
memset(&_values, 0, sizeof(_values));
while ((c = getopt_long(*argc, *argv, "j:m:rv",
long_options, &ind)) != -1) {
optarg = 0;
optind = OPTIND_INIT;
while ((c = GETOPTLONG_FN(*argc, *argv, "j:m:nru:v",
long_options, &ind)) != -1) {
if (c == 'r' || ind == READ_ONLY)
_switches[READ_ONLY]++;
if (c == 'j' || ind == MAJOR_ARG) {
@@ -529,8 +675,14 @@ static int _process_switches(int *argc, char ***argv)
_switches[MINOR_ARG]++;
_values[MINOR_ARG] = atoi(optarg);
}
if (c == 'n' || ind == NOTABLE_ARG)
_switches[NOTABLE_ARG]++;
if (c == 'v' || ind == VERBOSE_ARG)
_switches[VERBOSE_ARG]++;
if (c == 'u' || ind == UUID_ARG) {
_switches[UUID_ARG]++;
_uuid = optarg;
}
if ((ind == VERSION_ARG))
_switches[VERSION_ARG]++;
}
@@ -575,7 +727,7 @@ int main(int argc, char **argv)
}
doit:
if (!c->fn(argc, argv)) {
if (!c->fn(argc, argv, NULL)) {
fprintf(stderr, "Command failed\n");
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

@@ -376,7 +376,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!lvchange_availability(cmd, lv))
return ECMD_FAILED;
return 0;
return ECMD_PROCESSED;
}
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)) {
log_error("Logical volume name \"%s\" has invalid "
"characters", lp->lv_name);
log_error("Logical volume name \"%s\" is invalid",
lp->lv_name);
return 0;
}
}
@@ -148,12 +148,22 @@ static int _read_size_params(struct lvcreate_params *lp,
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);
}
/* 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;
}
return 1;
}
@@ -172,8 +182,13 @@ static int _read_stripe_params(struct lvcreate_params *lp,
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);
}
if (lp->stripes == 1 && lp->stripe_size) {
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");
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);
log_verbose("Setting chunksize to %d sectors.", lp->chunk_size);
} else {
@@ -328,7 +347,7 @@ static int _zero_lv(struct cmd_context *cmd, struct logical_volume *lv)
return 0;
dev_zero(dev, UINT64_C(0), (size_t) 4096);
dev_close(dev);
dev_close_immediate(dev);
return 1;
}
@@ -337,6 +356,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
{
uint32_t size_rest;
uint32_t status = 0;
uint64_t tmp_size;
alloc_policy_t alloc = ALLOC_DEFAULT;
struct volume_group *vg;
struct logical_volume *lv, *org = NULL;
@@ -393,17 +413,16 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
if (lp->size) {
/* No of 512-byte sectors */
lp->extents = lp->size;
tmp_size = lp->size;
if (lp->extents % vg->extent_size) {
lp->extents += vg->extent_size - lp->extents %
if (tmp_size % vg->extent_size) {
tmp_size += vg->extent_size - tmp_size %
vg->extent_size;
log_print("Rounding up size to full physical extent %s",
display_size(cmd, (uint64_t) lp->extents / 2,
SIZE_SHORT));
display_size(cmd, tmp_size / 2, SIZE_SHORT));
}
lp->extents /= vg->extent_size;
lp->extents = tmp_size / vg->extent_size;
}
if ((size_rest = lp->extents % lp->stripes)) {
@@ -434,6 +453,8 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
"supported yet");
return 0;
}
/* Must zero cow */
status |= LVM_WRITE;
}
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) {
/* Reset permission after zeroing */
if (!(lp->permission & LVM_WRITE))
lv->status &= ~LVM_WRITE;
if (!lock_vol(cmd, lv->lvid.s, LCK_LV_DEACTIVATE)) {
log_err("Couldn't unlock snapshot.");
return 0;
@@ -539,11 +563,11 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv)
memset(&lp, 0, sizeof(lp));
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)) {
log_error("Can't get lock for %s", lp.vg_name);
return 0;
return ECMD_FAILED;
}
if (!_lvcreate(cmd, &lp)) {
@@ -551,7 +575,7 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv)
goto out;
}
r = 0;
r = ECMD_PROCESSED;
out:
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);
}
return 0;
return ECMD_PROCESSED;
}
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)
{
struct format_type *fmt;
struct list *fmth;
char *format;
format = a->value;
list_iterate(fmth, &cmd->formats) {
fmt = list_item(fmth, struct format_type);
list_iterate_items(fmt, &cmd->formats) {
if (!strcasecmp(fmt->name, format) ||
!strcasecmp(fmt->name + 3, 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->ui_value = (uint32_t) v;
a->i64_value = (int64_t) v;
a->ui64_value = (uint64_t) v;
return 1;
}
@@ -485,6 +484,15 @@ static int _process_command_line(struct cmd_context *cmd, int *argc,
}
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) {
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)))
return ECMD_FAILED;
log_debug("Processing: %s", cmd->cmd_line);
if (!(cmd->command = _find_command(argv[0])))
return ENO_SUCH_CMD;

View File

@@ -22,6 +22,6 @@
int lvmchange(struct cmd_context *cmd, int argc, char **argv)
{
log_print("With the device mapper, this program is obsolete.");
return 0;
log_print("With LVM2 and the device mapper, this program is obsolete.");
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))) {
log_error("dev_iter_create failed");
return 0;
return ECMD_FAILED;
}
/* Do scan */
@@ -135,5 +135,5 @@ int lvmdiskscan(struct cmd_context *cmd, int argc, char **argv)
log_print("%d LVM physical volume%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') {
log_print("Logical volume \"%s\" not removed",
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;
log_print("Logical volume \"%s\" successfully removed", lv->name);
return 0;
return ECMD_PROCESSED;
}
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)) {
log_error
("New logical volume name \"%s\" has invalid characters",
log_error("New logical volume name \"%s\" is invalid",
lv_name_new);
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\"",
lv_name_old, lv_name_new, vg_name);
return 0;
return ECMD_PROCESSED;
error:
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;
char *st, *lock_lvid;
const char *cmd_name;
struct list *pvh, *segh;
struct list *pvh;
struct lv_list *lvl;
int opt = 0;
int consistent = 1;
struct lv_segment *seg;
uint32_t seg_extents;
uint32_t sz, str;
enum {
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_sign_value(cmd, stripesize_ARG, 0) == SIGN_MINUS) {
log_error("Stripesize may not be negative.");
goto error;
}
if (vg->fid->fmt->features & FMT_SEGMENTS)
ssize = 2 * arg_uint_value(cmd, stripesize_ARG, 0);
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 (extents > lv->le_count && !(stripes == 1 || (stripes > 1 && ssize))) {
list_iterate(segh, &lv->segments) {
struct lv_segment *seg;
uint32_t sz, str;
seg = list_item(segh, struct lv_segment);
list_iterate_items(seg, &lv->segments) {
if (seg->type != SEG_STRIPED)
continue;
@@ -244,12 +246,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
log_error("Ignoring stripes and stripesize arguments "
"when reducing");
list_iterate(segh, &lv->segments) {
struct lv_segment *seg;
uint32_t seg_extents;
seg = list_item(segh, struct lv_segment);
list_iterate_items(seg, &lv->segments) {
seg_extents = seg->len;
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);
return 0;
return ECMD_PROCESSED;
error:
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;
return 0;
return ECMD_PROCESSED;
}
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 */
if (allocatable && (pv->status & ALLOCATABLE_PV)) {
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);
else
unlock_vg(cmd, ORPHAN);
return 0;
return 1;
}
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);
else
unlock_vg(cmd, ORPHAN);
return 0;
return 1;
}
if (allocatable) {
@@ -131,7 +139,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
backup(vg);
unlock_vg(cmd, pv->vg_name);
} else {
if (!(pv_write(cmd, pv, &mdas, (int64_t) sector))) {
if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
unlock_vg(cmd, ORPHAN);
log_error("Failed to store physical volume \"%s\"",
pv_name);
@@ -154,7 +162,8 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
struct physical_volume *pv;
char *pv_name;
struct list *pvh, *pvslist;
struct pv_list *pvl;
struct list *pvslist;
struct list mdas;
list_init(&mdas);
@@ -194,12 +203,9 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
list_iterate(pvh, pvslist) {
list_iterate_items(pvl, pvslist) {
total++;
done += _pvchange_single(cmd,
list_item(pvh,
struct pv_list)->pv,
NULL);
done += _pvchange_single(cmd, pvl->pv, NULL);
}
}
@@ -208,5 +214,5 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
done, 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;
}
static void pvcreate_single(struct cmd_context *cmd, const char *pv_name,
void *handle)
static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
void *handle)
{
struct physical_volume *pv, *existing_pv;
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)) {
uuid = arg_str_value(cmd, uuidstr_ARG, "");
if (!id_read_format(&id, uuid))
return;
return EINVALID_CMD_LINE;
if ((dev = device_from_pvid(cmd, &id)) &&
(dev != dev_cache_get(pv_name, cmd->filter))) {
log_error("uuid %s already in use on \"%s\"", uuid,
dev_name(dev));
return;
return ECMD_FAILED;
}
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))) {
log_error("Unable to read volume group from %s",
restorefile);
return;
return ECMD_FAILED;
}
init_partial(0);
if (!(existing_pv = find_pv_in_vg_by_uuid(vg, idp))) {
log_error("Can't find uuid %s in backup file %s",
uuid, restorefile);
return;
return ECMD_FAILED;
}
pe_start = existing_pv->pe_start;
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)) {
log_error("Can't get lock for orphan PVs");
return;
return ECMD_FAILED;
}
if (!pvcreate_check(cmd, pv_name))
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;
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))
* 2;
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);
unlock_vg(cmd, "");
return ECMD_PROCESSED;
error:
unlock_vg(cmd, "");
return;
return ECMD_FAILED;
}
int pvcreate(struct cmd_context *cmd, int argc, char **argv)
{
int i;
int i, r;
int ret = ECMD_PROCESSED;
if (!argc) {
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++) {
pvcreate_single(cmd, argv[i], NULL);
pool_empty(cmd->mem);
r = pvcreate_single(cmd, argv[i], NULL);
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)) {
log_print("Device \"%s\" has a capacity of %s", pv_name,
display_size(cmd, size / 2, SIZE_SHORT));
return 0;
return ECMD_PROCESSED;
}
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)) {
pvdisplay_colons(pv);
return 0;
return ECMD_PROCESSED;
}
pvdisplay_full(cmd, pv, handle);
if (!arg_count(cmd, maps_ARG))
return 0;
return ECMD_PROCESSED;
return 0;
}
@@ -82,7 +82,5 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
process_each_pv(cmd, argc, argv, NULL, NULL, _pvdisplay_single);
return 0;
return process_each_pv(cmd, argc, argv, NULL, NULL, _pvdisplay_single);
}

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);
if ((pvl->pv->dev == pv->dev) ||
(pvl->pv->pe_count == pvl->pv->pe_alloc_count))
list_del(&pvl->list);
list_del(&pvl->list);
}
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 logical_volume *lv_mirr, *lv;
struct list *lvh;
struct lv_list *lvl;
/* FIXME Cope with non-contiguous => splitting existing segments */
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);
/* Find segments to be moved and set up mirrors */
list_iterate(lvh, &vg->lvs) {
lv = list_item(lvh, struct lv_list)->lv;
list_iterate_items(lvl, &vg->lvs) {
lv = lvl->lv;
if ((lv == lv_mirr) || (lv_name && strcmp(lv->name, lv_name)))
continue;
if (lv_is_origin(lv) || lv_is_cow(lv)) {
@@ -483,6 +483,16 @@ static int _check_pvmove_status(struct cmd_context *cmd,
*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,
&event_nr)) {
log_error("ABORTING: Mirror percentage check failed.");
@@ -495,7 +505,7 @@ static int _check_pvmove_status(struct cmd_context *cmd,
else
log_verbose("%s: Moved: %.1f%%", pv_name, overall_percent);
if (segment_percent < 100.0 && !parms->aborting) {
if (segment_percent < 100.0) {
*finished = 0;
return 1;
}
@@ -505,11 +515,6 @@ static int _check_pvmove_status(struct cmd_context *cmd,
return 0;
}
if (parms->aborting) {
_finish_pvmove(cmd, vg, lv_mirr, lvs_changed);
return 0;
}
if (overall_percent >= 100.0) {
if (!_finish_pvmove(cmd, vg, lv_mirr, lvs_changed))
return 0;
@@ -571,18 +576,29 @@ static int _poll_pvmove_vgs(struct cmd_context *cmd, const char *vgname,
void *handle)
{
struct pvmove_parms *parms = (struct pvmove_parms *) handle;
struct list *lvh;
struct lv_list *lvl;
struct logical_volume *lv_mirr;
struct physical_volume *pv;
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) {
log_error("Volume group \"%s\" is exported", vg->name);
return ECMD_FAILED;
}
list_iterate(lvh, &vg->lvs) {
lv_mirr = list_item(lvh, struct lv_list)->lv;
list_iterate_items(lvl, &vg->lvs) {
lv_mirr = lvl->lv;
if (!(lv_mirr->status & PVMOVE))
continue;
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",
parms.interval);
if (parms.interval == 0) {
parms.interval = DEFAULT_INTERVAL;
if (!parms.interval) {
parms.progress_display = 0;
if (!pv_name)
parms.interval = DEFAULT_INTERVAL;
}
if (parms.background) {
@@ -653,8 +671,9 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv)
argc--;
argv++;
if ((ret = _set_up_pvmove(cmd, pv_name, argc, argv)) !=
ECMD_PROCESSED) {
if (!arg_count(cmd, abort_ARG) &&
(ret = _set_up_pvmove(cmd, pv_name, argc, argv)) !=
ECMD_PROCESSED) {
stack;
return ret;
}

View File

@@ -72,14 +72,14 @@ static int pvremove_check(struct cmd_context *cmd, const char *name)
return 1;
}
static void pvremove_single(struct cmd_context *cmd, const char *pv_name,
void *handle)
static int pvremove_single(struct cmd_context *cmd, const char *pv_name,
void *handle)
{
struct device *dev;
if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs");
return;
return ECMD_FAILED;
}
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",
pv_name);
unlock_vg(cmd, "");
return ECMD_PROCESSED;
error:
unlock_vg(cmd, "");
return;
return ECMD_FAILED;
}
int pvremove(struct cmd_context *cmd, int argc, char **argv)
{
int i;
int i, r;
int ret = ECMD_PROCESSED;
if (!argc) {
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++) {
pvremove_single(cmd, argv[i], NULL);
pool_empty(cmd->mem);
r = pvremove_single(cmd, argv[i], NULL);
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;
struct list *pvslist;
struct list *pvh;
struct pv_list *pvl;
struct physical_volume *pv;
@@ -141,8 +140,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
/* eliminate exported/new if required */
list_iterate(pvh, pvslist) {
pvl = list_item(pvh, struct pv_list);
list_iterate_items(pvl, pvslist) {
pv = pvl->pv;
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 */
pv_max_name_len = vg_max_name_len = 0;
list_iterate(pvh, pvslist) {
pv = list_item(pvh, struct pv_list)->pv;
list_iterate_items(pvl, pvslist) {
pv = pvl->pv;
len = strlen(dev_name(pv->dev));
if (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;
vg_max_name_len += 2;
list_iterate(pvh, pvslist)
_pvscan_display_single(cmd, list_item(pvh, struct pv_list)->pv,
NULL);
list_iterate_items(pvl, pvslist)
_pvscan_display_single(cmd, pvl->pv, NULL);
if (!pvs_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]",
@@ -203,5 +200,5 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
display_size(cmd, (size_total - 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))
return ECMD_FAILED;
return 0;
return ECMD_PROCESSED;
}
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))
return ECMD_FAILED;
return 0;
return ECMD_PROCESSED;
}
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))
return ECMD_FAILED;
return 0;
return ECMD_PROCESSED;
}
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)) {
log_error("Can't lock %s: skipping", pv->vg_name);
return 0;
return ECMD_FAILED;
}
if (!(vg = vg_read(cmd, pv->vg_name, &consistent))) {
log_error("Can't read %s: skipping", pv->vg_name);
unlock_vg(cmd, pv->vg_name);
return 0;
return ECMD_FAILED;
}
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);
return 0;
return ECMD_PROCESSED;
}
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;
char *str;
const char *keys = NULL, *options = NULL, *separator;
int r = ECMD_PROCESSED;
int aligned, buffered, headings;
@@ -192,27 +193,27 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
switch (report_type) {
case LVS:
process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle,
&_lvs_single);
r = process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle,
&_lvs_single);
break;
case VGS:
process_each_vg(cmd, argc, argv, LCK_VG_READ, 0, report_handle,
&_vgs_single);
r = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0,
report_handle, &_vgs_single);
break;
case PVS:
process_each_pv(cmd, argc, argv, NULL, report_handle,
&_pvs_single);
r = process_each_pv(cmd, argc, argv, NULL, report_handle,
&_pvs_single);
break;
case SEGS:
process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle,
&_lvsegs_single);
r = process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle,
&_lvsegs_single);
break;
}
report_output(report_handle);
report_free(report_handle);
return ECMD_PROCESSED;
return r;
}
int lvs(struct cmd_context *cmd, int argc, char **argv)

View File

@@ -6,9 +6,16 @@
#define unimplemented \
{ log_error("Command not implemented yet."); return ECMD_FAILED;}
/*int e2fsadm(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 pvdata(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 = 0;
struct list *lvh;
struct logical_volume *lv;
struct lv_list *lvl;
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg->name);
return ECMD_FAILED;
}
list_iterate(lvh, &vg->lvs) {
lv = list_item(lvh, struct lv_list)->lv;
ret = process_single(cmd, lv, handle);
list_iterate_items(lvl, &vg->lvs) {
ret = process_single(cmd, lvl->lv, handle);
if (ret > ret_max)
ret_max = ret;
}
@@ -233,13 +231,11 @@ int process_each_segment_in_lv(struct cmd_context *cmd,
struct lv_segment * seg,
void *handle))
{
struct list *segh;
struct lv_segment *seg;
int ret_max = 0;
int ret;
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct lv_segment);
list_iterate_items(seg, &lv->segments) {
ret = process_single(cmd, seg, handle);
if (ret > ret_max)
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 = 0;
struct list *pvh;
struct physical_volume *pv;
struct pv_list *pvl;
list_iterate(pvh, &vg->pvs) {
pv = list_item(pvh, struct pv_list)->pv;
if ((ret = process_single(cmd, vg, pv, handle)) > ret_max)
list_iterate_items(pvl, &vg->pvs)
if ((ret = process_single(cmd, vg, pvl->pv, handle)) > ret_max)
ret_max = ret;
}
return ret_max;
}
@@ -354,7 +346,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
struct pv_list *pvl;
struct physical_volume *pv;
struct list *pvslist, *pvh;
struct list *pvslist;
if (argc) {
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 "
"\"%s\"", argv[opt],
vg->name);
ret_max = ECMD_FAILED;
continue;
}
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))) {
log_error("Failed to read physical "
"volume \"%s\"", argv[opt]);
ret_max = ECMD_FAILED;
continue;
}
}
@@ -384,15 +378,17 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
if (vg) {
log_verbose("Using all physical volume(s) in "
"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 {
log_verbose("Scanning for physical volume names");
if (!(pvslist = get_pvs(cmd)))
return ECMD_FAILED;
list_iterate(pvh, pvslist) {
pv = list_item(pvh, struct pv_list)->pv;
ret = process_single(cmd, NULL, pv, handle);
list_iterate_items(pvl, pvslist) {
ret = process_single(cmd, NULL, pvl->pv,
handle);
if (ret > ret_max)
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)
{
struct alloc_area *aa;
struct list *aah;
log_debug("Adding alloc area: start PE %" PRIu32 " length %" PRIu32,
start, count);
/* Ensure no overlap with existing areas */
list_iterate(aah, alloc_areas) {
aa = list_item(aah, struct alloc_area);
list_iterate_items(aa, alloc_areas) {
if (((start < aa->start) && (start + count - 1 >= aa->start)) ||
((start >= aa->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 *r, *pvh;
struct list *r;
struct pv_list *pvl, *new_pvl;
/* Build up list of PVs */
@@ -676,9 +670,7 @@ struct list *clone_pv_list(struct pool *mem, struct list *pvsl)
}
list_init(r);
list_iterate(pvh, pvsl) {
pvl = list_item(pvh, struct pv_list);
list_iterate_items(pvl, pvsl) {
if (!(new_pvl = pool_zalloc(mem, sizeof(*new_pvl)))) {
log_error("Unable to allocate physical volume list.");
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);
return 0;
return ECMD_PROCESSED;
}
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);
if (!validate_name(vg_name)) {
log_error("Volume group name \"%s\" has invalid characters",
vg_name);
log_error("Volume group name \"%s\" is invalid", vg_name);
return ECMD_FAILED;
}
@@ -34,7 +33,7 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
if (!archive_display(cmd, vg_name))
return ECMD_FAILED;
return 0;
return ECMD_PROCESSED;
}
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, ORPHAN);
return 0;
return ECMD_PROCESSED;
}

View File

@@ -23,13 +23,13 @@
static int _activate_lvs_in_vg(struct cmd_context *cmd,
struct volume_group *vg, int lock)
{
struct list *lvh;
struct lv_list *lvl;
struct logical_volume *lv;
struct physical_volume *pv;
int count = 0;
list_iterate(lvh, &vg->lvs) {
lv = list_item(lvh, struct lv_list)->lv;
list_iterate_items(lvl, &vg->lvs) {
lv = lvl->lv;
/* Only request activation of snapshot origin devices */
if (lv_is_cow(lv))
@@ -56,8 +56,8 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd,
return count;
}
static void _vgchange_available(struct cmd_context *cmd,
struct volume_group *vg)
static int _vgchange_available(struct cmd_context *cmd,
struct volume_group *vg)
{
int lv_open, active;
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))) {
log_error("Can't deactivate volume group \"%s\" with %d open "
"logical volume(s)", vg->name, lv_open);
return;
return ECMD_FAILED;
}
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",
lvs_in_vg_activated(vg), vg->name);
return;
return ECMD_PROCESSED;
}
static void _vgchange_resizeable(struct cmd_context *cmd,
struct volume_group *vg)
static int _vgchange_resizeable(struct cmd_context *cmd,
struct volume_group *vg)
{
int resizeable = !strcmp(arg_str_value(cmd, resizeable_ARG, "n"), "y");
if (resizeable && (vg->status & RESIZEABLE_VG)) {
log_error("Volume group \"%s\" is already resizeable",
vg->name);
return;
return ECMD_FAILED;
}
if (!resizeable && !(vg->status & RESIZEABLE_VG)) {
log_error("Volume group \"%s\" is already not resizeable",
vg->name);
return;
return ECMD_FAILED;
}
if (!archive(vg))
return;
return ECMD_FAILED;
if (resizeable)
vg->status |= RESIZEABLE_VG;
@@ -112,52 +112,63 @@ static void _vgchange_resizeable(struct cmd_context *cmd,
vg->status &= ~RESIZEABLE_VG;
if (!vg_write(vg) || !vg_commit(vg))
return;
return ECMD_FAILED;
backup(vg);
log_print("Volume group \"%s\" successfully changed", vg->name);
return;
return ECMD_PROCESSED;
}
static void _vgchange_logicalvolume(struct cmd_context *cmd,
struct volume_group *vg)
static int _vgchange_logicalvolume(struct cmd_context *cmd,
struct volume_group *vg)
{
uint32_t max_lv = arg_uint_value(cmd, logicalvolume_ARG, 0);
if (!(vg->status & RESIZEABLE_VG)) {
log_error("Volume group \"%s\" must be resizeable "
"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 "
"%d of logical volume(s) for \"%s\"", vg->lv_count,
vg->name);
return;
return ECMD_FAILED;
}
if (!archive(vg))
return;
return ECMD_FAILED;
vg->max_lv = max_lv;
if (!vg_write(vg) || !vg_commit(vg))
return;
return ECMD_FAILED;
backup(vg);
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,
struct volume_group *vg, int consistent,
void *handle)
{
int r = 0;
if (!vg) {
log_error("Unable to find volume group \"%s\"", vg_name);
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))
_vgchange_available(cmd, vg);
r = _vgchange_available(cmd, vg);
if (arg_count(cmd, resizeable_ARG))
_vgchange_resizeable(cmd, vg);
else if (arg_count(cmd, resizeable_ARG))
r = _vgchange_resizeable(cmd, vg);
if (arg_count(cmd, logicalvolume_ARG))
_vgchange_logicalvolume(cmd, vg);
else if (arg_count(cmd, logicalvolume_ARG))
r = _vgchange_logicalvolume(cmd, vg);
return 0;
return r;
}
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,
struct volume_group *vg, int consistent, void *handle)
{
if (!consistent) {
log_error("Volume group \"%s\" inconsistent", vg_name);
if (!vg) {
log_error("Volume group \"%s\" not found", vg_name);
return ECMD_FAILED;
}
if (!vg) {
log_error("Volume group \"%s\" not found", vg_name);
if (!consistent) {
log_error("Volume group \"%s\" inconsistent", vg_name);
return ECMD_FAILED;
}
@@ -38,8 +38,7 @@ static int vgck_single(struct cmd_context *cmd, const char *vg_name,
return ECMD_FAILED;
}
/* FIXME: free */
return 0;
return ECMD_PROCESSED;
}
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)
{
struct physical_volume *pv, *existing_pv;
struct logical_volume *lv;
struct lv_list *lvl;
uint64_t size = 0;
struct list mdas;
int pvmetadatacopies = 0;
uint64_t pvmetadatasize = 0;
uint64_t pe_end = 0, pe_start = 0;
struct list *pvh;
struct pv_list *pvl;
int change_made = 0;
struct lvinfo info;
int active = 0;
if (!vg) {
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 (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,
UINT64_C(0)) * 2;
if (!pvmetadatasize)
@@ -83,8 +92,29 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
return ECMD_FAILED;
}
list_iterate(pvh, &vg->pvs) {
existing_pv = list_item(pvh, struct pv_list)->pv;
/* Attempt to change any LVIDs that are too big */
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_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()) {
log_verbose("Test mode: Skipping metadata writing for VG %s in"
" format %s", vg_name, cmd->fmt->name);
return 0;
return ECMD_PROCESSED;
}
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);
return 0;
return ECMD_PROCESSED;
}
int vgconvert(struct cmd_context *cmd, int argc, char **argv)

View File

@@ -20,10 +20,6 @@
#include "tools.h"
/* FIXME From config file? */
#define DEFAULT_PV 256
#define DEFAULT_LV 256
#define DEFAULT_EXTENT 4096 /* In KB */
int vgcreate(struct cmd_context *cmd, int argc, char **argv)
@@ -46,26 +42,47 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
}
vg_name = argv[0];
max_lv = arg_uint_value(cmd, maxlogicalvolumes_ARG, DEFAULT_LV);
max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, DEFAULT_PV);
max_lv = arg_uint_value(cmd, maxlogicalvolumes_ARG, 0);
max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, 0);
/* Units of 512-byte sectors */
extent_size =
arg_uint_value(cmd, physicalextentsize_ARG, DEFAULT_EXTENT) * 2;
if (!(cmd->fmt->features & FMT_UNLIMITED_VOLS)) {
if (!max_lv)
max_lv = 255;
if (!max_pv)
max_pv = 255;
if (max_lv > 255 || max_pv > 255) {
log_error("Number of volumes may not exceed 255");
return EINVALID_CMD_LINE;
}
}
if (arg_sign_value(cmd, physicalextentsize_ARG, 0) == SIGN_MINUS) {
log_error("Physical extent size may not be negative");
return EINVALID_CMD_LINE;
}
if (arg_sign_value(cmd, maxlogicalvolumes_ARG, 0) == SIGN_MINUS) {
log_error("Max Logical Volumes may not be negative");
return EINVALID_CMD_LINE;
}
if (arg_sign_value(cmd, maxphysicalvolumes_ARG, 0) == SIGN_MINUS) {
log_error("Max Physical Volumes may not be negative");
return EINVALID_CMD_LINE;
}
/* Units of 512-byte sectors */
extent_size =
arg_uint_value(cmd, physicalextentsize_ARG, DEFAULT_EXTENT) * 2;
if (max_lv < 1) {
log_error("maxlogicalvolumes too low");
if (!extent_size) {
log_error("Physical extent size may not be zero");
return EINVALID_CMD_LINE;
}
if (max_pv < 1) {
log_error("maxphysicalvolumes too low");
return EINVALID_CMD_LINE;
}
/* Strip dev_dir if present */
if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir)))
vg_name += strlen(cmd->dev_dir);
/* Strip dev_dir if present */
if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir)))
vg_name += strlen(cmd->dev_dir);
snprintf(vg_path, PATH_MAX, "%s%s", cmd->dev_dir, vg_name);
if (path_exists(vg_path)) {
@@ -74,8 +91,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
}
if (!validate_name(vg_name)) {
log_error("New volume group name \"%s\" has invalid characters",
vg_name);
log_error("New volume group name \"%s\" is invalid", vg_name);
return ECMD_FAILED;
}
@@ -85,12 +101,12 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
if (max_lv != vg->max_lv)
log_error("Warning: Setting maxlogicalvolumes to %d",
vg->max_lv);
log_error("Warning: Setting maxlogicalvolumes to %d "
"(0 means unlimited)", vg->max_lv);
if (max_pv != vg->max_pv)
log_error("Warning: Setting maxphysicalvolumes to %d",
vg->max_pv);
log_error("Warning: Setting maxphysicalvolumes to %d "
"(0 means unlimited)", vg->max_pv);
if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs");
@@ -123,5 +139,5 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
log_print("Volume group \"%s\" successfully created", vg->name);
return 0;
return ECMD_PROCESSED;
}

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