1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-24 21:44:22 +03:00

Compare commits

...

161 Commits

Author SHA1 Message Date
Alasdair Kergon
bab349047d updates for release 2004-03-31 20:14:02 +00:00
Alasdair Kergon
28ea6b8de8 update text for release 2004-03-31 20:09:56 +00:00
Alasdair Kergon
9d51bbdae8 Update VERSION 2004-03-31 19:12:17 +00:00
Alasdair Kergon
d622f79533 Add 2.4 support for DM_LIST_VERSIONS (dmsetup targets).
Rebaseline patches to 2.4.26-rc1.
2004-03-31 18:54:17 +00:00
Alasdair Kergon
04c8515ad1 Missing dev_close_all()s 2004-03-31 18:41:39 +00:00
Alasdair Kergon
53bc4251d1 Update changelog. 2004-03-30 20:33:26 +00:00
Alasdair Kergon
a5a751f02f Example cmdlib program. 2004-03-30 19:54:59 +00:00
Alasdair Kergon
66ed5f82c4 Update copyright notices. 2004-03-30 19:35:44 +00:00
Alasdair Kergon
c802a9e6aa Update changelog. 2004-03-30 19:12:42 +00:00
Alasdair Kergon
880f210946 Update copyright messages. 2004-03-30 19:08:57 +00:00
Alasdair Kergon
4f9f7eb6a6 Fix vgmknodes to remove dud /dev/mapper entries 2004-03-30 14:40:03 +00:00
Alasdair Kergon
f910c4a8e7 Rename dev_manager_mknodes -> dev_manager_lv_mknodes etc. 2004-03-30 14:38:57 +00:00
Alasdair Kergon
529686d965 spelling corrections 2004-03-30 14:36:50 +00:00
Alasdair Kergon
84dfd1536f vgdisplay_colons 2004-03-30 14:35:40 +00:00
Alasdair Kergon
85dedc324c Move full mknodes functionality from dmsetup into libdevmapper. 2004-03-30 14:31:58 +00:00
Alasdair Kergon
d639237411 and another typo 2004-03-26 21:49:57 +00:00
Alasdair Kergon
449aaf75f1 typo 2004-03-26 21:47:43 +00:00
Alasdair Kergon
b1fda66caa missing definition 2004-03-26 21:46:01 +00:00
Alasdair Kergon
66a8e90fd9 lvchange --refresh 2004-03-26 21:24:03 +00:00
Alasdair Kergon
37b487d191 tweak memlock includes 2004-03-26 21:11:34 +00:00
Alasdair Kergon
6c59fe3577 Add string display to mem leak dump. 2004-03-26 21:09:44 +00:00
Alasdair Kergon
1cbb70c992 indent 2004-03-26 21:07:30 +00:00
Alasdair Kergon
e06b39f882 move lock_lvs; add lock memlock code 2004-03-26 20:49:35 +00:00
Alasdair Kergon
2602b1493e LV allocation variable renaming 2004-03-26 20:35:14 +00:00
Alasdair Kergon
989d14502d Add locking flags + memlock option. 2004-03-26 20:17:11 +00:00
Alasdair Kergon
f78a550282 makefile spacing 2004-03-26 20:03:58 +00:00
Alasdair Kergon
54a1abb284 Add list_versions to library 2004-03-26 19:52:09 +00:00
Alasdair Kergon
97b492a8e2 Ignore open hidden LVs when checking if deactivation is OK. 2004-03-26 19:13:39 +00:00
Alasdair Kergon
0873bd14a9 Suppress move percentage when inactive 2004-03-26 19:10:48 +00:00
Alasdair Kergon
eff6ba429a Tidy sysfs includes 2004-03-26 18:54:55 +00:00
Alasdair Kergon
8c18064be4 indent 2004-03-26 15:46:37 +00:00
Alasdair Kergon
44a1ac0cf3 lv_info_by_lvid 2004-03-26 15:35:01 +00:00
Alasdair Kergon
28dc8d88dd cmdlib prototypes 2004-03-26 14:56:41 +00:00
Alasdair Kergon
2c0c2b64ba .export.sym generation 2004-03-26 14:51:23 +00:00
Alasdair Kergon
bd3e0f5248 cmdlib logging function 2004-03-26 14:47:14 +00:00
Alasdair Kergon
cd52d98938 update configure for cmdlib 2004-03-26 14:17:14 +00:00
Alasdair Kergon
894c70e7f8 Update makefiles (incl. cmdlib). 2004-03-26 13:21:12 +00:00
Alasdair Kergon
51d70c2edd Rename some files to avoid duplicate filenames in tree. 2004-03-26 12:25:15 +00:00
Alasdair Kergon
7d4b355240 Add cmdlib code. 2004-03-26 12:21:24 +00:00
Alasdair Kergon
3b56193b98 Add --nolocking option for read operations if locking is failing/unavailable. 2004-03-26 12:09:33 +00:00
Alasdair Kergon
b16045b57d Move main() into separate file. 2004-03-26 12:00:24 +00:00
Alasdair Kergon
9e8b0fca5b Indent; _init -> _init_lvm 2004-03-26 11:49:07 +00:00
Alasdair Kergon
35cf1b3b5b Rebaseline internal verbose level. 2004-03-26 11:45:01 +00:00
Alasdair Kergon
83f788af57 Document metadata tagging. 2004-03-22 15:08:50 +00:00
Alasdair Kergon
2ffe378d3f Only print warning message once when compiled without libdevmapper. 2004-03-19 16:26:46 +00:00
Alasdair Kergon
38b33a4a5e Fix lvreduce pv extents calculations. 2004-03-19 16:19:41 +00:00
Alasdair Kergon
60bf9ed0a0 Avoid sscanf %as for uClibc 2004-03-19 15:52:22 +00:00
Alasdair Kergon
16adf4de1b Fix DESTDIR with configure path overrides. 2004-03-17 19:37:44 +00:00
Alasdair Kergon
80de983023 additional activation functions 2004-03-08 18:54:13 +00:00
Alasdair Kergon
8703ca623f rename config file vars & always use / as separator 2004-03-08 18:28:45 +00:00
Alasdair Kergon
286253a73f host tags 2004-03-08 18:13:22 +00:00
Alasdair Kergon
bd806a41df move hostname into global 2004-03-08 17:25:59 +00:00
Alasdair Kergon
b89c4e9002 tagging 2004-03-08 17:19:15 +00:00
Alasdair Kergon
6dbf31c0c3 More str_list fns. 2004-03-08 15:23:01 +00:00
Alasdair Kergon
060c45d8a1 Fix (rare) bug in recognition of long argument forms. 2004-03-08 13:54:45 +00:00
Alasdair Kergon
33d3e82e4d Detailed changelog. 2004-02-27 22:36:13 +00:00
Alasdair Kergon
4bb074514d Update man page incl. 'targets', event_nr. 2004-02-27 19:36:49 +00:00
Alasdair Kergon
e3f8892003 more syncing with lvm2 build process 2004-02-24 19:23:28 +00:00
Alasdair Kergon
9d00ad5f18 Extract log.h and tweak funcs to be like lvm2 ones. 2004-02-24 18:50:09 +00:00
Alasdair Kergon
dae4344850 more makefile syncing 2004-02-24 18:46:20 +00:00
Alasdair Kergon
aa7f3fabe2 File missed from last checkin. 2004-02-18 13:06:21 +00:00
Alasdair Kergon
f93434a8ce Basic internationalisation support. 2004-02-13 22:56:45 +00:00
Alasdair Kergon
25dee56be9 Don't recurse symlinked dirs such as /dev/fd on 2.6. 2004-02-13 18:55:43 +00:00
Alasdair Kergon
ce9a3f3797 Update autoconf files 2004-02-13 16:00:22 +00:00
Alasdair Kergon
11e384920a don't inline pool_zalloc(); lift duplicated pool_str(n)dup to pool.c 2004-02-13 15:38:54 +00:00
Alasdair Kergon
a0a1f1e536 Don't inline hash _find 2004-02-13 15:36:58 +00:00
Alasdair Kergon
3b3d0ea9eb Sysfs block device filtering option for 2.6. 2004-02-13 14:46:04 +00:00
Alasdair Kergon
2f4d78286d split_words() 2004-02-13 14:43:35 +00:00
Alasdair Kergon
677dc6f985 Update CVS info for move to sources.redhat.com. 2004-02-10 15:26:51 +00:00
Alasdair Kergon
d52057e732 Static build too. 2004-01-28 03:40:31 +00:00
Alasdair Kergon
fa2a1cb1fb Define BLKGETSIZE64 on systems with out-of-date header files. 2004-01-27 20:53:57 +00:00
Alasdair Kergon
19a0fb04ad Userspace support for LIST_VERSIONS ioctl. 2004-01-23 14:37:47 +00:00
Alasdair Kergon
947352f2fe Add event number arg to dmsetup wait. 2004-01-23 14:09:33 +00:00
Alasdair Kergon
adcbedb686 Document that sector size is always 512 bytes. [AJ] 2004-01-23 14:08:09 +00:00
Alasdair Kergon
7732f92acd pv/vgchange --uuid to change (non-random) UUIDs to random values 2004-01-13 18:42:05 +00:00
Alasdair Kergon
ad8a001688 If PV/VG uuids are missing, generate them from the pv/vg numbers.
[This situation could occur if the uuids were oritinally created by
LVM1 on a system without /dev/urandom.]
2004-01-09 19:18:20 +00:00
Alasdair Kergon
9121eada08 Log full details when "VG data differs between PVs" error message occurs. 2004-01-02 14:04:44 +00:00
Alasdair Kergon
49bd4d25a2 Option to revert to default logging function after using a custom one. 2003-12-21 16:08:20 +00:00
Alasdair Kergon
d80b4129c6 Change pvscan to show total of usable device size (instead of free data space). 2003-12-09 22:32:47 +00:00
Alasdair Kergon
7edb4172d5 Remove undocumented -m abbreviation. 2003-12-09 22:17:17 +00:00
Alasdair Kergon
c3a4677990 Relax restriction on pe_start location when re-writing LVM1 metadata. 2003-12-09 17:51:39 +00:00
Alasdair Kergon
5cbb893a3b Fix support for PVs on read only devices. [Still must set LVs read only] 2003-11-21 19:54:40 +00:00
Alasdair Kergon
f28a2a432b dumpconfig 2003-11-21 19:53:05 +00:00
Alasdair Kergon
03b75a2d27 Don't remove mirror LV until after other LVs reloaded. 2003-11-20 16:22:04 +00:00
Alasdair Kergon
859fe69083 Update dmsetup man. 2003-11-17 14:24:22 +00:00
Alasdair Kergon
f6f2205ddb Ready for another release. 2003-11-14 23:46:49 +00:00
Alasdair Kergon
0f9a03ef61 lvcreate should close the initialised snapshot device immediately. 2003-11-14 17:55:39 +00:00
Alasdair Kergon
9aa417c084 Add/update some man pages. 2003-11-14 16:17:55 +00:00
Alasdair Kergon
7b70952f5d vgscan --mknodes 2003-11-14 14:03:48 +00:00
Alasdair Kergon
edd3d07b49 Fix dev_zero() offset. 2003-11-13 23:55:03 +00:00
Alasdair Kergon
5293d0a4ec Immediate error on big memory allocations when --enable-debug. 2003-11-13 23:54:02 +00:00
Alasdair Kergon
3c8c7beae1 Missing include. 2003-11-13 18:47:22 +00:00
Alasdair Kergon
9c3ba9fdcd vgmknodes also creates necessary nodes in /dev/mapper 2003-11-13 14:11:41 +00:00
Alasdair Kergon
fb1748fb0f dmsetup mknodes 2003-11-13 13:14:28 +00:00
Alasdair Kergon
0a109fbd03 The LVM2 part of vgmknodes [still to do the non-devfs device-mapper bit]. 2003-11-12 19:16:48 +00:00
Alasdair Kergon
5cf64db74e Accept tables from stdin with dmsetup.
Update autoconf.
2003-11-12 17:30:32 +00:00
Alasdair Kergon
488cc94f36 Exclude v1 compatibility code when configured with --disable-compat
[Use this with 2.6 kernels + device-mapper V4 interface]
CVS ----------------------------------------------------------------------
2003-11-10 21:06:16 +00:00
Alasdair Kergon
e15846bf79 Default to unlimited number of LVs/PVs in lvm2 format. 2003-11-06 20:33:34 +00:00
Alasdair Kergon
752bd00674 Prevent PV allocation bit getting changed for format_text orphans. 2003-11-06 20:15:13 +00:00
Alasdair Kergon
7fadfcbe32 Fix vgremove 'all OK' check 2003-11-06 17:16:22 +00:00
Alasdair Kergon
41141e75bb Configuration-time O_DIRECT setting. 2003-11-06 17:14:06 +00:00
Alasdair Kergon
50f641e627 Add drbd. 2003-11-06 17:10:35 +00:00
Alasdair Kergon
c7883fd093 Fit locking bits into 1 byte. 2003-11-06 17:08:18 +00:00
Alasdair Kergon
4fcb24b2b1 Ban vgcreate -s 0 2003-11-06 17:07:19 +00:00
Alasdair Kergon
5003557935 Fix pvchange segfault with orphans. 2003-11-06 17:06:06 +00:00
Alasdair Kergon
bdf1ba84da Don't trigger error if changing PV allocation to the state it already is. 2003-11-06 17:04:35 +00:00
Alasdair Kergon
b0b4def983 Cope better with LVM1 minor numbers & LV numbers. 2003-11-06 16:58:38 +00:00
Alasdair Kergon
cc184bbe9e Fix exported format1 VG recognition. 2003-10-21 22:21:41 +00:00
Alasdair Kergon
ad30c830aa More consistent error code usage. 2003-10-21 22:06:07 +00:00
Alasdair Kergon
1d791a8af4 Check no fs mounted before deactivating. 2003-10-21 22:00:36 +00:00
Alasdair Kergon
e63c51cd97 Inherit CFLAGS at make time 2003-10-21 21:59:42 +00:00
Alasdair Kergon
f202e32908 Dump active configuration 2003-10-15 20:19:43 +00:00
Alasdair Kergon
26e1a08e82 dumpconfig to dump active configuration 2003-10-15 20:17:19 +00:00
Alasdair Kergon
4d5119d435 relax a scanning restriction 2003-10-15 20:10:11 +00:00
Alasdair Kergon
75e34ea62e Fix >32bit lvcreate size calculation. 2003-10-15 20:07:55 +00:00
Alasdair Kergon
0a183d6274 Prevent creation of MDA bigger than disk. 2003-10-15 20:06:37 +00:00
Alasdair Kergon
21d8060aea Don't forget to set 64-bit arg values too. 2003-10-15 20:05:30 +00:00
Alasdair Kergon
9cbe906f60 more str_list fns 2003-10-15 20:04:29 +00:00
Alasdair Kergon
8ce4137399 macro changes 2003-10-15 20:02:46 +00:00
Alasdair Kergon
5f8a139347 str_list_del 2003-10-15 20:01:12 +00:00
Alasdair Kergon
9bb009a3fe Extract some common functions. 2003-09-17 20:35:57 +00:00
Alasdair Kergon
726d65923f Update to incorporate most of version 4 interface changes. 2003-09-17 13:23:49 +00:00
Alasdair Kergon
8a6be4cb2d Remove incorrect comments. 2003-09-16 16:23:21 +00:00
Alasdair Kergon
10b06beb8e out-of-date 2003-09-16 16:18:50 +00:00
Alasdair Kergon
81318c7968 Update 2003-09-16 16:15:07 +00:00
Alasdair Kergon
47a2c1c6e5 Fix read-only snapshot creation. 2003-09-16 16:08:05 +00:00
Alasdair Kergon
39cee65c6b Make dev_name optional to show details for all devices.
e.g. 'dmsetup info', 'dmsetup status -v', 'dmsetup table'
2003-09-16 14:13:51 +00:00
Alasdair Kergon
8582ec724e Improve segment merge/split code. 2003-09-15 18:22:50 +00:00
Alasdair Kergon
b0139682e8 Don't install the pvdata stub; update built-in mesg. 2003-09-15 15:05:23 +00:00
Alasdair Kergon
d39c475a6d Ensure more args aren't negative. 2003-09-15 15:04:39 +00:00
Alasdair Kergon
48f38354c6 Missing vg_commit() 2003-09-15 15:03:54 +00:00
Alasdair Kergon
cd5a920ed5 vgcfgrestore -l lists backup file too 2003-09-15 15:03:22 +00:00
Alasdair Kergon
71bc1f378d Prevent cmdline flags that take args getting repeated. 2003-09-15 15:02:24 +00:00
Alasdair Kergon
0ee6c31cff Missing ] in pvmove usage display 2003-09-15 15:01:36 +00:00
Alasdair Kergon
af89a9971e Generalise 'invalid chars' error mesg to just say 'invalid' 2003-09-15 15:01:00 +00:00
Alasdair Kergon
c718a8ef72 Correct order of consistency/exists checks. 2003-09-15 15:00:01 +00:00
Alasdair Kergon
8c8ad0faf0 Don't use !# in randomly-generated uuids. 2003-09-15 14:58:43 +00:00
Alasdair Kergon
314d5bbb7f Fix makefile install mesg displayed for man5 2003-09-15 14:57:15 +00:00
Alasdair Kergon
102255757a Additional validation of LV segments read from metadata. [HM] 2003-09-01 19:55:16 +00:00
Alasdair Kergon
914067a0d0 Fix unsafe list iteration in segment merge code. [HM] 2003-08-27 15:30:39 +00:00
Alasdair Kergon
06e3ae2536 Remove unnecessary file. 2003-08-26 21:12:45 +00:00
Alasdair Kergon
7f9b252556 Cope better when format functions are missing. 2003-08-26 21:12:06 +00:00
Alasdair Kergon
3d700e243f Log each command & args. 2003-08-26 21:00:05 +00:00
Alasdair Kergon
bcfc78ce11 Update. 2003-08-20 15:48:46 +00:00
Alasdair Kergon
09241765d5 Some tidyups and minor fixes. 2003-08-20 15:48:27 +00:00
Alasdair Kergon
671c83c265 Remove small hard-coded activation target line parameter limit. 2003-08-20 12:53:57 +00:00
Alasdair Kergon
772d28b766 Also allow pvmove --abort when pvmove mirror not active (e.g. after a reboot). 2003-08-18 17:21:51 +00:00
Alasdair Kergon
c26fcea58d Missing check for inconsistent VG in pvmove. 2003-08-18 13:52:43 +00:00
Alasdair Kergon
1e5e26dbff update 2003-07-18 00:41:04 +00:00
Alasdair Kergon
742fc54864 Accept signed numbers in config file. 2003-07-15 16:32:20 +00:00
Alasdair Kergon
49738f43c0 update 2003-07-15 01:30:18 +00:00
Alasdair Kergon
9f85f61010 Fix vgimport fix to work outside debug mode. 2003-07-15 01:26:24 +00:00
Alasdair Kergon
239f422039 update 2003-07-13 11:07:50 +00:00
Alasdair Kergon
67af3c37be Fix detection of exported LVM1 volume groups. 2003-07-13 11:07:25 +00:00
Alasdair Kergon
a9442385c4 vsn 2.00.02 (rc3) 2003-07-12 12:02:12 +00:00
Alasdair Kergon
8c9cd10b8b Restrict active lvchange -My with -f 2003-07-11 17:10:19 +00:00
Alasdair Kergon
72542059dd Fix inactive snapshot display. 2003-07-11 17:09:21 +00:00
Alasdair Kergon
a843fc6d40 update 2003-07-05 23:27:17 +00:00
Alasdair Kergon
4beed60c08 Driver version 1 compatibility fix for snapshots. 2003-07-05 23:24:10 +00:00
Alasdair Kergon
4049c1e480 Backwards compatibility fix for version1 suspend/resume. 2003-07-05 23:20:43 +00:00
Alasdair Kergon
8449314da2 Another sync point - numerous fixes & clean ups. 2003-07-04 22:34:56 +00:00
241 changed files with 21680 additions and 6586 deletions

2
BUGS
View File

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

View File

@@ -1,35 +1,45 @@
#
# Copyright (C) 2001 Sistina Software
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This LVM library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
# This file is part of the LVM2.
#
# This LVM library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU Library General Public
# License along with this LVM library; if not, write to the Free
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SUBDIRS = include man lib tools
SUBDIRS = include man
ifeq ("@INTL@", "yes")
SUBDIRS += po
endif
SUBDIRS += lib tools
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS += lib/format1 \
po \
test/mm test/device test/format1 test/regex test/filters
endif
include make.tmpl
lib: include
tools: include lib
tools: lib
po: lib tools
ifeq ("@INTL@", "yes")
lib.pofile: include.pofile
tools.pofile: lib.pofile
po.pofile: lib.pofile tools.pofile
pofile: po.pofile
endif

16
README
View File

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

View File

@@ -1 +1 @@
1.95.17-cvs (2003-04-24)
2.00.09-cvs (2004-03-31)

View File

@@ -1,3 +1,48 @@
Version 2.00.09 - 31 Mar 2004
=============================
Update copyright notices for Red Hat.
Fix vgmknodes to remove dud /dev/mapper entries. (libdevmapper update reqd).
Add LVM1-style colon output to vgdisplay.
lvchange --refresh to reload active LVs.
Add string display to memory leak dump.
Add locking flags & memlock option.
Add list_versions to library.
Ignore open hidden LVs when checking if deactivation is OK.
Suppress move percentage when device inactive.
Add lv_info_by_lvid.
Various tidy-ups to the build process.
Rebaseline internal verbose level.
Add --nolocking option for read operations if locking is failing.
Add option to compile into a library.
When compiled without libdevmapper, only print warning message once.
Fix lvreduce PV extent calculations.
Fix DESTDIR to work with configure path overrides.
Always use / as config file separator & rename internal config file variables.
Add support for tagging PV/VG/LVs and hosts.
Fix rare bug in recognition of long cmdline argument forms.
Add basic internationalisation infrastructure.
Don't recurse symlinked dirs such as /dev/fd on 2.6 kernels.
Update autoconf files.
Add sysfs block device filtering for 2.6 kernels.
Update refs for move to sources.redhat.com.
Friday 14th November 2003
=========================
Some bug fixes & minor enhancements, including:
Backwards compatibility with LVM1 metadata improved.
Missing man pages written.
Tool error codes made more consistent.
vgmknodes written.
O_DIRECT can be turned off if it doesn't work in your kernel.
dumpconfig to display the active configuration file
You need to update libdevmapper before using 'vgmknodes' or 'vgscan --mknodes'.
If your root filesystem is on an LV, you should run one of those two
commands to fix up the special files in /dev in your real root filesystem
after finishing with your initrd. Also, remember you can use
'vgchange --ignorelockingfailure' on your initrd if the tool fails because
it can't write a lock file to a read-only filesystem.
Wednesday 30th April 2003
=========================
A pvmove implementation is now available for the new metadata format.
@@ -25,6 +70,7 @@ to provide us with diagnostic information:
log {
file="/tmp/lvm2.log"
level=7
activation=1
}
You should schedule regular backups of your configuration file and
@@ -74,7 +120,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
@@ -91,6 +137,3 @@ Display output. Some metadata information cannot yet be displayed.
Recovery tools to salvage "lost" metadata directly from the disks:
but we hope the new format will mean such tools are hardly ever needed!
pvmove will be enhanced to remove the volume group lock so that you can
run other commands alongside.

22
WHATS_NEW_DM Normal file
View File

@@ -0,0 +1,22 @@
Version 1.00.09 - 31 Mar 2004
=============================
Update copyright notices to Red Hat.
Move full mknodes functionality from dmsetup into libdevmapper.
Avoid sscanf %as for uClibc compatibility.
Cope if DM_LIST_VERSIONS is not defined.
Add DM_LIST_VERSIONS functionality to kernel patches.
Generate new kernel patches for 2.4.26-rc1.
Version 1.00.08 - 27 Feb 2004
=============================
Added 'dmsetup targets'.
Added event_nr support to 'dmsetup wait'.
Updated dmsetup man page.
Allow logging function to be reset to use internal one.
Bring log macros in line with LVM2 ones.
Added 'make install_static_lib' which installs libdevmapper.a.
Made configure/makefiles closer to LVM2 versions.
Fixed DESTDIR for make install/install_static_lib.
Updated README/INSTALL to reflect move to sources.redhat.com.
Updated autoconf files to 2003-06-17.

537
autoconf/config.guess vendored
View File

