1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-08 13:44:19 +03:00

Compare commits

...

97 Commits

Author SHA1 Message Date
Alasdair Kergon
8449314da2 Another sync point - numerous fixes & clean ups. 2003-07-04 22:34:56 +00:00
Alasdair Kergon
63ad057028 Synchronise repository / 2.4.21 support 2003-07-04 19:38:49 +00:00
Alasdair Kergon
e720464330 Support for v4 interface 2003-07-01 21:20:58 +00:00
Alasdair Kergon
24036afef9 move functions 2003-05-06 12:22:24 +00:00
Alasdair Kergon
c78fa1a1bc remove global pvmove lock & poll for completion 2003-05-06 12:20:11 +00:00
Alasdair Kergon
faa8b9022c Check for locked LVs/pvmoves. 2003-05-06 12:14:36 +00:00
Alasdair Kergon
729bafef7a unsigned 2003-05-06 12:13:19 +00:00
Alasdair Kergon
590b028632 Prevent renaming active VGs for now. 2003-05-06 12:11:46 +00:00
Alasdair Kergon
8150d00f36 Don't process locked LVs 2003-05-06 12:10:18 +00:00
Alasdair Kergon
060065926f Store argv 2003-05-06 12:09:28 +00:00
Alasdair Kergon
70babe8a28 --abort --background 2003-05-06 12:08:58 +00:00
Alasdair Kergon
c36e09664f move fields 2003-05-06 12:06:02 +00:00
Alasdair Kergon
a9672246f3 reset_locking() 2003-05-06 12:03:13 +00:00
Alasdair Kergon
ff571884e9 Move fields. 2003-05-06 12:02:36 +00:00
Alasdair Kergon
475138bceb list_next 2003-05-06 12:01:13 +00:00
Alasdair Kergon
4a8af199c2 Add argv 2003-05-06 12:00:51 +00:00
Alasdair Kergon
bdabf5db72 Distinguish between visible & top level devices. 2003-05-06 12:00:29 +00:00
Alasdair Kergon
6a5f21b34e Missing 'make install' dependency. 2003-05-06 11:58:55 +00:00
Alasdair Kergon
d608be103c Update 2003-04-30 16:49:27 +00:00
Alasdair Kergon
374bb5d18a Don't move snapshots 2003-04-30 15:58:09 +00:00
Alasdair Kergon
031d6c25ff Add pvmove 2003-04-30 15:28:17 +00:00
Alasdair Kergon
223fb7b075 add region size & interval 2003-04-30 15:27:48 +00:00
Alasdair Kergon
a746741971 configurable region size 2003-04-30 15:26:54 +00:00
Alasdair Kergon
120faf2a58 pvmove support 2003-04-30 15:26:25 +00:00
Alasdair Kergon
990bca0dc6 use pvmove flag 2003-04-30 15:25:34 +00:00
Alasdair Kergon
3406472db7 Add mirror.c 2003-04-30 15:24:49 +00:00
Alasdair Kergon
1bd733c9f6 Outline pvmove man page 2003-04-30 15:24:08 +00:00
Alasdair Kergon
238c7f982e basic pvmove support 2003-04-30 15:23:43 +00:00
Alasdair Kergon
fcb81147cb pvmove flag 2003-04-30 15:22:52 +00:00
Alasdair Kergon
1915b73783 mirror type 2003-04-30 15:22:36 +00:00
Alasdair Kergon
ee79e621fb mirror display type 2003-04-30 15:21:43 +00:00
Alasdair Kergon
d203275a3b Add comment 2003-04-30 15:21:10 +00:00
Alasdair Kergon
9e8a996222 Up interface to major version number 4. 2003-04-30 13:48:53 +00:00
Alasdair Kergon
0126b0b3ed Up interface to major version number 4. 2003-04-29 22:52:11 +00:00
Alasdair Kergon
458928612c Display event number. 2003-04-29 11:34:40 +00:00
Alasdair Kergon
e33f88e28d Event number support. 2003-04-29 11:34:23 +00:00
Alasdair Kergon
be570bbf9e Try alternative syncs if BLKFLSBUF fails. 2003-04-28 16:20:39 +00:00
Alasdair Kergon
f59b4be110 Extra metadata-reading debug message. 2003-04-28 12:18:53 +00:00
Alasdair Kergon
37336e41be Revert to data_start 2003-04-28 11:55:58 +00:00
Alasdair Kergon
d24a1a3f0a Version 1.95.17 (new <PV>:<PE range list> allocation restriction feature). 2003-04-24 22:52:14 +00:00
Alasdair Kergon
f7258955bd Update segment area length when merging consecutive segments. 2003-04-24 22:46:47 +00:00
Alasdair Kergon
2a1eae5d6f o Metadata area struct change.
o Support physical extent restrictions on PV lists for allocations
    e.g. lvcreate -l 200 vg1 /dev/sda1:100-199:300-399
2003-04-24 22:23:24 +00:00
Alasdair Kergon
50ee0a4adb Stop more gracefully when in test mode. 2003-04-24 22:13:48 +00:00
Alasdair Kergon
955a26584e stripe filler parameter 2003-04-24 22:10:56 +00:00
Alasdair Kergon
1d3e407c8f o Rejig activation code device dependencies to make things a bit more robust
and further reduce the number of ioctl calls made.
o Metadata area struct change.
o Make config file accessible to activation functions & get stripe_filler
  from it.
o Allow kernel to return snapshot status as a fraction or a percentage.
2003-04-24 22:09:13 +00:00
Alasdair Kergon
cb809c4596 indent 2003-04-24 22:00:29 +00:00
Alasdair Kergon
53bbe2888e fix optind after last change to it 2003-04-24 21:59:42 +00:00
Alasdair Kergon
7246f476a5 Add pool_strndup 2003-04-24 21:58:34 +00:00
Alasdair Kergon
0785d1c390 DM_EXISTS_FLAG replaced by ENXIO 2003-04-24 16:08:18 +00:00
Alasdair Kergon
85d2c49d14 Some ioctl code tidying: removing duplicate internal buffers; making bounds
checks clearer (incl. variable renaming); using a flag to indicate when
output data doesn't fit into supplied buffer instead of returning an error etc.
2003-04-22 21:22:04 +00:00
Alasdair Kergon
8b77d62b7f Improve message for pvcreate of empty device. 2003-04-22 16:09:11 +00:00
Alasdair Kergon
373058a32a Improve build robustness. 2003-04-15 13:24:42 +00:00
Alasdair Kergon
e6293c2c8c Abort if any filter creation fails. 2003-04-15 13:22:43 +00:00
Alasdair Kergon
eff181c959 Cope with intentionally missing /proc. 2003-04-15 13:21:38 +00:00
Alasdair Kergon
54752c2305 Support snapshot status fraction. 2003-04-15 13:20:16 +00:00
Alasdair Kergon
b4753c044f Display read-only state. 2003-04-15 12:30:44 +00:00
Alasdair Kergon
26493424ae alignment fixes 2003-04-08 21:20:31 +00:00
Alasdair Kergon
0282fd1332 Add major arg 2003-04-04 13:22:58 +00:00
Alasdair Kergon
b9a019a08b Allow for specification of major number as well as minor. 2003-04-02 19:14:43 +00:00
Alasdair Kergon
66f6a0e687 size_t tidying 2003-04-02 19:11:23 +00:00
Alasdair Kergon
2dd1b9f97d Allow device major to be set too. 2003-04-02 19:03:00 +00:00
Alasdair Kergon
89615f3045 Reinstate lost vg_write() in lvchange --permission. 2003-04-02 13:01:04 +00:00
Alasdair Kergon
7e46192f67 Proposed changes to the ioctl interface to fix alignment issues on some
architectures and specify an explicit width for every numeric field.
2003-03-28 18:58:59 +00:00
Alasdair Kergon
e78d985cdf Avoid report segfault with non-partial inconsistent VG. 2003-03-24 18:22:48 +00:00
Alasdair Kergon
e8c4bf56fe Tidy various pre-processing incl. making libdl optional. 2003-03-24 18:08:53 +00:00
Alasdair Kergon
e6aa7d323d Fix incomplete munmap. (pjc) 2003-03-20 14:29:28 +00:00
Alasdair Kergon
fca8e25929 Fix typo. 2003-03-03 12:57:27 +00:00
Joe Thornber
8e8ac286b4 HAT_CHAR and DOLLAR_CHAR were defined to the same value ! 2003-02-20 14:53:56 +00:00
Alasdair Kergon
7d9770b9a2 Fix table output bug in last commit. 2003-02-20 13:30:03 +00:00
Andres Salomon
1996230460 Update packages. 2003-02-16 22:12:28 +00:00
Alasdair Kergon
de7897a864 LV name validation 2003-02-03 20:09:58 +00:00
Alasdair Kergon
e2884dcdb7 Identifiers may now start with digits etc. 2003-02-03 20:08:45 +00:00
Alasdair Kergon
544a53a42b Allow strings in single quotes too 2003-01-28 17:20:11 +00:00
Alasdair Kergon
2e4787bfc8 Treat 'section{' as equivalent to 'section {' 2003-01-28 16:07:04 +00:00
Alasdair Kergon
1829eeb171 merge back accidentally overwritten r1.2 change 2003-01-25 13:34:35 +00:00
Alasdair Kergon
c7488e3c4a Prepare for ioctl version number change. 2003-01-21 21:27:36 +00:00
Alasdair Kergon
3bf9606383 Allow optional verbose logging. 2003-01-21 21:25:51 +00:00
Alasdair Kergon
4f43f18f0a Allow optional verbose logging 2003-01-21 21:25:11 +00:00
Alasdair Kergon
5b7f197397 Add --enable-debug --disable-compat 2003-01-21 21:22:55 +00:00
Alasdair Kergon
018141c97f Indicate full (dropped) snapshot. 2003-01-21 18:50:50 +00:00
Alasdair Kergon
4d7813e57c vgreduce --removemissing to remove missing PVs & deps & make VG consistent 2003-01-17 21:04:26 +00:00
Alasdair Kergon
605c60208f Add success message; validate given VG name. 2003-01-17 21:02:04 +00:00
Alasdair Kergon
884fafcc30 Activation commands now return success in test mode. 2003-01-17 20:16:23 +00:00
Alasdair Kergon
56baa90320 Update 2003-01-10 22:51:18 +00:00
Alasdair Kergon
6bb20ee09e Fix (rare) cache bug on machines with large /dev directories. 2003-01-10 19:14:01 +00:00
Alasdair Kergon
541356430c Fix segfault in uuid display (substitution missed during bulk change) 2003-01-09 19:35:17 +00:00
Alasdair Kergon
2f4d91fd69 configure --disable-devmapper if you don't have libdevmapper 2003-01-08 22:44:07 +00:00
Alasdair Kergon
f58c5e6b30 o Additional device/filter-level debugging messages + duplicate alias fix
o 32/64-bit size_t fix (pjc)
2003-01-08 16:41:22 +00:00
Alasdair Kergon
0311d0132c Update date. 2003-01-07 17:06:58 +00:00
Alasdair Kergon
c946c97402 Detect duplicate PV uuids - select the one on an md device if appropriate. 2003-01-06 21:10:43 +00:00
Alasdair Kergon
84a6f51318 Ignore filter cache at startup if config file is newer than cache. 2003-01-06 21:09:04 +00:00
Alasdair Kergon
24a1501b0d More docn for filter changes. 2003-01-06 21:07:27 +00:00
Alasdair Kergon
383b6f5fcc Correct error message for non-snapshot activation failure. 2003-01-06 21:06:43 +00:00
Alasdair Kergon
633dd7ff9b When there are device name aliases, choose the "nicest" to display. 2003-01-03 21:11:23 +00:00
Alasdair Kergon
580624fad6 Also lock memory during LV updates. 2003-01-03 21:10:28 +00:00
Alasdair Kergon
a8190f7efa When activating an LV, remove any stray LVM1 /dev nodes and group file. 2003-01-03 13:50:47 +00:00
Alasdair Kergon
dd2157534b Default stripesize 64k & config file setting for it;
Clear many compiler warnings (i386) & associated bugs - hopefully without
introducing too many new bugs:-)  (Same exercise required for other archs.)
Default compilation has optimisation - or else use ./configure --enable-debug
2002-12-19 23:25:55 +00:00
163 changed files with 8691 additions and 2742 deletions

View File

@@ -1 +1 @@
1.95.12-cvs (2002-12-12)
2.00.00-cvs (2003-07-04)

View File

@@ -1,4 +1,13 @@
Mondy 18th November 2002
Wednesday 30th April 2003
=========================
A pvmove implementation is now available for the new metadata format.
When running a command that allocates space (e.g. lvcreate), you can now
restrict not only which disk(s) may be used but also the Physical Extents
on those disks. e.g. lvcreate -L 10 vg1 /dev/hda6:1000-2000:3000-4000
Monday 18th November 2002
========================
The new format of LVM metadata is ready for you to test!
@@ -15,7 +24,7 @@ While testing, we recommend turning logging on in the configuration file
to provide us with diagnostic information:
log {
file="/tmp/lvm2.log"
level=6
level=7
}
You should schedule regular backups of your configuration file and
@@ -65,7 +74,7 @@ changes.
What's not finished?
====================
The internal cache. If you turn on debugging output you'll see lots of
repeated disk reads, many of which will eventually get optimised out.
repeated messages, many of which will eventually get optimised out.
--test sometimes causes a command to fail (e.g. vgconvert --test) even
though the real command would work: again, fixing this is waiting for
@@ -78,9 +87,7 @@ finds something unexpected. This applies particularly to tools that
work on more than one volume group at once (e.g. vgsplit).
Display output. Some metadata information cannot yet be displayed.
Work has started on new display tools.
Recovery tools to salvage "lost" metadata directly from the disks:
but we hope the new format will mean such tools are hardly ever needed!

777
autoconf/config.guess vendored

File diff suppressed because it is too large Load Diff

373
autoconf/config.sub vendored
View File

@@ -1,6 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc.
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
timestamp='2001-09-07'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
@@ -25,6 +29,8 @@
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <config-patches@gnu.org>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
@@ -45,30 +51,73 @@
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
if [ x$1 = x ]
then
echo Configuration name missing. 1>&2
echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
echo "or $0 ALIAS" 1>&2
echo where ALIAS is a recognized configuration type. 1>&2
exit 1
fi
me=`echo "$0" | sed -e 's,.*/,,'`
# First pass through any local machine types.
case $1 in
*local*)
echo $1
exit 0
;;
*)
;;
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS
$0 [OPTION] ALIAS
Canonicalize a configuration name.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help"
exit 1 ;;
*local*)
# First pass through any local machine types.
echo $1
exit 0;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
linux-gnu*)
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -94,7 +143,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple)
-apple | -axis)
os=
basic_machine=$1
;;
@@ -105,9 +154,17 @@ case $os in
-scout)
;;
-wrs)
os=vxworks
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
@@ -156,33 +213,60 @@ case $os in
-psos*)
os=-psos
;;
-mint | -mint[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
| 580 | i960 | h8300 \
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
| alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \
| we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
| 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
| mips64vr5000 | miprs64vr5000el | mcore \
| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
| thumb | d10v)
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dsp16xx \
| fr30 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| m32r | m68000 | m68k | m88k | mcore \
| mips16 | mips64 | mips64el | mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el | mips64vr4300 \
| mips64vr4300el | mips64vr5000 | mips64vr5000el \
| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
| mipsisa32 \
| mn10200 | mn10300 \
| ns16k | ns32k \
| openrisc \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| s390 | s390x \
| sh | sh[34] | sh[34]eb | shbe | shle \
| sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
| stormy16 | strongarm \
| tahoe | thumb | tic80 | tron \
| v850 \
| we32k \
| x86 | xscale \
| z8k)
basic_machine=$basic_machine-unknown
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65)
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i[34567]86)
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
@@ -191,24 +275,43 @@ case $basic_machine in
exit 1
;;
# Recognize the basic CPU types with company name.
# FIXME: clean up the formatting here.
vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
| xmp-* | ymp-* \
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \
| alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
| clipper-* | orion-* \
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
| mipstx39-* | mipstx39el-* | mcore-* \
| f301-* | armv*-* | t3e-* \
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
| thumb-* | v850-* | d30v-* | tic30-* | c30-* )
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alphapca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armv*-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c54x-* \
| clipper-* | cray2-* | cydra-* \
| d10v-* | d30v-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| m32r-* \
| m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
| mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| s390-* | s390x-* \
| sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
| sparc-* | sparc64-* | sparc86x-* | sparclite-* \
| sparcv9-* | sparcv9b-* | stormy16-* | strongarm-* | sv1-* \
| t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
| v850-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \
| ymp-* \
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -245,14 +348,14 @@ case $basic_machine in
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-cbm
basic_machine=m68k-unknown
;;
amigaos | amigados)
basic_machine=m68k-cbm
basic_machine=m68k-unknown
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-cbm
basic_machine=m68k-unknown
os=-sysv4
;;
apollo68)
@@ -299,13 +402,16 @@ case $basic_machine in
basic_machine=cray2-cray
os=-unicos
;;
[ctj]90-cray)
basic_machine=c90-cray
[cjt]90)
basic_machine=${basic_machine}-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
@@ -353,6 +459,10 @@ case $basic_machine in
basic_machine=tron-gmicro
os=-sysv
;;
go32)
basic_machine=i386-pc
os=-go32
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
@@ -426,22 +536,21 @@ case $basic_machine in
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i[34567]86v32)
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i[34567]86v4*)
i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i[34567]86v)
i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i[34567]86sol2)
i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
@@ -453,14 +562,6 @@ case $basic_machine in
basic_machine=i386-unknown
os=-vsta
;;
i386-go32 | go32)
basic_machine=i386-unknown
os=-go32
;;
i386-mingw32 | mingw32)
basic_machine=i386-unknown
os=-mingw32
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
@@ -486,10 +587,14 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
mingw32)
basic_machine=i386-pc
os=-mingw32
;;
miniframe)
basic_machine=m68000-convergent
;;
*mint | *MiNT)
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
@@ -507,14 +612,22 @@ case $basic_machine in
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
mmix*)
basic_machine=mmix-knuth
os=-mmixware
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
;;
msdos)
basic_machine=i386-unknown
basic_machine=i386-pc
os=-msdos
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -524,7 +637,7 @@ case $basic_machine in
os=-netbsd
;;
netwinder)
basic_machine=armv4l-corel
basic_machine=armv4l-rebel
os=-linux
;;
news | news700 | news800 | news900)
@@ -572,9 +685,16 @@ case $basic_machine in
basic_machine=i960-intel
os=-mon960
;;
nonstopux)
basic_machine=mips-compaq
os=-nonstopux
;;
np1)
basic_machine=np1-gould
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
@@ -604,28 +724,28 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexen)
pentium | p5 | k5 | k6 | nexgen)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86)
pentiumpro | p6 | 6x86 | athlon)
basic_machine=i686-pc
;;
pentiumii | pentium2)
basic_machine=i786-pc
basic_machine=i686-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexen-*)
pentium-* | p5-* | k5-* | k6-* | nexgen-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-*)
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=rs6000-ibm
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
@@ -637,9 +757,23 @@ case $basic_machine in
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
pw32)
basic_machine=i586-unknown
os=-pw32
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
@@ -719,6 +853,10 @@ case $basic_machine in
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
basic_machine=sv1-cray
os=-unicos
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
@@ -727,6 +865,10 @@ case $basic_machine in
basic_machine=t3e-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
;;
@@ -779,6 +921,10 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
windows32)
basic_machine=i386-pc
os=-windows32-msvcrt
;;
xmp)
basic_machine=xmp-cray
os=-unicos
@@ -822,13 +968,20 @@ case $basic_machine in
vax)
basic_machine=vax-dec
;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sparc | sparcv9)
sh3 | sh4 | sh3eb | sh4eb)
basic_machine=sh-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
@@ -850,6 +1003,9 @@ case $basic_machine in
basic_machine=c4x-none
os=-coff
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
@@ -906,14 +1062,30 @@ case $os in
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*)
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
case $basic_machine in
x86-* | i*86-*)
;;
*)
os=-nto$os
;;
esac
;;
-nto*)
os=-nto-qnx
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -macos* | -mpw* | -magic* | -mon960* | -lnews*)
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
@@ -927,6 +1099,12 @@ case $os in
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
;;
-wince*)
os=-wince
;;
-osfrose*)
os=-osfrose
;;
@@ -951,6 +1129,9 @@ case $os in
-ns2 )
os=-nextstep2
;;
-nsk*)
os=-nsk
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
@@ -985,7 +1166,7 @@ case $os in
-xenix)
os=-xenix
;;
-*mint | -*MiNT)
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-none)
@@ -1013,12 +1194,15 @@ case $basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-corel)
arm*-rebel)
os=-linux
;;
arm*-semi)
os=-aout
;;
pdp10-*)
os=-tops20
;;
pdp11-*)
os=-none
;;
@@ -1127,7 +1311,7 @@ case $basic_machine in
*-masscomp)
os=-rtu
;;
f301-fujitsu)
f30[01]-fujitsu | f700-fujitsu)
os=-uxpv
;;
*-rom68k)
@@ -1187,7 +1371,7 @@ case $basic_machine in
-genix*)
vendor=ns
;;
-mvs*)
-mvs* | -opened*)
vendor=ibm
;;
-ptx*)
@@ -1205,12 +1389,23 @@ case $basic_machine in
-mpw* | -macos*)
vendor=apple
;;
-*mint | -*MiNT)
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:

417
configure vendored
View File

