mirror of
				git://sourceware.org/git/lvm2.git
				synced 2025-10-25 03:33:16 +03:00 
			
		
		
		
	Compare commits
	
		
			160 Commits
		
	
	
		
			old-v1_00_
			...
			v1_00_20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 9812657777 | ||
|  | 0b09312fc6 | ||
|  | d0a7ac6b74 | ||
|  | ff9a238fbd | ||
|  | 359fffa5f1 | ||
|  | 5bf92ced1a | ||
|  | 340bcc7b45 | ||
|  | ef03742bd4 | ||
|  | 20431ec16d | ||
|  | becba8157b | ||
|  | 51fd3bb0eb | ||
|  | 4bbd3acb4e | ||
|  | 3bc930ea7b | ||
|  | d1b26f8e86 | ||
|  | fdf15caaff | ||
|  | c7b4a53c0b | ||
|  | af78dc0308 | ||
|  | 5ad39493c4 | ||
|  | 61f597b408 | ||
|  | 2162825240 | ||
|  | 2b780e70d1 | ||
|  | a3823f818e | ||
|  | 1f7c47bcaf | ||
|  | ec53c365a2 | ||
|  | 793ad1f2d4 | ||
|  | 9bc733b76c | ||
|  | 21b28f0217 | ||
|  | d3e23caa52 | ||
|  | 9e7518de67 | ||
|  | 679f0047aa | ||
|  | d77d5ce14b | ||
|  | 33ec22a2af | ||
|  | 353053225f | ||
|  | b7f3d6f7f7 | ||
|  | e34577499d | ||
|  | 4cf8960c0c | ||
|  | 1f93ea0675 | ||
|  | 25b705c3a8 | ||
|  | 0725588731 | ||
|  | fc5c61cc8b | ||
|  | ac282e63c6 | ||
|  | c3941941ce | ||
|  | 46cdd53323 | ||
|  | 3ff3e302c3 | ||
|  | f2ceecf95c | ||
|  | 9314c7c881 | ||
|  | 54abb2c572 | ||
|  | 8fa3bdd025 | ||
|  | 5e7a308528 | ||
|  | 7952177786 | ||
|  | 9afbe49c84 | ||
|  | 9f06ba2db3 | ||
|  | fe55bfddcf | ||
|  | c0842e6444 | ||
|  | 3fed20d06a | ||
|  | 5e8f2e2c04 | ||
|  | e4df99ea84 | ||
|  | b3276f5f11 | ||
|  | 32667ca256 | ||
|  | bed122a170 | ||
|  | 14adc9b875 | ||
|  | a8778bbc5a | ||
|  | a54e641f44 | ||
|  | 5c99efe87a | ||
|  | 7da1d731ff | ||
|  | af9828e819 | ||
|  | 7a27136142 | ||
|  | 012ad2d423 | ||
|  | ef3bdbf4da | ||
|  | b3bb698f7b | ||
|  | 1ed5d1e4c1 | ||
|  | bdee01a03d | ||
|  | 458f7376d7 | ||
|  | cb3a00e027 | ||
|  | 482eb1f3fb | ||
|  | 6e0f638f5e | ||
|  | bab349047d | ||
|  | 28ea6b8de8 | ||
|  | 9d51bbdae8 | ||
|  | d622f79533 | ||
|  | 04c8515ad1 | ||
|  | 53bc4251d1 | ||
|  | a5a751f02f | ||
|  | 66ed5f82c4 | ||
|  | c802a9e6aa | ||
|  | 880f210946 | ||
|  | 4f9f7eb6a6 | ||
|  | f910c4a8e7 | ||
|  | 529686d965 | ||
|  | 84dfd1536f | ||
|  | 85dedc324c | ||
|  | d639237411 | ||
|  | 449aaf75f1 | ||
|  | b1fda66caa | ||
|  | 66a8e90fd9 | ||
|  | 37b487d191 | ||
|  | 6c59fe3577 | ||
|  | 1cbb70c992 | ||
|  | e06b39f882 | ||
|  | 2602b1493e | ||
|  | 989d14502d | ||
|  | f78a550282 | ||
|  | 54a1abb284 | ||
|  | 97b492a8e2 | ||
|  | 0873bd14a9 | ||
|  | eff6ba429a | ||
|  | 8c18064be4 | ||
|  | 44a1ac0cf3 | ||
|  | 28dc8d88dd | ||
|  | 2c0c2b64ba | ||
|  | bd3e0f5248 | ||
|  | cd52d98938 | ||
|  | 894c70e7f8 | ||
|  | 51d70c2edd | ||
|  | 7d4b355240 | ||
|  | 3b56193b98 | ||
|  | b16045b57d | ||
|  | 9e8b0fca5b | ||
|  | 35cf1b3b5b | ||
|  | 83f788af57 | ||
|  | 2ffe378d3f | ||
|  | 38b33a4a5e | ||
|  | 60bf9ed0a0 | ||
|  | 16adf4de1b | ||
|  | 80de983023 | ||
|  | 8703ca623f | ||
|  | 286253a73f | ||
|  | bd806a41df | ||
|  | b89c4e9002 | ||
|  | 6dbf31c0c3 | ||
|  | 060c45d8a1 | ||
|  | 33d3e82e4d | ||
|  | 4bb074514d | ||
|  | e3f8892003 | ||
|  | 9d00ad5f18 | ||
|  | dae4344850 | ||
|  | aa7f3fabe2 | ||
|  | f93434a8ce | ||
|  | 25dee56be9 | ||
|  | ce9a3f3797 | ||
|  | 11e384920a | ||
|  | a0a1f1e536 | ||
|  | 3b3d0ea9eb | ||
|  | 2f4d78286d | ||
|  | 677dc6f985 | ||
|  | d52057e732 | ||
|  | fa2a1cb1fb | ||
|  | 19a0fb04ad | ||
|  | 947352f2fe | ||
|  | adcbedb686 | ||
|  | 7732f92acd | ||
|  | ad8a001688 | ||
|  | 9121eada08 | ||
|  | 49bd4d25a2 | ||
|  | d80b4129c6 | ||
|  | 7edb4172d5 | ||
|  | c3a4677990 | ||
|  | 5cbb893a3b | ||
|  | f28a2a432b | ||
|  | 03b75a2d27 | 
							
								
								
									
										43
									
								
								Makefile.in
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								Makefile.in
									
									
									
									
									
								
							| @@ -1,35 +1,48 @@ | ||||
| # | ||||
| # 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 = doc include man  | ||||
|  | ||||
| ifeq ("@INTL@", "yes") | ||||
|   SUBDIRS += po | ||||
| endif | ||||
|  | ||||
| SUBDIRS += lib tools | ||||
|  | ||||
| ifeq ($(MAKECMDGOALS),distclean) | ||||
|   SUBDIRS += lib/format1 \ | ||||
| 	     lib/format_pool \ | ||||
| 	     lib/mirror \ | ||||
| 	     lib/snapshot \ | ||||
| 	     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 | ||||
|  | ||||
|   | ||||
							
								
								
									
										10
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README
									
									
									
									
									
								
							| @@ -13,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. | ||||
|   linux-lvm@sistina.com | ||||
|   Subscribe from http://lists.sistina.com/mailman/listinfo/linux-lvm | ||||
|   linux-lvm@redhat.com | ||||
|   Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm | ||||
|  | ||||
|   | ||||
							
								
								
									
										110
									
								
								WHATS_NEW
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								WHATS_NEW
									
									
									
									
									
								
							| @@ -1,3 +1,112 @@ | ||||
| Version 2.00.17 - | ||||
| ============================= | ||||
|   Add read-only GFS pool support. | ||||
|   Add lvm2create_initrd script from http://poochiereds.net/svn/lvm2/ | ||||
|   Fix rounding of large diplayed sizes. | ||||
|   Suppress decimal point when using units of sectors/bytes. | ||||
|   Additional kernel target checks before pvmove & snapshot creation. | ||||
|   Add i2o_block. | ||||
|  | ||||
| Version 2.00.16 - 24 May 2004 | ||||
| ============================= | ||||
|   Set area_count within alloc_lv_segment. | ||||
|   Remove error labels from lvresize. | ||||
|   Fix a pvs error path. | ||||
|   xxchange -ae for exclusive activation. | ||||
|   Don't return non-zero status if there aren't any volume groups. | ||||
|   Add --alloc argument to tools. | ||||
|   Rename allocation policies to contiguous, normal, anywhere, inherit. | ||||
|   nextfree becomes normal; anywhere isn't implemented yet. | ||||
|   LV inherits allocation policy from VG. Defaults: LV - inherit; VG - normal | ||||
|   Additional status character added to vgs to indicate allocation policy. | ||||
|   Add reset_fn to external_locking. | ||||
|   Ensure presence of virtual targets before attempting activating. | ||||
|   Attempt to fix resizing of snapshot origins. | ||||
|   Restructure lvresize, bringing it closer to lvcreate. | ||||
|   A quick sanity check on vg_disk struct when read in.  More checks needed. | ||||
|   Only include visible LVs in active/open counts. | ||||
|   Add virtual segment types, zero and error.  A large sparse device can be | ||||
| constructed as a writeable snapshot of a large zero segment. | ||||
|   Add --type to lvcreate/resize. | ||||
|   Push lv_create & alloc policy up to tool level. | ||||
|   Fix pvdisplay return code. | ||||
|   Detect invalid LV names in arg lists. | ||||
|   Reporting uses line-at-a-time output. | ||||
|   lvm2 format sets unlimited_vols format flag. | ||||
|   Internal-only metadata flag support. | ||||
|   Basic checking for presence of device-mapper targets. | ||||
|   Separate out polldaemon. | ||||
|   Revise internal locking semantics. | ||||
|   Move find_pv_by_name to library. | ||||
|   Rename move->copy. | ||||
|   Add devices to segments report. | ||||
|   Begin separating out segment code. There's a lot of change here. | ||||
|   Compress any (obsolete) long LVM1 pvids encountered. | ||||
|   Support for tagged config files. | ||||
|   Don't abort operations if selinux present but disabled. | ||||
|   Fix typo in configure which left HAVE_LIBDL unset. | ||||
|  | ||||
| Version 2.00.15 - 19 Apr 2004 | ||||
| ============================= | ||||
|   configure --with-owner= --with-group= to avoid -o and -g args to 'install' | ||||
|  | ||||
| Version 2.00.14 - 16 Apr 2004 | ||||
| ============================= | ||||
|   Use 64-bit file functions by default. | ||||
|  | ||||
| Version 2.00.13 - 16 Apr 2004 | ||||
| ============================= | ||||
|   Set devices/md_component_detection = 1 to ignore devices containing md | ||||
|   superblocks. [Luca Berra] | ||||
|   Ignore error setting selinux file context if fs doesn't support it. | ||||
|  | ||||
| Version 2.00.12 - 14 Apr 2004 | ||||
| ============================= | ||||
|   Install a default lvm.conf into /etc/lvm if there isn't one already. | ||||
|   Allow different installation dir for lvm.static (configure --staticdir=) | ||||
|   Fix inverted selinux error check. | ||||
|   Recognise power2 in /proc/devices. | ||||
|   Fix counting in lvs_in_vg_opened. [It ignored devices open more than once.] | ||||
|  | ||||
| Version 2.00.11 - 8 Apr 2004 | ||||
| ============================ | ||||
|   Set fallback_to_lvm1 in lvm.conf (or configure --enable-lvm1_fallback) | ||||
|   to run lvm1 binaries if running a 2.4 kernel without device-mapper. | ||||
|  | ||||
| Version 2.00.10 - 7 Apr 2004 | ||||
| ============================ | ||||
|   More fixes for static build. | ||||
|   Add basic selinux support. | ||||
|   Fix sysfs detection. | ||||
|  | ||||
| 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: | ||||
| @@ -6,6 +115,7 @@ Some bug fixes & minor enhancements, including: | ||||
|   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 | ||||
|   | ||||
							
								
								
									
										63
									
								
								WHATS_NEW_DM
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								WHATS_NEW_DM
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| Version 1.00.18 | ||||
| ============================= | ||||
|   Add target message-passing ioctl. | ||||
|  | ||||
| Version 1.00.17 - 17 Apr 2004 | ||||
| ============================= | ||||
|   configure --with-owner= --with-group= to avoid -o and -g args to 'install' | ||||
|   Fix library selinux linking. | ||||
|  | ||||
| Version 1.00.16 - 16 Apr 2004 | ||||
| ============================= | ||||
|   Ignore error setting selinux file context if fs doesn't support it. | ||||
|  | ||||
| Version 1.00.15 - 7 Apr 2004 | ||||
| ============================ | ||||
|   Fix status overflow check in kernel patches. | ||||
|  | ||||
| Version 1.00.14 - 6 Apr 2004 | ||||
| ============================ | ||||
|   Fix static selinux build. | ||||
|  | ||||
| Version 1.00.13 - 6 Apr 2004 | ||||
| ============================ | ||||
|   Add some basic selinux support. | ||||
|  | ||||
| Version 1.00.12 - 6 Apr 2004 | ||||
| ============================ | ||||
|   Fix dmsetup.static install. | ||||
|  | ||||
| Version 1.00.11 - 5 Apr 2004 | ||||
| ============================ | ||||
|   configure --enable-static_link does static build in addition to dynamic. | ||||
|   Moved Makefile library targets definition into template. | ||||
|  | ||||
| Version 1.00.10 - 2 Apr 2004 | ||||
| ============================ | ||||
|   Fix DESTDIR handling. | ||||
|   Static build installs to dmsetup.static. | ||||
|   Basic support for internationalisation. | ||||
|   Minor Makefile tidy-ups/fixes. | ||||
|  | ||||
| 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
									
									
								
							
							
						
						
									
										537
									
								
								autoconf/config.guess
									
									
									
									
										vendored
									
									
								
							| @@ -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
									
									
								
							
							
						
						
									
										303
									
								
								autoconf/config.sub
									
									
									
									
										vendored
									
									
								
							| @@ -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*) | ||||
|   | ||||
| @@ -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: | ||||
|   | ||||
							
								
								
									
										204
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										204
									
								
								configure.in
									
									
									
									
									
								
							| @@ -1,4 +1,3 @@ | ||||