@@ -1,9 +1,9 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2001-09-04'
timestamp='2003-06-17'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -24,8 +24,9 @@ timestamp='2001-09-04'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Written by Per Bothner <bothner@cygnus.com>.
# Please send patches to <config-patches@gnu.org>.
# Originally written by Per Bothner <per@bothner.com>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
@@ -87,30 +88,42 @@ if test $# != 0; then
exit 1
fi
trap 'exit 1' 1 2 15
dummy=dummy-$$
trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# CC_FOR_BUILD -- compiler used by this script.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int dummy(){}" > $dummy.c ;
for c in cc gcc c89 ; do
($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
if test $? = 0 ; then
# Portable tmp directory creation inspired by the Autoconf team.
set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int x;" > $dummy.c ;
for c in cc gcc c89 c99 ; do
if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
rm -f $dummy.c $dummy.o $dummy.rel ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac'
esac ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
@@ -127,29 +140,30 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# Netbsd (nbsd) targets should (where applicable) match one or
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
# Determine the machine/vendor (is the vendor relevant).
case "${UNAME_MACHINE}" in
amiga) machine=m68k-unknown ;;
arm32) machine=arm-unknown ;;
atari*) machine=m68k-atari ;;
sun3*) machine=m68k-sun ;;
mac68k) machine=m68k-apple ;;
macppc) machine=powerpc-apple ;;
hp3[0-9][05]) machine=m68k-hp ;;
ibmrt|romp-ibm) machine=romp-ibm ;;
*) machine=${UNAME_MACHINE}-unknown ;;
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE}" in
i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
case "${UNAME_MACHINE_ARCH}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
@@ -166,75 +180,112 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# The OS release
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
case "${UNAME_VERSION}" in
Debian*)
release='-gnu'
;;
*)
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
macppc:OpenBSD:*:*)
echo powerpc-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme88k:OpenBSD:*:*)
echo m88k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvmeppc:OpenBSD:*:*)
echo powerpc-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
pmax:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sgi:OpenBSD:*:*)
echo mipseb-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sun3:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
wgrisc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
fi
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
UNAME_MACHINE="alpha" ;;
"EV4.5 (21064)")
UNAME_MACHINE="alpha" ;;
"LCA4 (21066/21068)")
UNAME_MACHINE="alpha" ;;
"EV5 (21164)")
UNAME_MACHINE="alphaev5" ;;
"EV5.6 (21164A)")
UNAME_MACHINE="alphaev56" ;;
"EV5.6 (21164PC)")
UNAME_MACHINE="alphapca56" ;;
"EV5.7 (21164PC)")
UNAME_MACHINE="alphapca57" ;;
"EV6 (21264)")
UNAME_MACHINE="alphaev6" ;;
"EV6.7 (21264A)")
UNAME_MACHINE="alphaev67" ;;
"EV6.8CB (21264C)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8AL (21264B)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8CX (21264D)")
UNAME_MACHINE="alphaev68" ;;
"EV6.9A (21264/EV69A)")
UNAME_MACHINE="alphaev69" ;;
"EV7 (21364)")
UNAME_MACHINE="alphaev7" ;;
"EV7.9 (21364A)")
UNAME_MACHINE="alphaev79" ;;
esac
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
cat <<EOF >$dummy.s
.data
\$Lformat:
.byte 37,100,45,37,120,10,0 # "%d-%x\n"
.text
.globl main
.align 4
.ent main
main:
.frame \$30,16,\$26,0
ldgp \$29,0(\$27)
.prologue 1
.long 0x47e03d80 # implver \$0
lda \$2,-1
.long 0x47e20c21 # amask \$2,\$1
lda \$16,\$Lformat
mov \$0,\$17
not \$1,\$18
jsr \$26,printf
ldgp \$29,0(\$26)
mov 0,\$16
jsr \$26,exit
.end main
EOF
eval $set_cc_for_build
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
case `./$dummy` in
0-0)
UNAME_MACHINE="alpha"
;;
1-0)
UNAME_MACHINE="alphaev5"
;;
1-1)
UNAME_MACHINE="alphaev56"
;;
1-101)
UNAME_MACHINE="alphapca56"
;;
2-303)
UNAME_MACHINE="alphaev6"
;;
2-307)
UNAME_MACHINE="alphaev67"
;;
2-1307)
UNAME_MACHINE="alphaev68"
;;
esac
fi
rm -f $dummy.s $dummy
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit 0 ;;
Alpha*:OpenVMS:*:*)
echo alpha-hp-vms
exit 0 ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@@ -247,29 +298,11 @@ EOF
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit 0;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit 0 ;;
arc64:OpenBSD:*:*)
echo mips64el-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
hkmips:OpenBSD:*:*)
echo mips-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
pmax:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sgi:OpenBSD:*:*)
echo mips-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
wgrisc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
*:[Mm]orph[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-morphos
exit 0 ;;
*:OS/390:*:*)
echo i370-ibm-openedition
@@ -291,6 +324,13 @@ EOF
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
DRS?6000:unix:4.0:6*)
echo sparc-icl-nx6
exit 0 ;;
DRS?6000:UNIX_SV:4.2*:7*)
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7 && exit 0 ;;
esac ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
@@ -319,7 +359,7 @@ EOF
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
@@ -333,12 +373,6 @@ EOF
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
sparc*:NetBSD:*)
echo `uname -p`-unknown-netbsd${UNAME_RELEASE}
exit 0 ;;
atari*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
@@ -365,18 +399,6 @@ EOF
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
sun3*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme88k:OpenBSD:*:*)
echo m88k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
@@ -415,15 +437,20 @@ EOF
exit (-1);
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy \
&& ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
$CC_FOR_BUILD -o $dummy $dummy.c \
&& $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& exit 0
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
exit 0 ;;
Motorola:*:4.3:PL8-*)
echo powerpc-harris-powermax
exit 0 ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
echo powerpc-harris-powermax
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
@@ -496,8 +523,7 @@ EOF
exit(0);
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
@@ -506,7 +532,7 @@ EOF
fi
exit 0 ;;
*:AIX:*:[45])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
@@ -546,10 +572,8 @@ EOF
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
case "${HPUX_REV}" in
11.[0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
@@ -558,13 +582,13 @@ EOF
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
fi ;;
esac
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
@@ -597,11 +621,21 @@ EOF
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
rm -f $dummy.c $dummy
fi ;;
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
if [ ${HP_ARCH} = "hppa2.0w" ]
then
# avoid double evaluation of $set_cc_for_build
test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
then
HP_ARCH="hppa2.0w"
else
HP_ARCH="hppa64"
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
ia64:HP-UX:*:*)
@@ -635,8 +669,7 @@ EOF
exit (0);
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
@@ -664,9 +697,6 @@ EOF
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
hppa*:OpenBSD:*:*)
echo hppa-unknown-openbsd
exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
@@ -685,9 +715,6 @@ EOF
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
CRAY*X-MP:*:*:*)
echo xmp-cray-unicos
exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
@@ -700,27 +727,21 @@ EOF
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*T3D:*:*:*)
echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
*:UNICOS/mp:*:*)
echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
@@ -730,11 +751,19 @@ EOF
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
*:FreeBSD:*:*|*:GNU/FreeBSD:*:*)
# Determine whether the default compiler uses glibc.
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <features.h>
#if __GLIBC__ >= 2
LIBC=gnu
#else
LIBC=
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
exit 0 ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
@@ -745,11 +774,17 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit 0 ;;
x86:Interix*:[34]*)
echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
exit 0 ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit 0 ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i386-pc-interix
echo i586-pc-interix
exit 0 ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
@@ -769,17 +804,52 @@ EOF
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
cris:Linux:*:*)
echo cris-axis-linux-gnu
exit 0 ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
mips:Linux:*:*)
case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
big) echo mips-unknown-linux-gnu && exit 0 ;;
little) echo mipsel-unknown-linux-gnu && exit 0 ;;
esac
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips
#undef mipsel
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mipsel
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
;;
mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips64
#undef mips64el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mips64el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips64
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
@@ -815,6 +885,9 @@ EOF
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit 0 ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
@@ -828,7 +901,8 @@ EOF
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
ld_supported_targets=`cd /; ld --help 2>&1 \
# Set LC_ALL=C to ensure ld outputs messages in English.
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
@@ -840,7 +914,7 @@ EOF
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit 0 ;;
exit 0 ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit 0 ;;
@@ -852,32 +926,28 @@ EOF
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
cat >$dummy.c <<EOF
#include <features.h>
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
printf ("%s-pc-linux-gnu\n", argv[1]);
# else
printf ("%s-pc-linux-gnulibc1\n", argv[1]);
# endif
# else
printf ("%s-pc-linux-gnulibc1\n", argv[1]);
# endif
#else
printf ("%s-pc-linux-gnuaout\n", argv[1]);
#endif
return 0;
}
sed 's/^ //' << EOF >$dummy.c
#include <features.h>
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
LIBC=gnu
# else
LIBC=gnulibc1
# endif
# else
LIBC=gnulibc1
# endif
#else
#ifdef __INTEL_COMPILER
LIBC=gnu
#else
LIBC=gnuaout
#endif
#endif
EOF
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
;;
i*86:DYNIX/ptx:4*:*)
@@ -894,6 +964,23 @@ EOF
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit 0 ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
exit 0 ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
exit 0 ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit 0 ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit 0 ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
@@ -915,22 +1002,19 @@ EOF
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit 0 ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -954,9 +1038,15 @@ EOF
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
mc68k:UNIX:SYSTEM5:3.51m)
echo m68k-convergent-sysv
exit 0 ;;
M680?0:D-NIX:5.3:*)
echo m68k-diab-dnix
exit 0 ;;
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
@@ -973,9 +1063,6 @@ EOF
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
@@ -1047,6 +1134,9 @@ EOF
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit 0 ;;
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit 0 ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
@@ -1054,18 +1144,24 @@ EOF
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Darwin:*:*)
echo `uname -p`-apple-darwin${UNAME_RELEASE}
case `uname -p` in
*86) UNAME_PROCESSOR=i686 ;;
powerpc) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit 0 ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
if test "${UNAME_MACHINE}" = "x86pc"; then
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
echo `uname -p`-${UNAME_MACHINE}-nto-qnx
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
exit 0 ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit 0 ;;
NSR-[KW]:NONSTOP_KERNEL:*:*)
NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;;
*:NonStop-UX:*:*)
@@ -1088,11 +1184,6 @@ EOF
fi
echo ${UNAME_MACHINE}-unknown-plan9
exit 0 ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
exit 0 ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
exit 0 ;;
@@ -1111,11 +1202,8 @@ EOF
*:ITS:*:*)
echo pdp10-unknown-its
exit 0 ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
exit 0 ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE}
exit 0 ;;
esac
@@ -1237,8 +1325,7 @@ main ()
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
# Apollos put the system type in the environment.

303
autoconf/config.sub vendored
View File

@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2001-09-07'
timestamp='2003-06-17'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -29,7 +29,8 @@ timestamp='2001-09-07'
# 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>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@@ -117,7 +118,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -226,32 +227,44 @@ case $basic_machine in
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dsp16xx \
| fr30 \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k \
| m32r | m68000 | m68k | m88k | mcore \
| mips16 | mips64 | mips64el | mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el | mips64vr4300 \
| mips64vr4300el | mips64vr5000 | mips64vr5000el \
| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
| mipsisa32 \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64vr | mips64vrel \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| msp430 \
| ns16k | ns32k \
| openrisc \
| openrisc | or32 \
| 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 \
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale \
| x86 | xscale | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
@@ -278,38 +291,55 @@ case $basic_machine in
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alphapca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armv*-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c54x-* \
| clipper-* | cray2-* | cydra-* \
| d10v-* | d30v-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | fx80-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* \
| m32r-* \
| m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
| m68000-* | m680[012346]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-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64vr-* | mips64vrel-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| msp430-* \
| none-* | np1-* | nv1-* | 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-* \
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-*)
;;
@@ -343,6 +373,9 @@ case $basic_machine in
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@@ -374,6 +407,10 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -394,16 +431,8 @@ case $basic_machine in
basic_machine=c38-convex
os=-bsd
;;
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
cray2)
basic_machine=cray2-cray
os=-unicos
;;
[cjt]90)
basic_machine=${basic_machine}-cray
cray | j90)
basic_machine=j90-cray
os=-unicos
;;
crds | unos)
@@ -418,6 +447,14 @@ case $basic_machine in
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
@@ -598,14 +635,6 @@ case $basic_machine in
basic_machine=m68k-atari
os=-mint
;;
mipsel*-linux*)
basic_machine=mipsel-unknown
os=-linux-gnu
;;
mips*-linux*)
basic_machine=mips-unknown
os=-linux-gnu
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
@@ -620,6 +649,10 @@ case $basic_machine in
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -692,6 +725,10 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
nv1)
basic_machine=nv1-cray
os=-unicosmp
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -699,6 +736,10 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
or32 | or32-*)
basic_machine=or32-unknown
os=-coff
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
@@ -721,49 +762,55 @@ case $basic_machine in
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen)
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon)
pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
pentiumii | pentium2)
pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-*)
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-*)
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
;;
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/^[^-]*-//'`
;;
@@ -784,10 +831,26 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
@@ -795,7 +858,10 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sparclite-wrs)
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@@ -862,19 +928,35 @@ case $basic_machine in
os=-dynix
;;
t3e)
basic_machine=t3e-cray
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
@@ -899,8 +981,8 @@ case $basic_machine in
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -921,17 +1003,13 @@ 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
;;
xps | xps100)
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
@@ -952,13 +1030,6 @@ case $basic_machine in
op60c)
basic_machine=hppa1.1-oki
;;
mips)
if [ x$os = x-linux-gnu ]; then
basic_machine=mips-unknown
else
basic_machine=mips-mips
fi
;;
romp)
basic_machine=romp-ibm
;;
@@ -978,13 +1049,16 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh3 | sh4 | sh3eb | sh4eb)
sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
cydra)
basic_machine=cydra-cydrome
;;
orion)
@@ -999,10 +1073,6 @@ case $basic_machine in
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
c4x*)
basic_machine=c4x-none
os=-coff
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
@@ -1065,10 +1135,12 @@ case $os in
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos*)
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1080,8 +1152,10 @@ case $os in
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=-nto-qnx
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
@@ -1120,14 +1194,20 @@ case $os in
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
os=-nextstep2
;;
-nsk*)
os=-nsk
@@ -1166,8 +1246,14 @@ case $os in
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-none)
;;
@@ -1200,10 +1286,14 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
pdp11-*)
os=-none
;;
*-dec | vax-*)
@@ -1230,6 +1320,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
@@ -1293,19 +1386,19 @@ case $basic_machine in
*-next)
os=-nextstep3
;;
*-gould)
*-gould)
os=-sysv
;;
*-highlevel)
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
*-sgi)
os=-irix
;;
*-siemens)
*-siemens)
os=-sysv4
;;
*-masscomp)
@@ -1377,7 +1470,7 @@ case $basic_machine in
-ptx*)
vendor=sequent
;;
-vxsim* | -vxworks*)
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)

View File

@@ -1,19 +1,38 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
scriptversion=2003-06-13.21
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright 1991 by the Massachusetts Institute of Technology
# Copyright (C) 1994 X Consortium
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
@@ -23,13 +42,11 @@
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
@@ -41,211 +58,229 @@ stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
transformbasename=
transform_arg=
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
src=
dst=
dir_arg=
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
or: $0 -d DIR1 DIR2...
-d) dir_arg=true
shift
continue;;
In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
In the second, create the directory path DIR.
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
Options:
-b=TRANSFORMBASENAME
-c copy source (using $cpprog) instead of moving (using $mvprog).
-d create directories instead of installing files.
-g GROUP $chgrp installed files to GROUP.
-m MODE $chmod installed files to MODE.
-o USER $chown installed files to USER.
-s strip installed files (using $stripprog).
-t=TRANSFORM
--help display this help and exit.
--version display version info and exit.
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
while test -n "$1"; do
case $1 in
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-c) instcmd=$cpprog
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-d) dir_arg=true
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
--help) echo "$usage"; exit 0;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
--version) echo "$0 $scriptversion"; exit 0;;
*) if test -z "$src"; then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
if test -z "$src"; then
echo "$0: no input file specified." >&2
exit 1
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
instcmd=:
chmodcmd=
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test -z "$dst"; then
echo "$0: no destination specified." >&2
exit 1
fi
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
dst=$dst/`basename "$src"`
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# (this part is taken from Noah Friedman's mkinstalldirs script.)
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS
pathcomp=''
pathcomp=
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
test -d "$pathcomp" || $mkdirprog "$pathcomp"
pathcomp=$pathcomp/
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if test -n "$dir_arg"; then
$doit $instcmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if test -z "$transformarg"; then
dstfile=`basename "$dst"`
else
dstfile=`basename "$dst" $transformbasename \
| sed $transformarg`$transformbasename
fi
# If we're going to rename the final executable, determine the name now.
# don't allow the sed command to completely eliminate the filename.
test -z "$dstfile" && dstfile=`basename "$dst"`
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# don't allow the sed command to completely eliminate the filename
# Trap to clean up those temp files at exit.
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Move or copy the file name to the temp name
$doit $instcmd "$src" "$dsttmp" &&
# Make a temp file name in the proper directory.
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
# Now remove or move aside any old file at destination location. We
# try this two ways since rm can't unlink itself on some systems and
# the destination file might be busy for other reasons. In this case,
# the final cleanup might fail but the new file should still install
# successfully.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
fi &&
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

6702
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,3 @@
################################################################################
##
## Copyright 1999-2000 Sistina Software, Inc.
##
@@ -51,7 +50,23 @@ AC_CANONICAL_SYSTEM
case "$host_os" in
linux*)
CFLAGS= ;;
CFLAGS=
CLDFLAGS="-Wl,--version-script,.export.sym"
CLDWHOLEARCHIVE="-Wl,-whole-archive"
CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive"
LD_DEPS=".export.sym"
SOFLAG="-shared"
DEVMAPPER=yes
ODIRECT=yes ;;
darwin*)
CFLAGS="-no-cpp-precomp -fno-common"
CLDFLAGS=
CLDWHOLEARCHIVE="-all_load"
CLDNOWHOLEARCHIVE=
LD_DEPS=
SOFLAG="-dynamiclib"
DEVMAPPER=no
ODIRECT=no ;;
esac
dnl -- prefix is /usr by default, the exec_prefix default is setup later
@@ -89,8 +104,8 @@ 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
dnl Enables staticly-linked tools
AC_ARG_ENABLE(static_link, [ --enable-static_link Use this to link the tools to their libraries
statically. Default is dynamic linking], STATIC_LINK=$enableval, STATIC_LINK=no)
dnl Enable readline
@@ -101,18 +116,42 @@ if test x$READLINE = xyes; then
CFLAGS="$CFLAGS -DREADLINE_SUPPORT"
fi
echo $ac_n "checking whether to enable debugging""... $ac_c" 1>&6
dnl Enable Debugging
AC_ARG_ENABLE(debug, [ --enable-debug Enable debugging], \
DEBUG=yes, DEBUG=no)
echo "$ac_t""$DEBUG" 1>&6
echo $ac_n "checking whether to enable device-mapper""... $ac_c" 1>&6
dnl Disable devmapper
AC_ARG_ENABLE(devmapper, [ --disable-devmapper Disable device-mapper interaction], \
DEVMAPPER=no, DEVMAPPER=yes)
DEVMAPPER=no)
echo "$ac_t""$DEVMAPPER" 1>&6
if test x$DEVMAPPER = xyes; then
CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT"
fi
echo $ac_n "checking whether to enable O_DIRECT""... $ac_c" 1>&6
dnl Disable O_DIRECT
AC_ARG_ENABLE(o_direct, [ --disable-o_direct Disable O_DIRECT], \
ODIRECT=no)
echo "$ac_t""$ODIRECT" 1>&6
if test x$ODIRECT = xyes; then
CFLAGS="$CFLAGS -DO_DIRECT_SUPPORT"
fi
echo $ac_n "checking whether to compile liblvm2cmd.so""... $ac_c" 1>&6
dnl Enable cmdlib
AC_ARG_ENABLE(cmdlib, [ --enable-cmdlib Build shared command library], \
CMDLIB=yes, CMDLIB=no)
echo "$ac_t""$CMDLIB" 1>&6
if test x$CMDLIB = xyes; then
CFLAGS="$CFLAGS -DCMDLIB"
fi
dnl Mess with default exec_prefix
if [[ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]];
then exec_prefix="";
@@ -169,6 +208,28 @@ package as well (which may be called readline-devel or something similar).
fi
echo $ac_n "checking whether to enable internationalisation""... $ac_c" 1>&6
dnl Internationalisation stuff
AC_ARG_ENABLE(nls, [ --enable-nls Enable Native Language Support],\
INTL=yes, INTL=no)
echo "$ac_t""$INTL" 1>&6
if test x$INTL = xyes; then
INTL_PACKAGE="lvm2"
AC_PATH_PROG(MSGFMT, msgfmt)
if [[ "x$MSGFMT" == x ]];
then AC_MSG_ERROR(
msgfmt not found in path $PATH
)
exit
fi;
AC_ARG_WITH(localedir,
[ --with-localedir=DIR Translation files in DIR [PREFIX/share/locale]],
[ LOCALEDIR="$withval" ],
[ LOCALEDIR='${prefix}/share/locale' ])
fi
if test "-f VERSION"; then
LVM_VERSION="\"`cat VERSION`\""
else
@@ -181,11 +242,22 @@ AC_SUBST(LVM1)
AC_SUBST(OWNER)
AC_SUBST(GROUP)
AC_SUBST(CFLAGS)
AC_SUBST(CLDFLAGS)
AC_SUBST(CLDWHOLEARCHIVE)
AC_SUBST(CLDNOWHOLEARCHIVE)
AC_SUBST(LD_DEPS)
AC_SUBST(SOFLAG)
AC_SUBST(LIBS)
AC_SUBST(LVM_VERSION)
AC_SUBST(DEBUG)
AC_SUBST(DEVMAPPER)
AC_SUBST(HAVE_LIBDL)
AC_SUBST(CMDLIB)
AC_SUBST(MSGFMT)
AC_SUBST(LOCALEDIR)
AC_SUBST(INTL_PACKAGE)
AC_SUBST(INTL)
dnl First and last lines should not contain files to generate in order to
dnl keep utility scripts running properly
AC_OUTPUT( \
@@ -195,6 +267,7 @@ include/Makefile \
lib/Makefile \
lib/format1/Makefile \
man/Makefile \
po/Makefile \
tools/Makefile \
tools/version.h \
test/mm/Makefile \
@@ -203,3 +276,10 @@ test/format1/Makefile \
test/regex/Makefile \
test/filters/Makefile \
)
if test x$ODIRECT != xyes; then
echo
echo Warning: O_DIRECT disabled.
echo Use of pvmove may cause machine to lock up under low memory conditions.
echo
fi

View File

@@ -61,6 +61,10 @@ devices {
# List of pairs of additional acceptable block device types found
# in /proc/devices with maximum (non-zero) number of partitions.
# types = [ "fd", 16 ]
# If sysfs is mounted (2.6 kernels) restrict device scanning to
# the block devices it believes are valid.
sysfs_scan = 1
}
# This section that allows you to configure the nature of the
@@ -104,6 +108,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
@@ -202,6 +210,23 @@ activation {
# 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
# If volume_list is defined, each LV is only activated if there is a
# match against the list.
# "vgname" and "vgname/lvname" are matched exactly.
# "@tag" matches any tag set in the LV or VG.
# "@*" matches if any tag defined on the host is also set in the LV or VG
#
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
}
@@ -231,7 +256,8 @@ activation {
# 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

47
doc/example_cmdlib.c Normal file
View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lvm2cmd.h"
/* All output gets passed to this function line-by-line */
void test_log_fn(int level, const char *file, int line, const char *format)
{
/* Extract and process output here rather than printing it */
if (level != 4)
return;
printf("%s\n", format);
return;
}
int main(int argc, char **argv)
{
void *handle;
int r;
lvm2_log_fn(test_log_fn);
handle = lvm2_init();
lvm2_log_level(handle, 1);
r = lvm2_run(handle, "vgs --noheadings vg1");
/* More commands here */
lvm2_exit(handle);
return r;
}

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
@@ -9,24 +9,28 @@
../lib/datastruct/hash.h
../lib/datastruct/list.h
../lib/datastruct/lvm-types.h
../lib/datastruct/str_list.h
../lib/device/dev-cache.h
../lib/device/device.h
../lib/display/display.h
../lib/filters/filter-composite.h
../lib/filters/filter-persistent.h
../lib/filters/filter-regex.h
../lib/filters/filter-sysfs.h
../lib/filters/filter.h
../lib/format1/format1.h
../lib/format1/lvm1-label.h
../lib/format_text/format-text.h
../lib/label/label.h
../lib/locking/locking.h
../lib/log/log.h
../lib/metadata/lv_alloc.h
../lib/metadata/metadata.h
../lib/mm/dbg_malloc.h
../lib/mm/memlock.h
../lib/mm/pool.h
../lib/mm/xlate.h
../lib/misc/crc.h
../lib/misc/intl.h
../lib/misc/lib.h
../lib/misc/lvm-file.h
../lib/misc/lvm-string.h
@@ -34,3 +38,4 @@
../lib/regex/matcher.h
../lib/report/report.h
../lib/uuid/uuid.h
../po/pogen.h

View File

@@ -1,20 +1,16 @@
#
# Copyright (C) 2001 Sistina Software
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This LVM library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
# This file is part of the LVM2.
#
# This LVM library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU Library General Public
# License along with this LVM library; if not, write to the Free
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
SHELL = /bin/sh
@@ -35,9 +31,11 @@ distclean:
find . -maxdepth 1 -type l -exec $(RM) \{\} \;
$(RM) Makefile .include_symlinks .symlinks_created
pofile: all
clean:
install:
.PHONY: clean distclean all install
.PHONY: clean distclean all install pofile

View File

@@ -1,8 +1,16 @@
#
# Copyright (C) 2001 Sistina Software (UK) Limited
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This file is released under the GPL.
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
@@ -12,14 +20,15 @@ ifeq ("@LVM1@", "shared")
SUBDIRS = format1
endif
SOURCES=\
SOURCES =\
activate/activate.c \
cache/cache.c \
cache/lvmcache.c \
commands/toolcontext.c \
config/config.c \
datastruct/bitset.c \
datastruct/btree.c \
datastruct/hash.c \
datastruct/str_list.c \
device/dev-cache.c \
device/dev-io.c \
device/device.c \
@@ -27,6 +36,7 @@ SOURCES=\
filters/filter-composite.c \
filters/filter-persistent.c \
filters/filter-regex.c \
filters/filter-sysfs.c \
filters/filter.c \
format_text/archive.c \
format_text/export.c \
@@ -34,6 +44,7 @@ SOURCES=\
format_text/format-text.c \
format_text/import.c \
format_text/import_vsn1.c \
format_text/tags.c \
format_text/text_label.c \
label/label.c \
locking/file_locking.c \
@@ -49,6 +60,7 @@ SOURCES=\
misc/crc.c \
misc/lvm-file.c \
misc/lvm-string.c \
mm/memlock.c \
mm/pool.c \
regex/matcher.c \
regex/parse_rx.c \
@@ -57,7 +69,7 @@ SOURCES=\
uuid/uuid.c
ifeq ("@LVM1@", "internal")
SOURCES+=\
SOURCES +=\
format1/disk-rep.c \
format1/format1.c \
format1/import-export.c \
@@ -68,28 +80,24 @@ ifeq ("@LVM1@", "internal")
endif
ifeq ("@DEBUG@", "yes")
SOURCES+=\
mm/dbg_malloc.c
SOURCES += mm/dbg_malloc.c
endif
ifeq ("@DEVMAPPER@", "yes")
SOURCES+=\
SOURCES +=\
activate/dev_manager.c \
activate/fs.c
endif
ifeq ("@HAVE_LIBDL@", "yes")
SOURCES+=\
SOURCES +=\
locking/external_locking.c \
misc/sharedlib.c
endif
TARGETS=liblvm.a
LIB_STATIC = liblvm.a
TARGETS = $(LIB_STATIC)
include ../make.tmpl
liblvm.a: $(OBJECTS)
$(RM) $@
$(AR) r $@ $(OBJECTS)
$(RANLIB) $@

View File

@@ -1,30 +1,48 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "metadata.h"
#include "activate.h"
#include "memlock.h"
#include "display.h"
#include "fs.h"
#include "lvm-string.h"
#include "pool.h"
#include "toolcontext.h"
#include "dev_manager.h"
#include "str_list.h"
#include <limits.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.");
static int warned = 0;
if (warned || !act)
return;
log_error("Compiled without libdevmapper support. "
"Can't enable activation.");
warned = 1;
}
int activation(void)
{
@@ -38,15 +56,25 @@ int driver_version(char *version, size_t size)
{
return 0;
}
int target_present(const char *target_name)
{
return 0;
}
int lv_info(const struct logical_volume *lv, struct lvinfo *info)
{
return 0;
}
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
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, float *percent, int wait)
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
uint32_t *event_nr)
{
return 0;
}
@@ -58,10 +86,18 @@ int lvs_in_vg_opened(struct volume_group *vg)
{
return 0;
}
int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
{
return 1;
}
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
{
return 1;
}
int lv_resume(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;
@@ -70,10 +106,29 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
{
return 1;
}
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv)
{
return 1;
}
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
{
return 1;
}
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
{
return 1;
}
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
{
return 1;
}
void activation_exit(void)
{
return;
}
#else /* DEVMAPPER_SUPPORT */
@@ -98,6 +153,86 @@ int activation(void)
return _activation;
}
static int _passes_activation_filter(struct cmd_context *cmd,
struct logical_volume *lv)
{
struct config_node *cn;
struct config_value *cv;
char *str;
char path[PATH_MAX];
if (!(cn = find_config_node(cmd->cft->root, "activation/volume_list"))) {
/* If no hosts tags defined, activate */
if (list_empty(&cmd->tags))
return 1;
/* If any host tag matches any LV or VG tag, activate */
if (str_list_match_list(&cmd->tags, &lv->tags) ||
str_list_match_list(&cmd->tags, &lv->vg->tags))
return 1;
/* Don't activate */
return 0;
}
for (cv = cn->v; cv; cv = cv->next) {
if (cv->type != CFG_STRING) {
log_error("Ignoring invalid string in config file "
"activation/volume_list");
continue;
}
str = cv->v.str;
if (!*str) {
log_error("Ignoring empty string in config file "
"activation/volume_list");
continue;
}
/* Tag? */
if (*str == '@') {
str++;
if (!*str) {
log_error("Ignoring empty tag in config file "
"activation/volume_list");
continue;
}
/* If any host tag matches any LV or VG tag, activate */
if (!strcmp(str, "*")) {
if (str_list_match_list(&cmd->tags, &lv->tags)
|| str_list_match_list(&cmd->tags,
&lv->vg->tags))
return 1;
else
continue;
}
/* If supplied tag matches LV or VG tag, activate */
if (str_list_match_item(&lv->tags, str) ||
str_list_match_item(&lv->vg->tags, str))
return 1;
else
continue;
}
if (!index(str, '/')) {
/* vgname supplied */
if (!strcmp(str, lv->vg->name))
return 1;
else
continue;
}
/* vgname/lvname */
if (lvm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
lv->name) < 0) {
log_error("lvm_snprintf error from %s/%s", lv->vg->name,
lv->name);
continue;
}
if (!strcmp(path, str))
return 1;
}
return 0;
}
int library_version(char *version, size_t size)
{
if (!activation())
@@ -136,10 +271,51 @@ int driver_version(char *version, size_t size)
return r;
}
int target_present(const char *target_name)
{
int r = 0;
struct dm_task *dmt;
struct dm_versions *target, *last_target;
if (!activation())
return 0;
log_very_verbose("Getting target version for %s", target_name);
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) {
stack;
return 0;
}
if (!dm_task_run(dmt)) {
log_debug("Failed to get %s target version", target_name);
/* Assume this was because LIST_VERSIONS isn't supported */
return 1;
}
target = dm_task_get_versions(dmt);
do {
last_target = target;
if (!strcmp(target_name, target->name)) {
r = 1;
goto out;
}
target = (void *) target + target->next;
} while (last_target != target);
out:
dm_task_destroy(dmt);
return r;
}
/*
* Returns 1 if info structure populated, else 0 on failure.
*/
int lv_info(const struct logical_volume *lv, struct lvinfo *info)
static int _lv_info(const struct logical_volume *lv, int mknodes,
struct lvinfo *info)
{
int r;
struct dev_manager *dm;
@@ -148,12 +324,12 @@ int lv_info(const struct logical_volume *lv, struct lvinfo *info)
if (!activation())
return 0;
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
stack;
return 0;
}
if (!(r = dev_manager_info(dm, lv, &dminfo)))
if (!(r = dev_manager_info(dm, lv, mknodes, &dminfo)))
stack;
info->exists = dminfo.exists;
@@ -167,6 +343,22 @@ int lv_info(const struct logical_volume *lv, struct lvinfo *info)
return r;
}
int lv_info(const struct logical_volume *lv, struct lvinfo *info)
{
return _lv_info(lv, 0, info);
}
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
struct lvinfo *info)
{
struct logical_volume *lv;
if (!(lv = lv_from_lvid(cmd, lvid_s)))
return 0;
return _lv_info(lv, 0, info);
}
/*
* Returns 1 if percent set, else 0 on failure.
*/
@@ -178,7 +370,7 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
if (!activation())
return 0;
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
stack;
return 0;
}
@@ -197,11 +389,20 @@ int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
{
int r;
struct dev_manager *dm;
struct lvinfo info;
if (!activation())
return 0;
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
if (!lv_info(lv, &info)) {
stack;
return 0;
}
if (!info.exists)
return 0;
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
stack;
return 0;
}
@@ -239,12 +440,12 @@ static int _lv_open_count(struct logical_volume *lv)
}
/* FIXME Need to detect and handle an lv rename */
static int _lv_activate(struct logical_volume *lv)
static int _lv_activate_lv(struct logical_volume *lv)
{
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
stack;
return 0;
}
@@ -261,7 +462,7 @@ static int _lv_deactivate(struct logical_volume *lv)
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
stack;
return 0;
}
@@ -273,12 +474,12 @@ static int _lv_deactivate(struct logical_volume *lv)
return r;
}
static int _lv_suspend(struct logical_volume *lv)
static int _lv_suspend_lv(struct logical_volume *lv)
{
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
stack;
return 0;
}
@@ -328,8 +529,8 @@ int lvs_in_vg_opened(struct volume_group *vg)
return count;
}
/* These return success if the device is not active */
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
int error_if_not_suspended)
{
struct logical_volume *lv;
struct lvinfo info;
@@ -340,9 +541,6 @@ 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 1;
@@ -353,13 +551,32 @@ 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 error_if_not_suspended ? 0 : 1;
memlock_inc();
if (!_lv_suspend_lv(lv)) {
memlock_dec();
fs_unlock();
return 0;
}
return 1;
}
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
/* Returns success if the device is not active */
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
{
return _lv_suspend(cmd, lvid_s, 0);
}
int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
{
return _lv_suspend(cmd, lvid_s, 1);
}
static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
int error_if_not_active)
{
struct logical_volume *lv;
struct lvinfo info;
@@ -380,16 +597,34 @@ 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 error_if_not_active ? 0 : 1;
if (!_lv_activate_lv(lv))
return 0;
memlock_dec();
fs_unlock();
return 1;
}
/* Returns success if the device is not active */
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
{
return _lv_resume(cmd, lvid_s, 0);
}
int lv_resume(struct cmd_context *cmd, const char *lvid_s)
{
return _lv_resume(cmd, lvid_s, 1);
}
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
{
struct logical_volume *lv;
struct lvinfo info;
int r;
if (!activation())
return 1;
@@ -407,16 +642,52 @@ 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;
if (info.open_count && (lv->status & VISIBLE_LV)) {
log_error("LV %s/%s in use: not removing", lv->vg->name,
lv->name);
return 0;
}
memlock_inc();
r = _lv_deactivate(lv);
memlock_dec();
fs_unlock();
return r;
}
/* Test if LV passes filter */
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv)
{
struct logical_volume *lv;
if (!activation())
goto activate;
if (!(lv = lv_from_lvid(cmd, lvid_s)))
return 0;
if (!_passes_activation_filter(cmd, lv)) {
log_verbose("Not activating %s/%s due to config file settings",
lv->vg->name, lv->name);
*activate_lv = 0;
return 1;
}
activate:
*activate_lv = 1;
return 1;
}
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
{
struct logical_volume *lv;
struct lvinfo info;
int r;
if (!activation())
return 1;
@@ -424,6 +695,12 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s)
if (!(lv = lv_from_lvid(cmd, lvid_s)))
return 0;
if (filter && !_passes_activation_filter(cmd, lv)) {
log_verbose("Not activating %s/%s due to config file settings",
lv->vg->name, lv->name);
return 0;
}
if (test_mode()) {
_skip("Activating '%s'.", lv->name);
return 1;
@@ -434,10 +711,57 @@ 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(lv);
memlock_dec();
fs_unlock();
return r;
}
/* Activate LV */
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
{
return _lv_activate(cmd, lvid_s, 0);
}
/* Activate LV only if it passes filter */
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
{
return _lv_activate(cmd, lvid_s, 1);
}
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
{
struct lvinfo info;
int r = 1;
if (!lv) {
r = dev_manager_mknodes();
fs_unlock();
return r;
}
if (!_lv_info(lv, 1, &info)) {
stack;
return 0;
}
if (info.exists)
r = dev_manager_lv_mknodes(lv);
else
r = dev_manager_lv_rmnodes(lv);
fs_unlock();
return r;
}
void activation_exit(void)
{
dev_manager_exit();
}
#endif

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef LVM_ACTIVATE_H
@@ -28,15 +37,33 @@ int activation(void);
int driver_version(char *version, size_t size);
int library_version(char *version, size_t size);
int target_present(const char *target_name);
void activation_exit(void);
int lv_suspend(struct cmd_context *cmd, const char *lvid_s);
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s);
int lv_resume(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_activate_with_filter(struct cmd_context *cmd, const char *lvid_s);
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s);
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
/*
* Returns 1 if info structure has been populated, else 0.
*/
int lv_info(const struct logical_volume *lv, struct lvinfo *info);
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
struct lvinfo *info);
/*
* Returns 1 if activate_lv has been set: 1 = activate; 0 = don't.
*/
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv);
/*
* Returns 1 if percent has been set, else 0.
*/

