mirror of
				git://sourceware.org/git/lvm2.git
				synced 2025-11-03 08:23:48 +03:00 
			
		
		
		
	Compare commits
	
		
			313 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					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 | ||
| 
						 | 
					859fe69083 | ||
| 
						 | 
					f6f2205ddb | ||
| 
						 | 
					0f9a03ef61 | ||
| 
						 | 
					9aa417c084 | ||
| 
						 | 
					7b70952f5d | ||
| 
						 | 
					edd3d07b49 | ||
| 
						 | 
					5293d0a4ec | ||
| 
						 | 
					3c8c7beae1 | ||
| 
						 | 
					9c3ba9fdcd | ||
| 
						 | 
					fb1748fb0f | ||
| 
						 | 
					0a109fbd03 | ||
| 
						 | 
					5cf64db74e | ||
| 
						 | 
					488cc94f36 | ||
| 
						 | 
					e15846bf79 | ||
| 
						 | 
					752bd00674 | ||
| 
						 | 
					7fadfcbe32 | ||
| 
						 | 
					41141e75bb | ||
| 
						 | 
					50f641e627 | ||
| 
						 | 
					c7883fd093 | ||
| 
						 | 
					4fcb24b2b1 | ||
| 
						 | 
					5003557935 | ||
| 
						 | 
					bdf1ba84da | ||
| 
						 | 
					b0b4def983 | ||
| 
						 | 
					cc184bbe9e | ||
| 
						 | 
					ad30c830aa | ||
| 
						 | 
					1d791a8af4 | ||
| 
						 | 
					e63c51cd97 | ||
| 
						 | 
					f202e32908 | ||
| 
						 | 
					26e1a08e82 | ||
| 
						 | 
					4d5119d435 | ||
| 
						 | 
					75e34ea62e | ||
| 
						 | 
					0a183d6274 | ||
| 
						 | 
					21d8060aea | ||
| 
						 | 
					9cbe906f60 | ||
| 
						 | 
					8ce4137399 | ||
| 
						 | 
					5f8a139347 | ||
| 
						 | 
					9bb009a3fe | ||
| 
						 | 
					726d65923f | ||
| 
						 | 
					8a6be4cb2d | ||
| 
						 | 
					10b06beb8e | ||
| 
						 | 
					81318c7968 | ||
| 
						 | 
					47a2c1c6e5 | ||
| 
						 | 
					39cee65c6b | ||
| 
						 | 
					8582ec724e | ||
| 
						 | 
					b0139682e8 | ||
| 
						 | 
					d39c475a6d | ||
| 
						 | 
					48f38354c6 | ||
| 
						 | 
					cd5a920ed5 | ||
| 
						 | 
					71bc1f378d | ||
| 
						 | 
					0ee6c31cff | ||
| 
						 | 
					af89a9971e | ||
| 
						 | 
					c718a8ef72 | ||
| 
						 | 
					8c8ad0faf0 | ||
| 
						 | 
					314d5bbb7f | ||
| 
						 | 
					102255757a | ||
| 
						 | 
					914067a0d0 | ||
| 
						 | 
					06e3ae2536 | ||
| 
						 | 
					7f9b252556 | ||
| 
						 | 
					3d700e243f | ||
| 
						 | 
					bcfc78ce11 | ||
| 
						 | 
					09241765d5 | ||
| 
						 | 
					671c83c265 | ||
| 
						 | 
					772d28b766 | ||
| 
						 | 
					c26fcea58d | ||
| 
						 | 
					1e5e26dbff | ||
| 
						 | 
					742fc54864 | ||
| 
						 | 
					49738f43c0 | ||
| 
						 | 
					9f85f61010 | ||
| 
						 | 
					239f422039 | ||
| 
						 | 
					67af3c37be | ||
| 
						 | 
					a9442385c4 | ||
| 
						 | 
					8c9cd10b8b | ||
| 
						 | 
					72542059dd | ||
| 
						 | 
					a843fc6d40 | ||
| 
						 | 
					4beed60c08 | ||
| 
						 | 
					4049c1e480 | ||
| 
						 | 
					8449314da2 | ||
| 
						 | 
					63ad057028 | ||
| 
						 | 
					e720464330 | ||
| 
						 | 
					24036afef9 | ||
| 
						 | 
					c78fa1a1bc | ||
| 
						 | 
					faa8b9022c | ||
| 
						 | 
					729bafef7a | ||
| 
						 | 
					590b028632 | ||
| 
						 | 
					8150d00f36 | ||
| 
						 | 
					060065926f | ||
| 
						 | 
					70babe8a28 | ||
| 
						 | 
					c36e09664f | ||
| 
						 | 
					a9672246f3 | ||
| 
						 | 
					ff571884e9 | ||
| 
						 | 
					475138bceb | ||
| 
						 | 
					4a8af199c2 | ||
| 
						 | 
					bdabf5db72 | ||
| 
						 | 
					6a5f21b34e | ||
| 
						 | 
					d608be103c | ||
| 
						 | 
					374bb5d18a | ||
| 
						 | 
					031d6c25ff | ||
| 
						 | 
					223fb7b075 | ||
| 
						 | 
					a746741971 | ||
| 
						 | 
					120faf2a58 | ||
| 
						 | 
					990bca0dc6 | ||
| 
						 | 
					3406472db7 | ||
| 
						 | 
					1bd733c9f6 | ||
| 
						 | 
					238c7f982e | ||
| 
						 | 
					fcb81147cb | ||
| 
						 | 
					1915b73783 | ||
| 
						 | 
					ee79e621fb | ||
| 
						 | 
					d203275a3b | ||
| 
						 | 
					9e8a996222 | ||
| 
						 | 
					0126b0b3ed | ||
| 
						 | 
					458928612c | ||
| 
						 | 
					e33f88e28d | ||
| 
						 | 
					be570bbf9e | ||
| 
						 | 
					f59b4be110 | ||
| 
						 | 
					37336e41be | ||
| 
						 | 
					d24a1a3f0a | ||
| 
						 | 
					f7258955bd | ||
| 
						 | 
					2a1eae5d6f | ||
| 
						 | 
					50ee0a4adb | ||
| 
						 | 
					955a26584e | ||
| 
						 | 
					1d3e407c8f | ||
| 
						 | 
					cb809c4596 | ||
| 
						 | 
					53bbe2888e | ||
| 
						 | 
					7246f476a5 | ||
| 
						 | 
					0785d1c390 | ||
| 
						 | 
					85d2c49d14 | ||
| 
						 | 
					8b77d62b7f | ||
| 
						 | 
					373058a32a | ||
| 
						 | 
					e6293c2c8c | ||
| 
						 | 
					eff181c959 | ||
| 
						 | 
					54752c2305 | ||
| 
						 | 
					b4753c044f | ||
| 
						 | 
					26493424ae | ||
| 
						 | 
					0282fd1332 | ||
| 
						 | 
					b9a019a08b | ||
| 
						 | 
					66f6a0e687 | ||
| 
						 | 
					2dd1b9f97d | ||
| 
						 | 
					89615f3045 | ||
| 
						 | 
					7e46192f67 | ||
| 
						 | 
					e78d985cdf | ||
| 
						 | 
					e8c4bf56fe | ||
| 
						 | 
					e6aa7d323d | ||
| 
						 | 
					fca8e25929 | ||
| 
						 | 
					8e8ac286b4 | ||
| 
						 | 
					7d9770b9a2 | ||
| 
						 | 
					1996230460 | ||
| 
						 | 
					de7897a864 | ||
| 
						 | 
					e2884dcdb7 | ||
| 
						 | 
					544a53a42b | ||
| 
						 | 
					2e4787bfc8 | ||
| 
						 | 
					1829eeb171 | ||
| 
						 | 
					c7488e3c4a | ||
| 
						 | 
					3bf9606383 | ||
| 
						 | 
					4f43f18f0a | ||
| 
						 | 
					5b7f197397 | ||
| 
						 | 
					018141c97f | ||
| 
						 | 
					4d7813e57c | ||
| 
						 | 
					605c60208f | ||
| 
						 | 
					884fafcc30 | ||
| 
						 | 
					56baa90320 | ||
| 
						 | 
					6bb20ee09e | ||
| 
						 | 
					541356430c | ||
| 
						 | 
					2f4d91fd69 | ||
| 
						 | 
					f58c5e6b30 | ||
| 
						 | 
					0311d0132c | ||
| 
						 | 
					c946c97402 | ||
| 
						 | 
					84a6f51318 | ||
| 
						 | 
					24a1501b0d | ||
| 
						 | 
					383b6f5fcc | ||
| 
						 | 
					633dd7ff9b | ||
| 
						 | 
					580624fad6 | ||
| 
						 | 
					a8190f7efa | ||
| 
						 | 
					dd2157534b | ||
| 
						 | 
					38a90e7669 | ||
| 
						 | 
					6bfc526dcd | ||
| 
						 | 
					aadb8a7405 | ||
| 
						 | 
					27082bf77e | ||
| 
						 | 
					a2903c80cd | ||
| 
						 | 
					9a77c5369c | ||
| 
						 | 
					3c30741a19 | ||
| 
						 | 
					7028ad4ec0 | ||
| 
						 | 
					8de750c6aa | ||
| 
						 | 
					04f98de9ee | ||
| 
						 | 
					a1a019784b | ||
| 
						 | 
					4aeeae77bd | ||
| 
						 | 
					651cfc2b78 | ||
| 
						 | 
					2ef8af25e2 | ||
| 
						 | 
					0b13852a5b | ||
| 
						 | 
					13427578c9 | ||
| 
						 | 
					d89ca2087e | ||
| 
						 | 
					8b0ea9fba6 | ||
| 
						 | 
					9f0b653d5a | ||
| 
						 | 
					659a339233 | ||
| 
						 | 
					4c29f177a0 | ||
| 
						 | 
					d664e63d55 | ||
| 
						 | 
					2493509dbe | ||
| 
						 | 
					1c8b27f554 | ||
| 
						 | 
					68297b7186 | 
							
								
								
									
										2
									
								
								BUGS
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								BUGS
									
									
									
									
									
								
							@@ -1,2 +0,0 @@
 | 
			
		||||
Snapshots under 2.4.18 can deadlock due to a bug in the VM system.
 | 
			
		||||
2.4.19-pre8 is fine.
 | 
			
		||||
							
								
								
									
										40
									
								
								Makefile.in
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								Makefile.in
									
									
									
									
									
								
							@@ -1,35 +1,45 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2001 Sistina Software
 | 
			
		||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This LVM library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Library General Public
 | 
			
		||||
# License as published by the Free Software Foundation; either
 | 
			
		||||
# version 2 of the License, or (at your option) any later version.
 | 
			
		||||
# This file is part of the LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This LVM library is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
# Library General Public License for more details.
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
# of the GNU General Public License v.2.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU Library General Public
 | 
			
		||||
# License along with this LVM library; if not, write to the Free
 | 
			
		||||
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 | 
			
		||||
# MA 02111-1307, USA
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
VPATH = @srcdir@
 | 
			
		||||
 | 
			
		||||
SUBDIRS = include man lib tools
 | 
			
		||||
SUBDIRS = doc include man 
 | 
			
		||||
 | 
			
		||||
ifeq ("@INTL@", "yes")
 | 
			
		||||
  SUBDIRS += po
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
SUBDIRS += lib tools
 | 
			
		||||
 | 
			
		||||
ifeq ($(MAKECMDGOALS),distclean)
 | 
			
		||||
  SUBDIRS += lib/format1 \
 | 
			
		||||
	     po \
 | 
			
		||||
	     test/mm test/device test/format1 test/regex test/filters
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
include make.tmpl
 | 
			
		||||
 | 
			
		||||
lib: include
 | 
			
		||||
tools: include lib
 | 
			
		||||
tools: lib
 | 
			
		||||
po: lib tools
 | 
			
		||||
 | 
			
		||||
ifeq ("@INTL@", "yes")
 | 
			
		||||
lib.pofile: include.pofile
 | 
			
		||||
tools.pofile: lib.pofile
 | 
			
		||||
po.pofile: lib.pofile tools.pofile
 | 
			
		||||
pofile: po.pofile
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								README
									
									
									
									
									
								
							@@ -1,13 +1,11 @@
 | 
			
		||||
This directory contains a beta release of LVM2, the new version of 
 | 
			
		||||
the userland LVM tools designed for the new device-mapper for 
 | 
			
		||||
the Linux kernel.
 | 
			
		||||
This directory contains LVM2, the new version of the userland LVM
 | 
			
		||||
tools designed for the new device-mapper for the Linux kernel.
 | 
			
		||||
 | 
			
		||||
The device-mapper needs to be installed before compiling these LVM2 tools.
 | 
			
		||||
 | 
			
		||||
For more information about LVM2 read the WHATS_NEW file.
 | 
			
		||||
Installation instructions are in INSTALL.
 | 
			
		||||
 | 
			
		||||
This is beta-quality software, released for testing purposes only.
 | 
			
		||||
There is no warranty - see COPYING and COPYING.LIB.
 | 
			
		||||
 | 
			
		||||
Tarballs are available from:
 | 
			
		||||
@@ -15,11 +13,11 @@ Tarballs are available from:
 | 
			
		||||
  ftp://ftp.sistina.com/pub/LVM2/device-mapper/
 | 
			
		||||
 | 
			
		||||
To access the CVS tree use:
 | 
			
		||||
  cvs -d :pserver:cvs@tech.sistina.com:/data/cvs login
 | 
			
		||||
  CVS password: cvs1
 | 
			
		||||
  cvs -d :pserver:cvs@tech.sistina.com:/data/cvs checkout LVM2
 | 
			
		||||
  cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 login
 | 
			
		||||
  CVS password: cvs
 | 
			
		||||
  cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 co LVM2
 | 
			
		||||
 | 
			
		||||
Mailing list for discussion/bug reports etc.
 | 
			
		||||
  lvm-devel@sistina.com
 | 
			
		||||
  Subscribe from http://lists.sistina.com/mailman/listinfo/lvm-devel
 | 
			
		||||
  linux-lvm@redhat.com
 | 
			
		||||
  Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										96
									
								
								WHATS_NEW
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								WHATS_NEW
									
									
									
									
									
								
							@@ -1,4 +1,91 @@
 | 
			
		||||
Mondy 18th November 2002
 | 
			
		||||
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:
 | 
			
		||||
  Backwards compatibility with LVM1 metadata improved.
 | 
			
		||||
  Missing man pages written.
 | 
			
		||||
  Tool error codes made more consistent.
 | 
			
		||||
  vgmknodes written.
 | 
			
		||||
  O_DIRECT can be turned off if it doesn't work in your kernel.
 | 
			
		||||
  dumpconfig to display the active configuration file
 | 
			
		||||
 | 
			
		||||
You need to update libdevmapper before using 'vgmknodes' or 'vgscan --mknodes'.
 | 
			
		||||
If your root filesystem is on an LV, you should run one of those two
 | 
			
		||||
commands to fix up the special files in /dev in your real root filesystem 
 | 
			
		||||
after finishing with your initrd.  Also, remember you can use
 | 
			
		||||
'vgchange --ignorelockingfailure' on your initrd if the tool fails because
 | 
			
		||||
it can't write a lock file to a read-only filesystem.
 | 
			
		||||
 | 
			
		||||
Wednesday 30th April 2003
 | 
			
		||||
=========================
 | 
			
		||||
A pvmove implementation is now available for the new metadata format.
 | 
			
		||||
 | 
			
		||||
When running a command that allocates space (e.g. lvcreate), you can now
 | 
			
		||||
restrict not only which disk(s) may be used but also the Physical Extents 
 | 
			
		||||
on those disks.  e.g. lvcreate -L 10 vg1 /dev/hda6:1000-2000:3000-4000
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Monday 18th November 2002
 | 
			
		||||
========================
 | 
			
		||||
 | 
			
		||||
The new format of LVM metadata is ready for you to test!
 | 
			
		||||
@@ -15,7 +102,8 @@ While testing, we recommend turning logging on in the configuration file
 | 
			
		||||
to provide us with diagnostic information:
 | 
			
		||||
  log {
 | 
			
		||||
        file="/tmp/lvm2.log"
 | 
			
		||||
	level=6
 | 
			
		||||
	level=7
 | 
			
		||||
	activation=1
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
You should schedule regular backups of your configuration file and
 | 
			
		||||
@@ -65,7 +153,7 @@ changes.
 | 
			
		||||
What's not finished?
 | 
			
		||||
====================
 | 
			
		||||
The internal cache.  If you turn on debugging output you'll see lots of
 | 
			
		||||
repeated disk reads, many of which will eventually get optimised out.
 | 
			
		||||
repeated messages, many of which will eventually get optimised out.
 | 
			
		||||
 | 
			
		||||
--test sometimes causes a command to fail (e.g. vgconvert --test) even 
 | 
			
		||||
though the real command would work: again, fixing this is waiting for 
 | 
			
		||||
@@ -78,9 +166,7 @@ finds something unexpected.  This applies particularly to tools that
 | 
			
		||||
work on more than one volume group at once (e.g. vgsplit).
 | 
			
		||||
 | 
			
		||||
Display output.  Some metadata information cannot yet be displayed.
 | 
			
		||||
Work has started on new display tools.
 | 
			
		||||
 | 
			
		||||
Recovery tools to salvage "lost" metadata directly from the disks:
 | 
			
		||||
but we hope the new format will mean such tools are hardly ever needed!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										58
									
								
								WHATS_NEW_DM
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								WHATS_NEW_DM
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
Version 1.00.17 - 17 Apr 2004
 | 
			
		||||
=============================
 | 
			
		||||
  configure --with-owner= --with-group= to avoid -o and -g args to 'install'
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1082
									
								
								autoconf/config.guess
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1082
									
								
								autoconf/config.guess
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										560
									
								
								autoconf/config.sub
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										560
									
								
								autoconf/config.sub
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +1,10 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
# Configuration validation subroutine script, version 1.1.
 | 
			
		||||
#   Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc.
 | 
			
		||||
# Configuration validation subroutine script.
 | 
			
		||||
#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 | 
			
		||||
#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
# can handle that machine.  It does not imply ALL GNU software can.
 | 
			
		||||
@@ -25,6 +29,9 @@
 | 
			
		||||
# 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>.  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.
 | 
			
		||||
# If it is invalid, we print an error message on stderr and exit with code 1.
 | 
			
		||||
@@ -45,30 +52,73 @@
 | 
			
		||||
#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
 | 
			
		||||
# It is wrong to echo any other type of specification.
 | 
			
		||||
 | 
			
		||||
if [ x$1 = x ]
 | 
			
		||||
then
 | 
			
		||||
	echo Configuration name missing. 1>&2
 | 
			
		||||
	echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
 | 
			
		||||
	echo "or     $0 ALIAS" 1>&2
 | 
			
		||||
	echo where ALIAS is a recognized configuration type. 1>&2
 | 
			
		||||
	exit 1
 | 
			
		||||
fi
 | 
			
		||||
me=`echo "$0" | sed -e 's,.*/,,'`
 | 
			
		||||
 | 
			
		||||
# First pass through any local machine types.
 | 
			
		||||
case $1 in
 | 
			
		||||
	*local*)
 | 
			
		||||
		echo $1
 | 
			
		||||
		exit 0
 | 
			
		||||
		;;
 | 
			
		||||
	*)
 | 
			
		||||
	;;
 | 
			
		||||
usage="\
 | 
			
		||||
Usage: $0 [OPTION] CPU-MFR-OPSYS
 | 
			
		||||
       $0 [OPTION] ALIAS
 | 
			
		||||
 | 
			
		||||
Canonicalize a configuration name.
 | 
			
		||||
 | 
			
		||||
Operation modes:
 | 
			
		||||
  -h, --help         print this help, then exit
 | 
			
		||||
  -t, --time-stamp   print date of last modification, then exit
 | 
			
		||||
  -v, --version      print version number, then exit
 | 
			
		||||
 | 
			
		||||
Report bugs and patches to <config-patches@gnu.org>."
 | 
			
		||||
 | 
			
		||||
version="\
 | 
			
		||||
GNU config.sub ($timestamp)
 | 
			
		||||
 | 
			
		||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
 | 
			
		||||
Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
This is free software; see the source for copying conditions.  There is NO
 | 
			
		||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
 | 
			
		||||
 | 
			
		||||
help="
 | 
			
		||||
Try \`$me --help' for more information."
 | 
			
		||||
 | 
			
		||||
# Parse command line
 | 
			
		||||
while test $# -gt 0 ; do
 | 
			
		||||
  case $1 in
 | 
			
		||||
    --time-stamp | --time* | -t )
 | 
			
		||||
       echo "$timestamp" ; exit 0 ;;
 | 
			
		||||
    --version | -v )
 | 
			
		||||
       echo "$version" ; exit 0 ;;
 | 
			
		||||
    --help | --h* | -h )
 | 
			
		||||
       echo "$usage"; exit 0 ;;
 | 
			
		||||
    -- )     # Stop option processing
 | 
			
		||||
       shift; break ;;
 | 
			
		||||
    - )	# Use stdin as input.
 | 
			
		||||
       break ;;
 | 
			
		||||
    -* )
 | 
			
		||||
       echo "$me: invalid option $1$help"
 | 
			
		||||
       exit 1 ;;
 | 
			
		||||
 | 
			
		||||
    *local*)
 | 
			
		||||
       # First pass through any local machine types.
 | 
			
		||||
       echo $1
 | 
			
		||||
       exit 0;;
 | 
			
		||||
 | 
			
		||||
    * )
 | 
			
		||||
       break ;;
 | 
			
		||||
  esac
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
case $# in
 | 
			
		||||
 0) echo "$me: missing argument$help" >&2
 | 
			
		||||
    exit 1;;
 | 
			
		||||
 1) ;;
 | 
			
		||||
 *) echo "$me: too many arguments$help" >&2
 | 
			
		||||
    exit 1;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
 | 
			
		||||
# Here we must recognize all the valid KERNEL-OS combinations.
 | 
			
		||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 | 
			
		||||
case $maybe_os in
 | 
			
		||||
  linux-gnu*)
 | 
			
		||||
  nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
 | 
			
		||||
    os=-$maybe_os
 | 
			
		||||
    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
 | 
			
		||||
    ;;
 | 
			
		||||
@@ -94,7 +144,7 @@ case $os in
 | 
			
		||||
	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
 | 
			
		||||
	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
 | 
			
		||||
	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
 | 
			
		||||
	-apple)
 | 
			
		||||
	-apple | -axis)
 | 
			
		||||
		os=
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
		;;
 | 
			
		||||
@@ -105,9 +155,17 @@ case $os in
 | 
			
		||||
	-scout)
 | 
			
		||||
		;;
 | 
			
		||||
	-wrs)
 | 
			
		||||
		os=vxworks
 | 
			
		||||
		os=-vxworks
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
		;;
 | 
			
		||||
	-chorusos*)
 | 
			
		||||
		os=-chorusos
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
		;;
 | 
			
		||||
 	-chorusrdb)
 | 
			
		||||
 		os=-chorusrdb
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
 		;;
 | 
			
		||||
	-hiux*)
 | 
			
		||||
		os=-hiuxwe2
 | 
			
		||||
		;;
 | 
			
		||||
@@ -156,33 +214,72 @@ case $os in
 | 
			
		||||
	-psos*)
 | 
			
		||||
		os=-psos
 | 
			
		||||
		;;
 | 
			
		||||
	-mint | -mint[0-9]*)
 | 
			
		||||
		basic_machine=m68k-atari
 | 
			
		||||
		os=-mint
 | 
			
		||||
		;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
# Decode aliases for certain CPU-COMPANY combinations.
 | 
			
		||||
case $basic_machine in
 | 
			
		||||
	# Recognize the basic CPU types without company name.
 | 
			
		||||
	# Some are omitted here because they have special meanings below.
 | 
			
		||||
	tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
 | 
			
		||||
		| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
 | 
			
		||||
		| 580 | i960 | h8300 \
 | 
			
		||||
		| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
 | 
			
		||||
		| alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \
 | 
			
		||||
		| we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
 | 
			
		||||
		| 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
 | 
			
		||||
		| mips64orion | mips64orionel | mipstx39 | mipstx39el \
 | 
			
		||||
		| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
 | 
			
		||||
		| mips64vr5000 | miprs64vr5000el | mcore \
 | 
			
		||||
		| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
 | 
			
		||||
		| thumb | d10v)
 | 
			
		||||
	1750a | 580 \
 | 
			
		||||
	| a29k \
 | 
			
		||||
	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
 | 
			
		||||
	| 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 | 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 \
 | 
			
		||||
	| 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 | or32 \
 | 
			
		||||
	| pdp10 | pdp11 | pj | pjl \
 | 
			
		||||
	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
 | 
			
		||||
	| pyramid \
 | 
			
		||||
	| 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 | xstormy16 | xtensa \
 | 
			
		||||
	| z8k)
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65)
 | 
			
		||||
	m6811 | m68hc11 | m6812 | m68hc12)
 | 
			
		||||
		# Motorola 68HC11/12.
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		os=-none
 | 
			
		||||
		;;
 | 
			
		||||
	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
 | 
			
		||||
		;;
 | 
			
		||||
 | 
			
		||||
	# We use `pc' rather than `unknown'
 | 
			
		||||
	# because (1) that's what they normally are, and
 | 
			
		||||
	# (2) the word "unknown" tends to confuse beginning users.
 | 
			
		||||
	i[34567]86)
 | 
			
		||||
	i*86 | x86_64)
 | 
			
		||||
	  basic_machine=$basic_machine-pc
 | 
			
		||||
	  ;;
 | 
			
		||||
	# Object if more than one company name word.
 | 
			
		||||
@@ -191,24 +288,60 @@ case $basic_machine in
 | 
			
		||||
		exit 1
 | 
			
		||||
		;;
 | 
			
		||||
	# Recognize the basic CPU types with company name.
 | 
			
		||||
	# FIXME: clean up the formatting here.
 | 
			
		||||
	vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
 | 
			
		||||
	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
 | 
			
		||||
	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
 | 
			
		||||
	      | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
 | 
			
		||||
	      | xmp-* | ymp-* \
 | 
			
		||||
	      | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \
 | 
			
		||||
	      | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \
 | 
			
		||||
	      | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
 | 
			
		||||
	      | clipper-* | orion-* \
 | 
			
		||||
	      | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
 | 
			
		||||
	      | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
 | 
			
		||||
	      | mips64el-* | mips64orion-* | mips64orionel-* \
 | 
			
		||||
	      | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
 | 
			
		||||
	      | mipstx39-* | mipstx39el-* | mcore-* \
 | 
			
		||||
	      | f301-* | armv*-* | t3e-* \
 | 
			
		||||
	      | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
 | 
			
		||||
	      | thumb-* | v850-* | d30v-* | tic30-* | c30-* )
 | 
			
		||||
	580-* \
 | 
			
		||||
	| a29k-* \
 | 
			
		||||
	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
 | 
			
		||||
	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
 | 
			
		||||
	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
 | 
			
		||||
	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 | 
			
		||||
	| avr-* \
 | 
			
		||||
	| bs2000-* \
 | 
			
		||||
	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
 | 
			
		||||
	| clipper-* | cydra-* \
 | 
			
		||||
	| d10v-* | d30v-* | dlx-* \
 | 
			
		||||
	| elxsi-* \
 | 
			
		||||
	| 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[012346]0-* | m68360-* | m683?2-* | m68k-* \
 | 
			
		||||
	| m88110-* | m88k-* | mcore-* \
 | 
			
		||||
	| 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-* \
 | 
			
		||||
	| 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-* | xps100-* | xscale-* | xstormy16-* \
 | 
			
		||||
	| xtensa-* \
 | 
			
		||||
	| ymp-* \
 | 
			
		||||
	| z8k-*)
 | 
			
		||||
		;;
 | 
			
		||||
	# Recognize the various machine names and aliases which stand
 | 
			
		||||
	# for a CPU type and a company and sometimes even an OS.
 | 
			
		||||
@@ -240,19 +373,22 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=a29k-none
 | 
			
		||||
		os=-bsd
 | 
			
		||||
		;;
 | 
			
		||||
	amd64)
 | 
			
		||||
		basic_machine=x86_64-pc
 | 
			
		||||
		;;
 | 
			
		||||
	amdahl)
 | 
			
		||||
		basic_machine=580-amdahl
 | 
			
		||||
		os=-sysv
 | 
			
		||||
		;;
 | 
			
		||||
	amiga | amiga-*)
 | 
			
		||||
		basic_machine=m68k-cbm
 | 
			
		||||
		basic_machine=m68k-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	amigaos | amigados)
 | 
			
		||||
		basic_machine=m68k-cbm
 | 
			
		||||
		basic_machine=m68k-unknown
 | 
			
		||||
		os=-amigaos
 | 
			
		||||
		;;
 | 
			
		||||
	amigaunix | amix)
 | 
			
		||||
		basic_machine=m68k-cbm
 | 
			
		||||
		basic_machine=m68k-unknown
 | 
			
		||||
		os=-sysv4
 | 
			
		||||
		;;
 | 
			
		||||
	apollo68)
 | 
			
		||||
@@ -271,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
 | 
			
		||||
@@ -291,27 +431,30 @@ 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
 | 
			
		||||
		;;
 | 
			
		||||
	[ctj]90-cray)
 | 
			
		||||
		basic_machine=c90-cray
 | 
			
		||||
	cray | j90)
 | 
			
		||||
		basic_machine=j90-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
		;;
 | 
			
		||||
	crds | unos)
 | 
			
		||||
		basic_machine=m68k-crds
 | 
			
		||||
		;;
 | 
			
		||||
	cris | cris-* | etrax*)
 | 
			
		||||
		basic_machine=cris-axis
 | 
			
		||||
		;;
 | 
			
		||||
	da30 | da30-*)
 | 
			
		||||
		basic_machine=m68k-da30
 | 
			
		||||
		;;
 | 
			
		||||
	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
 | 
			
		||||
@@ -353,6 +496,10 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=tron-gmicro
 | 
			
		||||
		os=-sysv
 | 
			
		||||
		;;
 | 
			
		||||
	go32)
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-go32
 | 
			
		||||
		;;
 | 
			
		||||
	h3050r* | hiux*)
 | 
			
		||||
		basic_machine=hppa1.1-hitachi
 | 
			
		||||
		os=-hiuxwe2
 | 
			
		||||
@@ -426,22 +573,21 @@ case $basic_machine in
 | 
			
		||||
		;;
 | 
			
		||||
	i370-ibm* | ibm*)
 | 
			
		||||
		basic_machine=i370-ibm
 | 
			
		||||
		os=-mvs
 | 
			
		||||
		;;
 | 
			
		||||
# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
 | 
			
		||||
	i[34567]86v32)
 | 
			
		||||
	i*86v32)
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 | 
			
		||||
		os=-sysv32
 | 
			
		||||
		;;
 | 
			
		||||
	i[34567]86v4*)
 | 
			
		||||
	i*86v4*)
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 | 
			
		||||
		os=-sysv4
 | 
			
		||||
		;;
 | 
			
		||||
	i[34567]86v)
 | 
			
		||||
	i*86v)
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 | 
			
		||||
		os=-sysv
 | 
			
		||||
		;;
 | 
			
		||||
	i[34567]86sol2)
 | 
			
		||||
	i*86sol2)
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 | 
			
		||||
		os=-solaris2
 | 
			
		||||
		;;
 | 
			
		||||
@@ -453,14 +599,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=i386-unknown
 | 
			
		||||
		os=-vsta
 | 
			
		||||
		;;
 | 
			
		||||
	i386-go32 | go32)
 | 
			
		||||
		basic_machine=i386-unknown
 | 
			
		||||
		os=-go32
 | 
			
		||||
		;;
 | 
			
		||||
	i386-mingw32 | mingw32)
 | 
			
		||||
		basic_machine=i386-unknown
 | 
			
		||||
		os=-mingw32
 | 
			
		||||
		;;
 | 
			
		||||
	iris | iris4d)
 | 
			
		||||
		basic_machine=mips-sgi
 | 
			
		||||
		case $os in
 | 
			
		||||
@@ -486,35 +624,43 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=ns32k-utek
 | 
			
		||||
		os=-sysv
 | 
			
		||||
		;;
 | 
			
		||||
	mingw32)
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-mingw32
 | 
			
		||||
		;;
 | 
			
		||||
	miniframe)
 | 
			
		||||
		basic_machine=m68000-convergent
 | 
			
		||||
		;;
 | 
			
		||||
	*mint | *MiNT)
 | 
			
		||||
	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
 | 
			
		||||
		basic_machine=m68k-atari
 | 
			
		||||
		os=-mint
 | 
			
		||||
		;;
 | 
			
		||||
	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/'`
 | 
			
		||||
		;;
 | 
			
		||||
	mips3*)
 | 
			
		||||
		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	mmix*)
 | 
			
		||||
		basic_machine=mmix-knuth
 | 
			
		||||
		os=-mmixware
 | 
			
		||||
		;;
 | 
			
		||||
	monitor)
 | 
			
		||||
		basic_machine=m68k-rom68k
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	morphos)
 | 
			
		||||
		basic_machine=powerpc-unknown
 | 
			
		||||
		os=-morphos
 | 
			
		||||
		;;
 | 
			
		||||
	msdos)
 | 
			
		||||
		basic_machine=i386-unknown
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-msdos
 | 
			
		||||
		;;
 | 
			
		||||
	mvs)
 | 
			
		||||
		basic_machine=i370-ibm
 | 
			
		||||
		os=-mvs
 | 
			
		||||
		;;
 | 
			
		||||
	ncr3000)
 | 
			
		||||
		basic_machine=i486-ncr
 | 
			
		||||
		os=-sysv4
 | 
			
		||||
@@ -524,7 +670,7 @@ case $basic_machine in
 | 
			
		||||
		os=-netbsd
 | 
			
		||||
		;;
 | 
			
		||||
	netwinder)
 | 
			
		||||
		basic_machine=armv4l-corel
 | 
			
		||||
		basic_machine=armv4l-rebel
 | 
			
		||||
		os=-linux
 | 
			
		||||
		;;
 | 
			
		||||
	news | news700 | news800 | news900)
 | 
			
		||||
@@ -572,13 +718,28 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=i960-intel
 | 
			
		||||
		os=-mon960
 | 
			
		||||
		;;
 | 
			
		||||
	nonstopux)
 | 
			
		||||
		basic_machine=mips-compaq
 | 
			
		||||
		os=-nonstopux
 | 
			
		||||
		;;
 | 
			
		||||
	np1)
 | 
			
		||||
		basic_machine=np1-gould
 | 
			
		||||
		;;
 | 
			
		||||
	nv1)
 | 
			
		||||
		basic_machine=nv1-cray
 | 
			
		||||
		os=-unicosmp
 | 
			
		||||
		;;
 | 
			
		||||
	nsr-tandem)
 | 
			
		||||
		basic_machine=nsr-tandem
 | 
			
		||||
		;;
 | 
			
		||||
	op50n-* | op60c-*)
 | 
			
		||||
		basic_machine=hppa1.1-oki
 | 
			
		||||
		os=-proelf
 | 
			
		||||
		;;
 | 
			
		||||
	or32 | or32-*)
 | 
			
		||||
		basic_machine=or32-unknown
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	OSE68000 | ose68000)
 | 
			
		||||
		basic_machine=m68000-ericsson
 | 
			
		||||
		os=-ose
 | 
			
		||||
@@ -601,45 +762,65 @@ case $basic_machine in
 | 
			
		||||
	pbb)
 | 
			
		||||
		basic_machine=m68k-tti
 | 
			
		||||
		;;
 | 
			
		||||
        pc532 | pc532-*)
 | 
			
		||||
	pc532 | pc532-*)
 | 
			
		||||
		basic_machine=ns32k-pc532
 | 
			
		||||
		;;
 | 
			
		||||
	pentium | p5 | k5 | k6 | nexen)
 | 
			
		||||
	pentium | p5 | k5 | k6 | nexgen | viac3)
 | 
			
		||||
		basic_machine=i586-pc
 | 
			
		||||
		;;
 | 
			
		||||
	pentiumpro | p6 | 6x86)
 | 
			
		||||
	pentiumpro | p6 | 6x86 | athlon | athlon_*)
 | 
			
		||||
		basic_machine=i686-pc
 | 
			
		||||
		;;
 | 
			
		||||
	pentiumii | pentium2)
 | 
			
		||||
	pentiumii | pentium2 | pentiumiii | pentium3)
 | 
			
		||||
		basic_machine=i686-pc
 | 
			
		||||
		;;
 | 
			
		||||
	pentium4)
 | 
			
		||||
		basic_machine=i786-pc
 | 
			
		||||
		;;
 | 
			
		||||
	pentium-* | p5-* | k5-* | k6-* | nexen-*)
 | 
			
		||||
	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
 | 
			
		||||
		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	pentiumpro-* | p6-* | 6x86-*)
 | 
			
		||||
	pentiumpro-* | p6-* | 6x86-* | athlon-*)
 | 
			
		||||
		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	pentiumii-* | pentium2-*)
 | 
			
		||||
	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=rs6000-ibm
 | 
			
		||||
	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/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	ps2)
 | 
			
		||||
		basic_machine=i386-ibm
 | 
			
		||||
		;;
 | 
			
		||||
	pw32)
 | 
			
		||||
		basic_machine=i586-unknown
 | 
			
		||||
		os=-pw32
 | 
			
		||||
		;;
 | 
			
		||||
	rom68k)
 | 
			
		||||
		basic_machine=m68k-rom68k
 | 
			
		||||
		os=-coff
 | 
			
		||||
@@ -650,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
 | 
			
		||||
		;;
 | 
			
		||||
@@ -661,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
 | 
			
		||||
		;;
 | 
			
		||||
@@ -719,20 +919,44 @@ case $basic_machine in
 | 
			
		||||
	sun386 | sun386i | roadrunner)
 | 
			
		||||
		basic_machine=i386-sun
 | 
			
		||||
		;;
 | 
			
		||||
	sv1)
 | 
			
		||||
		basic_machine=sv1-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
		;;
 | 
			
		||||
	symmetry)
 | 
			
		||||
		basic_machine=i386-sequent
 | 
			
		||||
		os=-dynix
 | 
			
		||||
		;;
 | 
			
		||||
	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
 | 
			
		||||
		;;
 | 
			
		||||
@@ -757,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
 | 
			
		||||
@@ -779,13 +1003,13 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=hppa1.1-winbond
 | 
			
		||||
		os=-proelf
 | 
			
		||||
		;;
 | 
			
		||||
	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
 | 
			
		||||
@@ -806,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
 | 
			
		||||
		;;
 | 
			
		||||
@@ -822,16 +1039,26 @@ case $basic_machine in
 | 
			
		||||
	vax)
 | 
			
		||||
		basic_machine=vax-dec
 | 
			
		||||
		;;
 | 
			
		||||
	pdp10)
 | 
			
		||||
		# there are many clones, so DEC is not a safe bet
 | 
			
		||||
		basic_machine=pdp10-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	pdp11)
 | 
			
		||||
		basic_machine=pdp11-dec
 | 
			
		||||
		;;
 | 
			
		||||
	we32k)
 | 
			
		||||
		basic_machine=we32k-att
 | 
			
		||||
		;;
 | 
			
		||||
	sparc | sparcv9)
 | 
			
		||||
	sh3 | sh4 | 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)
 | 
			
		||||
@@ -846,9 +1073,8 @@ 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.
 | 
			
		||||
		;;
 | 
			
		||||
	*)
 | 
			
		||||
		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
 | 
			
		||||
@@ -906,14 +1132,34 @@ case $os in
 | 
			
		||||
	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 | 
			
		||||
	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 | 
			
		||||
	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 | 
			
		||||
	      | -chorusos* | -chorusrdb* \
 | 
			
		||||
	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 | 
			
		||||
	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
 | 
			
		||||
	      | -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*)
 | 
			
		||||
	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 | 
			
		||||
	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 | 
			
		||||
	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 | 
			
		||||
	      | -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*)
 | 
			
		||||
		case $basic_machine in
 | 
			
		||||
		    x86-* | i*86-*)
 | 
			
		||||
			;;
 | 
			
		||||
		    *)
 | 
			
		||||
			os=-nto$os
 | 
			
		||||
			;;
 | 
			
		||||
		esac
 | 
			
		||||
		;;
 | 
			
		||||
	-nto-qnx*)
 | 
			
		||||
		;;
 | 
			
		||||
	-nto*)
 | 
			
		||||
		os=`echo $os | sed -e 's|nto|nto-qnx|'`
 | 
			
		||||
		;;
 | 
			
		||||
	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
 | 
			
		||||
	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
 | 
			
		||||
	      | -macos* | -mpw* | -magic* | -mon960* | -lnews*)
 | 
			
		||||
	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
 | 
			
		||||
		;;
 | 
			
		||||
	-mac*)
 | 
			
		||||
		os=`echo $os | sed -e 's|mac|macos|'`
 | 
			
		||||
@@ -927,6 +1173,12 @@ case $os in
 | 
			
		||||
	-sunos6*)
 | 
			
		||||
		os=`echo $os | sed -e 's|sunos6|solaris3|'`
 | 
			
		||||
		;;
 | 
			
		||||
	-opened*)
 | 
			
		||||
		os=-openedition
 | 
			
		||||
		;;
 | 
			
		||||
	-wince*)
 | 
			
		||||
		os=-wince
 | 
			
		||||
		;;
 | 
			
		||||
	-osfrose*)
 | 
			
		||||
		os=-osfrose
 | 
			
		||||
		;;
 | 
			
		||||
@@ -942,14 +1194,23 @@ 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
 | 
			
		||||
		;;
 | 
			
		||||
	# Preserve the version number of sinix5.
 | 
			
		||||
	-sinix5.*)
 | 
			
		||||
@@ -985,8 +1246,14 @@ case $os in
 | 
			
		||||
	-xenix)
 | 
			
		||||
		os=-xenix
 | 
			
		||||
		;;
 | 
			
		||||
        -*mint | -*MiNT)
 | 
			
		||||
	        os=-mint
 | 
			
		||||
	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
 | 
			
		||||
		os=-mint
 | 
			
		||||
		;;
 | 
			
		||||
	-aros*)
 | 
			
		||||
		os=-aros
 | 
			
		||||
		;;
 | 
			
		||||
	-kaos*)
 | 
			
		||||
		os=-kaos
 | 
			
		||||
		;;
 | 
			
		||||
	-none)
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1013,13 +1280,20 @@ case $basic_machine in
 | 
			
		||||
	*-acorn)
 | 
			
		||||
		os=-riscix1.2
 | 
			
		||||
		;;
 | 
			
		||||
	arm*-corel)
 | 
			
		||||
	arm*-rebel)
 | 
			
		||||
		os=-linux
 | 
			
		||||
		;;
 | 
			
		||||
	arm*-semi)
 | 
			
		||||
		os=-aout
 | 
			
		||||
		;;
 | 
			
		||||
        pdp11-*)
 | 
			
		||||
    c4x-* | tic4x-*)
 | 
			
		||||
        os=-coff
 | 
			
		||||
        ;;
 | 
			
		||||
	# This must come before the *-dec entry.
 | 
			
		||||
	pdp10-*)
 | 
			
		||||
		os=-tops20
 | 
			
		||||
		;;
 | 
			
		||||
	pdp11-*)
 | 
			
		||||
		os=-none
 | 
			
		||||
		;;
 | 
			
		||||
	*-dec | vax-*)
 | 
			
		||||
@@ -1046,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
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1109,25 +1386,25 @@ 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)
 | 
			
		||||
		os=-rtu
 | 
			
		||||
		;;
 | 
			
		||||
	f301-fujitsu)
 | 
			
		||||
	f30[01]-fujitsu | f700-fujitsu)
 | 
			
		||||
		os=-uxpv
 | 
			
		||||
		;;
 | 
			
		||||
	*-rom68k)
 | 
			
		||||
@@ -1187,13 +1464,13 @@ case $basic_machine in
 | 
			
		||||
			-genix*)
 | 
			
		||||
				vendor=ns
 | 
			
		||||
				;;
 | 
			
		||||
			-mvs*)
 | 
			
		||||
			-mvs* | -opened*)
 | 
			
		||||
				vendor=ibm
 | 
			
		||||
				;;
 | 
			
		||||
			-ptx*)
 | 
			
		||||
				vendor=sequent
 | 
			
		||||
				;;
 | 
			
		||||
			-vxsim* | -vxworks*)
 | 
			
		||||
			-vxsim* | -vxworks* | -windiss*)
 | 
			
		||||
				vendor=wrs
 | 
			
		||||
				;;
 | 
			
		||||
			-aux*)
 | 
			
		||||
@@ -1205,12 +1482,23 @@ case $basic_machine in
 | 
			
		||||
			-mpw* | -macos*)
 | 
			
		||||
				vendor=apple
 | 
			
		||||
				;;
 | 
			
		||||
			-*mint | -*MiNT)
 | 
			
		||||
			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
 | 
			
		||||
				vendor=atari
 | 
			
		||||
				;;
 | 
			
		||||
			-vos*)
 | 
			
		||||
				vendor=stratus
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
 | 
			
		||||
		;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
echo $basic_machine$os
 | 
			
		||||
exit 0
 | 
			
		||||
 | 
			
		||||
# Local variables:
 | 
			
		||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
 | 
			
		||||
# time-stamp-start: "timestamp='"
 | 
			
		||||
# time-stamp-format: "%:y-%02m-%02d"
 | 
			
		||||
# time-stamp-end: "'"
 | 
			
		||||
# End:
 | 
			
		||||
 
 | 
			
		||||
@@ -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:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										199
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								configure.in
									
									
									
									
									
								
							@@ -1,4 +1,3 @@
 | 
			
		||||
################################################################################
 | 
			
		||||
##
 | 
			
		||||
##    Copyright 1999-2000 Sistina Software, Inc.
 | 
			
		||||
##
 | 
			
		||||
@@ -46,20 +45,63 @@ AC_TYPE_SIZE_T
 | 
			
		||||
AC_STRUCT_ST_RDEV
 | 
			
		||||
AC_HEADER_TIME
 | 
			
		||||
 | 
			
		||||
dnl Get system type
 | 
			
		||||
AC_CANONICAL_SYSTEM
 | 
			
		||||
 | 
			
		||||
case "$host_os" in
 | 
			
		||||
	linux*)
 | 
			
		||||
		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,
 | 
			
		||||
@@ -75,16 +117,60 @@ if [[ "x$LVM1" != xnone -a "x$LVM1" != xinternal -a "x$LVM1" != xshared ]];
 | 
			
		||||
 exit
 | 
			
		||||
fi;
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(jobs, [  --enable-jobs=NUM       Number of jobs to run simultaneously], JOBS=-j$enableval, JOBS=)
 | 
			
		||||
if test x$LVM1 = xinternal; then
 | 
			
		||||
	CFLAGS="$CFLAGS -DLVM1_INTERNAL"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
dnl Enables staticly linked tools
 | 
			
		||||
AC_ARG_ENABLE(static_link, [  --enable-static_link    Use this to link the tools to the liblvm library
 | 
			
		||||
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 their libraries
 | 
			
		||||
                          statically.  Default is dynamic linking],  STATIC_LINK=$enableval, STATIC_LINK=no)
 | 
			
		||||
 | 
			
		||||
dnl Enable readline
 | 
			
		||||
AC_ARG_ENABLE(readline, [  --enable-readline       Enable readline support],  \
 | 
			
		||||
READLINE=$enableval, READLINE=no)
 | 
			
		||||
 | 
			
		||||
if test x$READLINE = xyes; then
 | 
			
		||||
	CFLAGS="$CFLAGS -DREADLINE_SUPPORT"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
echo "$ac_t""$DEVMAPPER" 1>&6
 | 
			
		||||
 | 
			
		||||
if test x$DEVMAPPER = xyes; then
 | 
			
		||||
	CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
echo $ac_n "checking whether to enable O_DIRECT""... $ac_c" 1>&6
 | 
			
		||||
dnl Disable O_DIRECT
 | 
			
		||||
AC_ARG_ENABLE(o_direct, [  --disable-o_direct      Disable O_DIRECT],  \
 | 
			
		||||
ODIRECT=no)
 | 
			
		||||
echo "$ac_t""$ODIRECT" 1>&6
 | 
			
		||||
 | 
			
		||||
if test x$ODIRECT = xyes; then
 | 
			
		||||
	CFLAGS="$CFLAGS -DO_DIRECT_SUPPORT"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
echo $ac_n "checking whether to compile liblvm2cmd.so""... $ac_c" 1>&6
 | 
			
		||||
dnl Enable cmdlib
 | 
			
		||||
AC_ARG_ENABLE(cmdlib, [  --enable-cmdlib         Build shared command library],  \
 | 
			
		||||
CMDLIB=yes, CMDLIB=no)
 | 
			
		||||
echo "$ac_t""$CMDLIB" 1>&6
 | 
			
		||||
 | 
			
		||||
if test x$CMDLIB = xyes; then
 | 
			
		||||
	CFLAGS="$CFLAGS -DCMDLIB"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
dnl Mess with default exec_prefix
 | 
			
		||||
if [[ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]];
 | 
			
		||||
 then  exec_prefix="";
 | 
			
		||||
@@ -113,6 +199,35 @@ Note: (n)curses also seems to work as a substitute for termcap.  This was
 | 
			
		||||
	)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
dnl Check for dlopen
 | 
			
		||||
AC_CHECK_LIB(dl, dlopen, HAVE_LIBDL=yes, HAVE_LIBDL=no)
 | 
			
		||||
 | 
			
		||||
if [[ "x$HAVE_LIBDL" = xyes -a "xSTATIC_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 -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
 | 
			
		||||
AC_CHECK_HEADERS(getopt.h, CFLAGS="$CFLAGS -DHAVE_GETOPTLONG")
 | 
			
		||||
 | 
			
		||||
dnl Check for readline (Shamelessly copied from parted 1.4.17)
 | 
			
		||||
if test x$READLINE = xyes; then
 | 
			
		||||
	AC_CHECK_LIB(readline, readline, ,
 | 
			
		||||
@@ -126,10 +241,43 @@ package as well (which may be called readline-devel or something similar).
 | 
			
		||||
)
 | 
			
		||||
		exit
 | 
			
		||||
	)
 | 
			
		||||
	AC_CHECK_FUNC(rl_completion_matches, HAVE_RL_COMPLETION_MATCHES=yes,
 | 
			
		||||
		HAVE_RL_COMPLETION_MATCHES=no)
 | 
			
		||||
	AC_CHECK_FUNC(rl_completion_matches, CFLAGS="$CFLAGS -DHAVE_RL_COMPLETION_MATCHES")
 | 
			
		||||
		
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -138,22 +286,42 @@ fi
 | 
			
		||||
 | 
			
		||||
AC_SUBST(JOBS)
 | 
			
		||||
AC_SUBST(STATIC_LINK)
 | 
			
		||||
AC_SUBST(READLINE)
 | 
			
		||||
AC_SUBST(LVM1)
 | 
			
		||||
AC_SUBST(HAVE_RL_COMPLETION_MATCHES)
 | 
			
		||||
AC_SUBST(OWNER)
 | 
			
		||||
AC_SUBST(GROUP)
 | 
			
		||||
AC_SUBST(CFLAGS)
 | 
			
		||||
AC_SUBST(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						 	\
 | 
			
		||||
man/Makefile							 	\
 | 
			
		||||
po/Makefile								\
 | 
			
		||||
tools/Makefile							 	\
 | 
			
		||||
tools/version.h								\
 | 
			
		||||
test/mm/Makefile							\
 | 
			
		||||
@@ -162,3 +330,10 @@ test/format1/Makefile							\
 | 
			
		||||
test/regex/Makefile                                                     \
 | 
			
		||||
test/filters/Makefile                                                   \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if test x$ODIRECT != xyes; then
 | 
			
		||||
  echo
 | 
			
		||||
  echo Warning: O_DIRECT disabled.
 | 
			
		||||
  echo Use of pvmove may cause machine to lock up under low memory conditions.
 | 
			
		||||
  echo
 | 
			
		||||
fi
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								debian/README.Debian
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								debian/README.Debian
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
LVM2 requires the device-mapper kernel module (dm-mod).  This is
 | 
			
		||||
available as a kernel patch for 2.4 (in kernel-patch-device-mapper), and
 | 
			
		||||
is distributed with linux 2.5 and above.  The LVM1 kernel module (lvm-mod)
 | 
			
		||||
will not work with lvm2 packages.  dm-mod and lvm-mod may both be loaded
 | 
			
		||||
in the kernel at the same time with no problems.  Without dm-mod, this
 | 
			
		||||
package is pretty useless.
 | 
			
		||||
							
								
								
									
										23
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,26 @@
 | 
			
		||||
lvm2 (1.95.15-1) unstable; urgency=low
 | 
			
		||||
  
 | 
			
		||||
  * New upstream release.
 | 
			
		||||
  * Remove undocumented manpage symlinks.
 | 
			
		||||
  * Update description to be more informative.  (Closes: #173499)
 | 
			
		||||
  * Add kernel-patch-device-mapper suggestion.
 | 
			
		||||
  * Update standards version.
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Sun, 16 Feb 2002 04:21:26 -0400
 | 
			
		||||
 | 
			
		||||
lvm2 (1.95.11-1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New upstream release.  (Closes: #171436)
 | 
			
		||||
  * Removed TODO and INTRO from debian/docs; added WHATS_NEW.
 | 
			
		||||
  * Remove vgcfgrestore.8 undocumented symlink.
 | 
			
		||||
  * Added a README.Debian, mentioning the device-mapper kernel module
 | 
			
		||||
    requirement that lvm2 has.  (Closes: #171674, #163020)
 | 
			
		||||
  * Get rid of debian/conffiles (debhelper's smart enough to figure that out).
 | 
			
		||||
  * debian/copyright fix to appease lintian.
 | 
			
		||||
  * Fix typo in tools/commands.h that caused /usr/sbin/; to be created.
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Mon,  9 Dec 2002 02:51:02 -0400
 | 
			
		||||
 | 
			
		||||
lvm2 (1.95.10-2) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fix software raid problems by ensuring lvm init script runs after
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/conffiles
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/conffiles
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +0,0 @@
 | 
			
		||||
/etc/lvm/lvm.conf
 | 
			
		||||
/etc/init.d/lvm2
 | 
			
		||||
							
								
								
									
										8
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@@ -3,7 +3,7 @@ Section: admin
 | 
			
		||||
Priority: optional
 | 
			
		||||
Maintainer: Andres Salomon <dilinger@mp3revolution.net>
 | 
			
		||||
Build-Depends: debhelper (>> 3.0.0), libdevmapper-dev (>= 0.96.04), libreadline4-dev
 | 
			
		||||
Standards-Version: 3.5.2
 | 
			
		||||
Standards-Version: 3.5.8.0
 | 
			
		||||
 | 
			
		||||
Package: lvm2
 | 
			
		||||
Architecture: any
 | 
			
		||||
@@ -11,10 +11,14 @@ Depends: ${shlibs:Depends}
 | 
			
		||||
Conflicts: lvm10, lvm-common
 | 
			
		||||
Replaces: lvm10, lvm-common
 | 
			
		||||
Provides: lvm-binaries
 | 
			
		||||
Suggests: dmsetup
 | 
			
		||||
Suggests: dmsetup, kernel-patch-device-mapper
 | 
			
		||||
Description: The Linux Logical Volume Manager
 | 
			
		||||
 This is LVM2, the rewrite of The Linux Logical Volume Manager.  LVM
 | 
			
		||||
 supports enterprise level volume management of disk and disk subsystems
 | 
			
		||||
 by grouping arbitrary disks into volume groups. The total capacity of
 | 
			
		||||
 volume groups can be allocated to logical volumes, which are accessed as
 | 
			
		||||
 regular block devices.
 | 
			
		||||
 .
 | 
			
		||||
 LVM2 is currently stable, but has some unimplemented features (most notably,
 | 
			
		||||
 pvmove and e2fsadm).  It is not yet recommended for production use.  It is
 | 
			
		||||
 backwards-compatible with LVM1 (lvm10), and requires Linux kernel 2.4.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							@@ -3,7 +3,7 @@ Wed, 20 Feb 2002 03:17:25 -0500.
 | 
			
		||||
 | 
			
		||||
It was downloaded from http://www.sistina.com/products_lvm.htm
 | 
			
		||||
 | 
			
		||||
Upstream Author(s): LVM Development Team
 | 
			
		||||
Upstream Author: LVM Development Team
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2001-2002 LVM Development Team
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								debian/docs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								debian/docs
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +1,5 @@
 | 
			
		||||
BUGS
 | 
			
		||||
INTRO
 | 
			
		||||
README
 | 
			
		||||
TODO
 | 
			
		||||
VERSION
 | 
			
		||||
WHATS_NEW
 | 
			
		||||
doc/*
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/rules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/rules
									
									
									
									
										vendored
									
									
								
							@@ -102,7 +102,6 @@ binary-arch: build install
 | 
			
		||||
	dh_installcron
 | 
			
		||||
	dh_installman
 | 
			
		||||
	dh_installinfo 
 | 
			
		||||
	dh_undocumented
 | 
			
		||||
	dh_installchangelogs
 | 
			
		||||
	dh_strip
 | 
			
		||||
	dh_link
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								debian/undocumented
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								debian/undocumented
									
									
									
									
										vendored
									
									
								
							@@ -1,14 +0,0 @@
 | 
			
		||||
e2fsadm.8
 | 
			
		||||
lvmdiskscan.8
 | 
			
		||||
lvmsadc.8
 | 
			
		||||
lvmsar.8
 | 
			
		||||
lvresize.8
 | 
			
		||||
pvdata.8
 | 
			
		||||
pvmove.8
 | 
			
		||||
pvresize.8
 | 
			
		||||
version.8
 | 
			
		||||
vgcfgrestore.8
 | 
			
		||||
vgexport.8
 | 
			
		||||
vgimport.8
 | 
			
		||||
vgmknodes.8
 | 
			
		||||
vgsplit.8
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
 | 
			
		||||
@@ -23,8 +23,12 @@ devices {
 | 
			
		||||
    # The filter consists of an array of regular expressions.  These
 | 
			
		||||
    # expressions can be delimited by a character of your choice, and
 | 
			
		||||
    # prefixed with either an 'a' (for accept) or 'r' (for reject).
 | 
			
		||||
    # The first expression found to match a device name determines if
 | 
			
		||||
    # the device will be accepted or rejected (ignored).  Devices that
 | 
			
		||||
    # don't match any patterns are accepted.
 | 
			
		||||
 | 
			
		||||
    # Remember to run vgscan after you change this parameter.
 | 
			
		||||
    # Remember to run vgscan after you change this parameter to ensure 
 | 
			
		||||
    # that the cache file gets regenerated (see below).
 | 
			
		||||
 | 
			
		||||
    # By default we accept every block device:
 | 
			
		||||
    filter = [ "a/.*/" ]
 | 
			
		||||
@@ -44,11 +48,27 @@ devices {
 | 
			
		||||
    # The results of the filtering are cached on disk to avoid
 | 
			
		||||
    # rescanning dud devices (which can take a very long time).  By
 | 
			
		||||
    # default this cache file is hidden in the /etc/lvm directory.
 | 
			
		||||
    # It is safe to delete this file. vgscan regenerates it.
 | 
			
		||||
    # It is safe to delete this file: the tools regenerate it.
 | 
			
		||||
    cache = "/etc/lvm/.cache"
 | 
			
		||||
 | 
			
		||||
    # You can turn off writing this cache file by setting this to 0.
 | 
			
		||||
    write_cache_state = 1
 | 
			
		||||
 | 
			
		||||
    # 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
 | 
			
		||||
@@ -92,6 +112,10 @@ log {
 | 
			
		||||
    #   indent = 0
 | 
			
		||||
    #   command_names = 1
 | 
			
		||||
    #   prefix = " -- "
 | 
			
		||||
 | 
			
		||||
    # Set this if you want log messages during activation.
 | 
			
		||||
    # Don't use this in low memory situations (can deadlock).
 | 
			
		||||
    # activation = 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Configuration of metadata backups and archiving.  In LVM2 when we
 | 
			
		||||
@@ -155,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".
 | 
			
		||||
@@ -181,6 +215,34 @@ global {
 | 
			
		||||
    #   library_dir = "/lib"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
activation {
 | 
			
		||||
    # Device used in place of missing stripes if activating incomplete volume.
 | 
			
		||||
    # For now, you need to set this up yourself first (e.g. with 'dmsetup')
 | 
			
		||||
    # For example, you could make it return I/O errors using the 'error' 
 | 
			
		||||
    # target or make it return zeros.
 | 
			
		||||
    missing_stripe_filler = "/dev/ioerror"
 | 
			
		||||
 | 
			
		||||
    # Size (in KB) of each copy operation when mirroring
 | 
			
		||||
    mirror_region_size = 512
 | 
			
		||||
 | 
			
		||||
    # How much stack (in KB) to reserve for use while devices suspended
 | 
			
		||||
    reserved_stack = 256
 | 
			
		||||
 | 
			
		||||
    # How much memory (in KB) to reserve for use while devices suspended
 | 
			
		||||
    reserved_memory = 8192
 | 
			
		||||
 | 
			
		||||
    # Nice value used while devices suspended
 | 
			
		||||
    process_priority = -18
 | 
			
		||||
 | 
			
		||||
    # 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", "@*" ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
####################
 | 
			
		||||
# Advanced section #
 | 
			
		||||
@@ -208,7 +270,8 @@ global {
 | 
			
		||||
    # preferably on different (non-LV) filesystems, and with no other 
 | 
			
		||||
    # on-disk metadata (pvmetadatacopies = 0). Or this can be in
 | 
			
		||||
    # addition to on-disk metadata areas.
 | 
			
		||||
    # The feature was originally added to simplify testing.
 | 
			
		||||
    # The feature was originally added to simplify testing and is not
 | 
			
		||||
    # supported under low memory situations - the machine could lock up.
 | 
			
		||||
    #
 | 
			
		||||
    # Never edit any files in these directories by hand unless you
 | 
			
		||||
    # you are absolutely sure you know what you are doing! Use
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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,5 +1,5 @@
 | 
			
		||||
../lib/activate/activate.h
 | 
			
		||||
../lib/cache/cache.h
 | 
			
		||||
../lib/cache/lvmcache.h
 | 
			
		||||
../lib/commands/errors.h
 | 
			
		||||
../lib/commands/toolcontext.h
 | 
			
		||||
../lib/config/config.h
 | 
			
		||||
@@ -9,28 +9,35 @@
 | 
			
		||||
../lib/datastruct/hash.h
 | 
			
		||||
../lib/datastruct/list.h
 | 
			
		||||
../lib/datastruct/lvm-types.h
 | 
			
		||||
../lib/datastruct/str_list.h
 | 
			
		||||
../lib/device/dev-cache.h
 | 
			
		||||
../lib/device/device.h
 | 
			
		||||
../lib/display/display.h
 | 
			
		||||
../lib/display/display_formats.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/format1/lvm1-label.h
 | 
			
		||||
../lib/format_text/format-text.h
 | 
			
		||||
../lib/label/label.h
 | 
			
		||||
../lib/locking/locking.h
 | 
			
		||||
../lib/log/log.h
 | 
			
		||||
../lib/metadata/lv_alloc.h
 | 
			
		||||
../lib/metadata/metadata.h
 | 
			
		||||
../lib/mm/dbg_malloc.h
 | 
			
		||||
../lib/mm/memlock.h
 | 
			
		||||
../lib/mm/pool.h
 | 
			
		||||
../lib/mm/xlate.h
 | 
			
		||||
../lib/misc/crc.h
 | 
			
		||||
../lib/misc/intl.h
 | 
			
		||||
../lib/misc/lib.h
 | 
			
		||||
../lib/misc/lvm-file.h
 | 
			
		||||
../lib/misc/lvm-string.h
 | 
			
		||||
../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,16 +20,15 @@ ifeq ("@LVM1@", "shared")
 | 
			
		||||
  SUBDIRS = format1
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
SOURCES=\
 | 
			
		||||
SOURCES =\
 | 
			
		||||
	activate/activate.c \
 | 
			
		||||
	activate/dev_manager.c \
 | 
			
		||||
	activate/fs.c \
 | 
			
		||||
	cache/cache.c \
 | 
			
		||||
	cache/lvmcache.c \
 | 
			
		||||
	commands/toolcontext.c \
 | 
			
		||||
	config/config.c \
 | 
			
		||||
	datastruct/bitset.c \
 | 
			
		||||
	datastruct/btree.c \
 | 
			
		||||
	datastruct/hash.c \
 | 
			
		||||
	datastruct/str_list.c \
 | 
			
		||||
	device/dev-cache.c \
 | 
			
		||||
	device/dev-io.c \
 | 
			
		||||
	device/device.c \
 | 
			
		||||
@@ -29,6 +36,8 @@ SOURCES=\
 | 
			
		||||
	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 \
 | 
			
		||||
@@ -36,9 +45,9 @@ 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/external_locking.c \
 | 
			
		||||
	locking/file_locking.c \
 | 
			
		||||
	locking/locking.c \
 | 
			
		||||
	locking/no_locking.c \
 | 
			
		||||
@@ -46,20 +55,22 @@ SOURCES=\
 | 
			
		||||
	metadata/lv_manip.c \
 | 
			
		||||
	metadata/merge.c \
 | 
			
		||||
	metadata/metadata.c \
 | 
			
		||||
	metadata/mirror.c \
 | 
			
		||||
	metadata/pv_map.c \
 | 
			
		||||
	metadata/snapshot_manip.c \
 | 
			
		||||
	misc/crc.c \
 | 
			
		||||
	misc/lvm-file.c \
 | 
			
		||||
	misc/sharedlib.c \
 | 
			
		||||
	mm/dbg_malloc.c \
 | 
			
		||||
	misc/lvm-string.c \
 | 
			
		||||
	mm/memlock.c \
 | 
			
		||||
	mm/pool.c \
 | 
			
		||||
	regex/matcher.c \
 | 
			
		||||
	regex/parse_rx.c \
 | 
			
		||||
	regex/ttree.c \
 | 
			
		||||
	report/report.c \
 | 
			
		||||
	uuid/uuid.c 
 | 
			
		||||
 | 
			
		||||
ifeq ("@LVM1@", "internal")
 | 
			
		||||
  SOURCES+=\
 | 
			
		||||
  SOURCES +=\
 | 
			
		||||
	format1/disk-rep.c \
 | 
			
		||||
	format1/format1.c \
 | 
			
		||||
	format1/import-export.c \
 | 
			
		||||
@@ -69,12 +80,29 @@ ifeq ("@LVM1@", "internal")
 | 
			
		||||
	format1/vg_number.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
TARGETS=liblvm.a
 | 
			
		||||
ifeq ("@DEBUG@", "yes")
 | 
			
		||||
  SOURCES += mm/dbg_malloc.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@DEVMAPPER@", "yes")
 | 
			
		||||
  SOURCES +=\
 | 
			
		||||
	activate/dev_manager.c \
 | 
			
		||||
	activate/fs.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@HAVE_LIBDL@", "yes")
 | 
			
		||||
  SOURCES +=\
 | 
			
		||||
	locking/external_locking.c \
 | 
			
		||||
	misc/sharedlib.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
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,33 +1,162 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
#include "activate.h"
 | 
			
		||||
#include "memlock.h"
 | 
			
		||||
#include "display.h"
 | 
			
		||||
#include "fs.h"
 | 
			
		||||
#include "lvm-file.h"
 | 
			
		||||
#include "lvm-string.h"
 | 
			
		||||
#include "pool.h"
 | 
			
		||||
#include "toolcontext.h"
 | 
			
		||||
#include "dev_manager.h"
 | 
			
		||||
#include "str_list.h"
 | 
			
		||||
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <linux/kdev_t.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
 | 
			
		||||
 | 
			
		||||
static int _activation = 1;
 | 
			
		||||
 | 
			
		||||
void set_activation(int activation)
 | 
			
		||||
int lvm1_present(struct cmd_context *cmd)
 | 
			
		||||
{
 | 
			
		||||
	if (activation == _activation)
 | 
			
		||||
	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)
 | 
			
		||||
{
 | 
			
		||||
	static int warned = 0;
 | 
			
		||||
 | 
			
		||||
	if (warned || !act)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	_activation = activation;
 | 
			
		||||
	log_error("Compiled without libdevmapper support. "
 | 
			
		||||
		  "Can't enable activation.");
 | 
			
		||||
 | 
			
		||||
	warned = 1;
 | 
			
		||||
}
 | 
			
		||||
int activation(void)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int library_version(char *version, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int driver_version(char *version, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int target_present(const char *target_name)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int lv_info(const struct logical_volume *lv, struct lvinfo *info)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
 | 
			
		||||
		    struct lvinfo *info)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int lv_snapshot_percent(struct logical_volume *lv, float *percent)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
 | 
			
		||||
		      uint32_t *event_nr)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int lvs_in_vg_activated(struct volume_group *vg)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int lvs_in_vg_opened(struct volume_group *vg)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
int lv_suspend(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;
 | 
			
		||||
}
 | 
			
		||||
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
 | 
			
		||||
			 int *activate_lv)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void activation_exit(void)
 | 
			
		||||
{
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else				/* DEVMAPPER_SUPPORT */
 | 
			
		||||
 | 
			
		||||
static int _activation = 1;
 | 
			
		||||
 | 
			
		||||
void set_activation(int act)
 | 
			
		||||
{
 | 
			
		||||
	if (act == _activation)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	_activation = act;
 | 
			
		||||
	if (_activation)
 | 
			
		||||
		log_verbose("Activation enabled. Device-mapper kernel "
 | 
			
		||||
			    "driver will be used.");
 | 
			
		||||
@@ -36,11 +165,91 @@ void set_activation(int activation)
 | 
			
		||||
			    "interaction will be attempted.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int activation()
 | 
			
		||||
int activation(void)
 | 
			
		||||
{
 | 
			
		||||
	return _activation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _passes_activation_filter(struct cmd_context *cmd,
 | 
			
		||||
				     struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *cn;
 | 
			
		||||
	struct config_value *cv;
 | 
			
		||||
	char *str;
 | 
			
		||||
	char path[PATH_MAX];
 | 
			
		||||
 | 
			
		||||
	if (!(cn = find_config_node(cmd->cft->root, "activation/volume_list"))) {
 | 
			
		||||
		/* If no hosts tags defined, activate */
 | 
			
		||||
		if (list_empty(&cmd->tags))
 | 
			
		||||
			return 1;
 | 
			
		||||
 | 
			
		||||
		/* If any host tag matches any LV or VG tag, activate */
 | 
			
		||||
		if (str_list_match_list(&cmd->tags, &lv->tags) ||
 | 
			
		||||
		    str_list_match_list(&cmd->tags, &lv->vg->tags))
 | 
			
		||||
			return 1;
 | 
			
		||||
 | 
			
		||||
		/* Don't activate */
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (cv = cn->v; cv; cv = cv->next) {
 | 
			
		||||
		if (cv->type != CFG_STRING) {
 | 
			
		||||
			log_error("Ignoring invalid string in config file "
 | 
			
		||||
				  "activation/volume_list");
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		str = cv->v.str;
 | 
			
		||||
		if (!*str) {
 | 
			
		||||
			log_error("Ignoring empty string in config file "
 | 
			
		||||
				  "activation/volume_list");
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Tag? */
 | 
			
		||||
		if (*str == '@') {
 | 
			
		||||
			str++;
 | 
			
		||||
			if (!*str) {
 | 
			
		||||
				log_error("Ignoring empty tag in config file "
 | 
			
		||||
					  "activation/volume_list");
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			/* If any host tag matches any LV or VG tag, activate */
 | 
			
		||||
			if (!strcmp(str, "*")) {
 | 
			
		||||
				if (str_list_match_list(&cmd->tags, &lv->tags)
 | 
			
		||||
				    || str_list_match_list(&cmd->tags,
 | 
			
		||||
							   &lv->vg->tags))
 | 
			
		||||
					    return 1;
 | 
			
		||||
				else
 | 
			
		||||
					continue;
 | 
			
		||||
			}
 | 
			
		||||
			/* If supplied tag matches LV or VG tag, activate */
 | 
			
		||||
			if (str_list_match_item(&lv->tags, str) ||
 | 
			
		||||
			    str_list_match_item(&lv->vg->tags, str))
 | 
			
		||||
				return 1;
 | 
			
		||||
			else
 | 
			
		||||
				continue;
 | 
			
		||||
		}
 | 
			
		||||
		if (!index(str, '/')) {
 | 
			
		||||
			/* vgname supplied */
 | 
			
		||||
			if (!strcmp(str, lv->vg->name))
 | 
			
		||||
				return 1;
 | 
			
		||||
			else
 | 
			
		||||
				continue;
 | 
			
		||||
		}
 | 
			
		||||
		/* vgname/lvname */
 | 
			
		||||
		if (lvm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
 | 
			
		||||
				 lv->name) < 0) {
 | 
			
		||||
			log_error("lvm_snprintf error from %s/%s", lv->vg->name,
 | 
			
		||||
				  lv->name);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		if (!strcmp(path, str))
 | 
			
		||||
			return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int library_version(char *version, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (!activation())
 | 
			
		||||
@@ -79,29 +288,94 @@ int driver_version(char *version, size_t size)
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Returns 1 if info structure populated, else 0 on failure.
 | 
			
		||||
 */
 | 
			
		||||
int lv_info(struct logical_volume *lv, struct dm_info *info)
 | 
			
		||||
int target_present(const char *target_name)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
	struct dev_manager *dm;
 | 
			
		||||
	int r = 0;
 | 
			
		||||
	struct dm_task *dmt;
 | 
			
		||||
	struct dm_versions *target, *last_target;
 | 
			
		||||
 | 
			
		||||
	if (!activation())
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!(dm = dev_manager_create(lv->vg->name))) {
 | 
			
		||||
	log_very_verbose("Getting target version for %s", target_name);
 | 
			
		||||
	if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(r = dev_manager_info(dm, lv, info)))
 | 
			
		||||
	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.
 | 
			
		||||
 */
 | 
			
		||||
static int _lv_info(const struct logical_volume *lv, int mknodes,
 | 
			
		||||
		    struct lvinfo *info)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
	struct dev_manager *dm;
 | 
			
		||||
	struct dm_info dminfo;
 | 
			
		||||
 | 
			
		||||
	if (!activation())
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(r = dev_manager_info(dm, lv, mknodes, &dminfo)))
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	info->exists = dminfo.exists;
 | 
			
		||||
	info->suspended = dminfo.suspended;
 | 
			
		||||
	info->open_count = dminfo.open_count;
 | 
			
		||||
	info->major = dminfo.major;
 | 
			
		||||
	info->minor = dminfo.minor;
 | 
			
		||||
	info->read_only = dminfo.read_only;
 | 
			
		||||
 | 
			
		||||
	dev_manager_destroy(dm);
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 */
 | 
			
		||||
@@ -113,7 +387,7 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
 | 
			
		||||
	if (!activation())
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!(dm = dev_manager_create(lv->vg->name))) {
 | 
			
		||||
	if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -126,9 +400,41 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* FIXME Merge with snapshot_percent */
 | 
			
		||||
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
 | 
			
		||||
		      uint32_t *event_nr)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
	struct dev_manager *dm;
 | 
			
		||||
	struct lvinfo info;
 | 
			
		||||
 | 
			
		||||
	if (!activation())
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!lv_info(lv, &info)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!info.exists)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	dev_manager_destroy(dm);
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _lv_active(struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	struct lvinfo info;
 | 
			
		||||
 | 
			
		||||
	if (!lv_info(lv, &info)) {
 | 
			
		||||
		stack;
 | 
			
		||||
@@ -140,7 +446,7 @@ static int _lv_active(struct logical_volume *lv)
 | 
			
		||||
 | 
			
		||||
static int _lv_open_count(struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	struct lvinfo info;
 | 
			
		||||
 | 
			
		||||
	if (!lv_info(lv, &info)) {
 | 
			
		||||
		stack;
 | 
			
		||||
@@ -151,12 +457,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))) {
 | 
			
		||||
	if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -173,7 +479,7 @@ static int _lv_deactivate(struct logical_volume *lv)
 | 
			
		||||
	int r;
 | 
			
		||||
	struct dev_manager *dm;
 | 
			
		||||
 | 
			
		||||
	if (!(dm = dev_manager_create(lv->vg->name))) {
 | 
			
		||||
	if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -185,12 +491,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))) {
 | 
			
		||||
	if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -234,17 +540,17 @@ 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);
 | 
			
		||||
		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 dm_info info;
 | 
			
		||||
	struct lvinfo info;
 | 
			
		||||
 | 
			
		||||
	if (!activation())
 | 
			
		||||
		return 1;
 | 
			
		||||
@@ -252,12 +558,9 @@ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
	if (!(lv = lv_from_lvid(cmd, lvid_s)))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!activation())
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (test_mode()) {
 | 
			
		||||
		_skip("Suspending '%s'.", lv->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!lv_info(lv, &info)) {
 | 
			
		||||
@@ -265,16 +568,35 @@ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (info.exists && !info.suspended)
 | 
			
		||||
		return _lv_suspend(lv);
 | 
			
		||||
	if (!info.exists || info.suspended)
 | 
			
		||||
		return error_if_not_suspended ? 0 : 1;
 | 
			
		||||
 | 
			
		||||
	memlock_inc();
 | 
			
		||||
	if (!_lv_suspend_lv(lv)) {
 | 
			
		||||
		memlock_dec();
 | 
			
		||||
		fs_unlock();
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
/* Returns success if the device is not active */
 | 
			
		||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
{
 | 
			
		||||
	return _lv_suspend(cmd, lvid_s, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
{
 | 
			
		||||
	return _lv_suspend(cmd, lvid_s, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
 | 
			
		||||
		      int error_if_not_active)
 | 
			
		||||
{
 | 
			
		||||
	struct logical_volume *lv;
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	struct lvinfo info;
 | 
			
		||||
 | 
			
		||||
	if (!activation())
 | 
			
		||||
		return 1;
 | 
			
		||||
@@ -284,7 +606,7 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
 | 
			
		||||
	if (test_mode()) {
 | 
			
		||||
		_skip("Resuming '%s'.", lv->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!lv_info(lv, &info)) {
 | 
			
		||||
@@ -292,16 +614,34 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (info.exists && info.suspended)
 | 
			
		||||
		return _lv_activate(lv);
 | 
			
		||||
	if (!info.exists || !info.suspended)
 | 
			
		||||
		return error_if_not_active ? 0 : 1;
 | 
			
		||||
 | 
			
		||||
	if (!_lv_activate_lv(lv))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	memlock_dec();
 | 
			
		||||
	fs_unlock();
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Returns success if the device is not active */
 | 
			
		||||
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
{
 | 
			
		||||
	return _lv_resume(cmd, lvid_s, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lv_resume(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
{
 | 
			
		||||
	return _lv_resume(cmd, lvid_s, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
{
 | 
			
		||||
	struct logical_volume *lv;
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	struct lvinfo info;
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	if (!activation())
 | 
			
		||||
		return 1;
 | 
			
		||||
@@ -311,7 +651,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
 | 
			
		||||
	if (test_mode()) {
 | 
			
		||||
		_skip("Deactivating '%s'.", lv->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!lv_info(lv, &info)) {
 | 
			
		||||
@@ -319,16 +659,52 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (info.exists)
 | 
			
		||||
		return _lv_deactivate(lv);
 | 
			
		||||
	if (!info.exists)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (info.open_count && (lv->status & VISIBLE_LV)) {
 | 
			
		||||
		log_error("LV %s/%s in use: not removing", lv->vg->name,
 | 
			
		||||
			  lv->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memlock_inc();
 | 
			
		||||
	r = _lv_deactivate(lv);
 | 
			
		||||
	memlock_dec();
 | 
			
		||||
	fs_unlock();
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Test if LV passes filter */
 | 
			
		||||
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
 | 
			
		||||
			 int *activate_lv)
 | 
			
		||||
{
 | 
			
		||||
	struct logical_volume *lv;
 | 
			
		||||
 | 
			
		||||
	if (!activation())
 | 
			
		||||
		goto activate;
 | 
			
		||||
 | 
			
		||||
	if (!(lv = lv_from_lvid(cmd, lvid_s)))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!_passes_activation_filter(cmd, lv)) {
 | 
			
		||||
		log_verbose("Not activating %s/%s due to config file settings",
 | 
			
		||||
			    lv->vg->name, lv->name);
 | 
			
		||||
		*activate_lv = 0;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      activate:
 | 
			
		||||
	*activate_lv = 1;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
 | 
			
		||||
{
 | 
			
		||||
	struct logical_volume *lv;
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	struct lvinfo info;
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	if (!activation())
 | 
			
		||||
		return 1;
 | 
			
		||||
@@ -336,9 +712,15 @@ 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 0;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!lv_info(lv, &info)) {
 | 
			
		||||
@@ -346,8 +728,57 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!info.exists || info.suspended)
 | 
			
		||||
		return _lv_activate(lv);
 | 
			
		||||
	if (info.exists && !info.suspended)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
	memlock_inc();
 | 
			
		||||
	r = _lv_activate_lv(lv);
 | 
			
		||||
	memlock_dec();
 | 
			
		||||
	fs_unlock();
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Activate LV */
 | 
			
		||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
{
 | 
			
		||||
	return _lv_activate(cmd, lvid_s, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Activate LV only if it passes filter */
 | 
			
		||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
 | 
			
		||||
{
 | 
			
		||||
	return _lv_activate(cmd, lvid_s, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
	struct lvinfo info;
 | 
			
		||||
	int r = 1;
 | 
			
		||||
 | 
			
		||||
	if (!lv) {
 | 
			
		||||
		r = dev_manager_mknodes();
 | 
			
		||||
		fs_unlock();
 | 
			
		||||
		return r;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!_lv_info(lv, 1, &info)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (info.exists)
 | 
			
		||||
		r = dev_manager_lv_mknodes(lv);
 | 
			
		||||
	else
 | 
			
		||||
		r = dev_manager_lv_rmnodes(lv);
 | 
			
		||||
 | 
			
		||||
	fs_unlock();
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void activation_exit(void)
 | 
			
		||||
{
 | 
			
		||||
	dev_manager_exit();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,43 +1,76 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
#define LVM_ACTIVATE_H
 | 
			
		||||
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
#include <libdevmapper.h>
 | 
			
		||||
 | 
			
		||||
#ifdef DEVMAPPER_SUPPORT
 | 
			
		||||
#  include <libdevmapper.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct lvinfo {
 | 
			
		||||
	int exists;
 | 
			
		||||
	int suspended;
 | 
			
		||||
	unsigned int open_count;
 | 
			
		||||
	int major;
 | 
			
		||||
	int minor;
 | 
			
		||||
	int read_only;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void set_activation(int activation);
 | 
			
		||||
int activation();
 | 
			
		||||
int activation(void);
 | 
			
		||||
 | 
			
		||||
int driver_version(char *version, size_t size);
 | 
			
		||||
int library_version(char *version, size_t size);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Returns 1 if info structure has been populated, else 0.
 | 
			
		||||
 */
 | 
			
		||||
int lv_info(struct logical_volume *lv, struct dm_info *info);
 | 
			
		||||
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.
 | 
			
		||||
 */
 | 
			
		||||
int lv_snapshot_percent(struct logical_volume *lv, float *percent);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * These should eventually use config file
 | 
			
		||||
 * to determine whether or not to activate
 | 
			
		||||
 */
 | 
			
		||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s);
 | 
			
		||||
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s);
 | 
			
		||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s);
 | 
			
		||||
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * FIXME:
 | 
			
		||||
 * I don't like the *lvs_in_vg* function names.
 | 
			
		||||
 */
 | 
			
		||||
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
 | 
			
		||||
		      uint32_t *event_nr);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return number of LVs in the VG that are active.
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,23 +1,34 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 <libdevmapper.h>
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
struct dev_manager;
 | 
			
		||||
struct dm_info;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Constructor and destructor.
 | 
			
		||||
 */
 | 
			
		||||
struct dev_manager *dev_manager_create(const char *vg_name);
 | 
			
		||||
struct dev_manager *dev_manager_create(const char *vg_name,
 | 
			
		||||
				       struct config_tree *cf);
 | 
			
		||||
void dev_manager_destroy(struct dev_manager *dm);
 | 
			
		||||
void dev_manager_exit(void);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The device handler is responsible for creating all the layered
 | 
			
		||||
@@ -25,14 +36,21 @@ void dev_manager_destroy(struct dev_manager *dm);
 | 
			
		||||
 * (eg, an origin is created before its snapshot, but is not
 | 
			
		||||
 * unsuspended until the snapshot is also created.)
 | 
			
		||||
 */
 | 
			
		||||
int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
 | 
			
		||||
		     struct dm_info *info);
 | 
			
		||||
int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
 | 
			
		||||
		     int mknodes, struct dm_info *info);
 | 
			
		||||
int dev_manager_snapshot_percent(struct dev_manager *dm,
 | 
			
		||||
				 struct logical_volume *lv, float *percent);
 | 
			
		||||
int dev_manager_mirror_percent(struct dev_manager *dm,
 | 
			
		||||
			       struct logical_volume *lv, int wait,
 | 
			
		||||
			       float *percent, uint32_t *event_nr);
 | 
			
		||||
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
 | 
			
		||||
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
 | 
			
		||||
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
 | 
			
		||||
 | 
			
		||||
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"
 | 
			
		||||
@@ -9,19 +18,25 @@
 | 
			
		||||
#include "toolcontext.h"
 | 
			
		||||
#include "lvm-string.h"
 | 
			
		||||
#include "lvm-file.h"
 | 
			
		||||
#include "memlock.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SELINUX
 | 
			
		||||
#  include "selinux.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <libdevmapper.h>
 | 
			
		||||
 | 
			
		||||
static int _mk_dir(struct volume_group *vg)
 | 
			
		||||
static int _mk_dir(const char *dev_dir, const char *vg_name)
 | 
			
		||||
{
 | 
			
		||||
	char vg_path[PATH_MAX];
 | 
			
		||||
 | 
			
		||||
	if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
 | 
			
		||||
			 vg->cmd->dev_dir, vg->name) == -1) {
 | 
			
		||||
			 dev_dir, vg_name) == -1) {
 | 
			
		||||
		log_error("Couldn't construct name of volume "
 | 
			
		||||
			  "group directory.");
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -39,12 +54,12 @@ static int _mk_dir(struct volume_group *vg)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _rm_dir(struct volume_group *vg)
 | 
			
		||||
static int _rm_dir(const char *dev_dir, const char *vg_name)
 | 
			
		||||
{
 | 
			
		||||
	char vg_path[PATH_MAX];
 | 
			
		||||
 | 
			
		||||
	if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
 | 
			
		||||
			 vg->cmd->dev_dir, vg->name) == -1) {
 | 
			
		||||
			 dev_dir, vg_name) == -1) {
 | 
			
		||||
		log_error("Couldn't construct name of volume "
 | 
			
		||||
			  "group directory.");
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -58,32 +73,100 @@ static int _rm_dir(struct volume_group *vg)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _mk_link(struct logical_volume *lv, const char *dev)
 | 
			
		||||
static void _rm_blks(const char *dir)
 | 
			
		||||
{
 | 
			
		||||
	char lv_path[PATH_MAX], link_path[PATH_MAX];
 | 
			
		||||
	const char *name;
 | 
			
		||||
	char path[PATH_MAX];
 | 
			
		||||
	struct dirent *dirent;
 | 
			
		||||
	struct stat buf;
 | 
			
		||||
	DIR *d;
 | 
			
		||||
 | 
			
		||||
	if (!(d = opendir(dir))) {
 | 
			
		||||
		log_sys_error("opendir", dir);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while ((dirent = readdir(d))) {
 | 
			
		||||
		name = dirent->d_name;
 | 
			
		||||
 | 
			
		||||
		if (!strcmp(name, ".") || !strcmp(name, ".."))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (lvm_snprintf(path, sizeof(path), "%s/%s", dir, name) == -1) {
 | 
			
		||||
			log_error("Couldn't create path for %s", name);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!lstat(path, &buf)) {
 | 
			
		||||
			if (!S_ISBLK(buf.st_mode))
 | 
			
		||||
				continue;
 | 
			
		||||
			log_very_verbose("Removing %s", path);
 | 
			
		||||
			if (unlink(path) < 0)
 | 
			
		||||
				log_sys_error("unlink", path);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _mk_link(const char *dev_dir, const char *vg_name,
 | 
			
		||||
		    const char *lv_name, const char *dev)
 | 
			
		||||
{
 | 
			
		||||
	char lv_path[PATH_MAX], link_path[PATH_MAX], lvm1_group_path[PATH_MAX];
 | 
			
		||||
	char vg_path[PATH_MAX];
 | 
			
		||||
	struct stat buf;
 | 
			
		||||
 | 
			
		||||
	if (lvm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
 | 
			
		||||
			 lv->vg->cmd->dev_dir, lv->vg->name, lv->name) == -1) {
 | 
			
		||||
	if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
 | 
			
		||||
			 dev_dir, vg_name) == -1) {
 | 
			
		||||
		log_error("Couldn't create path for volume group dir %s",
 | 
			
		||||
			  vg_name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lvm_snprintf(lv_path, sizeof(lv_path), "%s/%s", vg_path,
 | 
			
		||||
			 lv_name) == -1) {
 | 
			
		||||
		log_error("Couldn't create source pathname for "
 | 
			
		||||
			  "logical volume link %s", lv->name);
 | 
			
		||||
			  "logical volume link %s", lv_name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lvm_snprintf(link_path, sizeof(link_path), "%s/%s",
 | 
			
		||||
			 dm_dir(), dev) == -1) {
 | 
			
		||||
		log_error("Couldn't create destination pathname for "
 | 
			
		||||
			  "logical volume link for %s", lv->name);
 | 
			
		||||
			  "logical volume link for %s", lv_name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lvm_snprintf(lvm1_group_path, sizeof(lvm1_group_path), "%s/group",
 | 
			
		||||
			 vg_path) == -1) {
 | 
			
		||||
		log_error("Couldn't create pathname for LVM1 group file for %s",
 | 
			
		||||
			  vg_name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* To reach this point, the VG must have been locked.
 | 
			
		||||
	 * As locking fails if the VG is active under LVM1, it's 
 | 
			
		||||
	 * now safe to remove any LVM1 devices we find here
 | 
			
		||||
	 * (as well as any existing LVM2 symlink). */
 | 
			
		||||
	if (!lstat(lvm1_group_path, &buf)) {
 | 
			
		||||
		if (!S_ISCHR(buf.st_mode)) {
 | 
			
		||||
			log_error("Non-LVM1 character device found at %s",
 | 
			
		||||
				  lvm1_group_path);
 | 
			
		||||
		} else {
 | 
			
		||||
			_rm_blks(vg_path);
 | 
			
		||||
 | 
			
		||||
			log_very_verbose("Removing %s", lvm1_group_path);
 | 
			
		||||
			if (unlink(lvm1_group_path) < 0)
 | 
			
		||||
				log_sys_error("unlink", lvm1_group_path);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!lstat(lv_path, &buf)) {
 | 
			
		||||
		if (!S_ISLNK(buf.st_mode)) {
 | 
			
		||||
		if (!S_ISLNK(buf.st_mode) && !S_ISBLK(buf.st_mode)) {
 | 
			
		||||
			log_error("Symbolic link %s not created: file exists",
 | 
			
		||||
				  link_path);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		log_very_verbose("Removing %s", lv_path);
 | 
			
		||||
		if (unlink(lv_path) < 0) {
 | 
			
		||||
			log_sys_error("unlink", lv_path);
 | 
			
		||||
			return 0;
 | 
			
		||||
@@ -96,26 +179,36 @@ static int _mk_link(struct logical_volume *lv, const char *dev)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SELINUX
 | 
			
		||||
        if (!set_selinux_context(lv_path)) {
 | 
			
		||||
                log_sys_error("set_selinux_context", lv_path);
 | 
			
		||||
                return 0;
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _rm_link(struct logical_volume *lv, const char *lv_name)
 | 
			
		||||
static int _rm_link(const char *dev_dir, const char *vg_name,
 | 
			
		||||
		    const char *lv_name)
 | 
			
		||||
{
 | 
			
		||||
	struct stat buf;
 | 
			
		||||
	char lv_path[PATH_MAX];
 | 
			
		||||
 | 
			
		||||
	if (lvm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
 | 
			
		||||
			 lv->vg->cmd->dev_dir, lv->vg->name, lv_name) == -1) {
 | 
			
		||||
			 dev_dir, vg_name, lv_name) == -1) {
 | 
			
		||||
		log_error("Couldn't determine link pathname.");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_very_verbose("Removing link %s", lv_path);
 | 
			
		||||
	if (lstat(lv_path, &buf) || !S_ISLNK(buf.st_mode)) {
 | 
			
		||||
		log_error("%s not symbolic link - not removing", lv_path);
 | 
			
		||||
		if (errno != ENOENT)
 | 
			
		||||
			log_error("%s not symbolic link - not removing",
 | 
			
		||||
				  lv_path);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_very_verbose("Removing link %s", lv_path);
 | 
			
		||||
	if (unlink(lv_path) < 0) {
 | 
			
		||||
		log_sys_error("unlink", lv_path);
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -124,35 +217,143 @@ static int _rm_link(struct logical_volume *lv, const char *lv_name)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fs_add_lv(struct logical_volume *lv, const char *dev)
 | 
			
		||||
typedef enum {
 | 
			
		||||
	FS_ADD,
 | 
			
		||||
	FS_DEL,
 | 
			
		||||
	FS_RENAME
 | 
			
		||||
} fs_op_t;
 | 
			
		||||
 | 
			
		||||
static int _do_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
 | 
			
		||||
		     const char *lv_name, const char *dev,
 | 
			
		||||
		     const char *old_lv_name)
 | 
			
		||||
{
 | 
			
		||||
	if (!_mk_dir(lv->vg) || !_mk_link(lv, dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	switch (type) {
 | 
			
		||||
	case FS_ADD:
 | 
			
		||||
		if (!_mk_dir(dev_dir, vg_name) ||
 | 
			
		||||
		    !_mk_link(dev_dir, vg_name, lv_name, dev)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case FS_DEL:
 | 
			
		||||
		if (!_rm_link(dev_dir, vg_name, lv_name) ||
 | 
			
		||||
		    !_rm_dir(dev_dir, vg_name)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
		/* FIXME Use rename() */
 | 
			
		||||
	case FS_RENAME:
 | 
			
		||||
		if (old_lv_name && !_rm_link(dev_dir, vg_name, old_lv_name))
 | 
			
		||||
			stack;
 | 
			
		||||
 | 
			
		||||
		if (!_mk_link(dev_dir, vg_name, lv_name, dev))
 | 
			
		||||
			stack;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fs_del_lv(struct logical_volume *lv)
 | 
			
		||||
static LIST_INIT(_fs_ops);
 | 
			
		||||
 | 
			
		||||
struct fs_op_parms {
 | 
			
		||||
	struct list list;
 | 
			
		||||
	fs_op_t type;
 | 
			
		||||
	char *dev_dir;
 | 
			
		||||
	char *vg_name;
 | 
			
		||||
	char *lv_name;
 | 
			
		||||
	char *dev;
 | 
			
		||||
	char *old_lv_name;
 | 
			
		||||
	char names[0];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void _store_str(char **pos, char **ptr, const char *str)
 | 
			
		||||
{
 | 
			
		||||
	if (!_rm_link(lv, lv->name) || !_rm_dir(lv->vg)) {
 | 
			
		||||
		stack;
 | 
			
		||||
	strcpy(*pos, str);
 | 
			
		||||
	*ptr = *pos;
 | 
			
		||||
	*pos += strlen(*ptr) + 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
 | 
			
		||||
			const char *lv_name, const char *dev,
 | 
			
		||||
			const char *old_lv_name)
 | 
			
		||||
{
 | 
			
		||||
	struct fs_op_parms *fsp;
 | 
			
		||||
	size_t len = strlen(dev_dir) + strlen(vg_name) + strlen(lv_name) +
 | 
			
		||||
	    strlen(dev) + strlen(old_lv_name) + 5;
 | 
			
		||||
	char *pos;
 | 
			
		||||
 | 
			
		||||
	if (!(fsp = dbg_malloc(sizeof(*fsp) + len))) {
 | 
			
		||||
		log_error("No space to stack fs operation");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pos = fsp->names;
 | 
			
		||||
	fsp->type = type;
 | 
			
		||||
 | 
			
		||||
	_store_str(&pos, &fsp->dev_dir, dev_dir);
 | 
			
		||||
	_store_str(&pos, &fsp->vg_name, vg_name);
 | 
			
		||||
	_store_str(&pos, &fsp->lv_name, lv_name);
 | 
			
		||||
	_store_str(&pos, &fsp->dev, dev);
 | 
			
		||||
	_store_str(&pos, &fsp->old_lv_name, old_lv_name);
 | 
			
		||||
 | 
			
		||||
	list_add(&_fs_ops, &fsp->list);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* FIXME Use rename() */
 | 
			
		||||
static void _pop_fs_ops(void)
 | 
			
		||||
{
 | 
			
		||||
	struct list *fsph, *fspht;
 | 
			
		||||
	struct fs_op_parms *fsp;
 | 
			
		||||
 | 
			
		||||
	list_iterate_safe(fsph, fspht, &_fs_ops) {
 | 
			
		||||
		fsp = list_item(fsph, struct fs_op_parms);
 | 
			
		||||
		_do_fs_op(fsp->type, fsp->dev_dir, fsp->vg_name, fsp->lv_name,
 | 
			
		||||
			  fsp->dev, fsp->old_lv_name);
 | 
			
		||||
		list_del(&fsp->list);
 | 
			
		||||
		dbg_free(fsp);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
 | 
			
		||||
		  const char *lv_name, const char *dev, const char *old_lv_name)
 | 
			
		||||
{
 | 
			
		||||
	if (memlock()) {
 | 
			
		||||
		if (!_stack_fs_op(type, dev_dir, vg_name, lv_name, dev,
 | 
			
		||||
				  old_lv_name)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return _do_fs_op(type, dev_dir, vg_name, lv_name, dev, old_lv_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fs_add_lv(const struct logical_volume *lv, const char *dev)
 | 
			
		||||
{
 | 
			
		||||
	return _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
 | 
			
		||||
		      dev, "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fs_del_lv(const struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
	return _fs_op(FS_DEL, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
 | 
			
		||||
		      "", "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fs_rename_lv(struct logical_volume *lv,
 | 
			
		||||
		 const char *dev, const char *old_name)
 | 
			
		||||
{
 | 
			
		||||
	if (old_name && !_rm_link(lv, old_name))
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	if (!_mk_link(lv, dev))
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
	return _fs_op(FS_RENAME, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
 | 
			
		||||
		      dev, old_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void fs_unlock(void)
 | 
			
		||||
{
 | 
			
		||||
	if (!memlock()) {
 | 
			
		||||
		dm_lib_release();
 | 
			
		||||
		_pop_fs_ops();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_FS_H
 | 
			
		||||
@@ -14,10 +23,10 @@
 | 
			
		||||
 * up the volume group directory in /dev and the
 | 
			
		||||
 * symbolic links to the dm device.
 | 
			
		||||
 */
 | 
			
		||||
int fs_add_lv(struct logical_volume *lv, const char *dev);
 | 
			
		||||
int fs_del_lv(struct logical_volume *lv);
 | 
			
		||||
int fs_add_lv(const struct logical_volume *lv, const char *dev);
 | 
			
		||||
int fs_del_lv(const struct logical_volume *lv);
 | 
			
		||||
int fs_rename_lv(struct logical_volume *lv,
 | 
			
		||||
		 const char *dev, const char *old_name);
 | 
			
		||||
 | 
			
		||||
void fs_unlock(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										73
									
								
								lib/cache/cache.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										73
									
								
								lib/cache/cache.h
									
									
									
									
										vendored
									
									
								
							@@ -1,73 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_CACHE_H
 | 
			
		||||
#define _LVM_CACHE_H
 | 
			
		||||
 | 
			
		||||
#include "dev-cache.h"
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "uuid.h"
 | 
			
		||||
#include "label.h"
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#define ORPHAN ""
 | 
			
		||||
 | 
			
		||||
#define CACHE_INVALID 0x00000001
 | 
			
		||||
 | 
			
		||||
/* LVM specific per-volume info */
 | 
			
		||||
/* Eventual replacement for struct physical_volume perhaps? */
 | 
			
		||||
 | 
			
		||||
struct cache_vginfo {
 | 
			
		||||
	struct list list;	/* Join these vginfos together */
 | 
			
		||||
	struct list infos;	/* List head for cache_infos */
 | 
			
		||||
	char *vgname;		/* "" == orphan */
 | 
			
		||||
	char vgid[ID_LEN + 1];
 | 
			
		||||
	struct format_type *fmt;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct cache_info {
 | 
			
		||||
	struct list list;	/* Join VG members together */
 | 
			
		||||
	struct list mdas;	/* list head for metadata areas */
 | 
			
		||||
	struct list das;	/* list head for data areas */
 | 
			
		||||
	struct cache_vginfo *vginfo;	/* NULL == unknown */
 | 
			
		||||
	struct label *label;
 | 
			
		||||
	struct format_type *fmt;
 | 
			
		||||
	struct device *dev;
 | 
			
		||||
	uint64_t device_size;	/* Bytes */
 | 
			
		||||
	uint32_t status;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int cache_init();
 | 
			
		||||
void cache_destroy();
 | 
			
		||||
 | 
			
		||||
/* Set full_scan to 1 to reread every filtered device label */
 | 
			
		||||
int cache_label_scan(struct cmd_context *cmd, int full_scan);
 | 
			
		||||
 | 
			
		||||
/* Add/delete a device */
 | 
			
		||||
struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
 | 
			
		||||
			     struct device *dev,
 | 
			
		||||
			     const char *vgname, const char *vgid);
 | 
			
		||||
void cache_del(struct cache_info *info);
 | 
			
		||||
 | 
			
		||||
/* Update things */
 | 
			
		||||
int cache_update_vgname(struct cache_info *info, const char *vgname);
 | 
			
		||||
int cache_update_vg(struct volume_group *vg);
 | 
			
		||||
 | 
			
		||||
/* Queries */
 | 
			
		||||
struct format_type *fmt_from_vgname(const char *vgname);
 | 
			
		||||
struct cache_vginfo *vginfo_from_vgname(const char *vgname);
 | 
			
		||||
struct cache_vginfo *vginfo_from_vgid(const char *vgid);
 | 
			
		||||
struct cache_info *info_from_pvid(const char *pvid);
 | 
			
		||||
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
 | 
			
		||||
 | 
			
		||||
/* Returns list of struct str_lists containing pool-allocated copy of vgnames */
 | 
			
		||||
/* Set full_scan to 1 to reread every filtered device label */
 | 
			
		||||
struct list *cache_get_vgnames(struct cmd_context *cmd, int full_scan);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										236
									
								
								lib/cache/cache.c → lib/cache/lvmcache.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										236
									
								
								lib/cache/cache.c → lib/cache/lvmcache.c
									
									
									
									
										vendored
									
									
								
							@@ -1,24 +1,38 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
#include "cache.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "toolcontext.h"
 | 
			
		||||
#include "dev-cache.h"
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
#include "filter.h"
 | 
			
		||||
#include "memlock.h"
 | 
			
		||||
#include "str_list.h"
 | 
			
		||||
 | 
			
		||||
static struct hash_table *_pvid_hash = NULL;
 | 
			
		||||
static struct hash_table *_vgid_hash = NULL;
 | 
			
		||||
static struct hash_table *_vgname_hash = NULL;
 | 
			
		||||
static struct hash_table *_lock_hash = NULL;
 | 
			
		||||
static struct list _vginfos;
 | 
			
		||||
int _has_scanned = 0;
 | 
			
		||||
static int _has_scanned = 0;
 | 
			
		||||
static int _vgs_locked = 0;
 | 
			
		||||
 | 
			
		||||
int cache_init()
 | 
			
		||||
int lvmcache_init(void)
 | 
			
		||||
{
 | 
			
		||||
	list_init(&_vginfos);
 | 
			
		||||
 | 
			
		||||
@@ -31,12 +45,52 @@ int cache_init()
 | 
			
		||||
	if (!(_pvid_hash = hash_create(128)))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!(_lock_hash = hash_create(128)))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct cache_vginfo *vginfo_from_vgname(const char *vgname)
 | 
			
		||||
void lvmcache_lock_vgname(const char *vgname, int read_only)
 | 
			
		||||
{
 | 
			
		||||
	struct cache_vginfo *vginfo;
 | 
			
		||||
	if (!_lock_hash && !lvmcache_init()) {
 | 
			
		||||
		log_error("Internal cache initialisation failed");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!hash_insert(_lock_hash, vgname, (void *) 1))
 | 
			
		||||
		log_error("Cache locking failure for %s", vgname);
 | 
			
		||||
 | 
			
		||||
	_vgs_locked++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _vgname_is_locked(const char *vgname) __attribute__ ((unused));
 | 
			
		||||
static int _vgname_is_locked(const char *vgname)
 | 
			
		||||
{
 | 
			
		||||
	if (!_lock_hash)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return hash_lookup(_lock_hash, vgname) ? 1 : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lvmcache_unlock_vgname(const char *vgname)
 | 
			
		||||
{
 | 
			
		||||
	/* FIXME: Clear all CACHE_LOCKED flags in this vg */
 | 
			
		||||
	hash_remove(_lock_hash, vgname);
 | 
			
		||||
 | 
			
		||||
	/* FIXME Do this per-VG */
 | 
			
		||||
	if (!--_vgs_locked)
 | 
			
		||||
		dev_close_all();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int vgs_locked(void)
 | 
			
		||||
{
 | 
			
		||||
	return _vgs_locked;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname)
 | 
			
		||||
{
 | 
			
		||||
	struct lvmcache_vginfo *vginfo;
 | 
			
		||||
 | 
			
		||||
	if (!_vgname_hash)
 | 
			
		||||
		return NULL;
 | 
			
		||||
@@ -47,9 +101,9 @@ struct cache_vginfo *vginfo_from_vgname(const char *vgname)
 | 
			
		||||
	return vginfo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct format_type *fmt_from_vgname(const char *vgname)
 | 
			
		||||
const struct format_type *fmt_from_vgname(const char *vgname)
 | 
			
		||||
{
 | 
			
		||||
	struct cache_vginfo *vginfo;
 | 
			
		||||
	struct lvmcache_vginfo *vginfo;
 | 
			
		||||
 | 
			
		||||
	if (!(vginfo = vginfo_from_vgname(vgname)))
 | 
			
		||||
		return NULL;
 | 
			
		||||
@@ -57,33 +111,42 @@ struct format_type *fmt_from_vgname(const char *vgname)
 | 
			
		||||
	return vginfo->fmt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct cache_vginfo *vginfo_from_vgid(const char *vgid)
 | 
			
		||||
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid)
 | 
			
		||||
{
 | 
			
		||||
	struct cache_vginfo *vginfo;
 | 
			
		||||
	struct lvmcache_vginfo *vginfo;
 | 
			
		||||
	char id[ID_LEN + 1];
 | 
			
		||||
 | 
			
		||||
	if (!_vgid_hash || !vgid)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	if (!(vginfo = hash_lookup_fixed(_vgid_hash, vgid, ID_LEN)))
 | 
			
		||||
	/* vgid not necessarily NULL-terminated */
 | 
			
		||||
	strncpy(&id[0], vgid, ID_LEN);
 | 
			
		||||
	id[ID_LEN] = '\0';
 | 
			
		||||
 | 
			
		||||
	if (!(vginfo = hash_lookup(_vgid_hash, id)))
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return vginfo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct cache_info *info_from_pvid(const char *pvid)
 | 
			
		||||
struct lvmcache_info *info_from_pvid(const char *pvid)
 | 
			
		||||
{
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
	char id[ID_LEN + 1];
 | 
			
		||||
 | 
			
		||||
	if (!_pvid_hash || !pvid)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	if (!(info = hash_lookup_fixed(_pvid_hash, pvid, ID_LEN)))
 | 
			
		||||
	strncpy(&id[0], pvid, ID_LEN);
 | 
			
		||||
	id[ID_LEN] = '\0';
 | 
			
		||||
 | 
			
		||||
	if (!(info = hash_lookup(_pvid_hash, id)))
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _rescan_entry(struct cache_info *info)
 | 
			
		||||
static void _rescan_entry(struct lvmcache_info *info)
 | 
			
		||||
{
 | 
			
		||||
	struct label *label;
 | 
			
		||||
 | 
			
		||||
@@ -91,14 +154,14 @@ static void _rescan_entry(struct cache_info *info)
 | 
			
		||||
		label_read(info->dev, &label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _scan_invalid(struct cmd_context *cmd)
 | 
			
		||||
static int _scan_invalid(void)
 | 
			
		||||
{
 | 
			
		||||
	hash_iter(_pvid_hash, (iterate_fn) _rescan_entry);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cache_label_scan(struct cmd_context *cmd, int full_scan)
 | 
			
		||||
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
 | 
			
		||||
{
 | 
			
		||||
	struct label *label;
 | 
			
		||||
	struct dev_iter *iter;
 | 
			
		||||
@@ -115,13 +178,13 @@ int cache_label_scan(struct cmd_context *cmd, int full_scan)
 | 
			
		||||
 | 
			
		||||
	_scanning_in_progress = 1;
 | 
			
		||||
 | 
			
		||||
	if (!_vgname_hash && !cache_init()) {
 | 
			
		||||
	if (!_vgname_hash && !lvmcache_init()) {
 | 
			
		||||
		log_error("Internal cache initialisation failed");
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (_has_scanned && !full_scan) {
 | 
			
		||||
		r = _scan_invalid(cmd);
 | 
			
		||||
		r = _scan_invalid();
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -152,33 +215,24 @@ int cache_label_scan(struct cmd_context *cmd, int full_scan)
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct list *cache_get_vgnames(struct cmd_context *cmd, int full_scan)
 | 
			
		||||
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
 | 
			
		||||
{
 | 
			
		||||
	struct list *vgih, *vgnames;
 | 
			
		||||
	struct str_list *sl;
 | 
			
		||||
	struct list *vgnames;
 | 
			
		||||
	struct lvmcache_vginfo *vgi;
 | 
			
		||||
 | 
			
		||||
	cache_label_scan(cmd, full_scan);
 | 
			
		||||
	lvmcache_label_scan(cmd, full_scan);
 | 
			
		||||
 | 
			
		||||
	if (!(vgnames = pool_alloc(cmd->mem, sizeof(struct list)))) {
 | 
			
		||||
	if (!(vgnames = str_list_create(cmd->mem))) {
 | 
			
		||||
		log_error("vgnames list allocation failed");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_init(vgnames);
 | 
			
		||||
 | 
			
		||||
	list_iterate(vgih, &_vginfos) {
 | 
			
		||||
		if (!(sl = pool_alloc(cmd->mem, sizeof(*sl)))) {
 | 
			
		||||
	list_iterate_items(vgi, &_vginfos) {
 | 
			
		||||
		if (!str_list_add(cmd->mem, vgnames, 
 | 
			
		||||
				  pool_strdup(cmd->mem, vgi->vgname))) {
 | 
			
		||||
			log_error("strlist allocation failed");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		if (!(sl->str = pool_strdup(cmd->mem,
 | 
			
		||||
					    list_item(vgih,
 | 
			
		||||
						      struct cache_vginfo)->
 | 
			
		||||
					    vgname))) {
 | 
			
		||||
			log_error("vgname allocation failed");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		list_add(vgnames, &sl->list);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return vgnames;
 | 
			
		||||
@@ -187,34 +241,37 @@ struct list *cache_get_vgnames(struct cmd_context *cmd, int full_scan)
 | 
			
		||||
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
 | 
			
		||||
{
 | 
			
		||||
	struct label *label;
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
 | 
			
		||||
	/* Already cached ? */
 | 
			
		||||
	if ((info = info_from_pvid((char *) pvid))) {
 | 
			
		||||
		if (label_read(info->dev, &label)) {
 | 
			
		||||
			info = (struct cache_info *) label->info;
 | 
			
		||||
			info = (struct lvmcache_info *) label->info;
 | 
			
		||||
			if (id_equal(pvid, (struct id *) &info->dev->pvid))
 | 
			
		||||
				return info->dev;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cache_label_scan(cmd, 0);
 | 
			
		||||
	lvmcache_label_scan(cmd, 0);
 | 
			
		||||
 | 
			
		||||
	/* Try again */
 | 
			
		||||
	if ((info = info_from_pvid((char *) pvid))) {
 | 
			
		||||
		if (label_read(info->dev, &label)) {
 | 
			
		||||
			info = (struct cache_info *) label->info;
 | 
			
		||||
			info = (struct lvmcache_info *) label->info;
 | 
			
		||||
			if (id_equal(pvid, (struct id *) &info->dev->pvid))
 | 
			
		||||
				return info->dev;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cache_label_scan(cmd, 1);
 | 
			
		||||
	if (memlock())
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	lvmcache_label_scan(cmd, 1);
 | 
			
		||||
 | 
			
		||||
	/* Try again */
 | 
			
		||||
	if ((info = info_from_pvid((char *) pvid))) {
 | 
			
		||||
		if (label_read(info->dev, &label)) {
 | 
			
		||||
			info = (struct cache_info *) label->info;
 | 
			
		||||
			info = (struct lvmcache_info *) label->info;
 | 
			
		||||
			if (id_equal(pvid, (struct id *) &info->dev->pvid))
 | 
			
		||||
				return info->dev;
 | 
			
		||||
		}
 | 
			
		||||
@@ -223,7 +280,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _drop_vginfo(struct cache_info *info)
 | 
			
		||||
static void _drop_vginfo(struct lvmcache_info *info)
 | 
			
		||||
{
 | 
			
		||||
	if (!list_empty(&info->list)) {
 | 
			
		||||
		list_del(&info->list);
 | 
			
		||||
@@ -244,7 +301,7 @@ void _drop_vginfo(struct cache_info *info)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Unused
 | 
			
		||||
void cache_del(struct cache_info *info)
 | 
			
		||||
void lvmcache_del(struct lvmcache_info *info)
 | 
			
		||||
{
 | 
			
		||||
	if (info->dev->pvid[0] && _pvid_hash)
 | 
			
		||||
		hash_remove(_pvid_hash, info->dev->pvid);
 | 
			
		||||
@@ -258,7 +315,7 @@ void cache_del(struct cache_info *info)
 | 
			
		||||
	return;
 | 
			
		||||
} */
 | 
			
		||||
 | 
			
		||||
static int _cache_update_pvid(struct cache_info *info, const char *pvid)
 | 
			
		||||
static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
 | 
			
		||||
{
 | 
			
		||||
	if (!strcmp(info->dev->pvid, pvid))
 | 
			
		||||
		return 1;
 | 
			
		||||
@@ -267,14 +324,14 @@ static int _cache_update_pvid(struct cache_info *info, const char *pvid)
 | 
			
		||||
	}
 | 
			
		||||
	strncpy(info->dev->pvid, pvid, sizeof(info->dev->pvid));
 | 
			
		||||
	if (!hash_insert(_pvid_hash, pvid, info)) {
 | 
			
		||||
		log_error("_cache_update: pvid insertion failed: %s", pvid);
 | 
			
		||||
		log_error("_lvmcache_update: pvid insertion failed: %s", pvid);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _cache_update_vgid(struct cache_info *info, const char *vgid)
 | 
			
		||||
static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
 | 
			
		||||
{
 | 
			
		||||
	if (!vgid || !info->vginfo || !strncmp(info->vginfo->vgid, vgid,
 | 
			
		||||
					       sizeof(info->vginfo->vgid)))
 | 
			
		||||
@@ -287,18 +344,18 @@ static int _cache_update_vgid(struct cache_info *info, const char *vgid)
 | 
			
		||||
 | 
			
		||||
	strncpy(info->vginfo->vgid, vgid, sizeof(info->vginfo->vgid));
 | 
			
		||||
	info->vginfo->vgid[sizeof(info->vginfo->vgid) - 1] = '\0';
 | 
			
		||||
	if (!hash_insert(_vgid_hash, vgid, info->vginfo)) {
 | 
			
		||||
		log_error("_cache_update: vgid hash insertion failed: %s",
 | 
			
		||||
			  vgid);
 | 
			
		||||
	if (!hash_insert(_vgid_hash, info->vginfo->vgid, info->vginfo)) {
 | 
			
		||||
		log_error("_lvmcache_update: vgid hash insertion failed: %s",
 | 
			
		||||
			  info->vginfo->vgid);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cache_update_vgname(struct cache_info *info, const char *vgname)
 | 
			
		||||
int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
 | 
			
		||||
{
 | 
			
		||||
	struct cache_vginfo *vginfo;
 | 
			
		||||
	struct lvmcache_vginfo *vginfo;
 | 
			
		||||
 | 
			
		||||
	/* If vgname is NULL and we don't already have a vgname, 
 | 
			
		||||
	 * assume ORPHAN - we want every entry to have a vginfo
 | 
			
		||||
@@ -316,7 +373,7 @@ int cache_update_vgname(struct cache_info *info, const char *vgname)
 | 
			
		||||
	/* Get existing vginfo or create new one */
 | 
			
		||||
	if (!(vginfo = vginfo_from_vgname(vgname))) {
 | 
			
		||||
		if (!(vginfo = dbg_malloc(sizeof(*vginfo)))) {
 | 
			
		||||
			log_error("cache_update_vgname: list alloc failed");
 | 
			
		||||
			log_error("lvmcache_update_vgname: list alloc failed");
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		memset(vginfo, 0, sizeof(*vginfo));
 | 
			
		||||
@@ -349,11 +406,11 @@ int cache_update_vgname(struct cache_info *info, const char *vgname)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cache_update_vg(struct volume_group *vg)
 | 
			
		||||
int lvmcache_update_vg(struct volume_group *vg)
 | 
			
		||||
{
 | 
			
		||||
	struct list *pvh;
 | 
			
		||||
	struct physical_volume *pv;
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
	char pvid_s[ID_LEN + 1];
 | 
			
		||||
	int vgid_updated = 0;
 | 
			
		||||
 | 
			
		||||
@@ -364,9 +421,9 @@ int cache_update_vg(struct volume_group *vg)
 | 
			
		||||
		strncpy(pvid_s, (char *) &pv->id, sizeof(pvid_s) - 1);
 | 
			
		||||
		/* FIXME Could pv->dev->pvid ever be different? */
 | 
			
		||||
		if ((info = info_from_pvid(pvid_s))) {
 | 
			
		||||
			cache_update_vgname(info, vg->name);
 | 
			
		||||
			lvmcache_update_vgname(info, vg->name);
 | 
			
		||||
			if (!vgid_updated) {
 | 
			
		||||
				_cache_update_vgid(info, (char *) &vg->id);
 | 
			
		||||
				_lvmcache_update_vgid(info, (char *) &vg->id);
 | 
			
		||||
				vgid_updated = 1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -375,15 +432,15 @@ int cache_update_vg(struct volume_group *vg)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
 | 
			
		||||
			     struct device *dev,
 | 
			
		||||
			     const char *vgname, const char *vgid)
 | 
			
		||||
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
 | 
			
		||||
				   struct device *dev,
 | 
			
		||||
				   const char *vgname, const char *vgid)
 | 
			
		||||
{
 | 
			
		||||
	struct label *label;
 | 
			
		||||
	struct cache_info *existing, *info;
 | 
			
		||||
	struct lvmcache_info *existing, *info;
 | 
			
		||||
	char pvid_s[ID_LEN + 1];
 | 
			
		||||
 | 
			
		||||
	if (!_vgname_hash && !cache_init()) {
 | 
			
		||||
	if (!_vgname_hash && !lvmcache_init()) {
 | 
			
		||||
		log_error("Internal cache initialisation failed");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
@@ -398,7 +455,7 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		if (!(info = dbg_malloc(sizeof(*info)))) {
 | 
			
		||||
			log_error("cache_info allocation failed");
 | 
			
		||||
			log_error("lvmcache_info allocation failed");
 | 
			
		||||
			label_destroy(label);
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
@@ -409,6 +466,26 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
 | 
			
		||||
		list_init(&info->list);
 | 
			
		||||
		info->dev = dev;
 | 
			
		||||
	} else {
 | 
			
		||||
		if (existing->dev != dev) {
 | 
			
		||||
			/* Is the existing entry a duplicate pvid e.g. md ? */
 | 
			
		||||
			if (MAJOR(existing->dev->dev) == md_major() &&
 | 
			
		||||
			    MAJOR(dev->dev) != md_major()) {
 | 
			
		||||
				log_very_verbose("Ignoring duplicate PV %s on "
 | 
			
		||||
						 "%s - using md %s",
 | 
			
		||||
						 pvid, dev_name(dev),
 | 
			
		||||
						 dev_name(existing->dev));
 | 
			
		||||
				return NULL;
 | 
			
		||||
			} else if (MAJOR(existing->dev->dev) != md_major() &&
 | 
			
		||||
				   MAJOR(dev->dev) == md_major())
 | 
			
		||||
				log_very_verbose("Duplicate PV %s on %s - "
 | 
			
		||||
						 "using md %s", pvid,
 | 
			
		||||
						 dev_name(existing->dev),
 | 
			
		||||
						 dev_name(dev));
 | 
			
		||||
			else
 | 
			
		||||
				log_error("Found duplicate PV %s: using %s not "
 | 
			
		||||
					  "%s", pvid, dev_name(dev),
 | 
			
		||||
					  dev_name(existing->dev));
 | 
			
		||||
		}
 | 
			
		||||
		info = existing;
 | 
			
		||||
		/* Has labeller changed? */
 | 
			
		||||
		if (info->label->labeller != labeller) {
 | 
			
		||||
@@ -423,10 +500,10 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
 | 
			
		||||
		label = info->label;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	info->fmt = (struct format_type *) labeller->private;
 | 
			
		||||
	info->fmt = (const struct format_type *) labeller->private;
 | 
			
		||||
	info->status |= CACHE_INVALID;
 | 
			
		||||
 | 
			
		||||
	if (!_cache_update_pvid(info, pvid_s)) {
 | 
			
		||||
	if (!_lvmcache_update_pvid(info, pvid_s)) {
 | 
			
		||||
		if (!existing) {
 | 
			
		||||
			dbg_free(info);
 | 
			
		||||
			label_destroy(label);
 | 
			
		||||
@@ -434,7 +511,7 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!cache_update_vgname(info, vgname)) {
 | 
			
		||||
	if (!lvmcache_update_vgname(info, vgname)) {
 | 
			
		||||
		if (!existing) {
 | 
			
		||||
			hash_remove(_pvid_hash, pvid_s);
 | 
			
		||||
			strcpy(info->dev->pvid, "");
 | 
			
		||||
@@ -444,14 +521,14 @@ struct cache_info *cache_add(struct labeller *labeller, const char *pvid,
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!_cache_update_vgid(info, vgid))
 | 
			
		||||
	if (!_lvmcache_update_vgid(info, vgid))
 | 
			
		||||
		/* Non-critical */
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _cache_destroy_entry(struct cache_info *info)
 | 
			
		||||
static void _lvmcache_destroy_entry(struct lvmcache_info *info)
 | 
			
		||||
{
 | 
			
		||||
	if (!list_empty(&info->list))
 | 
			
		||||
		list_del(&info->list);
 | 
			
		||||
@@ -460,14 +537,19 @@ static void _cache_destroy_entry(struct cache_info *info)
 | 
			
		||||
	dbg_free(info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _cache_destroy_vgnamelist(struct cache_vginfo *vginfo)
 | 
			
		||||
static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
 | 
			
		||||
{
 | 
			
		||||
	if (vginfo->vgname)
 | 
			
		||||
		dbg_free(vginfo->vgname);
 | 
			
		||||
	dbg_free(vginfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cache_destroy()
 | 
			
		||||
static void _lvmcache_destroy_lockname(int present)
 | 
			
		||||
{
 | 
			
		||||
	/* Nothing to do */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lvmcache_destroy(void)
 | 
			
		||||
{
 | 
			
		||||
	_has_scanned = 0;
 | 
			
		||||
 | 
			
		||||
@@ -477,15 +559,23 @@ void cache_destroy()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (_pvid_hash) {
 | 
			
		||||
		hash_iter(_pvid_hash, (iterate_fn) _cache_destroy_entry);
 | 
			
		||||
		hash_iter(_pvid_hash, (iterate_fn) _lvmcache_destroy_entry);
 | 
			
		||||
		hash_destroy(_pvid_hash);
 | 
			
		||||
		_pvid_hash = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (_vgname_hash) {
 | 
			
		||||
		hash_iter(_vgname_hash, (iterate_fn) _cache_destroy_vgnamelist);
 | 
			
		||||
		hash_iter(_vgname_hash,
 | 
			
		||||
			  (iterate_fn) _lvmcache_destroy_vgnamelist);
 | 
			
		||||
		hash_destroy(_vgname_hash);
 | 
			
		||||
		_vgname_hash = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (_lock_hash) {
 | 
			
		||||
		hash_iter(_lock_hash, (iterate_fn) _lvmcache_destroy_lockname);
 | 
			
		||||
		hash_destroy(_lock_hash);
 | 
			
		||||
		_lock_hash = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_init(&_vginfos);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										84
									
								
								lib/cache/lvmcache.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								lib/cache/lvmcache.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_CACHE_H
 | 
			
		||||
#define _LVM_CACHE_H
 | 
			
		||||
 | 
			
		||||
#include "dev-cache.h"
 | 
			
		||||
#include "uuid.h"
 | 
			
		||||
#include "label.h"
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
 | 
			
		||||
#define ORPHAN ""
 | 
			
		||||
 | 
			
		||||
#define CACHE_INVALID	0x00000001
 | 
			
		||||
#define CACHE_LOCKED	0x00000002
 | 
			
		||||
 | 
			
		||||
/* LVM specific per-volume info */
 | 
			
		||||
/* Eventual replacement for struct physical_volume perhaps? */
 | 
			
		||||
 | 
			
		||||
struct lvmcache_vginfo {
 | 
			
		||||
	struct list list;	/* Join these vginfos together */
 | 
			
		||||
	struct list infos;	/* List head for lvmcache_infos */
 | 
			
		||||
	char *vgname;		/* "" == orphan */
 | 
			
		||||
	char vgid[ID_LEN + 1];
 | 
			
		||||
	const struct format_type *fmt;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct lvmcache_info {
 | 
			
		||||
	struct list list;	/* Join VG members together */
 | 
			
		||||
	struct list mdas;	/* list head for metadata areas */
 | 
			
		||||
	struct list das;	/* list head for data areas */
 | 
			
		||||
	struct lvmcache_vginfo *vginfo;	/* NULL == unknown */
 | 
			
		||||
	struct label *label;
 | 
			
		||||
	const struct format_type *fmt;
 | 
			
		||||
	struct device *dev;
 | 
			
		||||
	uint64_t device_size;	/* Bytes */
 | 
			
		||||
	uint32_t status;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int lvmcache_init(void);
 | 
			
		||||
void lvmcache_destroy(void);
 | 
			
		||||
 | 
			
		||||
/* Set full_scan to 1 to reread every filtered device label */
 | 
			
		||||
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan);
 | 
			
		||||
 | 
			
		||||
/* Add/delete a device */
 | 
			
		||||
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
 | 
			
		||||
				   struct device *dev,
 | 
			
		||||
				   const char *vgname, const char *vgid);
 | 
			
		||||
void lvmcache_del(struct lvmcache_info *info);
 | 
			
		||||
 | 
			
		||||
/* Update things */
 | 
			
		||||
int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname);
 | 
			
		||||
int lvmcache_update_vg(struct volume_group *vg);
 | 
			
		||||
 | 
			
		||||
void lvmcache_lock_vgname(const char *vgname, int read_only);
 | 
			
		||||
void lvmcache_unlock_vgname(const char *vgname);
 | 
			
		||||
 | 
			
		||||
/* Queries */
 | 
			
		||||
const struct format_type *fmt_from_vgname(const char *vgname);
 | 
			
		||||
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname);
 | 
			
		||||
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);
 | 
			
		||||
struct lvmcache_info *info_from_pvid(const char *pvid);
 | 
			
		||||
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
 | 
			
		||||
int vgs_locked(void);
 | 
			
		||||
 | 
			
		||||
/* Returns list of struct str_lists containing pool-allocated copy of vgnames */
 | 
			
		||||
/* Set full_scan to 1 to reread every filtered device label */
 | 
			
		||||
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,16 +1,24 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_ERRORS_H
 | 
			
		||||
#define _LVM_ERRORS_H
 | 
			
		||||
 | 
			
		||||
#define EINVALID_CMD_LINE	1
 | 
			
		||||
#define ENO_SUCH_CMD		3
 | 
			
		||||
#define ECMD_PROCESSED		4
 | 
			
		||||
#define ECMD_PROCESSED		1
 | 
			
		||||
#define ENO_SUCH_CMD		2
 | 
			
		||||
#define EINVALID_CMD_LINE	3
 | 
			
		||||
#define ECMD_FAILED		5
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,12 +23,20 @@
 | 
			
		||||
#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"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LIBDL
 | 
			
		||||
#include "sharedlib.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LVM1_INTERNAL
 | 
			
		||||
#include "format1.h"
 | 
			
		||||
@@ -27,10 +44,14 @@
 | 
			
		||||
 | 
			
		||||
#include <locale.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#ifdef linux
 | 
			
		||||
#  include <malloc.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static FILE *_log;
 | 
			
		||||
 | 
			
		||||
static int _get_env_vars(struct cmd_context *cmd)
 | 
			
		||||
@@ -52,14 +73,14 @@ static int _get_env_vars(struct cmd_context *cmd)
 | 
			
		||||
 | 
			
		||||
static void _init_logging(struct cmd_context *cmd)
 | 
			
		||||
{
 | 
			
		||||
	char *open_mode = "a";
 | 
			
		||||
	int append = 1;
 | 
			
		||||
	time_t t;
 | 
			
		||||
 | 
			
		||||
	const char *log_file;
 | 
			
		||||
 | 
			
		||||
	/* 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();
 | 
			
		||||
 | 
			
		||||
@@ -68,51 +89,59 @@ static void _init_logging(struct cmd_context *cmd)
 | 
			
		||||
 | 
			
		||||
	/* Debug level for log file output */
 | 
			
		||||
	cmd->default_settings.debug =
 | 
			
		||||
	    find_config_int(cmd->cf->root, "log/level", '/', DEFAULT_LOGLEVEL);
 | 
			
		||||
	    find_config_int(cmd->cft->root, "log/level", DEFAULT_LOGLEVEL);
 | 
			
		||||
	init_debug(cmd->default_settings.debug);
 | 
			
		||||
 | 
			
		||||
	/* Verbose level for tty output */
 | 
			
		||||
	cmd->default_settings.verbose =
 | 
			
		||||
	    find_config_int(cmd->cf->root, "log/verbose", '/', DEFAULT_VERBOSE);
 | 
			
		||||
	init_verbose(cmd->default_settings.verbose);
 | 
			
		||||
	    find_config_int(cmd->cft->root, "log/verbose", DEFAULT_VERBOSE);
 | 
			
		||||
	init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL);
 | 
			
		||||
 | 
			
		||||
	/* Log message formatting */
 | 
			
		||||
	init_indent(find_config_int(cmd->cf->root, "log/indent", '/',
 | 
			
		||||
	init_indent(find_config_int(cmd->cft->root, "log/indent",
 | 
			
		||||
				    DEFAULT_INDENT));
 | 
			
		||||
 | 
			
		||||
	cmd->default_settings.msg_prefix = find_config_str(cmd->cf->root,
 | 
			
		||||
							   "log/prefix", '/',
 | 
			
		||||
	cmd->default_settings.msg_prefix = find_config_str(cmd->cft->root,
 | 
			
		||||
							   "log/prefix",
 | 
			
		||||
							   DEFAULT_MSG_PREFIX);
 | 
			
		||||
	init_msg_prefix(cmd->default_settings.msg_prefix);
 | 
			
		||||
 | 
			
		||||
	cmd->default_settings.cmd_name = find_config_int(cmd->cf->root,
 | 
			
		||||
	cmd->default_settings.cmd_name = find_config_int(cmd->cft->root,
 | 
			
		||||
							 "log/command_names",
 | 
			
		||||
							 '/', DEFAULT_CMD_NAME);
 | 
			
		||||
							 DEFAULT_CMD_NAME);
 | 
			
		||||
	init_cmd_name(cmd->default_settings.cmd_name);
 | 
			
		||||
 | 
			
		||||
	/* Test mode */
 | 
			
		||||
	cmd->default_settings.test =
 | 
			
		||||
	    find_config_int(cmd->cf->root, "global/test", '/', 0);
 | 
			
		||||
	    find_config_int(cmd->cft->root, "global/test", 0);
 | 
			
		||||
 | 
			
		||||
	/* Settings for logging to file */
 | 
			
		||||
	if (find_config_int(cmd->cf->root, "log/overwrite", '/',
 | 
			
		||||
	if (find_config_int(cmd->cft->root, "log/overwrite",
 | 
			
		||||
			    DEFAULT_OVERWRITE))
 | 
			
		||||
		open_mode = "w";
 | 
			
		||||
		append = 0;
 | 
			
		||||
 | 
			
		||||
	log_file = find_config_str(cmd->cft->root, "log/file", 0);
 | 
			
		||||
 | 
			
		||||
	log_file = find_config_str(cmd->cf->root, "log/file", '/', 0);
 | 
			
		||||
	if (log_file) {
 | 
			
		||||
		/* set up the logging */
 | 
			
		||||
		if (!(_log = fopen(log_file, open_mode)))
 | 
			
		||||
			log_error("Couldn't open log file %s", log_file);
 | 
			
		||||
		else
 | 
			
		||||
			init_log(_log);
 | 
			
		||||
		release_log_memory();
 | 
			
		||||
		fin_log();
 | 
			
		||||
		init_log_file(log_file, append);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_file = find_config_str(cmd->cft->root, "log/activate_file", 0);
 | 
			
		||||
	if (log_file)
 | 
			
		||||
		init_log_direct(log_file, append);
 | 
			
		||||
 | 
			
		||||
	init_log_while_suspended(find_config_int(cmd->cft->root,
 | 
			
		||||
						 "log/activation", 0));
 | 
			
		||||
 | 
			
		||||
	t = time(NULL);
 | 
			
		||||
	log_verbose("Logging initialised at %s", ctime(&t));
 | 
			
		||||
 | 
			
		||||
	/* Tell device-mapper about our logging */
 | 
			
		||||
#ifdef DEVMAPPER_SUPPORT
 | 
			
		||||
	dm_log_init(print_log);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _process_config(struct cmd_context *cmd)
 | 
			
		||||
@@ -120,8 +149,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)) !=
 | 
			
		||||
@@ -130,29 +159,42 @@ 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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef DEVMAPPER_SUPPORT
 | 
			
		||||
	dm_set_dev_dir(cmd->dev_dir);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* 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->cft->root,
 | 
			
		||||
						       "global/suffix",
 | 
			
		||||
						       DEFAULT_SUFFIX);
 | 
			
		||||
 | 
			
		||||
	if (!(cmd->default_settings.unit_factor =
 | 
			
		||||
	      units_to_bytes(find_config_str(cmd->cft->root,
 | 
			
		||||
					     "global/units",
 | 
			
		||||
					     DEFAULT_UNITS),
 | 
			
		||||
			     &cmd->default_settings.unit_type))) {
 | 
			
		||||
		log_error("Invalid units specification");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -162,7 +204,7 @@ static int _init_config(struct cmd_context *cmd)
 | 
			
		||||
	struct stat info;
 | 
			
		||||
	char config_file[PATH_MAX] = "";
 | 
			
		||||
 | 
			
		||||
	if (!(cmd->cf = create_config_tree())) {
 | 
			
		||||
	if (!(cmd->cft = create_config_tree())) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -174,7 +216,7 @@ static int _init_config(struct cmd_context *cmd)
 | 
			
		||||
	if (lvm_snprintf(config_file, sizeof(config_file),
 | 
			
		||||
			 "%s/lvm.conf", cmd->sys_dir) < 0) {
 | 
			
		||||
		log_error("LVM_SYSTEM_DIR was too long");
 | 
			
		||||
		destroy_config_tree(cmd->cf);
 | 
			
		||||
		destroy_config_tree(cmd->cft);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -183,13 +225,13 @@ static int _init_config(struct cmd_context *cmd)
 | 
			
		||||
		if (errno == ENOENT)
 | 
			
		||||
			return 1;
 | 
			
		||||
		log_sys_error("stat", config_file);
 | 
			
		||||
		destroy_config_tree(cmd->cf);
 | 
			
		||||
		destroy_config_tree(cmd->cft);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!read_config_file(cmd->cf, config_file)) {
 | 
			
		||||
	if (!read_config_file(cmd->cft, config_file)) {
 | 
			
		||||
		log_error("Failed to load config file %s", config_file);
 | 
			
		||||
		destroy_config_tree(cmd->cf);
 | 
			
		||||
		destroy_config_tree(cmd->cft);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -206,7 +248,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(cn = find_config_node(cmd->cf->root, "devices/scan", '/'))) {
 | 
			
		||||
	if (!(cn = find_config_node(cmd->cft->root, "devices/scan"))) {
 | 
			
		||||
		if (!dev_cache_add_dir("/dev")) {
 | 
			
		||||
			log_error("Failed to add /dev to internal "
 | 
			
		||||
				  "device cache");
 | 
			
		||||
@@ -234,36 +276,65 @@ 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)
 | 
			
		||||
{
 | 
			
		||||
	unsigned nr_filt = 0;
 | 
			
		||||
	struct config_node *cn;
 | 
			
		||||
	struct dev_filter *f1, *f2, *f3;
 | 
			
		||||
	struct dev_filter *filters[MAX_FILTERS];
 | 
			
		||||
 | 
			
		||||
	if (!(f2 = lvm_type_filter_create(cmd->proc_dir)))
 | 
			
		||||
		return NULL;
 | 
			
		||||
	memset(filters, 0, sizeof(filters));
 | 
			
		||||
 | 
			
		||||
	if (!(cn = find_config_node(cmd->cf->root, "devices/filter", '/'))) {
 | 
			
		||||
	/*
 | 
			
		||||
	 * 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.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * 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++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* 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");
 | 
			
		||||
		return f2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(f1 = regex_filter_create(cn->v))) {
 | 
			
		||||
	else if (!(filters[nr_filt++] = regex_filter_create(cn->v))) {
 | 
			
		||||
		log_error("Failed to create regex device filter");
 | 
			
		||||
		return f2;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(f3 = composite_filter_create(2, f1, f2))) {
 | 
			
		||||
		log_error("Failed to create composite device filter");
 | 
			
		||||
		return f2;
 | 
			
		||||
	/* 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)
 | 
			
		||||
{
 | 
			
		||||
	const char *lvm_cache;
 | 
			
		||||
	const char *dev_cache;
 | 
			
		||||
	struct dev_filter *f3, *f4;
 | 
			
		||||
	struct stat st;
 | 
			
		||||
	char cache_file[PATH_MAX];
 | 
			
		||||
@@ -280,23 +351,25 @@ static int _init_filters(struct cmd_context *cmd)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lvm_cache =
 | 
			
		||||
	    find_config_str(cmd->cf->root, "devices/cache", '/', cache_file);
 | 
			
		||||
	if (!(f4 = persistent_filter_create(f3, lvm_cache))) {
 | 
			
		||||
	dev_cache =
 | 
			
		||||
	    find_config_str(cmd->cft->root, "devices/cache", cache_file);
 | 
			
		||||
	if (!(f4 = persistent_filter_create(f3, dev_cache))) {
 | 
			
		||||
		log_error("Failed to create persistent device filter");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Should we ever dump persistent filter state? */
 | 
			
		||||
	if (find_config_int(cmd->cf->root, "devices/write_cache_state", '/', 1))
 | 
			
		||||
	if (find_config_int(cmd->cft->root, "devices/write_cache_state", 1))
 | 
			
		||||
		cmd->dump_filter = 1;
 | 
			
		||||
 | 
			
		||||
	if (!*cmd->sys_dir)
 | 
			
		||||
		cmd->dump_filter = 0;
 | 
			
		||||
 | 
			
		||||
	if (!stat(lvm_cache, &st) && !persistent_filter_load(f4))
 | 
			
		||||
	if (!stat(dev_cache, &st) &&
 | 
			
		||||
	    (st.st_mtime > config_file_timestamp(cmd->cft)) &&
 | 
			
		||||
	    !persistent_filter_load(f4))
 | 
			
		||||
		log_verbose("Failed to load existing device cache from %s",
 | 
			
		||||
			    lvm_cache);
 | 
			
		||||
			    dev_cache);
 | 
			
		||||
 | 
			
		||||
	cmd->filter = f4;
 | 
			
		||||
 | 
			
		||||
@@ -309,12 +382,10 @@ static int _init_formats(struct cmd_context *cmd)
 | 
			
		||||
 | 
			
		||||
	struct format_type *fmt;
 | 
			
		||||
	struct list *fmth;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LIBDL
 | 
			
		||||
	struct config_node *cn;
 | 
			
		||||
	struct config_value *cv;
 | 
			
		||||
 | 
			
		||||
	struct format_type *(*init_format_fn) (struct cmd_context * cmd);
 | 
			
		||||
 | 
			
		||||
	void *lib;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	label_init();
 | 
			
		||||
 | 
			
		||||
@@ -325,16 +396,21 @@ static int _init_formats(struct cmd_context *cmd)
 | 
			
		||||
	list_add(&cmd->formats, &fmt->list);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LIBDL
 | 
			
		||||
	/* Load any formats in shared libs */
 | 
			
		||||
	if ((cn = find_config_node(cmd->cf->root, "global/format_libraries",
 | 
			
		||||
				   '/'))) {
 | 
			
		||||
	if ((cn = find_config_node(cmd->cft->root, "global/format_libraries"))) {
 | 
			
		||||
 | 
			
		||||
		struct config_value *cv;
 | 
			
		||||
		struct format_type *(*init_format_fn) (struct cmd_context *);
 | 
			
		||||
		void *lib;
 | 
			
		||||
 | 
			
		||||
		for (cv = cn->v; cv; cv = cv->next) {
 | 
			
		||||
			if (cv->type != CFG_STRING) {
 | 
			
		||||
				log_error("Invalid string in config file: "
 | 
			
		||||
					  "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;
 | 
			
		||||
@@ -353,6 +429,7 @@ static int _init_formats(struct cmd_context *cmd)
 | 
			
		||||
			list_add(&cmd->formats, &fmt->list);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (!(fmt = create_text_format(cmd)))
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -361,7 +438,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) {
 | 
			
		||||
@@ -377,14 +454,143 @@ static int _init_formats(struct cmd_context *cmd)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _init_hostname(struct cmd_context *cmd)
 | 
			
		||||
{
 | 
			
		||||
	struct utsname uts;
 | 
			
		||||
 | 
			
		||||
	if (uname(&uts)) {
 | 
			
		||||
		log_sys_error("uname", "_init_hostname");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(cmd->hostname = pool_strdup(cmd->libmem, uts.nodename))) {
 | 
			
		||||
		log_error("_init_hostname: pool_strdup failed");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(cmd->kernel_vsn = pool_strdup(cmd->libmem, uts.release))) {
 | 
			
		||||
		log_error("_init_hostname: pool_strdup kernel_vsn failed");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _set_tag(struct cmd_context *cmd, const char *tag)
 | 
			
		||||
{
 | 
			
		||||
	log_very_verbose("Setting host tag: %s", pool_strdup(cmd->libmem, tag));
 | 
			
		||||
 | 
			
		||||
	if (!str_list_add(cmd->libmem, &cmd->tags, tag)) {
 | 
			
		||||
		log_error("_init_tags: str_list_add %s failed", tag);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _check_host_filters(struct cmd_context *cmd, struct config_node *hn,
 | 
			
		||||
			       int *passes)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *cn;
 | 
			
		||||
	struct config_value *cv;
 | 
			
		||||
 | 
			
		||||
	*passes = 1;
 | 
			
		||||
 | 
			
		||||
	for (cn = hn; cn; cn = cn->sib) {
 | 
			
		||||
		if (!cn->v)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!strcmp(cn->key, "host_list")) {
 | 
			
		||||
			*passes = 0;
 | 
			
		||||
			if (cn->v->type == CFG_EMPTY_ARRAY)
 | 
			
		||||
				continue;
 | 
			
		||||
			for (cv = cn->v; cv; cv = cv->next) {
 | 
			
		||||
				if (cv->type != CFG_STRING) {
 | 
			
		||||
					log_error("Invalid hostname string "
 | 
			
		||||
						  "for tag %s", cn->key);
 | 
			
		||||
					return 0;
 | 
			
		||||
				}
 | 
			
		||||
				if (!strcmp(cv->v.str, cmd->hostname)) {
 | 
			
		||||
					*passes = 1;
 | 
			
		||||
					return 1;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!strcmp(cn->key, "host_filter")) {
 | 
			
		||||
			log_error("host_filter not supported yet");
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
static int _init_tags(struct cmd_context *cmd)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *tn, *cn;
 | 
			
		||||
	const char *tag;
 | 
			
		||||
	int passes;
 | 
			
		||||
 | 
			
		||||
	list_init(&cmd->tags);
 | 
			
		||||
 | 
			
		||||
	if (!(tn = find_config_node(cmd->cft->root, "tags")) ||
 | 
			
		||||
	    !tn->child) {
 | 
			
		||||
		log_very_verbose("No tags defined in config file");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (find_config_int(cmd->cft->root, "tags/hosttags",
 | 
			
		||||
			    DEFAULT_HOSTTAGS)) {
 | 
			
		||||
		/* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
 | 
			
		||||
		if (!_set_tag(cmd, cmd->hostname)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (cn = tn->child; cn; cn = cn->sib) {
 | 
			
		||||
		if (cn->v)
 | 
			
		||||
			continue;
 | 
			
		||||
		tag = cn->key;
 | 
			
		||||
		if (*tag == '@')
 | 
			
		||||
			tag++;
 | 
			
		||||
		if (!validate_name(tag)) {
 | 
			
		||||
			log_error("Invalid tag in config file: %s", cn->key);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (cn->child) {
 | 
			
		||||
			passes = 0;
 | 
			
		||||
			if (!_check_host_filters(cmd, cn->child, &passes)) {
 | 
			
		||||
				stack;
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
			if (!passes)
 | 
			
		||||
				continue;
 | 
			
		||||
		}
 | 
			
		||||
		if (!_set_tag(cmd, tag)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Entry point */
 | 
			
		||||
struct cmd_context *create_toolcontext(struct arg *the_args)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_context *cmd;
 | 
			
		||||
 | 
			
		||||
#ifdef M_MMAP_MAX
 | 
			
		||||
	mallopt(M_MMAP_MAX, 0);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (!setlocale(LC_ALL, ""))
 | 
			
		||||
		log_error("setlocale failed");
 | 
			
		||||
 | 
			
		||||
#ifdef INTL_PACKAGE
 | 
			
		||||
	bindtextdomain(INTL_PACKAGE, LOCALEDIR);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	init_syslog(DEFAULT_LOG_FACILITY);
 | 
			
		||||
 | 
			
		||||
	if (!(cmd = dbg_malloc(sizeof(*cmd)))) {
 | 
			
		||||
@@ -409,6 +615,11 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
 | 
			
		||||
 | 
			
		||||
	_init_logging(cmd);
 | 
			
		||||
 | 
			
		||||
	if (!(cmd->libmem = pool_create(4 * 1024))) {
 | 
			
		||||
		log_error("Library memory pool creation failed");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!_process_config(cmd))
 | 
			
		||||
		goto error;
 | 
			
		||||
 | 
			
		||||
@@ -423,9 +634,17 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memlock_init(cmd);
 | 
			
		||||
 | 
			
		||||
	if (!_init_formats(cmd))
 | 
			
		||||
		goto error;
 | 
			
		||||
 | 
			
		||||
	if (!_init_hostname(cmd))
 | 
			
		||||
		goto error;
 | 
			
		||||
 | 
			
		||||
	if (!_init_tags(cmd))
 | 
			
		||||
		goto error;
 | 
			
		||||
 | 
			
		||||
	cmd->current_settings = cmd->default_settings;
 | 
			
		||||
 | 
			
		||||
	return cmd;
 | 
			
		||||
@@ -435,7 +654,17 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void destroy_formats(struct list *formats)
 | 
			
		||||
int refresh_toolcontext(struct cmd_context *cmd)
 | 
			
		||||
{
 | 
			
		||||
	_init_logging(cmd);
 | 
			
		||||
	_init_tags(cmd);
 | 
			
		||||
 | 
			
		||||
	/* FIXME Reset filters and dev_cache */
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _destroy_formats(struct list *formats)
 | 
			
		||||
{
 | 
			
		||||
	struct list *fmtl, *tmp;
 | 
			
		||||
	struct format_type *fmt;
 | 
			
		||||
@@ -446,8 +675,10 @@ void destroy_formats(struct list *formats)
 | 
			
		||||
		list_del(&fmt->list);
 | 
			
		||||
		lib = fmt->library;
 | 
			
		||||
		fmt->ops->destroy(fmt);
 | 
			
		||||
#ifdef HAVE_LIBDL
 | 
			
		||||
		if (lib)
 | 
			
		||||
			dlclose(lib);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -456,15 +687,18 @@ void destroy_toolcontext(struct cmd_context *cmd)
 | 
			
		||||
	if (cmd->dump_filter)
 | 
			
		||||
		persistent_filter_dump(cmd->filter);
 | 
			
		||||
 | 
			
		||||
	cache_destroy();
 | 
			
		||||
	activation_exit();
 | 
			
		||||
	lvmcache_destroy();
 | 
			
		||||
	label_exit();
 | 
			
		||||
	destroy_formats(&cmd->formats);
 | 
			
		||||
	_destroy_formats(&cmd->formats);
 | 
			
		||||
	cmd->filter->destroy(cmd->filter);
 | 
			
		||||
	pool_destroy(cmd->mem);
 | 
			
		||||
	dev_cache_exit();
 | 
			
		||||
	destroy_config_tree(cmd->cf);
 | 
			
		||||
	destroy_config_tree(cmd->cft);
 | 
			
		||||
	pool_destroy(cmd->libmem);
 | 
			
		||||
	dbg_free(cmd);
 | 
			
		||||
 | 
			
		||||
	release_log_memory();
 | 
			
		||||
	dump_memory();
 | 
			
		||||
	fin_log();
 | 
			
		||||
	fin_syslog();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_TOOLCONTEXT_H
 | 
			
		||||
@@ -25,6 +33,9 @@ struct config_info {
 | 
			
		||||
	int test;
 | 
			
		||||
	int syslog;
 | 
			
		||||
	int activation;
 | 
			
		||||
	int suffix;
 | 
			
		||||
	uint64_t unit_factor;
 | 
			
		||||
	char unit_type;
 | 
			
		||||
	const char *msg_prefix;
 | 
			
		||||
	int cmd_name;		/* Show command name? */
 | 
			
		||||
 | 
			
		||||
@@ -39,25 +50,31 @@ struct config_info {
 | 
			
		||||
/* FIXME Split into tool & library contexts */
 | 
			
		||||
/* command-instance-related variables needed by library */
 | 
			
		||||
struct cmd_context {
 | 
			
		||||
	/* format handler allocates all objects from here */
 | 
			
		||||
	struct pool *mem;
 | 
			
		||||
	struct pool *libmem;	/* For permanent config data */
 | 
			
		||||
	struct pool *mem;	/* Transient: Cleared between each command */
 | 
			
		||||
 | 
			
		||||
	struct format_type *fmt;	/* Current format to use by default */
 | 
			
		||||
	const struct format_type *fmt;	/* Current format to use by default */
 | 
			
		||||
	struct format_type *fmt_backup;	/* Format to use for backups */
 | 
			
		||||
 | 
			
		||||
	struct list formats;	/* Available formats */
 | 
			
		||||
	const char *hostname;
 | 
			
		||||
	const char *kernel_vsn;
 | 
			
		||||
 | 
			
		||||
	char *cmd_line;
 | 
			
		||||
	struct command *command;
 | 
			
		||||
	struct arg *args;
 | 
			
		||||
	char **argv;
 | 
			
		||||
 | 
			
		||||
	struct dev_filter *filter;
 | 
			
		||||
	int dump_filter;	/* Dump filter when exiting? */
 | 
			
		||||
 | 
			
		||||
	struct config_tree *cf;
 | 
			
		||||
	struct config_tree *cft;
 | 
			
		||||
	struct config_info default_settings;
 | 
			
		||||
	struct config_info current_settings;
 | 
			
		||||
 | 
			
		||||
	/* List of defined tags */
 | 
			
		||||
	struct list tags;
 | 
			
		||||
 | 
			
		||||
	char sys_dir[PATH_MAX];
 | 
			
		||||
	char dev_dir[PATH_MAX];
 | 
			
		||||
	char proc_dir[PATH_MAX];
 | 
			
		||||
@@ -65,5 +82,6 @@ struct cmd_context {
 | 
			
		||||
 | 
			
		||||
struct cmd_context *create_toolcontext(struct arg *the_args);
 | 
			
		||||
void destroy_toolcontext(struct cmd_context *cmd);
 | 
			
		||||
int refresh_toolcontext(struct cmd_context *cmd);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -15,7 +24,6 @@
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <asm/page.h>
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	TOK_INT,
 | 
			
		||||
@@ -44,13 +52,13 @@ struct parser {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct cs {
 | 
			
		||||
	struct config_tree cf;
 | 
			
		||||
	struct config_tree cft;
 | 
			
		||||
	struct pool *mem;
 | 
			
		||||
	time_t timestamp;
 | 
			
		||||
	char *filename;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void _get_token(struct parser *p);
 | 
			
		||||
static void _get_token(struct parser *p, int tok_prev);
 | 
			
		||||
static void _eat_space(struct parser *p);
 | 
			
		||||
static struct config_node *_file(struct parser *p);
 | 
			
		||||
static struct config_node *_section(struct parser *p);
 | 
			
		||||
@@ -61,6 +69,8 @@ static struct config_value *_create_value(struct parser *p);
 | 
			
		||||
static struct config_node *_create_node(struct parser *p);
 | 
			
		||||
static char *_dup_tok(struct parser *p);
 | 
			
		||||
 | 
			
		||||
static const int sep = '/';
 | 
			
		||||
 | 
			
		||||
#define MAX_INDENT 32
 | 
			
		||||
 | 
			
		||||
#define match(t) do {\
 | 
			
		||||
@@ -100,25 +110,26 @@ struct config_tree *create_config_tree(void)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c->mem = mem;
 | 
			
		||||
	c->cf.root = (struct config_node *) NULL;
 | 
			
		||||
	c->cft.root = (struct config_node *) NULL;
 | 
			
		||||
	c->timestamp = 0;
 | 
			
		||||
	c->filename = NULL;
 | 
			
		||||
	return &c->cf;
 | 
			
		||||
	return &c->cft;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void destroy_config_tree(struct config_tree *cf)
 | 
			
		||||
void destroy_config_tree(struct config_tree *cft)
 | 
			
		||||
{
 | 
			
		||||
	pool_destroy(((struct cs *) cf)->mem);
 | 
			
		||||
	pool_destroy(((struct cs *) cft)->mem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int read_config_fd(struct config_tree *cf, int fd, const char *file,
 | 
			
		||||
		   off_t offset, uint32_t size, off_t offset2, uint32_t size2,
 | 
			
		||||
int read_config_fd(struct config_tree *cft, struct device *dev,
 | 
			
		||||
		   off_t offset, size_t size, off_t offset2, size_t size2,
 | 
			
		||||
		   checksum_fn_t checksum_fn, uint32_t checksum)
 | 
			
		||||
{
 | 
			
		||||
	struct cs *c = (struct cs *) cf;
 | 
			
		||||
	struct cs *c = (struct cs *) cft;
 | 
			
		||||
	struct parser *p;
 | 
			
		||||
	off_t mmap_offset;
 | 
			
		||||
	int r = 0;
 | 
			
		||||
	int use_mmap = 1;
 | 
			
		||||
	off_t mmap_offset = 0;
 | 
			
		||||
 | 
			
		||||
	if (!(p = pool_alloc(c->mem, sizeof(*p)))) {
 | 
			
		||||
		stack;
 | 
			
		||||
@@ -126,47 +137,43 @@ int read_config_fd(struct config_tree *cf, int fd, const char *file,
 | 
			
		||||
	}
 | 
			
		||||
	p->mem = c->mem;
 | 
			
		||||
 | 
			
		||||
	if (size2) {
 | 
			
		||||
		/* FIXME Attempt adjacent mmaps MAP_FIXED into malloced space 
 | 
			
		||||
		 * one PAGE_SIZE larger than required...
 | 
			
		||||
		 */
 | 
			
		||||
	/* Only use mmap with regular files */
 | 
			
		||||
	if (!(dev->flags & DEV_REGULAR) || size2)
 | 
			
		||||
		use_mmap = 0;
 | 
			
		||||
 | 
			
		||||
	if (use_mmap) {
 | 
			
		||||
		mmap_offset = offset % getpagesize();
 | 
			
		||||
		/* memory map the file */
 | 
			
		||||
		p->fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
 | 
			
		||||
			     MAP_PRIVATE, dev_fd(dev), offset - mmap_offset);
 | 
			
		||||
		if (p->fb == (caddr_t) (-1)) {
 | 
			
		||||
			log_sys_error("mmap", dev_name(dev));
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
		p->fb = p->fb + mmap_offset;
 | 
			
		||||
	} else {
 | 
			
		||||
		if (!(p->fb = dbg_malloc(size + size2))) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (lseek(fd, offset, SEEK_SET) < 0) {
 | 
			
		||||
			log_sys_error("lseek", file);
 | 
			
		||||
		if (!dev_read(dev, (uint64_t) offset, size, p->fb)) {
 | 
			
		||||
			log_error("Read from %s failed", dev_name(dev));
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
		if (raw_read(fd, p->fb, size) != size) {
 | 
			
		||||
			log_error("Circular read from %s failed", file);
 | 
			
		||||
			goto out;
 | 
			
		||||
		if (size2) {
 | 
			
		||||
			if (!dev_read(dev, (uint64_t) offset2, size2,
 | 
			
		||||
				      p->fb + size)) {
 | 
			
		||||
				log_error("Circular read from %s failed",
 | 
			
		||||
					  dev_name(dev));
 | 
			
		||||
				goto out;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (lseek(fd, offset2, SEEK_SET) < 0) {
 | 
			
		||||
			log_sys_error("lseek", file);
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
		if (raw_read(fd, p->fb + size, size2) != size2) {
 | 
			
		||||
			log_error("Circular read from %s failed", file);
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		mmap_offset = offset % PAGE_SIZE;
 | 
			
		||||
		/* memory map the file */
 | 
			
		||||
		p->fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
 | 
			
		||||
			     MAP_PRIVATE, fd, offset - mmap_offset);
 | 
			
		||||
		if (p->fb == (caddr_t) (-1)) {
 | 
			
		||||
			log_sys_error("mmap", file);
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		p->fb = p->fb + mmap_offset;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (checksum_fn && checksum !=
 | 
			
		||||
	    (checksum_fn(checksum_fn(INITIAL_CRC, p->fb, size),
 | 
			
		||||
			 p->fb + size, size2))) {
 | 
			
		||||
		log_error("%s: Checksum error", file);
 | 
			
		||||
		log_error("%s: Checksum error", dev_name(dev));
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -175,8 +182,8 @@ int read_config_fd(struct config_tree *cf, int fd, const char *file,
 | 
			
		||||
	/* parse */
 | 
			
		||||
	p->tb = p->te = p->fb;
 | 
			
		||||
	p->line = 1;
 | 
			
		||||
	_get_token(p);
 | 
			
		||||
	if (!(cf->root = _file(p))) {
 | 
			
		||||
	_get_token(p, TOK_SECTION_E);
 | 
			
		||||
	if (!(cft->root = _file(p))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
@@ -184,12 +191,12 @@ int read_config_fd(struct config_tree *cf, int fd, const char *file,
 | 
			
		||||
	r = 1;
 | 
			
		||||
 | 
			
		||||
      out:
 | 
			
		||||
	if (size2)
 | 
			
		||||
	if (!use_mmap)
 | 
			
		||||
		dbg_free(p->fb);
 | 
			
		||||
	else {
 | 
			
		||||
		/* unmap the file */
 | 
			
		||||
		if (munmap((char *) (p->fb - mmap_offset), size)) {
 | 
			
		||||
			log_sys_error("munmap", file);
 | 
			
		||||
		if (munmap((char *) (p->fb - mmap_offset), size + mmap_offset)) {
 | 
			
		||||
			log_sys_error("munmap", dev_name(dev));
 | 
			
		||||
			r = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -197,11 +204,12 @@ int read_config_fd(struct config_tree *cf, int fd, const char *file,
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int read_config_file(struct config_tree *cf, const char *file)
 | 
			
		||||
int read_config_file(struct config_tree *cft, const char *file)
 | 
			
		||||
{
 | 
			
		||||
	struct cs *c = (struct cs *) cf;
 | 
			
		||||
	struct cs *c = (struct cs *) cft;
 | 
			
		||||
	struct stat info;
 | 
			
		||||
	int r = 1, fd;
 | 
			
		||||
	struct device *dev;
 | 
			
		||||
	int r = 1;
 | 
			
		||||
 | 
			
		||||
	if (stat(file, &info)) {
 | 
			
		||||
		log_sys_error("stat", file);
 | 
			
		||||
@@ -218,15 +226,20 @@ int read_config_file(struct config_tree *cf, const char *file)
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((fd = open(file, O_RDONLY)) < 0) {
 | 
			
		||||
		log_sys_error("open", file);
 | 
			
		||||
	if (!(dev = dev_create_file(file, NULL, NULL))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r = read_config_fd(cf, fd, file, 0, info.st_size, 0, 0,
 | 
			
		||||
	if (!dev_open_flags(dev, O_RDONLY, 0, 0)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r = read_config_fd(cft, dev, 0, (size_t) info.st_size, 0, 0,
 | 
			
		||||
			   (checksum_fn_t) NULL, 0);
 | 
			
		||||
 | 
			
		||||
	close(fd);
 | 
			
		||||
	dev_close(dev);
 | 
			
		||||
 | 
			
		||||
	c->timestamp = info.st_mtime;
 | 
			
		||||
	c->filename = pool_strdup(c->mem, file);
 | 
			
		||||
@@ -234,16 +247,27 @@ int read_config_file(struct config_tree *cf, const char *file)
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
time_t config_file_timestamp(struct config_tree *cft)
 | 
			
		||||
{
 | 
			
		||||
	struct cs *c = (struct cs *) cft;
 | 
			
		||||
 | 
			
		||||
	return c->timestamp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Returns 1 if config file reloaded
 | 
			
		||||
 */
 | 
			
		||||
int reload_config_file(struct config_tree **cf)
 | 
			
		||||
int reload_config_file(struct config_tree **cft)
 | 
			
		||||
{
 | 
			
		||||
	struct config_tree *new_cf;
 | 
			
		||||
	struct cs *c = (struct cs *) *cf;
 | 
			
		||||
	struct config_tree *new_cft;
 | 
			
		||||
	struct cs *c = (struct cs *) *cft;
 | 
			
		||||
	struct cs *new_cs;
 | 
			
		||||
	struct stat info;
 | 
			
		||||
	int r, fd;
 | 
			
		||||
	struct device *dev;
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	if (!c->filename)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (stat(c->filename, &info) == -1) {
 | 
			
		||||
		if (errno == ENOENT)
 | 
			
		||||
@@ -270,26 +294,32 @@ int reload_config_file(struct config_tree **cf)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((fd = open(c->filename, O_RDONLY)) < 0) {
 | 
			
		||||
		log_sys_error("open", c->filename);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(new_cf = create_config_tree())) {
 | 
			
		||||
	if (!(new_cft = create_config_tree())) {
 | 
			
		||||
		log_error("Allocation of new config_tree failed");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r = read_config_fd(new_cf, fd, c->filename, 0, info.st_size, 0, 0,
 | 
			
		||||
			   (checksum_fn_t) NULL, 0);
 | 
			
		||||
	close(fd);
 | 
			
		||||
	if (!(dev = dev_create_file(c->filename, NULL, NULL))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!dev_open_flags(dev, O_RDONLY, 0, 0)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r = read_config_fd(new_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 = (struct cs *) new_cft;
 | 
			
		||||
		new_cs->filename = pool_strdup(new_cs->mem, c->filename);
 | 
			
		||||
		new_cs->timestamp = info.st_mtime;
 | 
			
		||||
		destroy_config_tree(*cf);
 | 
			
		||||
		*cf = new_cf;
 | 
			
		||||
		destroy_config_tree(*cft);
 | 
			
		||||
		*cft = new_cft;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
@@ -363,20 +393,28 @@ static int _write_config(struct config_node *n, FILE *fp, int level)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int write_config_file(struct config_tree *cf, const char *file)
 | 
			
		||||
int write_config_file(struct config_tree *cft, const char *file)
 | 
			
		||||
{
 | 
			
		||||
	int r = 1;
 | 
			
		||||
	FILE *fp = fopen(file, "w");
 | 
			
		||||
	if (!fp) {
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
 | 
			
		||||
	if (!file) {
 | 
			
		||||
		fp = stdout;
 | 
			
		||||
		file = "stdout";
 | 
			
		||||
	} else if (!(fp = fopen(file, "w"))) {
 | 
			
		||||
		log_sys_error("open", file);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!_write_config(cf->root, fp, 0)) {
 | 
			
		||||
		stack;
 | 
			
		||||
	log_verbose("Dumping configuration to %s", file);
 | 
			
		||||
	if (!_write_config(cft->root, fp, 0)) {
 | 
			
		||||
		log_error("Failure while writing configuration");
 | 
			
		||||
		r = 0;
 | 
			
		||||
	}
 | 
			
		||||
	fclose(fp);
 | 
			
		||||
 | 
			
		||||
	if (fp != stdout)
 | 
			
		||||
		fclose(fp);
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -483,7 +521,7 @@ static struct config_value *_value(struct parser *p)
 | 
			
		||||
 | 
			
		||||
static struct config_value *_type(struct parser *p)
 | 
			
		||||
{
 | 
			
		||||
	/* [0-9]+ | [0-9]*\.[0-9]* | ".*" */
 | 
			
		||||
	/* [+-]{0,1}[0-9]+ | [0-9]*\.[0-9]* | ".*" */
 | 
			
		||||
	struct config_value *v = _create_value(p);
 | 
			
		||||
 | 
			
		||||
	if (!v)
 | 
			
		||||
@@ -526,15 +564,17 @@ static int _match_aux(struct parser *p, int t)
 | 
			
		||||
	if (p->t != t)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	_get_token(p);
 | 
			
		||||
	_get_token(p, t);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * tokeniser
 | 
			
		||||
 */
 | 
			
		||||
static void _get_token(struct parser *p)
 | 
			
		||||
static void _get_token(struct parser *p, int tok_prev)
 | 
			
		||||
{
 | 
			
		||||
	int values_allowed = 0;
 | 
			
		||||
 | 
			
		||||
	p->tb = p->te;
 | 
			
		||||
	_eat_space(p);
 | 
			
		||||
	if (p->tb == p->fe || !*p->tb) {
 | 
			
		||||
@@ -542,6 +582,11 @@ static void _get_token(struct parser *p)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Should next token be interpreted as value instead of identifier? */
 | 
			
		||||
	if (tok_prev == TOK_EQ || tok_prev == TOK_ARRAY_B ||
 | 
			
		||||
	    tok_prev == TOK_COMMA)
 | 
			
		||||
		values_allowed = 1;
 | 
			
		||||
 | 
			
		||||
	p->t = TOK_INT;		/* fudge so the fall through for
 | 
			
		||||
				   floats works */
 | 
			
		||||
	switch (*p->te) {
 | 
			
		||||
@@ -589,6 +634,16 @@ static void _get_token(struct parser *p)
 | 
			
		||||
			p->te++;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case '\'':
 | 
			
		||||
		p->t = TOK_STRING;
 | 
			
		||||
		p->te++;
 | 
			
		||||
		while ((p->te != p->fe) && (*p->te) && (*p->te != '\''))
 | 
			
		||||
			p->te++;
 | 
			
		||||
 | 
			
		||||
		if ((p->te != p->fe) && (*p->te))
 | 
			
		||||
			p->te++;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case '.':
 | 
			
		||||
		p->t = TOK_FLOAT;
 | 
			
		||||
	case '0':
 | 
			
		||||
@@ -601,22 +656,27 @@ static void _get_token(struct parser *p)
 | 
			
		||||
	case '7':
 | 
			
		||||
	case '8':
 | 
			
		||||
	case '9':
 | 
			
		||||
		p->te++;
 | 
			
		||||
		while ((p->te != p->fe) && (*p->te)) {
 | 
			
		||||
			if (*p->te == '.') {
 | 
			
		||||
				if (p->t == TOK_FLOAT)
 | 
			
		||||
					break;
 | 
			
		||||
				p->t = TOK_FLOAT;
 | 
			
		||||
			} else if (!isdigit((int) *p->te))
 | 
			
		||||
				break;
 | 
			
		||||
	case '+':
 | 
			
		||||
	case '-':
 | 
			
		||||
		if (values_allowed) {
 | 
			
		||||
			p->te++;
 | 
			
		||||
			while ((p->te != p->fe) && (*p->te)) {
 | 
			
		||||
				if (*p->te == '.') {
 | 
			
		||||
					if (p->t == TOK_FLOAT)
 | 
			
		||||
						break;
 | 
			
		||||
					p->t = TOK_FLOAT;
 | 
			
		||||
				} else if (!isdigit((int) *p->te))
 | 
			
		||||
					break;
 | 
			
		||||
				p->te++;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		p->t = TOK_IDENTIFIER;
 | 
			
		||||
		while ((p->te != p->fe) && (*p->te) && !isspace(*p->te) &&
 | 
			
		||||
		       (*p->te != '#') && (*p->te != '='))
 | 
			
		||||
		       (*p->te != '#') && (*p->te != '=') && (*p->te != '{') &&
 | 
			
		||||
		       (*p->te != '}'))
 | 
			
		||||
			p->te++;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
@@ -665,7 +725,7 @@ static struct config_node *_create_node(struct parser *p)
 | 
			
		||||
 | 
			
		||||
static char *_dup_tok(struct parser *p)
 | 
			
		||||
{
 | 
			
		||||
	int len = p->te - p->tb;
 | 
			
		||||
	size_t len = p->te - p->tb;
 | 
			
		||||
	char *str = pool_alloc(p->mem, len + 1);
 | 
			
		||||
	if (!str) {
 | 
			
		||||
		stack;
 | 
			
		||||
@@ -679,8 +739,7 @@ static char *_dup_tok(struct parser *p)
 | 
			
		||||
/*
 | 
			
		||||
 * utility functions
 | 
			
		||||
 */
 | 
			
		||||
struct config_node *find_config_node(struct config_node *cn,
 | 
			
		||||
				     const char *path, char sep)
 | 
			
		||||
struct config_node *find_config_node(struct config_node *cn, const char *path)
 | 
			
		||||
{
 | 
			
		||||
	const char *e;
 | 
			
		||||
 | 
			
		||||
@@ -712,9 +771,9 @@ struct config_node *find_config_node(struct config_node *cn,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *find_config_str(struct config_node *cn,
 | 
			
		||||
			    const char *path, char sep, const char *fail)
 | 
			
		||||
			    const char *path, const char *fail)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *n = find_config_node(cn, path, sep);
 | 
			
		||||
	struct config_node *n = find_config_node(cn, path);
 | 
			
		||||
 | 
			
		||||
	if (n && n->v->type == CFG_STRING) {
 | 
			
		||||
		if (*n->v->v.str)
 | 
			
		||||
@@ -728,10 +787,9 @@ const char *find_config_str(struct config_node *cn,
 | 
			
		||||
	return fail;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int find_config_int(struct config_node *cn, const char *path,
 | 
			
		||||
		    char sep, int fail)
 | 
			
		||||
int find_config_int(struct config_node *cn, const char *path, int fail)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *n = find_config_node(cn, path, sep);
 | 
			
		||||
	struct config_node *n = find_config_node(cn, path);
 | 
			
		||||
 | 
			
		||||
	if (n && n->v->type == CFG_INT) {
 | 
			
		||||
		log_very_verbose("Setting %s to %d", path, n->v->v.i);
 | 
			
		||||
@@ -743,10 +801,9 @@ int find_config_int(struct config_node *cn, const char *path,
 | 
			
		||||
	return fail;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float find_config_float(struct config_node *cn, const char *path,
 | 
			
		||||
			char sep, float fail)
 | 
			
		||||
float find_config_float(struct config_node *cn, const char *path, float fail)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *n = find_config_node(cn, path, sep);
 | 
			
		||||
	struct config_node *n = find_config_node(cn, path);
 | 
			
		||||
 | 
			
		||||
	if (n && n->v->type == CFG_FLOAT) {
 | 
			
		||||
		log_very_verbose("Setting %s to %f", path, n->v->v.r);
 | 
			
		||||
@@ -786,10 +843,9 @@ static int _str_to_bool(const char *str, int fail)
 | 
			
		||||
	return fail;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int find_config_bool(struct config_node *cn, const char *path,
 | 
			
		||||
		     char sep, int fail)
 | 
			
		||||
int find_config_bool(struct config_node *cn, const char *path, int fail)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *n = find_config_node(cn, path, sep);
 | 
			
		||||
	struct config_node *n = find_config_node(cn, path);
 | 
			
		||||
	struct config_value *v;
 | 
			
		||||
 | 
			
		||||
	if (!n)
 | 
			
		||||
@@ -809,11 +865,11 @@ int find_config_bool(struct config_node *cn, const char *path,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int get_config_uint32(struct config_node *cn, const char *path,
 | 
			
		||||
		      char sep, uint32_t *result)
 | 
			
		||||
		      uint32_t *result)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *n;
 | 
			
		||||
 | 
			
		||||
	n = find_config_node(cn, path, sep);
 | 
			
		||||
	n = find_config_node(cn, path);
 | 
			
		||||
 | 
			
		||||
	if (!n || !n->v || n->v->type != CFG_INT)
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -823,11 +879,11 @@ int get_config_uint32(struct config_node *cn, const char *path,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int get_config_uint64(struct config_node *cn, const char *path,
 | 
			
		||||
		      char sep, uint64_t *result)
 | 
			
		||||
		      uint64_t *result)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *n;
 | 
			
		||||
 | 
			
		||||
	n = find_config_node(cn, path, sep);
 | 
			
		||||
	n = find_config_node(cn, path);
 | 
			
		||||
 | 
			
		||||
	if (!n || !n->v || n->v->type != CFG_INT)
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -837,12 +893,11 @@ int get_config_uint64(struct config_node *cn, const char *path,
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int get_config_str(struct config_node *cn, const char *path,
 | 
			
		||||
		   char sep, char **result)
 | 
			
		||||
int get_config_str(struct config_node *cn, const char *path, char **result)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *n;
 | 
			
		||||
 | 
			
		||||
	n = find_config_node(cn, path, sep);
 | 
			
		||||
	n = find_config_node(cn, path);
 | 
			
		||||
 | 
			
		||||
	if (!n || !n->v || n->v->type != CFG_STRING)
 | 
			
		||||
		return 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,22 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 <inttypes.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include "device.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	CFG_STRING,
 | 
			
		||||
@@ -42,40 +50,37 @@ void destroy_config_tree(struct config_tree *cf);
 | 
			
		||||
 | 
			
		||||
typedef uint32_t (*checksum_fn_t) (uint32_t initial, void *buf, uint32_t size);
 | 
			
		||||
 | 
			
		||||
int read_config_fd(struct config_tree *cf, int fd, const char *file,
 | 
			
		||||
		   off_t offset, uint32_t size, off_t offset2, uint32_t size2,
 | 
			
		||||
int read_config_fd(struct config_tree *cf, struct device *dev,
 | 
			
		||||
		   off_t offset, size_t size, off_t offset2, size_t size2,
 | 
			
		||||
		   checksum_fn_t checksum_fn, uint32_t checksum);
 | 
			
		||||
 | 
			
		||||
int read_config_file(struct config_tree *cf, const char *file);
 | 
			
		||||
int write_config_file(struct config_tree *cf, const char *file);
 | 
			
		||||
int reload_config_file(struct config_tree **cf);
 | 
			
		||||
time_t config_file_timestamp(struct config_tree *cf);
 | 
			
		||||
 | 
			
		||||
struct config_node *find_config_node(struct config_node *cn,
 | 
			
		||||
				     const char *path, char seperator);
 | 
			
		||||
				     const char *path);
 | 
			
		||||
 | 
			
		||||
const char *find_config_str(struct config_node *cn,
 | 
			
		||||
			    const char *path, char sep, const char *fail);
 | 
			
		||||
const char *find_config_str(struct config_node *cn, const char *path,
 | 
			
		||||
			    const char *fail);
 | 
			
		||||
 | 
			
		||||
int find_config_int(struct config_node *cn, const char *path,
 | 
			
		||||
		    char sep, int fail);
 | 
			
		||||
int find_config_int(struct config_node *cn, const char *path, int fail);
 | 
			
		||||
 | 
			
		||||
float find_config_float(struct config_node *cn, const char *path,
 | 
			
		||||
			char sep, float fail);
 | 
			
		||||
float find_config_float(struct config_node *cn, const char *path, float fail);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Understands (0, ~0), (y, n), (yes, no), (on,
 | 
			
		||||
 * off), (true, false).
 | 
			
		||||
 */
 | 
			
		||||
int find_config_bool(struct config_node *cn, const char *path,
 | 
			
		||||
		     char sep, int fail);
 | 
			
		||||
int find_config_bool(struct config_node *cn, const char *path, int fail);
 | 
			
		||||
 | 
			
		||||
int get_config_uint32(struct config_node *cn, const char *path,
 | 
			
		||||
		      char sep, uint32_t *result);
 | 
			
		||||
		      uint32_t *result);
 | 
			
		||||
 | 
			
		||||
int get_config_uint64(struct config_node *cn, const char *path,
 | 
			
		||||
		      char sep, uint64_t *result);
 | 
			
		||||
		      uint64_t *result);
 | 
			
		||||
 | 
			
		||||
int get_config_str(struct config_node *cn, const char *path,
 | 
			
		||||
		   char sep, char **result);
 | 
			
		||||
int get_config_str(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,39 +28,82 @@
 | 
			
		||||
#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_SUPPORT
 | 
			
		||||
  #define DEFAULT_FORMAT "lvm1"
 | 
			
		||||
#ifdef LVM1_FALLBACK
 | 
			
		||||
#  define DEFAULT_FALLBACK_TO_LVM1 1
 | 
			
		||||
#else
 | 
			
		||||
  #define DEFAULT_FORMAT "lvm2"
 | 
			
		||||
#  define DEFAULT_FALLBACK_TO_LVM1 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LVM1_SUPPORT
 | 
			
		||||
#  define DEFAULT_FORMAT "lvm1"
 | 
			
		||||
#else
 | 
			
		||||
#  define DEFAULT_FORMAT "lvm2"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_STRIPESIZE 64	/* KB */
 | 
			
		||||
#define DEFAULT_PVMETADATASIZE 255
 | 
			
		||||
#define DEFAULT_PVMETADATACOPIES 1
 | 
			
		||||
#define DEFAULT_LABELSECTOR 1
 | 
			
		||||
#define DEFAULT_LABELSECTOR UINT64_C(1)
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_MSG_PREFIX "  "
 | 
			
		||||
#define DEFAULT_CMD_NAME 0
 | 
			
		||||
#define DEFAULT_OVERWRITE 0
 | 
			
		||||
 | 
			
		||||
#ifndef DEFAULT_LOG_FACILITY
 | 
			
		||||
  #define DEFAULT_LOG_FACILITY LOG_USER
 | 
			
		||||
#  define DEFAULT_LOG_FACILITY LOG_USER
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_SYSLOG 1
 | 
			
		||||
#define DEFAULT_VERBOSE 0
 | 
			
		||||
#define DEFAULT_LOGLEVEL 0
 | 
			
		||||
#define DEFAULT_INDENT 1
 | 
			
		||||
#define DEFAULT_UNITS "h"
 | 
			
		||||
#define DEFAULT_SUFFIX 1
 | 
			
		||||
#define DEFAULT_HOSTTAGS 0
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_ACTIVATION 1
 | 
			
		||||
 | 
			
		||||
#ifdef READLINE_SUPPORT
 | 
			
		||||
  #define DEFAULT_MAX_HISTORY 100
 | 
			
		||||
#ifdef DEVMAPPER_SUPPORT
 | 
			
		||||
#  define DEFAULT_ACTIVATION 1
 | 
			
		||||
#  define DEFAULT_RESERVED_MEMORY 8192
 | 
			
		||||
#  define DEFAULT_RESERVED_STACK 256
 | 
			
		||||
#  define DEFAULT_PROCESS_PRIORITY -18
 | 
			
		||||
#else
 | 
			
		||||
#  define DEFAULT_ACTIVATION 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_STRIPE_FILLER "/dev/ioerror"
 | 
			
		||||
#define DEFAULT_MIRROR_REGION_SIZE 512	/* KB */
 | 
			
		||||
#define DEFAULT_INTERVAL 15
 | 
			
		||||
 | 
			
		||||
#ifdef READLINE_SUPPORT
 | 
			
		||||
#  define DEFAULT_MAX_HISTORY 100
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_REP_ALIGNED 1
 | 
			
		||||
#define DEFAULT_REP_BUFFERED 1
 | 
			
		||||
#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_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_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"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_LVS_SORT "vg_name,lv_name"
 | 
			
		||||
#define DEFAULT_VGS_SORT "vg_name"
 | 
			
		||||
#define DEFAULT_PVS_SORT "pv_name"
 | 
			
		||||
#define DEFAULT_SEGS_SORT "vg_name,lv_name,seg_start"
 | 
			
		||||
 | 
			
		||||
#endif				/* _LVM_DEFAULTS_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"
 | 
			
		||||
@@ -12,8 +21,8 @@
 | 
			
		||||
 | 
			
		||||
bitset_t bitset_create(struct pool *mem, unsigned num_bits)
 | 
			
		||||
{
 | 
			
		||||
	int n = (num_bits / BITS_PER_INT) + 2;
 | 
			
		||||
	int size = sizeof(int) * n;
 | 
			
		||||
	unsigned n = (num_bits / BITS_PER_INT) + 2;
 | 
			
		||||
	size_t size = sizeof(int) * n;
 | 
			
		||||
	unsigned *bs = pool_zalloc(mem, size);
 | 
			
		||||
 | 
			
		||||
	if (!bs)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,21 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
#define _LVM_BITSET_H
 | 
			
		||||
 | 
			
		||||
#include "lvm-types.h"
 | 
			
		||||
#include "pool.h"
 | 
			
		||||
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
@@ -15,12 +23,12 @@
 | 
			
		||||
typedef uint32_t *bitset_t;
 | 
			
		||||
 | 
			
		||||
bitset_t bitset_create(struct pool *mem, unsigned num_bits);
 | 
			
		||||
void bitset_destroy(bitset_t bs);
 | 
			
		||||
 | 
			
		||||
void bit_union(bitset_t out, bitset_t in1, bitset_t in2);
 | 
			
		||||
int bit_get_first(bitset_t bs);
 | 
			
		||||
int bit_get_next(bitset_t bs, int last_bit);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BITS_PER_INT (sizeof(int) * CHAR_BIT)
 | 
			
		||||
 | 
			
		||||
#define bit(bs, i) \
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -46,7 +55,7 @@ static uint32_t _shuffle(uint32_t k)
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct node **_lookup(struct node **c, uint32_t key, struct node **p)
 | 
			
		||||
static struct node **_lookup(struct node **c, uint32_t key, struct node **p)
 | 
			
		||||
{
 | 
			
		||||
	*p = NULL;
 | 
			
		||||
	while (*c) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,21 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
#define _LVM_BTREE_H
 | 
			
		||||
 | 
			
		||||
#include "lvm-types.h"
 | 
			
		||||
#include "pool.h"
 | 
			
		||||
 | 
			
		||||
struct btree;
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -59,10 +68,10 @@ static struct hash_node *_create_node(const char *str)
 | 
			
		||||
	return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned _hash(const char *str, int len)
 | 
			
		||||
static unsigned _hash(const char *str)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long int h = 0, g;
 | 
			
		||||
	while (*str && len--) {
 | 
			
		||||
	unsigned long h = 0, g;
 | 
			
		||||
	while (*str) {
 | 
			
		||||
		h <<= 4;
 | 
			
		||||
		h += _nums[(int) *str++];
 | 
			
		||||
		g = h & ((unsigned long) 0xf << 16u);
 | 
			
		||||
@@ -125,30 +134,18 @@ void hash_destroy(struct hash_table *t)
 | 
			
		||||
	dbg_free(t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline struct hash_node **_find_fixed(struct hash_table *t,
 | 
			
		||||
					     const char *key, uint32_t len)
 | 
			
		||||
static struct hash_node **_find(struct hash_table *t, const char *key)
 | 
			
		||||
{
 | 
			
		||||
	unsigned h = _hash(key, len) & (t->num_slots - 1);
 | 
			
		||||
	unsigned h = _hash(key) & (t->num_slots - 1);
 | 
			
		||||
	struct hash_node **c;
 | 
			
		||||
 | 
			
		||||
	for (c = &t->slots[h]; *c; c = &((*c)->next))
 | 
			
		||||
		if (!strncmp(key, (*c)->key, len))
 | 
			
		||||
		if (!strcmp(key, (*c)->key))
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline struct hash_node **_find(struct hash_table *t, const char *key)
 | 
			
		||||
{
 | 
			
		||||
	return _find_fixed(t, key, strlen(key));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *hash_lookup_fixed(struct hash_table *t, const char *key, uint32_t len)
 | 
			
		||||
{
 | 
			
		||||
	struct hash_node **c = _find_fixed(t, key, len);
 | 
			
		||||
	return *c ? (*c)->data : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *hash_lookup(struct hash_table *t, const char *key)
 | 
			
		||||
{
 | 
			
		||||
	struct hash_node **c = _find(t, key);
 | 
			
		||||
@@ -220,7 +217,7 @@ void *hash_get_data(struct hash_table *t, struct hash_node *n)
 | 
			
		||||
	return n->data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct hash_node *_next_slot(struct hash_table *t, unsigned int s)
 | 
			
		||||
static struct hash_node *_next_slot(struct hash_table *t, unsigned s)
 | 
			
		||||
{
 | 
			
		||||
	struct hash_node *c = NULL;
 | 
			
		||||
	int i;
 | 
			
		||||
@@ -238,6 +235,6 @@ struct hash_node *hash_get_first(struct hash_table *t)
 | 
			
		||||
 | 
			
		||||
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int h = _hash(n->key, strlen(n->key)) & (t->num_slots - 1);
 | 
			
		||||
	unsigned h = _hash(n->key) & (t->num_slots - 1);
 | 
			
		||||
	return n->next ? n->next : _next_slot(t, h + 1);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,25 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the 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
 | 
			
		||||
#define _LVM_HASH_H
 | 
			
		||||
 | 
			
		||||
#include "lvm-types.h"
 | 
			
		||||
 | 
			
		||||
struct hash_table;
 | 
			
		||||
struct hash_node;
 | 
			
		||||
 | 
			
		||||
typedef void (*iterate_fn)(void *data);
 | 
			
		||||
typedef void (*iterate_fn) (void *data);
 | 
			
		||||
 | 
			
		||||
struct hash_table *hash_create(unsigned size_hint);
 | 
			
		||||
void hash_destroy(struct hash_table *t);
 | 
			
		||||
@@ -36,4 +43,3 @@ struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n);
 | 
			
		||||
	     v = hash_get_next(h, v))
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_LIST_H
 | 
			
		||||
@@ -13,11 +22,15 @@ struct list {
 | 
			
		||||
	struct list *n, *p;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline void list_init(struct list *head) {
 | 
			
		||||
#define LIST_INIT(name)	struct list name = { &(name), &(name) }
 | 
			
		||||
 | 
			
		||||
static inline void list_init(struct list *head)
 | 
			
		||||
{
 | 
			
		||||
	head->n = head->p = head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void list_add(struct list *head, struct list *elem) {
 | 
			
		||||
static inline void list_add(struct list *head, struct list *elem)
 | 
			
		||||
{
 | 
			
		||||
	assert(head->n);
 | 
			
		||||
 | 
			
		||||
	elem->n = head;
 | 
			
		||||
@@ -27,7 +40,8 @@ static inline void list_add(struct list *head, struct list *elem) {
 | 
			
		||||
	head->p = elem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void list_add_h(struct list *head, struct list *elem) {
 | 
			
		||||
static inline void list_add_h(struct list *head, struct list *elem)
 | 
			
		||||
{
 | 
			
		||||
	assert(head->n);
 | 
			
		||||
 | 
			
		||||
	elem->n = head->n;
 | 
			
		||||
@@ -37,36 +51,62 @@ static inline void list_add_h(struct list *head, struct list *elem) {
 | 
			
		||||
	head->n = elem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void list_del(struct list *elem) {
 | 
			
		||||
static inline void list_del(struct list *elem)
 | 
			
		||||
{
 | 
			
		||||
	elem->n->p = elem->p;
 | 
			
		||||
	elem->p->n = elem->n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int list_empty(struct list *head) {
 | 
			
		||||
static inline int list_empty(struct list *head)
 | 
			
		||||
{
 | 
			
		||||
	return head->n == head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define list_iterate(v, head) \
 | 
			
		||||
	for (v = (head)->n; v != head; v = v->n)
 | 
			
		||||
static inline int list_end(struct list *head, struct list *elem)
 | 
			
		||||
{
 | 
			
		||||
	return elem->n == head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define list_iterate_safe(v, t, head) \
 | 
			
		||||
	for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
 | 
			
		||||
 | 
			
		||||
static inline int list_size(struct list *head) {
 | 
			
		||||
	int s = 0;
 | 
			
		||||
	struct list *v;
 | 
			
		||||
 | 
			
		||||
	list_iterate(v, head)
 | 
			
		||||
		s++;
 | 
			
		||||
 | 
			
		||||
	return s;
 | 
			
		||||
static inline struct list *list_next(struct list *head, struct list *elem)
 | 
			
		||||
{
 | 
			
		||||
	return (list_end(head, elem) ? NULL : elem->n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define list_item(v, t) \
 | 
			
		||||
    ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list))
 | 
			
		||||
 | 
			
		||||
/* Given a known element in a known structure, locate the struct list */
 | 
			
		||||
#define list_head(v, t, e) \
 | 
			
		||||
    (((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->list)
 | 
			
		||||
#define list_struct_base(v, t, h) \
 | 
			
		||||
    ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->h))
 | 
			
		||||
 | 
			
		||||
/* Given a known element in a known structure, locate another */
 | 
			
		||||
#define struct_field(v, t, e, f) \
 | 
			
		||||
    (((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f)
 | 
			
		||||
 | 
			
		||||
/* Given a known element in a known structure, locate the list head */
 | 
			
		||||
#define list_head(v, t, e) struct_field(v, t, e, list)
 | 
			
		||||
 | 
			
		||||
#define list_iterate(v, head) \
 | 
			
		||||
	for (v = (head)->n; v != head; v = v->n)
 | 
			
		||||
 | 
			
		||||
#define list_uniterate(v, head, start) \
 | 
			
		||||
	for (v = (start)->p; v != head; v = v->p)
 | 
			
		||||
 | 
			
		||||
#define list_iterate_safe(v, t, head) \
 | 
			
		||||
	for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
 | 
			
		||||
 | 
			
		||||
#define list_iterate_items(v, head) \
 | 
			
		||||
	for (v = list_item((head)->n, typeof(*v)); &v->list != (head); \
 | 
			
		||||
	     v = list_item(v->list.n, typeof(*v)))
 | 
			
		||||
 | 
			
		||||
static inline unsigned int list_size(const struct list *head)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int s = 0;
 | 
			
		||||
	const struct list *v;
 | 
			
		||||
 | 
			
		||||
	list_iterate(v, head)
 | 
			
		||||
	    s++;
 | 
			
		||||
 | 
			
		||||
	return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -12,9 +21,12 @@
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
/* Define some portable printing types */
 | 
			
		||||
#define PRIsize_t "Zu"
 | 
			
		||||
 | 
			
		||||
struct str_list {
 | 
			
		||||
	struct list list;
 | 
			
		||||
	char *str;
 | 
			
		||||
	const char *str;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										128
									
								
								lib/datastruct/str_list.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								lib/datastruct/str_list.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
#include "str_list.h"
 | 
			
		||||
 | 
			
		||||
struct list *str_list_create(struct pool *mem)
 | 
			
		||||
{
 | 
			
		||||
	struct list *sl;
 | 
			
		||||
 | 
			
		||||
	if (!(sl = pool_alloc(mem, sizeof(struct list)))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_init(sl);
 | 
			
		||||
 | 
			
		||||
	return sl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int str_list_add(struct pool *mem, struct list *sll, const char *str)
 | 
			
		||||
{
 | 
			
		||||
	struct str_list *sln;
 | 
			
		||||
 | 
			
		||||
	if (!str) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Already in list? */
 | 
			
		||||
	if (str_list_match_item(sll, str))
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (!(sln = pool_alloc(mem, sizeof(*sln)))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sln->str = str;
 | 
			
		||||
	list_add(sll, &sln->list);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int str_list_del(struct list *sll, const char *str)
 | 
			
		||||
{
 | 
			
		||||
	struct list *slh, *slht;
 | 
			
		||||
 | 
			
		||||
	list_iterate_safe(slh, slht, sll) {
 | 
			
		||||
		if (!strcmp(str, list_item(slh, struct str_list)->str))
 | 
			
		||||
			 list_del(slh);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int str_list_dup(struct pool *mem, struct list *sllnew, struct list *sllold)
 | 
			
		||||
{
 | 
			
		||||
	struct str_list *sl;
 | 
			
		||||
 | 
			
		||||
	list_init(sllnew);
 | 
			
		||||
 | 
			
		||||
	list_iterate_items(sl, sllold) {
 | 
			
		||||
		if (!str_list_add(mem, sllnew, strdup(sl->str))) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Is item on list?
 | 
			
		||||
 */
 | 
			
		||||
int str_list_match_item(struct list *sll, const char *str)
 | 
			
		||||
{
 | 
			
		||||
	struct str_list *sl;
 | 
			
		||||
 | 
			
		||||
	list_iterate_items(sl, sll)
 | 
			
		||||
	    if (!strcmp(str, sl->str))
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Is at least one item on both lists?
 | 
			
		||||
 */
 | 
			
		||||
int str_list_match_list(struct list *sll, struct list *sll2)
 | 
			
		||||
{
 | 
			
		||||
	struct str_list *sl;
 | 
			
		||||
 | 
			
		||||
	list_iterate_items(sl, sll)
 | 
			
		||||
	    if (str_list_match_item(sll2, sl->str))
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Do both lists contain the same set of items?
 | 
			
		||||
 */
 | 
			
		||||
int str_list_lists_equal(struct list *sll, struct list *sll2)
 | 
			
		||||
{
 | 
			
		||||
	struct str_list *sl;
 | 
			
		||||
 | 
			
		||||
	if (list_size(sll) != list_size(sll2))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	list_iterate_items(sl, sll)
 | 
			
		||||
	    if (!str_list_match_item(sll2, sl->str))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								lib/datastruct/str_list.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/datastruct/str_list.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_STR_LIST_H
 | 
			
		||||
#define _LVM_STR_LIST_H
 | 
			
		||||
 | 
			
		||||
#include "pool.h"
 | 
			
		||||
 | 
			
		||||
struct list *str_list_create(struct pool *mem);
 | 
			
		||||
int str_list_add(struct pool *mem, struct list *sll, const char *str);
 | 
			
		||||
int str_list_del(struct list *sll, const char *str);
 | 
			
		||||
int str_list_match_item(struct list *sll, const char *str);
 | 
			
		||||
int str_list_match_list(struct list *sll, struct list *sll2);
 | 
			
		||||
int str_list_lists_equal(struct list *sll, struct list *sll2);
 | 
			
		||||
int str_list_dup(struct pool *mem, struct list *sllnew, struct list *sllold);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -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,17 +20,11 @@
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "lvm-types.h"
 | 
			
		||||
#include "btree.h"
 | 
			
		||||
#include "filter.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <linux/kdev_t.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * FIXME: really need to seperate names from the devices since
 | 
			
		||||
 * multiple names can point to the same device.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct dev_iter {
 | 
			
		||||
	struct btree_iter *current;
 | 
			
		||||
@@ -48,38 +51,163 @@ static struct {
 | 
			
		||||
 | 
			
		||||
static int _insert(const char *path, int rec);
 | 
			
		||||
 | 
			
		||||
static struct device *_create_dev(dev_t d)
 | 
			
		||||
struct device *dev_create_file(const char *filename, struct device *dev,
 | 
			
		||||
			       struct str_list *alias)
 | 
			
		||||
{
 | 
			
		||||
	int allocate = !dev;
 | 
			
		||||
 | 
			
		||||
	if (allocate && !(dev = dbg_malloc(sizeof(*dev)))) {
 | 
			
		||||
		log_error("struct device allocation failed");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	if (allocate && !(alias = dbg_malloc(sizeof(*alias)))) {
 | 
			
		||||
		log_error("struct str_list allocation failed");
 | 
			
		||||
		dbg_free(dev);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	if (!(alias->str = dbg_strdup(filename))) {
 | 
			
		||||
		log_error("filename strdup failed");
 | 
			
		||||
		if (allocate) {
 | 
			
		||||
			dbg_free(dev);
 | 
			
		||||
			dbg_free(alias);
 | 
			
		||||
		}
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	dev->flags = DEV_REGULAR;
 | 
			
		||||
	if (allocate)
 | 
			
		||||
		dev->flags |= DEV_ALLOCED;
 | 
			
		||||
	list_init(&dev->aliases);
 | 
			
		||||
	list_add(&dev->aliases, &alias->list);
 | 
			
		||||
	dev->end = UINT64_C(0);
 | 
			
		||||
	dev->dev = 0;
 | 
			
		||||
	dev->fd = -1;
 | 
			
		||||
	dev->open_count = 0;
 | 
			
		||||
	memset(dev->pvid, 0, sizeof(dev->pvid));
 | 
			
		||||
	list_init(&dev->open_list);
 | 
			
		||||
 | 
			
		||||
	return dev;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct device *_dev_create(dev_t d)
 | 
			
		||||
{
 | 
			
		||||
	struct device *dev;
 | 
			
		||||
 | 
			
		||||
	if (!(dev = _alloc(sizeof(*dev)))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		log_error("struct device allocation failed");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev->flags = 0;
 | 
			
		||||
	list_init(&dev->aliases);
 | 
			
		||||
	dev->dev = d;
 | 
			
		||||
	dev->fd = -1;
 | 
			
		||||
	dev->flags = 0;
 | 
			
		||||
	dev->open_count = 0;
 | 
			
		||||
	dev->end = UINT64_C(0);
 | 
			
		||||
	memset(dev->pvid, 0, sizeof(dev->pvid));
 | 
			
		||||
	list_init(&dev->open_list);
 | 
			
		||||
 | 
			
		||||
	return dev;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Return 1 if we prefer path1 else return 0 */
 | 
			
		||||
static int _compare_paths(const char *path0, const char *path1)
 | 
			
		||||
{
 | 
			
		||||
	int slash0 = 0, slash1 = 0;
 | 
			
		||||
	const char *p;
 | 
			
		||||
	char p0[PATH_MAX], p1[PATH_MAX];
 | 
			
		||||
	char *s0, *s1;
 | 
			
		||||
	struct stat stat0, stat1;
 | 
			
		||||
 | 
			
		||||
	/* Return the path with fewer slashes */
 | 
			
		||||
	for (p = path0; p++; p = (const char *) strchr(p, '/'))
 | 
			
		||||
		slash0++;
 | 
			
		||||
 | 
			
		||||
	for (p = path1; p++; p = (const char *) strchr(p, '/'))
 | 
			
		||||
		slash1++;
 | 
			
		||||
 | 
			
		||||
	if (slash0 < slash1)
 | 
			
		||||
		return 0;
 | 
			
		||||
	if (slash1 < slash0)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	strncpy(p0, path0, PATH_MAX);
 | 
			
		||||
	strncpy(p1, path1, PATH_MAX);
 | 
			
		||||
	s0 = &p0[0] + 1;
 | 
			
		||||
	s1 = &p1[0] + 1;
 | 
			
		||||
 | 
			
		||||
	/* We prefer symlinks - they exist for a reason!
 | 
			
		||||
	 * So we prefer a shorter path before the first symlink in the name.
 | 
			
		||||
	 * FIXME Configuration option to invert this? */
 | 
			
		||||
	while (s0) {
 | 
			
		||||
		s0 = strchr(s0, '/');
 | 
			
		||||
		s1 = strchr(s1, '/');
 | 
			
		||||
		if (s0) {
 | 
			
		||||
			*s0 = '\0';
 | 
			
		||||
			*s1 = '\0';
 | 
			
		||||
		}
 | 
			
		||||
		if (lstat(p0, &stat0)) {
 | 
			
		||||
			log_sys_error("lstat", p0);
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
		if (lstat(p1, &stat1)) {
 | 
			
		||||
			log_sys_error("lstat", p1);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (S_ISLNK(stat0.st_mode) && !S_ISLNK(stat1.st_mode))
 | 
			
		||||
			return 0;
 | 
			
		||||
		if (!S_ISLNK(stat0.st_mode) && S_ISLNK(stat1.st_mode))
 | 
			
		||||
			return 1;
 | 
			
		||||
		if (s0) {
 | 
			
		||||
			*s0++ = '/';
 | 
			
		||||
			*s1++ = '/';
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* ASCII comparison */
 | 
			
		||||
	if (strcmp(path0, path1) < 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	else
 | 
			
		||||
		return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _add_alias(struct device *dev, const char *path)
 | 
			
		||||
{
 | 
			
		||||
	struct str_list *sl = _alloc(sizeof(*sl));
 | 
			
		||||
	struct list *ah;
 | 
			
		||||
	const char *oldpath;
 | 
			
		||||
	int prefer_old = 1;
 | 
			
		||||
 | 
			
		||||
	if (!sl) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Is name already there? */
 | 
			
		||||
	list_iterate(ah, &dev->aliases) {
 | 
			
		||||
		if (!strcmp(list_item(ah, struct str_list)->str, path)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(sl->str = pool_strdup(_cache.mem, path))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_add(&dev->aliases, &sl->list);
 | 
			
		||||
	if (!list_empty(&dev->aliases)) {
 | 
			
		||||
		oldpath = list_item(dev->aliases.n, struct str_list)->str;
 | 
			
		||||
		prefer_old = _compare_paths(path, oldpath);
 | 
			
		||||
		log_debug("%s: Aliased to %s in device cache%s",
 | 
			
		||||
			  path, oldpath, prefer_old ? "" : " (preferred name)");
 | 
			
		||||
 | 
			
		||||
	} else
 | 
			
		||||
		log_debug("%s: Added to device cache", path);
 | 
			
		||||
 | 
			
		||||
	if (prefer_old)
 | 
			
		||||
		list_add(&dev->aliases, &sl->list);
 | 
			
		||||
	else
 | 
			
		||||
		list_add_h(&dev->aliases, &sl->list);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -92,14 +220,15 @@ static int _insert_dev(const char *path, dev_t d)
 | 
			
		||||
	struct device *dev;
 | 
			
		||||
 | 
			
		||||
	/* is this device already registered ? */
 | 
			
		||||
	if (!(dev = (struct device *) btree_lookup(_cache.devices, d))) {
 | 
			
		||||
	if (!(dev = (struct device *) btree_lookup(_cache.devices,
 | 
			
		||||
						   (uint32_t) d))) {
 | 
			
		||||
		/* create new device */
 | 
			
		||||
		if (!(dev = _create_dev(d))) {
 | 
			
		||||
		if (!(dev = _dev_create(d))) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!(btree_insert(_cache.devices, d, dev))) {
 | 
			
		||||
		if (!(btree_insert(_cache.devices, (uint32_t) d, dev))) {
 | 
			
		||||
			log_err("Couldn't insert device into binary tree.");
 | 
			
		||||
			_free(dev);
 | 
			
		||||
			return 0;
 | 
			
		||||
@@ -121,7 +250,7 @@ static int _insert_dev(const char *path, dev_t d)
 | 
			
		||||
 | 
			
		||||
static char *_join(const char *dir, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	int len = strlen(dir) + strlen(name) + 2;
 | 
			
		||||
	size_t len = strlen(dir) + strlen(name) + 2;
 | 
			
		||||
	char *r = dbg_malloc(len);
 | 
			
		||||
	if (r)
 | 
			
		||||
		snprintf(r, len, "%s/%s", dir, name);
 | 
			
		||||
@@ -193,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);
 | 
			
		||||
 | 
			
		||||
@@ -273,7 +413,7 @@ int dev_cache_init(void)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _check_closed(struct device *dev)
 | 
			
		||||
static void _check_closed(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	if (dev->fd >= 0)
 | 
			
		||||
		log_err("Device '%s' has been left open.", dev_name(dev));
 | 
			
		||||
@@ -286,11 +426,22 @@ static inline void _check_for_open_devices(void)
 | 
			
		||||
 | 
			
		||||
void dev_cache_exit(void)
 | 
			
		||||
{
 | 
			
		||||
	_check_for_open_devices();
 | 
			
		||||
 | 
			
		||||
	pool_destroy(_cache.mem);
 | 
			
		||||
	if (_cache.names)
 | 
			
		||||
		_check_for_open_devices();
 | 
			
		||||
 | 
			
		||||
	if (_cache.mem) {
 | 
			
		||||
		pool_destroy(_cache.mem);
 | 
			
		||||
		_cache.mem = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (_cache.names) {
 | 
			
		||||
		hash_destroy(_cache.names);
 | 
			
		||||
		_cache.names = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_cache.devices = NULL;
 | 
			
		||||
	_cache.has_scanned = 0;
 | 
			
		||||
	list_init(&_cache.dirs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dev_cache_add_dir(const char *path)
 | 
			
		||||
@@ -309,8 +460,10 @@ int dev_cache_add_dir(const char *path)
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(dl = _alloc(sizeof(*dl) + strlen(path) + 1)))
 | 
			
		||||
	if (!(dl = _alloc(sizeof(*dl) + strlen(path) + 1))) {
 | 
			
		||||
		log_error("dir_list allocation failed");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	strcpy(dl->dir, path);
 | 
			
		||||
	list_add(&_cache.dirs, &dl->list);
 | 
			
		||||
@@ -319,20 +472,31 @@ int dev_cache_add_dir(const char *path)
 | 
			
		||||
 | 
			
		||||
/* Check cached device name is still valid before returning it */
 | 
			
		||||
/* This should be a rare occurrence */
 | 
			
		||||
/* set quiet if the cache is expected to be out-of-date */
 | 
			
		||||
/* FIXME Make rest of code pass/cache struct device instead of dev_name */
 | 
			
		||||
const char *dev_name_confirmed(struct device *dev)
 | 
			
		||||
const char *dev_name_confirmed(struct device *dev, int quiet)
 | 
			
		||||
{
 | 
			
		||||
	struct stat buf;
 | 
			
		||||
	char *name;
 | 
			
		||||
	const char *name;
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	while ((r = stat(name = list_item(dev->aliases.n,
 | 
			
		||||
					  struct str_list)->str, &buf)) ||
 | 
			
		||||
	       (buf.st_rdev != dev->dev)) {
 | 
			
		||||
		if (r < 0)
 | 
			
		||||
			log_sys_error("stat", name);
 | 
			
		||||
		log_error("Path %s no longer valid for device(%d,%d)",
 | 
			
		||||
			  name, (int) MAJOR(dev->dev), (int) MINOR(dev->dev));
 | 
			
		||||
		if (r < 0) {
 | 
			
		||||
			if (quiet)
 | 
			
		||||
				log_sys_debug("stat", name);
 | 
			
		||||
			else
 | 
			
		||||
				log_sys_error("stat", name);
 | 
			
		||||
		}
 | 
			
		||||
		if (quiet)
 | 
			
		||||
			log_debug("Path %s no longer valid for device(%d,%d)",
 | 
			
		||||
				  name, (int) MAJOR(dev->dev),
 | 
			
		||||
				  (int) MINOR(dev->dev));
 | 
			
		||||
		else
 | 
			
		||||
			log_error("Path %s no longer valid for device(%d,%d)",
 | 
			
		||||
				  name, (int) MAJOR(dev->dev),
 | 
			
		||||
				  (int) MINOR(dev->dev));
 | 
			
		||||
 | 
			
		||||
		/* Remove the incorrect hash entry */
 | 
			
		||||
		hash_remove(_cache.names, name);
 | 
			
		||||
@@ -378,8 +542,10 @@ struct dev_iter *dev_iter_create(struct dev_filter *f)
 | 
			
		||||
{
 | 
			
		||||
	struct dev_iter *di = dbg_malloc(sizeof(*di));
 | 
			
		||||
 | 
			
		||||
	if (!di)
 | 
			
		||||
	if (!di) {
 | 
			
		||||
		log_error("dev_iter allocation failed");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_full_scan();
 | 
			
		||||
	di->current = btree_first(_cache.devices);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,21 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
#define _LVM_DEV_CACHE_H
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include "lvm-types.h"
 | 
			
		||||
#include "device.h"
 | 
			
		||||
 | 
			
		||||
@@ -15,12 +23,11 @@
 | 
			
		||||
 * predicate for devices.
 | 
			
		||||
 */
 | 
			
		||||
struct dev_filter {
 | 
			
		||||
	int (*passes_filter)(struct dev_filter *f, struct device *dev);
 | 
			
		||||
	void (*destroy)(struct dev_filter *f);
 | 
			
		||||
	int (*passes_filter) (struct dev_filter * f, struct device * dev);
 | 
			
		||||
	void (*destroy) (struct dev_filter * f);
 | 
			
		||||
	void *private;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The global device cache.
 | 
			
		||||
 */
 | 
			
		||||
@@ -34,7 +41,6 @@ int dev_cache_has_scanned(void);
 | 
			
		||||
int dev_cache_add_dir(const char *path);
 | 
			
		||||
struct device *dev_cache_get(const char *name, struct dev_filter *f);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Object for iterating through the cache.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,220 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
#include "device.h"
 | 
			
		||||
#include "lvm-types.h"
 | 
			
		||||
#include "device.h"
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
#include "memlock.h"
 | 
			
		||||
#include "locking.h"
 | 
			
		||||
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <linux/fs.h>		// UGH!!! for BLKSSZGET
 | 
			
		||||
 | 
			
		||||
#ifdef linux
 | 
			
		||||
#  define u64 uint64_t		/* Missing without __KERNEL__ */
 | 
			
		||||
#  undef WNOHANG		/* Avoid redefinition */
 | 
			
		||||
#  undef WUNTRACED		/* Avoid redefinition */
 | 
			
		||||
#  include <linux/fs.h>		/* For block ioctl definitions */
 | 
			
		||||
#  define BLKSIZE_SHIFT SECTOR_SHIFT
 | 
			
		||||
#  ifndef BLKGETSIZE64		/* fs.h out-of-date */
 | 
			
		||||
#    define BLKGETSIZE64 _IOR(0x12, 114, size_t)
 | 
			
		||||
#  endif /* BLKGETSIZE64 */
 | 
			
		||||
#else
 | 
			
		||||
#  include <sys/disk.h>
 | 
			
		||||
#  define BLKBSZGET DKIOCGETBLOCKSIZE
 | 
			
		||||
#  define BLKSSZGET DKIOCGETBLOCKSIZE
 | 
			
		||||
#  define BLKGETSIZE64 DKIOCGETBLOCKCOUNT
 | 
			
		||||
#  define BLKFLSBUF DKIOCSYNCHRONIZECACHE
 | 
			
		||||
#  define BLKSIZE_SHIFT 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef O_DIRECT_SUPPORT
 | 
			
		||||
#  ifndef O_DIRECT
 | 
			
		||||
#    error O_DIRECT support configured but O_DIRECT definition not found in headers
 | 
			
		||||
#  endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static LIST_INIT(_open_devices);
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------
 | 
			
		||||
 * The standard io loop that keeps submitting an io until it's
 | 
			
		||||
 * all gone.
 | 
			
		||||
 *---------------------------------------------------------------*/
 | 
			
		||||
static int _io(struct device_area *where, void *buffer, int should_write)
 | 
			
		||||
{
 | 
			
		||||
	int fd = dev_fd(where->dev);
 | 
			
		||||
	ssize_t n = 0;
 | 
			
		||||
	size_t total = 0;
 | 
			
		||||
 | 
			
		||||
	if (fd < 0) {
 | 
			
		||||
		log_error("Attempt to read an unopened device (%s).",
 | 
			
		||||
			  dev_name(where->dev));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Skip all writes in test mode.
 | 
			
		||||
	 */
 | 
			
		||||
	if (should_write && test_mode())
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (where->size > SSIZE_MAX) {
 | 
			
		||||
		log_error("Read size too large: %" PRIu64, where->size);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lseek(fd, (off_t) where->start, SEEK_SET) < 0) {
 | 
			
		||||
		log_sys_error("lseek", dev_name(where->dev));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (total < (size_t) where->size) {
 | 
			
		||||
		do
 | 
			
		||||
			n = should_write ?
 | 
			
		||||
			    write(fd, buffer, (size_t) where->size - total) :
 | 
			
		||||
			    read(fd, buffer, (size_t) where->size - total);
 | 
			
		||||
		while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
 | 
			
		||||
 | 
			
		||||
		if (n <= 0)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		total += n;
 | 
			
		||||
		buffer += n;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (total == (size_t) where->size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------
 | 
			
		||||
 * LVM2 uses O_DIRECT when performing metadata io, which requires
 | 
			
		||||
 * block size aligned accesses.  If any io is not aligned we have
 | 
			
		||||
 * to perform the io via a bounce buffer, obviously this is quite
 | 
			
		||||
 * inefficient.
 | 
			
		||||
 *---------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Get the sector size from an _open_ device.
 | 
			
		||||
 */
 | 
			
		||||
static int _get_block_size(struct device *dev, unsigned int *size)
 | 
			
		||||
{
 | 
			
		||||
	int s;
 | 
			
		||||
 | 
			
		||||
	if (ioctl(dev_fd(dev), BLKBSZGET, &s) < 0) {
 | 
			
		||||
		log_sys_error("ioctl BLKBSZGET", dev_name(dev));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*size = (unsigned int) s;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Widens a region to be an aligned region.
 | 
			
		||||
 */
 | 
			
		||||
static void _widen_region(unsigned int block_size, struct device_area *region,
 | 
			
		||||
			  struct device_area *result)
 | 
			
		||||
{
 | 
			
		||||
	uint64_t mask = block_size - 1, delta;
 | 
			
		||||
	memcpy(result, region, sizeof(*result));
 | 
			
		||||
 | 
			
		||||
	/* adjust the start */
 | 
			
		||||
	delta = result->start & mask;
 | 
			
		||||
	if (delta) {
 | 
			
		||||
		result->start -= delta;
 | 
			
		||||
		result->size += delta;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* adjust the end */
 | 
			
		||||
	delta = (result->start + result->size) & mask;
 | 
			
		||||
	if (delta)
 | 
			
		||||
		result->size += block_size - delta;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _aligned_io(struct device_area *where, void *buffer,
 | 
			
		||||
		       int should_write)
 | 
			
		||||
{
 | 
			
		||||
	void *bounce;
 | 
			
		||||
	unsigned int block_size = 0;
 | 
			
		||||
	uintptr_t mask;
 | 
			
		||||
	struct device_area widened;
 | 
			
		||||
 | 
			
		||||
	if (!(where->dev->flags & DEV_REGULAR) &&
 | 
			
		||||
	    !_get_block_size(where->dev, &block_size)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!block_size)
 | 
			
		||||
		block_size = getpagesize();
 | 
			
		||||
 | 
			
		||||
	_widen_region(block_size, where, &widened);
 | 
			
		||||
 | 
			
		||||
	/* Do we need to use a bounce buffer? */
 | 
			
		||||
	mask = block_size - 1;
 | 
			
		||||
	if (!memcmp(where, &widened, sizeof(widened)) &&
 | 
			
		||||
	    !((uintptr_t) buffer & mask))
 | 
			
		||||
		return _io(where, buffer, should_write);
 | 
			
		||||
 | 
			
		||||
	/* Allocate a bounce buffer with an extra block */
 | 
			
		||||
	if (!(bounce = alloca((size_t) widened.size + block_size))) {
 | 
			
		||||
		log_error("Bounce buffer alloca failed");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Realign start of bounce buffer (using the extra sector)
 | 
			
		||||
	 */
 | 
			
		||||
	if (((uintptr_t) bounce) & mask)
 | 
			
		||||
		bounce = (void *) ((((uintptr_t) bounce) + mask) & ~mask);
 | 
			
		||||
 | 
			
		||||
	/* channel the io through the bounce buffer */
 | 
			
		||||
	if (!_io(&widened, bounce, 0)) {
 | 
			
		||||
		if (!should_write) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		/* FIXME pre-extend the file */
 | 
			
		||||
		memset(bounce, '\n', widened.size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (should_write) {
 | 
			
		||||
		memcpy(bounce + (where->start - widened.start), buffer,
 | 
			
		||||
		       (size_t) where->size);
 | 
			
		||||
 | 
			
		||||
		/* ... then we write */
 | 
			
		||||
		return _io(&widened, bounce, 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memcpy(buffer, bounce + (where->start - widened.start),
 | 
			
		||||
	       (size_t) where->size);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------
 | 
			
		||||
 * Public functions
 | 
			
		||||
 *---------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
int dev_get_size(struct device *dev, uint64_t *size)
 | 
			
		||||
{
 | 
			
		||||
	int fd;
 | 
			
		||||
	long s;
 | 
			
		||||
	const char *name = dev_name(dev);
 | 
			
		||||
 | 
			
		||||
	log_very_verbose("Getting size of %s", name);
 | 
			
		||||
@@ -27,15 +223,14 @@ int dev_get_size(struct device *dev, uint64_t *size)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* FIXME: add 64 bit ioctl */
 | 
			
		||||
	if (ioctl(fd, BLKGETSIZE, &s) < 0) {
 | 
			
		||||
		log_sys_error("ioctl BLKGETSIZE", name);
 | 
			
		||||
	if (ioctl(fd, BLKGETSIZE64, size) < 0) {
 | 
			
		||||
		log_sys_error("ioctl BLKGETSIZE64", name);
 | 
			
		||||
		close(fd);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*size >>= BLKSIZE_SHIFT;	/* Convert to sectors */
 | 
			
		||||
	close(fd);
 | 
			
		||||
	*size = (uint64_t) s;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -62,49 +257,116 @@ int dev_get_sectsize(struct device *dev, uint32_t *size)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _flush(int fd)
 | 
			
		||||
void dev_flush(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	ioctl(fd, BLKFLSBUF, 0);
 | 
			
		||||
	if (!(dev->flags & DEV_REGULAR) && ioctl(dev->fd, BLKFLSBUF, 0) >= 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (fsync(dev->fd) >= 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	sync();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dev_open(struct device *dev, int flags)
 | 
			
		||||
int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
 | 
			
		||||
{
 | 
			
		||||
	struct stat buf;
 | 
			
		||||
	const char *name = dev_name_confirmed(dev);
 | 
			
		||||
	const char *name;
 | 
			
		||||
 | 
			
		||||
	if (!name) {
 | 
			
		||||
	if (dev->fd >= 0) {
 | 
			
		||||
		dev->open_count++;
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (memlock())
 | 
			
		||||
		log_error("WARNING: dev_open(%s) called while suspended",
 | 
			
		||||
			  dev_name(dev));
 | 
			
		||||
 | 
			
		||||
	if (dev->flags & DEV_REGULAR)
 | 
			
		||||
		name = dev_name(dev);
 | 
			
		||||
	else if (!(name = dev_name_confirmed(dev, quiet))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (dev->fd >= 0) {
 | 
			
		||||
		log_error("Device '%s' has already been opened", name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((stat(name, &buf) < 0) || (buf.st_rdev != dev->dev)) {
 | 
			
		||||
	if (!(dev->flags & DEV_REGULAR) &&
 | 
			
		||||
	    ((stat(name, &buf) < 0) || (buf.st_rdev != dev->dev))) {
 | 
			
		||||
		log_error("%s: stat failed: Has device name changed?", name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((dev->fd = open(name, flags)) < 0) {
 | 
			
		||||
#ifdef O_DIRECT_SUPPORT
 | 
			
		||||
	if (direct)
 | 
			
		||||
		flags |= O_DIRECT;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if ((dev->fd = open(name, flags, 0777)) < 0) {
 | 
			
		||||
		log_sys_error("open", name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev)) {
 | 
			
		||||
	dev->open_count = 1;
 | 
			
		||||
	dev->flags &= ~DEV_ACCESSED_W;
 | 
			
		||||
 | 
			
		||||
	if (!(dev->flags & DEV_REGULAR) &&
 | 
			
		||||
	    ((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
 | 
			
		||||
		log_error("%s: fstat failed: Has device name changed?", name);
 | 
			
		||||
		dev_close(dev);
 | 
			
		||||
		dev->fd = -1;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	_flush(dev->fd);
 | 
			
		||||
	dev->flags = 0;
 | 
			
		||||
 | 
			
		||||
#ifndef O_DIRECT_SUPPORT
 | 
			
		||||
	if (!(dev->flags & DEV_REGULAR))
 | 
			
		||||
		dev_flush(dev);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if ((flags & O_CREAT) && !(flags & O_TRUNC)) {
 | 
			
		||||
		dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_add(&_open_devices, &dev->open_list);
 | 
			
		||||
	log_debug("Opened %s", dev_name(dev));
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dev_close(struct device *dev)
 | 
			
		||||
int dev_open_quiet(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	int flags;
 | 
			
		||||
 | 
			
		||||
	flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
 | 
			
		||||
 | 
			
		||||
	return dev_open_flags(dev, flags, 1, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dev_open(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	int flags;
 | 
			
		||||
 | 
			
		||||
	flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
 | 
			
		||||
 | 
			
		||||
	return dev_open_flags(dev, flags, 1, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _close(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	if (close(dev->fd))
 | 
			
		||||
		log_sys_error("close", dev_name(dev));
 | 
			
		||||
	dev->fd = -1;
 | 
			
		||||
	list_del(&dev->open_list);
 | 
			
		||||
 | 
			
		||||
	log_debug("Closed %s", dev_name(dev));
 | 
			
		||||
 | 
			
		||||
	if (dev->flags & DEV_ALLOCED) {
 | 
			
		||||
		dbg_free((void *) list_item(dev->aliases.n, struct str_list)->
 | 
			
		||||
			 str);
 | 
			
		||||
		dbg_free(dev->aliases.n);
 | 
			
		||||
		dbg_free(dev);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _dev_close(struct device *dev, int immediate)
 | 
			
		||||
{
 | 
			
		||||
	if (dev->fd < 0) {
 | 
			
		||||
		log_error("Attempt to close device '%s' "
 | 
			
		||||
@@ -112,150 +374,125 @@ int dev_close(struct device *dev)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifndef O_DIRECT_SUPPORT
 | 
			
		||||
	if (dev->flags & DEV_ACCESSED_W)
 | 
			
		||||
		_flush(dev->fd);
 | 
			
		||||
		dev_flush(dev);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (close(dev->fd))
 | 
			
		||||
		log_sys_error("close", dev_name(dev));
 | 
			
		||||
 | 
			
		||||
	dev->fd = -1;
 | 
			
		||||
	/* FIXME lookup device in cache to get vgname and see if it's locked? */
 | 
			
		||||
	if (--dev->open_count < 1 && (immediate || !vgs_locked()))
 | 
			
		||||
		_close(dev);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  FIXME: factor common code out.
 | 
			
		||||
int dev_close(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	return _dev_close(dev, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dev_close_immediate(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	return _dev_close(dev, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dev_close_all(void)
 | 
			
		||||
{
 | 
			
		||||
	struct list *doh, *doht;
 | 
			
		||||
	struct device *dev;
 | 
			
		||||
 | 
			
		||||
	list_iterate_safe(doh, doht, &_open_devices) {
 | 
			
		||||
		dev = list_struct_base(doh, struct device, open_list);
 | 
			
		||||
		if (dev->open_count < 1)
 | 
			
		||||
			_close(dev);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer)
 | 
			
		||||
{
 | 
			
		||||
	struct device_area where;
 | 
			
		||||
 | 
			
		||||
	if (!dev->open_count)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	where.dev = dev;
 | 
			
		||||
	where.start = offset;
 | 
			
		||||
	where.size = len;
 | 
			
		||||
 | 
			
		||||
	return _aligned_io(&where, buffer, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* FIXME If O_DIRECT can't extend file, dev_extend first; dev_truncate after.
 | 
			
		||||
 *       But fails if concurrent processes writing
 | 
			
		||||
 */
 | 
			
		||||
int raw_read(int fd, void *buf, size_t count)
 | 
			
		||||
 | 
			
		||||
/* FIXME pre-extend the file */
 | 
			
		||||
int dev_append(struct device *dev, size_t len, void *buffer)
 | 
			
		||||
{
 | 
			
		||||
	size_t n = 0;
 | 
			
		||||
	int tot = 0;
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	while (tot < count) {
 | 
			
		||||
		do
 | 
			
		||||
			n = read(fd, buf, count - tot);
 | 
			
		||||
		while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
 | 
			
		||||
	if (!dev->open_count)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
		if (n <= 0)
 | 
			
		||||
			return tot ? tot : n;
 | 
			
		||||
	r = dev_write(dev, dev->end, len, buffer);
 | 
			
		||||
	dev->end += (uint64_t) len;
 | 
			
		||||
 | 
			
		||||
		tot += n;
 | 
			
		||||
		buf += n;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return tot;
 | 
			
		||||
#ifndef O_DIRECT_SUPPORT
 | 
			
		||||
	dev_flush(dev);
 | 
			
		||||
#endif
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int64_t dev_read(struct device * dev, uint64_t offset,
 | 
			
		||||
		 int64_t len, void *buffer)
 | 
			
		||||
int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer)
 | 
			
		||||
{
 | 
			
		||||
	const char *name = dev_name(dev);
 | 
			
		||||
	int fd = dev->fd;
 | 
			
		||||
	struct device_area where;
 | 
			
		||||
 | 
			
		||||
	if (fd < 0) {
 | 
			
		||||
		log_err("Attempt to read an unopened device (%s).", name);
 | 
			
		||||
	if (!dev->open_count)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lseek(fd, offset, SEEK_SET) < 0) {
 | 
			
		||||
		log_sys_error("lseek", name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw_read(fd, buffer, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int _write(int fd, const void *buf, size_t count)
 | 
			
		||||
{
 | 
			
		||||
	ssize_t n = 0;
 | 
			
		||||
	int tot = 0;
 | 
			
		||||
 | 
			
		||||
	/* Skip all writes */
 | 
			
		||||
	if (test_mode())
 | 
			
		||||
		return count;
 | 
			
		||||
 | 
			
		||||
	while (tot < count) {
 | 
			
		||||
		do
 | 
			
		||||
			n = write(fd, buf, count - tot);
 | 
			
		||||
		while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
 | 
			
		||||
 | 
			
		||||
		if (n <= 0)
 | 
			
		||||
			return tot ? tot : n;
 | 
			
		||||
 | 
			
		||||
		tot += n;
 | 
			
		||||
		buf += n;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return tot;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int64_t dev_write(struct device * dev, uint64_t offset,
 | 
			
		||||
		  int64_t len, void *buffer)
 | 
			
		||||
{
 | 
			
		||||
	const char *name = dev_name(dev);
 | 
			
		||||
	int fd = dev->fd;
 | 
			
		||||
 | 
			
		||||
	if (fd < 0) {
 | 
			
		||||
		log_error("Attempt to write to unopened device %s", name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lseek(fd, offset, SEEK_SET) < 0) {
 | 
			
		||||
		log_sys_error("lseek", name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	where.dev = dev;
 | 
			
		||||
	where.start = offset;
 | 
			
		||||
	where.size = len;
 | 
			
		||||
 | 
			
		||||
	dev->flags |= DEV_ACCESSED_W;
 | 
			
		||||
 | 
			
		||||
	return _write(fd, buffer, len);
 | 
			
		||||
	return _aligned_io(&where, buffer, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dev_zero(struct device *dev, uint64_t offset, int64_t len)
 | 
			
		||||
int dev_zero(struct device *dev, uint64_t offset, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	int64_t r, s;
 | 
			
		||||
	size_t s;
 | 
			
		||||
	char buffer[4096];
 | 
			
		||||
	int already_open;
 | 
			
		||||
 | 
			
		||||
	already_open = dev_is_open(dev);
 | 
			
		||||
 | 
			
		||||
	if (!already_open && !dev_open(dev, O_RDWR)) {
 | 
			
		||||
	if (!dev_open(dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lseek(dev->fd, offset, SEEK_SET) < 0) {
 | 
			
		||||
		log_sys_error("lseek", dev_name(dev));
 | 
			
		||||
		if (!already_open && !dev_close(dev))
 | 
			
		||||
			stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((offset % SECTOR_SIZE) || (len % SECTOR_SIZE))
 | 
			
		||||
		log_debug("Wiping %s at %" PRIu64 " length %" PRId64,
 | 
			
		||||
		log_debug("Wiping %s at %" PRIu64 " length %" PRIsize_t,
 | 
			
		||||
			  dev_name(dev), offset, len);
 | 
			
		||||
	else
 | 
			
		||||
		log_debug("Wiping %s at sector %" PRIu64 " length %" PRId64
 | 
			
		||||
		log_debug("Wiping %s at sector %" PRIu64 " length %" PRIsize_t
 | 
			
		||||
			  " sectors", dev_name(dev), offset >> SECTOR_SHIFT,
 | 
			
		||||
			  len >> SECTOR_SHIFT);
 | 
			
		||||
 | 
			
		||||
	memset(buffer, 0, sizeof(buffer));
 | 
			
		||||
	while (1) {
 | 
			
		||||
		s = len > sizeof(buffer) ? sizeof(buffer) : len;
 | 
			
		||||
		r = _write(dev->fd, buffer, s);
 | 
			
		||||
 | 
			
		||||
		if (r <= 0)
 | 
			
		||||
		if (!dev_write(dev, offset, s, buffer))
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		len -= r;
 | 
			
		||||
		if (!len) {
 | 
			
		||||
			r = 1;
 | 
			
		||||
		len -= s;
 | 
			
		||||
		if (!len)
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		offset += s;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev->flags |= DEV_ACCESSED_W;
 | 
			
		||||
 | 
			
		||||
	if (!already_open && !dev_close(dev))
 | 
			
		||||
	if (!dev_close(dev))
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	/* FIXME: Always display error */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/mman.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,27 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the GPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_DEVICE_H
 | 
			
		||||
#define _LVM_DEVICE_H
 | 
			
		||||
 | 
			
		||||
#include "lvm-types.h"
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "uuid.h"
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
#define DEV_ACCESSED_W		0x00000001	/* Device written to? */
 | 
			
		||||
#define DEV_REGULAR		0x00000002	/* Regular file? */
 | 
			
		||||
#define DEV_ALLOCED		0x00000004	/* dbg_malloc used */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * All devices in LVM will be represented by one of these.
 | 
			
		||||
@@ -23,7 +33,10 @@ struct device {
 | 
			
		||||
 | 
			
		||||
	/* private */
 | 
			
		||||
	int fd;
 | 
			
		||||
	int open_count;
 | 
			
		||||
	uint32_t flags;
 | 
			
		||||
	uint64_t end;
 | 
			
		||||
	struct list open_list;
 | 
			
		||||
 | 
			
		||||
	char pvid[ID_LEN + 1];
 | 
			
		||||
};
 | 
			
		||||
@@ -45,39 +58,46 @@ struct device_area {
 | 
			
		||||
int dev_get_size(struct device *dev, uint64_t *size);
 | 
			
		||||
int dev_get_sectsize(struct device *dev, uint32_t *size);
 | 
			
		||||
 | 
			
		||||
int dev_open(struct device *dev, int flags);
 | 
			
		||||
/* Use quiet version if device number could change e.g. when opening LV */
 | 
			
		||||
int dev_open(struct device *dev);
 | 
			
		||||
int dev_open_quiet(struct device *dev);
 | 
			
		||||
int dev_open_flags(struct device *dev, int flags, int append, int quiet);
 | 
			
		||||
int dev_close(struct device *dev);
 | 
			
		||||
int dev_close_immediate(struct device *dev);
 | 
			
		||||
void dev_close_all(void);
 | 
			
		||||
 | 
			
		||||
static inline int dev_fd(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	return dev->fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int raw_read(int fd, void *buf, size_t count);
 | 
			
		||||
int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer);
 | 
			
		||||
int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer);
 | 
			
		||||
int dev_append(struct device *dev, size_t len, void *buffer);
 | 
			
		||||
int dev_zero(struct device *dev, uint64_t offset, size_t len);
 | 
			
		||||
void dev_flush(struct device *dev);
 | 
			
		||||
 | 
			
		||||
int64_t dev_read(struct device *dev,
 | 
			
		||||
		 uint64_t offset, int64_t len, void *buffer);
 | 
			
		||||
int64_t dev_write(struct device *dev,
 | 
			
		||||
		  uint64_t offset, int64_t len, void *buffer);
 | 
			
		||||
int dev_zero(struct device *dev, uint64_t offset, int64_t len);
 | 
			
		||||
struct device *dev_create_file(const char *filename, struct device *dev,
 | 
			
		||||
			       struct str_list *alias);
 | 
			
		||||
 | 
			
		||||
static inline const char *dev_name(struct device *dev)
 | 
			
		||||
static inline const char *dev_name(const struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	return (dev) ? list_item(dev->aliases.n, struct str_list)->str :
 | 
			
		||||
	    "unknown device";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Return a valid device name from the alias list; NULL otherwise */
 | 
			
		||||
const char *dev_name_confirmed(struct device *dev);
 | 
			
		||||
const char *dev_name_confirmed(struct device *dev, int quiet);
 | 
			
		||||
 | 
			
		||||
/* FIXME Check partition type if appropriate */
 | 
			
		||||
 | 
			
		||||
#define is_lvm_partition(a) 1
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
static inline int is_lvm_partition(const char *name)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int dev_is_open(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	return dev->fd >= 0 ? 1 : 0;
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -42,13 +37,82 @@ static struct {
 | 
			
		||||
} _segtypes[] = {
 | 
			
		||||
	{
 | 
			
		||||
	SEG_STRIPED, "striped"}, {
 | 
			
		||||
	SEG_MIRROR, "mirror"}, {
 | 
			
		||||
	SEG_MIRRORED, "mirror"}, {
 | 
			
		||||
	SEG_SNAPSHOT, "snapshot"}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
	char *ptr = NULL;
 | 
			
		||||
	uint64_t v;
 | 
			
		||||
 | 
			
		||||
	if (isdigit(*units)) {
 | 
			
		||||
		v = (uint64_t) strtod(units, &ptr);
 | 
			
		||||
		if (ptr == units)
 | 
			
		||||
			return 0;
 | 
			
		||||
		units = ptr;
 | 
			
		||||
	} else
 | 
			
		||||
		v = 1;
 | 
			
		||||
 | 
			
		||||
	if (v == 1)
 | 
			
		||||
		*unit_type = *units;
 | 
			
		||||
	else
 | 
			
		||||
		*unit_type = 'U';
 | 
			
		||||
 | 
			
		||||
	switch (*units) {
 | 
			
		||||
	case 'h':
 | 
			
		||||
	case 'H':
 | 
			
		||||
		v = UINT64_C(1);
 | 
			
		||||
		*unit_type = *units;
 | 
			
		||||
		break;
 | 
			
		||||
	case 's':
 | 
			
		||||
		v *= SECTOR_SIZE;
 | 
			
		||||
		break;
 | 
			
		||||
	case 'b':
 | 
			
		||||
	case 'B':
 | 
			
		||||
		v *= UINT64_C(1);
 | 
			
		||||
		break;
 | 
			
		||||
#define KILO UINT64_C(1024)
 | 
			
		||||
	case 'k':
 | 
			
		||||
		v *= KILO;
 | 
			
		||||
		break;
 | 
			
		||||
	case 'm':
 | 
			
		||||
		v *= KILO * KILO;
 | 
			
		||||
		break;
 | 
			
		||||
	case 'g':
 | 
			
		||||
		v *= KILO * KILO * KILO;
 | 
			
		||||
		break;
 | 
			
		||||
	case 't':
 | 
			
		||||
		v *= KILO * KILO * KILO * KILO;
 | 
			
		||||
		break;
 | 
			
		||||
#undef KILO
 | 
			
		||||
#define KILO UINT64_C(1000)
 | 
			
		||||
	case 'K':
 | 
			
		||||
		v *= KILO;
 | 
			
		||||
		break;
 | 
			
		||||
	case 'M':
 | 
			
		||||
		v *= KILO * KILO;
 | 
			
		||||
		break;
 | 
			
		||||
	case 'G':
 | 
			
		||||
		v *= KILO * KILO * KILO;
 | 
			
		||||
		break;
 | 
			
		||||
	case 'T':
 | 
			
		||||
		v *= KILO * KILO * KILO * KILO;
 | 
			
		||||
		break;
 | 
			
		||||
#undef KILO
 | 
			
		||||
	default:
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (*(units + 1))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *get_alloc_string(alloc_policy_t alloc)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
@@ -68,7 +132,7 @@ const char *get_segtype_string(segment_type_t segtype)
 | 
			
		||||
		if (_segtypes[i].segtype == segtype)
 | 
			
		||||
			return _segtypes[i].str;
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
	return "unknown";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
alloc_policy_t get_alloc_from_string(const char *str)
 | 
			
		||||
@@ -95,35 +159,60 @@ segment_type_t get_segtype_from_string(const char *str)
 | 
			
		||||
	return SEG_STRIPED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *display_size(uint64_t size, size_len_t sl)
 | 
			
		||||
const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl)
 | 
			
		||||
{
 | 
			
		||||
	int s;
 | 
			
		||||
	ulong byte = 1024 * 1024 * 1024;
 | 
			
		||||
	int suffix = 1;
 | 
			
		||||
	uint64_t byte = UINT64_C(0);
 | 
			
		||||
	uint64_t units = UINT64_C(1024);
 | 
			
		||||
	char *size_buf = NULL;
 | 
			
		||||
	char *size_str[][2] = {
 | 
			
		||||
		{"Terabyte", "TB"},
 | 
			
		||||
		{"Gigabyte", "GB"},
 | 
			
		||||
		{"Megabyte", "MB"},
 | 
			
		||||
		{"Kilobyte", "KB"},
 | 
			
		||||
		{"", ""}
 | 
			
		||||
	const char *size_str[][3] = {
 | 
			
		||||
		{" Terabyte", " TB", "T"},
 | 
			
		||||
		{" Gigabyte", " GB", "G"},
 | 
			
		||||
		{" Megabyte", " MB", "M"},
 | 
			
		||||
		{" Kilobyte", " KB", "K"},
 | 
			
		||||
		{"", "", ""},
 | 
			
		||||
		{" Byte    ", " B ", "B"},
 | 
			
		||||
		{" Units   ", " Un", "U"},
 | 
			
		||||
		{" Sectors ", " Se", "S"},
 | 
			
		||||
		{"         ", "   ", " "},
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	if (!(size_buf = dbg_malloc(SIZE_BUF))) {
 | 
			
		||||
	if (!(size_buf = pool_alloc(cmd->mem, SIZE_BUF))) {
 | 
			
		||||
		log_error("no memory for size display buffer");
 | 
			
		||||
		return NULL;
 | 
			
		||||
		return "";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (size == 0LL)
 | 
			
		||||
		sprintf(size_buf, "0");
 | 
			
		||||
	else {
 | 
			
		||||
	suffix = cmd->current_settings.suffix;
 | 
			
		||||
 | 
			
		||||
	for (s = 0; s < 8; s++)
 | 
			
		||||
		if (toupper((int) cmd->current_settings.unit_type) ==
 | 
			
		||||
		    *size_str[s][2])
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
	if (size == UINT64_C(0)) {
 | 
			
		||||
		sprintf(size_buf, "0%s", suffix ? size_str[s][sl] : "");
 | 
			
		||||
		return size_buf;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (s < 8) {
 | 
			
		||||
		byte = cmd->current_settings.unit_factor;
 | 
			
		||||
		size *= UINT64_C(1024);
 | 
			
		||||
	} else {
 | 
			
		||||
		suffix = 1;
 | 
			
		||||
		if (cmd->current_settings.unit_type == 'H')
 | 
			
		||||
			units = UINT64_C(1000);
 | 
			
		||||
		else
 | 
			
		||||
			units = UINT64_C(1024);
 | 
			
		||||
		byte = units * units * units;
 | 
			
		||||
		s = 0;
 | 
			
		||||
		while (size_str[s] && size < byte)
 | 
			
		||||
			s++, byte /= 1024;
 | 
			
		||||
		snprintf(size_buf, SIZE_BUF - 1,
 | 
			
		||||
			 "%.2f %s", (float) size / byte, size_str[s][sl]);
 | 
			
		||||
			s++, byte /= units;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Caller to deallocate */
 | 
			
		||||
	snprintf(size_buf, SIZE_BUF - 1, "%.2f%s", (float) size / byte,
 | 
			
		||||
		 suffix ? size_str[s][sl] : "");
 | 
			
		||||
 | 
			
		||||
	return size_buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -139,7 +228,7 @@ void pvdisplay_colons(struct physical_volume *pv)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_print("%s:%s:%" PRIu64 ":-1:%u:%u:-1:%" PRIu64 ":%u:%u:%u:%s",
 | 
			
		||||
	log_print("%s:%s:%" PRIu64 ":-1:%u:%u:-1:%" PRIu32 ":%u:%u:%u:%s",
 | 
			
		||||
		  dev_name(pv->dev), pv->vg_name, pv->size,
 | 
			
		||||
		  /* FIXME pv->pv_number, Derive or remove? */
 | 
			
		||||
		  pv->status,	/* FIXME Support old or new format here? */
 | 
			
		||||
@@ -154,12 +243,13 @@ void pvdisplay_colons(struct physical_volume *pv)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* FIXME Include label fields */
 | 
			
		||||
void pvdisplay_full(struct physical_volume *pv, void *handle)
 | 
			
		||||
void pvdisplay_full(struct cmd_context *cmd, struct physical_volume *pv,
 | 
			
		||||
		    void *handle)
 | 
			
		||||
{
 | 
			
		||||
	char uuid[64];
 | 
			
		||||
	char *size, *size1;	/*, *size2; */
 | 
			
		||||
	const char *size;
 | 
			
		||||
 | 
			
		||||
	uint64_t pe_free;
 | 
			
		||||
	uint32_t pe_free;
 | 
			
		||||
 | 
			
		||||
	if (!pv)
 | 
			
		||||
		return;
 | 
			
		||||
@@ -174,23 +264,21 @@ void pvdisplay_full(struct physical_volume *pv, void *handle)
 | 
			
		||||
	log_print("VG Name               %s%s", pv->vg_name,
 | 
			
		||||
		  pv->status & EXPORTED_VG ? " (exported)" : "");
 | 
			
		||||
 | 
			
		||||
	size = display_size((uint64_t) pv->size / 2, SIZE_SHORT);
 | 
			
		||||
	size = display_size(cmd, (uint64_t) pv->size / 2, SIZE_SHORT);
 | 
			
		||||
	if (pv->pe_size && pv->pe_count) {
 | 
			
		||||
		size1 = display_size((pv->size - pv->pe_count * pv->pe_size)
 | 
			
		||||
				     / 2, SIZE_SHORT);
 | 
			
		||||
 | 
			
		||||
/******** FIXME display LVM on-disk data size
 | 
			
		||||
		size2 = display_size(pv->size / 2, SIZE_SHORT);
 | 
			
		||||
********/
 | 
			
		||||
 | 
			
		||||
		log_print("PV Size               %s" " / not usable %s",	/*  [LVM: %s]", */
 | 
			
		||||
			  size, size1);	/* , size2);    */
 | 
			
		||||
			  size, display_size(cmd,
 | 
			
		||||
					     (pv->size -
 | 
			
		||||
					      pv->pe_count * pv->pe_size) / 2,
 | 
			
		||||
					     SIZE_SHORT));
 | 
			
		||||
 | 
			
		||||
		dbg_free(size1);
 | 
			
		||||
		/* dbg_free(size2); */
 | 
			
		||||
	} else
 | 
			
		||||
		log_print("PV Size               %s", size);
 | 
			
		||||
	dbg_free(size);
 | 
			
		||||
 | 
			
		||||
	/* PV number not part of LVM2 design
 | 
			
		||||
	   log_print("PV#                   %u", pv->pv_number);
 | 
			
		||||
@@ -206,9 +294,9 @@ void pvdisplay_full(struct physical_volume *pv, void *handle)
 | 
			
		||||
	/* LV count is no longer available when displaying PV
 | 
			
		||||
	   log_print("Cur LV                %u", vg->lv_count);
 | 
			
		||||
	 */
 | 
			
		||||
	log_print("PE Size (KByte)       %" PRIu64, pv->pe_size / 2);
 | 
			
		||||
	log_print("PE Size (KByte)       %" PRIu32, pv->pe_size / 2);
 | 
			
		||||
	log_print("Total PE              %u", pv->pe_count);
 | 
			
		||||
	log_print("Free PE               %" PRIu64, pe_free);
 | 
			
		||||
	log_print("Free PE               %" PRIu32, pe_free);
 | 
			
		||||
	log_print("Allocated PE          %u", pv->pe_alloc_count);
 | 
			
		||||
	log_print("PV UUID               %s", *uuid ? uuid : "none");
 | 
			
		||||
	log_print(" ");
 | 
			
		||||
@@ -219,11 +307,19 @@ void pvdisplay_full(struct physical_volume *pv, void *handle)
 | 
			
		||||
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
 | 
			
		||||
		    struct physical_volume *pv, void *handle)
 | 
			
		||||
{
 | 
			
		||||
	char uuid[64];
 | 
			
		||||
 | 
			
		||||
	if (!pv)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_print("PV Name               %s     ", dev_name(pv->dev));
 | 
			
		||||
	/* FIXME  pv->pv_number); */
 | 
			
		||||
	log_print("PV UUID               %s", *uuid ? uuid : "none");
 | 
			
		||||
	log_print("PV Status             %sallocatable",
 | 
			
		||||
		  (pv->status & ALLOCATABLE_PV) ? "" : "NOT ");
 | 
			
		||||
	log_print("Total PE / Free PE    %u / %u",
 | 
			
		||||
@@ -236,7 +332,7 @@ int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
 | 
			
		||||
void lvdisplay_colons(struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
	int inkernel;
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	struct lvinfo info;
 | 
			
		||||
	inkernel = lv_info(lv, &info) && info.exists;
 | 
			
		||||
 | 
			
		||||
	log_print("%s%s/%s:%s:%d:%d:-1:%d:%" PRIu64 ":%d:-1:%d:%d:%d:%d",
 | 
			
		||||
@@ -256,13 +352,12 @@ void lvdisplay_colons(struct logical_volume *lv)
 | 
			
		||||
int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
		   void *handle)
 | 
			
		||||
{
 | 
			
		||||
	char *size;
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	struct lvinfo info;
 | 
			
		||||
	int inkernel, snap_active;
 | 
			
		||||
	char uuid[64];
 | 
			
		||||
	struct snapshot *snap = NULL;
 | 
			
		||||
	struct list *slh, *snaplist;
 | 
			
		||||
	float snap_percent; /* fused, fsize; */
 | 
			
		||||
	float snap_percent;	/* fused, fsize; */
 | 
			
		||||
 | 
			
		||||
	if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) {
 | 
			
		||||
		stack;
 | 
			
		||||
@@ -290,13 +385,19 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
			snap = list_item(slh, struct snapshot_list)->snapshot;
 | 
			
		||||
			snap_active = lv_snapshot_percent(snap->cow,
 | 
			
		||||
							  &snap_percent);
 | 
			
		||||
			if (!snap_active || snap_percent < 0 ||
 | 
			
		||||
			    snap_percent >= 100)
 | 
			
		||||
				snap_active = 0;
 | 
			
		||||
			log_print("                       %s%s/%s [%s]",
 | 
			
		||||
				  lv->vg->cmd->dev_dir, lv->vg->name,
 | 
			
		||||
				  snap->cow->name,
 | 
			
		||||
				  (snap_active > 0) ? "active" : "INACTIVE");
 | 
			
		||||
		}
 | 
			
		||||
		snap = NULL;
 | 
			
		||||
	} else if ((snap = find_cow(lv))) {
 | 
			
		||||
		snap_active = lv_snapshot_percent(lv, &snap_percent);
 | 
			
		||||
		if (!snap_active || snap_percent < 0 || snap_percent >= 100)
 | 
			
		||||
			snap_active = 0;
 | 
			
		||||
		log_print("LV snapshot status     %s destination for %s%s/%s",
 | 
			
		||||
			  (snap_active > 0) ? "active" : "INACTIVE",
 | 
			
		||||
			  lv->vg->cmd->dev_dir, lv->vg->name,
 | 
			
		||||
@@ -316,10 +417,10 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
	if (inkernel)
 | 
			
		||||
		log_print("# open                 %u", info.open_count);
 | 
			
		||||
 | 
			
		||||
	size = display_size(snap ? snap->origin->size / 2 : lv->size / 2,
 | 
			
		||||
			    SIZE_SHORT);
 | 
			
		||||
	log_print("LV Size                %s", size);
 | 
			
		||||
	dbg_free(size);
 | 
			
		||||
	log_print("LV Size                %s",
 | 
			
		||||
		  display_size(cmd,
 | 
			
		||||
			       snap ? snap->origin->size / 2 : lv->size / 2,
 | 
			
		||||
			       SIZE_SHORT));
 | 
			
		||||
 | 
			
		||||
	log_print("Current LE             %u",
 | 
			
		||||
		  snap ? snap->origin->le_count : lv->le_count);
 | 
			
		||||
@@ -334,23 +435,23 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
	log_print("Stripe size (KByte)    %u", lv->stripesize / 2);
 | 
			
		||||
***********/
 | 
			
		||||
 | 
			
		||||
    if (snap) {
 | 
			
		||||
    	if (snap_percent == -1)
 | 
			
		||||
		snap_percent = 100;
 | 
			
		||||
	if (snap) {
 | 
			
		||||
		if (snap_percent == -1)
 | 
			
		||||
			snap_percent = 100;
 | 
			
		||||
 | 
			
		||||
	size = display_size(snap->chunk_size / 2, SIZE_SHORT);
 | 
			
		||||
	log_print("Snapshot chunk size    %s", size);
 | 
			
		||||
	dbg_free(size);
 | 
			
		||||
		log_print("Snapshot chunk size    %s",
 | 
			
		||||
			  display_size(cmd, (uint64_t) snap->chunk_size / 2,
 | 
			
		||||
				       SIZE_SHORT));
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	size = display_size(lv->size / 2, SIZE_SHORT);
 | 
			
		||||
	sscanf(size, "%f", &fsize);
 | 
			
		||||
	fused = fsize * snap_percent / 100;
 | 
			
		||||
*/
 | 
			
		||||
	log_print("Allocated to snapshot  %.2f%% ", /* [%.2f/%s]", */
 | 
			
		||||
		  snap_percent);  /*, fused, size); */
 | 
			
		||||
	/* dbg_free(size); */
 | 
			
		||||
    }
 | 
			
		||||
		log_print("Allocated to snapshot  %.2f%% ",	/* [%.2f/%s]", */
 | 
			
		||||
			  snap_percent);	/*, fused, size); */
 | 
			
		||||
		/* dbg_free(size); */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/********** FIXME Snapshot
 | 
			
		||||
	size = ???
 | 
			
		||||
@@ -362,8 +463,11 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
	log_print("Allocation             %s", get_alloc_string(lv->alloc));
 | 
			
		||||
	log_print("Read ahead sectors     %u", lv->read_ahead);
 | 
			
		||||
 | 
			
		||||
	if (lv->status & FIXED_MINOR)
 | 
			
		||||
	if (lv->status & FIXED_MINOR) {
 | 
			
		||||
		if (lv->major >= 0)
 | 
			
		||||
			log_print("Persistent major       %d", lv->major);
 | 
			
		||||
		log_print("Persistent minor       %d", lv->minor);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (inkernel)
 | 
			
		||||
		log_print("Block device           %d:%d", info.major,
 | 
			
		||||
@@ -374,21 +478,35 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _display_stripe(struct lv_segment *seg, int s, const char *pre)
 | 
			
		||||
static void _display_stripe(struct lv_segment *seg, uint32_t s, const char *pre)
 | 
			
		||||
{
 | 
			
		||||
	uint32_t len = seg->len / seg->stripes;
 | 
			
		||||
	switch (seg->area[s].type) {
 | 
			
		||||
	case AREA_PV:
 | 
			
		||||
		log_print("%sPhysical volume\t%s", pre,
 | 
			
		||||
			  seg->area[s].u.pv.pv ?
 | 
			
		||||
			  dev_name(seg->area[s].u.pv.pv->dev) : "Missing");
 | 
			
		||||
 | 
			
		||||
	log_print("%sPhysical volume\t%s", pre,
 | 
			
		||||
		  seg->area[s].pv ? dev_name(seg->area[s].pv->dev) : "Missing");
 | 
			
		||||
		if (seg->area[s].u.pv.pv)
 | 
			
		||||
			log_print("%sPhysical extents\t%d to %d", pre,
 | 
			
		||||
				  seg->area[s].u.pv.pe,
 | 
			
		||||
				  seg->area[s].u.pv.pe + seg->area_len - 1);
 | 
			
		||||
		break;
 | 
			
		||||
	case AREA_LV:
 | 
			
		||||
		log_print("%sLogical volume\t%s", pre,
 | 
			
		||||
			  seg->area[s].u.lv.lv ?
 | 
			
		||||
			  seg->area[s].u.lv.lv->name : "Missing");
 | 
			
		||||
 | 
			
		||||
	if (seg->area[s].pv)
 | 
			
		||||
		log_print("%sPhysical extents\t%d to %d", pre,
 | 
			
		||||
			  seg->area[s].pe, seg->area[s].pe + len - 1);
 | 
			
		||||
		if (seg->area[s].u.lv.lv)
 | 
			
		||||
			log_print("%sLogical extents\t%d to %d", pre,
 | 
			
		||||
				  seg->area[s].u.lv.le,
 | 
			
		||||
				  seg->area[s].u.lv.le + seg->area_len - 1);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int lvdisplay_segments(struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
	int s;
 | 
			
		||||
	uint32_t s;
 | 
			
		||||
	struct list *segh;
 | 
			
		||||
	struct lv_segment *seg;
 | 
			
		||||
 | 
			
		||||
@@ -397,21 +515,25 @@ int lvdisplay_segments(struct logical_volume *lv)
 | 
			
		||||
	list_iterate(segh, &lv->segments) {
 | 
			
		||||
		seg = list_item(segh, struct lv_segment);
 | 
			
		||||
 | 
			
		||||
		log_print("Logical extent %d to %d:",
 | 
			
		||||
		log_print("Logical extent %u to %u:",
 | 
			
		||||
			  seg->le, seg->le + seg->len - 1);
 | 
			
		||||
 | 
			
		||||
		log_print("  Type\t\t%s", get_segtype_string(seg->type));
 | 
			
		||||
		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));
 | 
			
		||||
 | 
			
		||||
		switch (seg->type) {
 | 
			
		||||
		case SEG_STRIPED:
 | 
			
		||||
			if (seg->stripes == 1)
 | 
			
		||||
			if (seg->area_count == 1)
 | 
			
		||||
				_display_stripe(seg, 0, "  ");
 | 
			
		||||
			else {
 | 
			
		||||
				log_print("  Stripes\t\t%d", seg->stripes);
 | 
			
		||||
				log_print("  Stripe size\t\t%d",
 | 
			
		||||
					  seg->stripe_size);
 | 
			
		||||
				log_print("  Stripes\t\t%u", seg->area_count);
 | 
			
		||||
				log_print("  Stripe size\t\t%u KB",
 | 
			
		||||
					  seg->stripe_size / 2);
 | 
			
		||||
 | 
			
		||||
				for (s = 0; s < seg->stripes; s++) {
 | 
			
		||||
				for (s = 0; s < seg->area_count; s++) {
 | 
			
		||||
					log_print("  Stripe %d:", s);
 | 
			
		||||
					_display_stripe(seg, s, "    ");
 | 
			
		||||
				}
 | 
			
		||||
@@ -419,8 +541,16 @@ int lvdisplay_segments(struct logical_volume *lv)
 | 
			
		||||
			log_print(" ");
 | 
			
		||||
			break;
 | 
			
		||||
		case SEG_SNAPSHOT:
 | 
			
		||||
		case SEG_MIRROR:
 | 
			
		||||
			;
 | 
			
		||||
			break;
 | 
			
		||||
		case SEG_MIRRORED:
 | 
			
		||||
			log_print("  Mirrors\t\t%u", seg->area_count);
 | 
			
		||||
			log_print("  Mirror size\t\t%u", seg->area_len);
 | 
			
		||||
			log_print("  Mirror original:");
 | 
			
		||||
			_display_stripe(seg, 0, "    ");
 | 
			
		||||
			log_print("  Mirror destination:");
 | 
			
		||||
			_display_stripe(seg, 1, "    ");
 | 
			
		||||
			log_print(" ");
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -437,7 +567,6 @@ void vgdisplay_full(struct volume_group *vg)
 | 
			
		||||
{
 | 
			
		||||
	uint32_t access;
 | 
			
		||||
	uint32_t active_pvs;
 | 
			
		||||
	char *s1;
 | 
			
		||||
	char uuid[64];
 | 
			
		||||
 | 
			
		||||
	if (vg->status & PARTIAL_VG)
 | 
			
		||||
@@ -483,28 +612,34 @@ void vgdisplay_full(struct volume_group *vg)
 | 
			
		||||
	log_print("Cur PV                %u", vg->pv_count);
 | 
			
		||||
	log_print("Act PV                %u", active_pvs);
 | 
			
		||||
 | 
			
		||||
	s1 = display_size((uint64_t) vg->extent_count * (vg->extent_size / 2),
 | 
			
		||||
			  SIZE_SHORT);
 | 
			
		||||
	log_print("VG Size               %s", s1);
 | 
			
		||||
	dbg_free(s1);
 | 
			
		||||
	log_print("VG Size               %s",
 | 
			
		||||
		  display_size(vg->cmd,
 | 
			
		||||
			       (uint64_t) vg->extent_count * (vg->extent_size /
 | 
			
		||||
							      2), SIZE_SHORT));
 | 
			
		||||
 | 
			
		||||
	s1 = display_size(vg->extent_size / 2, SIZE_SHORT);
 | 
			
		||||
	log_print("PE Size               %s", s1);
 | 
			
		||||
	dbg_free(s1);
 | 
			
		||||
	log_print("PE Size               %s",
 | 
			
		||||
		  display_size(vg->cmd, (uint64_t) vg->extent_size / 2,
 | 
			
		||||
			       SIZE_SHORT));
 | 
			
		||||
 | 
			
		||||
	log_print("Total PE              %u", vg->extent_count);
 | 
			
		||||
 | 
			
		||||
	s1 = display_size(((uint64_t)
 | 
			
		||||
			   vg->extent_count - vg->free_count) *
 | 
			
		||||
			  (vg->extent_size / 2), SIZE_SHORT);
 | 
			
		||||
	log_print("Alloc PE / Size       %u / %s",
 | 
			
		||||
		  vg->extent_count - vg->free_count, s1);
 | 
			
		||||
	dbg_free(s1);
 | 
			
		||||
		  vg->extent_count - vg->free_count, display_size(vg->cmd,
 | 
			
		||||
								  ((uint64_t)
 | 
			
		||||
								   vg->
 | 
			
		||||
								   extent_count
 | 
			
		||||
								   -
 | 
			
		||||
								   vg->
 | 
			
		||||
								   free_count) *
 | 
			
		||||
								  (vg->
 | 
			
		||||
								   extent_size /
 | 
			
		||||
								   2),
 | 
			
		||||
								  SIZE_SHORT));
 | 
			
		||||
 | 
			
		||||
	s1 = display_size((uint64_t) vg->free_count * (vg->extent_size / 2),
 | 
			
		||||
			  SIZE_SHORT);
 | 
			
		||||
	log_print("Free  PE / Size       %u / %s", vg->free_count, s1);
 | 
			
		||||
	dbg_free(s1);
 | 
			
		||||
	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));
 | 
			
		||||
 | 
			
		||||
	if (!id_write_format(&vg->id, uuid, sizeof(uuid))) {
 | 
			
		||||
		stack;
 | 
			
		||||
@@ -519,21 +654,69 @@ 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void vgdisplay_short(struct volume_group *vg)
 | 
			
		||||
{
 | 
			
		||||
	char *s1, *s2, *s3;
 | 
			
		||||
	s1 = display_size(vg->extent_count * vg->extent_size / 2, SIZE_SHORT);
 | 
			
		||||
	s2 = display_size((vg->extent_count -
 | 
			
		||||
			   vg->free_count) * vg->extent_size / 2, SIZE_SHORT);
 | 
			
		||||
	s3 = display_size(vg->free_count * vg->extent_size / 2, SIZE_SHORT);
 | 
			
		||||
	log_print("\"%s\" %-9s [%-9s used / %s free]", vg->name,
 | 
			
		||||
/********* FIXME if "open" print "/used" else print "/idle"???  ******/
 | 
			
		||||
		  s1, s2, s3);
 | 
			
		||||
	dbg_free(s1);
 | 
			
		||||
	dbg_free(s2);
 | 
			
		||||
	dbg_free(s3);
 | 
			
		||||
		  display_size(vg->cmd, (uint64_t) vg->extent_count *
 | 
			
		||||
			       vg->extent_size / 2, SIZE_SHORT),
 | 
			
		||||
		  display_size(vg->cmd,
 | 
			
		||||
			       ((uint64_t) vg->extent_count -
 | 
			
		||||
				vg->free_count) * vg->extent_size / 2,
 | 
			
		||||
			       SIZE_SHORT), display_size(vg->cmd,
 | 
			
		||||
							 (uint64_t) vg->
 | 
			
		||||
							 free_count *
 | 
			
		||||
							 vg->extent_size / 2,
 | 
			
		||||
							 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
 | 
			
		||||
@@ -25,14 +20,17 @@
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
typedef enum { SIZE_LONG = 0, SIZE_SHORT = 1 } size_len_t;
 | 
			
		||||
typedef enum { SIZE_LONG = 0, SIZE_SHORT = 1, SIZE_UNIT = 2 } size_len_t;
 | 
			
		||||
 | 
			
		||||
uint64_t units_to_bytes(const char *units, char *unit_type);
 | 
			
		||||
 | 
			
		||||
/* Specify size in KB */
 | 
			
		||||
char *display_size(uint64_t size, size_len_t sl);
 | 
			
		||||
const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl);
 | 
			
		||||
char *display_uuid(char *uuidstr);
 | 
			
		||||
 | 
			
		||||
void pvdisplay_colons(struct physical_volume *pv);
 | 
			
		||||
void pvdisplay_full(struct physical_volume *pv, void *handle);
 | 
			
		||||
void pvdisplay_full(struct cmd_context *cmd, struct physical_volume *pv,
 | 
			
		||||
		    void *handle);
 | 
			
		||||
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
 | 
			
		||||
		    struct physical_volume *pv, void *handle);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -19,6 +28,8 @@ static int _and_p(struct dev_filter *f, struct device *dev)
 | 
			
		||||
		filters++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_debug("Using %s", dev_name(dev));
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -35,35 +46,32 @@ static void _destroy(struct dev_filter *f)
 | 
			
		||||
	dbg_free(f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct dev_filter *composite_filter_create(int n, ...)
 | 
			
		||||
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
 | 
			
		||||
{
 | 
			
		||||
	struct dev_filter **filters = dbg_malloc(sizeof(*filters) * (n + 1));
 | 
			
		||||
	struct dev_filter *cf;
 | 
			
		||||
	va_list ap;
 | 
			
		||||
	int i;
 | 
			
		||||
	struct dev_filter **filters_copy, *cf;
 | 
			
		||||
 | 
			
		||||
	if (!filters) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(cf = dbg_malloc(sizeof(*cf)))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		dbg_free(filters);
 | 
			
		||||
	if (!(filters_copy = dbg_malloc(sizeof(*filters) * (n + 1)))) {
 | 
			
		||||
		log_error("composite filters allocation failed");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	va_start(ap, n);
 | 
			
		||||
	for (i = 0; i < n; i++) {
 | 
			
		||||
		struct dev_filter *f = va_arg(ap, struct dev_filter *);
 | 
			
		||||
		filters[i] = f;
 | 
			
		||||
	memcpy(filters_copy, filters, sizeof(*filters) * n);
 | 
			
		||||
	filters_copy[n] = NULL;
 | 
			
		||||
 | 
			
		||||
	if (!(cf = dbg_malloc(sizeof(*cf)))) {
 | 
			
		||||
		log_error("compsoite filters allocation failed");
 | 
			
		||||
		dbg_free(filters_copy);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	filters[i] = NULL;
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
 | 
			
		||||
	cf->passes_filter = _and_p;
 | 
			
		||||
	cf->destroy = _destroy;
 | 
			
		||||
	cf->private = filters;
 | 
			
		||||
	cf->private = filters_copy;
 | 
			
		||||
 | 
			
		||||
	return cf;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -32,8 +41,12 @@ static int _init_hash(struct pfilter *pf)
 | 
			
		||||
	if (pf->devices)
 | 
			
		||||
		hash_destroy(pf->devices);
 | 
			
		||||
 | 
			
		||||
	pf->devices = hash_create(128);
 | 
			
		||||
	return pf->devices ? 1 : 0;
 | 
			
		||||
	if (!(pf->devices = hash_create(128))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int persistent_filter_wipe(struct dev_filter *f)
 | 
			
		||||
@@ -47,13 +60,13 @@ int persistent_filter_wipe(struct dev_filter *f)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _read_array(struct pfilter *pf, struct config_tree *cf,
 | 
			
		||||
static int _read_array(struct pfilter *pf, struct config_tree *cft,
 | 
			
		||||
		       const char *path, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *cn;
 | 
			
		||||
	struct config_value *cv;
 | 
			
		||||
 | 
			
		||||
	if (!(cn = find_config_node(cf->root, path, '/'))) {
 | 
			
		||||
	if (!(cn = find_config_node(cft->root, path))) {
 | 
			
		||||
		log_very_verbose("Couldn't find %s array in '%s'",
 | 
			
		||||
				 path, pf->file);
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -84,22 +97,22 @@ int persistent_filter_load(struct dev_filter *f)
 | 
			
		||||
	struct pfilter *pf = (struct pfilter *) f->private;
 | 
			
		||||
 | 
			
		||||
	int r = 0;
 | 
			
		||||
	struct config_tree *cf;
 | 
			
		||||
	struct config_tree *cft;
 | 
			
		||||
 | 
			
		||||
	if (!(cf = create_config_tree())) {
 | 
			
		||||
	if (!(cft = create_config_tree())) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!read_config_file(cf, pf->file)) {
 | 
			
		||||
	if (!read_config_file(cft, pf->file)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_read_array(pf, cf, "persistent_filter_cache/valid_devices",
 | 
			
		||||
	_read_array(pf, cft, "persistent_filter_cache/valid_devices",
 | 
			
		||||
		    PF_GOOD_DEVICE);
 | 
			
		||||
	/* We don't gain anything by holding invalid devices */
 | 
			
		||||
	/* _read_array(pf, cf, "persistent_filter_cache/invalid_devices",
 | 
			
		||||
	/* _read_array(pf, cft, "persistent_filter_cache/invalid_devices",
 | 
			
		||||
	   PF_BAD_DEVICE); */
 | 
			
		||||
 | 
			
		||||
	/* Did we find anything? */
 | 
			
		||||
@@ -109,8 +122,10 @@ int persistent_filter_load(struct dev_filter *f)
 | 
			
		||||
		r = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_very_verbose("Loaded persistent filter cache from %s", pf->file);
 | 
			
		||||
 | 
			
		||||
      out:
 | 
			
		||||
	destroy_config_tree(cf);
 | 
			
		||||
	destroy_config_tree(cft);
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -199,7 +214,11 @@ static int _lookup_p(struct dev_filter *f, struct device *dev)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return l == PF_GOOD_DEVICE;
 | 
			
		||||
	if (l == PF_BAD_DEVICE) {
 | 
			
		||||
		log_debug("%s: Skipping (cached)", dev_name(dev));
 | 
			
		||||
		return 0;
 | 
			
		||||
	} else
 | 
			
		||||
		return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _destroy(struct dev_filter *f)
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -19,7 +28,7 @@ struct rfilter {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int _extract_pattern(struct pool *mem, const char *pat,
 | 
			
		||||
			    char **regex, bitset_t accept, int index)
 | 
			
		||||
			    char **regex, bitset_t accept, int ix)
 | 
			
		||||
{
 | 
			
		||||
	char sep, *r, *ptr;
 | 
			
		||||
 | 
			
		||||
@@ -28,11 +37,11 @@ static int _extract_pattern(struct pool *mem, const char *pat,
 | 
			
		||||
	 */
 | 
			
		||||
	switch (*pat) {
 | 
			
		||||
	case 'a':
 | 
			
		||||
		bit_set(accept, index);
 | 
			
		||||
		bit_set(accept, ix);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case 'r':
 | 
			
		||||
		bit_clear(accept, index);
 | 
			
		||||
		bit_clear(accept, ix);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
@@ -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,12 +84,12 @@ 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';
 | 
			
		||||
 | 
			
		||||
	regex[index] = r;
 | 
			
		||||
	regex[ix] = r;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -89,7 +98,8 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
 | 
			
		||||
	struct pool *scratch;
 | 
			
		||||
	struct config_value *v;
 | 
			
		||||
	char **regex;
 | 
			
		||||
	int count = 0, i, r = 0;
 | 
			
		||||
	unsigned count = 0;
 | 
			
		||||
	int i, r = 0;
 | 
			
		||||
 | 
			
		||||
	if (!(scratch = pool_create(1024))) {
 | 
			
		||||
		stack;
 | 
			
		||||
@@ -161,6 +171,8 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
 | 
			
		||||
			if (bit(rf->accept, m)) {
 | 
			
		||||
 | 
			
		||||
				if (!first) {
 | 
			
		||||
					log_debug("%s: New preferred name",
 | 
			
		||||
						  sl->str);
 | 
			
		||||
					list_del(&sl->list);
 | 
			
		||||
					list_add_h(&dev->aliases, &sl->list);
 | 
			
		||||
				}
 | 
			
		||||
 
 | 
			
		||||
@@ -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,46 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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"
 | 
			
		||||
#include "dev-cache.h"
 | 
			
		||||
#include "filter.h"
 | 
			
		||||
#include "lvm-string.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <linux/kdev_t.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
#define NUMBER_OF_MAJORS 256
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	char *name;
 | 
			
		||||
	int max_partitions;
 | 
			
		||||
	const char *name;
 | 
			
		||||
	const int max_partitions;
 | 
			
		||||
} device_info_t;
 | 
			
		||||
 | 
			
		||||
static int _md_major = -1;
 | 
			
		||||
 | 
			
		||||
/* FIXME Move list into config file */
 | 
			
		||||
static device_info_t device_info[] = {
 | 
			
		||||
int md_major(void)
 | 
			
		||||
{
 | 
			
		||||
	return _md_major;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This list can be supplemented with devices/types in the config file */
 | 
			
		||||
static const device_info_t device_info[] = {
 | 
			
		||||
	{"ide", 16},		/* IDE disk */
 | 
			
		||||
	{"sd", 16},		/* SCSI disk */
 | 
			
		||||
	{"md", 16},		/* Multiple Disk driver (SoftRAID) */
 | 
			
		||||
@@ -52,24 +52,28 @@ static device_info_t device_info[] = {
 | 
			
		||||
	{"cciss", 16},		/* Compaq CCISS array */
 | 
			
		||||
	{"ubd", 16},		/* User-mode virtual block device */
 | 
			
		||||
	{"ataraid", 16},	/* ATA Raid */
 | 
			
		||||
	{"drbd", 16},		/* Distributed Replicated Block Device */
 | 
			
		||||
	{"power2", 16},		/* EMC Powerpath */
 | 
			
		||||
	{NULL, 0}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int *scan_proc_dev(const char *proc);
 | 
			
		||||
 | 
			
		||||
static int passes_lvm_type_device_filter(struct dev_filter *f,
 | 
			
		||||
					 struct device *dev)
 | 
			
		||||
static int _passes_lvm_type_device_filter(struct dev_filter *f,
 | 
			
		||||
					  struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	int fd;
 | 
			
		||||
	const char *name = dev_name(dev);
 | 
			
		||||
 | 
			
		||||
	/* Is this a recognised device type? */
 | 
			
		||||
	if (!(((int *) f->private)[MAJOR(dev->dev)]))
 | 
			
		||||
	if (!(((int *) f->private)[MAJOR(dev->dev)])) {
 | 
			
		||||
		log_debug("%s: Skipping: Unrecognised LVM device type %"
 | 
			
		||||
			  PRIu64, name, (uint64_t) MAJOR(dev->dev));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check it's accessible */
 | 
			
		||||
	if ((fd = open(name, O_RDONLY)) < 0) {
 | 
			
		||||
		log_debug("Unable to open %s: %s", name, strerror(errno));
 | 
			
		||||
		log_debug("%s: Skipping: open failed: %s", name,
 | 
			
		||||
			  strerror(errno));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -78,48 +82,18 @@ static int passes_lvm_type_device_filter(struct dev_filter *f,
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct dev_filter *lvm_type_filter_create(const char *proc)
 | 
			
		||||
{
 | 
			
		||||
	struct dev_filter *f;
 | 
			
		||||
 | 
			
		||||
	if (!(f = dbg_malloc(sizeof(struct dev_filter)))) {
 | 
			
		||||
		log_error("LVM type filter allocation failed");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	f->passes_filter = passes_lvm_type_device_filter;
 | 
			
		||||
	f->destroy = lvm_type_filter_destroy;
 | 
			
		||||
 | 
			
		||||
	if (!(f->private = scan_proc_dev(proc)))
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int md_major(void)
 | 
			
		||||
{
 | 
			
		||||
	return _md_major;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lvm_type_filter_destroy(struct dev_filter *f)
 | 
			
		||||
{
 | 
			
		||||
	dbg_free(f->private);
 | 
			
		||||
	dbg_free(f);
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int *scan_proc_dev(const char *proc)
 | 
			
		||||
static int *_scan_proc_dev(const char *proc, struct config_node *cn)
 | 
			
		||||
{
 | 
			
		||||
	char line[80];
 | 
			
		||||
	char proc_devices[PATH_MAX];
 | 
			
		||||
	FILE *pd = NULL;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	int i, j = 0;
 | 
			
		||||
	int line_maj = 0;
 | 
			
		||||
	int blocksection = 0;
 | 
			
		||||
	int dev_len = 0;
 | 
			
		||||
 | 
			
		||||
	size_t dev_len = 0;
 | 
			
		||||
	struct config_value *cv;
 | 
			
		||||
	int *max_partitions_by_major;
 | 
			
		||||
	char *name;
 | 
			
		||||
 | 
			
		||||
	if (!(max_partitions_by_major =
 | 
			
		||||
	      dbg_malloc(sizeof(int) * NUMBER_OF_MAJORS))) {
 | 
			
		||||
@@ -127,6 +101,14 @@ static int *scan_proc_dev(const char *proc)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!*proc) {
 | 
			
		||||
		log_verbose("No proc filesystem found: using all block device "
 | 
			
		||||
			    "types");
 | 
			
		||||
		for (i = 0; i < NUMBER_OF_MAJORS; i++)
 | 
			
		||||
			max_partitions_by_major[i] = 1;
 | 
			
		||||
		return max_partitions_by_major;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lvm_snprintf(proc_devices, sizeof(proc_devices),
 | 
			
		||||
			 "%s/devices", proc) < 0) {
 | 
			
		||||
		log_error("Failed to create /proc/devices string");
 | 
			
		||||
@@ -170,12 +152,44 @@ static int *scan_proc_dev(const char *proc)
 | 
			
		||||
		for (j = 0; device_info[j].name != NULL; j++) {
 | 
			
		||||
 | 
			
		||||
			dev_len = strlen(device_info[j].name);
 | 
			
		||||
			if (dev_len <= strlen(line + i)
 | 
			
		||||
			    && !strncmp(device_info[j].name, line + i, dev_len)
 | 
			
		||||
			    && (line_maj < NUMBER_OF_MAJORS)) {
 | 
			
		||||
			if (dev_len <= strlen(line + i) &&
 | 
			
		||||
			    !strncmp(device_info[j].name, line + i, dev_len) &&
 | 
			
		||||
			    (line_maj < NUMBER_OF_MAJORS)) {
 | 
			
		||||
				max_partitions_by_major[line_maj] =
 | 
			
		||||
				    device_info[j].max_partitions;
 | 
			
		||||
				ret++;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (max_partitions_by_major[line_maj] || !cn)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* Check devices/types for local variations */
 | 
			
		||||
		for (cv = cn->v; cv; cv = cv->next) {
 | 
			
		||||
			if (cv->type != CFG_STRING) {
 | 
			
		||||
				log_error("Expecting string in devices/types "
 | 
			
		||||
					  "in config file");
 | 
			
		||||
				return NULL;
 | 
			
		||||
			}
 | 
			
		||||
			dev_len = strlen(cv->v.str);
 | 
			
		||||
			name = cv->v.str;
 | 
			
		||||
			cv = cv->next;
 | 
			
		||||
			if (!cv || cv->type != CFG_INT) {
 | 
			
		||||
				log_error("Max partition count missing for %s "
 | 
			
		||||
					  "in devices/types in config file",
 | 
			
		||||
					  name);
 | 
			
		||||
				return NULL;
 | 
			
		||||
			}
 | 
			
		||||
			if (!cv->v.i) {
 | 
			
		||||
				log_error("Zero partition count invalid for "
 | 
			
		||||
					  "%s in devices/types in config file",
 | 
			
		||||
					  name);
 | 
			
		||||
				return NULL;
 | 
			
		||||
			}
 | 
			
		||||
			if (dev_len <= strlen(line + i) &&
 | 
			
		||||
			    !strncmp(name, line + i, dev_len) &&
 | 
			
		||||
			    (line_maj < NUMBER_OF_MAJORS)) {
 | 
			
		||||
				max_partitions_by_major[line_maj] = cv->v.i;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -183,3 +197,31 @@ static int *scan_proc_dev(const char *proc)
 | 
			
		||||
	fclose(pd);
 | 
			
		||||
	return max_partitions_by_major;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct dev_filter *lvm_type_filter_create(const char *proc,
 | 
			
		||||
					  struct config_node *cn)
 | 
			
		||||
{
 | 
			
		||||
	struct dev_filter *f;
 | 
			
		||||
 | 
			
		||||
	if (!(f = dbg_malloc(sizeof(struct dev_filter)))) {
 | 
			
		||||
		log_error("LVM type filter allocation failed");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	f->passes_filter = _passes_lvm_type_device_filter;
 | 
			
		||||
	f->destroy = lvm_type_filter_destroy;
 | 
			
		||||
 | 
			
		||||
	if (!(f->private = _scan_proc_dev(proc, cn))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lvm_type_filter_destroy(struct dev_filter *f)
 | 
			
		||||
{
 | 
			
		||||
	dbg_free(f->private);
 | 
			
		||||
	dbg_free(f);
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,38 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
#define _LVM_FILTER_H
 | 
			
		||||
 | 
			
		||||
struct dev_filter *lvm_type_filter_create(const char *proc);
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#ifdef linux
 | 
			
		||||
#  include <linux/kdev_t.h>
 | 
			
		||||
#else
 | 
			
		||||
#  define MAJOR(x) major((x))
 | 
			
		||||
#  define MINOR(x) minor((x))
 | 
			
		||||
#  define MKDEV(x,y) makedev((x),(y))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct dev_filter *lvm_type_filter_create(const char *proc,
 | 
			
		||||
					  struct config_node *cn);
 | 
			
		||||
 | 
			
		||||
void lvm_type_filter_destroy(struct dev_filter *f);
 | 
			
		||||
 | 
			
		||||
int md_major(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
{ 
 | 
			
		||||
	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: libformat1.so
 | 
			
		||||
	$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \
 | 
			
		||||
install: liblvm2format1.so
 | 
			
		||||
	$(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"
 | 
			
		||||
@@ -9,11 +18,9 @@
 | 
			
		||||
#include "pool.h"
 | 
			
		||||
#include "xlate.h"
 | 
			
		||||
#include "filter.h"
 | 
			
		||||
#include "cache.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <linux/kdev_t.h>
 | 
			
		||||
 | 
			
		||||
#define fail do {stack; return 0;} while(0)
 | 
			
		||||
#define xx16(v) disk->v = xlate16(disk->v)
 | 
			
		||||
@@ -94,7 +101,7 @@ static void _xlate_vgd(struct vg_disk *disk)
 | 
			
		||||
	xx32(pvg_total);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _xlate_extents(struct pe_disk *extents, int count)
 | 
			
		||||
static void _xlate_extents(struct pe_disk *extents, uint32_t count)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
@@ -132,7 +139,7 @@ static int _munge_formats(struct pv_disk *pvd)
 | 
			
		||||
 | 
			
		||||
static int _read_pvd(struct device *dev, struct pv_disk *pvd)
 | 
			
		||||
{
 | 
			
		||||
	if (dev_read(dev, 0, sizeof(*pvd), pvd) != sizeof(*pvd)) {
 | 
			
		||||
	if (!dev_read(dev, UINT64_C(0), sizeof(*pvd), pvd)) {
 | 
			
		||||
		log_very_verbose("Failed to read PV data from %s",
 | 
			
		||||
				 dev_name(dev));
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -152,12 +159,16 @@ static int _read_pvd(struct device *dev, struct pv_disk *pvd)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* If UUID is missing, create one */
 | 
			
		||||
	if (pvd->pv_uuid[0] == '\0')
 | 
			
		||||
		uuid_from_num(pvd->pv_uuid, pvd->pv_number);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _read_lvd(struct device *dev, ulong pos, struct lv_disk *disk)
 | 
			
		||||
static int _read_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
 | 
			
		||||
{
 | 
			
		||||
	if (dev_read(dev, pos, sizeof(*disk), disk) != sizeof(*disk))
 | 
			
		||||
	if (!dev_read(dev, pos, sizeof(*disk), disk))
 | 
			
		||||
		fail;
 | 
			
		||||
 | 
			
		||||
	_xlate_lvd(disk);
 | 
			
		||||
@@ -168,12 +179,16 @@ static int _read_lvd(struct device *dev, ulong pos, struct lv_disk *disk)
 | 
			
		||||
static int _read_vgd(struct disk_list *data)
 | 
			
		||||
{
 | 
			
		||||
	struct vg_disk *vgd = &data->vgd;
 | 
			
		||||
	ulong pos = data->pvd.vg_on_disk.base;
 | 
			
		||||
	if (dev_read(data->dev, pos, sizeof(*vgd), vgd) != sizeof(*vgd))
 | 
			
		||||
	uint64_t pos = data->pvd.vg_on_disk.base;
 | 
			
		||||
	if (!dev_read(data->dev, pos, sizeof(*vgd), vgd))
 | 
			
		||||
		fail;
 | 
			
		||||
 | 
			
		||||
	_xlate_vgd(vgd);
 | 
			
		||||
 | 
			
		||||
	/* If UUID is missing, create one */
 | 
			
		||||
	if (vgd->vg_uuid[0] == '\0')
 | 
			
		||||
		uuid_from_num(vgd->vg_uuid, vgd->vg_number);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -182,12 +197,11 @@ static int _read_uuids(struct disk_list *data)
 | 
			
		||||
	int num_read = 0;
 | 
			
		||||
	struct uuid_list *ul;
 | 
			
		||||
	char buffer[NAME_LEN];
 | 
			
		||||
	ulong pos = data->pvd.pv_uuidlist_on_disk.base;
 | 
			
		||||
	ulong end = pos + data->pvd.pv_uuidlist_on_disk.size;
 | 
			
		||||
	uint64_t pos = data->pvd.pv_uuidlist_on_disk.base;
 | 
			
		||||
	uint64_t end = pos + data->pvd.pv_uuidlist_on_disk.size;
 | 
			
		||||
 | 
			
		||||
	while (pos < end && num_read < data->vgd.pv_cur) {
 | 
			
		||||
		if (dev_read(data->dev, pos, sizeof(buffer), buffer) !=
 | 
			
		||||
		    sizeof(buffer))
 | 
			
		||||
		if (!dev_read(data->dev, pos, sizeof(buffer), buffer))
 | 
			
		||||
			fail;
 | 
			
		||||
 | 
			
		||||
		if (!(ul = pool_alloc(data->mem, sizeof(*ul))))
 | 
			
		||||
@@ -212,8 +226,8 @@ static inline int _check_lvd(struct lv_disk *lvd)
 | 
			
		||||
 | 
			
		||||
static int _read_lvs(struct disk_list *data)
 | 
			
		||||
{
 | 
			
		||||
	int i, read = 0;
 | 
			
		||||
	ulong pos;
 | 
			
		||||
	unsigned int i, read = 0;
 | 
			
		||||
	uint64_t pos;
 | 
			
		||||
	struct lvd_list *ll;
 | 
			
		||||
	struct vg_disk *vgd = &data->vgd;
 | 
			
		||||
 | 
			
		||||
@@ -241,12 +255,12 @@ static int _read_extents(struct disk_list *data)
 | 
			
		||||
{
 | 
			
		||||
	size_t len = sizeof(struct pe_disk) * data->pvd.pe_total;
 | 
			
		||||
	struct pe_disk *extents = pool_alloc(data->mem, len);
 | 
			
		||||
	ulong pos = data->pvd.pe_on_disk.base;
 | 
			
		||||
	uint64_t pos = data->pvd.pe_on_disk.base;
 | 
			
		||||
 | 
			
		||||
	if (!extents)
 | 
			
		||||
		fail;
 | 
			
		||||
 | 
			
		||||
	if (dev_read(data->dev, pos, len, extents) != len)
 | 
			
		||||
	if (!dev_read(data->dev, pos, len, extents))
 | 
			
		||||
		fail;
 | 
			
		||||
 | 
			
		||||
	_xlate_extents(extents, data->pvd.pe_total);
 | 
			
		||||
@@ -258,29 +272,30 @@ static int _read_extents(struct disk_list *data)
 | 
			
		||||
/* 
 | 
			
		||||
 * If exported, remove "PV_EXP" from end of VG name 
 | 
			
		||||
 */
 | 
			
		||||
static void _munge_exported_vg(struct disk_list *data)
 | 
			
		||||
void munge_exported_vg(struct pv_disk *pvd)
 | 
			
		||||
{
 | 
			
		||||
	int l, s;
 | 
			
		||||
	int l;
 | 
			
		||||
	size_t s;
 | 
			
		||||
 | 
			
		||||
	/* Return if PV not in a VG or VG not exported */
 | 
			
		||||
	if ((!*data->pvd.vg_name) || !(data->vgd.vg_status & VG_EXPORTED))
 | 
			
		||||
	/* Return if PV not in a VG */
 | 
			
		||||
	if ((!*pvd->vg_name))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	l = strlen(data->pvd.vg_name);
 | 
			
		||||
	l = strlen(pvd->vg_name);
 | 
			
		||||
	s = sizeof(EXPORTED_TAG);
 | 
			
		||||
	if (!strncmp(data->pvd.vg_name + l - s + 1, EXPORTED_TAG, s))
 | 
			
		||||
		data->pvd.vg_name[l - s + 1] = '\0';
 | 
			
		||||
 | 
			
		||||
	data->pvd.pv_status |= VG_EXPORTED;
 | 
			
		||||
	if (!strncmp(pvd->vg_name + l - s + 1, EXPORTED_TAG, s)) {
 | 
			
		||||
		pvd->vg_name[l - s + 1] = '\0'; 
 | 
			
		||||
		pvd->pv_status |= VG_EXPORTED;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct disk_list *__read_disk(struct format_type *fmt,
 | 
			
		||||
static struct disk_list *__read_disk(const struct format_type *fmt,
 | 
			
		||||
				     struct device *dev, struct pool *mem,
 | 
			
		||||
				     const char *vg_name)
 | 
			
		||||
{
 | 
			
		||||
	struct disk_list *dl = pool_alloc(mem, sizeof(*dl));
 | 
			
		||||
	const char *name = dev_name(dev);
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
 | 
			
		||||
	if (!dl) {
 | 
			
		||||
		stack;
 | 
			
		||||
@@ -297,8 +312,11 @@ static struct disk_list *__read_disk(struct format_type *fmt,
 | 
			
		||||
		goto bad;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(info = cache_add(fmt->labeller, dl->pvd.pv_uuid, dev,
 | 
			
		||||
			       dl->pvd.vg_name, NULL)))
 | 
			
		||||
	/* If VG is exported, set VG name back to the real name */
 | 
			
		||||
	munge_exported_vg(&dl->pvd);
 | 
			
		||||
 | 
			
		||||
	if (!(info = lvmcache_add(fmt->labeller, dl->pvd.pv_uuid, dev,
 | 
			
		||||
				  dl->pvd.vg_name, NULL)))
 | 
			
		||||
		stack;
 | 
			
		||||
	else {
 | 
			
		||||
		info->device_size = xlate32(dl->pvd.pv_size) << SECTOR_SHIFT;
 | 
			
		||||
@@ -323,9 +341,6 @@ static struct disk_list *__read_disk(struct format_type *fmt,
 | 
			
		||||
		goto bad;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* If VG is exported, set VG name back to the real name */
 | 
			
		||||
	_munge_exported_vg(dl);
 | 
			
		||||
 | 
			
		||||
	/* Update VG cache with what we found */
 | 
			
		||||
	/* vgcache_add(dl->pvd.vg_name, dl->vgd.vg_uuid, dev, fmt); */
 | 
			
		||||
 | 
			
		||||
@@ -361,12 +376,12 @@ static struct disk_list *__read_disk(struct format_type *fmt,
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct disk_list *read_disk(struct format_type *fmt, struct device *dev,
 | 
			
		||||
struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
 | 
			
		||||
			    struct pool *mem, const char *vg_name)
 | 
			
		||||
{
 | 
			
		||||
	struct disk_list *r;
 | 
			
		||||
 | 
			
		||||
	if (!dev_open(dev, O_RDONLY)) {
 | 
			
		||||
	if (!dev_open(dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
@@ -408,7 +423,7 @@ static void _add_pv_to_list(struct list *head, struct disk_list *data)
 | 
			
		||||
 * We keep track of the first object allocated form the pool
 | 
			
		||||
 * so we can free off all the memory if something goes wrong.
 | 
			
		||||
 */
 | 
			
		||||
int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
 | 
			
		||||
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
 | 
			
		||||
		   struct dev_filter *filter, struct pool *mem,
 | 
			
		||||
		   struct list *head)
 | 
			
		||||
{
 | 
			
		||||
@@ -416,13 +431,13 @@ int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
 | 
			
		||||
	struct device *dev;
 | 
			
		||||
	struct disk_list *data = NULL;
 | 
			
		||||
	struct list *vgih;
 | 
			
		||||
	struct cache_vginfo *vginfo;
 | 
			
		||||
	struct lvmcache_vginfo *vginfo;
 | 
			
		||||
 | 
			
		||||
	/* Fast path if we already saw this VG and cached the list of PVs */
 | 
			
		||||
	if (vg_name && (vginfo = vginfo_from_vgname(vg_name)) &&
 | 
			
		||||
	    vginfo->infos.n) {
 | 
			
		||||
		list_iterate(vgih, &vginfo->infos) {
 | 
			
		||||
			dev = list_item(vgih, struct cache_info)->dev;
 | 
			
		||||
			dev = list_item(vgih, struct lvmcache_info)->dev;
 | 
			
		||||
			if (dev && !(data = read_disk(fmt, dev, mem, vg_name)))
 | 
			
		||||
				break;
 | 
			
		||||
			_add_pv_to_list(head, data);
 | 
			
		||||
@@ -461,10 +476,10 @@ int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
 | 
			
		||||
static int _write_vgd(struct disk_list *data)
 | 
			
		||||
{
 | 
			
		||||
	struct vg_disk *vgd = &data->vgd;
 | 
			
		||||
	ulong pos = data->pvd.vg_on_disk.base;
 | 
			
		||||
	uint64_t pos = data->pvd.vg_on_disk.base;
 | 
			
		||||
 | 
			
		||||
	_xlate_vgd(vgd);
 | 
			
		||||
	if (dev_write(data->dev, pos, sizeof(*vgd), vgd) != sizeof(*vgd))
 | 
			
		||||
	if (!dev_write(data->dev, pos, sizeof(*vgd), vgd))
 | 
			
		||||
		fail;
 | 
			
		||||
 | 
			
		||||
	_xlate_vgd(vgd);
 | 
			
		||||
@@ -476,8 +491,8 @@ static int _write_uuids(struct disk_list *data)
 | 
			
		||||
{
 | 
			
		||||
	struct uuid_list *ul;
 | 
			
		||||
	struct list *uh;
 | 
			
		||||
	ulong pos = data->pvd.pv_uuidlist_on_disk.base;
 | 
			
		||||
	ulong end = pos + data->pvd.pv_uuidlist_on_disk.size;
 | 
			
		||||
	uint64_t pos = data->pvd.pv_uuidlist_on_disk.base;
 | 
			
		||||
	uint64_t end = pos + data->pvd.pv_uuidlist_on_disk.size;
 | 
			
		||||
 | 
			
		||||
	list_iterate(uh, &data->uuids) {
 | 
			
		||||
		if (pos >= end) {
 | 
			
		||||
@@ -487,7 +502,7 @@ static int _write_uuids(struct disk_list *data)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ul = list_item(uh, struct uuid_list);
 | 
			
		||||
		if (dev_write(data->dev, pos, NAME_LEN, ul->uuid) != NAME_LEN)
 | 
			
		||||
		if (!dev_write(data->dev, pos, NAME_LEN, ul->uuid))
 | 
			
		||||
			fail;
 | 
			
		||||
 | 
			
		||||
		pos += NAME_LEN;
 | 
			
		||||
@@ -496,10 +511,10 @@ static int _write_uuids(struct disk_list *data)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _write_lvd(struct device *dev, ulong pos, struct lv_disk *disk)
 | 
			
		||||
static int _write_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
 | 
			
		||||
{
 | 
			
		||||
	_xlate_lvd(disk);
 | 
			
		||||
	if (dev_write(dev, pos, sizeof(*disk), disk) != sizeof(*disk))
 | 
			
		||||
	if (!dev_write(dev, pos, sizeof(*disk), disk))
 | 
			
		||||
		fail;
 | 
			
		||||
 | 
			
		||||
	_xlate_lvd(disk);
 | 
			
		||||
@@ -510,7 +525,7 @@ static int _write_lvd(struct device *dev, ulong pos, struct lv_disk *disk)
 | 
			
		||||
static int _write_lvs(struct disk_list *data)
 | 
			
		||||
{
 | 
			
		||||
	struct list *lvh;
 | 
			
		||||
	ulong pos, offset;
 | 
			
		||||
	uint64_t pos, offset;
 | 
			
		||||
 | 
			
		||||
	pos = data->pvd.lv_on_disk.base;
 | 
			
		||||
 | 
			
		||||
@@ -540,10 +555,10 @@ static int _write_extents(struct disk_list *data)
 | 
			
		||||
{
 | 
			
		||||
	size_t len = sizeof(struct pe_disk) * data->pvd.pe_total;
 | 
			
		||||
	struct pe_disk *extents = data->extents;
 | 
			
		||||
	ulong pos = data->pvd.pe_on_disk.base;
 | 
			
		||||
	uint64_t pos = data->pvd.pe_on_disk.base;
 | 
			
		||||
 | 
			
		||||
	_xlate_extents(extents, data->pvd.pe_total);
 | 
			
		||||
	if (dev_write(data->dev, pos, len, extents) != len)
 | 
			
		||||
	if (!dev_write(data->dev, pos, len, extents))
 | 
			
		||||
		fail;
 | 
			
		||||
 | 
			
		||||
	_xlate_extents(extents, data->pvd.pe_total);
 | 
			
		||||
@@ -554,8 +569,8 @@ static int _write_extents(struct disk_list *data)
 | 
			
		||||
static int _write_pvd(struct disk_list *data)
 | 
			
		||||
{
 | 
			
		||||
	char *buf;
 | 
			
		||||
	ulong pos = data->pvd.pv_on_disk.base;
 | 
			
		||||
	ulong size = data->pvd.pv_on_disk.size;
 | 
			
		||||
	uint64_t pos = data->pvd.pv_on_disk.base;
 | 
			
		||||
	size_t size = data->pvd.pv_on_disk.size;
 | 
			
		||||
 | 
			
		||||
	if (size < sizeof(struct pv_disk)) {
 | 
			
		||||
		log_error("Invalid PV structure size.");
 | 
			
		||||
@@ -575,7 +590,7 @@ static int _write_pvd(struct disk_list *data)
 | 
			
		||||
	memcpy(buf, &data->pvd, sizeof(struct pv_disk));
 | 
			
		||||
 | 
			
		||||
	_xlate_pvd((struct pv_disk *) buf);
 | 
			
		||||
	if (dev_write(data->dev, pos, size, buf) != size) {
 | 
			
		||||
	if (!dev_write(data->dev, pos, size, buf)) {
 | 
			
		||||
		dbg_free(buf);
 | 
			
		||||
		fail;
 | 
			
		||||
	}
 | 
			
		||||
@@ -587,7 +602,8 @@ static int _write_pvd(struct disk_list *data)
 | 
			
		||||
/*
 | 
			
		||||
 * assumes the device has been opened.
 | 
			
		||||
 */
 | 
			
		||||
static int __write_all_pvd(struct format_type *fmt, struct disk_list *data)
 | 
			
		||||
static int __write_all_pvd(const struct format_type *fmt,
 | 
			
		||||
			   struct disk_list *data)
 | 
			
		||||
{
 | 
			
		||||
	const char *pv_name = dev_name(data->dev);
 | 
			
		||||
 | 
			
		||||
@@ -636,11 +652,11 @@ static int __write_all_pvd(struct format_type *fmt, struct disk_list *data)
 | 
			
		||||
/*
 | 
			
		||||
 * opens the device and hands to the above fn.
 | 
			
		||||
 */
 | 
			
		||||
static int _write_all_pvd(struct format_type *fmt, struct disk_list *data)
 | 
			
		||||
static int _write_all_pvd(const struct format_type *fmt, struct disk_list *data)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	if (!dev_open(data->dev, O_WRONLY)) {
 | 
			
		||||
	if (!dev_open(data->dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -658,7 +674,7 @@ static int _write_all_pvd(struct format_type *fmt, struct disk_list *data)
 | 
			
		||||
 * little sanity checking, so make sure correct
 | 
			
		||||
 * data is passed to here.
 | 
			
		||||
 */
 | 
			
		||||
int write_disks(struct format_type *fmt, struct list *pvs)
 | 
			
		||||
int write_disks(const struct format_type *fmt, struct list *pvs)
 | 
			
		||||
{
 | 
			
		||||
	struct list *pvh;
 | 
			
		||||
	struct disk_list *dl;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the GPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef DISK_REP_FORMAT1_H
 | 
			
		||||
@@ -10,11 +19,14 @@
 | 
			
		||||
#include "lvm-types.h"
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
#include "pool.h"
 | 
			
		||||
#include "toolcontext.h"
 | 
			
		||||
 | 
			
		||||
#define MAX_PV 256
 | 
			
		||||
#define MAX_LV 256
 | 
			
		||||
#define MAX_VG 99
 | 
			
		||||
 | 
			
		||||
#define LVM_BLK_MAJOR 58
 | 
			
		||||
 | 
			
		||||
#define MAX_PV_SIZE	((uint32_t) -1)	/* 2TB in sectors - 1 */
 | 
			
		||||
#define MIN_PE_SIZE	(8192L >> SECTOR_SHIFT)	/* 8 KB in sectors */
 | 
			
		||||
#define MAX_PE_SIZE	(16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L)
 | 
			
		||||
@@ -171,21 +183,21 @@ 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
 | 
			
		||||
 * disk_lists.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct disk_list *read_disk(struct format_type *fmt, struct device *dev,
 | 
			
		||||
struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
 | 
			
		||||
			    struct pool *mem, const char *vg_name);
 | 
			
		||||
 | 
			
		||||
int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
 | 
			
		||||
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
 | 
			
		||||
		   struct dev_filter *filter,
 | 
			
		||||
		   struct pool *mem, struct list *results);
 | 
			
		||||
 | 
			
		||||
int write_disks(struct format_type *fmt, struct list *pvds);
 | 
			
		||||
int write_disks(const struct format_type *fmt, struct list *pvds);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Functions to translate to between disk and in
 | 
			
		||||
@@ -194,7 +206,8 @@ int write_disks(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,10 +218,10 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd);
 | 
			
		||||
 | 
			
		||||
int import_extents(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
		   struct list *pvds);
 | 
			
		||||
int export_extents(struct disk_list *dl, int lv_num,
 | 
			
		||||
int export_extents(struct disk_list *dl, uint32_t lv_num,
 | 
			
		||||
		   struct logical_volume *lv, struct physical_volume *pv);
 | 
			
		||||
 | 
			
		||||
int import_pvs(struct format_type *fmt, struct pool *mem,
 | 
			
		||||
int import_pvs(const struct format_type *fmt, struct pool *mem,
 | 
			
		||||
	       struct volume_group *vg,
 | 
			
		||||
	       struct list *pvds, struct list *results, int *count);
 | 
			
		||||
 | 
			
		||||
@@ -224,6 +237,7 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg);
 | 
			
		||||
void export_numbers(struct list *pvds, struct volume_group *vg);
 | 
			
		||||
 | 
			
		||||
void export_pv_act(struct list *pvds);
 | 
			
		||||
void munge_exported_vg(struct pv_disk *pvd);
 | 
			
		||||
 | 
			
		||||
/* blech */
 | 
			
		||||
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
@@ -12,10 +21,12 @@
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "display.h"
 | 
			
		||||
#include "toolcontext.h"
 | 
			
		||||
#include "cache.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
#include "lvm1-label.h"
 | 
			
		||||
#include "format1.h"
 | 
			
		||||
 | 
			
		||||
#define FMT_LVM1_NAME "lvm1"
 | 
			
		||||
 | 
			
		||||
/* VG consistency checks */
 | 
			
		||||
static int _check_vgs(struct list *pvs, int *partial)
 | 
			
		||||
{
 | 
			
		||||
@@ -23,8 +34,9 @@ static int _check_vgs(struct list *pvs, int *partial)
 | 
			
		||||
	struct disk_list *dl = NULL;
 | 
			
		||||
	struct disk_list *first = NULL;
 | 
			
		||||
 | 
			
		||||
	int pv_count = 0;
 | 
			
		||||
	int exported = -1;
 | 
			
		||||
	uint32_t pv_count = 0;
 | 
			
		||||
	uint32_t exported = 0;
 | 
			
		||||
	int first_time = 1;
 | 
			
		||||
 | 
			
		||||
	*partial = 0;
 | 
			
		||||
 | 
			
		||||
@@ -36,8 +48,9 @@ static int _check_vgs(struct list *pvs, int *partial)
 | 
			
		||||
	list_iterate(pvh, pvs) {
 | 
			
		||||
		dl = list_item(pvh, struct disk_list);
 | 
			
		||||
 | 
			
		||||
		if (exported < 0) {
 | 
			
		||||
		if (first_time) {
 | 
			
		||||
			exported = dl->pvd.pv_status & VG_EXPORTED;
 | 
			
		||||
			first_time = 0;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -62,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;
 | 
			
		||||
@@ -73,9 +115,9 @@ static int _check_vgs(struct list *pvs, int *partial)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* On entry to fn, list known to be non-empty */
 | 
			
		||||
	if (pv_count != dl->vgd.pv_cur) {
 | 
			
		||||
	if (pv_count != first->vgd.pv_cur) {
 | 
			
		||||
		log_error("%d PV(s) found for VG %s: expected %d",
 | 
			
		||||
			  pv_count, dl->pvd.vg_name, dl->vgd.pv_cur);
 | 
			
		||||
			  pv_count, first->pvd.vg_name, first->vgd.pv_cur);
 | 
			
		||||
		if (!partial_mode())
 | 
			
		||||
			return 0;
 | 
			
		||||
		*partial = 1;
 | 
			
		||||
@@ -106,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;
 | 
			
		||||
@@ -168,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)
 | 
			
		||||
{
 | 
			
		||||
@@ -185,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)) {
 | 
			
		||||
@@ -209,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;
 | 
			
		||||
		}
 | 
			
		||||
@@ -246,13 +290,13 @@ static int _vg_write(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
			 fid->fmt->cmd->filter) &&
 | 
			
		||||
	     write_disks(fid->fmt, &pvds));
 | 
			
		||||
 | 
			
		||||
	cache_update_vg(vg);
 | 
			
		||||
	lvmcache_update_vg(vg);
 | 
			
		||||
	pool_destroy(mem);
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int _pv_read(struct format_type *fmt, const char *pv_name,
 | 
			
		||||
	     struct physical_volume *pv, struct list *mdas)
 | 
			
		||||
static int _pv_read(const struct format_type *fmt, const char *pv_name,
 | 
			
		||||
		    struct physical_volume *pv, struct list *mdas)
 | 
			
		||||
{
 | 
			
		||||
	struct pool *mem = pool_create(1024);
 | 
			
		||||
	struct disk_list *dl;
 | 
			
		||||
@@ -290,21 +334,19 @@ int _pv_read(struct format_type *fmt, const char *pv_name,
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _pv_setup(struct format_type *fmt,
 | 
			
		||||
static int _pv_setup(const struct format_type *fmt,
 | 
			
		||||
		     uint64_t pe_start, uint32_t extent_count,
 | 
			
		||||
		     uint32_t extent_size,
 | 
			
		||||
		     int pvmetadatacopies,
 | 
			
		||||
		     uint64_t pvmetadatasize, struct list *mdas,
 | 
			
		||||
		     struct physical_volume *pv, struct volume_group *vg)
 | 
			
		||||
{
 | 
			
		||||
	char *sz;
 | 
			
		||||
 | 
			
		||||
	if (pv->size > MAX_PV_SIZE)
 | 
			
		||||
		pv->size--;
 | 
			
		||||
	if (pv->size > MAX_PV_SIZE) {
 | 
			
		||||
		log_error("Physical volumes cannot be bigger than %s",
 | 
			
		||||
			  sz = display_size(MAX_PV_SIZE / 2, SIZE_SHORT));
 | 
			
		||||
		dbg_free(sz);
 | 
			
		||||
			  display_size(fmt->cmd, (uint64_t) MAX_PV_SIZE / 2,
 | 
			
		||||
				       SIZE_SHORT));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -315,14 +357,12 @@ static int _pv_setup(struct format_type *fmt,
 | 
			
		||||
	/*
 | 
			
		||||
	 * This works out pe_start and pe_count.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!calculate_extent_count(pv, extent_size, extent_count)) {
 | 
			
		||||
	if (!calculate_extent_count(pv, extent_size, extent_count, pe_start)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Retain existing extent locations exactly */
 | 
			
		||||
	/* FIXME Relax this so a non-overlapping existing pe_start can also 
 | 
			
		||||
	 * be used in place of the calculated one */
 | 
			
		||||
	if (((pe_start || extent_count) && (pe_start != pv->pe_start)) ||
 | 
			
		||||
	    (extent_count && (extent_count != pv->pe_count))) {
 | 
			
		||||
		log_error("Metadata would overwrite physical extents");
 | 
			
		||||
@@ -332,32 +372,12 @@ static int _pv_setup(struct format_type *fmt,
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _find_free_lvnum(struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
	int lvnum_used[MAX_LV];
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	struct list *lvh;
 | 
			
		||||
	struct lv_list *lvl;
 | 
			
		||||
 | 
			
		||||
	memset(&lvnum_used, 0, sizeof(lvnum_used));
 | 
			
		||||
 | 
			
		||||
	list_iterate(lvh, &lv->vg->lvs) {
 | 
			
		||||
		lvl = list_item(lvh, struct lv_list);
 | 
			
		||||
		lvnum_used[lvnum_from_lvid(&lvl->lv->lvid)] = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (lvnum_used[i])
 | 
			
		||||
		i++;
 | 
			
		||||
 | 
			
		||||
	return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
	uint64_t max_size = UINT_MAX;
 | 
			
		||||
 | 
			
		||||
	if (!*lv->lvid.s)
 | 
			
		||||
		lvid_from_lvnum(&lv->lvid, &lv->vg->id, _find_free_lvnum(lv));
 | 
			
		||||
		lvid_from_lvnum(&lv->lvid, &lv->vg->id, find_free_lvnum(lv));
 | 
			
		||||
 | 
			
		||||
	if (lv->le_count > MAX_LE_TOTAL) {
 | 
			
		||||
		log_error("logical volumes cannot contain more than "
 | 
			
		||||
@@ -365,26 +385,26 @@ static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if (lv->size > max_size) {
 | 
			
		||||
		char *dummy = display_size(max_size, SIZE_SHORT);
 | 
			
		||||
		log_error("logical volumes cannot be larger than %s", dummy);
 | 
			
		||||
		dbg_free(dummy);
 | 
			
		||||
		log_error("logical volumes cannot be larger than %s",
 | 
			
		||||
			  display_size(fid->fmt->cmd, max_size / 2,
 | 
			
		||||
				       SIZE_SHORT));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
 | 
			
		||||
static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
 | 
			
		||||
		     struct list *mdas, int64_t sector)
 | 
			
		||||
{
 | 
			
		||||
	struct pool *mem;
 | 
			
		||||
	struct disk_list *dl;
 | 
			
		||||
	struct list pvs;
 | 
			
		||||
	struct label *label;
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
 | 
			
		||||
	if (!(info = cache_add(fmt->labeller, (char *) &pv->id, pv->dev,
 | 
			
		||||
			       pv->vg_name, NULL))) {
 | 
			
		||||
	if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
 | 
			
		||||
				  pv->vg_name, NULL))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -412,7 +432,7 @@ static int _pv_write(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;
 | 
			
		||||
	}
 | 
			
		||||
@@ -437,32 +457,32 @@ static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int _vg_setup(struct format_instance *fid, struct volume_group *vg)
 | 
			
		||||
static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
 | 
			
		||||
{
 | 
			
		||||
	/* just check max_pv and max_lv */
 | 
			
		||||
	if (vg->max_lv >= MAX_LV)
 | 
			
		||||
	if (!vg->max_lv || vg->max_lv >= MAX_LV)
 | 
			
		||||
		vg->max_lv = MAX_LV - 1;
 | 
			
		||||
 | 
			
		||||
	if (vg->max_pv >= MAX_PV)
 | 
			
		||||
	if (!vg->max_pv || vg->max_pv >= MAX_PV)
 | 
			
		||||
		vg->max_pv = MAX_PV - 1;
 | 
			
		||||
 | 
			
		||||
	if (vg->extent_size > MAX_PE_SIZE || vg->extent_size < MIN_PE_SIZE) {
 | 
			
		||||
		char *dummy, *dummy2;
 | 
			
		||||
 | 
			
		||||
		log_error("Extent size must be between %s and %s",
 | 
			
		||||
			  (dummy = display_size(MIN_PE_SIZE / 2, SIZE_SHORT)),
 | 
			
		||||
			  (dummy2 = display_size(MAX_PE_SIZE / 2, SIZE_SHORT)));
 | 
			
		||||
			  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));
 | 
			
		||||
 | 
			
		||||
		dbg_free(dummy);
 | 
			
		||||
		dbg_free(dummy2);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (vg->extent_size % MIN_PE_SIZE) {
 | 
			
		||||
		char *dummy;
 | 
			
		||||
		log_error("Extent size must be multiple of %s",
 | 
			
		||||
			  (dummy = display_size(MIN_PE_SIZE / 2, SIZE_SHORT)));
 | 
			
		||||
		dbg_free(dummy);
 | 
			
		||||
			  display_size(fid->fmt->cmd,
 | 
			
		||||
				       (uint64_t) MIN_PE_SIZE / 2, SIZE_SHORT));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -480,8 +500,9 @@ static struct metadata_area_ops _metadata_format1_ops = {
 | 
			
		||||
	vg_write:_vg_write,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct format_instance *_create_instance(struct format_type *fmt,
 | 
			
		||||
					 const char *vgname, void *private)
 | 
			
		||||
static struct format_instance *_create_instance(const struct format_type *fmt,
 | 
			
		||||
						const char *vgname,
 | 
			
		||||
						void *private)
 | 
			
		||||
{
 | 
			
		||||
	struct format_instance *fid;
 | 
			
		||||
	struct metadata_area *mda;
 | 
			
		||||
@@ -508,14 +529,14 @@ struct format_instance *_create_instance(struct format_type *fmt,
 | 
			
		||||
	return fid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _destroy_instance(struct format_instance *fid)
 | 
			
		||||
static void _destroy_instance(struct format_instance *fid)
 | 
			
		||||
{
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _destroy(struct format_type *fmt)
 | 
			
		||||
static void _destroy(const struct format_type *fmt)
 | 
			
		||||
{
 | 
			
		||||
	dbg_free(fmt);
 | 
			
		||||
	dbg_free((void *) fmt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct format_handler _format1_ops = {
 | 
			
		||||
@@ -532,6 +553,7 @@ static struct format_handler _format1_ops = {
 | 
			
		||||
#ifdef LVM1_INTERNAL
 | 
			
		||||
struct format_type *init_lvm1_format(struct cmd_context *cmd)
 | 
			
		||||
#else				/* Shared */
 | 
			
		||||
struct format_type *init_format(struct cmd_context *cmd);
 | 
			
		||||
struct format_type *init_format(struct cmd_context *cmd)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
@@ -546,7 +568,7 @@ struct format_type *init_format(struct cmd_context *cmd)
 | 
			
		||||
	fmt->ops = &_format1_ops;
 | 
			
		||||
	fmt->name = FMT_LVM1_NAME;
 | 
			
		||||
	fmt->alias = NULL;
 | 
			
		||||
	fmt->features = 0;
 | 
			
		||||
	fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE;
 | 
			
		||||
	fmt->private = NULL;
 | 
			
		||||
 | 
			
		||||
	if (!(fmt->labeller = lvm1_labeller_create(fmt))) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the GPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_FORMAT1_H
 | 
			
		||||
@@ -9,8 +18,6 @@
 | 
			
		||||
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
 | 
			
		||||
#define FMT_LVM1_NAME "lvm1"
 | 
			
		||||
 | 
			
		||||
#ifdef LVM1_INTERNAL
 | 
			
		||||
struct format_type *init_lvm1_format(struct cmd_context *cmd);
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -12,10 +23,10 @@
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "lvm-string.h"
 | 
			
		||||
#include "filter.h"
 | 
			
		||||
#include "toolcontext.h"
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <linux/kdev_t.h>
 | 
			
		||||
 | 
			
		||||
static int _check_vg_name(const char *name)
 | 
			
		||||
{
 | 
			
		||||
@@ -56,9 +67,9 @@ int import_pv(struct pool *mem, struct device *dev,
 | 
			
		||||
 | 
			
		||||
	if (vg &&
 | 
			
		||||
	    strncmp(vg->system_id, pvd->system_id, sizeof(pvd->system_id)))
 | 
			
		||||
		log_very_verbose("System ID %s on %s differs from %s for "
 | 
			
		||||
				 "volume group", pvd->system_id,
 | 
			
		||||
				 dev_name(pv->dev), vg->system_id);
 | 
			
		||||
		    log_very_verbose("System ID %s on %s differs from %s for "
 | 
			
		||||
				     "volume group", pvd->system_id,
 | 
			
		||||
				     dev_name(pv->dev), vg->system_id);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If exported, we still need to flag in pv->status too because
 | 
			
		||||
@@ -76,20 +87,16 @@ int import_pv(struct pool *mem, struct device *dev,
 | 
			
		||||
	pv->pe_count = pvd->pe_total;
 | 
			
		||||
	pv->pe_alloc_count = pvd->pe_allocated;
 | 
			
		||||
 | 
			
		||||
	list_init(&pv->tags);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int _system_id(char *s, const char *prefix)
 | 
			
		||||
static int _system_id(struct cmd_context *cmd, char *s, const char *prefix)
 | 
			
		||||
{
 | 
			
		||||
	struct utsname uts;
 | 
			
		||||
 | 
			
		||||
	if (uname(&uts) != 0) {
 | 
			
		||||
		log_sys_error("uname", "_system_id");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lvm_snprintf(s, NAME_LEN, "%s%s%lu",
 | 
			
		||||
			 prefix, uts.nodename, time(NULL)) < 0) {
 | 
			
		||||
			 prefix, cmd->hostname, time(NULL)) < 0) {
 | 
			
		||||
		log_error("Generated system_id too long");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -97,7 +104,8 @@ int _system_id(char *s, const char *prefix)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int export_pv(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
int export_pv(struct cmd_context *cmd, struct pool *mem,
 | 
			
		||||
	      struct volume_group *vg,
 | 
			
		||||
	      struct pv_disk *pvd, struct physical_volume *pv)
 | 
			
		||||
{
 | 
			
		||||
	memset(pvd, 0, sizeof(*pvd));
 | 
			
		||||
@@ -128,7 +136,7 @@ int export_pv(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
		if (!*vg->system_id ||
 | 
			
		||||
		    strncmp(vg->system_id, EXPORTED_TAG,
 | 
			
		||||
			    sizeof(EXPORTED_TAG) - 1)) {
 | 
			
		||||
			if (!_system_id(pvd->system_id, EXPORTED_TAG)) {
 | 
			
		||||
			if (!_system_id(cmd, pvd->system_id, EXPORTED_TAG)) {
 | 
			
		||||
				stack;
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
@@ -145,7 +153,7 @@ int export_pv(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
	/* Is VG being imported? */
 | 
			
		||||
	if (vg && !(vg->status & EXPORTED_VG) && *vg->system_id &&
 | 
			
		||||
	    !strncmp(vg->system_id, EXPORTED_TAG, sizeof(EXPORTED_TAG) - 1)) {
 | 
			
		||||
		if (!_system_id(pvd->system_id, IMPORTED_TAG)) {
 | 
			
		||||
		if (!_system_id(cmd, pvd->system_id, IMPORTED_TAG)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
@@ -153,7 +161,7 @@ int export_pv(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
 | 
			
		||||
	/* Generate system_id if PV is in VG */
 | 
			
		||||
	if (!pvd->system_id || !*pvd->system_id)
 | 
			
		||||
		if (!_system_id(pvd->system_id, "")) {
 | 
			
		||||
		if (!_system_id(cmd, pvd->system_id, "")) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
@@ -162,7 +170,7 @@ int export_pv(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
	if (vg &&
 | 
			
		||||
	    (!*vg->system_id ||
 | 
			
		||||
	     strncmp(vg->system_id, pvd->system_id, sizeof(pvd->system_id))))
 | 
			
		||||
		strncpy(vg->system_id, pvd->system_id, NAME_LEN);
 | 
			
		||||
		    strncpy(vg->system_id, pvd->system_id, NAME_LEN);
 | 
			
		||||
 | 
			
		||||
	//pvd->pv_major = MAJOR(pv->dev);
 | 
			
		||||
 | 
			
		||||
@@ -288,8 +296,11 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
 | 
			
		||||
	if (lvd->lv_status & LV_PERSISTENT_MINOR) {
 | 
			
		||||
		lv->status |= FIXED_MINOR;
 | 
			
		||||
		lv->minor = MINOR(lvd->lv_dev);
 | 
			
		||||
	} else
 | 
			
		||||
		lv->major = MAJOR(lvd->lv_dev);
 | 
			
		||||
	} else {
 | 
			
		||||
		lv->major = -1;
 | 
			
		||||
		lv->minor = -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lvd->lv_access & LV_READ)
 | 
			
		||||
		lv->status |= LVM_READ;
 | 
			
		||||
@@ -311,6 +322,7 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
 | 
			
		||||
	lv->le_count = lvd->lv_allocated_le;
 | 
			
		||||
 | 
			
		||||
	list_init(&lv->segments);
 | 
			
		||||
	list_init(&lv->tags);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -335,13 +347,16 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
 | 
			
		||||
 | 
			
		||||
	if (lv->status & FIXED_MINOR) {
 | 
			
		||||
		lvd->lv_status |= LV_PERSISTENT_MINOR;
 | 
			
		||||
		lvd->lv_dev = MKDEV(0, lv->minor);
 | 
			
		||||
		lvd->lv_dev = MKDEV(lv->major, lv->minor);
 | 
			
		||||
	} else {
 | 
			
		||||
		lvd->lv_dev = MKDEV(LVM_BLK_MAJOR, lvnum_from_lvid(&lv->lvid));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lvd->lv_read_ahead = lv->read_ahead;
 | 
			
		||||
	lvd->lv_stripes = list_item(lv->segments.n, struct lv_segment)->stripes;
 | 
			
		||||
	lvd->lv_stripesize = list_item(lv->segments.n,
 | 
			
		||||
				       struct lv_segment)->stripe_size;
 | 
			
		||||
	lvd->lv_stripes =
 | 
			
		||||
	    list_item(lv->segments.n, struct lv_segment)->area_count;
 | 
			
		||||
	lvd->lv_stripesize =
 | 
			
		||||
	    list_item(lv->segments.n, struct lv_segment)->stripe_size;
 | 
			
		||||
 | 
			
		||||
	lvd->lv_size = lv->size;
 | 
			
		||||
	lvd->lv_allocated_le = lv->le_count;
 | 
			
		||||
@@ -353,7 +368,7 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
 | 
			
		||||
		lvd->lv_allocation |= LV_CONTIGUOUS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int export_extents(struct disk_list *dl, int lv_num,
 | 
			
		||||
int export_extents(struct disk_list *dl, uint32_t lv_num,
 | 
			
		||||
		   struct logical_volume *lv, struct physical_volume *pv)
 | 
			
		||||
{
 | 
			
		||||
	struct list *segh;
 | 
			
		||||
@@ -364,15 +379,25 @@ int export_extents(struct disk_list *dl, int lv_num,
 | 
			
		||||
	list_iterate(segh, &lv->segments) {
 | 
			
		||||
		seg = list_item(segh, struct lv_segment);
 | 
			
		||||
 | 
			
		||||
		for (s = 0; s < seg->stripes; s++) {
 | 
			
		||||
			if (seg->area[s].pv != pv)
 | 
			
		||||
		for (s = 0; s < seg->area_count; s++) {
 | 
			
		||||
			if (seg->type != SEG_STRIPED) {
 | 
			
		||||
				log_error("Non-striped segment type in LV %s: "
 | 
			
		||||
					  "unsupported by format1", lv->name);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
			if (seg->area[s].type != AREA_PV) {
 | 
			
		||||
				log_error("LV stripe found in LV %s: "
 | 
			
		||||
					  "unsupported by format1", lv->name);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
			if (seg->area[s].u.pv.pv != pv)
 | 
			
		||||
				continue;	/* not our pv */
 | 
			
		||||
 | 
			
		||||
			for (pe = 0; pe < (seg->len / seg->stripes); pe++) {
 | 
			
		||||
				ped = &dl->extents[pe + seg->area[s].pe];
 | 
			
		||||
			for (pe = 0; pe < (seg->len / seg->area_count); pe++) {
 | 
			
		||||
				ped = &dl->extents[pe + seg->area[s].u.pv.pe];
 | 
			
		||||
				ped->lv_num = lv_num;
 | 
			
		||||
				ped->le_num = (seg->le / seg->stripes) + pe +
 | 
			
		||||
				    s * (lv->le_count / seg->stripes);
 | 
			
		||||
				ped->le_num = (seg->le / seg->area_count) + pe +
 | 
			
		||||
				    s * (lv->le_count / seg->area_count);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -380,7 +405,7 @@ int export_extents(struct disk_list *dl, int lv_num,
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int import_pvs(struct format_type *fmt, struct pool *mem,
 | 
			
		||||
int import_pvs(const struct format_type *fmt, struct pool *mem,
 | 
			
		||||
	       struct volume_group *vg,
 | 
			
		||||
	       struct list *pvds, struct list *results, int *count)
 | 
			
		||||
{
 | 
			
		||||
@@ -393,7 +418,7 @@ int import_pvs(struct format_type *fmt, struct pool *mem,
 | 
			
		||||
 | 
			
		||||
		dl = list_item(pvdh, struct disk_list);
 | 
			
		||||
 | 
			
		||||
		if (!(pvl = pool_alloc(mem, sizeof(*pvl))) ||
 | 
			
		||||
		if (!(pvl = pool_zalloc(mem, sizeof(*pvl))) ||
 | 
			
		||||
		    !(pvl->pv = pool_alloc(mem, sizeof(*pvl->pv)))) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
@@ -470,7 +495,8 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
 | 
			
		||||
	struct list *lvh, *sh;
 | 
			
		||||
	struct lv_list *ll;
 | 
			
		||||
	struct lvd_list *lvdl;
 | 
			
		||||
	int lv_num, len;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	uint32_t lv_num;
 | 
			
		||||
	struct hash_table *lvd_hash;
 | 
			
		||||
 | 
			
		||||
	if (!_check_vg_name(vg->name)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
@@ -9,6 +18,7 @@
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "pool.h"
 | 
			
		||||
#include "disk-rep.h"
 | 
			
		||||
#include "lv_alloc.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * After much thought I have decided it is easier,
 | 
			
		||||
@@ -191,44 +201,33 @@ static int _check_maps_are_complete(struct hash_table *maps)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct lv_segment *_alloc_seg(struct pool *mem, uint32_t stripes)
 | 
			
		||||
{
 | 
			
		||||
	struct lv_segment *seg;
 | 
			
		||||
	uint32_t len = sizeof(*seg) + (stripes * sizeof(seg->area[0]));
 | 
			
		||||
 | 
			
		||||
	if (!(seg = pool_zalloc(mem, len))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return seg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _read_linear(struct pool *mem, struct lv_map *lvm)
 | 
			
		||||
{
 | 
			
		||||
	uint32_t le = 0;
 | 
			
		||||
	struct lv_segment *seg;
 | 
			
		||||
 | 
			
		||||
	while (le < lvm->lv->le_count) {
 | 
			
		||||
		seg = _alloc_seg(mem, 1);
 | 
			
		||||
		seg = alloc_lv_segment(mem, 1);
 | 
			
		||||
 | 
			
		||||
		seg->lv = lvm->lv;
 | 
			
		||||
		seg->type = SEG_STRIPED;
 | 
			
		||||
		seg->le = le;
 | 
			
		||||
		seg->len = 0;
 | 
			
		||||
		seg->area_len = 0;
 | 
			
		||||
		seg->stripe_size = 0;
 | 
			
		||||
		seg->stripes = 1;
 | 
			
		||||
		seg->area_count = 1;
 | 
			
		||||
 | 
			
		||||
		seg->area[0].pv = lvm->map[le].pv;
 | 
			
		||||
		seg->area[0].pe = lvm->map[le].pe;
 | 
			
		||||
		seg->area[0].type = AREA_PV;
 | 
			
		||||
		seg->area[0].u.pv.pv = lvm->map[le].pv;
 | 
			
		||||
		seg->area[0].u.pv.pe = lvm->map[le].pe;
 | 
			
		||||
 | 
			
		||||
		do
 | 
			
		||||
		do {
 | 
			
		||||
			seg->len++;
 | 
			
		||||
 | 
			
		||||
		while ((lvm->map[le + seg->len].pv == seg->area[0].pv) &&
 | 
			
		||||
		       (seg->area[0].pv &&
 | 
			
		||||
			lvm->map[le + seg->len].pe == seg->area[0].pe +
 | 
			
		||||
			seg->len));
 | 
			
		||||
			seg->area_len++;
 | 
			
		||||
		} while ((lvm->map[le + seg->len].pv == seg->area[0].u.pv.pv) &&
 | 
			
		||||
			 (seg->area[0].u.pv.pv &&
 | 
			
		||||
			  lvm->map[le + seg->len].pe == seg->area[0].u.pv.pe +
 | 
			
		||||
			  seg->len));
 | 
			
		||||
 | 
			
		||||
		le += seg->len;
 | 
			
		||||
 | 
			
		||||
@@ -248,10 +247,11 @@ static int _check_stripe(struct lv_map *lvm, struct lv_segment *seg,
 | 
			
		||||
	/*
 | 
			
		||||
	 * Is the next physical extent in every stripe adjacent to the last?
 | 
			
		||||
	 */
 | 
			
		||||
	for (st = 0; st < seg->stripes; st++)
 | 
			
		||||
		if ((lvm->map[le + st * len].pv != seg->area[st].pv) ||
 | 
			
		||||
		    (seg->area[st].pv &&
 | 
			
		||||
		     lvm->map[le + st * len].pe != seg->area[st].pe + seg->len))
 | 
			
		||||
	for (st = 0; st < seg->area_count; st++)
 | 
			
		||||
		if ((lvm->map[le + st * len].pv != seg->area[st].u.pv.pv) ||
 | 
			
		||||
		    (seg->area[st].u.pv.pv &&
 | 
			
		||||
		     lvm->map[le + st * len].pe !=
 | 
			
		||||
		     seg->area[st].u.pv.pe + seg->len))
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
@@ -273,7 +273,7 @@ static int _read_stripes(struct pool *mem, struct lv_map *lvm)
 | 
			
		||||
	len = lvm->lv->le_count / lvm->stripes;
 | 
			
		||||
 | 
			
		||||
	while (le < len) {
 | 
			
		||||
		if (!(seg = _alloc_seg(mem, lvm->stripes))) {
 | 
			
		||||
		if (!(seg = alloc_lv_segment(mem, lvm->stripes))) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
@@ -281,27 +281,30 @@ static int _read_stripes(struct pool *mem, struct lv_map *lvm)
 | 
			
		||||
		seg->lv = lvm->lv;
 | 
			
		||||
		seg->type = SEG_STRIPED;
 | 
			
		||||
		seg->stripe_size = lvm->stripe_size;
 | 
			
		||||
		seg->stripes = lvm->stripes;
 | 
			
		||||
		seg->le = seg->stripes * le;
 | 
			
		||||
		seg->area_count = lvm->stripes;
 | 
			
		||||
		seg->le = seg->area_count * le;
 | 
			
		||||
		seg->len = 1;
 | 
			
		||||
		seg->area_len = 1;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Set up start positions of each stripe in this segment
 | 
			
		||||
		 */
 | 
			
		||||
		for (st = 0; st < seg->stripes; st++) {
 | 
			
		||||
			seg->area[st].pv = lvm->map[le + st * len].pv;
 | 
			
		||||
			seg->area[st].pe = lvm->map[le + st * len].pe;
 | 
			
		||||
		for (st = 0; st < seg->area_count; st++) {
 | 
			
		||||
			seg->area[st].u.pv.pv = lvm->map[le + st * len].pv;
 | 
			
		||||
			seg->area[st].u.pv.pe = lvm->map[le + st * len].pe;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* 
 | 
			
		||||
		 * Find how many blocks are contiguous in all stripes
 | 
			
		||||
		 * and so can form part of this segment
 | 
			
		||||
		 */
 | 
			
		||||
		while (_check_stripe(lvm, seg, le, len))
 | 
			
		||||
		while (_check_stripe(lvm, seg, le, len)) {
 | 
			
		||||
			seg->len++;
 | 
			
		||||
			seg->area_len++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		le += seg->len;
 | 
			
		||||
		seg->len *= seg->stripes;
 | 
			
		||||
		seg->len *= seg->area_count;
 | 
			
		||||
 | 
			
		||||
		list_add(&lvm->lv->segments, &seg->list);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -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,13 +19,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Only works with powers of 2.
 | 
			
		||||
 */
 | 
			
		||||
static inline ulong _round_up(ulong n, ulong size)
 | 
			
		||||
static inline uint32_t _round_up(uint32_t n, uint32_t size)
 | 
			
		||||
{
 | 
			
		||||
	size--;
 | 
			
		||||
	return (n + size) & ~size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline ulong _div_up(ulong n, ulong size)
 | 
			
		||||
static inline uint32_t _div_up(uint32_t n, uint32_t size)
 | 
			
		||||
{
 | 
			
		||||
	return _round_up(n, size) / size;
 | 
			
		||||
}
 | 
			
		||||
@@ -62,7 +71,7 @@ static void _calc_simple_layout(struct pv_disk *pvd)
 | 
			
		||||
	pvd->pe_on_disk.size = pvd->pe_total * sizeof(struct pe_disk);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int _check_vg_limits(struct disk_list *dl)
 | 
			
		||||
static int _check_vg_limits(struct disk_list *dl)
 | 
			
		||||
{
 | 
			
		||||
	if (dl->vgd.lv_max > MAX_LV) {
 | 
			
		||||
		log_error("MaxLogicalVolumes of %d exceeds format limit of %d "
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -10,7 +19,7 @@
 | 
			
		||||
#include "label.h"
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
#include "xlate.h"
 | 
			
		||||
#include "cache.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
@@ -49,10 +58,13 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
 | 
			
		||||
		 struct label **label)
 | 
			
		||||
{
 | 
			
		||||
	struct pv_disk *pvd = (struct pv_disk *) buf;
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
 | 
			
		||||
	if (!(info = cache_add(l, pvd->pv_uuid, dev, pvd->vg_name, NULL)))
 | 
			
		||||
	munge_exported_vg(pvd);
 | 
			
		||||
	if (!(info = lvmcache_add(l, pvd->pv_uuid, dev, pvd->vg_name, NULL))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	*label = info->label;
 | 
			
		||||
 | 
			
		||||
	info->device_size = xlate32(pvd->pv_size) << SECTOR_SHIFT;
 | 
			
		||||
@@ -100,7 +112,7 @@ struct labeller *lvm1_labeller_create(struct format_type *fmt)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	l->ops = &_lvm1_ops;
 | 
			
		||||
	l->private = (void *) fmt;
 | 
			
		||||
	l->private = (const void *) fmt;
 | 
			
		||||
 | 
			
		||||
	return l;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
@@ -50,32 +59,32 @@ struct archive_file {
 | 
			
		||||
/*
 | 
			
		||||
 * Extract vg name and version number from a filename.
 | 
			
		||||
 */
 | 
			
		||||
static int _split_vg(const char *filename, char *vg, size_t vg_size,
 | 
			
		||||
		     uint32_t *index)
 | 
			
		||||
static int _split_vg(const char *filename, char *vgname, size_t vg_size,
 | 
			
		||||
		     uint32_t *ix)
 | 
			
		||||
{
 | 
			
		||||
	int len, vg_len;
 | 
			
		||||
	char *dot, *underscore;
 | 
			
		||||
	size_t len, vg_len;
 | 
			
		||||
	const char *dot, *underscore;
 | 
			
		||||
 | 
			
		||||
	len = strlen(filename);
 | 
			
		||||
	if (len < 7)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	dot = (char *) (filename + len - 3);
 | 
			
		||||
	dot = (filename + len - 3);
 | 
			
		||||
	if (strcmp(".vg", dot))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!(underscore = rindex(filename, '_')))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (sscanf(underscore + 1, "%u", index) != 1)
 | 
			
		||||
	if (sscanf(underscore + 1, "%u", ix) != 1)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	vg_len = underscore - filename;
 | 
			
		||||
	if (vg_len + 1 > vg_size)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	strncpy(vg, filename, vg_len);
 | 
			
		||||
	vg[vg_len] = '\0';
 | 
			
		||||
	strncpy(vgname, filename, vg_len);
 | 
			
		||||
	vgname[vg_len] = '\0';
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -83,7 +92,7 @@ static int _split_vg(const char *filename, char *vg, size_t vg_size,
 | 
			
		||||
static void _insert_file(struct list *head, struct archive_file *b)
 | 
			
		||||
{
 | 
			
		||||
	struct list *bh;
 | 
			
		||||
	struct archive_file *bf;
 | 
			
		||||
	struct archive_file *bf = NULL;
 | 
			
		||||
 | 
			
		||||
	if (list_empty(head)) {
 | 
			
		||||
		list_add(head, &b->list);
 | 
			
		||||
@@ -121,10 +130,10 @@ static char *_join(struct pool *mem, const char *dir, const char *name)
 | 
			
		||||
 * Returns a list of archive_files.
 | 
			
		||||
 */
 | 
			
		||||
static struct list *_scan_archive(struct pool *mem,
 | 
			
		||||
				  const char *vg, const char *dir)
 | 
			
		||||
				  const char *vgname, const char *dir)
 | 
			
		||||
{
 | 
			
		||||
	int i, count, index;
 | 
			
		||||
	char vg_name[64], *path;
 | 
			
		||||
	int i, count, ix;
 | 
			
		||||
	char vgname_found[64], *path;
 | 
			
		||||
	struct dirent **dirent;
 | 
			
		||||
	struct archive_file *af;
 | 
			
		||||
	struct list *results;
 | 
			
		||||
@@ -148,12 +157,12 @@ static struct list *_scan_archive(struct pool *mem,
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* check the name is the correct format */
 | 
			
		||||
		if (!_split_vg(dirent[i]->d_name, vg_name, sizeof(vg_name),
 | 
			
		||||
			       &index))
 | 
			
		||||
		if (!_split_vg(dirent[i]->d_name, vgname_found,
 | 
			
		||||
			       sizeof(vgname_found), &ix))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* is it the vg we're interested in ? */
 | 
			
		||||
		if (strcmp(vg, vg_name))
 | 
			
		||||
		if (strcmp(vgname, vgname_found))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (!(path = _join(mem, dir, dirent[i]->d_name))) {
 | 
			
		||||
@@ -170,7 +179,7 @@ static struct list *_scan_archive(struct pool *mem,
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		af->index = index;
 | 
			
		||||
		af->index = ix;
 | 
			
		||||
		af->path = path;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
@@ -231,7 +240,7 @@ int archive_vg(struct volume_group *vg,
 | 
			
		||||
	       uint32_t retain_days, uint32_t min_archive)
 | 
			
		||||
{
 | 
			
		||||
	int i, fd, renamed = 0;
 | 
			
		||||
	unsigned int index = 0;
 | 
			
		||||
	unsigned int ix = 0;
 | 
			
		||||
	struct archive_file *last;
 | 
			
		||||
	FILE *fp = NULL;
 | 
			
		||||
	char temp_file[PATH_MAX], archive_name[PATH_MAX];
 | 
			
		||||
@@ -268,15 +277,15 @@ int archive_vg(struct volume_group *vg,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (list_empty(archives))
 | 
			
		||||
		index = 0;
 | 
			
		||||
		ix = 0;
 | 
			
		||||
	else {
 | 
			
		||||
		last = list_item(archives->p, struct archive_file);
 | 
			
		||||
		index = last->index + 1;
 | 
			
		||||
		ix = last->index + 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 10; i++) {
 | 
			
		||||
		if (lvm_snprintf(archive_name, sizeof(archive_name),
 | 
			
		||||
				 "%s/%s_%05d.vg", dir, vg->name, index) < 0) {
 | 
			
		||||
				 "%s/%s_%05d.vg", dir, vg->name, ix) < 0) {
 | 
			
		||||
			log_error("Archive file name too long.");
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
@@ -284,7 +293,7 @@ int archive_vg(struct volume_group *vg,
 | 
			
		||||
		if ((renamed = lvm_rename(temp_file, archive_name)))
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		index++;
 | 
			
		||||
		ix++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!renamed)
 | 
			
		||||
@@ -304,7 +313,8 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
 | 
			
		||||
	char *desc;
 | 
			
		||||
	void *context;
 | 
			
		||||
 | 
			
		||||
	log_print("path:\t\t%s", af->path);
 | 
			
		||||
	log_print(" ");
 | 
			
		||||
	log_print("File:\t\t%s", af->path);
 | 
			
		||||
 | 
			
		||||
	if (!(context = create_text_context(cmd, af->path, NULL)) ||
 | 
			
		||||
	    !(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
 | 
			
		||||
@@ -324,34 +334,50 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_print("description:\t%s", desc ? desc : "<No description>");
 | 
			
		||||
	log_print("time:\t\t%s", ctime(&when));
 | 
			
		||||
	log_print("VG name:    \t%s", vg->name);
 | 
			
		||||
	log_print("Description:\t%s", desc ? desc : "<No description>");
 | 
			
		||||
	log_print("Backup Time:\t%s", ctime(&when));
 | 
			
		||||
 | 
			
		||||
	pool_free(cmd->mem, vg);
 | 
			
		||||
	tf->fmt->ops->destroy_instance(tf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int archive_list(struct cmd_context *cmd, const char *dir, const char *vg)
 | 
			
		||||
int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
 | 
			
		||||
{
 | 
			
		||||
	struct list *archives, *ah;
 | 
			
		||||
	struct archive_file *af;
 | 
			
		||||
 | 
			
		||||
	if (!(archives = _scan_archive(cmd->mem, vg, dir))) {
 | 
			
		||||
	if (!(archives = _scan_archive(cmd->mem, vgname, dir))) {
 | 
			
		||||
		log_err("Couldn't scan the archive directory (%s).", dir);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (list_empty(archives))
 | 
			
		||||
		log_print("No archives found.");
 | 
			
		||||
		log_print("No archives found in %s.", dir);
 | 
			
		||||
 | 
			
		||||
	list_iterate(ah, archives) {
 | 
			
		||||
		af = list_item(ah, struct archive_file);
 | 
			
		||||
 | 
			
		||||
		_display_archive(cmd, af);
 | 
			
		||||
		log_print(" ");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pool_free(cmd->mem, archives);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int backup_list(struct cmd_context *cmd, const char *dir, const char *vgname)
 | 
			
		||||
{
 | 
			
		||||
	struct archive_file af;
 | 
			
		||||
 | 
			
		||||
	if (!(af.path = _join(cmd->mem, dir, vgname))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (path_exists(af.path))
 | 
			
		||||
		_display_archive(cmd, &af);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -173,7 +182,7 @@ static int _out_with_comment_raw(struct formatter *f, const char *comment,
 | 
			
		||||
 */
 | 
			
		||||
static int _sectors_to_units(uint64_t sectors, char *buffer, size_t s)
 | 
			
		||||
{
 | 
			
		||||
	static char *_units[] = {
 | 
			
		||||
	static const char *_units[] = {
 | 
			
		||||
		"Kilobytes",
 | 
			
		||||
		"Megabytes",
 | 
			
		||||
		"Gigabytes",
 | 
			
		||||
@@ -270,7 +279,7 @@ static int _print_header(struct formatter *f,
 | 
			
		||||
 | 
			
		||||
static int _print_vg(struct formatter *f, struct volume_group *vg)
 | 
			
		||||
{
 | 
			
		||||
	char buffer[256];
 | 
			
		||||
	char buffer[4096];
 | 
			
		||||
 | 
			
		||||
	if (!id_write_format(&vg->id, buffer, sizeof(buffer))) {
 | 
			
		||||
		stack;
 | 
			
		||||
@@ -280,15 +289,26 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
 | 
			
		||||
	_outf(f, "id = \"%s\"", buffer);
 | 
			
		||||
 | 
			
		||||
	_outf(f, "seqno = %u", vg->seqno);
 | 
			
		||||
 | 
			
		||||
	if (!print_flags(vg->status, VG_FLAGS, buffer, sizeof(buffer))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_outf(f, "status = %s", buffer);
 | 
			
		||||
 | 
			
		||||
	if (!list_empty(&vg->tags)) {
 | 
			
		||||
		if (!print_tags(&vg->tags, buffer, sizeof(buffer))) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		_outf(f, "tags = %s", buffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (vg->system_id && *vg->system_id)
 | 
			
		||||
		_outf(f, "system_id = \"%s\"", vg->system_id);
 | 
			
		||||
	if (!_out_size(f, vg->extent_size, "extent_size = %u", vg->extent_size)) {
 | 
			
		||||
 | 
			
		||||
	if (!_out_size(f, (uint64_t) vg->extent_size, "extent_size = %u",
 | 
			
		||||
		       vg->extent_size)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -313,14 +333,13 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
 | 
			
		||||
{
 | 
			
		||||
	struct list *pvh;
 | 
			
		||||
	struct physical_volume *pv;
 | 
			
		||||
	char buffer[256];
 | 
			
		||||
	char buffer[4096];
 | 
			
		||||
	const char *name;
 | 
			
		||||
 | 
			
		||||
	_outf(f, "physical_volumes {");
 | 
			
		||||
	_inc_indent(f);
 | 
			
		||||
 | 
			
		||||
	list_iterate(pvh, &vg->pvs) {
 | 
			
		||||
 | 
			
		||||
		pv = list_item(pvh, struct pv_list)->pv;
 | 
			
		||||
 | 
			
		||||
		if (!(name = _get_pv_name(f, pv))) {
 | 
			
		||||
@@ -348,8 +367,16 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_outf(f, "status = %s", buffer);
 | 
			
		||||
 | 
			
		||||
		if (!list_empty(&pv->tags)) {
 | 
			
		||||
			if (!print_tags(&pv->tags, buffer, sizeof(buffer))) {
 | 
			
		||||
				stack;
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
			_outf(f, "tags = %s", buffer);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_outf(f, "pe_start = %" PRIu64, pv->pe_start);
 | 
			
		||||
		if (!_out_size(f, vg->extent_size * (uint64_t) pv->pe_count,
 | 
			
		||||
			       "pe_count = %u", pv->pe_count)) {
 | 
			
		||||
@@ -369,15 +396,17 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
 | 
			
		||||
static int _print_segment(struct formatter *f, struct volume_group *vg,
 | 
			
		||||
			  int count, struct lv_segment *seg)
 | 
			
		||||
{
 | 
			
		||||
	int s;
 | 
			
		||||
	unsigned int s;
 | 
			
		||||
	const char *name;
 | 
			
		||||
	const char *type;
 | 
			
		||||
	char buffer[4096];
 | 
			
		||||
 | 
			
		||||
	_outf(f, "segment%u {", count);
 | 
			
		||||
	_inc_indent(f);
 | 
			
		||||
 | 
			
		||||
	_outf(f, "start_extent = %u", seg->le);
 | 
			
		||||
	if (!_out_size(f, seg->len * vg->extent_size, "extent_count = %u",
 | 
			
		||||
		       seg->len)) {
 | 
			
		||||
	if (!_out_size(f, (uint64_t) seg->len * vg->extent_size,
 | 
			
		||||
		       "extent_count = %u", seg->len)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -385,41 +414,64 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
 | 
			
		||||
	f->nl(f);
 | 
			
		||||
	_outf(f, "type = \"%s\"", get_segtype_string(seg->type));
 | 
			
		||||
 | 
			
		||||
	switch (seg->type) {
 | 
			
		||||
	case SEG_STRIPED:
 | 
			
		||||
		_outf(f, "stripe_count = %u%s", seg->stripes,
 | 
			
		||||
		      (seg->stripes == 1) ? "\t# linear" : "");
 | 
			
		||||
 | 
			
		||||
		if (seg->stripes > 1)
 | 
			
		||||
			_out_size(f, seg->stripe_size,
 | 
			
		||||
				  "stripe_size = %u", seg->stripe_size);
 | 
			
		||||
 | 
			
		||||
		f->nl(f);
 | 
			
		||||
		_outf(f, "stripes = [");
 | 
			
		||||
		_inc_indent(f);
 | 
			
		||||
 | 
			
		||||
		for (s = 0; s < seg->stripes; s++) {
 | 
			
		||||
			if (!(name = _get_pv_name(f, seg->area[s].pv))) {
 | 
			
		||||
				stack;
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			_outf(f, "\"%s\", %u%s", name, seg->area[s].pe,
 | 
			
		||||
			      (s == seg->stripes - 1) ? "" : ",");
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
	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_MIRROR:
 | 
			
		||||
		/* mirrors = [ "lvol1", 10, ... ] */
 | 
			
		||||
		;
 | 
			
		||||
 | 
			
		||||
	case SEG_MIRRORED:
 | 
			
		||||
	case SEG_STRIPED:
 | 
			
		||||
		type = (seg->type == SEG_MIRRORED) ? "mirror" : "stripe";
 | 
			
		||||
		_outf(f, "%s_count = %u%s", type, seg->area_count,
 | 
			
		||||
		      (seg->area_count == 1) ? "\t# linear" : "");
 | 
			
		||||
 | 
			
		||||
		if ((seg->type == SEG_MIRRORED) && (seg->status & PVMOVE))
 | 
			
		||||
			_out_size(f, (uint64_t) seg->extents_moved,
 | 
			
		||||
				  "extents_moved = %u", seg->extents_moved);
 | 
			
		||||
 | 
			
		||||
		if ((seg->type == SEG_STRIPED) && (seg->area_count > 1))
 | 
			
		||||
			_out_size(f, (uint64_t) seg->stripe_size,
 | 
			
		||||
				  "stripe_size = %u", seg->stripe_size);
 | 
			
		||||
 | 
			
		||||
		f->nl(f);
 | 
			
		||||
 | 
			
		||||
		_outf(f, "%ss = [", type);
 | 
			
		||||
		_inc_indent(f);
 | 
			
		||||
 | 
			
		||||
		for (s = 0; s < seg->area_count; s++) {
 | 
			
		||||
			switch (seg->area[s].type) {
 | 
			
		||||
			case AREA_PV:
 | 
			
		||||
				if (!(name = _get_pv_name(f, seg->
 | 
			
		||||
							  area[s].u.pv.pv))) {
 | 
			
		||||
					stack;
 | 
			
		||||
					return 0;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				_outf(f, "\"%s\", %u%s", name,
 | 
			
		||||
				      seg->area[s].u.pv.pe,
 | 
			
		||||
				      (s == seg->area_count - 1) ? "" : ",");
 | 
			
		||||
				break;
 | 
			
		||||
			case AREA_LV:
 | 
			
		||||
				_outf(f, "\"%s\", %u%s",
 | 
			
		||||
				      seg->area[s].u.lv.lv->name,
 | 
			
		||||
				      seg->area[s].u.lv.le,
 | 
			
		||||
				      (s == seg->area_count - 1) ? "" : ",");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_dec_indent(f);
 | 
			
		||||
		_outf(f, "]");
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_dec_indent(f);
 | 
			
		||||
@@ -474,6 +526,9 @@ static int _print_snapshot(struct formatter *f, struct snapshot *snap,
 | 
			
		||||
	seg.cow = snap->cow;
 | 
			
		||||
	seg.chunk_size = snap->chunk_size;
 | 
			
		||||
 | 
			
		||||
	/* Can't tag a snapshot independently of its origin */
 | 
			
		||||
	list_init(&seg.tags);
 | 
			
		||||
 | 
			
		||||
	if (!_print_segment(f, snap->origin->vg, 1, &seg)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -505,10 +560,10 @@ static int _print_snapshots(struct formatter *f, struct volume_group *vg)
 | 
			
		||||
 | 
			
		||||
static int _print_lvs(struct formatter *f, struct volume_group *vg)
 | 
			
		||||
{
 | 
			
		||||
	struct list *lvh, *segh;
 | 
			
		||||
	struct list *lvh;
 | 
			
		||||
	struct logical_volume *lv;
 | 
			
		||||
	struct lv_segment *seg;
 | 
			
		||||
	char buffer[256];
 | 
			
		||||
	char buffer[4096];
 | 
			
		||||
	int seg_count;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
@@ -539,22 +594,30 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
 | 
			
		||||
			stack;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_outf(f, "status = %s", buffer);
 | 
			
		||||
 | 
			
		||||
		if (!list_empty(&lv->tags)) {
 | 
			
		||||
			if (!print_tags(&lv->tags, buffer, sizeof(buffer))) {
 | 
			
		||||
				stack;
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
			_outf(f, "tags = %s", buffer);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (lv->alloc != ALLOC_DEFAULT)
 | 
			
		||||
			_outf(f, "allocation_policy = \"%s\"",
 | 
			
		||||
			      get_alloc_string(lv->alloc));
 | 
			
		||||
		if (lv->read_ahead)
 | 
			
		||||
			_outf(f, "read_ahead = %u", lv->read_ahead);
 | 
			
		||||
		if (lv->major >= 0)
 | 
			
		||||
			_outf(f, "major = %d", lv->major);
 | 
			
		||||
		if (lv->minor >= 0)
 | 
			
		||||
			_outf(f, "minor = %d", lv->minor);
 | 
			
		||||
		_outf(f, "segment_count = %u", _count_segments(lv));
 | 
			
		||||
		f->nl(f);
 | 
			
		||||
 | 
			
		||||
		seg_count = 1;
 | 
			
		||||
		list_iterate(segh, &lv->segments) {
 | 
			
		||||
			seg = list_item(segh, struct lv_segment);
 | 
			
		||||
 | 
			
		||||
		list_iterate_items(seg, &lv->segments) {
 | 
			
		||||
			if (!_print_segment(f, vg, seg_count++, seg)) {
 | 
			
		||||
				stack;
 | 
			
		||||
				return 0;
 | 
			
		||||
@@ -601,6 +664,7 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
 | 
			
		||||
	list_iterate(pvh, &vg->pvs) {
 | 
			
		||||
		pv = list_item(pvh, struct pv_list)->pv;
 | 
			
		||||
 | 
			
		||||
		/* FIXME But skip if there's already an LV called pv%d ! */
 | 
			
		||||
		if (lvm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0) {
 | 
			
		||||
			stack;
 | 
			
		||||
			goto bad;
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -14,14 +23,15 @@
 | 
			
		||||
 * converted into arrays of strings.
 | 
			
		||||
 */
 | 
			
		||||
struct flag {
 | 
			
		||||
	int mask;
 | 
			
		||||
	char *description;
 | 
			
		||||
	const int mask;
 | 
			
		||||
	const char *description;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct flag _vg_flags[] = {
 | 
			
		||||
	{EXPORTED_VG, "EXPORTED"},
 | 
			
		||||
	{RESIZEABLE_VG, "RESIZEABLE"},
 | 
			
		||||
	{PARTIAL_VG, "PARTIAL"},
 | 
			
		||||
	{PVMOVE, "PVMOVE"},
 | 
			
		||||
	{LVM_READ, "READ"},
 | 
			
		||||
	{LVM_WRITE, "WRITE"},
 | 
			
		||||
	{CLUSTERED, "CLUSTERED"},
 | 
			
		||||
@@ -40,6 +50,8 @@ static struct flag _lv_flags[] = {
 | 
			
		||||
	{LVM_WRITE, "WRITE"},
 | 
			
		||||
	{FIXED_MINOR, "FIXED_MINOR"},
 | 
			
		||||
	{VISIBLE_LV, "VISIBLE"},
 | 
			
		||||
	{PVMOVE, "PVMOVE"},
 | 
			
		||||
	{LOCKED, "LOCKED"},
 | 
			
		||||
	{0, NULL}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -60,23 +72,6 @@ static struct flag *_get_flags(int type)
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _emit(char **buffer, size_t *size, const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	size_t n;
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, fmt);
 | 
			
		||||
	n = vsnprintf(*buffer, *size, fmt, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
 | 
			
		||||
	if (n < 0 || (n == *size))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	*buffer += n;
 | 
			
		||||
	*size -= n;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Converts a bitset to an array of string values,
 | 
			
		||||
 * using one of the tables defined at the top of
 | 
			
		||||
@@ -92,27 +87,27 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!_emit(&buffer, &size, "["))
 | 
			
		||||
	if (!emit_to_buffer(&buffer, &size, "["))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	for (f = 0; flags[f].mask; f++) {
 | 
			
		||||
		if (status & flags[f].mask) {
 | 
			
		||||
			if (!first) {
 | 
			
		||||
				if (!_emit(&buffer, &size, ", "))
 | 
			
		||||
				if (!emit_to_buffer(&buffer, &size, ", "))
 | 
			
		||||
					return 0;
 | 
			
		||||
 | 
			
		||||
			} else
 | 
			
		||||
				first = 0;
 | 
			
		||||
 | 
			
		||||
			if (!_emit(&buffer, &size, "\"%s\"",
 | 
			
		||||
				   flags[f].description))
 | 
			
		||||
			if (!emit_to_buffer(&buffer, &size, "\"%s\"",
 | 
			
		||||
					    flags[f].description))
 | 
			
		||||
				return 0;
 | 
			
		||||
 | 
			
		||||
			status &= ~flags[f].mask;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!_emit(&buffer, &size, "]"))
 | 
			
		||||
	if (!emit_to_buffer(&buffer, &size, "]"))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (status)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.   
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
@@ -20,6 +29,7 @@
 | 
			
		||||
#include "crc.h"
 | 
			
		||||
#include "xlate.h"
 | 
			
		||||
#include "label.h"
 | 
			
		||||
#include "memlock.h"
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/file.h>
 | 
			
		||||
@@ -27,8 +37,11 @@
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
 | 
			
		||||
static struct format_instance *_create_text_instance(struct format_type *fmt,
 | 
			
		||||
						     const char *vgname,
 | 
			
		||||
#define FMT_TEXT_NAME "lvm2"
 | 
			
		||||
#define FMT_TEXT_ALIAS "text"
 | 
			
		||||
 | 
			
		||||
static struct format_instance *_create_text_instance(const struct format_type
 | 
			
		||||
						     *fmt, const char *vgname,
 | 
			
		||||
						     void *context);
 | 
			
		||||
 | 
			
		||||
struct dir_list {
 | 
			
		||||
@@ -48,9 +61,7 @@ struct text_context {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * NOTE: Currently there can be only one vg per text file, and locking
 | 
			
		||||
 *       assumes VG's metadata is only held in metadata areas on PVs 
 | 
			
		||||
 *       inside the VG.
 | 
			
		||||
 * NOTE: Currently there can be only one vg per text file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
 | 
			
		||||
@@ -65,17 +76,19 @@ static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
 | 
			
		||||
 | 
			
		||||
static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
 | 
			
		||||
{
 | 
			
		||||
/******** FIXME Any LV size restriction? 
 | 
			
		||||
	uint64_t max_size = UINT_MAX;
 | 
			
		||||
 | 
			
		||||
	if (!*lv->lvid.s)
 | 
			
		||||
		lvid_create(&lv->lvid, &lv->vg->id);
 | 
			
		||||
 | 
			
		||||
	if (lv->size > max_size) {
 | 
			
		||||
		char *dummy = display_size(max_size, SIZE_SHORT);
 | 
			
		||||
		char *dummy = display_size(max_size / 2, SIZE_SHORT);
 | 
			
		||||
		log_error("logical volumes cannot be larger than %s", dummy);
 | 
			
		||||
		dbg_free(dummy);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
	if (!*lv->lvid.s)
 | 
			
		||||
		lvid_create(&lv->lvid, &lv->vg->id);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -97,7 +110,7 @@ static void _xlate_mdah(struct mda_header *mdah)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct mda_header *_raw_read_mda_header(struct format_type *fmt,
 | 
			
		||||
static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
 | 
			
		||||
					       struct device_area *dev_area)
 | 
			
		||||
{
 | 
			
		||||
	struct mda_header *mdah;
 | 
			
		||||
@@ -107,8 +120,7 @@ static struct mda_header *_raw_read_mda_header(struct format_type *fmt,
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah) !=
 | 
			
		||||
	    MDA_HEADER_SIZE) {
 | 
			
		||||
	if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		pool_free(fmt->cmd->mem, mdah);
 | 
			
		||||
		return NULL;
 | 
			
		||||
@@ -143,7 +155,7 @@ static struct mda_header *_raw_read_mda_header(struct format_type *fmt,
 | 
			
		||||
	return mdah;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _raw_write_mda_header(struct format_type *fmt,
 | 
			
		||||
static int _raw_write_mda_header(const struct format_type *fmt,
 | 
			
		||||
				 struct device *dev,
 | 
			
		||||
				 uint64_t start_byte, struct mda_header *mdah)
 | 
			
		||||
{
 | 
			
		||||
@@ -156,8 +168,7 @@ static int _raw_write_mda_header(struct format_type *fmt,
 | 
			
		||||
					     MDA_HEADER_SIZE -
 | 
			
		||||
					     sizeof(mdah->checksum_xl)));
 | 
			
		||||
 | 
			
		||||
	if (dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)
 | 
			
		||||
	    != MDA_HEADER_SIZE) {
 | 
			
		||||
	if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		pool_free(fmt->cmd->mem, mdah);
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -170,7 +181,7 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
 | 
			
		||||
				       struct mda_header *mdah,
 | 
			
		||||
				       const char *vgname)
 | 
			
		||||
{
 | 
			
		||||
	int len;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	char vgnamebuf[NAME_LEN + 2];
 | 
			
		||||
	struct raw_locn *rlocn;
 | 
			
		||||
 | 
			
		||||
@@ -178,9 +189,8 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
 | 
			
		||||
 | 
			
		||||
	/* FIXME Ignore if checksum incorrect!!! */
 | 
			
		||||
	while (rlocn->offset) {
 | 
			
		||||
		if (dev_read(dev_area->dev, dev_area->start + rlocn->offset,
 | 
			
		||||
			     sizeof(vgnamebuf), vgnamebuf)
 | 
			
		||||
		    != sizeof(vgnamebuf)) {
 | 
			
		||||
		if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
 | 
			
		||||
			      sizeof(vgnamebuf), vgnamebuf)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
@@ -214,7 +224,7 @@ static int _raw_holds_vgname(struct format_instance *fid,
 | 
			
		||||
{
 | 
			
		||||
	int r = 0;
 | 
			
		||||
 | 
			
		||||
	if (!dev_open(dev_area->dev, O_RDONLY)) {
 | 
			
		||||
	if (!dev_open(dev_area->dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -237,9 +247,9 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
 | 
			
		||||
	struct mda_header *mdah;
 | 
			
		||||
	time_t when;
 | 
			
		||||
	char *desc;
 | 
			
		||||
	uint64_t wrap = 0;
 | 
			
		||||
	uint32_t wrap = 0;
 | 
			
		||||
 | 
			
		||||
	if (!dev_open(area->dev, O_RDONLY)) {
 | 
			
		||||
	if (!dev_open(area->dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
@@ -255,7 +265,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (rlocn->offset + rlocn->size > mdah->size)
 | 
			
		||||
		wrap = (rlocn->offset + rlocn->size) - mdah->size;
 | 
			
		||||
		wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
 | 
			
		||||
 | 
			
		||||
	if (wrap > rlocn->offset) {
 | 
			
		||||
		log_error("VG %s metadata too large for circular buffer",
 | 
			
		||||
@@ -263,16 +273,19 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(vg = text_vg_import_fd(fid, dev_name(area->dev),
 | 
			
		||||
				     dev_fd(area->dev),
 | 
			
		||||
				     area->start + rlocn->offset,
 | 
			
		||||
				     rlocn->size - wrap,
 | 
			
		||||
				     area->start + MDA_HEADER_SIZE, wrap,
 | 
			
		||||
				     calc_crc, rlocn->checksum, &when,
 | 
			
		||||
	/* FIXME 64-bit */
 | 
			
		||||
	if (!(vg = text_vg_import_fd(fid, NULL, area->dev,
 | 
			
		||||
				     (off_t) (area->start + rlocn->offset),
 | 
			
		||||
				     (uint32_t) (rlocn->size - wrap),
 | 
			
		||||
				     (off_t) (area->start + MDA_HEADER_SIZE),
 | 
			
		||||
				     wrap, calc_crc, rlocn->checksum, &when,
 | 
			
		||||
				     &desc))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
	log_debug("Read %s metadata (%u) from %s at %" PRIu64 " size %" PRIu64,
 | 
			
		||||
		  vg->name, vg->seqno, dev_name(area->dev),
 | 
			
		||||
		  area->start + rlocn->offset, rlocn->size);
 | 
			
		||||
 | 
			
		||||
      out:
 | 
			
		||||
	if (!dev_close(area->dev))
 | 
			
		||||
@@ -299,7 +312,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
	struct physical_volume *pv;
 | 
			
		||||
	struct list *pvh;
 | 
			
		||||
	int r = 0;
 | 
			
		||||
	uint64_t new_wrap = 0, old_wrap = 0;
 | 
			
		||||
	uint32_t new_wrap = 0, old_wrap = 0;
 | 
			
		||||
 | 
			
		||||
	/* FIXME Essential fix! Make dynamic (realloc? pool?) */
 | 
			
		||||
	char buf[65536];
 | 
			
		||||
@@ -317,7 +330,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
	if (!found)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (!dev_open(mdac->area.dev, O_RDWR)) {
 | 
			
		||||
	if (!dev_open(mdac->area.dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -366,29 +379,29 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
		  mdac->rlocn.offset, mdac->rlocn.size - new_wrap);
 | 
			
		||||
 | 
			
		||||
	/* Write text out, circularly */
 | 
			
		||||
	if (dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
 | 
			
		||||
		      mdac->rlocn.size - new_wrap,
 | 
			
		||||
		      buf) != mdac->rlocn.size - new_wrap) {
 | 
			
		||||
	if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
 | 
			
		||||
		       (size_t) (mdac->rlocn.size - new_wrap), buf)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (new_wrap) {
 | 
			
		||||
		log_debug("Writing metadata to %s at %" PRIu64 " len %" PRIu64,
 | 
			
		||||
		log_debug("Writing metadata to %s at %" PRIu64 " len %" PRIu32,
 | 
			
		||||
			  dev_name(mdac->area.dev), mdac->area.start +
 | 
			
		||||
			  MDA_HEADER_SIZE, new_wrap);
 | 
			
		||||
 | 
			
		||||
		if (dev_write(mdac->area.dev,
 | 
			
		||||
			      mdac->area.start + MDA_HEADER_SIZE,
 | 
			
		||||
			      new_wrap, buf + mdac->rlocn.size - new_wrap)
 | 
			
		||||
		    != new_wrap) {
 | 
			
		||||
		if (!dev_write(mdac->area.dev,
 | 
			
		||||
			       mdac->area.start + MDA_HEADER_SIZE,
 | 
			
		||||
			       (size_t) new_wrap,
 | 
			
		||||
			       buf + mdac->rlocn.size - new_wrap)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mdac->rlocn.checksum = calc_crc(INITIAL_CRC, buf,
 | 
			
		||||
					mdac->rlocn.size - new_wrap);
 | 
			
		||||
					(uint32_t) (mdac->rlocn.size -
 | 
			
		||||
						    new_wrap));
 | 
			
		||||
	if (new_wrap)
 | 
			
		||||
		mdac->rlocn.checksum = calc_crc(mdac->rlocn.checksum,
 | 
			
		||||
						buf + mdac->rlocn.size -
 | 
			
		||||
@@ -397,7 +410,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
	r = 1;
 | 
			
		||||
 | 
			
		||||
      out:
 | 
			
		||||
	if (!dev_close(mdac->area.dev))
 | 
			
		||||
	if (!r && !dev_close(mdac->area.dev))
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
@@ -426,11 +439,6 @@ static int _vg_commit_raw(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
	if (!found)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (!dev_open(mdac->area.dev, O_RDWR)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		goto out;
 | 
			
		||||
@@ -463,6 +471,33 @@ static int _vg_commit_raw(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Close metadata area devices */
 | 
			
		||||
static int _vg_revert_raw(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
			  struct metadata_area *mda)
 | 
			
		||||
{
 | 
			
		||||
	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
 | 
			
		||||
	struct physical_volume *pv;
 | 
			
		||||
	struct list *pvh;
 | 
			
		||||
	int found = 0;
 | 
			
		||||
 | 
			
		||||
	/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
 | 
			
		||||
	list_iterate(pvh, &vg->pvs) {
 | 
			
		||||
		pv = list_item(pvh, struct pv_list)->pv;
 | 
			
		||||
		if (pv->dev == mdac->area.dev) {
 | 
			
		||||
			found = 1;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!found)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (!dev_close(mdac->area.dev))
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
			  struct metadata_area *mda)
 | 
			
		||||
{
 | 
			
		||||
@@ -471,7 +506,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
	struct raw_locn *rlocn;
 | 
			
		||||
	int r = 0;
 | 
			
		||||
 | 
			
		||||
	if (!dev_open(mdac->area.dev, O_RDWR)) {
 | 
			
		||||
	if (!dev_open(mdac->area.dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -558,7 +593,8 @@ static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
	if (slash == 0)
 | 
			
		||||
		strcpy(temp_dir, ".");
 | 
			
		||||
	else if (slash - tc->path_edit < PATH_MAX) {
 | 
			
		||||
		strncpy(temp_dir, tc->path_edit, slash - tc->path_edit);
 | 
			
		||||
		strncpy(temp_dir, tc->path_edit,
 | 
			
		||||
			(size_t) (slash - tc->path_edit));
 | 
			
		||||
		temp_dir[slash - tc->path_edit] = '\0';
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -625,12 +661,12 @@ static int _vg_commit_file_backup(struct format_instance *fid,
 | 
			
		||||
		log_debug("Renaming %s to %s", tc->path_edit, tc->path_live);
 | 
			
		||||
		if (rename(tc->path_edit, tc->path_live)) {
 | 
			
		||||
			log_error("%s: rename to %s failed: %s", tc->path_edit,
 | 
			
		||||
				  tc->path_edit, strerror(errno));
 | 
			
		||||
				  tc->path_live, strerror(errno));
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sync();
 | 
			
		||||
	sync_dir(tc->path_edit);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -641,7 +677,7 @@ static int _vg_commit_file(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
	struct text_context *tc = (struct text_context *) mda->metadata_locn;
 | 
			
		||||
	char *slash;
 | 
			
		||||
	char newname[PATH_MAX];
 | 
			
		||||
	int len;
 | 
			
		||||
	size_t len;
 | 
			
		||||
 | 
			
		||||
	if (!_vg_commit_file_backup(fid, vg, mda))
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -664,7 +700,7 @@ static int _vg_commit_file(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
				log_error("%s: rename to %s failed: %s",
 | 
			
		||||
					  tc->path_live, newname,
 | 
			
		||||
					  strerror(errno));
 | 
			
		||||
				sync();
 | 
			
		||||
				sync_dir(newname);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -688,12 +724,12 @@ static int _vg_remove_file(struct format_instance *fid, struct volume_group *vg,
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sync();
 | 
			
		||||
	sync_dir(tc->path_live);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _scan_file(struct format_type *fmt)
 | 
			
		||||
static int _scan_file(const struct format_type *fmt)
 | 
			
		||||
{
 | 
			
		||||
	struct dirent *dirent;
 | 
			
		||||
	struct dir_list *dl;
 | 
			
		||||
@@ -731,7 +767,7 @@ static int _scan_file(struct format_type *fmt)
 | 
			
		||||
				fid = _create_text_instance(fmt, NULL, NULL);
 | 
			
		||||
				if ((vg = _vg_read_file_name(fid, vgname,
 | 
			
		||||
							     path)))
 | 
			
		||||
					cache_update_vg(vg);
 | 
			
		||||
					lvmcache_update_vg(vg);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		if (closedir(d))
 | 
			
		||||
@@ -741,18 +777,15 @@ static int _scan_file(struct format_type *fmt)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int vgname_from_mda(struct format_type *fmt, struct device_area *dev_area,
 | 
			
		||||
int vgname_from_mda(const struct format_type *fmt, struct device_area *dev_area,
 | 
			
		||||
		    char *buf, uint32_t size)
 | 
			
		||||
{
 | 
			
		||||
	struct raw_locn *rlocn;
 | 
			
		||||
	struct mda_header *mdah;
 | 
			
		||||
	int already_open;
 | 
			
		||||
	int len;
 | 
			
		||||
	unsigned int len;
 | 
			
		||||
	int r = 0;
 | 
			
		||||
 | 
			
		||||
	already_open = dev_is_open(dev_area->dev);
 | 
			
		||||
 | 
			
		||||
	if (!already_open && !dev_open(dev_area->dev, O_RDONLY)) {
 | 
			
		||||
	if (!dev_open(dev_area->dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -765,19 +798,19 @@ int vgname_from_mda(struct format_type *fmt, struct device_area *dev_area,
 | 
			
		||||
	rlocn = mdah->raw_locns;
 | 
			
		||||
 | 
			
		||||
	while (rlocn->offset) {
 | 
			
		||||
		if (dev_read(dev_area->dev, dev_area->start + rlocn->offset,
 | 
			
		||||
			     size, buf) != size) {
 | 
			
		||||
		if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
 | 
			
		||||
			      size, buf)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
		len = 0;
 | 
			
		||||
		while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
 | 
			
		||||
		       len < size - 1)
 | 
			
		||||
		       len < (size - 1))
 | 
			
		||||
			len++;
 | 
			
		||||
		buf[len] = '\0';
 | 
			
		||||
 | 
			
		||||
		/* Ignore this entry if the characters aren't permissible */
 | 
			
		||||
		if (!validate_vgname(buf)) {
 | 
			
		||||
		if (!validate_name(buf)) {
 | 
			
		||||
			stack;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
@@ -790,13 +823,13 @@ int vgname_from_mda(struct format_type *fmt, struct device_area *dev_area,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      out:
 | 
			
		||||
	if (!already_open && dev_close(dev_area->dev))
 | 
			
		||||
	if (!dev_close(dev_area->dev))
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _scan_raw(struct format_type *fmt)
 | 
			
		||||
static int _scan_raw(const struct format_type *fmt)
 | 
			
		||||
{
 | 
			
		||||
	struct raw_list *rl;
 | 
			
		||||
	struct list *rlh, *raw_list;
 | 
			
		||||
@@ -817,21 +850,21 @@ static int _scan_raw(struct format_type *fmt)
 | 
			
		||||
				    sizeof(vgnamebuf))) {
 | 
			
		||||
			if ((vg = _vg_read_raw_area(&fid, vgnamebuf,
 | 
			
		||||
						    &rl->dev_area)))
 | 
			
		||||
				cache_update_vg(vg);
 | 
			
		||||
				lvmcache_update_vg(vg);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _scan(struct format_type *fmt)
 | 
			
		||||
static int _scan(const struct format_type *fmt)
 | 
			
		||||
{
 | 
			
		||||
	return (_scan_file(fmt) & _scan_raw(fmt));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* For orphan, creates new mdas according to policy.
 | 
			
		||||
   Always have an mda between end-of-label and PE_ALIGN boundary */
 | 
			
		||||
static int _mda_setup(struct format_type *fmt,
 | 
			
		||||
static int _mda_setup(const struct format_type *fmt,
 | 
			
		||||
		      uint64_t pe_start, uint64_t pe_end,
 | 
			
		||||
		      int pvmetadatacopies,
 | 
			
		||||
		      uint64_t pvmetadatasize, struct list *mdas,
 | 
			
		||||
@@ -868,6 +901,17 @@ static int _mda_setup(struct format_type *fmt,
 | 
			
		||||
	/* Place mda straight after label area at start of disk */
 | 
			
		||||
	start1 = LABEL_SCAN_SIZE;
 | 
			
		||||
 | 
			
		||||
	/* Ensure it's not going to be bigger than the disk! */
 | 
			
		||||
	if (mda_size1 > disk_size) {
 | 
			
		||||
		log_print("Warning: metadata area fills disk %s",
 | 
			
		||||
			  dev_name(pv->dev));
 | 
			
		||||
		/* Leave some free space for rounding */
 | 
			
		||||
		/* Avoid empty data area as could cause tools problems */
 | 
			
		||||
		mda_size1 = disk_size - start1 - alignment * 2;
 | 
			
		||||
		/* Only have 1 mda in this case */
 | 
			
		||||
		pvmetadatacopies = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Round up to PE_ALIGN boundary */
 | 
			
		||||
	mda_adjustment = (mda_size1 + start1) % alignment;
 | 
			
		||||
	if (mda_adjustment)
 | 
			
		||||
@@ -887,8 +931,9 @@ static int _mda_setup(struct format_type *fmt,
 | 
			
		||||
			     mda_size1))
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		if (!dev_zero(pv->dev, start1,
 | 
			
		||||
			      mda_size1 > wipe_size ? wipe_size : mda_size1)) {
 | 
			
		||||
		if (!dev_zero((struct device *) pv->dev, start1,
 | 
			
		||||
			      (size_t) (mda_size1 >
 | 
			
		||||
					wipe_size ? wipe_size : mda_size1))) {
 | 
			
		||||
			log_error("Failed to wipe new metadata area");
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
@@ -934,7 +979,8 @@ static int _mda_setup(struct format_type *fmt,
 | 
			
		||||
			     mda_size2))
 | 
			
		||||
			return 0;
 | 
			
		||||
		if (!dev_zero(pv->dev, start2,
 | 
			
		||||
			      mda_size1 > wipe_size ? wipe_size : mda_size1)) {
 | 
			
		||||
			      (size_t) (mda_size1 >
 | 
			
		||||
					wipe_size ? wipe_size : mda_size1))) {
 | 
			
		||||
			log_error("Failed to wipe new metadata area");
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
@@ -947,11 +993,11 @@ static int _mda_setup(struct format_type *fmt,
 | 
			
		||||
 | 
			
		||||
/* Only for orphans */
 | 
			
		||||
/* Set label_sector to -1 if rewriting existing label into same sector */
 | 
			
		||||
static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
 | 
			
		||||
static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
 | 
			
		||||
		     struct list *mdas, int64_t label_sector)
 | 
			
		||||
{
 | 
			
		||||
	struct label *label;
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
	struct mda_context *mdac;
 | 
			
		||||
	struct list *mdash;
 | 
			
		||||
	struct metadata_area *mda;
 | 
			
		||||
@@ -959,8 +1005,10 @@ static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
 | 
			
		||||
	struct mda_header *mdah = (struct mda_header *) buf;
 | 
			
		||||
	uint64_t adjustment;
 | 
			
		||||
 | 
			
		||||
	if (!(info = cache_add(fmt->labeller, (char *) &pv->id, pv->dev,
 | 
			
		||||
			       ORPHAN, NULL))) {
 | 
			
		||||
	/* FIXME Test mode don't update cache? */
 | 
			
		||||
 | 
			
		||||
	if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
 | 
			
		||||
				  ORPHAN, NULL))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -1017,12 +1065,14 @@ static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
 | 
			
		||||
				pv->pe_start += (PE_ALIGN - adjustment);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!add_da(fmt, NULL, &info->das, pv->pe_start << SECTOR_SHIFT, 0)) {
 | 
			
		||||
	if (!add_da
 | 
			
		||||
	    (fmt, NULL, &info->das, pv->pe_start << SECTOR_SHIFT,
 | 
			
		||||
	     UINT64_C(0))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!dev_open(pv->dev, O_RDWR)) {
 | 
			
		||||
	if (!dev_open(pv->dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -1051,7 +1101,7 @@ static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _get_pv_from_vg(struct format_type *fmt, const char *vg_name,
 | 
			
		||||
static int _get_pv_from_vg(const struct format_type *fmt, const char *vg_name,
 | 
			
		||||
			   const char *id, struct physical_volume *pv)
 | 
			
		||||
{
 | 
			
		||||
	struct volume_group *vg;
 | 
			
		||||
@@ -1071,7 +1121,7 @@ static int _get_pv_from_vg(struct format_type *fmt, const char *vg_name,
 | 
			
		||||
 | 
			
		||||
	list_iterate(pvh, &vg->pvs) {
 | 
			
		||||
		pvl = list_item(pvh, struct pv_list);
 | 
			
		||||
		if (id_equal(&pvl->pv->id, (struct id *) id)) {
 | 
			
		||||
		if (id_equal(&pvl->pv->id, (const struct id *) id)) {
 | 
			
		||||
			memcpy(pv, pvl->pv, sizeof(*pv));
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
@@ -1103,12 +1153,12 @@ static int _add_raw(struct list *raw_list, struct device_area *dev_area)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _pv_read(struct format_type *fmt, const char *pv_name,
 | 
			
		||||
static int _pv_read(const struct format_type *fmt, const char *pv_name,
 | 
			
		||||
		    struct physical_volume *pv, struct list *mdas)
 | 
			
		||||
{
 | 
			
		||||
	struct label *label;
 | 
			
		||||
	struct device *dev;
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
	struct metadata_area *mda, *mda_new;
 | 
			
		||||
	struct mda_context *mdac, *mdac_new;
 | 
			
		||||
	struct list *mdah, *dah;
 | 
			
		||||
@@ -1119,11 +1169,12 @@ static int _pv_read(struct format_type *fmt, const char *pv_name,
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* FIXME Optimise out repeated reading when cache lock held */
 | 
			
		||||
	if (!(label_read(dev, &label))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	info = (struct cache_info *) label->info;
 | 
			
		||||
	info = (struct lvmcache_info *) label->info;
 | 
			
		||||
 | 
			
		||||
	/* Have we already cached vgname? */
 | 
			
		||||
	if (info->vginfo && info->vginfo->vgname && *info->vginfo->vgname &&
 | 
			
		||||
@@ -1133,12 +1184,15 @@ static int _pv_read(struct format_type *fmt, const char *pv_name,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Perform full scan and try again */
 | 
			
		||||
	cache_label_scan(fmt->cmd, 0);
 | 
			
		||||
	if (!memlock()) {
 | 
			
		||||
		lvmcache_label_scan(fmt->cmd, 1);
 | 
			
		||||
 | 
			
		||||
	if (info->vginfo && info->vginfo->vgname && *info->vginfo->vgname &&
 | 
			
		||||
	    _get_pv_from_vg(info->fmt, info->vginfo->vgname, info->dev->pvid,
 | 
			
		||||
			    pv)) {
 | 
			
		||||
		return 1;
 | 
			
		||||
		if (info->vginfo && info->vginfo->vgname &&
 | 
			
		||||
		    *info->vginfo->vgname &&
 | 
			
		||||
		    _get_pv_from_vg(info->fmt, info->vginfo->vgname,
 | 
			
		||||
				    info->dev->pvid, pv)) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Orphan */
 | 
			
		||||
@@ -1208,7 +1262,7 @@ static void _free_raws(struct list *raw_list)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _destroy(struct format_type *fmt)
 | 
			
		||||
static void _destroy(const struct format_type *fmt)
 | 
			
		||||
{
 | 
			
		||||
	if (fmt->private) {
 | 
			
		||||
		_free_dirs(&((struct mda_lists *) fmt->private)->dirs);
 | 
			
		||||
@@ -1216,7 +1270,7 @@ static void _destroy(struct format_type *fmt)
 | 
			
		||||
		dbg_free(fmt->private);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dbg_free(fmt);
 | 
			
		||||
	dbg_free((void *) fmt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct metadata_area_ops _metadata_text_file_ops = {
 | 
			
		||||
@@ -1237,11 +1291,12 @@ static struct metadata_area_ops _metadata_text_raw_ops = {
 | 
			
		||||
	vg_read:_vg_read_raw,
 | 
			
		||||
	vg_write:_vg_write_raw,
 | 
			
		||||
	vg_remove:_vg_remove_raw,
 | 
			
		||||
	vg_commit:_vg_commit_raw
 | 
			
		||||
	vg_commit:_vg_commit_raw,
 | 
			
		||||
	vg_revert:_vg_revert_raw
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* pvmetadatasize in sectors */
 | 
			
		||||
static int _pv_setup(struct format_type *fmt,
 | 
			
		||||
static int _pv_setup(const struct format_type *fmt,
 | 
			
		||||
		     uint64_t pe_start, uint32_t extent_count,
 | 
			
		||||
		     uint32_t extent_size,
 | 
			
		||||
		     int pvmetadatacopies,
 | 
			
		||||
@@ -1251,7 +1306,7 @@ static int _pv_setup(struct format_type *fmt,
 | 
			
		||||
	struct metadata_area *mda, *mda_new, *mda2;
 | 
			
		||||
	struct mda_context *mdac, *mdac_new, *mdac2;
 | 
			
		||||
	struct list *pvmdas, *pvmdash, *mdash;
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
	int found;
 | 
			
		||||
	uint64_t pe_end = 0;
 | 
			
		||||
 | 
			
		||||
@@ -1332,8 +1387,8 @@ static int _pv_setup(struct format_type *fmt,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* NULL vgname means use only the supplied context e.g. an archive file */
 | 
			
		||||
static struct format_instance *_create_text_instance(struct format_type *fmt,
 | 
			
		||||
						     const char *vgname,
 | 
			
		||||
static struct format_instance *_create_text_instance(const struct format_type
 | 
			
		||||
						     *fmt, const char *vgname,
 | 
			
		||||
						     void *context)
 | 
			
		||||
{
 | 
			
		||||
	struct format_instance *fid;
 | 
			
		||||
@@ -1343,7 +1398,7 @@ static struct format_instance *_create_text_instance(struct format_type *fmt,
 | 
			
		||||
	struct raw_list *rl;
 | 
			
		||||
	struct list *dlh, *dir_list, *rlh, *raw_list, *mdas, *mdash, *infoh;
 | 
			
		||||
	char path[PATH_MAX];
 | 
			
		||||
	struct cache_vginfo *vginfo;
 | 
			
		||||
	struct lvmcache_vginfo *vginfo;
 | 
			
		||||
 | 
			
		||||
	if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
 | 
			
		||||
		log_error("Couldn't allocate format instance object.");
 | 
			
		||||
@@ -1406,17 +1461,18 @@ static struct format_instance *_create_text_instance(struct format_type *fmt,
 | 
			
		||||
			/* FIXME Allow multiple dev_areas inside area */
 | 
			
		||||
			memcpy(&mdac->area, &rl->dev_area, sizeof(mdac->area));
 | 
			
		||||
			mda->ops = &_metadata_text_raw_ops;
 | 
			
		||||
			/* FIXME MISTAKE? mda->metadata_locn = context; */
 | 
			
		||||
			list_add(&fid->metadata_areas, &mda->list);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Scan PVs in VG for any further MDAs */
 | 
			
		||||
		cache_label_scan(fmt->cmd, 0);
 | 
			
		||||
		lvmcache_label_scan(fmt->cmd, 0);
 | 
			
		||||
		if (!(vginfo = vginfo_from_vgname(vgname))) {
 | 
			
		||||
			stack;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
		list_iterate(infoh, &vginfo->infos) {
 | 
			
		||||
			mdas = &(list_item(infoh, struct cache_info)->mdas);
 | 
			
		||||
			mdas = &(list_item(infoh, struct lvmcache_info)->mdas);
 | 
			
		||||
			list_iterate(mdash, mdas) {
 | 
			
		||||
				mda = list_item(mdash, struct metadata_area);
 | 
			
		||||
				mdac =
 | 
			
		||||
@@ -1537,21 +1593,21 @@ static int _get_config_disk_area(struct cmd_context *cmd,
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!get_config_uint64(cn, "start_sector", '/', &dev_area.start)) {
 | 
			
		||||
	if (!get_config_uint64(cn, "start_sector", &dev_area.start)) {
 | 
			
		||||
		log_error("Missing start_sector in metadata disk_area section "
 | 
			
		||||
			  "of config file");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	dev_area.start <<= SECTOR_SHIFT;
 | 
			
		||||
 | 
			
		||||
	if (!get_config_uint64(cn, "size", '/', &dev_area.size)) {
 | 
			
		||||
	if (!get_config_uint64(cn, "size", &dev_area.size)) {
 | 
			
		||||
		log_error("Missing size in metadata disk_area section "
 | 
			
		||||
			  "of config file");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	dev_area.size <<= SECTOR_SHIFT;
 | 
			
		||||
 | 
			
		||||
	if (!get_config_str(cn, "id", '/', &id_str)) {
 | 
			
		||||
	if (!get_config_str(cn, "id", &id_str)) {
 | 
			
		||||
		log_error("Missing uuid in metadata disk_area section "
 | 
			
		||||
			  "of config file");
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -1593,7 +1649,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
 | 
			
		||||
	fmt->ops = &_text_handler;
 | 
			
		||||
	fmt->name = FMT_TEXT_NAME;
 | 
			
		||||
	fmt->alias = FMT_TEXT_ALIAS;
 | 
			
		||||
	fmt->features = FMT_SEGMENTS | FMT_MDAS;
 | 
			
		||||
	fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS;
 | 
			
		||||
 | 
			
		||||
	if (!(mda_lists = dbg_malloc(sizeof(struct mda_lists)))) {
 | 
			
		||||
		log_error("Failed to allocate dir_list");
 | 
			
		||||
@@ -1616,7 +1672,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((cn = find_config_node(cmd->cf->root, "metadata/dirs", '/'))) {
 | 
			
		||||
	if ((cn = find_config_node(cmd->cft->root, "metadata/dirs"))) {
 | 
			
		||||
		for (cv = cn->v; cv; cv = cv->next) {
 | 
			
		||||
			if (cv->type != CFG_STRING) {
 | 
			
		||||
				log_error("Invalid string in config file: "
 | 
			
		||||
@@ -1632,7 +1688,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(cn = find_config_node(cmd->cf->root, "metadata/disk_areas", '/')))
 | 
			
		||||
	if (!(cn = find_config_node(cmd->cft->root, "metadata/disk_areas")))
 | 
			
		||||
		return fmt;
 | 
			
		||||
 | 
			
		||||
	for (cn = cn->child; cn; cn = cn->sib) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_FORMAT_TEXT_H
 | 
			
		||||
@@ -11,9 +20,6 @@
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
#include "pool.h"
 | 
			
		||||
 | 
			
		||||
#define FMT_TEXT_NAME "lvm2"
 | 
			
		||||
#define FMT_TEXT_ALIAS "text"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Archives a vg config.  'retain_days' is the minimum number of
 | 
			
		||||
 * days that an archive file must be held for.  'min_archives' is
 | 
			
		||||
@@ -27,7 +33,8 @@ int archive_vg(struct volume_group *vg,
 | 
			
		||||
/*
 | 
			
		||||
 * Displays a list of vg backups in a particular archive directory.
 | 
			
		||||
 */
 | 
			
		||||
int archive_list(struct cmd_context *cmd, const char *dir, const char *vg);
 | 
			
		||||
int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname);
 | 
			
		||||
int backup_list(struct cmd_context *cmd, const char *dir, const char *vgname);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The text format can read and write a volume_group to a file.
 | 
			
		||||
@@ -36,19 +43,19 @@ struct format_type *create_text_format(struct cmd_context *cmd);
 | 
			
		||||
void *create_text_context(struct cmd_context *cmd, const char *path,
 | 
			
		||||
			  const char *desc);
 | 
			
		||||
 | 
			
		||||
struct labeller *text_labeller_create(struct format_type *fmt);
 | 
			
		||||
struct labeller *text_labeller_create(const struct format_type *fmt);
 | 
			
		||||
 | 
			
		||||
int pvhdr_read(struct device *dev, char *buf);
 | 
			
		||||
 | 
			
		||||
int add_da(struct format_type *fmt, struct pool *mem, struct list *das,
 | 
			
		||||
int add_da(const struct format_type *fmt, struct pool *mem, struct list *das,
 | 
			
		||||
	   uint64_t start, uint64_t size);
 | 
			
		||||
void del_das(struct list *das);
 | 
			
		||||
 | 
			
		||||
int add_mda(struct format_type *fmt, struct pool *mem, struct list *mdas,
 | 
			
		||||
int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
 | 
			
		||||
	    struct device *dev, uint64_t start, uint64_t size);
 | 
			
		||||
void del_mdas(struct list *mdas);
 | 
			
		||||
 | 
			
		||||
int vgname_from_mda(struct format_type *fmt, struct device_area *dev_area,
 | 
			
		||||
int vgname_from_mda(const struct format_type *fmt, struct device_area *dev_area,
 | 
			
		||||
		    char *buf, uint32_t size);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_TEXT_IMPORT_EXPORT_H
 | 
			
		||||
@@ -46,6 +55,9 @@ struct text_vg_version_ops *text_vg_vsn1_init(void);
 | 
			
		||||
int print_flags(uint32_t status, int type, char *buffer, size_t size);
 | 
			
		||||
int read_flags(uint32_t *status, int type, struct config_value *cv);
 | 
			
		||||
 | 
			
		||||
int print_tags(struct list *tags, char *buffer, size_t size);
 | 
			
		||||
int read_tags(struct pool *mem, struct list *tags, struct config_value *cv);
 | 
			
		||||
 | 
			
		||||
int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp);
 | 
			
		||||
int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
 | 
			
		||||
		       uint32_t size);
 | 
			
		||||
@@ -54,7 +66,7 @@ struct volume_group *text_vg_import_file(struct format_instance *fid,
 | 
			
		||||
					 time_t *when, char **desc);
 | 
			
		||||
struct volume_group *text_vg_import_fd(struct format_instance *fid,
 | 
			
		||||
				       const char *file,
 | 
			
		||||
				       int fd,
 | 
			
		||||
				       struct device *dev,
 | 
			
		||||
				       off_t offset, uint32_t size,
 | 
			
		||||
				       off_t offset2, uint32_t size2,
 | 
			
		||||
				       checksum_fn_t checksum_fn,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
@@ -11,14 +20,14 @@
 | 
			
		||||
#include "display.h"
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "toolcontext.h"
 | 
			
		||||
#include "cache.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
 | 
			
		||||
/* FIXME Use tidier inclusion method */
 | 
			
		||||
static struct text_vg_version_ops *(_text_vsn_list[2]);
 | 
			
		||||
 | 
			
		||||
struct volume_group *text_vg_import_fd(struct format_instance *fid,
 | 
			
		||||
				       const char *file,
 | 
			
		||||
				       int fd,
 | 
			
		||||
				       struct device *dev,
 | 
			
		||||
				       off_t offset, uint32_t size,
 | 
			
		||||
				       off_t offset2, uint32_t size2,
 | 
			
		||||
				       checksum_fn_t checksum_fn,
 | 
			
		||||
@@ -26,7 +35,7 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
 | 
			
		||||
				       time_t *when, char **desc)
 | 
			
		||||
{
 | 
			
		||||
	struct volume_group *vg = NULL;
 | 
			
		||||
	struct config_tree *cf;
 | 
			
		||||
	struct config_tree *cft;
 | 
			
		||||
	struct text_vg_version_ops **vsn;
 | 
			
		||||
 | 
			
		||||
	static int _initialised = 0;
 | 
			
		||||
@@ -40,15 +49,14 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
 | 
			
		||||
	*desc = NULL;
 | 
			
		||||
	*when = 0;
 | 
			
		||||
 | 
			
		||||
	if (!(cf = create_config_tree())) {
 | 
			
		||||
	if (!(cft = create_config_tree())) {
 | 
			
		||||
		stack;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((fd == -1 && !read_config_file(cf, file)) ||
 | 
			
		||||
	    (fd != -1 && !read_config_fd(cf, fd, file, offset, size,
 | 
			
		||||
					 offset2, size2, checksum_fn,
 | 
			
		||||
					 checksum))) {
 | 
			
		||||
	if ((!dev && !read_config_file(cft, file)) ||
 | 
			
		||||
	    (dev && !read_config_fd(cft, dev, offset, size,
 | 
			
		||||
				    offset2, size2, checksum_fn, checksum))) {
 | 
			
		||||
		log_error("Couldn't read volume group metadata.");
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
@@ -57,20 +65,20 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
 | 
			
		||||
	 * Find a set of version functions that can read this file
 | 
			
		||||
	 */
 | 
			
		||||
	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
 | 
			
		||||
		if (!(*vsn)->check_version(cf))
 | 
			
		||||
		if (!(*vsn)->check_version(cft))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (!(vg = (*vsn)->read_vg(fid, cf))) {
 | 
			
		||||
		if (!(vg = (*vsn)->read_vg(fid, cft))) {
 | 
			
		||||
			stack;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		(*vsn)->read_desc(fid->fmt->cmd->mem, cf, when, desc);
 | 
			
		||||
		(*vsn)->read_desc(fid->fmt->cmd->mem, cft, when, desc);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      out:
 | 
			
		||||
	destroy_config_tree(cf);
 | 
			
		||||
	destroy_config_tree(cft);
 | 
			
		||||
	return vg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -78,6 +86,6 @@ struct volume_group *text_vg_import_file(struct format_instance *fid,
 | 
			
		||||
					 const char *file,
 | 
			
		||||
					 time_t *when, char **desc)
 | 
			
		||||
{
 | 
			
		||||
	return text_vg_import_fd(fid, file, -1, 0, 0, 0, 0, NULL, 0,
 | 
			
		||||
	return text_vg_import_fd(fid, file, NULL, 0, 0, 0, 0, NULL, 0,
 | 
			
		||||
				 when, desc);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
@@ -11,7 +20,8 @@
 | 
			
		||||
#include "display.h"
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "toolcontext.h"
 | 
			
		||||
#include "cache.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
#include "lv_alloc.h"
 | 
			
		||||
 | 
			
		||||
typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
 | 
			
		||||
			   struct volume_group * vg, struct config_node * pvn,
 | 
			
		||||
@@ -19,13 +29,13 @@ typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
 | 
			
		||||
			   struct hash_table * pv_hash);
 | 
			
		||||
 | 
			
		||||
#define _read_int32(root, path, result) \
 | 
			
		||||
	get_config_uint32(root, path, '/', result)
 | 
			
		||||
	get_config_uint32(root, path, result)
 | 
			
		||||
 | 
			
		||||
#define _read_uint32(root, path, result) \
 | 
			
		||||
	get_config_uint32(root, path, '/', result)
 | 
			
		||||
	get_config_uint32(root, path, result)
 | 
			
		||||
 | 
			
		||||
#define _read_int64(root, path, result) \
 | 
			
		||||
	get_config_uint64(root, path, '/', result)
 | 
			
		||||
	get_config_uint64(root, path, result)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Logs an attempt to read an invalid format file.
 | 
			
		||||
@@ -39,7 +49,7 @@ static void _invalid_format(const char *str)
 | 
			
		||||
 * Checks that the config file contains vg metadata, and that it
 | 
			
		||||
 * we recognise the version number,
 | 
			
		||||
 */
 | 
			
		||||
static int _check_version(struct config_tree *cf)
 | 
			
		||||
static int _check_version(struct config_tree *cft)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *cn;
 | 
			
		||||
	struct config_value *cv;
 | 
			
		||||
@@ -47,7 +57,7 @@ static int _check_version(struct config_tree *cf)
 | 
			
		||||
	/*
 | 
			
		||||
	 * Check the contents field.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!(cn = find_config_node(cf->root, CONTENTS_FIELD, '/'))) {
 | 
			
		||||
	if (!(cn = find_config_node(cft->root, CONTENTS_FIELD))) {
 | 
			
		||||
		_invalid_format("missing contents field");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -61,7 +71,7 @@ static int _check_version(struct config_tree *cf)
 | 
			
		||||
	/*
 | 
			
		||||
	 * Check the version number.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!(cn = find_config_node(cf->root, FORMAT_VERSION_FIELD, '/'))) {
 | 
			
		||||
	if (!(cn = find_config_node(cft->root, FORMAT_VERSION_FIELD))) {
 | 
			
		||||
		_invalid_format("missing version number");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -79,7 +89,7 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path)
 | 
			
		||||
{
 | 
			
		||||
	struct config_value *cv;
 | 
			
		||||
 | 
			
		||||
	if (!(cn = find_config_node(cn, path, '/'))) {
 | 
			
		||||
	if (!(cn = find_config_node(cn, path))) {
 | 
			
		||||
		log_error("Couldn't find uuid.");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -156,7 +166,7 @@ static int _read_pv(struct format_instance *fid, struct pool *mem,
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(cn = find_config_node(pvn, "status", '/'))) {
 | 
			
		||||
	if (!(cn = find_config_node(pvn, "status"))) {
 | 
			
		||||
		log_error("Couldn't find status flags for physical volume.");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -177,6 +187,16 @@ static int _read_pv(struct format_instance *fid, struct pool *mem,
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_init(&pv->tags);
 | 
			
		||||
 | 
			
		||||
	/* Optional tags */
 | 
			
		||||
	if ((cn = find_config_node(pvn, "tags")) &&
 | 
			
		||||
	    !(read_tags(mem, &pv->tags, cn->v))) {
 | 
			
		||||
		log_error("Couldn't read tags for physical volume %s in %s.",
 | 
			
		||||
			  dev_name(pv->dev), vg->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* adjust the volume group. */
 | 
			
		||||
	vg->extent_count += pv->pe_count;
 | 
			
		||||
	vg->free_count += pv->pe_count;
 | 
			
		||||
@@ -214,16 +234,16 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
			 struct logical_volume *lv, struct config_node *sn,
 | 
			
		||||
			 struct hash_table *pv_hash)
 | 
			
		||||
{
 | 
			
		||||
	int s;
 | 
			
		||||
	uint32_t stripes = 0;
 | 
			
		||||
	unsigned int s;
 | 
			
		||||
	uint32_t area_count = 0;
 | 
			
		||||
	struct lv_segment *seg;
 | 
			
		||||
	struct config_node *cn;
 | 
			
		||||
	struct config_value *cv;
 | 
			
		||||
	const char *seg_name = sn->key;
 | 
			
		||||
	uint32_t start_extent, extent_count;
 | 
			
		||||
	uint32_t chunk_size;
 | 
			
		||||
	uint32_t chunk_size, extents_moved = 0u, seg_status = 0u;
 | 
			
		||||
	const char *org_name, *cow_name;
 | 
			
		||||
	struct logical_volume *org, *cow;
 | 
			
		||||
	struct logical_volume *org, *cow, *lv1;
 | 
			
		||||
	segment_type_t segtype;
 | 
			
		||||
 | 
			
		||||
	if (!(sn = sn->child)) {
 | 
			
		||||
@@ -244,7 +264,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	segtype = SEG_STRIPED;	/* Default */
 | 
			
		||||
	if ((cn = find_config_node(sn, "type", '/'))) {
 | 
			
		||||
	if ((cn = find_config_node(sn, "type"))) {
 | 
			
		||||
		cv = cn->v;
 | 
			
		||||
		if (!cv || !cv->v.str) {
 | 
			
		||||
			log_error("Segment type must be a string.");
 | 
			
		||||
@@ -254,25 +274,53 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (segtype == SEG_STRIPED) {
 | 
			
		||||
		if (!_read_int32(sn, "stripe_count", &stripes)) {
 | 
			
		||||
		if (!_read_int32(sn, "stripe_count", &area_count)) {
 | 
			
		||||
			log_error("Couldn't read 'stripe_count' for "
 | 
			
		||||
				  "segment '%s'.", sn->key);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(seg = pool_zalloc(mem, sizeof(*seg) +
 | 
			
		||||
				(sizeof(seg->area[0]) * stripes)))) {
 | 
			
		||||
		stack;
 | 
			
		||||
	if (segtype == SEG_MIRRORED) {
 | 
			
		||||
		if (!_read_int32(sn, "mirror_count", &area_count)) {
 | 
			
		||||
			log_error("Couldn't read 'mirror_count' for "
 | 
			
		||||
				  "segment '%s'.", sn->key);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (find_config_node(sn, "extents_moved")) {
 | 
			
		||||
			if (_read_uint32(sn, "extents_moved", &extents_moved))
 | 
			
		||||
				seg_status |= PVMOVE;
 | 
			
		||||
			else {
 | 
			
		||||
				log_error("Couldn't read 'extents_moved' for "
 | 
			
		||||
					  "segment '%s'.", sn->key);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(seg = alloc_lv_segment(mem, area_count))) {
 | 
			
		||||
		log_error("Segment allocation failed");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	seg->lv = lv;
 | 
			
		||||
	seg->le = start_extent;
 | 
			
		||||
	seg->len = extent_count;
 | 
			
		||||
	seg->area_len = extent_count;
 | 
			
		||||
	seg->type = segtype;
 | 
			
		||||
	seg->status = seg_status;
 | 
			
		||||
	seg->extents_moved = extents_moved;
 | 
			
		||||
 | 
			
		||||
	/* Optional tags */
 | 
			
		||||
	if ((cn = find_config_node(sn, "tags")) &&
 | 
			
		||||
	    !(read_tags(mem, &seg->tags, cn->v))) {
 | 
			
		||||
		log_error("Couldn't read tags for a segment of %s/%s.",
 | 
			
		||||
			  vg->name, lv->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch (segtype) {
 | 
			
		||||
	case SEG_MIRROR:
 | 
			
		||||
	case SEG_SNAPSHOT:
 | 
			
		||||
		lv->status |= SNAPSHOT;
 | 
			
		||||
 | 
			
		||||
@@ -283,13 +331,13 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
 | 
			
		||||
		log_suppress(1);
 | 
			
		||||
 | 
			
		||||
		if (!(cow_name = find_config_str(sn, "cow_store", '/', NULL))) {
 | 
			
		||||
		if (!(cow_name = find_config_str(sn, "cow_store", NULL))) {
 | 
			
		||||
			log_suppress(0);
 | 
			
		||||
			log_error("Snapshot cow storage not specified.");
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!(org_name = find_config_str(sn, "origin", '/', NULL))) {
 | 
			
		||||
		if (!(org_name = find_config_str(sn, "origin", NULL))) {
 | 
			
		||||
			log_suppress(0);
 | 
			
		||||
			log_error("Snapshot origin not specified.");
 | 
			
		||||
			return 0;
 | 
			
		||||
@@ -316,76 +364,91 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case SEG_STRIPED:
 | 
			
		||||
		seg->stripes = stripes;
 | 
			
		||||
 | 
			
		||||
		if (!seg->stripes) {
 | 
			
		||||
			log_error("Zero stripes *not* allowed for segment '%s'",
 | 
			
		||||
				  sn->key);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ((seg->stripes != 1) &&
 | 
			
		||||
		if ((area_count != 1) &&
 | 
			
		||||
		    !_read_int32(sn, "stripe_size", &seg->stripe_size)) {
 | 
			
		||||
			log_error("Couldn't read stripe_size for segment '%s'.",
 | 
			
		||||
				  sn->key);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!(cn = find_config_node(sn, "stripes", '/'))) {
 | 
			
		||||
		if (!(cn = find_config_node(sn, "stripes"))) {
 | 
			
		||||
			log_error("Couldn't find stripes array for segment "
 | 
			
		||||
				  "'%s'.", sn->key);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (cv = cn->v, s = 0; cv && s < seg->stripes;
 | 
			
		||||
		seg->area_len /= area_count;
 | 
			
		||||
 | 
			
		||||
	case SEG_MIRRORED:
 | 
			
		||||
		seg->area_count = area_count;
 | 
			
		||||
 | 
			
		||||
		if (!seg->area_count) {
 | 
			
		||||
			log_error("Zero areas not allowed for segment '%s'",
 | 
			
		||||
				  sn->key);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ((seg->type == SEG_MIRRORED) &&
 | 
			
		||||
		    !(cn = find_config_node(sn, "mirrors"))) {
 | 
			
		||||
			log_error("Couldn't find mirrors array for segment "
 | 
			
		||||
				  "'%s'.", sn->key);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (cv = cn->v, s = 0; cv && s < seg->area_count;
 | 
			
		||||
		     s++, cv = cv->next) {
 | 
			
		||||
 | 
			
		||||
			/* first we read the pv */
 | 
			
		||||
			const char *bad = "Badly formed areas array for "
 | 
			
		||||
			    "segment '%s'.";
 | 
			
		||||
			struct physical_volume *pv;
 | 
			
		||||
			uint32_t allocated;
 | 
			
		||||
 | 
			
		||||
			if (cv->type != CFG_STRING) {
 | 
			
		||||
				log_error(bad, sn->key);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (!(pv = hash_lookup(pv_hash, cv->v.str))) {
 | 
			
		||||
				log_error("Couldn't find physical volume '%s' "
 | 
			
		||||
			if (!cv->next) {
 | 
			
		||||
				log_error(bad, sn->key);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cv->next->type != CFG_INT) {
 | 
			
		||||
				log_error(bad, sn->key);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* FIXME Cope if LV not yet read in */
 | 
			
		||||
			if ((pv = hash_lookup(pv_hash, cv->v.str))) {
 | 
			
		||||
				seg->area[s].type = AREA_PV;
 | 
			
		||||
				seg->area[s].u.pv.pv = pv;
 | 
			
		||||
				seg->area[s].u.pv.pe = cv->next->v.i;
 | 
			
		||||
				/*
 | 
			
		||||
				 * Adjust extent counts in the pv and vg.
 | 
			
		||||
				 */
 | 
			
		||||
				pv->pe_alloc_count += seg->area_len;
 | 
			
		||||
				vg->free_count -= seg->area_len;
 | 
			
		||||
 | 
			
		||||
			} else if ((lv1 = find_lv(vg, cv->v.str))) {
 | 
			
		||||
				seg->area[s].type = AREA_LV;
 | 
			
		||||
				seg->area[s].u.lv.lv = lv1;
 | 
			
		||||
				seg->area[s].u.lv.le = cv->next->v.i;
 | 
			
		||||
			} else {
 | 
			
		||||
				log_error("Couldn't find volume '%s' "
 | 
			
		||||
					  "for segment '%s'.",
 | 
			
		||||
					  cv->v.str ? cv->v.str : "NULL",
 | 
			
		||||
					  seg_name);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			seg->area[s].pv = pv;
 | 
			
		||||
 | 
			
		||||
			if (!(cv = cv->next)) {
 | 
			
		||||
				log_error(bad, sn->key);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cv->type != CFG_INT) {
 | 
			
		||||
				log_error(bad, sn->key);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			seg->area[s].pe = cv->v.i;
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			   * Adjust the extent counts in the pv and vg.
 | 
			
		||||
			 */
 | 
			
		||||
			allocated = seg->len / seg->stripes;
 | 
			
		||||
			pv->pe_alloc_count += allocated;
 | 
			
		||||
			vg->free_count -= allocated;
 | 
			
		||||
			cv = cv->next;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Check we read the correct number of stripes.
 | 
			
		||||
		 */
 | 
			
		||||
		if (cv || (s < seg->stripes)) {
 | 
			
		||||
			log_error("Incorrect number of stripes in 'area' array "
 | 
			
		||||
		if (cv || (s < seg->area_count)) {
 | 
			
		||||
			log_error("Incorrect number of areas in area array "
 | 
			
		||||
				  "for segment '%s'.", seg_name);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
@@ -456,9 +519,9 @@ static int _read_segments(struct pool *mem, struct volume_group *vg,
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _read_lv(struct format_instance *fid, struct pool *mem,
 | 
			
		||||
		    struct volume_group *vg, struct config_node *lvn,
 | 
			
		||||
		    struct config_node *vgn, struct hash_table *pv_hash)
 | 
			
		||||
static int _read_lvnames(struct format_instance *fid, struct pool *mem,
 | 
			
		||||
			 struct volume_group *vg, struct config_node *lvn,
 | 
			
		||||
			 struct config_node *vgn, struct hash_table *pv_hash)
 | 
			
		||||
{
 | 
			
		||||
	struct logical_volume *lv;
 | 
			
		||||
	struct lv_list *lvl;
 | 
			
		||||
@@ -482,18 +545,7 @@ static int _read_lv(struct format_instance *fid, struct pool *mem,
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lv->vg = vg;
 | 
			
		||||
 | 
			
		||||
	/* FIXME: read full lvid */
 | 
			
		||||
	if (!_read_id(&lv->lvid.id[1], lvn, "id")) {
 | 
			
		||||
		log_error("Couldn't read uuid for logical volume %s.",
 | 
			
		||||
			  lv->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memcpy(&lv->lvid.id[0], &lv->vg->id, sizeof(lv->lvid.id[0]));
 | 
			
		||||
 | 
			
		||||
	if (!(cn = find_config_node(lvn, "status", '/'))) {
 | 
			
		||||
	if (!(cn = find_config_node(lvn, "status"))) {
 | 
			
		||||
		log_error("Couldn't find status flags for logical volume.");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -503,14 +555,8 @@ static int _read_lv(struct format_instance *fid, struct pool *mem,
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_init(&lv->segments);
 | 
			
		||||
	if (!_read_segments(mem, vg, lv, lvn, pv_hash)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lv->alloc = ALLOC_DEFAULT;
 | 
			
		||||
	if ((cn = find_config_node(lvn, "allocation_policy", '/'))) {
 | 
			
		||||
	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.");
 | 
			
		||||
@@ -524,6 +570,57 @@ static int _read_lv(struct format_instance *fid, struct pool *mem,
 | 
			
		||||
	if (!_read_int32(lvn, "read_ahead", &lv->read_ahead))
 | 
			
		||||
		lv->read_ahead = 0;
 | 
			
		||||
 | 
			
		||||
	list_init(&lv->segments);
 | 
			
		||||
	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++;
 | 
			
		||||
	list_add(&vg->lvs, &lvl->list);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _read_lvsegs(struct format_instance *fid, struct pool *mem,
 | 
			
		||||
			struct volume_group *vg, struct config_node *lvn,
 | 
			
		||||
			struct config_node *vgn, struct hash_table *pv_hash)
 | 
			
		||||
{
 | 
			
		||||
	struct logical_volume *lv;
 | 
			
		||||
	struct lv_list *lvl;
 | 
			
		||||
 | 
			
		||||
	if (!(lvl = find_lv_in_vg(vg, lvn->key))) {
 | 
			
		||||
		log_error("Lost logical volume reference %s", lvn->key);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lv = lvl->lv;
 | 
			
		||||
 | 
			
		||||
	if (!(lvn = lvn->child)) {
 | 
			
		||||
		log_error("Empty logical volume section.");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* FIXME: read full lvid */
 | 
			
		||||
	if (!_read_id(&lv->lvid.id[1], lvn, "id")) {
 | 
			
		||||
		log_error("Couldn't read uuid for logical volume %s.",
 | 
			
		||||
			  lv->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memcpy(&lv->lvid.id[0], &lv->vg->id, sizeof(lv->lvid.id[0]));
 | 
			
		||||
 | 
			
		||||
	if (!_read_segments(mem, vg, lv, lvn, pv_hash)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size;
 | 
			
		||||
 | 
			
		||||
	/* Skip this for now for snapshots */
 | 
			
		||||
@@ -532,12 +629,18 @@ static int _read_lv(struct format_instance *fid, struct pool *mem,
 | 
			
		||||
		if ((lv->status & FIXED_MINOR) &&
 | 
			
		||||
		    !_read_int32(lvn, "minor", &lv->minor)) {
 | 
			
		||||
			log_error("Couldn't read minor number for logical "
 | 
			
		||||
				  "volume.");
 | 
			
		||||
				  "volume %s.", lv->name);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		vg->lv_count++;
 | 
			
		||||
		list_add(&vg->lvs, &lvl->list);
 | 
			
		||||
		lv->major = -1;
 | 
			
		||||
		if ((lv->status & FIXED_MINOR) &&
 | 
			
		||||
		    !_read_int32(lvn, "major", &lv->major)) {
 | 
			
		||||
			log_error("Couldn't read major number for logical "
 | 
			
		||||
				  "volume %s.", lv->name);
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		vg->lv_count--;
 | 
			
		||||
		list_del(&lvl->list);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
@@ -551,7 +654,7 @@ static int _read_sections(struct format_instance *fid,
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *n;
 | 
			
		||||
 | 
			
		||||
	if (!(n = find_config_node(vgn, section, '/'))) {
 | 
			
		||||
	if (!(n = find_config_node(vgn, section))) {
 | 
			
		||||
		if (!optional) {
 | 
			
		||||
			log_error("Couldn't find section '%s'.", section);
 | 
			
		||||
			return 0;
 | 
			
		||||
@@ -571,7 +674,7 @@ static int _read_sections(struct format_instance *fid,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct volume_group *_read_vg(struct format_instance *fid,
 | 
			
		||||
				     struct config_tree *cf)
 | 
			
		||||
				     struct config_tree *cft)
 | 
			
		||||
{
 | 
			
		||||
	struct config_node *vgn, *cn;
 | 
			
		||||
	struct volume_group *vg;
 | 
			
		||||
@@ -579,7 +682,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
 | 
			
		||||
	struct pool *mem = fid->fmt->cmd->mem;
 | 
			
		||||
 | 
			
		||||
	/* skip any top-level values */
 | 
			
		||||
	for (vgn = cf->root; (vgn && vgn->v); vgn = vgn->sib) ;
 | 
			
		||||
	for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) ;
 | 
			
		||||
 | 
			
		||||
	if (!vgn) {
 | 
			
		||||
		log_error("Couldn't find volume group in file.");
 | 
			
		||||
@@ -608,7 +711,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
 | 
			
		||||
 | 
			
		||||
	vgn = vgn->child;
 | 
			
		||||
 | 
			
		||||
	if ((cn = find_config_node(vgn, "system_id", '/')) && cn->v) {
 | 
			
		||||
	if ((cn = find_config_node(vgn, "system_id")) && cn->v) {
 | 
			
		||||
		if (!cn->v->v.str) {
 | 
			
		||||
			log_error("system_id must be a string");
 | 
			
		||||
			goto bad;
 | 
			
		||||
@@ -627,7 +730,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
 | 
			
		||||
		goto bad;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(cn = find_config_node(vgn, "status", '/'))) {
 | 
			
		||||
	if (!(cn = find_config_node(vgn, "status"))) {
 | 
			
		||||
		log_error("Couldn't find status flags for volume group %s.",
 | 
			
		||||
			  vg->name);
 | 
			
		||||
		goto bad;
 | 
			
		||||
@@ -681,13 +784,29 @@ static struct volume_group *_read_vg(struct format_instance *fid,
 | 
			
		||||
 | 
			
		||||
	list_init(&vg->lvs);
 | 
			
		||||
	list_init(&vg->snapshots);
 | 
			
		||||
	if (!_read_sections(fid, "logical_volumes", _read_lv, mem, vg,
 | 
			
		||||
	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)) {
 | 
			
		||||
		log_error("Couldn't read all logical volumes for volume "
 | 
			
		||||
		log_error("Couldn't read all logical volume names for volume "
 | 
			
		||||
			  "group %s.", vg->name);
 | 
			
		||||
		goto bad;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!_read_sections(fid, "logical_volumes", _read_lvsegs, mem, vg,
 | 
			
		||||
			    vgn, pv_hash, 1)) {
 | 
			
		||||
		log_error("Couldn't read all logical volumes for "
 | 
			
		||||
			  "volume group %s.", vg->name);
 | 
			
		||||
		goto bad;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hash_destroy(pv_hash);
 | 
			
		||||
 | 
			
		||||
	if (vg->status & PARTIAL_VG) {
 | 
			
		||||
@@ -709,17 +828,17 @@ static struct volume_group *_read_vg(struct format_instance *fid,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _read_desc(struct pool *mem,
 | 
			
		||||
		       struct config_tree *cf, time_t *when, char **desc)
 | 
			
		||||
		       struct config_tree *cft, time_t *when, char **desc)
 | 
			
		||||
{
 | 
			
		||||
	const char *d;
 | 
			
		||||
	unsigned int u = 0u;
 | 
			
		||||
 | 
			
		||||
	log_suppress(1);
 | 
			
		||||
	d = find_config_str(cf->root, "description", '/', "");
 | 
			
		||||
	d = find_config_str(cft->root, "description", "");
 | 
			
		||||
	log_suppress(0);
 | 
			
		||||
	*desc = pool_strdup(mem, d);
 | 
			
		||||
 | 
			
		||||
	get_config_uint32(cf->root, "creation_time", '/', &u);
 | 
			
		||||
	get_config_uint32(cft->root, "creation_time", &u);
 | 
			
		||||
	*when = u;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2002 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
@@ -27,7 +36,7 @@ static int _write(struct label *label, char *buf)
 | 
			
		||||
{
 | 
			
		||||
	struct label_header *lh = (struct label_header *) buf;
 | 
			
		||||
	struct pv_header *pvhdr;
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
	struct disk_locn *pvh_dlocn_xl;
 | 
			
		||||
	struct list *mdash, *dash;
 | 
			
		||||
	struct metadata_area *mda;
 | 
			
		||||
@@ -40,7 +49,7 @@ static int _write(struct label *label, char *buf)
 | 
			
		||||
	strncpy(lh->type, label->type, sizeof(label->type));
 | 
			
		||||
 | 
			
		||||
	pvhdr = (struct pv_header *) ((void *) buf + xlate32(lh->offset_xl));
 | 
			
		||||
	info = (struct cache_info *) label->info;
 | 
			
		||||
	info = (struct lvmcache_info *) label->info;
 | 
			
		||||
	pvhdr->device_size_xl = xlate64(info->device_size);
 | 
			
		||||
	memcpy(pvhdr->pv_uuid, &info->dev->pvid, sizeof(struct id));
 | 
			
		||||
 | 
			
		||||
@@ -56,8 +65,8 @@ static int _write(struct label *label, char *buf)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* NULL-termination */
 | 
			
		||||
	pvh_dlocn_xl->offset = xlate64(0);
 | 
			
		||||
	pvh_dlocn_xl->size = xlate64(0);
 | 
			
		||||
	pvh_dlocn_xl->offset = xlate64(UINT64_C(0));
 | 
			
		||||
	pvh_dlocn_xl->size = xlate64(UINT64_C(0));
 | 
			
		||||
	pvh_dlocn_xl++;
 | 
			
		||||
 | 
			
		||||
	/* List of metadata area header locations */
 | 
			
		||||
@@ -74,13 +83,13 @@ static int _write(struct label *label, char *buf)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* NULL-termination */
 | 
			
		||||
	pvh_dlocn_xl->offset = xlate64(0);
 | 
			
		||||
	pvh_dlocn_xl->size = xlate64(0);
 | 
			
		||||
	pvh_dlocn_xl->offset = xlate64(UINT64_C(0));
 | 
			
		||||
	pvh_dlocn_xl->size = xlate64(UINT64_C(0));
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int add_da(struct format_type *fmt, struct pool *mem, struct list *das,
 | 
			
		||||
int add_da(const struct format_type *fmt, struct pool *mem, struct list *das,
 | 
			
		||||
	   uint64_t start, uint64_t size)
 | 
			
		||||
{
 | 
			
		||||
	struct data_area_list *dal;
 | 
			
		||||
@@ -117,7 +126,7 @@ void del_das(struct list *das)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int add_mda(struct format_type *fmt, struct pool *mem, struct list *mdas,
 | 
			
		||||
int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
 | 
			
		||||
	    struct device *dev, uint64_t start, uint64_t size)
 | 
			
		||||
{
 | 
			
		||||
/* FIXME List size restricted by pv_header SECTOR_SIZE */
 | 
			
		||||
@@ -185,7 +194,7 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
 | 
			
		||||
{
 | 
			
		||||
	struct label_header *lh = (struct label_header *) buf;
 | 
			
		||||
	struct pv_header *pvhdr;
 | 
			
		||||
	struct cache_info *info;
 | 
			
		||||
	struct lvmcache_info *info;
 | 
			
		||||
	struct disk_locn *dlocn_xl;
 | 
			
		||||
	uint64_t offset;
 | 
			
		||||
	struct list *mdah;
 | 
			
		||||
@@ -195,7 +204,7 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
 | 
			
		||||
 | 
			
		||||
	pvhdr = (struct pv_header *) ((void *) buf + xlate32(lh->offset_xl));
 | 
			
		||||
 | 
			
		||||
	if (!(info = cache_add(l, pvhdr->pv_uuid, dev, NULL, NULL)))
 | 
			
		||||
	if (!(info = lvmcache_add(l, pvhdr->pv_uuid, dev, NULL, NULL)))
 | 
			
		||||
		return 0;
 | 
			
		||||
	*label = info->label;
 | 
			
		||||
 | 
			
		||||
@@ -230,7 +239,7 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
 | 
			
		||||
		mdac = (struct mda_context *) mda->metadata_locn;
 | 
			
		||||
		if (vgname_from_mda(info->fmt, &mdac->area, vgnamebuf,
 | 
			
		||||
				    sizeof(vgnamebuf))) {
 | 
			
		||||
			cache_update_vgname(info, vgnamebuf);
 | 
			
		||||
			lvmcache_update_vgname(info, vgnamebuf);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -241,7 +250,7 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
 | 
			
		||||
 | 
			
		||||
static void _destroy_label(struct labeller *l, struct label *label)
 | 
			
		||||
{
 | 
			
		||||
	struct cache_info *info = (struct cache_info *) label->info;
 | 
			
		||||
	struct lvmcache_info *info = (struct lvmcache_info *) label->info;
 | 
			
		||||
 | 
			
		||||
	if (info->mdas.n)
 | 
			
		||||
		del_mdas(&info->mdas);
 | 
			
		||||
@@ -264,7 +273,7 @@ struct label_ops _text_ops = {
 | 
			
		||||
	destroy:_destroy
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct labeller *text_labeller_create(struct format_type *fmt)
 | 
			
		||||
struct labeller *text_labeller_create(const struct format_type *fmt)
 | 
			
		||||
{
 | 
			
		||||
	struct labeller *l;
 | 
			
		||||
 | 
			
		||||
@@ -274,7 +283,7 @@ struct labeller *text_labeller_create(struct format_type *fmt)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	l->ops = &_text_ops;
 | 
			
		||||
	l->private = (void *) fmt;
 | 
			
		||||
	l->private = (const void *) fmt;
 | 
			
		||||
 | 
			
		||||
	return l;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2002 Sistina Software
 | 
			
		||||
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
@@ -9,7 +18,7 @@
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "crc.h"
 | 
			
		||||
#include "xlate.h"
 | 
			
		||||
#include "cache.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
@@ -104,20 +113,17 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
 | 
			
		||||
	struct list *lih;
 | 
			
		||||
	struct labeller_i *li;
 | 
			
		||||
	struct labeller *r = NULL;
 | 
			
		||||
	int already_open;
 | 
			
		||||
	struct label_header *lh;
 | 
			
		||||
	uint64_t sector;
 | 
			
		||||
	int found = 0;
 | 
			
		||||
	char readbuf[LABEL_SCAN_SIZE];
 | 
			
		||||
 | 
			
		||||
	already_open = dev_is_open(dev);
 | 
			
		||||
 | 
			
		||||
	if (!already_open && !dev_open(dev, O_RDONLY)) {
 | 
			
		||||
	if (!dev_open(dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (dev_read(dev, 0, LABEL_SCAN_SIZE, readbuf) != LABEL_SCAN_SIZE) {
 | 
			
		||||
	if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, readbuf)) {
 | 
			
		||||
		log_debug("%s: Failed to read label area", dev_name(dev));
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
@@ -177,7 +183,7 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
 | 
			
		||||
		log_very_verbose("%s: No label detected", dev_name(dev));
 | 
			
		||||
 | 
			
		||||
      out:
 | 
			
		||||
	if (!already_open && !dev_close(dev))
 | 
			
		||||
	if (!dev_close(dev))
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
@@ -199,12 +205,18 @@ int label_remove(struct device *dev)
 | 
			
		||||
 | 
			
		||||
	log_very_verbose("Scanning for labels to wipe from %s", dev_name(dev));
 | 
			
		||||
 | 
			
		||||
	if (!dev_open(dev, O_RDWR)) {
 | 
			
		||||
	if (!dev_open(dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (dev_read(dev, 0, LABEL_SCAN_SIZE, readbuf) != LABEL_SCAN_SIZE) {
 | 
			
		||||
	/*
 | 
			
		||||
	 * We flush the device just in case someone is stupid
 | 
			
		||||
	 * enough to be trying to import an open pv into lvm.
 | 
			
		||||
	 */
 | 
			
		||||
	dev_flush(dev);
 | 
			
		||||
 | 
			
		||||
	if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, readbuf)) {
 | 
			
		||||
		log_debug("%s: Failed to read label area", dev_name(dev));
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
@@ -234,8 +246,8 @@ int label_remove(struct device *dev)
 | 
			
		||||
		if (wipe) {
 | 
			
		||||
			log_info("%s: Wiping label at sector %" PRIu64,
 | 
			
		||||
				 dev_name(dev), sector);
 | 
			
		||||
			if (dev_write(dev, sector << SECTOR_SHIFT, LABEL_SIZE,
 | 
			
		||||
				      buf) != LABEL_SIZE) {
 | 
			
		||||
			if (!dev_write(dev, sector << SECTOR_SHIFT, LABEL_SIZE,
 | 
			
		||||
				       buf)) {
 | 
			
		||||
				log_error("Failed to remove label from %s at "
 | 
			
		||||
					  "sector %" PRIu64, dev_name(dev),
 | 
			
		||||
					  sector);
 | 
			
		||||
@@ -276,7 +288,11 @@ int label_write(struct device *dev, struct label *label)
 | 
			
		||||
	char buf[LABEL_SIZE];
 | 
			
		||||
	struct label_header *lh = (struct label_header *) buf;
 | 
			
		||||
	int r = 1;
 | 
			
		||||
	int already_open;
 | 
			
		||||
 | 
			
		||||
	if (!label->labeller->ops->write) {
 | 
			
		||||
		log_err("Label handler does not support label writes");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((LABEL_SIZE + (label->sector << SECTOR_SHIFT)) > LABEL_SCAN_SIZE) {
 | 
			
		||||
		log_error("Label sector %" PRIu64 " beyond range (%ld)",
 | 
			
		||||
@@ -290,27 +306,27 @@ int label_write(struct device *dev, struct label *label)
 | 
			
		||||
	lh->sector_xl = xlate64(label->sector);
 | 
			
		||||
	lh->offset_xl = xlate32(sizeof(*lh));
 | 
			
		||||
 | 
			
		||||
	if (!label->labeller->ops->write(label, buf))
 | 
			
		||||
	if (!label->labeller->ops->write(label, buf)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lh->crc_xl = xlate32(calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE -
 | 
			
		||||
				      ((void *) &lh->offset_xl - (void *) lh)));
 | 
			
		||||
 | 
			
		||||
	already_open = dev_is_open(dev);
 | 
			
		||||
	if (!already_open && dev_open(dev, O_RDWR)) {
 | 
			
		||||
	if (!dev_open(dev)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_info("%s: Writing label to sector %" PRIu64, dev_name(dev),
 | 
			
		||||
		 label->sector);
 | 
			
		||||
	if (dev_write(dev, label->sector << SECTOR_SHIFT, LABEL_SIZE, buf) !=
 | 
			
		||||
	    LABEL_SIZE) {
 | 
			
		||||
	if (!dev_write(dev, label->sector << SECTOR_SHIFT, LABEL_SIZE, buf)) {
 | 
			
		||||
		log_debug("Failed to write label to %s", dev_name(dev));
 | 
			
		||||
		r = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!already_open && dev_close(dev))
 | 
			
		||||
	if (!dev_close(dev))
 | 
			
		||||
		stack;
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
@@ -327,7 +343,7 @@ int label_verify(struct device *dev)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return l->ops->verify(l, buf, sector);
 | 
			
		||||
	return ((l->ops->verify) ? l->ops->verify(l, buf, sector) : 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void label_destroy(struct label *label)
 | 
			
		||||
 
 | 
			
		||||
@@ -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 LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_LABEL_H
 | 
			
		||||
#define _LVM_LABEL_H
 | 
			
		||||
 | 
			
		||||
#include "cache.h"
 | 
			
		||||
#include "lvm-types.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
#include "uuid.h"
 | 
			
		||||
#include "device.h"
 | 
			
		||||
 | 
			
		||||
@@ -76,7 +84,7 @@ struct label_ops {
 | 
			
		||||
 | 
			
		||||
struct labeller {
 | 
			
		||||
	struct label_ops *ops;
 | 
			
		||||
	void *private;
 | 
			
		||||
	const void *private;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int label_init(void);
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -10,13 +18,12 @@
 | 
			
		||||
#include "defaults.h"
 | 
			
		||||
#include "sharedlib.h"
 | 
			
		||||
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
 | 
			
		||||
static void *_locking_lib = NULL;
 | 
			
		||||
static void (*_end_fn) (void) = NULL;
 | 
			
		||||
static int (*_lock_fn) (struct cmd_context * cmd, const char *resource,
 | 
			
		||||
			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)
 | 
			
		||||
@@ -40,7 +47,7 @@ static void _fin_external_locking(void)
 | 
			
		||||
	_lock_fn = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int init_external_locking(struct locking_type *locking, struct config_tree *cf)
 | 
			
		||||
int init_external_locking(struct locking_type *locking, struct config_tree *cft)
 | 
			
		||||
{
 | 
			
		||||
	const char *libname;
 | 
			
		||||
 | 
			
		||||
@@ -51,19 +58,20 @@ int init_external_locking(struct locking_type *locking, struct config_tree *cf)
 | 
			
		||||
 | 
			
		||||
	locking->lock_resource = _lock_resource;
 | 
			
		||||
	locking->fin_locking = _fin_external_locking;
 | 
			
		||||
	locking->flags = 0;
 | 
			
		||||
 | 
			
		||||
	libname = find_config_str(cf->root, "global/locking_library", '/',
 | 
			
		||||
	libname = find_config_str(cft->root, "global/locking_library",
 | 
			
		||||
				  DEFAULT_LOCKING_LIB);
 | 
			
		||||
 | 
			
		||||
	if (!(_locking_lib = load_shared_library(cf, libname, "locking"))) {
 | 
			
		||||
	if (!(_locking_lib = load_shared_library(cft, libname, "locking"))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Get the functions we need */
 | 
			
		||||
	if (!(_init_fn = dlsym(_locking_lib, "init_locking")) ||
 | 
			
		||||
	if (!(_init_fn = dlsym(_locking_lib, "locking_init")) ||
 | 
			
		||||
	    !(_lock_fn = dlsym(_locking_lib, "lock_resource")) ||
 | 
			
		||||
	    !(_end_fn = dlsym(_locking_lib, "end_locking"))) {
 | 
			
		||||
	    !(_end_fn = dlsym(_locking_lib, "locking_end"))) {
 | 
			
		||||
		log_error("Shared library %s does not contain locking "
 | 
			
		||||
			  "functions", libname);
 | 
			
		||||
		dlclose(_locking_lib);
 | 
			
		||||
@@ -72,5 +80,5 @@ int init_external_locking(struct locking_type *locking, struct config_tree *cf)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_verbose("Loaded external locking library %s", libname);
 | 
			
		||||
	return _init_fn(2, cf);
 | 
			
		||||
	return _init_fn(2, cft, &locking->flags);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
@@ -13,6 +21,7 @@
 | 
			
		||||
#include "defaults.h"
 | 
			
		||||
#include "lvm-file.h"
 | 
			
		||||
#include "lvm-string.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
@@ -34,7 +43,7 @@ static sig_t _oldhandler;
 | 
			
		||||
static sigset_t _fullsigset, _intsigset;
 | 
			
		||||
static int _handler_installed;
 | 
			
		||||
 | 
			
		||||
static int _release_lock(const char *file)
 | 
			
		||||
static int _release_lock(const char *file, int unlock)
 | 
			
		||||
{
 | 
			
		||||
	struct lock_list *ll;
 | 
			
		||||
	struct list *llh, *llt;
 | 
			
		||||
@@ -46,10 +55,11 @@ static int _release_lock(const char *file)
 | 
			
		||||
 | 
			
		||||
		if (!file || !strcmp(ll->res, file)) {
 | 
			
		||||
			list_del(llh);
 | 
			
		||||
			log_very_verbose("Unlocking %s", ll->res);
 | 
			
		||||
 | 
			
		||||
			if (flock(ll->lf, LOCK_NB | LOCK_UN))
 | 
			
		||||
				log_sys_error("flock", ll->res);
 | 
			
		||||
			if (unlock) {
 | 
			
		||||
				log_very_verbose("Unlocking %s", ll->res);
 | 
			
		||||
				if (flock(ll->lf, LOCK_NB | LOCK_UN))
 | 
			
		||||
					log_sys_error("flock", ll->res);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (!flock(ll->lf, LOCK_NB | LOCK_EX) &&
 | 
			
		||||
			    !stat(ll->res, &buf1) &&
 | 
			
		||||
@@ -72,9 +82,14 @@ static int _release_lock(const char *file)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void fin_file_locking(void)
 | 
			
		||||
static void _fin_file_locking(void)
 | 
			
		||||
{
 | 
			
		||||
	_release_lock(NULL);
 | 
			
		||||
	_release_lock(NULL, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _reset_file_locking(void)
 | 
			
		||||
{
 | 
			
		||||
	_release_lock(NULL, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _remove_ctrl_c_handler()
 | 
			
		||||
@@ -90,7 +105,7 @@ static void _remove_ctrl_c_handler()
 | 
			
		||||
	_handler_installed = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _trap_ctrl_c(int signal)
 | 
			
		||||
static void _trap_ctrl_c(int sig)
 | 
			
		||||
{
 | 
			
		||||
	_remove_ctrl_c_handler();
 | 
			
		||||
	log_error("CTRL-c detected: giving up waiting for lock");
 | 
			
		||||
@@ -127,7 +142,7 @@ static int _lock_file(const char *file, int flags)
 | 
			
		||||
		state = 'W';
 | 
			
		||||
		break;
 | 
			
		||||
	case LCK_UNLOCK:
 | 
			
		||||
		return _release_lock(file);
 | 
			
		||||
		return _release_lock(file, 1);
 | 
			
		||||
	default:
 | 
			
		||||
		log_error("Unrecognised lock type: %d", flags & LCK_TYPE_MASK);
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -183,7 +198,8 @@ static int _lock_file(const char *file, int flags)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int file_lock_resource(struct cmd_context *cmd, const char *resource, int flags)
 | 
			
		||||
static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
 | 
			
		||||
			       int flags)
 | 
			
		||||
{
 | 
			
		||||
	char lockfile[PATH_MAX];
 | 
			
		||||
 | 
			
		||||
@@ -195,24 +211,39 @@ int file_lock_resource(struct cmd_context *cmd, const char *resource, int flags)
 | 
			
		||||
		else
 | 
			
		||||
			lvm_snprintf(lockfile, sizeof(lockfile),
 | 
			
		||||
				     "%s/V_%s", _lock_dir, resource);
 | 
			
		||||
 | 
			
		||||
		if (!_lock_file(lockfile, flags))
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		switch (flags & LCK_TYPE_MASK) {
 | 
			
		||||
		case LCK_UNLOCK:
 | 
			
		||||
			lvmcache_unlock_vgname(resource);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			lvmcache_lock_vgname(resource,
 | 
			
		||||
					     (flags & LCK_TYPE_MASK) ==
 | 
			
		||||
					     LCK_READ);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case LCK_LV:
 | 
			
		||||
		switch (flags & LCK_TYPE_MASK) {
 | 
			
		||||
		case LCK_UNLOCK:
 | 
			
		||||
			log_debug("Unlocking LV %s", resource);
 | 
			
		||||
			if (!lv_resume_if_active(cmd, resource))
 | 
			
		||||
				return 0;
 | 
			
		||||
			break;
 | 
			
		||||
		case LCK_READ:
 | 
			
		||||
			log_debug("Locking LV %s (R)", resource);
 | 
			
		||||
			if (!lv_activate(cmd, resource))
 | 
			
		||||
				return 0;
 | 
			
		||||
			break;
 | 
			
		||||
		case LCK_WRITE:
 | 
			
		||||
			log_debug("Locking LV %s (W)", resource);
 | 
			
		||||
			if (!lv_suspend_if_active(cmd, resource))
 | 
			
		||||
				return 0;
 | 
			
		||||
			break;
 | 
			
		||||
		case LCK_EXCL:
 | 
			
		||||
			log_debug("Locking LV %s (EX)", resource);
 | 
			
		||||
			if (!lv_deactivate(cmd, resource))
 | 
			
		||||
				return 0;
 | 
			
		||||
			break;
 | 
			
		||||
@@ -229,14 +260,16 @@ int file_lock_resource(struct cmd_context *cmd, const char *resource, int flags)
 | 
			
		||||
	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->fin_locking = fin_file_locking;
 | 
			
		||||
	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))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
@@ -11,18 +19,21 @@
 | 
			
		||||
#include "lvm-string.h"
 | 
			
		||||
#include "activate.h"
 | 
			
		||||
#include "toolcontext.h"
 | 
			
		||||
#include "memlock.h"
 | 
			
		||||
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
static struct locking_type _locking;
 | 
			
		||||
static sigset_t _oldset;
 | 
			
		||||
 | 
			
		||||
static int _lock_count = 0;	/* Number of locks held */
 | 
			
		||||
static int _vg_lock_count = 0;		/* Number of locks held */
 | 
			
		||||
static int _vg_write_lock_held = 0;	/* VG write lock held? */
 | 
			
		||||
static int _signals_blocked = 0;
 | 
			
		||||
 | 
			
		||||
static void _block_signals(void)
 | 
			
		||||
static void _block_signals(int flags)
 | 
			
		||||
{
 | 
			
		||||
	sigset_t set;
 | 
			
		||||
 | 
			
		||||
@@ -47,7 +58,7 @@ static void _block_signals(void)
 | 
			
		||||
static void _unblock_signals(void)
 | 
			
		||||
{
 | 
			
		||||
	/* Don't unblock signals while any locks are held */
 | 
			
		||||
	if (!_signals_blocked || _lock_count)
 | 
			
		||||
	if (!_signals_blocked || _vg_lock_count)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (sigprocmask(SIG_SETMASK, &_oldset, NULL)) {
 | 
			
		||||
@@ -60,37 +71,79 @@ static void _unblock_signals(void)
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void _update_lock_count(int flags)
 | 
			
		||||
static void _lock_memory(int flags)
 | 
			
		||||
{
 | 
			
		||||
	if (!(_locking.flags & LCK_PRE_MEMLOCK))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if ((flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_SUSPEND)
 | 
			
		||||
		memlock_inc();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _unlock_memory(int flags)
 | 
			
		||||
{
 | 
			
		||||
	if (!(_locking.flags & LCK_PRE_MEMLOCK))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if ((flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_RESUME)
 | 
			
		||||
		memlock_dec();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void reset_locking(void)
 | 
			
		||||
{
 | 
			
		||||
	int was_locked = _vg_lock_count;
 | 
			
		||||
 | 
			
		||||
	_vg_lock_count = 0;
 | 
			
		||||
	_vg_write_lock_held = 0;
 | 
			
		||||
 | 
			
		||||
	_locking.reset_locking();
 | 
			
		||||
 | 
			
		||||
	if (was_locked)
 | 
			
		||||
		_unblock_signals();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void _update_vg_lock_count(int flags)
 | 
			
		||||
{
 | 
			
		||||
	if ((flags & LCK_SCOPE_MASK) != LCK_VG)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)
 | 
			
		||||
		_lock_count--;
 | 
			
		||||
		_vg_lock_count--;
 | 
			
		||||
	else
 | 
			
		||||
		_lock_count++;
 | 
			
		||||
		_vg_lock_count++;
 | 
			
		||||
 | 
			
		||||
	/* We don't bother to reset this until all VG locks are dropped */
 | 
			
		||||
	if ((flags & LCK_TYPE_MASK) == LCK_WRITE)
 | 
			
		||||
		_vg_write_lock_held = 1;
 | 
			
		||||
	else if (!_vg_lock_count)
 | 
			
		||||
		_vg_write_lock_held = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Select a locking type
 | 
			
		||||
 */
 | 
			
		||||
int init_locking(int type, struct config_tree *cf)
 | 
			
		||||
int init_locking(int type, struct config_tree *cft)
 | 
			
		||||
{
 | 
			
		||||
	switch (type) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		init_no_locking(&_locking, cf);
 | 
			
		||||
		init_no_locking(&_locking, cft);
 | 
			
		||||
		log_print("WARNING: Locking disabled. Be careful! "
 | 
			
		||||
			  "This could corrupt your metadata.");
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	case 1:
 | 
			
		||||
		if (!init_file_locking(&_locking, cf))
 | 
			
		||||
		if (!init_file_locking(&_locking, cft))
 | 
			
		||||
			break;
 | 
			
		||||
		log_very_verbose("File-based locking enabled.");
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LIBDL
 | 
			
		||||
	case 2:
 | 
			
		||||
		if (!init_external_locking(&_locking, cf))
 | 
			
		||||
		if (!init_external_locking(&_locking, cft))
 | 
			
		||||
			break;
 | 
			
		||||
		log_very_verbose("External locking enabled.");
 | 
			
		||||
		return 1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		log_error("Unknown locking type requested.");
 | 
			
		||||
@@ -103,7 +156,7 @@ int init_locking(int type, struct config_tree *cf)
 | 
			
		||||
	/* FIXME Ensure only read ops are permitted */
 | 
			
		||||
	log_verbose("Locking disabled - only read operations permitted.");
 | 
			
		||||
 | 
			
		||||
	init_no_locking(&_locking, cf);
 | 
			
		||||
	init_no_locking(&_locking, cft);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -147,16 +200,19 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
 | 
			
		||||
 * VG locking is by VG name.
 | 
			
		||||
 * FIXME This should become VG uuid.
 | 
			
		||||
 */
 | 
			
		||||
int _lock_vol(struct cmd_context *cmd, const char *resource, int flags)
 | 
			
		||||
static int _lock_vol(struct cmd_context *cmd, const char *resource, int flags)
 | 
			
		||||
{
 | 
			
		||||
	_block_signals();
 | 
			
		||||
	_block_signals(flags);
 | 
			
		||||
	_lock_memory(flags);
 | 
			
		||||
 | 
			
		||||
	if (!(_locking.lock_resource(cmd, resource, flags))) {
 | 
			
		||||
		_unlock_memory(flags);
 | 
			
		||||
		_unblock_signals();
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_update_lock_count(flags);
 | 
			
		||||
	_update_vg_lock_count(flags);
 | 
			
		||||
	_unlock_memory(flags);
 | 
			
		||||
	_unblock_signals();
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
@@ -174,7 +230,7 @@ int lock_vol(struct cmd_context *cmd, const char *vol, int flags)
 | 
			
		||||
			return 0;
 | 
			
		||||
	case LCK_LV:
 | 
			
		||||
		/* Suspend LV if it's active. */
 | 
			
		||||
		strncpy(resource, (char *) vol, sizeof(resource));
 | 
			
		||||
		strncpy(resource, vol, sizeof(resource));
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		log_error("Unrecognised lock scope: %d",
 | 
			
		||||
@@ -194,3 +250,44 @@ int lock_vol(struct cmd_context *cmd, const char *vol, int flags)
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Unlock list of LVs */
 | 
			
		||||
int unlock_lvs(struct cmd_context *cmd, struct list *lvs)
 | 
			
		||||
{
 | 
			
		||||
	struct list *lvh;
 | 
			
		||||
	struct logical_volume *lv;
 | 
			
		||||
 | 
			
		||||
	list_iterate(lvh, lvs) {
 | 
			
		||||
		lv = list_item(lvh, struct lv_list)->lv;
 | 
			
		||||
		unlock_lv(cmd, lv->lvid.s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Lock a list of LVs */
 | 
			
		||||
int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags)
 | 
			
		||||
{
 | 
			
		||||
	struct list *lvh;
 | 
			
		||||
	struct logical_volume *lv;
 | 
			
		||||
 | 
			
		||||
	list_iterate(lvh, lvs) {
 | 
			
		||||
		lv = list_item(lvh, struct lv_list)->lv;
 | 
			
		||||
		if (!lock_vol(cmd, lv->lvid.s, flags)) {
 | 
			
		||||
			log_error("Failed to suspend %s", lv->name);
 | 
			
		||||
			list_uniterate(lvh, lvs, lvh) {
 | 
			
		||||
				lv = list_item(lvh, struct lv_list)->lv;
 | 
			
		||||
				unlock_lv(cmd, lv->lvid.s);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int vg_write_lock_held(void)
 | 
			
		||||
{
 | 
			
		||||
	return _vg_write_lock_held;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
@@ -11,6 +19,8 @@
 | 
			
		||||
 | 
			
		||||
int init_locking(int type, struct config_tree *cf);
 | 
			
		||||
void fin_locking(void);
 | 
			
		||||
void reset_locking(void);
 | 
			
		||||
int vg_write_lock_held(void);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * LCK_VG:
 | 
			
		||||
@@ -32,7 +42,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
 | 
			
		||||
/*
 | 
			
		||||
 * Lock type - these numbers are the same as VMS and the IBM DLM
 | 
			
		||||
 */
 | 
			
		||||
#define LCK_TYPE_MASK	0x000000FF
 | 
			
		||||
#define LCK_TYPE_MASK	0x00000007
 | 
			
		||||
 | 
			
		||||
#define LCK_NULL	0x00000000	/* LCK$_NLMODE */
 | 
			
		||||
#define LCK_READ	0x00000001	/* LCK$_CRMODE */
 | 
			
		||||
@@ -40,20 +50,20 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
 | 
			
		||||
					/* LCK$_PRMODE */
 | 
			
		||||
#define LCK_WRITE	0x00000004	/* LCK$_PWMODE */
 | 
			
		||||
#define LCK_EXCL	0x00000005	/* LCK$_EXMODE */
 | 
			
		||||
#define LCK_UNLOCK      0x00000010	/* This is ours */
 | 
			
		||||
#define LCK_UNLOCK      0x00000006	/* This is ours */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Lock scope
 | 
			
		||||
 */
 | 
			
		||||
#define LCK_SCOPE_MASK	0x0000FF00
 | 
			
		||||
#define LCK_SCOPE_MASK	0x00000008
 | 
			
		||||
#define LCK_VG		0x00000000
 | 
			
		||||
#define LCK_LV		0x00000100
 | 
			
		||||
#define LCK_LV		0x00000008
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Lock bits
 | 
			
		||||
 */
 | 
			
		||||
#define LCK_NONBLOCK	0x00010000	/* Don't block waiting for lock? */
 | 
			
		||||
#define LCK_HOLD	0x00020000	/* Hold lock when lock_vol returns? */
 | 
			
		||||
#define LCK_NONBLOCK	0x00000010	/* Don't block waiting for lock? */
 | 
			
		||||
#define LCK_HOLD	0x00000020	/* Hold lock when lock_vol returns? */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Common combinations
 | 
			
		||||
@@ -62,10 +72,16 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
 | 
			
		||||
#define LCK_VG_WRITE		(LCK_VG | LCK_WRITE | LCK_HOLD)
 | 
			
		||||
#define LCK_VG_UNLOCK		(LCK_VG | LCK_UNLOCK)
 | 
			
		||||
 | 
			
		||||
#define LCK_LV_DEACTIVATE	(LCK_LV | LCK_EXCL)
 | 
			
		||||
#define LCK_LV_SUSPEND		(LCK_LV | LCK_WRITE)
 | 
			
		||||
#define LCK_LV_ACTIVATE		(LCK_LV | LCK_READ)
 | 
			
		||||
#define LCK_LV_RESUME		(LCK_LV | LCK_UNLOCK | LCK_NONBLOCK)
 | 
			
		||||
#define LCK_LV_UNLOCK		(LCK_LV | LCK_UNLOCK)
 | 
			
		||||
#define LCK_LV_ACTIVATE		(LCK_LV | LCK_READ)
 | 
			
		||||
#define LCK_LV_DEACTIVATE	(LCK_LV | LCK_EXCL)
 | 
			
		||||
 | 
			
		||||
#define unlock_lv(cmd, vol)	lock_vol(cmd, vol, LCK_LV_UNLOCK)
 | 
			
		||||
#define unlock_vg(cmd, vol)	lock_vol(cmd, vol, LCK_VG_UNLOCK)
 | 
			
		||||
 | 
			
		||||
/* Process list of LVs */
 | 
			
		||||
int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags);
 | 
			
		||||
int unlock_lvs(struct cmd_context *cmd, struct list *lvs);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,26 +1,37 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2001 Sistina Software (UK) Limited.
 | 
			
		||||
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is released under the LGPL.
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
typedef int (*lock_resource_fn)(struct cmd_context *cmd, const char *resource, 
 | 
			
		||||
				int flags);
 | 
			
		||||
typedef int (*lock_resource_fn) (struct cmd_context * cmd, const char *resource,
 | 
			
		||||
				 int flags);
 | 
			
		||||
 | 
			
		||||
typedef void (*fin_lock_fn)(void);
 | 
			
		||||
typedef void (*fin_lock_fn) (void);
 | 
			
		||||
typedef void (*reset_lock_fn) (void);
 | 
			
		||||
 | 
			
		||||
#define LCK_PRE_MEMLOCK	0x00000001	/* Is memlock() needed before calls? */
 | 
			
		||||
 | 
			
		||||
struct locking_type {
 | 
			
		||||
	uint32_t flags;
 | 
			
		||||
	lock_resource_fn lock_resource;
 | 
			
		||||
 | 
			
		||||
	reset_lock_fn reset_locking;
 | 
			
		||||
	fin_lock_fn fin_locking;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Locking types
 | 
			
		||||
 */
 | 
			
		||||
@@ -29,4 +40,3 @@ int init_no_locking(struct locking_type *locking, struct config_tree *cf);
 | 
			
		||||
int init_file_locking(struct locking_type *locking, struct config_tree *cf);
 | 
			
		||||
 | 
			
		||||
int init_external_locking(struct locking_type *locking, struct config_tree *cf);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user