| ################################################################################ | ||||
| ## | ||||
| ##    Copyright 1999-2000 Sistina Software, Inc. | ||||
| ## | ||||
| @@ -51,23 +50,58 @@ 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" | ||||
| 		LD_FLAGS="-Wl,--export-dynamic" | ||||
| 		SOFLAG="-shared" | ||||
| 		DEVMAPPER=yes | ||||
| 		ODIRECT=yes ;; | ||||
| 	darwin*) | ||||
| 		CFLAGS="-no-cpp-precomp -fno-common" | ||||
| 		CLDFLAGS= | ||||
| 		CLDWHOLEARCHIVE="-all_load" | ||||
| 		CLDNOWHOLEARCHIVE= | ||||
| 		LD_DEPS= | ||||
| 		LD_FLAGS= | ||||
| 		SOFLAG="-dynamiclib" | ||||
| 		DEVMAPPER=no | ||||
| 		ODIRECT=no ;; | ||||
| esac | ||||
|  | ||||
| dnl -- prefix is /usr by default, the exec_prefix default is setup later | ||||
| AC_PREFIX_DEFAULT(/usr) | ||||
|  | ||||
| OWNER="root" | ||||
| GROUP="root" | ||||
|  | ||||
| dnl -- setup the ownership of the files | ||||
| AC_ARG_WITH(user, | ||||
|   [  --with-user=USER        Set the owner of installed files ], | ||||
|   [ OWNER="$withval" ], | ||||
|   [ OWNER="root" ]) | ||||
|   [ OWNER="$withval" ]) | ||||
|  | ||||
| if test x$OWNER != x; then | ||||
| 	OWNER="-o $OWNER" | ||||
| fi | ||||
|  | ||||
| dnl -- setup the group ownership of the files | ||||
| AC_ARG_WITH(group, | ||||
|   [  --with-group=GROUP      Set the group owner of installed files ], | ||||
|   [ GROUP="$withval" ], | ||||
|   [ GROUP="root" ]) | ||||
|   [ GROUP="$withval" ]) | ||||
|  | ||||
| if test x$GROUP != x; then | ||||
| 	GROUP="-g $GROUP" | ||||
| fi | ||||
|  | ||||
| dnl -- LVM1 tool fallback option | ||||
| AC_ARG_ENABLE(lvm1_fallback, [  --enable-lvm1_fallback  Use this to fall back and use LVM1 binaries if | ||||
|                           device-mapper is missing from the kernel],  LVM1_FALLBACK=$enableval, LVM1_FALLBACK=no) | ||||
|  | ||||
| if test x$LVM1_FALLBACK = xyes; then | ||||
| 	CFLAGS="$CFLAGS -DLVM1_FALLBACK" | ||||
| fi | ||||
|  | ||||
| dnl -- format1 inclusion type | ||||
| AC_ARG_WITH(lvm1, | ||||
| @@ -87,10 +121,65 @@ if test x$LVM1 = xinternal; then | ||||
| 	CFLAGS="$CFLAGS -DLVM1_INTERNAL" | ||||
| fi | ||||
|  | ||||
| dnl -- format_pool inclusion type | ||||
| AC_ARG_WITH(pool, | ||||
|   [  --with-pool=TYPE        GFS pool read-only support: internal/shared/none | ||||
|                           [TYPE=internal] ], | ||||
|   [ POOL="$withval" ], | ||||
|   [ POOL="internal" ]) | ||||
|  | ||||
| if [[ "x$POOL" != xnone -a "x$POOL" != xinternal -a "x$POOL" != xshared ]]; | ||||
|  then  AC_MSG_ERROR( | ||||
| --with-pool parameter invalid | ||||
| ) | ||||
|  exit | ||||
| fi; | ||||
|  | ||||
| if test x$POOL = xinternal; then | ||||
| 	CFLAGS="$CFLAGS -DPOOL_INTERNAL" | ||||
| fi | ||||
|  | ||||
|  | ||||
| AC_ARG_ENABLE(jobs, [  --enable-jobs=NUM       Number of jobs to run simultaneously], JOBS=-j$enableval, JOBS=-j2) | ||||
|  | ||||
| dnl Enables staticly linked tools | ||||
| AC_ARG_ENABLE(static_link, [  --enable-static_link    Use this to link the tools to the liblvm library | ||||
| dnl -- snapshots inclusion type | ||||
| AC_ARG_WITH(snapshots, | ||||
|   [  --with-snapshots=TYPE   Snapshot support: internal/shared/none | ||||
|                           [TYPE=internal] ], | ||||
|   [ SNAPSHOTS="$withval" ], | ||||
|   [ SNAPSHOTS="internal" ]) | ||||
|  | ||||
| if [[ "x$SNAPSHOTS" != xnone -a "x$SNAPSHOTS" != xinternal -a "x$SNAPSHOTS" != xshared ]]; | ||||
|  then  AC_MSG_ERROR( | ||||
| --with-snapshots parameter invalid | ||||
| ) | ||||
|  exit | ||||
| fi; | ||||
|  | ||||
| if test x$SNAPSHOTS = xinternal; then | ||||
| 	CFLAGS="$CFLAGS -DSNAPSHOT_INTERNAL" | ||||
| fi | ||||
|  | ||||
| dnl -- mirrors inclusion type | ||||
| AC_ARG_WITH(mirrors, | ||||
|   [  --with-mirrors=TYPE     Mirror support: internal/shared/none | ||||
|                           [TYPE=internal] ], | ||||
|   [ MIRRORS="$withval" ], | ||||
|   [ MIRRORS="internal" ]) | ||||
|  | ||||
| if [[ "x$MIRRORS" != xnone -a "x$MIRRORS" != xinternal -a "x$MIRRORS" != xshared ]]; | ||||
|  then  AC_MSG_ERROR( | ||||
| --with-mirrors parameter invalid | ||||
| ) | ||||
|  exit | ||||
| fi; | ||||
|  | ||||
| if test x$MIRRORS = xinternal; then | ||||
| 	CFLAGS="$CFLAGS -DMIRRORED_INTERNAL" | ||||
| fi | ||||
|  | ||||
| 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,26 +190,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, ODIRECT=yes) | ||||
| 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=""; | ||||
| @@ -152,9 +257,29 @@ fi | ||||
| dnl Check for dlopen | ||||
| AC_CHECK_LIB(dl, dlopen, HAVE_LIBDL=yes, HAVE_LIBDL=no) | ||||
|  | ||||
| if test x$HAVE_LIBDL = xyes; then | ||||
| if [[ "x$HAVE_LIBDL" = xyes -a "x$STATIC_LINK" = xno ]]; then | ||||
| 	CFLAGS="$CFLAGS -DHAVE_LIBDL" | ||||
| 	LIBS="-ldl $LIBS" | ||||
| else | ||||
| 	HAVE_LIBDL=no | ||||
| fi | ||||
|  | ||||
| dnl Check for shared/static conflicts | ||||
| if [[ \( "x$LVM1" = xshared -o "x$POOL" = xshared -o \ | ||||
|       "x$SNAPSHOTS" = xshared -o "x$MIRRORS" = xshared \ | ||||
|       \) -a "x$STATIC_LINK" = xyes ]]; | ||||
|  then  AC_MSG_ERROR( | ||||
| Features cannot be 'shared' when building statically | ||||
| ) | ||||
|  exit | ||||
| fi | ||||
|  | ||||
| dnl Check for is_selinux_enabled | ||||
| AC_CHECK_LIB(selinux, is_selinux_enabled, HAVE_SELINUX=yes, HAVE_SELINUX=no) | ||||
|  | ||||
| if test x$HAVE_SELINUX = xyes; then | ||||
| 	CFLAGS="$CFLAGS -DHAVE_SELINUX" | ||||
| 	LIBS="-lselinux $LIBS" | ||||
| fi | ||||
|  | ||||
| dnl Check for getopt | ||||
| @@ -177,6 +302,39 @@ 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 | ||||
|  | ||||
| AC_ARG_WITH(confdir, | ||||
| 	    [  --with-confdir=DIR      Configuration files in DIR [/etc]], | ||||
|   	    [ CONFDIR="$withval" ], | ||||
|  	    [ CONFDIR='/etc' ]) | ||||
|  | ||||
| AC_ARG_WITH(staticdir, | ||||
| 	    [  --with-staticdir=DIR    Static binary in DIR [EXEC_PREFIX/sbin]], | ||||
|   	    [ STATICDIR="$withval" ], | ||||
|  	    [ STATICDIR='${exec_prefix}/sbin' ]) | ||||
|  | ||||
|  | ||||
| if test "-f VERSION"; then | ||||
|   LVM_VERSION="\"`cat VERSION`\"" | ||||
| else | ||||
| @@ -186,23 +344,47 @@ fi | ||||
| AC_SUBST(JOBS) | ||||
| AC_SUBST(STATIC_LINK) | ||||
| AC_SUBST(LVM1) | ||||
| AC_SUBST(POOL) | ||||
| AC_SUBST(SNAPSHOTS) | ||||
| AC_SUBST(MIRRORS) | ||||
| AC_SUBST(OWNER) | ||||
| AC_SUBST(GROUP) | ||||
| AC_SUBST(CFLAGS) | ||||
| AC_SUBST(CLDFLAGS) | ||||
| AC_SUBST(CLDWHOLEARCHIVE) | ||||
| AC_SUBST(CLDNOWHOLEARCHIVE) | ||||
| AC_SUBST(LD_DEPS) | ||||
| AC_SUBST(LD_FLAGS) | ||||
| AC_SUBST(SOFLAG) | ||||
| AC_SUBST(LIBS) | ||||
| AC_SUBST(LVM_VERSION) | ||||
| AC_SUBST(LVM1_FALLBACK) | ||||
| AC_SUBST(DEBUG) | ||||
| AC_SUBST(DEVMAPPER) | ||||
| AC_SUBST(HAVE_LIBDL) | ||||
| AC_SUBST(HAVE_SELINUX) | ||||
| AC_SUBST(CMDLIB) | ||||
| AC_SUBST(MSGFMT) | ||||
| AC_SUBST(LOCALEDIR) | ||||
| AC_SUBST(CONFDIR) | ||||
| AC_SUBST(STATICDIR) | ||||
| 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( 								\ | ||||
| Makefile								\ | ||||
| make.tmpl                                                               \ | ||||
| doc/Makefile								\ | ||||
| include/Makefile						 	\ | ||||
| lib/Makefile							 	\ | ||||
| lib/format1/Makefile						 	\ | ||||
| lib/format_pool/Makefile						\ | ||||
| lib/mirror/Makefile							\ | ||||
| lib/snapshot/Makefile							\ | ||||
| man/Makefile							 	\ | ||||
| po/Makefile								\ | ||||
| tools/Makefile							 	\ | ||||
| tools/version.h								\ | ||||
| test/mm/Makefile							\ | ||||
|   | ||||
							
								
								
									
										29
									
								
								doc/Makefile.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								doc/Makefile.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| # | ||||
| # Copyright (C) 2004 Red Hat, Inc. All rights reserved. | ||||
| # | ||||
| # 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@ | ||||
|  | ||||
| CONFSRC=example.conf | ||||
| CONFDEST=lvm.conf | ||||
|  | ||||
| include ../make.tmpl | ||||
|  | ||||
| install: | ||||
| 	@if [ ! -e $(confdir)/$(CONFDEST) ]; then \ | ||||
| 		echo "Installing $(CONFSRC) as $(confdir)/$(CONFDEST)"; \ | ||||
| 		@INSTALL@ -D $(OWNER) $(GROUP) -m 644 $(CONFSRC) \ | ||||
| 			$(confdir)/$(CONFDEST); \ | ||||
| 	fi | ||||
|  | ||||
| @@ -27,9 +27,6 @@ devices { | ||||
|     # the device will be accepted or rejected (ignored).  Devices that | ||||
|     # don't match any patterns are accepted. | ||||
|  | ||||
|     # If using RAID md devices as physical volumes, you should | ||||
|     # set up a filter here to reject the constituent devices. | ||||
|  | ||||
|     # Remember to run vgscan after you change this parameter to ensure  | ||||
|     # that the cache file gets regenerated (see below). | ||||
|  | ||||
| @@ -57,10 +54,21 @@ devices { | ||||
|     # You can turn off writing this cache file by setting this to 0. | ||||
|     write_cache_state = 1 | ||||
|  | ||||
|     # An advanced setting. | ||||
|     # Advanced settings. | ||||
|  | ||||
|     # 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. | ||||
|     # 1 enables; 0 disables. | ||||
|     sysfs_scan = 1	 | ||||
|  | ||||
|     # By default, LVM2 will ignore devices used as components of | ||||
|     # software RAID (md) devices by looking for md superblocks. | ||||
|     # 1 enables; 0 disables. | ||||
|     md_component_detection = 1 | ||||
| } | ||||
|  | ||||
| # This section that allows you to configure the nature of the | ||||
| @@ -171,6 +179,16 @@ global { | ||||
|     # setting this to 0 should suppress the error messages. | ||||
|     activation = 1 | ||||
|  | ||||
|     # If we can't communicate with device-mapper, should we try running  | ||||
|     # the LVM1 tools? | ||||
|     # This option only applies to 2.4 kernels and is provided to help you | ||||
|     # switch between device-mapper kernels and LVM1 kernels. | ||||
|     # The LVM1 tools need to be installed with .lvm1 suffices | ||||
|     # e.g. vgscan.lvm1 and they will stop working after you start using | ||||
|     # the new lvm2 on-disk metadata format. | ||||
|     # The default value is set when the tools are built. | ||||
|     # fallback_to_lvm1 = 0 | ||||
|  | ||||
|     # The default metadata format that commands should use - "lvm1" or "lvm2". | ||||
|     # The command line override is -M1 or -M2. | ||||
|     # Defaults to "lvm1" if compiled in, else "lvm2". | ||||
| @@ -215,6 +233,14 @@ activation { | ||||
|  | ||||
|     # 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", "@*" ] | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										47
									
								
								doc/example_cmdlib.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								doc/example_cmdlib.c
									
									
									
									
									
										Normal 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; | ||||
| } | ||||
|  | ||||
| @@ -1,4 +1,5 @@ | ||||
| ../lib/activate/activate.h | ||||
| ../lib/activate/targets.h | ||||
| ../lib/cache/lvmcache.h | ||||
| ../lib/commands/errors.h | ||||
| ../lib/commands/toolcontext.h | ||||
| @@ -14,25 +15,34 @@ | ||||
| ../lib/device/device.h | ||||
| ../lib/display/display.h | ||||
| ../lib/filters/filter-composite.h | ||||
| ../lib/filters/filter-md.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/format_pool/format_pool.h | ||||
| ../lib/format_text/format-text.h | ||||
| ../lib/format_text/text_export.h | ||||
| ../lib/format_text/text_import.h | ||||
| ../lib/label/label.h | ||||
| ../lib/locking/locking.h | ||||
| ../lib/log/log.h | ||||
| ../lib/metadata/lv_alloc.h | ||||
| ../lib/metadata/metadata.h | ||||
| ../lib/metadata/segtypes.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 | ||||
| ../lib/misc/selinux.h | ||||
| ../lib/misc/sharedlib.h | ||||
| ../lib/regex/matcher.h | ||||
| ../lib/report/report.h | ||||
| ../lib/uuid/uuid.h | ||||
| ../po/pogen.h | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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,7 +20,19 @@ ifeq ("@LVM1@", "shared") | ||||
|   SUBDIRS = format1 | ||||
| endif | ||||
|  | ||||
| SOURCES=\ | ||||
| ifeq ("@POOL@", "shared") | ||||
|   SUBDIRS += format_pool | ||||
| endif | ||||
|  | ||||
| ifeq ("@SNAPSHOTS@", "shared") | ||||
|   SUBDIRS += snapshot | ||||
| endif | ||||
|  | ||||
| ifeq ("@MIRRORS@", "shared") | ||||
|   SUBDIRS += mirror | ||||
| endif | ||||
|  | ||||
| SOURCES =\ | ||||
| 	activate/activate.c \ | ||||
| 	cache/lvmcache.c \ | ||||
| 	commands/toolcontext.c \ | ||||
| @@ -25,9 +45,12 @@ SOURCES=\ | ||||
| 	device/dev-io.c \ | ||||
| 	device/device.c \ | ||||
| 	display/display.c \ | ||||
| 	error/errseg.c \ | ||||
| 	filters/filter-composite.c \ | ||||
| 	filters/filter-persistent.c \ | ||||
| 	filters/filter-regex.c \ | ||||
| 	filters/filter-sysfs.c \ | ||||
| 	filters/filter-md.c \ | ||||
| 	filters/filter.c \ | ||||
| 	format_text/archive.c \ | ||||
| 	format_text/export.c \ | ||||
| @@ -35,6 +58,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 \ | ||||
| @@ -46,6 +70,7 @@ SOURCES=\ | ||||
| 	metadata/metadata.c \ | ||||
| 	metadata/mirror.c \ | ||||
| 	metadata/pv_map.c \ | ||||
| 	metadata/segtypes.c \ | ||||
| 	metadata/snapshot_manip.c \ | ||||
| 	misc/crc.c \ | ||||
| 	misc/lvm-file.c \ | ||||
| @@ -56,10 +81,12 @@ SOURCES=\ | ||||
| 	regex/parse_rx.c \ | ||||
| 	regex/ttree.c \ | ||||
| 	report/report.c \ | ||||
| 	uuid/uuid.c  | ||||
| 	striped/striped.c \ | ||||
| 	uuid/uuid.c \ | ||||
| 	zero/zero.c | ||||
|  | ||||
| ifeq ("@LVM1@", "internal") | ||||
|   SOURCES+=\ | ||||
|   SOURCES +=\ | ||||
| 	format1/disk-rep.c \ | ||||
| 	format1/format1.c \ | ||||
| 	format1/import-export.c \ | ||||
| @@ -69,29 +96,45 @@ ifeq ("@LVM1@", "internal") | ||||
| 	format1/vg_number.c | ||||
| endif | ||||
|  | ||||
| ifeq ("@POOL@", "internal") | ||||
|   SOURCES +=\ | ||||
| 	format_pool/disk_rep.c \ | ||||
| 	format_pool/format_pool.c \ | ||||
| 	format_pool/import_export.c \ | ||||
| 	format_pool/pool_label.c | ||||
| endif | ||||
|  | ||||
| ifeq ("@SNAPSHOTS@", "internal") | ||||
|   SOURCES += snapshot/snapshot.c | ||||
| endif | ||||
|  | ||||
| ifeq ("@MIRRORS@", "internal") | ||||
|   SOURCES += mirror/mirrored.c | ||||
| 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 | ||||
| ifeq ("@HAVE_SELINUX@", "yes") | ||||
|   SOURCES += misc/selinux.c | ||||
| endif | ||||
|  | ||||
| LIB_STATIC = liblvm.a | ||||
|  | ||||
| $(SUBDIRS): $(LIB_STATIC) | ||||
|  | ||||
| include ../make.tmpl | ||||
|  | ||||
| liblvm.a: $(OBJECTS) | ||||
| 	$(RM) $@ | ||||
| 	$(AR) r $@ $(OBJECTS) | ||||
| 	$(RANLIB) $@ | ||||
|  | ||||
|   | ||||
| @@ -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,10 +19,13 @@ | ||||
| #include "memlock.h" | ||||
| #include "display.h" | ||||
| #include "fs.h" | ||||
| #include "lvm-file.h" | ||||
| #include "lvm-string.h" | ||||
| #include "pool.h" | ||||
| #include "toolcontext.h" | ||||
| #include "dev_manager.h" | ||||
| #include "str_list.h" | ||||
| #include "config.h" | ||||
|  | ||||
| #include <limits.h> | ||||
| #include <fcntl.h> | ||||
| @@ -21,12 +33,34 @@ | ||||
|  | ||||
| #define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args) | ||||
|  | ||||
| int lvm1_present(struct cmd_context *cmd) | ||||
| { | ||||
| 	char path[PATH_MAX]; | ||||
|  | ||||
| 	if (lvm_snprintf(path, sizeof(path), "%s/lvm/global", cmd->proc_dir) | ||||
| 	    < 0) { | ||||
| 		log_error("LVM1 proc global snprintf failed"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (path_exists(path)) | ||||
| 		return 1; | ||||
| 	else | ||||
| 		return 0; | ||||
| } | ||||
|  | ||||
| #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) | ||||
| { | ||||
| @@ -40,10 +74,19 @@ 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; | ||||
| @@ -61,10 +104,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; | ||||
| @@ -73,10 +124,19 @@ 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) | ||||
| { | ||||
| @@ -111,6 +171,86 @@ int activation(void) | ||||
| 	return _activation; | ||||
| } | ||||
|  | ||||
| static int _passes_activation_filter(struct cmd_context *cmd, | ||||
| 				     struct logical_volume *lv) | ||||
| { | ||||
| 	const 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 host 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()) | ||||
| @@ -149,6 +289,46 @@ 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. | ||||
|  */ | ||||
| @@ -162,7 +342,7 @@ static int _lv_info(const struct logical_volume *lv, int mknodes, | ||||
| 	if (!activation()) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) { | ||||
| 	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -186,6 +366,17 @@ 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. | ||||
|  */ | ||||
| @@ -197,7 +388,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->cmd, lv->vg->name))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -216,11 +407,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->cmd, lv->vg->name))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -258,12 +458,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->cmd, lv->vg->name))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -280,7 +480,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->cmd, lv->vg->name))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -292,12 +492,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->cmd, lv->vg->name))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -310,7 +510,7 @@ static int _lv_suspend(struct logical_volume *lv) | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * These two functions return the number of LVs in the state, | ||||
|  * These two functions return the number of visible LVs in the state, | ||||
|  * or -1 on error. | ||||
|  */ | ||||
| int lvs_in_vg_activated(struct volume_group *vg) | ||||
| @@ -324,7 +524,8 @@ int lvs_in_vg_activated(struct volume_group *vg) | ||||
|  | ||||
| 	list_iterate(lvh, &vg->lvs) { | ||||
| 		lv = list_item(lvh, struct lv_list)->lv; | ||||
| 		count += (_lv_active(lv) == 1); | ||||
| 		if (lv->status & VISIBLE_LV) | ||||
| 			count += (_lv_active(lv) == 1); | ||||
| 	} | ||||
|  | ||||
| 	return count; | ||||
| @@ -341,14 +542,15 @@ int lvs_in_vg_opened(struct volume_group *vg) | ||||
|  | ||||
| 	list_iterate(lvh, &vg->lvs) { | ||||
| 		lv = list_item(lvh, struct lv_list)->lv; | ||||
| 		count += (_lv_open_count(lv) == 1); | ||||
| 		if (lv->status & VISIBLE_LV) | ||||
| 			count += (_lv_open_count(lv) > 0); | ||||
| 	} | ||||
|  | ||||
| 	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; | ||||
| @@ -370,10 +572,10 @@ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s) | ||||
| 	} | ||||
|  | ||||
| 	if (!info.exists || info.suspended) | ||||
| 		return 1; | ||||
| 		return error_if_not_suspended ? 0 : 1; | ||||
|  | ||||
| 	memlock_inc(); | ||||
| 	if (!_lv_suspend(lv)) { | ||||
| 	if (!_lv_suspend_lv(lv)) { | ||||
| 		memlock_dec(); | ||||
| 		fs_unlock(); | ||||
| 		return 0; | ||||
| @@ -382,7 +584,19 @@ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s) | ||||
| /* 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; | ||||
| @@ -404,9 +618,9 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s) | ||||
| 	} | ||||
|  | ||||
| 	if (!info.exists || !info.suspended) | ||||
| 		return 1; | ||||
| 		return error_if_not_active ? 0 : 1; | ||||
|  | ||||
| 	if (!_lv_activate(lv)) | ||||
| 	if (!_lv_activate_lv(lv)) | ||||
| 		return 0; | ||||
|  | ||||
| 	memlock_dec(); | ||||
| @@ -415,6 +629,17 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s) | ||||
| 	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; | ||||
| @@ -440,7 +665,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s) | ||||
| 	if (!info.exists) | ||||
| 		return 1; | ||||
|  | ||||
| 	if (info.open_count) { | ||||
| 	if (info.open_count && (lv->status & VISIBLE_LV)) { | ||||
| 		log_error("LV %s/%s in use: not removing", lv->vg->name, | ||||
| 			  lv->name); | ||||
| 		return 0; | ||||
| @@ -454,7 +679,31 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s) | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| int lv_activate(struct cmd_context *cmd, const char *lvid_s) | ||||
| /* 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; | ||||
| } | ||||
|  | ||||
| static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter) | ||||
| { | ||||
| 	struct logical_volume *lv; | ||||
| 	struct lvinfo info; | ||||
| @@ -466,6 +715,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; | ||||
| @@ -480,27 +735,45 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s) | ||||
| 		return 1; | ||||
|  | ||||
| 	memlock_inc(); | ||||
| 	r = _lv_activate(lv); | ||||
| 	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_mknodes(lv); | ||||
| 		r = dev_manager_lv_mknodes(lv); | ||||
| 	else | ||||
| 		r = dev_manager_rmnodes(lv); | ||||
| 		r = dev_manager_lv_rmnodes(lv); | ||||
|  | ||||
| 	fs_unlock(); | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| @@ -27,12 +36,18 @@ int activation(void); | ||||
|  | ||||
| int driver_version(char *version, size_t size); | ||||
| int library_version(char *version, size_t size); | ||||
| int lvm1_present(struct cmd_context *cmd); | ||||
|  | ||||
| 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); | ||||
| @@ -41,6 +56,15 @@ 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. | ||||
|  */ | ||||
|   | ||||
| @@ -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" | ||||
| @@ -12,7 +21,11 @@ | ||||
| #include "lvm-string.h" | ||||
| #include "fs.h" | ||||
| #include "defaults.h" | ||||
| #include "segtypes.h" | ||||
| #include "display.h" | ||||
| #include "toolcontext.h" | ||||
| #include "targets.h" | ||||
| #include "config.h" | ||||
|  | ||||
| #include <libdevmapper.h> | ||||
| #include <limits.h> | ||||
| @@ -53,13 +66,8 @@ enum { | ||||
| 	SUSPENDED = 4, | ||||
| 	NOPROPAGATE = 5, | ||||
| 	TOPLEVEL = 6, | ||||
| 	REMOVE = 7 | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	MIRR_DISABLED, | ||||
| 	MIRR_RUNNING, | ||||
| 	MIRR_COMPLETED | ||||
| 	REMOVE = 7, | ||||
| 	RESUME_IMMEDIATE = 8 | ||||
| }; | ||||
|  | ||||
| typedef enum { | ||||
| @@ -103,14 +111,14 @@ struct dl_list { | ||||
| }; | ||||
|  | ||||
| static const char *stripe_filler = NULL; | ||||
| static uint32_t mirror_region_size = 0; | ||||
|  | ||||
| struct dev_manager { | ||||
| 	struct pool *mem; | ||||
|  | ||||
| 	struct config_tree *cf; | ||||
| 	struct cmd_context *cmd; | ||||
|  | ||||
| 	const char *stripe_filler; | ||||
| 	uint32_t mirror_region_size; | ||||
| 	void *target_state; | ||||
| 	uint32_t pvmove_mirror_count; | ||||
|  | ||||
| 	char *vg_name; | ||||
| @@ -327,7 +335,7 @@ static int _info_run(const char *name, const char *uuid, struct dm_info *info, | ||||
| static int _info(const char *name, const char *uuid, int mknodes, | ||||
| 		 struct dm_info *info, struct pool *mem, char **uuid_out) | ||||
| { | ||||
| 	if (!mknodes && uuid && *uuid &&  | ||||
| 	if (!mknodes && uuid && *uuid && | ||||
| 	    _info_run(NULL, uuid, info, 0, mem, uuid_out) && info->exists) | ||||
| 		return 1; | ||||
|  | ||||
| @@ -418,18 +426,16 @@ static int _percent_run(struct dev_manager *dm, const char *name, | ||||
| 	uint64_t start, length; | ||||
| 	char *type = NULL; | ||||
| 	char *params = NULL; | ||||
| 	float percent2; | ||||
| 	struct list *segh = &lv->segments; | ||||
| 	struct lv_segment *seg = NULL; | ||||
| 	struct segment_type *segtype; | ||||
|  | ||||
| 	uint64_t numerator, denominator; | ||||
| 	uint64_t total_numerator = 0, total_denominator = 0; | ||||
|  | ||||
| 	*percent = -1; | ||||
|  | ||||
| 	if (!(dmt = _setup_task(name, uuid, event_nr, | ||||
| 				wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS))) | ||||
| 	{ | ||||
| 				wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -462,40 +468,19 @@ static int _percent_run(struct dev_manager *dm, const char *name, | ||||
| 		if (!type || !params || strcmp(type, target_type)) | ||||
| 			continue; | ||||
|  | ||||
| 		/* Mirror? */ | ||||
| 		if (!strcmp(type, "mirror")) { | ||||
| 			log_debug("Mirror status: %s", params); | ||||
| 			if (sscanf(params, "%*d %*x:%*x %*x:%*x %" PRIu64 | ||||
| 				   "/%" PRIu64, &numerator, | ||||
| 				   &denominator) != 2) { | ||||
| 				log_error("Failure parsing mirror status: %s", | ||||
| 					  params); | ||||
| 				goto out; | ||||
| 			} | ||||
| 			total_numerator += numerator; | ||||
| 			total_denominator += denominator; | ||||
|  | ||||
| 			if (seg && (seg->status & PVMOVE)) | ||||
| 				seg->extents_moved = dm->mirror_region_size * | ||||
| 				    numerator / lv->vg->extent_size; | ||||
| 		if (!(segtype = get_segtype_from_string(dm->cmd, type))) | ||||
| 			continue; | ||||
|  | ||||
| 		if (segtype->ops->target_percent && | ||||
| 		    !segtype->ops->target_percent(&dm->target_state, dm->mem, | ||||
| 						  dm->cmd->cft, seg, params, | ||||
| 						  &total_numerator, | ||||
| 						  &total_denominator, | ||||
| 						  percent)) { | ||||
| 			stack; | ||||
| 			goto out; | ||||
| 		} | ||||
|  | ||||
| 		if (strcmp(type, "snapshot")) | ||||
| 			continue; | ||||
|  | ||||
| 		/* Snapshot */ | ||||
| 		if (index(params, '/')) { | ||||
| 			if (sscanf(params, "%" PRIu64 "/%" PRIu64, | ||||
| 				   &numerator, &denominator) == 2) { | ||||
| 				total_numerator += numerator; | ||||
| 				total_denominator += denominator; | ||||
| 			} | ||||
| 			continue; | ||||
| 		} else if (sscanf(params, "%f", &percent2) == 1) { | ||||
| 			*percent += percent2; | ||||
| 			*percent /= 2; | ||||
| 		} | ||||
| 	} while (next); | ||||
|  | ||||
| 	if (lv && (segh = list_next(&lv->segments, segh))) { | ||||
| @@ -506,7 +491,7 @@ static int _percent_run(struct dev_manager *dm, const char *name, | ||||
|  | ||||
| 	if (total_denominator) | ||||
| 		*percent = (float) total_numerator *100 / total_denominator; | ||||
| 	else | ||||
| 	else if (*percent < 0) | ||||
| 		*percent = 100; | ||||
|  | ||||
| 	log_debug("LV percent: %f", *percent); | ||||
| @@ -565,6 +550,55 @@ static int _rename(struct dev_layer *dl, char *newname) | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| static int _suspend_or_resume(const char *name, action_t suspend) | ||||
| { | ||||
| 	int r; | ||||
| 	struct dm_task *dmt; | ||||
| 	int sus = (suspend == SUSPEND) ? 1 : 0; | ||||
| 	int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME; | ||||
|  | ||||
| 	log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name); | ||||
| 	if (!(dmt = _setup_task(name, NULL, 0, task))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!(r = dm_task_run(dmt))) | ||||
| 		log_error("Couldn't %s device '%s'", sus ? "suspend" : "resume", | ||||
| 			  name); | ||||
|  | ||||
| 	dm_task_destroy(dmt); | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| static int _suspend(struct dev_layer *dl) | ||||
| { | ||||
| 	if (!dl->info.exists || dl->info.suspended) | ||||
| 		return 1; | ||||
|  | ||||
| 	if (!_suspend_or_resume(dl->name, SUSPEND)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	dl->info.suspended = 1; | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _resume(struct dev_layer *dl) | ||||
| { | ||||
| 	if (!dl->info.exists || !dl->info.suspended) | ||||
| 		return 1; | ||||
|  | ||||
| 	if (!_suspend_or_resume(dl->name, RESUME)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	dl->info.suspended = 0; | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _load(struct dev_manager *dm, struct dev_layer *dl, int task) | ||||
| { | ||||
| 	int r = 1; | ||||
| @@ -624,9 +658,9 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task) | ||||
| 		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); | ||||
| 			    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)) { | ||||
| @@ -641,6 +675,13 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task) | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	if (_get_flag(dl, RESUME_IMMEDIATE) && dl->info.suspended && | ||||
| 	    !_resume(dl)) { | ||||
| 		stack; | ||||
| 		r = 0; | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	log_very_verbose("Activated %s %s %03u:%03u", dl->name, | ||||
| 			 dl->dlid, dl->info.major, dl->info.minor); | ||||
|  | ||||
| @@ -687,55 +728,6 @@ static int _remove(struct dev_layer *dl) | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| static int _suspend_or_resume(const char *name, action_t suspend) | ||||
| { | ||||
| 	int r; | ||||
| 	struct dm_task *dmt; | ||||
| 	int sus = (suspend == SUSPEND) ? 1 : 0; | ||||
| 	int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME; | ||||
|  | ||||
| 	log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name); | ||||
| 	if (!(dmt = _setup_task(name, NULL, 0, task))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!(r = dm_task_run(dmt))) | ||||
| 		log_error("Couldn't %s device '%s'", sus ? "suspend" : "resume", | ||||
| 			  name); | ||||
|  | ||||
| 	dm_task_destroy(dmt); | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| static int _suspend(struct dev_layer *dl) | ||||
| { | ||||
| 	if (!dl->info.exists || dl->info.suspended) | ||||
| 		return 1; | ||||
|  | ||||
| 	if (!_suspend_or_resume(dl->name, SUSPEND)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	dl->info.suspended = 1; | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _resume(struct dev_layer *dl) | ||||
| { | ||||
| 	if (!dl->info.exists || !dl->info.suspended) | ||||
| 		return 1; | ||||
|  | ||||
| 	if (!_suspend_or_resume(dl->name, RESUME)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	dl->info.suspended = 0; | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * The functions that populate the table in a dm_task as part of | ||||
|  * a create/reload. | ||||
| @@ -750,98 +742,26 @@ static int _emit_target_line(struct dev_manager *dm, struct dm_task *dmt, | ||||
| 			     size_t paramsize) | ||||
| { | ||||
| 	uint64_t esize = seg->lv->vg->extent_size; | ||||
| 	uint32_t s, start_area = 0u, areas = seg->area_count; | ||||
| 	int w = 0, tw = 0; | ||||
| 	int w = 0; | ||||
| 	const char *target = NULL; | ||||
| 	const char *trailing_space; | ||||
| 	int mirror_status; | ||||
| 	struct dev_layer *dl; | ||||
| 	char devbuf[10]; | ||||
| 	int r; | ||||
|  | ||||
| 	switch (seg->type) { | ||||
| 	case SEG_SNAPSHOT: | ||||
| 	if (!seg->segtype->ops->compose_target_line) { | ||||
| 		log_error("_emit_target: Internal error: Can't handle " | ||||
| 			  "SEG_SNAPSHOT"); | ||||
| 			  "segment type %s", seg->segtype->name); | ||||
| 		return 0; | ||||
| 		/* Target formats: | ||||
| 		 *   linear [device offset]+ | ||||
| 		 *   striped #stripes stripe_size [device offset]+ | ||||
| 		 *   mirror  log_type #log_params [log_params]*  | ||||
| 		 *           #mirrors [device offset]+ | ||||
| 		 */ | ||||
| 	case SEG_STRIPED: | ||||
| 		if (areas == 1) | ||||
| 			target = "linear"; | ||||
| 		else if (areas > 1) { | ||||
| 			target = "striped"; | ||||
| 			if ((tw = lvm_snprintf(params, paramsize, "%u %u ", | ||||
| 					       areas, seg->stripe_size)) < 0) | ||||
| 				goto error; | ||||
| 			w = tw; | ||||
| 		} else { | ||||
| 			log_error("_emit_target: Internal error: SEG_STRIPED " | ||||
| 				  "with no stripes"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		break; | ||||
| 	case SEG_MIRRORED: | ||||
| 		mirror_status = MIRR_RUNNING; | ||||
| 		if (seg->status & PVMOVE) { | ||||
| 			if (seg->extents_moved == seg->area_len) { | ||||
| 				mirror_status = MIRR_COMPLETED; | ||||
| 				start_area = 1; | ||||
| 			} else if (dm->pvmove_mirror_count++) { | ||||
| 				mirror_status = MIRR_DISABLED; | ||||
| 				areas = 1; | ||||
| 			} | ||||
| 		} | ||||
| 		if (mirror_status != MIRR_RUNNING) { | ||||
| 			target = "linear"; | ||||
| 			break; | ||||
| 		} | ||||
| 		target = "mirror"; | ||||
| 		if ((tw = lvm_snprintf(params, paramsize, "core 1 %u %u ", | ||||
| 				       dm->mirror_region_size, areas)) < 0) | ||||
| 			goto error; | ||||
| 		w = tw; | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	for (s = start_area; s < areas; s++, w += tw) { | ||||
| 		trailing_space = (areas - s - 1) ? " " : ""; | ||||
| 		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, paramsize - w, | ||||
| 					  "%s 0%s", dm->stripe_filler, | ||||
| 					  trailing_space); | ||||
| 		else if (seg->area[s].type == AREA_PV) | ||||
| 			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 { | ||||
| 			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; | ||||
| 	if ((r = seg->segtype->ops->compose_target_line(dm, dm->mem, | ||||
| 							dm->cmd->cft, | ||||
| 							&dm->target_state, seg, | ||||
| 							params, paramsize, | ||||
| 							&target, &w, | ||||
| 							&dm-> | ||||
| 							pvmove_mirror_count)) <= | ||||
| 	    0) { | ||||
| 		stack; | ||||
| 		return r; | ||||
| 	} | ||||
|  | ||||
| 	log_debug("Adding target: %" PRIu64 " %" PRIu64 " %s %s", | ||||
| @@ -854,11 +774,62 @@ static int _emit_target_line(struct dev_manager *dm, struct dm_task *dmt, | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
|       error: | ||||
| 	log_debug("Insufficient space in params[%" PRIsize_t "] for target " | ||||
| 		  "parameters.", paramsize); | ||||
| 	return -1; | ||||
| int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg, | ||||
| 		       char *params, size_t paramsize, int *pos, int start_area, | ||||
| 		       int areas) | ||||
| { | ||||
| 	uint32_t s; | ||||
| 	int tw = 0; | ||||
| 	const char *trailing_space; | ||||
| 	uint64_t esize = seg->lv->vg->extent_size; | ||||
| 	struct dev_layer *dl; | ||||
| 	char devbuf[10]; | ||||
|  | ||||
| 	for (s = start_area; s < areas; s++, *pos += tw) { | ||||
| 		trailing_space = (areas - s - 1) ? " " : ""; | ||||
| 		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 + *pos, paramsize - *pos, | ||||
| 					  "%s 0%s", dm->stripe_filler, | ||||
| 					  trailing_space); | ||||
| 		else if (seg->area[s].type == AREA_PV) | ||||
| 			tw = lvm_snprintf(params + *pos, paramsize - *pos, | ||||
| 					  "%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 { | ||||
| 			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 + *pos, paramsize - *pos, | ||||
| 					  "%s %" PRIu64 "%s", devbuf, | ||||
| 					  esize * seg->area[s].u.lv.le, | ||||
| 					  trailing_space); | ||||
| 		} | ||||
|  | ||||
| 		if (tw < 0) { | ||||
| 			stack; | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _emit_target(struct dev_manager *dm, struct dm_task *dmt, | ||||
| @@ -883,6 +854,9 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt, | ||||
| 		if (ret >= 0) | ||||
| 			return ret; | ||||
|  | ||||
| 		log_debug("Insufficient space in params[%" PRIsize_t | ||||
| 			  "] for target parameters.", paramsize); | ||||
|  | ||||
| 		paramsize *= 2; | ||||
| 	} while (paramsize < MAX_TARGET_PARAMSIZE); | ||||
|  | ||||
| @@ -1014,8 +988,8 @@ 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 dev_manager *dev_manager_create(struct cmd_context *cmd, | ||||
| 				       const char *vg_name) | ||||
| { | ||||
| 	struct pool *mem; | ||||
| 	struct dev_manager *dm; | ||||
| @@ -1030,23 +1004,16 @@ struct dev_manager *dev_manager_create(const char *vg_name, | ||||
| 		goto bad; | ||||
| 	} | ||||
|  | ||||
| 	dm->cmd = cmd; | ||||
| 	dm->mem = mem; | ||||
| 	dm->cf = cf; | ||||
|  | ||||
| 	if (!stripe_filler) { | ||||
| 		stripe_filler = find_config_str(cf->root, | ||||
| 		stripe_filler = find_config_str(cmd->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, | ||||
| 							 "activation/mirror_region_size", | ||||
| 							 '/', | ||||
| 							 DEFAULT_MIRROR_REGION_SIZE); | ||||
| 	} | ||||
| 	dm->mirror_region_size = mirror_region_size; | ||||
|  | ||||
| 	if (!(dm->vg_name = pool_strdup(dm->mem, vg_name))) { | ||||
| 		stack; | ||||
| 		goto bad; | ||||
| @@ -1062,6 +1029,8 @@ struct dev_manager *dev_manager_create(const char *vg_name, | ||||
| 	list_init(&dm->remove_list); | ||||
| 	list_init(&dm->suspend_list); | ||||
|  | ||||
| 	dm->target_state = NULL; | ||||
|  | ||||
| 	return dm; | ||||
|  | ||||
|       bad: | ||||
| @@ -1274,15 +1243,13 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv, | ||||
| 	/* Add dependencies for any LVs that segments refer to */ | ||||
| 	list_iterate(segh, &lv->segments) { | ||||
| 		seg = list_item(segh, struct lv_segment); | ||||
| 		if (seg->type != SEG_STRIPED && seg->type != SEG_MIRRORED) | ||||
| 			continue; | ||||
| 		for (s = 0; s < seg->area_count; s++) { | ||||
| 			if (seg->area[s].type != AREA_LV) | ||||
| 				continue; | ||||
| 			if (!str_list_add(dm->mem, &dl->pre_create, | ||||
| 					  _build_dlid(dm->mem, | ||||
| 						      seg->area[s].u.lv. | ||||
| 						      lv->lvid.s, NULL))) { | ||||
| 						      seg->area[s].u.lv.lv-> | ||||
| 						      lvid.s, NULL))) { | ||||
| 				stack; | ||||
| 				return 0; | ||||
| 			} | ||||
| @@ -1303,7 +1270,7 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv, | ||||
| 	_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))) { | ||||
| @@ -1328,6 +1295,9 @@ static int _expand_origin_real(struct dev_manager *dm, | ||||
| 	_clear_flag(dl, VISIBLE); | ||||
| 	_clear_flag(dl, TOPLEVEL); | ||||
|  | ||||
| 	/* Size changes must take effect before tables using it are reloaded */ | ||||
| 	_set_flag(dl, RESUME_IMMEDIATE); | ||||
|  | ||||
| 	real_dlid = dl->dlid; | ||||
|  | ||||
| 	if (!(dl = _create_layer(dm, NULL, lv))) { | ||||
| @@ -1680,7 +1650,6 @@ static int _create_rec(struct dev_manager *dm, struct dev_layer *dl) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int _build_all_layers(struct dev_manager *dm, struct volume_group *vg) | ||||
| { | ||||
| 	struct list *lvh; | ||||
| @@ -1748,8 +1717,7 @@ static int _populate_pre_suspend_lists(struct dev_manager *dm) | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if (!str_list_add(dm->mem, &dep->pre_create, | ||||
| 					  dl->dlid)) { | ||||
| 			if (!str_list_add(dm->mem, &dep->pre_create, dl->dlid)) { | ||||
| 				stack; | ||||
| 				return 0; | ||||
| 			} | ||||
| @@ -1765,8 +1733,7 @@ static int _populate_pre_suspend_lists(struct dev_manager *dm) | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if (!str_list_add(dm->mem, &dep->pre_suspend, | ||||
| 					  dl->dlid)) { | ||||
| 			if (!str_list_add(dm->mem, &dep->pre_suspend, dl->dlid)) { | ||||
| 				stack; | ||||
| 				return 0; | ||||
| 			} | ||||
| @@ -1940,7 +1907,6 @@ static int _add_existing_layer(struct dev_manager *dm, const char *name) | ||||
|  | ||||
| static int _scan_existing_devices(struct dev_manager *dm) | ||||
| { | ||||
|  | ||||
| 	int r = 0; | ||||
| 	struct dm_names *names; | ||||
| 	unsigned next = 0; | ||||
| @@ -2079,6 +2045,73 @@ static int _remove_suspended_lvs(struct dev_manager *dm, | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _targets_present(struct dev_manager *dm, struct list *lvs) | ||||
| { | ||||
| 	struct logical_volume *lv; | ||||
| 	struct list *lvh, *segh; | ||||
| 	struct segment_type *segtype; | ||||
| 	struct lv_segment *seg; | ||||
| 	int snapshots = 0, mirrors = 0; | ||||
|  | ||||
| 	list_iterate(lvh, lvs) { | ||||
| 		lv = list_item(lvh, struct lv_list)->lv; | ||||
|  | ||||
| 		if (!snapshots) | ||||
| 			if (lv_is_cow(lv) || lv_is_origin(lv)) | ||||
| 				snapshots = 1; | ||||
|  | ||||
| 		if (!mirrors) | ||||
| 			if (lv->status & PVMOVE) | ||||
| 				mirrors = 1; | ||||
|  | ||||
| 		if (lv->status & VIRTUAL) { | ||||
| 			list_iterate(segh, &lv->segments) { | ||||
| 				seg = list_item(segh, struct lv_segment); | ||||
| 				if (seg->segtype->ops->target_present && | ||||
| 				    !seg->segtype->ops->target_present()) { | ||||
| 					log_error("Can't expand LV: %s target " | ||||
| 						  "support missing " | ||||
| 						  "from kernel?", | ||||
| 						  seg->segtype->name); | ||||
| 					return 0; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (mirrors) { | ||||
| 		if (!(segtype = get_segtype_from_string(dm->cmd, "mirror"))) { | ||||
| 			log_error("Can't expand LV: Mirror support " | ||||
| 				  "missing from tools?"); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (!segtype->ops->target_present || | ||||
| 		    !segtype->ops->target_present()) { | ||||
| 			log_error("Can't expand LV: Mirror support missing " | ||||
| 				  "from kernel?"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (snapshots) { | ||||
| 		if (!(segtype = get_segtype_from_string(dm->cmd, "snapshot"))) { | ||||
| 			log_error("Can't expand LV: Snapshot support " | ||||
| 				  "missing from tools?"); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (!segtype->ops->target_present || | ||||
| 		    !segtype->ops->target_present()) { | ||||
| 			log_error("Can't expand LV: Snapshot support missing " | ||||
| 				  "from kernel?"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg) | ||||
| { | ||||
| 	char *dlid; | ||||
| @@ -2161,6 +2194,12 @@ static int _action(struct dev_manager *dm, struct logical_volume *lv, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!_targets_present(dm, &dm->active_list) || | ||||
| 	    !_targets_present(dm, &dm->reload_list)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!_execute(dm, lv->vg)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| @@ -2184,7 +2223,7 @@ int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv) | ||||
| 	return _action(dm, lv, SUSPEND); | ||||
| } | ||||
|  | ||||
| int dev_manager_mknodes(const struct logical_volume *lv) | ||||
| int dev_manager_lv_mknodes(const struct logical_volume *lv) | ||||
| { | ||||
| 	char *name; | ||||
|  | ||||
| @@ -2197,11 +2236,25 @@ int dev_manager_mknodes(const struct logical_volume *lv) | ||||
| 	return fs_add_lv(lv, name); | ||||
| } | ||||
|  | ||||
| int dev_manager_rmnodes(const struct logical_volume *lv) | ||||
| 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(); | ||||
|   | ||||
| @@ -1,23 +1,31 @@ | ||||
| /* | ||||
|  * 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 | ||||
| #define _LVM_DEV_MANAGER_H | ||||
|  | ||||
| #include "metadata.h" | ||||
| #include "config.h" | ||||
|  | ||||
| struct logical_volume; | ||||
| struct cmd_context; | ||||
| struct dev_manager; | ||||
| struct dm_info; | ||||
|  | ||||
| /* | ||||
|  * Constructor and destructor. | ||||
|  */ | ||||
| struct dev_manager *dev_manager_create(const char *vg_name, | ||||
| 				       struct config_tree *cf); | ||||
| struct dev_manager *dev_manager_create(struct cmd_context *cmd, | ||||
| 				       const char *vg_name); | ||||
| void dev_manager_destroy(struct dev_manager *dm); | ||||
| void dev_manager_exit(void); | ||||
|  | ||||
| @@ -38,8 +46,9 @@ int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv); | ||||
| int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv); | ||||
| int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv); | ||||
|  | ||||
| int dev_manager_mknodes(const struct logical_volume *lv); | ||||
| int dev_manager_rmnodes(const struct logical_volume *lv); | ||||
| 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. | ||||
|   | ||||
| @@ -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,6 +20,10 @@ | ||||
| #include "lvm-file.h" | ||||
| #include "memlock.h" | ||||
|  | ||||
| #ifdef HAVE_SELINUX | ||||
| #  include "selinux.h" | ||||
| #endif | ||||
|  | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
| #include <unistd.h> | ||||
| @@ -166,6 +179,13 @@ static int _mk_link(const char *dev_dir, const char *vg_name, | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| #ifdef HAVE_SELINUX | ||||
|         if (!set_selinux_context(lv_path)) { | ||||
|                 stack; | ||||
|                 return 0; | ||||
|         } | ||||
| #endif | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
							
								
								
									
										25
									
								
								lib/activate/targets.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								lib/activate/targets.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| /* | ||||
|  * 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_TARGETS_H | ||||
| #define _LVM_TARGETS_H | ||||
|  | ||||
| struct dev_manager; | ||||
| struct lv_segment; | ||||
|  | ||||
| int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,                                 char *params, size_t paramsize, int *pos, | ||||
| 		                        int start_area, int areas); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										13
									
								
								lib/cache/lvmcache.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								lib/cache/lvmcache.c
									
									
									
									
										vendored
									
									
								
							| @@ -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 | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|   | ||||
							
								
								
									
										18
									
								
								lib/cache/lvmcache.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								lib/cache/lvmcache.h
									
									
									
									
										vendored
									
									
								
							| @@ -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 | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| @@ -11,7 +20,6 @@ | ||||
| #include "dev-cache.h" | ||||
| #include "uuid.h" | ||||
| #include "label.h" | ||||
| #include "metadata.h" | ||||
|  | ||||
| #define ORPHAN "" | ||||
|  | ||||
| @@ -21,6 +29,10 @@ | ||||
| /* LVM specific per-volume info */ | ||||
| /* Eventual replacement for struct physical_volume perhaps? */ | ||||
|  | ||||
| struct cmd_context; | ||||
| struct format_type; | ||||
| struct volume_group; | ||||
|  | ||||
| struct lvmcache_vginfo { | ||||
| 	struct list list;	/* Join these vginfos together */ | ||||
| 	struct list infos;	/* List head for lvmcache_infos */ | ||||
|   | ||||
| @@ -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_ERRORS_H | ||||
|   | ||||
| @@ -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 | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| @@ -14,13 +23,18 @@ | ||||
| #include "activate.h" | ||||
| #include "filter.h" | ||||
| #include "filter-composite.h" | ||||
| #include "filter-md.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" | ||||
| #include "segtypes.h" | ||||
| #include "lvmcache.h" | ||||
|  | ||||
| #ifdef HAVE_LIBDL | ||||
| #include "sharedlib.h" | ||||
| @@ -30,8 +44,13 @@ | ||||
| #include "format1.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef POOL_INTERNAL | ||||
| #include "format_pool.h" | ||||
| #endif | ||||
|  | ||||
| #include <locale.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/utsname.h> | ||||
| #include <syslog.h> | ||||
| #include <time.h> | ||||
|  | ||||
| @@ -67,7 +86,7 @@ static void _init_logging(struct cmd_context *cmd) | ||||
|  | ||||
| 	/* 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(); | ||||
|  | ||||
| @@ -76,47 +95,50 @@ 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", '/', | ||||
| 			    DEFAULT_OVERWRITE)) | ||||
| 	if (find_config_int(cmd->cft->root, "log/overwrite", DEFAULT_OVERWRITE)) | ||||
| 		append = 0; | ||||
|  | ||||
| 	log_file = find_config_str(cmd->cf->root, "log/file", '/', 0); | ||||
| 	if (log_file) | ||||
| 		init_log_file(log_file, append); | ||||
| 	log_file = find_config_str(cmd->cft->root, "log/file", 0); | ||||
|  | ||||
| 	log_file = find_config_str(cmd->cf->root, "log/activate_file", '/', 0); | ||||
| 	if (log_file) { | ||||
| 		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->cf->root, | ||||
| 						 "log/activation", '/', 0)); | ||||
| 	init_log_while_suspended(find_config_int(cmd->cft->root, | ||||
| 						 "log/activation", 0)); | ||||
|  | ||||
| 	t = time(NULL); | ||||
| 	log_verbose("Logging initialised at %s", ctime(&t)); | ||||
| @@ -132,8 +154,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)) != | ||||
| @@ -142,8 +164,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; | ||||
| 	} | ||||
| @@ -153,27 +175,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"); | ||||
| @@ -183,57 +203,266 @@ static int _process_config(struct cmd_context *cmd) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /* Find and read config file */ | ||||
| static int _init_config(struct cmd_context *cmd) | ||||
| static int _set_tag(struct cmd_context *cmd, const char *tag) | ||||
| { | ||||
| 	struct stat info; | ||||
| 	char config_file[PATH_MAX] = ""; | ||||
| 	log_very_verbose("Setting host tag: %s", pool_strdup(cmd->libmem, tag)); | ||||
|  | ||||
| 	if (!(cmd->cf = create_config_tree())) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	/* No config file if LVM_SYSTEM_DIR is empty */ | ||||
| 	if (!*cmd->sys_dir) | ||||
| 		return 1; | ||||
|  | ||||
| 	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); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	/* Is there a config file? */ | ||||
| 	if (stat(config_file, &info) == -1) { | ||||
| 		if (errno == ENOENT) | ||||
| 			return 1; | ||||
| 		log_sys_error("stat", config_file); | ||||
| 		destroy_config_tree(cmd->cf); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!read_config_file(cmd->cf, config_file)) { | ||||
| 		log_error("Failed to load config file %s", config_file); | ||||
| 		destroy_config_tree(cmd->cf); | ||||
| 	if (!str_list_add(cmd->libmem, &cmd->tags, tag)) { | ||||
| 		log_error("_set_tag: str_list_add %s failed", tag); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _init_dev_cache(struct cmd_context *cmd) | ||||
| 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_tree *cft) | ||||
| { | ||||
| 	const struct config_node *tn, *cn; | ||||
| 	const char *tag; | ||||
| 	int passes; | ||||
|  | ||||
| 	if (!(tn = find_config_node(cft->root, "tags")) || !tn->child) | ||||
| 		return 1; | ||||
|  | ||||
| 	/* NB hosttags 0 when already 1 intentionally does not delete the tag */ | ||||
| 	if (!cmd->hosttags && find_config_int(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; | ||||
| 		} | ||||
| 		cmd->hosttags = 1; | ||||
| 	} | ||||
|  | ||||
| 	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; | ||||
| } | ||||
|  | ||||
| static int _load_config_file(struct cmd_context *cmd, const char *tag) | ||||
| { | ||||
| 	char config_file[PATH_MAX] = ""; | ||||
| 	const char *filler = ""; | ||||
| 	struct stat info; | ||||
| 	struct config_tree_list *cfl; | ||||
|  | ||||
| 	if (*tag) | ||||
| 		filler = "_"; | ||||
|  | ||||
| 	if (lvm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf", | ||||
| 			 cmd->sys_dir, filler, tag) < 0) { | ||||
| 		log_error("LVM_SYSTEM_DIR or tag was too long"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!(cfl = pool_alloc(cmd->libmem, sizeof(*cfl)))) { | ||||
| 		log_error("config_tree_list allocation failed"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!(cfl->cft = create_config_tree(config_file))) { | ||||
| 		log_error("config_tree allocation failed"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	/* Is there a config file? */ | ||||
| 	if (stat(config_file, &info) == -1) { | ||||
| 		if (errno == ENOENT) { | ||||
| 			list_add(&cmd->config_files, &cfl->list); | ||||
| 			goto out; | ||||
| 		} | ||||
| 		log_sys_error("stat", config_file); | ||||
| 		destroy_config_tree(cfl->cft); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	log_very_verbose("Loading config file: %s", config_file); | ||||
| 	if (!read_config_file(cfl->cft)) { | ||||
| 		log_error("Failed to load config file %s", config_file); | ||||
| 		destroy_config_tree(cfl->cft); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	list_add(&cmd->config_files, &cfl->list); | ||||
|  | ||||
|       out: | ||||
| 	if (*tag) | ||||
| 		_init_tags(cmd, cfl->cft); | ||||
| 	else | ||||
| 		/* Use temporary copy of lvm.conf while loading other files */ | ||||
| 		cmd->cft = cfl->cft; | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /* Find and read first config file */ | ||||
| static int _init_lvm_conf(struct cmd_context *cmd) | ||||
| { | ||||
| 	/* No config file if LVM_SYSTEM_DIR is empty */ | ||||
| 	if (!*cmd->sys_dir) { | ||||
| 		if (!(cmd->cft = create_config_tree(NULL))) { | ||||
| 			log_error("Failed to create config tree"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	if (!_load_config_file(cmd, "")) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /* Read any additional config files */ | ||||
| static int _init_tag_configs(struct cmd_context *cmd) | ||||
| { | ||||
| 	struct str_list *sl; | ||||
|  | ||||
| 	/* Tag list may grow while inside this loop */ | ||||
| 	list_iterate_items(sl, &cmd->tags) { | ||||
| 		if (!_load_config_file(cmd, sl->str)) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _merge_config_files(struct cmd_context *cmd) | ||||
| { | ||||
| 	struct config_tree_list *cfl; | ||||
|  | ||||
| 	/* Replace temporary duplicate copy of lvm.conf */ | ||||
| 	if (cmd->cft->root) { | ||||
| 		if (!(cmd->cft = create_config_tree(NULL))) { | ||||
| 			log_error("Failed to create config tree"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	list_iterate_items(cfl, &cmd->config_files) { | ||||
| 		/* Merge all config trees into cmd->cft using merge/tag rules */ | ||||
| 		if (!merge_config_tree(cmd, cmd->cft, cfl->cft)) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static void _destroy_tags(struct cmd_context *cmd) | ||||
| { | ||||
| 	struct list *slh, *slht; | ||||
|  | ||||
| 	list_iterate_safe(slh, slht, &cmd->tags) { | ||||
| 		list_del(slh); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int config_files_changed(struct cmd_context *cmd) | ||||
| { | ||||
| 	struct config_tree_list *cfl; | ||||
|  | ||||
| 	list_iterate_items(cfl, &cmd->config_files) { | ||||
| 		if (config_file_changed(cfl->cft)) | ||||
| 			return 1; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void _destroy_tag_configs(struct cmd_context *cmd) | ||||
| { | ||||
| 	struct config_tree_list *cfl; | ||||
|  | ||||
| 	if (cmd->cft && cmd->cft->root) { | ||||
| 		destroy_config_tree(cmd->cft); | ||||
| 		cmd->cft = NULL; | ||||
| 	} | ||||
|  | ||||
| 	list_iterate_items(cfl, &cmd->config_files) { | ||||
| 		destroy_config_tree(cfl->cft); | ||||
| 	} | ||||
|  | ||||
| 	list_init(&cmd->config_files); | ||||
| } | ||||
|  | ||||
| static int _init_dev_cache(struct cmd_context *cmd) | ||||
| { | ||||
| 	const struct config_node *cn; | ||||
| 	struct config_value *cv; | ||||
|  | ||||
| 	if (!dev_cache_init()) { | ||||
| 		stack; | ||||
| 		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"); | ||||
| @@ -261,33 +490,60 @@ static int _init_dev_cache(struct cmd_context *cmd) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| #define MAX_FILTERS 4 | ||||
|  | ||||
| static struct dev_filter *_init_filter_components(struct cmd_context *cmd) | ||||
| { | ||||
| 	struct config_node *cn; | ||||
| 	struct dev_filter *f1, *f2, *f3; | ||||
| 	unsigned nr_filt = 0; | ||||
| 	const struct config_node *cn; | ||||
| 	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; | ||||
| 	/* | ||||
| 	 * Filters listed in order: top one gets applied first. | ||||
| 	 * Failure to initialise some filters is not fatal. | ||||
| 	 * Update MAX_FILTERS definition above when adding new filters. | ||||
| 	 */ | ||||
|  | ||||
| 	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. Only available on 2.6 kernels.  Non-critical. | ||||
| 	 * Listed first because it's very efficient at eliminating  | ||||
| 	 * unavailable devices. | ||||
| 	 */ | ||||
| 	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. Optional. */ | ||||
| 	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. Required. */ | ||||
| 	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; | ||||
| 	/* md component filter. Optional, non-critical. */ | ||||
| 	if (find_config_bool(cmd->cft->root, "devices/md_component_detection", | ||||
| 			     DEFAULT_MD_COMPONENT_DETECTION)) { | ||||
| 		if ((filters[nr_filt] = md_filter_create())) | ||||
| 			nr_filt++; | ||||
| 	} | ||||
|  | ||||
| 	/* 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) | ||||
| @@ -309,22 +565,22 @@ static int _init_filters(struct cmd_context *cmd) | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	dev_cache = | ||||
| 	    find_config_str(cmd->cf->root, "devices/cache", '/', cache_file); | ||||
| 	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(dev_cache, &st) && | ||||
| 	    (st.st_mtime > config_file_timestamp(cmd->cf)) && | ||||
| 	    (st.st_mtime > config_file_timestamp(cmd->cft)) && | ||||
| 	    !persistent_filter_load(f4)) | ||||
| 		log_verbose("Failed to load existing device cache from %s", | ||||
| 			    dev_cache); | ||||
| @@ -342,7 +598,7 @@ static int _init_formats(struct cmd_context *cmd) | ||||
| 	struct list *fmth; | ||||
|  | ||||
| #ifdef HAVE_LIBDL | ||||
| 	struct config_node *cn; | ||||
| 	const struct config_node *cn; | ||||
| #endif | ||||
|  | ||||
| 	label_init(); | ||||
| @@ -354,10 +610,16 @@ static int _init_formats(struct cmd_context *cmd) | ||||
| 	list_add(&cmd->formats, &fmt->list); | ||||
| #endif | ||||
|  | ||||
| #ifdef POOL_INTERNAL | ||||
| 	if (!(fmt = init_pool_format(cmd))) | ||||
| 		return 0; | ||||
| 	fmt->library = NULL; | ||||
| 	list_add(&cmd->formats, &fmt->list); | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_LIBDL | ||||
| 	/* Load any formats in shared libs */ | ||||
| 	if ((cn = find_config_node(cmd->cf->root, "global/format_libraries", | ||||
| 				   '/'))) { | ||||
| 	if ((cn = find_config_node(cmd->cft->root, "global/format_libraries"))) { | ||||
|  | ||||
| 		struct config_value *cv; | ||||
| 		struct format_type *(*init_format_fn) (struct cmd_context *); | ||||
| @@ -369,7 +631,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; | ||||
| @@ -397,7 +659,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) { | ||||
| @@ -413,6 +675,119 @@ static int _init_formats(struct cmd_context *cmd) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int _init_segtypes(struct cmd_context *cmd) | ||||
| { | ||||
| 	struct segment_type *segtype; | ||||
|  | ||||
| #ifdef HAVE_LIBDL | ||||
| 	const struct config_node *cn; | ||||
| #endif | ||||
|  | ||||
| 	if (!(segtype = init_striped_segtype(cmd))) | ||||
| 		return 0; | ||||
| 	segtype->library = NULL; | ||||
| 	list_add(&cmd->segtypes, &segtype->list); | ||||
|  | ||||
| 	if (!(segtype = init_zero_segtype(cmd))) | ||||
| 		return 0; | ||||
| 	segtype->library = NULL; | ||||
| 	list_add(&cmd->segtypes, &segtype->list); | ||||
|  | ||||
| 	if (!(segtype = init_error_segtype(cmd))) | ||||
| 		return 0; | ||||
| 	segtype->library = NULL; | ||||
| 	list_add(&cmd->segtypes, &segtype->list); | ||||
|  | ||||
| #ifdef SNAPSHOT_INTERNAL | ||||
| 	if (!(segtype = init_snapshot_segtype(cmd))) | ||||
| 		return 0; | ||||
| 	segtype->library = NULL; | ||||
| 	list_add(&cmd->segtypes, &segtype->list); | ||||
| #endif | ||||
|  | ||||
| #ifdef MIRRORED_INTERNAL | ||||
| 	if (!(segtype = init_mirrored_segtype(cmd))) | ||||
| 		return 0; | ||||
| 	segtype->library = NULL; | ||||
| 	list_add(&cmd->segtypes, &segtype->list); | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_LIBDL | ||||
| 	/* Load any formats in shared libs */ | ||||
| 	if ((cn = find_config_node(cmd->cft->root, "global/segment_libraries"))) { | ||||
|  | ||||
| 		struct config_value *cv; | ||||
| 		struct segment_type *(*init_segtype_fn) (struct cmd_context *); | ||||
| 		void *lib; | ||||
| 		struct list *sgtl, *tmp; | ||||
| 		struct segment_type *segtype2; | ||||
|  | ||||
| 		for (cv = cn->v; cv; cv = cv->next) { | ||||
| 			if (cv->type != CFG_STRING) { | ||||
| 				log_error("Invalid string in config file: " | ||||
| 					  "global/segment_libraries"); | ||||
| 				return 0; | ||||
| 			} | ||||
| 			if (!(lib = load_shared_library(cmd->cft, cv->v.str, | ||||
| 							"segment type"))) { | ||||
| 				stack; | ||||
| 				return 0; | ||||
| 			} | ||||
|  | ||||
| 			if (!(init_segtype_fn = dlsym(lib, "init_segtype"))) { | ||||
| 				log_error("Shared library %s does not contain " | ||||
| 					  "segment type functions", cv->v.str); | ||||
| 				dlclose(lib); | ||||
| 				return 0; | ||||
| 			} | ||||
|  | ||||
| 			if (!(segtype = init_segtype_fn(cmd))) | ||||
| 				return 0; | ||||
| 			segtype->library = lib; | ||||
| 			list_add(&cmd->segtypes, &segtype->list); | ||||
|  | ||||
| 			list_iterate_safe(sgtl, tmp, &cmd->segtypes) { | ||||
| 				segtype2 = list_item(sgtl, struct segment_type); | ||||
| 				if (!strcmp(segtype2->name, segtype->name)) { | ||||
| 					log_error("Duplicate segment type %s: " | ||||
| 						  "unloading shared library %s", | ||||
| 						  segtype->name, cv->v.str); | ||||
| 					list_del(&segtype->list); | ||||
| 					segtype->ops->destroy(segtype); | ||||
| 					dlclose(lib); | ||||
| 					break; | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| 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; | ||||
| 	} | ||||
|  | ||||
| 	if (!(cmd->kernel_vsn = pool_strdup(cmd->libmem, uts.release))) { | ||||
| 		log_error("_init_hostname: pool_strdup kernel_vsn failed"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /* Entry point */ | ||||
| struct cmd_context *create_toolcontext(struct arg *the_args) | ||||
| { | ||||
| @@ -425,6 +800,10 @@ struct cmd_context *create_toolcontext(struct arg *the_args) | ||||
| 	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)))) { | ||||
| @@ -433,7 +812,11 @@ struct cmd_context *create_toolcontext(struct arg *the_args) | ||||
| 	} | ||||
| 	memset(cmd, 0, sizeof(*cmd)); | ||||
| 	cmd->args = the_args; | ||||
| 	cmd->hosttags = 0; | ||||
| 	list_init(&cmd->formats); | ||||
| 	list_init(&cmd->segtypes); | ||||
| 	list_init(&cmd->tags); | ||||
| 	list_init(&cmd->config_files); | ||||
|  | ||||
| 	strcpy(cmd->sys_dir, DEFAULT_SYS_DIR); | ||||
|  | ||||
| @@ -444,11 +827,28 @@ struct cmd_context *create_toolcontext(struct arg *the_args) | ||||
| 	if (*cmd->sys_dir && !create_dir(cmd->sys_dir)) | ||||
| 		goto error; | ||||
|  | ||||
| 	if (!_init_config(cmd)) | ||||
| 	if (!(cmd->libmem = pool_create(4 * 1024))) { | ||||
| 		log_error("Library memory pool creation failed"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!_init_lvm_conf(cmd)) | ||||
| 		goto error; | ||||
|  | ||||
| 	_init_logging(cmd); | ||||
|  | ||||
| 	if (!_init_hostname(cmd)) | ||||
| 		goto error; | ||||
|  | ||||
| 	if (!_init_tags(cmd, cmd->cft)) | ||||
| 		goto error; | ||||
|  | ||||
| 	if (!_init_tag_configs(cmd)) | ||||
| 		goto error; | ||||
|  | ||||
| 	if (!_merge_config_files(cmd)) | ||||
| 		goto error; | ||||
|  | ||||
| 	if (!_process_config(cmd)) | ||||
| 		goto error; | ||||
|  | ||||
| @@ -468,8 +868,12 @@ struct cmd_context *create_toolcontext(struct arg *the_args) | ||||
| 	if (!_init_formats(cmd)) | ||||
| 		goto error; | ||||
|  | ||||
| 	if (!_init_segtypes(cmd)) | ||||
| 		goto error; | ||||
|  | ||||
| 	cmd->current_settings = cmd->default_settings; | ||||
|  | ||||
| 	cmd->config_valid = 1; | ||||
| 	return cmd; | ||||
|  | ||||
|       error: | ||||
| @@ -495,6 +899,83 @@ static void _destroy_formats(struct list *formats) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void _destroy_segtypes(struct list *segtypes) | ||||
| { | ||||
| 	struct list *sgtl, *tmp; | ||||
| 	struct segment_type *segtype; | ||||
| 	void *lib; | ||||
|  | ||||
| 	list_iterate_safe(sgtl, tmp, segtypes) { | ||||
| 		segtype = list_item(sgtl, struct segment_type); | ||||
| 		list_del(&segtype->list); | ||||
| 		lib = segtype->library; | ||||
| 		segtype->ops->destroy(segtype); | ||||
| #ifdef HAVE_LIBDL | ||||
| 		if (lib) | ||||
| 			dlclose(lib); | ||||
| #endif | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int refresh_toolcontext(struct cmd_context *cmd) | ||||
| { | ||||
| 	log_verbose("Reloading config files"); | ||||
|  | ||||
| 	if (cmd->config_valid) { | ||||
| 		if (cmd->dump_filter) | ||||
| 			persistent_filter_dump(cmd->filter); | ||||
| 	} | ||||
|  | ||||
| 	activation_exit(); | ||||
| 	lvmcache_destroy(); | ||||
| 	label_exit(); | ||||
| 	_destroy_segtypes(&cmd->segtypes); | ||||
| 	_destroy_formats(&cmd->formats); | ||||
| 	if (cmd->filter) { | ||||
| 		cmd->filter->destroy(cmd->filter); | ||||
| 		cmd->filter = NULL; | ||||
| 	} | ||||
| 	dev_cache_exit(); | ||||
| 	_destroy_tags(cmd); | ||||
| 	_destroy_tag_configs(cmd); | ||||
|  | ||||
| 	cmd->config_valid = 0; | ||||
|  | ||||
| 	cmd->hosttags = 0; | ||||
|  | ||||
| 	if (!_init_lvm_conf(cmd)) | ||||
| 		return 0; | ||||
|  | ||||
| 	_init_logging(cmd); | ||||
|  | ||||
| 	if (!_init_tags(cmd, cmd->cft)) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (!_init_tag_configs(cmd)) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (!_merge_config_files(cmd)) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (!_process_config(cmd)) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (!_init_dev_cache(cmd)) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (!_init_filters(cmd)) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (!_init_formats(cmd)) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (!_init_segtypes(cmd)) | ||||
| 		return 0; | ||||
|  | ||||
| 	cmd->config_valid = 1; | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| void destroy_toolcontext(struct cmd_context *cmd) | ||||
| { | ||||
| 	if (cmd->dump_filter) | ||||
| @@ -503,11 +984,14 @@ void destroy_toolcontext(struct cmd_context *cmd) | ||||
| 	activation_exit(); | ||||
| 	lvmcache_destroy(); | ||||
| 	label_exit(); | ||||
| 	_destroy_segtypes(&cmd->segtypes); | ||||
| 	_destroy_formats(&cmd->formats); | ||||
| 	cmd->filter->destroy(cmd->filter); | ||||
| 	pool_destroy(cmd->mem); | ||||
| 	dev_cache_exit(); | ||||
| 	destroy_config_tree(cmd->cf); | ||||
| 	_destroy_tags(cmd); | ||||
| 	_destroy_tag_configs(cmd); | ||||
| 	pool_destroy(cmd->libmem); | ||||
| 	dbg_free(cmd); | ||||
|  | ||||
| 	release_log_memory(); | ||||
|   | ||||
| @@ -1,17 +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_TOOLCONTEXT_H | ||||
| #define _LVM_TOOLCONTEXT_H | ||||
|  | ||||
| #include "dev-cache.h" | ||||
| #include "config.h" | ||||
| #include "pool.h" | ||||
| #include "metadata.h" | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <limits.h> | ||||
| @@ -39,16 +45,21 @@ struct config_info { | ||||
| 	mode_t umask; | ||||
| }; | ||||
|  | ||||
| struct config_tree; | ||||
|  | ||||
| /* 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 */ | ||||
| 	struct list segtypes;	/* Available segment types */ | ||||
| 	const char *hostname; | ||||
| 	const char *kernel_vsn; | ||||
|  | ||||
| 	char *cmd_line; | ||||
| 	struct command *command; | ||||
| @@ -58,10 +69,16 @@ struct cmd_context { | ||||
| 	struct dev_filter *filter; | ||||
| 	int dump_filter;	/* Dump filter when exiting? */ | ||||
|  | ||||
| 	struct config_tree *cf; | ||||
| 	struct list config_files; | ||||
| 	int config_valid; | ||||
| 	struct config_tree *cft; | ||||
| 	struct config_info default_settings; | ||||
| 	struct config_info current_settings; | ||||
|  | ||||
| 	/* List of defined tags */ | ||||
| 	struct list tags; | ||||
| 	int hosttags; | ||||
|  | ||||
| 	char sys_dir[PATH_MAX]; | ||||
| 	char dev_dir[PATH_MAX]; | ||||
| 	char proc_dir[PATH_MAX]; | ||||
| @@ -69,5 +86,7 @@ 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); | ||||
| int config_files_changed(struct cmd_context *cmd); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -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,8 @@ | ||||
| #include "crc.h" | ||||
| #include "pool.h" | ||||
| #include "device.h" | ||||
| #include "str_list.h" | ||||
| #include "toolcontext.h" | ||||
|  | ||||
| #include <sys/stat.h> | ||||
| #include <sys/mman.h> | ||||
| @@ -43,10 +54,11 @@ struct parser { | ||||
| }; | ||||
|  | ||||
| struct cs { | ||||
| 	struct config_tree cf; | ||||
| 	struct config_tree cft; | ||||
| 	struct pool *mem; | ||||
| 	time_t timestamp; | ||||
| 	char *filename; | ||||
| 	int exists; | ||||
| }; | ||||
|  | ||||
| static void _get_token(struct parser *p, int tok_prev); | ||||
| @@ -60,6 +72,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 {\ | ||||
| @@ -82,7 +96,7 @@ static int _tok_match(const char *str, const char *b, const char *e) | ||||
| /* | ||||
|  * public interface | ||||
|  */ | ||||
| struct config_tree *create_config_tree(void) | ||||
| struct config_tree *create_config_tree(const char *filename) | ||||
| { | ||||
| 	struct cs *c; | ||||
| 	struct pool *mem = pool_create(10 * 1024); | ||||
| @@ -92,29 +106,31 @@ struct config_tree *create_config_tree(void) | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!(c = pool_alloc(mem, sizeof(*c)))) { | ||||
| 	if (!(c = pool_zalloc(mem, sizeof(*c)))) { | ||||
| 		stack; | ||||
| 		pool_destroy(mem); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	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; | ||||
| 	c->exists = 0; | ||||
| 	if (filename) | ||||
| 		c->filename = pool_strdup(c->mem, filename); | ||||
| 	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, struct device *dev, | ||||
| 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; | ||||
| 	int r = 0; | ||||
| 	int use_mmap = 1; | ||||
| @@ -172,7 +188,7 @@ int read_config_fd(struct config_tree *cf, struct device *dev, | ||||
| 	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; | ||||
| 	} | ||||
| @@ -193,99 +209,30 @@ int read_config_fd(struct config_tree *cf, struct device *dev, | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| int read_config_file(struct config_tree *cf, const char *file) | ||||
| int read_config_file(struct config_tree *cft) | ||||
| { | ||||
| 	struct cs *c = (struct cs *) cf; | ||||
| 	struct cs *c = (struct cs *) cft; | ||||
| 	struct stat info; | ||||
| 	struct device *dev; | ||||
| 	int r = 1; | ||||
|  | ||||
| 	if (stat(file, &info)) { | ||||
| 		log_sys_error("stat", file); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!S_ISREG(info.st_mode)) { | ||||
| 		log_error("%s is not a regular file", file); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (info.st_size == 0) { | ||||
| 		log_verbose("%s is empty", file); | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	if (!(dev = dev_create_file(file, NULL, NULL))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!dev_open_flags(dev, O_RDONLY, 0, 0)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	r = read_config_fd(cf, dev, 0, (size_t) info.st_size, 0, 0, | ||||
| 			   (checksum_fn_t) NULL, 0); | ||||
|  | ||||
| 	dev_close(dev); | ||||
|  | ||||
| 	c->timestamp = info.st_mtime; | ||||
| 	c->filename = pool_strdup(c->mem, file); | ||||
|  | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| time_t config_file_timestamp(struct config_tree *cf) | ||||
| { | ||||
| 	struct cs *c = (struct cs *) cf; | ||||
|  | ||||
| 	return c->timestamp; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Returns 1 if config file reloaded | ||||
|  */ | ||||
| int reload_config_file(struct config_tree **cf) | ||||
| { | ||||
| 	struct config_tree *new_cf; | ||||
| 	struct cs *c = (struct cs *) *cf; | ||||
| 	struct cs *new_cs; | ||||
| 	struct stat info; | ||||
| 	struct device *dev; | ||||
| 	int r; | ||||
|  | ||||
| 	if (!c->filename) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (stat(c->filename, &info) == -1) { | ||||
| 		if (errno == ENOENT) | ||||
| 			return 1; | ||||
| 	if (stat(c->filename, &info)) { | ||||
| 		log_sys_error("stat", c->filename); | ||||
| 		log_error("Failed to reload configuration file"); | ||||
| 		c->exists = 0; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!S_ISREG(info.st_mode)) { | ||||
| 		log_error("Configuration file %s is not a regular file", | ||||
| 			  c->filename); | ||||
| 		log_error("%s is not a regular file", c->filename); | ||||
| 		c->exists = 0; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	/* Unchanged? */ | ||||
| 	if (c->timestamp == info.st_mtime) | ||||
| 		return 0; | ||||
|  | ||||
| 	log_verbose("Detected config file change: Reloading %s", c->filename); | ||||
| 	c->exists = 1; | ||||
|  | ||||
| 	if (info.st_size == 0) { | ||||
| 		log_verbose("Config file reload: %s is empty", c->filename); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!(new_cf = create_config_tree())) { | ||||
| 		log_error("Allocation of new config_tree failed"); | ||||
| 		return 0; | ||||
| 		log_verbose("%s is empty", c->filename); | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	if (!(dev = dev_create_file(c->filename, NULL, NULL))) { | ||||
| @@ -298,22 +245,63 @@ int reload_config_file(struct config_tree **cf) | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	r = read_config_fd(new_cf, dev, 0, (size_t) info.st_size, | ||||
| 			   0, 0, (checksum_fn_t) NULL, 0); | ||||
| 	r = read_config_fd(cft, dev, 0, (size_t) info.st_size, 0, 0, | ||||
| 			   (checksum_fn_t) NULL, 0); | ||||
|  | ||||
| 	dev_close(dev); | ||||
|  | ||||
| 	if (r) { | ||||
| 		new_cs = (struct cs *) new_cf; | ||||
| 		new_cs->filename = pool_strdup(new_cs->mem, c->filename); | ||||
| 		new_cs->timestamp = info.st_mtime; | ||||
| 		destroy_config_tree(*cf); | ||||
| 		*cf = new_cf; | ||||
| 	} | ||||
| 	c->timestamp = info.st_mtime; | ||||
|  | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| time_t config_file_timestamp(struct config_tree *cft) | ||||
| { | ||||
| 	struct cs *c = (struct cs *) cft; | ||||
|  | ||||
| 	return c->timestamp; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Return 1 if config files ought to be reloaded | ||||
|  */ | ||||
| int config_file_changed(struct config_tree *cft) | ||||
| { | ||||
| 	struct cs *c = (struct cs *) cft; | ||||
| 	struct stat info; | ||||
|  | ||||
| 	if (!c->filename) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (stat(c->filename, &info) == -1) { | ||||
| 		/* Ignore a deleted config file: still use original data */ | ||||
| 		if (errno == ENOENT) { | ||||
| 			if (!c->exists) | ||||
| 				return 0; | ||||
| 			log_very_verbose("Config file %s has disappeared!", | ||||
| 					 c->filename); | ||||
| 			goto reload; | ||||
| 		} | ||||
| 		log_sys_error("stat", c->filename); | ||||
| 		log_error("Failed to reload configuration files"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!S_ISREG(info.st_mode)) { | ||||
| 		log_error("Configuration file %s is not a regular file", | ||||
| 			  c->filename); | ||||
| 		goto reload; | ||||
| 	} | ||||
|  | ||||
| 	/* Unchanged? */ | ||||
| 	if (c->timestamp == info.st_mtime) | ||||
| 		return 0; | ||||
|  | ||||
|       reload: | ||||
| 	log_verbose("Detected config file change to %s", c->filename); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static void _write_value(FILE *fp, struct config_value *v) | ||||
| { | ||||
| 	switch (v->type) { | ||||
| @@ -382,7 +370,7 @@ 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; | ||||
| @@ -396,7 +384,7 @@ int write_config_file(struct config_tree *cf, const char *file) | ||||
| 	} | ||||
|  | ||||
| 	log_verbose("Dumping configuration to %s", file); | ||||
| 	if (!_write_config(cf->root, fp, 0)) { | ||||
| 	if (!_write_config(cft->root, fp, 0)) { | ||||
| 		log_error("Failure while writing configuration"); | ||||
| 		r = 0; | ||||
| 	} | ||||
| @@ -728,8 +716,8 @@ 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(const struct config_node *cn, | ||||
| 				     const char *path) | ||||
| { | ||||
| 	const char *e; | ||||
|  | ||||
| @@ -757,13 +745,13 @@ struct config_node *find_config_node(struct config_node *cn, | ||||
| 		path = e; | ||||
| 	} | ||||
|  | ||||
| 	return cn; | ||||
| 	return (struct config_node *) cn; | ||||
| } | ||||
|  | ||||
| const char *find_config_str(struct config_node *cn, | ||||
| 			    const char *path, const int sep, const char *fail) | ||||
| const char *find_config_str(const struct config_node *cn, | ||||
| 			    const char *path, const char *fail) | ||||
| { | ||||
| 	struct config_node *n = find_config_node(cn, path, sep); | ||||
| 	const struct config_node *n = find_config_node(cn, path); | ||||
|  | ||||
| 	if (n && n->v->type == CFG_STRING) { | ||||
| 		if (*n->v->v.str) | ||||
| @@ -777,10 +765,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(const struct config_node *cn, const char *path, int fail) | ||||
| { | ||||
| 	struct config_node *n = find_config_node(cn, path, sep); | ||||
| 	const 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); | ||||
| @@ -792,10 +779,10 @@ 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(const struct config_node *cn, const char *path, | ||||
| 			float fail) | ||||
| { | ||||
| 	struct config_node *n = find_config_node(cn, path, sep); | ||||
| 	const 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); | ||||
| @@ -835,10 +822,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(const struct config_node *cn, const char *path, int fail) | ||||
| { | ||||
| 	struct config_node *n = find_config_node(cn, path, sep); | ||||
| 	const struct config_node *n = find_config_node(cn, path); | ||||
| 	struct config_value *v; | ||||
|  | ||||
| 	if (!n) | ||||
| @@ -857,12 +843,12 @@ int find_config_bool(struct config_node *cn, const char *path, | ||||
| 	return fail; | ||||
| } | ||||
|  | ||||
| int get_config_uint32(struct config_node *cn, const char *path, | ||||
| 		      const int sep, uint32_t *result) | ||||
| int get_config_uint32(const struct config_node *cn, const char *path, | ||||
| 		      uint32_t *result) | ||||
| { | ||||
| 	struct config_node *n; | ||||
| 	const 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; | ||||
| @@ -871,12 +857,12 @@ int get_config_uint32(struct config_node *cn, const char *path, | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int get_config_uint64(struct config_node *cn, const char *path, | ||||
| 		      const int sep, uint64_t *result) | ||||
| int get_config_uint64(const struct config_node *cn, const char *path, | ||||
| 		      uint64_t *result) | ||||
| { | ||||
| 	struct config_node *n; | ||||
| 	const 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; | ||||
| @@ -886,12 +872,12 @@ 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(const struct config_node *cn, const char *path, | ||||
| 		   char **result) | ||||
| { | ||||
| 	struct config_node *n; | ||||
| 	const 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; | ||||
| @@ -899,3 +885,115 @@ int get_config_str(struct config_node *cn, const char *path, | ||||
| 	*result = n->v->v.str; | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /* Insert cn2 after cn1 */ | ||||
| static void _insert_config_node(struct config_node **cn1, | ||||
| 				struct config_node *cn2) | ||||
| { | ||||
| 	if (!*cn1) { | ||||
| 		*cn1 = cn2; | ||||
| 		cn2->sib = NULL; | ||||
| 	} else { | ||||
| 		cn2->sib = (*cn1)->sib; | ||||
| 		(*cn1)->sib = cn2; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Merge section cn2 into section cn1 (which has the same name) | ||||
|  * overwriting any existing cn1 nodes with matching names. | ||||
|  */ | ||||
| static void _merge_section(struct config_node *cn1, struct config_node *cn2) | ||||
| { | ||||
| 	struct config_node *cn, *nextn, *oldn; | ||||
| 	struct config_value *cv; | ||||
|  | ||||
| 	for (cn = cn2->child; cn; cn = nextn) { | ||||
| 		nextn = cn->sib; | ||||
|  | ||||
| 		/* Skip "tags" */ | ||||
| 		if (!strcmp(cn->key, "tags")) | ||||
| 			continue; | ||||
|  | ||||
| 		/* Subsection? */ | ||||
| 		if (!cn->v) | ||||
| 			/* Ignore - we don't have any of these yet */ | ||||
| 			continue; | ||||
| 		/* Not already present? */ | ||||
| 		if (!(oldn = find_config_node(cn1->child, cn->key))) { | ||||
| 			_insert_config_node(&cn1->child, cn); | ||||
| 			continue; | ||||
| 		} | ||||
| 		/* Merge certain value lists */ | ||||
| 		if ((!strcmp(cn1->key, "activation") && | ||||
| 		     !strcmp(cn->key, "volume_list")) || | ||||
| 		    (!strcmp(cn1->key, "devices") && | ||||
| 		     (!strcmp(cn->key, "filter") || !strcmp(cn->key, "types")))) { | ||||
| 			cv = cn->v; | ||||
| 			while (cv->next) | ||||
| 				cv = cv->next; | ||||
| 			cv->next = oldn->v; | ||||
| 		} | ||||
|  | ||||
| 		/* Replace values */ | ||||
| 		oldn->v = cn->v; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int _match_host_tags(struct list *tags, struct config_node *tn) | ||||
| { | ||||
| 	struct config_value *tv; | ||||
| 	const char *str; | ||||
|  | ||||
| 	for (tv = tn->v; tv; tv = tv->next) { | ||||
| 		if (tv->type != CFG_STRING) | ||||
| 			continue; | ||||
| 		str = tv->v.str; | ||||
| 		if (*str == '@') | ||||
| 			str++; | ||||
| 		if (!*str) | ||||
| 			continue; | ||||
| 		if (str_list_match_item(tags, str)) | ||||
| 			return 1; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* Destructively merge a new config tree into an existing one */ | ||||
| int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft, | ||||
| 		      struct config_tree *newdata) | ||||
| { | ||||
| 	struct config_node *root = cft->root; | ||||
| 	struct config_node *cn, *nextn, *oldn, *tn, *cn2; | ||||
|  | ||||
| 	for (cn = newdata->root; cn; cn = nextn) { | ||||
| 		nextn = cn->sib; | ||||
| 		/* Ignore tags section */ | ||||
| 		if (!strcmp(cn->key, "tags")) | ||||
| 			continue; | ||||
| 		/* If there's a tags node, skip if host tags don't match */ | ||||
| 		if ((tn = find_config_node(cn->child, "tags"))) { | ||||
| 			if (!_match_host_tags(&cmd->tags, tn)) | ||||
| 				continue; | ||||
| 		} | ||||
| 		if (!(oldn = find_config_node(root, cn->key))) { | ||||
| 			_insert_config_node(&cft->root, cn); | ||||
| 			/* Remove any "tags" nodes */ | ||||
| 			for (cn2 = cn->child; cn2; cn2 = cn2->sib) { | ||||
| 				if (!strcmp(cn2->key, "tags")) { | ||||
| 					cn->child = cn2->sib; | ||||
| 					continue; | ||||
| 				} | ||||
| 				if (cn2->sib && !strcmp(cn2->sib->key, "tags")) { | ||||
| 					cn2->sib = cn2->sib->sib; | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 			continue; | ||||
| 		} | ||||
| 		_merge_section(oldn, cn); | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|   | ||||
| @@ -1,13 +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" | ||||
| struct device; | ||||
| struct cmd_context; | ||||
|  | ||||
| enum { | ||||
| 	CFG_STRING, | ||||
| @@ -36,46 +46,51 @@ struct config_tree { | ||||
| 	struct config_node *root; | ||||
| }; | ||||
|  | ||||
| struct config_tree *create_config_tree(void); | ||||
| void destroy_config_tree(struct config_tree *cf); | ||||
| struct config_tree_list { | ||||
| 	struct list list; | ||||
| 	struct config_tree *cft; | ||||
| }; | ||||
|  | ||||
| struct config_tree *create_config_tree(const char *filename); | ||||
| void destroy_config_tree(struct config_tree *cft); | ||||
|  | ||||
| typedef uint32_t (*checksum_fn_t) (uint32_t initial, void *buf, uint32_t size); | ||||
|  | ||||
| int read_config_fd(struct config_tree *cf, struct device *dev, | ||||
| 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); | ||||
|  | ||||
| int read_config_file(struct config_tree *cf, const char *file); | ||||
| int write_config_file(struct config_tree *cf, const char *file); | ||||
| int reload_config_file(struct config_tree **cf); | ||||
| time_t config_file_timestamp(struct config_tree *cf); | ||||
| int read_config_file(struct config_tree *cft); | ||||
| int write_config_file(struct config_tree *cft, const char *file); | ||||
| time_t config_file_timestamp(struct config_tree *cft); | ||||
| int config_file_changed(struct config_tree *cft); | ||||
| int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft, | ||||
| 		      struct config_tree *newdata); | ||||
|  | ||||
| struct config_node *find_config_node(struct config_node *cn, | ||||
| 				     const char *path, const int separator); | ||||
| struct config_node *find_config_node(const struct config_node *cn, | ||||
| 				     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(const 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(const 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(const 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(const 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); | ||||
| int get_config_uint32(const struct config_node *cn, const char *path, | ||||
| 		      uint32_t *result); | ||||
|  | ||||
| int get_config_uint64(struct config_node *cn, const char *path, | ||||
| 		      const int sep, uint64_t *result); | ||||
| int get_config_uint64(const struct config_node *cn, const char *path, | ||||
| 		      uint64_t *result); | ||||
|  | ||||
| int get_config_str(struct config_node *cn, const char *path, | ||||
| 		   const int sep, char **result); | ||||
| int get_config_str(const struct config_node *cn, const char *path, | ||||
| 		   char **result); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -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,12 +28,20 @@ | ||||
| #define DEFAULT_SYS_DIR "/etc/lvm" | ||||
| #define DEFAULT_DEV_DIR "/dev" | ||||
| #define DEFAULT_PROC_DIR "/proc" | ||||
| #define DEFAULT_SYSFS_SCAN 1 | ||||
| #define DEFAULT_MD_COMPONENT_DETECTION 1 | ||||
|  | ||||
| #define DEFAULT_LOCK_DIR "/var/lock/lvm" | ||||
| #define DEFAULT_LOCKING_LIB "lvm2_locking.so" | ||||
|  | ||||
| #define DEFAULT_UMASK 0077 | ||||
|  | ||||
| #ifdef LVM1_FALLBACK | ||||
| #  define DEFAULT_FALLBACK_TO_LVM1 1 | ||||
| #else | ||||
| #  define DEFAULT_FALLBACK_TO_LVM1 0 | ||||
| #endif | ||||
|  | ||||
| #ifdef LVM1_SUPPORT | ||||
| #  define DEFAULT_FORMAT "lvm1" | ||||
| #else | ||||
| @@ -50,6 +67,7 @@ | ||||
| #define DEFAULT_INDENT 1 | ||||
| #define DEFAULT_UNITS "h" | ||||
| #define DEFAULT_SUFFIX 1 | ||||
| #define DEFAULT_HOSTTAGS 0 | ||||
|  | ||||
| #ifdef DEVMAPPER_SUPPORT | ||||
| #  define DEFAULT_ACTIVATION 1 | ||||
| @@ -73,12 +91,12 @@ | ||||
| #define DEFAULT_REP_HEADINGS 1 | ||||
| #define DEFAULT_REP_SEPARATOR " " | ||||
|  | ||||
| #define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,move_percent" | ||||
| #define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,copy_percent" | ||||
| #define DEFAULT_VGS_COLS "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free" | ||||
| #define DEFAULT_PVS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free" | ||||
| #define DEFAULT_SEGS_COLS "lv_name,vg_name,lv_attr,stripes,segtype,seg_size" | ||||
|  | ||||
| #define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,origin,snap_percent,move_pv,move_percent,lv_uuid" | ||||
| #define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,origin,snap_percent,move_pv,copy_percent,lv_uuid" | ||||
| #define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid" | ||||
| #define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pv_uuid" | ||||
| #define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize" | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -1,7 +1,16 @@ | ||||
| /* | ||||
|  * Copyright (C) 2003 Sistina Software | ||||
|  * 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" | ||||
| @@ -57,6 +66,25 @@ int str_list_del(struct list *sll, const char *str) | ||||
| 	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; | ||||
| @@ -68,6 +96,9 @@ int str_list_match_item(struct list *sll, const char *str) | ||||
| 	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; | ||||
| @@ -78,3 +109,20 @@ int str_list_match_list(struct list *sll, struct list *sll2) | ||||
|  | ||||
| 	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; | ||||
| } | ||||
|   | ||||
| @@ -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 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_STR_LIST_H | ||||
| @@ -14,5 +23,7 @@ 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 | ||||
|   | ||||
| @@ -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" | ||||
| @@ -313,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); | ||||
|  | ||||
| @@ -471,7 +491,7 @@ const char *dev_name_confirmed(struct device *dev, int quiet) | ||||
| 		} | ||||
| 		if (quiet) | ||||
| 			log_debug("Path %s no longer valid for device(%d,%d)", | ||||
| 			  	  name, (int) MAJOR(dev->dev), | ||||
| 				  name, (int) MAJOR(dev->dev), | ||||
| 				  (int) MINOR(dev->dev)); | ||||
| 		else | ||||
| 			log_error("Path %s no longer valid for device(%d,%d)", | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 "metadata.h" | ||||
| #include "lvmcache.h" | ||||
| #include "memlock.h" | ||||
| #include "locking.h" | ||||
|  | ||||
| #include <limits.h> | ||||
| #include <sys/stat.h> | ||||
| @@ -23,6 +33,9 @@ | ||||
| #  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 | ||||
| @@ -38,12 +51,6 @@ | ||||
| #  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); | ||||
|  | ||||
| /*----------------------------------------------------------------- | ||||
| @@ -326,14 +333,20 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) | ||||
|  | ||||
| int dev_open_quiet(struct device *dev) | ||||
| { | ||||
| 	/* FIXME Open O_RDONLY if vg read lock? */ | ||||
| 	return dev_open_flags(dev, O_RDWR, 1, 1); | ||||
| 	int flags; | ||||
|  | ||||
| 	flags = vg_write_lock_held() ? O_RDWR : O_RDONLY; | ||||
|  | ||||
| 	return dev_open_flags(dev, flags, 1, 1); | ||||
| } | ||||
|  | ||||
| int dev_open(struct device *dev) | ||||
| { | ||||
| 	/* FIXME Open O_RDONLY if vg read lock? */ | ||||
| 	return dev_open_flags(dev, O_RDWR, 1, 0); | ||||
| 	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) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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_DEVICE_H | ||||
|   | ||||
| @@ -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" | ||||
| @@ -23,6 +18,7 @@ | ||||
| #include "display.h" | ||||
| #include "activate.h" | ||||
| #include "toolcontext.h" | ||||
| #include "segtypes.h" | ||||
|  | ||||
| #define SIZE_BUF 128 | ||||
|  | ||||
| @@ -31,23 +27,13 @@ static struct { | ||||
| 	const char *str; | ||||
| } _policies[] = { | ||||
| 	{ | ||||
| 	ALLOC_NEXT_FREE, "next free"}, { | ||||
| 	ALLOC_CONTIGUOUS, "contiguous"}, { | ||||
| 	ALLOC_DEFAULT, "next free (default)"} | ||||
| }; | ||||
|  | ||||
| static struct { | ||||
| 	segment_type_t segtype; | ||||
| 	const char *str; | ||||
| } _segtypes[] = { | ||||
| 	{ | ||||
| 	SEG_STRIPED, "striped"}, { | ||||
| 	SEG_MIRRORED, "mirror"}, { | ||||
| 	SEG_SNAPSHOT, "snapshot"} | ||||
| 	ALLOC_NORMAL, "normal"}, { | ||||
| 	ALLOC_ANYWHERE, "anywhere"}, { | ||||
| 	ALLOC_INHERIT, "inherit"} | ||||
| }; | ||||
|  | ||||
| static int _num_policies = sizeof(_policies) / sizeof(*_policies); | ||||
| static int _num_segtypes = sizeof(_segtypes) / sizeof(*_segtypes); | ||||
|  | ||||
| uint64_t units_to_bytes(const char *units, char *unit_type) | ||||
| { | ||||
| @@ -129,17 +115,6 @@ const char *get_alloc_string(alloc_policy_t alloc) | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| const char *get_segtype_string(segment_type_t segtype) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0; i < _num_segtypes; i++) | ||||
| 		if (_segtypes[i].segtype == segtype) | ||||
| 			return _segtypes[i].str; | ||||
|  | ||||
| 	return "unknown"; | ||||
| } | ||||
|  | ||||
| alloc_policy_t get_alloc_from_string(const char *str) | ||||
| { | ||||
| 	int i; | ||||
| @@ -148,26 +123,19 @@ alloc_policy_t get_alloc_from_string(const char *str) | ||||
| 		if (!strcmp(_policies[i].str, str)) | ||||
| 			return _policies[i].alloc; | ||||
|  | ||||
| 	log_error("Unrecognised allocation policy - using default"); | ||||
| 	return ALLOC_DEFAULT; | ||||
| } | ||||
|  | ||||
| segment_type_t get_segtype_from_string(const char *str) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0; i < _num_segtypes; i++) | ||||
| 		if (!strcmp(_segtypes[i].str, str)) | ||||
| 			return _segtypes[i].segtype; | ||||
|  | ||||
| 	log_error("Unrecognised segment type - using default (striped)"); | ||||
| 	return SEG_STRIPED; | ||||
| 	/* Special case for old metadata */ | ||||
| 	if(!strcmp("next free", str)) | ||||
| 		return ALLOC_NORMAL; | ||||
|  | ||||
| 	log_error("Unrecognised allocation policy %s", str); | ||||
| 	return ALLOC_INVALID; | ||||
| } | ||||
|  | ||||
| /* Size supplied in sectors */ | ||||
| const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl) | ||||
| { | ||||
| 	int s; | ||||
| 	int suffix = 1; | ||||
| 	int suffix = 1, precision; | ||||
| 	uint64_t byte = UINT64_C(0); | ||||
| 	uint64_t units = UINT64_C(1024); | ||||
| 	char *size_buf = NULL; | ||||
| @@ -202,8 +170,9 @@ const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl) | ||||
|  | ||||
| 	if (s < 8) { | ||||
| 		byte = cmd->current_settings.unit_factor; | ||||
| 		size *= UINT64_C(1024); | ||||
| 		size *= UINT64_C(512); | ||||
| 	} else { | ||||
| 		size /= 2; | ||||
| 		suffix = 1; | ||||
| 		if (cmd->current_settings.unit_type == 'H') | ||||
| 			units = UINT64_C(1000); | ||||
| @@ -215,8 +184,18 @@ const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl) | ||||
| 			s++, byte /= units; | ||||
| 	} | ||||
|  | ||||
| 	snprintf(size_buf, SIZE_BUF - 1, "%.2f%s", (float) size / byte, | ||||
| 		 suffix ? size_str[s][sl] : ""); | ||||
| 	/* FIXME Make precision configurable */ | ||||
| 	switch(toupper((int) cmd->current_settings.unit_type)) { | ||||
| 	case 'B': | ||||
| 	case 'S': | ||||
| 		precision = 0; | ||||
| 		break; | ||||
| 	default: | ||||
| 		precision = 2; | ||||
| 	} | ||||
|  | ||||
| 	snprintf(size_buf, SIZE_BUF - 1, "%.*f%s", precision, | ||||
| 		 (double) size / byte, suffix ? size_str[s][sl] : ""); | ||||
|  | ||||
| 	return size_buf; | ||||
| } | ||||
| @@ -269,18 +248,18 @@ void pvdisplay_full(struct cmd_context *cmd, struct physical_volume *pv, | ||||
| 	log_print("VG Name               %s%s", pv->vg_name, | ||||
| 		  pv->status & EXPORTED_VG ? " (exported)" : ""); | ||||
|  | ||||
| 	size = display_size(cmd, (uint64_t) pv->size / 2, SIZE_SHORT); | ||||
| 	size = display_size(cmd, (uint64_t) pv->size, SIZE_SHORT); | ||||
| 	if (pv->pe_size && pv->pe_count) { | ||||
|  | ||||
| /******** FIXME display LVM on-disk data size | ||||
| 		size2 = display_size(pv->size / 2, SIZE_SHORT); | ||||
| 		size2 = display_size(pv->size, SIZE_SHORT); | ||||
| ********/ | ||||
|  | ||||
| 		log_print("PV Size               %s" " / not usable %s",	/*  [LVM: %s]", */ | ||||
| 			  size, display_size(cmd, | ||||
| 					     (pv->size - | ||||
| 					      pv->pe_count * pv->pe_size) / 2, | ||||
| 					     SIZE_SHORT)); | ||||
| 			  size, | ||||
| 			  display_size(cmd, (pv->size - | ||||
| 					     pv->pe_count * pv->pe_size), | ||||
| 				       SIZE_SHORT)); | ||||
|  | ||||
| 	} else | ||||
| 		log_print("PV Size               %s", size); | ||||
| @@ -391,8 +370,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv, | ||||
| 			snap_active = lv_snapshot_percent(snap->cow, | ||||
| 							  &snap_percent); | ||||
| 			if (!snap_active || snap_percent < 0 || | ||||
| 			    snap_percent >= 100) | ||||
| 				snap_active = 0; | ||||
| 			    snap_percent >= 100) snap_active = 0; | ||||
| 			log_print("                       %s%s/%s [%s]", | ||||
| 				  lv->vg->cmd->dev_dir, lv->vg->name, | ||||
| 				  snap->cow->name, | ||||
| @@ -424,7 +402,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv, | ||||
|  | ||||
| 	log_print("LV Size                %s", | ||||
| 		  display_size(cmd, | ||||
| 			       snap ? snap->origin->size / 2 : lv->size / 2, | ||||
| 			       snap ? snap->origin->size : lv->size, | ||||
| 			       SIZE_SHORT)); | ||||
|  | ||||
| 	log_print("Current LE             %u", | ||||
| @@ -445,11 +423,11 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv, | ||||
| 			snap_percent = 100; | ||||
|  | ||||
| 		log_print("Snapshot chunk size    %s", | ||||
| 			  display_size(cmd, (uint64_t) snap->chunk_size / 2, | ||||
| 			  display_size(cmd, (uint64_t) snap->chunk_size, | ||||
| 				       SIZE_SHORT)); | ||||
|  | ||||
| /* | ||||
| 	size = display_size(lv->size / 2, SIZE_SHORT); | ||||
| 	size = display_size(lv->size, SIZE_SHORT); | ||||
| 	sscanf(size, "%f", &fsize); | ||||
| 	fused = fsize * snap_percent / 100; | ||||
| */ | ||||
| @@ -483,7 +461,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void _display_stripe(struct lv_segment *seg, uint32_t s, const char *pre) | ||||
| void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre) | ||||
| { | ||||
| 	switch (seg->area[s].type) { | ||||
| 	case AREA_PV: | ||||
| @@ -511,52 +489,18 @@ static void _display_stripe(struct lv_segment *seg, uint32_t s, const char *pre) | ||||
|  | ||||
| int lvdisplay_segments(struct logical_volume *lv) | ||||
| { | ||||
| 	uint32_t s; | ||||
| 	struct list *segh; | ||||
| 	struct lv_segment *seg; | ||||
|  | ||||
| 	log_print("--- Segments ---"); | ||||
|  | ||||
| 	list_iterate(segh, &lv->segments) { | ||||
| 		seg = list_item(segh, struct lv_segment); | ||||
|  | ||||
| 	list_iterate_items(seg, &lv->segments) { | ||||
| 		log_print("Logical extent %u to %u:", | ||||
| 			  seg->le, seg->le + seg->len - 1); | ||||
|  | ||||
| 		if (seg->type == SEG_STRIPED && seg->area_count == 1) | ||||
| 			log_print("  Type\t\tlinear"); | ||||
| 		else | ||||
| 			log_print("  Type\t\t%s", | ||||
| 				  get_segtype_string(seg->type)); | ||||
| 		log_print("  Type\t\t%s", seg->segtype->ops->name(seg)); | ||||
|  | ||||
| 		switch (seg->type) { | ||||
| 		case SEG_STRIPED: | ||||
| 			if (seg->area_count == 1) | ||||
| 				_display_stripe(seg, 0, "  "); | ||||
| 			else { | ||||
| 				log_print("  Stripes\t\t%u", seg->area_count); | ||||
| 				log_print("  Stripe size\t\t%u KB", | ||||
| 					  seg->stripe_size / 2); | ||||
|  | ||||
| 				for (s = 0; s < seg->area_count; s++) { | ||||
| 					log_print("  Stripe %d:", s); | ||||
| 					_display_stripe(seg, s, "    "); | ||||
| 				} | ||||
| 			} | ||||
| 			log_print(" "); | ||||
| 			break; | ||||
| 		case SEG_SNAPSHOT: | ||||
| 			break; | ||||
| 		case SEG_MIRRORED: | ||||
| 			log_print("  Mirrors\t\t%u", seg->area_count); | ||||
| 			log_print("  Mirror size\t\t%u", seg->area_len); | ||||
| 			log_print("  Mirror original:"); | ||||
| 			_display_stripe(seg, 0, "    "); | ||||
| 			log_print("  Mirror destination:"); | ||||
| 			_display_stripe(seg, 1, "    "); | ||||
| 			log_print(" "); | ||||
| 			break; | ||||
| 		} | ||||
| 		if (seg->segtype->ops->display) | ||||
| 			seg->segtype->ops->display(seg); | ||||
| 	} | ||||
|  | ||||
| 	log_print(" "); | ||||
| @@ -610,7 +554,7 @@ void vgdisplay_full(struct volume_group *vg) | ||||
| 	log_print("Open LV               %u", lvs_in_vg_opened(vg)); | ||||
| /****** FIXME Max LV Size | ||||
|       log_print ( "MAX LV Size           %s", | ||||
|                ( s1 = display_size ( LVM_LV_SIZE_MAX(vg) / 2, SIZE_SHORT))); | ||||
|                ( s1 = display_size ( LVM_LV_SIZE_MAX(vg), SIZE_SHORT))); | ||||
|       free ( s1); | ||||
| *********/ | ||||
| 	log_print("Max PV                %u", vg->max_pv); | ||||
| @@ -619,32 +563,25 @@ void vgdisplay_full(struct volume_group *vg) | ||||
|  | ||||
| 	log_print("VG Size               %s", | ||||
| 		  display_size(vg->cmd, | ||||
| 			       (uint64_t) vg->extent_count * (vg->extent_size / | ||||
| 							      2), SIZE_SHORT)); | ||||
| 			       (uint64_t) vg->extent_count * vg->extent_size, | ||||
| 			       SIZE_SHORT)); | ||||
|  | ||||
| 	log_print("PE Size               %s", | ||||
| 		  display_size(vg->cmd, (uint64_t) vg->extent_size / 2, | ||||
| 		  display_size(vg->cmd, (uint64_t) vg->extent_size, | ||||
| 			       SIZE_SHORT)); | ||||
|  | ||||
| 	log_print("Total PE              %u", vg->extent_count); | ||||
|  | ||||
| 	log_print("Alloc PE / Size       %u / %s", | ||||
| 		  vg->extent_count - vg->free_count, display_size(vg->cmd, | ||||
| 								  ((uint64_t) | ||||
| 								   vg-> | ||||
| 								   extent_count | ||||
| 								   - | ||||
| 								   vg-> | ||||
| 								   free_count) * | ||||
| 								  (vg-> | ||||
| 								   extent_size / | ||||
| 								   2), | ||||
| 								  SIZE_SHORT)); | ||||
| 		  vg->extent_count - vg->free_count, | ||||
| 		  display_size(vg->cmd, | ||||
| 			       ((uint64_t) vg->extent_count - vg->free_count) * | ||||
| 			       vg->extent_size, SIZE_SHORT)); | ||||
|  | ||||
| 	log_print("Free  PE / Size       %u / %s", vg->free_count, | ||||
| 		  display_size(vg->cmd, | ||||
| 			       (uint64_t) vg->free_count * (vg->extent_size / | ||||
| 							    2), SIZE_SHORT)); | ||||
| 			       (uint64_t) vg->free_count * vg->extent_size, | ||||
| 			       SIZE_SHORT)); | ||||
|  | ||||
| 	if (!id_write_format(&vg->id, uuid, sizeof(uuid))) { | ||||
| 		stack; | ||||
| @@ -659,6 +596,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; | ||||
| } | ||||
|  | ||||
| @@ -666,15 +650,15 @@ void vgdisplay_short(struct volume_group *vg) | ||||
| { | ||||
| 	log_print("\"%s\" %-9s [%-9s used / %s free]", vg->name, | ||||
| /********* FIXME if "open" print "/used" else print "/idle"???  ******/ | ||||
| 		  display_size(vg->cmd, (uint64_t) vg->extent_count * | ||||
| 			       vg->extent_size / 2, SIZE_SHORT), | ||||
| 		  display_size(vg->cmd, | ||||
| 			       (uint64_t) vg->extent_count * vg->extent_size, | ||||
| 			       SIZE_SHORT), | ||||
| 		  display_size(vg->cmd, | ||||
| 			       ((uint64_t) vg->extent_count - | ||||
| 				vg->free_count) * vg->extent_size / 2, | ||||
| 			       SIZE_SHORT), display_size(vg->cmd, | ||||
| 							 (uint64_t) vg-> | ||||
| 							 free_count * | ||||
| 							 vg->extent_size / 2, | ||||
| 							 SIZE_SHORT)); | ||||
| 				vg->free_count) * vg->extent_size, | ||||
| 			       SIZE_SHORT), | ||||
| 		  display_size(vg->cmd, | ||||
| 			       (uint64_t) vg->free_count * vg->extent_size, | ||||
| 			       SIZE_SHORT)); | ||||
| 	return; | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
| @@ -32,6 +27,7 @@ uint64_t units_to_bytes(const char *units, char *unit_type); | ||||
| /* Specify size in KB */ | ||||
| const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl); | ||||
| char *display_uuid(char *uuidstr); | ||||
| void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre); | ||||
|  | ||||
| void pvdisplay_colons(struct physical_volume *pv); | ||||
| void pvdisplay_full(struct cmd_context *cmd, struct physical_volume *pv, | ||||
| @@ -55,10 +51,4 @@ void vgdisplay_short(struct volume_group *vg); | ||||
| const char *get_alloc_string(alloc_policy_t alloc); | ||||
| alloc_policy_t get_alloc_from_string(const char *str); | ||||
|  | ||||
| /* | ||||
|  * Segment type display conversion routines. | ||||
|  */ | ||||
| segment_type_t get_segtype_from_string(const char *str); | ||||
| const char *get_segtype_string(segment_type_t segtype); | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										101
									
								
								lib/error/errseg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								lib/error/errseg.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| /* | ||||
|  * 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 "pool.h" | ||||
| #include "list.h" | ||||
| #include "toolcontext.h" | ||||
| #include "segtypes.h" | ||||
| #include "display.h" | ||||
| #include "text_export.h" | ||||
| #include "text_import.h" | ||||
| #include "config.h" | ||||
| #include "str_list.h" | ||||
| #include "targets.h" | ||||
| #include "lvm-string.h" | ||||
| #include "activate.h" | ||||
|  | ||||
| static const char *_name(const struct lv_segment *seg) | ||||
| { | ||||
| 	return seg->segtype->name; | ||||
| } | ||||
|  | ||||
| static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2) | ||||
| { | ||||
| 	seg1->len += seg2->len; | ||||
| 	seg1->area_len += seg2->area_len; | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| #ifdef DEVMAPPER_SUPPORT | ||||
| static int _compose_target_line(struct dev_manager *dm, struct pool *mem, | ||||
| 				struct config_tree *cft, void **target_state, | ||||
| 				struct lv_segment *seg, char *params, | ||||
| 				size_t paramsize, const char **target, int *pos, | ||||
| 				uint32_t *pvmove_mirror_count) | ||||
| { | ||||
| 	/*   error */ | ||||
|  | ||||
| 	*target = "error"; | ||||
| 	*params = '\0'; | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _target_present(void) | ||||
| { | ||||
| 	static int checked = 0; | ||||
| 	static int present = 0; | ||||
|  | ||||
| 	if (!checked) | ||||
| 		present = target_present("error"); | ||||
|  | ||||
| 	checked = 1; | ||||
| 	return present; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static void _destroy(const struct segment_type *segtype) | ||||
| { | ||||
| 	dbg_free((void *) segtype); | ||||
| } | ||||
|  | ||||
| static struct segtype_handler _error_ops = { | ||||
| 	name:_name, | ||||
| 	merge_segments:_merge_segments, | ||||
| #ifdef DEVMAPPER_SUPPORT | ||||
| 	compose_target_line:_compose_target_line, | ||||
| 	target_present:_target_present, | ||||
| #endif | ||||
| 	destroy:_destroy, | ||||
| }; | ||||
|  | ||||
| struct segment_type *init_error_segtype(struct cmd_context *cmd) | ||||
| { | ||||
| 	struct segment_type *segtype = dbg_malloc(sizeof(*segtype)); | ||||
|  | ||||
| 	if (!segtype) { | ||||
| 		stack; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	segtype->cmd = cmd; | ||||
| 	segtype->ops = &_error_ops; | ||||
| 	segtype->name = "error"; | ||||
| 	segtype->private = NULL; | ||||
| 	segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL; | ||||
|  | ||||
| 	return segtype; | ||||
| } | ||||
| @@ -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, *cft; | ||||
|  | ||||
| 	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 (!(cft = dbg_malloc(sizeof(*cft)))) { | ||||
| 		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; | ||||
| 	cft->passes_filter = _and_p; | ||||
| 	cft->destroy = _destroy; | ||||
| 	cft->private = filters_copy; | ||||
|  | ||||
| 	return cf; | ||||
| 	return cft; | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
							
								
								
									
										98
									
								
								lib/filters/filter-md.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								lib/filters/filter-md.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| /* | ||||
|  * Copyright (C) 2004 Luca Berra | ||||
|  * | ||||
|  * This file is part of LVM2. | ||||
|  * | ||||
|  * This copyrighted material is made available to anyone wishing to use, | ||||
|  * modify, copy, or redistribute it subject to the terms and conditions | ||||
|  * of the GNU Lesser General Public License v.2.1. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software Foundation, | ||||
|  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
|  | ||||
| #include "lib.h" | ||||
| #include "filter-md.h" | ||||
| #include "metadata.h" | ||||
|  | ||||
| #ifdef linux | ||||
|  | ||||
| /* Lifted from <linux/raid/md_p.h> because of difficulty including it */ | ||||
|  | ||||
| #define MD_SB_MAGIC 0xa92b4efc | ||||
| #define MD_RESERVED_BYTES (64 * 1024) | ||||
| #define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512) | ||||
| #define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) \ | ||||
| 				- MD_RESERVED_SECTORS) | ||||
|  | ||||
| static int _ignore_md(struct dev_filter *f, struct device *dev) | ||||
| { | ||||
| 	uint64_t size, sector; | ||||
| 	uint32_t md_magic; | ||||
|  | ||||
| 	if (!dev_get_size(dev, &size)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (size < MD_RESERVED_SECTORS * 2) | ||||
| 		/* | ||||
| 		 * We could ignore it since it is obviously too | ||||
| 		 * small, but that's not our job. | ||||
| 		 */ | ||||
| 		return 1; | ||||
|  | ||||
| 	if (!dev_open(dev)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	sector = MD_NEW_SIZE_SECTORS(size); | ||||
|  | ||||
| 	/* Check if it is an md component device. */ | ||||
| 	if (dev_read(dev, sector << SECTOR_SHIFT, sizeof(uint32_t), &md_magic)) { | ||||
| 		if (md_magic == MD_SB_MAGIC) { | ||||
| 			log_debug("%s: Skipping md component device", | ||||
| 				  dev_name(dev)); | ||||
| 			if (!dev_close(dev)) | ||||
| 				stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!dev_close(dev)) | ||||
| 		stack; | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static void _destroy(struct dev_filter *f) | ||||
| { | ||||
| 	dbg_free(f); | ||||
| } | ||||
|  | ||||
| struct dev_filter *md_filter_create(void) | ||||
| { | ||||
| 	struct dev_filter *f; | ||||
|  | ||||
| 	if (!(f = dbg_malloc(sizeof(*f)))) { | ||||
| 		log_error("md filter allocation failed"); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	f->passes_filter = _ignore_md; | ||||
| 	f->destroy = _destroy; | ||||
| 	f->private = NULL; | ||||
|  | ||||
| 	return f; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| struct dev_filter *md_filter_create(void) | ||||
| { | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										23
									
								
								lib/filters/filter-md.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								lib/filters/filter-md.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| /* | ||||
|  * Copyright (C) 2004 Luca Berra | ||||
|  * | ||||
|  * This file is part of LVM2. | ||||
|  * | ||||
|  * This copyrighted material is made available to anyone wishing to use, | ||||
|  * modify, copy, or redistribute it subject to the terms and conditions | ||||
|  * of the GNU Lesser General Public License v.2.1. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software Foundation, | ||||
|  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
|  | ||||
| #ifndef _LVM_FILTER_MD_H | ||||
| #define _LVM_FILTER_MD_H | ||||
|  | ||||
| #include "dev-cache.h" | ||||
|  | ||||
| struct dev_filter *md_filter_create(void); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| @@ -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; | ||||
| 	const 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(pf->file))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!read_config_file(cf, pf->file)) { | ||||
| 	if (!read_config_file(cft)) { | ||||
| 		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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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'; | ||||
|   | ||||
| @@ -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
									
								
							
							
						
						
									
										288
									
								
								lib/filters/filter-sysfs.c
									
									
									
									
									
										Normal 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[4], 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, 4, split) == 4 && | ||||
| 		    !strcmp(split[2], "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 | ||||
							
								
								
									
										23
									
								
								lib/filters/filter-sysfs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								lib/filters/filter-sysfs.h
									
									
									
									
									
										Normal 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 | ||||
| @@ -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" | ||||
| @@ -58,6 +53,8 @@ static const device_info_t device_info[] = { | ||||
| 	{"ubd", 16},		/* User-mode virtual block device */ | ||||
| 	{"ataraid", 16},	/* ATA Raid */ | ||||
| 	{"drbd", 16},		/* Distributed Replicated Block Device */ | ||||
| 	{"power2", 16},		/* EMC Powerpath */ | ||||
| 	{"i2o_block", 16},	/* i2o Block Disk */ | ||||
| 	{NULL, 0} | ||||
| }; | ||||
|  | ||||
| @@ -86,7 +83,7 @@ static int _passes_lvm_type_device_filter(struct dev_filter *f, | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int *_scan_proc_dev(const char *proc, struct config_node *cn) | ||||
| static int *_scan_proc_dev(const char *proc, const struct config_node *cn) | ||||
| { | ||||
| 	char line[80]; | ||||
| 	char proc_devices[PATH_MAX]; | ||||
| @@ -203,7 +200,7 @@ static int *_scan_proc_dev(const char *proc, struct config_node *cn) | ||||
| } | ||||
|  | ||||
| struct dev_filter *lvm_type_filter_create(const char *proc, | ||||
| 					  struct config_node *cn) | ||||
| 					  const struct config_node *cn) | ||||
| { | ||||
| 	struct dev_filter *f; | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| @@ -34,7 +29,7 @@ | ||||
| #endif | ||||
|  | ||||
| struct dev_filter *lvm_type_filter_create(const char *proc, | ||||
| 					  struct config_node *cn); | ||||
| 					  const struct config_node *cn); | ||||
|  | ||||
| void lvm_type_filter_destroy(struct dev_filter *f); | ||||
|  | ||||
|   | ||||
| @@ -1,7 +0,0 @@ | ||||
| Base {  | ||||
| 	global: | ||||
| 		init_format; | ||||
| 	local: | ||||
| 		*; | ||||
| }; | ||||
|  | ||||
							
								
								
									
										1
									
								
								lib/format1/.exported_symbols
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								lib/format1/.exported_symbols
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| init_format | ||||
| @@ -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 | ||||
| LIB_SHARED = liblvm2format1.so | ||||
|  | ||||
| include ../../make.tmpl | ||||
|  | ||||
| .PHONY: install | ||||
|  | ||||
| install: liblvm2format1.so | ||||
| 	$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \ | ||||
| 	$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \ | ||||
| 		$(libdir)/liblvm2format1.so.$(LIB_VERSION) | ||||
| 	$(LN_S) -f liblvm2format1.so.$(LIB_VERSION) $(libdir)/liblvm2format1.so | ||||
|  | ||||
| .PHONY: install | ||||
|  | ||||
|   | ||||
| @@ -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" | ||||
| @@ -108,6 +117,7 @@ static void _xlate_extents(struct pe_disk *extents, uint32_t count) | ||||
| static int _munge_formats(struct pv_disk *pvd) | ||||
| { | ||||
| 	uint32_t pe_start; | ||||
| 	int b, e; | ||||
|  | ||||
| 	switch (pvd->version) { | ||||
| 	case 1: | ||||
| @@ -125,17 +135,54 @@ static int _munge_formats(struct pv_disk *pvd) | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
|         /* UUID too long? */ | ||||
|         if (pvd->pv_uuid[ID_LEN]) { | ||||
| 		/* Retain ID_LEN chars from end */ | ||||
|                 for (e = ID_LEN; e < sizeof(pvd->pv_uuid); e++) { | ||||
|                         if (!pvd->pv_uuid[e]) { | ||||
|                                 e--; | ||||
|                                 break; | ||||
|                         } | ||||
|                 } | ||||
| 		for (b = 0; b < ID_LEN; b++) { | ||||
| 			pvd->pv_uuid[b] = pvd->pv_uuid[++e - ID_LEN]; | ||||
| 			/* FIXME Remove all invalid chars */ | ||||
| 			if (pvd->pv_uuid[b] == '/') | ||||
| 				pvd->pv_uuid[b] = '#'; | ||||
| 		} | ||||
| 		memset(&pvd->pv_uuid[ID_LEN], 0, sizeof(pvd->pv_uuid) - ID_LEN); | ||||
|         } | ||||
|  | ||||
| 	/* 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_pvd(struct device *dev, struct pv_disk *pvd) | ||||
| /*  | ||||
|  * If exported, remove "PV_EXP" from end of VG name  | ||||
|  */ | ||||
| static void _munge_exported_vg(struct pv_disk *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; | ||||
| 	} | ||||
| 	int l; | ||||
| 	size_t s; | ||||
|  | ||||
| 	/* Return if PV not in a VG */ | ||||
| 	if ((!*pvd->vg_name)) | ||||
| 		return; | ||||
| 	/* FIXME also check vgd->status & VG_EXPORTED? */ | ||||
|  | ||||
| 	l = strlen(pvd->vg_name); | ||||
| 	s = sizeof(EXPORTED_TAG); | ||||
| 	if (!strncmp(pvd->vg_name + l - s + 1, EXPORTED_TAG, s)) { | ||||
| 		pvd->vg_name[l - s + 1] = '\0'; | ||||
|                 pvd->pv_status |= VG_EXPORTED; | ||||
|         } | ||||
| } | ||||
|  | ||||
| int munge_pvd(struct device *dev, struct pv_disk *pvd) | ||||
| { | ||||
| 	_xlate_pvd(pvd); | ||||
|  | ||||
| 	if (pvd->id[0] != 'H' || pvd->id[1] != 'M') { | ||||
| @@ -150,9 +197,23 @@ static int _read_pvd(struct device *dev, struct pv_disk *pvd) | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	/* If VG is exported, set VG name back to the real name */ | ||||
| 	_munge_exported_vg(pvd); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _read_pvd(struct device *dev, struct pv_disk *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; | ||||
| 	} | ||||
|  | ||||
| 	return munge_pvd(dev, pvd); | ||||
| } | ||||
|  | ||||
| static int _read_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk) | ||||
| { | ||||
| 	if (!dev_read(dev, pos, sizeof(*disk), disk)) | ||||
| @@ -172,6 +233,13 @@ static int _read_vgd(struct disk_list *data) | ||||
|  | ||||
| 	_xlate_vgd(vgd); | ||||
|  | ||||
| 	if ((vgd->lv_max > MAX_LV) || (vgd->pv_max > MAX_PV)) | ||||
| 		fail; | ||||
| 		 | ||||
| 	/* If UUID is missing, create one */ | ||||
| 	if (vgd->vg_uuid[0] == '\0') | ||||
| 		uuid_from_num(vgd->vg_uuid, vgd->vg_number); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| @@ -252,26 +320,6 @@ static int _read_extents(struct disk_list *data) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /*  | ||||
|  * If exported, remove "PV_EXP" from end of VG name  | ||||
|  */ | ||||
| void munge_exported_vg(struct pv_disk *pvd) | ||||
| { | ||||
| 	int l; | ||||
| 	size_t s; | ||||
|  | ||||
| 	/* Return if PV not in a VG */ | ||||
| 	if ((!*pvd->vg_name)) | ||||
| 		return; | ||||
|  | ||||
| 	l = strlen(pvd->vg_name); | ||||
| 	s = sizeof(EXPORTED_TAG); | ||||
| 	if (!strncmp(pvd->vg_name + l - s + 1, EXPORTED_TAG, s)) { | ||||
| 		pvd->vg_name[l - s + 1] = '\0';  | ||||
| 		pvd->pv_status |= VG_EXPORTED; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static struct disk_list *__read_disk(const struct format_type *fmt, | ||||
| 				     struct device *dev, struct pool *mem, | ||||
| 				     const char *vg_name) | ||||
| @@ -295,9 +343,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->pvd); | ||||
|  | ||||
| 	if (!(info = lvmcache_add(fmt->labeller, dl->pvd.pv_uuid, dev, | ||||
| 				  dl->pvd.vg_name, NULL))) | ||||
| 		stack; | ||||
|   | ||||
| @@ -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,6 +19,7 @@ | ||||
| #include "lvm-types.h" | ||||
| #include "metadata.h" | ||||
| #include "pool.h" | ||||
| #include "toolcontext.h" | ||||
|  | ||||
| #define MAX_PV 256 | ||||
| #define MAX_LV 256 | ||||
| @@ -173,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 | ||||
| @@ -196,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, | ||||
| @@ -205,7 +216,7 @@ int export_vg(struct vg_disk *vgd, struct volume_group *vg); | ||||
|  | ||||
| int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd); | ||||
|  | ||||
| int import_extents(struct pool *mem, struct volume_group *vg, | ||||
| int import_extents(struct cmd_context *cmd, struct volume_group *vg, | ||||
| 		   struct list *pvds); | ||||
| int export_extents(struct disk_list *dl, uint32_t lv_num, | ||||
| 		   struct logical_volume *lv, struct physical_volume *pv); | ||||
| @@ -226,7 +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); | ||||
| int munge_pvd(struct device *dev, struct pv_disk *pvd); | ||||
|  | ||||
| /* blech */ | ||||
| int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter, | ||||
|   | ||||
| @@ -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" | ||||
| @@ -66,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; | ||||
| @@ -110,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; | ||||
| @@ -125,7 +164,7 @@ static struct volume_group *_build_vg(struct format_instance *fid, | ||||
| 	if (!import_lvs(mem, vg, pvs)) | ||||
| 		goto bad; | ||||
|  | ||||
| 	if (!import_extents(mem, vg, pvs)) | ||||
| 	if (!import_extents(fid->fmt->cmd, vg, pvs)) | ||||
| 		goto bad; | ||||
|  | ||||
| 	if (!import_snapshots(mem, vg, pvs)) | ||||
| @@ -172,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) | ||||
| { | ||||
| @@ -189,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)) { | ||||
| @@ -213,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; | ||||
| 		} | ||||
| @@ -305,7 +345,7 @@ static int _pv_setup(const struct format_type *fmt, | ||||
| 		pv->size--; | ||||
| 	if (pv->size > MAX_PV_SIZE) { | ||||
| 		log_error("Physical volumes cannot be bigger than %s", | ||||
| 			  display_size(fmt->cmd, (uint64_t) MAX_PV_SIZE / 2, | ||||
| 			  display_size(fmt->cmd, (uint64_t) MAX_PV_SIZE, | ||||
| 				       SIZE_SHORT)); | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -317,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"); | ||||
| @@ -348,7 +386,7 @@ static int _lv_setup(struct format_instance *fid, struct logical_volume *lv) | ||||
| 	} | ||||
| 	if (lv->size > max_size) { | ||||
| 		log_error("logical volumes cannot be larger than %s", | ||||
| 			  display_size(fid->fmt->cmd, max_size / 2, | ||||
| 			  display_size(fid->fmt->cmd, max_size, | ||||
| 				       SIZE_SHORT)); | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -394,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; | ||||
| 	} | ||||
| @@ -430,21 +468,18 @@ static int _vg_setup(struct format_instance *fid, struct volume_group *vg) | ||||
|  | ||||
| 	if (vg->extent_size > MAX_PE_SIZE || vg->extent_size < MIN_PE_SIZE) { | ||||
| 		log_error("Extent size must be between %s and %s", | ||||
| 			  display_size(fid->fmt->cmd, (uint64_t) MIN_PE_SIZE | ||||
| 				       / 2, | ||||
| 				       SIZE_SHORT), display_size(fid->fmt->cmd, | ||||
| 								 (uint64_t) | ||||
| 								 MAX_PE_SIZE | ||||
| 								 / 2, | ||||
| 								 SIZE_SHORT)); | ||||
| 			  display_size(fid->fmt->cmd, (uint64_t) MIN_PE_SIZE, | ||||
| 				       SIZE_SHORT), | ||||
| 			  display_size(fid->fmt->cmd, (uint64_t) MAX_PE_SIZE, | ||||
| 				       SIZE_SHORT)); | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (vg->extent_size % MIN_PE_SIZE) { | ||||
| 		log_error("Extent size must be multiple of %s", | ||||
| 			  display_size(fid->fmt->cmd, | ||||
| 				       (uint64_t) MIN_PE_SIZE / 2, SIZE_SHORT)); | ||||
| 			  display_size(fid->fmt->cmd, (uint64_t) MIN_PE_SIZE, | ||||
| 				       SIZE_SHORT)); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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,10 @@ | ||||
| #include "list.h" | ||||
| #include "lvm-string.h" | ||||
| #include "filter.h" | ||||
| #include "toolcontext.h" | ||||
| #include "segtypes.h" | ||||
|  | ||||
| #include <time.h> | ||||
| #include <sys/utsname.h> | ||||
|  | ||||
| static int _check_vg_name(const char *name) | ||||
| { | ||||
| @@ -56,9 +68,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 +88,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 +105,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 +137,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 +154,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 +162,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 +171,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); | ||||
|  | ||||
| @@ -228,6 +237,7 @@ int import_vg(struct pool *mem, | ||||
| 	vg->free_count = vgd->pe_total - vgd->pe_allocated; | ||||
| 	vg->max_lv = vgd->lv_max; | ||||
| 	vg->max_pv = vgd->pv_max; | ||||
| 	vg->alloc = ALLOC_NORMAL; | ||||
|  | ||||
| 	if (partial) | ||||
| 		vg->status |= PARTIAL_VG; | ||||
| @@ -307,13 +317,14 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd) | ||||
| 	if (lvd->lv_allocation & LV_CONTIGUOUS) | ||||
| 		lv->alloc = ALLOC_CONTIGUOUS; | ||||
| 	else | ||||
| 		lv->alloc = ALLOC_NEXT_FREE; | ||||
| 		lv->alloc = ALLOC_NORMAL; | ||||
|  | ||||
| 	lv->read_ahead = lvd->lv_read_ahead; | ||||
| 	lv->size = lvd->lv_size; | ||||
| 	lv->le_count = lvd->lv_allocated_le; | ||||
|  | ||||
| 	list_init(&lv->segments); | ||||
| 	list_init(&lv->tags); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
| @@ -371,9 +382,10 @@ int export_extents(struct disk_list *dl, uint32_t lv_num, | ||||
| 		seg = list_item(segh, struct lv_segment); | ||||
|  | ||||
| 		for (s = 0; s < seg->area_count; s++) { | ||||
| 			if (seg->type != SEG_STRIPED) { | ||||
| 				log_error("Non-striped segment type in LV %s: " | ||||
| 					  "unsupported by format1", lv->name); | ||||
| 			if (!(seg->segtype->flags & SEG_FORMAT1_SUPPORT)) { | ||||
| 				log_error("Segment type %s in LV %s: " | ||||
| 					  "unsupported by format1", | ||||
| 					  seg->segtype->name, lv->name); | ||||
| 				return 0; | ||||
| 			} | ||||
| 			if (seg->area[s].type != AREA_PV) { | ||||
|   | ||||
| @@ -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,6 +19,8 @@ | ||||
| #include "pool.h" | ||||
| #include "disk-rep.h" | ||||
| #include "lv_alloc.h" | ||||
| #include "display.h" | ||||
| #include "segtypes.h" | ||||
|  | ||||
| /* | ||||
|  * After much thought I have decided it is easier, | ||||
| @@ -192,21 +203,24 @@ static int _check_maps_are_complete(struct hash_table *maps) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _read_linear(struct pool *mem, struct lv_map *lvm) | ||||
| static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm) | ||||
| { | ||||
| 	uint32_t le = 0; | ||||
| 	struct lv_segment *seg; | ||||
|  | ||||
| 	while (le < lvm->lv->le_count) { | ||||
| 		seg = alloc_lv_segment(mem, 1); | ||||
| 		seg = alloc_lv_segment(cmd->mem, 1); | ||||
|  | ||||
| 		seg->lv = lvm->lv; | ||||
| 		seg->type = SEG_STRIPED; | ||||
| 		if (!(seg->segtype = get_segtype_from_string(cmd, "striped"))) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		seg->le = le; | ||||
| 		seg->len = 0; | ||||
| 		seg->area_len = 0; | ||||
| 		seg->stripe_size = 0; | ||||
| 		seg->area_count = 1; | ||||
|  | ||||
| 		seg->area[0].type = AREA_PV; | ||||
| 		seg->area[0].u.pv.pv = lvm->map[le].pv; | ||||
| @@ -242,13 +256,12 @@ static int _check_stripe(struct lv_map *lvm, struct lv_segment *seg, | ||||
| 		if ((lvm->map[le + st * len].pv != seg->area[st].u.pv.pv) || | ||||
| 		    (seg->area[st].u.pv.pv && | ||||
| 		     lvm->map[le + st * len].pe != | ||||
| 		     seg->area[st].u.pv.pe + seg->len)) | ||||
| 			return 0; | ||||
| 		     seg->area[st].u.pv.pe + seg->len)) return 0; | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _read_stripes(struct pool *mem, struct lv_map *lvm) | ||||
| static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm) | ||||
| { | ||||
| 	uint32_t st, le = 0, len; | ||||
| 	struct lv_segment *seg; | ||||
| @@ -264,15 +277,17 @@ static int _read_stripes(struct pool *mem, struct lv_map *lvm) | ||||
| 	len = lvm->lv->le_count / lvm->stripes; | ||||
|  | ||||
| 	while (le < len) { | ||||
| 		if (!(seg = alloc_lv_segment(mem, lvm->stripes))) { | ||||
| 		if (!(seg = alloc_lv_segment(cmd->mem, lvm->stripes))) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		seg->lv = lvm->lv; | ||||
| 		seg->type = SEG_STRIPED; | ||||
| 		if (!(seg->segtype = get_segtype_from_string(cmd, "striped"))) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| 		seg->stripe_size = lvm->stripe_size; | ||||
| 		seg->area_count = lvm->stripes; | ||||
| 		seg->le = seg->area_count * le; | ||||
| 		seg->len = 1; | ||||
| 		seg->area_len = 1; | ||||
| @@ -303,20 +318,20 @@ static int _read_stripes(struct pool *mem, struct lv_map *lvm) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _build_segments(struct pool *mem, struct lv_map *lvm) | ||||
| static int _build_segments(struct cmd_context *cmd, struct lv_map *lvm) | ||||
| { | ||||
| 	return (lvm->stripes > 1 ? _read_stripes(mem, lvm) : | ||||
| 		_read_linear(mem, lvm)); | ||||
| 	return (lvm->stripes > 1 ? _read_stripes(cmd, lvm) : | ||||
| 		_read_linear(cmd, lvm)); | ||||
| } | ||||
|  | ||||
| static int _build_all_segments(struct pool *mem, struct hash_table *maps) | ||||
| static int _build_all_segments(struct cmd_context *cmd, struct hash_table *maps) | ||||
| { | ||||
| 	struct hash_node *n; | ||||
| 	struct lv_map *lvm; | ||||
|  | ||||
| 	for (n = hash_get_first(maps); n; n = hash_get_next(maps, n)) { | ||||
| 		lvm = (struct lv_map *) hash_get_data(maps, n); | ||||
| 		if (!_build_segments(mem, lvm)) { | ||||
| 		if (!_build_segments(cmd, lvm)) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| @@ -325,7 +340,8 @@ static int _build_all_segments(struct pool *mem, struct hash_table *maps) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int import_extents(struct pool *mem, struct volume_group *vg, struct list *pvds) | ||||
| int import_extents(struct cmd_context *cmd, struct volume_group *vg, | ||||
| 		   struct list *pvds) | ||||
| { | ||||
| 	int r = 0; | ||||
| 	struct pool *scratch = pool_create(10 * 1024); | ||||
| @@ -351,7 +367,7 @@ int import_extents(struct pool *mem, struct volume_group *vg, struct list *pvds) | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	if (!_build_all_segments(mem, maps)) { | ||||
| 	if (!_build_all_segments(cmd, maps)) { | ||||
| 		log_err("Couldn't build extent segments."); | ||||
| 		goto out; | ||||
| 	} | ||||
|   | ||||
| @@ -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)) | ||||
|   | ||||
| @@ -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" | ||||
| @@ -51,7 +60,8 @@ static int _read(struct labeller *l, struct device *dev, char *buf, | ||||
| 	struct pv_disk *pvd = (struct pv_disk *) buf; | ||||
| 	struct lvmcache_info *info; | ||||
|  | ||||
| 	munge_exported_vg(pvd); | ||||
| 	munge_pvd(dev, pvd); | ||||
|  | ||||
| 	if (!(info = lvmcache_add(l, pvd->pv_uuid, dev, pvd->vg_name, NULL))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
							
								
								
									
										1
									
								
								lib/format_pool/.exported_symbols
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								lib/format_pool/.exported_symbols
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| init_format | ||||
							
								
								
									
										37
									
								
								lib/format_pool/Makefile.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/format_pool/Makefile.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| # | ||||
| # Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved. | ||||
| # Copyright (C) 2004 Red Hat, Inc. All rights reserved. | ||||
| # | ||||
| # 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 =\ | ||||
| 	disk_rep.c \ | ||||
| 	format_pool.c \ | ||||
| 	import_export.c \ | ||||
| 	pool_label.c | ||||
|  | ||||
| LIB_SHARED = liblvm2formatpool.so | ||||
|  | ||||
| include ../../make.tmpl | ||||
|  | ||||
| .PHONY: install | ||||
|  | ||||
| install: liblvm2formatpool.so | ||||
| 	$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \ | ||||
| 		$(libdir)/liblvm2formatpool.so.$(LIB_VERSION) | ||||
| 	$(LN_S) -f liblvm2formatpool.so.$(LIB_VERSION) \ | ||||
| 		$(libdir)/liblvm2formatpool.so | ||||
|  | ||||
|  | ||||
							
								
								
									
										385
									
								
								lib/format_pool/disk_rep.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										385
									
								
								lib/format_pool/disk_rep.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,385 @@ | ||||
| /* | ||||
|  * Copyright (C) 1997-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 "pool.h" | ||||
| #include "label.h" | ||||
| #include "metadata.h" | ||||
| #include "lvmcache.h" | ||||
| #include "filter.h" | ||||
| #include "list.h" | ||||
| #include "xlate.h" | ||||
|  | ||||
| #include "disk_rep.h" | ||||
|  | ||||
| /* FIXME: memcpy might not be portable */ | ||||
| #define CPIN_8(x, y, z) {memcpy((x), (y), (z));} | ||||
| #define CPOUT_8(x, y, z) {memcpy((y), (x), (z));} | ||||
| #define CPIN_16(x, y) {(x) = xlate16_be((y));} | ||||
| #define CPOUT_16(x, y) {(y) = xlate16_be((x));} | ||||
| #define CPIN_32(x, y) {(x) = xlate32_be((y));} | ||||
| #define CPOUT_32(x, y) {(y) = xlate32_be((x));} | ||||
| #define CPIN_64(x, y) {(x) = xlate64_be((y));} | ||||
| #define CPOUT_64(x, y) {(y) = xlate64_be((x));} | ||||
|  | ||||
| static int __read_pool_disk(const struct format_type *fmt, struct device *dev, | ||||
| 			    struct pool *mem, struct pool_list *pl, | ||||
| 			    const char *vg_name) | ||||
| { | ||||
| 	char buf[512]; | ||||
|  | ||||
| 	/* FIXME: Need to check the cache here first */ | ||||
| 	if (!dev_read(dev, UINT64_C(0), 512, buf)) { | ||||
| 		log_very_verbose("Failed to read PV data from %s", | ||||
| 				 dev_name(dev)); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!read_pool_label(pl, fmt->labeller, dev, buf, NULL)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static void _add_pl_to_list(struct list *head, struct pool_list *data) | ||||
| { | ||||
| 	struct list *pvdh; | ||||
| 	struct pool_list *pl; | ||||
|  | ||||
| 	list_iterate(pvdh, head) { | ||||
| 		pl = list_item(pvdh, struct pool_list); | ||||
|  | ||||
| 		if (id_equal(&data->pv_uuid, &pl->pv_uuid)) { | ||||
| 			char uuid[ID_LEN + 7]; | ||||
|  | ||||
| 			id_write_format(&pl->pv_uuid, uuid, ID_LEN + 7); | ||||
|  | ||||
| 			if (MAJOR(data->dev->dev) != md_major()) { | ||||
| 				log_very_verbose("Ignoring duplicate PV %s on " | ||||
| 						 "%s", uuid, | ||||
| 						 dev_name(data->dev)); | ||||
| 				return; | ||||
| 			} | ||||
| 			log_very_verbose("Duplicate PV %s - using md %s", | ||||
| 					 uuid, dev_name(data->dev)); | ||||
| 			list_del(pvdh); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	list_add(head, &data->list); | ||||
| } | ||||
|  | ||||
| int read_pool_label(struct pool_list *pl, struct labeller *l, | ||||
| 		    struct device *dev, char *buf, struct label **label) | ||||
| { | ||||
| 	struct lvmcache_info *info; | ||||
| 	struct id pvid; | ||||
| 	struct id vgid; | ||||
| 	char uuid[ID_LEN + 7]; | ||||
| 	struct pool_disk *pd = &pl->pd; | ||||
|  | ||||
| 	pool_label_in(pd, buf); | ||||
|  | ||||
| 	get_pool_pv_uuid(&pvid, pd); | ||||
| 	id_write_format(&pvid, uuid, ID_LEN + 7); | ||||
| 	log_debug("Calculated uuid %s for %s", uuid, dev_name(dev)); | ||||
|  | ||||
| 	get_pool_vg_uuid(&vgid, pd); | ||||
| 	id_write_format(&vgid, uuid, ID_LEN + 7); | ||||
| 	log_debug("Calculated uuid %s for %s", uuid, pd->pl_pool_name); | ||||
|  | ||||
| 	if (!(info = lvmcache_add(l, (char *) &pvid, dev, pd->pl_pool_name, | ||||
| 				  (char *) &vgid))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if (label) | ||||
| 		*label = info->label; | ||||
|  | ||||
| 	info->device_size = xlate32_be(pd->pl_blocks) << SECTOR_SHIFT; | ||||
| 	list_init(&info->mdas); | ||||
|  | ||||
| 	info->status &= ~CACHE_INVALID; | ||||
|  | ||||
| 	pl->dev = dev; | ||||
| 	pl->pv = NULL; | ||||
| 	memcpy(&pl->pv_uuid, &pvid, sizeof(pvid)); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * pool_label_out - copies a pool_label_t into a char buffer | ||||
|  * @pl: ptr to a pool_label_t struct | ||||
|  * @buf: ptr to raw space where label info will be copied | ||||
|  * | ||||
|  * This function is important because it takes care of all of | ||||
|  * the endian issues when copying to disk.  This way, when | ||||
|  * machines of different architectures are used, they will | ||||
|  * be able to interpret ondisk labels correctly.  Always use | ||||
|  * this function before writing to disk. | ||||
|  */ | ||||
| void pool_label_out(struct pool_disk *pl, char *buf) | ||||
| { | ||||
| 	struct pool_disk *bufpl = (struct pool_disk *) buf; | ||||
|  | ||||
| 	CPOUT_64(pl->pl_magic, bufpl->pl_magic); | ||||
| 	CPOUT_64(pl->pl_pool_id, bufpl->pl_pool_id); | ||||
| 	CPOUT_8(pl->pl_pool_name, bufpl->pl_pool_name, POOL_NAME_SIZE); | ||||
| 	CPOUT_32(pl->pl_version, bufpl->pl_version); | ||||
| 	CPOUT_32(pl->pl_subpools, bufpl->pl_subpools); | ||||
| 	CPOUT_32(pl->pl_sp_id, bufpl->pl_sp_id); | ||||
| 	CPOUT_32(pl->pl_sp_devs, bufpl->pl_sp_devs); | ||||
| 	CPOUT_32(pl->pl_sp_devid, bufpl->pl_sp_devid); | ||||
| 	CPOUT_32(pl->pl_sp_type, bufpl->pl_sp_type); | ||||
| 	CPOUT_64(pl->pl_blocks, bufpl->pl_blocks); | ||||
| 	CPOUT_32(pl->pl_striping, bufpl->pl_striping); | ||||
| 	CPOUT_32(pl->pl_sp_dmepdevs, bufpl->pl_sp_dmepdevs); | ||||
| 	CPOUT_32(pl->pl_sp_dmepid, bufpl->pl_sp_dmepid); | ||||
| 	CPOUT_32(pl->pl_sp_weight, bufpl->pl_sp_weight); | ||||
| 	CPOUT_32(pl->pl_minor, bufpl->pl_minor); | ||||
| 	CPOUT_32(pl->pl_padding, bufpl->pl_padding); | ||||
| 	CPOUT_8(pl->pl_reserve, bufpl->pl_reserve, 184); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * pool_label_in - copies a char buffer into a pool_label_t | ||||
|  * @pl: ptr to a pool_label_t struct | ||||
|  * @buf: ptr to raw space where label info is copied from | ||||
|  * | ||||
|  * This function is important because it takes care of all of | ||||
|  * the endian issues when information from disk is about to be | ||||
|  * used.  This way, when machines of different architectures | ||||
|  * are used, they will be able to interpret ondisk labels | ||||
|  * correctly.  Always use this function before using labels that | ||||
|  * were read from disk. | ||||
|  */ | ||||
| void pool_label_in(struct pool_disk *pl, char *buf) | ||||
| { | ||||
| 	struct pool_disk *bufpl = (struct pool_disk *) buf; | ||||
|  | ||||
| 	CPIN_64(pl->pl_magic, bufpl->pl_magic); | ||||
| 	CPIN_64(pl->pl_pool_id, bufpl->pl_pool_id); | ||||
| 	CPIN_8(pl->pl_pool_name, bufpl->pl_pool_name, POOL_NAME_SIZE); | ||||
| 	CPIN_32(pl->pl_version, bufpl->pl_version); | ||||
| 	CPIN_32(pl->pl_subpools, bufpl->pl_subpools); | ||||
| 	CPIN_32(pl->pl_sp_id, bufpl->pl_sp_id); | ||||
| 	CPIN_32(pl->pl_sp_devs, bufpl->pl_sp_devs); | ||||
| 	CPIN_32(pl->pl_sp_devid, bufpl->pl_sp_devid); | ||||
| 	CPIN_32(pl->pl_sp_type, bufpl->pl_sp_type); | ||||
| 	CPIN_64(pl->pl_blocks, bufpl->pl_blocks); | ||||
| 	CPIN_32(pl->pl_striping, bufpl->pl_striping); | ||||
| 	CPIN_32(pl->pl_sp_dmepdevs, bufpl->pl_sp_dmepdevs); | ||||
| 	CPIN_32(pl->pl_sp_dmepid, bufpl->pl_sp_dmepid); | ||||
| 	CPIN_32(pl->pl_sp_weight, bufpl->pl_sp_weight); | ||||
| 	CPIN_32(pl->pl_minor, bufpl->pl_minor); | ||||
| 	CPIN_32(pl->pl_padding, bufpl->pl_padding); | ||||
| 	CPIN_8(pl->pl_reserve, bufpl->pl_reserve, 184); | ||||
| } | ||||
|  | ||||
| static char _calc_char(unsigned int id) | ||||
| { | ||||
| 	/* | ||||
| 	 * [0-9A-Za-z!#] - 64 printable chars (6-bits) | ||||
| 	 */ | ||||
|  | ||||
| 	if (id < 10) | ||||
| 		return id + 48; | ||||
| 	if (id < 36) | ||||
| 		return (id - 10) + 65; | ||||
| 	if (id < 62) | ||||
| 		return (id - 36) + 97; | ||||
| 	if (id == 62) | ||||
| 		return '!'; | ||||
| 	if (id == 63) | ||||
| 		return '#'; | ||||
|  | ||||
| 	return '%'; | ||||
| } | ||||
|  | ||||
| void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid) | ||||
| { | ||||
| 	int i; | ||||
| 	unsigned shifter = 0x003F; | ||||
|  | ||||
| 	assert(ID_LEN == 32); | ||||
| 	memset(uuid, 0, ID_LEN); | ||||
| 	strcat(uuid, "POOL0000000000"); | ||||
|  | ||||
| 	/* We grab the entire 64 bits (+2 that get shifted in) */ | ||||
| 	for (i = 13; i < 24; i++) { | ||||
| 		uuid[i] = _calc_char(((unsigned) poolid) & shifter); | ||||
| 		poolid = poolid >> 6; | ||||
| 	} | ||||
|  | ||||
| 	/* We grab the entire 32 bits (+4 that get shifted in) */ | ||||
| 	for (i = 24; i < 30; i++) { | ||||
| 		uuid[i] = _calc_char((unsigned) (spid & shifter)); | ||||
| 		spid = spid >> 6; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * Since we can only have 128 devices, we only worry about the | ||||
| 	 * last 12 bits | ||||
| 	 */ | ||||
| 	for (i = 30; i < 32; i++) { | ||||
| 		uuid[i] = _calc_char((unsigned) (devid & shifter)); | ||||
| 		devid = devid >> 6; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| static int _read_vg_pds(const struct format_type *fmt, struct pool *mem, | ||||
| 			struct lvmcache_vginfo *vginfo, struct list *head, | ||||
| 			uint32_t *devcount) | ||||
| { | ||||
|  | ||||
| 	struct list *vgih = NULL; | ||||
| 	struct device *dev; | ||||
| 	struct pool_list *pl = NULL; | ||||
| 	struct pool *tmpmem = NULL; | ||||
|  | ||||
| 	uint32_t sp_count = 0; | ||||
| 	uint32_t *sp_devs = NULL; | ||||
| 	int i; | ||||
|  | ||||
| 	/* FIXME: maybe should return a different error in memory | ||||
| 	 * allocation failure */ | ||||
| 	if (!(tmpmem = pool_create(512))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	list_iterate(vgih, &vginfo->infos) { | ||||
| 		dev = list_item(vgih, struct lvmcache_info)->dev; | ||||
| 		if (dev && | ||||
| 		    !(pl = read_pool_disk(fmt, dev, mem, vginfo->vgname))) | ||||
| 			    break; | ||||
| 		/* | ||||
| 		 * We need to keep track of the total expected number | ||||
| 		 * of devices per subpool | ||||
| 		 */ | ||||
| 		if (!sp_count) { | ||||
| 			sp_count = pl->pd.pl_subpools; | ||||
| 			if (!(sp_devs = | ||||
| 			      pool_zalloc(tmpmem, | ||||
| 					  sizeof(uint32_t) * sp_count))) { | ||||
| 				log_error("Unable to allocate %d 32-bit uints", | ||||
| 					  sp_count); | ||||
| 				pool_destroy(tmpmem); | ||||
| 				return 0; | ||||
| 			} | ||||
| 		} | ||||
| 		/* | ||||
| 		 * watch out for a pool label with a different subpool | ||||
| 		 * count than the original - give up if it does | ||||
| 		 */ | ||||
| 		if (sp_count != pl->pd.pl_subpools) | ||||
| 			break; | ||||
|  | ||||
| 		_add_pl_to_list(head, pl); | ||||
|  | ||||
| 		if (sp_count > pl->pd.pl_sp_id && sp_devs[pl->pd.pl_sp_id] == 0) | ||||
| 			sp_devs[pl->pd.pl_sp_id] = pl->pd.pl_sp_devs; | ||||
| 	} | ||||
|  | ||||
| 	*devcount = 0; | ||||
| 	for (i = 0; i < sp_count; i++) { | ||||
| 		*devcount += sp_devs[i]; | ||||
| 	} | ||||
|  | ||||
| 	pool_destroy(tmpmem); | ||||
|  | ||||
| 	if (pl && *pl->pd.pl_pool_name) | ||||
| 		return 1; | ||||
|  | ||||
| 	return 0; | ||||
|  | ||||
| } | ||||
|  | ||||
| int read_pool_pds(const struct format_type *fmt, const char *vg_name, | ||||
| 		  struct pool *mem, struct list *pdhead) | ||||
| { | ||||
| 	struct lvmcache_vginfo *vginfo; | ||||
| 	uint32_t totaldevs; | ||||
| 	int full_scan = -1; | ||||
|  | ||||
| 	do { | ||||
| 		/* | ||||
| 		 * If the cache scanning doesn't work, this will never work | ||||
| 		 */ | ||||
| 		if (vg_name && (vginfo = vginfo_from_vgname(vg_name)) && | ||||
| 		    vginfo->infos.n) { | ||||
|  | ||||
| 			if (_read_vg_pds(fmt, mem, vginfo, pdhead, &totaldevs)) { | ||||
| 				/* | ||||
| 				 * If we found all the devices we were | ||||
| 				 * expecting, return success | ||||
| 				 */ | ||||
| 				if (list_size(pdhead) == totaldevs) | ||||
| 					return 1; | ||||
|  | ||||
| 				/* | ||||
| 				 * accept partial pool if we've done a full | ||||
| 				 * rescan of the cache | ||||
| 				 */ | ||||
| 				if (full_scan > 0) | ||||
| 					return 1; | ||||
| 			} | ||||
| 		} | ||||
| 		/* Failed */ | ||||
| 		list_init(pdhead); | ||||
|  | ||||
| 		full_scan++; | ||||
| 		if (full_scan > 1) { | ||||
| 			log_debug("No devices for vg %s found in cache", | ||||
| 				  vg_name); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		lvmcache_label_scan(fmt->cmd, full_scan); | ||||
|  | ||||
| 	} while (1); | ||||
|  | ||||
| } | ||||
|  | ||||
| struct pool_list *read_pool_disk(const struct format_type *fmt, | ||||
| 				 struct device *dev, struct pool *mem, | ||||
| 				 const char *vg_name) | ||||
| { | ||||
| 	struct pool_list *pl; | ||||
|  | ||||
| 	if (!dev_open(dev)) { | ||||
| 		stack; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (!(pl = pool_zalloc(mem, sizeof(*pl)))) { | ||||
| 		log_error("Unable to allocate pool list structure"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!__read_pool_disk(fmt, dev, mem, pl, vg_name)) { | ||||
| 		stack; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (!dev_close(dev)) | ||||
| 		stack; | ||||
|  | ||||
| 	return pl; | ||||
|  | ||||
| } | ||||
							
								
								
									
										178
									
								
								lib/format_pool/disk_rep.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								lib/format_pool/disk_rep.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | ||||
| /* | ||||
|  * Copyright (C) 1997-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 DISK_REP_FORMAT_POOL_H | ||||
| #define DISK_REP_FORMAT_POOL_H | ||||
|  | ||||
| #include "label.h" | ||||
| #include "metadata.h" | ||||
| #include "pool.h" | ||||
|  | ||||
| /* From NSP.cf */ | ||||
| #define NSPMajorVersion	4 | ||||
| #define NSPMinorVersion	1 | ||||
| #define NSPUpdateLevel	3 | ||||
|  | ||||
| /* From pool_std.h */ | ||||
| #define POOL_NAME_SIZE          (256) | ||||
| #define POOL_MAGIC 		0x011670 | ||||
| #define POOL_MAJOR              (121) | ||||
| #define POOL_MAX_DEVICES 	128 | ||||
|  | ||||
| /* When checking for version matching, the first two numbers ** | ||||
| ** are important for metadata formats, a.k.a pool labels.   ** | ||||
| ** All the numbers are important when checking if the user  ** | ||||
| ** space tools match up with the kernel module............. */ | ||||
| #define POOL_VERSION		(NSPMajorVersion << 16 | \ | ||||
| 				 NSPMinorVersion <<  8 | \ | ||||
| 				 NSPUpdateLevel) | ||||
|  | ||||
| /* Pool label is at the head of every pool disk partition */ | ||||
| #define SIZEOF_POOL_LABEL       (8192) | ||||
|  | ||||
| /* in sectors */ | ||||
| #define POOL_PE_SIZE     (SIZEOF_POOL_LABEL >> SECTOR_SHIFT) | ||||
| #define POOL_PE_START    (SIZEOF_POOL_LABEL >> SECTOR_SHIFT) | ||||
|  | ||||
| /* Helper fxns */ | ||||
| #define get_pool_vg_uuid(id, pd) do { get_pool_uuid((char *)(id), \ | ||||
|                                                     (pd)->pl_pool_id, 0, 0); \ | ||||
|                                     } while(0) | ||||
| #define get_pool_pv_uuid(id, pd) do { get_pool_uuid((char *)(id), \ | ||||
|                                                     (pd)->pl_pool_id, \ | ||||
|                                                     (pd)->pl_sp_id, \ | ||||
|                                                     (pd)->pl_sp_devid); \ | ||||
|                                     } while(0) | ||||
| #define get_pool_lv_uuid(id, pd) do { get_pool_uuid((char *)&(id)[0], \ | ||||
|                                                     (pd)->pl_pool_id, 0, 0); \ | ||||
|                                       get_pool_uuid((char*)&(id)[1], \ | ||||
|                                                     (pd)->pl_pool_id, 0, 0); \ | ||||
|                                     } while(0) | ||||
|  | ||||
| struct pool_disk; | ||||
| struct pool_list; | ||||
| struct user_subpool; | ||||
| struct user_device; | ||||
|  | ||||
| /* This must be kept up to date with sistina/pool/module/pool_sptypes.h */ | ||||
|  | ||||
| /*  Generic Labels  */ | ||||
| #define SPTYPE_DATA                (0x00000000) | ||||
|  | ||||
| /*  GFS specific labels  */ | ||||
| #define SPTYPE_GFS_DATA            (0x68011670) | ||||
| #define SPTYPE_GFS_JOURNAL         (0x69011670) | ||||
|  | ||||
| struct sptype_name { | ||||
| 	const char *name; | ||||
| 	uint32_t label; | ||||
| }; | ||||
|  | ||||
| static const struct sptype_name sptype_names[] = { | ||||
| 	{"data",	SPTYPE_DATA}, | ||||
|  | ||||
| 	{"gfs_data",	SPTYPE_GFS_DATA}, | ||||
| 	{"gfs_journal",	SPTYPE_GFS_JOURNAL}, | ||||
|  | ||||
| 	{"", 0x0}		/*  This must be the last flag.  */ | ||||
| }; | ||||
|  | ||||
| struct pool_disk { | ||||
| 	uint64_t pl_magic;	/* Pool magic number */ | ||||
| 	uint64_t pl_pool_id;	/* Unique pool identifier */ | ||||
| 	char pl_pool_name[POOL_NAME_SIZE];	/* Name of pool */ | ||||
| 	uint32_t pl_version;	/* Pool version */ | ||||
| 	uint32_t pl_subpools;	/* Number of subpools in this pool */ | ||||
| 	uint32_t pl_sp_id;	/* Subpool number within pool */ | ||||
| 	uint32_t pl_sp_devs;	/* Number of data partitions in this subpool */ | ||||
| 	uint32_t pl_sp_devid;	/* Partition number within subpool */ | ||||
| 	uint32_t pl_sp_type;	/* Partition type */ | ||||
| 	uint64_t pl_blocks;	/* Number of blocks in this partition */ | ||||
| 	uint32_t pl_striping;	/* Striping size within subpool */ | ||||
| 	/* | ||||
| 	 * If the number of DMEP devices is zero, then the next field ** | ||||
| 	 * ** (pl_sp_dmepid) becomes the subpool ID for redirection.  In ** | ||||
| 	 * ** other words, if this subpool does not have the capability  ** | ||||
| 	 * ** to do DMEP, then it must specify which subpool will do it  ** | ||||
| 	 * ** in it's place | ||||
| 	 */ | ||||
|  | ||||
| 	/* | ||||
| 	 * While the next 3 field are no longer used, they must stay to keep ** | ||||
| 	 * ** backward compatibility........................................... | ||||
| 	 */ | ||||
| 	uint32_t pl_sp_dmepdevs;/* Number of dmep devices in this subpool */ | ||||
| 	uint32_t pl_sp_dmepid;	/* Dmep device number within subpool */ | ||||
| 	uint32_t pl_sp_weight;	/* if dmep dev, pref to using it */ | ||||
|  | ||||
| 	uint32_t pl_minor;	/* the pool minor number */ | ||||
| 	uint32_t pl_padding;	/* reminder - think about alignment */ | ||||
|  | ||||
| 	/* | ||||
| 	 * Even though we're zeroing out 8k at the front of the disk before | ||||
| 	 * writing the label, putting this in | ||||
| 	 */ | ||||
| 	char pl_reserve[184];	/* bump the structure size out to 512 bytes */ | ||||
| }; | ||||
|  | ||||
| struct pool_list { | ||||
| 	struct list list; | ||||
| 	struct pool_disk pd; | ||||
| 	struct physical_volume *pv; | ||||
| 	struct id pv_uuid; | ||||
| 	struct device *dev; | ||||
| }; | ||||
|  | ||||
| struct user_subpool { | ||||
| 	uint32_t initialized; | ||||
| 	uint32_t id; | ||||
| 	uint32_t striping; | ||||
| 	uint32_t num_devs; | ||||
| 	uint32_t type; | ||||
| 	uint32_t dummy; | ||||
| 	struct user_device *devs; | ||||
| }; | ||||
|  | ||||
| struct user_device { | ||||
| 	uint32_t initialized; | ||||
| 	uint32_t sp_id; | ||||
| 	uint32_t devid; | ||||
| 	uint32_t dummy; | ||||
| 	uint64_t blocks; | ||||
| 	struct physical_volume *pv; | ||||
| }; | ||||
|  | ||||
| int read_pool_label(struct pool_list *pl, struct labeller *l, | ||||
| 		    struct device *dev, char *buf, struct label **label); | ||||
| void pool_label_out(struct pool_disk *pl, char *buf); | ||||
| void pool_label_in(struct pool_disk *pl, char *buf); | ||||
| void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid); | ||||
| int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls); | ||||
| int import_pool_lvs(struct volume_group *vg, struct pool *mem, | ||||
| 		    struct list *pls); | ||||
| int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg, | ||||
| 		    struct list *pvs, struct pool *mem, struct list *pls); | ||||
| int import_pool_pv(const struct format_type *fmt, struct pool *mem, | ||||
| 		   struct volume_group *vg, struct physical_volume *pv, | ||||
| 		   struct pool_list *pl); | ||||
| int import_pool_segments(struct list *lvs, struct pool *mem, | ||||
| 			 struct user_subpool *usp, int sp_count); | ||||
| int read_pool_pds(const struct format_type *fmt, const char *vgname, | ||||
| 		  struct pool *mem, struct list *head); | ||||
| struct pool_list *read_pool_disk(const struct format_type *fmt, | ||||
| 				 struct device *dev, struct pool *mem, | ||||
| 				 const char *vg_name); | ||||
|  | ||||
| #endif				/* DISK_REP_POOL_FORMAT_H */ | ||||
							
								
								
									
										361
									
								
								lib/format_pool/format_pool.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										361
									
								
								lib/format_pool/format_pool.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,361 @@ | ||||
| /* | ||||
|  * Copyright (C) 1997-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 "pool.h" | ||||
| #include "label.h" | ||||
| #include "metadata.h" | ||||
| #include "hash.h" | ||||
| #include "limits.h" | ||||
| #include "list.h" | ||||
| #include "display.h" | ||||
| #include "toolcontext.h" | ||||
| #include "lvmcache.h" | ||||
| #include "disk_rep.h" | ||||
| #include "format_pool.h" | ||||
| #include "pool_label.h" | ||||
|  | ||||
| #define FMT_POOL_NAME "pool" | ||||
|  | ||||
| /* Must be called after pvs are imported */ | ||||
| static struct user_subpool *_build_usp(struct list *pls, struct pool *mem, | ||||
| 				       int *sps) | ||||
| { | ||||
|  | ||||
| 	struct list *plhs; | ||||
| 	struct pool_list *pl; | ||||
| 	struct user_subpool *usp = NULL, *cur_sp = NULL; | ||||
| 	struct user_device *cur_dev = NULL; | ||||
|  | ||||
| 	/* | ||||
| 	 * FIXME: Need to do some checks here - I'm tempted to add a | ||||
| 	 * user_pool structure and build the entire thing to check against. | ||||
| 	 */ | ||||
| 	list_iterate(plhs, pls) { | ||||
| 		pl = list_item(plhs, struct pool_list); | ||||
|  | ||||
| 		*sps = pl->pd.pl_subpools; | ||||
| 		if (!usp && (!(usp = pool_zalloc(mem, sizeof(*usp) * (*sps))))) { | ||||
| 			log_error("Unable to allocate %d subpool structures", | ||||
| 				  *sps); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (cur_sp != &usp[pl->pd.pl_sp_id]) { | ||||
| 			cur_sp = &usp[pl->pd.pl_sp_id]; | ||||
|  | ||||
| 			cur_sp->id = pl->pd.pl_sp_id; | ||||
| 			cur_sp->striping = pl->pd.pl_striping; | ||||
| 			cur_sp->num_devs = pl->pd.pl_sp_devs; | ||||
| 			cur_sp->type = pl->pd.pl_sp_type; | ||||
| 			cur_sp->initialized = 1; | ||||
| 		} | ||||
|  | ||||
| 		if (!cur_sp->devs && | ||||
| 		    (!(cur_sp->devs = | ||||
| 		       pool_zalloc(mem, | ||||
| 				   sizeof(*usp->devs) * pl->pd.pl_sp_devs)))) { | ||||
|  | ||||
| 			log_error("Unable to allocate %d pool_device " | ||||
| 				  "structures", pl->pd.pl_sp_devs); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		cur_dev = &cur_sp->devs[pl->pd.pl_sp_devid]; | ||||
| 		cur_dev->sp_id = cur_sp->id; | ||||
| 		cur_dev->devid = pl->pd.pl_sp_id; | ||||
| 		cur_dev->blocks = pl->pd.pl_blocks; | ||||
| 		cur_dev->pv = pl->pv; | ||||
| 		cur_dev->initialized = 1; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return usp; | ||||
| } | ||||
|  | ||||
| static int _check_usp(char *vgname, struct user_subpool *usp, int sp_count) | ||||
| { | ||||
| 	int i, j; | ||||
|  | ||||
| 	for (i = 0; i < sp_count; i++) { | ||||
| 		if (!usp[i].initialized) { | ||||
| 			log_error("Missing subpool %d in pool %s", i, vgname); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		for (j = 0; j < usp[i].num_devs; j++) { | ||||
| 			if (!usp[i].devs[j].initialized) { | ||||
| 				log_error("Missing device %d for subpool %d" | ||||
| 					  " in pool %s", j, i, vgname); | ||||
| 				return 0; | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static struct volume_group *_build_vg_from_pds(struct format_instance | ||||
| 					       *fid, struct pool *mem, | ||||
| 					       struct list *pds) | ||||
| { | ||||
| 	struct pool *smem = fid->fmt->cmd->mem; | ||||
| 	struct volume_group *vg = NULL; | ||||
| 	struct user_subpool *usp = NULL; | ||||
| 	int sp_count; | ||||
|  | ||||
| 	if (!(vg = pool_zalloc(smem, sizeof(*vg)))) { | ||||
| 		log_error("Unable to allocate volume group structure"); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	vg->cmd = fid->fmt->cmd; | ||||
| 	vg->fid = fid; | ||||
| 	vg->name = NULL; | ||||
| 	vg->status = 0; | ||||
| 	vg->extent_count = 0; | ||||
| 	vg->pv_count = 0; | ||||
| 	vg->lv_count = 0; | ||||
| 	vg->snapshot_count = 0; | ||||
| 	vg->seqno = 1; | ||||
| 	vg->system_id = NULL; | ||||
| 	list_init(&vg->pvs); | ||||
| 	list_init(&vg->lvs); | ||||
| 	list_init(&vg->snapshots); | ||||
| 	list_init(&vg->tags); | ||||
|  | ||||
| 	if (!import_pool_vg(vg, smem, pds)) { | ||||
| 		stack; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (!import_pool_pvs(fid->fmt, vg, &vg->pvs, smem, pds)) { | ||||
| 		stack; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (!import_pool_lvs(vg, smem, pds)) { | ||||
| 		stack; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * I need an intermediate subpool structure that contains all the | ||||
| 	 * relevant info for this.  Then i can iterate through the subpool | ||||
| 	 * structures for checking, and create the segments | ||||
| 	 */ | ||||
| 	if (!(usp = _build_usp(pds, mem, &sp_count))) { | ||||
| 		stack; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * check the subpool structures - we can't handle partial VGs in | ||||
| 	 * the pool format, so this will error out if we're missing PVs | ||||
| 	 */ | ||||
| 	if (!_check_usp(vg->name, usp, sp_count)) { | ||||
| 		stack; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (!import_pool_segments(&vg->lvs, smem, usp, sp_count)) { | ||||
| 		stack; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	return vg; | ||||
| } | ||||
|  | ||||
| static struct volume_group *_vg_read(struct format_instance *fid, | ||||
| 				     const char *vg_name, | ||||
| 				     struct metadata_area *mda) | ||||
| { | ||||
| 	struct pool *mem = pool_create(1024); | ||||
| 	struct list pds; | ||||
| 	struct volume_group *vg = NULL; | ||||
|  | ||||
| 	list_init(&pds); | ||||
|  | ||||
| 	/* We can safely ignore the mda passed in */ | ||||
|  | ||||
| 	if (!mem) { | ||||
| 		stack; | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* Strip dev_dir if present */ | ||||
| 	vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir); | ||||
|  | ||||
| 	/* Read all the pvs in the vg */ | ||||
| 	if (!read_pool_pds(fid->fmt, vg_name, mem, &pds)) { | ||||
| 		stack; | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	/* Do the rest of the vg stuff */ | ||||
| 	if (!(vg = _build_vg_from_pds(fid, mem, &pds))) { | ||||
| 		stack; | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
|       out: | ||||
| 	pool_destroy(mem); | ||||
| 	return vg; | ||||
| } | ||||
|  | ||||
| static int _pv_setup(const struct format_type *fmt, | ||||
| 		     uint64_t pe_start, uint32_t extent_count, | ||||
| 		     uint32_t extent_size, | ||||
| 		     int pvmetadatacopies, | ||||
| 		     uint64_t pvmetadatasize, struct list *mdas, | ||||
| 		     struct physical_volume *pv, struct volume_group *vg) | ||||
| { | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _pv_read(const struct format_type *fmt, const char *pv_name, | ||||
| 		    struct physical_volume *pv, struct list *mdas) | ||||
| { | ||||
| 	struct pool *mem = pool_create(1024); | ||||
| 	struct pool_list *pl; | ||||
| 	struct device *dev; | ||||
| 	int r = 0; | ||||
|  | ||||
| 	log_very_verbose("Reading physical volume data %s from disk", pv_name); | ||||
|  | ||||
| 	if (!mem) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) { | ||||
| 		stack; | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * I need to read the disk and populate a pv structure here | ||||
| 	 * I'll probably need to abstract some of this later for the | ||||
| 	 * vg_read code | ||||
| 	 */ | ||||
| 	if (!(pl = read_pool_disk(fmt, dev, mem, NULL))) { | ||||
| 		stack; | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	if (!import_pool_pv(fmt, fmt->cmd->mem, NULL, pv, pl)) { | ||||
| 		stack; | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	pv->fmt = fmt; | ||||
|  | ||||
| 	r = 1; | ||||
|  | ||||
|       out: | ||||
| 	pool_destroy(mem); | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| /* *INDENT-OFF* */ | ||||
| static struct metadata_area_ops _metadata_format_pool_ops = { | ||||
| 	vg_read:_vg_read, | ||||
| }; | ||||
| /* *INDENT-ON* */ | ||||
|  | ||||
| static struct format_instance *_create_instance(const struct format_type *fmt, | ||||
| 						const char *vgname, | ||||
| 						void *private) | ||||
| { | ||||
| 	struct format_instance *fid; | ||||
| 	struct metadata_area *mda; | ||||
|  | ||||
| 	if (!(fid = pool_zalloc(fmt->cmd->mem, sizeof(*fid)))) { | ||||
| 		log_error("Unable to allocate format instance structure for " | ||||
| 			  "pool format"); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	fid->fmt = fmt; | ||||
| 	list_init(&fid->metadata_areas); | ||||
|  | ||||
| 	/* Define a NULL metadata area */ | ||||
| 	if (!(mda = pool_zalloc(fmt->cmd->mem, sizeof(*mda)))) { | ||||
| 		log_error("Unable to allocate metadata area structure " | ||||
| 			  "for pool format"); | ||||
| 		pool_free(fmt->cmd->mem, fid); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	mda->ops = &_metadata_format_pool_ops; | ||||
| 	mda->metadata_locn = NULL; | ||||
| 	list_add(&fid->metadata_areas, &mda->list); | ||||
|  | ||||
| 	return fid; | ||||
| } | ||||
|  | ||||
| static void _destroy_instance(struct format_instance *fid) | ||||
| { | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| static void _destroy(const struct format_type *fmt) | ||||
| { | ||||
| 	dbg_free((void *) fmt); | ||||
| } | ||||
|  | ||||
| /* *INDENT-OFF* */ | ||||
| static struct format_handler _format_pool_ops = { | ||||
| 	pv_read:_pv_read, | ||||
| 	pv_setup:_pv_setup, | ||||
| 	create_instance:_create_instance, | ||||
| 	destroy_instance:_destroy_instance, | ||||
| 	destroy:_destroy, | ||||
| }; | ||||
| /* *INDENT-ON */ | ||||
|  | ||||
| #ifdef POOL_INTERNAL | ||||
| struct format_type *init_pool_format(struct cmd_context *cmd) | ||||
| #else				/* Shared */ | ||||
| struct format_type *init_format(struct cmd_context *cmd); | ||||
| struct format_type *init_format(struct cmd_context *cmd) | ||||
| #endif | ||||
| { | ||||
| 	struct format_type *fmt = dbg_malloc(sizeof(*fmt)); | ||||
|  | ||||
| 	if (!fmt) { | ||||
| 		log_error("Unable to allocate format type structure for pool " | ||||
| 			  "format"); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	fmt->cmd = cmd; | ||||
| 	fmt->ops = &_format_pool_ops; | ||||
| 	fmt->name = FMT_POOL_NAME; | ||||
| 	fmt->alias = NULL; | ||||
| 	fmt->features = 0; | ||||
| 	fmt->private = NULL; | ||||
|  | ||||
| 	if (!(fmt->labeller = pool_labeller_create(fmt))) { | ||||
| 		log_error("Couldn't create pool label handler."); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (!(label_register_handler(FMT_POOL_NAME, fmt->labeller))) { | ||||
| 		log_error("Couldn't register pool label handler."); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	return fmt; | ||||
| } | ||||
							
								
								
									
										25
									
								
								lib/format_pool/format_pool.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								lib/format_pool/format_pool.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| /* | ||||
|  * 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_FORMAT_POOL_H | ||||
| #define _LVM_FORMAT_POOL_H | ||||
|  | ||||
| #include "metadata.h" | ||||
|  | ||||
| #ifdef POOL_INTERNAL | ||||
| struct format_type *init_pool_format(struct cmd_context *cmd); | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										309
									
								
								lib/format_pool/import_export.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								lib/format_pool/import_export.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,309 @@ | ||||
| /* | ||||
|  * Copyright (C) 1997-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 "pool.h" | ||||
| #include "label.h" | ||||
| #include "metadata.h" | ||||
| #include "lvmcache.h" | ||||
| #include "disk_rep.h" | ||||
| #include "lv_alloc.h" | ||||
| #include "str_list.h" | ||||
| #include "display.h" | ||||
| #include "segtypes.h" | ||||
|  | ||||
| /* This file contains only imports at the moment... */ | ||||
|  | ||||
| int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls) | ||||
| { | ||||
| 	struct list *plhs; | ||||
| 	struct pool_list *pl; | ||||
|  | ||||
| 	list_iterate(plhs, pls) { | ||||
| 		pl = list_item(plhs, struct pool_list); | ||||
|  | ||||
| 		vg->extent_count += | ||||
| 		    ((pl->pd.pl_blocks) / POOL_PE_SIZE); | ||||
|  | ||||
| 		vg->pv_count++; | ||||
|  | ||||
| 		if (vg->name) | ||||
| 			continue; | ||||
|  | ||||
| 		vg->name = pool_strdup(mem, pl->pd.pl_pool_name); | ||||
| 		get_pool_vg_uuid(&vg->id, &pl->pd); | ||||
| 		vg->extent_size = POOL_PE_SIZE; | ||||
| 		vg->status |= LVM_READ | LVM_WRITE | CLUSTERED | SHARED; | ||||
| 		vg->free_count = 0; | ||||
| 		vg->max_lv = 1; | ||||
| 		vg->max_pv = POOL_MAX_DEVICES; | ||||
| 		vg->alloc = ALLOC_NORMAL; | ||||
| 		vg->lv_count = 0; | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls) | ||||
| { | ||||
| 	struct pool_list *pl; | ||||
| 	struct list *plhs; | ||||
| 	struct lv_list *lvl = pool_zalloc(mem, sizeof(*lvl)); | ||||
| 	struct logical_volume *lv; | ||||
|  | ||||
| 	if (!lvl) { | ||||
| 		log_error("Unable to allocate lv list structure"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!(lvl->lv = pool_zalloc(mem, sizeof(*lvl->lv)))) { | ||||
| 		log_error("Unable to allocate logical volume structure"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	lv = lvl->lv; | ||||
| 	lv->status = 0; | ||||
| 	lv->vg = vg; | ||||
| 	lv->alloc = ALLOC_NORMAL; | ||||
| 	lv->size = 0; | ||||
| 	lv->name = NULL; | ||||
| 	lv->le_count = 0; | ||||
| 	lv->read_ahead = 0; | ||||
| 	list_init(&lv->segments); | ||||
| 	list_init(&lv->tags); | ||||
|  | ||||
| 	list_iterate(plhs, pls) { | ||||
| 		pl = list_item(plhs, struct pool_list); | ||||
|  | ||||
| 		lv->size += pl->pd.pl_blocks; | ||||
|  | ||||
| 		if (lv->name) | ||||
| 			continue; | ||||
|  | ||||
| 		if (!(lv->name = pool_strdup(mem, pl->pd.pl_pool_name))) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		get_pool_lv_uuid(lv->lvid.id, &pl->pd); | ||||
| 		log_debug("Calculated lv uuid for lv %s: %s", lv->name, | ||||
| 			  lv->lvid.s); | ||||
|  | ||||
| 		lv->status |= VISIBLE_LV | LVM_READ | LVM_WRITE; | ||||
| 		lv->major = POOL_MAJOR; | ||||
|  | ||||
| 		/* for pool a minor of 0 is dynamic */ | ||||
| 		if (pl->pd.pl_minor) { | ||||
| 			lv->status |= FIXED_MINOR; | ||||
| 			lv->minor = pl->pd.pl_minor; | ||||
| 		} else { | ||||
| 			lv->minor = -1; | ||||
| 		} | ||||
| 		list_init(&lv->segments); | ||||
| 		list_init(&lv->tags); | ||||
| 	} | ||||
|  | ||||
| 	lv->le_count = lv->size / POOL_PE_SIZE; | ||||
| 	lvl->lv = lv; | ||||
| 	list_add(&vg->lvs, &lvl->list); | ||||
| 	vg->lv_count++; | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg, | ||||
| 		    struct list *pvs, struct pool *mem, struct list *pls) | ||||
| { | ||||
| 	struct pv_list *pvl; | ||||
| 	struct pool_list *pl; | ||||
| 	struct list *plhs; | ||||
|  | ||||
| 	list_iterate(plhs, pls) { | ||||
| 		pl = list_item(plhs, struct pool_list); | ||||
|  | ||||
| 		if (!(pvl = pool_zalloc(mem, sizeof(*pvl)))) { | ||||
| 			log_error("Unable to allocate pv list structure"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		if (!(pvl->pv = pool_zalloc(mem, sizeof(*pvl->pv)))) { | ||||
| 			log_error("Unable to allocate pv structure"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		if (!import_pool_pv(fmt, mem, vg, pvl->pv, pl)) { | ||||
| 			return 0; | ||||
| 		} | ||||
| 		pl->pv = pvl->pv; | ||||
| 		pvl->mdas = NULL; | ||||
| 		pvl->alloc_areas = NULL; | ||||
| 		list_add(pvs, &pvl->list); | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int import_pool_pv(const struct format_type *fmt, struct pool *mem, | ||||
| 		   struct volume_group *vg, struct physical_volume *pv, | ||||
| 		   struct pool_list *pl) | ||||
| { | ||||
| 	struct pool_disk *pd = &pl->pd; | ||||
|  | ||||
| 	memset(pv, 0, sizeof(*pv)); | ||||
|  | ||||
| 	get_pool_pv_uuid(&pv->id, pd); | ||||
| 	pv->fmt = fmt; | ||||
|  | ||||
| 	pv->dev = pl->dev; | ||||
| 	if (!(pv->vg_name = pool_strdup(mem, pd->pl_pool_name))) { | ||||
| 		log_error("Unable to duplicate vg_name string"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	pv->status = 0; | ||||
| 	pv->size = pd->pl_blocks; | ||||
| 	pv->pe_size = POOL_PE_SIZE; | ||||
| 	pv->pe_start = POOL_PE_START; | ||||
| 	pv->pe_count = pv->size / POOL_PE_SIZE; | ||||
| 	pv->pe_alloc_count = pv->pe_count; | ||||
|  | ||||
| 	list_init(&pv->tags); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static const char *_cvt_sptype(uint32_t sptype) | ||||
| { | ||||
| 	int i; | ||||
| 	for (i = 0; sptype_names[i].name[0]; i++) { | ||||
| 		if (sptype == sptype_names[i].label) { | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	log_debug("Found sptype %X and converted it to %s", | ||||
| 		  sptype, sptype_names[i].name); | ||||
| 	return sptype_names[i].name; | ||||
| } | ||||
|  | ||||
| static int _add_stripe_seg(struct pool *mem, | ||||
| 			   struct user_subpool *usp, struct logical_volume *lv, | ||||
| 			   uint32_t *le_cur) | ||||
| { | ||||
| 	struct lv_segment *seg; | ||||
| 	int j; | ||||
|  | ||||
| 	if (!(seg = alloc_lv_segment(mem, usp->num_devs))) { | ||||
| 		log_error("Unable to allocate striped lv_segment structure"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if(usp->striping & (usp->striping - 1)) { | ||||
| 		log_error("Stripe size must be a power of 2"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	seg->stripe_size = usp->striping; | ||||
| 	seg->status |= 0; | ||||
| 	seg->le += *le_cur; | ||||
|  | ||||
| 	/* add the subpool type to the segment tag list */ | ||||
| 	str_list_add(mem, &seg->tags, _cvt_sptype(usp->type)); | ||||
|  | ||||
| 	for (j = 0; j < usp->num_devs; j++) { | ||||
| 		if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd, | ||||
| 							     "striped"))) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		seg->area_len = (usp->devs[j].blocks) / POOL_PE_SIZE; | ||||
| 		seg->len += seg->area_len; | ||||
| 		*le_cur += seg->area_len; | ||||
| 		seg->lv = lv; | ||||
|  | ||||
| 		seg->area[j].type = AREA_PV; | ||||
| 		seg->area[j].u.pv.pv = usp->devs[j].pv; | ||||
| 		seg->area[j].u.pv.pe = 0; | ||||
| 	} | ||||
| 	list_add(&lv->segments, &seg->list); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _add_linear_seg(struct pool *mem, | ||||
| 			   struct user_subpool *usp, struct logical_volume *lv, | ||||
| 			   uint32_t *le_cur) | ||||
| { | ||||
| 	struct lv_segment *seg; | ||||
| 	int j; | ||||
|  | ||||
| 	for (j = 0; j < usp->num_devs; j++) { | ||||
| 		/* linear segments only have 1 data area */ | ||||
| 		if (!(seg = alloc_lv_segment(mem, 1))) { | ||||
| 			log_error("Unable to allocate linear lv_segment " | ||||
| 				  "structure"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		seg->stripe_size = usp->striping; | ||||
| 		seg->le += *le_cur; | ||||
| 		seg->chunk_size = POOL_PE_SIZE; | ||||
| 		seg->status |= 0; | ||||
| 		if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd, | ||||
| 							     "striped"))) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| 		/* add the subpool type to the segment tag list */ | ||||
| 		str_list_add(mem, &seg->tags, _cvt_sptype(usp->type)); | ||||
|  | ||||
| 		seg->lv = lv; | ||||
|  | ||||
| 		seg->area_len = (usp->devs[j].blocks) / POOL_PE_SIZE; | ||||
| 		seg->len = seg->area_len; | ||||
| 		*le_cur += seg->len; | ||||
| 		seg->area[0].type = AREA_PV; | ||||
| 		seg->area[0].u.pv.pv = usp->devs[j].pv; | ||||
| 		seg->area[0].u.pv.pe = 0; | ||||
| 		list_add(&lv->segments, &seg->list); | ||||
| 	} | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int import_pool_segments(struct list *lvs, struct pool *mem, | ||||
| 			 struct user_subpool *usp, int subpools) | ||||
| { | ||||
|  | ||||
| 	struct list *lvhs; | ||||
| 	struct lv_list *lvl; | ||||
| 	struct logical_volume *lv; | ||||
| 	uint32_t le_cur = 0; | ||||
| 	int i; | ||||
|  | ||||
| 	list_iterate(lvhs, lvs) { | ||||
| 		lvl = list_item(lvhs, struct lv_list); | ||||
|  | ||||
| 		lv = lvl->lv; | ||||
| 		for (i = 0; i < subpools; i++) { | ||||
| 			if (usp[i].striping) { | ||||
| 				if (!_add_stripe_seg(mem, &usp[i], lv, &le_cur)) { | ||||
| 					stack; | ||||
| 					return 0; | ||||
| 				} | ||||
| 			} else { | ||||
| 				if (!_add_linear_seg(mem, &usp[i], lv, &le_cur)) { | ||||
| 					stack; | ||||
| 					return 0; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
|  | ||||
| } | ||||
							
								
								
									
										108
									
								
								lib/format_pool/pool_label.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								lib/format_pool/pool_label.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| /* | ||||
|  * Copyright (C) 1997-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 "pool.h" | ||||
| #include "label.h" | ||||
| #include "metadata.h" | ||||
| #include "xlate.h" | ||||
| #include "disk_rep.h" | ||||
| #include "pool_label.h" | ||||
|  | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
|  | ||||
| static void _not_supported(const char *op) | ||||
| { | ||||
| 	log_error("The '%s' operation is not supported for the pool labeller.", | ||||
| 		  op); | ||||
| } | ||||
|  | ||||
| static int _can_handle(struct labeller *l, char *buf, uint64_t sector) | ||||
| { | ||||
|  | ||||
| 	struct pool_disk pd; | ||||
|  | ||||
| 	/* | ||||
| 	 * POOL label must always be in first sector | ||||
| 	 */ | ||||
| 	if (sector) | ||||
| 		return 0; | ||||
|  | ||||
| 	pool_label_in(&pd, buf); | ||||
|  | ||||
| 	/* can ignore 8 rightmost bits for ondisk format check */ | ||||
| 	if ((pd.pl_magic == POOL_MAGIC) && | ||||
| 	    (pd.pl_version >> 8 == POOL_VERSION >> 8)) | ||||
| 		return 1; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int _write(struct label *label, char *buf) | ||||
| { | ||||
| 	_not_supported("write"); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int _read(struct labeller *l, struct device *dev, char *buf, | ||||
| 		 struct label **label) | ||||
| { | ||||
| 	struct pool_list pl; | ||||
|  | ||||
| 	return read_pool_label(&pl, l, dev, buf, label); | ||||
| } | ||||
|  | ||||
| static int _initialise_label(struct labeller *l, struct label *label) | ||||
| { | ||||
| 	strcpy(label->type, "POOL"); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static void _destroy_label(struct labeller *l, struct label *label) | ||||
| { | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| static void _destroy(struct labeller *l) | ||||
| { | ||||
| 	dbg_free(l); | ||||
| } | ||||
|  | ||||
| struct label_ops _pool_ops = { | ||||
|       can_handle:_can_handle, | ||||
|       write:_write, | ||||
|       read:_read, | ||||
|       verify:_can_handle, | ||||
|       initialise_label:_initialise_label, | ||||
|       destroy_label:_destroy_label, | ||||
|       destroy:_destroy | ||||
| }; | ||||
|  | ||||
| struct labeller *pool_labeller_create(struct format_type *fmt) | ||||
| { | ||||
| 	struct labeller *l; | ||||
|  | ||||
| 	if (!(l = dbg_malloc(sizeof(*l)))) { | ||||
| 		log_error("Couldn't allocate labeller object."); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	l->ops = &_pool_ops; | ||||
| 	l->private = (const void *) fmt; | ||||
|  | ||||
| 	return l; | ||||
| } | ||||
							
								
								
									
										23
									
								
								lib/format_pool/pool_label.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								lib/format_pool/pool_label.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| /* | ||||
|  * Copyright (C) 1997-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_POOL_LABEL_H | ||||
| #define _LVM_POOL_LABEL_H | ||||
|  | ||||
| #include "metadata.h" | ||||
|  | ||||
| struct labeller *pool_labeller_create(struct format_type *fmt); | ||||
|  | ||||
| #endif | ||||
| @@ -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" | ||||
| @@ -371,4 +380,3 @@ int backup_list(struct cmd_context *cmd, const char *dir, const char *vgname) | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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,6 +20,8 @@ | ||||
| #include "pool.h" | ||||
| #include "display.h" | ||||
| #include "lvm-string.h" | ||||
| #include "segtypes.h" | ||||
| #include "text_export.h" | ||||
|  | ||||
| #include <stdarg.h> | ||||
| #include <time.h> | ||||
| @@ -65,14 +76,6 @@ static void _init(void) | ||||
| /* | ||||
|  * Formatting functions. | ||||
|  */ | ||||
| static int _out_size(struct formatter *f, uint64_t size, const char *fmt, ...) | ||||
|     __attribute__ ((format(printf, 3, 4))); | ||||
|  | ||||
| static int _out_hint(struct formatter *f, const char *fmt, ...) | ||||
|     __attribute__ ((format(printf, 2, 3))); | ||||
|  | ||||
| static int _out(struct formatter *f, const char *fmt, ...) | ||||
|     __attribute__ ((format(printf, 2, 3))); | ||||
|  | ||||
| #define MAX_INDENT 5 | ||||
| static void _inc_indent(struct formatter *f) | ||||
| @@ -197,7 +200,7 @@ static int _sectors_to_units(uint64_t sectors, char *buffer, size_t s) | ||||
|  * Appends a comment giving a size in more easily | ||||
|  * readable form (eg, 4M instead of 8096). | ||||
|  */ | ||||
| static int _out_size(struct formatter *f, uint64_t size, const char *fmt, ...) | ||||
| int out_size(struct formatter *f, uint64_t size, const char *fmt, ...) | ||||
| { | ||||
| 	char buffer[64]; | ||||
| 	va_list ap; | ||||
| @@ -217,7 +220,7 @@ static int _out_size(struct formatter *f, uint64_t size, const char *fmt, ...) | ||||
|  * Appends a comment indicating that the line is | ||||
|  * only a hint. | ||||
|  */ | ||||
| static int _out_hint(struct formatter *f, const char *fmt, ...) | ||||
| int out_hint(struct formatter *f, const char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 	int r; | ||||
| @@ -232,7 +235,7 @@ static int _out_hint(struct formatter *f, const char *fmt, ...) | ||||
| /* | ||||
|  * The normal output function. | ||||
|  */ | ||||
| static int _out(struct formatter *f, const char *fmt, ...) | ||||
| int out_text(struct formatter *f, const char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 	int r; | ||||
| @@ -244,8 +247,6 @@ static int _out(struct formatter *f, const char *fmt, ...) | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| #define _outf(args...) do {if (!_out(args)) {stack; return 0;}} while (0) | ||||
|  | ||||
| static int _print_header(struct formatter *f, | ||||
| 			 struct volume_group *vg, const char *desc) | ||||
| { | ||||
| @@ -253,48 +254,65 @@ static int _print_header(struct formatter *f, | ||||
|  | ||||
| 	t = time(NULL); | ||||
|  | ||||
| 	_outf(f, "# Generated by LVM2: %s", ctime(&t)); | ||||
| 	_outf(f, CONTENTS_FIELD " = \"" CONTENTS_VALUE "\""); | ||||
| 	_outf(f, FORMAT_VERSION_FIELD " = %d", FORMAT_VERSION_VALUE); | ||||
| 	outf(f, "# Generated by LVM2: %s", ctime(&t)); | ||||
| 	outf(f, CONTENTS_FIELD " = \"" CONTENTS_VALUE "\""); | ||||
| 	outf(f, FORMAT_VERSION_FIELD " = %d", FORMAT_VERSION_VALUE); | ||||
| 	f->nl(f); | ||||
|  | ||||
| 	_outf(f, "description = \"%s\"", desc); | ||||
| 	outf(f, "description = \"%s\"", desc); | ||||
| 	f->nl(f); | ||||
| 	_outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename, | ||||
| 	      _utsname.sysname, _utsname.nodename, _utsname.release, | ||||
| 	      _utsname.version, _utsname.machine); | ||||
| 	_outf(f, "creation_time = %lu\t# %s", t, ctime(&t)); | ||||
| 	outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename, | ||||
| 	     _utsname.sysname, _utsname.nodename, _utsname.release, | ||||
| 	     _utsname.version, _utsname.machine); | ||||
| 	outf(f, "creation_time = %lu\t# %s", t, ctime(&t)); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| 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; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	_outf(f, "id = \"%s\"", buffer); | ||||
| 	outf(f, "id = \"%s\"", buffer); | ||||
|  | ||||
| 	outf(f, "seqno = %u", vg->seqno); | ||||
|  | ||||
| 	_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); | ||||
| 	} | ||||
|  | ||||
| 	_outf(f, "status = %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)) { | ||||
| 		outf(f, "system_id = \"%s\"", vg->system_id); | ||||
|  | ||||
| 	if (!out_size(f, (uint64_t) vg->extent_size, "extent_size = %u", | ||||
| 		      vg->extent_size)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	_outf(f, "max_lv = %u", vg->max_lv); | ||||
| 	_outf(f, "max_pv = %u", vg->max_pv); | ||||
| 	outf(f, "max_lv = %u", vg->max_lv); | ||||
| 	outf(f, "max_pv = %u", vg->max_pv); | ||||
|  | ||||
| 	/* Default policy is NORMAL; INHERIT is meaningless */ | ||||
| 	if (vg->alloc != ALLOC_NORMAL && vg->alloc != ALLOC_INHERIT) { | ||||
| 		f->nl(f); | ||||
| 		outf(f, "allocation_policy = \"%s\"", | ||||
| 		     get_alloc_string(vg->alloc)); | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
| @@ -314,10 +332,10 @@ 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 {"); | ||||
| 	outf(f, "physical_volumes {"); | ||||
| 	_inc_indent(f); | ||||
|  | ||||
| 	list_iterate(pvh, &vg->pvs) { | ||||
| @@ -329,7 +347,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg) | ||||
| 		} | ||||
|  | ||||
| 		f->nl(f); | ||||
| 		_outf(f, "%s {", name); | ||||
| 		outf(f, "%s {", name); | ||||
| 		_inc_indent(f); | ||||
|  | ||||
| 		if (!id_write_format(&pv->id, buffer, sizeof(buffer))) { | ||||
| @@ -337,8 +355,8 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg) | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		_outf(f, "id = \"%s\"", buffer); | ||||
| 		if (!_out_hint(f, "device = \"%s\"", dev_name(pv->dev))) { | ||||
| 		outf(f, "id = \"%s\"", buffer); | ||||
| 		if (!out_hint(f, "device = \"%s\"", dev_name(pv->dev))) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| @@ -348,102 +366,106 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg) | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| 		outf(f, "status = %s", buffer); | ||||
|  | ||||
| 		_outf(f, "status = %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)) { | ||||
| 		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)) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		_dec_indent(f); | ||||
| 		_outf(f, "}"); | ||||
| 		outf(f, "}"); | ||||
| 	} | ||||
|  | ||||
| 	_dec_indent(f); | ||||
| 	_outf(f, "}"); | ||||
| 	outf(f, "}"); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _print_segment(struct formatter *f, struct volume_group *vg, | ||||
| 			  int count, struct lv_segment *seg) | ||||
| { | ||||
| 	unsigned int s; | ||||
| 	const char *name; | ||||
| 	const char *type; | ||||
| 	char buffer[4096]; | ||||
|  | ||||
| 	_outf(f, "segment%u {", count); | ||||
| 	outf(f, "segment%u {", count); | ||||
| 	_inc_indent(f); | ||||
|  | ||||
| 	_outf(f, "start_extent = %u", seg->le); | ||||
| 	if (!_out_size(f, (uint64_t) seg->len * vg->extent_size, | ||||
| 		       "extent_count = %u", seg->len)) { | ||||
| 	outf(f, "start_extent = %u", seg->le); | ||||
| 	if (!out_size(f, (uint64_t) seg->len * vg->extent_size, | ||||
| 		      "extent_count = %u", seg->len)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	f->nl(f); | ||||
| 	_outf(f, "type = \"%s\"", get_segtype_string(seg->type)); | ||||
| 	outf(f, "type = \"%s\"", seg->segtype->name); | ||||
|  | ||||
| 	switch (seg->type) { | ||||
| 	case SEG_SNAPSHOT: | ||||
| 		_outf(f, "chunk_size = %u", seg->chunk_size); | ||||
| 		_outf(f, "origin = \"%s\"", seg->origin->name); | ||||
| 		_outf(f, "cow_store = \"%s\"", seg->cow->name); | ||||
| 		break; | ||||
|  | ||||
| 	case SEG_MIRRORED: | ||||
| 	case SEG_STRIPED: | ||||
| 		type = (seg->type == SEG_MIRRORED) ? "mirror" : "stripe"; | ||||
| 		_outf(f, "%s_count = %u%s", type, seg->area_count, | ||||
| 		      (seg->area_count == 1) ? "\t# linear" : ""); | ||||
|  | ||||
| 		if ((seg->type == SEG_MIRRORED) && (seg->status & PVMOVE)) | ||||
| 			_out_size(f, (uint64_t) seg->extents_moved, | ||||
| 				  "extents_moved = %u", seg->extents_moved); | ||||
|  | ||||
| 		if ((seg->type == SEG_STRIPED) && (seg->area_count > 1)) | ||||
| 			_out_size(f, (uint64_t) seg->stripe_size, | ||||
| 				  "stripe_size = %u", seg->stripe_size); | ||||
|  | ||||
| 		f->nl(f); | ||||
|  | ||||
| 		_outf(f, "%ss = [", type); | ||||
| 		_inc_indent(f); | ||||
|  | ||||
| 		for (s = 0; s < seg->area_count; s++) { | ||||
| 			switch (seg->area[s].type) { | ||||
| 			case AREA_PV: | ||||
| 				if (!(name = _get_pv_name(f, seg-> | ||||
| 							  area[s].u.pv.pv))) { | ||||
| 					stack; | ||||
| 					return 0; | ||||
| 				} | ||||
|  | ||||
| 				_outf(f, "\"%s\", %u%s", name, | ||||
| 				      seg->area[s].u.pv.pe, | ||||
| 				      (s == seg->area_count - 1) ? "" : ","); | ||||
| 				break; | ||||
| 			case AREA_LV: | ||||
| 				_outf(f, "\"%s\", %u%s", | ||||
| 				      seg->area[s].u.lv.lv->name, | ||||
| 				      seg->area[s].u.lv.le, | ||||
| 				      (s == seg->area_count - 1) ? "" : ","); | ||||
| 			} | ||||
| 	if (!list_empty(&seg->tags)) { | ||||
| 		if (!print_tags(&seg->tags, buffer, sizeof(buffer))) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| 		outf(f, "tags = %s", buffer); | ||||
| 	} | ||||
|  | ||||
| 		_dec_indent(f); | ||||
| 		_outf(f, "]"); | ||||
| 		break; | ||||
| 	if (seg->segtype->ops->text_export && | ||||
| 	    !seg->segtype->ops->text_export(seg, f)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	_dec_indent(f); | ||||
| 	_outf(f, "}"); | ||||
| 	outf(f, "}"); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int out_areas(struct formatter *f, const struct lv_segment *seg, | ||||
| 	      const char *type) | ||||
| { | ||||
| 	const char *name; | ||||
| 	unsigned int s; | ||||
|  | ||||
| 	f->nl(f); | ||||
|  | ||||
| 	outf(f, "%ss = [", type); | ||||
| 	_inc_indent(f); | ||||
|  | ||||
| 	for (s = 0; s < seg->area_count; s++) { | ||||
| 		switch (seg->area[s].type) { | ||||
| 		case AREA_PV: | ||||
| 			if (!(name = _get_pv_name(f, seg->area[s].u.pv.pv))) { | ||||
| 				stack; | ||||
| 				return 0; | ||||
| 			} | ||||
|  | ||||
| 			outf(f, "\"%s\", %u%s", name, | ||||
| 			     seg->area[s].u.pv.pe, | ||||
| 			     (s == seg->area_count - 1) ? "" : ","); | ||||
| 			break; | ||||
| 		case AREA_LV: | ||||
| 			outf(f, "\"%s\", %u%s", | ||||
| 			     seg->area[s].u.lv.lv->name, | ||||
| 			     seg->area[s].u.lv.le, | ||||
| 			     (s == seg->area_count - 1) ? "" : ","); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	_dec_indent(f); | ||||
| 	outf(f, "]"); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int _count_segments(struct logical_volume *lv) | ||||
| { | ||||
| 	int r = 0; | ||||
| @@ -463,7 +485,7 @@ static int _print_snapshot(struct formatter *f, struct snapshot *snap, | ||||
|  | ||||
| 	f->nl(f); | ||||
|  | ||||
| 	_outf(f, "snapshot%u {", count); | ||||
| 	outf(f, "snapshot%u {", count); | ||||
| 	_inc_indent(f); | ||||
|  | ||||
| 	if (!id_write_format(&snap->id, buffer, sizeof(buffer))) { | ||||
| @@ -471,32 +493,49 @@ static int _print_snapshot(struct formatter *f, struct snapshot *snap, | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	_outf(f, "id = \"%s\"", buffer); | ||||
| 	if (!print_flags(LVM_READ | LVM_WRITE | VISIBLE_LV, LV_FLAGS, | ||||
| 			 buffer, sizeof(buffer))) { | ||||
| 	outf(f, "id = \"%s\"", buffer); | ||||
|  | ||||
| 	seg.status = LVM_READ | LVM_WRITE | VISIBLE_LV; | ||||
| 	if (!print_flags(seg.status, LV_FLAGS, buffer, sizeof(buffer))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	_outf(f, "status = %s", buffer); | ||||
| 	_outf(f, "segment_count = 1"); | ||||
| 	outf(f, "status = %s", buffer); | ||||
| 	outf(f, "segment_count = 1"); | ||||
|  | ||||
| 	f->nl(f); | ||||
|  | ||||
| 	seg.type = SEG_SNAPSHOT; | ||||
| 	if (!(seg.segtype = get_segtype_from_string(snap->origin->vg->cmd, | ||||
| 						    "snapshot"))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	seg.le = 0; | ||||
| 	seg.len = snap->origin->le_count; | ||||
| 	seg.origin = snap->origin; | ||||
| 	seg.cow = snap->cow; | ||||
| 	seg.chunk_size = snap->chunk_size; | ||||
|  | ||||
| 	/* FIXME Dummy values */ | ||||
| 	list_init(&seg.list); | ||||
| 	seg.lv = snap->cow; | ||||
| 	seg.stripe_size = 0; | ||||
| 	seg.area_count = 0; | ||||
| 	seg.area_len = 0; | ||||
| 	seg.extents_copied = 0; | ||||
|  | ||||
| 	/* 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; | ||||
| 	} | ||||
|  | ||||
| 	_dec_indent(f); | ||||
| 	_outf(f, "}"); | ||||
| 	outf(f, "}"); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
| @@ -524,7 +563,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) | ||||
| 	struct list *lvh; | ||||
| 	struct logical_volume *lv; | ||||
| 	struct lv_segment *seg; | ||||
| 	char buffer[256]; | ||||
| 	char buffer[4096]; | ||||
| 	int seg_count; | ||||
|  | ||||
| 	/* | ||||
| @@ -533,14 +572,14 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) | ||||
| 	if (list_empty(&vg->lvs)) | ||||
| 		return 1; | ||||
|  | ||||
| 	_outf(f, "logical_volumes {"); | ||||
| 	outf(f, "logical_volumes {"); | ||||
| 	_inc_indent(f); | ||||
|  | ||||
| 	list_iterate(lvh, &vg->lvs) { | ||||
| 		lv = list_item(lvh, struct lv_list)->lv; | ||||
|  | ||||
| 		f->nl(f); | ||||
| 		_outf(f, "%s {", lv->name); | ||||
| 		outf(f, "%s {", lv->name); | ||||
| 		_inc_indent(f); | ||||
|  | ||||
| 		/* FIXME: Write full lvid */ | ||||
| @@ -549,24 +588,33 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		_outf(f, "id = \"%s\"", buffer); | ||||
| 		outf(f, "id = \"%s\"", buffer); | ||||
|  | ||||
| 		if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer))) { | ||||
| 			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_INHERIT) | ||||
| 			outf(f, "allocation_policy = \"%s\"", | ||||
| 			     get_alloc_string(lv->alloc)); | ||||
|  | ||||
| 		_outf(f, "status = %s", buffer); | ||||
| 		if (lv->alloc != ALLOC_DEFAULT) | ||||
| 			_outf(f, "allocation_policy = \"%s\"", | ||||
| 			      get_alloc_string(lv->alloc)); | ||||
| 		if (lv->read_ahead) | ||||
| 			_outf(f, "read_ahead = %u", lv->read_ahead); | ||||
| 			outf(f, "read_ahead = %u", lv->read_ahead); | ||||
| 		if (lv->major >= 0) | ||||
| 			_outf(f, "major = %d", lv->major); | ||||
| 			outf(f, "major = %d", lv->major); | ||||
| 		if (lv->minor >= 0) | ||||
| 			_outf(f, "minor = %d", lv->minor); | ||||
| 		_outf(f, "segment_count = %u", _count_segments(lv)); | ||||
| 			outf(f, "minor = %d", lv->minor); | ||||
| 		outf(f, "segment_count = %u", _count_segments(lv)); | ||||
| 		f->nl(f); | ||||
|  | ||||
| 		seg_count = 1; | ||||
| @@ -578,7 +626,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) | ||||
| 		} | ||||
|  | ||||
| 		_dec_indent(f); | ||||
| 		_outf(f, "}"); | ||||
| 		outf(f, "}"); | ||||
| 	} | ||||
|  | ||||
| 	if (!_print_snapshots(f, vg)) { | ||||
| @@ -587,7 +635,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) | ||||
| 	} | ||||
|  | ||||
| 	_dec_indent(f); | ||||
| 	_outf(f, "}"); | ||||
| 	outf(f, "}"); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
| @@ -660,7 +708,7 @@ static int _text_vg_export(struct formatter *f, | ||||
| 	if (f->header && !_print_header(f, vg, desc)) | ||||
| 		fail; | ||||
|  | ||||
| 	if (!_out(f, "%s {", vg->name)) | ||||
| 	if (!out_text(f, "%s {", vg->name)) | ||||
| 		fail; | ||||
|  | ||||
| 	_inc_indent(f); | ||||
| @@ -677,7 +725,7 @@ static int _text_vg_export(struct formatter *f, | ||||
| 		fail; | ||||
|  | ||||
| 	_dec_indent(f); | ||||
| 	if (!_out(f, "}")) | ||||
| 	if (!out_text(f, "}")) | ||||
| 		fail; | ||||
|  | ||||
| 	if (!f->header && !_print_header(f, vg, desc)) | ||||
| @@ -757,4 +805,4 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf, | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| #undef _outf | ||||
| #undef outf | ||||
|   | ||||
| @@ -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,6 +52,8 @@ static struct flag _lv_flags[] = { | ||||
| 	{VISIBLE_LV, "VISIBLE"}, | ||||
| 	{PVMOVE, "PVMOVE"}, | ||||
| 	{LOCKED, "LOCKED"}, | ||||
| 	{MIRRORED, NULL}, | ||||
| 	{VIRTUAL, NULL}, | ||||
| 	{0, NULL} | ||||
| }; | ||||
|  | ||||
| @@ -83,18 +94,21 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size) | ||||
|  | ||||
| 	for (f = 0; flags[f].mask; f++) { | ||||
| 		if (status & flags[f].mask) { | ||||
| 			status &= ~flags[f].mask; | ||||
|  | ||||
| 			/* Internal-only flag? */ | ||||
| 			if (!flags[f].description) | ||||
| 				continue; | ||||
|  | ||||
| 			if (!first) { | ||||
| 				if (!emit_to_buffer(&buffer, &size, ", ")) | ||||
| 					return 0; | ||||
|  | ||||
| 			} else | ||||
| 				first = 0; | ||||
|  | ||||
| 	 | ||||
| 			if (!emit_to_buffer(&buffer, &size, "\"%s\"", | ||||
| 					    flags[f].description)) | ||||
| 			    flags[f].description)) | ||||
| 				return 0; | ||||
|  | ||||
| 			status &= ~flags[f].mask; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -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" | ||||
| @@ -21,6 +30,7 @@ | ||||
| #include "xlate.h" | ||||
| #include "label.h" | ||||
| #include "memlock.h" | ||||
| #include "lvmcache.h" | ||||
|  | ||||
| #include <unistd.h> | ||||
| #include <sys/file.h> | ||||
| @@ -71,7 +81,7 @@ static int _lv_setup(struct format_instance *fid, struct logical_volume *lv) | ||||
| 	uint64_t max_size = UINT_MAX; | ||||
|  | ||||
| 	if (lv->size > max_size) { | ||||
| 		char *dummy = display_size(max_size / 2, SIZE_SHORT); | ||||
| 		char *dummy = display_size(max_size, SIZE_SHORT); | ||||
| 		log_error("logical volumes cannot be larger than %s", dummy); | ||||
| 		dbg_free(dummy); | ||||
| 		return 0; | ||||
| @@ -919,8 +929,7 @@ static int _mda_setup(const struct format_type *fmt, | ||||
| 	/* FIXME If creating new mdas, wipe them! */ | ||||
| 	if (mda_size1) { | ||||
| 		if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start1, | ||||
| 			     mda_size1)) | ||||
| 			return 0; | ||||
| 			     mda_size1)) return 0; | ||||
|  | ||||
| 		if (!dev_zero((struct device *) pv->dev, start1, | ||||
| 			      (size_t) (mda_size1 > | ||||
| @@ -967,8 +976,7 @@ static int _mda_setup(const struct format_type *fmt, | ||||
|  | ||||
| 	if (mda_size2) { | ||||
| 		if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start2, | ||||
| 			     mda_size2)) | ||||
| 			return 0; | ||||
| 			     mda_size2)) return 0; | ||||
| 		if (!dev_zero(pv->dev, start2, | ||||
| 			      (size_t) (mda_size1 > | ||||
| 					wipe_size ? wipe_size : mda_size1))) { | ||||
| @@ -1057,8 +1065,7 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv, | ||||
| 		} | ||||
| 	} | ||||
| 	if (!add_da | ||||
| 	    (fmt, NULL, &info->das, pv->pe_start << SECTOR_SHIFT, | ||||
| 	     UINT64_C(0))) { | ||||
| 	    (fmt, NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -1130,8 +1137,7 @@ static int _add_raw(struct list *raw_list, struct device_area *dev_area) | ||||
| 		rl = list_item(rlh, struct raw_list); | ||||
| 		/* FIXME Check size/overlap consistency too */ | ||||
| 		if (rl->dev_area.dev == dev_area->dev && | ||||
| 		    rl->dev_area.start == dev_area->start) | ||||
| 			return 1; | ||||
| 		    rl->dev_area.start == dev_area->start) return 1; | ||||
| 	} | ||||
|  | ||||
| 	if (!(rl = dbg_malloc(sizeof(struct raw_list)))) { | ||||
| @@ -1325,11 +1331,10 @@ static int _pv_setup(const struct format_type *fmt, | ||||
| 					    list_item(mdash, | ||||
| 						      struct metadata_area); | ||||
| 					if (mda2->ops != | ||||
| 					    &_metadata_text_raw_ops) | ||||
| 						continue; | ||||
| 					    &_metadata_text_raw_ops) continue; | ||||
| 					mdac2 = | ||||
| 					    (struct mda_context *) mda2-> | ||||
| 					    metadata_locn; | ||||
| 					    (struct mda_context *) | ||||
| 					    mda2->metadata_locn; | ||||
| 					if (!memcmp | ||||
| 					    (&mdac2->area, &mdac->area, | ||||
| 					     sizeof(mdac->area))) { | ||||
| @@ -1347,8 +1352,7 @@ static int _pv_setup(const struct format_type *fmt, | ||||
| 				} | ||||
|  | ||||
| 				if (!(mdac_new = pool_alloc(fmt->cmd->mem, | ||||
| 							    sizeof(*mdac_new)))) | ||||
| 				{ | ||||
| 							    sizeof(*mdac_new)))) { | ||||
| 					stack; | ||||
| 					return 0; | ||||
| 				} | ||||
| @@ -1477,8 +1481,7 @@ static struct format_instance *_create_text_instance(const struct format_type | ||||
| 				} | ||||
|  | ||||
| 				if (!(mdac_new = pool_alloc(fmt->cmd->mem, | ||||
| 							    sizeof(*mdac_new)))) | ||||
| 				{ | ||||
| 							    sizeof(*mdac_new)))) { | ||||
| 					stack; | ||||
| 					return NULL; | ||||
| 				} | ||||
| @@ -1584,21 +1587,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; | ||||
| @@ -1640,7 +1643,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 | FMT_UNLIMITED_VOLS; | ||||
|  | ||||
| 	if (!(mda_lists = dbg_malloc(sizeof(struct mda_lists)))) { | ||||
| 		log_error("Failed to allocate dir_list"); | ||||
| @@ -1663,7 +1666,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: " | ||||
| @@ -1679,7 +1682,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) { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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" | ||||
| @@ -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,13 +49,13 @@ 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(file))) { | ||||
| 		stack; | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	if ((!dev && !read_config_file(cf, file)) || | ||||
| 	    (dev && !read_config_fd(cf, dev, offset, size, | ||||
| 	if ((!dev && !read_config_file(cft)) || | ||||
| 	    (dev && !read_config_fd(cft, dev, offset, size, | ||||
| 				    offset2, size2, checksum_fn, checksum))) { | ||||
| 		log_error("Couldn't read volume group metadata."); | ||||
| 		goto out; | ||||
| @@ -56,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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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" | ||||
| @@ -13,6 +22,8 @@ | ||||
| #include "toolcontext.h" | ||||
| #include "lvmcache.h" | ||||
| #include "lv_alloc.h" | ||||
| #include "segtypes.h" | ||||
| #include "text_import.h" | ||||
|  | ||||
| typedef int (*section_fn) (struct format_instance * fid, struct pool * mem, | ||||
| 			   struct volume_group * vg, struct config_node * pvn, | ||||
| @@ -20,13 +31,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. | ||||
| @@ -40,7 +51,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; | ||||
| @@ -48,7 +59,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; | ||||
| 	} | ||||
| @@ -62,7 +73,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; | ||||
| 	} | ||||
| @@ -80,7 +91,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; | ||||
| 	} | ||||
| @@ -157,7 +168,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; | ||||
| 	} | ||||
| @@ -178,6 +189,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; | ||||
| @@ -215,17 +236,13 @@ static int _read_segment(struct pool *mem, struct volume_group *vg, | ||||
| 			 struct logical_volume *lv, struct config_node *sn, | ||||
| 			 struct hash_table *pv_hash) | ||||
| { | ||||
| 	unsigned int s; | ||||
| 	uint32_t area_count = 0; | ||||
| 	uint32_t area_count = 0u; | ||||
| 	struct lv_segment *seg; | ||||
| 	struct config_node *cn; | ||||
| 	struct config_value *cv; | ||||
| 	const char *seg_name = sn->key; | ||||
| 	uint32_t start_extent, extent_count; | ||||
| 	uint32_t chunk_size, extents_moved = 0u, seg_status = 0u; | ||||
| 	const char *org_name, *cow_name; | ||||
| 	struct logical_volume *org, *cow, *lv1; | ||||
| 	segment_type_t segtype; | ||||
| 	struct segment_type *segtype; | ||||
| 	const char *segtype_str; | ||||
|  | ||||
| 	if (!(sn = sn->child)) { | ||||
| 		log_error("Empty segment section."); | ||||
| @@ -244,40 +261,26 @@ static int _read_segment(struct pool *mem, struct volume_group *vg, | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	segtype = SEG_STRIPED;	/* Default */ | ||||
| 	if ((cn = find_config_node(sn, "type", '/'))) { | ||||
| 	segtype_str = "striped"; | ||||
|  | ||||
| 	if ((cn = find_config_node(sn, "type"))) { | ||||
| 		cv = cn->v; | ||||
| 		if (!cv || !cv->v.str) { | ||||
| 			log_error("Segment type must be a string."); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		segtype = get_segtype_from_string(cv->v.str); | ||||
| 		segtype_str = cv->v.str; | ||||
| 	} | ||||
|  | ||||
| 	if (segtype == SEG_STRIPED) { | ||||
| 		if (!_read_int32(sn, "stripe_count", &area_count)) { | ||||
| 			log_error("Couldn't read 'stripe_count' for " | ||||
| 				  "segment '%s'.", sn->key); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	if (!(segtype = get_segtype_from_string(vg->cmd, segtype_str))) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (segtype == SEG_MIRRORED) { | ||||
| 		if (!_read_int32(sn, "mirror_count", &area_count)) { | ||||
| 			log_error("Couldn't read 'mirror_count' for " | ||||
| 				  "segment '%s'.", sn->key); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (find_config_node(sn, "extents_moved", '/')) { | ||||
| 			if (_read_uint32(sn, "extents_moved", &extents_moved)) | ||||
| 				seg_status |= PVMOVE; | ||||
| 			else { | ||||
| 				log_error("Couldn't read 'extents_moved' for " | ||||
| 					  "segment '%s'.", sn->key); | ||||
| 				return 0; | ||||
| 			} | ||||
| 		} | ||||
| 	if (segtype->ops->text_import_area_count && | ||||
| 	    !segtype->ops->text_import_area_count(sn, &area_count)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!(seg = alloc_lv_segment(mem, area_count))) { | ||||
| @@ -289,149 +292,107 @@ static int _read_segment(struct pool *mem, struct volume_group *vg, | ||||
| 	seg->le = start_extent; | ||||
| 	seg->len = extent_count; | ||||
| 	seg->area_len = extent_count; | ||||
| 	seg->type = segtype; | ||||
| 	seg->status = seg_status; | ||||
| 	seg->extents_moved = extents_moved; | ||||
| 	seg->status = 0u; | ||||
| 	seg->segtype = segtype; | ||||
| 	seg->extents_copied = 0u; | ||||
|  | ||||
| 	switch (segtype) { | ||||
| 	case SEG_SNAPSHOT: | ||||
| 		lv->status |= SNAPSHOT; | ||||
|  | ||||
| 		if (!_read_uint32(sn, "chunk_size", &chunk_size)) { | ||||
| 			log_error("Couldn't read chunk size for snapshot."); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		log_suppress(1); | ||||
|  | ||||
| 		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))) { | ||||
| 			log_suppress(0); | ||||
| 			log_error("Snapshot origin not specified."); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		log_suppress(0); | ||||
|  | ||||
| 		if (!(cow = find_lv(vg, cow_name))) { | ||||
| 			log_error("Unknown logical volume specified for " | ||||
| 				  "snapshot cow store."); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (!(org = find_lv(vg, org_name))) { | ||||
| 			log_error("Unknown logical volume specified for " | ||||
| 				  "snapshot origin."); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (!vg_add_snapshot(org, cow, 1, &lv->lvid.id[1], chunk_size)) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 	case SEG_STRIPED: | ||||
| 		if ((area_count != 1) && | ||||
| 		    !_read_int32(sn, "stripe_size", &seg->stripe_size)) { | ||||
| 			log_error("Couldn't read stripe_size for segment '%s'.", | ||||
| 				  sn->key); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (!(cn = find_config_node(sn, "stripes", '/'))) { | ||||
| 			log_error("Couldn't find stripes array for segment " | ||||
| 				  "'%s'.", sn->key); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		seg->area_len /= area_count; | ||||
|  | ||||
| 	case SEG_MIRRORED: | ||||
| 		seg->area_count = area_count; | ||||
|  | ||||
| 		if (!seg->area_count) { | ||||
| 			log_error("Zero areas not allowed for segment '%s'", | ||||
| 				  sn->key); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if ((seg->type == SEG_MIRRORED) && | ||||
| 		    !(cn = find_config_node(sn, "mirrors", '/'))) { | ||||
| 			log_error("Couldn't find mirrors array for segment " | ||||
| 				  "'%s'.", sn->key); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		for (cv = cn->v, s = 0; cv && s < seg->area_count; | ||||
| 		     s++, cv = cv->next) { | ||||
|  | ||||
| 			/* first we read the pv */ | ||||
| 			const char *bad = "Badly formed areas array for " | ||||
| 			    "segment '%s'."; | ||||
| 			struct physical_volume *pv; | ||||
|  | ||||
| 			if (cv->type != CFG_STRING) { | ||||
| 				log_error(bad, sn->key); | ||||
| 				return 0; | ||||
| 			} | ||||
|  | ||||
| 			if (!cv->next) { | ||||
| 				log_error(bad, sn->key); | ||||
| 				return 0; | ||||
| 			} | ||||
|  | ||||
| 			if (cv->next->type != CFG_INT) { | ||||
| 				log_error(bad, sn->key); | ||||
| 				return 0; | ||||
| 			} | ||||
|  | ||||
| 			/* FIXME Cope if LV not yet read in */ | ||||
| 			if ((pv = hash_lookup(pv_hash, cv->v.str))) { | ||||
| 				seg->area[s].type = AREA_PV; | ||||
| 				seg->area[s].u.pv.pv = pv; | ||||
| 				seg->area[s].u.pv.pe = cv->next->v.i; | ||||
| 				/* | ||||
| 				 * Adjust extent counts in the pv and vg. | ||||
| 				 */ | ||||
| 				pv->pe_alloc_count += seg->area_len; | ||||
| 				vg->free_count -= seg->area_len; | ||||
|  | ||||
| 			} else if ((lv1 = find_lv(vg, cv->v.str))) { | ||||
| 				seg->area[s].type = AREA_LV; | ||||
| 				seg->area[s].u.lv.lv = lv1; | ||||
| 				seg->area[s].u.lv.le = cv->next->v.i; | ||||
| 			} else { | ||||
| 				log_error("Couldn't find volume '%s' " | ||||
| 					  "for segment '%s'.", | ||||
| 					  cv->v.str ? cv->v.str : "NULL", | ||||
| 					  seg_name); | ||||
| 				return 0; | ||||
| 			} | ||||
|  | ||||
| 			cv = cv->next; | ||||
| 		} | ||||
|  | ||||
| 		/* | ||||
| 		 * Check we read the correct number of stripes. | ||||
| 		 */ | ||||
| 		if (cv || (s < seg->area_count)) { | ||||
| 			log_error("Incorrect number of areas in area array " | ||||
| 				  "for segment '%s'.", seg_name); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	if (seg->segtype->ops->text_import && | ||||
| 	    !seg->segtype->ops->text_import(seg, sn, pv_hash)) { | ||||
| 		stack; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	/* 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; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * Insert into correct part of segment list. | ||||
| 	 */ | ||||
| 	_insert_segment(lv, seg); | ||||
|  | ||||
| 	if (seg->segtype->flags & SEG_AREAS_MIRRORED) | ||||
| 		lv->status |= MIRRORED; | ||||
|  | ||||
| 	if (seg->segtype->flags & SEG_VIRTUAL) | ||||
| 		lv->status |= VIRTUAL; | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int text_import_areas(struct lv_segment *seg, const struct config_node *sn, | ||||
| 		      const struct config_node *cn, struct hash_table *pv_hash) | ||||
| { | ||||
| 	unsigned int s; | ||||
| 	struct config_value *cv; | ||||
| 	struct logical_volume *lv1; | ||||
| 	const char *seg_name = sn->key; | ||||
|  | ||||
| 	if (!seg->area_count) { | ||||
| 		log_error("Zero areas not allowed for segment '%s'", sn->key); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	for (cv = cn->v, s = 0; cv && s < seg->area_count; s++, cv = cv->next) { | ||||
|  | ||||
| 		/* first we read the pv */ | ||||
| 		const char *bad = "Badly formed areas array for " | ||||
| 		    "segment '%s'."; | ||||
| 		struct physical_volume *pv; | ||||
|  | ||||
| 		if (cv->type != CFG_STRING) { | ||||
| 			log_error(bad, sn->key); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (!cv->next) { | ||||
| 			log_error(bad, sn->key); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (cv->next->type != CFG_INT) { | ||||
| 			log_error(bad, sn->key); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		/* FIXME Cope if LV not yet read in */ | ||||
| 		if ((pv = hash_lookup(pv_hash, cv->v.str))) { | ||||
| 			seg->area[s].type = AREA_PV; | ||||
| 			seg->area[s].u.pv.pv = pv; | ||||
| 			seg->area[s].u.pv.pe = cv->next->v.i; | ||||
| 			/* | ||||
| 			 * Adjust extent counts in the pv and vg. | ||||
| 			 */ | ||||
| 			pv->pe_alloc_count += seg->area_len; | ||||
| 			seg->lv->vg->free_count -= seg->area_len; | ||||
|  | ||||
| 		} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) { | ||||
| 			seg->area[s].type = AREA_LV; | ||||
| 			seg->area[s].u.lv.lv = lv1; | ||||
| 			seg->area[s].u.lv.le = cv->next->v.i; | ||||
| 		} else { | ||||
| 			log_error("Couldn't find volume '%s' " | ||||
| 				  "for segment '%s'.", | ||||
| 				  cv->v.str ? cv->v.str : "NULL", seg_name); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		cv = cv->next; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * Check we read the correct number of stripes. | ||||
| 	 */ | ||||
| 	if (cv || (s < seg->area_count)) { | ||||
| 		log_error("Incorrect number of areas in area array " | ||||
| 			  "for segment '%s'.", seg_name); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| @@ -518,7 +479,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; | ||||
| 	} | ||||
| @@ -528,8 +489,8 @@ static int _read_lvnames(struct format_instance *fid, struct pool *mem, | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	lv->alloc = ALLOC_DEFAULT; | ||||
| 	if ((cn = find_config_node(lvn, "allocation_policy", '/'))) { | ||||
| 	lv->alloc = ALLOC_INHERIT; | ||||
| 	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."); | ||||
| @@ -537,6 +498,10 @@ static int _read_lvnames(struct format_instance *fid, struct pool *mem, | ||||
| 		} | ||||
|  | ||||
| 		lv->alloc = get_alloc_from_string(cv->v.str); | ||||
| 		if (lv->alloc == ALLOC_INVALID) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* read_ahead defaults to 0 */ | ||||
| @@ -544,6 +509,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 +592,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 +612,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 +620,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 +649,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 +668,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; | ||||
| @@ -729,6 +703,21 @@ static struct volume_group *_read_vg(struct format_instance *fid, | ||||
| 		goto bad; | ||||
| 	} | ||||
|  | ||||
| 	vg->alloc = ALLOC_NORMAL; | ||||
| 	if ((cn = find_config_node(vgn, "allocation_policy"))) { | ||||
| 		struct config_value *cv = cn->v; | ||||
| 		if (!cv || !cv->v.str) { | ||||
| 			log_error("allocation_policy must be a string."); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		vg->alloc = get_alloc_from_string(cv->v.str); | ||||
| 		if (vg->alloc == ALLOC_INVALID) { | ||||
| 			stack; | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * The pv hash memoises the pv section names -> pv | ||||
| 	 * structures. | ||||
| @@ -748,6 +737,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 +781,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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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
									
								
							
							
						
						
									
										76
									
								
								lib/format_text/tags.c
									
									
									
									
									
										Normal 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; | ||||
| } | ||||
							
								
								
									
										36
									
								
								lib/format_text/text_export.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								lib/format_text/text_export.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| /* | ||||
|  * 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_TEXT_EXPORT_H | ||||
| #define _LVM_TEXT_EXPORT_H | ||||
|  | ||||
| #define outf(args...) do {if (!out_text(args)) {stack; return 0;}} while (0) | ||||
|  | ||||
| struct formatter; | ||||
| struct lv_segment; | ||||
|  | ||||
| int out_size(struct formatter *f, uint64_t size, const char *fmt, ...) | ||||
|     __attribute__ ((format(printf, 3, 4))); | ||||
|  | ||||
| int out_hint(struct formatter *f, const char *fmt, ...) | ||||
|     __attribute__ ((format(printf, 2, 3))); | ||||
|  | ||||
| int out_text(struct formatter *f, const char *fmt, ...) | ||||
|     __attribute__ ((format(printf, 2, 3))); | ||||
|  | ||||
| int out_areas(struct formatter *f, const struct lv_segment *seg, | ||||
| 	      const char *type); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										25
									
								
								lib/format_text/text_import.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								lib/format_text/text_import.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| /* | ||||
|  * 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_TEXT_IMPORT_H | ||||
| #define _LVM_TEXT_IMPORT_H | ||||
|  | ||||
| struct lv_segment; | ||||
| struct config_node; | ||||
|  | ||||
| int text_import_areas(struct lv_segment *seg, const struct config_node *sn, | ||||
| 		      const struct config_node *cn, struct hash_table *pv_hash); | ||||
|  | ||||
| #endif | ||||
| @@ -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" | ||||
| @@ -9,6 +18,7 @@ | ||||
| #include "layout.h" | ||||
| #include "label.h" | ||||
| #include "xlate.h" | ||||
| #include "lvmcache.h" | ||||
|  | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
|   | ||||
| @@ -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" | ||||
| @@ -10,6 +19,7 @@ | ||||
| #include "crc.h" | ||||
| #include "xlate.h" | ||||
| #include "lvmcache.h" | ||||
| #include "metadata.h" | ||||
|  | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
| @@ -69,6 +79,8 @@ void label_exit(void) | ||||
| 		li->l->ops->destroy(li->l); | ||||
| 		_free_li(li); | ||||
| 	} | ||||
|  | ||||
| 	list_init(&_labellers); | ||||
| } | ||||
|  | ||||
| int label_register_handler(const char *name, struct labeller *handler) | ||||
|   | ||||
| @@ -1,13 +1,21 @@ | ||||
| /* | ||||
|  * 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 "lvmcache.h" | ||||
| #include "uuid.h" | ||||
| #include "device.h" | ||||
|  | ||||
| @@ -16,6 +24,8 @@ | ||||
| #define LABEL_SCAN_SECTORS 4L | ||||
| #define LABEL_SCAN_SIZE (LABEL_SCAN_SECTORS << SECTOR_SHIFT) | ||||
|  | ||||
| struct labeller; | ||||
|  | ||||
| /* On disk - 32 bytes */ | ||||
| struct label_header { | ||||
| 	uint8_t id[8];		/* LABELONE */ | ||||
|   | ||||
| @@ -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" | ||||
| @@ -11,10 +19,12 @@ | ||||
| #include "sharedlib.h" | ||||
|  | ||||
| static void *_locking_lib = NULL; | ||||
| static void (*_reset_fn) (void) = 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) | ||||
| @@ -36,9 +46,16 @@ static void _fin_external_locking(void) | ||||
| 	_init_fn = NULL; | ||||
| 	_end_fn = NULL; | ||||
| 	_lock_fn = NULL; | ||||
| 	_reset_fn = NULL; | ||||
| } | ||||
|  | ||||
| int init_external_locking(struct locking_type *locking, struct config_tree *cf) | ||||
| static void _reset_external_locking(void) | ||||
| { | ||||
| 	if (_reset_fn) | ||||
| 		_reset_fn(); | ||||
| } | ||||
|  | ||||
| int init_external_locking(struct locking_type *locking, struct config_tree *cft) | ||||
| { | ||||
| 	const char *libname; | ||||
|  | ||||
| @@ -49,19 +66,22 @@ int init_external_locking(struct locking_type *locking, struct config_tree *cf) | ||||
|  | ||||
| 	locking->lock_resource = _lock_resource; | ||||
| 	locking->fin_locking = _fin_external_locking; | ||||
| 	locking->reset_locking = _reset_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"))) { | ||||
| 	    !(_reset_fn = dlsym(_locking_lib, "reset_locking")) || | ||||
| 	    !(_end_fn = dlsym(_locking_lib, "locking_end"))) { | ||||
| 		log_error("Shared library %s does not contain locking " | ||||
| 			  "functions", libname); | ||||
| 		dlclose(_locking_lib); | ||||
| @@ -70,5 +90,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); | ||||
| } | ||||
|   | ||||
| @@ -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" | ||||
| @@ -224,9 +232,14 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource, | ||||
| 			if (!lv_resume_if_active(cmd, resource)) | ||||
| 				return 0; | ||||
| 			break; | ||||
| 		case LCK_NULL: | ||||
| 			log_debug("Locking LV %s (NL)", resource); | ||||
| 			if (!lv_deactivate(cmd, resource)) | ||||
| 				return 0; | ||||
| 			break; | ||||
| 		case LCK_READ: | ||||
| 			log_debug("Locking LV %s (R)", resource); | ||||
| 			if (!lv_activate(cmd, resource)) | ||||
| 			if (!lv_activate_with_filter(cmd, resource)) | ||||
| 				return 0; | ||||
| 			break; | ||||
| 		case LCK_WRITE: | ||||
| @@ -236,7 +249,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource, | ||||
| 			break; | ||||
| 		case LCK_EXCL: | ||||
| 			log_debug("Locking LV %s (EX)", resource); | ||||
| 			if (!lv_deactivate(cmd, resource)) | ||||
| 			if (!lv_activate_with_filter(cmd, resource)) | ||||
| 				return 0; | ||||
| 			break; | ||||
| 		default: | ||||
| @@ -252,15 +265,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)) | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user