View File

@@ -1,16 +1,27 @@
/*
* Copyright (C) 2002 Sistina Software (UK) Limited.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "str_list.h"
#include "dev_manager.h"
#include "pool.h"
#include "hash.h"
#include "lvm-string.h"
#include "fs.h"
#include "defaults.h"
#include "toolcontext.h"
#include <libdevmapper.h>
#include <limits.h>
@@ -41,6 +52,8 @@
*
*/
#define MAX_TARGET_PARAMSIZE 50000
enum {
ACTIVE = 0,
RELOAD = 1,
@@ -48,7 +61,8 @@ enum {
READWRITE = 3,
SUSPENDED = 4,
NOPROPAGATE = 5,
TOPLEVEL = 6
TOPLEVEL = 6,
REMOVE = 7
};
enum {
@@ -87,6 +101,9 @@ struct dev_layer {
*/
struct list pre_create;
/* Inverse of pre_create */
struct list pre_suspend;
};
struct dl_list {
@@ -100,7 +117,7 @@ static uint32_t mirror_region_size = 0;
struct dev_manager {
struct pool *mem;
struct config_tree *cf;
struct config_tree *cft;
const char *stripe_filler;
uint32_t mirror_region_size;
uint32_t pvmove_mirror_count;
@@ -149,30 +166,6 @@ static inline void _clear_flag(struct dev_layer *dl, int bit)
dl->flags &= ~(1 << bit);
}
static int _pre_list_add(struct pool *mem, struct list *pl, char *str)
{
struct str_list *sl;
struct list *plh;
if (!str) {
stack;
return 0;
}
list_iterate(plh, pl) {
}
if (!(sl = pool_alloc(mem, sizeof(*sl)))) {
stack;
return 0;
}
sl->str = str;
list_add(pl, &sl->list);
return 1;
}
/*
* Device layer names are all of the form <vg>-<lv>-<layer>, any
* other hyphens that appear in these names are quoted with yet
@@ -302,13 +295,16 @@ static struct dm_task *_setup_task(const char *name, const char *uuid,
}
static int _info_run(const char *name, const char *uuid, struct dm_info *info,
struct pool *mem, char **uuid_out)
int mknodes, struct pool *mem, char **uuid_out)
{
int r = 0;
struct dm_task *dmt;
const char *u;
int dmtask;
if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_INFO))) {
dmtask = mknodes ? DM_DEVICE_MKNODES : DM_DEVICE_INFO;
if (!(dmt = _setup_task(name, uuid, 0, dmtask))) {
stack;
return 0;
}
@@ -337,15 +333,15 @@ static int _info_run(const char *name, const char *uuid, struct dm_info *info,
return r;
}
static int _info(const char *name, const char *uuid, struct dm_info *info,
struct pool *mem, char **uuid_out)
static int _info(const char *name, const char *uuid, int mknodes,
struct dm_info *info, struct pool *mem, char **uuid_out)
{
if (uuid && *uuid && _info_run(NULL, uuid, info, mem, uuid_out)
&& info->exists)
if (!mknodes && uuid && *uuid &&
_info_run(NULL, uuid, info, 0, mem, uuid_out) && info->exists)
return 1;
if (name)
return _info_run(name, NULL, info, mem, uuid_out);
return _info_run(name, NULL, info, mknodes, mem, uuid_out);
return 0;
}
@@ -522,7 +518,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
else
*percent = 100;
log_debug("Mirror percent: %f", *percent);
log_debug("LV percent: %f", *percent);
r = 1;
out:
@@ -633,8 +629,14 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
log_very_verbose("Activating %s read-only", dl->name);
}
if (!(r = dm_task_run(dmt)))
if (!(r = dm_task_run(dmt))) {
log_error("Couldn't load device '%s'.", dl->name);
if ((dl->lv->minor >= 0 || dl->lv->major >= 0) &&
_get_flag(dl, VISIBLE))
log_error("Perhaps the persistent device number "
"%d:%d is already in use?",
dl->lv->major, dl->lv->minor);
}
if (!dm_task_get_info(dmt, &dl->info)) {
stack;
@@ -642,6 +644,15 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
goto out;
}
if (!dl->info.exists || !dl->info.live_table) {
stack;
r = 0;
goto out;
}
log_very_verbose("Activated %s %s %03u:%03u", dl->name,
dl->dlid, dl->info.major, dl->info.minor);
if (r && _get_flag(dl, VISIBLE))
fs_add_lv(dl->lv, dl->name);
@@ -743,16 +754,18 @@ static int _resume(struct dev_layer *dl)
* Emit a target for a given segment.
* FIXME: tidy this function.
*/
static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
struct lv_segment *seg)
static int _emit_target_line(struct dev_manager *dm, struct dm_task *dmt,
struct lv_segment *seg, char *params,
size_t paramsize)
{
char params[1024];
uint64_t esize = seg->lv->vg->extent_size;
uint32_t s, start_area = 0u, areas = seg->area_count;
int w = 0, tw = 0;
const char *target = NULL;
const char *trailing_space;
int mirror_status;
struct dev_layer *dl;
char devbuf[10];
switch (seg->type) {
case SEG_SNAPSHOT:
@@ -770,7 +783,7 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
target = "linear";
else if (areas > 1) {
target = "striped";
if ((tw = lvm_snprintf(params, sizeof(params), "%u %u ",
if ((tw = lvm_snprintf(params, paramsize, "%u %u ",
areas, seg->stripe_size)) < 0)
goto error;
w = tw;
@@ -796,8 +809,7 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
break;
}
target = "mirror";
if ((tw = lvm_snprintf(params, sizeof(params),
"core 1 %u %u ",
if ((tw = lvm_snprintf(params, paramsize, "core 1 %u %u ",
dm->mirror_region_size, areas)) < 0)
goto error;
w = tw;
@@ -809,25 +821,33 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
if ((seg->area[s].type == AREA_PV &&
(!seg->area[s].u.pv.pv || !seg->area[s].u.pv.pv->dev)) ||
(seg->area[s].type == AREA_LV && !seg->area[s].u.lv.lv))
tw = lvm_snprintf(params + w, sizeof(params) - w,
tw = lvm_snprintf(params + w, paramsize - w,
"%s 0%s", dm->stripe_filler,
trailing_space);
else if (seg->area[s].type == AREA_PV)
tw = lvm_snprintf(params + w, sizeof(params) - w,
tw = lvm_snprintf(params + w, paramsize - w,
"%s %" PRIu64 "%s",
dev_name(seg->area[s].u.pv.pv->dev),
(seg->area[s].u.pv.pv->pe_start +
(esize * seg->area[s].u.pv.pe)),
trailing_space);
else
tw = lvm_snprintf(params + w, sizeof(params) - w,
"%s/%s %" PRIu64 "%s", dm_dir(),
_build_name(dm->mem,
seg->lv->vg->name,
seg->area[s].u.lv.lv->
name, NULL),
else {
if (!(dl = hash_lookup(dm->layers,
seg->area[s].u.lv.lv->lvid.s))) {
log_error("device layer %s missing from hash",
seg->area[s].u.lv.lv->lvid.s);
return 0;
}
if (!dm_format_dev(devbuf, sizeof(devbuf), dl->info.major, dl->info.minor)) {
log_error("Failed to format device number as dm target (%u,%u)",
dl->info.major, dl->info.minor);
return 0;
}
tw = lvm_snprintf(params + w, paramsize - w,
"%s %" PRIu64 "%s", devbuf,
esize * seg->area[s].u.lv.le,
trailing_space);
}
if (tw < 0)
goto error;
@@ -845,7 +865,37 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
return 1;
error:
log_error("Insufficient space in params[] to write target parameters.");
log_debug("Insufficient space in params[%" PRIsize_t "] for target "
"parameters.", paramsize);
return -1;
}
static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
struct lv_segment *seg)
{
char *params;
size_t paramsize = 4096;
int ret;
do {
if (!(params = dbg_malloc(paramsize))) {
log_error("Insufficient space for target parameters.");
return 0;
}
ret = _emit_target_line(dm, dmt, seg, params, paramsize);
dbg_free(params);
if (!ret)
stack;
if (ret >= 0)
return ret;
paramsize *= 2;
} while (paramsize < MAX_TARGET_PARAMSIZE);
log_error("Target parameter size too big. Aborting.");
return 0;
}
@@ -874,13 +924,20 @@ static int _populate_origin(struct dev_manager *dm,
{
char *real;
char params[PATH_MAX + 32];
struct dev_layer *dlr;
if (!(real = _build_name(dm->mem, dm->vg_name, dl->lv->name, "real"))) {
if (!(real = _build_dlid(dm->mem, dl->lv->lvid.s, "real"))) {
stack;
return 0;
}
if (lvm_snprintf(params, sizeof(params), "%s/%s", dm_dir(), real) == -1) {
if (!(dlr = hash_lookup(dm->layers, real))) {
log_error("Couldn't find real device layer %s in hash", real);
return 0;
}
if (!dm_format_dev(params, sizeof(params), dlr->info.major,
dlr->info.minor)) {
log_error("Couldn't create origin device parameters for '%s'.",
real);
return 0;
@@ -903,25 +960,51 @@ static int _populate_snapshot(struct dev_manager *dm,
char *origin, *cow;
char params[PATH_MAX * 2 + 32];
struct snapshot *s;
struct dev_layer *dlo, *dlc;
char devbufo[10], devbufc[10];
if (!(s = find_cow(dl->lv))) {
log_error("Couldn't find snapshot for '%s'.", dl->lv->name);
return 0;
}
if (!(origin = _build_name(dm->mem, dm->vg_name,
s->origin->name, "real"))) {
if (!(origin = _build_dlid(dm->mem, s->origin->lvid.s, "real"))) {
stack;
return 0;
}
if (!(cow = _build_name(dm->mem, dm->vg_name, s->cow->name, "cow"))) {
if (!(cow = _build_dlid(dm->mem, s->cow->lvid.s, "cow"))) {
stack;
return 0;
}
if (snprintf(params, sizeof(params), "%s/%s %s/%s P %d",
dm_dir(), origin, dm_dir(), cow, s->chunk_size) == -1) {
if (!(dlo = hash_lookup(dm->layers, origin))) {
log_error("Couldn't find origin device layer %s in hash",
origin);
return 0;
}
if (!(dlc = hash_lookup(dm->layers, cow))) {
log_error("Couldn't find cow device layer %s in hash", cow);
return 0;
}
if (!dm_format_dev(devbufo, sizeof(devbufo), dlo->info.major,
dlo->info.minor)) {
log_error("Couldn't create origin device parameters for '%s'.",
s->origin->name);
return 0;
}
if (!dm_format_dev(devbufc, sizeof(devbufc), dlc->info.major,
dlc->info.minor)) {
log_error("Couldn't create cow device parameters for '%s'.",
s->cow->name);
return 0;
}
if (lvm_snprintf(params, sizeof(params), "%s %s P %d",
devbufo, devbufc, s->chunk_size) == -1) {
stack;
return 0;
}
@@ -941,7 +1024,7 @@ static int _populate_snapshot(struct dev_manager *dm,
* dev_manager implementation.
*/
struct dev_manager *dev_manager_create(const char *vg_name,
struct config_tree *cf)
struct config_tree *cft)
{
struct pool *mem;
struct dev_manager *dm;
@@ -957,18 +1040,17 @@ struct dev_manager *dev_manager_create(const char *vg_name,
}
dm->mem = mem;
dm->cf = cf;
dm->cft = cft;
if (!stripe_filler) {
stripe_filler = find_config_str(cf->root,
stripe_filler = find_config_str(cft->root,
"activation/missing_stripe_filler",
'/', DEFAULT_STRIPE_FILLER);
DEFAULT_STRIPE_FILLER);
}
dm->stripe_filler = stripe_filler;
if (!mirror_region_size) {
mirror_region_size = 2 * find_config_int(cf->root,
mirror_region_size = 2 * find_config_int(cft->root,
"activation/mirror_region_size",
'/',
DEFAULT_MIRROR_REGION_SIZE);
}
dm->mirror_region_size = mirror_region_size;
@@ -1002,7 +1084,7 @@ void dev_manager_destroy(struct dev_manager *dm)
}
int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
struct dm_info *info)
int mknodes, struct dm_info *info)
{
char *name;
@@ -1018,7 +1100,7 @@ int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
* Try and get some info on this device.
*/
log_debug("Getting device info for %s", name);
if (!_info(name, lv->lvid.s, info, NULL, NULL)) {
if (!_info(name, lv->lvid.s, mknodes, info, NULL, NULL)) {
stack;
return 0;
}
@@ -1097,7 +1179,7 @@ static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
dl->name = name;
log_debug("Getting device info for %s", dl->name);
if (!_info(dl->name, dlid, &dl->info, dm->mem, &uuid)) {
if (!_info(dl->name, dlid, 0, &dl->info, dm->mem, &uuid)) {
stack;
return NULL;
}
@@ -1108,6 +1190,7 @@ static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
dl->dlid = dlid;
list_init(&dl->pre_create);
list_init(&dl->pre_suspend);
if (!hash_insert(dm->layers, dl->dlid, dl)) {
stack;
@@ -1172,12 +1255,13 @@ static struct dev_layer *_lookup(struct dev_manager *dm,
return dl;
}
static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv)
static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
int was_origin)
{
/*
* only one layer.
*/
struct dev_layer *dl;
struct dev_layer *dl, *dlr;
struct list *segh;
struct lv_segment *seg;
uint32_t s;
@@ -1203,10 +1287,10 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv)
for (s = 0; s < seg->area_count; s++) {
if (seg->area[s].type != AREA_LV)
continue;
if (!_pre_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem,
seg->area[s].u.lv.lv->
lvid.s, NULL))) {
if (!str_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem,
seg->area[s].u.lv.
lv->lvid.s, NULL))) {
stack;
return 0;
}
@@ -1214,6 +1298,27 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv)
}
}
if (!was_origin)
return 1;
/* Deactivating the last snapshot */
if (!(dlr = _create_layer(dm, "real", lv))) {
stack;
return 0;
}
dlr->populate = _populate_vanilla;
_clear_flag(dlr, VISIBLE);
_clear_flag(dlr, TOPLEVEL);
_set_flag(dlr, REMOVE);
/* add the dependency on the real device */
if (!str_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, dlr->dlid))) {
stack;
return 0;
}
return 1;
}
@@ -1242,8 +1347,8 @@ static int _expand_origin_real(struct dev_manager *dm,
_set_flag(dl, TOPLEVEL);
/* add the dependency on the real device */
if (!_pre_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, real_dlid))) {
if (!str_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, real_dlid))) {
stack;
return 0;
}
@@ -1259,7 +1364,7 @@ static int _expand_origin(struct dev_manager *dm, struct logical_volume *lv)
/*
* We only need to create an origin layer if one of our
* snapshots is in the active list.
* snapshots is in the active list
*/
list_iterate(sh, &dm->active_list) {
active = list_item(sh, struct lv_list)->lv;
@@ -1267,7 +1372,10 @@ static int _expand_origin(struct dev_manager *dm, struct logical_volume *lv)
return _expand_origin_real(dm, lv);
}
return _expand_vanilla(dm, lv);
/*
* We're deactivating the last snapshot
*/
return _expand_vanilla(dm, lv, 1);
}
static int _expand_snapshot(struct dev_manager *dm, struct logical_volume *lv,
@@ -1287,6 +1395,7 @@ static int _expand_snapshot(struct dev_manager *dm, struct logical_volume *lv,
dl->populate = _populate_vanilla;
_clear_flag(dl, VISIBLE);
_clear_flag(dl, TOPLEVEL);
_set_flag(dl, READWRITE);
cow_dlid = dl->dlid;
@@ -1298,16 +1407,22 @@ static int _expand_snapshot(struct dev_manager *dm, struct logical_volume *lv,
_set_flag(dl, VISIBLE);
_set_flag(dl, TOPLEVEL);
/* add the dependency on the real device */
if (!_pre_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, cow_dlid))) {
/* add the dependency on the cow device */
if (!str_list_add(dm->mem, &dl->pre_create,
pool_strdup(dm->mem, cow_dlid))) {
stack;
return 0;
}
/* add the dependency on the org device */
if (!_pre_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem, s->origin->lvid.s, "real"))) {
/* add the dependency on the real origin device */
if (!str_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem, s->origin->lvid.s, "real"))) {
stack;
return 0;
}
/* add the dependency on the visible origin device */
if (!str_list_add(dm->mem, &dl->pre_suspend, s->origin->lvid.s)) {
stack;
return 0;
}
@@ -1331,7 +1446,7 @@ static int _expand_lv(struct dev_manager *dm, struct logical_volume *lv)
else if (lv_is_origin(lv))
return _expand_origin(dm, lv);
return _expand_vanilla(dm, lv);
return _expand_vanilla(dm, lv, 0);
}
/*
@@ -1355,7 +1470,7 @@ static int _trace_layer_marks(struct dev_manager *dm, struct dev_layer *dl,
int flag)
{
struct list *sh;
char *dlid;
const char *dlid;
struct dev_layer *dep;
list_iterate(sh, &dl->pre_create) {
@@ -1432,25 +1547,88 @@ static int _mark_lvs(struct dev_manager *dm, struct list *lvs, int flag)
return 1;
}
static inline int _suspend_parent(struct dev_layer *parent)
static int _suspend_parents(struct dev_manager *dm, struct dev_layer *dl)
{
return (!parent || !parent->info.exists || _suspend(parent));
struct list *sh;
struct dev_layer *dep;
const char *dlid;
list_iterate(sh, &dl->pre_suspend) {
dlid = list_item(sh, struct str_list)->str;
if (!(dep = hash_lookup(dm->layers, dlid))) {
log_debug("_suspend_parents couldn't find device "
"layer '%s' - skipping.", dlid);
continue;
}
if (!strcmp(dep->dlid, dl->dlid)) {
log_error("BUG: pre-suspend loop detected (%s)", dlid);
return 0;
}
if (!_suspend_parents(dm, dep)) {
stack;
return 0;
}
if (dep->info.exists & !_suspend(dep)) {
stack;
return 0;
}
}
return 1;
}
static int _resume_with_deps(struct dev_manager *dm, struct dev_layer *dl)
{
struct list *sh;
struct dev_layer *dep;
const char *dlid;
list_iterate(sh, &dl->pre_create) {
dlid = list_item(sh, struct str_list)->str;
if (!(dep = hash_lookup(dm->layers, dlid))) {
log_debug("_resume_with_deps couldn't find device "
"layer '%s' - skipping.", dlid);
continue;
}
if (!strcmp(dep->dlid, dl->dlid)) {
log_error("BUG: pre-create loop detected (%s)", dlid);
return 0;
}
if (!_resume_with_deps(dm, dep)) {
stack;
return 0;
}
}
if (dl->info.exists & !_get_flag(dl, SUSPENDED) && !_resume(dl)) {
stack;
return 0;
}
return 1;
}
/*
* Recurses through the tree, ensuring that devices are created
* in correct order.
*/
static int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
struct dev_layer *parent)
static int _create_rec(struct dev_manager *dm, struct dev_layer *dl)
{
struct list *sh;
struct dev_layer *dep;
char *dlid, *newname, *suffix;
const char *dlid;
char *newname, *suffix;
/* FIXME Create and use a _suspend_parents() function instead */
/* Suspend? */
if (_get_flag(dl, SUSPENDED) && (!_suspend_parent || !_suspend(dl))) {
if (_get_flag(dl, SUSPENDED) &&
(!_suspend_parents(dm, dl) || !_suspend(dl))) {
stack;
return 0;
}
@@ -1463,17 +1641,12 @@ static int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
return 0;
}
if (!_suspend_parent(parent)) {
stack;
return 0;
}
if (!strcmp(dep->dlid, dl->dlid)) {
log_error("BUG: pre-create loop detected (%s)", dlid);
return 0;
}
if (!_create_rec(dm, dep, dl)) {
if (!_create_rec(dm, dep)) {
stack;
return 0;
}
@@ -1486,7 +1659,7 @@ static int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
newname = _build_name(dm->mem, dm->vg_name, dl->lv->name,
suffix);
if (strcmp(newname, dl->name)) {
if (!_suspend_parent(parent) ||
if (!_suspend_parents(dm, dl) ||
!_suspend(dl) || !_rename(dl, newname)) {
stack;
return 0;
@@ -1496,7 +1669,7 @@ static int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
/* Create? */
if (!dl->info.exists) {
if (!_suspend_parent(parent) ||
if (!_suspend_parents(dm, dl) ||
!_load(dm, dl, DM_DEVICE_CREATE)) {
stack;
return 0;
@@ -1506,21 +1679,16 @@ static int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
/* Reload? */
if (_get_flag(dl, RELOAD) &&
(!_suspend_parent(parent) || !_suspend(dl) ||
(!_suspend_parents(dm, dl) || !_suspend(dl) ||
!_load(dm, dl, DM_DEVICE_RELOAD))) {
stack;
return 0;
}
/* Resume? */
if (!_get_flag(dl, SUSPENDED) && (!_suspend_parent || !_resume(dl))) {
stack;
return 0;
}
return 1;
}
static int _build_all_layers(struct dev_manager *dm, struct volume_group *vg)
{
struct list *lvh;
@@ -1549,6 +1717,9 @@ static int _fill_in_remove_list(struct dev_manager *dm)
hash_iterate(hn, dm->layers) {
dl = hash_get_data(dm->layers, hn);
if (_get_flag(dl, REMOVE))
_clear_flag(dl, ACTIVE);
if (!_get_flag(dl, ACTIVE)) {
dll = pool_alloc(dm->mem, sizeof(*dll));
if (!dll) {
@@ -1564,6 +1735,55 @@ static int _fill_in_remove_list(struct dev_manager *dm)
return 1;
}
static int _populate_pre_suspend_lists(struct dev_manager *dm)
{
struct hash_node *hn;
struct dev_layer *dl;
struct list *sh;
const char *dlid;
struct dev_layer *dep;
hash_iterate(hn, dm->layers) {
dl = hash_get_data(dm->layers, hn);
list_iterate(sh, &dl->pre_suspend) {
dlid = list_item(sh, struct str_list)->str;
if (!(dep = hash_lookup(dm->layers, dlid))) {
log_debug("_populate_pre_suspend_lists: "
"Couldn't find device layer '%s' - "
"skipping.", dlid);
continue;
}
if (!str_list_add(dm->mem, &dep->pre_create,
dl->dlid)) {
stack;
return 0;
}
}
list_iterate(sh, &dl->pre_create) {
dlid = list_item(sh, struct str_list)->str;
if (!(dep = hash_lookup(dm->layers, dlid))) {
log_debug("_populate_pre_suspend_lists: "
"Couldn't find device layer '%s' - "
"skipping.", dlid);
continue;
}
if (!str_list_add(dm->mem, &dep->pre_suspend,
dl->dlid)) {
stack;
return 0;
}
}
}
return 1;
}
/*
* Layers are removed in a top-down manner.
*/
@@ -1649,6 +1869,11 @@ static int _execute(struct dev_manager *dm, struct volume_group *vg)
return 0;
}
if (!_populate_pre_suspend_lists(dm)) {
stack;
return 0;
}
/*
* Now only top level devices will be unmarked.
*/
@@ -1656,7 +1881,20 @@ static int _execute(struct dev_manager *dm, struct volume_group *vg)
dl = hash_get_data(dm->layers, hn);
if (_get_flag(dl, ACTIVE) && _get_flag(dl, TOPLEVEL))
_create_rec(dm, dl, NULL);
if (!_create_rec(dm, dl)) {
stack;
return 0;
}
}
/* Resume devices */
hash_iterate(hn, dm->layers) {
dl = hash_get_data(dm->layers, hn);
if (!_resume_with_deps(dm, dl)) {
stack;
return 0;
}
}
if (!_remove_old_layers(dm)) {
@@ -1708,41 +1946,40 @@ static int _add_existing_layer(struct dev_manager *dm, const char *name)
return 1;
}
/* FIXME Get this info directly from the driver not the unreliable fs */
static int _scan_existing_devices(struct dev_manager *dm)
{
const char *dev_dir = dm_dir();
int r = 0;
struct dm_names *names;
unsigned next = 0;
int r = 1;
const char *name;
struct dirent *dirent;
DIR *d;
struct dm_task *dmt;
if (!(d = opendir(dev_dir))) {
log_sys_error("opendir", dev_dir);
if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
return 0;
}
while ((dirent = readdir(d))) {
name = dirent->d_name;
if (!dm_task_run(dmt))
goto out;
if (name[0] == '.')
continue;
if (!(names = dm_task_get_names(dmt)))
goto out;
/*
* Does this layer belong to us ?
*/
if (_belong_to_vg(dm->vg_name, name) &&
!_add_existing_layer(dm, name)) {
r = 1;
if (!names->dev)
goto out;
do {
names = (void *) names + next;
if (_belong_to_vg(dm->vg_name, names->name) &&
!_add_existing_layer(dm, names->name)) {
stack;
r = 0;
break;
}
}
if (closedir(d))
log_sys_error("closedir", dev_dir);
next = names->next;
} while (next);
out:
dm_task_destroy(dmt);
return r;
}
@@ -1953,3 +2190,40 @@ int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv)
{
return _action(dm, lv, SUSPEND);
}
int dev_manager_lv_mknodes(const struct logical_volume *lv)
{
char *name;
if (!(name = _build_name(lv->vg->cmd->mem, lv->vg->name,
lv->name, NULL))) {
stack;
return 0;
}
return fs_add_lv(lv, name);
}
int dev_manager_lv_rmnodes(const struct logical_volume *lv)
{
return fs_del_lv(lv);
}
int dev_manager_mknodes(void)
{
struct dm_task *dmt;
int r;
if (!(dmt = dm_task_create(DM_DEVICE_MKNODES)))
return 0;
r = dm_task_run(dmt);
dm_task_destroy(dmt);
return r;
}
void dev_manager_exit(void)
{
dm_lib_exit();
}

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2002 Sistina Software (UK) Limited.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_DEV_MANAGER_H
@@ -19,6 +28,7 @@ struct dm_info;
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
@@ -27,7 +37,7 @@ void dev_manager_destroy(struct dev_manager *dm);
* unsuspended until the snapshot is also created.)
*/
int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
struct dm_info *info);
int mknodes, struct dm_info *info);
int dev_manager_snapshot_percent(struct dev_manager *dm,
struct logical_volume *lv, float *percent);
int dev_manager_mirror_percent(struct dev_manager *dm,
@@ -37,6 +47,10 @@ int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_lv_mknodes(const struct logical_volume *lv);
int dev_manager_lv_rmnodes(const struct logical_volume *lv);
int dev_manager_mknodes(void);
/*
* Put the desired changes into effect.
*/

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -9,6 +18,7 @@
#include "toolcontext.h"
#include "lvm-string.h"
#include "lvm-file.h"
#include "memlock.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -17,12 +27,12 @@
#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;
@@ -40,12 +50,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;
@@ -93,37 +103,38 @@ static void _rm_blks(const char *dir)
}
}
static int _mk_link(struct logical_volume *lv, const char *dev)
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(vg_path, sizeof(vg_path), "%s%s",
lv->vg->cmd->dev_dir, lv->vg->name) == -1) {
dev_dir, vg_name) == -1) {
log_error("Couldn't create path for volume group dir %s",
lv->vg->name);
vg_name);
return 0;
}
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s/%s", vg_path,
lv->name) == -1) {
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",
lv->vg->name);
vg_name);
return 0;
}
@@ -167,19 +178,22 @@ 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;
}
if (lstat(lv_path, &buf) || !S_ISLNK(buf.st_mode)) {
log_error("%s not symbolic link - not removing", lv_path);
if (errno != ENOENT)
log_error("%s not symbolic link - not removing",
lv_path);
return 0;
}
@@ -192,35 +206,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;
}
int fs_del_lv(struct logical_volume *lv)
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)
{
if (!_rm_link(lv, lv->name) || !_rm_dir(lv->vg)) {
stack;
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;
}
/* FIXME Use rename() */
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(const struct logical_volume *lv, const char *dev)
{
return _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, "");
}
int fs_del_lv(const struct logical_volume *lv)
{
return _fs_op(FS_DEL, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
"", "");
}
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

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_FS_H
@@ -14,9 +23,10 @@
* up the volume group directory in /dev and the
* symbolic links to the dm device.
*/
int fs_add_lv(struct logical_volume *lv, const char *dev);
int fs_del_lv(struct logical_volume *lv);
int fs_add_lv(const struct logical_volume *lv, const char *dev);
int fs_del_lv(const struct logical_volume *lv);
int fs_rename_lv(struct logical_volume *lv,
const char *dev, const char *old_name);
void fs_unlock(void);
#endif

70
lib/cache/cache.h vendored
View File

@@ -1,70 +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 "uuid.h"
#include "label.h"
#include "metadata.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];
const 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;
const struct format_type *fmt;
struct device *dev;
uint64_t device_size; /* Bytes */
uint32_t status;
};
int cache_init(void);
void cache_destroy(void);
/* 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 */
const 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

@@ -1,25 +1,38 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#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"
#include "str_list.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(void)
int lvmcache_init(void)
{
list_init(&_vginfos);
@@ -32,12 +45,52 @@ int cache_init(void)
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;
@@ -50,7 +103,7 @@ struct cache_vginfo *vginfo_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;
@@ -58,9 +111,9 @@ const 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)
@@ -76,9 +129,9 @@ struct cache_vginfo *vginfo_from_vgid(const char *vgid)
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)
@@ -93,7 +146,7 @@ struct cache_info *info_from_pvid(const char *pvid)
return info;
}
static void _rescan_entry(struct cache_info *info)
static void _rescan_entry(struct lvmcache_info *info)
{
struct label *label;
@@ -108,7 +161,7 @@ static int _scan_invalid(void)
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;
@@ -125,7 +178,7 @@ 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;
}
@@ -162,33 +215,24 @@ 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;
struct list *vgnames;
struct lvmcache_vginfo *vgi;
cache_label_scan(cmd, full_scan);
lvmcache_label_scan(cmd, full_scan);
if (!(vgnames = pool_alloc(cmd->mem, sizeof(struct list)))) {
if (!(vgnames = str_list_create(cmd->mem))) {
log_error("vgnames list allocation failed");
return NULL;
}
list_init(vgnames);
list_iterate(vgih, &_vginfos) {
if (!(sl = pool_alloc(cmd->mem, sizeof(*sl)))) {
list_iterate_items(vgi, &_vginfos) {
if (!str_list_add(cmd->mem, vgnames,
pool_strdup(cmd->mem, vgi->vgname))) {
log_error("strlist allocation failed");
return NULL;
}
if (!(sl->str = pool_strdup(cmd->mem,
list_item(vgih,
struct cache_vginfo)->
vgname))) {
log_error("vgname allocation failed");
return NULL;
}
list_add(vgnames, &sl->list);
}
return vgnames;
@@ -197,34 +241,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;
}
@@ -233,7 +280,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
return NULL;
}
static void _drop_vginfo(struct cache_info *info)
static void _drop_vginfo(struct lvmcache_info *info)
{
if (!list_empty(&info->list)) {
list_del(&info->list);
@@ -254,7 +301,7 @@ static 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);
@@ -268,7 +315,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;
@@ -277,14 +324,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)))
@@ -297,18 +344,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
@@ -326,7 +373,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));
@@ -359,11 +406,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;
@@ -374,9 +421,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;
}
}
@@ -385,15 +432,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;
}
@@ -408,7 +455,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;
}
@@ -456,7 +503,7 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
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);
@@ -464,7 +511,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, "");
@@ -474,14 +521,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);
@@ -490,14 +537,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(void)
static void _lvmcache_destroy_lockname(int present)
{
/* Nothing to do */
}
void lvmcache_destroy(void)
{
_has_scanned = 0;
@@ -507,15 +559,23 @@ void cache_destroy(void)
}
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);
}

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

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#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