@@ -26,6 +26,10 @@ ac_help="$ac_help
statically. Default is dynamic linking"
ac_help="$ac_help
--enable-readline Enable readline support"
ac_help="$ac_help
--enable-debug Enable debugging"
ac_help="$ac_help
--disable-devmapper Disable device-mapper interaction"
# Initialize some variables set by options.
# The variables have the same names as the options, with
@@ -562,7 +566,7 @@ 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:566: checking for $ac_word" >&5
echo "configure:570: 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
@@ -594,7 +598,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:598: checking for $ac_word" >&5
echo "configure:602: 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
@@ -624,7 +628,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:628: checking for $ac_word" >&5
echo "configure:632: 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
@@ -675,7 +679,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:679: checking for $ac_word" >&5
echo "configure:683: 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
@@ -707,7 +711,7 @@ fi
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:711: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
echo "configure:715: 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.
@@ -718,12 +722,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF
#line 722 "configure"
#line 726 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
if { (eval echo configure:727: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:731: \"$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
@@ -749,12 +753,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:753: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "configure:757: 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:758: checking whether we are using GNU C" >&5
echo "configure:762: 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
@@ -763,7 +767,7 @@ else
yes;
#endif
EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:767: \"$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:771: \"$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
@@ -782,7 +786,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:786: checking whether ${CC-cc} accepts -g" >&5
echo "configure:790: 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
@@ -825,7 +829,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:829: checking for a BSD compatible install" >&5
echo "configure:833: 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
@@ -878,7 +882,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:882: checking whether ln -s works" >&5
echo "configure:886: 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
@@ -899,7 +903,7 @@ else
fi
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
echo "configure:903: checking whether ${MAKE-make} sets \${MAKE}" >&5
echo "configure:907: 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
@@ -928,7 +932,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:932: checking for $ac_word" >&5
echo "configure:936: 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
@@ -961,12 +965,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:965: checking for $ac_hdr that defines DIR" >&5
echo "configure:969: 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 970 "configure"
#line 974 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_hdr>
@@ -974,7 +978,7 @@ int main() {
DIR *dirp = 0;
; return 0; }
EOF
if { (eval echo configure:978: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:982: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_header_dirent_$ac_safe=yes"
else
@@ -999,7 +1003,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:1003: checking for opendir in -ldir" >&5
echo "configure:1007: 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
@@ -1007,7 +1011,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldir $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1011 "configure"
#line 1015 "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
@@ -1018,7 +1022,7 @@ int main() {
opendir()
; return 0; }
EOF
if { (eval echo configure:1022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1026: \"$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
@@ -1040,7 +1044,7 @@ fi
else
echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
echo "configure:1044: checking for opendir in -lx" >&5
echo "configure:1048: 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
@@ -1048,7 +1052,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lx $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1052 "configure"
#line 1056 "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
@@ -1059,7 +1063,7 @@ int main() {
opendir()
; return 0; }
EOF
if { (eval echo configure:1063: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1067: \"$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
@@ -1082,7 +1086,7 @@ fi
fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:1086: checking how to run the C preprocessor" >&5
echo "configure:1090: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -1097,13 +1101,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 1101 "configure"
#line 1105 "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:1107: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1111: \"$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
:
@@ -1114,13 +1118,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
#line 1118 "configure"
#line 1122 "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:1124: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1128: \"$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
:
@@ -1131,13 +1135,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
#line 1135 "configure"
#line 1139 "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:1141: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1145: \"$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
:
@@ -1162,12 +1166,12 @@ fi
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
echo "configure:1166: checking for ANSI C header files" >&5
echo "configure:1170: 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 1171 "configure"
#line 1175 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1175,7 +1179,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1179: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1183: \"$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*
@@ -1192,7 +1196,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 1196 "configure"
#line 1200 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1210,7 +1214,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 1214 "configure"
#line 1218 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1231,7 +1235,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
#line 1235 "configure"
#line 1239 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1242,7 +1246,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
if { (eval echo configure:1246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
if { (eval echo configure:1250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
@@ -1269,17 +1273,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:1273: checking for $ac_hdr" >&5
echo "configure:1277: 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 1278 "configure"
#line 1282 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1283: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:1287: \"$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*
@@ -1307,12 +1311,12 @@ done
echo $ac_n "checking for working const""... $ac_c" 1>&6
echo "configure:1311: checking for working const" >&5
echo "configure:1315: 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 1316 "configure"
#line 1320 "configure"
#include "confdefs.h"
int main() {
@@ -1361,7 +1365,7 @@ ccp = (char const *const *) p;
; return 0; }
EOF
if { (eval echo configure:1365: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1369: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
@@ -1382,21 +1386,21 @@ EOF
fi
echo $ac_n "checking for inline""... $ac_c" 1>&6
echo "configure:1386: checking for inline" >&5
echo "configure:1390: 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 1393 "configure"
#line 1397 "configure"
#include "confdefs.h"
int main() {
} int $ac_kw foo() {
; return 0; }
EOF
if { (eval echo configure:1400: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1404: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
else
@@ -1422,12 +1426,12 @@ EOF
esac
echo $ac_n "checking for off_t""... $ac_c" 1>&6
echo "configure:1426: checking for off_t" >&5
echo "configure:1430: 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 1431 "configure"
#line 1435 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1455,12 +1459,12 @@ EOF
fi
echo $ac_n "checking for pid_t""... $ac_c" 1>&6
echo "configure:1459: checking for pid_t" >&5
echo "configure:1463: 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 1464 "configure"
#line 1468 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1488,12 +1492,12 @@ EOF
fi
echo $ac_n "checking for size_t""... $ac_c" 1>&6
echo "configure:1492: checking for size_t" >&5
echo "configure:1496: 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 1497 "configure"
#line 1501 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1521,12 +1525,12 @@ EOF
fi
echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
echo "configure:1525: checking for st_rdev in struct stat" >&5
echo "configure:1529: 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 1530 "configure"
#line 1534 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -1534,7 +1538,7 @@ int main() {
struct stat s; s.st_rdev;
; return 0; }
EOF
if { (eval echo configure:1538: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1542: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_st_rdev=yes
else
@@ -1555,12 +1559,12 @@ EOF
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
echo "configure:1559: checking whether time.h and sys/time.h may both be included" >&5
echo "configure:1563: 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 1564 "configure"
#line 1568 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
@@ -1569,7 +1573,7 @@ int main() {
struct tm *tp;
; return 0; }
EOF
if { (eval echo configure:1573: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1577: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
@@ -1591,6 +1595,101 @@ fi
# Do some error checking and defaulting for the host and target type.
# The inputs are:
# configure --host=HOST --target=TARGET --build=BUILD NONOPT
#
# The rules are:
# 1. You are not allowed to specify --host, --target, and nonopt at the
# same time.
# 2. Host defaults to nonopt.
# 3. If nonopt is not specified, then host defaults to the current host,
# as determined by config.guess.
# 4. Target and build default to nonopt.
# 5. If nonopt is not specified, then target and build default to host.
# The aliases save the names the user supplied, while $host etc.
# will get canonicalized.
case $host---$target---$nonopt in
NONE---*---* | *---NONE---* | *---*---NONE) ;;
*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
esac
# Make sure we can run config.sub.
if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
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
host_alias=$host
case "$host_alias" in
NONE)
case $nonopt in
NONE)
if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
fi ;;
*) host_alias=$nonopt ;;
esac ;;
esac
host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
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
target_alias=$target
case "$target_alias" in
NONE)
case $nonopt in
NONE) target_alias=$host_alias ;;
*) target_alias=$nonopt ;;
esac ;;
esac
target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
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
build_alias=$build
case "$build_alias" in
NONE)
case $nonopt in
NONE) build_alias=$host_alias ;;
*) build_alias=$nonopt ;;
esac ;;
esac
build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$build" 1>&6
test "$host_alias" != "$target_alias" &&
test "$program_prefix$program_suffix$program_transform_name" = \
NONENONEs,x,x, &&
program_prefix=${target_alias}-
case "$host_os" in
linux*)
CFLAGS= ;;
esac
# Check whether --with-user or --without-user was given.
if test "${with_user+set}" = set; then
@@ -1625,12 +1724,16 @@ if [ "x$LVM1" != xnone -a "x$LVM1" != xinternal -a "x$LVM1" != xshared ];
exit
fi;
if test x$LVM1 = xinternal; then
CFLAGS="$CFLAGS -DLVM1_INTERNAL"
fi
# Check whether --enable-jobs or --disable-jobs was given.
if test "${enable_jobs+set}" = set; then
enableval="$enable_jobs"
JOBS=-j$enableval
else
JOBS=
JOBS=-j2
fi
@@ -1653,19 +1756,47 @@ else
fi
if test x$READLINE = xyes; then
CFLAGS="$CFLAGS -DREADLINE_SUPPORT"
fi
# Check whether --enable-debug or --disable-debug was given.
if test "${enable_debug+set}" = set; then
enableval="$enable_debug"
\
DEBUG=yes
else
DEBUG=no
fi
# Check whether --enable-devmapper or --disable-devmapper was given.
if test "${enable_devmapper+set}" = set; then
enableval="$enable_devmapper"
\
DEVMAPPER=no
else
DEVMAPPER=yes
fi
if test x$DEVMAPPER = xyes; then
CFLAGS="$CFLAGS -DDEVMAPPER_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:1663: checking whether ${CC-cc} needs -traditional" >&5
echo "configure:1794: 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 1669 "configure"
#line 1800 "configure"
#include "confdefs.h"
#include <sgtty.h>
Autoconf TIOCGETP
@@ -1683,7 +1814,7 @@ rm -f conftest*
if test $ac_cv_prog_gcc_traditional = no; then
cat > conftest.$ac_ext <<EOF
#line 1687 "configure"
#line 1818 "configure"
#include "confdefs.h"
#include <termio.h>
Autoconf TCGETA
@@ -1705,12 +1836,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:1709: checking return type of signal handlers" >&5
echo "configure:1840: 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 1714 "configure"
#line 1845 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
@@ -1727,7 +1858,7 @@ int main() {
int i;
; return 0; }
EOF
if { (eval echo configure:1731: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1862: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_type_signal=void
else
@@ -1746,12 +1877,12 @@ EOF
echo $ac_n "checking for vprintf""... $ac_c" 1>&6
echo "configure:1750: checking for vprintf" >&5
echo "configure:1881: 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 1755 "configure"
#line 1886 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vprintf(); below. */
@@ -1774,7 +1905,7 @@ vprintf();
; return 0; }
EOF
if { (eval echo configure:1778: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1909: \"$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
@@ -1798,12 +1929,12 @@ fi
if test "$ac_cv_func_vprintf" != yes; then
echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
echo "configure:1802: checking for _doprnt" >&5
echo "configure:1933: 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 1807 "configure"
#line 1938 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char _doprnt(); below. */
@@ -1826,7 +1957,7 @@ _doprnt();
; return 0; }
EOF
if { (eval echo configure:1830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:1961: \"$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
@@ -1853,12 +1984,12 @@ fi
for ac_func in mkdir rmdir uname
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:1857: checking for $ac_func" >&5
echo "configure:1988: 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 1862 "configure"
#line 1993 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1881,7 +2012,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:1885: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:2016: \"$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
@@ -1909,14 +2040,14 @@ done
if test x$READLINE = xyes; then
echo $ac_n "checking for library containing tgetent""... $ac_c" 1>&6
echo "configure:1913: checking for library containing tgetent" >&5
echo "configure:2044: 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 1920 "configure"
#line 2051 "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
@@ -1927,7 +2058,7 @@ int main() {
tgetent()
; return 0; }
EOF
if { (eval echo configure:1931: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:2062: \"$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
@@ -1938,7 +2069,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 1942 "configure"
#line 2073 "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
@@ -1949,7 +2080,7 @@ int main() {
tgetent()
; return 0; }
EOF
if { (eval echo configure:1953: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:2084: \"$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
@@ -1981,9 +2112,97 @@ Note: (n)curses also seems to work as a substitute for termcap. This was
fi
fi
echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
echo "configure:2117: 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
else
ac_save_LIBS="$LIBS"
LIBS="-ldl $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2125 "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
builtin and then its argument prototype would still apply. */
char dlopen();
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
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
HAVE_LIBDL=yes
else
echo "$ac_t""no" 1>&6
HAVE_LIBDL=no
fi
if test x$HAVE_LIBDL = xyes; then
CFLAGS="$CFLAGS -DHAVE_LIBDL"
LIBS="-ldl $LIBS"
fi
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
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"
#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; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_header_$ac_safe=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
cat >> confdefs.h <<EOF
#define $ac_tr_hdr 1
EOF
CFLAGS="$CFLAGS -DHAVE_GETOPTLONG"
else
echo "$ac_t""no" 1>&6
fi
done
if test x$READLINE = xyes; then
echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
echo "configure:1987: checking for readline in -lreadline" >&5
echo "configure:2206: 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
@@ -1991,7 +2210,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lreadline $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1995 "configure"
#line 2214 "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
@@ -2002,7 +2221,7 @@ int main() {
readline()
; return 0; }
EOF
if { (eval echo configure:2006: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:2225: \"$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
@@ -2039,12 +2258,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:2043: checking for rl_completion_matches" >&5
echo "configure:2262: 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 2048 "configure"
#line 2267 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char rl_completion_matches(); below. */
@@ -2067,7 +2286,7 @@ rl_completion_matches();
; return 0; }
EOF
if { (eval echo configure:2071: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:2290: \"$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
@@ -2081,12 +2300,12 @@ fi
if eval "test \"`echo '$ac_cv_func_'rl_completion_matches`\" = yes"; then
echo "$ac_t""yes" 1>&6
HAVE_RL_COMPLETION_MATCHES=yes
CFLAGS="$CFLAGS -DHAVE_RL_COMPLETION_MATCHES"
else
echo "$ac_t""no" 1>&6
HAVE_RL_COMPLETION_MATCHES=no
fi
fi
if test "-f VERSION"; then
@@ -2104,6 +2323,8 @@ fi
trap '' 1 2 15
cat > confcache <<\EOF
# This file is a shell script that caches the results of configure
@@ -2272,14 +2493,30 @@ s%@LN_S@%$LN_S%g
s%@SET_MAKE@%$SET_MAKE%g
s%@RANLIB@%$RANLIB%g
s%@CPP@%$CPP%g
s%@host@%$host%g
s%@host_alias@%$host_alias%g
s%@host_cpu@%$host_cpu%g
s%@host_vendor@%$host_vendor%g
s%@host_os@%$host_os%g
s%@target@%$target%g
s%@target_alias@%$target_alias%g
s%@target_cpu@%$target_cpu%g
s%@target_vendor@%$target_vendor%g
s%@target_os@%$target_os%g
s%@build@%$build%g
s%@build_alias@%$build_alias%g
s%@build_cpu@%$build_cpu%g
s%@build_vendor@%$build_vendor%g
s%@build_os@%$build_os%g
s%@JOBS@%$JOBS%g
s%@STATIC_LINK@%$STATIC_LINK%g
s%@READLINE@%$READLINE%g
s%@LVM1@%$LVM1%g
s%@HAVE_RL_COMPLETION_MATCHES@%$HAVE_RL_COMPLETION_MATCHES%g
s%@OWNER@%$OWNER%g
s%@GROUP@%$GROUP%g
s%@LVM_VERSION@%$LVM_VERSION%g
s%@DEBUG@%$DEBUG%g
s%@DEVMAPPER@%$DEVMAPPER%g
s%@HAVE_LIBDL@%$HAVE_LIBDL%g
CEOF
EOF

View File

@@ -46,6 +46,14 @@ AC_TYPE_SIZE_T
AC_STRUCT_ST_RDEV
AC_HEADER_TIME
dnl Get system type
AC_CANONICAL_SYSTEM
case "$host_os" in
linux*)
CFLAGS= ;;
esac
dnl -- prefix is /usr by default, the exec_prefix default is setup later
AC_PREFIX_DEFAULT(/usr)
@@ -75,7 +83,11 @@ if [[ "x$LVM1" != xnone -a "x$LVM1" != xinternal -a "x$LVM1" != xshared ]];
exit
fi;
AC_ARG_ENABLE(jobs, [ --enable-jobs=NUM Number of jobs to run simultaneously], JOBS=-j$enableval, JOBS=)
if test x$LVM1 = xinternal; then
CFLAGS="$CFLAGS -DLVM1_INTERNAL"
fi
AC_ARG_ENABLE(jobs, [ --enable-jobs=NUM Number of jobs to run simultaneously], JOBS=-j$enableval, JOBS=-j2)
dnl Enables staticly linked tools
AC_ARG_ENABLE(static_link, [ --enable-static_link Use this to link the tools to the liblvm library
@@ -85,6 +97,22 @@ dnl Enable readline
AC_ARG_ENABLE(readline, [ --enable-readline Enable readline support], \
READLINE=$enableval, READLINE=no)
if test x$READLINE = xyes; then
CFLAGS="$CFLAGS -DREADLINE_SUPPORT"
fi
dnl Enable Debugging
AC_ARG_ENABLE(debug, [ --enable-debug Enable debugging], \
DEBUG=yes, DEBUG=no)
dnl Disable devmapper
AC_ARG_ENABLE(devmapper, [ --disable-devmapper Disable device-mapper interaction], \
DEVMAPPER=no, DEVMAPPER=yes)
if test x$DEVMAPPER = xyes; then
CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT"
fi
dnl Mess with default exec_prefix
if [[ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]];
then exec_prefix="";
@@ -113,6 +141,17 @@ Note: (n)curses also seems to work as a substitute for termcap. This was
)
fi
dnl Check for dlopen
AC_CHECK_LIB(dl, dlopen, HAVE_LIBDL=yes, HAVE_LIBDL=no)
if test x$HAVE_LIBDL = xyes; then
CFLAGS="$CFLAGS -DHAVE_LIBDL"
LIBS="-ldl $LIBS"
fi
dnl Check for getopt
AC_CHECK_HEADERS(getopt.h, CFLAGS="$CFLAGS -DHAVE_GETOPTLONG")
dnl Check for readline (Shamelessly copied from parted 1.4.17)
if test x$READLINE = xyes; then
AC_CHECK_LIB(readline, readline, ,
@@ -126,8 +165,8 @@ package as well (which may be called readline-devel or something similar).
)
exit
)
AC_CHECK_FUNC(rl_completion_matches, HAVE_RL_COMPLETION_MATCHES=yes,
HAVE_RL_COMPLETION_MATCHES=no)
AC_CHECK_FUNC(rl_completion_matches, CFLAGS="$CFLAGS -DHAVE_RL_COMPLETION_MATCHES")
fi
if test "-f VERSION"; then
@@ -138,13 +177,15 @@ fi
AC_SUBST(JOBS)
AC_SUBST(STATIC_LINK)
AC_SUBST(READLINE)
AC_SUBST(LVM1)
AC_SUBST(HAVE_RL_COMPLETION_MATCHES)
AC_SUBST(OWNER)
AC_SUBST(GROUP)
AC_SUBST(CFLAGS)
AC_SUBST(LIBS)
AC_SUBST(LVM_VERSION)
AC_SUBST(DEBUG)
AC_SUBST(DEVMAPPER)
AC_SUBST(HAVE_LIBDL)
dnl First and last lines should not contain files to generate in order to
dnl keep utility scripts running properly
AC_OUTPUT( \

10
debian/changelog vendored
View File

@@ -1,3 +1,13 @@
lvm2 (1.95.15-1) unstable; urgency=low
* New upstream release.
* Remove undocumented manpage symlinks.
* Update description to be more informative. (Closes: #173499)
* Add kernel-patch-device-mapper suggestion.
* Update standards version.
-- Andres Salomon <dilinger@mp3revolution.net> Sun, 16 Feb 2002 04:21:26 -0400
lvm2 (1.95.11-1) unstable; urgency=low
* New upstream release. (Closes: #171436)

8
debian/control vendored
View File

@@ -3,7 +3,7 @@ Section: admin
Priority: optional
Maintainer: Andres Salomon <dilinger@mp3revolution.net>
Build-Depends: debhelper (>> 3.0.0), libdevmapper-dev (>= 0.96.04), libreadline4-dev
Standards-Version: 3.5.2
Standards-Version: 3.5.8.0
Package: lvm2
Architecture: any
@@ -11,10 +11,14 @@ Depends: ${shlibs:Depends}
Conflicts: lvm10, lvm-common
Replaces: lvm10, lvm-common
Provides: lvm-binaries
Suggests: dmsetup
Suggests: dmsetup, kernel-patch-device-mapper
Description: The Linux Logical Volume Manager
This is LVM2, the rewrite of The Linux Logical Volume Manager. LVM
supports enterprise level volume management of disk and disk subsystems
by grouping arbitrary disks into volume groups. The total capacity of
volume groups can be allocated to logical volumes, which are accessed as
regular block devices.
.
LVM2 is currently stable, but has some unimplemented features (most notably,
pvmove and e2fsadm). It is not yet recommended for production use. It is
backwards-compatible with LVM1 (lvm10), and requires Linux kernel 2.4.

1
debian/rules vendored
View File

@@ -102,7 +102,6 @@ binary-arch: build install
dh_installcron
dh_installman
dh_installinfo
dh_undocumented
dh_installchangelogs
dh_strip
dh_link

13
debian/undocumented vendored
View File

@@ -1,13 +0,0 @@
e2fsadm.8
lvmdiskscan.8
lvmsadc.8
lvmsar.8
lvresize.8
pvdata.8
pvmove.8
pvresize.8
version.8
vgexport.8
vgimport.8
vgmknodes.8
vgsplit.8

View File

@@ -23,8 +23,15 @@ devices {
# The filter consists of an array of regular expressions. These
# expressions can be delimited by a character of your choice, and
# prefixed with either an 'a' (for accept) or 'r' (for reject).
# The first expression found to match a device name determines if
# the device will be accepted or rejected (ignored). Devices that
# don't match any patterns are accepted.
# Remember to run vgscan after you change this parameter.
# If using RAID md devices as physical volumes, you should
# set up a filter here to reject the constituent devices.
# Remember to run vgscan after you change this parameter to ensure
# that the cache file gets regenerated (see below).
# By default we accept every block device:
filter = [ "a/.*/" ]
@@ -44,7 +51,7 @@ devices {
# The results of the filtering are cached on disk to avoid
# rescanning dud devices (which can take a very long time). By
# default this cache file is hidden in the /etc/lvm directory.
# It is safe to delete this file. vgscan regenerates it.
# It is safe to delete this file: the tools regenerate it.
cache = "/etc/lvm/.cache"
# You can turn off writing this cache file by setting this to 0.
@@ -97,6 +104,10 @@ log {
# indent = 0
# command_names = 1
# prefix = " -- "
# Set this if you want log messages during activation.
# Don't use this in low memory situations (can deadlock).
# activation = 0
}
# Configuration of metadata backups and archiving. In LVM2 when we
@@ -186,6 +197,26 @@ global {
# library_dir = "/lib"
}
activation {
# Device used in place of missing stripes if activating incomplete volume.
# For now, you need to set this up yourself first (e.g. with 'dmsetup')
# For example, you could make it return I/O errors using the 'error'
# target or make it return zeros.
missing_stripe_filler = "/dev/ioerror"
# Size (in KB) of each copy operation when mirroring
mirror_region_size = 512
# How much stack (in KB) to reserve for use while devices suspended
reserved_stack = 256
# How much memory (in KB) to reserve for use while devices suspended
reserved_memory = 8192
# Nice value used while devices suspended
process_priority = -18
}
####################
# Advanced section #
@@ -213,7 +244,8 @@ global {
# preferably on different (non-LV) filesystems, and with no other
# on-disk metadata (pvmetadatacopies = 0). Or this can be in
# addition to on-disk metadata areas.
# The feature was originally added to simplify testing.
# The feature was originally added to simplify testing and is not
# supported under low memory situations - the machine could lock up.
#
# Never edit any files in these directories by hand unless you
# you are absolutely sure you know what you are doing! Use

View File

@@ -1,5 +1,5 @@
../lib/activate/activate.h
../lib/cache/cache.h
../lib/cache/lvmcache.h
../lib/commands/errors.h
../lib/commands/toolcontext.h
../lib/config/config.h
@@ -24,6 +24,7 @@
../lib/log/log.h
../lib/metadata/metadata.h
../lib/mm/dbg_malloc.h
../lib/mm/memlock.h
../lib/mm/pool.h
../lib/mm/xlate.h
../lib/misc/crc.h

View File

@@ -14,9 +14,7 @@ endif
SOURCES=\
activate/activate.c \
activate/dev_manager.c \
activate/fs.c \
cache/cache.c \
cache/lvmcache.c \
commands/toolcontext.c \
config/config.c \
datastruct/bitset.c \
@@ -38,7 +36,6 @@ SOURCES=\
format_text/import_vsn1.c \
format_text/text_label.c \
label/label.c \
locking/external_locking.c \
locking/file_locking.c \
locking/locking.c \
locking/no_locking.c \
@@ -46,12 +43,13 @@ SOURCES=\
metadata/lv_manip.c \
metadata/merge.c \
metadata/metadata.c \
metadata/mirror.c \
metadata/pv_map.c \
metadata/snapshot_manip.c \
misc/crc.c \
misc/lvm-file.c \
misc/sharedlib.c \
mm/dbg_malloc.c \
misc/lvm-string.c \
mm/memlock.c \
mm/pool.c \
regex/matcher.c \
regex/parse_rx.c \
@@ -70,6 +68,23 @@ ifeq ("@LVM1@", "internal")
format1/vg_number.c
endif
ifeq ("@DEBUG@", "yes")
SOURCES+=\
mm/dbg_malloc.c
endif
ifeq ("@DEVMAPPER@", "yes")
SOURCES+=\
activate/dev_manager.c \
activate/fs.c
endif
ifeq ("@HAVE_LIBDL@", "yes")
SOURCES+=\
locking/external_locking.c \
misc/sharedlib.c
endif
TARGETS=liblvm.a
include ../make.tmpl

View File

@@ -7,6 +7,7 @@
#include "lib.h"
#include "metadata.h"
#include "activate.h"
#include "memlock.h"
#include "display.h"
#include "fs.h"
#include "lvm-string.h"
@@ -15,19 +16,82 @@
#include "dev_manager.h"
#include <limits.h>
#include <linux/kdev_t.h>
#include <fcntl.h>
#include <unistd.h>
#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
#ifndef DEVMAPPER_SUPPORT
void set_activation(int act)
{
if (act)
log_error("Compiled without libdevmapper support. "
"Can't enable activation.");
}
int activation(void)
{
return 0;
}
int library_version(char *version, size_t size)
{
return 0;
}
int driver_version(char *version, size_t size)
{
return 0;
}
int lv_info(const struct logical_volume *lv, struct lvinfo *info)
{
return 0;
}
int lv_snapshot_percent(struct logical_volume *lv, float *percent)
{
return 0;
}
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
uint32_t *event_nr)
{
return 0;
}
int lvs_in_vg_activated(struct volume_group *vg)
{
return 0;
}
int lvs_in_vg_opened(struct volume_group *vg)
{
return 0;
}
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
{
return 1;
}
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
{
return 1;
}
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
{
return 1;
}
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
{
return 1;
}
void activation_exit(void)
{
return;
}
#else /* DEVMAPPER_SUPPORT */
static int _activation = 1;
void set_activation(int activation)
void set_activation(int act)
{
if (activation == _activation)
if (act == _activation)
return;
_activation = activation;
_activation = act;
if (_activation)
log_verbose("Activation enabled. Device-mapper kernel "
"driver will be used.");
@@ -36,7 +100,7 @@ void set_activation(int activation)
"interaction will be attempted.");
}
int activation()
int activation(void)
{
return _activation;
}
@@ -82,22 +146,30 @@ int driver_version(char *version, size_t size)
/*
* Returns 1 if info structure populated, else 0 on failure.
*/
int lv_info(struct logical_volume *lv, struct dm_info *info)
int lv_info(const struct logical_volume *lv, struct lvinfo *info)
{
int r;
struct dev_manager *dm;
struct dm_info dminfo;
if (!activation())
return 0;
if (!(dm = dev_manager_create(lv->vg->name))) {
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
stack;
return 0;
}
if (!(r = dev_manager_info(dm, lv, info)))
if (!(r = dev_manager_info(dm, lv, &dminfo)))
stack;
info->exists = dminfo.exists;
info->suspended = dminfo.suspended;
info->open_count = dminfo.open_count;
info->major = dminfo.major;
info->minor = dminfo.minor;
info->read_only = dminfo.read_only;
dev_manager_destroy(dm);
return r;
}
@@ -113,7 +185,7 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
if (!activation())
return 0;
if (!(dm = dev_manager_create(lv->vg->name))) {
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
stack;
return 0;
}
@@ -126,9 +198,32 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
return r;
}
/* FIXME Merge with snapshot_percent */
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
uint32_t *event_nr)
{
int r;
struct dev_manager *dm;
if (!activation())
return 0;
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
stack;
return 0;
}
if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
stack;
dev_manager_destroy(dm);
return r;
}
static int _lv_active(struct logical_volume *lv)
{
struct dm_info info;
struct lvinfo info;
if (!lv_info(lv, &info)) {
stack;
@@ -140,7 +235,7 @@ static int _lv_active(struct logical_volume *lv)
static int _lv_open_count(struct logical_volume *lv)
{
struct dm_info info;
struct lvinfo info;
if (!lv_info(lv, &info)) {
stack;
@@ -156,7 +251,7 @@ static int _lv_activate(struct logical_volume *lv)
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->name))) {
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
stack;
return 0;
}
@@ -173,7 +268,7 @@ static int _lv_deactivate(struct logical_volume *lv)
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->name))) {
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
stack;
return 0;
}
@@ -190,7 +285,7 @@ static int _lv_suspend(struct logical_volume *lv)
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->name))) {
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
stack;
return 0;
}
@@ -244,7 +339,7 @@ int lvs_in_vg_opened(struct volume_group *vg)
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
{
struct logical_volume *lv;
struct dm_info info;
struct lvinfo info;
if (!activation())
return 1;
@@ -252,12 +347,9 @@ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
if (!(lv = lv_from_lvid(cmd, lvid_s)))
return 0;
if (!activation())
return 1;
if (test_mode()) {
_skip("Suspending '%s'.", lv->name);
return 0;
return 1;
}
if (!lv_info(lv, &info)) {
@@ -265,8 +357,15 @@ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
return 0;
}
if (info.exists && !info.suspended)
return _lv_suspend(lv);
if (!info.exists || info.suspended)
return 1;
memlock_inc();
if (!_lv_suspend(lv)) {
memlock_dec();
fs_unlock();
return 0;
}
return 1;
}
@@ -274,7 +373,7 @@ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
{
struct logical_volume *lv;
struct dm_info info;
struct lvinfo info;
if (!activation())
return 1;
@@ -284,7 +383,7 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
if (test_mode()) {
_skip("Resuming '%s'.", lv->name);
return 0;
return 1;
}
if (!lv_info(lv, &info)) {
@@ -292,8 +391,14 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
return 0;
}
if (info.exists && info.suspended)
return _lv_activate(lv);
if (!info.exists || !info.suspended)
return 1;
if (!_lv_activate(lv))
return 0;
memlock_dec();
fs_unlock();
return 1;
}
@@ -301,7 +406,8 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
{
struct logical_volume *lv;
struct dm_info info;
struct lvinfo info;
int r;
if (!activation())
return 1;
@@ -311,7 +417,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
if (test_mode()) {
_skip("Deactivating '%s'.", lv->name);
return 0;
return 1;
}
if (!lv_info(lv, &info)) {
@@ -319,16 +425,22 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
return 0;
}
if (info.exists)
return _lv_deactivate(lv);
if (!info.exists)
return 1;
return 1;
memlock_inc();
r = _lv_deactivate(lv);
memlock_dec();
fs_unlock();
return r;
}
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
{
struct logical_volume *lv;
struct dm_info info;
struct lvinfo info;
int r;
if (!activation())
return 1;
@@ -338,7 +450,7 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s)
if (test_mode()) {
_skip("Activating '%s'.", lv->name);
return 0;
return 1;
}
if (!lv_info(lv, &info)) {
@@ -346,8 +458,19 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s)
return 0;
}
if (!info.exists || info.suspended)
return _lv_activate(lv);
if (info.exists && !info.suspended)
return 1;
return 1;
memlock_inc();
r = _lv_activate(lv);
memlock_dec();
fs_unlock();
return r;
}
void activation_exit(void)
{
dev_manager_exit();
}
#endif

View File

@@ -8,36 +8,43 @@
#define LVM_ACTIVATE_H
#include "metadata.h"
#include <libdevmapper.h>
#ifdef DEVMAPPER_SUPPORT
# include <libdevmapper.h>
#endif
struct lvinfo {
int exists;
int suspended;
unsigned int open_count;
int major;
int minor;
int read_only;
};
void set_activation(int activation);
int activation();
int activation(void);
int driver_version(char *version, size_t size);
int library_version(char *version, size_t size);
/*
* Returns 1 if info structure has been populated, else 0.
*/
int lv_info(struct logical_volume *lv, struct dm_info *info);
/*
* Returns 1 if percent has been set, else 0.
*/
int lv_snapshot_percent(struct logical_volume *lv, float *percent);
void activation_exit(void);
/*
* These should eventually use config file
* to determine whether or not to activate
*/
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s);
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);
/*
* FIXME:
* I don't like the *lvs_in_vg* function names.
* Returns 1 if info structure has been populated, else 0.
*/
int lv_info(const struct logical_volume *lv, struct lvinfo *info);
/*
* Returns 1 if percent has been set, else 0.
*/
int lv_snapshot_percent(struct logical_volume *lv, float *percent);
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
uint32_t *event_nr);
/*
* Return number of LVs in the VG that are active.

File diff suppressed because it is too large Load Diff

View File

@@ -8,16 +8,18 @@
#define _LVM_DEV_MANAGER_H
#include "metadata.h"
#include <libdevmapper.h>
#include "config.h"
struct dev_manager;
struct dm_info;
/*
* Constructor and destructor.
*/
struct dev_manager *dev_manager_create(const char *vg_name);
struct dev_manager *dev_manager_create(const char *vg_name,
struct config_tree *cf);
void dev_manager_destroy(struct dev_manager *dm);
void dev_manager_exit(void);
/*
* The device handler is responsible for creating all the layered
@@ -25,10 +27,13 @@ void dev_manager_destroy(struct dev_manager *dm);
* (eg, an origin is created before its snapshot, but is not
* unsuspended until the snapshot is also created.)
*/
int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
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,
struct logical_volume *lv, int wait,
float *percent, uint32_t *event_nr);
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);

View File

@@ -9,19 +9,21 @@
#include "toolcontext.h"
#include "lvm-string.h"
#include "lvm-file.h"
#include "memlock.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <dirent.h>
#include <libdevmapper.h>
static int _mk_dir(struct volume_group *vg)
static int _mk_dir(const char *dev_dir, const char *vg_name)
{
char vg_path[PATH_MAX];
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
vg->cmd->dev_dir, vg->name) == -1) {
dev_dir, vg_name) == -1) {
log_error("Couldn't construct name of volume "
"group directory.");
return 0;
@@ -39,12 +41,12 @@ static int _mk_dir(struct volume_group *vg)
return 1;
}
static int _rm_dir(struct volume_group *vg)
static int _rm_dir(const char *dev_dir, const char *vg_name)
{
char vg_path[PATH_MAX];
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
vg->cmd->dev_dir, vg->name) == -1) {
dev_dir, vg_name) == -1) {
log_error("Couldn't construct name of volume "
"group directory.");
return 0;
@@ -58,32 +60,100 @@ static int _rm_dir(struct volume_group *vg)
return 1;
}
static int _mk_link(struct logical_volume *lv, const char *dev)
static void _rm_blks(const char *dir)
{
char lv_path[PATH_MAX], link_path[PATH_MAX];
const char *name;
char path[PATH_MAX];
struct dirent *dirent;
struct stat buf;
DIR *d;
if (!(d = opendir(dir))) {
log_sys_error("opendir", dir);
return;
}
while ((dirent = readdir(d))) {
name = dirent->d_name;
if (!strcmp(name, ".") || !strcmp(name, ".."))
continue;
if (lvm_snprintf(path, sizeof(path), "%s/%s", dir, name) == -1) {
log_error("Couldn't create path for %s", name);
continue;
}
if (!lstat(path, &buf)) {
if (!S_ISBLK(buf.st_mode))
continue;
log_very_verbose("Removing %s", path);
if (unlink(path) < 0)
log_sys_error("unlink", path);
}
}
}
static int _mk_link(const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev)
{
char lv_path[PATH_MAX], link_path[PATH_MAX], lvm1_group_path[PATH_MAX];
char vg_path[PATH_MAX];
struct stat buf;
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
lv->vg->cmd->dev_dir, lv->vg->name, lv->name) == -1) {
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
dev_dir, vg_name) == -1) {
log_error("Couldn't create path for volume group dir %s",
vg_name);
return 0;
}
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s/%s", vg_path,
lv_name) == -1) {
log_error("Couldn't create source pathname for "
"logical volume link %s", lv->name);
"logical volume link %s", lv_name);
return 0;
}
if (lvm_snprintf(link_path, sizeof(link_path), "%s/%s",
dm_dir(), dev) == -1) {
log_error("Couldn't create destination pathname for "
"logical volume link for %s", lv->name);
"logical volume link for %s", lv_name);
return 0;
}
if (lvm_snprintf(lvm1_group_path, sizeof(lvm1_group_path), "%s/group",
vg_path) == -1) {
log_error("Couldn't create pathname for LVM1 group file for %s",
vg_name);
return 0;
}
/* To reach this point, the VG must have been locked.
* As locking fails if the VG is active under LVM1, it's
* now safe to remove any LVM1 devices we find here
* (as well as any existing LVM2 symlink). */
if (!lstat(lvm1_group_path, &buf)) {
if (!S_ISCHR(buf.st_mode)) {
log_error("Non-LVM1 character device found at %s",
lvm1_group_path);
} else {
_rm_blks(vg_path);
log_very_verbose("Removing %s", lvm1_group_path);
if (unlink(lvm1_group_path) < 0)
log_sys_error("unlink", lvm1_group_path);
}
}
if (!lstat(lv_path, &buf)) {
if (!S_ISLNK(buf.st_mode)) {
if (!S_ISLNK(buf.st_mode) && !S_ISBLK(buf.st_mode)) {
log_error("Symbolic link %s not created: file exists",
link_path);
return 0;
}
log_very_verbose("Removing %s", lv_path);
if (unlink(lv_path) < 0) {
log_sys_error("unlink", lv_path);
return 0;
@@ -99,23 +169,24 @@ static int _mk_link(struct logical_volume *lv, const char *dev)
return 1;
}
static int _rm_link(struct logical_volume *lv, const char *lv_name)
static int _rm_link(const char *dev_dir, const char *vg_name,
const char *lv_name)
{
struct stat buf;
char lv_path[PATH_MAX];
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
lv->vg->cmd->dev_dir, lv->vg->name, lv_name) == -1) {
dev_dir, vg_name, lv_name) == -1) {
log_error("Couldn't determine link pathname.");
return 0;
}
log_very_verbose("Removing link %s", lv_path);
if (lstat(lv_path, &buf) || !S_ISLNK(buf.st_mode)) {
log_error("%s not symbolic link - not removing", lv_path);
return 0;
}
log_very_verbose("Removing link %s", lv_path);
if (unlink(lv_path) < 0) {
log_sys_error("unlink", lv_path);
return 0;
@@ -124,35 +195,143 @@ static int _rm_link(struct logical_volume *lv, const char *lv_name)
return 1;
}
int fs_add_lv(struct logical_volume *lv, const char *dev)
typedef enum {
FS_ADD,
FS_DEL,
FS_RENAME
} fs_op_t;
static int _do_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev,
const char *old_lv_name)
{
if (!_mk_dir(lv->vg) || !_mk_link(lv, dev)) {
stack;
return 0;
switch (type) {
case FS_ADD:
if (!_mk_dir(dev_dir, vg_name) ||
!_mk_link(dev_dir, vg_name, lv_name, dev)) {
stack;
return 0;
}
break;
case FS_DEL:
if (!_rm_link(dev_dir, vg_name, lv_name) ||
!_rm_dir(dev_dir, vg_name)) {
stack;
return 0;
}
break;
/* FIXME Use rename() */
case FS_RENAME:
if (old_lv_name && !_rm_link(dev_dir, vg_name, old_lv_name))
stack;
if (!_mk_link(dev_dir, vg_name, lv_name, dev))
stack;
}
return 1;
}
static LIST_INIT(_fs_ops);
struct fs_op_parms {
struct list list;
fs_op_t type;
char *dev_dir;
char *vg_name;
char *lv_name;
char *dev;
char *old_lv_name;
char names[0];
};
static void _store_str(char **pos, char **ptr, const char *str)
{
strcpy(*pos, str);
*ptr = *pos;
*pos += strlen(*ptr) + 1;
}
static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev,
const char *old_lv_name)
{
struct fs_op_parms *fsp;
size_t len = strlen(dev_dir) + strlen(vg_name) + strlen(lv_name) +
strlen(dev) + strlen(old_lv_name) + 5;
char *pos;
if (!(fsp = dbg_malloc(sizeof(*fsp) + len))) {
log_error("No space to stack fs operation");
return 0;
}
pos = fsp->names;
fsp->type = type;
_store_str(&pos, &fsp->dev_dir, dev_dir);
_store_str(&pos, &fsp->vg_name, vg_name);
_store_str(&pos, &fsp->lv_name, lv_name);
_store_str(&pos, &fsp->dev, dev);
_store_str(&pos, &fsp->old_lv_name, old_lv_name);
list_add(&_fs_ops, &fsp->list);
return 1;
}
static void _pop_fs_ops(void)
{
struct list *fsph, *fspht;
struct fs_op_parms *fsp;
list_iterate_safe(fsph, fspht, &_fs_ops) {
fsp = list_item(fsph, struct fs_op_parms);
_do_fs_op(fsp->type, fsp->dev_dir, fsp->vg_name, fsp->lv_name,
fsp->dev, fsp->old_lv_name);
list_del(&fsp->list);
dbg_free(fsp);
}
}
static int _fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev, const char *old_lv_name)
{
if (memlock()) {
if (!_stack_fs_op(type, dev_dir, vg_name, lv_name, dev,
old_lv_name)) {
stack;
return 0;
}
return 1;
}
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)
{
return _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, "");
}
int fs_del_lv(struct logical_volume *lv)
{
if (!_rm_link(lv, lv->name) || !_rm_dir(lv->vg)) {
stack;
return 0;
}
return 1;
return _fs_op(FS_DEL, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
"", "");
}
/* FIXME Use rename() */
int fs_rename_lv(struct logical_volume *lv,
const char *dev, const char *old_name)
{
if (old_name && !_rm_link(lv, old_name))
stack;
if (!_mk_link(lv, dev))
stack;
return 1;
return _fs_op(FS_RENAME, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, old_name);
}
void fs_unlock(void)
{
if (!memlock()) {
dm_lib_release();
_pop_fs_ops();
}
}

View File

@@ -18,6 +18,6 @@ int fs_add_lv(struct logical_volume *lv, const char *dev);
int fs_del_lv(struct logical_volume *lv);
int fs_rename_lv(struct logical_volume *lv,
const char *dev, const char *old_name);
void fs_unlock(void);
#endif

73
lib/cache/cache.h vendored
View File

@@ -1,73 +0,0 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the LGPL.
*
*/
#ifndef _LVM_CACHE_H
#define _LVM_CACHE_H
#include "dev-cache.h"
#include "list.h"
#include "uuid.h"
#include "label.h"
#include "metadata.h"
#include <sys/types.h>
#define ORPHAN ""
#define CACHE_INVALID 0x00000001
/* LVM specific per-volume info */
/* Eventual replacement for struct physical_volume perhaps? */
struct cache_vginfo {
struct list list; /* Join these vginfos together */
struct list infos; /* List head for cache_infos */
char *vgname; /* "" == orphan */
char vgid[ID_LEN + 1];
struct format_type *fmt;
};
struct cache_info {
struct list list; /* Join VG members together */
struct list mdas; /* list head for metadata areas */
struct list das; /* list head for data areas */
struct cache_vginfo *vginfo; /* NULL == unknown */
struct label *label;
struct format_type *fmt;
struct device *dev;
uint64_t device_size; /* Bytes */
uint32_t status;
};
int cache_init();
void cache_destroy();
/* Set full_scan to 1 to reread every filtered device label */
int cache_label_scan(struct cmd_context *cmd, int full_scan);
/* Add/delete a device */
struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid);
void cache_del(struct cache_info *info);
/* Update things */
int cache_update_vgname(struct cache_info *info, const char *vgname);
int cache_update_vg(struct volume_group *vg);
/* Queries */
struct format_type *fmt_from_vgname(const char *vgname);
struct cache_vginfo *vginfo_from_vgname(const char *vgname);
struct cache_vginfo *vginfo_from_vgid(const char *vgid);
struct cache_info *info_from_pvid(const char *pvid);
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
/* Returns list of struct str_lists containing pool-allocated copy of vgnames */
/* Set full_scan to 1 to reread every filtered device label */
struct list *cache_get_vgnames(struct cmd_context *cmd, int full_scan);
#endif

View File

@@ -6,19 +6,23 @@
*/
#include "lib.h"
#include "cache.h"
#include "lvmcache.h"
#include "hash.h"
#include "toolcontext.h"
#include "dev-cache.h"
#include "metadata.h"
#include "filter.h"
#include "memlock.h"
static struct hash_table *_pvid_hash = NULL;
static struct hash_table *_vgid_hash = NULL;
static struct hash_table *_vgname_hash = NULL;
static struct hash_table *_lock_hash = NULL;
static struct list _vginfos;
int _has_scanned = 0;
static int _has_scanned = 0;
static int _vgs_locked = 0;
int cache_init()
int lvmcache_init(void)
{
list_init(&_vginfos);
@@ -31,12 +35,52 @@ int cache_init()
if (!(_pvid_hash = hash_create(128)))
return 0;
if (!(_lock_hash = hash_create(128)))
return 0;
return 1;
}
struct cache_vginfo *vginfo_from_vgname(const char *vgname)
void lvmcache_lock_vgname(const char *vgname, int read_only)
{
struct cache_vginfo *vginfo;
if (!_lock_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
return;
}
if (!hash_insert(_lock_hash, vgname, (void *) 1))
log_error("Cache locking failure for %s", vgname);
_vgs_locked++;
}
static int _vgname_is_locked(const char *vgname) __attribute__ ((unused));
static int _vgname_is_locked(const char *vgname)
{
if (!_lock_hash)
return 0;
return hash_lookup(_lock_hash, vgname) ? 1 : 0;
}
void lvmcache_unlock_vgname(const char *vgname)
{
/* FIXME: Clear all CACHE_LOCKED flags in this vg */
hash_remove(_lock_hash, vgname);
/* FIXME Do this per-VG */
if (!--_vgs_locked)
dev_close_all();
}
int vgs_locked(void)
{
return _vgs_locked;
}
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname)
{
struct lvmcache_vginfo *vginfo;
if (!_vgname_hash)
return NULL;
@@ -47,9 +91,9 @@ struct cache_vginfo *vginfo_from_vgname(const char *vgname)
return vginfo;
}
struct format_type *fmt_from_vgname(const char *vgname)
const struct format_type *fmt_from_vgname(const char *vgname)
{
struct cache_vginfo *vginfo;
struct lvmcache_vginfo *vginfo;
if (!(vginfo = vginfo_from_vgname(vgname)))
return NULL;
@@ -57,33 +101,42 @@ struct format_type *fmt_from_vgname(const char *vgname)
return vginfo->fmt;
}
struct cache_vginfo *vginfo_from_vgid(const char *vgid)
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid)
{
struct cache_vginfo *vginfo;
struct lvmcache_vginfo *vginfo;
char id[ID_LEN + 1];
if (!_vgid_hash || !vgid)
return NULL;
if (!(vginfo = hash_lookup_fixed(_vgid_hash, vgid, ID_LEN)))
/* vgid not necessarily NULL-terminated */
strncpy(&id[0], vgid, ID_LEN);
id[ID_LEN] = '\0';
if (!(vginfo = hash_lookup(_vgid_hash, id)))
return NULL;
return vginfo;
}
struct cache_info *info_from_pvid(const char *pvid)
struct lvmcache_info *info_from_pvid(const char *pvid)
{
struct cache_info *info;
struct lvmcache_info *info;
char id[ID_LEN + 1];
if (!_pvid_hash || !pvid)
return NULL;
if (!(info = hash_lookup_fixed(_pvid_hash, pvid, ID_LEN)))
strncpy(&id[0], pvid, ID_LEN);
id[ID_LEN] = '\0';
if (!(info = hash_lookup(_pvid_hash, id)))
return NULL;
return info;
}
static void _rescan_entry(struct cache_info *info)
static void _rescan_entry(struct lvmcache_info *info)
{
struct label *label;
@@ -91,14 +144,14 @@ static void _rescan_entry(struct cache_info *info)
label_read(info->dev, &label);
}
static int _scan_invalid(struct cmd_context *cmd)
static int _scan_invalid(void)
{
hash_iter(_pvid_hash, (iterate_fn) _rescan_entry);
return 1;
}
int cache_label_scan(struct cmd_context *cmd, int full_scan)
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
{
struct label *label;
struct dev_iter *iter;
@@ -115,13 +168,13 @@ int cache_label_scan(struct cmd_context *cmd, int full_scan)
_scanning_in_progress = 1;
if (!_vgname_hash && !cache_init()) {
if (!_vgname_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
goto out;
}
if (_has_scanned && !full_scan) {
r = _scan_invalid(cmd);
r = _scan_invalid();
goto out;
}
@@ -152,12 +205,12 @@ int cache_label_scan(struct cmd_context *cmd, int full_scan)
return r;
}
struct list *cache_get_vgnames(struct cmd_context *cmd, int full_scan)
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
{
struct list *vgih, *vgnames;
struct str_list *sl;
cache_label_scan(cmd, full_scan);
lvmcache_label_scan(cmd, full_scan);
if (!(vgnames = pool_alloc(cmd->mem, sizeof(struct list)))) {
log_error("vgnames list allocation failed");
@@ -173,7 +226,7 @@ struct list *cache_get_vgnames(struct cmd_context *cmd, int full_scan)
}
if (!(sl->str = pool_strdup(cmd->mem,
list_item(vgih,
struct cache_vginfo)->
struct lvmcache_vginfo)->
vgname))) {
log_error("vgname allocation failed");
return NULL;
@@ -187,34 +240,37 @@ struct list *cache_get_vgnames(struct cmd_context *cmd, int full_scan)
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
{
struct label *label;
struct cache_info *info;
struct lvmcache_info *info;
/* Already cached ? */
if ((info = info_from_pvid((char *) pvid))) {
if (label_read(info->dev, &label)) {
info = (struct cache_info *) label->info;
info = (struct lvmcache_info *) label->info;
if (id_equal(pvid, (struct id *) &info->dev->pvid))
return info->dev;
}
}
cache_label_scan(cmd, 0);
lvmcache_label_scan(cmd, 0);
/* Try again */
if ((info = info_from_pvid((char *) pvid))) {
if (label_read(info->dev, &label)) {
info = (struct cache_info *) label->info;
info = (struct lvmcache_info *) label->info;
if (id_equal(pvid, (struct id *) &info->dev->pvid))
return info->dev;
}
}
cache_label_scan(cmd, 1);
if (memlock())
return NULL;
lvmcache_label_scan(cmd, 1);
/* Try again */
if ((info = info_from_pvid((char *) pvid))) {
if (label_read(info->dev, &label)) {
info = (struct cache_info *) label->info;
info = (struct lvmcache_info *) label->info;
if (id_equal(pvid, (struct id *) &info->dev->pvid))
return info->dev;
}
@@ -223,7 +279,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
return NULL;
}
void _drop_vginfo(struct cache_info *info)
static void _drop_vginfo(struct lvmcache_info *info)
{
if (!list_empty(&info->list)) {
list_del(&info->list);
@@ -244,7 +300,7 @@ void _drop_vginfo(struct cache_info *info)
}
/* Unused
void cache_del(struct cache_info *info)
void lvmcache_del(struct lvmcache_info *info)
{
if (info->dev->pvid[0] && _pvid_hash)
hash_remove(_pvid_hash, info->dev->pvid);
@@ -258,7 +314,7 @@ void cache_del(struct cache_info *info)
return;
} */
static int _cache_update_pvid(struct cache_info *info, const char *pvid)
static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
{
if (!strcmp(info->dev->pvid, pvid))
return 1;
@@ -267,14 +323,14 @@ static int _cache_update_pvid(struct cache_info *info, const char *pvid)
}
strncpy(info->dev->pvid, pvid, sizeof(info->dev->pvid));
if (!hash_insert(_pvid_hash, pvid, info)) {
log_error("_cache_update: pvid insertion failed: %s", pvid);
log_error("_lvmcache_update: pvid insertion failed: %s", pvid);
return 0;
}
return 1;
}
static int _cache_update_vgid(struct cache_info *info, const char *vgid)
static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
{
if (!vgid || !info->vginfo || !strncmp(info->vginfo->vgid, vgid,
sizeof(info->vginfo->vgid)))
@@ -287,18 +343,18 @@ static int _cache_update_vgid(struct cache_info *info, const char *vgid)
strncpy(info->vginfo->vgid, vgid, sizeof(info->vginfo->vgid));
info->vginfo->vgid[sizeof(info->vginfo->vgid) - 1] = '\0';
if (!hash_insert(_vgid_hash, vgid, info->vginfo)) {
log_error("_cache_update: vgid hash insertion failed: %s",
vgid);
if (!hash_insert(_vgid_hash, info->vginfo->vgid, info->vginfo)) {
log_error("_lvmcache_update: vgid hash insertion failed: %s",
info->vginfo->vgid);
return 0;
}
return 1;
}
int cache_update_vgname(struct cache_info *info, const char *vgname)
int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
{
struct cache_vginfo *vginfo;
struct lvmcache_vginfo *vginfo;
/* If vgname is NULL and we don't already have a vgname,
* assume ORPHAN - we want every entry to have a vginfo
@@ -316,7 +372,7 @@ int cache_update_vgname(struct cache_info *info, const char *vgname)
/* Get existing vginfo or create new one */
if (!(vginfo = vginfo_from_vgname(vgname))) {
if (!(vginfo = dbg_malloc(sizeof(*vginfo)))) {
log_error("cache_update_vgname: list alloc failed");
log_error("lvmcache_update_vgname: list alloc failed");
return 0;
}
memset(vginfo, 0, sizeof(*vginfo));
@@ -349,11 +405,11 @@ int cache_update_vgname(struct cache_info *info, const char *vgname)
return 1;
}
int cache_update_vg(struct volume_group *vg)
int lvmcache_update_vg(struct volume_group *vg)
{
struct list *pvh;
struct physical_volume *pv;
struct cache_info *info;
struct lvmcache_info *info;
char pvid_s[ID_LEN + 1];
int vgid_updated = 0;
@@ -364,9 +420,9 @@ int cache_update_vg(struct volume_group *vg)
strncpy(pvid_s, (char *) &pv->id, sizeof(pvid_s) - 1);
/* FIXME Could pv->dev->pvid ever be different? */
if ((info = info_from_pvid(pvid_s))) {
cache_update_vgname(info, vg->name);
lvmcache_update_vgname(info, vg->name);
if (!vgid_updated) {
_cache_update_vgid(info, (char *) &vg->id);
_lvmcache_update_vgid(info, (char *) &vg->id);
vgid_updated = 1;
}
}
@@ -375,15 +431,15 @@ int cache_update_vg(struct volume_group *vg)
return 1;
}
struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid)
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid)
{
struct label *label;
struct cache_info *existing, *info;
struct lvmcache_info *existing, *info;
char pvid_s[ID_LEN + 1];
if (!_vgname_hash && !cache_init()) {
if (!_vgname_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
return NULL;
}
@@ -398,7 +454,7 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
return NULL;
}
if (!(info = dbg_malloc(sizeof(*info)))) {
log_error("cache_info allocation failed");
log_error("lvmcache_info allocation failed");
label_destroy(label);
return NULL;
}
@@ -409,6 +465,26 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
list_init(&info->list);
info->dev = dev;
} else {
if (existing->dev != dev) {
/* Is the existing entry a duplicate pvid e.g. md ? */
if (MAJOR(existing->dev->dev) == md_major() &&
MAJOR(dev->dev) != md_major()) {
log_very_verbose("Ignoring duplicate PV %s on "
"%s - using md %s",
pvid, dev_name(dev),
dev_name(existing->dev));
return NULL;
} else if (MAJOR(existing->dev->dev) != md_major() &&
MAJOR(dev->dev) == md_major())
log_very_verbose("Duplicate PV %s on %s - "
"using md %s", pvid,
dev_name(existing->dev),
dev_name(dev));
else
log_error("Found duplicate PV %s: using %s not "
"%s", pvid, dev_name(dev),
dev_name(existing->dev));
}
info = existing;
/* Has labeller changed? */
if (info->label->labeller != labeller) {
@@ -423,10 +499,10 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
label = info->label;
}
info->fmt = (struct format_type *) labeller->private;
info->fmt = (const struct format_type *) labeller->private;
info->status |= CACHE_INVALID;
if (!_cache_update_pvid(info, pvid_s)) {
if (!_lvmcache_update_pvid(info, pvid_s)) {
if (!existing) {
dbg_free(info);
label_destroy(label);
@@ -434,7 +510,7 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
return NULL;
}
if (!cache_update_vgname(info, vgname)) {
if (!lvmcache_update_vgname(info, vgname)) {
if (!existing) {
hash_remove(_pvid_hash, pvid_s);
strcpy(info->dev->pvid, "");
@@ -444,14 +520,14 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
return NULL;
}
if (!_cache_update_vgid(info, vgid))
if (!_lvmcache_update_vgid(info, vgid))
/* Non-critical */
stack;
return info;
}
static void _cache_destroy_entry(struct cache_info *info)
static void _lvmcache_destroy_entry(struct lvmcache_info *info)
{
if (!list_empty(&info->list))
list_del(&info->list);
@@ -460,14 +536,19 @@ static void _cache_destroy_entry(struct cache_info *info)
dbg_free(info);
}
static void _cache_destroy_vgnamelist(struct cache_vginfo *vginfo)
static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
{
if (vginfo->vgname)
dbg_free(vginfo->vgname);
dbg_free(vginfo);
}
void cache_destroy()
static void _lvmcache_destroy_lockname(int present)
{
/* Nothing to do */
}
void lvmcache_destroy(void)
{
_has_scanned = 0;
@@ -477,15 +558,23 @@ void cache_destroy()
}
if (_pvid_hash) {
hash_iter(_pvid_hash, (iterate_fn) _cache_destroy_entry);
hash_iter(_pvid_hash, (iterate_fn) _lvmcache_destroy_entry);
hash_destroy(_pvid_hash);
_pvid_hash = NULL;
}
if (_vgname_hash) {
hash_iter(_vgname_hash, (iterate_fn) _cache_destroy_vgnamelist);
hash_iter(_vgname_hash,
(iterate_fn) _lvmcache_destroy_vgnamelist);
hash_destroy(_vgname_hash);
_vgname_hash = NULL;
}
if (_lock_hash) {
hash_iter(_lock_hash, (iterate_fn) _lvmcache_destroy_lockname);
hash_destroy(_lock_hash);
_lock_hash = NULL;
}
list_init(&_vginfos);
}

75
lib/cache/lvmcache.h vendored Normal file
View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the LGPL.
*
*/
#ifndef _LVM_CACHE_H
#define _LVM_CACHE_H
#include "dev-cache.h"
#include "uuid.h"
#include "label.h"
#include "metadata.h"
#define ORPHAN ""
#define CACHE_INVALID 0x00000001
#define CACHE_LOCKED 0x00000002
/* LVM specific per-volume info */
/* Eventual replacement for struct physical_volume perhaps? */
struct lvmcache_vginfo {
struct list list; /* Join these vginfos together */
struct list infos; /* List head for lvmcache_infos */
char *vgname; /* "" == orphan */
char vgid[ID_LEN + 1];
const struct format_type *fmt;
};
struct lvmcache_info {
struct list list; /* Join VG members together */
struct list mdas; /* list head for metadata areas */
struct list das; /* list head for data areas */
struct lvmcache_vginfo *vginfo; /* NULL == unknown */
struct label *label;
const struct format_type *fmt;
struct device *dev;
uint64_t device_size; /* Bytes */
uint32_t status;
};
int lvmcache_init(void);
void lvmcache_destroy(void);
/* Set full_scan to 1 to reread every filtered device label */
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan);
/* Add/delete a device */
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid);
void lvmcache_del(struct lvmcache_info *info);
/* Update things */
int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname);
int lvmcache_update_vg(struct volume_group *vg);
void lvmcache_lock_vgname(const char *vgname, int read_only);
void lvmcache_unlock_vgname(const char *vgname);
/* Queries */
const struct format_type *fmt_from_vgname(const char *vgname);
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname);
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);
struct lvmcache_info *info_from_pvid(const char *pvid);
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
int vgs_locked(void);
/* Returns list of struct str_lists containing pool-allocated copy of vgnames */
/* Set full_scan to 1 to reread every filtered device label */
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan);
#endif

View File

@@ -13,4 +13,3 @@
#define ECMD_FAILED 5
#endif

View File

@@ -19,8 +19,12 @@
#include "label.h"
#include "lvm-file.h"
#include "format-text.h"
#include "sharedlib.h"
#include "display.h"
#include "memlock.h"
#ifdef HAVE_LIBDL
#include "sharedlib.h"
#endif
#ifdef LVM1_INTERNAL
#include "format1.h"
@@ -29,9 +33,12 @@
#include <locale.h>
#include <sys/stat.h>
#include <syslog.h>
#include <dlfcn.h>
#include <time.h>
#ifdef linux
# include <malloc.h>
#endif
static FILE *_log;
static int _get_env_vars(struct cmd_context *cmd)
@@ -53,7 +60,7 @@ static int _get_env_vars(struct cmd_context *cmd)
static void _init_logging(struct cmd_context *cmd)
{
char *open_mode = "a";
int append = 1;
time_t t;
const char *log_file;
@@ -98,22 +105,26 @@ static void _init_logging(struct cmd_context *cmd)
/* Settings for logging to file */
if (find_config_int(cmd->cf->root, "log/overwrite", '/',
DEFAULT_OVERWRITE))
open_mode = "w";
append = 0;
log_file = find_config_str(cmd->cf->root, "log/file", '/', 0);
if (log_file) {
/* set up the logging */
if (!(_log = fopen(log_file, open_mode)))
log_error("Couldn't open log file %s", log_file);
else
init_log(_log);
}
if (log_file)
init_log_file(log_file, append);
log_file = find_config_str(cmd->cf->root, "log/activate_file", '/', 0);
if (log_file)
init_log_direct(log_file, append);
init_log_while_suspended(find_config_int(cmd->cf->root,
"log/activation", '/', 0));
t = time(NULL);
log_verbose("Logging initialised at %s", ctime(&t));
/* Tell device-mapper about our logging */
#ifdef DEVMAPPER_SUPPORT
dm_log_init(print_log);
#endif
}
static int _process_config(struct cmd_context *cmd)
@@ -136,8 +147,9 @@ static int _process_config(struct cmd_context *cmd)
log_error("Device directory given in config file too long");
return 0;
}
#ifdef DEVMAPPER_SUPPORT
dm_set_dev_dir(cmd->dev_dir);
#endif
/* proc dir */
if (lvm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
@@ -267,12 +279,12 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
if (!(f1 = regex_filter_create(cn->v))) {
log_error("Failed to create regex device filter");
return f2;
return NULL;
}
if (!(f3 = composite_filter_create(2, f1, f2))) {
log_error("Failed to create composite device filter");
return f2;
return NULL;
}
return f3;
@@ -280,7 +292,7 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
static int _init_filters(struct cmd_context *cmd)
{
const char *lvm_cache;
const char *dev_cache;
struct dev_filter *f3, *f4;
struct stat st;
char cache_file[PATH_MAX];
@@ -297,9 +309,9 @@ static int _init_filters(struct cmd_context *cmd)
return 0;
}
lvm_cache =
dev_cache =
find_config_str(cmd->cf->root, "devices/cache", '/', cache_file);
if (!(f4 = persistent_filter_create(f3, lvm_cache))) {
if (!(f4 = persistent_filter_create(f3, dev_cache))) {
log_error("Failed to create persistent device filter");
return 0;
}
@@ -311,9 +323,11 @@ static int _init_filters(struct cmd_context *cmd)
if (!*cmd->sys_dir)
cmd->dump_filter = 0;
if (!stat(lvm_cache, &st) && !persistent_filter_load(f4))
if (!stat(dev_cache, &st) &&
(st.st_mtime > config_file_timestamp(cmd->cf)) &&
!persistent_filter_load(f4))
log_verbose("Failed to load existing device cache from %s",
lvm_cache);
dev_cache);
cmd->filter = f4;
@@ -326,12 +340,10 @@ static int _init_formats(struct cmd_context *cmd)
struct format_type *fmt;
struct list *fmth;
#ifdef HAVE_LIBDL
struct config_node *cn;
struct config_value *cv;
struct format_type *(*init_format_fn) (struct cmd_context * cmd);
void *lib;
#endif
label_init();
@@ -342,9 +354,15 @@ static int _init_formats(struct cmd_context *cmd)
list_add(&cmd->formats, &fmt->list);
#endif
#ifdef HAVE_LIBDL
/* Load any formats in shared libs */
if ((cn = find_config_node(cmd->cf->root, "global/format_libraries",
'/'))) {
struct config_value *cv;
struct format_type *(*init_format_fn) (struct cmd_context *);
void *lib;
for (cv = cn->v; cv; cv = cv->next) {
if (cv->type != CFG_STRING) {
log_error("Invalid string in config file: "
@@ -370,6 +388,7 @@ static int _init_formats(struct cmd_context *cmd)
list_add(&cmd->formats, &fmt->list);
}
}
#endif
if (!(fmt = create_text_format(cmd)))
return 0;
@@ -399,6 +418,10 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
{
struct cmd_context *cmd;
#ifdef M_MMAP_MAX
mallopt(M_MMAP_MAX, 0);
#endif
if (!setlocale(LC_ALL, ""))
log_error("setlocale failed");
@@ -440,6 +463,8 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
return 0;
}
memlock_init(cmd);
if (!_init_formats(cmd))
goto error;
@@ -452,7 +477,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
return NULL;
}
void destroy_formats(struct list *formats)
static void _destroy_formats(struct list *formats)
{
struct list *fmtl, *tmp;
struct format_type *fmt;
@@ -463,8 +488,10 @@ void destroy_formats(struct list *formats)
list_del(&fmt->list);
lib = fmt->library;
fmt->ops->destroy(fmt);
#ifdef HAVE_LIBDL
if (lib)
dlclose(lib);
#endif
}
}
@@ -473,15 +500,17 @@ void destroy_toolcontext(struct cmd_context *cmd)
if (cmd->dump_filter)
persistent_filter_dump(cmd->filter);
cache_destroy();
activation_exit();
lvmcache_destroy();
label_exit();
destroy_formats(&cmd->formats);
_destroy_formats(&cmd->formats);
cmd->filter->destroy(cmd->filter);
pool_destroy(cmd->mem);
dev_cache_exit();
destroy_config_tree(cmd->cf);
dbg_free(cmd);
release_log_memory();
dump_memory();
fin_log();
fin_syslog();

View File

@@ -45,7 +45,7 @@ struct cmd_context {
/* format handler allocates all objects from here */
struct pool *mem;
struct format_type *fmt; /* Current format to use by default */
const struct format_type *fmt; /* Current format to use by default */
struct format_type *fmt_backup; /* Format to use for backups */
struct list formats; /* Available formats */
@@ -53,6 +53,7 @@ struct cmd_context {
char *cmd_line;
struct command *command;
struct arg *args;
char **argv;
struct dev_filter *filter;
int dump_filter; /* Dump filter when exiting? */

View File

@@ -15,7 +15,6 @@
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <asm/page.h>
enum {
TOK_INT,
@@ -50,7 +49,7 @@ struct cs {
char *filename;
};
static void _get_token(struct parser *p);
static void _get_token(struct parser *p, int tok_prev);
static void _eat_space(struct parser *p);
static struct config_node *_file(struct parser *p);
static struct config_node *_section(struct parser *p);
@@ -111,14 +110,15 @@ void destroy_config_tree(struct config_tree *cf)
pool_destroy(((struct cs *) cf)->mem);
}
int read_config_fd(struct config_tree *cf, int fd, const char *file,
off_t offset, uint32_t size, off_t offset2, uint32_t size2,
int read_config_fd(struct config_tree *cf, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum)
{
struct cs *c = (struct cs *) cf;
struct parser *p;
off_t mmap_offset;
int r = 0;
int use_mmap = 1;
off_t mmap_offset = 0;
if (!(p = pool_alloc(c->mem, sizeof(*p)))) {
stack;
@@ -126,47 +126,43 @@ int read_config_fd(struct config_tree *cf, int fd, const char *file,
}
p->mem = c->mem;
if (size2) {
/* FIXME Attempt adjacent mmaps MAP_FIXED into malloced space
* one PAGE_SIZE larger than required...
*/
/* Only use mmap with regular files */
if (!(dev->flags & DEV_REGULAR) || size2)
use_mmap = 0;
if (use_mmap) {
mmap_offset = offset % getpagesize();
/* memory map the file */
p->fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
MAP_PRIVATE, dev_fd(dev), offset - mmap_offset);
if (p->fb == (caddr_t) (-1)) {
log_sys_error("mmap", dev_name(dev));
goto out;
}
p->fb = p->fb + mmap_offset;
} else {
if (!(p->fb = dbg_malloc(size + size2))) {
stack;
return 0;
}
if (lseek(fd, offset, SEEK_SET) < 0) {
log_sys_error("lseek", file);
if (!dev_read(dev, (uint64_t) offset, size, p->fb)) {
log_error("Read from %s failed", dev_name(dev));
goto out;
}
if (raw_read(fd, p->fb, size) != size) {
log_error("Circular read from %s failed", file);
goto out;
if (size2) {
if (!dev_read(dev, (uint64_t) offset2, size2,
p->fb + size)) {
log_error("Circular read from %s failed",
dev_name(dev));
goto out;
}
}
if (lseek(fd, offset2, SEEK_SET) < 0) {
log_sys_error("lseek", file);
goto out;
}
if (raw_read(fd, p->fb + size, size2) != size2) {
log_error("Circular read from %s failed", file);
goto out;
}
} else {
mmap_offset = offset % PAGE_SIZE;
/* memory map the file */
p->fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
MAP_PRIVATE, fd, offset - mmap_offset);
if (p->fb == (caddr_t) (-1)) {
log_sys_error("mmap", file);
goto out;
}
p->fb = p->fb + mmap_offset;
}
if (checksum_fn && checksum !=
(checksum_fn(checksum_fn(INITIAL_CRC, p->fb, size),
p->fb + size, size2))) {
log_error("%s: Checksum error", file);
log_error("%s: Checksum error", dev_name(dev));
goto out;
}
@@ -175,7 +171,7 @@ int read_config_fd(struct config_tree *cf, int fd, const char *file,
/* parse */
p->tb = p->te = p->fb;
p->line = 1;
_get_token(p);
_get_token(p, TOK_SECTION_E);
if (!(cf->root = _file(p))) {
stack;
goto out;
@@ -184,12 +180,12 @@ int read_config_fd(struct config_tree *cf, int fd, const char *file,
r = 1;
out:
if (size2)
if (!use_mmap)
dbg_free(p->fb);
else {
/* unmap the file */
if (munmap((char *) (p->fb - mmap_offset), size)) {
log_sys_error("munmap", file);
if (munmap((char *) (p->fb - mmap_offset), size + mmap_offset)) {
log_sys_error("munmap", dev_name(dev));
r = 0;
}
}
@@ -201,7 +197,8 @@ int read_config_file(struct config_tree *cf, const char *file)
{
struct cs *c = (struct cs *) cf;
struct stat info;
int r = 1, fd;
struct device *dev;
int r = 1;
if (stat(file, &info)) {
log_sys_error("stat", file);
@@ -218,15 +215,20 @@ int read_config_file(struct config_tree *cf, const char *file)
return 1;
}
if ((fd = open(file, O_RDONLY)) < 0) {
log_sys_error("open", file);
if (!(dev = dev_create_file(file, NULL, NULL))) {
stack;
return 0;
}
r = read_config_fd(cf, fd, file, 0, info.st_size, 0, 0,
if (!dev_open_flags(dev, O_RDONLY, 0, 0)) {
stack;
return 0;
}
r = read_config_fd(cf, dev, 0, (size_t) info.st_size, 0, 0,
(checksum_fn_t) NULL, 0);
close(fd);
dev_close(dev);
c->timestamp = info.st_mtime;
c->filename = pool_strdup(c->mem, file);
@@ -234,6 +236,13 @@ int read_config_file(struct config_tree *cf, const char *file)
return r;
}
time_t config_file_timestamp(struct config_tree *cf)
{
struct cs *c = (struct cs *) cf;
return c->timestamp;
}
/*
* Returns 1 if config file reloaded
*/
@@ -243,7 +252,8 @@ int reload_config_file(struct config_tree **cf)
struct cs *c = (struct cs *) *cf;
struct cs *new_cs;
struct stat info;
int r, fd;
struct device *dev;
int r;
if (!c->filename)
return 0;
@@ -273,19 +283,25 @@ int reload_config_file(struct config_tree **cf)
return 0;
}
if ((fd = open(c->filename, O_RDONLY)) < 0) {
log_sys_error("open", c->filename);
return 0;
}
if (!(new_cf = create_config_tree())) {
log_error("Allocation of new config_tree failed");
return 0;
}
r = read_config_fd(new_cf, fd, c->filename, 0, info.st_size, 0, 0,
(checksum_fn_t) NULL, 0);
close(fd);
if (!(dev = dev_create_file(c->filename, NULL, NULL))) {
stack;
return 0;
}
if (!dev_open_flags(dev, O_RDONLY, 0, 0)) {
stack;
return 0;
}
r = read_config_fd(new_cf, dev, 0, (size_t) info.st_size,
0, 0, (checksum_fn_t) NULL, 0);
dev_close(dev);
if (r) {
new_cs = (struct cs *) new_cf;
@@ -529,15 +545,17 @@ static int _match_aux(struct parser *p, int t)
if (p->t != t)
return 0;
_get_token(p);
_get_token(p, t);
return 1;
}
/*
* tokeniser
*/
static void _get_token(struct parser *p)
static void _get_token(struct parser *p, int tok_prev)
{
int values_allowed = 0;
p->tb = p->te;
_eat_space(p);
if (p->tb == p->fe || !*p->tb) {
@@ -545,6 +563,11 @@ static void _get_token(struct parser *p)
return;
}
/* Should next token be interpreted as value instead of identifier? */
if (tok_prev == TOK_EQ || tok_prev == TOK_ARRAY_B ||
tok_prev == TOK_COMMA)
values_allowed = 1;
p->t = TOK_INT; /* fudge so the fall through for
floats works */
switch (*p->te) {
@@ -592,6 +615,16 @@ static void _get_token(struct parser *p)
p->te++;
break;
case '\'':
p->t = TOK_STRING;
p->te++;
while ((p->te != p->fe) && (*p->te) && (*p->te != '\''))
p->te++;
if ((p->te != p->fe) && (*p->te))
p->te++;
break;
case '.':
p->t = TOK_FLOAT;
case '0':
@@ -604,22 +637,25 @@ static void _get_token(struct parser *p)
case '7':
case '8':
case '9':
p->te++;
while ((p->te != p->fe) && (*p->te)) {
if (*p->te == '.') {
if (p->t == TOK_FLOAT)
break;
p->t = TOK_FLOAT;
} else if (!isdigit((int) *p->te))
break;
if (values_allowed) {
p->te++;
while ((p->te != p->fe) && (*p->te)) {
if (*p->te == '.') {
if (p->t == TOK_FLOAT)
break;
p->t = TOK_FLOAT;
} else if (!isdigit((int) *p->te))
break;
p->te++;
}
break;
}
break;
default:
p->t = TOK_IDENTIFIER;
while ((p->te != p->fe) && (*p->te) && !isspace(*p->te) &&
(*p->te != '#') && (*p->te != '='))
(*p->te != '#') && (*p->te != '=') && (*p->te != '{') &&
(*p->te != '}'))
p->te++;
break;
}
@@ -668,7 +704,7 @@ static struct config_node *_create_node(struct parser *p)
static char *_dup_tok(struct parser *p)
{
int len = p->te - p->tb;
size_t len = p->te - p->tb;
char *str = pool_alloc(p->mem, len + 1);
if (!str) {
stack;
@@ -683,7 +719,7 @@ static char *_dup_tok(struct parser *p)
* utility functions
*/
struct config_node *find_config_node(struct config_node *cn,
const char *path, char sep)
const char *path, const int sep)
{
const char *e;
@@ -715,7 +751,7 @@ struct config_node *find_config_node(struct config_node *cn,
}
const char *find_config_str(struct config_node *cn,
const char *path, const char sep, const char *fail)
const char *path, const int sep, const char *fail)
{
struct config_node *n = find_config_node(cn, path, sep);
@@ -732,7 +768,7 @@ const char *find_config_str(struct config_node *cn,
}
int find_config_int(struct config_node *cn, const char *path,
char sep, int fail)
const int sep, int fail)
{
struct config_node *n = find_config_node(cn, path, sep);
@@ -747,7 +783,7 @@ int find_config_int(struct config_node *cn, const char *path,
}
float find_config_float(struct config_node *cn, const char *path,
char sep, float fail)
const int sep, float fail)
{
struct config_node *n = find_config_node(cn, path, sep);
@@ -790,7 +826,7 @@ static int _str_to_bool(const char *str, int fail)
}
int find_config_bool(struct config_node *cn, const char *path,
char sep, int fail)
const int sep, int fail)
{
struct config_node *n = find_config_node(cn, path, sep);
struct config_value *v;
@@ -812,7 +848,7 @@ int find_config_bool(struct config_node *cn, const char *path,
}
int get_config_uint32(struct config_node *cn, const char *path,
char sep, uint32_t *result)
const int sep, uint32_t *result)
{
struct config_node *n;
@@ -826,7 +862,7 @@ int get_config_uint32(struct config_node *cn, const char *path,
}
int get_config_uint64(struct config_node *cn, const char *path,
char sep, uint64_t *result)
const int sep, uint64_t *result)
{
struct config_node *n;
@@ -841,7 +877,7 @@ int get_config_uint64(struct config_node *cn, const char *path,
}
int get_config_str(struct config_node *cn, const char *path,
char sep, char **result)
const int sep, char **result)
{
struct config_node *n;

View File

@@ -7,8 +7,7 @@
#ifndef _LVM_CONFIG_H
#define _LVM_CONFIG_H
#include <inttypes.h>
#include <sys/types.h>
#include "device.h"
enum {
CFG_STRING,
@@ -42,40 +41,41 @@ void destroy_config_tree(struct config_tree *cf);
typedef uint32_t (*checksum_fn_t) (uint32_t initial, void *buf, uint32_t size);
int read_config_fd(struct config_tree *cf, int fd, const char *file,
off_t offset, uint32_t size, off_t offset2, uint32_t size2,
int read_config_fd(struct config_tree *cf, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum);
int read_config_file(struct config_tree *cf, const char *file);
int write_config_file(struct config_tree *cf, const char *file);
int reload_config_file(struct config_tree **cf);
time_t config_file_timestamp(struct config_tree *cf);
struct config_node *find_config_node(struct config_node *cn,
const char *path, char separator);
const char *path, const int separator);
const char *find_config_str(struct config_node *cn,
const char *path, const char sep, const char *fail);
const char *path, const int sep, const char *fail);
int find_config_int(struct config_node *cn, const char *path,
char sep, int fail);
const int sep, int fail);
float find_config_float(struct config_node *cn, const char *path,
char sep, float fail);
const int sep, float fail);
/*
* Understands (0, ~0), (y, n), (yes, no), (on,
* off), (true, false).
*/
int find_config_bool(struct config_node *cn, const char *path,
char sep, int fail);
const int sep, int fail);
int get_config_uint32(struct config_node *cn, const char *path,
char sep, uint32_t *result);
const int sep, uint32_t *result);
int get_config_uint64(struct config_node *cn, const char *path,
char sep, uint64_t *result);
const int sep, uint64_t *result);
int get_config_str(struct config_node *cn, const char *path,
char sep, char **result);
const int sep, char **result);
#endif

View File

@@ -26,21 +26,22 @@
#define DEFAULT_UMASK 0077
#ifdef LVM1_SUPPORT
#define DEFAULT_FORMAT "lvm1"
# define DEFAULT_FORMAT "lvm1"
#else
#define DEFAULT_FORMAT "lvm2"
# define DEFAULT_FORMAT "lvm2"
#endif
#define DEFAULT_STRIPESIZE 64 /* KB */
#define DEFAULT_PVMETADATASIZE 255
#define DEFAULT_PVMETADATACOPIES 1
#define DEFAULT_LABELSECTOR 1
#define DEFAULT_LABELSECTOR UINT64_C(1)
#define DEFAULT_MSG_PREFIX " "
#define DEFAULT_CMD_NAME 0
#define DEFAULT_OVERWRITE 0
#ifndef DEFAULT_LOG_FACILITY
#define DEFAULT_LOG_FACILITY LOG_USER
# define DEFAULT_LOG_FACILITY LOG_USER
#endif
#define DEFAULT_SYSLOG 1
@@ -50,10 +51,21 @@
#define DEFAULT_UNITS "h"
#define DEFAULT_SUFFIX 1
#define DEFAULT_ACTIVATION 1
#ifdef DEVMAPPER_SUPPORT
# define DEFAULT_ACTIVATION 1
# define DEFAULT_RESERVED_MEMORY 8192
# define DEFAULT_RESERVED_STACK 256
# define DEFAULT_PROCESS_PRIORITY -18
#else
# define DEFAULT_ACTIVATION 0
#endif
#define DEFAULT_STRIPE_FILLER "/dev/ioerror"
#define DEFAULT_MIRROR_REGION_SIZE 512 /* KB */
#define DEFAULT_INTERVAL 15
#ifdef READLINE_SUPPORT
#define DEFAULT_MAX_HISTORY 100
# define DEFAULT_MAX_HISTORY 100
#endif
#define DEFAULT_REP_ALIGNED 1
@@ -61,12 +73,12 @@
#define DEFAULT_REP_HEADINGS 1
#define DEFAULT_REP_SEPARATOR " "
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent"
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,move_percent"
#define DEFAULT_VGS_COLS "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
#define DEFAULT_PVS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
#define DEFAULT_SEGS_COLS "lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_minor,origin,snap_percent,lv_uuid"
#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,origin,snap_percent,move_pv,move_percent,lv_uuid"
#define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid"
#define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pv_uuid"
#define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"

View File

@@ -12,8 +12,8 @@
bitset_t bitset_create(struct pool *mem, unsigned num_bits)
{
int n = (num_bits / BITS_PER_INT) + 2;
int size = sizeof(int) * n;
unsigned n = (num_bits / BITS_PER_INT) + 2;
size_t size = sizeof(int) * n;
unsigned *bs = pool_zalloc(mem, size);
if (!bs)

View File

@@ -7,7 +7,6 @@
#ifndef _LVM_BITSET_H
#define _LVM_BITSET_H
#include "lvm-types.h"
#include "pool.h"
#include <limits.h>
@@ -15,12 +14,12 @@
typedef uint32_t *bitset_t;
bitset_t bitset_create(struct pool *mem, unsigned num_bits);
void bitset_destroy(bitset_t bs);
void bit_union(bitset_t out, bitset_t in1, bitset_t in2);
int bit_get_first(bitset_t bs);
int bit_get_next(bitset_t bs, int last_bit);
#define BITS_PER_INT (sizeof(int) * CHAR_BIT)
#define bit(bs, i) \

View File

@@ -46,7 +46,7 @@ static uint32_t _shuffle(uint32_t k)
#endif
}
struct node **_lookup(struct node **c, uint32_t key, struct node **p)
static struct node **_lookup(struct node **c, uint32_t key, struct node **p)
{
*p = NULL;
while (*c) {

View File

@@ -7,7 +7,6 @@
#ifndef _LVM_BTREE_H
#define _LVM_BTREE_H
#include "lvm-types.h"
#include "pool.h"
struct btree;

View File

@@ -59,10 +59,10 @@ static struct hash_node *_create_node(const char *str)
return n;
}
static unsigned _hash(const char *str, int len)
static unsigned _hash(const char *str)
{
unsigned long int h = 0, g;
while (*str && len--) {
unsigned long h = 0, g;
while (*str) {
h <<= 4;
h += _nums[(int) *str++];
g = h & ((unsigned long) 0xf << 16u);
@@ -125,30 +125,18 @@ void hash_destroy(struct hash_table *t)
dbg_free(t);
}
static inline struct hash_node **_find_fixed(struct hash_table *t,
const char *key, uint32_t len)
static inline struct hash_node **_find(struct hash_table *t, const char *key)
{
unsigned h = _hash(key, len) & (t->num_slots - 1);
unsigned h = _hash(key) & (t->num_slots - 1);
struct hash_node **c;
for (c = &t->slots[h]; *c; c = &((*c)->next))
if (!strncmp(key, (*c)->key, len))
if (!strcmp(key, (*c)->key))
break;
return c;
}
static inline struct hash_node **_find(struct hash_table *t, const char *key)
{
return _find_fixed(t, key, strlen(key));
}
void *hash_lookup_fixed(struct hash_table *t, const char *key, uint32_t len)
{
struct hash_node **c = _find_fixed(t, key, len);
return *c ? (*c)->data : 0;
}
void *hash_lookup(struct hash_table *t, const char *key)
{
struct hash_node **c = _find(t, key);
@@ -220,7 +208,7 @@ void *hash_get_data(struct hash_table *t, struct hash_node *n)
return n->data;
}
static struct hash_node *_next_slot(struct hash_table *t, unsigned int s)
static struct hash_node *_next_slot(struct hash_table *t, unsigned s)
{
struct hash_node *c = NULL;
int i;
@@ -238,6 +226,6 @@ struct hash_node *hash_get_first(struct hash_table *t)
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
{
unsigned int h = _hash(n->key, strlen(n->key)) & (t->num_slots - 1);
unsigned h = _hash(n->key) & (t->num_slots - 1);
return n->next ? n->next : _next_slot(t, h + 1);
}

View File

@@ -7,12 +7,10 @@
#ifndef _LVM_HASH_H
#define _LVM_HASH_H
#include "lvm-types.h"
struct hash_table;
struct hash_node;
typedef void (*iterate_fn)(void *data);
typedef void (*iterate_fn) (void *data);
struct hash_table *hash_create(unsigned size_hint);
void hash_destroy(struct hash_table *t);
@@ -36,4 +34,3 @@ struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n);
v = hash_get_next(h, v))
#endif

View File

@@ -13,6 +13,8 @@ struct list {
struct list *n, *p;
};
#define LIST_INIT(name) struct list name = { &(name), &(name) }
static inline void list_init(struct list *head)
{
head->n = head->p = head;
@@ -56,16 +58,24 @@ static inline int list_end(struct list *head, struct list *elem)
return elem->n == head;
}
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 int list_size(struct list *head)
static inline unsigned int list_size(const struct list *head)
{
int s = 0;
struct list *v;
unsigned int s = 0;
const struct list *v;
list_iterate(v, head)
s++;
@@ -76,8 +86,14 @@ static inline int list_size(struct list *head)
#define list_item(v, t) \
((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list))
/* Given a known element in a known structure, locate the struct list */
#define list_head(v, t, e) \
(((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->list)
#define list_struct_base(v, t, h) \
((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->h))
/* Given a known element in a known structure, locate another */
#define struct_field(v, t, e, f) \
(((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f)
/* Given a known element in a known structure, locate the list head */
#define list_head(v, t, e) struct_field(v, t, e, list)
#endif

View File

@@ -12,9 +12,12 @@
#include <sys/types.h>
#include <inttypes.h>
/* Define some portable printing types */
#define PRIsize_t "Zu"
struct str_list {
struct list list;
char *str;
const char *str;
};
#endif

View File

@@ -11,17 +11,11 @@
#include "list.h"
#include "lvm-types.h"
#include "btree.h"
#include "filter.h"
#include <sys/stat.h>
#include <unistd.h>
#include <sys/param.h>
#include <dirent.h>
#include <linux/kdev_t.h>
/*
* FIXME: really need to seperate names from the devices since
* multiple names can point to the same device.
*/
struct dev_iter {
struct btree_iter *current;
@@ -48,38 +42,163 @@ static struct {
static int _insert(const char *path, int rec);
static struct device *_create_dev(dev_t d)
struct device *dev_create_file(const char *filename, struct device *dev,
struct str_list *alias)
{
int allocate = !dev;
if (allocate && !(dev = dbg_malloc(sizeof(*dev)))) {
log_error("struct device allocation failed");
return NULL;
}
if (allocate && !(alias = dbg_malloc(sizeof(*alias)))) {
log_error("struct str_list allocation failed");
dbg_free(dev);
return NULL;
}
if (!(alias->str = dbg_strdup(filename))) {
log_error("filename strdup failed");
if (allocate) {
dbg_free(dev);
dbg_free(alias);
}
return NULL;
}
dev->flags = DEV_REGULAR;
if (allocate)
dev->flags |= DEV_ALLOCED;
list_init(&dev->aliases);
list_add(&dev->aliases, &alias->list);
dev->end = UINT64_C(0);
dev->dev = 0;
dev->fd = -1;
dev->open_count = 0;
memset(dev->pvid, 0, sizeof(dev->pvid));
list_init(&dev->open_list);
return dev;
}
static struct device *_dev_create(dev_t d)
{
struct device *dev;
if (!(dev = _alloc(sizeof(*dev)))) {
stack;
log_error("struct device allocation failed");
return NULL;
}
dev->flags = 0;
list_init(&dev->aliases);
dev->dev = d;
dev->fd = -1;
dev->flags = 0;
dev->open_count = 0;
dev->end = UINT64_C(0);
memset(dev->pvid, 0, sizeof(dev->pvid));
list_init(&dev->open_list);
return dev;
}
/* Return 1 if we prefer path1 else return 0 */
static int _compare_paths(const char *path0, const char *path1)
{
int slash0 = 0, slash1 = 0;
const char *p;
char p0[PATH_MAX], p1[PATH_MAX];
char *s0, *s1;
struct stat stat0, stat1;
/* Return the path with fewer slashes */
for (p = path0; p++; p = (const char *) strchr(p, '/'))
slash0++;
for (p = path1; p++; p = (const char *) strchr(p, '/'))
slash1++;
if (slash0 < slash1)
return 0;
if (slash1 < slash0)
return 1;
strncpy(p0, path0, PATH_MAX);
strncpy(p1, path1, PATH_MAX);
s0 = &p0[0] + 1;
s1 = &p1[0] + 1;
/* We prefer symlinks - they exist for a reason!
* So we prefer a shorter path before the first symlink in the name.
* FIXME Configuration option to invert this? */
while (s0) {
s0 = strchr(s0, '/');
s1 = strchr(s1, '/');
if (s0) {
*s0 = '\0';
*s1 = '\0';
}
if (lstat(p0, &stat0)) {
log_sys_error("lstat", p0);
return 1;
}
if (lstat(p1, &stat1)) {
log_sys_error("lstat", p1);
return 0;
}
if (S_ISLNK(stat0.st_mode) && !S_ISLNK(stat1.st_mode))
return 0;
if (!S_ISLNK(stat0.st_mode) && S_ISLNK(stat1.st_mode))
return 1;
if (s0) {
*s0++ = '/';
*s1++ = '/';
}
}
/* ASCII comparison */
if (strcmp(path0, path1) < 0)
return 0;
else
return 1;
}
static int _add_alias(struct device *dev, const char *path)
{
struct str_list *sl = _alloc(sizeof(*sl));
struct list *ah;
const char *oldpath;
int prefer_old = 1;
if (!sl) {
stack;
return 0;
}
/* Is name already there? */
list_iterate(ah, &dev->aliases) {
if (!strcmp(list_item(ah, struct str_list)->str, path)) {
stack;
return 1;
}
}
if (!(sl->str = pool_strdup(_cache.mem, path))) {
stack;
return 0;
}
list_add(&dev->aliases, &sl->list);
if (!list_empty(&dev->aliases)) {
oldpath = list_item(dev->aliases.n, struct str_list)->str;
prefer_old = _compare_paths(path, oldpath);
log_debug("%s: Aliased to %s in device cache%s",
path, oldpath, prefer_old ? "" : " (preferred name)");
} else
log_debug("%s: Added to device cache", path);
if (prefer_old)
list_add(&dev->aliases, &sl->list);
else
list_add_h(&dev->aliases, &sl->list);
return 1;
}
@@ -92,14 +211,15 @@ static int _insert_dev(const char *path, dev_t d)
struct device *dev;
/* is this device already registered ? */
if (!(dev = (struct device *) btree_lookup(_cache.devices, d))) {
if (!(dev = (struct device *) btree_lookup(_cache.devices,
(uint32_t) d))) {
/* create new device */
if (!(dev = _create_dev(d))) {
if (!(dev = _dev_create(d))) {
stack;
return 0;
}
if (!(btree_insert(_cache.devices, d, dev))) {
if (!(btree_insert(_cache.devices, (uint32_t) d, dev))) {
log_err("Couldn't insert device into binary tree.");
_free(dev);
return 0;
@@ -121,7 +241,7 @@ static int _insert_dev(const char *path, dev_t d)
static char *_join(const char *dir, const char *name)
{
int len = strlen(dir) + strlen(name) + 2;
size_t len = strlen(dir) + strlen(name) + 2;
char *r = dbg_malloc(len);
if (r)
snprintf(r, len, "%s/%s", dir, name);
@@ -273,7 +393,7 @@ int dev_cache_init(void)
return 0;
}
void _check_closed(struct device *dev)
static void _check_closed(struct device *dev)
{
if (dev->fd >= 0)
log_err("Device '%s' has been left open.", dev_name(dev));
@@ -309,8 +429,10 @@ int dev_cache_add_dir(const char *path)
return 1;
}
if (!(dl = _alloc(sizeof(*dl) + strlen(path) + 1)))
if (!(dl = _alloc(sizeof(*dl) + strlen(path) + 1))) {
log_error("dir_list allocation failed");
return 0;
}
strcpy(dl->dir, path);
list_add(&_cache.dirs, &dl->list);
@@ -319,20 +441,31 @@ int dev_cache_add_dir(const char *path)
/* Check cached device name is still valid before returning it */
/* This should be a rare occurrence */
/* set quiet if the cache is expected to be out-of-date */
/* FIXME Make rest of code pass/cache struct device instead of dev_name */
const char *dev_name_confirmed(struct device *dev)
const char *dev_name_confirmed(struct device *dev, int quiet)
{
struct stat buf;
char *name;
const char *name;
int r;
while ((r = stat(name = list_item(dev->aliases.n,
struct str_list)->str, &buf)) ||
(buf.st_rdev != dev->dev)) {
if (r < 0)
log_sys_error("stat", name);
log_error("Path %s no longer valid for device(%d,%d)",
name, (int) MAJOR(dev->dev), (int) MINOR(dev->dev));
if (r < 0) {
if (quiet)
log_sys_debug("stat", name);
else
log_sys_error("stat", name);
}
if (quiet)
log_debug("Path %s no longer valid for device(%d,%d)",
name, (int) MAJOR(dev->dev),
(int) MINOR(dev->dev));
else
log_error("Path %s no longer valid for device(%d,%d)",
name, (int) MAJOR(dev->dev),
(int) MINOR(dev->dev));
/* Remove the incorrect hash entry */
hash_remove(_cache.names, name);
@@ -378,8 +511,10 @@ struct dev_iter *dev_iter_create(struct dev_filter *f)
{
struct dev_iter *di = dbg_malloc(sizeof(*di));
if (!di)
if (!di) {
log_error("dev_iter allocation failed");
return NULL;
}
_full_scan();
di->current = btree_first(_cache.devices);

View File

@@ -7,7 +7,6 @@
#ifndef _LVM_DEV_CACHE_H
#define _LVM_DEV_CACHE_H
#include <sys/types.h>
#include "lvm-types.h"
#include "device.h"
@@ -15,12 +14,11 @@
* predicate for devices.
*/
struct dev_filter {
int (*passes_filter)(struct dev_filter *f, struct device *dev);
void (*destroy)(struct dev_filter *f);
int (*passes_filter) (struct dev_filter * f, struct device * dev);
void (*destroy) (struct dev_filter * f);
void *private;
};
/*
* The global device cache.
*/
@@ -34,7 +32,6 @@ int dev_cache_has_scanned(void);
int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(const char *name, struct dev_filter *f);
/*
* Object for iterating through the cache.
*/

View File

@@ -5,20 +5,205 @@
*/
#include "lib.h"
#include "device.h"
#include "lvm-types.h"
#include "device.h"
#include "metadata.h"
#include "lvmcache.h"
#include "memlock.h"
#include <limits.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fs.h> // UGH!!! for BLKSSZGET
#ifdef linux
# define u64 uint64_t /* Missing without __KERNEL__ */
# undef WNOHANG /* Avoid redefinition */
# undef WUNTRACED /* Avoid redefinition */
# include <linux/fs.h> /* For block ioctl definitions */
# define BLKSIZE_SHIFT SECTOR_SHIFT
#else
# include <sys/disk.h>
# define BLKBSZGET DKIOCGETBLOCKSIZE
# define BLKSSZGET DKIOCGETBLOCKSIZE
# define BLKGETSIZE64 DKIOCGETBLOCKCOUNT
# define BLKFLSBUF DKIOCSYNCHRONIZECACHE
# define BLKSIZE_SHIFT 0
# ifndef O_DIRECT
# define O_DIRECT 0
# 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) {
*/
static LIST_INIT(_open_devices);
/*-----------------------------------------------------------------
* The standard io loop that keeps submitting an io until it's
* all gone.
*---------------------------------------------------------------*/
static int _io(struct device_area *where, void *buffer, int should_write)
{
int fd = dev_fd(where->dev);
ssize_t n = 0;
size_t total = 0;
if (fd < 0) {
log_error("Attempt to read an unopened device (%s).",
dev_name(where->dev));
return 0;
}
/*
* Skip all writes in test mode.
*/
if (should_write && test_mode())
return 1;
if (where->size > SSIZE_MAX) {
log_error("Read size too large: %" PRIu64, where->size);
return 0;
}
if (lseek(fd, (off_t) where->start, SEEK_SET) < 0) {
log_sys_error("lseek", dev_name(where->dev));
return 0;
}
while (total < (size_t) where->size) {
do
n = should_write ?
write(fd, buffer, (size_t) where->size - total) :
read(fd, buffer, (size_t) where->size - total);
while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (n <= 0)
break;
total += n;
buffer += n;
}
return (total == (size_t) where->size);
}
/*-----------------------------------------------------------------
* LVM2 uses O_DIRECT when performing metadata io, which requires
* block size aligned accesses. If any io is not aligned we have
* to perform the io via a bounce buffer, obviously this is quite
* inefficient.
*---------------------------------------------------------------*/
/*
* Get the sector size from an _open_ device.
*/
static int _get_block_size(struct device *dev, unsigned int *size)
{
int s;
if (ioctl(dev_fd(dev), BLKBSZGET, &s) < 0) {
log_sys_error("ioctl BLKBSZGET", dev_name(dev));
return 0;
}
*size = (unsigned int) s;
return 1;
}
/*
* Widens a region to be an aligned region.
*/
static void _widen_region(unsigned int block_size, struct device_area *region,
struct device_area *result)
{
uint64_t mask = block_size - 1, delta;
memcpy(result, region, sizeof(*result));
/* adjust the start */
delta = result->start & mask;
if (delta) {
result->start -= delta;
result->size += delta;
}
/* adjust the end */
delta = (result->start + result->size) & mask;
if (delta)
result->size += block_size - delta;
}
static int _aligned_io(struct device_area *where, void *buffer,
int should_write)
{
void *bounce;
unsigned int block_size = 0;
uintptr_t mask;
struct device_area widened;
if (!(where->dev->flags & DEV_REGULAR) &&
!_get_block_size(where->dev, &block_size)) {
stack;
return 0;
}
if (!block_size)
block_size = SECTOR_SIZE * 2;
_widen_region(block_size, where, &widened);
/* Do we need to use a bounce buffer? */
mask = block_size - 1;
if (!memcmp(where, &widened, sizeof(widened)) &&
!((uintptr_t) buffer & mask))
return _io(where, buffer, should_write);
/* Allocate a bounce buffer with an extra block */
if (!(bounce = alloca((size_t) widened.size + block_size))) {
log_error("Bounce buffer alloca failed");
return 0;
}
/*
* Realign start of bounce buffer (using the extra sector)
*/
if (((uintptr_t) bounce) & mask)
bounce = (void *) ((((uintptr_t) bounce) + mask) & ~mask);
/* channel the io through the bounce buffer */
if (!_io(&widened, bounce, 0)) {
if (!should_write) {
stack;
return 0;
}
/* FIXME pre-extend the file */
memset(bounce, '\n', widened.size);
}
if (should_write) {
memcpy(bounce + (where->start - widened.start), buffer,
(size_t) where->size);
/* ... then we write */
return _io(&widened, bounce, 1);
}
memcpy(buffer, bounce + (where->start - widened.start),
(size_t) where->size);
return 1;
}
/*-----------------------------------------------------------------
* Public functions
*---------------------------------------------------------------*/
int dev_get_size(struct device *dev, uint64_t *size)
{
int fd;
long s;
const char *name = dev_name(dev);
log_very_verbose("Getting size of %s", name);
@@ -27,15 +212,14 @@ int dev_get_size(struct device *dev, uint64_t *size)
return 0;
}
/* FIXME: add 64 bit ioctl */
if (ioctl(fd, BLKGETSIZE, &s) < 0) {
log_sys_error("ioctl BLKGETSIZE", name);
if (ioctl(fd, BLKGETSIZE64, size) < 0) {
log_sys_error("ioctl BLKGETSIZE64", name);
close(fd);
return 0;
}
*size >>= BLKSIZE_SHIFT; /* Convert to sectors */
close(fd);
*size = (uint64_t) s;
return 1;
}
@@ -62,48 +246,106 @@ int dev_get_sectsize(struct device *dev, uint32_t *size)
return 1;
}
static void _flush(int fd)
void dev_flush(struct device *dev)
{
ioctl(fd, BLKFLSBUF, 0);
if (!(dev->flags & DEV_REGULAR) && ioctl(dev->fd, BLKFLSBUF, 0) >= 0)
return;
if (fsync(dev->fd) >= 0)
return;
sync();
}
int dev_open(struct device *dev, int flags)
int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
{
struct stat buf;
const char *name = dev_name_confirmed(dev);
const char *name;
if (!name) {
if (dev->fd >= 0) {
dev->open_count++;
return 1;
}
if (memlock())
log_error("WARNING: dev_open(%s) called while suspended",
dev_name(dev));
if (dev->flags & DEV_REGULAR)
name = dev_name(dev);
else if (!(name = dev_name_confirmed(dev, quiet))) {
stack;
return 0;
}
if (dev->fd >= 0) {
log_error("Device '%s' has already been opened", name);
return 0;
}
if ((stat(name, &buf) < 0) || (buf.st_rdev != dev->dev)) {
if (!(dev->flags & DEV_REGULAR) &&
((stat(name, &buf) < 0) || (buf.st_rdev != dev->dev))) {
log_error("%s: stat failed: Has device name changed?", name);
return 0;
}
if ((dev->fd = open(name, flags)) < 0) {
if (direct)
flags |= O_DIRECT;
if ((dev->fd = open(name, flags, 0777)) < 0) {
log_sys_error("open", name);
return 0;
}
if ((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev)) {
dev->open_count = 1;
dev->flags &= ~DEV_ACCESSED_W;
if (!(dev->flags & DEV_REGULAR) &&
((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
log_error("%s: fstat failed: Has device name changed?", name);
dev_close(dev);
dev->fd = -1;
return 0;
}
_flush(dev->fd);
dev->flags = 0;
#if !O_DIRECT
if (!(dev->flags & DEV_REGULAR))
dev_flush(dev);
#endif
if ((flags & O_CREAT) && !(flags & O_TRUNC)) {
dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
}
list_add(&_open_devices, &dev->open_list);
log_debug("Opened %s", dev_name(dev));
return 1;
}
int dev_open_quiet(struct device *dev)
{
/* FIXME Open O_RDONLY if vg read lock? */
return dev_open_flags(dev, O_RDWR, 1, 1);
}
int dev_open(struct device *dev)
{
/* FIXME Open O_RDONLY if vg read lock? */
return dev_open_flags(dev, O_RDWR, 1, 0);
}
static void _close(struct device *dev)
{
if (close(dev->fd))
log_sys_error("close", dev_name(dev));
dev->fd = -1;
list_del(&dev->open_list);
log_debug("Closed %s", dev_name(dev));
if (dev->flags & DEV_ALLOCED) {
dbg_free((void *) list_item(dev->aliases.n, struct str_list)->
str);
dbg_free(dev->aliases.n);
dbg_free(dev);
}
}
int dev_close(struct device *dev)
{
if (dev->fd < 0) {
@@ -111,151 +353,113 @@ int dev_close(struct device *dev)
"which is not open.", dev_name(dev));
return 0;
}
#if !O_DIRECT
if (dev->flags & DEV_ACCESSED_W)
_flush(dev->fd);
dev_flush(dev);
#endif
if (close(dev->fd))
log_sys_error("close", dev_name(dev));
dev->fd = -1;
/* FIXME lookup device in cache to get vgname and see if it's locked? */
if (--dev->open_count < 1 && !vgs_locked())
_close(dev);
return 1;
}
/*
* FIXME: factor common code out.
void dev_close_all(void)
{
struct list *doh, *doht;
struct device *dev;
list_iterate_safe(doh, doht, &_open_devices) {
dev = list_struct_base(doh, struct device, open_list);
if (dev->open_count < 1)
_close(dev);
}
}
int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer)
{
struct device_area where;
if (!dev->open_count)
return 0;
where.dev = dev;
where.start = offset;
where.size = len;
return _aligned_io(&where, buffer, 0);
}
/* FIXME If O_DIRECT can't extend file, dev_extend first; dev_truncate after.
* But fails if concurrent processes writing
*/
int raw_read(int fd, void *buf, size_t count)
/* FIXME pre-extend the file */
int dev_append(struct device *dev, size_t len, void *buffer)
{
size_t n = 0;
int tot = 0;
int r;
while (tot < count) {
do
n = read(fd, buf, count - tot);
while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (!dev->open_count)
return 0;
if (n <= 0)
return tot ? tot : n;
r = dev_write(dev, dev->end, len, buffer);
dev->end += (uint64_t) len;
tot += n;
buf += n;
}
return tot;
#if !O_DIRECT
dev_flush(dev);
#endif
return r;
}
int64_t dev_read(struct device * dev, uint64_t offset,
int64_t len, void *buffer)
int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer)
{
const char *name = dev_name(dev);
int fd = dev->fd;
struct device_area where;
if (fd < 0) {
log_err("Attempt to read an unopened device (%s).", name);
if (!dev->open_count)
return 0;
}
if (lseek(fd, offset, SEEK_SET) < 0) {
log_sys_error("lseek", name);
return 0;
}
return raw_read(fd, buffer, len);
}
int _write(int fd, const void *buf, size_t count)
{
ssize_t n = 0;
int tot = 0;
/* Skip all writes */
if (test_mode())
return count;
while (tot < count) {
do
n = write(fd, buf, count - tot);
while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (n <= 0)
return tot ? tot : n;
tot += n;
buf += n;
}
return tot;
}
int64_t dev_write(struct device * dev, uint64_t offset,
int64_t len, void *buffer)
{
const char *name = dev_name(dev);
int fd = dev->fd;
if (fd < 0) {
log_error("Attempt to write to unopened device %s", name);
return 0;
}
if (lseek(fd, offset, SEEK_SET) < 0) {
log_sys_error("lseek", name);
return 0;
}
where.dev = dev;
where.start = offset;
where.size = len;
dev->flags |= DEV_ACCESSED_W;
return _write(fd, buffer, len);
return _aligned_io(&where, buffer, 1);
}
int dev_zero(struct device *dev, uint64_t offset, int64_t len)
int dev_zero(struct device *dev, uint64_t offset, size_t len)
{
int64_t r, s;
size_t s;
char buffer[4096];
int already_open;
already_open = dev_is_open(dev);
if (!already_open && !dev_open(dev, O_RDWR)) {
if (!dev_open(dev)) {
stack;
return 0;
}
if (lseek(dev->fd, offset, SEEK_SET) < 0) {
log_sys_error("lseek", dev_name(dev));
if (!already_open && !dev_close(dev))
stack;
return 0;
}
if ((offset % SECTOR_SIZE) || (len % SECTOR_SIZE))
log_debug("Wiping %s at %" PRIu64 " length %" PRId64,
log_debug("Wiping %s at %" PRIu64 " length %" PRIsize_t,
dev_name(dev), offset, len);
else
log_debug("Wiping %s at sector %" PRIu64 " length %" PRId64
log_debug("Wiping %s at sector %" PRIu64 " length %" PRIsize_t
" sectors", dev_name(dev), offset >> SECTOR_SHIFT,
len >> SECTOR_SHIFT);
memset(buffer, 0, sizeof(buffer));
while (1) {
s = len > sizeof(buffer) ? sizeof(buffer) : len;
r = _write(dev->fd, buffer, s);
if (r <= 0)
if (!dev_write(dev, offset, s, buffer))
break;
len -= r;
if (!len) {
r = 1;
len -= s;
if (!len)
break;
}
}
dev->flags |= DEV_ACCESSED_W;
if (!already_open && !dev_close(dev))
if (!dev_close(dev))
stack;
/* FIXME: Always display error */

View File

@@ -18,7 +18,6 @@
*/
#if 0
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdio.h>

View File

@@ -7,11 +7,12 @@
#ifndef _LVM_DEVICE_H
#define _LVM_DEVICE_H
#include "lvm-types.h"
#include "list.h"
#include "uuid.h"
#include <fcntl.h>
#define DEV_ACCESSED_W 0x00000001 /* Device written to? */
#define DEV_REGULAR 0x00000002 /* Regular file? */
#define DEV_ALLOCED 0x00000004 /* dbg_malloc used */
/*
* All devices in LVM will be represented by one of these.
@@ -23,7 +24,10 @@ struct device {
/* private */
int fd;
int open_count;
uint32_t flags;
uint64_t end;
struct list open_list;
char pvid[ID_LEN + 1];
};
@@ -45,39 +49,45 @@ struct device_area {
int dev_get_size(struct device *dev, uint64_t *size);
int dev_get_sectsize(struct device *dev, uint32_t *size);
int dev_open(struct device *dev, int flags);
/* Use quiet version if device number could change e.g. when opening LV */
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);
void dev_close_all(void);
static inline int dev_fd(struct device *dev)
{
return dev->fd;
}
int raw_read(int fd, void *buf, size_t count);
int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer);
int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer);
int dev_append(struct device *dev, size_t len, void *buffer);
int dev_zero(struct device *dev, uint64_t offset, size_t len);
void dev_flush(struct device *dev);
int64_t dev_read(struct device *dev,
uint64_t offset, int64_t len, void *buffer);
int64_t dev_write(struct device *dev,
uint64_t offset, int64_t len, void *buffer);
int dev_zero(struct device *dev, uint64_t offset, int64_t len);
struct device *dev_create_file(const char *filename, struct device *dev,
struct str_list *alias);
static inline const char *dev_name(struct device *dev)
static inline const char *dev_name(const struct device *dev)
{
return (dev) ? list_item(dev->aliases.n, struct str_list)->str :
"unknown device";
}
/* Return a valid device name from the alias list; NULL otherwise */
const char *dev_name_confirmed(struct device *dev);
const char *dev_name_confirmed(struct device *dev, int quiet);
/* FIXME Check partition type if appropriate */
#define is_lvm_partition(a) 1
/*
static inline int is_lvm_partition(const char *name)
{
return 1;
}
static inline int dev_is_open(struct device *dev)
{
return dev->fd >= 0 ? 1 : 0;
}
*/
#endif

View File

@@ -42,7 +42,7 @@ static struct {
} _segtypes[] = {
{
SEG_STRIPED, "striped"}, {
SEG_MIRROR, "mirror"}, {
SEG_MIRRORED, "mirror"}, {
SEG_SNAPSHOT, "snapshot"}
};
@@ -51,65 +51,68 @@ static int _num_segtypes = sizeof(_segtypes) / sizeof(*_segtypes);
uint64_t units_to_bytes(const char *units, char *unit_type)
{
char *ptr;
char *ptr = NULL;
uint64_t v;
ptr = (char *) units;
if (isdigit(*units)) {
v = (uint64_t) strtod(units, &ptr);
if (ptr == units)
return 0;
units = ptr;
} else
v = 1;
if (v == 1)
*unit_type = *ptr;
*unit_type = *units;
else
*unit_type = 'U';
switch (*ptr) {
switch (*units) {
case 'h':
case 'H':
v = 1ULL;
*unit_type = *ptr;
v = UINT64_C(1);
*unit_type = *units;
break;
case 's':
v *= SECTOR_SIZE;
break;
case 'b':
case 'B':
v *= 1ULL;
v *= UINT64_C(1);
break;
#define KILO UINT64_C(1024)
case 'k':
v *= 1024ULL;
v *= KILO;
break;
case 'm':
v *= 1024ULL * 1024ULL;
v *= KILO * KILO;
break;
case 'g':
v *= 1024ULL * 1024ULL * 1024ULL;
v *= KILO * KILO * KILO;
break;
case 't':
v *= 1024ULL * 1024ULL * 1024ULL * 1024ULL;
v *= KILO * KILO * KILO * KILO;
break;
#undef KILO
#define KILO UINT64_C(1000)
case 'K':
v *= 1000ULL;
v *= KILO;
break;
case 'M':
v *= 1000ULL * 1000ULL;
v *= KILO * KILO;
break;
case 'G':
v *= 1000ULL * 1000ULL * 1000ULL;
v *= KILO * KILO * KILO;
break;
case 'T':
v *= 1000ULL * 1000ULL * 1000ULL * 1000ULL;
v *= KILO * KILO * KILO * KILO;
break;
#undef KILO
default:
return 0;
}
if (*(ptr + 1))
if (*(units + 1))
return 0;
return v;
@@ -165,10 +168,10 @@ const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl)
{
int s;
int suffix = 1;
uint64_t byte;
uint64_t units = 1024ULL;
uint64_t byte = UINT64_C(0);
uint64_t units = UINT64_C(1024);
char *size_buf = NULL;
char *size_str[][3] = {
const char *size_str[][3] = {
{" Terabyte", " TB", "T"},
{" Gigabyte", " GB", "G"},
{" Megabyte", " MB", "M"},
@@ -192,20 +195,20 @@ const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl)
*size_str[s][2])
break;
if (size == 0ULL) {
if (size == UINT64_C(0)) {
sprintf(size_buf, "0%s", suffix ? size_str[s][sl] : "");
return size_buf;
}
if (s < 8) {
byte = cmd->current_settings.unit_factor;
size *= 1024ULL;
size *= UINT64_C(1024);
} else {
suffix = 1;
if (cmd->current_settings.unit_type == 'H')
units = 1000ULL;
units = UINT64_C(1000);
else
units = 1024ULL;
units = UINT64_C(1024);
byte = units * units * units;
s = 0;
while (size_str[s] && size < byte)
@@ -230,7 +233,7 @@ void pvdisplay_colons(struct physical_volume *pv)
return;
}
log_print("%s:%s:%" PRIu64 ":-1:%u:%u:-1:%" PRIu64 ":%u:%u:%u:%s",
log_print("%s:%s:%" PRIu64 ":-1:%u:%u:-1:%" PRIu32 ":%u:%u:%u:%s",
dev_name(pv->dev), pv->vg_name, pv->size,
/* FIXME pv->pv_number, Derive or remove? */
pv->status, /* FIXME Support old or new format here? */
@@ -251,7 +254,7 @@ void pvdisplay_full(struct cmd_context *cmd, struct physical_volume *pv,
char uuid[64];
const char *size;
uint64_t pe_free;
uint32_t pe_free;
if (!pv)
return;
@@ -296,9 +299,9 @@ void pvdisplay_full(struct cmd_context *cmd, struct physical_volume *pv,
/* LV count is no longer available when displaying PV
log_print("Cur LV %u", vg->lv_count);
*/
log_print("PE Size (KByte) %" PRIu64, pv->pe_size / 2);
log_print("PE Size (KByte) %" PRIu32, pv->pe_size / 2);
log_print("Total PE %u", pv->pe_count);
log_print("Free PE %" PRIu64, pe_free);
log_print("Free PE %" PRIu32, pe_free);
log_print("Allocated PE %u", pv->pe_alloc_count);
log_print("PV UUID %s", *uuid ? uuid : "none");
log_print(" ");
@@ -334,7 +337,7 @@ int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
void lvdisplay_colons(struct logical_volume *lv)
{
int inkernel;
struct dm_info info;
struct lvinfo info;
inkernel = lv_info(lv, &info) && info.exists;
log_print("%s%s/%s:%s:%d:%d:-1:%d:%" PRIu64 ":%d:-1:%d:%d:%d:%d",
@@ -354,7 +357,7 @@ void lvdisplay_colons(struct logical_volume *lv)
int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
struct dm_info info;
struct lvinfo info;
int inkernel, snap_active;
char uuid[64];
struct snapshot *snap = NULL;
@@ -437,7 +440,8 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
snap_percent = 100;
log_print("Snapshot chunk size %s",
display_size(cmd, snap->chunk_size / 2, SIZE_SHORT));
display_size(cmd, (uint64_t) snap->chunk_size / 2,
SIZE_SHORT));
/*
size = display_size(lv->size / 2, SIZE_SHORT);
@@ -459,8 +463,11 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
log_print("Allocation %s", get_alloc_string(lv->alloc));
log_print("Read ahead sectors %u", lv->read_ahead);
if (lv->status & FIXED_MINOR)
if (lv->status & FIXED_MINOR) {
if (lv->major >= 0)
log_print("Persistent major %d", lv->major);
log_print("Persistent minor %d", lv->minor);
}
if (inkernel)
log_print("Block device %d:%d", info.major,
@@ -471,21 +478,35 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
void _display_stripe(struct lv_segment *seg, int s, const char *pre)
static void _display_stripe(struct lv_segment *seg, uint32_t s, const char *pre)
{
uint32_t len = seg->len / seg->stripes;
switch (seg->area[s].type) {
case AREA_PV:
log_print("%sPhysical volume\t%s", pre,
seg->area[s].u.pv.pv ?
dev_name(seg->area[s].u.pv.pv->dev) : "Missing");
log_print("%sPhysical volume\t%s", pre,
seg->area[s].pv ? dev_name(seg->area[s].pv->dev) : "Missing");
if (seg->area[s].u.pv.pv)
log_print("%sPhysical extents\t%d to %d", pre,
seg->area[s].u.pv.pe,
seg->area[s].u.pv.pe + seg->area_len - 1);
break;
case AREA_LV:
log_print("%sLogical volume\t%s", pre,
seg->area[s].u.lv.lv ?
seg->area[s].u.lv.lv->name : "Missing");
if (seg->area[s].pv)
log_print("%sPhysical extents\t%d to %d", pre,
seg->area[s].pe, seg->area[s].pe + len - 1);
if (seg->area[s].u.lv.lv)
log_print("%sLogical extents\t%d to %d", pre,
seg->area[s].u.lv.le,
seg->area[s].u.lv.le + seg->area_len - 1);
}
}
int lvdisplay_segments(struct logical_volume *lv)
{
int s;
uint32_t s;
struct list *segh;
struct lv_segment *seg;
@@ -497,7 +518,7 @@ int lvdisplay_segments(struct logical_volume *lv)
log_print("Logical extent %u to %u:",
seg->le, seg->le + seg->len - 1);
if (seg->type == SEG_STRIPED && seg->stripes == 1)
if (seg->type == SEG_STRIPED && seg->area_count == 1)
log_print(" Type\t\tlinear");
else
log_print(" Type\t\t%s",
@@ -505,14 +526,14 @@ int lvdisplay_segments(struct logical_volume *lv)
switch (seg->type) {
case SEG_STRIPED:
if (seg->stripes == 1)
if (seg->area_count == 1)
_display_stripe(seg, 0, " ");
else {
log_print(" Stripes\t\t%u", seg->stripes);
log_print(" Stripes\t\t%u", seg->area_count);
log_print(" Stripe size\t\t%u KB",
seg->stripe_size / 2);
for (s = 0; s < seg->stripes; s++) {
for (s = 0; s < seg->area_count; s++) {
log_print(" Stripe %d:", s);
_display_stripe(seg, s, " ");
}
@@ -520,8 +541,16 @@ int lvdisplay_segments(struct logical_volume *lv)
log_print(" ");
break;
case SEG_SNAPSHOT:
case SEG_MIRROR:
;
break;
case SEG_MIRRORED:
log_print(" Mirrors\t\t%u", seg->area_count);
log_print(" Mirror size\t\t%u", seg->area_len);
log_print(" Mirror original:");
_display_stripe(seg, 0, " ");
log_print(" Mirror destination:");
_display_stripe(seg, 1, " ");
log_print(" ");
break;
}
}
@@ -589,7 +618,8 @@ void vgdisplay_full(struct volume_group *vg)
2), SIZE_SHORT));
log_print("PE Size %s",
display_size(vg->cmd, vg->extent_size / 2, SIZE_SHORT));
display_size(vg->cmd, (uint64_t) vg->extent_size / 2,
SIZE_SHORT));
log_print("Total PE %u", vg->extent_count);
@@ -631,13 +661,15 @@ void vgdisplay_short(struct volume_group *vg)
{
log_print("\"%s\" %-9s [%-9s used / %s free]", vg->name,
/********* FIXME if "open" print "/used" else print "/idle"??? ******/
display_size(vg->cmd, vg->extent_count * vg->extent_size / 2,
display_size(vg->cmd, (uint64_t) vg->extent_count *
vg->extent_size / 2, SIZE_SHORT),
display_size(vg->cmd,
((uint64_t) vg->extent_count -
vg->free_count) * vg->extent_size / 2,
SIZE_SHORT), display_size(vg->cmd,
(vg->extent_count -
vg->free_count) *
(uint64_t) vg->
free_count *
vg->extent_size / 2,
SIZE_SHORT),
display_size(vg->cmd, vg->free_count * vg->extent_size / 2,
SIZE_SHORT));
SIZE_SHORT));
return;
}

View File

@@ -19,6 +19,8 @@ static int _and_p(struct dev_filter *f, struct device *dev)
filters++;
}
log_debug("Using %s", dev_name(dev));
return 1;
}

View File

@@ -32,8 +32,12 @@ static int _init_hash(struct pfilter *pf)
if (pf->devices)
hash_destroy(pf->devices);
pf->devices = hash_create(128);
return pf->devices ? 1 : 0;
if (!(pf->devices = hash_create(128))) {
stack;
return 0;
}
return 1;
}
int persistent_filter_wipe(struct dev_filter *f)
@@ -109,6 +113,8 @@ int persistent_filter_load(struct dev_filter *f)
r = 1;
}
log_very_verbose("Loaded persistent filter cache from %s", pf->file);
out:
destroy_config_tree(cf);
return r;
@@ -199,7 +205,11 @@ static int _lookup_p(struct dev_filter *f, struct device *dev)
}
}
return l == PF_GOOD_DEVICE;
if (l == PF_BAD_DEVICE) {
log_debug("%s: Skipping (cached)", dev_name(dev));
return 0;
} else
return 1;
}
static void _destroy(struct dev_filter *f)

View File

@@ -19,7 +19,7 @@ struct rfilter {
};
static int _extract_pattern(struct pool *mem, const char *pat,
char **regex, bitset_t accept, int index)
char **regex, bitset_t accept, int ix)
{
char sep, *r, *ptr;
@@ -28,11 +28,11 @@ static int _extract_pattern(struct pool *mem, const char *pat,
*/
switch (*pat) {
case 'a':
bit_set(accept, index);
bit_set(accept, ix);
break;
case 'r':
bit_clear(accept, index);
bit_clear(accept, ix);
break;
default:
@@ -80,7 +80,7 @@ static int _extract_pattern(struct pool *mem, const char *pat,
}
*ptr = '\0';
regex[index] = r;
regex[ix] = r;
return 1;
}
@@ -89,7 +89,8 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
struct pool *scratch;
struct config_value *v;
char **regex;
int count = 0, i, r = 0;
unsigned count = 0;
int i, r = 0;
if (!(scratch = pool_create(1024))) {
stack;
@@ -161,6 +162,8 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
if (bit(rf->accept, m)) {
if (!first) {
log_debug("%s: New preferred name",
sl->str);
list_del(&sl->list);
list_add_h(&dev->aliases, &sl->list);
}

View File

@@ -25,17 +25,16 @@
#include "config.h"
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include <linux/kdev_t.h>
#include <limits.h>
#define NUMBER_OF_MAJORS 256
typedef struct {
char *name;
int max_partitions;
const char *name;
const int max_partitions;
} device_info_t;
static int _md_major = -1;
@@ -46,7 +45,7 @@ int md_major(void)
}
/* This list can be supplemented with devices/types in the config file */
static device_info_t device_info[] = {
static const device_info_t device_info[] = {
{"ide", 16}, /* IDE disk */
{"sd", 16}, /* SCSI disk */
{"md", 16}, /* Multiple Disk driver (SoftRAID) */
@@ -68,12 +67,16 @@ static int _passes_lvm_type_device_filter(struct dev_filter *f,
const char *name = dev_name(dev);
/* Is this a recognised device type? */
if (!(((int *) f->private)[MAJOR(dev->dev)]))
if (!(((int *) f->private)[MAJOR(dev->dev)])) {
log_debug("%s: Skipping: Unrecognised LVM device type %"
PRIu64, name, (uint64_t) MAJOR(dev->dev));
return 0;
}
/* Check it's accessible */
if ((fd = open(name, O_RDONLY)) < 0) {
log_debug("Unable to open %s: %s", name, strerror(errno));
log_debug("%s: Skipping: open failed: %s", name,
strerror(errno));
return 0;
}
@@ -90,7 +93,7 @@ static int *_scan_proc_dev(const char *proc, struct config_node *cn)
int i, j = 0;
int line_maj = 0;
int blocksection = 0;
int dev_len = 0;
size_t dev_len = 0;
struct config_value *cv;
int *max_partitions_by_major;
char *name;
@@ -101,6 +104,14 @@ static int *_scan_proc_dev(const char *proc, struct config_node *cn)
return NULL;
}
if (!*proc) {
log_verbose("No proc filesystem found: using all block device "
"types");
for (i = 0; i < NUMBER_OF_MAJORS; i++)
max_partitions_by_major[i] = 1;
return max_partitions_by_major;
}
if (lvm_snprintf(proc_devices, sizeof(proc_devices),
"%s/devices", proc) < 0) {
log_error("Failed to create /proc/devices string");
@@ -203,8 +214,10 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
f->passes_filter = _passes_lvm_type_device_filter;
f->destroy = lvm_type_filter_destroy;
if (!(f->private = _scan_proc_dev(proc, cn)))
if (!(f->private = _scan_proc_dev(proc, cn))) {
stack;
return NULL;
}
return f;
}

View File

@@ -23,6 +23,16 @@
#include "config.h"
#include <sys/stat.h>
#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
struct dev_filter *lvm_type_filter_create(const char *proc,
struct config_node *cn);

View File

@@ -9,11 +9,9 @@
#include "pool.h"
#include "xlate.h"
#include "filter.h"
#include "cache.h"
#include "lvmcache.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/kdev_t.h>
#define fail do {stack; return 0;} while(0)
#define xx16(v) disk->v = xlate16(disk->v)
@@ -94,7 +92,7 @@ static void _xlate_vgd(struct vg_disk *disk)
xx32(pvg_total);
}
static void _xlate_extents(struct pe_disk *extents, int count)
static void _xlate_extents(struct pe_disk *extents, uint32_t count)
{
int i;
@@ -132,7 +130,7 @@ static int _munge_formats(struct pv_disk *pvd)
static int _read_pvd(struct device *dev, struct pv_disk *pvd)
{
if (dev_read(dev, 0, sizeof(*pvd), pvd) != sizeof(*pvd)) {
if (!dev_read(dev, UINT64_C(0), sizeof(*pvd), pvd)) {
log_very_verbose("Failed to read PV data from %s",
dev_name(dev));
return 0;
@@ -155,9 +153,9 @@ static int _read_pvd(struct device *dev, struct pv_disk *pvd)
return 1;
}
static int _read_lvd(struct device *dev, ulong pos, struct lv_disk *disk)
static int _read_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
{
if (dev_read(dev, pos, sizeof(*disk), disk) != sizeof(*disk))
if (!dev_read(dev, pos, sizeof(*disk), disk))
fail;
_xlate_lvd(disk);
@@ -168,8 +166,8 @@ static int _read_lvd(struct device *dev, ulong pos, struct lv_disk *disk)
static int _read_vgd(struct disk_list *data)
{
struct vg_disk *vgd = &data->vgd;
ulong pos = data->pvd.vg_on_disk.base;
if (dev_read(data->dev, pos, sizeof(*vgd), vgd) != sizeof(*vgd))
uint64_t pos = data->pvd.vg_on_disk.base;
if (!dev_read(data->dev, pos, sizeof(*vgd), vgd))
fail;
_xlate_vgd(vgd);
@@ -182,12 +180,11 @@ static int _read_uuids(struct disk_list *data)
int num_read = 0;
struct uuid_list *ul;
char buffer[NAME_LEN];
ulong pos = data->pvd.pv_uuidlist_on_disk.base;
ulong end = pos + data->pvd.pv_uuidlist_on_disk.size;
uint64_t pos = data->pvd.pv_uuidlist_on_disk.base;
uint64_t end = pos + data->pvd.pv_uuidlist_on_disk.size;
while (pos < end && num_read < data->vgd.pv_cur) {
if (dev_read(data->dev, pos, sizeof(buffer), buffer) !=
sizeof(buffer))
if (!dev_read(data->dev, pos, sizeof(buffer), buffer))
fail;
if (!(ul = pool_alloc(data->mem, sizeof(*ul))))
@@ -212,8 +209,8 @@ static inline int _check_lvd(struct lv_disk *lvd)
static int _read_lvs(struct disk_list *data)
{
int i, read = 0;
ulong pos;
unsigned int i, read = 0;
uint64_t pos;
struct lvd_list *ll;
struct vg_disk *vgd = &data->vgd;
@@ -241,12 +238,12 @@ static int _read_extents(struct disk_list *data)
{
size_t len = sizeof(struct pe_disk) * data->pvd.pe_total;
struct pe_disk *extents = pool_alloc(data->mem, len);
ulong pos = data->pvd.pe_on_disk.base;
uint64_t pos = data->pvd.pe_on_disk.base;
if (!extents)
fail;
if (dev_read(data->dev, pos, len, extents) != len)
if (!dev_read(data->dev, pos, len, extents))
fail;
_xlate_extents(extents, data->pvd.pe_total);
@@ -260,7 +257,8 @@ static int _read_extents(struct disk_list *data)
*/
static void _munge_exported_vg(struct disk_list *data)
{
int l, s;
int l;
size_t s;
/* Return if PV not in a VG or VG not exported */
if ((!*data->pvd.vg_name) || !(data->vgd.vg_status & VG_EXPORTED))
@@ -274,13 +272,13 @@ static void _munge_exported_vg(struct disk_list *data)
data->pvd.pv_status |= VG_EXPORTED;
}
static struct disk_list *__read_disk(struct format_type *fmt,
static struct disk_list *__read_disk(const struct format_type *fmt,
struct device *dev, struct pool *mem,
const char *vg_name)
{
struct disk_list *dl = pool_alloc(mem, sizeof(*dl));
const char *name = dev_name(dev);
struct cache_info *info;
struct lvmcache_info *info;
if (!dl) {
stack;
@@ -297,8 +295,8 @@ static struct disk_list *__read_disk(struct format_type *fmt,
goto bad;
}
if (!(info = cache_add(fmt->labeller, dl->pvd.pv_uuid, dev,
dl->pvd.vg_name, NULL)))
if (!(info = lvmcache_add(fmt->labeller, dl->pvd.pv_uuid, dev,
dl->pvd.vg_name, NULL)))
stack;
else {
info->device_size = xlate32(dl->pvd.pv_size) << SECTOR_SHIFT;
@@ -361,12 +359,12 @@ static struct disk_list *__read_disk(struct format_type *fmt,
return NULL;
}
struct disk_list *read_disk(struct format_type *fmt, struct device *dev,
struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
struct pool *mem, const char *vg_name)
{
struct disk_list *r;
if (!dev_open(dev, O_RDONLY)) {
if (!dev_open(dev)) {
stack;
return NULL;
}
@@ -408,7 +406,7 @@ static void _add_pv_to_list(struct list *head, struct disk_list *data)
* We keep track of the first object allocated form the pool
* so we can free off all the memory if something goes wrong.
*/
int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
struct dev_filter *filter, struct pool *mem,
struct list *head)
{
@@ -416,13 +414,13 @@ int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
struct device *dev;
struct disk_list *data = NULL;
struct list *vgih;
struct cache_vginfo *vginfo;
struct lvmcache_vginfo *vginfo;
/* Fast path if we already saw this VG and cached the list of PVs */
if (vg_name && (vginfo = vginfo_from_vgname(vg_name)) &&
vginfo->infos.n) {
list_iterate(vgih, &vginfo->infos) {
dev = list_item(vgih, struct cache_info)->dev;
dev = list_item(vgih, struct lvmcache_info)->dev;
if (dev && !(data = read_disk(fmt, dev, mem, vg_name)))
break;
_add_pv_to_list(head, data);
@@ -461,10 +459,10 @@ int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
static int _write_vgd(struct disk_list *data)
{
struct vg_disk *vgd = &data->vgd;
ulong pos = data->pvd.vg_on_disk.base;
uint64_t pos = data->pvd.vg_on_disk.base;
_xlate_vgd(vgd);
if (dev_write(data->dev, pos, sizeof(*vgd), vgd) != sizeof(*vgd))
if (!dev_write(data->dev, pos, sizeof(*vgd), vgd))
fail;
_xlate_vgd(vgd);
@@ -476,8 +474,8 @@ static int _write_uuids(struct disk_list *data)
{
struct uuid_list *ul;
struct list *uh;
ulong pos = data->pvd.pv_uuidlist_on_disk.base;
ulong end = pos + data->pvd.pv_uuidlist_on_disk.size;
uint64_t pos = data->pvd.pv_uuidlist_on_disk.base;
uint64_t end = pos + data->pvd.pv_uuidlist_on_disk.size;
list_iterate(uh, &data->uuids) {
if (pos >= end) {
@@ -487,7 +485,7 @@ static int _write_uuids(struct disk_list *data)
}
ul = list_item(uh, struct uuid_list);
if (dev_write(data->dev, pos, NAME_LEN, ul->uuid) != NAME_LEN)
if (!dev_write(data->dev, pos, NAME_LEN, ul->uuid))
fail;
pos += NAME_LEN;
@@ -496,10 +494,10 @@ static int _write_uuids(struct disk_list *data)
return 1;
}
static int _write_lvd(struct device *dev, ulong pos, struct lv_disk *disk)
static int _write_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
{
_xlate_lvd(disk);
if (dev_write(dev, pos, sizeof(*disk), disk) != sizeof(*disk))
if (!dev_write(dev, pos, sizeof(*disk), disk))
fail;
_xlate_lvd(disk);
@@ -510,7 +508,7 @@ static int _write_lvd(struct device *dev, ulong pos, struct lv_disk *disk)
static int _write_lvs(struct disk_list *data)
{
struct list *lvh;
ulong pos, offset;
uint64_t pos, offset;
pos = data->pvd.lv_on_disk.base;
@@ -540,10 +538,10 @@ static int _write_extents(struct disk_list *data)
{
size_t len = sizeof(struct pe_disk) * data->pvd.pe_total;
struct pe_disk *extents = data->extents;
ulong pos = data->pvd.pe_on_disk.base;
uint64_t pos = data->pvd.pe_on_disk.base;
_xlate_extents(extents, data->pvd.pe_total);
if (dev_write(data->dev, pos, len, extents) != len)
if (!dev_write(data->dev, pos, len, extents))
fail;
_xlate_extents(extents, data->pvd.pe_total);
@@ -554,8 +552,8 @@ static int _write_extents(struct disk_list *data)
static int _write_pvd(struct disk_list *data)
{
char *buf;
ulong pos = data->pvd.pv_on_disk.base;
ulong size = data->pvd.pv_on_disk.size;
uint64_t pos = data->pvd.pv_on_disk.base;
size_t size = data->pvd.pv_on_disk.size;
if (size < sizeof(struct pv_disk)) {
log_error("Invalid PV structure size.");
@@ -575,7 +573,7 @@ static int _write_pvd(struct disk_list *data)
memcpy(buf, &data->pvd, sizeof(struct pv_disk));
_xlate_pvd((struct pv_disk *) buf);
if (dev_write(data->dev, pos, size, buf) != size) {
if (!dev_write(data->dev, pos, size, buf)) {
dbg_free(buf);
fail;
}
@@ -587,7 +585,8 @@ static int _write_pvd(struct disk_list *data)
/*
* assumes the device has been opened.
*/
static int __write_all_pvd(struct format_type *fmt, struct disk_list *data)
static int __write_all_pvd(const struct format_type *fmt,
struct disk_list *data)
{
const char *pv_name = dev_name(data->dev);
@@ -636,11 +635,11 @@ static int __write_all_pvd(struct format_type *fmt, struct disk_list *data)
/*
* opens the device and hands to the above fn.
*/
static int _write_all_pvd(struct format_type *fmt, struct disk_list *data)
static int _write_all_pvd(const struct format_type *fmt, struct disk_list *data)
{
int r;
if (!dev_open(data->dev, O_WRONLY)) {
if (!dev_open(data->dev)) {
stack;
return 0;
}
@@ -658,7 +657,7 @@ static int _write_all_pvd(struct format_type *fmt, struct disk_list *data)
* little sanity checking, so make sure correct
* data is passed to here.
*/
int write_disks(struct format_type *fmt, struct list *pvs)
int write_disks(const struct format_type *fmt, struct list *pvs)
{
struct list *pvh;
struct disk_list *dl;

View File

@@ -178,14 +178,14 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
* disk_lists.
*/
struct disk_list *read_disk(struct format_type *fmt, struct device *dev,
struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
struct pool *mem, const char *vg_name);
int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
struct dev_filter *filter,
struct pool *mem, struct list *results);
int write_disks(struct format_type *fmt, struct list *pvds);
int write_disks(const struct format_type *fmt, struct list *pvds);
/*
* Functions to translate to between disk and in
@@ -205,10 +205,10 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd);
int import_extents(struct pool *mem, struct volume_group *vg,
struct list *pvds);
int export_extents(struct disk_list *dl, int lv_num,
int export_extents(struct disk_list *dl, uint32_t lv_num,
struct logical_volume *lv, struct physical_volume *pv);
int import_pvs(struct format_type *fmt, struct pool *mem,
int import_pvs(const struct format_type *fmt, struct pool *mem,
struct volume_group *vg,
struct list *pvds, struct list *results, int *count);

View File

@@ -12,7 +12,7 @@
#include "list.h"
#include "display.h"
#include "toolcontext.h"
#include "cache.h"
#include "lvmcache.h"
#include "lvm1-label.h"
#include "format1.h"
@@ -23,8 +23,9 @@ static int _check_vgs(struct list *pvs, int *partial)
struct disk_list *dl = NULL;
struct disk_list *first = NULL;
int pv_count = 0;
int exported = -1;
uint32_t pv_count = 0;
uint32_t exported = 0;
int first_time = 1;
*partial = 0;
@@ -36,8 +37,9 @@ static int _check_vgs(struct list *pvs, int *partial)
list_iterate(pvh, pvs) {
dl = list_item(pvh, struct disk_list);
if (exported < 0) {
if (first_time) {
exported = dl->pvd.pv_status & VG_EXPORTED;
first_time = 0;
continue;
}
@@ -246,13 +248,13 @@ static int _vg_write(struct format_instance *fid, struct volume_group *vg,
fid->fmt->cmd->filter) &&
write_disks(fid->fmt, &pvds));
cache_update_vg(vg);
lvmcache_update_vg(vg);
pool_destroy(mem);
return r;
}
int _pv_read(struct format_type *fmt, const char *pv_name,
struct physical_volume *pv, struct list *mdas)
static int _pv_read(const struct format_type *fmt, const char *pv_name,
struct physical_volume *pv, struct list *mdas)
{
struct pool *mem = pool_create(1024);
struct disk_list *dl;
@@ -290,7 +292,7 @@ int _pv_read(struct format_type *fmt, const char *pv_name,
return r;
}
static int _pv_setup(struct format_type *fmt,
static int _pv_setup(const struct format_type *fmt,
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size,
int pvmetadatacopies,
@@ -301,7 +303,8 @@ static int _pv_setup(struct format_type *fmt,
pv->size--;
if (pv->size > MAX_PV_SIZE) {
log_error("Physical volumes cannot be bigger than %s",
display_size(fmt->cmd, MAX_PV_SIZE / 2, SIZE_SHORT));
display_size(fmt->cmd, (uint64_t) MAX_PV_SIZE / 2,
SIZE_SHORT));
return 0;
}
@@ -329,10 +332,10 @@ static int _pv_setup(struct format_type *fmt,
return 1;
}
static int _find_free_lvnum(struct logical_volume *lv)
static uint32_t _find_free_lvnum(struct logical_volume *lv)
{
int lvnum_used[MAX_LV];
int i = 0;
uint32_t i = 0;
struct list *lvh;
struct lv_list *lvl;
@@ -371,17 +374,17 @@ static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
return 1;
}
static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
struct list *mdas, int64_t sector)
{
struct pool *mem;
struct disk_list *dl;
struct list pvs;
struct label *label;
struct cache_info *info;
struct lvmcache_info *info;
if (!(info = cache_add(fmt->labeller, (char *) &pv->id, pv->dev,
pv->vg_name, NULL))) {
if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
pv->vg_name, NULL))) {
stack;
return 0;
}
@@ -434,7 +437,7 @@ static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
return 0;
}
int _vg_setup(struct format_instance *fid, struct volume_group *vg)
static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
{
/* just check max_pv and max_lv */
if (vg->max_lv >= MAX_LV)
@@ -445,10 +448,12 @@ int _vg_setup(struct format_instance *fid, struct volume_group *vg)
if (vg->extent_size > MAX_PE_SIZE || vg->extent_size < MIN_PE_SIZE) {
log_error("Extent size must be between %s and %s",
display_size(fid->fmt->cmd, MIN_PE_SIZE / 2,
display_size(fid->fmt->cmd, (uint64_t) MIN_PE_SIZE
/ 2,
SIZE_SHORT), display_size(fid->fmt->cmd,
MAX_PE_SIZE /
2,
(uint64_t)
MAX_PE_SIZE
/ 2,
SIZE_SHORT));
return 0;
@@ -456,8 +461,8 @@ int _vg_setup(struct format_instance *fid, struct volume_group *vg)
if (vg->extent_size % MIN_PE_SIZE) {
log_error("Extent size must be multiple of %s",
display_size(fid->fmt->cmd, MIN_PE_SIZE / 2,
SIZE_SHORT));
display_size(fid->fmt->cmd,
(uint64_t) MIN_PE_SIZE / 2, SIZE_SHORT));
return 0;
}
@@ -475,8 +480,9 @@ static struct metadata_area_ops _metadata_format1_ops = {
vg_write:_vg_write,
};
struct format_instance *_create_instance(struct format_type *fmt,
const char *vgname, void *private)
static struct format_instance *_create_instance(const struct format_type *fmt,
const char *vgname,
void *private)
{
struct format_instance *fid;
struct metadata_area *mda;
@@ -503,14 +509,14 @@ struct format_instance *_create_instance(struct format_type *fmt,
return fid;
}
void _destroy_instance(struct format_instance *fid)
static void _destroy_instance(struct format_instance *fid)
{
return;
}
void _destroy(struct format_type *fmt)
static void _destroy(const struct format_type *fmt)
{
dbg_free(fmt);
dbg_free((void *) fmt);
}
static struct format_handler _format1_ops = {
@@ -527,6 +533,7 @@ static struct format_handler _format1_ops = {
#ifdef LVM1_INTERNAL
struct format_type *init_lvm1_format(struct cmd_context *cmd)
#else /* Shared */
struct format_type *init_format(struct cmd_context *cmd);
struct format_type *init_format(struct cmd_context *cmd)
#endif
{

View File

@@ -12,10 +12,10 @@
#include "hash.h"
#include "list.h"
#include "lvm-string.h"
#include "filter.h"
#include <time.h>
#include <sys/utsname.h>
#include <linux/kdev_t.h>
static int _check_vg_name(const char *name)
{
@@ -79,7 +79,7 @@ int import_pv(struct pool *mem, struct device *dev,
return 1;
}
int _system_id(char *s, const char *prefix)
static int _system_id(char *s, const char *prefix)
{
struct utsname uts;
@@ -288,8 +288,11 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
if (lvd->lv_status & LV_PERSISTENT_MINOR) {
lv->status |= FIXED_MINOR;
lv->minor = MINOR(lvd->lv_dev);
} else
lv->major = MAJOR(lvd->lv_dev);
} else {
lv->major = -1;
lv->minor = -1;
}
if (lvd->lv_access & LV_READ)
lv->status |= LVM_READ;
@@ -335,13 +338,14 @@ 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(0, lv->minor);
lvd->lv_dev = MKDEV(lv->major, lv->minor);
}
lvd->lv_read_ahead = lv->read_ahead;
lvd->lv_stripes = list_item(lv->segments.n, struct lv_segment)->stripes;
lvd->lv_stripesize = list_item(lv->segments.n,
struct lv_segment)->stripe_size;
lvd->lv_stripes =
list_item(lv->segments.n, struct lv_segment)->area_count;
lvd->lv_stripesize =
list_item(lv->segments.n, struct lv_segment)->stripe_size;
lvd->lv_size = lv->size;
lvd->lv_allocated_le = lv->le_count;
@@ -353,7 +357,7 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
lvd->lv_allocation |= LV_CONTIGUOUS;
}
int export_extents(struct disk_list *dl, int lv_num,
int export_extents(struct disk_list *dl, uint32_t lv_num,
struct logical_volume *lv, struct physical_volume *pv)
{
struct list *segh;
@@ -364,15 +368,25 @@ int export_extents(struct disk_list *dl, int lv_num,
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct lv_segment);
for (s = 0; s < seg->stripes; s++) {
if (seg->area[s].pv != pv)
for (s = 0; s < seg->area_count; s++) {
if (seg->type != SEG_STRIPED) {
log_error("Non-striped segment type in LV %s: "
"unsupported by format1", lv->name);
return 0;
}
if (seg->area[s].type != AREA_PV) {
log_error("LV stripe found in LV %s: "
"unsupported by format1", lv->name);
return 0;
}
if (seg->area[s].u.pv.pv != pv)
continue; /* not our pv */
for (pe = 0; pe < (seg->len / seg->stripes); pe++) {
ped = &dl->extents[pe + seg->area[s].pe];
for (pe = 0; pe < (seg->len / seg->area_count); pe++) {
ped = &dl->extents[pe + seg->area[s].u.pv.pe];
ped->lv_num = lv_num;
ped->le_num = (seg->le / seg->stripes) + pe +
s * (lv->le_count / seg->stripes);
ped->le_num = (seg->le / seg->area_count) + pe +
s * (lv->le_count / seg->area_count);
}
}
}
@@ -380,7 +394,7 @@ int export_extents(struct disk_list *dl, int lv_num,
return 1;
}
int import_pvs(struct format_type *fmt, struct pool *mem,
int import_pvs(const struct format_type *fmt, struct pool *mem,
struct volume_group *vg,
struct list *pvds, struct list *results, int *count)
{
@@ -393,7 +407,7 @@ int import_pvs(struct format_type *fmt, struct pool *mem,
dl = list_item(pvdh, struct disk_list);
if (!(pvl = pool_alloc(mem, sizeof(*pvl))) ||
if (!(pvl = pool_zalloc(mem, sizeof(*pvl))) ||
!(pvl->pv = pool_alloc(mem, sizeof(*pvl->pv)))) {
stack;
return 0;
@@ -470,7 +484,8 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
struct list *lvh, *sh;
struct lv_list *ll;
struct lvd_list *lvdl;
int lv_num, len;
size_t len;
uint32_t lv_num;
struct hash_table *lvd_hash;
if (!_check_vg_name(vg->name)) {

View File

@@ -216,19 +216,21 @@ static int _read_linear(struct pool *mem, struct lv_map *lvm)
seg->type = SEG_STRIPED;
seg->le = le;
seg->len = 0;
seg->area_len = 0;
seg->stripe_size = 0;
seg->stripes = 1;
seg->area_count = 1;
seg->area[0].pv = lvm->map[le].pv;
seg->area[0].pe = lvm->map[le].pe;
seg->area[0].type = AREA_PV;
seg->area[0].u.pv.pv = lvm->map[le].pv;
seg->area[0].u.pv.pe = lvm->map[le].pe;
do
do {
seg->len++;
while ((lvm->map[le + seg->len].pv == seg->area[0].pv) &&
(seg->area[0].pv &&
lvm->map[le + seg->len].pe == seg->area[0].pe +
seg->len));
seg->area_len++;
} while ((lvm->map[le + seg->len].pv == seg->area[0].u.pv.pv) &&
(seg->area[0].u.pv.pv &&
lvm->map[le + seg->len].pe == seg->area[0].u.pv.pe +
seg->len));
le += seg->len;
@@ -248,10 +250,11 @@ static int _check_stripe(struct lv_map *lvm, struct lv_segment *seg,
/*
* Is the next physical extent in every stripe adjacent to the last?
*/
for (st = 0; st < seg->stripes; st++)
if ((lvm->map[le + st * len].pv != seg->area[st].pv) ||
(seg->area[st].pv &&
lvm->map[le + st * len].pe != seg->area[st].pe + seg->len))
for (st = 0; st < seg->area_count; st++)
if ((lvm->map[le + st * len].pv != seg->area[st].u.pv.pv) ||
(seg->area[st].u.pv.pv &&
lvm->map[le + st * len].pe !=
seg->area[st].u.pv.pe + seg->len))
return 0;
return 1;
@@ -281,27 +284,30 @@ static int _read_stripes(struct pool *mem, struct lv_map *lvm)
seg->lv = lvm->lv;
seg->type = SEG_STRIPED;
seg->stripe_size = lvm->stripe_size;
seg->stripes = lvm->stripes;
seg->le = seg->stripes * le;
seg->area_count = lvm->stripes;
seg->le = seg->area_count * le;
seg->len = 1;
seg->area_len = 1;
/*
* Set up start positions of each stripe in this segment
*/
for (st = 0; st < seg->stripes; st++) {
seg->area[st].pv = lvm->map[le + st * len].pv;
seg->area[st].pe = lvm->map[le + st * len].pe;
for (st = 0; st < seg->area_count; st++) {
seg->area[st].u.pv.pv = lvm->map[le + st * len].pv;
seg->area[st].u.pv.pe = lvm->map[le + st * len].pe;
}
/*
* Find how many blocks are contiguous in all stripes
* and so can form part of this segment
*/
while (_check_stripe(lvm, seg, le, len))
while (_check_stripe(lvm, seg, le, len)) {
seg->len++;
seg->area_len++;
}
le += seg->len;
seg->len *= seg->stripes;
seg->len *= seg->area_count;
list_add(&lvm->lv->segments, &seg->list);
}

View File

@@ -10,13 +10,13 @@
/*
* Only works with powers of 2.
*/
static inline ulong _round_up(ulong n, ulong size)
static inline uint32_t _round_up(uint32_t n, uint32_t size)
{
size--;
return (n + size) & ~size;
}
static inline ulong _div_up(ulong n, ulong size)
static inline uint32_t _div_up(uint32_t n, uint32_t size)
{
return _round_up(n, size) / size;
}
@@ -62,7 +62,7 @@ static void _calc_simple_layout(struct pv_disk *pvd)
pvd->pe_on_disk.size = pvd->pe_total * sizeof(struct pe_disk);
}
int _check_vg_limits(struct disk_list *dl)
static int _check_vg_limits(struct disk_list *dl)
{
if (dl->vgd.lv_max > MAX_LV) {
log_error("MaxLogicalVolumes of %d exceeds format limit of %d "

View File

@@ -10,7 +10,7 @@
#include "label.h"
#include "metadata.h"
#include "xlate.h"
#include "cache.h"
#include "lvmcache.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -49,9 +49,9 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
struct label **label)
{
struct pv_disk *pvd = (struct pv_disk *) buf;
struct cache_info *info;
struct lvmcache_info *info;
if (!(info = cache_add(l, pvd->pv_uuid, dev, pvd->vg_name, NULL)))
if (!(info = lvmcache_add(l, pvd->pv_uuid, dev, pvd->vg_name, NULL)))
return 0;
*label = info->label;
@@ -100,7 +100,7 @@ struct labeller *lvm1_labeller_create(struct format_type *fmt)
}
l->ops = &_lvm1_ops;
l->private = (void *) fmt;
l->private = (const void *) fmt;
return l;
}

View File

@@ -51,23 +51,23 @@ 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,
uint32_t *index)
uint32_t *ix)
{
int len, vg_len;
char *dot, *underscore;
size_t len, vg_len;
const char *dot, *underscore;
len = strlen(filename);
if (len < 7)
return 0;
dot = (char *) (filename + len - 3);
dot = (filename + len - 3);
if (strcmp(".vg", dot))
return 0;
if (!(underscore = rindex(filename, '_')))
return 0;
if (sscanf(underscore + 1, "%u", index) != 1)
if (sscanf(underscore + 1, "%u", ix) != 1)
return 0;
vg_len = underscore - filename;
@@ -83,7 +83,7 @@ static int _split_vg(const char *filename, char *vg, size_t vg_size,
static void _insert_file(struct list *head, struct archive_file *b)
{
struct list *bh;
struct archive_file *bf;
struct archive_file *bf = NULL;
if (list_empty(head)) {
list_add(head, &b->list);
@@ -123,7 +123,7 @@ static char *_join(struct pool *mem, const char *dir, const char *name)
static struct list *_scan_archive(struct pool *mem,
const char *vg, const char *dir)
{
int i, count, index;
int i, count, ix;
char vg_name[64], *path;
struct dirent **dirent;
struct archive_file *af;
@@ -149,7 +149,7 @@ static struct list *_scan_archive(struct pool *mem,
/* check the name is the correct format */
if (!_split_vg(dirent[i]->d_name, vg_name, sizeof(vg_name),
&index))
&ix))
continue;
/* is it the vg we're interested in ? */
@@ -170,7 +170,7 @@ static struct list *_scan_archive(struct pool *mem,
goto out;
}
af->index = index;
af->index = ix;
af->path = path;
/*
@@ -231,7 +231,7 @@ int archive_vg(struct volume_group *vg,
uint32_t retain_days, uint32_t min_archive)
{
int i, fd, renamed = 0;
unsigned int index = 0;
unsigned int ix = 0;
struct archive_file *last;
FILE *fp = NULL;
char temp_file[PATH_MAX], archive_name[PATH_MAX];
@@ -268,15 +268,15 @@ int archive_vg(struct volume_group *vg,
}
if (list_empty(archives))
index = 0;
ix = 0;
else {
last = list_item(archives->p, struct archive_file);
index = last->index + 1;
ix = last->index + 1;
}
for (i = 0; i < 10; i++) {
if (lvm_snprintf(archive_name, sizeof(archive_name),
"%s/%s_%05d.vg", dir, vg->name, index) < 0) {
"%s/%s_%05d.vg", dir, vg->name, ix) < 0) {
log_error("Archive file name too long.");
return 0;
}
@@ -284,7 +284,7 @@ int archive_vg(struct volume_group *vg,
if ((renamed = lvm_rename(temp_file, archive_name)))
break;
index++;
ix++;
}
if (!renamed)

View File

@@ -173,7 +173,7 @@ static int _out_with_comment_raw(struct formatter *f, const char *comment,
*/
static int _sectors_to_units(uint64_t sectors, char *buffer, size_t s)
{
static char *_units[] = {
static const char *_units[] = {
"Kilobytes",
"Megabytes",
"Gigabytes",
@@ -288,7 +288,8 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
_outf(f, "status = %s", buffer);
if (vg->system_id && *vg->system_id)
_outf(f, "system_id = \"%s\"", vg->system_id);
if (!_out_size(f, vg->extent_size, "extent_size = %u", vg->extent_size)) {
if (!_out_size(f, (uint64_t) vg->extent_size, "extent_size = %u",
vg->extent_size)) {
stack;
return 0;
}
@@ -369,15 +370,16 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
static int _print_segment(struct formatter *f, struct volume_group *vg,
int count, struct lv_segment *seg)
{
int s;
unsigned int s;
const char *name;
const char *type;
_outf(f, "segment%u {", count);
_inc_indent(f);
_outf(f, "start_extent = %u", seg->le);
if (!_out_size(f, seg->len * vg->extent_size, "extent_count = %u",
seg->len)) {
if (!_out_size(f, (uint64_t) seg->len * vg->extent_size,
"extent_count = %u", seg->len)) {
stack;
return 0;
}
@@ -386,40 +388,55 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
_outf(f, "type = \"%s\"", get_segtype_string(seg->type));
switch (seg->type) {
case SEG_STRIPED:
_outf(f, "stripe_count = %u%s", seg->stripes,
(seg->stripes == 1) ? "\t# linear" : "");
if (seg->stripes > 1)
_out_size(f, seg->stripe_size,
"stripe_size = %u", seg->stripe_size);
f->nl(f);
_outf(f, "stripes = [");
_inc_indent(f);
for (s = 0; s < seg->stripes; s++) {
if (!(name = _get_pv_name(f, seg->area[s].pv))) {
stack;
return 0;
}
_outf(f, "\"%s\", %u%s", name, seg->area[s].pe,
(s == seg->stripes - 1) ? "" : ",");
}
_dec_indent(f);
_outf(f, "]");
break;
case SEG_SNAPSHOT:
_outf(f, "chunk_size = %u", seg->chunk_size);
_outf(f, "origin = \"%s\"", seg->origin->name);
_outf(f, "cow_store = \"%s\"", seg->cow->name);
break;
case SEG_MIRROR:
/* mirrors = [ "lvol1", 10, ... ] */
;
case SEG_MIRRORED:
case SEG_STRIPED:
type = (seg->type == SEG_MIRRORED) ? "mirror" : "stripe";
_outf(f, "%s_count = %u%s", type, seg->area_count,
(seg->area_count == 1) ? "\t# linear" : "");
if ((seg->type == SEG_MIRRORED) && (seg->status & PVMOVE))
_out_size(f, (uint64_t) seg->extents_moved,
"extents_moved = %u", seg->extents_moved);
if ((seg->type == SEG_STRIPED) && (seg->area_count > 1))
_out_size(f, (uint64_t) seg->stripe_size,
"stripe_size = %u", seg->stripe_size);
f->nl(f);
_outf(f, "%ss = [", type);
_inc_indent(f);
for (s = 0; s < seg->area_count; s++) {
switch (seg->area[s].type) {
case AREA_PV:
if (!(name = _get_pv_name(f, seg->
area[s].u.pv.pv))) {
stack;
return 0;
}
_outf(f, "\"%s\", %u%s", name,
seg->area[s].u.pv.pe,
(s == seg->area_count - 1) ? "" : ",");
break;
case AREA_LV:
_outf(f, "\"%s\", %u%s",
seg->area[s].u.lv.lv->name,
seg->area[s].u.lv.le,
(s == seg->area_count - 1) ? "" : ",");
}
}
_dec_indent(f);
_outf(f, "]");
break;
}
_dec_indent(f);
@@ -546,6 +563,8 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
get_alloc_string(lv->alloc));
if (lv->read_ahead)
_outf(f, "read_ahead = %u", lv->read_ahead);
if (lv->major >= 0)
_outf(f, "major = %d", lv->major);
if (lv->minor >= 0)
_outf(f, "minor = %d", lv->minor);
_outf(f, "segment_count = %u", _count_segments(lv));
@@ -601,6 +620,7 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
list_iterate(pvh, &vg->pvs) {
pv = list_item(pvh, struct pv_list)->pv;
/* FIXME But skip if there's already an LV called pv%d ! */
if (lvm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0) {
stack;
goto bad;

View File

@@ -14,14 +14,15 @@
* converted into arrays of strings.
*/
struct flag {
int mask;
char *description;
const int mask;
const char *description;
};
static struct flag _vg_flags[] = {
{EXPORTED_VG, "EXPORTED"},
{RESIZEABLE_VG, "RESIZEABLE"},
{PARTIAL_VG, "PARTIAL"},
{PVMOVE, "PVMOVE"},
{LVM_READ, "READ"},
{LVM_WRITE, "WRITE"},
{CLUSTERED, "CLUSTERED"},
@@ -40,6 +41,8 @@ static struct flag _lv_flags[] = {
{LVM_WRITE, "WRITE"},
{FIXED_MINOR, "FIXED_MINOR"},
{VISIBLE_LV, "VISIBLE"},
{PVMOVE, "PVMOVE"},
{LOCKED, "LOCKED"},
{0, NULL}
};
@@ -62,7 +65,7 @@ static struct flag *_get_flags(int type)
static int _emit(char **buffer, size_t *size, const char *fmt, ...)
{
size_t n;
int n;
va_list ap;
va_start(ap, fmt);

View File

@@ -20,6 +20,7 @@
#include "crc.h"
#include "xlate.h"
#include "label.h"
#include "memlock.h"
#include <unistd.h>
#include <sys/file.h>
@@ -27,8 +28,8 @@
#include <dirent.h>
#include <ctype.h>
static struct format_instance *_create_text_instance(struct format_type *fmt,
const char *vgname,
static struct format_instance *_create_text_instance(const struct format_type
*fmt, const char *vgname,
void *context);
struct dir_list {
@@ -48,9 +49,7 @@ struct text_context {
};
/*
* NOTE: Currently there can be only one vg per text file, and locking
* assumes VG's metadata is only held in metadata areas on PVs
* inside the VG.
* NOTE: Currently there can be only one vg per text file.
*/
static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
@@ -99,7 +98,7 @@ static void _xlate_mdah(struct mda_header *mdah)
}
}
static struct mda_header *_raw_read_mda_header(struct format_type *fmt,
static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
struct device_area *dev_area)
{
struct mda_header *mdah;
@@ -109,8 +108,7 @@ static struct mda_header *_raw_read_mda_header(struct format_type *fmt,
return NULL;
}
if (dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah) !=
MDA_HEADER_SIZE) {
if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah)) {
stack;
pool_free(fmt->cmd->mem, mdah);
return NULL;
@@ -145,7 +143,7 @@ static struct mda_header *_raw_read_mda_header(struct format_type *fmt,
return mdah;
}
static int _raw_write_mda_header(struct format_type *fmt,
static int _raw_write_mda_header(const struct format_type *fmt,
struct device *dev,
uint64_t start_byte, struct mda_header *mdah)
{
@@ -158,8 +156,7 @@ static int _raw_write_mda_header(struct format_type *fmt,
MDA_HEADER_SIZE -
sizeof(mdah->checksum_xl)));
if (dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)
!= MDA_HEADER_SIZE) {
if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) {
stack;
pool_free(fmt->cmd->mem, mdah);
return 0;
@@ -172,7 +169,7 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
struct mda_header *mdah,
const char *vgname)
{
int len;
size_t len;
char vgnamebuf[NAME_LEN + 2];
struct raw_locn *rlocn;
@@ -180,9 +177,8 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
/* FIXME Ignore if checksum incorrect!!! */
while (rlocn->offset) {
if (dev_read(dev_area->dev, dev_area->start + rlocn->offset,
sizeof(vgnamebuf), vgnamebuf)
!= sizeof(vgnamebuf)) {
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
sizeof(vgnamebuf), vgnamebuf)) {
stack;
return NULL;
}
@@ -216,7 +212,7 @@ static int _raw_holds_vgname(struct format_instance *fid,
{
int r = 0;
if (!dev_open(dev_area->dev, O_RDONLY)) {
if (!dev_open(dev_area->dev)) {
stack;
return 0;
}
@@ -239,9 +235,9 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
struct mda_header *mdah;
time_t when;
char *desc;
uint64_t wrap = 0;
uint32_t wrap = 0;
if (!dev_open(area->dev, O_RDONLY)) {
if (!dev_open(area->dev)) {
stack;
return NULL;
}
@@ -257,7 +253,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
}
if (rlocn->offset + rlocn->size > mdah->size)
wrap = (rlocn->offset + rlocn->size) - mdah->size;
wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
if (wrap > rlocn->offset) {
log_error("VG %s metadata too large for circular buffer",
@@ -265,16 +261,19 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
goto out;
}
if (!(vg = text_vg_import_fd(fid, dev_name(area->dev),
dev_fd(area->dev),
area->start + rlocn->offset,
rlocn->size - wrap,
area->start + MDA_HEADER_SIZE, wrap,
calc_crc, rlocn->checksum, &when,
/* FIXME 64-bit */
if (!(vg = text_vg_import_fd(fid, NULL, area->dev,
(off_t) (area->start + rlocn->offset),
(uint32_t) (rlocn->size - wrap),
(off_t) (area->start + MDA_HEADER_SIZE),
wrap, calc_crc, rlocn->checksum, &when,
&desc))) {
stack;
goto out;
}
log_debug("Read %s metadata (%u) from %s at %" PRIu64 " size %" PRIu64,
vg->name, vg->seqno, dev_name(area->dev),
area->start + rlocn->offset, rlocn->size);
out:
if (!dev_close(area->dev))
@@ -301,7 +300,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
struct physical_volume *pv;
struct list *pvh;
int r = 0;
uint64_t new_wrap = 0, old_wrap = 0;
uint32_t new_wrap = 0, old_wrap = 0;
/* FIXME Essential fix! Make dynamic (realloc? pool?) */
char buf[65536];
@@ -319,7 +318,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
if (!found)
return 1;
if (!dev_open(mdac->area.dev, O_RDWR)) {
if (!dev_open(mdac->area.dev)) {
stack;
return 0;
}
@@ -368,29 +367,29 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
mdac->rlocn.offset, mdac->rlocn.size - new_wrap);
/* Write text out, circularly */
if (dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
mdac->rlocn.size - new_wrap,
buf) != mdac->rlocn.size - new_wrap) {
if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
(size_t) (mdac->rlocn.size - new_wrap), buf)) {
stack;
goto out;
}
if (new_wrap) {
log_debug("Writing metadata to %s at %" PRIu64 " len %" PRIu64,
log_debug("Writing metadata to %s at %" PRIu64 " len %" PRIu32,
dev_name(mdac->area.dev), mdac->area.start +
MDA_HEADER_SIZE, new_wrap);
if (dev_write(mdac->area.dev,
mdac->area.start + MDA_HEADER_SIZE,
new_wrap, buf + mdac->rlocn.size - new_wrap)
!= new_wrap) {
if (!dev_write(mdac->area.dev,
mdac->area.start + MDA_HEADER_SIZE,
(size_t) new_wrap,
buf + mdac->rlocn.size - new_wrap)) {
stack;
goto out;
}
}
mdac->rlocn.checksum = calc_crc(INITIAL_CRC, buf,
mdac->rlocn.size - new_wrap);
(uint32_t) (mdac->rlocn.size -
new_wrap));
if (new_wrap)
mdac->rlocn.checksum = calc_crc(mdac->rlocn.checksum,
buf + mdac->rlocn.size -
@@ -399,7 +398,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
r = 1;
out:
if (!dev_close(mdac->area.dev))
if (!r && !dev_close(mdac->area.dev))
stack;
return r;
@@ -428,11 +427,6 @@ static int _vg_commit_raw(struct format_instance *fid, struct volume_group *vg,
if (!found)
return 1;
if (!dev_open(mdac->area.dev, O_RDWR)) {
stack;
return 0;
}
if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) {
stack;
goto out;
@@ -465,6 +459,33 @@ static int _vg_commit_raw(struct format_instance *fid, struct volume_group *vg,
return r;
}
/* Close metadata area devices */
static int _vg_revert_raw(struct format_instance *fid, struct volume_group *vg,
struct metadata_area *mda)
{
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct physical_volume *pv;
struct list *pvh;
int found = 0;
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
list_iterate(pvh, &vg->pvs) {
pv = list_item(pvh, struct pv_list)->pv;
if (pv->dev == mdac->area.dev) {
found = 1;
break;
}
}
if (!found)
return 1;
if (!dev_close(mdac->area.dev))
stack;
return 1;
}
static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
struct metadata_area *mda)
{
@@ -473,7 +494,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
struct raw_locn *rlocn;
int r = 0;
if (!dev_open(mdac->area.dev, O_RDWR)) {
if (!dev_open(mdac->area.dev)) {
stack;
return 0;
}
@@ -560,7 +581,8 @@ static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
if (slash == 0)
strcpy(temp_dir, ".");
else if (slash - tc->path_edit < PATH_MAX) {
strncpy(temp_dir, tc->path_edit, slash - tc->path_edit);
strncpy(temp_dir, tc->path_edit,
(size_t) (slash - tc->path_edit));
temp_dir[slash - tc->path_edit] = '\0';
} else {
@@ -643,7 +665,7 @@ static int _vg_commit_file(struct format_instance *fid, struct volume_group *vg,
struct text_context *tc = (struct text_context *) mda->metadata_locn;
char *slash;
char newname[PATH_MAX];
int len;
size_t len;
if (!_vg_commit_file_backup(fid, vg, mda))
return 0;
@@ -695,7 +717,7 @@ static int _vg_remove_file(struct format_instance *fid, struct volume_group *vg,
return 1;
}
static int _scan_file(struct format_type *fmt)
static int _scan_file(const struct format_type *fmt)
{
struct dirent *dirent;
struct dir_list *dl;
@@ -733,7 +755,7 @@ static int _scan_file(struct format_type *fmt)
fid = _create_text_instance(fmt, NULL, NULL);
if ((vg = _vg_read_file_name(fid, vgname,
path)))
cache_update_vg(vg);
lvmcache_update_vg(vg);
}
if (closedir(d))
@@ -743,18 +765,15 @@ static int _scan_file(struct format_type *fmt)
return 1;
}
int vgname_from_mda(struct format_type *fmt, struct device_area *dev_area,
int vgname_from_mda(const struct format_type *fmt, struct device_area *dev_area,
char *buf, uint32_t size)
{
struct raw_locn *rlocn;
struct mda_header *mdah;
int already_open;
int len;
unsigned int len;
int r = 0;
already_open = dev_is_open(dev_area->dev);
if (!already_open && !dev_open(dev_area->dev, O_RDONLY)) {
if (!dev_open(dev_area->dev)) {
stack;
return 0;
}
@@ -767,19 +786,19 @@ int vgname_from_mda(struct format_type *fmt, struct device_area *dev_area,
rlocn = mdah->raw_locns;
while (rlocn->offset) {
if (dev_read(dev_area->dev, dev_area->start + rlocn->offset,
size, buf) != size) {
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
size, buf)) {
stack;
goto out;
}
len = 0;
while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
len < size - 1)
len < (size - 1))
len++;
buf[len] = '\0';
/* Ignore this entry if the characters aren't permissible */
if (!validate_vgname(buf)) {
if (!validate_name(buf)) {
stack;
goto out;
}
@@ -792,13 +811,13 @@ int vgname_from_mda(struct format_type *fmt, struct device_area *dev_area,
}
out:
if (!already_open && dev_close(dev_area->dev))
if (!dev_close(dev_area->dev))
stack;
return r;
}
static int _scan_raw(struct format_type *fmt)
static int _scan_raw(const struct format_type *fmt)
{
struct raw_list *rl;
struct list *rlh, *raw_list;
@@ -819,21 +838,21 @@ static int _scan_raw(struct format_type *fmt)
sizeof(vgnamebuf))) {
if ((vg = _vg_read_raw_area(&fid, vgnamebuf,
&rl->dev_area)))
cache_update_vg(vg);
lvmcache_update_vg(vg);
}
}
return 1;
}
static int _scan(struct format_type *fmt)
static int _scan(const struct format_type *fmt)
{
return (_scan_file(fmt) & _scan_raw(fmt));
}
/* For orphan, creates new mdas according to policy.
Always have an mda between end-of-label and PE_ALIGN boundary */
static int _mda_setup(struct format_type *fmt,
static int _mda_setup(const struct format_type *fmt,
uint64_t pe_start, uint64_t pe_end,
int pvmetadatacopies,
uint64_t pvmetadatasize, struct list *mdas,
@@ -889,8 +908,9 @@ static int _mda_setup(struct format_type *fmt,
mda_size1))
return 0;
if (!dev_zero(pv->dev, start1,
mda_size1 > wipe_size ? wipe_size : mda_size1)) {
if (!dev_zero((struct device *) pv->dev, start1,
(size_t) (mda_size1 >
wipe_size ? wipe_size : mda_size1))) {
log_error("Failed to wipe new metadata area");
return 0;
}
@@ -936,7 +956,8 @@ static int _mda_setup(struct format_type *fmt,
mda_size2))
return 0;
if (!dev_zero(pv->dev, start2,
mda_size1 > wipe_size ? wipe_size : mda_size1)) {
(size_t) (mda_size1 >
wipe_size ? wipe_size : mda_size1))) {
log_error("Failed to wipe new metadata area");
return 0;
}
@@ -949,11 +970,11 @@ static int _mda_setup(struct format_type *fmt,
/* Only for orphans */
/* Set label_sector to -1 if rewriting existing label into same sector */
static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
struct list *mdas, int64_t label_sector)
{
struct label *label;
struct cache_info *info;
struct lvmcache_info *info;
struct mda_context *mdac;
struct list *mdash;
struct metadata_area *mda;
@@ -961,8 +982,10 @@ static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
struct mda_header *mdah = (struct mda_header *) buf;
uint64_t adjustment;
if (!(info = cache_add(fmt->labeller, (char *) &pv->id, pv->dev,
ORPHAN, NULL))) {
/* FIXME Test mode don't update cache? */
if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
ORPHAN, NULL))) {
stack;
return 0;
}
@@ -1019,12 +1042,14 @@ static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
pv->pe_start += (PE_ALIGN - adjustment);
}
}
if (!add_da(fmt, NULL, &info->das, pv->pe_start << SECTOR_SHIFT, 0)) {
if (!add_da
(fmt, NULL, &info->das, pv->pe_start << SECTOR_SHIFT,
UINT64_C(0))) {
stack;
return 0;
}
if (!dev_open(pv->dev, O_RDWR)) {
if (!dev_open(pv->dev)) {
stack;
return 0;
}
@@ -1053,7 +1078,7 @@ static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
return 1;
}
static int _get_pv_from_vg(struct format_type *fmt, const char *vg_name,
static int _get_pv_from_vg(const struct format_type *fmt, const char *vg_name,
const char *id, struct physical_volume *pv)
{
struct volume_group *vg;
@@ -1073,7 +1098,7 @@ static int _get_pv_from_vg(struct format_type *fmt, const char *vg_name,
list_iterate(pvh, &vg->pvs) {
pvl = list_item(pvh, struct pv_list);
if (id_equal(&pvl->pv->id, (struct id *) id)) {
if (id_equal(&pvl->pv->id, (const struct id *) id)) {
memcpy(pv, pvl->pv, sizeof(*pv));
return 1;
}
@@ -1105,12 +1130,12 @@ static int _add_raw(struct list *raw_list, struct device_area *dev_area)
return 1;
}
static int _pv_read(struct format_type *fmt, const char *pv_name,
static int _pv_read(const struct format_type *fmt, const char *pv_name,
struct physical_volume *pv, struct list *mdas)
{
struct label *label;
struct device *dev;
struct cache_info *info;
struct lvmcache_info *info;
struct metadata_area *mda, *mda_new;
struct mda_context *mdac, *mdac_new;
struct list *mdah, *dah;
@@ -1121,11 +1146,12 @@ static int _pv_read(struct format_type *fmt, const char *pv_name,
return 0;
}
/* FIXME Optimise out repeated reading when cache lock held */
if (!(label_read(dev, &label))) {
stack;
return 0;
}
info = (struct cache_info *) label->info;
info = (struct lvmcache_info *) label->info;
/* Have we already cached vgname? */
if (info->vginfo && info->vginfo->vgname && *info->vginfo->vgname &&
@@ -1135,12 +1161,15 @@ static int _pv_read(struct format_type *fmt, const char *pv_name,
}
/* Perform full scan and try again */
cache_label_scan(fmt->cmd, 0);
if (!memlock()) {
lvmcache_label_scan(fmt->cmd, 1);
if (info->vginfo && info->vginfo->vgname && *info->vginfo->vgname &&
_get_pv_from_vg(info->fmt, info->vginfo->vgname, info->dev->pvid,
pv)) {
return 1;
if (info->vginfo && info->vginfo->vgname &&
*info->vginfo->vgname &&
_get_pv_from_vg(info->fmt, info->vginfo->vgname,
info->dev->pvid, pv)) {
return 1;
}
}
/* Orphan */
@@ -1210,7 +1239,7 @@ static void _free_raws(struct list *raw_list)
}
}
static void _destroy(struct format_type *fmt)
static void _destroy(const struct format_type *fmt)
{
if (fmt->private) {
_free_dirs(&((struct mda_lists *) fmt->private)->dirs);
@@ -1218,7 +1247,7 @@ static void _destroy(struct format_type *fmt)
dbg_free(fmt->private);
}
dbg_free(fmt);
dbg_free((void *) fmt);
}
static struct metadata_area_ops _metadata_text_file_ops = {
@@ -1239,11 +1268,12 @@ static struct metadata_area_ops _metadata_text_raw_ops = {
vg_read:_vg_read_raw,
vg_write:_vg_write_raw,
vg_remove:_vg_remove_raw,
vg_commit:_vg_commit_raw
vg_commit:_vg_commit_raw,
vg_revert:_vg_revert_raw
};
/* pvmetadatasize in sectors */
static int _pv_setup(struct format_type *fmt,
static int _pv_setup(const struct format_type *fmt,
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size,
int pvmetadatacopies,
@@ -1253,7 +1283,7 @@ static int _pv_setup(struct format_type *fmt,
struct metadata_area *mda, *mda_new, *mda2;
struct mda_context *mdac, *mdac_new, *mdac2;
struct list *pvmdas, *pvmdash, *mdash;
struct cache_info *info;
struct lvmcache_info *info;
int found;
uint64_t pe_end = 0;
@@ -1334,8 +1364,8 @@ static int _pv_setup(struct format_type *fmt,
}
/* NULL vgname means use only the supplied context e.g. an archive file */
static struct format_instance *_create_text_instance(struct format_type *fmt,
const char *vgname,
static struct format_instance *_create_text_instance(const struct format_type
*fmt, const char *vgname,
void *context)
{
struct format_instance *fid;
@@ -1345,7 +1375,7 @@ static struct format_instance *_create_text_instance(struct format_type *fmt,
struct raw_list *rl;
struct list *dlh, *dir_list, *rlh, *raw_list, *mdas, *mdash, *infoh;
char path[PATH_MAX];
struct cache_vginfo *vginfo;
struct lvmcache_vginfo *vginfo;
if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
log_error("Couldn't allocate format instance object.");
@@ -1408,17 +1438,18 @@ static struct format_instance *_create_text_instance(struct format_type *fmt,
/* FIXME Allow multiple dev_areas inside area */
memcpy(&mdac->area, &rl->dev_area, sizeof(mdac->area));
mda->ops = &_metadata_text_raw_ops;
/* FIXME MISTAKE? mda->metadata_locn = context; */
list_add(&fid->metadata_areas, &mda->list);
}
/* Scan PVs in VG for any further MDAs */
cache_label_scan(fmt->cmd, 0);
lvmcache_label_scan(fmt->cmd, 0);
if (!(vginfo = vginfo_from_vgname(vgname))) {
stack;
goto out;
}
list_iterate(infoh, &vginfo->infos) {
mdas = &(list_item(infoh, struct cache_info)->mdas);
mdas = &(list_item(infoh, struct lvmcache_info)->mdas);
list_iterate(mdash, mdas) {
mda = list_item(mdash, struct metadata_area);
mdac =

View File

@@ -36,19 +36,19 @@ struct format_type *create_text_format(struct cmd_context *cmd);
void *create_text_context(struct cmd_context *cmd, const char *path,
const char *desc);
struct labeller *text_labeller_create(struct format_type *fmt);
struct labeller *text_labeller_create(const struct format_type *fmt);
int pvhdr_read(struct device *dev, char *buf);
int add_da(struct format_type *fmt, struct pool *mem, struct list *das,
int add_da(const struct format_type *fmt, struct pool *mem, struct list *das,
uint64_t start, uint64_t size);
void del_das(struct list *das);
int add_mda(struct format_type *fmt, struct pool *mem, struct list *mdas,
int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
struct device *dev, uint64_t start, uint64_t size);
void del_mdas(struct list *mdas);
int vgname_from_mda(struct format_type *fmt, struct device_area *dev_area,
int vgname_from_mda(const struct format_type *fmt, struct device_area *dev_area,
char *buf, uint32_t size);
#endif

View File

@@ -54,7 +54,7 @@ struct volume_group *text_vg_import_file(struct format_instance *fid,
time_t *when, char **desc);
struct volume_group *text_vg_import_fd(struct format_instance *fid,
const char *file,
int fd,
struct device *dev,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn,

View File

@@ -11,14 +11,14 @@
#include "display.h"
#include "hash.h"
#include "toolcontext.h"
#include "cache.h"
#include "lvmcache.h"
/* FIXME Use tidier inclusion method */
static struct text_vg_version_ops *(_text_vsn_list[2]);
struct volume_group *text_vg_import_fd(struct format_instance *fid,
const char *file,
int fd,
struct device *dev,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn,
@@ -45,10 +45,9 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
goto out;
}
if ((fd == -1 && !read_config_file(cf, file)) ||
(fd != -1 && !read_config_fd(cf, fd, file, offset, size,
offset2, size2, checksum_fn,
checksum))) {
if ((!dev && !read_config_file(cf, file)) ||
(dev && !read_config_fd(cf, dev, offset, size,
offset2, size2, checksum_fn, checksum))) {
log_error("Couldn't read volume group metadata.");
goto out;
}
@@ -78,6 +77,6 @@ struct volume_group *text_vg_import_file(struct format_instance *fid,
const char *file,
time_t *when, char **desc)
{
return text_vg_import_fd(fid, file, -1, 0, 0, 0, 0, NULL, 0,
return text_vg_import_fd(fid, file, NULL, 0, 0, 0, 0, NULL, 0,
when, desc);
}

View File

@@ -11,7 +11,7 @@
#include "display.h"
#include "hash.h"
#include "toolcontext.h"
#include "cache.h"
#include "lvmcache.h"
typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
struct volume_group * vg, struct config_node * pvn,
@@ -214,16 +214,16 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
struct logical_volume *lv, struct config_node *sn,
struct hash_table *pv_hash)
{
int s;
uint32_t stripes = 0;
unsigned int s;
uint32_t area_count = 0;
struct lv_segment *seg;
struct config_node *cn;
struct config_value *cv;
const char *seg_name = sn->key;
uint32_t start_extent, extent_count;
uint32_t chunk_size;
uint32_t chunk_size, extents_moved = 0u, seg_status = 0u;
const char *org_name, *cow_name;
struct logical_volume *org, *cow;
struct logical_volume *org, *cow, *lv1;
segment_type_t segtype;
if (!(sn = sn->child)) {
@@ -254,15 +254,33 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
}
if (segtype == SEG_STRIPED) {
if (!_read_int32(sn, "stripe_count", &stripes)) {
if (!_read_int32(sn, "stripe_count", &area_count)) {
log_error("Couldn't read 'stripe_count' for "
"segment '%s'.", sn->key);
return 0;
}
}
if (segtype == SEG_MIRRORED) {
if (!_read_int32(sn, "mirror_count", &area_count)) {
log_error("Couldn't read 'mirror_count' for "
"segment '%s'.", sn->key);
return 0;
}
if (find_config_node(sn, "extents_moved", '/')) {
if (_read_uint32(sn, "extents_moved", &extents_moved))
seg_status |= PVMOVE;
else {
log_error("Couldn't read 'extents_moved' for "
"segment '%s'.", sn->key);
return 0;
}
}
}
if (!(seg = pool_zalloc(mem, sizeof(*seg) +
(sizeof(seg->area[0]) * stripes)))) {
(sizeof(seg->area[0]) * area_count)))) {
stack;
return 0;
}
@@ -270,9 +288,12 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
seg->lv = lv;
seg->le = start_extent;
seg->len = extent_count;
seg->area_len = extent_count;
seg->type = segtype;
seg->status = seg_status;
seg->extents_moved = extents_moved;
switch (segtype) {
case SEG_MIRROR:
case SEG_SNAPSHOT:
lv->status |= SNAPSHOT;
@@ -316,15 +337,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
break;
case SEG_STRIPED:
seg->stripes = stripes;
if (!seg->stripes) {
log_error("Zero stripes *not* allowed for segment '%s'",
sn->key);
return 0;
}
if ((seg->stripes != 1) &&
if ((area_count != 1) &&
!_read_int32(sn, "stripe_size", &seg->stripe_size)) {
log_error("Couldn't read stripe_size for segment '%s'.",
sn->key);
@@ -337,55 +350,78 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
return 0;
}
for (cv = cn->v, s = 0; cv && s < seg->stripes;
seg->area_len /= area_count;
case SEG_MIRRORED:
seg->area_count = area_count;
if (!seg->area_count) {
log_error("Zero areas not allowed for segment '%s'",
sn->key);
return 0;
}
if ((seg->type == SEG_MIRRORED) &&
!(cn = find_config_node(sn, "mirrors", '/'))) {
log_error("Couldn't find mirrors array for segment "
"'%s'.", sn->key);
return 0;
}
for (cv = cn->v, s = 0; cv && s < seg->area_count;
s++, cv = cv->next) {
/* first we read the pv */
const char *bad = "Badly formed areas array for "
"segment '%s'.";
struct physical_volume *pv;
uint32_t allocated;
if (cv->type != CFG_STRING) {
log_error(bad, sn->key);
return 0;
}
if (!(pv = hash_lookup(pv_hash, cv->v.str))) {
log_error("Couldn't find physical volume '%s' "
if (!cv->next) {
log_error(bad, sn->key);
return 0;
}
if (cv->next->type != CFG_INT) {
log_error(bad, sn->key);
return 0;
}
/* FIXME Cope if LV not yet read in */
if ((pv = hash_lookup(pv_hash, cv->v.str))) {
seg->area[s].type = AREA_PV;
seg->area[s].u.pv.pv = pv;
seg->area[s].u.pv.pe = cv->next->v.i;
/*
* Adjust extent counts in the pv and vg.
*/
pv->pe_alloc_count += seg->area_len;
vg->free_count -= seg->area_len;
} else if ((lv1 = find_lv(vg, cv->v.str))) {
seg->area[s].type = AREA_LV;
seg->area[s].u.lv.lv = lv1;
seg->area[s].u.lv.le = cv->next->v.i;
} else {
log_error("Couldn't find volume '%s' "
"for segment '%s'.",
cv->v.str ? cv->v.str : "NULL",
seg_name);
return 0;
}
seg->area[s].pv = pv;
if (!(cv = cv->next)) {
log_error(bad, sn->key);
return 0;
}
if (cv->type != CFG_INT) {
log_error(bad, sn->key);
return 0;
}
seg->area[s].pe = cv->v.i;
/*
* Adjust the extent counts in the pv and vg.
*/
allocated = seg->len / seg->stripes;
pv->pe_alloc_count += allocated;
vg->free_count -= allocated;
cv = cv->next;
}
/*
* Check we read the correct number of stripes.
*/
if (cv || (s < seg->stripes)) {
log_error("Incorrect number of stripes in 'area' array "
if (cv || (s < seg->area_count)) {
log_error("Incorrect number of areas in area array "
"for segment '%s'.", seg_name);
return 0;
}
@@ -456,9 +492,9 @@ static int _read_segments(struct pool *mem, struct volume_group *vg,
return 1;
}
static int _read_lv(struct format_instance *fid, struct pool *mem,
struct volume_group *vg, struct config_node *lvn,
struct config_node *vgn, struct hash_table *pv_hash)
static int _read_lvnames(struct format_instance *fid, struct pool *mem,
struct volume_group *vg, struct config_node *lvn,
struct config_node *vgn, struct hash_table *pv_hash)
{
struct logical_volume *lv;
struct lv_list *lvl;
@@ -482,17 +518,6 @@ static int _read_lv(struct format_instance *fid, struct pool *mem,
return 0;
}
lv->vg = vg;
/* FIXME: read full lvid */
if (!_read_id(&lv->lvid.id[1], lvn, "id")) {
log_error("Couldn't read uuid for logical volume %s.",
lv->name);
return 0;
}
memcpy(&lv->lvid.id[0], &lv->vg->id, sizeof(lv->lvid.id[0]));
if (!(cn = find_config_node(lvn, "status", '/'))) {
log_error("Couldn't find status flags for logical volume.");
return 0;
@@ -503,12 +528,6 @@ static int _read_lv(struct format_instance *fid, struct pool *mem,
return 0;
}
list_init(&lv->segments);
if (!_read_segments(mem, vg, lv, lvn, pv_hash)) {
stack;
return 0;
}
lv->alloc = ALLOC_DEFAULT;
if ((cn = find_config_node(lvn, "allocation_policy", '/'))) {
struct config_value *cv = cn->v;
@@ -524,6 +543,48 @@ static int _read_lv(struct format_instance *fid, struct pool *mem,
if (!_read_int32(lvn, "read_ahead", &lv->read_ahead))
lv->read_ahead = 0;
list_init(&lv->segments);
lv->vg = vg;
vg->lv_count++;
list_add(&vg->lvs, &lvl->list);
return 1;
}
static int _read_lvsegs(struct format_instance *fid, struct pool *mem,
struct volume_group *vg, struct config_node *lvn,
struct config_node *vgn, struct hash_table *pv_hash)
{
struct logical_volume *lv;
struct lv_list *lvl;
if (!(lvl = find_lv_in_vg(vg, lvn->key))) {
log_error("Lost logical volume reference %s", lvn->key);
return 0;
}
lv = lvl->lv;
if (!(lvn = lvn->child)) {
log_error("Empty logical volume section.");
return 0;
}
/* FIXME: read full lvid */
if (!_read_id(&lv->lvid.id[1], lvn, "id")) {
log_error("Couldn't read uuid for logical volume %s.",
lv->name);
return 0;
}
memcpy(&lv->lvid.id[0], &lv->vg->id, sizeof(lv->lvid.id[0]));
if (!_read_segments(mem, vg, lv, lvn, pv_hash)) {
stack;
return 0;
}
lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size;
/* Skip this for now for snapshots */
@@ -532,12 +593,18 @@ static int _read_lv(struct format_instance *fid, struct pool *mem,
if ((lv->status & FIXED_MINOR) &&
!_read_int32(lvn, "minor", &lv->minor)) {
log_error("Couldn't read minor number for logical "
"volume.");
"volume %s.", lv->name);
return 0;
}
vg->lv_count++;
list_add(&vg->lvs, &lvl->list);
lv->major = -1;
if ((lv->status & FIXED_MINOR) &&
!_read_int32(lvn, "major", &lv->major)) {
log_error("Couldn't read major number for logical "
"volume %s.", lv->name);
}
} else {
vg->lv_count--;
list_del(&lvl->list);
}
return 1;
@@ -681,13 +748,21 @@ static struct volume_group *_read_vg(struct format_instance *fid,
list_init(&vg->lvs);
list_init(&vg->snapshots);
if (!_read_sections(fid, "logical_volumes", _read_lv, mem, vg,
if (!_read_sections(fid, "logical_volumes", _read_lvnames, mem, vg,
vgn, pv_hash, 1)) {
log_error("Couldn't read all logical volumes for volume "
log_error("Couldn't read all logical volume names for volume "
"group %s.", vg->name);
goto bad;
}
if (!_read_sections(fid, "logical_volumes", _read_lvsegs, mem, vg,
vgn, pv_hash, 1)) {
log_error("Couldn't read all logical volumes for "
"volume group %s.", vg->name);
goto bad;
}
hash_destroy(pv_hash);
if (vg->status & PARTIAL_VG) {

View File

@@ -27,7 +27,7 @@ static int _write(struct label *label, char *buf)
{
struct label_header *lh = (struct label_header *) buf;
struct pv_header *pvhdr;
struct cache_info *info;
struct lvmcache_info *info;
struct disk_locn *pvh_dlocn_xl;
struct list *mdash, *dash;
struct metadata_area *mda;
@@ -40,7 +40,7 @@ static int _write(struct label *label, char *buf)
strncpy(lh->type, label->type, sizeof(label->type));
pvhdr = (struct pv_header *) ((void *) buf + xlate32(lh->offset_xl));
info = (struct cache_info *) label->info;
info = (struct lvmcache_info *) label->info;
pvhdr->device_size_xl = xlate64(info->device_size);
memcpy(pvhdr->pv_uuid, &info->dev->pvid, sizeof(struct id));
@@ -80,7 +80,7 @@ static int _write(struct label *label, char *buf)
return 1;
}
int add_da(struct format_type *fmt, struct pool *mem, struct list *das,
int add_da(const struct format_type *fmt, struct pool *mem, struct list *das,
uint64_t start, uint64_t size)
{
struct data_area_list *dal;
@@ -117,7 +117,7 @@ void del_das(struct list *das)
}
}
int add_mda(struct format_type *fmt, struct pool *mem, struct list *mdas,
int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
struct device *dev, uint64_t start, uint64_t size)
{
/* FIXME List size restricted by pv_header SECTOR_SIZE */
@@ -185,7 +185,7 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
{
struct label_header *lh = (struct label_header *) buf;
struct pv_header *pvhdr;
struct cache_info *info;
struct lvmcache_info *info;
struct disk_locn *dlocn_xl;
uint64_t offset;
struct list *mdah;
@@ -195,7 +195,7 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
pvhdr = (struct pv_header *) ((void *) buf + xlate32(lh->offset_xl));
if (!(info = cache_add(l, pvhdr->pv_uuid, dev, NULL, NULL)))
if (!(info = lvmcache_add(l, pvhdr->pv_uuid, dev, NULL, NULL)))
return 0;
*label = info->label;
@@ -230,7 +230,7 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
mdac = (struct mda_context *) mda->metadata_locn;
if (vgname_from_mda(info->fmt, &mdac->area, vgnamebuf,
sizeof(vgnamebuf))) {
cache_update_vgname(info, vgnamebuf);
lvmcache_update_vgname(info, vgnamebuf);
}
}
@@ -241,7 +241,7 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
static void _destroy_label(struct labeller *l, struct label *label)
{
struct cache_info *info = (struct cache_info *) label->info;
struct lvmcache_info *info = (struct lvmcache_info *) label->info;
if (info->mdas.n)
del_mdas(&info->mdas);
@@ -264,7 +264,7 @@ struct label_ops _text_ops = {
destroy:_destroy
};
struct labeller *text_labeller_create(struct format_type *fmt)
struct labeller *text_labeller_create(const struct format_type *fmt)
{
struct labeller *l;
@@ -274,7 +274,7 @@ struct labeller *text_labeller_create(struct format_type *fmt)
}
l->ops = &_text_ops;
l->private = (void *) fmt;
l->private = (const void *) fmt;
return l;
}

View File

@@ -9,7 +9,7 @@
#include "list.h"
#include "crc.h"
#include "xlate.h"
#include "cache.h"
#include "lvmcache.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -104,20 +104,17 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
struct list *lih;
struct labeller_i *li;
struct labeller *r = NULL;
int already_open;
struct label_header *lh;
uint64_t sector;
int found = 0;
char readbuf[LABEL_SCAN_SIZE];
already_open = dev_is_open(dev);
if (!already_open && !dev_open(dev, O_RDONLY)) {
if (!dev_open(dev)) {
stack;
return NULL;
}
if (dev_read(dev, 0, LABEL_SCAN_SIZE, readbuf) != LABEL_SCAN_SIZE) {
if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, readbuf)) {
log_debug("%s: Failed to read label area", dev_name(dev));
goto out;
}
@@ -177,7 +174,7 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
log_very_verbose("%s: No label detected", dev_name(dev));
out:
if (!already_open && !dev_close(dev))
if (!dev_close(dev))
stack;
return r;
@@ -199,12 +196,18 @@ int label_remove(struct device *dev)
log_very_verbose("Scanning for labels to wipe from %s", dev_name(dev));
if (!dev_open(dev, O_RDWR)) {
if (!dev_open(dev)) {
stack;
return 0;
}
if (dev_read(dev, 0, LABEL_SCAN_SIZE, readbuf) != LABEL_SCAN_SIZE) {
/*
* We flush the device just in case someone is stupid
* enough to be trying to import an open pv into lvm.
*/
dev_flush(dev);
if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, readbuf)) {
log_debug("%s: Failed to read label area", dev_name(dev));
goto out;
}
@@ -234,8 +237,8 @@ int label_remove(struct device *dev)
if (wipe) {
log_info("%s: Wiping label at sector %" PRIu64,
dev_name(dev), sector);
if (dev_write(dev, sector << SECTOR_SHIFT, LABEL_SIZE,
buf) != LABEL_SIZE) {
if (!dev_write(dev, sector << SECTOR_SHIFT, LABEL_SIZE,
buf)) {
log_error("Failed to remove label from %s at "
"sector %" PRIu64, dev_name(dev),
sector);
@@ -276,7 +279,6 @@ int label_write(struct device *dev, struct label *label)
char buf[LABEL_SIZE];
struct label_header *lh = (struct label_header *) buf;
int r = 1;
int already_open;
if ((LABEL_SIZE + (label->sector << SECTOR_SHIFT)) > LABEL_SCAN_SIZE) {
log_error("Label sector %" PRIu64 " beyond range (%ld)",
@@ -296,21 +298,19 @@ int label_write(struct device *dev, struct label *label)
lh->crc_xl = xlate32(calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE -
((void *) &lh->offset_xl - (void *) lh)));
already_open = dev_is_open(dev);
if (!already_open && dev_open(dev, O_RDWR)) {
if (!dev_open(dev)) {
stack;
return 0;
}
log_info("%s: Writing label to sector %" PRIu64, dev_name(dev),
label->sector);
if (dev_write(dev, label->sector << SECTOR_SHIFT, LABEL_SIZE, buf) !=
LABEL_SIZE) {
if (!dev_write(dev, label->sector << SECTOR_SHIFT, LABEL_SIZE, buf)) {
log_debug("Failed to write label to %s", dev_name(dev));
r = 0;
}
if (!already_open && dev_close(dev))
if (!dev_close(dev))
stack;
return r;

View File

@@ -7,8 +7,7 @@
#ifndef _LVM_LABEL_H
#define _LVM_LABEL_H
#include "cache.h"
#include "lvm-types.h"
#include "lvmcache.h"
#include "uuid.h"
#include "device.h"
@@ -76,7 +75,7 @@ struct label_ops {
struct labeller {
struct label_ops *ops;
void *private;
const void *private;
};
int label_init(void);

View File

@@ -10,8 +10,6 @@
#include "defaults.h"
#include "sharedlib.h"
#include <dlfcn.h>
static void *_locking_lib = NULL;
static void (*_end_fn) (void) = NULL;
static int (*_lock_fn) (struct cmd_context * cmd, const char *resource,

View File

@@ -13,6 +13,7 @@
#include "defaults.h"
#include "lvm-file.h"
#include "lvm-string.h"
#include "lvmcache.h"
#include <limits.h>
#include <unistd.h>
@@ -34,7 +35,7 @@ static sig_t _oldhandler;
static sigset_t _fullsigset, _intsigset;
static int _handler_installed;
static int _release_lock(const char *file)
static int _release_lock(const char *file, int unlock)
{
struct lock_list *ll;
struct list *llh, *llt;
@@ -46,10 +47,11 @@ static int _release_lock(const char *file)
if (!file || !strcmp(ll->res, file)) {
list_del(llh);
log_very_verbose("Unlocking %s", ll->res);
if (flock(ll->lf, LOCK_NB | LOCK_UN))
log_sys_error("flock", ll->res);
if (unlock) {
log_very_verbose("Unlocking %s", ll->res);
if (flock(ll->lf, LOCK_NB | LOCK_UN))
log_sys_error("flock", ll->res);
}
if (!flock(ll->lf, LOCK_NB | LOCK_EX) &&
!stat(ll->res, &buf1) &&
@@ -72,9 +74,14 @@ static int _release_lock(const char *file)
return 0;
}
void fin_file_locking(void)
static void _fin_file_locking(void)
{
_release_lock(NULL);
_release_lock(NULL, 1);
}
static void _reset_file_locking(void)
{
_release_lock(NULL, 0);
}
static void _remove_ctrl_c_handler()
@@ -90,7 +97,7 @@ static void _remove_ctrl_c_handler()
_handler_installed = 0;
}
void _trap_ctrl_c(int signal)
static void _trap_ctrl_c(int sig)
{
_remove_ctrl_c_handler();
log_error("CTRL-c detected: giving up waiting for lock");
@@ -127,7 +134,7 @@ static int _lock_file(const char *file, int flags)
state = 'W';
break;
case LCK_UNLOCK:
return _release_lock(file);
return _release_lock(file, 1);
default:
log_error("Unrecognised lock type: %d", flags & LCK_TYPE_MASK);
return 0;
@@ -183,7 +190,8 @@ static int _lock_file(const char *file, int flags)
return 0;
}
int file_lock_resource(struct cmd_context *cmd, const char *resource, int flags)
static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
int flags)
{
char lockfile[PATH_MAX];
@@ -195,24 +203,39 @@ int file_lock_resource(struct cmd_context *cmd, const char *resource, int flags)
else
lvm_snprintf(lockfile, sizeof(lockfile),
"%s/V_%s", _lock_dir, resource);
if (!_lock_file(lockfile, flags))
return 0;
switch (flags & LCK_TYPE_MASK) {
case LCK_UNLOCK:
lvmcache_unlock_vgname(resource);
break;
default:
lvmcache_lock_vgname(resource,
(flags & LCK_TYPE_MASK) ==
LCK_READ);
}
break;
case LCK_LV:
switch (flags & LCK_TYPE_MASK) {
case LCK_UNLOCK:
log_debug("Unlocking LV %s", resource);
if (!lv_resume_if_active(cmd, resource))
return 0;
break;
case LCK_READ:
log_debug("Locking LV %s (R)", resource);
if (!lv_activate(cmd, resource))
return 0;
break;
case LCK_WRITE:
log_debug("Locking LV %s (W)", resource);
if (!lv_suspend_if_active(cmd, resource))
return 0;
break;
case LCK_EXCL:
log_debug("Locking LV %s (EX)", resource);
if (!lv_deactivate(cmd, resource))
return 0;
break;
@@ -231,8 +254,9 @@ int file_lock_resource(struct cmd_context *cmd, const char *resource, int flags)
int init_file_locking(struct locking_type *locking, struct config_tree *cf)
{
locking->lock_resource = file_lock_resource;
locking->fin_locking = fin_file_locking;
locking->lock_resource = _file_lock_resource;
locking->reset_locking = _reset_file_locking;
locking->fin_locking = _fin_file_locking;
/* Get lockfile directory from config file */
strncpy(_lock_dir, find_config_str(cf->root, "global/locking_dir",

View File

@@ -15,6 +15,7 @@
#include <signal.h>
#include <sys/stat.h>
#include <limits.h>
#include <unistd.h>
static struct locking_type _locking;
static sigset_t _oldset;
@@ -22,7 +23,7 @@ static sigset_t _oldset;
static int _lock_count = 0; /* Number of locks held */
static int _signals_blocked = 0;
static void _block_signals(void)
static void _block_signals(int flags)
{
sigset_t set;
@@ -60,6 +61,18 @@ static void _unblock_signals(void)
return;
}
void reset_locking(void)
{
int was_locked = _lock_count;
_lock_count = 0;
_locking.reset_locking();
if (was_locked)
_unblock_signals();
}
static inline void _update_lock_count(int flags)
{
if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)
@@ -86,11 +99,13 @@ int init_locking(int type, struct config_tree *cf)
log_very_verbose("File-based locking enabled.");
return 1;
#ifdef HAVE_LIBDL
case 2:
if (!init_external_locking(&_locking, cf))
break;
log_very_verbose("External locking enabled.");
return 1;
#endif
default:
log_error("Unknown locking type requested.");
@@ -147,9 +162,9 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
* VG locking is by VG name.
* FIXME This should become VG uuid.
*/
int _lock_vol(struct cmd_context *cmd, const char *resource, int flags)
static int _lock_vol(struct cmd_context *cmd, const char *resource, int flags)
{
_block_signals();
_block_signals(flags);
if (!(_locking.lock_resource(cmd, resource, flags))) {
_unblock_signals();
@@ -174,7 +189,7 @@ int lock_vol(struct cmd_context *cmd, const char *vol, int flags)
return 0;
case LCK_LV:
/* Suspend LV if it's active. */
strncpy(resource, (char *) vol, sizeof(resource));
strncpy(resource, vol, sizeof(resource));
break;
default:
log_error("Unrecognised lock scope: %d",

View File

@@ -11,6 +11,7 @@
int init_locking(int type, struct config_tree *cf);
void fin_locking(void);
void reset_locking(void);
/*
* LCK_VG:

View File

@@ -8,19 +8,19 @@
#include "metadata.h"
#include "config.h"
typedef int (*lock_resource_fn)(struct cmd_context *cmd, const char *resource,
int flags);
typedef void (*fin_lock_fn)(void);
typedef int (*lock_resource_fn) (struct cmd_context * cmd, const char *resource,
int flags);
typedef void (*fin_lock_fn) (void);
typedef void (*reset_lock_fn) (void);
struct locking_type {
lock_resource_fn lock_resource;
reset_lock_fn reset_locking;
fin_lock_fn fin_locking;
};
/*
* Locking types
*/
@@ -29,4 +29,3 @@ int init_no_locking(struct locking_type *locking, struct config_tree *cf);
int init_file_locking(struct locking_type *locking, struct config_tree *cf);
int init_external_locking(struct locking_type *locking, struct config_tree *cf);

View File

@@ -10,6 +10,7 @@
#include "locking_types.h"
#include "lvm-string.h"
#include "activate.h"
#include "lvmcache.h"
#include <signal.h>
@@ -22,11 +23,25 @@ static void _no_fin_locking(void)
return;
}
static void _no_reset_locking(void)
{
return;
}
static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
int flags)
{
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
switch (flags & LCK_TYPE_MASK) {
case LCK_UNLOCK:
lvmcache_unlock_vgname(resource);
break;
default:
lvmcache_lock_vgname(resource,
(flags & LCK_TYPE_MASK) ==
LCK_READ);
}
break;
case LCK_LV:
switch (flags & LCK_TYPE_MASK) {
@@ -54,6 +69,7 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
int init_no_locking(struct locking_type *locking, struct config_tree *cf)
{
locking->lock_resource = _no_lock_resource;
locking->reset_locking = _no_reset_locking;
locking->fin_locking = _no_fin_locking;
return 1;

View File

@@ -5,27 +5,62 @@
*/
#include "lib.h"
#include "device.h"
#include "memlock.h"
#include "lvm-string.h"
#include <stdarg.h>
#include <syslog.h>
static FILE *_log = 0;
static FILE *_log_file;
static struct device _log_dev;
static struct str_list _log_dev_alias;
static int _verbose_level = 0;
static int _test = 0;
static int _partial = 0;
static int _pvmove = 0;
static int _debug_level = 0;
static int _syslog = 0;
static int _log_to_file = 0;
static int _log_direct = 0;
static int _log_while_suspended = 0;
static int _indent = 1;
static int _log_cmd_name = 0;
static int _log_suppress = 0;
static int _ignorelockingfailure = 0;
static char _cmd_name[30] = "";
static char _msg_prefix[30] = " ";
static int _already_logging = 0;
void init_log(FILE *fp)
void init_log_file(const char *log_file, int append)
{
_log = fp;
const char *open_mode = append ? "a" : "w";
if (!(_log_file = fopen(log_file, open_mode))) {
log_sys_error("fopen", log_file);
return;
}
_log_to_file = 1;
}
void init_log_direct(const char *log_file, int append)
{
const char *filename;
int open_flags = append ? 0 : O_TRUNC;
filename = dbg_strdup(log_file);
dev_create_file(filename, &_log_dev, &_log_dev_alias);
if (!dev_open_flags(&_log_dev, O_RDWR | O_CREAT | open_flags, 1, 0))
return;
_log_direct = 1;
}
void init_log_while_suspended(int log_while_suspended)
{
_log_while_suspended = log_while_suspended;
}
void init_syslog(int facility)
@@ -39,9 +74,23 @@ void log_suppress(int suppress)
_log_suppress = suppress;
}
void fin_log()
void release_log_memory(void)
{
_log = 0;
dbg_free((char *) _log_dev_alias.str);
_log_dev_alias.str = "activate_log file";
}
void fin_log(void)
{
if (_log_direct) {
dev_close(&_log_dev);
_log_direct = 0;
}
if (_log_to_file) {
fclose(_log_file);
_log_to_file = 0;
}
}
void fin_syslog()
@@ -68,6 +117,11 @@ void init_partial(int level)
_partial = level;
}
void init_pvmove(int level)
{
_pvmove = level;
}
void init_ignorelockingfailure(int level)
{
_ignorelockingfailure = level;
@@ -107,6 +161,11 @@ int partial_mode()
return _partial;
}
int pvmove_mode()
{
return _pvmove;
}
int ignorelockingfailure()
{
return _ignorelockingfailure;
@@ -125,6 +184,8 @@ int debug_level()
void print_log(int level, const char *file, int line, const char *format, ...)
{
va_list ap;
char buf[1024];
int bufused, n;
if (!_log_suppress) {
va_start(ap, format);
@@ -183,20 +244,48 @@ void print_log(int level, const char *file, int line, const char *format, ...)
if (level > _debug_level)
return;
if (_log) {
fprintf(_log, "%s:%d %s%s", file, line, _cmd_name, _msg_prefix);
if (_log_to_file && (_log_while_suspended || !memlock())) {
fprintf(_log_file, "%s:%d %s%s", file, line, _cmd_name,
_msg_prefix);
va_start(ap, format);
vfprintf(_log, format, ap);
vfprintf(_log_file, format, ap);
va_end(ap);
fprintf(_log, "\n");
fflush(_log);
fprintf(_log_file, "\n");
fflush(_log_file);
}
if (_syslog) {
if (_syslog && (_log_while_suspended || !memlock())) {
va_start(ap, format);
vsyslog(level, format, ap);
va_end(ap);
}
/* FIXME This code is unfinished - pre-extend & condense. */
if (!_already_logging && _log_direct && memlock()) {
_already_logging = 1;
memset(&buf, ' ', sizeof(buf));
bufused = 0;
if ((n = lvm_snprintf(buf, sizeof(buf) - bufused - 1,
"%s:%d %s%s", file, line, _cmd_name,
_msg_prefix)) == -1)
goto done;
bufused += n;
va_start(ap, format);
n = vsnprintf(buf + bufused - 1, sizeof(buf) - bufused - 1,
format, ap);
va_end(ap);
bufused += n;
done:
buf[bufused - 1] = '\n';
buf[bufused] = '\n';
buf[sizeof(buf) - 1] = '\n';
/* FIXME real size bufused */
dev_append(&_log_dev, sizeof(buf), buf);
_already_logging = 0;
}
}

View File

@@ -39,8 +39,11 @@
#define _LOG_ERR 3
#define _LOG_FATAL 2
void init_log(FILE *fp);
void init_log_file(const char *log_file, int append);
void init_log_direct(const char *log_file, int append);
void init_log_while_suspended(int log_while_suspended);
void fin_log(void);
void release_log_memory(void);
void init_syslog(int facility);
void fin_syslog(void);
@@ -48,6 +51,7 @@ void fin_syslog(void);
void init_verbose(int level);
void init_test(int level);
void init_partial(int level);
void init_pvmove(int level);
void init_debug(int level);
void init_cmd_name(int status);
void init_msg_prefix(const char *prefix);
@@ -58,12 +62,16 @@ void set_cmd_name(const char *cmd_name);
int test_mode(void);
int partial_mode(void);
int pvmove_mode(void);
int debug_level(void);
int ignorelockingfailure(void);
/* Suppress messages to stdout/stderr */
void log_suppress(int suppress);
/* Suppress messages to syslog */
void syslog_suppress(int suppress);
void print_log(int level, const char *file, int line, const char *format, ...)
__attribute__ ((format(printf, 4, 5)));
@@ -78,15 +86,17 @@ void print_log(int level, const char *file, int line, const char *format, ...)
#define stack log_debug("<backtrace>") /* Backtrace on error */
#define log_error(fmt, args...) log_err(fmt , ## args)
#define log_print(fmt, args...) log_warn(fmt , ## args)
#define log_verbose(fmt, args...) log_notice(fmt , ## args)
#define log_very_verbose(fmt, args...) log_info(fmt , ## args)
#define log_error(args...) log_err(args)
#define log_print(args...) log_warn(args)
#define log_verbose(args...) log_notice(args)
#define log_very_verbose(args...) log_info(args)
/* Two System call equivalents */
#define log_sys_error(x, y) \
log_err("%s: %s failed: %s", y, x, strerror(errno))
#define log_sys_very_verbose(x, y) \
log_info("%s: %s failed: %s", y, x, strerror(errno))
#define log_sys_debug(x, y) \
log_debug("%s: %s failed: %s", y, x, strerror(errno))
#endif

View File

@@ -6,43 +6,50 @@
#include "lib.h"
#include "metadata.h"
#include "locking.h"
#include "pv_map.h"
#include "lvm-string.h"
#include "toolcontext.h"
#include <assert.h>
/*
* These functions adjust the pe counts in pv's
* after we've added or removed segments.
*/
static void _get_extents(struct lv_segment *seg)
{
int s, count;
unsigned int s, count;
struct physical_volume *pv;
for (s = 0; s < seg->stripes; s++) {
pv = seg->area[s].pv;
count = seg->len / seg->stripes;
for (s = 0; s < seg->area_count; s++) {
if (seg->area[s].type != AREA_PV)
continue;
pv = seg->area[s].u.pv.pv;
count = seg->area_len;
pv->pe_alloc_count += count;
}
}
static void _put_extents(struct lv_segment *seg)
{
int s, count;
unsigned int s, count;
struct physical_volume *pv;
for (s = 0; s < seg->stripes; s++) {
pv = seg->area[s].pv;
count = seg->len / seg->stripes;
for (s = 0; s < seg->area_count; s++) {
if (seg->area[s].type != AREA_PV)
continue;
assert(pv->pe_alloc_count >= count);
pv->pe_alloc_count -= count;
pv = seg->area[s].u.pv.pv;
if (pv) {
count = seg->area_len;
assert(pv->pe_alloc_count >= count);
pv->pe_alloc_count -= count;
}
}
}
static struct lv_segment *_alloc_segment(struct pool *mem, int stripes)
static struct lv_segment *_alloc_segment(struct pool *mem, uint32_t stripes)
{
struct lv_segment *seg;
uint32_t len = sizeof(*seg) + (stripes * sizeof(seg->area[0]));
@@ -57,16 +64,16 @@ static struct lv_segment *_alloc_segment(struct pool *mem, int stripes)
static int _alloc_stripe_area(struct logical_volume *lv, uint32_t stripes,
uint32_t stripe_size,
struct pv_area **areas, uint32_t *index)
struct pv_area **areas, uint32_t *ix)
{
uint32_t count = lv->le_count - *index;
uint32_t per_area = count / stripes;
uint32_t count = lv->le_count - *ix;
uint32_t area_len = count / stripes;
uint32_t smallest = areas[stripes - 1]->count;
uint32_t s;
struct lv_segment *seg;
if (smallest < per_area)
per_area = smallest;
if (smallest < area_len)
area_len = smallest;
if (!(seg = _alloc_segment(lv->vg->cmd->mem, stripes))) {
log_err("Couldn't allocate new stripe segment.");
@@ -75,27 +82,29 @@ static int _alloc_stripe_area(struct logical_volume *lv, uint32_t stripes,
seg->lv = lv;
seg->type = SEG_STRIPED;
seg->le = *index;
seg->len = per_area * stripes;
seg->stripes = stripes;
seg->le = *ix;
seg->len = area_len * stripes;
seg->area_len = area_len;
seg->area_count = stripes;
seg->stripe_size = stripe_size;
for (s = 0; s < stripes; s++) {
struct pv_area *pva = areas[s];
seg->area[s].pv = pva->map->pv;
seg->area[s].pe = pva->start;
consume_pv_area(pva, per_area);
seg->area[s].type = AREA_PV;
seg->area[s].u.pv.pv = pva->map->pvl->pv;
seg->area[s].u.pv.pe = pva->start;
consume_pv_area(pva, area_len);
}
list_add(&lv->segments, &seg->list);
*index += seg->len;
*ix += seg->len;
return 1;
}
static int _comp_area(const void *l, const void *r)
{
struct pv_area *lhs = *((struct pv_area **) l);
struct pv_area *rhs = *((struct pv_area **) r);
const struct pv_area *lhs = *((const struct pv_area **) l);
const struct pv_area *rhs = *((const struct pv_area **) r);
if (lhs->count < rhs->count)
return 1;
@@ -113,7 +122,7 @@ static int _alloc_striped(struct logical_volume *lv,
int r = 0;
struct list *pvmh;
struct pv_area **areas;
int pv_count = 0, index;
unsigned int pv_count = 0, ix;
struct pv_map *pvm;
size_t len;
@@ -129,18 +138,17 @@ static int _alloc_striped(struct logical_volume *lv,
while (allocated != lv->le_count) {
index = 0;
ix = 0;
list_iterate(pvmh, pvms) {
pvm = list_item(pvmh, struct pv_map);
if (list_empty(&pvm->areas))
continue;
areas[index++] = list_item(pvm->areas.n,
struct pv_area);
areas[ix++] = list_item(pvm->areas.n, struct pv_area);
}
if (index < stripes) {
if (ix < stripes) {
log_error("Insufficient allocatable extents suitable "
"for striping for logical volume "
"%s: %u required", lv->name, lv->le_count);
@@ -148,7 +156,7 @@ static int _alloc_striped(struct logical_volume *lv,
}
/* sort the areas so we allocate from the biggest */
qsort(areas, index, sizeof(*areas), _comp_area);
qsort(areas, ix, sizeof(*areas), _comp_area);
if (!_alloc_stripe_area(lv, stripes, stripe_size, areas,
&allocated)) {
@@ -169,14 +177,14 @@ static int _alloc_striped(struct logical_volume *lv,
* the complete area then the area is split, otherwise the area
* is unlinked from the pv_map.
*/
static int _alloc_linear_area(struct logical_volume *lv, uint32_t *index,
static int _alloc_linear_area(struct logical_volume *lv, uint32_t *ix,
struct pv_map *map, struct pv_area *pva)
{
uint32_t count, remaining;
struct lv_segment *seg;
count = pva->count;
remaining = lv->le_count - *index;
remaining = lv->le_count - *ix;
if (count > remaining)
count = remaining;
@@ -187,17 +195,60 @@ static int _alloc_linear_area(struct logical_volume *lv, uint32_t *index,
seg->lv = lv;
seg->type = SEG_STRIPED;
seg->le = *index;
seg->le = *ix;
seg->len = count;
seg->area_len = count;
seg->stripe_size = 0;
seg->stripes = 1;
seg->area[0].pv = map->pv;
seg->area[0].pe = pva->start;
seg->area_count = 1;
seg->area[0].type = AREA_PV;
seg->area[0].u.pv.pv = map->pvl->pv;
seg->area[0].u.pv.pe = pva->start;
list_add(&lv->segments, &seg->list);
consume_pv_area(pva, count);
*index += count;
*ix += count;
return 1;
}
static int _alloc_mirrored_area(struct logical_volume *lv, uint32_t *ix,
struct pv_map *map, struct pv_area *pva,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe)
{
uint32_t count, remaining;
struct lv_segment *seg;
count = pva->count;
remaining = lv->le_count - *ix;
if (count > remaining)
count = remaining;
if (!(seg = _alloc_segment(lv->vg->cmd->mem, 2))) {
log_err("Couldn't allocate new mirrored segment.");
return 0;
}
seg->lv = lv;
seg->type = SEG_MIRRORED;
seg->status = 0u;
seg->le = *ix;
seg->len = count;
seg->area_len = count;
seg->stripe_size = 0;
seg->area_count = 2;
seg->extents_moved = 0u;
/* FIXME Remove AREA_PV restriction here? */
seg->area[0].type = AREA_PV;
seg->area[0].u.pv.pv = mirrored_pv;
seg->area[0].u.pv.pe = mirrored_pe;
seg->area[1].type = AREA_PV;
seg->area[1].u.pv.pv = map->pvl->pv;
seg->area[1].u.pv.pe = pva->start;
list_add(&lv->segments, &seg->list);
consume_pv_area(pva, count);
*ix += count;
return 1;
}
@@ -225,14 +276,15 @@ static int _alloc_contiguous(struct logical_volume *lv,
/* first item in the list is the biggest */
pva = list_item(pvm->areas.n, struct pv_area);
if (pva->count < lv->le_count)
continue;
if (!_alloc_linear_area(lv, &allocated, pvm, pva)) {
stack;
return 0;
}
if (allocated == lv->le_count)
break;
break;
}
if (allocated != lv->le_count) {
@@ -245,6 +297,50 @@ static int _alloc_contiguous(struct logical_volume *lv,
return 1;
}
/* FIXME Contiguous depends on *segment* (i.e. stripe) not LV */
static int _alloc_mirrored(struct logical_volume *lv,
struct list *pvms, uint32_t allocated,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe)
{
struct list *tmp1;
struct pv_map *pvm;
struct pv_area *pva;
uint32_t max_found = 0;
/* Try each PV in turn */
list_iterate(tmp1, pvms) {
pvm = list_item(tmp1, struct pv_map);
if (list_empty(&pvm->areas))
continue;
/* first item in the list is the biggest */
pva = list_item(pvm->areas.n, struct pv_area);
if (pva->count < lv->le_count - allocated) {
max_found = pva->count;
continue;
}
if (!_alloc_mirrored_area(lv, &allocated, pvm, pva,
mirrored_pv, mirrored_pe)) {
stack;
return 0;
}
break;
}
if (allocated != lv->le_count) {
log_error("Insufficient contiguous allocatable extents (%u) "
"for logical volume %s: %u required",
allocated + max_found, lv->name, lv->le_count);
return 0;
}
return 1;
}
/*
* Areas just get allocated in order until the lv
* is full.
@@ -282,12 +378,15 @@ static int _alloc_next_free(struct logical_volume *lv,
* Chooses a correct allocation policy.
*/
static int _allocate(struct volume_group *vg, struct logical_volume *lv,
struct list *acceptable_pvs, uint32_t allocated,
uint32_t stripes, uint32_t stripe_size)
struct list *allocatable_pvs, uint32_t allocated,
uint32_t stripes, uint32_t stripe_size,
struct physical_volume *mirrored_pv, uint32_t mirrored_pe,
uint32_t status)
{
int r = 0;
struct pool *scratch;
struct list *pvms, *old_tail = lv->segments.p, *segh;
struct lv_segment *seg;
if (!(scratch = pool_create(1024))) {
stack;
@@ -297,12 +396,15 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
/*
* Build the sets of available areas on the pv's.
*/
if (!(pvms = create_pv_maps(scratch, vg, acceptable_pvs)))
if (!(pvms = create_pv_maps(scratch, vg, allocatable_pvs)))
goto out;
if (stripes > 1)
r = _alloc_striped(lv, pvms, allocated, stripes, stripe_size);
else if (mirrored_pv)
r = _alloc_mirrored(lv, pvms, allocated, mirrored_pv,
mirrored_pe);
else if (lv->alloc == ALLOC_CONTIGUOUS)
r = _alloc_contiguous(lv, pvms, allocated);
@@ -322,8 +424,11 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
* Iterate through the new segments, updating pe
* counts in pv's.
*/
for (segh = lv->segments.p; segh != old_tail; segh = segh->p)
_get_extents(list_item(segh, struct lv_segment));
for (segh = lv->segments.p; segh != old_tail; segh = segh->p) {
seg = list_item(segh, struct lv_segment);
_get_extents(seg);
seg->status = status;
}
} else {
/*
* Put the segment list back how we found it.
@@ -337,7 +442,7 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
return r;
}
static char *_generate_lv_name(struct volume_group *vg,
static char *_generate_lv_name(struct volume_group *vg, const char *format,
char *buffer, size_t len)
{
struct list *lvh;
@@ -347,19 +452,86 @@ static char *_generate_lv_name(struct volume_group *vg,
list_iterate(lvh, &vg->lvs) {
lv = (list_item(lvh, struct lv_list)->lv);
if (sscanf(lv->name, "lvol%d", &i) != 1)
if (sscanf(lv->name, format, &i) != 1)
continue;
if (i > high)
high = i;
}
if (lvm_snprintf(buffer, len, "lvol%d", high + 1) < 0)
if (lvm_snprintf(buffer, len, format, high + 1) < 0)
return NULL;
return buffer;
}
struct logical_volume *lv_create_empty(struct format_instance *fi,
const char *name,
const char *name_format,
uint32_t status,
alloc_policy_t alloc,
struct volume_group *vg)
{
struct cmd_context *cmd = vg->cmd;
struct lv_list *ll = NULL;
struct logical_volume *lv;
char dname[32];
if (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;
}
if (!name && !(name = _generate_lv_name(vg, name_format, dname,
sizeof(dname)))) {
log_error("Failed to generate unique name for the new "
"logical volume");
return NULL;
}
log_verbose("Creating logical volume %s", name);
if (!(ll = pool_zalloc(cmd->mem, sizeof(*ll))) ||
!(ll->lv = pool_zalloc(cmd->mem, sizeof(*ll->lv)))) {
log_error("lv_list allocation failed");
if (ll)
pool_free(cmd->mem, ll);
return NULL;
}
lv = ll->lv;
lv->vg = vg;
if (!(lv->name = pool_strdup(cmd->mem, name))) {
log_error("lv name strdup failed");
if (ll)
pool_free(cmd->mem, ll);
return NULL;
}
lv->status = status;
lv->alloc = alloc;
lv->read_ahead = 0;
lv->major = -1;
lv->minor = -1;
lv->size = UINT64_C(0);
lv->le_count = 0;
list_init(&lv->segments);
if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
stack;
if (ll)
pool_free(cmd->mem, ll);
return NULL;
}
vg->lv_count++;
list_add(&vg->lvs, &ll->list);
return lv;
}
struct logical_volume *lv_create(struct format_instance *fi,
const char *name,
uint32_t status,
@@ -368,12 +540,9 @@ struct logical_volume *lv_create(struct format_instance *fi,
uint32_t stripe_size,
uint32_t extents,
struct volume_group *vg,
struct list *acceptable_pvs)
struct list *allocatable_pvs)
{
struct cmd_context *cmd = vg->cmd;
struct lv_list *ll = NULL;
struct logical_volume *lv;
char dname[32];
if (!extents) {
log_error("Unable to create logical volume %s with no extents",
@@ -387,70 +556,33 @@ struct logical_volume *lv_create(struct format_instance *fi,
return NULL;
}
if (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;
}
if (stripes > list_size(acceptable_pvs)) {
if (stripes > list_size(allocatable_pvs)) {
log_error("Number of stripes (%u) must not exceed "
"number of physical volumes (%d)", stripes,
list_size(acceptable_pvs));
list_size(allocatable_pvs));
return NULL;
}
if (!name && !(name = _generate_lv_name(vg, dname, sizeof(dname)))) {
log_error("Failed to generate unique name for the new "
"logical volume");
return NULL;
}
log_verbose("Creating logical volume %s", name);
if (!(ll = pool_zalloc(cmd->mem, sizeof(*ll))) ||
!(ll->lv = pool_zalloc(cmd->mem, sizeof(*ll->lv)))) {
if (!(lv = lv_create_empty(fi, name, "lvol%d", status, alloc, vg))) {
stack;
return NULL;
}
lv = ll->lv;
lv->vg = vg;
if (!(lv->name = pool_strdup(cmd->mem, name))) {
stack;
goto bad;
}
lv->status = status;
lv->alloc = alloc;
lv->read_ahead = 0;
lv->minor = -1;
lv->size = (uint64_t) extents *vg->extent_size;
lv->le_count = extents;
list_init(&lv->segments);
if (!_allocate(vg, lv, acceptable_pvs, 0u, stripes, stripe_size)) {
if (!_allocate(vg, lv, allocatable_pvs, 0u, stripes, stripe_size,
NULL, 0u, 0u)) {
stack;
goto bad;
return NULL;
}
if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
stack;
goto bad;
return NULL;
}
vg->lv_count++;
list_add(&vg->lvs, &ll->list);
return lv;
bad:
if (ll)
pool_free(cmd->mem, ll);
return NULL;
}
int lv_reduce(struct format_instance *fi,
@@ -493,7 +625,7 @@ int lv_reduce(struct format_instance *fi,
int lv_extend(struct format_instance *fi,
struct logical_volume *lv,
uint32_t stripes, uint32_t stripe_size,
uint32_t extents, struct list *acceptable_pvs)
uint32_t extents, struct list *allocatable_pvs)
{
uint32_t old_le_count = lv->le_count;
uint64_t old_size = lv->size;
@@ -501,10 +633,11 @@ int lv_extend(struct format_instance *fi,
lv->le_count += extents;
lv->size += (uint64_t) extents *lv->vg->extent_size;
if (!_allocate(lv->vg, lv, acceptable_pvs, old_le_count,
stripes, stripe_size)) {
if (!_allocate(lv->vg, lv, allocatable_pvs, old_le_count,
stripes, stripe_size, NULL, 0u, 0u)) {
lv->le_count = old_le_count;
lv->size = old_size;
stack;
return 0;
}
@@ -522,6 +655,35 @@ int lv_extend(struct format_instance *fi,
return 1;
}
int lv_extend_mirror(struct format_instance *fid,
struct logical_volume *lv,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe,
uint32_t extents, struct list *allocatable_pvs,
uint32_t status)
{
uint32_t old_le_count = lv->le_count;
uint64_t old_size = lv->size;
lv->le_count += extents;
lv->size += (uint64_t) extents *lv->vg->extent_size;
if (!_allocate(lv->vg, lv, allocatable_pvs, old_le_count,
1, extents, mirrored_pv, mirrored_pe, status)) {
lv->le_count = old_le_count;
lv->size = old_size;
stack;
return 0;
}
if (fid->fmt->ops->lv_setup && !fid->fmt->ops->lv_setup(fid, lv)) {
stack;
return 0;
}
return 1;
}
int lv_remove(struct volume_group *vg, struct logical_volume *lv)
{
struct list *segh;
@@ -544,3 +706,36 @@ int lv_remove(struct volume_group *vg, struct logical_volume *lv)
return 1;
}
/* Unlock list of LVs */
int unlock_lvs(struct cmd_context *cmd, struct list *lvs)
{
struct list *lvh;
struct logical_volume *lv;
list_iterate(lvh, lvs) {
lv = list_item(lvh, struct lv_list)->lv;
unlock_lv(cmd, lv->lvid.s);
}
return 1;
}
/* Lock a list of LVs */
int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags)
{
struct list *lvh;
struct logical_volume *lv;
list_iterate(lvh, lvs) {
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);
return 0;
}
}
return 1;
}

View File

@@ -14,26 +14,32 @@
*/
static int _merge(struct lv_segment *first, struct lv_segment *second)
{
int s;
unsigned int s;
uint32_t width;
if (!first ||
(first->type != SEG_STRIPED) ||
(first->type != second->type) ||
(first->stripes != second->stripes) ||
(first->area_count != second->area_count) ||
(first->stripe_size != second->stripe_size))
return 0;
for (s = 0; s < first->stripes; s++) {
width = first->len / first->stripes;
for (s = 0; s < first->area_count; s++) {
width = first->area_len;
if ((first->area[s].pv != second->area[s].pv) ||
(first->area[s].pe + width != second->area[s].pe))
/* FIXME Relax this to first type != second type ? */
if (first->area[s].type != AREA_PV ||
second->area[s].type != AREA_PV)
return 0;
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 */
first->len += second->len;
first->area_len += second->area_len;
return 1;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2003 Sistina Software (UK) Limited.
*
* This file is released under the LGPL.
*/
@@ -10,10 +10,11 @@
#include "metadata.h"
#include "toolcontext.h"
#include "lvm-string.h"
#include "cache.h"
#include "lvmcache.h"
#include "memlock.h"
int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
const char *pv_name)
static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
const char *pv_name)
{
struct pv_list *pvl;
struct physical_volume *pv;
@@ -23,14 +24,14 @@ int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
log_verbose("Adding physical volume '%s' to volume group '%s'",
pv_name, vg->name);
if (!(pvl = pool_alloc(mem, sizeof(*pvl)))) {
if (!(pvl = pool_zalloc(mem, sizeof(*pvl)))) {
log_error("pv_list allocation for '%s' failed", pv_name);
return 0;
}
list_init(&mdas);
if (!(pv = pv_read(fid->fmt->cmd, pv_name, &mdas, NULL))) {
log_error("Failed to read existing physical volume '%s'",
log_error("%s not identified as an existing physical volume",
pv_name);
return 0;
}
@@ -68,7 +69,8 @@ int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
pv->pe_alloc_count = 0;
if (!fid->fmt->ops->pv_setup(fid->fmt, 0, 0, vg->extent_size, 0, 0,
if (!fid->fmt->ops->pv_setup(fid->fmt, UINT64_C(0), 0,
vg->extent_size, 0, UINT64_C(0),
&fid->metadata_areas, pv, vg)) {
log_error("Format-specific setup of physical volume '%s' "
"failed.", pv_name);
@@ -98,6 +100,30 @@ int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
return 1;
}
int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
const char *new_name)
{
struct pool *mem = cmd->mem;
struct physical_volume *pv;
struct list *pvh;
if (!(vg->name = pool_strdup(mem, new_name))) {
log_error("vg->name allocation failed for '%s'", new_name);
return 0;
}
list_iterate(pvh, &vg->pvs) {
pv = list_item(pvh, struct pv_list)->pv;
if (!(pv->vg_name = pool_strdup(mem, new_name))) {
log_error("pv->vg_name allocation failed for '%s'",
dev_name(pv->dev));
return 0;
}
}
return 1;
}
int vg_extend(struct format_instance *fid,
struct volume_group *vg, int pv_count, char **pv_names)
{
@@ -118,7 +144,7 @@ int vg_extend(struct format_instance *fid,
const char *strip_dir(const char *vg_name, const char *dev_dir)
{
int len = strlen(dev_dir);
size_t len = strlen(dev_dir);
if (!strncmp(vg_name, dev_dir, len))
vg_name += len;
@@ -126,12 +152,13 @@ const char *strip_dir(const char *vg_name, const char *dev_dir)
}
struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
uint32_t extent_size, int max_pv, int max_lv,
int pv_count, char **pv_names)
uint32_t extent_size, uint32_t max_pv,
uint32_t max_lv, int pv_count, char **pv_names)
{
struct volume_group *vg;
struct pool *mem = cmd->mem;
int consistent = 0;
int old_partial;
if (!(vg = pool_zalloc(mem, sizeof(*vg)))) {
stack;
@@ -139,12 +166,13 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
}
/* is this vg name already in use ? */
old_partial = partial_mode();
init_partial(1);
if (vg_read(cmd, vg_name, &consistent)) {
log_err("A volume group called '%s' already exists.", vg_name);
goto bad;
}
init_partial(0);
init_partial(old_partial);
if (!id_create(&vg->id)) {
log_err("Couldn't create uuid for volume group '%s'.", vg_name);
@@ -207,7 +235,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
}
/* Sizes in sectors */
struct physical_volume *pv_create(struct format_type *fmt,
struct physical_volume *pv_create(const struct format_type *fmt,
struct device *dev,
struct id *id, uint64_t size,
uint64_t pe_start,
@@ -231,12 +259,11 @@ struct physical_volume *pv_create(struct format_type *fmt,
pv->dev = dev;
if (!(pv->vg_name = pool_alloc(mem, NAME_LEN))) {
if (!(pv->vg_name = pool_zalloc(mem, NAME_LEN))) {
stack;
goto bad;
}
*pv->vg_name = 0;
pv->status = ALLOCATABLE_PV;
if (!dev_get_size(pv->dev, &pv->size)) {
@@ -294,6 +321,18 @@ struct pv_list *find_pv_in_vg(struct volume_group *vg, const char *pv_name)
return NULL;
}
int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv)
{
struct list *pvh;
list_iterate(pvh, &vg->pvs) {
if (pv == list_item(pvh, struct pv_list)->pv)
return 1;
}
return 0;
}
struct physical_volume *find_pv_in_vg_by_uuid(struct volume_group *vg,
struct id *id)
{
@@ -330,7 +369,8 @@ struct lv_list *find_lv_in_vg(struct volume_group *vg, const char *lv_name)
return NULL;
}
struct lv_list *find_lv_in_vg_by_lvid(struct volume_group *vg, union lvid *lvid)
struct lv_list *find_lv_in_vg_by_lvid(struct volume_group *vg,
const union lvid *lvid)
{
struct list *lvh;
struct lv_list *lvl;
@@ -364,6 +404,21 @@ struct physical_volume *find_pv(struct volume_group *vg, struct device *dev)
return NULL;
}
/* Find segment at a given logical extent in an LV */
struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le)
{
struct list *segh;
struct lv_segment *seg;
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct lv_segment);
if (le >= seg->le && le < seg->le + seg->len)
return seg;
}
return NULL;
}
int vg_remove(struct volume_group *vg)
{
struct list *mdah;
@@ -383,11 +438,14 @@ int vg_remove(struct volume_group *vg)
return 1;
}
/*
* After vg_write() returns success,
* caller MUST call either vg_commit() or vg_revert()
*/
int vg_write(struct volume_group *vg)
{
struct list *mdah;
struct list *mdah, *mdah2;
struct metadata_area *mda;
int cache_updated = 0;
if (vg->status & PARTIAL_VG) {
log_error("Cannot change metadata for partial volume group %s",
@@ -407,20 +465,14 @@ int vg_write(struct volume_group *vg)
mda = list_item(mdah, struct metadata_area);
if (!mda->ops->vg_write(vg->fid, vg, mda)) {
stack;
return 0;
}
}
/* Commit to each copy of the metadata area */
list_iterate(mdah, &vg->fid->metadata_areas) {
mda = list_item(mdah, struct metadata_area);
if (!cache_updated) {
cache_update_vg(vg);
cache_updated = 1;
}
if (mda->ops->vg_commit &&
!mda->ops->vg_commit(vg->fid, vg, mda)) {
stack;
/* 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;
}
}
@@ -428,10 +480,56 @@ int vg_write(struct volume_group *vg)
return 1;
}
/* Make orphan PVs look like a VG */
struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
/* Commit pending changes */
int vg_commit(struct volume_group *vg)
{
struct cache_vginfo *vginfo;
struct list *mdah;
struct metadata_area *mda;
int cache_updated = 0;
int failed = 0;
/* Commit to each copy of the metadata area */
list_iterate(mdah, &vg->fid->metadata_areas) {
mda = list_item(mdah, struct metadata_area);
failed = 0;
if (mda->ops->vg_commit &&
!mda->ops->vg_commit(vg->fid, vg, mda)) {
stack;
failed = 1;
}
/* Update cache first time we succeed */
if (!failed && !cache_updated) {
lvmcache_update_vg(vg);
cache_updated = 1;
}
}
/* If at least one mda commit succeeded, it was committed */
return cache_updated;
}
/* Don't commit any pending changes */
int vg_revert(struct volume_group *vg)
{
struct list *mdah;
struct metadata_area *mda;
list_iterate(mdah, &vg->fid->metadata_areas) {
mda = list_item(mdah, struct metadata_area);
if (mda->ops->vg_revert &&
!mda->ops->vg_revert(vg->fid, vg, mda)) {
stack;
}
}
return 1;
}
/* Make orphan PVs look like a VG */
static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
{
struct lvmcache_vginfo *vginfo;
struct list *ih;
struct device *dev;
struct pv_list *pvl;
@@ -457,7 +555,7 @@ struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
}
list_iterate(ih, &vginfo->infos) {
dev = list_item(ih, struct cache_info)->dev;
dev = list_item(ih, struct lvmcache_info)->dev;
if (!(pv = pv_read(cmd, dev_name(dev), NULL, NULL))) {
continue;
}
@@ -484,11 +582,11 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
int *consistent)
{
struct format_instance *fid;
struct format_type *fmt;
struct volume_group *vg, *correct_vg;
const struct format_type *fmt;
struct volume_group *vg, *correct_vg = NULL;
struct list *mdah;
struct metadata_area *mda;
int inconsistent = 0, first_time = 1;
int inconsistent = 0;
if (!*vgname) {
*consistent = 1;
@@ -498,9 +596,13 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
/* Find the vgname in the cache */
/* If it's not there we must do full scan to be completely sure */
if (!(fmt = fmt_from_vgname(vgname))) {
cache_label_scan(cmd, 0);
lvmcache_label_scan(cmd, 0);
if (!(fmt = fmt_from_vgname(vgname))) {
cache_label_scan(cmd, 1);
if (memlock()) {
stack;
return NULL;
}
lvmcache_label_scan(cmd, 1);
if (!(fmt = fmt_from_vgname(vgname))) {
stack;
return NULL;
@@ -521,9 +623,8 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
inconsistent = 1;
continue;
}
if (first_time) {
if (!correct_vg) {
correct_vg = vg;
first_time = 0;
continue;
}
/* FIXME Also ensure contents same - checksum compare? */
@@ -535,12 +636,12 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
}
/* Failed to find VG */
if (first_time) {
if (!correct_vg) {
stack;
return NULL;
}
cache_update_vg(correct_vg);
lvmcache_update_vg(correct_vg);
if (inconsistent) {
if (!*consistent)
@@ -563,8 +664,15 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
}
}
*consistent = 1;
if ((correct_vg->status & PVMOVE) && !pvmove_mode()) {
log_error("WARNING: Interrupted pvmove detected in "
"volume group %s", vg->name);
log_error("Please restore the metadata by running "
"vgcfgrestore.");
return NULL;
}
*consistent = 1;
return correct_vg;
}
@@ -574,10 +682,10 @@ 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)
{
char *vgname;
struct list *vgnames, *slh;
// const char *vgname;
// struct list *vgnames, *slh;
struct volume_group *vg;
struct cache_vginfo *vginfo;
struct lvmcache_vginfo *vginfo;
int consistent = 0;
/* Is corresponding vgname already cached? */
@@ -594,7 +702,14 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
}
}
/* The slow way - full scan required to cope with vgrename */
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");
return NULL;
@@ -603,7 +718,7 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
list_iterate(slh, vgnames) {
vgname = list_item(slh, struct str_list)->str;
if (!vgname || !*vgname)
continue; /* FIXME Unnecessary? */
continue; // FIXME Unnecessary?
consistent = 0;
if ((vg = vg_read(cmd, vgname, &consistent)) &&
!strncmp(vg->id.uuid, vgid, ID_LEN)) {
@@ -617,6 +732,7 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
}
return NULL;
***/
}
/* Only called by activate.c */
@@ -624,9 +740,9 @@ struct logical_volume *lv_from_lvid(struct cmd_context *cmd, const char *lvid_s)
{
struct lv_list *lvl;
struct volume_group *vg;
union lvid *lvid;
const union lvid *lvid;
lvid = (union lvid *) lvid_s;
lvid = (const union lvid *) lvid_s;
log_very_verbose("Finding volume group for uuid %s", lvid_s);
if (!(vg = vg_read_by_vgid(cmd, lvid->id[0].uuid))) {
@@ -653,7 +769,7 @@ struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
{
struct physical_volume *pv;
struct label *label;
struct cache_info *info;
struct lvmcache_info *info;
struct device *dev;
if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
@@ -662,17 +778,16 @@ struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
}
if (!(label_read(dev, &label))) {
log_error("Failed to read label on physical volume %s",
pv_name);
log_error("No physical volume label read from %s", pv_name);
return 0;
}
info = (struct cache_info *) label->info;
info = (struct lvmcache_info *) label->info;
if (label_sector && *label_sector)
*label_sector = label->sector;
if (!(pv = pool_zalloc(cmd->mem, sizeof(*pv)))) {
log_error("pv_list allocation for '%s' failed", pv_name);
log_error("pv allocation for '%s' failed", pv_name);
return 0;
}
@@ -692,19 +807,21 @@ struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
/* May return empty list */
struct list *get_vgs(struct cmd_context *cmd, int full_scan)
{
return cache_get_vgnames(cmd, full_scan);
return lvmcache_get_vgnames(cmd, full_scan);
}
struct list *get_pvs(struct cmd_context *cmd)
{
struct list *results;
char *vgname;
const char *vgname;
struct list *pvh, *tmp;
struct list *vgnames, *slh;
struct volume_group *vg;
int consistent = 0;
int old_partial;
int old_pvmove;
cache_label_scan(cmd, 0);
lvmcache_label_scan(cmd, 0);
if (!(results = pool_alloc(cmd->mem, sizeof(*results)))) {
log_error("PV list allocation failed");
@@ -721,7 +838,10 @@ struct list *get_pvs(struct cmd_context *cmd)
/* Read every VG to ensure cache consistency */
/* Orphan VG is last on list */
old_partial = partial_mode();
old_pvmove = pvmove_mode();
init_partial(1);
init_pvmove(1);
list_iterate(slh, vgnames) {
vgname = list_item(slh, struct str_list)->str;
if (!vgname)
@@ -740,7 +860,8 @@ struct list *get_pvs(struct cmd_context *cmd)
list_add(results, pvh);
}
}
init_partial(0);
init_pvmove(old_pvmove);
init_partial(old_partial);
return results;
}

View File

@@ -12,17 +12,13 @@
#include "ctype.h"
#include "dev-cache.h"
#include "list.h"
#include "uuid.h"
#include <sys/types.h>
#include <asm/page.h>
#define NAME_LEN 128
#define MAX_STRIPES 128
#define SECTOR_SHIFT 9L
#define SECTOR_SIZE ( 1L << SECTOR_SHIFT )
#define STRIPE_SIZE_DEFAULT 16 /* 16KB */
#define STRIPE_SIZE_MIN ( PAGE_SIZE >> SECTOR_SHIFT) /* PAGESIZE in sectors */
#define STRIPE_SIZE_MIN ( getpagesize() >> SECTOR_SHIFT) /* PAGESIZE in sectors */
#define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
@@ -42,7 +38,9 @@
#define VISIBLE_LV 0x00000040 /* LV */
#define FIXED_MINOR 0x00000080 /* LV */
/* FIXME Remove when metadata restructuring is completed */
#define SNAPSHOT 0x00001000 /* LV - temp internal use only */
#define SNAPSHOT 0x00001000 /* LV - tmp internal use only */
#define PVMOVE 0x00002000 /* VG LV SEG */
#define LOCKED 0x00004000 /* LV */
#define LVM_READ 0x00000100 /* LV VG */
#define LVM_WRITE 0x00000200 /* LV VG */
@@ -62,9 +60,14 @@ typedef enum {
typedef enum {
SEG_STRIPED,
SEG_SNAPSHOT,
SEG_MIRROR
SEG_MIRRORED
} segment_type_t;
typedef enum {
AREA_PV,
AREA_LV
} area_type_t;
struct cmd_context;
struct format_handler;
struct labeller;
@@ -84,14 +87,14 @@ struct format_type {
struct physical_volume {
struct id id;
struct device *dev;
struct format_type *fmt;
char *vg_name;
const struct format_type *fmt;
const char *vg_name;
uint32_t status;
uint64_t size;
/* physical extents */
uint64_t pe_size;
uint32_t pe_size;
uint64_t pe_start;
uint32_t pe_count;
uint32_t pe_alloc_count;
@@ -123,6 +126,8 @@ struct metadata_area_ops {
struct metadata_area * mda);
int (*vg_commit) (struct format_instance * fid,
struct volume_group * vg, struct metadata_area * mda);
int (*vg_revert) (struct format_instance * fid,
struct volume_group * vg, struct metadata_area * mda);
int (*vg_remove) (struct format_instance * fi, struct volume_group * vg,
struct metadata_area * mda);
};
@@ -134,7 +139,7 @@ struct metadata_area {
};
struct format_instance {
struct format_type *fmt;
const struct format_type *fmt;
struct list metadata_areas; /* e.g. metadata locations */
};
@@ -177,17 +182,30 @@ struct lv_segment {
uint32_t le;
uint32_t len;
uint32_t status;
/* FIXME Fields depend on segment type */
uint32_t stripe_size;
uint32_t stripes;
uint32_t area_count;
uint32_t area_len;
struct logical_volume *origin;
struct logical_volume *cow;
uint32_t chunk_size;
uint32_t extents_moved;
/* There will be one area for each stripe */
struct {
struct physical_volume *pv;
uint32_t pe;
area_type_t type;
union {
struct {
struct physical_volume *pv;
uint32_t pe;
} pv;
struct {
struct logical_volume *lv;
uint32_t le;
} lv;
} u;
} area[0];
};
@@ -200,6 +218,7 @@ struct logical_volume {
uint32_t status;
alloc_policy_t alloc;
uint32_t read_ahead;
int32_t major;
int32_t minor;
uint64_t size;
@@ -223,10 +242,17 @@ struct name_list {
char *name;
};
struct alloc_area {
struct list list;
uint32_t start; /* PEs */
uint32_t count; /* PEs */
};
struct pv_list {
struct list list;
struct physical_volume *pv;
struct list *mdas;
struct list *mdas; /* Metadata areas */
struct list *alloc_areas; /* Areas we may allocate from */
};
struct lv_list {
@@ -252,19 +278,19 @@ struct format_handler {
/*
* Scan any metadata areas that aren't referenced in PV labels
*/
int (*scan) (struct format_type * fmt);
int (*scan) (const struct format_type * fmt);
/*
* Return PV with given path.
*/
int (*pv_read) (struct format_type * fmt, const char *pv_name,
int (*pv_read) (const struct format_type * fmt, const char *pv_name,
struct physical_volume * pv, struct list * mdas);
/*
* Tweak an already filled out a pv ready for importing into a
* vg. eg. pe_count is format specific.
*/
int (*pv_setup) (struct format_type * fmt,
int (*pv_setup) (const struct format_type * fmt,
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size,
int pvmetadatacopies,
@@ -275,8 +301,9 @@ struct format_handler {
* Write a PV structure to disk. Fails if the PV is in a VG ie
* pv->vg_name must be null.
*/
int (*pv_write) (struct format_type * fmt, struct physical_volume * pv,
struct list * mdas, int64_t label_sector);
int (*pv_write) (const struct format_type * fmt,
struct physical_volume * pv, struct list * mdas,
int64_t label_sector);
/*
* Tweak an already filled out a lv eg, check there
@@ -294,8 +321,8 @@ struct format_handler {
/*
* Create format instance with a particular metadata area
*/
struct format_instance *(*create_instance) (struct format_type * fmt,
const char *vgname,
struct format_instance *(*create_instance) (const struct format_type *
fmt, const char *vgname,
void *context);
/*
@@ -306,13 +333,15 @@ struct format_handler {
/*
* Destructor for format type
*/
void (*destroy) (struct format_type * fmt);
void (*destroy) (const struct format_type * fmt);
};
/*
* Utility functions
*/
int vg_write(struct volume_group *vg);
int vg_commit(struct volume_group *vg);
int vg_revert(struct volume_group *vg);
struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name,
int *consistent);
struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid);
@@ -328,7 +357,7 @@ int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
/* pe_start and pe_end relate to any existing data so that new metadata
* areas can avoid overlap */
struct physical_volume *pv_create(struct format_type *fmt,
struct physical_volume *pv_create(const struct format_type *fmt,
struct device *dev,
struct id *id,
uint64_t size,
@@ -339,10 +368,11 @@ struct physical_volume *pv_create(struct format_type *fmt,
uint64_t pvmetadatasize, struct list *mdas);
struct volume_group *vg_create(struct cmd_context *cmd, const char *name,
uint32_t extent_size, int max_pv, int max_lv,
int pv_count, char **pv_names);
uint32_t extent_size, uint32_t max_pv,
uint32_t max_lv, int pv_count, char **pv_names);
int vg_remove(struct volume_group *vg);
int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
const char *new_name);
int vg_extend(struct format_instance *fi, struct volume_group *vg,
int pv_count, char **pv_names);
@@ -358,8 +388,16 @@ struct logical_volume *lv_create(struct format_instance *fi,
uint32_t stripe_size,
uint32_t extents,
struct volume_group *vg,
struct list *acceptable_pvs);
struct list *allocatable_pvs);
struct logical_volume *lv_create_empty(struct format_instance *fi,
const char *name,
const char *name_format,
uint32_t status,
alloc_policy_t alloc,
struct volume_group *vg);
/* Manipulate LVs */
int lv_reduce(struct format_instance *fi,
struct logical_volume *lv, uint32_t extents);
@@ -369,6 +407,17 @@ int lv_extend(struct format_instance *fi,
uint32_t stripe_size,
uint32_t extents, struct list *allocatable_pvs);
int lv_extend_mirror(struct format_instance *fid,
struct logical_volume *lv,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe,
uint32_t extents, struct list *allocatable_pvs,
uint32_t status);
/* Lock list of LVs */
int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags);
int unlock_lvs(struct cmd_context *cmd, struct list *lvs);
/* lv must be part of vg->lvs */
int lv_remove(struct volume_group *vg, struct logical_volume *lv);
@@ -385,7 +434,7 @@ struct physical_volume *find_pv_in_vg_by_uuid(struct volume_group *vg,
/* Find an LV within a given VG */
struct lv_list *find_lv_in_vg(struct volume_group *vg, const char *lv_name);
struct lv_list *find_lv_in_vg_by_lvid(struct volume_group *vg,
union lvid *lvid);
const union lvid *lvid);
/* Return the VG that contains a given LV (based on path given in lv_name) */
/* or environment var */
@@ -399,6 +448,9 @@ struct logical_volume *lv_from_lvid(struct cmd_context *cmd,
struct physical_volume *find_pv(struct volume_group *vg, struct device *dev);
struct logical_volume *find_lv(struct volume_group *vg, const char *lv_name);
/* Find LV segment containing given LE */
struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le);
/*
* Remove a dev_dir if present.
*/
@@ -419,12 +471,14 @@ int lv_merge_segments(struct logical_volume *lv);
/*
* Useful functions for managing snapshots.
*/
int lv_is_origin(struct logical_volume *lv);
int lv_is_cow(struct logical_volume *lv);
int lv_is_origin(const struct logical_volume *lv);
int lv_is_cow(const struct logical_volume *lv);
struct snapshot *find_cow(struct logical_volume *lv);
struct snapshot *find_origin(struct logical_volume *lv);
struct list *find_snapshots(struct logical_volume *lv);
int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv);
struct snapshot *find_cow(const struct logical_volume *lv);
struct snapshot *find_origin(const struct logical_volume *lv);
struct list *find_snapshots(const struct logical_volume *lv);
int vg_add_snapshot(struct logical_volume *origin,
struct logical_volume *cow,
@@ -432,7 +486,27 @@ int vg_add_snapshot(struct logical_volume *origin,
int vg_remove_snapshot(struct volume_group *vg, struct logical_volume *cow);
static inline int validate_vgname(const char *n)
/*
* Mirroring functions
*/
int insert_pvmove_mirrors(struct cmd_context *cmd,
struct logical_volume *lv_mirr,
struct physical_volume *pv,
struct logical_volume *lv,
struct list *allocatable_pvs,
struct list *lvs_changed);
int remove_pvmove_mirrors(struct volume_group *vg,
struct logical_volume *lv_mirr);
struct logical_volume *find_pvmove_lv(struct volume_group *vg,
struct device *dev);
struct physical_volume *get_pvmove_pv_from_lv(struct logical_volume *lv);
struct physical_volume *get_pvmove_pv_from_lv_mirr(struct logical_volume
*lv_mirr);
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);
static inline int validate_name(const char *n)
{
register char c;
register int len = 0;

250
lib/metadata/mirror.c Normal file
View File

@@ -0,0 +1,250 @@
/*
* Copyright (C) 2003 Sistina Software (UK) Limited.
*
* This file is released under the LGPL.
*/
#include "lib.h"
#include "metadata.h"
#include "toolcontext.h"
/*
* Replace any LV segments on given PV with temporary mirror.
* Returns list of LVs changed.
*/
int insert_pvmove_mirrors(struct cmd_context *cmd,
struct logical_volume *lv_mirr,
struct physical_volume *pv,
struct logical_volume *lv,
struct list *allocatable_pvs,
struct list *lvs_changed)
{
struct list *segh;
struct lv_segment *seg;
struct lv_list *lvl;
int lv_used = 0;
uint32_t s, start_le, extent_count = 0u;
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct lv_segment);
for (s = 0; s < seg->area_count; s++) {
if (seg->area[s].type != AREA_PV ||
seg->area[s].u.pv.pv->dev != pv->dev)
continue;
if (!lv_used) {
if (!(lvl = pool_alloc(cmd->mem, sizeof(*lvl)))) {
log_error("lv_list alloc failed");
return 0;
}
lvl->lv = lv;
list_add(lvs_changed, &lvl->list);
lv_used = 1;
}
start_le = lv_mirr->le_count;
if (!lv_extend_mirror(lv->vg->fid, lv_mirr,
seg->area[s].u.pv.pv,
seg->area[s].u.pv.pe,
seg->area_len, allocatable_pvs,
PVMOVE)) {
log_error("Allocation for temporary "
"pvmove LV failed");
return 0;
}
seg->area[s].type = AREA_LV;
seg->area[s].u.lv.lv = lv_mirr;
seg->area[s].u.lv.le = start_le;
extent_count += seg->area_len;
lv->status |= LOCKED;
}
}
log_verbose("Moving %u extents of logical volume %s/%s", extent_count,
lv->vg->name, lv->name);
return 1;
}
int remove_pvmove_mirrors(struct volume_group *vg,
struct logical_volume *lv_mirr)
{
struct list *lvh, *segh;
struct logical_volume *lv1;
struct lv_segment *seg, *mir_seg;
uint32_t s, c;
list_iterate(lvh, &vg->lvs) {
lv1 = list_item(lvh, struct lv_list)->lv;
if (lv1 == lv_mirr)
continue;
list_iterate(segh, &lv1->segments) {
seg = list_item(segh, struct lv_segment);
for (s = 0; s < seg->area_count; s++) {
if (seg->area[s].type != AREA_LV ||
seg->area[s].u.lv.lv != lv_mirr)
continue;
if (!(mir_seg = find_seg_by_le(lv_mirr,
seg->area[s].u.
lv.le))) {
log_error("No segment found with LE");
return 0;
}
if (mir_seg->type != SEG_MIRRORED ||
!(mir_seg->status & PVMOVE) ||
mir_seg->le != seg->area[s].u.lv.le ||
mir_seg->area_count != 2 ||
mir_seg->area_len != seg->area_len) {
log_error("Incompatible segments");
return 0;
}
if (mir_seg->extents_moved == mir_seg->area_len)
c = 1;
else
c = 0;
seg->area[s].type = AREA_PV;
seg->area[s].u.pv.pv = mir_seg->area[c].u.pv.pv;
seg->area[s].u.pv.pe = mir_seg->area[c].u.pv.pe;
mir_seg->type = SEG_STRIPED;
mir_seg->area_count = 1;
lv1->status &= ~LOCKED;
}
}
}
return 1;
}
struct physical_volume *get_pvmove_pv_from_lv_mirr(struct logical_volume
*lv_mirr)
{
struct list *segh;
struct lv_segment *seg;
list_iterate(segh, &lv_mirr->segments) {
seg = list_item(segh, struct lv_segment);
if (seg->type != SEG_MIRRORED)
continue;
if (seg->area[0].type != AREA_PV)
continue;
return seg->area[0].u.pv.pv;
}
return NULL;
}
struct physical_volume *get_pvmove_pv_from_lv(struct logical_volume *lv)
{
struct list *segh;
struct lv_segment *seg;
uint32_t s;
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct lv_segment);
for (s = 0; s < seg->area_count; s++) {
if (seg->area[s].type != AREA_LV)
continue;
return get_pvmove_pv_from_lv_mirr(seg->area[s].u.lv.lv);
}
}
return NULL;
}
struct logical_volume *find_pvmove_lv(struct volume_group *vg,
struct device *dev)
{
struct list *lvh, *segh;
struct logical_volume *lv;
struct lv_segment *seg;
/* Loop through all LVs */
list_iterate(lvh, &vg->lvs) {
lv = list_item(lvh, struct lv_list)->lv;
if (!(lv->status & PVMOVE))
continue;
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct lv_segment);
if (seg->area[0].type != AREA_PV)
continue;
if (seg->area[0].u.pv.pv->dev != dev)
continue;
return lv;
}
}
return NULL;
}
struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv)
{
struct list *lvh, *segh, *lvs;
struct logical_volume *lv1;
struct lv_list *lvl;
struct lv_segment *seg;
uint32_t s;
if (!(lvs = pool_alloc(cmd->mem, sizeof(*lvs)))) {
log_error("lvs list alloc failed");
return NULL;
}
list_init(lvs);
/* Loop through all LVs except the one supplied */
list_iterate(lvh, &vg->lvs) {
lv1 = list_item(lvh, struct lv_list)->lv;
if (lv1 == lv)
continue;
list_iterate(segh, &lv1->segments) {
seg = list_item(segh, struct lv_segment);
for (s = 0; s < seg->area_count; s++) {
if (seg->area[s].type != AREA_LV ||
seg->area[s].u.lv.lv != lv)
continue;
if (!(lvl = pool_alloc(cmd->mem, sizeof(*lvl)))) {
log_error("lv_list alloc failed");
return NULL;
}
lvl->lv = lv1;
list_add(lvs, &lvl->list);
goto next_lv;
}
}
next_lv:
;
}
return lvs;
}
float pvmove_percent(struct logical_volume *lv_mirr)
{
uint32_t numerator = 0u, denominator = 0u;
struct list *segh;
struct lv_segment *seg;
list_iterate(segh, &lv_mirr->segments) {
seg = list_item(segh, struct lv_segment);
if (!(seg->status & PVMOVE))
continue;
numerator += seg->extents_moved;
denominator += seg->area_len;
}
return denominator ? (float) numerator *100 / denominator : 100.0;
}

View File

@@ -8,18 +8,16 @@
#include "pv_map.h"
#include "hash.h"
#include <assert.h>
static int _create_maps(struct pool *mem, struct list *pvs, struct list *maps)
{
struct list *tmp;
struct physical_volume *pv;
struct pv_map *pvm;
struct pv_list *pvl;
list_iterate(tmp, pvs) {
pv = list_item(tmp, struct pv_list)->pv;
pvl = list_item(tmp, struct pv_list);
if (!(pv->status & ALLOCATABLE_PV))
if (!(pvl->pv->status & ALLOCATABLE_PV))
continue;
if (!(pvm = pool_zalloc(mem, sizeof(*pvm)))) {
@@ -27,9 +25,9 @@ static int _create_maps(struct pool *mem, struct list *pvs, struct list *maps)
return 0;
}
pvm->pv = pv;
pvm->pvl = pvl;
if (!(pvm->allocated_extents =
bitset_create(mem, pv->pe_count))) {
bitset_create(mem, pvl->pv->pe_count))) {
stack;
return 0;
}
@@ -41,8 +39,8 @@ static int _create_maps(struct pool *mem, struct list *pvs, struct list *maps)
return 1;
}
static int _set_allocated(struct hash_table *hash,
struct physical_volume *pv, int pe)
static int _set_allocd(struct hash_table *hash,
struct physical_volume *pv, uint32_t pe)
{
struct pv_map *pvm;
@@ -84,7 +82,7 @@ static int _fill_bitsets(struct volume_group *vg, struct list *maps)
/* populate the hash table */
list_iterate(pvmh, maps) {
pvm = list_item(pvmh, struct pv_map);
if (!hash_insert(hash, dev_name(pvm->pv->dev), pvm)) {
if (!hash_insert(hash, dev_name(pvm->pvl->pv->dev), pvm)) {
stack;
goto out;
}
@@ -97,13 +95,14 @@ static int _fill_bitsets(struct volume_group *vg, struct list *maps)
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct lv_segment);
for (s = 0; s < seg->stripes; s++) {
for (pe = 0; pe < (seg->len / seg->stripes);
pe++) {
if (!_set_allocated(hash,
seg->area[s].pv,
seg->area[s].pe
+ pe)) {
for (s = 0u; s < seg->area_count; s++) {
for (pe = 0u; pe < seg->area_len; pe++) {
if (seg->area[s].type != AREA_PV)
continue;
if (!_set_allocd(hash,
seg->area[s].u.pv.pv,
seg->area[s].u.pv.pe
+ pe)) {
stack;
goto out;
}
@@ -124,7 +123,7 @@ static int _fill_bitsets(struct volume_group *vg, struct list *maps)
static void _insert_area(struct list *head, struct pv_area *a)
{
struct list *pvah;
struct pv_area *pva;
struct pv_area *pva = NULL;
if (list_empty(head)) {
list_add(head, &a->list);
@@ -142,22 +141,22 @@ static void _insert_area(struct list *head, struct pv_area *a)
}
static int _create_single_area(struct pool *mem, struct pv_map *pvm,
uint32_t *extent)
uint32_t end, uint32_t *extent)
{
uint32_t e = *extent, b, count = pvm->pv->pe_count;
uint32_t e = *extent, b;
struct pv_area *pva;
while (e < count && bit(pvm->allocated_extents, e))
while (e <= end && bit(pvm->allocated_extents, e))
e++;
if (e == count) {
if (e > end) {
*extent = e;
return 1;
}
b = e++;
while (e < count && !bit(pvm->allocated_extents, e))
while (e <= end && !bit(pvm->allocated_extents, e))
e++;
if (!(pva = pool_zalloc(mem, sizeof(*pva)))) {
@@ -165,6 +164,8 @@ static int _create_single_area(struct pool *mem, struct pv_map *pvm,
return 0;
}
log_debug("Allowing allocation on %s start PE %" PRIu32 " length %"
PRIu32, dev_name(pvm->pvl->pv->dev), b, e - b);
pva->map = pvm;
pva->start = b;
pva->count = e - b;
@@ -174,12 +175,18 @@ static int _create_single_area(struct pool *mem, struct pv_map *pvm,
return 1;
}
static int _create_areas(struct pool *mem, struct pv_map *pvm)
static int _create_areas(struct pool *mem, struct pv_map *pvm, uint32_t start,
uint32_t count)
{
uint32_t pe = 0;
uint32_t pe, end;
while (pe < pvm->pv->pe_count)
if (!_create_single_area(mem, pvm, &pe)) {
end = start + count - 1;
if (end > pvm->pvl->pv->pe_count - 1)
end = pvm->pvl->pv->pe_count - 1;
pe = start;
while (pe <= end)
if (!_create_single_area(mem, pvm, end, &pe)) {
stack;
return 0;
}
@@ -187,7 +194,36 @@ static int _create_areas(struct pool *mem, struct pv_map *pvm)
return 1;
}
static int _create_all_areas(struct pool *mem, struct list *maps)
static int _create_allocatable_areas(struct pool *mem, struct pv_map *pvm)
{
struct list *alloc_areas, *aah;
struct alloc_area *aa;
alloc_areas = pvm->pvl->alloc_areas;
if (alloc_areas) {
list_iterate(aah, alloc_areas) {
aa = list_item(aah, struct alloc_area);
if (!_create_areas(mem, pvm, aa->start, aa->count)) {
stack;
return 0;
}
}
} else {
/* Use whole PV */
if (!_create_areas(mem, pvm, UINT32_C(0),
pvm->pvl->pv->pe_count)) {
stack;
return 0;
}
}
return 1;
}
static int _create_all_areas(struct pool *mem, struct list *maps,
struct list *pvs)
{
struct list *tmp;
struct pv_map *pvm;
@@ -195,7 +231,7 @@ static int _create_all_areas(struct pool *mem, struct list *maps)
list_iterate(tmp, maps) {
pvm = list_item(tmp, struct pv_map);
if (!_create_areas(mem, pvm)) {
if (!_create_allocatable_areas(mem, pvm)) {
stack;
return 0;
}
@@ -228,7 +264,7 @@ struct list *create_pv_maps(struct pool *mem, struct volume_group *vg,
goto bad;
}
if (!_create_all_areas(mem, maps)) {
if (!_create_all_areas(mem, maps, pvs)) {
log_error("Couldn't create area maps in %s", vg->name);
goto bad;
}

View File

@@ -28,7 +28,7 @@ struct pv_area {
};
struct pv_map {
struct physical_volume *pv;
struct pv_list *pvl;
bitset_t allocated_extents;
struct list areas;

View File

@@ -8,7 +8,7 @@
#include "metadata.h"
#include "toolcontext.h"
int lv_is_origin(struct logical_volume *lv)
int lv_is_origin(const struct logical_volume *lv)
{
struct list *slh;
struct snapshot *s;
@@ -22,7 +22,7 @@ int lv_is_origin(struct logical_volume *lv)
return 0;
}
int lv_is_cow(struct logical_volume *lv)
int lv_is_cow(const struct logical_volume *lv)
{
struct list *slh;
struct snapshot *s;
@@ -36,7 +36,7 @@ int lv_is_cow(struct logical_volume *lv)
return 0;
}
struct snapshot *find_origin(struct logical_volume *lv)
struct snapshot *find_origin(const struct logical_volume *lv)
{
struct list *slh;
struct snapshot *s;
@@ -50,7 +50,7 @@ struct snapshot *find_origin(struct logical_volume *lv)
return NULL;
}
struct snapshot *find_cow(struct logical_volume *lv)
struct snapshot *find_cow(const struct logical_volume *lv)
{
struct list *slh;
struct snapshot *s;
@@ -64,7 +64,7 @@ struct snapshot *find_cow(struct logical_volume *lv)
return NULL;
}
struct list *find_snapshots(struct logical_volume *lv)
struct list *find_snapshots(const struct logical_volume *lv)
{
struct list *slh;
struct list *snaplist;

View File

@@ -5,7 +5,8 @@
*/
#include "lib.h"
#include "lvm-types.h"
#include "crc.h"
/* Calculate an endian-independent CRC of supplied buffer */
uint32_t calc_crc(uint32_t initial, void *buf, uint32_t size)

View File

@@ -7,8 +7,6 @@
#ifndef _LVM_CRC_H
#define _LVM_CRC_H
#include "lvm-types.h"
#define INITIAL_CRC 0xf597a6cf
uint32_t calc_crc(uint32_t initial, void *buf, uint32_t size);

View File

@@ -5,12 +5,13 @@
*/
/*
* This file must be included first by every source file.
* This file must be included first by every library source file.
*/
#ifndef _LVM_LIB_H
#define _LVM_LIB_H
#define _REENTRANT
#define _GNU_SOURCE
#include "log.h"
#include "dbg_malloc.h"

31
lib/misc/lvm-string.c Normal file
View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the LGPL.
*/
#include "lib.h"
#include "lvm-types.h"
#include "lvm-string.h"
/*
* On error, up to glibc 2.0.6, snprintf returned -1 if buffer was too small;
* From glibc 2.1 it returns number of chars (excl. trailing null) that would
* have been written had there been room.
*
* lvm_snprintf reverts to the old behaviour.
*/
int lvm_snprintf(char *buf, size_t bufsize, const char *format, ...)
{
int n;
va_list ap;
va_start(ap, format);
n = vsnprintf(buf, bufsize, format, ap);
va_end(ap);
if (n < 0 || (n > bufsize - 1))
return -1;
return n;
}

View File

@@ -17,20 +17,6 @@
*
* lvm_snprintf reverts to the old behaviour.
*/
static inline int lvm_snprintf(char *buf, size_t bufsize,
const char *format, ...)
{
int n;
va_list ap;
va_start(ap, format);
n = vsnprintf(buf, bufsize, format, ap);
va_end(ap);
if (n < 0 || (n > bufsize - 1))
return -1;
return n;
}
int lvm_snprintf(char *buf, size_t bufsize, const char *format, ...);
#endif

View File

@@ -8,6 +8,7 @@
#include "lib.h"
#include "config.h"
#include "lvm-string.h"
#include "sharedlib.h"
#include <limits.h>
#include <sys/stat.h>

View File

@@ -6,6 +6,7 @@
*/
#include "config.h"
#include <dlfcn.h>
void *load_shared_library(struct config_tree *cf, const char *libname,
const char *what);

View File

@@ -6,8 +6,8 @@
#include "lib.h"
#include "lvm-types.h"
#include "dbg_malloc.h"
#include <assert.h>
#include <stdarg.h>
struct memblock {
@@ -66,7 +66,7 @@ void *malloc_aux(size_t s, const char *file, int line)
and fill in the boundary bytes */
{
char *ptr = (char *) (nb + 1);
int i;
size_t i;
for (i = 0; i < s; i++)
*ptr++ = i & 0x1 ? (char) 0xba : (char) 0xbe;
@@ -87,7 +87,7 @@ void *malloc_aux(size_t s, const char *file, int line)
void free_aux(void *p)
{
char *ptr;
int i;
size_t i;
struct memblock *mb = ((struct memblock *) p) - 1;
if (!p)
return;
@@ -173,7 +173,7 @@ void bounds_check(void)
{
struct memblock *mb = _head;
while (mb) {
int i;
size_t i;
char *ptr = ((char *) (mb + 1)) + mb->length;
for (i = 0; i < sizeof(unsigned long); i++)
if (*ptr++ != (char) mb->id)

View File

@@ -7,9 +7,9 @@
#ifndef _LVM_DBG_MALLOC_H
#define _LVM_DBG_MALLOC_H
#include "lvm-types.h"
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifdef DEBUG_MEM
void *malloc_aux(size_t s, const char *file, int line);
@@ -18,15 +18,15 @@ void *realloc_aux(void *p, unsigned int s, const char *file, int line);
int dump_memory(void);
void bounds_check(void);
#define dbg_malloc(s) malloc_aux((s), __FILE__, __LINE__)
#define dbg_free(p) free_aux(p)
#define dbg_realloc(p, s) realloc_aux(p, s, __FILE__, __LINE__)
# define dbg_malloc(s) malloc_aux((s), __FILE__, __LINE__)
# define dbg_free(p) free_aux(p)
# define dbg_realloc(p, s) realloc_aux(p, s, __FILE__, __LINE__)
#else
#define dbg_malloc(s) malloc(s)
#define dbg_free(p) free(p)
#define dbg_realloc(p, s) realloc(p, s)
#define dump_memory()
#define bounds_check()
# define dbg_malloc(s) malloc(s)
# define dbg_free(p) free(p)
# define dbg_realloc(p, s) realloc(p, s)
# define dump_memory()
# define bounds_check()
#endif
static inline char *dbg_strdup(const char *str)

144
lib/mm/memlock.c Normal file
View File

@@ -0,0 +1,144 @@
/*
* Copyright (C) 2003 Sistina Software (UK) Limited.
*
* This file is released under the LGPL.
*/
#include "lib.h"
#include "memlock.h"
#include "pool.h"
#include "defaults.h"
#include <limits.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/resource.h>
#ifndef DEVMAPPER_SUPPORT
void memlock_inc(void)
{
return;
}
void memlock_dec(void)
{
return;
}
int memlock(void)
{
return 0;
}
#else /* DEVMAPPER_SUPPORT */
static size_t _size_stack;
static size_t _size_malloc_tmp;
static size_t _size_malloc = 2000000;
static void *_malloc_mem = NULL;
static int _memlock_count = 0;
static int _priority;
static int _default_priority;
static void _touch_memory(void *mem, size_t size)
{
size_t pagesize = getpagesize();
void *pos = mem;
void *end = mem + size - sizeof(long);
while (pos < end) {
*(long *) pos = 1;
pos += pagesize;
}
}
static void _allocate_memory(void)
{
void *stack_mem, *temp_malloc_mem;
if ((stack_mem = alloca(_size_stack)))
_touch_memory(stack_mem, _size_stack);
if ((temp_malloc_mem = malloc(_size_malloc_tmp)))
_touch_memory(temp_malloc_mem, _size_malloc_tmp);
if ((_malloc_mem = malloc(_size_malloc)))
_touch_memory(_malloc_mem, _size_malloc);
free(temp_malloc_mem);
}
static void _release_memory(void)
{
free(_malloc_mem);
}
/* Stop memory getting swapped out */
static void _lock_memory(void)
{
#ifdef MCL_CURRENT
if (mlockall(MCL_CURRENT | MCL_FUTURE))
log_sys_error("mlockall", "");
else
log_very_verbose("Locking memory");
#endif
_allocate_memory();
errno = 0;
if (((_priority = getpriority(PRIO_PROCESS, 0)) == -1) && errno)
log_sys_error("getpriority", "");
else
if (setpriority(PRIO_PROCESS, 0, _default_priority))
log_error("setpriority %u failed: %s",
_default_priority, strerror(errno));
}
static void _unlock_memory(void)
{
#ifdef MCL_CURRENT
if (munlockall())
log_sys_error("munlockall", "");
else
log_very_verbose("Unlocking memory");
#endif
_release_memory();
if (setpriority(PRIO_PROCESS, 0, _priority))
log_error("setpriority %u failed: %s", _priority,
strerror(errno));
}
void memlock_inc(void)
{
if (!_memlock_count++)
_lock_memory();
log_debug("memlock_count inc to %d", _memlock_count);
}
void memlock_dec(void)
{
if (_memlock_count && (!--_memlock_count))
_unlock_memory();
log_debug("memlock_count dec to %d", _memlock_count);
}
int memlock(void)
{
return _memlock_count;
}
void memlock_init(struct cmd_context *cmd)
{
_size_stack = find_config_int(cmd->cf->root,
"activation/reserved_stack",
'/', DEFAULT_RESERVED_STACK) * 1024;
_size_malloc_tmp = find_config_int(cmd->cf->root,
"activation/reserved_memory",
'/', DEFAULT_RESERVED_MEMORY) * 1024;
_default_priority = find_config_int(cmd->cf->root,
"activation/process_priority",
'/', DEFAULT_PROCESS_PRIORITY);
}
#endif

17
lib/mm/memlock.h Normal file
View File

@@ -0,0 +1,17 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the LGPL.
*/
#ifndef LVM_MEMLOCK_H
#define LVM_MEMLOCK_H
#include "toolcontext.h"
void memlock_inc(void);
void memlock_dec(void);
int memlock(void);
void memlock_init(struct cmd_context *cmd);
#endif

View File

@@ -7,8 +7,6 @@
#include "lib.h"
#include "pool.h"
#include <assert.h>
struct block {
struct block *next;
size_t size;
@@ -31,7 +29,7 @@ struct pool *pool_create(size_t chunk_hint)
struct pool *mem = dbg_malloc(sizeof(*mem));
if (!mem) {
log_error("Couldn't create memory pool (size %u)",
log_error("Couldn't create memory pool (size %" PRIsize_t ")",
sizeof(*mem));
return NULL;
}
@@ -207,3 +205,15 @@ char *pool_strdup(struct pool *p, const char *str)
return ret;
}
char *pool_strndup(struct pool *p, const char *str, size_t n)
{
char *ret = pool_alloc(p, n + 1);
if (ret) {
strncpy(ret, str, n);
ret[n] = '\0';
}
return ret;
}

View File

@@ -33,7 +33,7 @@ struct pool *pool_create(size_t chunk_hint)
struct pool *p = dbg_malloc(sizeof(*p));
if (!p) {
log_error("Couldn't create memory pool (size %" PRIuPTR ")",
log_error("Couldn't create memory pool (size %" PRIsize_t ")",
sizeof(*p));
return 0;
}
@@ -205,6 +205,18 @@ char *pool_strdup(struct pool *p, const char *str)
return ret;
}
char *pool_strndup(struct pool *p, const char *str, size_t n)
{
char *ret = pool_alloc(p, n + 1);
if (ret) {
strncpy(ret, str, n);
ret[n] = '\0';
}
return ret;
}
void _align_chunk(struct chunk *c, unsigned alignment)
{
c->begin += alignment - ((unsigned long) c->begin & (alignment - 1));
@@ -221,8 +233,8 @@ struct chunk *_new_chunk(struct pool *p, size_t s)
p->spare_chunk = 0;
} else {
if (!(c = dbg_malloc(s))) {
log_err("Out of memory. Requested %" PRIuPTR " bytes.",
s);
log_err("Out of memory. Requested %" PRIsize_t
" bytes.", s);
return NULL;
}

View File

@@ -10,7 +10,6 @@
#include <string.h>
#include <stdlib.h>
/*
* The pool allocator is useful when you are going to allocate
* lots of memory, use the memory for a bit, and then free the
@@ -107,8 +106,10 @@ void pool_abandon_object(struct pool *p);
/* utilities */
char *pool_strdup(struct pool *p, const char *str);
char *pool_strndup(struct pool *p, const char *str, size_t n);
static inline void *pool_zalloc(struct pool *p, size_t s) {
static inline void *pool_zalloc(struct pool *p, size_t s)
{
void *ptr = pool_alloc(p, s);
if (ptr)
@@ -118,4 +119,3 @@ static inline void *pool_zalloc(struct pool *p, size_t s) {
}
#endif

View File

@@ -8,10 +8,37 @@
#ifndef _LVM_XLATE_H
#define _LVM_XLATE_H
#include <asm/byteorder.h>
#define xlate16(x) __cpu_to_le16((x))
#define xlate32(x) __cpu_to_le32((x))
#define xlate64(x) __cpu_to_le64((x))
#ifdef linux
# include <asm/byteorder.h>
# define xlate16(x) __cpu_to_le16((x))
# define xlate32(x) __cpu_to_le32((x))
# define xlate64(x) __cpu_to_le64((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
# if BYTE_ORDER == LITTLE_ENDIAN
# define xlate16(x) (x)
# define xlate32(x) (x)
# define xlate64(x) (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)
# endif
#endif
#endif

View File

@@ -10,8 +10,6 @@
#include "ttree.h"
#include "bitset.h"
#include <assert.h>
struct dfa_state {
int final;
struct dfa_state *lookup[256];
@@ -25,7 +23,8 @@ struct state_queue {
struct matcher { /* Instance variables for the lexer */
struct dfa_state *start;
int num_nodes, nodes_entered;
unsigned num_nodes;
int nodes_entered;
struct rx_node **nodes;
struct pool *scratch, *mem;
};
@@ -184,7 +183,7 @@ static struct state_queue *_create_state_queue(struct pool *mem,
static int _calc_states(struct matcher *m, struct rx_node *rx)
{
int iwidth = (m->num_nodes / BITS_PER_INT) + 1;
unsigned iwidth = (m->num_nodes / BITS_PER_INT) + 1;
struct ttree *tt = ttree_create(m->scratch, iwidth);
struct state_queue *h, *t, *tmp;
struct dfa_state *dfa, *ldfa;
@@ -260,10 +259,12 @@ static int _calc_states(struct matcher *m, struct rx_node *rx)
return 1;
}
struct matcher *matcher_create(struct pool *mem, const char **patterns, int num)
struct matcher *matcher_create(struct pool *mem, const char **patterns,
unsigned num)
{
char *all, *ptr;
int i, len = 0;
int i;
size_t len = 0;
struct rx_node *rx;
struct pool *scratch = pool_create(10 * 1024);
struct matcher *m;
@@ -328,10 +329,10 @@ struct matcher *matcher_create(struct pool *mem, const char **patterns, int num)
return NULL;
}
static inline struct dfa_state *_step_matcher(unsigned char c,
static inline struct dfa_state *_step_matcher(int c,
struct dfa_state *cs, int *r)
{
if (!(cs = cs->lookup[c]))
if (!(cs = cs->lookup[(unsigned char) c]))
return NULL;
if (cs->final && (cs->final > *r))

View File

@@ -10,8 +10,8 @@
#include "pool.h"
struct matcher;
struct matcher *matcher_create(struct pool *mem,
const char **patterns, int num);
struct matcher *matcher_create(struct pool *mem, const char **patterns,
unsigned num);
int matcher_run(struct matcher *m, const char *begin);

View File

@@ -24,7 +24,7 @@ enum {
* start and end of a string.
*/
#define HAT_CHAR 0x2
#define DOLLAR_CHAR 0x2
#define DOLLAR_CHAR 0x3
struct rx_node {
int type;

View File

@@ -20,7 +20,7 @@ struct ttree {
struct node *root;
};
struct node **_lookup_single(struct node **c, unsigned int k)
static struct node **_lookup_single(struct node **c, unsigned int k)
{
while (*c) {
if (k < (*c)->k)

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