@@ -1,15 +1,24 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_ERRORS_H
#define _LVM_ERRORS_H
#define EINVALID_CMD_LINE 1
#define ENO_SUCH_CMD 3
#define ECMD_PROCESSED 4
#define ECMD_PROCESSED 1
#define ENO_SUCH_CMD 2
#define EINVALID_CMD_LINE 3
#define ECMD_FAILED 5
#endif

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
@@ -16,10 +25,13 @@
#include "filter-composite.h"
#include "filter-persistent.h"
#include "filter-regex.h"
#include "filter-sysfs.h"
#include "label.h"
#include "lvm-file.h"
#include "format-text.h"
#include "display.h"
#include "memlock.h"
#include "str_list.h"
#ifdef HAVE_LIBDL
#include "sharedlib.h"
@@ -31,9 +43,14 @@
#include <locale.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <syslog.h>
#include <time.h>
#ifdef linux
# include <malloc.h>
#endif
static FILE *_log;
static int _get_env_vars(struct cmd_context *cmd)
@@ -55,14 +72,14 @@ static int _get_env_vars(struct cmd_context *cmd)
static void _init_logging(struct cmd_context *cmd)
{
const char *open_mode = "a";
int append = 1;
time_t t;
const char *log_file;
/* Syslog */
cmd->default_settings.syslog =
find_config_int(cmd->cf->root, "log/syslog", '/', DEFAULT_SYSLOG);
find_config_int(cmd->cft->root, "log/syslog", DEFAULT_SYSLOG);
if (cmd->default_settings.syslog != 1)
fin_syslog();
@@ -71,46 +88,52 @@ static void _init_logging(struct cmd_context *cmd)
/* Debug level for log file output */
cmd->default_settings.debug =
find_config_int(cmd->cf->root, "log/level", '/', DEFAULT_LOGLEVEL);
find_config_int(cmd->cft->root, "log/level", DEFAULT_LOGLEVEL);
init_debug(cmd->default_settings.debug);
/* Verbose level for tty output */
cmd->default_settings.verbose =
find_config_int(cmd->cf->root, "log/verbose", '/', DEFAULT_VERBOSE);
init_verbose(cmd->default_settings.verbose);
find_config_int(cmd->cft->root, "log/verbose", DEFAULT_VERBOSE);
init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL);
/* Log message formatting */
init_indent(find_config_int(cmd->cf->root, "log/indent", '/',
init_indent(find_config_int(cmd->cft->root, "log/indent",
DEFAULT_INDENT));
cmd->default_settings.msg_prefix = find_config_str(cmd->cf->root,
"log/prefix", '/',
cmd->default_settings.msg_prefix = find_config_str(cmd->cft->root,
"log/prefix",
DEFAULT_MSG_PREFIX);
init_msg_prefix(cmd->default_settings.msg_prefix);
cmd->default_settings.cmd_name = find_config_int(cmd->cf->root,
cmd->default_settings.cmd_name = find_config_int(cmd->cft->root,
"log/command_names",
'/', DEFAULT_CMD_NAME);
DEFAULT_CMD_NAME);
init_cmd_name(cmd->default_settings.cmd_name);
/* Test mode */
cmd->default_settings.test =
find_config_int(cmd->cf->root, "global/test", '/', 0);
find_config_int(cmd->cft->root, "global/test", 0);
/* Settings for logging to file */
if (find_config_int(cmd->cf->root, "log/overwrite", '/',
if (find_config_int(cmd->cft->root, "log/overwrite",
DEFAULT_OVERWRITE))
open_mode = "w";
append = 0;
log_file = find_config_str(cmd->cft->root, "log/file", 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);
release_log_memory();
fin_log();
init_log_file(log_file, append);
}
log_file = find_config_str(cmd->cft->root, "log/activate_file", 0);
if (log_file)
init_log_direct(log_file, append);
init_log_while_suspended(find_config_int(cmd->cft->root,
"log/activation", 0));
t = time(NULL);
log_verbose("Logging initialised at %s", ctime(&t));
@@ -125,8 +148,8 @@ static int _process_config(struct cmd_context *cmd)
mode_t old_umask;
/* umask */
cmd->default_settings.umask = find_config_int(cmd->cf->root,
"global/umask", '/',
cmd->default_settings.umask = find_config_int(cmd->cft->root,
"global/umask",
DEFAULT_UMASK);
if ((old_umask = umask((mode_t) cmd->default_settings.umask)) !=
@@ -135,8 +158,8 @@ static int _process_config(struct cmd_context *cmd)
/* dev dir */
if (lvm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/",
find_config_str(cmd->cf->root, "devices/dir",
'/', DEFAULT_DEV_DIR)) < 0) {
find_config_str(cmd->cft->root, "devices/dir",
DEFAULT_DEV_DIR)) < 0) {
log_error("Device directory given in config file too long");
return 0;
}
@@ -146,27 +169,25 @@ static int _process_config(struct cmd_context *cmd)
/* proc dir */
if (lvm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
find_config_str(cmd->cf->root, "global/proc",
'/', DEFAULT_PROC_DIR)) < 0) {
find_config_str(cmd->cft->root, "global/proc",
DEFAULT_PROC_DIR)) < 0) {
log_error("Device directory given in config file too long");
return 0;
}
/* activation? */
cmd->default_settings.activation = find_config_int(cmd->cf->root,
cmd->default_settings.activation = find_config_int(cmd->cft->root,
"global/activation",
'/',
DEFAULT_ACTIVATION);
set_activation(cmd->default_settings.activation);
cmd->default_settings.suffix = find_config_int(cmd->cf->root,
cmd->default_settings.suffix = find_config_int(cmd->cft->root,
"global/suffix",
'/', DEFAULT_SUFFIX);
DEFAULT_SUFFIX);
if (!(cmd->default_settings.unit_factor =
units_to_bytes(find_config_str(cmd->cf->root,
units_to_bytes(find_config_str(cmd->cft->root,
"global/units",
'/',
DEFAULT_UNITS),
&cmd->default_settings.unit_type))) {
log_error("Invalid units specification");
@@ -182,7 +203,7 @@ static int _init_config(struct cmd_context *cmd)
struct stat info;
char config_file[PATH_MAX] = "";
if (!(cmd->cf = create_config_tree())) {
if (!(cmd->cft = create_config_tree())) {
stack;
return 0;
}
@@ -194,7 +215,7 @@ static int _init_config(struct cmd_context *cmd)
if (lvm_snprintf(config_file, sizeof(config_file),
"%s/lvm.conf", cmd->sys_dir) < 0) {
log_error("LVM_SYSTEM_DIR was too long");
destroy_config_tree(cmd->cf);
destroy_config_tree(cmd->cft);
return 0;
}
@@ -203,13 +224,13 @@ static int _init_config(struct cmd_context *cmd)
if (errno == ENOENT)
return 1;
log_sys_error("stat", config_file);
destroy_config_tree(cmd->cf);
destroy_config_tree(cmd->cft);
return 0;
}
if (!read_config_file(cmd->cf, config_file)) {
if (!read_config_file(cmd->cft, config_file)) {
log_error("Failed to load config file %s", config_file);
destroy_config_tree(cmd->cf);
destroy_config_tree(cmd->cft);
return 0;
}
@@ -226,7 +247,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
return 0;
}
if (!(cn = find_config_node(cmd->cf->root, "devices/scan", '/'))) {
if (!(cn = find_config_node(cmd->cft->root, "devices/scan"))) {
if (!dev_cache_add_dir("/dev")) {
log_error("Failed to add /dev to internal "
"device cache");
@@ -254,38 +275,48 @@ static int _init_dev_cache(struct cmd_context *cmd)
return 1;
}
#define MAX_FILTERS 3
static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
{
unsigned nr_filt = 0;
struct config_node *cn;
struct dev_filter *f1, *f2, *f3;
struct dev_filter *filters[MAX_FILTERS];
cn = find_config_node(cmd->cf->root, "devices/types", '/');
memset(filters, 0, sizeof(filters));
if (!(f2 = lvm_type_filter_create(cmd->proc_dir, cn)))
return NULL;
if (!(cn = find_config_node(cmd->cf->root, "devices/filter", '/'))) {
log_debug("devices/filter not found in config file: no regex "
"filter installed");
return f2;
/* sysfs filter */
if (find_config_bool(cmd->cft->root, "devices/sysfs_scan",
DEFAULT_SYSFS_SCAN)) {
if ((filters[nr_filt] = sysfs_filter_create(cmd->proc_dir)))
nr_filt++;
}
if (!(f1 = regex_filter_create(cn->v))) {
/* regex filter */
if (!(cn = find_config_node(cmd->cft->root, "devices/filter")))
log_debug("devices/filter not found in config file: no regex "
"filter installed");
else if (!(filters[nr_filt++] = regex_filter_create(cn->v))) {
log_error("Failed to create regex device filter");
return NULL;
}
if (!(f3 = composite_filter_create(2, f1, f2))) {
log_error("Failed to create composite device filter");
/* device type filter */
cn = find_config_node(cmd->cft->root, "devices/types");
if (!(filters[nr_filt++] = lvm_type_filter_create(cmd->proc_dir, cn))) {
log_error("Failed to create lvm type filter");
return NULL;
}
return f3;
/* only build a composite filter if we really need it */
return (nr_filt == 1) ?
filters[0] : composite_filter_create(nr_filt, filters);
}
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];
@@ -302,25 +333,25 @@ static int _init_filters(struct cmd_context *cmd)
return 0;
}
lvm_cache =
find_config_str(cmd->cf->root, "devices/cache", '/', cache_file);
if (!(f4 = persistent_filter_create(f3, lvm_cache))) {
dev_cache =
find_config_str(cmd->cft->root, "devices/cache", cache_file);
if (!(f4 = persistent_filter_create(f3, dev_cache))) {
log_error("Failed to create persistent device filter");
return 0;
}
/* Should we ever dump persistent filter state? */
if (find_config_int(cmd->cf->root, "devices/write_cache_state", '/', 1))
if (find_config_int(cmd->cft->root, "devices/write_cache_state", 1))
cmd->dump_filter = 1;
if (!*cmd->sys_dir)
cmd->dump_filter = 0;
if (!stat(lvm_cache, &st) &&
(st.st_mtime > config_file_timestamp(cmd->cf)) &&
if (!stat(dev_cache, &st) &&
(st.st_mtime > config_file_timestamp(cmd->cft)) &&
!persistent_filter_load(f4))
log_verbose("Failed to load existing device cache from %s",
lvm_cache);
dev_cache);
cmd->filter = f4;
@@ -349,8 +380,7 @@ static int _init_formats(struct cmd_context *cmd)
#ifdef HAVE_LIBDL
/* Load any formats in shared libs */
if ((cn = find_config_node(cmd->cf->root, "global/format_libraries",
'/'))) {
if ((cn = find_config_node(cmd->cft->root, "global/format_libraries"))) {
struct config_value *cv;
struct format_type *(*init_format_fn) (struct cmd_context *);
@@ -362,7 +392,7 @@ static int _init_formats(struct cmd_context *cmd)
"global/format_libraries");
return 0;
}
if (!(lib = load_shared_library(cmd->cf, cv->v.str,
if (!(lib = load_shared_library(cmd->cft, cv->v.str,
"format"))) {
stack;
return 0;
@@ -390,7 +420,7 @@ static int _init_formats(struct cmd_context *cmd)
cmd->fmt_backup = fmt;
format = find_config_str(cmd->cf->root, "global/format", '/',
format = find_config_str(cmd->cft->root, "global/format",
DEFAULT_FORMAT);
list_iterate(fmth, &cmd->formats) {
@@ -406,14 +436,138 @@ static int _init_formats(struct cmd_context *cmd)
return 0;
}
static int _init_hostname(struct cmd_context *cmd)
{
struct utsname uts;
if (uname(&uts)) {
log_sys_error("uname", "_init_hostname");
return 0;
}
if (!(cmd->hostname = pool_strdup(cmd->libmem, uts.nodename))) {
log_error("_init_hostname: pool_strdup failed");
return 0;
}
return 1;
}
static int _set_tag(struct cmd_context *cmd, const char *tag)
{
log_very_verbose("Setting host tag: %s", pool_strdup(cmd->libmem, tag));
if (!str_list_add(cmd->libmem, &cmd->tags, tag)) {
log_error("_init_tags: str_list_add %s failed", tag);
return 0;
}
return 1;
}
static int _check_host_filters(struct cmd_context *cmd, struct config_node *hn,
int *passes)
{
struct config_node *cn;
struct config_value *cv;
*passes = 1;
for (cn = hn; cn; cn = cn->sib) {
if (!cn->v)
continue;
if (!strcmp(cn->key, "host_list")) {
*passes = 0;
if (cn->v->type == CFG_EMPTY_ARRAY)
continue;
for (cv = cn->v; cv; cv = cv->next) {
if (cv->type != CFG_STRING) {
log_error("Invalid hostname string "
"for tag %s", cn->key);
return 0;
}
if (!strcmp(cv->v.str, cmd->hostname)) {
*passes = 1;
return 1;
}
}
}
if (!strcmp(cn->key, "host_filter")) {
log_error("host_filter not supported yet");
return 0;
}
}
return 1;
}
static int _init_tags(struct cmd_context *cmd)
{
struct config_node *tn, *cn;
const char *tag;
int passes;
list_init(&cmd->tags);
if (!(tn = find_config_node(cmd->cft->root, "tags")) ||
!tn->child) {
log_very_verbose("No tags defined in config file");
return 1;
}
if (find_config_int(cmd->cft->root, "tags/hosttags",
DEFAULT_HOSTTAGS)) {
/* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
if (!_set_tag(cmd, cmd->hostname)) {
stack;
return 0;
}
}
for (cn = tn->child; cn; cn = cn->sib) {
if (cn->v)
continue;
tag = cn->key;
if (*tag == '@')
tag++;
if (!validate_name(tag)) {
log_error("Invalid tag in config file: %s", cn->key);
return 0;
}
if (cn->child) {
passes = 0;
if (!_check_host_filters(cmd, cn->child, &passes)) {
stack;
return 0;
}
if (!passes)
continue;
}
if (!_set_tag(cmd, tag)) {
stack;
return 0;
}
}
return 1;
}
/* Entry point */
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");
#ifdef INTL_PACKAGE
bindtextdomain(INTL_PACKAGE, LOCALEDIR);
#endif
init_syslog(DEFAULT_LOG_FACILITY);
if (!(cmd = dbg_malloc(sizeof(*cmd)))) {
@@ -438,6 +592,11 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
_init_logging(cmd);
if (!(cmd->libmem = pool_create(4 * 1024))) {
log_error("Library memory pool creation failed");
return 0;
}
if (!_process_config(cmd))
goto error;
@@ -452,9 +611,17 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
return 0;
}
memlock_init(cmd);
if (!_init_formats(cmd))
goto error;
if (!_init_hostname(cmd))
goto error;
if (!_init_tags(cmd))
goto error;
cmd->current_settings = cmd->default_settings;
return cmd;
@@ -464,6 +631,16 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
return NULL;
}
int refresh_toolcontext(struct cmd_context *cmd)
{
_init_logging(cmd);
_init_tags(cmd);
/* FIXME Reset filters and dev_cache */
return 1;
}
static void _destroy_formats(struct list *formats)
{
struct list *fmtl, *tmp;
@@ -487,15 +664,18 @@ 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);
cmd->filter->destroy(cmd->filter);
pool_destroy(cmd->mem);
dev_cache_exit();
destroy_config_tree(cmd->cf);
destroy_config_tree(cmd->cft);
pool_destroy(cmd->libmem);
dbg_free(cmd);
release_log_memory();
dump_memory();
fin_log();
fin_syslog();

View File

@@ -1,8 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_TOOLCONTEXT_H
@@ -42,13 +50,14 @@ struct config_info {
/* FIXME Split into tool & library contexts */
/* command-instance-related variables needed by library */
struct cmd_context {
/* format handler allocates all objects from here */
struct pool *mem;
struct pool *libmem; /* For permanent config data */
struct pool *mem; /* Transient: Cleared between each command */
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 */
const char *hostname;
char *cmd_line;
struct command *command;
@@ -58,10 +67,13 @@ struct cmd_context {
struct dev_filter *filter;
int dump_filter; /* Dump filter when exiting? */
struct config_tree *cf;
struct config_tree *cft;
struct config_info default_settings;
struct config_info current_settings;
/* List of defined tags */
struct list tags;
char sys_dir[PATH_MAX];
char dev_dir[PATH_MAX];
char proc_dir[PATH_MAX];
@@ -69,5 +81,6 @@ struct cmd_context {
struct cmd_context *create_toolcontext(struct arg *the_args);
void destroy_toolcontext(struct cmd_context *cmd);
int refresh_toolcontext(struct cmd_context *cmd);
#endif

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -43,7 +52,7 @@ struct parser {
};
struct cs {
struct config_tree cf;
struct config_tree cft;
struct pool *mem;
time_t timestamp;
char *filename;
@@ -60,6 +69,8 @@ static struct config_value *_create_value(struct parser *p);
static struct config_node *_create_node(struct parser *p);
static char *_dup_tok(struct parser *p);
static const int sep = '/';
#define MAX_INDENT 32
#define match(t) do {\
@@ -99,25 +110,26 @@ struct config_tree *create_config_tree(void)
}
c->mem = mem;
c->cf.root = (struct config_node *) NULL;
c->cft.root = (struct config_node *) NULL;
c->timestamp = 0;
c->filename = NULL;
return &c->cf;
return &c->cft;
}
void destroy_config_tree(struct config_tree *cf)
void destroy_config_tree(struct config_tree *cft)
{
pool_destroy(((struct cs *) cf)->mem);
pool_destroy(((struct cs *) cft)->mem);
}
int read_config_fd(struct config_tree *cf, int fd, const char *file,
int read_config_fd(struct config_tree *cft, 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 cs *c = (struct cs *) cft;
struct parser *p;
off_t mmap_offset = 0;
int r = 0;
int use_mmap = 1;
off_t mmap_offset = 0;
if (!(p = pool_alloc(c->mem, sizeof(*p)))) {
stack;
@@ -125,47 +137,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 % getpagesize();
/* 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 +183,7 @@ int read_config_fd(struct config_tree *cf, int fd, const char *file,
p->tb = p->te = p->fb;
p->line = 1;
_get_token(p, TOK_SECTION_E);
if (!(cf->root = _file(p))) {
if (!(cft->root = _file(p))) {
stack;
goto out;
}
@@ -183,12 +191,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 + mmap_offset)) {
log_sys_error("munmap", file);
log_sys_error("munmap", dev_name(dev));
r = 0;
}
}
@@ -196,11 +204,12 @@ int read_config_fd(struct config_tree *cf, int fd, const char *file,
return r;
}
int read_config_file(struct config_tree *cf, const char *file)
int read_config_file(struct config_tree *cft, const char *file)
{
struct cs *c = (struct cs *) cf;
struct cs *c = (struct cs *) cft;
struct stat info;
int r = 1, fd;
struct device *dev;
int r = 1;
if (stat(file, &info)) {
log_sys_error("stat", file);
@@ -217,15 +226,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, (size_t) info.st_size, 0, 0,
if (!dev_open_flags(dev, O_RDONLY, 0, 0)) {
stack;
return 0;
}
r = read_config_fd(cft, 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);
@@ -233,9 +247,9 @@ int read_config_file(struct config_tree *cf, const char *file)
return r;
}
time_t config_file_timestamp(struct config_tree *cf)
time_t config_file_timestamp(struct config_tree *cft)
{
struct cs *c = (struct cs *) cf;
struct cs *c = (struct cs *) cft;
return c->timestamp;
}
@@ -243,13 +257,14 @@ time_t config_file_timestamp(struct config_tree *cf)
/*
* Returns 1 if config file reloaded
*/
int reload_config_file(struct config_tree **cf)
int reload_config_file(struct config_tree **cft)
{
struct config_tree *new_cf;
struct cs *c = (struct cs *) *cf;
struct config_tree *new_cft;
struct cs *c = (struct cs *) *cft;
struct cs *new_cs;
struct stat info;
int r, fd;
struct device *dev;
int r;
if (!c->filename)
return 0;
@@ -279,26 +294,32 @@ 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())) {
if (!(new_cft = create_config_tree())) {
log_error("Allocation of new config_tree failed");
return 0;
}
r = read_config_fd(new_cf, fd, c->filename, 0, (size_t) info.st_size,
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_cft, dev, 0, (size_t) info.st_size,
0, 0, (checksum_fn_t) NULL, 0);
close(fd);
dev_close(dev);
if (r) {
new_cs = (struct cs *) new_cf;
new_cs = (struct cs *) new_cft;
new_cs->filename = pool_strdup(new_cs->mem, c->filename);
new_cs->timestamp = info.st_mtime;
destroy_config_tree(*cf);
*cf = new_cf;
destroy_config_tree(*cft);
*cft = new_cft;
}
return r;
@@ -372,20 +393,28 @@ static int _write_config(struct config_node *n, FILE *fp, int level)
return 1;
}
int write_config_file(struct config_tree *cf, const char *file)
int write_config_file(struct config_tree *cft, const char *file)
{
int r = 1;
FILE *fp = fopen(file, "w");
if (!fp) {
FILE *fp;
if (!file) {
fp = stdout;
file = "stdout";
} else if (!(fp = fopen(file, "w"))) {
log_sys_error("open", file);
return 0;
}
if (!_write_config(cf->root, fp, 0)) {
stack;
log_verbose("Dumping configuration to %s", file);
if (!_write_config(cft->root, fp, 0)) {
log_error("Failure while writing configuration");
r = 0;
}
fclose(fp);
if (fp != stdout)
fclose(fp);
return r;
}
@@ -492,7 +521,7 @@ static struct config_value *_value(struct parser *p)
static struct config_value *_type(struct parser *p)
{
/* [0-9]+ | [0-9]*\.[0-9]* | ".*" */
/* [+-]{0,1}[0-9]+ | [0-9]*\.[0-9]* | ".*" */
struct config_value *v = _create_value(p);
if (!v)
@@ -627,6 +656,8 @@ static void _get_token(struct parser *p, int tok_prev)
case '7':
case '8':
case '9':
case '+':
case '-':
if (values_allowed) {
p->te++;
while ((p->te != p->fe) && (*p->te)) {
@@ -708,8 +739,7 @@ static char *_dup_tok(struct parser *p)
/*
* utility functions
*/
struct config_node *find_config_node(struct config_node *cn,
const char *path, const int sep)
struct config_node *find_config_node(struct config_node *cn, const char *path)
{
const char *e;
@@ -741,9 +771,9 @@ struct config_node *find_config_node(struct config_node *cn,
}
const char *find_config_str(struct config_node *cn,
const char *path, const int sep, const char *fail)
const char *path, const char *fail)
{
struct config_node *n = find_config_node(cn, path, sep);
struct config_node *n = find_config_node(cn, path);
if (n && n->v->type == CFG_STRING) {
if (*n->v->v.str)
@@ -757,10 +787,9 @@ const char *find_config_str(struct config_node *cn,
return fail;
}
int find_config_int(struct config_node *cn, const char *path,
const int sep, int fail)
int find_config_int(struct config_node *cn, const char *path, int fail)
{
struct config_node *n = find_config_node(cn, path, sep);
struct config_node *n = find_config_node(cn, path);
if (n && n->v->type == CFG_INT) {
log_very_verbose("Setting %s to %d", path, n->v->v.i);
@@ -772,10 +801,9 @@ int find_config_int(struct config_node *cn, const char *path,
return fail;
}
float find_config_float(struct config_node *cn, const char *path,
const int sep, float fail)
float find_config_float(struct config_node *cn, const char *path, float fail)
{
struct config_node *n = find_config_node(cn, path, sep);
struct config_node *n = find_config_node(cn, path);
if (n && n->v->type == CFG_FLOAT) {
log_very_verbose("Setting %s to %f", path, n->v->v.r);
@@ -815,10 +843,9 @@ static int _str_to_bool(const char *str, int fail)
return fail;
}
int find_config_bool(struct config_node *cn, const char *path,
const int sep, int fail)
int find_config_bool(struct config_node *cn, const char *path, int fail)
{
struct config_node *n = find_config_node(cn, path, sep);
struct config_node *n = find_config_node(cn, path);
struct config_value *v;
if (!n)
@@ -838,11 +865,11 @@ int find_config_bool(struct config_node *cn, const char *path,
}
int get_config_uint32(struct config_node *cn, const char *path,
const int sep, uint32_t *result)
uint32_t *result)
{
struct config_node *n;
n = find_config_node(cn, path, sep);
n = find_config_node(cn, path);
if (!n || !n->v || n->v->type != CFG_INT)
return 0;
@@ -852,11 +879,11 @@ int get_config_uint32(struct config_node *cn, const char *path,
}
int get_config_uint64(struct config_node *cn, const char *path,
const int sep, uint64_t *result)
uint64_t *result)
{
struct config_node *n;
n = find_config_node(cn, path, sep);
n = find_config_node(cn, path);
if (!n || !n->v || n->v->type != CFG_INT)
return 0;
@@ -866,12 +893,11 @@ int get_config_uint64(struct config_node *cn, const char *path,
return 1;
}
int get_config_str(struct config_node *cn, const char *path,
const int sep, char **result)
int get_config_str(struct config_node *cn, const char *path, char **result)
{
struct config_node *n;
n = find_config_node(cn, path, sep);
n = find_config_node(cn, path);
if (!n || !n->v || n->v->type != CFG_STRING)
return 0;

View File

@@ -1,12 +1,23 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_CONFIG_H
#define _LVM_CONFIG_H
#include "device.h"
enum {
CFG_STRING,
CFG_FLOAT,
@@ -39,7 +50,7 @@ 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,
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);
@@ -49,31 +60,27 @@ 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, const int separator);
const char *path);
const char *find_config_str(struct config_node *cn,
const char *path, const int sep, const char *fail);
const char *find_config_str(struct config_node *cn, const char *path,
const char *fail);
int find_config_int(struct config_node *cn, const char *path,
const int sep, int fail);
int find_config_int(struct config_node *cn, const char *path, int fail);
float find_config_float(struct config_node *cn, const char *path,
const int sep, float fail);
float find_config_float(struct config_node *cn, const char *path, float fail);
/*
* Understands (0, ~0), (y, n), (yes, no), (on,
* off), (true, false).
*/
int find_config_bool(struct config_node *cn, const char *path,
const int sep, int fail);
int find_config_bool(struct config_node *cn, const char *path, int fail);
int get_config_uint32(struct config_node *cn, const char *path,
const int sep, uint32_t *result);
uint32_t *result);
int get_config_uint64(struct config_node *cn, const char *path,
const int sep, uint64_t *result);
uint64_t *result);
int get_config_str(struct config_node *cn, const char *path,
const int sep, char **result);
int get_config_str(struct config_node *cn, const char *path, char **result);
#endif

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_DEFAULTS_H
@@ -19,6 +28,7 @@
#define DEFAULT_SYS_DIR "/etc/lvm"
#define DEFAULT_DEV_DIR "/dev"
#define DEFAULT_PROC_DIR "/proc"
#define DEFAULT_SYSFS_SCAN 1
#define DEFAULT_LOCK_DIR "/var/lock/lvm"
#define DEFAULT_LOCKING_LIB "lvm2_locking.so"
@@ -50,9 +60,13 @@
#define DEFAULT_INDENT 1
#define DEFAULT_UNITS "h"
#define DEFAULT_SUFFIX 1
#define DEFAULT_HOSTTAGS 0
#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

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_BITSET_H

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_BTREE_H

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -125,7 +134,7 @@ void hash_destroy(struct hash_table *t)
dbg_free(t);
}
static inline struct hash_node **_find(struct hash_table *t, const char *key)
static struct hash_node **_find(struct hash_table *t, const char *key)
{
unsigned h = _hash(key) & (t->num_slots - 1);
struct hash_node **c;

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_HASH_H

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_LIST_H
@@ -13,6 +22,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;
@@ -61,12 +72,32 @@ static inline struct list *list_next(struct list *head, struct list *elem)
return (list_end(head, elem) ? NULL : elem->n);
}
#define list_item(v, t) \
((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->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)
#define list_iterate(v, head) \
for (v = (head)->n; v != head; v = v->n)
#define list_uniterate(v, head, start) \
for (v = (start)->p; v != head; v = v->p)
#define list_iterate_safe(v, t, head) \
for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
#define list_iterate_items(v, head) \
for (v = list_item((head)->n, typeof(*v)); &v->list != (head); \
v = list_item(v->list.n, typeof(*v)))
static inline unsigned int list_size(const struct list *head)
{
unsigned int s = 0;
@@ -78,14 +109,4 @@ static inline unsigned int list_size(const struct list *head)
return s;
}
#define list_item(v, t) \
((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list))
/* 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

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_TYPES_H
@@ -17,7 +26,7 @@
struct str_list {
struct list list;
char *str;
const char *str;
};
#endif

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

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "str_list.h"
struct list *str_list_create(struct pool *mem)
{
struct list *sl;
if (!(sl = pool_alloc(mem, sizeof(struct list)))) {
stack;
return NULL;
}
list_init(sl);
return sl;
}
int str_list_add(struct pool *mem, struct list *sll, const char *str)
{
struct str_list *sln;
if (!str) {
stack;
return 0;
}
/* Already in list? */
if (str_list_match_item(sll, str))
return 1;
if (!(sln = pool_alloc(mem, sizeof(*sln)))) {
stack;
return 0;
}
sln->str = str;
list_add(sll, &sln->list);
return 1;
}
int str_list_del(struct list *sll, const char *str)
{
struct list *slh, *slht;
list_iterate_safe(slh, slht, sll) {
if (!strcmp(str, list_item(slh, struct str_list)->str))
list_del(slh);
}
return 1;
}
int str_list_dup(struct pool *mem, struct list *sllnew, struct list *sllold)
{
struct str_list *sl;
list_init(sllnew);
list_iterate_items(sl, sllold) {
if (!str_list_add(mem, sllnew, strdup(sl->str))) {
stack;
return 0;
}
}
return 1;
}
/*
* Is item on list?
*/
int str_list_match_item(struct list *sll, const char *str)
{
struct str_list *sl;
list_iterate_items(sl, sll)
if (!strcmp(str, sl->str))
return 1;
return 0;
}
/*
* Is at least one item on both lists?
*/
int str_list_match_list(struct list *sll, struct list *sll2)
{
struct str_list *sl;
list_iterate_items(sl, sll)
if (str_list_match_item(sll2, sl->str))
return 1;
return 0;
}
/*
* Do both lists contain the same set of items?
*/
int str_list_lists_equal(struct list *sll, struct list *sll2)
{
struct str_list *sl;
if (list_size(sll) != list_size(sll2))
return 0;
list_iterate_items(sl, sll)
if (!str_list_match_item(sll2, sl->str))
return 0;
return 1;
}

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

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_STR_LIST_H
#define _LVM_STR_LIST_H
#include "pool.h"
struct list *str_list_create(struct pool *mem);
int str_list_add(struct pool *mem, struct list *sll, const char *str);
int str_list_del(struct list *sll, const char *str);
int str_list_match_item(struct list *sll, const char *str);
int str_list_match_list(struct list *sll, struct list *sll2);
int str_list_lists_equal(struct list *sll, struct list *sll2);
int str_list_dup(struct pool *mem, struct list *sllnew, struct list *sllold);
#endif

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -42,7 +51,44 @@ 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;
@@ -50,12 +96,14 @@ static struct device *_create_dev(dev_t d)
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;
}
@@ -175,7 +223,7 @@ static int _insert_dev(const char *path, dev_t 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;
}
@@ -274,6 +322,17 @@ static int _insert(const char *path, int rec)
}
if (S_ISDIR(info.st_mode)) { /* add a directory */
/* check it's not a symbolic link */
if (lstat(path, &info) < 0) {
log_sys_very_verbose("lstat", path);
return 0;
}
if (S_ISLNK(info.st_mode)) {
log_debug("%s: Symbolic link to directory", path);
return 0;
}
if (rec)
r = _insert_dir(path);
@@ -367,11 +426,22 @@ static inline void _check_for_open_devices(void)
void dev_cache_exit(void)
{
_check_for_open_devices();
pool_destroy(_cache.mem);
if (_cache.names)
_check_for_open_devices();
if (_cache.mem) {
pool_destroy(_cache.mem);
_cache.mem = NULL;
}
if (_cache.names) {
hash_destroy(_cache.names);
_cache.names = NULL;
}
_cache.devices = NULL;
_cache.has_scanned = 0;
list_init(&_cache.dirs);
}
int dev_cache_add_dir(const char *path)
@@ -402,20 +472,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);

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_DEV_CACHE_H

View File

@@ -1,13 +1,25 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "lvm-types.h"
#include "device.h"
#include "metadata.h"
#include "lvmcache.h"
#include "memlock.h"
#include "locking.h"
#include <limits.h>
#include <sys/stat.h>
@@ -17,14 +29,195 @@
#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
# ifndef BLKGETSIZE64 /* fs.h out-of-date */
# define BLKGETSIZE64 _IOR(0x12, 114, size_t)
# endif /* BLKGETSIZE64 */
#else
# include <sys/disk.h>
# define BLKBSZGET DKIOCGETBLOCKSIZE
# define BLKSSZGET DKIOCGETBLOCKSIZE
# define BLKGETSIZE64 DKIOCGETBLOCKCOUNT
# define BLKFLSBUF DKIOCSYNCHRONIZECACHE
# define BLKSIZE_SHIFT 0
#endif
/* FIXME 64 bit offset!!!
#ifdef O_DIRECT_SUPPORT
# ifndef O_DIRECT
# error O_DIRECT support configured but O_DIRECT definition not found in headers
# endif
#endif
/* FIXME Use _llseek for 64-bit
_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh);
if (_llseek((unsigned) fd, (ulong) (offset >> 32), (ulong) (offset & 0xFFFFFFFF), &pos, SEEK_SET) < 0) {
*/
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 = getpagesize();
_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;
@@ -70,55 +263,116 @@ int dev_get_sectsize(struct device *dev, uint32_t *size)
return 1;
}
static void _flush(int fd)
void dev_flush(struct device *dev)
{
if (ioctl(fd, BLKFLSBUF, 0) >= 0)
if (!(dev->flags & DEV_REGULAR) && ioctl(dev->fd, BLKFLSBUF, 0) >= 0)
return;
if (fsync(fd) >= 0)
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) {
#ifdef O_DIRECT_SUPPORT
if (direct)
flags |= O_DIRECT;
#endif
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;
#ifndef O_DIRECT_SUPPORT
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_close(struct device *dev)
int dev_open_quiet(struct device *dev)
{
int flags;
flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
return dev_open_flags(dev, flags, 1, 1);
}
int dev_open(struct device *dev)
{
int flags;
flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
return dev_open_flags(dev, flags, 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);
}
}
static int _dev_close(struct device *dev, int immediate)
{
if (dev->fd < 0) {
log_error("Attempt to close device '%s' "
@@ -126,125 +380,101 @@ int dev_close(struct device *dev)
return 0;
}
#ifndef O_DIRECT_SUPPORT
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 && (immediate || !vgs_locked()))
_close(dev);
return 1;
}
ssize_t raw_read(int fd, void *buf, size_t count)
int dev_close(struct device *dev)
{
ssize_t n = 0, tot = 0;
if (count > SSIZE_MAX)
return -1;
while (tot < (signed) count) {
do
n = read(fd, buf, count - tot);
while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (n <= 0)
return tot ? tot : n;
tot += n;
buf += n;
}
return tot;
return _dev_close(dev, 0);
}
ssize_t dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer)
int dev_close_immediate(struct device *dev)
{
const char *name = dev_name(dev);
int fd = dev->fd;
/* loff_t pos; */
if (fd < 0) {
log_err("Attempt to read an unopened device (%s).", name);
return 0;
}
/* if (_llseek((unsigned) fd, (ulong) (offset >> 32), (ulong) (offset & 0xFFFFFFFF), &pos, SEEK_SET) < 0) { */
if (lseek(fd, (off_t) offset, SEEK_SET) < 0) {
log_sys_error("lseek", name);
return 0;
}
return raw_read(fd, buffer, len);
return _dev_close(dev, 1);
}
static int _write(int fd, const void *buf, size_t count)
void dev_close_all(void)
{
ssize_t n = 0;
int tot = 0;
struct list *doh, *doht;
struct device *dev;
/* 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;
list_iterate_safe(doh, doht, &_open_devices) {
dev = list_struct_base(doh, struct device, open_list);
if (dev->open_count < 1)
_close(dev);
}
return tot;
}
int64_t dev_write(struct device * dev, uint64_t offset, size_t len,
void *buffer)
int dev_read(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_error("Attempt to write to unopened device %s", name);
if (!dev->open_count)
return 0;
}
if (lseek(fd, (off_t) offset, SEEK_SET) < 0) {
log_sys_error("lseek", name);
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
*/
/* FIXME pre-extend the file */
int dev_append(struct device *dev, size_t len, void *buffer)
{
int r;
if (!dev->open_count)
return 0;
}
r = dev_write(dev, dev->end, len, buffer);
dev->end += (uint64_t) len;
#ifndef O_DIRECT_SUPPORT
dev_flush(dev);
#endif
return r;
}
int dev_write(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;
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, size_t len)
{
int64_t r;
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, (off_t) 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 %" PRIsize_t,
dev_name(dev), offset, len);
@@ -256,21 +486,19 @@ int dev_zero(struct device *dev, uint64_t offset, size_t len)
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;
}
offset += s;
}
dev->flags |= DEV_ACCESSED_W;
if (!already_open && !dev_close(dev))
if (!dev_close(dev))
stack;
/* FIXME: Always display error */

View File

@@ -1,20 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This file is part of LVM2.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#if 0

View File

@@ -1,15 +1,27 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_DEVICE_H
#define _LVM_DEVICE_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.
@@ -21,7 +33,10 @@ struct device {
/* private */
int fd;
int open_count;
uint32_t flags;
uint64_t end;
struct list open_list;
char pvid[ID_LEN + 1];
};
@@ -43,20 +58,27 @@ 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);
int dev_close_immediate(struct device *dev);
void dev_close_all(void);
static inline int dev_fd(struct device *dev)
{
return dev->fd;
}
ssize_t raw_read(int fd, void *buf, size_t count);
ssize_t dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer);
int64_t dev_write(struct device *dev, uint64_t offset, size_t len,
void *buffer);
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);
struct device *dev_create_file(const char *filename, struct device *dev,
struct str_list *alias);
static inline const char *dev_name(const struct device *dev)
{
@@ -65,12 +87,7 @@ static inline const char *dev_name(const struct device *dev)
}
/* Return a valid device name from the alias list; NULL otherwise */
const char *dev_name_confirmed(struct device *dev);
static inline int dev_is_open(struct device *dev)
{
return dev->fd >= 0 ? 1 : 0;
}
const char *dev_name_confirmed(struct device *dev, int quiet);
/* FIXME Check partition type if appropriate */

View File

@@ -1,21 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This file is part of LVM2.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -75,6 +70,7 @@ uint64_t units_to_bytes(const char *units, char *unit_type)
break;
case 's':
v *= SECTOR_SIZE;
break;
case 'b':
case 'B':
v *= UINT64_C(1);
@@ -82,6 +78,7 @@ uint64_t units_to_bytes(const char *units, char *unit_type)
#define KILO UINT64_C(1024)
case 'k':
v *= KILO;
break;
case 'm':
v *= KILO * KILO;
break;
@@ -388,6 +385,9 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
snap = list_item(slh, struct snapshot_list)->snapshot;
snap_active = lv_snapshot_percent(snap->cow,
&snap_percent);
if (!snap_active || snap_percent < 0 ||
snap_percent >= 100)
snap_active = 0;
log_print(" %s%s/%s [%s]",
lv->vg->cmd->dev_dir, lv->vg->name,
snap->cow->name,
@@ -396,6 +396,8 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
snap = NULL;
} else if ((snap = find_cow(lv))) {
snap_active = lv_snapshot_percent(lv, &snap_percent);
if (!snap_active || snap_percent < 0 || snap_percent >= 100)
snap_active = 0;
log_print("LV snapshot status %s destination for %s%s/%s",
(snap_active > 0) ? "active" : "INACTIVE",
lv->vg->cmd->dev_dir, lv->vg->name,
@@ -652,6 +654,53 @@ void vgdisplay_full(struct volume_group *vg)
void vgdisplay_colons(struct volume_group *vg)
{
uint32_t active_pvs;
const char *access;
char uuid[64];
if (vg->status & PARTIAL_VG)
active_pvs = list_size(&vg->pvs);
else
active_pvs = vg->pv_count;
switch (vg->status & (LVM_READ | LVM_WRITE)) {
case LVM_READ | LVM_WRITE:
access = "r/w";
break;
case LVM_READ:
access = "r";
break;
case LVM_WRITE:
access = "w";
break;
default:
access = "";
}
if (!id_write_format(&vg->id, uuid, sizeof(uuid))) {
stack;
return;
}
log_print("%s:%s:%d:-1:%u:%u:%u:-1:%u:%u:%u:%" PRIu64 ":%" PRIu32
":%u:%u:%u:%s",
vg->name,
access,
vg->status,
/* internal volume group number; obsolete */
vg->max_lv,
vg->lv_count,
lvs_in_vg_opened(vg),
/* FIXME: maximum logical volume size */
vg->max_pv,
vg->pv_count,
active_pvs,
(uint64_t) vg->extent_count * (vg->extent_size / 2),
vg->extent_size / 2,
vg->extent_count,
vg->extent_count - vg->free_count,
vg->free_count,
uuid[0] ? uuid : "none");
return;
}

View File

@@ -1,21 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This file is part of LVM2.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_DISPLAY_H

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -37,35 +46,32 @@ static void _destroy(struct dev_filter *f)
dbg_free(f);
}
struct dev_filter *composite_filter_create(int n, ...)
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
{
struct dev_filter **filters = dbg_malloc(sizeof(*filters) * (n + 1));
struct dev_filter *cf;
va_list ap;
int i;
struct dev_filter **filters_copy, *cf;
if (!filters) {
stack;
return NULL;
}
if (!(cf = dbg_malloc(sizeof(*cf)))) {
stack;
dbg_free(filters);
if (!(filters_copy = dbg_malloc(sizeof(*filters) * (n + 1)))) {
log_error("composite filters allocation failed");
return NULL;
}
va_start(ap, n);
for (i = 0; i < n; i++) {
struct dev_filter *f = va_arg(ap, struct dev_filter *);
filters[i] = f;
memcpy(filters_copy, filters, sizeof(*filters) * n);
filters_copy[n] = NULL;
if (!(cf = dbg_malloc(sizeof(*cf)))) {
log_error("compsoite filters allocation failed");
dbg_free(filters_copy);
return NULL;
}
filters[i] = NULL;
va_end(ap);
cf->passes_filter = _and_p;
cf->destroy = _destroy;
cf->private = filters;
cf->private = filters_copy;
return cf;
}

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_FILTER_COMPOSITE_H
@@ -9,6 +18,6 @@
#include "dev-cache.h"
struct dev_filter *composite_filter_create(int n, ...);
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters);
#endif

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -51,13 +60,13 @@ int persistent_filter_wipe(struct dev_filter *f)
return 1;
}
static int _read_array(struct pfilter *pf, struct config_tree *cf,
static int _read_array(struct pfilter *pf, struct config_tree *cft,
const char *path, void *data)
{
struct config_node *cn;
struct config_value *cv;
if (!(cn = find_config_node(cf->root, path, '/'))) {
if (!(cn = find_config_node(cft->root, path))) {
log_very_verbose("Couldn't find %s array in '%s'",
path, pf->file);
return 0;
@@ -88,22 +97,22 @@ int persistent_filter_load(struct dev_filter *f)
struct pfilter *pf = (struct pfilter *) f->private;
int r = 0;
struct config_tree *cf;
struct config_tree *cft;
if (!(cf = create_config_tree())) {
if (!(cft = create_config_tree())) {
stack;
return 0;
}
if (!read_config_file(cf, pf->file)) {
if (!read_config_file(cft, pf->file)) {
stack;
goto out;
}
_read_array(pf, cf, "persistent_filter_cache/valid_devices",
_read_array(pf, cft, "persistent_filter_cache/valid_devices",
PF_GOOD_DEVICE);
/* We don't gain anything by holding invalid devices */
/* _read_array(pf, cf, "persistent_filter_cache/invalid_devices",
/* _read_array(pf, cft, "persistent_filter_cache/invalid_devices",
PF_BAD_DEVICE); */
/* Did we find anything? */
@@ -116,7 +125,7 @@ int persistent_filter_load(struct dev_filter *f)
log_very_verbose("Loaded persistent filter cache from %s", pf->file);
out:
destroy_config_tree(cf);
destroy_config_tree(cft);
return r;
}

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_FILTER_PERSISTENT_H

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -42,7 +51,7 @@ static int _extract_pattern(struct pool *mem, const char *pat,
pat++;
/*
* get the seperator
* get the separator
*/
switch (*pat) {
case '(':
@@ -75,7 +84,7 @@ static int _extract_pattern(struct pool *mem, const char *pat,
*/
ptr = r + strlen(r) - 1;
if (*ptr != sep) {
log_info("invalid seperator at end of regex");
log_info("invalid separator at end of regex");
return 0;
}
*ptr = '\0';

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_FILTER_REGEX_H

288
lib/filters/filter-sysfs.c Normal file
View File

@@ -0,0 +1,288 @@
/*
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "filter-sysfs.h"
#include "lvm-string.h"
#include "pool.h"
#ifdef linux
#include <dirent.h>
static int _locate_sysfs_blocks(const char *proc, char *path, size_t len)
{
char proc_mounts[PATH_MAX];
int r = 0;
FILE *fp;
char *split[2], buffer[PATH_MAX + 16];
if (!*proc) {
log_verbose("No proc filesystem found: skipping sysfs filter");
return 0;
}
if (lvm_snprintf(proc_mounts, sizeof(proc_mounts),
"%s/mounts", proc) < 0) {
log_error("Failed to create /proc/mounts string");
return 0;
}
if (!(fp = fopen(proc_mounts, "r"))) {
log_sys_error("fopen %s", proc_mounts);
return 0;
}
while (fgets(buffer, sizeof(buffer), fp)) {
if (split_words(buffer, 2, split) == 2 &&
!strcmp(split[0], "sysfs")) {
if (lvm_snprintf(path, len, "%s/%s", split[1],
"block") >= 0) {
r = 1;
}
break;
}
}
fclose(fp);
return r;
}
/*----------------------------------------------------------------
* We need to store a set of dev_t.
*--------------------------------------------------------------*/
struct entry {
struct entry *next;
dev_t dev;
};
#define SET_BUCKETS 64
struct dev_set {
struct pool *mem;
const char *sys_block;
int initialised;
struct entry *slots[SET_BUCKETS];
};
static struct dev_set *_dev_set_create(struct pool *mem, const char *sys_block)
{
struct dev_set *ds;
if (!(ds = pool_zalloc(mem, sizeof(*ds))))
return NULL;
ds->mem = mem;
ds->sys_block = pool_strdup(mem, sys_block);
ds->initialised = 0;
return ds;
}
static inline unsigned _hash_dev(dev_t dev)
{
return (major(dev) ^ minor(dev)) & (SET_BUCKETS - 1);
}
/*
* Doesn't check that the set already contains dev.
*/
static int _set_insert(struct dev_set *ds, dev_t dev)
{
struct entry *e;
unsigned h = _hash_dev(dev);
if (!(e = pool_alloc(ds->mem, sizeof(*e))))
return 0;
e->next = ds->slots[h];
e->dev = dev;
ds->slots[h] = e;
return 1;
}
static int _set_lookup(struct dev_set *ds, dev_t dev)
{
unsigned h = _hash_dev(dev);
struct entry *e;
for (e = ds->slots[h]; e; e = e->next)
if (e->dev == dev)
return 1;
return 0;
}
/*----------------------------------------------------------------
* filter methods
*--------------------------------------------------------------*/
static int _parse_dev(const char *file, FILE *fp, dev_t *result)
{
unsigned major, minor;
char buffer[64];
if (!fgets(buffer, sizeof(buffer), fp)) {
log_error("Empty sysfs device file: %s", file);
return 0;
}
if (sscanf(buffer, "%u:%u", &major, &minor) != 2) {
log_info("sysfs device file not correct format");
return 0;
}
*result = makedev(major, minor);
return 1;
}
static int _read_dev(const char *file, dev_t *result)
{
int r;
FILE *fp;
if (!(fp = fopen(file, "r"))) {
log_sys_error("fopen", file);
return 0;
}
r = _parse_dev(file, fp, result);
fclose(fp);
return r;
}
/*
* Recurse through sysfs directories, inserting any devs found.
*/
static int _read_devs(struct dev_set *ds, const char *dir)
{
struct dirent *d;
DIR *dr;
char path[PATH_MAX];
dev_t dev;
int r = 1;
if (!(dr = opendir(dir))) {
log_sys_error("opendir", dir);
return 0;
}
while ((d = readdir(dr))) {
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
if (lvm_snprintf(path, sizeof(path), "%s/%s", dir,
d->d_name) < 0) {
log_error("sysfs path name too long: %s in %s",
d->d_name, dir);
continue;
}
if (d->d_type == DT_DIR) {
if (!_read_devs(ds, path)) {
r = 0;
break;
}
}
if ((d->d_type == DT_REG && !strcmp(d->d_name, "dev")))
if (!_read_dev(path, &dev) || !_set_insert(ds, dev)) {
r = 0;
break;
}
}
if (closedir(dr))
log_sys_error("closedir", dir);
return r;
}
static int _init_devs(struct dev_set *ds)
{
if (!_read_devs(ds, ds->sys_block)) {
ds->initialised = -1;
return 0;
}
ds->initialised = 1;
return 1;
}
static int _accept_p(struct dev_filter *f, struct device *dev)
{
struct dev_set *ds = (struct dev_set *) f->private;
if (!ds->initialised)
_init_devs(ds);
/* Pass through if initialisation failed */
if (ds->initialised != 1)
return 1;
return _set_lookup(ds, dev->dev);
}
static void _destroy(struct dev_filter *f)
{
struct dev_set *ds = (struct dev_set *) f->private;
pool_destroy(ds->mem);
}
struct dev_filter *sysfs_filter_create(const char *proc)
{
char sys_block[PATH_MAX];
struct pool *mem;
struct dev_set *ds;
struct dev_filter *f;
if (!_locate_sysfs_blocks(proc, sys_block, sizeof(sys_block)))
return NULL;
if (!(mem = pool_create(256))) {
log_error("sysfs pool creation failed");
return NULL;
}
if (!(ds = _dev_set_create(mem, sys_block))) {
log_error("sysfs dev_set creation failed");
goto bad;
}
if (!(f = pool_zalloc(mem, sizeof(*f)))) {
stack;
goto bad;
}
f->passes_filter = _accept_p;
f->destroy = _destroy;
f->private = ds;
return f;
bad:
pool_destroy(mem);
return NULL;
}
#else
struct dev_filter *sysfs_filter_create(const char *proc)
{
return NULL;
}
#endif

View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_FILTER_SYSFS_H
#define _LVM_FILTER_SYSFS_H
#include "config.h"
#include "dev-cache.h"
struct dev_filter *sysfs_filter_create(const char *proc);
#endif

View File

@@ -1,21 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* lvm is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
* This file is part of LVM2.
*
* lvm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -57,6 +52,7 @@ static const device_info_t device_info[] = {
{"cciss", 16}, /* Compaq CCISS array */
{"ubd", 16}, /* User-mode virtual block device */
{"ataraid", 16}, /* ATA Raid */
{"drbd", 16}, /* Distributed Replicated Block Device */
{NULL, 0}
};

View File

@@ -1,21 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* lvm is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
* This file is part of LVM2.
*
* lvm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_FILTER_H

View File

@@ -1,7 +0,0 @@
Base {
global:
init_format;
local:
*;
};

View File

@@ -0,0 +1 @@
init_format

View File

@@ -1,14 +1,22 @@
#
# Copyright (C) 2002 Sistina Software (UK) Limited.
# Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This file is released under the LGPL.
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SOURCES=\
SOURCES =\
disk-rep.c \
format1.c \
import-export.c \
@@ -17,15 +25,14 @@ SOURCES=\
lvm1-label.c \
vg_number.c
TARGETS=liblvm2format1.so
TARGETS = liblvm2format1.so
include ../../make.tmpl
.PHONY: install
install: libformat1.so
install: liblvm2format1.so
$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/liblvm2format1.so.$(LIB_VERSION)
$(LN_S) -f liblvm2format1.so.$(LIB_VERSION) $(libdir)/liblvm2format1.so
.PHONY: install

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -9,7 +18,7 @@
#include "pool.h"
#include "xlate.h"
#include "filter.h"
#include "cache.h"
#include "lvmcache.h"
#include <fcntl.h>
@@ -130,7 +139,7 @@ static int _munge_formats(struct pv_disk *pvd)
static int _read_pvd(struct device *dev, struct pv_disk *pvd)
{
if (dev_read(dev, UINT64_C(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;
@@ -150,12 +159,16 @@ static int _read_pvd(struct device *dev, struct pv_disk *pvd)
return 0;
}
/* If UUID is missing, create one */
if (pvd->pv_uuid[0] == '\0')
uuid_from_num(pvd->pv_uuid, pvd->pv_number);
return 1;
}
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);
@@ -167,11 +180,15 @@ static int _read_vgd(struct disk_list *data)
{
struct vg_disk *vgd = &data->vgd;
uint64_t pos = data->pvd.vg_on_disk.base;
if (dev_read(data->dev, pos, sizeof(*vgd), vgd) != sizeof(*vgd))
if (!dev_read(data->dev, pos, sizeof(*vgd), vgd))
fail;
_xlate_vgd(vgd);
/* If UUID is missing, create one */
if (vgd->vg_uuid[0] == '\0')
uuid_from_num(vgd->vg_uuid, vgd->vg_number);
return 1;
}
@@ -184,8 +201,7 @@ static int _read_uuids(struct disk_list *data)
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))))
@@ -244,7 +260,7 @@ static int _read_extents(struct disk_list *data)
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);
@@ -256,21 +272,21 @@ static int _read_extents(struct disk_list *data)
/*
* If exported, remove "PV_EXP" from end of VG name
*/
static void _munge_exported_vg(struct disk_list *data)
void munge_exported_vg(struct pv_disk *pvd)
{
int l;
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))
/* Return if PV not in a VG */
if ((!*pvd->vg_name))
return;
l = strlen(data->pvd.vg_name);
l = strlen(pvd->vg_name);
s = sizeof(EXPORTED_TAG);
if (!strncmp(data->pvd.vg_name + l - s + 1, EXPORTED_TAG, s))
data->pvd.vg_name[l - s + 1] = '\0';
data->pvd.pv_status |= VG_EXPORTED;
if (!strncmp(pvd->vg_name + l - s + 1, EXPORTED_TAG, s)) {
pvd->vg_name[l - s + 1] = '\0';
pvd->pv_status |= VG_EXPORTED;
}
}
static struct disk_list *__read_disk(const struct format_type *fmt,
@@ -279,7 +295,7 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
{
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;
@@ -296,8 +312,11 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
goto bad;
}
if (!(info = cache_add(fmt->labeller, dl->pvd.pv_uuid, dev,
dl->pvd.vg_name, NULL)))
/* If VG is exported, set VG name back to the real name */
munge_exported_vg(&dl->pvd);
if (!(info = lvmcache_add(fmt->labeller, dl->pvd.pv_uuid, dev,
dl->pvd.vg_name, NULL)))
stack;
else {
info->device_size = xlate32(dl->pvd.pv_size) << SECTOR_SHIFT;
@@ -322,9 +341,6 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
goto bad;
}
/* If VG is exported, set VG name back to the real name */
_munge_exported_vg(dl);
/* Update VG cache with what we found */
/* vgcache_add(dl->pvd.vg_name, dl->vgd.vg_uuid, dev, fmt); */
@@ -365,7 +381,7 @@ struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
{
struct disk_list *r;
if (!dev_open(dev, O_RDONLY)) {
if (!dev_open(dev)) {
stack;
return NULL;
}
@@ -415,13 +431,13 @@ int read_pvs_in_vg(const 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);
@@ -463,7 +479,7 @@ static int _write_vgd(struct disk_list *data)
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);
@@ -486,7 +502,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;
@@ -498,7 +514,7 @@ static int _write_uuids(struct disk_list *data)
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);
@@ -542,7 +558,7 @@ static int _write_extents(struct disk_list *data)
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);
@@ -574,7 +590,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;
}
@@ -640,7 +656,7 @@ 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;
}

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DISK_REP_FORMAT1_H
@@ -10,11 +19,14 @@
#include "lvm-types.h"
#include "metadata.h"
#include "pool.h"
#include "toolcontext.h"
#define MAX_PV 256
#define MAX_LV 256
#define MAX_VG 99
#define LVM_BLK_MAJOR 58
#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */
#define MIN_PE_SIZE (8192L >> SECTOR_SHIFT) /* 8 KB in sectors */
#define MAX_PE_SIZE (16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L)
@@ -171,7 +183,7 @@ struct disk_list {
*/
int calculate_layout(struct disk_list *dl);
int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
uint32_t max_extent_count);
uint32_t max_extent_count, uint64_t pe_start);
/*
* Low level io routines which read/write
@@ -194,7 +206,8 @@ int write_disks(const struct format_type *fmt, struct list *pvds);
int import_pv(struct pool *mem, struct device *dev,
struct volume_group *vg,
struct physical_volume *pv, struct pv_disk *pvd);
int export_pv(struct pool *mem, struct volume_group *vg,
int export_pv(struct cmd_context *cmd, struct pool *mem,
struct volume_group *vg,
struct pv_disk *pvd, struct physical_volume *pv);
int import_vg(struct pool *mem,
@@ -224,6 +237,7 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg);
void export_numbers(struct list *pvds, struct volume_group *vg);
void export_pv_act(struct list *pvds);
void munge_exported_vg(struct pv_disk *pvd);
/* blech */
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -12,10 +21,12 @@
#include "list.h"
#include "display.h"
#include "toolcontext.h"
#include "cache.h"
#include "lvmcache.h"
#include "lvm1-label.h"
#include "format1.h"
#define FMT_LVM1_NAME "lvm1"
/* VG consistency checks */
static int _check_vgs(struct list *pvs, int *partial)
{
@@ -64,6 +75,35 @@ static int _check_vgs(struct list *pvs, int *partial)
else if (memcmp(&first->vgd, &dl->vgd, sizeof(first->vgd))) {
log_error("VG data differs between PVs %s and %s",
dev_name(first->dev), dev_name(dl->dev));
log_debug("VG data on %s: %s %s %" PRIu32 " %" PRIu32
" %" PRIu32 " %" PRIu32 " %" PRIu32 " %"
PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32
" %" PRIu32 " %" PRIu32 " %" PRIu32 " %"
PRIu32 " %" PRIu32 " %" PRIu32,
dev_name(first->dev), first->vgd.vg_uuid,
first->vgd.vg_name_dummy,
first->vgd.vg_number, first->vgd.vg_access,
first->vgd.vg_status, first->vgd.lv_max,
first->vgd.lv_cur, first->vgd.lv_open,
first->vgd.pv_max, first->vgd.pv_cur,
first->vgd.pv_act, first->vgd.dummy,
first->vgd.vgda, first->vgd.pe_size,
first->vgd.pe_total, first->vgd.pe_allocated,
first->vgd.pvg_total);
log_debug("VG data on %s: %s %s %" PRIu32 " %" PRIu32
" %" PRIu32 " %" PRIu32 " %" PRIu32 " %"
PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32
" %" PRIu32 " %" PRIu32 " %" PRIu32 " %"
PRIu32 " %" PRIu32 " %" PRIu32,
dev_name(dl->dev), dl->vgd.vg_uuid,
dl->vgd.vg_name_dummy, dl->vgd.vg_number,
dl->vgd.vg_access, dl->vgd.vg_status,
dl->vgd.lv_max, dl->vgd.lv_cur,
dl->vgd.lv_open, dl->vgd.pv_max,
dl->vgd.pv_cur, dl->vgd.pv_act, dl->vgd.dummy,
dl->vgd.vgda, dl->vgd.pe_size,
dl->vgd.pe_total, dl->vgd.pe_allocated,
dl->vgd.pvg_total);
list_del(pvh);
if (partial_mode()) {
*partial = 1;
@@ -75,9 +115,9 @@ static int _check_vgs(struct list *pvs, int *partial)
}
/* On entry to fn, list known to be non-empty */
if (pv_count != dl->vgd.pv_cur) {
if (pv_count != first->vgd.pv_cur) {
log_error("%d PV(s) found for VG %s: expected %d",
pv_count, dl->pvd.vg_name, dl->vgd.pv_cur);
pv_count, first->pvd.vg_name, first->vgd.pv_cur);
if (!partial_mode())
return 0;
*partial = 1;
@@ -108,6 +148,7 @@ static struct volume_group *_build_vg(struct format_instance *fid,
list_init(&vg->pvs);
list_init(&vg->lvs);
list_init(&vg->snapshots);
list_init(&vg->tags);
if (!_check_vgs(pvs, &partial))
goto bad;
@@ -170,7 +211,8 @@ static struct volume_group *_vg_read(struct format_instance *fid,
return vg;
}
static struct disk_list *_flatten_pv(struct pool *mem, struct volume_group *vg,
static struct disk_list *_flatten_pv(struct format_instance *fid,
struct pool *mem, struct volume_group *vg,
struct physical_volume *pv,
const char *dev_dir)
{
@@ -187,7 +229,7 @@ static struct disk_list *_flatten_pv(struct pool *mem, struct volume_group *vg,
list_init(&dl->uuids);
list_init(&dl->lvds);
if (!export_pv(mem, vg, &dl->pvd, pv) ||
if (!export_pv(fid->fmt->cmd, mem, vg, &dl->pvd, pv) ||
!export_vg(&dl->vgd, vg) ||
!export_uuids(dl, vg) ||
!export_lvs(dl, vg, pv, dev_dir) || !calculate_layout(dl)) {
@@ -211,7 +253,7 @@ static int _flatten_vg(struct format_instance *fid, struct pool *mem,
list_iterate(pvh, &vg->pvs) {
pvl = list_item(pvh, struct pv_list);
if (!(data = _flatten_pv(mem, vg, pvl->pv, dev_dir))) {
if (!(data = _flatten_pv(fid, mem, vg, pvl->pv, dev_dir))) {
stack;
return 0;
}
@@ -248,7 +290,7 @@ 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;
}
@@ -315,14 +357,12 @@ static int _pv_setup(const struct format_type *fmt,
/*
* This works out pe_start and pe_count.
*/
if (!calculate_extent_count(pv, extent_size, extent_count)) {
if (!calculate_extent_count(pv, extent_size, extent_count, pe_start)) {
stack;
return 0;
}
/* Retain existing extent locations exactly */
/* FIXME Relax this so a non-overlapping existing pe_start can also
* be used in place of the calculated one */
if (((pe_start || extent_count) && (pe_start != pv->pe_start)) ||
(extent_count && (extent_count != pv->pe_count))) {
log_error("Metadata would overwrite physical extents");
@@ -332,32 +372,12 @@ static int _pv_setup(const struct format_type *fmt,
return 1;
}
static uint32_t _find_free_lvnum(struct logical_volume *lv)
{
int lvnum_used[MAX_LV];
uint32_t i = 0;
struct list *lvh;
struct lv_list *lvl;
memset(&lvnum_used, 0, sizeof(lvnum_used));
list_iterate(lvh, &lv->vg->lvs) {
lvl = list_item(lvh, struct lv_list);
lvnum_used[lvnum_from_lvid(&lvl->lv->lvid)] = 1;
}
while (lvnum_used[i])
i++;
return i;
}
static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
{
uint64_t max_size = UINT_MAX;
if (!*lv->lvid.s)
lvid_from_lvnum(&lv->lvid, &lv->vg->id, _find_free_lvnum(lv));
lvid_from_lvnum(&lv->lvid, &lv->vg->id, find_free_lvnum(lv));
if (lv->le_count > MAX_LE_TOTAL) {
log_error("logical volumes cannot contain more than "
@@ -381,10 +401,10 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
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;
}
@@ -412,7 +432,7 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
dl->mem = mem;
dl->dev = pv->dev;
if (!export_pv(mem, NULL, &dl->pvd, pv)) {
if (!export_pv(fmt->cmd, mem, NULL, &dl->pvd, pv)) {
stack;
goto bad;
}
@@ -440,10 +460,10 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
{
/* just check max_pv and max_lv */
if (vg->max_lv >= MAX_LV)
if (!vg->max_lv || vg->max_lv >= MAX_LV)
vg->max_lv = MAX_LV - 1;
if (vg->max_pv >= MAX_PV)
if (!vg->max_pv || vg->max_pv >= MAX_PV)
vg->max_pv = MAX_PV - 1;
if (vg->extent_size > MAX_PE_SIZE || vg->extent_size < MIN_PE_SIZE) {
@@ -548,7 +568,7 @@ struct format_type *init_format(struct cmd_context *cmd)
fmt->ops = &_format1_ops;
fmt->name = FMT_LVM1_NAME;
fmt->alias = NULL;
fmt->features = 0;
fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE;
fmt->private = NULL;
if (!(fmt->labeller = lvm1_labeller_create(fmt))) {

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_FORMAT1_H
@@ -9,8 +18,6 @@
#include "metadata.h"
#define FMT_LVM1_NAME "lvm1"
#ifdef LVM1_INTERNAL
struct format_type *init_lvm1_format(struct cmd_context *cmd);
#endif

View File

@@ -1,9 +1,20 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Translates between disk and in-core formats.
*
* This file is released under the LGPL.
*/
#include "lib.h"
@@ -13,9 +24,9 @@
#include "list.h"
#include "lvm-string.h"
#include "filter.h"
#include "toolcontext.h"
#include <time.h>
#include <sys/utsname.h>
static int _check_vg_name(const char *name)
{
@@ -56,9 +67,9 @@ int import_pv(struct pool *mem, struct device *dev,
if (vg &&
strncmp(vg->system_id, pvd->system_id, sizeof(pvd->system_id)))
log_very_verbose("System ID %s on %s differs from %s for "
"volume group", pvd->system_id,
dev_name(pv->dev), vg->system_id);
log_very_verbose("System ID %s on %s differs from %s for "
"volume group", pvd->system_id,
dev_name(pv->dev), vg->system_id);
/*
* If exported, we still need to flag in pv->status too because
@@ -76,20 +87,16 @@ int import_pv(struct pool *mem, struct device *dev,
pv->pe_count = pvd->pe_total;
pv->pe_alloc_count = pvd->pe_allocated;
list_init(&pv->tags);
return 1;
}
static int _system_id(char *s, const char *prefix)
static int _system_id(struct cmd_context *cmd, char *s, const char *prefix)
{
struct utsname uts;
if (uname(&uts) != 0) {
log_sys_error("uname", "_system_id");
return 0;
}
if (lvm_snprintf(s, NAME_LEN, "%s%s%lu",
prefix, uts.nodename, time(NULL)) < 0) {
prefix, cmd->hostname, time(NULL)) < 0) {
log_error("Generated system_id too long");
return 0;
}
@@ -97,7 +104,8 @@ static int _system_id(char *s, const char *prefix)
return 1;
}
int export_pv(struct pool *mem, struct volume_group *vg,
int export_pv(struct cmd_context *cmd, struct pool *mem,
struct volume_group *vg,
struct pv_disk *pvd, struct physical_volume *pv)
{
memset(pvd, 0, sizeof(*pvd));
@@ -128,7 +136,7 @@ int export_pv(struct pool *mem, struct volume_group *vg,
if (!*vg->system_id ||
strncmp(vg->system_id, EXPORTED_TAG,
sizeof(EXPORTED_TAG) - 1)) {
if (!_system_id(pvd->system_id, EXPORTED_TAG)) {
if (!_system_id(cmd, pvd->system_id, EXPORTED_TAG)) {
stack;
return 0;
}
@@ -145,7 +153,7 @@ int export_pv(struct pool *mem, struct volume_group *vg,
/* Is VG being imported? */
if (vg && !(vg->status & EXPORTED_VG) && *vg->system_id &&
!strncmp(vg->system_id, EXPORTED_TAG, sizeof(EXPORTED_TAG) - 1)) {
if (!_system_id(pvd->system_id, IMPORTED_TAG)) {
if (!_system_id(cmd, pvd->system_id, IMPORTED_TAG)) {
stack;
return 0;
}
@@ -153,7 +161,7 @@ int export_pv(struct pool *mem, struct volume_group *vg,
/* Generate system_id if PV is in VG */
if (!pvd->system_id || !*pvd->system_id)
if (!_system_id(pvd->system_id, "")) {
if (!_system_id(cmd, pvd->system_id, "")) {
stack;
return 0;
}
@@ -162,7 +170,7 @@ int export_pv(struct pool *mem, struct volume_group *vg,
if (vg &&
(!*vg->system_id ||
strncmp(vg->system_id, pvd->system_id, sizeof(pvd->system_id))))
strncpy(vg->system_id, pvd->system_id, NAME_LEN);
strncpy(vg->system_id, pvd->system_id, NAME_LEN);
//pvd->pv_major = MAJOR(pv->dev);
@@ -314,6 +322,7 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
lv->le_count = lvd->lv_allocated_le;
list_init(&lv->segments);
list_init(&lv->tags);
return 1;
}
@@ -339,6 +348,8 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
if (lv->status & FIXED_MINOR) {
lvd->lv_status |= LV_PERSISTENT_MINOR;
lvd->lv_dev = MKDEV(lv->major, lv->minor);
} else {
lvd->lv_dev = MKDEV(LVM_BLK_MAJOR, lvnum_from_lvid(&lv->lvid));
}
lvd->lv_read_ahead = lv->read_ahead;

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -9,6 +18,7 @@
#include "hash.h"
#include "pool.h"
#include "disk-rep.h"
#include "lv_alloc.h"
/*
* After much thought I have decided it is easier,
@@ -191,26 +201,13 @@ static int _check_maps_are_complete(struct hash_table *maps)
return 1;
}
static struct lv_segment *_alloc_seg(struct pool *mem, uint32_t stripes)
{
struct lv_segment *seg;
uint32_t len = sizeof(*seg) + (stripes * sizeof(seg->area[0]));
if (!(seg = pool_zalloc(mem, len))) {
stack;
return NULL;
}
return seg;
}
static int _read_linear(struct pool *mem, struct lv_map *lvm)
{
uint32_t le = 0;
struct lv_segment *seg;
while (le < lvm->lv->le_count) {
seg = _alloc_seg(mem, 1);
seg = alloc_lv_segment(mem, 1);
seg->lv = lvm->lv;
seg->type = SEG_STRIPED;
@@ -276,7 +273,7 @@ static int _read_stripes(struct pool *mem, struct lv_map *lvm)
len = lvm->lv->le_count / lvm->stripes;
while (le < len) {
if (!(seg = _alloc_seg(mem, lvm->stripes))) {
if (!(seg = alloc_lv_segment(mem, lvm->stripes))) {
stack;
return 0;
}

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -103,9 +112,10 @@ int calculate_layout(struct disk_list *dl)
/*
* The number of extents that can fit on a disk is metadata format dependant.
* pe_start is any existing value for pe_start
*/
int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
uint32_t max_extent_count)
uint32_t max_extent_count, uint64_t pe_start)
{
struct pv_disk *pvd = dbg_malloc(sizeof(*pvd));
uint32_t end;
@@ -138,6 +148,9 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
end = ((pvd->pe_on_disk.base + pvd->pe_on_disk.size +
SECTOR_SIZE - 1) >> SECTOR_SHIFT);
if (pe_start && end < pe_start)
end = pe_start;
pvd->pe_start = _round_up(end, PE_ALIGN);
} while ((pvd->pe_start + (pvd->pe_total * extent_size))

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2002 Sistina Software (UK) Limited.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -10,7 +19,7 @@
#include "label.h"
#include "metadata.h"
#include "xlate.h"
#include "cache.h"
#include "lvmcache.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -49,10 +58,13 @@ 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)))
munge_exported_vg(pvd);
if (!(info = lvmcache_add(l, pvd->pv_uuid, dev, pvd->vg_name, NULL))) {
stack;
return 0;
}
*label = info->label;
info->device_size = xlate32(pvd->pv_size) << SECTOR_SHIFT;

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2002 Sistina Software (UK) Limited.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_LVM1_LABEL_H

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -50,7 +59,7 @@ struct archive_file {
/*
* Extract vg name and version number from a filename.
*/
static int _split_vg(const char *filename, char *vg, size_t vg_size,
static int _split_vg(const char *filename, char *vgname, size_t vg_size,
uint32_t *ix)
{
size_t len, vg_len;
@@ -74,8 +83,8 @@ static int _split_vg(const char *filename, char *vg, size_t vg_size,
if (vg_len + 1 > vg_size)
return 0;
strncpy(vg, filename, vg_len);
vg[vg_len] = '\0';
strncpy(vgname, filename, vg_len);
vgname[vg_len] = '\0';
return 1;
}
@@ -121,10 +130,10 @@ static char *_join(struct pool *mem, const char *dir, const char *name)
* Returns a list of archive_files.
*/
static struct list *_scan_archive(struct pool *mem,
const char *vg, const char *dir)
const char *vgname, const char *dir)
{
int i, count, ix;
char vg_name[64], *path;
char vgname_found[64], *path;
struct dirent **dirent;
struct archive_file *af;
struct list *results;
@@ -148,12 +157,12 @@ static struct list *_scan_archive(struct pool *mem,
continue;
/* check the name is the correct format */
if (!_split_vg(dirent[i]->d_name, vg_name, sizeof(vg_name),
&ix))
if (!_split_vg(dirent[i]->d_name, vgname_found,
sizeof(vgname_found), &ix))
continue;
/* is it the vg we're interested in ? */
if (strcmp(vg, vg_name))
if (strcmp(vgname, vgname_found))
continue;
if (!(path = _join(mem, dir, dirent[i]->d_name))) {
@@ -304,7 +313,8 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
char *desc;
void *context;
log_print("path:\t\t%s", af->path);
log_print(" ");
log_print("File:\t\t%s", af->path);
if (!(context = create_text_context(cmd, af->path, NULL)) ||
!(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
@@ -324,34 +334,50 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
return;
}
log_print("description:\t%s", desc ? desc : "<No description>");
log_print("time:\t\t%s", ctime(&when));
log_print("VG name: \t%s", vg->name);
log_print("Description:\t%s", desc ? desc : "<No description>");
log_print("Backup Time:\t%s", ctime(&when));
pool_free(cmd->mem, vg);
tf->fmt->ops->destroy_instance(tf);
}
int archive_list(struct cmd_context *cmd, const char *dir, const char *vg)
int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
{
struct list *archives, *ah;
struct archive_file *af;
if (!(archives = _scan_archive(cmd->mem, vg, dir))) {
if (!(archives = _scan_archive(cmd->mem, vgname, dir))) {
log_err("Couldn't scan the archive directory (%s).", dir);
return 0;
}
if (list_empty(archives))
log_print("No archives found.");
log_print("No archives found in %s.", dir);
list_iterate(ah, archives) {
af = list_item(ah, struct archive_file);
_display_archive(cmd, af);
log_print(" ");
}
pool_free(cmd->mem, archives);
return 1;
}
int backup_list(struct cmd_context *cmd, const char *dir, const char *vgname)
{
struct archive_file af;
if (!(af.path = _join(cmd->mem, dir, vgname))) {
stack;
return 0;
}
if (path_exists(af.path))
_display_archive(cmd, &af);
return 1;
}

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -270,7 +279,7 @@ static int _print_header(struct formatter *f,
static int _print_vg(struct formatter *f, struct volume_group *vg)
{
char buffer[256];
char buffer[4096];
if (!id_write_format(&vg->id, buffer, sizeof(buffer))) {
stack;
@@ -280,14 +289,24 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
_outf(f, "id = \"%s\"", buffer);
_outf(f, "seqno = %u", vg->seqno);
if (!print_flags(vg->status, VG_FLAGS, buffer, sizeof(buffer))) {
stack;
return 0;
}
_outf(f, "status = %s", buffer);
if (!list_empty(&vg->tags)) {
if (!print_tags(&vg->tags, buffer, sizeof(buffer))) {
stack;
return 0;
}
_outf(f, "tags = %s", buffer);
}
if (vg->system_id && *vg->system_id)
_outf(f, "system_id = \"%s\"", vg->system_id);
if (!_out_size(f, (uint64_t) vg->extent_size, "extent_size = %u",
vg->extent_size)) {
stack;
@@ -314,14 +333,13 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
{
struct list *pvh;
struct physical_volume *pv;
char buffer[256];
char buffer[4096];
const char *name;
_outf(f, "physical_volumes {");
_inc_indent(f);
list_iterate(pvh, &vg->pvs) {
pv = list_item(pvh, struct pv_list)->pv;
if (!(name = _get_pv_name(f, pv))) {
@@ -349,8 +367,16 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
stack;
return 0;
}
_outf(f, "status = %s", buffer);
if (!list_empty(&pv->tags)) {
if (!print_tags(&pv->tags, buffer, sizeof(buffer))) {
stack;
return 0;
}
_outf(f, "tags = %s", buffer);
}
_outf(f, "pe_start = %" PRIu64, pv->pe_start);
if (!_out_size(f, vg->extent_size * (uint64_t) pv->pe_count,
"pe_count = %u", pv->pe_count)) {
@@ -373,6 +399,7 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
unsigned int s;
const char *name;
const char *type;
char buffer[4096];
_outf(f, "segment%u {", count);
_inc_indent(f);
@@ -387,6 +414,14 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
f->nl(f);
_outf(f, "type = \"%s\"", get_segtype_string(seg->type));
if (!list_empty(&seg->tags)) {
if (!print_tags(&seg->tags, buffer, sizeof(buffer))) {
stack;
return 0;
}
_outf(f, "tags = %s", buffer);
}
switch (seg->type) {
case SEG_SNAPSHOT:
_outf(f, "chunk_size = %u", seg->chunk_size);
@@ -491,6 +526,9 @@ static int _print_snapshot(struct formatter *f, struct snapshot *snap,
seg.cow = snap->cow;
seg.chunk_size = snap->chunk_size;
/* Can't tag a snapshot independently of its origin */
list_init(&seg.tags);
if (!_print_segment(f, snap->origin->vg, 1, &seg)) {
stack;
return 0;
@@ -522,10 +560,10 @@ static int _print_snapshots(struct formatter *f, struct volume_group *vg)
static int _print_lvs(struct formatter *f, struct volume_group *vg)
{
struct list *lvh, *segh;
struct list *lvh;
struct logical_volume *lv;
struct lv_segment *seg;
char buffer[256];
char buffer[4096];
int seg_count;
/*
@@ -556,8 +594,16 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
stack;
return 0;
}
_outf(f, "status = %s", buffer);
if (!list_empty(&lv->tags)) {
if (!print_tags(&lv->tags, buffer, sizeof(buffer))) {
stack;
return 0;
}
_outf(f, "tags = %s", buffer);
}
if (lv->alloc != ALLOC_DEFAULT)
_outf(f, "allocation_policy = \"%s\"",
get_alloc_string(lv->alloc));
@@ -571,9 +617,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
f->nl(f);
seg_count = 1;
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct lv_segment);
list_iterate_items(seg, &lv->segments) {
if (!_print_segment(f, vg, seg_count++, seg)) {
stack;
return 0;

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -63,23 +72,6 @@ static struct flag *_get_flags(int type)
return NULL;
}
static int _emit(char **buffer, size_t *size, const char *fmt, ...)
{
int n;
va_list ap;
va_start(ap, fmt);
n = vsnprintf(*buffer, *size, fmt, ap);
va_end(ap);
if (n < 0 || (n == *size))
return 0;
*buffer += n;
*size -= n;
return 1;
}
/*
* Converts a bitset to an array of string values,
* using one of the tables defined at the top of
@@ -95,27 +87,27 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size)
return 0;
}
if (!_emit(&buffer, &size, "["))
if (!emit_to_buffer(&buffer, &size, "["))
return 0;
for (f = 0; flags[f].mask; f++) {
if (status & flags[f].mask) {
if (!first) {
if (!_emit(&buffer, &size, ", "))
if (!emit_to_buffer(&buffer, &size, ", "))
return 0;
} else
first = 0;
if (!_emit(&buffer, &size, "\"%s\"",
flags[f].description))
if (!emit_to_buffer(&buffer, &size, "\"%s\"",
flags[f].description))
return 0;
status &= ~flags[f].mask;
}
}
if (!_emit(&buffer, &size, "]"))
if (!emit_to_buffer(&buffer, &size, "]"))
return 0;
if (status)

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001-2002 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -20,6 +29,7 @@
#include "crc.h"
#include "xlate.h"
#include "label.h"
#include "memlock.h"
#include <unistd.h>
#include <sys/file.h>
@@ -27,6 +37,9 @@
#include <dirent.h>
#include <ctype.h>
#define FMT_TEXT_NAME "lvm2"
#define FMT_TEXT_ALIAS "text"
static struct format_instance *_create_text_instance(const struct format_type
*fmt, const char *vgname,
void *context);
@@ -107,8 +120,7 @@ static struct mda_header *_raw_read_mda_header(const 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;
@@ -156,8 +168,7 @@ static int _raw_write_mda_header(const struct format_type *fmt,
MDA_HEADER_SIZE -
sizeof(mdah->checksum_xl)));
if (dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)
!= MDA_HEADER_SIZE) {
if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) {
stack;
pool_free(fmt->cmd->mem, mdah);
return 0;
@@ -178,9 +189,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;
}
@@ -214,7 +224,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,7 +249,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
char *desc;
uint32_t wrap = 0;
if (!dev_open(area->dev, O_RDONLY)) {
if (!dev_open(area->dev)) {
stack;
return NULL;
}
@@ -264,8 +274,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
}
/* FIXME 64-bit */
if (!(vg = text_vg_import_fd(fid, dev_name(area->dev),
dev_fd(area->dev),
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),
@@ -321,7 +330,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;
}
@@ -370,9 +379,8 @@ 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,
(size_t) (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;
}
@@ -382,11 +390,10 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
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,
(size_t) 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;
}
@@ -403,7 +410,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;
@@ -432,11 +439,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;
@@ -469,6 +471,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)
{
@@ -477,7 +506,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;
}
@@ -738,7 +767,7 @@ static int _scan_file(const 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))
@@ -753,13 +782,10 @@ int vgname_from_mda(const struct format_type *fmt, struct device_area *dev_area,
{
struct raw_locn *rlocn;
struct mda_header *mdah;
int already_open;
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;
}
@@ -772,8 +798,8 @@ int vgname_from_mda(const 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) != (signed) size) {
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
size, buf)) {
stack;
goto out;
}
@@ -797,7 +823,7 @@ int vgname_from_mda(const 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;
@@ -824,7 +850,7 @@ static int _scan_raw(const 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);
}
}
@@ -875,6 +901,17 @@ static int _mda_setup(const struct format_type *fmt,
/* Place mda straight after label area at start of disk */
start1 = LABEL_SCAN_SIZE;
/* Ensure it's not going to be bigger than the disk! */
if (mda_size1 > disk_size) {
log_print("Warning: metadata area fills disk %s",
dev_name(pv->dev));
/* Leave some free space for rounding */
/* Avoid empty data area as could cause tools problems */
mda_size1 = disk_size - start1 - alignment * 2;
/* Only have 1 mda in this case */
pvmetadatacopies = 1;
}
/* Round up to PE_ALIGN boundary */
mda_adjustment = (mda_size1 + start1) % alignment;
if (mda_adjustment)
@@ -960,7 +997,7 @@ 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;
@@ -970,8 +1007,8 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
/* FIXME Test mode don't update cache? */
if (!(info = cache_add(fmt->labeller, (char *) &pv->id, pv->dev,
ORPHAN, NULL))) {
if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
ORPHAN, NULL))) {
stack;
return 0;
}
@@ -1035,7 +1072,7 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
return 0;
}
if (!dev_open(pv->dev, O_RDWR)) {
if (!dev_open(pv->dev)) {
stack;
return 0;
}
@@ -1121,7 +1158,7 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
{
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;
@@ -1137,7 +1174,7 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
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 &&
@@ -1147,12 +1184,15 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
}
/* Perform full scan and try again */
cache_label_scan(fmt->cmd, 1);
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 */
@@ -1251,7 +1291,8 @@ 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 */
@@ -1265,7 +1306,7 @@ static int _pv_setup(const 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;
@@ -1357,7 +1398,7 @@ static struct format_instance *_create_text_instance(const struct format_type
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.");
@@ -1425,13 +1466,13 @@ static struct format_instance *_create_text_instance(const struct format_type
}
/* 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 =
@@ -1552,21 +1593,21 @@ static int _get_config_disk_area(struct cmd_context *cmd,
return 0;
}
if (!get_config_uint64(cn, "start_sector", '/', &dev_area.start)) {
if (!get_config_uint64(cn, "start_sector", &dev_area.start)) {
log_error("Missing start_sector in metadata disk_area section "
"of config file");
return 0;
}
dev_area.start <<= SECTOR_SHIFT;
if (!get_config_uint64(cn, "size", '/', &dev_area.size)) {
if (!get_config_uint64(cn, "size", &dev_area.size)) {
log_error("Missing size in metadata disk_area section "
"of config file");
return 0;
}
dev_area.size <<= SECTOR_SHIFT;
if (!get_config_str(cn, "id", '/', &id_str)) {
if (!get_config_str(cn, "id", &id_str)) {
log_error("Missing uuid in metadata disk_area section "
"of config file");
return 0;
@@ -1608,7 +1649,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
fmt->ops = &_text_handler;
fmt->name = FMT_TEXT_NAME;
fmt->alias = FMT_TEXT_ALIAS;
fmt->features = FMT_SEGMENTS | FMT_MDAS;
fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS;
if (!(mda_lists = dbg_malloc(sizeof(struct mda_lists)))) {
log_error("Failed to allocate dir_list");
@@ -1631,7 +1672,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
return NULL;
}
if ((cn = find_config_node(cmd->cf->root, "metadata/dirs", '/'))) {
if ((cn = find_config_node(cmd->cft->root, "metadata/dirs"))) {
for (cv = cn->v; cv; cv = cv->next) {
if (cv->type != CFG_STRING) {
log_error("Invalid string in config file: "
@@ -1647,7 +1688,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
}
}
if (!(cn = find_config_node(cmd->cf->root, "metadata/disk_areas", '/')))
if (!(cn = find_config_node(cmd->cft->root, "metadata/disk_areas")))
return fmt;
for (cn = cn->child; cn; cn = cn->sib) {

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_FORMAT_TEXT_H
@@ -11,9 +20,6 @@
#include "metadata.h"
#include "pool.h"
#define FMT_TEXT_NAME "lvm2"
#define FMT_TEXT_ALIAS "text"
/*
* Archives a vg config. 'retain_days' is the minimum number of
* days that an archive file must be held for. 'min_archives' is
@@ -27,7 +33,8 @@ int archive_vg(struct volume_group *vg,
/*
* Displays a list of vg backups in a particular archive directory.
*/
int archive_list(struct cmd_context *cmd, const char *dir, const char *vg);
int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname);
int backup_list(struct cmd_context *cmd, const char *dir, const char *vgname);
/*
* The text format can read and write a volume_group to a file.

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_TEXT_IMPORT_EXPORT_H
@@ -46,6 +55,9 @@ struct text_vg_version_ops *text_vg_vsn1_init(void);
int print_flags(uint32_t status, int type, char *buffer, size_t size);
int read_flags(uint32_t *status, int type, struct config_value *cv);
int print_tags(struct list *tags, char *buffer, size_t size);
int read_tags(struct pool *mem, struct list *tags, struct config_value *cv);
int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp);
int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
uint32_t size);
@@ -54,7 +66,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

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -11,14 +20,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,
@@ -26,7 +35,7 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
time_t *when, char **desc)
{
struct volume_group *vg = NULL;
struct config_tree *cf;
struct config_tree *cft;
struct text_vg_version_ops **vsn;
static int _initialised = 0;
@@ -40,15 +49,14 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
*desc = NULL;
*when = 0;
if (!(cf = create_config_tree())) {
if (!(cft = create_config_tree())) {
stack;
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(cft, file)) ||
(dev && !read_config_fd(cft, dev, offset, size,
offset2, size2, checksum_fn, checksum))) {
log_error("Couldn't read volume group metadata.");
goto out;
}
@@ -57,20 +65,20 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
* Find a set of version functions that can read this file
*/
for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
if (!(*vsn)->check_version(cf))
if (!(*vsn)->check_version(cft))
continue;
if (!(vg = (*vsn)->read_vg(fid, cf))) {
if (!(vg = (*vsn)->read_vg(fid, cft))) {
stack;
goto out;
}
(*vsn)->read_desc(fid->fmt->cmd->mem, cf, when, desc);
(*vsn)->read_desc(fid->fmt->cmd->mem, cft, when, desc);
break;
}
out:
destroy_config_tree(cf);
destroy_config_tree(cft);
return vg;
}
@@ -78,6 +86,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

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -11,7 +20,8 @@
#include "display.h"
#include "hash.h"
#include "toolcontext.h"
#include "cache.h"
#include "lvmcache.h"
#include "lv_alloc.h"
typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
struct volume_group * vg, struct config_node * pvn,
@@ -19,13 +29,13 @@ typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
struct hash_table * pv_hash);
#define _read_int32(root, path, result) \
get_config_uint32(root, path, '/', result)
get_config_uint32(root, path, result)
#define _read_uint32(root, path, result) \
get_config_uint32(root, path, '/', result)
get_config_uint32(root, path, result)
#define _read_int64(root, path, result) \
get_config_uint64(root, path, '/', result)
get_config_uint64(root, path, result)
/*
* Logs an attempt to read an invalid format file.
@@ -39,7 +49,7 @@ static void _invalid_format(const char *str)
* Checks that the config file contains vg metadata, and that it
* we recognise the version number,
*/
static int _check_version(struct config_tree *cf)
static int _check_version(struct config_tree *cft)
{
struct config_node *cn;
struct config_value *cv;
@@ -47,7 +57,7 @@ static int _check_version(struct config_tree *cf)
/*
* Check the contents field.
*/
if (!(cn = find_config_node(cf->root, CONTENTS_FIELD, '/'))) {
if (!(cn = find_config_node(cft->root, CONTENTS_FIELD))) {
_invalid_format("missing contents field");
return 0;
}
@@ -61,7 +71,7 @@ static int _check_version(struct config_tree *cf)
/*
* Check the version number.
*/
if (!(cn = find_config_node(cf->root, FORMAT_VERSION_FIELD, '/'))) {
if (!(cn = find_config_node(cft->root, FORMAT_VERSION_FIELD))) {
_invalid_format("missing version number");
return 0;
}
@@ -79,7 +89,7 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path)
{
struct config_value *cv;
if (!(cn = find_config_node(cn, path, '/'))) {
if (!(cn = find_config_node(cn, path))) {
log_error("Couldn't find uuid.");
return 0;
}
@@ -156,7 +166,7 @@ static int _read_pv(struct format_instance *fid, struct pool *mem,
return 0;
}
if (!(cn = find_config_node(pvn, "status", '/'))) {
if (!(cn = find_config_node(pvn, "status"))) {
log_error("Couldn't find status flags for physical volume.");
return 0;
}
@@ -177,6 +187,16 @@ static int _read_pv(struct format_instance *fid, struct pool *mem,
return 0;
}
list_init(&pv->tags);
/* Optional tags */
if ((cn = find_config_node(pvn, "tags")) &&
!(read_tags(mem, &pv->tags, cn->v))) {
log_error("Couldn't read tags for physical volume %s in %s.",
dev_name(pv->dev), vg->name);
return 0;
}
/* adjust the volume group. */
vg->extent_count += pv->pe_count;
vg->free_count += pv->pe_count;
@@ -244,7 +264,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
}
segtype = SEG_STRIPED; /* Default */
if ((cn = find_config_node(sn, "type", '/'))) {
if ((cn = find_config_node(sn, "type"))) {
cv = cn->v;
if (!cv || !cv->v.str) {
log_error("Segment type must be a string.");
@@ -268,7 +288,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
return 0;
}
if (find_config_node(sn, "extents_moved", '/')) {
if (find_config_node(sn, "extents_moved")) {
if (_read_uint32(sn, "extents_moved", &extents_moved))
seg_status |= PVMOVE;
else {
@@ -279,9 +299,8 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
}
}
if (!(seg = pool_zalloc(mem, sizeof(*seg) +
(sizeof(seg->area[0]) * area_count)))) {
stack;
if (!(seg = alloc_lv_segment(mem, area_count))) {
log_error("Segment allocation failed");
return 0;
}
@@ -293,6 +312,14 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
seg->status = seg_status;
seg->extents_moved = extents_moved;
/* Optional tags */
if ((cn = find_config_node(sn, "tags")) &&
!(read_tags(mem, &seg->tags, cn->v))) {
log_error("Couldn't read tags for a segment of %s/%s.",
vg->name, lv->name);
return 0;
}
switch (segtype) {
case SEG_SNAPSHOT:
lv->status |= SNAPSHOT;
@@ -304,13 +331,13 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
log_suppress(1);
if (!(cow_name = find_config_str(sn, "cow_store", '/', NULL))) {
if (!(cow_name = find_config_str(sn, "cow_store", NULL))) {
log_suppress(0);
log_error("Snapshot cow storage not specified.");
return 0;
}
if (!(org_name = find_config_str(sn, "origin", '/', NULL))) {
if (!(org_name = find_config_str(sn, "origin", NULL))) {
log_suppress(0);
log_error("Snapshot origin not specified.");
return 0;
@@ -344,7 +371,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
return 0;
}
if (!(cn = find_config_node(sn, "stripes", '/'))) {
if (!(cn = find_config_node(sn, "stripes"))) {
log_error("Couldn't find stripes array for segment "
"'%s'.", sn->key);
return 0;
@@ -362,7 +389,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
}
if ((seg->type == SEG_MIRRORED) &&
!(cn = find_config_node(sn, "mirrors", '/'))) {
!(cn = find_config_node(sn, "mirrors"))) {
log_error("Couldn't find mirrors array for segment "
"'%s'.", sn->key);
return 0;
@@ -518,7 +545,7 @@ static int _read_lvnames(struct format_instance *fid, struct pool *mem,
return 0;
}
if (!(cn = find_config_node(lvn, "status", '/'))) {
if (!(cn = find_config_node(lvn, "status"))) {
log_error("Couldn't find status flags for logical volume.");
return 0;
}
@@ -529,7 +556,7 @@ static int _read_lvnames(struct format_instance *fid, struct pool *mem,
}
lv->alloc = ALLOC_DEFAULT;
if ((cn = find_config_node(lvn, "allocation_policy", '/'))) {
if ((cn = find_config_node(lvn, "allocation_policy"))) {
struct config_value *cv = cn->v;
if (!cv || !cv->v.str) {
log_error("allocation_policy must be a string.");
@@ -544,6 +571,15 @@ static int _read_lvnames(struct format_instance *fid, struct pool *mem,
lv->read_ahead = 0;
list_init(&lv->segments);
list_init(&lv->tags);
/* Optional tags */
if ((cn = find_config_node(lvn, "tags")) &&
!(read_tags(mem, &lv->tags, cn->v))) {
log_error("Couldn't read tags for logical volume %s/%s.",
vg->name, lv->name);
return 0;
}
lv->vg = vg;
vg->lv_count++;
@@ -618,7 +654,7 @@ static int _read_sections(struct format_instance *fid,
{
struct config_node *n;
if (!(n = find_config_node(vgn, section, '/'))) {
if (!(n = find_config_node(vgn, section))) {
if (!optional) {
log_error("Couldn't find section '%s'.", section);
return 0;
@@ -638,7 +674,7 @@ static int _read_sections(struct format_instance *fid,
}
static struct volume_group *_read_vg(struct format_instance *fid,
struct config_tree *cf)
struct config_tree *cft)
{
struct config_node *vgn, *cn;
struct volume_group *vg;
@@ -646,7 +682,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
struct pool *mem = fid->fmt->cmd->mem;
/* skip any top-level values */
for (vgn = cf->root; (vgn && vgn->v); vgn = vgn->sib) ;
for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) ;
if (!vgn) {
log_error("Couldn't find volume group in file.");
@@ -675,7 +711,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
vgn = vgn->child;
if ((cn = find_config_node(vgn, "system_id", '/')) && cn->v) {
if ((cn = find_config_node(vgn, "system_id")) && cn->v) {
if (!cn->v->v.str) {
log_error("system_id must be a string");
goto bad;
@@ -694,7 +730,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad;
}
if (!(cn = find_config_node(vgn, "status", '/'))) {
if (!(cn = find_config_node(vgn, "status"))) {
log_error("Couldn't find status flags for volume group %s.",
vg->name);
goto bad;
@@ -748,6 +784,14 @@ static struct volume_group *_read_vg(struct format_instance *fid,
list_init(&vg->lvs);
list_init(&vg->snapshots);
list_init(&vg->tags);
/* Optional tags */
if ((cn = find_config_node(vgn, "tags")) &&
!(read_tags(mem, &vg->tags, cn->v))) {
log_error("Couldn't read tags for volume group %s.", vg->name);
goto bad;
}
if (!_read_sections(fid, "logical_volumes", _read_lvnames, mem, vg,
vgn, pv_hash, 1)) {
@@ -784,17 +828,17 @@ static struct volume_group *_read_vg(struct format_instance *fid,
}
static void _read_desc(struct pool *mem,
struct config_tree *cf, time_t *when, char **desc)
struct config_tree *cft, time_t *when, char **desc)
{
const char *d;
unsigned int u = 0u;
log_suppress(1);
d = find_config_str(cf->root, "description", '/', "");
d = find_config_str(cft->root, "description", "");
log_suppress(0);
*desc = pool_strdup(mem, d);
get_config_uint32(cf->root, "creation_time", '/', &u);
get_config_uint32(cft->root, "creation_time", &u);
*when = u;
}

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_TEXT_LAYOUT_H

76
lib/format_text/tags.c Normal file
View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "metadata.h"
#include "import-export.h"
#include "pool.h"
#include "str_list.h"
#include "lvm-string.h"
int print_tags(struct list *tags, char *buffer, size_t size)
{
struct str_list *sl;
int first = 1;
if (!emit_to_buffer(&buffer, &size, "[")) {
stack;
return 0;
}
list_iterate_items(sl, tags) {
if (!first) {
if (!emit_to_buffer(&buffer, &size, ", ")) {
stack;
return 0;
}
} else
first = 0;
if (!emit_to_buffer(&buffer, &size, "\"%s\"", sl->str)) {
stack;
return 0;
}
}
if (!emit_to_buffer(&buffer, &size, "]")) {
stack;
return 0;
}
return 1;
}
int read_tags(struct pool *mem, struct list *tags, struct config_value *cv)
{
if (cv->type == CFG_EMPTY_ARRAY)
return 1;
while (cv) {
if (cv->type != CFG_STRING) {
log_error("Found a tag that is not a string");
return 0;
}
if (!str_list_add(mem, tags, pool_strdup(mem, cv->v.str))) {
stack;
return 0;
}
cv = cv->next;
}
return 1;
}

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2002 Sistina Software (UK) Limited.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -27,7 +36,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 +49,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));
@@ -56,8 +65,8 @@ static int _write(struct label *label, char *buf)
}
/* NULL-termination */
pvh_dlocn_xl->offset = xlate64(0);
pvh_dlocn_xl->size = xlate64(0);
pvh_dlocn_xl->offset = xlate64(UINT64_C(0));
pvh_dlocn_xl->size = xlate64(UINT64_C(0));
pvh_dlocn_xl++;
/* List of metadata area header locations */
@@ -74,8 +83,8 @@ static int _write(struct label *label, char *buf)
}
/* NULL-termination */
pvh_dlocn_xl->offset = xlate64(0);
pvh_dlocn_xl->size = xlate64(0);
pvh_dlocn_xl->offset = xlate64(UINT64_C(0));
pvh_dlocn_xl->size = xlate64(UINT64_C(0));
return 1;
}
@@ -185,7 +194,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 +204,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 +239,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 +250,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);

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2002 Sistina Software
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -9,7 +18,7 @@
#include "list.h"
#include "crc.h"
#include "xlate.h"
#include "cache.h"
#include "lvmcache.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -104,21 +113,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, UINT64_C(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;
}
@@ -178,7 +183,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;
@@ -200,13 +205,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, UINT64_C(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;
}
@@ -236,8 +246,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);
@@ -278,7 +288,11 @@ 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->labeller->ops->write) {
log_err("Label handler does not support label writes");
return 0;
}
if ((LABEL_SIZE + (label->sector << SECTOR_SHIFT)) > LABEL_SCAN_SIZE) {
log_error("Label sector %" PRIu64 " beyond range (%ld)",
@@ -292,27 +306,27 @@ int label_write(struct device *dev, struct label *label)
lh->sector_xl = xlate64(label->sector);
lh->offset_xl = xlate32(sizeof(*lh));
if (!label->labeller->ops->write(label, buf))
if (!label->labeller->ops->write(label, buf)) {
stack;
return 0;
}
lh->crc_xl = xlate32(calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE -
((void *) &lh->offset_xl - (void *) lh)));
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;
@@ -329,7 +343,7 @@ int label_verify(struct device *dev)
return 0;
}
return l->ops->verify(l, buf, sector);
return ((l->ops->verify) ? l->ops->verify(l, buf, sector) : 1);
}
void label_destroy(struct label *label)

View File

@@ -1,13 +1,22 @@
/*
* Copyright (C) 2002 Sistina Software (UK) Limited.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_LABEL_H
#define _LVM_LABEL_H
#include "cache.h"
#include "lvmcache.h"
#include "uuid.h"
#include "device.h"

View File

@@ -1,8 +1,16 @@
/*
* Copyright (C) 2002 Sistina Software (UK) Limited.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -14,7 +22,8 @@ static void *_locking_lib = NULL;
static void (*_end_fn) (void) = NULL;
static int (*_lock_fn) (struct cmd_context * cmd, const char *resource,
int flags) = NULL;
static int (*_init_fn) (int type, struct config_tree * cf) = NULL;
static int (*_init_fn) (int type, struct config_tree * cft,
uint32_t *flags) = NULL;
static int _lock_resource(struct cmd_context *cmd, const char *resource,
int flags)
@@ -38,7 +47,7 @@ static void _fin_external_locking(void)
_lock_fn = NULL;
}
int init_external_locking(struct locking_type *locking, struct config_tree *cf)
int init_external_locking(struct locking_type *locking, struct config_tree *cft)
{
const char *libname;
@@ -49,19 +58,20 @@ int init_external_locking(struct locking_type *locking, struct config_tree *cf)
locking->lock_resource = _lock_resource;
locking->fin_locking = _fin_external_locking;
locking->flags = 0;
libname = find_config_str(cf->root, "global/locking_library", '/',
libname = find_config_str(cft->root, "global/locking_library",
DEFAULT_LOCKING_LIB);
if (!(_locking_lib = load_shared_library(cf, libname, "locking"))) {
if (!(_locking_lib = load_shared_library(cft, libname, "locking"))) {
stack;
return 0;
}
/* Get the functions we need */
if (!(_init_fn = dlsym(_locking_lib, "init_locking")) ||
if (!(_init_fn = dlsym(_locking_lib, "locking_init")) ||
!(_lock_fn = dlsym(_locking_lib, "lock_resource")) ||
!(_end_fn = dlsym(_locking_lib, "end_locking"))) {
!(_end_fn = dlsym(_locking_lib, "locking_end"))) {
log_error("Shared library %s does not contain locking "
"functions", libname);
dlclose(_locking_lib);
@@ -70,5 +80,5 @@ int init_external_locking(struct locking_type *locking, struct config_tree *cf)
}
log_verbose("Loaded external locking library %s", libname);
return _init_fn(2, cf);
return _init_fn(2, cft, &locking->flags);
}

View File

@@ -1,8 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -13,6 +21,7 @@
#include "defaults.h"
#include "lvm-file.h"
#include "lvm-string.h"
#include "lvmcache.h"
#include <limits.h>
#include <unistd.h>
@@ -202,24 +211,39 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
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;
@@ -236,15 +260,16 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
return 1;
}
int init_file_locking(struct locking_type *locking, struct config_tree *cf)
int init_file_locking(struct locking_type *locking, struct config_tree *cft)
{
locking->lock_resource = _file_lock_resource;
locking->reset_locking = _reset_file_locking;
locking->fin_locking = _fin_file_locking;
locking->flags = 0;
/* Get lockfile directory from config file */
strncpy(_lock_dir, find_config_str(cf->root, "global/locking_dir",
'/', DEFAULT_LOCK_DIR),
strncpy(_lock_dir, find_config_str(cft->root, "global/locking_dir",
DEFAULT_LOCK_DIR),
sizeof(_lock_dir));
if (!create_dir(_lock_dir))

View File

@@ -1,8 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -11,36 +19,24 @@
#include "lvm-string.h"
#include "activate.h"
#include "toolcontext.h"
#include "memlock.h"
#include <signal.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <limits.h>
#include <unistd.h>
static struct locking_type _locking;
static sigset_t _oldset;
static int _lock_count = 0; /* Number of locks held */
static int _write_lock_held = 0;
static int _vg_lock_count = 0; /* Number of locks held */
static int _vg_write_lock_held = 0; /* VG write lock held? */
static int _signals_blocked = 0;
static void _block_signals(int flags)
{
sigset_t set;
/* Stop process memory getting swapped out */
#ifdef MCL_CURRENT
if (!_write_lock_held && (flags & LCK_SCOPE_MASK) == LCK_LV &&
(flags & LCK_TYPE_MASK) == LCK_WRITE) {
if (mlockall(MCL_CURRENT | MCL_FUTURE))
log_sys_error("mlockall", "");
else {
log_very_verbose("Locking memory");
_write_lock_held = 1;
}
}
#endif
if (_signals_blocked)
return;
@@ -61,19 +57,8 @@ static void _block_signals(int flags)
static void _unblock_signals(void)
{
#ifdef MCL_CURRENT
if (!_lock_count && _write_lock_held) {
if (munlockall()) {
log_very_verbose("Unlocking memory");
log_sys_error("munlockall", "");
}
_write_lock_held = 0;
}
#endif
/* Don't unblock signals while any locks are held */
if (!_signals_blocked || _lock_count)
if (!_signals_blocked || _vg_lock_count)
return;
if (sigprocmask(SIG_SETMASK, &_oldset, NULL)) {
@@ -86,12 +71,30 @@ static void _unblock_signals(void)
return;
}
static void _lock_memory(int flags)
{
if (!(_locking.flags & LCK_PRE_MEMLOCK))
return;
if ((flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_SUSPEND)
memlock_inc();
}
static void _unlock_memory(int flags)
{
if (!(_locking.flags & LCK_PRE_MEMLOCK))
return;
if ((flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_RESUME)
memlock_dec();
}
void reset_locking(void)
{
int was_locked = _lock_count;
int was_locked = _vg_lock_count;
_lock_count = 0;
_write_lock_held = 0;
_vg_lock_count = 0;
_vg_write_lock_held = 0;
_locking.reset_locking();
@@ -99,35 +102,44 @@ void reset_locking(void)
_unblock_signals();
}
static inline void _update_lock_count(int flags)
static inline void _update_vg_lock_count(int flags)
{
if ((flags & LCK_SCOPE_MASK) != LCK_VG)
return;
if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)
_lock_count--;
_vg_lock_count--;
else
_lock_count++;
_vg_lock_count++;
/* We don't bother to reset this until all VG locks are dropped */
if ((flags & LCK_TYPE_MASK) == LCK_WRITE)
_vg_write_lock_held = 1;
else if (!_vg_lock_count)
_vg_write_lock_held = 0;
}
/*
* Select a locking type
*/
int init_locking(int type, struct config_tree *cf)
int init_locking(int type, struct config_tree *cft)
{
switch (type) {
case 0:
init_no_locking(&_locking, cf);
init_no_locking(&_locking, cft);
log_print("WARNING: Locking disabled. Be careful! "
"This could corrupt your metadata.");
return 1;
case 1:
if (!init_file_locking(&_locking, cf))
if (!init_file_locking(&_locking, cft))
break;
log_very_verbose("File-based locking enabled.");
return 1;
#ifdef HAVE_LIBDL
case 2:
if (!init_external_locking(&_locking, cf))
if (!init_external_locking(&_locking, cft))
break;
log_very_verbose("External locking enabled.");
return 1;
@@ -144,7 +156,7 @@ int init_locking(int type, struct config_tree *cf)
/* FIXME Ensure only read ops are permitted */
log_verbose("Locking disabled - only read operations permitted.");
init_no_locking(&_locking, cf);
init_no_locking(&_locking, cft);
return 1;
}
@@ -191,13 +203,16 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
static int _lock_vol(struct cmd_context *cmd, const char *resource, int flags)
{
_block_signals(flags);
_lock_memory(flags);
if (!(_locking.lock_resource(cmd, resource, flags))) {
_unlock_memory(flags);
_unblock_signals();
return 0;
}
_update_lock_count(flags);
_update_vg_lock_count(flags);
_unlock_memory(flags);
_unblock_signals();
return 1;
@@ -235,3 +250,44 @@ int lock_vol(struct cmd_context *cmd, const char *vol, int flags)
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 suspend %s", lv->name);
list_uniterate(lvh, lvs, lvh) {
lv = list_item(lvh, struct lv_list)->lv;
unlock_lv(cmd, lv->lvid.s);
}
return 0;
}
}
return 1;
}
int vg_write_lock_held(void)
{
return _vg_write_lock_held;
}

View File

@@ -1,8 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "metadata.h"
@@ -12,6 +20,7 @@
int init_locking(int type, struct config_tree *cf);
void fin_locking(void);
void reset_locking(void);
int vg_write_lock_held(void);
/*
* LCK_VG:
@@ -33,7 +42,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
/*
* Lock type - these numbers are the same as VMS and the IBM DLM
*/
#define LCK_TYPE_MASK 0x000000FF
#define LCK_TYPE_MASK 0x00000007
#define LCK_NULL 0x00000000 /* LCK$_NLMODE */
#define LCK_READ 0x00000001 /* LCK$_CRMODE */
@@ -41,20 +50,20 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
/* LCK$_PRMODE */
#define LCK_WRITE 0x00000004 /* LCK$_PWMODE */
#define LCK_EXCL 0x00000005 /* LCK$_EXMODE */
#define LCK_UNLOCK 0x00000010 /* This is ours */
#define LCK_UNLOCK 0x00000006 /* This is ours */
/*
* Lock scope
*/
#define LCK_SCOPE_MASK 0x0000FF00
#define LCK_SCOPE_MASK 0x00000008
#define LCK_VG 0x00000000
#define LCK_LV 0x00000100
#define LCK_LV 0x00000008
/*
* Lock bits
*/
#define LCK_NONBLOCK 0x00010000 /* Don't block waiting for lock? */
#define LCK_HOLD 0x00020000 /* Hold lock when lock_vol returns? */
#define LCK_NONBLOCK 0x00000010 /* Don't block waiting for lock? */
#define LCK_HOLD 0x00000020 /* Hold lock when lock_vol returns? */
/*
* Common combinations
@@ -63,10 +72,16 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_VG_WRITE (LCK_VG | LCK_WRITE | LCK_HOLD)
#define LCK_VG_UNLOCK (LCK_VG | LCK_UNLOCK)
#define LCK_LV_DEACTIVATE (LCK_LV | LCK_EXCL)
#define LCK_LV_SUSPEND (LCK_LV | LCK_WRITE)
#define LCK_LV_ACTIVATE (LCK_LV | LCK_READ)
#define LCK_LV_RESUME (LCK_LV | LCK_UNLOCK | LCK_NONBLOCK)
#define LCK_LV_UNLOCK (LCK_LV | LCK_UNLOCK)
#define LCK_LV_ACTIVATE (LCK_LV | LCK_READ)
#define LCK_LV_DEACTIVATE (LCK_LV | LCK_EXCL)
#define unlock_lv(cmd, vol) lock_vol(cmd, vol, LCK_LV_UNLOCK)
#define unlock_vg(cmd, vol) lock_vol(cmd, vol, LCK_VG_UNLOCK)
/* Process 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);

View File

@@ -1,8 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "metadata.h"
@@ -14,7 +22,10 @@ typedef int (*lock_resource_fn) (struct cmd_context * cmd, const char *resource,
typedef void (*fin_lock_fn) (void);
typedef void (*reset_lock_fn) (void);
#define LCK_PRE_MEMLOCK 0x00000001 /* Is memlock() needed before calls? */
struct locking_type {
uint32_t flags;
lock_resource_fn lock_resource;
reset_lock_fn reset_locking;

View File

@@ -1,8 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -10,6 +18,7 @@
#include "locking_types.h"
#include "lvm-string.h"
#include "activate.h"
#include "lvmcache.h"
#include <signal.h>
@@ -32,6 +41,15 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
{
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) {
@@ -56,11 +74,12 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
return 1;
}
int init_no_locking(struct locking_type *locking, struct config_tree *cf)
int init_no_locking(struct locking_type *locking, struct config_tree *cft)
{
locking->lock_resource = _no_lock_resource;
locking->reset_locking = _no_reset_locking;
locking->fin_locking = _no_fin_locking;
locking->flags = 0;
return 1;
}

View File

@@ -1,32 +1,83 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#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 _verbose_level = VERBOSE_BASE_LEVEL;
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)
static lvm2_log_fn_t _lvm2_log_fn = NULL;
void init_log_fn(lvm2_log_fn_t log_fn)
{
_log = fp;
if (log_fn)
_lvm2_log_fn = log_fn;
else
_lvm2_log_fn = NULL;
}
void init_log_file(const char *log_file, int append)
{
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)
{
int open_flags = append ? 0 : O_TRUNC;
dev_create_file(log_file, &_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)
@@ -40,9 +91,26 @@ void log_suppress(int suppress)
_log_suppress = suppress;
}
void fin_log()
void release_log_memory(void)
{
_log = 0;
if (!_log_direct)
return;
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()
@@ -136,57 +204,88 @@ int debug_level()
void print_log(int level, const char *file, int line, const char *format, ...)
{
va_list ap;
char buf[1024], buf2[4096];
int bufused, n;
const char *message;
const char *trformat; /* Translated format string */
trformat = _(format);
if (_lvm2_log_fn) {
va_start(ap, format);
n = vsnprintf(buf2, sizeof(buf2) - 1, trformat, ap);
va_end(ap);
if (n < 0) {
fprintf(stderr, _("vsnprintf failed: skipping external "
"logging function"));
goto log_it;
}
buf2[sizeof(buf2) - 1] = '\0';
message = &buf2[0];
_lvm2_log_fn(level, file, line, message);
return;
}
log_it:
if (!_log_suppress) {
va_start(ap, format);
switch (level) {
case _LOG_DEBUG:
if (!strcmp("<backtrace>", format))
break;
if (_verbose_level > 2) {
if (_verbose_level >= _LOG_DEBUG) {
printf("%s%s", _cmd_name, _msg_prefix);
if (_indent)
printf(" ");
vprintf(format, ap);
vprintf(trformat, ap);
putchar('\n');
}
break;
case _LOG_INFO:
if (_verbose_level > 1) {
if (_verbose_level >= _LOG_INFO) {
printf("%s%s", _cmd_name, _msg_prefix);
if (_indent)
printf(" ");
vprintf(format, ap);
vprintf(trformat, ap);
putchar('\n');
}
break;
case _LOG_NOTICE:
if (_verbose_level) {
if (_verbose_level >= _LOG_NOTICE) {
printf("%s%s", _cmd_name, _msg_prefix);
if (_indent)
printf(" ");
vprintf(format, ap);
vprintf(trformat, ap);
putchar('\n');
}
break;
case _LOG_WARN:
printf("%s%s", _cmd_name, _msg_prefix);
vprintf(format, ap);
putchar('\n');
if (_verbose_level >= _LOG_WARN) {
printf("%s%s", _cmd_name, _msg_prefix);
vprintf(trformat, ap);
putchar('\n');
}
break;
case _LOG_ERR:
fprintf(stderr, "%s%s", _cmd_name, _msg_prefix);
vfprintf(stderr, format, ap);
fputc('\n', stderr);
if (_verbose_level >= _LOG_ERR) {
fprintf(stderr, "%s%s", _cmd_name, _msg_prefix);
vfprintf(stderr, trformat, ap);
fputc('\n', stderr);
}
break;
case _LOG_FATAL:
default:
fprintf(stderr, "%s%s", _cmd_name, _msg_prefix);
vfprintf(stderr, format, ap);
fputc('\n', stderr);
if (_verbose_level >= _LOG_FATAL) {
fprintf(stderr, "%s%s", _cmd_name, _msg_prefix);
vfprintf(stderr, trformat, ap);
fputc('\n', stderr);
}
break;
;
}
va_end(ap);
}
@@ -194,20 +293,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, trformat, 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);
vsyslog(level, trformat, 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,
trformat, 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

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_LOG_H
@@ -39,8 +48,13 @@
#define _LOG_ERR 3
#define _LOG_FATAL 2
void init_log(FILE *fp);
#define VERBOSE_BASE_LEVEL _LOG_WARN
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);
@@ -66,6 +80,14 @@ int ignorelockingfailure(void);
/* Suppress messages to stdout/stderr */
void log_suppress(int suppress);
/* Suppress messages to syslog */
void syslog_suppress(int suppress);
typedef void (*lvm2_log_fn_t) (int level, const char *file, int line,
const char *message);
void init_log_fn(lvm2_log_fn_t log_fn);
void print_log(int level, const char *file, int line, const char *format, ...)
__attribute__ ((format(printf, 4, 5)));
@@ -90,5 +112,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
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

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

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_LV_ALLOC_H
#include "pool.h"
struct lv_segment *alloc_lv_segment(struct pool *mem, uint32_t num_areas);
#endif

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -10,6 +19,7 @@
#include "pv_map.h"
#include "lvm-string.h"
#include "toolcontext.h"
#include "lv_alloc.h"
/*
* These functions adjust the pe counts in pv's
@@ -49,46 +59,54 @@ static void _put_extents(struct lv_segment *seg)
}
}
static struct lv_segment *_alloc_segment(struct pool *mem, uint32_t stripes)
struct lv_segment *alloc_lv_segment(struct pool *mem, uint32_t num_areas)
{
struct lv_segment *seg;
uint32_t len = sizeof(*seg) + (stripes * sizeof(seg->area[0]));
uint32_t len = sizeof(*seg) + (num_areas * sizeof(seg->area[0]));
if (!(seg = pool_zalloc(mem, len))) {
stack;
return NULL;
}
list_init(&seg->tags);
return seg;
}
static int _alloc_stripe_area(struct logical_volume *lv, uint32_t stripes,
uint32_t stripe_size,
struct pv_area **areas, uint32_t *ix)
static int _alloc_parallel_area(struct logical_volume *lv, uint32_t area_count,
uint32_t stripe_size,
struct pv_area **areas, uint32_t *ix)
{
uint32_t count = lv->le_count - *ix;
uint32_t area_len = count / stripes;
uint32_t smallest = areas[stripes - 1]->count;
uint32_t count, area_len, smallest;
uint32_t s;
struct lv_segment *seg;
int striped = 0;
striped = 1;
count = lv->le_count - *ix;
area_len = count / (striped ? area_count : 1);
smallest = areas[area_count - 1]->count;
if (smallest < area_len)
area_len = smallest;
if (!(seg = _alloc_segment(lv->vg->cmd->mem, stripes))) {
log_err("Couldn't allocate new stripe segment.");
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, area_count))) {
log_err("Couldn't allocate new parallel segment.");
return 0;
}
seg->lv = lv;
seg->type = SEG_STRIPED;
seg->le = *ix;
seg->len = area_len * stripes;
seg->len = area_len * (striped ? area_count : 1);
seg->area_len = area_len;
seg->area_count = stripes;
seg->area_count = area_count;
seg->stripe_size = stripe_size;
seg->extents_moved = 0u;
for (s = 0; s < stripes; s++) {
for (s = 0; s < area_count; s++) {
struct pv_area *pva = areas[s];
seg->area[s].type = AREA_PV;
seg->area[s].u.pv.pv = pva->map->pvl->pv;
@@ -115,9 +133,9 @@ static int _comp_area(const void *l, const void *r)
return 0;
}
static int _alloc_striped(struct logical_volume *lv,
struct list *pvms, uint32_t allocated,
uint32_t stripes, uint32_t stripe_size)
static int _alloc_parallel(struct logical_volume *lv,
struct list *pvms, uint32_t allocated,
uint32_t stripes, uint32_t stripe_size)
{
int r = 0;
struct list *pvmh;
@@ -125,6 +143,9 @@ static int _alloc_striped(struct logical_volume *lv,
unsigned int pv_count = 0, ix;
struct pv_map *pvm;
size_t len;
uint32_t area_count;
area_count = stripes;
list_iterate(pvmh, pvms)
pv_count++;
@@ -148,9 +169,9 @@ static int _alloc_striped(struct logical_volume *lv,
areas[ix++] = list_item(pvm->areas.n, struct pv_area);
}
if (ix < stripes) {
if (ix < area_count) {
log_error("Insufficient allocatable extents suitable "
"for striping for logical volume "
"for parallel use for logical volume "
"%s: %u required", lv->name, lv->le_count);
goto out;
}
@@ -158,8 +179,8 @@ static int _alloc_striped(struct logical_volume *lv,
/* sort the areas so we allocate from the biggest */
qsort(areas, ix, sizeof(*areas), _comp_area);
if (!_alloc_stripe_area(lv, stripes, stripe_size, areas,
&allocated)) {
if (!_alloc_parallel_area(lv, area_count, stripe_size, areas,
&allocated)) {
stack;
goto out;
}
@@ -188,7 +209,7 @@ static int _alloc_linear_area(struct logical_volume *lv, uint32_t *ix,
if (count > remaining)
count = remaining;
if (!(seg = _alloc_segment(lv->vg->cmd->mem, 1))) {
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 1))) {
log_err("Couldn't allocate new stripe segment.");
return 0;
}
@@ -224,7 +245,7 @@ static int _alloc_mirrored_area(struct logical_volume *lv, uint32_t *ix,
if (count > remaining)
count = remaining;
if (!(seg = _alloc_segment(lv->vg->cmd->mem, 2))) {
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 2))) {
log_err("Couldn't allocate new mirrored segment.");
return 0;
}
@@ -400,7 +421,7 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
goto out;
if (stripes > 1)
r = _alloc_striped(lv, pvms, allocated, stripes, stripe_size);
r = _alloc_parallel(lv, pvms, allocated, stripes, stripe_size);
else if (mirrored_pv)
r = _alloc_mirrored(lv, pvms, allocated, mirrored_pv,
@@ -477,7 +498,7 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
struct logical_volume *lv;
char dname[32];
if (vg->max_lv == vg->lv_count) {
if (vg->max_lv && (vg->max_lv == vg->lv_count)) {
log_error("Maximum number of logical volumes (%u) reached "
"in volume group %s", vg->max_lv, vg->name);
return NULL;
@@ -518,6 +539,7 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
lv->size = UINT64_C(0);
lv->le_count = 0;
list_init(&lv->segments);
list_init(&lv->tags);
if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
stack;
@@ -591,6 +613,7 @@ int lv_reduce(struct format_instance *fi,
struct list *segh;
struct lv_segment *seg;
uint32_t count = extents;
int striped;
for (segh = lv->segments.p;
(segh != &lv->segments) && count; segh = segh->p) {
@@ -605,6 +628,16 @@ int lv_reduce(struct format_instance *fi,
/* reduce this segment */
_put_extents(seg);
seg->len -= count;
striped = (seg->type == SEG_STRIPED);
/* Caller must ensure exact divisibility */
if (striped && (count % seg->area_count)) {
log_error("Segment extent reduction %" PRIu32
"not divisible by #stripes %" PRIu32,
count, seg->area_count);
return 0;
}
seg->area_len -=
count / (striped ? seg->area_count : 1);
_get_extents(seg);
count = 0;
}
@@ -707,35 +740,25 @@ 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)
uint32_t find_free_lvnum(struct logical_volume *lv)
{
int lvnum_used[MAX_RESTRICTED_LVS + 1];
uint32_t i = 0;
struct list *lvh;
struct logical_volume *lv;
struct lv_list *lvl;
int lvnum;
list_iterate(lvh, lvs) {
lv = list_item(lvh, struct lv_list)->lv;
unlock_lv(cmd, lv->lvid.s);
memset(&lvnum_used, 0, sizeof(lvnum_used));
list_iterate(lvh, &lv->vg->lvs) {
lvl = list_item(lvh, struct lv_list);
lvnum = lvnum_from_lvid(&lvl->lv->lvid);
if (lvnum <= MAX_RESTRICTED_LVS)
lvnum_used[lvnum] = 1;
}
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;
while (lvnum_used[i])
i++;
return i;
}

View File

@@ -1,43 +1,73 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "metadata.h"
#include "toolcontext.h"
#include "lv_alloc.h"
#include "str_list.h"
/*
* Returns success if the segments were
* successfully merged. If the do merge, 'first'
* will be adjusted to contain both areas.
* Test whether two segments could be merged by the current merging code
*/
static int _merge(struct lv_segment *first, struct lv_segment *second)
static int _segments_compatible(struct lv_segment *first,
struct lv_segment *second)
{
unsigned int s;
uint32_t width;
unsigned s;
if (!first ||
(first->type != SEG_STRIPED) ||
(first->type != second->type) ||
/* FIXME Relax the seg type restriction */
if (!first || !second ||
(first->type != SEG_STRIPED) || (second->type != first->type) ||
(first->area_count != second->area_count) ||
(first->stripe_size != second->stripe_size))
return 0;
for (s = 0; s < first->area_count; s++) {
width = first->area_len;
/* FIXME Relax this to first type != second type ? */
if (first->area[s].type != AREA_PV ||
second->area[s].type != AREA_PV)
/* FIXME Relax this to first area type != second area type */
/* plus the additional AREA_LV checks needed */
if ((first->area[s].type != AREA_PV) ||
(second->area[s].type != AREA_PV))
return 0;
width = first->area_len;
if ((first->area[s].u.pv.pv != second->area[s].u.pv.pv) ||
(first->area[s].u.pv.pe + width != second->area[s].u.pv.pe))
return 0;
}
/* we should merge */
if (!str_list_lists_equal(&first->tags, &second->tags))
return 0;
return 1;
}
/*
* Attempt to merge two adjacent segments.
* Currently only supports SEG_STRIPED on AREA_PV.
* Returns success if successful, in which case 'first'
* gets adjusted to contain both areas.
*/
static int _merge(struct lv_segment *first, struct lv_segment *second)
{
if (!_segments_compatible(first, second))
return 0;
first->len += second->len;
first->area_len += second->area_len;
@@ -46,10 +76,10 @@ static int _merge(struct lv_segment *first, struct lv_segment *second)
int lv_merge_segments(struct logical_volume *lv)
{
struct list *segh;
struct list *segh, *t;
struct lv_segment *current, *prev = NULL;
list_iterate(segh, &lv->segments) {
list_iterate_safe(segh, t, &lv->segments) {
current = list_item(segh, struct lv_segment);
if (_merge(prev, current))
@@ -61,7 +91,118 @@ int lv_merge_segments(struct logical_volume *lv)
return 1;
}
/*
* Verify that an LV's segments are consecutive, complete and don't overlap.
*/
int lv_check_segments(struct logical_volume *lv)
{
struct lv_segment *seg;
uint32_t le = 0;
unsigned seg_count = 0;
list_iterate_items(seg, &lv->segments) {
seg_count++;
if (seg->le != le) {
log_error("LV %s invalid: segment %u should begin at "
"LE %" PRIu32 " (found %" PRIu32 ").",
lv->name, seg_count, le, seg->le);
return 0;
}
le += seg->len;
}
return 1;
}
/*
* Split the supplied segment at the supplied logical extent
*/
static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
uint32_t le)
{
size_t len;
struct lv_segment *split_seg;
uint32_t s;
uint32_t offset = le - seg->le;
if (seg->type == SEG_SNAPSHOT) {
log_error("Unable to split the snapshot segment at LE %" PRIu32
" in LV %s", le, lv->name);
return 0;
}
/* Clone the existing segment */
if (!(split_seg = alloc_lv_segment(lv->vg->cmd->mem,
seg->area_count))) {
log_error("Couldn't allocate new LV segment.");
return 0;
}
len = sizeof(*seg) + (seg->area_count * sizeof(seg->area[0]));
memcpy(split_seg, seg, len);
if (!str_list_dup(lv->vg->cmd->mem, &split_seg->tags, &seg->tags)) {
log_error("LV segment tags duplication failed");
return 0;
}
/* In case of a striped segment, the offset has to be / stripes */
if (seg->type == SEG_STRIPED)
offset /= seg->area_count;
/* Adjust the PV mapping */
for (s = 0; s < seg->area_count; s++) {
/* Split area at the offset */
switch (seg->area[s].type) {
case AREA_LV:
split_seg->area[s].u.lv.le =
seg->area[s].u.lv.le + offset;
break;
case AREA_PV:
split_seg->area[s].u.pv.pe =
seg->area[s].u.pv.pe + offset;
break;
default:
log_error("Unrecognised segment type %u",
seg->area[s].type);
return 0;
}
}
split_seg->area_len = seg->area_len - offset;
seg->area_len = offset;
/* Add split off segment to the list _after_ the original one */
list_add_h(&seg->list, &split_seg->list);
return 1;
}
/*
* Ensure there's a segment boundary at the given logical extent
*/
int lv_split_segment(struct logical_volume *lv, uint32_t le)
{
struct lv_segment *seg;
if (!(seg = find_seg_by_le(lv, le))) {
log_error("Segment with extent %" PRIu32 " in LV %s not found",
le, lv->name);
return 0;
}
/* This is a segment start already */
if (le == seg->le)
return 1;
if (!_lv_split_segment(lv, seg, le)) {
stack;
return 0;
}
return 1;
}

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -10,7 +19,8 @@
#include "metadata.h"
#include "toolcontext.h"
#include "lvm-string.h"
#include "cache.h"
#include "lvmcache.h"
#include "memlock.h"
static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
const char *pv_name)
@@ -82,7 +92,7 @@ static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
return 0;
}
if (vg->pv_count == vg->max_pv) {
if (vg->pv_count && (vg->pv_count == vg->max_pv)) {
log_error("No space for '%s' - volume group '%s' "
"holds max %d physical volume(s).", pv_name,
vg->name, vg->max_pv);
@@ -210,13 +220,16 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
vg->snapshot_count = 0;
list_init(&vg->snapshots);
list_init(&vg->tags);
if (!(vg->fid = cmd->fmt->ops->create_instance(cmd->fmt, vg_name,
NULL))) {
log_error("Failed to create format instance");
goto bad;
}
if (!vg->fid->fmt->ops->vg_setup(vg->fid, vg)) {
if (vg->fid->fmt->ops->vg_setup &&
!vg->fid->fmt->ops->vg_setup(vg->fid, vg)) {
log_error("Format specific setup of volume group '%s' failed.",
vg_name);
goto bad;
@@ -291,6 +304,8 @@ struct physical_volume *pv_create(const struct format_type *fmt,
pv->pe_alloc_count = 0;
pv->fmt = fmt;
list_init(&pv->tags);
if (!fmt->ops->pv_setup(fmt, pe_start, existing_extent_count,
existing_extent_size,
pvmetadatacopies, pvmetadatasize, mdas,
@@ -437,11 +452,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",
@@ -459,23 +477,76 @@ int vg_write(struct volume_group *vg)
/* Write to each copy of the metadata area */
list_iterate(mdah, &vg->fid->metadata_areas) {
mda = list_item(mdah, struct metadata_area);
if (!mda->ops->vg_write) {
log_error("Format does not support writing volume"
"group metadata areas");
/* Revert */
list_uniterate(mdah2, &vg->fid->metadata_areas, mdah) {
mda = list_item(mdah2, struct metadata_area);
if (mda->ops->vg_revert &&
!mda->ops->vg_revert(vg->fid, vg, mda)) {
stack;
}
}
return 0;
}
if (!mda->ops->vg_write(vg->fid, vg, mda)) {
stack;
/* Revert */
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;
}
}
return 1;
}
/* Commit pending changes */
int vg_commit(struct volume_group *vg)
{
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);
if (!cache_updated) {
cache_update_vg(vg);
cache_updated = 1;
}
failed = 0;
if (mda->ops->vg_commit &&
!mda->ops->vg_commit(vg->fid, vg, mda)) {
stack;
return 0;
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;
}
}
@@ -485,7 +556,7 @@ int vg_write(struct volume_group *vg)
/* Make orphan PVs look like a VG */
static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
{
struct cache_vginfo *vginfo;
struct lvmcache_vginfo *vginfo;
struct list *ih;
struct device *dev;
struct pv_list *pvl;
@@ -504,6 +575,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
list_init(&vg->pvs);
list_init(&vg->lvs);
list_init(&vg->snapshots);
list_init(&vg->tags);
vg->cmd = cmd;
if (!(vg->name = pool_strdup(cmd->mem, ORPHAN))) {
log_error("vg name allocation failed");
@@ -511,7 +583,7 @@ static 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;
}
@@ -552,9 +624,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;
@@ -593,7 +669,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
return NULL;
}
cache_update_vg(correct_vg);
lvmcache_update_vg(correct_vg);
if (inconsistent) {
if (!*consistent)
@@ -618,7 +694,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
if ((correct_vg->status & PVMOVE) && !pvmove_mode()) {
log_error("WARNING: Interrupted pvmove detected in "
"volume group %s", vg->name);
"volume group %s", correct_vg->name);
log_error("Please restore the metadata by running "
"vgcfgrestore.");
return NULL;
@@ -634,10 +710,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;
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? */
@@ -654,7 +730,15 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
}
}
/* The slow way - full scan required to cope with vgrename */
/* Mustn't scan if memory locked: ensure cache gets pre-populated! */
if (memlock())
return NULL;
/* FIXME Need a genuine read by ID here - don't vg_read by name! */
/* FIXME Disabled vgrenames while active for now because we aren't
* allowed to do a full scan here any more. */
// 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;
@@ -663,7 +747,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)) {
@@ -713,7 +797,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))) {
@@ -726,7 +810,7 @@ struct physical_volume *pv_read(struct cmd_context *cmd, const char *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;
@@ -735,6 +819,8 @@ struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
return 0;
}
list_init(&pv->tags);
/* FIXME Move more common code up here */
if (!(info->fmt->ops->pv_read(info->fmt, pv_name, pv, mdas))) {
log_error("Failed to read existing physical volume '%s'",
@@ -751,13 +837,13 @@ 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;
@@ -765,7 +851,7 @@ struct list *get_pvs(struct cmd_context *cmd)
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");
@@ -813,6 +899,11 @@ struct list *get_pvs(struct cmd_context *cmd)
int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
struct list *mdas, int64_t label_sector)
{
if (!pv->fmt->ops->pv_write) {
log_error("Format does not support writing physical volumes");
return 0;
}
if (*pv->vg_name || pv->pe_alloc_count) {
log_error("Assertion failed: can't _pv_write non-orphan PV "
"(in VG %s)", pv->vg_name);

View File

@@ -1,8 +1,19 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* This is the in core representation of a volume group and its
* associated physical and logical volumes.
*/
@@ -22,6 +33,7 @@
#define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
/* Various flags */
/* Note that the bits no longer necessarily correspond to LVM1 disk format */
@@ -50,7 +62,11 @@
/* Format features flags */
#define FMT_SEGMENTS 0x00000001 /* Arbitrary segment params? */
#define FMT_MDAS 0x00000002 /* Proper metadata areas? */
#define FMT_TAGS 0x00000004 /* Tagging? */
#define FMT_UNLIMITED_VOLS 0x00000008 /* Unlimited PVs/LVs? */
#define FMT_RESTRICTED_LVIDS 0x00000010 /* LVID <= 255 */
#define FMT_ORPHAN_ALLOCATABLE 0x00000020 /* Orphan PV allocatable? */
typedef enum {
ALLOC_DEFAULT,
ALLOC_NEXT_FREE,
@@ -98,6 +114,8 @@ struct physical_volume {
uint64_t pe_start;
uint32_t pe_count;
uint32_t pe_alloc_count;
struct list tags;
};
struct metadata_area;
@@ -126,6 +144,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);
};
@@ -170,6 +190,8 @@ struct volume_group {
/* snapshots */
uint32_t snapshot_count;
struct list snapshots;
struct list tags;
};
struct lv_segment {
@@ -191,6 +213,8 @@ struct lv_segment {
uint32_t chunk_size;
uint32_t extents_moved;
struct list tags;
/* There will be one area for each stripe */
struct {
area_type_t type;
@@ -223,6 +247,7 @@ struct logical_volume {
uint32_t le_count;
struct list segments;
struct list tags;
};
struct snapshot {
@@ -338,6 +363,8 @@ struct format_handler {
* 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);
@@ -410,10 +437,6 @@ int lv_extend_mirror(struct format_instance *fid,
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);
@@ -464,6 +487,11 @@ int lv_check_segments(struct logical_volume *lv);
*/
int lv_merge_segments(struct logical_volume *lv);
/*
* Ensure there's a segment boundary at a given LE, splitting if necessary
*/
int lv_split_segment(struct logical_volume *lv, uint32_t le);
/*
* Useful functions for managing snapshots.
*/
@@ -502,6 +530,8 @@ float pvmove_percent(struct logical_volume *lv_mirr);
struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv);
uint32_t find_free_lvnum(struct logical_volume *lv);
static inline int validate_name(const char *n)
{
register char c;

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2003 Sistina Software (UK) Limited.
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
@@ -68,7 +77,6 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
return 1;
}
/* Remove a temporary mirror */
int remove_pvmove_mirrors(struct volume_group *vg,
struct logical_volume *lv_mirr)
{
@@ -226,6 +234,7 @@ struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
}
}
next_lv:
;
}
return lvs;

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_PV_MAP_H

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