1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-24 16:23:50 +03:00

Compare commits

..

131 Commits

Author SHA1 Message Date
Alasdair Kergon
f95dbff71f fix makefile 2006-04-19 17:32:05 +00:00
Alasdair Kergon
098f6830a6 fix makefile 2006-04-19 17:24:00 +00:00
Alasdair Kergon
d1ecebdb52 post-release 2006-04-19 17:21:39 +00:00
Alasdair Kergon
590b654251 fix makefile 2006-04-19 17:15:08 +00:00
Alasdair Kergon
3bf190c8ab update version 2006-04-19 16:41:03 +00:00
Alasdair Kergon
dcca7638e0 make pkgconfig installation step optional, and clean up generated files 2006-04-19 16:38:56 +00:00
Alasdair Kergon
70e45ad37b Check for libsepol.
Add some cflow & scope support.
Separate out DEFS from CFLAGS.
Remove inlines and use unique function names.
2006-04-19 15:33:07 +00:00
Alasdair Kergon
db88210289 configure/makefile tidying + pkg-config support. 2006-04-19 15:23:10 +00:00
Alasdair Kergon
d2e0d96cc3 post-release 2006-04-14 21:39:32 +00:00
Alasdair Kergon
3feba82ccc pre-release 2006-04-14 21:11:38 +00:00
Alasdair Kergon
db924da231 vgrename accepts vgid and exported VG. 2006-04-13 21:08:29 +00:00
Alasdair Kergon
fc55ae7e6d Add --partial to pvs. 2006-04-13 17:51:40 +00:00
Alasdair Kergon
86e757a6ad When choosing between identically-named VGs, also consider creation_host. 2006-04-13 17:32:24 +00:00
Alasdair Kergon
4790715cd3 Fix vgexport/vgimport to set/reset PV exported flag so pv_attr is correct.
Add vgid to struct physical_volume and pass with vg_name to some functions.
2006-04-12 21:23:04 +00:00
Alasdair Kergon
e7e9c60042 If two or more VGs are found with the same name, use one that is not exported. 2006-04-12 17:54:11 +00:00
Alasdair Kergon
1c3bc52cc4 tidy 2006-04-11 19:09:55 +00:00
Alasdair Kergon
5227dff0e1 When scanning, also record whether or not VG is exported. 2006-04-11 17:42:15 +00:00
Alasdair Kergon
33f0b5b7c2 Use lvmcache_update_vgname_and_id throughout. 2006-04-11 16:00:26 +00:00
Alasdair Kergon
0a02968303 Whenever vgname is captured, also capture vgid. 2006-04-11 13:55:59 +00:00
Alasdair Kergon
f7bf658c07 Capture vgid in more places. 2006-04-10 22:09:00 +00:00
Alasdair Kergon
8d16a0abad lv_is_visible() 2006-04-07 17:41:56 +00:00
Alasdair Kergon
c974b97ca3 missing vg_name initialisation 2006-04-07 14:14:31 +00:00
Alasdair Kergon
b8025bfebd Update extent size information in vgchange and vgcreate man pages 2006-04-06 21:15:14 +00:00
Alasdair Kergon
30323b253f Bring dmsetup man page up-to-date. 2006-04-06 16:20:40 +00:00
Alasdair Kergon
535c3ede96 more snapshot code tidying 2006-04-06 14:06:27 +00:00
Alasdair Kergon
89fed8ca33 Introduce origin_from_cow() 2006-04-06 13:39:16 +00:00
Alasdair Kergon
f43c77aaed pvremove without -f now fails if there's no PV label. 2006-04-05 22:24:16 +00:00
Alasdair Kergon
96c676b371 Support lvconvert -s. 2006-04-05 20:43:23 +00:00
Alasdair Kergon
113047e1a2 Suppress locking library load failure message if --ignorelockingfailure. 2006-04-03 18:43:55 +00:00
Alasdair Kergon
abed57cb53 Use name-based device refs if kernel doesn't support device number refs.
Fix memory leak (struct dm_ioctl) when struct dm_task is reused.
2006-04-03 15:56:02 +00:00
Alasdair Kergon
c01a800a6b If _create_and_load_v4 fails part way through, revert the creation. 2006-03-30 15:15:47 +00:00
Patrick Caulfield
d648832a2d allow new cman to shutdown on request. 2006-03-21 10:31:08 +00:00
Patrick Caulfield
f06833fbd2 Make sure it compiles if gulm is NOT selected AND using an old libcman.h 2006-03-15 08:36:11 +00:00
Patrick Caulfield
c561addc94 Get clvmd to use libcman rather than cman ioctl calls. This makes
it forward-compatible with the new userland CMAN in cluster head.

To build it you will need the libcman header & library installed.
2006-03-14 14:18:34 +00:00
Alasdair Kergon
702f5f1f4c Remove an incorrect unlock_vg() from process_each_lv(). 2006-03-10 15:41:04 +00:00
Alasdair Kergon
1273f179e8 Propagate partial mode around cluster. 2006-03-09 22:34:13 +00:00
Alasdair Kergon
5d02f60bde dmeventd thread/fifo fixes. 2006-03-09 21:33:59 +00:00
Alasdair Kergon
4cf7a108e8 Fix archive file expiration. 2006-03-07 15:43:05 +00:00
Alasdair Kergon
42635c3938 Add file & line to dm_strdup_aux(). 2006-02-23 19:11:51 +00:00
Alasdair Kergon
ed43dc842b A setgeometry implementation. [untested] 2006-02-20 23:55:58 +00:00
Alasdair Kergon
49d4db6cd2 post-release 2006-02-08 23:24:02 +00:00
Alasdair Kergon
ea80ab2cae post-release
fix dmeventd build
2006-02-08 23:23:19 +00:00
Alasdair Kergon
382e808b8d fix mirror log parm count 2006-02-08 14:14:13 +00:00
Alasdair Kergon
846befa7e0 release 2006-02-07 16:33:48 +00:00
Alasdair Kergon
74dd29f843 add clustered log uuid 2006-02-06 20:18:10 +00:00
Alasdair Kergon
b0473bffcb remove a dmeventd_mirror syslog message 2006-02-06 19:34:45 +00:00
Alasdair Kergon
24dd9ab1a7 Change prefix for clustered log from "clustered " to "clustered_" 2006-02-06 19:32:18 +00:00
Alasdair Kergon
49d3037e87 fix tabs 2006-02-03 21:34:11 +00:00
Alasdair Kergon
37ad2bd4e8 tweak clvmd makefile 2006-02-03 21:31:00 +00:00
Alasdair Kergon
7d7b332b02 Temporary device_exists() fixes. 2006-02-03 19:44:59 +00:00
Alasdair Kergon
ac033b8612 Use supplied full dso name. 2006-02-03 19:41:34 +00:00
Alasdair Kergon
a7b98dfe25 suspend using existing LV metadata; vgreduce then needs partial flag 2006-02-03 19:36:20 +00:00
Alasdair Kergon
7fb7c86c46 fix libdevmapper-event-mirror liblvm2cmd link search path 2006-02-03 14:48:38 +00:00
Alasdair Kergon
ed036598a9 Add exported functions to set uid, gid and mode. [Bastian Blank] 2006-02-03 14:23:22 +00:00
Alasdair Kergon
160bb70cdf Add %.so: %.a make template rule. 2006-02-02 19:16:47 +00:00
Alasdair Kergon
c2e61f3c21 autoconf LIB_SUFFIX 2006-02-02 18:39:23 +00:00
Alasdair Kergon
18218467f3 remove unnecessary 0 in format string 2006-02-02 17:23:04 +00:00
Alasdair Kergon
17e298ad2a Only do lockfs filesystem sync when suspending snapshots.
Switchover library building to use LIB_SUFFIX.
2006-01-31 14:52:30 +00:00
Alasdair Kergon
d031a374f9 Rename _log to dm_log and export.
Fix misc compile-time warnings.
2006-01-31 14:50:38 +00:00
Alasdair Kergon
55f69c98cb Add dm_tree_skip_lockfs. 2006-01-30 23:36:04 +00:00
Alasdair Kergon
71f2e4306d Tidy some comments/messages. 2006-01-27 20:52:21 +00:00
Alasdair Kergon
f8af23a025 Fix renamed dso. 2006-01-27 20:51:36 +00:00
Alasdair Kergon
4ef55a6cd3 dmeventd thread termination fix 2006-01-27 20:50:01 +00:00
Alasdair Kergon
312f866723 some init_client cleanup 2006-01-27 20:49:13 +00:00
Alasdair Kergon
0ebe1f6dec More dmeventd mirror cleanups. 2006-01-27 20:48:19 +00:00
Alasdair Kergon
2ad92e0e6e Remove avoidable dmeventd mirror forking. 2006-01-27 20:47:20 +00:00
Alasdair Kergon
ac8823cdcf Fix libdevmapper event daemon_running status. 2006-01-27 20:46:06 +00:00
Alasdair Kergon
77565f7ee4 Replace deprecated signal functions. 2006-01-27 20:45:17 +00:00
Alasdair Kergon
d656d90fa8 Use split_dm_name in dmeventd mirror code. 2006-01-27 20:43:52 +00:00
Alasdair Kergon
175b3b0834 When suspending, dmeventd deregistration needs to use existing details
not precommitted ones.
2006-01-27 20:39:37 +00:00
Alasdair Kergon
7477e6b714 Fix dmeventd sharedlib path & start tidying registration code. 2006-01-27 20:13:12 +00:00
Alasdair Kergon
cd6568db69 fix dmevent registration return codes 2006-01-27 20:01:45 +00:00
Alasdair Kergon
6aff325fb2 Add config file setting: dmeventd/mirror_library 2006-01-27 19:05:05 +00:00
Alasdair Kergon
0d603cfe9c Rename register_dev; fix missing initialisation; reduce number of ifdefs. 2006-01-27 18:38:14 +00:00
Alasdair Kergon
34a1f14a17 Fix dm_strdup debug definition. 2006-01-11 15:40:54 +00:00
Alasdair Kergon
efe1c8a070 Fix dm_strdup debug definition. 2006-01-10 22:19:41 +00:00
Alasdair Kergon
1575844344 Fix hash function to avoid using a negative array offset. 2006-01-09 20:35:24 +00:00
Alasdair Kergon
221ac1c208 vgreduce remove mirror images
adjust block_on_error version no detection for RHEL4U3
2006-01-04 18:09:52 +00:00
Alasdair Kergon
57442db759 Don't inline _find in hash.c and tidy signed/unsigned etc. 2006-01-04 16:07:27 +00:00
Alasdair Kergon
5fdb3e7cd6 Fix libdevmapper.h #endif 2006-01-04 16:05:44 +00:00
Alasdair Kergon
96f259726c Fix dmsetup version driver version 2006-01-03 20:53:57 +00:00
Alasdair Kergon
4936efba5e Always print warning if activation is disabled. 2005-12-22 16:13:38 +00:00
Alasdair Kergon
d5a3559a2f Add --mirrorsonly arg to vgreduce. (Doesn't handle mirrors yet.) 2005-12-21 21:21:45 +00:00
Alasdair Kergon
114a1c7f52 some fixes 2005-12-21 20:24:22 +00:00
Alasdair Kergon
ce5265c203 fix libdevmapper-event include 2005-12-21 19:45:16 +00:00
Alasdair Kergon
1a575d926f vgreduce replaces active LVs with error segment before removing them. 2005-12-21 18:51:50 +00:00
Alasdair Kergon
85c818a39e read/write loop fixes 2005-12-19 22:56:47 +00:00
Alasdair Kergon
4ffa2defe4 fixme 2005-12-19 22:36:04 +00:00
Alasdair Kergon
8825157fbb Change dm_tree_node_add_mirror_target_log parm order 2005-12-19 21:03:17 +00:00
Alasdair Kergon
966d608dc5 Set block_on_error parameter if available.
Add target_version.
2005-12-19 21:01:39 +00:00
Alasdair Kergon
b808c89471 Add details to format1 'Invalid LV in extent map' error message. 2005-12-19 16:28:35 +00:00
Alasdair Kergon
75d4e6490f ability to pass log flags to libdevmapper 2005-12-13 15:57:32 +00:00
Alasdair Kergon
a82775f544 Add sync, nosync and block_on_error mirror log parameters.
Add hweight32.
2005-12-13 15:49:27 +00:00
Alasdair Kergon
6a22ad0171 comments 2005-12-13 13:34:31 +00:00
Alasdair Kergon
c854e88186 comment 2005-12-13 13:32:19 +00:00
Alasdair Kergon
d02203060c Fix lvscan snapshot full display.
dmeventd fixes
2005-12-08 17:49:34 +00:00
Alasdair Kergon
cf703b0433 Fix dmeventd build. 2005-12-05 11:16:48 +00:00
Alasdair Kergon
c0197a72d3 fix exports 2005-12-02 21:00:33 +00:00
Alasdair Kergon
e5a543e283 More dmeventd support. 2005-12-02 20:35:07 +00:00
Alasdair Kergon
b8b029b7d3 Add mirror dmeventd library 2005-12-02 19:52:06 +00:00
Alasdair Kergon
370f368b1a post-release 2005-12-02 17:24:06 +00:00
Alasdair Kergon
8288b45b4f 1.02.02 2005-12-02 15:44:18 +00:00
Alasdair Kergon
fe529faf8e dmeventd 2005-12-02 15:41:14 +00:00
Alasdair Kergon
ab931b177d dmeventd updates 2005-12-02 15:39:16 +00:00
Alasdair Kergon
9aa3465513 Export dm_task_update_nodes.
Use names instead of numbers in messages when ioctls fail.
2005-12-01 23:11:41 +00:00
Alasdair Kergon
6c70fc1a6c Add some FIXMEs to libdm-event. 2005-11-30 18:35:03 +00:00
Alasdair Kergon
1ccc39962a more lvconvert mirror code 2005-11-29 18:20:23 +00:00
Alasdair Kergon
99c941fc85 Allow signed mirrors arguments.
Move create_mirror_log() into toollib.
2005-11-28 21:00:37 +00:00
Alasdair Kergon
19729fdcc2 Determine parallel PVs to avoid with ALLOC_NORMAL allocation. (untested) 2005-11-28 20:01:00 +00:00
Alasdair Kergon
02e17998ce alloc avoids parallel pvs when supplied 2005-11-24 21:23:55 +00:00
Alasdair Kergon
459e00c67a preparation for parallel_areas changes to allocation code 2005-11-24 20:58:44 +00:00
Alasdair Kergon
292f665650 Fix lv_empty. 2005-11-24 18:46:51 +00:00
Alasdair Kergon
93bbb79569 _find_parallel_space -> _find_segment_space 2005-11-24 18:00:47 +00:00
Alasdair Kergon
273e724f2b post_release 2005-11-23 18:45:30 +00:00
Alasdair Kergon
5d2615c56f post-release 2005-11-23 18:44:59 +00:00
Alasdair Kergon
bfaaf21330 2.02.01 2005-11-23 18:42:45 +00:00
Alasdair Kergon
dcb8415b7a 1.02.01 2005-11-23 18:36:33 +00:00
Alasdair Kergon
699e1c75ce Fix lvdisplay cmdline to accept snapshots. 2005-11-23 16:16:39 +00:00
Alasdair Kergon
465b6e613e Fix open RO->RW promotions. 2005-11-23 16:07:40 +00:00
Alasdair Kergon
05fa105855 Resume snapshot-origins last. 2005-11-22 20:00:35 +00:00
Alasdair Kergon
d7a0cdebe5 Remove a resolved FIXME. 2005-11-22 19:37:14 +00:00
Alasdair Kergon
b049ab31eb Suppress unnecessary resumes. 2005-11-22 19:31:20 +00:00
Alasdair Kergon
6db4dcff7a Drop leading zeros from dm_format_dev.
Suppress attempt to reload identical table.
2005-11-22 18:43:12 +00:00
Alasdair Kergon
3eeaef00ec Additional LVM- prefix matching for transitional period. 2005-11-12 22:46:48 +00:00
Alasdair Kergon
8bf4c38a00 lvcreate vg_revert 2005-11-12 22:42:08 +00:00
Alasdair Kergon
3a32b09ad1 A missing vg_revert in an error path. 2005-11-12 22:00:50 +00:00
Alasdair Kergon
6315982752 more debug fixes 2005-11-11 16:16:37 +00:00
Alasdair Kergon
374a171e82 Fix selinux compile. 2005-11-10 18:31:17 +00:00
Alasdair Kergon
fc5d801f91 fix debug linking 2005-11-10 16:33:04 +00:00
Alasdair Kergon
5146641848 post-release 2005-11-10 16:06:29 +00:00
Alasdair Kergon
cdd0ac42cf pre-release 2005-11-10 15:27:19 +00:00
146 changed files with 5739 additions and 2252 deletions

View File

@@ -24,8 +24,13 @@ endif
SUBDIRS += lib tools daemons
ifeq ("@DMEVENTD@", "yes")
SUBDIRS += dmeventd
endif
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS += daemons/clvmd \
dmeventd \
lib/format1 \
lib/format_pool \
lib/locking \
@@ -40,13 +45,25 @@ include make.tmpl
daemons: lib
lib: include
tools: lib
po: tools daemons
dmeventd: tools
po: tools daemons dmeventd
ifeq ("@INTL@", "yes")
lib.pofile: include.pofile
tools.pofile: lib.pofile
daemons.pofile: lib.pofile
po.pofile: tools.pofile daemons.pofile
dmeventd.pofile: tools.pofile
po.pofile: tools.pofile daemons.pofile dmeventd.pofile
pofile: po.pofile
endif
ifneq ("@CFLOW_CMD@", "")
tools.cflow: lib.cflow
cflow: tools.cflow
endif
ifneq ("@CSCOPE_CMD@", "")
cscope.out: tools
@CSCOPE_CMD@ -b -R
all: cscope.out
endif

View File

@@ -1 +1 @@
2.02.00-cvs (2005-10-16)
2.02.04-cvs (2006-04-14)

View File

@@ -1,5 +1,63 @@
Version 2.02.00 -
Version 2.02.04 -
=================================
Check for libsepol.
Add some cflow & scope support.
Separate out DEFS from CFLAGS.
Remove inlines and use unique function names.
Version 2.02.03 - 14th April 2006
=================================
vgrename accepts vgid and exported VG.
Add --partial to pvs.
When choosing between identically-named VGs, also consider creation_host.
Provide total log suppression with 2.
Fix vgexport/vgimport to set/reset PV exported flag so pv_attr is correct.
Add vgid to struct physical_volume and pass with vg_name to some functions.
If two or more VGs are found with the same name, use one that is not exported.
Whenever vgname is captured, also capture vgid and whether exported.
Remove an incorrect unlock_vg() from process_each_lv().
Update extent size information in vgchange and vgcreate man pages.
Introduce origin_from_cow() and lv_is_visible().
pvremove without -f now fails if there's no PV label.
Support lvconvert -s.
Suppress locking library load failure message if --ignorelockingfailure.
Propagate partial mode around cluster.
Fix archive file expiration.
Fix dmeventd build.
clvmd now uses libcman rather than cman ioctls.
clvmd will allow new cman to shutdown on request.
Version 2.02.02 - 7th February 2006
===================================
Add %.so: %.a make template rule.
Switchover library building to use LIB_SUFFIX.
Only do lockfs filesystem sync when suspending snapshots.
Always print warning if activation is disabled.
vgreduce removes mirror images.
Add --mirrorsonly to vgreduce.
vgreduce replaces active LVs with error segment before removing them.
Set block_on_error parameter if available.
Add target_version.
Add details to format1 'Invalid LV in extent map' error message.
Fix lvscan snapshot full display.
Bring lvdisplay man page example into line.
Add mirror dmeventd library.
Add some activation logic to remove_mirror_images().
lvconvert can remove specified PVs from a mirror.
lvconvert turns an existing LV into a mirror.
Allow signed mirrors arguments.
Move create_mirror_log() into toollib.
Determine parallel PVs to avoid with ALLOC_NORMAL allocation.
Fix lv_empty.
Version 2.02.01 - 23rd November 2005
====================================
Fix lvdisplay cmdline to accept snapshots.
Fix open RO->RW promotion.
Fix missing vg_revert in lvcreate error path.
Version 2.02.00 - 10th November 2005
====================================
Extend allocation areas to avoid overflow with contiguous with other PVs.
Stop lvcreate attempting to wipe zero or error segments.
Added new lvs table attributes.

View File

@@ -1,4 +1,51 @@
Version 1.02.00 -
Version 1.02.06 -
=============================
Version 1.02.05 - 19 Apr 2006
=============================
Separate install_include target in makefiles.
Separate out DEFS from CFLAGS.
Support pkg-config.
Check for libsepol.
Version 1.02.04 - 14 Apr 2006
=============================
Bring dmsetup man page up-to-date.
Use name-based device refs if kernel doesn't support device number refs.
Fix memory leak (struct dm_ioctl) when struct dm_task is reused.
If _create_and_load_v4 fails part way through, revert the creation.
dmeventd thread/fifo fixes.
Add file & line to dm_strdup_aux().
Add setgeometry.
Version 1.02.03 - 7 Feb 2006
============================
Add exported functions to set uid, gid and mode.
Rename _log to dm_log and export.
Add dm_tree_skip_lockfs.
Fix dm_strdup debug definition.
Fix hash function to avoid using a negative array offset.
Don't inline _find in hash.c and tidy signed/unsigned etc.
Fix libdevmapper.h #endif.
Fix dmsetup version driver version.
Add sync, nosync and block_on_error mirror log parameters.
Add hweight32.
Fix dmeventd build.
Version 1.02.02 - 2 Dec 2005
============================
dmeventd added.
Export dm_task_update_nodes.
Use names instead of numbers in messages when ioctls fail.
Version 1.02.01 - 23 Nov 2005
=============================
Resume snapshot-origins last.
Drop leading zeros from dm_format_dev.
Suppress attempt to reload identical table.
Additional LVM- prefix matching for transitional period.
Version 1.02.00 - 10 Nov 2005
=============================
Added activation functions to library.
Added return macros.

237
configure vendored
View File

@@ -310,7 +310,7 @@ ac_includes_default="\
#endif"
ac_default_prefix=/usr
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB CPP EGREP ALLOCA LIBOBJS POW_LIB MSGFMT MODPROBE_CMD JOBS STATIC_LINK LVM1 POOL SNAPSHOTS MIRRORS OWNER GROUP COPTIMISE_FLAG CLDFLAGS CLDWHOLEARCHIVE CLDNOWHOLEARCHIVE LDDEPS SOFLAG LVM_VERSION LVM1_FALLBACK DEBUG DEVMAPPER HAVE_LIBDL HAVE_SELINUX CMDLIB LOCALEDIR CONFDIR STATICDIR INTL_PACKAGE INTL CLVMD CLUSTER FSADM LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB CFLOW_CMD CSCOPE_CMD CPP EGREP ALLOCA LIBOBJS POW_LIB MSGFMT MODPROBE_CMD JOBS STATIC_LINK LVM1 POOL SNAPSHOTS MIRRORS OWNER GROUP LVM_DEFS COPTIMISE_FLAG CLDFLAGS CLDWHOLEARCHIVE CLDNOWHOLEARCHIVE LDDEPS LIB_SUFFIX LVM_VERSION LVM1_FALLBACK DEBUG DEVMAPPER HAVE_LIBDL HAVE_SELINUX CMDLIB LOCALEDIR CONFDIR STATICDIR INTL_PACKAGE INTL CLVMD CLUSTER FSADM DMEVENTD LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -858,6 +858,7 @@ Optional Features:
--disable-o_direct Disable O_DIRECT
--enable-cmdlib Build shared command library
--enable-fsadm Enable fsadm
--enable-dmeventd Enable the device-mapper event daemon
--enable-nls Enable Native Language Support
Optional Packages:
@@ -1450,7 +1451,7 @@ case "$host_os" in
CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive"
LDDEPS="$LDDEPS .export.sym"
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
SOFLAG="-shared"
LIB_SUFFIX="so"
DEVMAPPER=yes
ODIRECT=yes
SELINUX=yes
@@ -1464,7 +1465,7 @@ case "$host_os" in
CLDNOWHOLEARCHIVE=
LDDEPS="$LDDEPS"
LDFLAGS="$LDFLAGS"
SOFLAG="-dynamiclib"
LIB_SUFFIX="dylib"
DEVMAPPER=yes
ODIRECT=no
SELINUX=no
@@ -2642,6 +2643,84 @@ else
RANLIB="$ac_cv_prog_RANLIB"
fi
# Extract the first word of "cflow", so it can be a program name with args.
set dummy cflow; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_path_CFLOW_CMD+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
case $CFLOW_CMD in
[\\/]* | ?:[\\/]*)
ac_cv_path_CFLOW_CMD="$CFLOW_CMD" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CFLOW_CMD="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
;;
esac
fi
CFLOW_CMD=$ac_cv_path_CFLOW_CMD
if test -n "$CFLOW_CMD"; then
echo "$as_me:$LINENO: result: $CFLOW_CMD" >&5
echo "${ECHO_T}$CFLOW_CMD" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
# Extract the first word of "cscope", so it can be a program name with args.
set dummy cscope; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_path_CSCOPE_CMD+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
case $CSCOPE_CMD in
[\\/]* | ?:[\\/]*)
ac_cv_path_CSCOPE_CMD="$CSCOPE_CMD" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CSCOPE_CMD="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
;;
esac
fi
CSCOPE_CMD=$ac_cv_path_CSCOPE_CMD
if test -n "$CSCOPE_CMD"; then
echo "$as_me:$LINENO: result: $CSCOPE_CMD" >&5
echo "${ECHO_T}$CSCOPE_CMD" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
################################################################################
@@ -7148,7 +7227,7 @@ echo "$as_me:$LINENO: result: $LVM1_FALLBACK" >&5
echo "${ECHO_T}$LVM1_FALLBACK" >&6
if test x$LVM1_FALLBACK = xyes; then
CFLAGS="$CFLAGS -DLVM1_FALLBACK"
LVM_DEFS="$LVM_DEFS -DLVM1_FALLBACK"
fi
################################################################################
@@ -7174,7 +7253,7 @@ echo "$as_me: error: --with-lvm1 parameter invalid
fi;
if test x$LVM1 = xinternal; then
CFLAGS="$CFLAGS -DLVM1_INTERNAL"
LVM_DEFS="$LVM_DEFS -DLVM1_INTERNAL"
fi
################################################################################
@@ -7200,7 +7279,7 @@ echo "$as_me: error: --with-pool parameter invalid
fi;
if test x$POOL = xinternal; then
CFLAGS="$CFLAGS -DPOOL_INTERNAL"
LVM_DEFS="$LVM_DEFS -DPOOL_INTERNAL"
fi
################################################################################
@@ -7224,7 +7303,7 @@ echo "$as_me: error: --with-cluster parameter invalid
fi;
if test x$CLUSTER = xinternal; then
CFLAGS="$CFLAGS -DCLUSTER_LOCKING_INTERNAL"
LVM_DEFS="$LVM_DEFS -DCLUSTER_LOCKING_INTERNAL"
fi
################################################################################
@@ -7250,7 +7329,7 @@ echo "$as_me: error: --with-snapshots parameter invalid
fi;
if test x$SNAPSHOTS = xinternal; then
CFLAGS="$CFLAGS -DSNAPSHOT_INTERNAL"
LVM_DEFS="$LVM_DEFS -DSNAPSHOT_INTERNAL"
fi
################################################################################
@@ -7276,7 +7355,7 @@ echo "$as_me: error: --with-mirrors parameter invalid
fi;
if test x$MIRRORS = xinternal; then
CFLAGS="$CFLAGS -DMIRRORED_INTERNAL"
LVM_DEFS="$LVM_DEFS -DMIRRORED_INTERNAL"
fi
################################################################################
@@ -7306,7 +7385,7 @@ echo "$as_me:$LINENO: result: $READLINE" >&5
echo "${ECHO_T}$READLINE" >&6
if test x$READLINE = xyes; then
CFLAGS="$CFLAGS -DREADLINE_SUPPORT"
LVM_DEFS="$LVM_DEFS -DREADLINE_SUPPORT"
fi
################################################################################
@@ -7356,6 +7435,8 @@ echo "${ECHO_T}$DEBUG" >&6
if test x$DEBUG = xyes; then
COPTIMISE_FLAG=
else
CSCOPE_CMD=
fi
################################################################################
@@ -7382,7 +7463,7 @@ echo "$as_me:$LINENO: result: $DEVMAPPER" >&5
echo "${ECHO_T}$DEVMAPPER" >&6
if test x$DEVMAPPER = xyes; then
CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT"
LVM_DEFS="$LVM_DEFS -DDEVMAPPER_SUPPORT"
fi
################################################################################
@@ -7397,7 +7478,7 @@ echo "$as_me:$LINENO: result: $ODIRECT" >&5
echo "${ECHO_T}$ODIRECT" >&6
if test x$ODIRECT = xyes; then
CFLAGS="$CFLAGS -DO_DIRECT_SUPPORT"
LVM_DEFS="$LVM_DEFS -DO_DIRECT_SUPPORT"
fi
################################################################################
@@ -7414,7 +7495,7 @@ echo "$as_me:$LINENO: result: $CMDLIB" >&5
echo "${ECHO_T}$CMDLIB" >&6
if test x$CMDLIB = xyes; then
CFLAGS="$CFLAGS -DCMDLIB"
LVM_DEFS="$LVM_DEFS -DCMDLIB"
fi
################################################################################
@@ -7428,6 +7509,28 @@ fi;
echo "$as_me:$LINENO: result: $FSADM" >&5
echo "${ECHO_T}$FSADM" >&6
################################################################################
echo "$as_me:$LINENO: checking whether to use dmeventd" >&5
echo $ECHO_N "checking whether to use dmeventd... $ECHO_C" >&6
# Check whether --enable-dmeventd or --disable-dmeventd was given.
if test "${enable_dmeventd+set}" = set; then
enableval="$enable_dmeventd"
DMEVENTD=$enableval
fi;
echo "$as_me:$LINENO: result: $DMEVENTD" >&5
echo "${ECHO_T}$DMEVENTD" >&6
if test x$DMEVENTD = xyes && test x$MIRRORS != xinternal; then
{ { echo "$as_me:$LINENO: error: --enable-dmeventd currently requires --with-mirrors=internal
" >&5
echo "$as_me: error: --enable-dmeventd currently requires --with-mirrors=internal
" >&2;}
{ (exit 1); exit 1; }; }
fi
if test x$DMEVENTD = xyes; then
LVM_DEFS="$LVM_DEFS -DDMEVENTD"
fi
################################################################################
if [ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ];
then exec_prefix="";
@@ -8087,7 +8190,7 @@ fi
if [ "x$HAVE_LIBDL" = xyes ]; then
CFLAGS="$CFLAGS -DHAVE_LIBDL"
LVM_DEFS="$LVM_DEFS -DHAVE_LIBDL"
LIBS="-ldl $LIBS"
else
HAVE_LIBDL=no
@@ -8106,6 +8209,85 @@ fi
################################################################################
if test x$SELINUX = xyes; then
echo "$as_me:$LINENO: checking for sepol_check_context function" >&5
echo $ECHO_N "checking for sepol_check_context function... $ECHO_C" >&6
echo "$as_me:$LINENO: checking for sepol_check_context in -lsepol" >&5
echo $ECHO_N "checking for sepol_check_context in -lsepol... $ECHO_C" >&6
if test "${ac_cv_lib_sepol_sepol_check_context+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lsepol $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char sepol_check_context ();
int
main ()
{
sepol_check_context ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_sepol_sepol_check_context=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_sepol_sepol_check_context=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_sepol_sepol_check_context" >&5
echo "${ECHO_T}$ac_cv_lib_sepol_sepol_check_context" >&6
if test $ac_cv_lib_sepol_sepol_check_context = yes; then
HAVE_SEPOL=yes
else
HAVE_SEPOL=no
fi
echo "$as_me:$LINENO: result: $HAVE_SEPOL" >&5
echo "${ECHO_T}$HAVE_SEPOL" >&6
if test x$HAVE_SEPOL = xyes; then
LIBS="-lsepol $LIBS"
fi
echo "$as_me:$LINENO: checking for is_selinux_enabled function" >&5
echo $ECHO_N "checking for is_selinux_enabled function... $ECHO_C" >&6
echo "$as_me:$LINENO: checking for is_selinux_enabled in -lselinux" >&5
@@ -8182,7 +8364,7 @@ fi
echo "${ECHO_T}$HAVE_SELINUX" >&6
if test x$HAVE_SELINUX = xyes; then
CFLAGS="$CFLAGS -DHAVE_SELINUX"
LVM_DEFS="$LVM_DEFS -DHAVE_SELINUX"
LIBS="-lselinux $LIBS"
else
{ echo "$as_me:$LINENO: WARNING: Disabling selinux" >&5
@@ -8336,7 +8518,7 @@ if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
CFLAGS="$CFLAGS -DHAVE_GETOPTLONG"
LVM_DEFS="$LVM_DEFS -DHAVE_GETOPTLONG"
fi
done
@@ -8526,7 +8708,7 @@ fi
echo "$as_me:$LINENO: result: $ac_cv_func_rl_completion_matches" >&5
echo "${ECHO_T}$ac_cv_func_rl_completion_matches" >&6
if test $ac_cv_func_rl_completion_matches = yes; then
CFLAGS="$CFLAGS -DHAVE_RL_COMPLETION_MATCHES"
LVM_DEFS="$LVM_DEFS -DHAVE_RL_COMPLETION_MATCHES"
fi
@@ -10810,7 +10992,7 @@ fi
if test x$MODPROBE_CMD != x; then
CFLAGS="$CFLAGS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
LVM_DEFS="$LVM_DEFS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
fi
################################################################################
@@ -10850,13 +11032,17 @@ fi
################################################################################
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile doc/Makefile include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/snapshot/Makefile man/Makefile po/Makefile tools/Makefile tools/version.h tools/fsadm/Makefile test/mm/Makefile test/device/Makefile test/format1/Makefile test/regex/Makefile test/filters/Makefile"
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile dmeventd/Makefile dmeventd/mirror/Makefile doc/Makefile include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/snapshot/Makefile man/Makefile po/Makefile tools/Makefile tools/version.h tools/fsadm/Makefile test/mm/Makefile test/device/Makefile test/format1/Makefile test/regex/Makefile test/filters/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@@ -11412,6 +11598,8 @@ do
"make.tmpl" ) CONFIG_FILES="$CONFIG_FILES make.tmpl" ;;
"daemons/Makefile" ) CONFIG_FILES="$CONFIG_FILES daemons/Makefile" ;;
"daemons/clvmd/Makefile" ) CONFIG_FILES="$CONFIG_FILES daemons/clvmd/Makefile" ;;
"dmeventd/Makefile" ) CONFIG_FILES="$CONFIG_FILES dmeventd/Makefile" ;;
"dmeventd/mirror/Makefile" ) CONFIG_FILES="$CONFIG_FILES dmeventd/mirror/Makefile" ;;
"doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
"include/Makefile" ) CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
"lib/Makefile" ) CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
@@ -11540,6 +11728,8 @@ s,@LN_S@,$LN_S,;t t
s,@SET_MAKE@,$SET_MAKE,;t t
s,@RANLIB@,$RANLIB,;t t
s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
s,@CFLOW_CMD@,$CFLOW_CMD,;t t
s,@CSCOPE_CMD@,$CSCOPE_CMD,;t t
s,@CPP@,$CPP,;t t
s,@EGREP@,$EGREP,;t t
s,@ALLOCA@,$ALLOCA,;t t
@@ -11555,12 +11745,13 @@ s,@SNAPSHOTS@,$SNAPSHOTS,;t t
s,@MIRRORS@,$MIRRORS,;t t
s,@OWNER@,$OWNER,;t t
s,@GROUP@,$GROUP,;t t
s,@LVM_DEFS@,$LVM_DEFS,;t t
s,@COPTIMISE_FLAG@,$COPTIMISE_FLAG,;t t
s,@CLDFLAGS@,$CLDFLAGS,;t t
s,@CLDWHOLEARCHIVE@,$CLDWHOLEARCHIVE,;t t
s,@CLDNOWHOLEARCHIVE@,$CLDNOWHOLEARCHIVE,;t t
s,@LDDEPS@,$LDDEPS,;t t
s,@SOFLAG@,$SOFLAG,;t t
s,@LIB_SUFFIX@,$LIB_SUFFIX,;t t
s,@LVM_VERSION@,$LVM_VERSION,;t t
s,@LVM1_FALLBACK@,$LVM1_FALLBACK,;t t
s,@DEBUG@,$DEBUG,;t t
@@ -11576,6 +11767,7 @@ s,@INTL@,$INTL,;t t
s,@CLVMD@,$CLVMD,;t t
s,@CLUSTER@,$CLUSTER,;t t
s,@FSADM@,$FSADM,;t t
s,@DMEVENTD@,$DMEVENTD,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
CEOF
@@ -11855,3 +12047,8 @@ if test x$FSADM == xyes; then
{ echo "$as_me:$LINENO: WARNING: fsadm support is untested" >&5
echo "$as_me: WARNING: fsadm support is untested" >&2;}
fi
if test x$DMEVENTD == xyes; then
{ echo "$as_me:$LINENO: WARNING: dmeventd support is untested" >&5
echo "$as_me: WARNING: dmeventd support is untested" >&2;}
fi

View File

@@ -35,7 +35,7 @@ case "$host_os" in
CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive"
LDDEPS="$LDDEPS .export.sym"
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
SOFLAG="-shared"
LIB_SUFFIX="so"
DEVMAPPER=yes
ODIRECT=yes
SELINUX=yes
@@ -49,7 +49,7 @@ case "$host_os" in
CLDNOWHOLEARCHIVE=
LDDEPS="$LDDEPS"
LDFLAGS="$LDFLAGS"
SOFLAG="-dynamiclib"
LIB_SUFFIX="dylib"
DEVMAPPER=yes
ODIRECT=no
SELINUX=no
@@ -65,6 +65,8 @@ AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_RANLIB
AC_PATH_PROG(CFLOW_CMD, cflow)
AC_PATH_PROG(CSCOPE_CMD, cscope)
################################################################################
dnl -- Checks for header files.
@@ -150,7 +152,7 @@ AC_ARG_ENABLE(lvm1_fallback, [ --enable-lvm1_fallback Use this to fall back an
AC_MSG_RESULT($LVM1_FALLBACK)
if test x$LVM1_FALLBACK = xyes; then
CFLAGS="$CFLAGS -DLVM1_FALLBACK"
LVM_DEFS="$LVM_DEFS -DLVM1_FALLBACK"
fi
################################################################################
@@ -170,7 +172,7 @@ if [[ "x$LVM1" != xnone -a "x$LVM1" != xinternal -a "x$LVM1" != xshared ]];
fi;
if test x$LVM1 = xinternal; then
CFLAGS="$CFLAGS -DLVM1_INTERNAL"
LVM_DEFS="$LVM_DEFS -DLVM1_INTERNAL"
fi
################################################################################
@@ -190,7 +192,7 @@ if [[ "x$POOL" != xnone -a "x$POOL" != xinternal -a "x$POOL" != xshared ]];
fi;
if test x$POOL = xinternal; then
CFLAGS="$CFLAGS -DPOOL_INTERNAL"
LVM_DEFS="$LVM_DEFS -DPOOL_INTERNAL"
fi
################################################################################
@@ -209,7 +211,7 @@ if [[ "x$CLUSTER" != xnone -a "x$CLUSTER" != xinternal -a "x$CLUSTER" != xshared
fi;
if test x$CLUSTER = xinternal; then
CFLAGS="$CFLAGS -DCLUSTER_LOCKING_INTERNAL"
LVM_DEFS="$LVM_DEFS -DCLUSTER_LOCKING_INTERNAL"
fi
################################################################################
@@ -229,7 +231,7 @@ if [[ "x$SNAPSHOTS" != xnone -a "x$SNAPSHOTS" != xinternal -a "x$SNAPSHOTS" != x
fi;
if test x$SNAPSHOTS = xinternal; then
CFLAGS="$CFLAGS -DSNAPSHOT_INTERNAL"
LVM_DEFS="$LVM_DEFS -DSNAPSHOT_INTERNAL"
fi
################################################################################
@@ -249,7 +251,7 @@ if [[ "x$MIRRORS" != xnone -a "x$MIRRORS" != xinternal -a "x$MIRRORS" != xshared
fi;
if test x$MIRRORS = xinternal; then
CFLAGS="$CFLAGS -DMIRRORED_INTERNAL"
LVM_DEFS="$LVM_DEFS -DMIRRORED_INTERNAL"
fi
################################################################################
@@ -267,7 +269,7 @@ READLINE=$enableval, READLINE=no)
AC_MSG_RESULT($READLINE)
if test x$READLINE = xyes; then
CFLAGS="$CFLAGS -DREADLINE_SUPPORT"
LVM_DEFS="$LVM_DEFS -DREADLINE_SUPPORT"
fi
################################################################################
@@ -305,6 +307,8 @@ AC_MSG_RESULT($DEBUG)
dnl -- Normally turn off optimisation for debug builds
if test x$DEBUG = xyes; then
COPTIMISE_FLAG=
else
CSCOPE_CMD=
fi
################################################################################
@@ -323,7 +327,7 @@ DEVMAPPER=$enableval)
AC_MSG_RESULT($DEVMAPPER)
if test x$DEVMAPPER = xyes; then
CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT"
LVM_DEFS="$LVM_DEFS -DDEVMAPPER_SUPPORT"
fi
################################################################################
@@ -334,7 +338,7 @@ ODIRECT=$enableval)
AC_MSG_RESULT($ODIRECT)
if test x$ODIRECT = xyes; then
CFLAGS="$CFLAGS -DO_DIRECT_SUPPORT"
LVM_DEFS="$LVM_DEFS -DO_DIRECT_SUPPORT"
fi
################################################################################
@@ -345,7 +349,7 @@ CMDLIB=$enableval, CMDLIB=no)
AC_MSG_RESULT($CMDLIB)
if test x$CMDLIB = xyes; then
CFLAGS="$CFLAGS -DCMDLIB"
LVM_DEFS="$LVM_DEFS -DCMDLIB"
fi
################################################################################
@@ -355,6 +359,23 @@ AC_ARG_ENABLE(fsadm, [ --enable-fsadm Enable fsadm],
FSADM=$enableval)
AC_MSG_RESULT($FSADM)
################################################################################
dnl -- enable dmeventd handling
AC_MSG_CHECKING(whether to use dmeventd)
AC_ARG_ENABLE(dmeventd, [ --enable-dmeventd Enable the device-mapper event daemon],
DMEVENTD=$enableval)
AC_MSG_RESULT($DMEVENTD)
dnl -- dmeventd currently requires internal mirror support
if test x$DMEVENTD = xyes && test x$MIRRORS != xinternal; then
AC_MSG_ERROR(
--enable-dmeventd currently requires --with-mirrors=internal
)
fi
if test x$DMEVENTD = xyes; then
LVM_DEFS="$LVM_DEFS -DDMEVENTD"
fi
################################################################################
dnl -- Mess with default exec_prefix
if [[ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]];
@@ -390,7 +411,7 @@ dnl -- Check for dlopen
AC_CHECK_LIB(dl, dlopen, HAVE_LIBDL=yes, HAVE_LIBDL=no)
if [[ "x$HAVE_LIBDL" = xyes ]]; then
CFLAGS="$CFLAGS -DHAVE_LIBDL"
LVM_DEFS="$LVM_DEFS -DHAVE_LIBDL"
LIBS="-ldl $LIBS"
else
HAVE_LIBDL=no
@@ -407,14 +428,22 @@ Features cannot be 'shared' when building statically
fi
################################################################################
dnl -- Check for is_selinux_enabled
dnl -- Check for selinux
if test x$SELINUX = xyes; then
AC_MSG_CHECKING(for sepol_check_context function)
AC_CHECK_LIB(sepol, sepol_check_context, HAVE_SEPOL=yes, HAVE_SEPOL=no)
AC_MSG_RESULT($HAVE_SEPOL)
if test x$HAVE_SEPOL = xyes; then
LIBS="-lsepol $LIBS"
fi
AC_MSG_CHECKING(for is_selinux_enabled function)
AC_CHECK_LIB(selinux, is_selinux_enabled, HAVE_SELINUX=yes, HAVE_SELINUX=no)
AC_MSG_RESULT($HAVE_SELINUX)
if test x$HAVE_SELINUX = xyes; then
CFLAGS="$CFLAGS -DHAVE_SELINUX"
LVM_DEFS="$LVM_DEFS -DHAVE_SELINUX"
LIBS="-lselinux $LIBS"
else
AC_MSG_WARN(Disabling selinux)
@@ -423,7 +452,7 @@ fi
################################################################################
dnl -- Check for getopt
AC_CHECK_HEADERS(getopt.h, CFLAGS="$CFLAGS -DHAVE_GETOPTLONG")
AC_CHECK_HEADERS(getopt.h, LVM_DEFS="$LVM_DEFS -DHAVE_GETOPTLONG")
################################################################################
dnl -- Check for readline (Shamelessly copied from parted 1.4.17)
@@ -438,7 +467,7 @@ Note: if you are using precompiled packages you will also need the development
package as well (which may be called readline-devel or something similar).
)
)
AC_CHECK_FUNC(rl_completion_matches, CFLAGS="$CFLAGS -DHAVE_RL_COMPLETION_MATCHES")
AC_CHECK_FUNC(rl_completion_matches, LVM_DEFS="$LVM_DEFS -DHAVE_RL_COMPLETION_MATCHES")
fi
@@ -519,7 +548,7 @@ fi
AC_PATH_PROG(MODPROBE_CMD, modprobe)
if test x$MODPROBE_CMD != x; then
CFLAGS="$CFLAGS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
LVM_DEFS="$LVM_DEFS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
fi
################################################################################
@@ -539,13 +568,14 @@ AC_SUBST(MIRRORS)
AC_SUBST(OWNER)
AC_SUBST(GROUP)
AC_SUBST(CFLAGS)
AC_SUBST(LVM_DEFS)
AC_SUBST(COPTIMISE_FLAG)
AC_SUBST(CLDFLAGS)
AC_SUBST(CLDWHOLEARCHIVE)
AC_SUBST(CLDNOWHOLEARCHIVE)
AC_SUBST(LDDEPS)
AC_SUBST(LDFLAGS)
AC_SUBST(SOFLAG)
AC_SUBST(LIB_SUFFIX)
AC_SUBST(LIBS)
AC_SUBST(LVM_VERSION)
AC_SUBST(LVM1_FALLBACK)
@@ -563,6 +593,9 @@ AC_SUBST(INTL)
AC_SUBST(CLVMD)
AC_SUBST(CLUSTER)
AC_SUBST(FSADM)
AC_SUBST(DMEVENTD)
AC_SUBST(CFLOW_CMD)
AC_SUBST(CSCOPE_CMD)
################################################################################
dnl -- First and last lines should not contain files to generate in order to
@@ -572,6 +605,8 @@ Makefile \
make.tmpl \
daemons/Makefile \
daemons/clvmd/Makefile \
dmeventd/Makefile \
dmeventd/mirror/Makefile \
doc/Makefile \
include/Makefile \
lib/Makefile \
@@ -599,3 +634,7 @@ fi
if test x$FSADM == xyes; then
AC_MSG_WARN(fsadm support is untested)
fi
if test x$DMEVENTD == xyes; then
AC_MSG_WARN(dmeventd support is untested)
fi

View File

@@ -35,28 +35,38 @@ ifeq ("@CLVMD@", "all")
endif
ifeq ("@DEBUG@", "yes")
CFLAGS += -DDEBUG
DEFS += -DDEBUG
endif
ifeq ("$(GULM)", "yes")
SOURCES += clvmd-gulm.c tcp-comms.c
LMLIBS += -lccs -lgulm
CFLAGS += -DUSE_GULM
DEFS += -DUSE_GULM
endif
ifeq ("$(CMAN)", "yes")
SOURCES += clvmd-cman.c
LMLIBS += -ldlm
CFLAGS += -DUSE_CMAN
LMLIBS += -ldlm -lcman
DEFS += -DUSE_CMAN
endif
TARGETS = \
clvmd
include $(top_srcdir)/make.tmpl
LVMLIBS = -llvm -lpthread
CFLAGS += -D_REENTRANT -fno-strict-aliasing
LIBS += -ldevmapper -llvm -lpthread
ifeq ("@DMEVENTD@", "yes")
LVMLIBS += -ldevmapper-event
endif
ifeq ("@DEVMAPPER@", "yes")
LVMLIBS += -ldevmapper
endif
DEFS += -D_REENTRANT
CFLAGS += -fno-strict-aliasing
include $(top_srcdir)/make.tmpl
INSTALL_TARGETS = \
install_clvmd

View File

@@ -46,19 +46,23 @@
#define LOCKSPACE_NAME "clvmd"
static int cluster_sock;
static int num_nodes;
static struct cl_cluster_node *nodes = NULL;
static struct cman_node *nodes = NULL;
static struct cman_node this_node;
static int count_nodes; /* size of allocated nodes array */
static int max_updown_nodes = 50; /* Current size of the allocated array */
/* Node up/down status, indexed by nodeid */
static int *node_updown = NULL;
static dlm_lshandle_t *lockspace;
static cman_handle_t c_handle;
static void count_clvmds_running(void);
static void get_members(void);
static int nodeid_from_csid(char *csid);
static int name_from_nodeid(int nodeid, char *name);
static void event_callback(cman_handle_t handle, void *private, int reason, int arg);
static void data_callback(cman_handle_t handle, void *private,
char *buf, int len, uint8_t port, int nodeid);
struct lock_wait {
pthread_cond_t cond;
@@ -68,30 +72,23 @@ struct lock_wait {
static int _init_cluster(void)
{
struct sockaddr_cl saddr;
int port = CLUSTER_PORT_CLVMD;
/* Open the cluster communication socket */
cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT);
if (cluster_sock == -1) {
/* Don't print an error here because we could be just probing for CMAN */
c_handle = cman_init(NULL);
if (!c_handle) {
syslog(LOG_ERR, "Can't open cluster manager socket: %m");
return -1;
}
/* Set Close-on-exec */
fcntl(cluster_sock, F_SETFD, 1);
/* Bind to our port number on the cluster.
Writes to this will block if the cluster loses quorum */
saddr.scl_family = AF_CLUSTER;
saddr.scl_port = port;
if (bind
(cluster_sock, (struct sockaddr *) &saddr,
sizeof(struct sockaddr_cl))) {
if (cman_start_recv_data(c_handle, data_callback, CLUSTER_PORT_CLVMD)) {
syslog(LOG_ERR, "Can't bind cluster socket: %m");
return -1;
}
if (cman_start_notification(c_handle, event_callback)) {
syslog(LOG_ERR, "Can't start cluster event listening");
return -1;
}
/* Get the cluster members list */
get_members();
count_clvmds_running();
@@ -114,63 +111,46 @@ static void _cluster_init_completed(void)
static int _get_main_cluster_fd()
{
return cluster_sock;
return cman_get_fd(c_handle);
}
static int _get_num_nodes()
{
return num_nodes;
int i;
int nnodes = 0;
/* return number of ACTIVE nodes */
for (i=0; i<num_nodes; i++) {
if (nodes[i].cn_member)
nnodes++;
}
return nnodes;
}
/* send_message with the fd check removed */
static int _cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
{
struct iovec iov[2];
struct msghdr msg;
struct sockaddr_cl saddr;
int len = 0;
int nodeid = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iovlen = 1;
msg.msg_iov = iov;
msg.msg_flags = 0;
iov[0].iov_len = msglen;
iov[0].iov_base = buf;
if (csid)
memcpy(&nodeid, csid, CMAN_MAX_CSID_LEN);
saddr.scl_family = AF_CLUSTER;
saddr.scl_port = CLUSTER_PORT_CLVMD;
if (csid) {
msg.msg_name = &saddr;
msg.msg_namelen = sizeof(saddr);
memcpy(&saddr.scl_nodeid, csid, CMAN_MAX_CSID_LEN);
} else { /* Cluster broadcast */
msg.msg_name = NULL;
msg.msg_namelen = 0;
}
do {
len = sendmsg(cluster_sock, &msg, 0);
if (len < 0 && errno != EAGAIN)
if (cman_send_data(c_handle, buf, msglen, 0, CLUSTER_PORT_CLVMD, nodeid) <= 0)
{
log_error(errtext);
} while (len == -1 && errno == EAGAIN);
return len;
}
return msglen;
}
static void _get_our_csid(char *csid)
{
int i;
memset(csid, 0, CMAN_MAX_CSID_LEN);
for (i = 0; i < num_nodes; i++) {
if (nodes[i].us)
memcpy(csid, &nodes[i].node_id, CMAN_MAX_CSID_LEN);
if (this_node.cn_nodeid == 0) {
cman_get_node(c_handle, 0, &this_node);
}
memcpy(csid, &this_node.cn_nodeid, CMAN_MAX_CSID_LEN);
}
/* Call a callback routine for each node that known (down mean not running a clvmd) */
/* Call a callback routine for each node is that known (down means not running a clvmd) */
static int _cluster_do_node_callback(struct local_client *client,
void (*callback) (struct local_client *, char *,
int))
@@ -179,8 +159,8 @@ static int _cluster_do_node_callback(struct local_client *client,
int somedown = 0;
for (i = 0; i < _get_num_nodes(); i++) {
callback(client, (char *)&nodes[i].node_id, node_updown[nodes[i].node_id]);
if (!node_updown[nodes[i].node_id])
callback(client, (char *)&nodes[i].cn_nodeid, node_updown[nodes[i].cn_nodeid]);
if (!node_updown[nodes[i].cn_nodeid])
somedown = -1;
}
return somedown;
@@ -188,78 +168,63 @@ static int _cluster_do_node_callback(struct local_client *client,
/* Process OOB message from the cluster socket,
this currently just means that a node has stopped listening on our port */
static void process_oob_msg(char *buf, int len, int nodeid)
static void event_callback(cman_handle_t handle, void *private, int reason, int arg)
{
char namebuf[256];
switch (buf[0]) {
case CLUSTER_OOB_MSG_PORTCLOSED:
name_from_nodeid(nodeid, namebuf);
log_notice("clvmd on node %s has died\n", namebuf);
DEBUGLOG("Got OOB message, removing node %s\n", namebuf);
char namebuf[MAX_CLUSTER_NAME_LEN];
node_updown[nodeid] = 0;
switch (reason) {
case CMAN_REASON_PORTCLOSED:
name_from_nodeid(arg, namebuf);
log_notice("clvmd on node %s has died\n", namebuf);
DEBUGLOG("Got port closed message, removing node %s\n", namebuf);
node_updown[arg] = 0;
break;
case CLUSTER_OOB_MSG_STATECHANGE:
DEBUGLOG("Got OOB message, Cluster state change\n");
case CMAN_REASON_STATECHANGE:
DEBUGLOG("Got state change message, re-reading members list\n");
get_members();
break;
#if defined(LIBCMAN_VERSION) && LIBCMAN_VERSION >= 2
case CMAN_REASON_PORTOPENED:
/* Ignore this, wait for startup message from clvmd itself */
break;
case CMAN_REASON_TRY_SHUTDOWN:
DEBUGLOG("Got try shutdown, sending OK\n");
cman_replyto_shutdown(c_handle, 1);
break;
#endif
default:
/* ERROR */
DEBUGLOG("Got unknown OOB message: %d\n", buf[0]);
DEBUGLOG("Got unknown event callback message: %d\n", reason);
break;
}
}
static int _cluster_fd_callback(struct local_client *client, char *buf, int len, char *csid,
static struct local_client *cman_client;
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len, char *csid,
struct local_client **new_client)
{
struct iovec iov[2];
struct msghdr msg;
struct sockaddr_cl saddr;
/* Save this for data_callback */
cman_client = fd;
/* We never return a new client */
*new_client = NULL;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iovlen = 1;
msg.msg_iov = iov;
msg.msg_name = &saddr;
msg.msg_flags = 0;
msg.msg_namelen = sizeof(saddr);
iov[0].iov_len = len;
iov[0].iov_base = buf;
return cman_dispatch(c_handle, 0);
}
len = recvmsg(cluster_sock, &msg, MSG_OOB | O_NONBLOCK);
if (len < 0 && errno == EAGAIN)
return len;
DEBUGLOG("Read on cluster socket, len = %d\n", len);
/* A real error */
if (len < 0) {
log_error("read error on cluster socket: %m");
return 0;
}
/* EOF - we have left the cluster */
if (len == 0)
return 0;
/* Is it OOB? probably a node gone down */
if (msg.msg_flags & MSG_OOB) {
process_oob_msg(iov[0].iov_base, len, saddr.scl_nodeid);
/* Tell the upper layer to ignore this message */
len = -1;
errno = EAGAIN;
}
else {
memcpy(csid, &saddr.scl_nodeid, sizeof(saddr.scl_nodeid));
/* Send it back to clvmd */
process_message(client, buf, len, csid);
}
return len;
static void data_callback(cman_handle_t handle, void *private,
char *buf, int len, uint8_t port, int nodeid)
{
/* Ignore looped back messages */
if (nodeid == this_node.cn_nodeid)
return;
process_message(cman_client, buf, len, (char *)&nodeid);
}
static void _add_up_node(char *csid)
@@ -290,19 +255,15 @@ static void _cluster_closedown()
{
unlock_all();
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
close(cluster_sock);
cman_finish(c_handle);
}
static int is_listening(int nodeid)
{
struct cl_listen_request rq;
int status;
rq.port = CLUSTER_PORT_CLVMD;
rq.nodeid = nodeid;
do {
status = ioctl(cluster_sock, SIOCCLUSTER_ISLISTENING, &rq);
status = cman_is_listening(c_handle, nodeid, CLUSTER_PORT_CLVMD);
if (status < 0 && errno == EBUSY) { /* Don't busywait */
sleep(1);
errno = EBUSY; /* In case sleep trashes it */
@@ -320,19 +281,22 @@ static void count_clvmds_running(void)
int i;
for (i = 0; i < num_nodes; i++) {
node_updown[nodes[i].node_id] = is_listening(nodes[i].node_id);
node_updown[nodes[i].cn_nodeid] = is_listening(nodes[i].cn_nodeid);
}
}
/* Get a list of active cluster members */
static void get_members()
{
struct cl_cluster_nodelist nodelist;
int retnodes;
int status;
num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, 0);
num_nodes = cman_get_node_count(c_handle);
if (num_nodes == -1) {
log_error("Unable to get node count");
} else {
return;
}
/* Not enough room for new nodes list ? */
if (num_nodes > count_nodes && nodes) {
free(nodes);
@@ -341,28 +305,19 @@ static void get_members()
if (nodes == NULL) {
count_nodes = num_nodes + 10; /* Overallocate a little */
nodes = malloc(count_nodes * sizeof(struct cl_cluster_node));
nodes = malloc(count_nodes * sizeof(struct cman_node));
if (!nodes) {
log_error("Unable to allocate nodes array\n");
exit(5);
}
}
nodelist.max_members = count_nodes;
nodelist.nodes = nodes;
num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, &nodelist);
if (num_nodes <= 0) {
status = cman_get_nodes(c_handle, count_nodes, &retnodes, nodes);
if (status < 0) {
log_error("Unable to get node details");
exit(6);
}
/* Sanity check struct */
if (nodes[0].size != sizeof(struct cl_cluster_node)) {
log_error
("sizeof(cl_cluster_node) does not match size returned from the kernel: aborting\n");
exit(10);
}
if (node_updown == NULL) {
node_updown =
(int *) malloc(sizeof(int) *
@@ -371,7 +326,6 @@ static void get_members()
sizeof(int) * max(num_nodes, max_updown_nodes));
}
}
}
/* Convert a node name to a CSID */
static int _csid_from_name(char *csid, char *name)
@@ -379,8 +333,8 @@ static int _csid_from_name(char *csid, char *name)
int i;
for (i = 0; i < num_nodes; i++) {
if (strcmp(name, nodes[i].name) == 0) {
memcpy(csid, &nodes[i].node_id, CMAN_MAX_CSID_LEN);
if (strcmp(name, nodes[i].cn_name) == 0) {
memcpy(csid, &nodes[i].cn_nodeid, CMAN_MAX_CSID_LEN);
return 0;
}
}
@@ -393,8 +347,8 @@ static int _name_from_csid(char *csid, char *name)
int i;
for (i = 0; i < num_nodes; i++) {
if (memcmp(csid, &nodes[i].node_id, CMAN_MAX_CSID_LEN) == 0) {
strcpy(name, nodes[i].name);
if (memcmp(csid, &nodes[i].cn_nodeid, CMAN_MAX_CSID_LEN) == 0) {
strcpy(name, nodes[i].cn_name);
return 0;
}
}
@@ -409,8 +363,8 @@ static int name_from_nodeid(int nodeid, char *name)
int i;
for (i = 0; i < num_nodes; i++) {
if (nodeid == nodes[i].node_id) {
strcpy(name, nodes[i].name);
if (nodeid == nodes[i].cn_nodeid) {
strcpy(name, nodes[i].cn_name);
return 0;
}
}
@@ -431,7 +385,7 @@ static int nodeid_from_csid(char *csid)
static int _is_quorate()
{
return ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0);
return cman_is_quorate(c_handle);
}
static void sync_ast_routine(void *arg)

View File

@@ -56,15 +56,19 @@ struct cluster_ops *init_gulm_cluster(void);
#endif
#ifdef USE_CMAN
# include "cnxman-socket.h"
# include <netinet/in.h>
# include "libcman.h"
# define CMAN_MAX_CSID_LEN 4
# ifndef MAX_CSID_LEN
# define MAX_CSID_LEN CMAN_MAX_CSID_LEN
# endif
# undef MAX_CLUSTER_MEMBER_NAME_LEN
# define MAX_CLUSTER_MEMBER_NAME_LEN CMAN_MAX_CLUSTER_MEMBER_NAME_LEN
# define MAX_CLUSTER_MEMBER_NAME_LEN CMAN_MAX_NODENAME_LEN
# define CMAN_MAX_CLUSTER_MESSAGE 1500
# define CLUSTER_PORT_CLVMD 11
struct cluster_ops *init_cman_cluster(void);
#endif
#endif

View File

@@ -247,7 +247,7 @@ int main(int argc, char *argv[])
if ((clops = init_cman_cluster())) {
max_csid_len = CMAN_MAX_CSID_LEN;
max_cluster_message = CMAN_MAX_CLUSTER_MESSAGE;
max_cluster_member_name_len = CMAN_MAX_CLUSTER_MEMBER_NAME_LEN;
max_cluster_member_name_len = CMAN_MAX_NODENAME_LEN;
syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to CMAN");
}
#endif
@@ -509,6 +509,7 @@ static void main_loop(int local_sock, int cmd_timeout)
int quorate = clops->is_quorate();
/* Wait on the cluster FD and all local sockets/pipes */
local_client_head.fd = clops->get_main_cluster_fd();
FD_ZERO(&in);
for (thisfd = &local_client_head; thisfd != NULL;
thisfd = thisfd->next) {

View File

@@ -303,6 +303,9 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
}
}
if (lock_flags & LCK_PARTIAL_MODE)
init_partial(1);
switch (command) {
case LCK_LV_EXCLUSIVE:
status = do_activate_lv(resource, lock_flags, LKM_EXMODE);
@@ -331,6 +334,9 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
break;
}
if (lock_flags & LCK_PARTIAL_MODE)
init_partial(0);
/* clean the pool for another command */
dm_pool_empty(cmd->mem);

View File

@@ -1,3 +1,5 @@
process_event
register_device
unregister_device
dm_event_register
dm_event_unregister
dm_event_get_registered_device
dm_event_set_timeout
dm_event_get_timeout

View File

@@ -1,14 +1,13 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
# Copyright (C) 2005 Red Hat, Inc. All rights reserved.
#
# This file is part of the device-mapper userspace tools.
#
# 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.
# of the GNU Lesser General Public License v.2.1.
#
# You should have received a copy of the GNU General Public License
# 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
@@ -16,36 +15,59 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
TARGETS = dmevent dmeventd
INSTALL_TYPE = install_dynamic
SOURCES = libdevmapper-event.c \
dmeventd.c
SOURCES = noop.c
CLEAN_TARGETS = dmevent.o dmeventd.o
LIB_STATIC = libdevmapper-event.a
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdmeventdnoop.dylib
LIB_SHARED = libdevmapper-event.dylib
else
LIB_SHARED = libdmeventdnoop.so
LIB_SHARED = libdevmapper-event.so
endif
LDFLAGS += -ldl -ldevmapper -lmultilog
include ../make.tmpl
libdmeventdnoop.so: noop.o
CLDFLAGS += -ldl -ldevmapper -lpthread
dmevent: dmevent.o $(interfacedir)/libdevmapper.$(LIB_SUFFIX) $(top_srcdir)/lib/event/libdmevent.$(LIB_SUFFIX)
$(CC) -o $@ dmevent.o $(LDFLAGS) \
-L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog $(LIBS)
.PHONY: install_dynamic install_static install_include \
install_pkgconfig
dmeventd: dmeventd.o $(interfacedir)/libdevmapper.$(LIB_SUFFIX) $(top_srcdir)/lib/event/libdmevent.$(LIB_SUFFIX)
$(CC) -o $@ dmeventd.o $(LDFLAGS) \
-L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog -lpthread -ldmevent $(LIBS)
INSTALL_TYPE = install_dynamic
install: $(INSTALL_TYPE)
ifeq ("@STATIC_LINK@", "yes")
INSTALL_TYPE += install_static
endif
.PHONY: install_dynamic
ifeq ("@PKGCONFIG@", "yes")
INSTALL_TYPE += install_pkgconfig
endif
install_dynamic: dmeventd
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) dmeventd $(sbindir)/dmeventd
install: $(INSTALL_TYPE) install_include
install_include:
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.h \
$(includedir)/libdevmapper-event.h
install_dynamic: libdevmapper-event.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION)
$(LN_S) -f libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION) \
$(libdir)/libdevmapper-event.$(LIB_SUFFIX)
install_pkgconfig:
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.pc \
$(usrlibdir)/pkgconfig/devmapper-event.pc
install_static: libdevmapper-event.a
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/libdevmapper-event.a.$(LIB_VERSION)
$(LN_S) -f libdevmapper-event.a.$(LIB_VERSION) $(libdir)/libdevmapper-event.a
.PHONY: distclean_lib distclean
distclean_lib:
$(RM) libdevmapper-event.pc
distclean: distclean_lib

View File

@@ -1,240 +0,0 @@
/*
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
* 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 "libdevmapper.h"
#include "libdm-event.h"
#include "libmultilog.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dlfcn.h>
static enum event_type events = ALL_ERRORS; /* All until we can distinguish. */
static char default_dso_name[] = "noop"; /* default DSO is noop */
static int default_reg = 1; /* default action is register */
static uint32_t timeout;
struct event_ops {
int (*dm_register_for_event)(char *dso_name, char *device,
enum event_type event_types);
int (*dm_unregister_for_event)(char *dso_name, char *device,
enum event_type event_types);
int (*dm_get_registered_device)(char **dso_name, char **device,
enum event_type *event_types, int next);
int (*dm_set_event_timeout)(char *device, uint32_t time);
int (*dm_get_event_timeout)(char *device, uint32_t *time);
};
/* Display help. */
static void print_usage(char *name)
{
char *cmd = strrchr(name, '/');
cmd = cmd ? cmd + 1 : name;
printf("Usage::\n"
"%s [options] <device>\n"
"\n"
"Options:\n"
" -d <dso> Specify the DSO to use.\n"
" -h Print this usage.\n"
" -l List registered devices.\n"
" -r Register for event (default).\n"
" -t <timeout> (un)register for timeout event.\n"
" -u Unregister for event.\n"
"\n", cmd);
}
/* Parse command line arguments. */
static int parse_argv(int argc, char **argv, char **dso_name_arg,
char **device_arg, int *reg, int *list)
{
int c;
const char *options = "d:hlrt:u";
while ((c = getopt(argc, argv, options)) != -1) {
switch (c) {
case 'd':
*dso_name_arg = optarg;
break;
case 'h':
print_usage(argv[0]);
exit(EXIT_SUCCESS);
case 'l':
*list = 1;
break;
case 'r':
*reg = 1;
break;
case 't':
events = TIMEOUT;
if (sscanf(optarg, "%"SCNu32, &timeout) != 1){
fprintf(stderr, "invalid timeout '%s'\n",
optarg);
timeout = 0;
}
break;
case 'u':
*reg = 0;
break;
default:
fprintf(stderr, "Unknown option '%c'.\n"
"Try '-h' for help.\n", c);
return 0;
}
}
if (optind >= argc) {
if (!*list) {
fprintf(stderr, "You need to specify a device.\n");
return 0;
}
} else
*device_arg = argv[optind];
return 1;
}
static int lookup_symbol(void *dl, void **symbol, const char *name)
{
if ((*symbol = dlsym(dl, name)))
return 1;
fprintf(stderr, "error looking up %s symbol: %s\n", name, dlerror());
return 0;
}
static int lookup_symbols(void *dl, struct event_ops *e)
{
return lookup_symbol(dl, (void *) &e->dm_register_for_event,
"dm_register_for_event") &&
lookup_symbol(dl, (void *) &e->dm_unregister_for_event,
"dm_unregister_for_event") &&
lookup_symbol(dl, (void *) &e->dm_get_registered_device,
"dm_get_registered_device") &&
lookup_symbol(dl, (void *) &e->dm_set_event_timeout,
"dm_set_event_timeout") &&
lookup_symbol(dl, (void *) &e->dm_get_event_timeout,
"dm_get_event_timeout");
}
int main(int argc, char **argv)
{
void *dl;
struct event_ops e;
int list = 0, next = 0, ret, reg = default_reg;
char *device, *device_arg = NULL, *dso_name, *dso_name_arg = NULL;
if (!parse_argv(argc, argv, &dso_name_arg, &device_arg, &reg, &list))
exit(EXIT_FAILURE);
if (device_arg) {
if (!(device = strdup(device_arg)))
exit(EXIT_FAILURE);
} else
device = NULL;
if (dso_name_arg) {
if (!(dso_name = strdup(dso_name_arg)))
exit(EXIT_FAILURE);
} else {
if (!(dso_name = strdup(default_dso_name)))
exit(EXIT_FAILURE);
}
/* FIXME: use -v/-q options to set this */
multilog_add_type(standard, NULL);
multilog_init_verbose(standard, _LOG_DEBUG);
if (!(dl = dlopen("libdmevent.so", RTLD_NOW))){
fprintf(stderr, "Cannot dlopen libdmevent.so: %s\n", dlerror());
goto out;
}
if (!(lookup_symbols(dl, &e)))
goto out;
if (list) {
while (1) {
if ((ret= e.dm_get_registered_device(&dso_name,
&device,
&events, next)))
break;
printf("%s %s 0x%x", dso_name, device, events);
if (events & TIMEOUT){
if ((ret = e.dm_get_event_timeout(device,
&timeout))) {
ret = EXIT_FAILURE;
goto out;
}
printf(" %"PRIu32"\n", timeout);
} else
printf("\n");
if (device_arg)
break;
next = 1;
}
ret = (ret && device_arg) ? EXIT_FAILURE : EXIT_SUCCESS;
goto out;
}
if ((ret = reg ? e.dm_register_for_event(dso_name, device, events) :
e.dm_unregister_for_event(dso_name, device, events))) {
fprintf(stderr, "Failed to %sregister %s: %s\n",
reg ? "": "un", device, strerror(-ret));
ret = EXIT_FAILURE;
} else {
if (reg && (events & TIMEOUT) &&
((ret = e.dm_set_event_timeout(device, timeout)))){
fprintf(stderr, "Failed to set timeout for %s: %s\n",
device, strerror(-ret));
ret = EXIT_FAILURE;
} else {
printf("%s %sregistered successfully.\n",
device, reg ? "" : "un");
ret = EXIT_SUCCESS;
}
}
out:
multilog_del_type(standard);
if (device)
free(device);
if (dso_name)
free(dso_name);
exit(ret);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
#ifndef __DMEVENTD_DOT_H__
#define __DMEVENTD_DOT_H__
#define EXIT_LOCKFILE_INUSE 2
#define EXIT_DESC_CLOSE_FAILURE 3
#define EXIT_OPEN_PID_FAILURE 4
#define EXIT_FIFO_FAILURE 5
#define EXIT_CHDIR_FAILURE 6
void dmeventd(void)
__attribute((noreturn));
#endif /* __DMEVENTD_DOT_H__ */

View File

@@ -0,0 +1,510 @@
/*
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
* 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 "libdevmapper-event.h"
//#include "libmultilog.h"
#include "dmeventd.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
/* Set by any of the external fxns the first time one of them is called */
/* FIXME Unused */
// static int _logging = 0;
/* Fetch a string off src and duplicate it into *dest. */
/* FIXME: move to seperate module to share with the daemon. */
static const char delimiter = ' ';
static char *fetch_string(char **src)
{
char *p, *ret;
if ((p = strchr(*src, delimiter)))
*p = 0;
if ((ret = dm_strdup(*src)))
*src += strlen(ret) + 1;
if (p)
*p = delimiter;
return ret;
}
/* Parse a device message from the daemon. */
static int parse_message(struct dm_event_daemon_message *msg, char **dso_name,
char **device, enum dm_event_type *events)
{
char *p = msg->msg;
if ((*dso_name = fetch_string(&p)) &&
(*device = fetch_string(&p))) {
*events = atoi(p);
return 0;
}
return -ENOMEM;
}
/*
* daemon_read
* @fifos
* @msg
*
* Read message from daemon.
*
* Returns: 0 on failure, 1 on success
*/
static int daemon_read(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
{
unsigned bytes = 0;
int ret = 0;
fd_set fds;
memset(msg, 0, sizeof(*msg));
while (bytes < sizeof(*msg)) {
do {
/* Watch daemon read FIFO for input. */
FD_ZERO(&fds);
FD_SET(fifos->server, &fds);
ret = select(fifos->server+1, &fds, NULL, NULL, NULL);
if (ret < 0 && errno != EINTR) {
/* FIXME Log error */
return 0;
}
} while (ret < 1);
ret = read(fifos->server, msg, sizeof(*msg) - bytes);
if (ret < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
else {
/* FIXME Log error */
return 0;
}
}
bytes += ret;
}
return bytes == sizeof(*msg);
}
/* Write message to daemon. */
static int daemon_write(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
{
unsigned bytes = 0;
int ret = 0;
fd_set fds;
while (bytes < sizeof(*msg)) {
do {
/* Watch daemon write FIFO to be ready for output. */
FD_ZERO(&fds);
FD_SET(fifos->client, &fds);
ret = select(fifos->client +1, NULL, &fds, NULL, NULL);
if ((ret < 0) && (errno != EINTR)) {
/* FIXME Log error */
return 0;
}
} while (ret < 1);
ret = write(fifos->client, msg, sizeof(*msg) - bytes);
if (ret < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
else {
/* fixme: log error */
return 0;
}
}
bytes += ret;
}
return bytes == sizeof(*msg);
}
static int daemon_talk(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg,
int cmd, char *dso_name, char *device,
enum dm_event_type events, uint32_t timeout)
{
memset(msg, 0, sizeof(*msg));
/*
* Set command and pack the arguments
* into ASCII message string.
*/
msg->opcode.cmd = cmd;
if (sizeof(msg->msg) <= (unsigned) snprintf(msg->msg, sizeof(msg->msg),
"%s %s %u %"PRIu32,
dso_name ? dso_name : "",
device ? device : "",
events, timeout)) {
stack;
return -ENAMETOOLONG;
}
/*
* Write command and message to and
* read status return code from daemon.
*/
if (!daemon_write(fifos, msg)) {
stack;
return -EIO;
}
if (!daemon_read(fifos, msg)) {
stack;
return -EIO;
}
return msg->opcode.status;
}
static volatile sig_atomic_t daemon_running = 0;
static void daemon_running_signal_handler(int sig)
{
daemon_running = 1;
}
/*
* start_daemon
*
* This function forks off a process (dmeventd) that will handle
* the events. A signal must be returned from the child to
* indicate when it is ready to handle requests. The parent
* (this function) returns 1 if there is a daemon running.
*
* Returns: 1 on success, 0 otherwise
*/
static int start_daemon(void)
{
int pid, ret=0;
void *old_hand;
sigset_t set, oset;
/* Must be able to acquire signal */
old_hand = signal(SIGUSR1, &daemon_running_signal_handler);
if (old_hand == SIG_ERR) {
log_error("Unable to setup signal handler.");
return 0;
}
if (sigemptyset(&set) || sigaddset(&set, SIGUSR1)) {
log_error("Unable to fill signal set.");
} else if (sigprocmask(SIG_UNBLOCK, &set, &oset)) {
log_error("Can't unblock the potentially blocked signal SIGUSR1");
}
pid = fork();
if (pid < 0)
log_error("Unable to fork.\n");
else if (pid) { /* parent waits for child to get ready for requests */
int status;
/* FIXME Better way to do this? */
while (!waitpid(pid, &status, WNOHANG) && !daemon_running)
sleep(1);
if (daemon_running) {
ret = 1;
} else {
switch (WEXITSTATUS(status)) {
case EXIT_LOCKFILE_INUSE:
/*
* Note, this is ok... we still have daemon
* that we can communicate with...
*/
log_print("Starting dmeventd failed: "
"dmeventd already running.\n");
ret = 1;
break;
default:
log_error("Unable to start dmeventd.\n");
break;
}
}
/*
* Sometimes, a single process may perform multiple calls
* that result in a daemon starting and exiting. If we
* don't reset this, the second (or greater) time the daemon
* is started will cause this logic not to work.
*/
daemon_running = 0;
} else {
signal(SIGUSR1, SIG_IGN); /* don't care about error */
/* dmeventd function is responsible for properly setting **
** itself up. It must never return - only exit. This is**
** why it is followed by an EXIT_FAILURE */
dmeventd();
exit(EXIT_FAILURE);
}
/* FIXME What if old_hand is SIG_ERR? */
if (signal(SIGUSR1, old_hand) == SIG_ERR)
log_error("Unable to reset signal handler.");
if (sigprocmask(SIG_SETMASK, &oset, NULL))
log_error("Unable to reset signal mask.");
return ret;
}
/* Initialize client. */
static int init_client(struct dm_event_fifos *fifos)
{
/* FIXME Is fifo the most suitable method? */
/* FIXME Why not share comms/daemon code with something else e.g. multipath? */
/* init fifos */
memset(fifos, 0, sizeof(*fifos));
fifos->client_path = DM_EVENT_FIFO_CLIENT;
fifos->server_path = DM_EVENT_FIFO_SERVER;
/* FIXME The server should be responsible for these, not the client. */
/* Create fifos */
if (((mkfifo(fifos->client_path, 0600) == -1) && errno != EEXIST) ||
((mkfifo(fifos->server_path, 0600) == -1) && errno != EEXIST)) {
log_error("%s: Failed to create a fifo.\n", __func__);
return 0;
}
/* FIXME Warn/abort if perms are wrong - not something to fix silently. */
/* If they were already there, make sure permissions are ok. */
if (chmod(fifos->client_path, 0600)) {
log_error("Unable to set correct file permissions on %s",
fifos->client_path);
return 0;
}
if (chmod(fifos->server_path, 0600)) {
log_error("Unable to set correct file permissions on %s",
fifos->server_path);
return 0;
}
/*
* Open the fifo used to read from the daemon.
* Allows daemon to create its write fifo...
*/
if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
log_error("%s: open server fifo %s\n",
__func__, fifos->server_path);
stack;
return 0;
}
/* Lock out anyone else trying to do communication with the daemon. */
/* FIXME Why failure not retry? How do multiple processes communicate? */
if (flock(fifos->server, LOCK_EX) < 0){
log_error("%s: flock %s\n", __func__, fifos->server_path);
close(fifos->server);
return 0;
}
/* Anyone listening? If not, errno will be ENXIO */
while ((fifos->client = open(fifos->client_path,
O_WRONLY | O_NONBLOCK)) < 0) {
if (errno != ENXIO) {
log_error("%s: Can't open client fifo %s: %s\n",
__func__, fifos->client_path, strerror(errno));
close(fifos->server);
stack;
return 0;
}
/* FIXME Unnecessary if daemon was started before calling this */
if (!start_daemon()) {
stack;
return 0;
}
}
return 1;
}
static void dtr_client(struct dm_event_fifos *fifos)
{
if (flock(fifos->server, LOCK_UN))
log_error("flock unlock %s\n", fifos->server_path);
close(fifos->client);
close(fifos->server);
}
/* Check, if a block device exists. */
static int device_exists(char *device)
{
struct stat st_buf;
char path2[PATH_MAX];
if (!device)
return 0;
if (device[0] == '/') /* absolute path */
return !stat(device, &st_buf) && S_ISBLK(st_buf.st_mode);
if (PATH_MAX <= snprintf(path2, PATH_MAX, "%s/%s", dm_dir(), device))
return 0;
return !stat(path2, &st_buf) && S_ISBLK(st_buf.st_mode);
}
/* Handle the event (de)registration call and return negative error codes. */
static int do_event(int cmd, struct dm_event_daemon_message *msg,
char *dso_name, char *device, enum dm_event_type events,
uint32_t timeout)
{
int ret;
struct dm_event_fifos fifos;
/* FIXME Start the daemon here if it's not running e.g. exclusive lock file */
/* FIXME Move this to separate 'dm_event_register_handler' - if no daemon here, fail */
if (!init_client(&fifos)) {
stack;
return -ESRCH;
}
/* FIXME Use separate 'dm_event_register_handler' function to pass in dso? */
ret = daemon_talk(&fifos, msg, cmd, dso_name, device, events, timeout);
/* what is the opposite of init? */
dtr_client(&fifos);
return ret;
}
/* FIXME remove dso_name - use handle instead */
/* FIXME Use uuid not path! */
/* External library interface. */
int dm_event_register(char *dso_name, char *device_path,
enum dm_event_type events)
{
int ret;
struct dm_event_daemon_message msg;
if (!device_exists(device_path)) {
log_error("%s: device not found", device_path);
return 0;
}
if ((ret = do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg,
dso_name, device_path, events, 0)) < 0) {
log_error("%s: event registration failed: %s", device_path,
strerror(-ret));
return 0;
}
return 1;
}
int dm_event_unregister(char *dso_name, char *device_path,
enum dm_event_type events)
{
int ret;
struct dm_event_daemon_message msg;
if (!device_exists(device_path)) {
log_error("%s: device not found", device_path);
return 0;
}
if ((ret = do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, &msg,
dso_name, device_path, events, 0)) < 0) {
log_error("%s: event deregistration failed: %s", device_path,
strerror(-ret));
return 0;
}
return 1;
}
int dm_event_get_registered_device(char **dso_name, char **device_path,
enum dm_event_type *events, int next)
{
int ret;
char *dso_name_arg = NULL, *device_path_arg = NULL;
struct dm_event_daemon_message msg;
if (!(ret = do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
DM_EVENT_CMD_GET_REGISTERED_DEVICE,
&msg, *dso_name, *device_path, *events, 0)))
ret = parse_message(&msg, &dso_name_arg, &device_path_arg,
events);
if (next){
if (*dso_name)
dm_free(*dso_name);
if (*device_path)
dm_free(*device_path);
*dso_name = dso_name_arg;
*device_path = device_path_arg;
} else {
if (!(*dso_name))
*dso_name = dso_name_arg;
if (!(*device_path))
*device_path = device_path_arg;
}
return ret;
}
int dm_event_set_timeout(char *device_path, uint32_t timeout)
{
struct dm_event_daemon_message msg;
if (!device_exists(device_path))
return -ENODEV;
return do_event(DM_EVENT_CMD_SET_TIMEOUT, &msg,
NULL, device_path, 0, timeout);
}
int dm_event_get_timeout(char *device_path, uint32_t *timeout)
{
int ret;
struct dm_event_daemon_message msg;
if (!device_exists(device_path))
return -ENODEV;
if (!(ret = do_event(DM_EVENT_CMD_GET_TIMEOUT, &msg, NULL, device_path, 0, 0)))
*timeout = atoi(msg.msg);
return ret;
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
* 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
*/
/*
* Note that this file is released only as part of a technology preview
* and its contents may change in future updates in ways that do not
* preserve compatibility.
*/
#ifndef LIB_DMEVENT_H
#define LIB_DMEVENT_H
#include <stdint.h>
/* FIXME This stuff must be configurable. */
#define DM_EVENT_DAEMON "/sbin/dmeventd"
#define DM_EVENT_LOCKFILE "/var/lock/dmeventd"
#define DM_EVENT_FIFO_CLIENT "/var/run/dmeventd-client"
#define DM_EVENT_FIFO_SERVER "/var/run/dmeventd-server"
#define DM_EVENT_PIDFILE "/var/run/dmeventd.pid"
#define DM_EVENT_DEFAULT_TIMEOUT 10
/* Commands for the daemon passed in the message below. */
enum dm_event_command {
DM_EVENT_CMD_ACTIVE = 1,
DM_EVENT_CMD_REGISTER_FOR_EVENT,
DM_EVENT_CMD_UNREGISTER_FOR_EVENT,
DM_EVENT_CMD_GET_REGISTERED_DEVICE,
DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE,
DM_EVENT_CMD_SET_TIMEOUT,
DM_EVENT_CMD_GET_TIMEOUT,
};
/* Message passed between client and daemon. */
struct dm_event_daemon_message {
union {
unsigned int cmd; /* FIXME Use fixed size. */
int status; /* FIXME Use fixed size. */
} opcode;
char msg[252]; /* FIXME Why is this 252 ? */
} __attribute__((packed)); /* FIXME Do this properly! */
/* FIXME Is this meant to be exported? I can't see where the interface uses it. */
/* Fifos for client/daemon communication. */
struct dm_event_fifos {
int client;
int server;
const char *client_path;
const char *server_path;
};
/* Event type definitions. */
/* FIXME Use masks to separate the types and provide for extension. */
enum dm_event_type {
DM_EVENT_SINGLE = 0x01, /* Report multiple errors just once. */
DM_EVENT_MULTI = 0x02, /* Report all of them. */
DM_EVENT_SECTOR_ERROR = 0x04, /* Failure on a particular sector. */
DM_EVENT_DEVICE_ERROR = 0x08, /* Device failure. */
DM_EVENT_PATH_ERROR = 0x10, /* Failure on an io path. */
DM_EVENT_ADAPTOR_ERROR = 0x20, /* Failure off a host adaptor. */
DM_EVENT_SYNC_STATUS = 0x40, /* Mirror synchronization completed/failed. */
DM_EVENT_TIMEOUT = 0x80, /* Timeout has occured */
};
/* FIXME Use a mask. */
#define DM_EVENT_ALL_ERRORS (DM_EVENT_SECTOR_ERROR | DM_EVENT_DEVICE_ERROR | \
DM_EVENT_PATH_ERROR | DM_EVENT_ADAPTOR_ERROR)
/* Prototypes for event lib interface. */
/* FIXME Replace device with standard name/uuid/devno choice */
/* Interface changes:
First register a handler, passing in a unique ref for the device. */
// int dm_event_register_handler(const char *dso_name, const char *device);
// int dm_event_register(const char *dso_name, const char *name, const char *uuid, uint32_t major, uint32_t minor, enum dm_event_type events);
/* Or (better?) add to task structure and use existing functions - run a task to register/unregister events - we may need to run task withe that with the new event mechanism anyway, then the dso calls just hook in.
*/
/* FIXME Missing consts? */
int dm_event_register(char *dso_name, char *device, enum dm_event_type events);
int dm_event_unregister(char *dso_name, char *device,
enum dm_event_type events);
int dm_event_get_registered_device(char **dso_name, char **device,
enum dm_event_type *events, int next);
int dm_event_set_timeout(char *device, uint32_t timeout);
int dm_event_get_timeout(char *device, uint32_t *timeout);
/* Prototypes for DSO interface. */
void process_event(const char *device, enum dm_event_type event);
int register_device(const char *device);
int unregister_device(const char *device);
#endif

View File

@@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: devmapper-event
Description: device-mapper event library
Version: @DM_LIB_VERSION@
Requires: devmapper
Cflags: -I${includedir}
Libs: -L${libdir} -ldevmapper-event
Libs.private: -lpthread -ldl

View File

@@ -1,12 +0,0 @@
#!/bin/sh
#
# Create test devices for dmeventd
#
trap "rm -f /tmp/tmp.$$" 0 1 2 3 15
echo "0 1024 zero" > /tmp/tmp.$$
dmsetup create test /tmp/tmp.$$
dmsetup create test1 /tmp/tmp.$$
kill -15 $$

View File

@@ -1,39 +0,0 @@
/*
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
* 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 "libdm-event.h"
#include "libmultilog.h"
void process_event(char *device, enum event_type event)
{
log_err("[%s] %s(%d) - Device: %s, Event %d\n",
__FILE__, __func__, __LINE__, device, event);
}
int register_device(char *device)
{
log_err("[%s] %s(%d) - Device: %s\n",
__FILE__, __func__, __LINE__, device);
return 1;
}
int unregister_device(char *device)
{
log_err("[%s] %s(%d) - Device: %s\n",
__FILE__, __func__, __LINE__, device);
return 1;
}

View File

@@ -0,0 +1,22 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005 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@
SUBDIRS += mirror
include $(top_srcdir)/make.tmpl

View File

@@ -0,0 +1,3 @@
process_event
register_device
unregister_device

View File

@@ -0,0 +1,36 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005 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@
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper -llvm2cmd
SOURCES = dmeventd_mirror.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2mirror.dylib
else
LIB_SHARED = libdevmapper-event-lvm2mirror.so
endif
include $(top_srcdir)/make.tmpl
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View File

@@ -0,0 +1,246 @@
/*
* Copyright (C) 2005 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 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 "libdevmapper.h"
#include "libdevmapper-event.h"
#include "lvm2cmd.h"
#include "lvm-string.h"
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
#define ME_IGNORE 0
#define ME_INSYNC 1
#define ME_FAILURE 2
/* FIXME: We may need to lock around operations to these */
static int register_count = 0;
static struct dm_pool *mem_pool = NULL;
static int _get_mirror_event(char *params)
{
int i, rtn = ME_INSYNC;
int max_args = 30; /* should support at least 8-way mirrors */
char *args[max_args];
char *dev_status_str;
char *log_status_str;
char *sync_str;
char *p;
int log_argc, num_devs, num_failures=0;
if (max_args <= split_words(params, max_args, args)) {
syslog(LOG_ERR, "Unable to split mirror parameters: Arg list too long");
return -E2BIG;
}
/*
* Unused: 0 409600 mirror
* Used : 2 253:4 253:5 400/400 1 AA 3 cluster 253:3 A
*/
num_devs = atoi(args[0]);
dev_status_str = args[3 + num_devs];
log_argc = atoi(args[4 + num_devs]);
log_status_str = args[4 + num_devs + log_argc];
sync_str = args[1 + num_devs];
/* Check for bad mirror devices */
for (i = 0; i < num_devs; i++) {
if (dev_status_str[i] == 'D') {
syslog(LOG_ERR, "Mirror device, %s, has failed.\n", args[i+1]);
num_failures++;
}
}
/* Check for bad log device */
if (log_status_str[0] == 'D') {
syslog(LOG_ERR, "Log device, %s, has failed.\n",
args[3 + num_devs + log_argc]);
num_failures++;
}
if (num_failures) {
rtn = ME_FAILURE;
goto out;
}
p = strstr(sync_str, "/");
if (p) {
p[0] = '\0';
if (strcmp(sync_str, p+1))
rtn = ME_IGNORE;
p[0] = '/';
} else {
/*
* How the hell did we get this?
* Might mean all our parameters are screwed.
*/
syslog(LOG_ERR, "Unable to parse sync string.");
rtn = ME_IGNORE;
}
out:
return rtn;
}
static void _temporary_log_fn(int level, const char *file, int line, const char *format)
{
return;
syslog(LOG_DEBUG, "%s", format);
}
static int _remove_failed_devices(const char *device)
{
int r;
void *handle;
int cmd_size = 256; /* FIXME Use system restriction */
char cmd_str[cmd_size];
char *vg = NULL, *lv = NULL, *layer = NULL;
if (strlen(device) > 200)
return -ENAMETOOLONG;
if (!split_dm_name(mem_pool, device, &vg, &lv, &layer)) {
syslog(LOG_ERR, "Unable to determine VG name from %s",
device);
return -ENOMEM;
}
/* FIXME Is any sanity-checking required on %s? */
if (cmd_size <= snprintf(cmd_str, cmd_size, "vgreduce --removemissing %s", vg)) {
/* this error should be caught above, but doesn't hurt to check again */
syslog(LOG_ERR, "Unable to form LVM command: Device name too long");
dm_pool_empty(mem_pool); /* FIXME: not safe with multiple threads */
return -ENAMETOOLONG;
}
lvm2_log_fn(_temporary_log_fn);
handle = lvm2_init();
lvm2_log_level(handle, 1);
r = lvm2_run(handle, cmd_str);
dm_pool_empty(mem_pool); /* FIXME: not safe with multiple threads */
return (r == 1)? 0: -1;
}
void process_event(const char *device, enum dm_event_type event)
{
struct dm_task *dmt;
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
/* FIXME Move inside libdevmapper */
if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) {
syslog(LOG_ERR, "Unable to create dm_task.\n");
goto fail;
}
if (!dm_task_set_name(dmt, device)) {
syslog(LOG_ERR, "Unable to set device name.\n");
goto fail;
}
if (!dm_task_run(dmt)) {
syslog(LOG_ERR, "Unable to run task.\n");
goto fail;
}
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (strcmp(target_type, "mirror")) {
syslog(LOG_INFO, "%s has unmirrored portion.\n", device);
continue;
}
switch(_get_mirror_event(params)) {
case ME_INSYNC:
/* FIXME: all we really know is that this
_part_ of the device is in sync
Also, this is not an error
*/
syslog(LOG_NOTICE, "%s is now in-sync\n", device);
break;
case ME_FAILURE:
syslog(LOG_ERR, "Device failure in %s\n", device);
if (_remove_failed_devices(device))
syslog(LOG_ERR, "Failed to remove faulty devices in %s\n",
device);
/* Should check before warning user that device is now linear
else
syslog(LOG_NOTICE, "%s is now a linear device.\n",
device);
*/
break;
case ME_IGNORE:
break;
default:
syslog(LOG_INFO, "Unknown event received.\n");
}
} while (next);
fail:
if (dmt)
dm_task_destroy(dmt);
}
int register_device(const char *device)
{
syslog(LOG_INFO, "Monitoring %s for events\n", device);
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!mem_pool)
mem_pool = dm_pool_create("mirror_dso", 1024);
if (!mem_pool)
return 0;
register_count++;
return 1;
}
int unregister_device(const char *device)
{
syslog(LOG_INFO, "Stopped monitoring %s for events\n", device);
if (!(--register_count)) {
dm_pool_destroy(mem_pool);
mem_pool = NULL;
}
return 1;
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

22
dmeventd/Makefile.in Normal file
View File

@@ -0,0 +1,22 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005 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@
SUBDIRS += mirror
include $(top_srcdir)/make.tmpl

View File

@@ -0,0 +1,3 @@
process_event
register_device
unregister_device

View File

@@ -0,0 +1,36 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005 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@
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper -llvm2cmd
SOURCES = dmeventd_mirror.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2mirror.dylib
else
LIB_SHARED = libdevmapper-event-lvm2mirror.so
endif
include $(top_srcdir)/make.tmpl
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View File

@@ -0,0 +1,246 @@
/*
* Copyright (C) 2005 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 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 "libdevmapper.h"
#include "libdevmapper-event.h"
#include "lvm2cmd.h"
#include "lvm-string.h"
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
#define ME_IGNORE 0
#define ME_INSYNC 1
#define ME_FAILURE 2
/* FIXME: We may need to lock around operations to these */
static int register_count = 0;
static struct dm_pool *mem_pool = NULL;
static int _get_mirror_event(char *params)
{
int i, rtn = ME_INSYNC;
int max_args = 30; /* should support at least 8-way mirrors */
char *args[max_args];
char *dev_status_str;
char *log_status_str;
char *sync_str;
char *p;
int log_argc, num_devs, num_failures=0;
if (max_args <= split_words(params, max_args, args)) {
syslog(LOG_ERR, "Unable to split mirror parameters: Arg list too long");
return -E2BIG;
}
/*
* Unused: 0 409600 mirror
* Used : 2 253:4 253:5 400/400 1 AA 3 cluster 253:3 A
*/
num_devs = atoi(args[0]);
dev_status_str = args[3 + num_devs];
log_argc = atoi(args[4 + num_devs]);
log_status_str = args[4 + num_devs + log_argc];
sync_str = args[1 + num_devs];
/* Check for bad mirror devices */
for (i = 0; i < num_devs; i++) {
if (dev_status_str[i] == 'D') {
syslog(LOG_ERR, "Mirror device, %s, has failed.\n", args[i+1]);
num_failures++;
}
}
/* Check for bad log device */
if (log_status_str[0] == 'D') {
syslog(LOG_ERR, "Log device, %s, has failed.\n",
args[3 + num_devs + log_argc]);
num_failures++;
}
if (num_failures) {
rtn = ME_FAILURE;
goto out;
}
p = strstr(sync_str, "/");
if (p) {
p[0] = '\0';
if (strcmp(sync_str, p+1))
rtn = ME_IGNORE;
p[0] = '/';
} else {
/*
* How the hell did we get this?
* Might mean all our parameters are screwed.
*/
syslog(LOG_ERR, "Unable to parse sync string.");
rtn = ME_IGNORE;
}
out:
return rtn;
}
static void _temporary_log_fn(int level, const char *file, int line, const char *format)
{
return;
syslog(LOG_DEBUG, "%s", format);
}
static int _remove_failed_devices(const char *device)
{
int r;
void *handle;
int cmd_size = 256; /* FIXME Use system restriction */
char cmd_str[cmd_size];
char *vg = NULL, *lv = NULL, *layer = NULL;
if (strlen(device) > 200)
return -ENAMETOOLONG;
if (!split_dm_name(mem_pool, device, &vg, &lv, &layer)) {
syslog(LOG_ERR, "Unable to determine VG name from %s",
device);
return -ENOMEM;
}
/* FIXME Is any sanity-checking required on %s? */
if (cmd_size <= snprintf(cmd_str, cmd_size, "vgreduce --removemissing %s", vg)) {
/* this error should be caught above, but doesn't hurt to check again */
syslog(LOG_ERR, "Unable to form LVM command: Device name too long");
dm_pool_empty(mem_pool); /* FIXME: not safe with multiple threads */
return -ENAMETOOLONG;
}
lvm2_log_fn(_temporary_log_fn);
handle = lvm2_init();
lvm2_log_level(handle, 1);
r = lvm2_run(handle, cmd_str);
dm_pool_empty(mem_pool); /* FIXME: not safe with multiple threads */
return (r == 1)? 0: -1;
}
void process_event(const char *device, enum dm_event_type event)
{
struct dm_task *dmt;
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
/* FIXME Move inside libdevmapper */
if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) {
syslog(LOG_ERR, "Unable to create dm_task.\n");
goto fail;
}
if (!dm_task_set_name(dmt, device)) {
syslog(LOG_ERR, "Unable to set device name.\n");
goto fail;
}
if (!dm_task_run(dmt)) {
syslog(LOG_ERR, "Unable to run task.\n");
goto fail;
}
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (strcmp(target_type, "mirror")) {
syslog(LOG_INFO, "%s has unmirrored portion.\n", device);
continue;
}
switch(_get_mirror_event(params)) {
case ME_INSYNC:
/* FIXME: all we really know is that this
_part_ of the device is in sync
Also, this is not an error
*/
syslog(LOG_NOTICE, "%s is now in-sync\n", device);
break;
case ME_FAILURE:
syslog(LOG_ERR, "Device failure in %s\n", device);
if (_remove_failed_devices(device))
syslog(LOG_ERR, "Failed to remove faulty devices in %s\n",
device);
/* Should check before warning user that device is now linear
else
syslog(LOG_NOTICE, "%s is now a linear device.\n",
device);
*/
break;
case ME_IGNORE:
break;
default:
syslog(LOG_INFO, "Unknown event received.\n");
}
} while (next);
fail:
if (dmt)
dm_task_destroy(dmt);
}
int register_device(const char *device)
{
syslog(LOG_INFO, "Monitoring %s for events\n", device);
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!mem_pool)
mem_pool = dm_pool_create("mirror_dso", 1024);
if (!mem_pool)
return 0;
register_count++;
return 1;
}
int unregister_device(const char *device)
{
syslog(LOG_INFO, "Stopped monitoring %s for events\n", device);
if (!(--register_count)) {
dm_pool_destroy(mem_pool);
mem_pool = NULL;
}
return 1;
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@@ -289,4 +289,9 @@ activation {
# dirs = [ "/etc/lvm/metadata", "/mnt/disk2/lvm/metadata2" ]
#}
# Event daemon
#
#dmeventd {
# mirror_library = "libdevmapper-event-lvm2mirror.so"
#}

View File

@@ -41,3 +41,5 @@ install:
install_cluster:
cflow:

View File

@@ -38,6 +38,7 @@ SOURCES =\
commands/toolcontext.c \
config/config.c \
datastruct/btree.c \
datastruct/list.c \
datastruct/str_list.c \
device/dev-cache.c \
device/dev-io.c \
@@ -133,9 +134,22 @@ ifeq ("@HAVE_LIBDL@", "yes")
misc/sharedlib.c
endif
ifeq ("@DMEVENTD@", "yes")
CLDFLAGS += -ldevmapper-event
endif
LIB_STATIC = liblvm.a
$(SUBDIRS): $(LIB_STATIC)
CLEAN_TARGETS += liblvm.cflow
include $(top_srcdir)/make.tmpl
liblvm.cflow: $(SOURCES)
set -e; (echo -n "SOURCES += "; \
echo $(SOURCES) | \
sed "s/^/ /;s/ / $(top_srcdir)\/lib\//g;s/$$//"; \
) > $@
cflow: liblvm.cflow

View File

@@ -27,6 +27,7 @@
#include "str_list.h"
#include "config.h"
#include "filter.h"
#include "segtype.h"
#include <limits.h>
#include <fcntl.h>
@@ -75,6 +76,11 @@ int driver_version(char *version, size_t size)
{
return 0;
}
int target_version(const char *target_name, uint32_t *maj,
uint32_t *min, uint32_t *patchlevel)
{
return 0;
}
int target_present(const char *target_name)
{
return 0;
@@ -89,12 +95,12 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
{
return 0;
}
int lv_snapshot_percent(struct logical_volume *lv, float *percent)
int lv_snapshot_percent(const struct logical_volume *lv, float *percent)
{
return 0;
}
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
uint32_t *event_nr)
int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
int wait, float *percent, uint32_t *event_nr)
{
return 0;
}
@@ -170,8 +176,8 @@ void set_activation(int act)
log_verbose("Activation enabled. Device-mapper kernel "
"driver will be used.");
else
log_verbose("Activation disabled. No device-mapper "
"interaction will be attempted.");
log_print("WARNING: Activation disabled. No device-mapper "
"interaction will be attempted.");
}
int activation(void)
@@ -277,7 +283,8 @@ int driver_version(char *version, size_t size)
return dm_driver_version(version, size);
}
static int _target_present(const char *target_name)
int target_version(const char *target_name, uint32_t *maj,
uint32_t *min, uint32_t *patchlevel)
{
int r = 0;
struct dm_task *dmt;
@@ -300,6 +307,9 @@ static int _target_present(const char *target_name)
if (!strcmp(target_name, target->name)) {
r = 1;
*maj = target->version[0];
*min = target->version[1];
*patchlevel = target->version[2];
goto out;
}
@@ -314,6 +324,7 @@ static int _target_present(const char *target_name)
int target_present(const char *target_name, int use_modprobe)
{
uint32_t maj, min, patchlevel;
#ifdef MODPROBE_CMD
char module[128];
#endif
@@ -323,7 +334,7 @@ int target_present(const char *target_name, int use_modprobe)
#ifdef MODPROBE_CMD
if (use_modprobe) {
if (_target_present(target_name))
if (target_version(target_name, &maj, &min, &patchlevel))
return 1;
if (lvm_snprintf(module, sizeof(module), "dm-%s", target_name)
@@ -338,7 +349,7 @@ int target_present(const char *target_name, int use_modprobe)
}
#endif
return _target_present(target_name);
return target_version(target_name, &maj, &min, &patchlevel);
}
/*
@@ -396,7 +407,7 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
/*
* Returns 1 if percent set, else 0 on failure.
*/
int lv_snapshot_percent(struct logical_volume *lv, float *percent)
int lv_snapshot_percent(const struct logical_volume *lv, float *percent)
{
int r;
struct dev_manager *dm;
@@ -416,8 +427,8 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
}
/* FIXME Merge with snapshot_percent */
int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, int wait, float *percent,
uint32_t *event_nr)
int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
int wait, float *percent, uint32_t *event_nr)
{
int r;
struct dev_manager *dm;
@@ -563,18 +574,53 @@ int lvs_in_vg_opened(struct volume_group *vg)
return count;
}
static int _register_dev_for_events(struct cmd_context *cmd,
struct logical_volume *lv, int do_reg)
{
#ifdef DMEVENTD
struct list *tmp;
struct lv_segment *seg;
int (*reg) (struct dm_pool *mem, struct lv_segment *,
struct config_tree *cft, int events);
list_iterate(tmp, &lv->segments) {
seg = list_item(tmp, struct lv_segment);
reg = NULL;
if (do_reg) {
if (seg->segtype->ops->target_register_events)
reg = seg->segtype->ops->target_register_events;
} else if (seg->segtype->ops->target_unregister_events)
reg = seg->segtype->ops->target_unregister_events;
if (reg)
/* FIXME specify events */
if (!reg(cmd->mem, seg, cmd->cft, 0)) {
stack;
return 0;
}
}
#endif
return 1;
}
static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
int error_if_not_suspended)
{
struct logical_volume *lv;
struct logical_volume *lv, *lv_pre;
struct lvinfo info;
if (!activation())
return 1;
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
return_0;
/* Use precommitted metadata if present */
if (!(lv = lv_from_lvid(cmd, lvid_s, 1)))
return 0;
if (!(lv_pre = lv_from_lvid(cmd, lvid_s, 1)))
return_0;
if (test_mode()) {
_skip("Suspending '%s'.", lv->name);
@@ -588,13 +634,16 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
return error_if_not_suspended ? 0 : 1;
/* If VG was precommitted, preload devices for the LV */
if ((lv->vg->status & PRECOMMITTED)) {
if (!_lv_preload(lv)) {
if ((lv_pre->vg->status & PRECOMMITTED)) {
if (!_lv_preload(lv_pre)) {
/* FIXME Revert preloading */
return_0;
}
}
if (!_register_dev_for_events(cmd, lv, 0))
stack;
memlock_inc();
if (!_lv_suspend_lv(lv)) {
memlock_dec();
@@ -645,6 +694,9 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
memlock_dec();
fs_unlock();
if (!_register_dev_for_events(cmd, lv, 1))
stack;
return 1;
}
@@ -688,6 +740,9 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
return 0;
}
if (!_register_dev_for_events(cmd, lv, 0))
stack;
memlock_inc();
r = _lv_deactivate(lv);
memlock_dec();
@@ -758,6 +813,9 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
memlock_dec();
fs_unlock();
if (!_register_dev_for_events(cmd, lv, 1))
stack;
return r;
}

View File

@@ -37,6 +37,8 @@ int library_version(char *version, size_t size);
int lvm1_present(struct cmd_context *cmd);
int target_present(const char *target_name, int use_modprobe);
int target_version(const char *target_name, uint32_t *maj,
uint32_t *min, uint32_t *patchlevel);
void activation_exit(void);
@@ -68,9 +70,9 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
/*
* Returns 1 if percent has been set, else 0.
*/
int lv_snapshot_percent(struct logical_volume *lv, float *percent);
int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, int wait, float *percent,
uint32_t *event_nr);
int lv_snapshot_percent(const struct logical_volume *lv, float *percent);
int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
int wait, float *percent, uint32_t *event_nr);
/*
* Return number of LVs in the VG that are active.

View File

@@ -85,7 +85,7 @@ char *build_dlid(struct dev_manager *dm, const char *lvid, const char *layer)
return _build_dlid(dm->mem, lvid, layer);
}
static inline int _read_only_lv(struct logical_volume *lv)
static int _read_only_lv(struct logical_volume *lv)
{
return (!(lv->vg->status & LVM_WRITE) || !(lv->status & LVM_WRITE));
}
@@ -432,7 +432,8 @@ void dev_manager_exit(void)
}
int dev_manager_snapshot_percent(struct dev_manager *dm,
struct logical_volume *lv, float *percent)
const struct logical_volume *lv,
float *percent)
{
char *name;
const char *dlid;
@@ -845,7 +846,6 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
dm_tree_node_get_context(dnode))
return 1;
/* FIXME How do we determine whether a pre-existing node need reloading or not? */
if (!(lvlayer = dm_pool_alloc(dm->mem, sizeof(*lvlayer)))) {
log_error("_add_new_lv_to_dtree: pool alloc failed for %s %s.", lv->name, layer);
return 0;
@@ -978,6 +978,8 @@ static int _tree_action(struct dev_manager *dm, struct logical_volume *lv, actio
goto_out;
break;
case SUSPEND:
if (!lv_is_origin(lv) && !lv_is_cow(lv))
dm_tree_skip_lockfs(root);
if (!dm_tree_suspend_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1))
goto_out;
break;

View File

@@ -41,7 +41,8 @@ int dev_manager_info(struct dm_pool *mem, const char *name,
const struct logical_volume *lv,
int mknodes, int with_open_count, struct dm_info *info);
int dev_manager_snapshot_percent(struct dev_manager *dm,
struct logical_volume *lv, float *percent);
const 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);

315
lib/cache/lvmcache.c vendored
View File

@@ -86,7 +86,8 @@ int vgs_locked(void)
return _vgs_locked;
}
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname)
/* If vgid supplied, require a match. */
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname, const char *vgid)
{
struct lvmcache_vginfo *vginfo;
@@ -96,10 +97,16 @@ struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname)
if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname)))
return NULL;
if (vgid)
do
if (!strncmp(vgid, vginfo->vgid, sizeof(vginfo->vgid)))
return vginfo;
while ((vginfo = vginfo->next));
return vginfo;
}
const struct format_type *fmt_from_vgname(const char *vgname)
const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid)
{
struct lvmcache_vginfo *vginfo;
struct lvmcache_info *info;
@@ -107,8 +114,9 @@ const struct format_type *fmt_from_vgname(const char *vgname)
struct list *devh, *tmp;
struct list devs;
struct device_list *devl;
char vgid_found[ID_LEN + 1];
if (!(vginfo = vginfo_from_vgname(vgname)))
if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
return NULL;
/* This function is normally called before reading metadata so
@@ -120,6 +128,8 @@ const struct format_type *fmt_from_vgname(const char *vgname)
list_add(&devs, &devl->list);
}
memcpy(vgid_found, vginfo->vgid, sizeof(vgid_found));
list_iterate_safe(devh, tmp, &devs) {
devl = list_item(devh, struct device_list);
label_read(devl->dev, &label);
@@ -127,6 +137,11 @@ const struct format_type *fmt_from_vgname(const char *vgname)
dm_free(devl);
}
/* If vginfo changed, caller needs to rescan */
if (!(vginfo = vginfo_from_vgname(vgname, vgid_found)) ||
strncmp(vginfo->vgid, vgid_found, sizeof(vgid_found)))
return NULL;
return vginfo->fmt;
}
@@ -148,6 +163,19 @@ struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid)
return vginfo;
}
const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid)
{
struct lvmcache_vginfo *vginfo;
if ((vginfo = vginfo_from_vgid(vgid))) {
if (mem)
return dm_pool_strdup(mem, vginfo->vgname);
return vginfo->vgname;
}
return NULL;
}
struct lvmcache_info *info_from_pvid(const char *pvid)
{
struct lvmcache_info *info;
@@ -232,10 +260,33 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
return r;
}
struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
{
struct list *vgids;
struct lvmcache_vginfo *vginfo;
lvmcache_label_scan(cmd, full_scan);
if (!(vgids = str_list_create(cmd->mem))) {
log_error("vgids list allocation failed");
return NULL;
}
list_iterate_items(vginfo, &_vginfos) {
if (!str_list_add(cmd->mem, vgids,
dm_pool_strdup(cmd->mem, vginfo->vgid))) {
log_error("strlist allocation failed");
return NULL;
}
}
return vgids;
}
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
{
struct list *vgnames;
struct lvmcache_vginfo *vgi;
struct lvmcache_vginfo *vginfo;
lvmcache_label_scan(cmd, full_scan);
@@ -244,9 +295,9 @@ struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
return NULL;
}
list_iterate_items(vgi, &_vginfos) {
list_iterate_items(vginfo, &_vginfos) {
if (!str_list_add(cmd->mem, vgnames,
dm_pool_strdup(cmd->mem, vgi->vgname))) {
dm_pool_strdup(cmd->mem, vginfo->vgname))) {
log_error("strlist allocation failed");
return NULL;
}
@@ -297,7 +348,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
return NULL;
}
static void _drop_vginfo(struct lvmcache_info *info)
static int _drop_vginfo(struct lvmcache_info *info)
{
if (!list_empty(&info->list)) {
list_del(&info->list);
@@ -306,8 +357,18 @@ static void _drop_vginfo(struct lvmcache_info *info)
if (info->vginfo && list_empty(&info->vginfo->infos)) {
dm_hash_remove(_vgname_hash, info->vginfo->vgname);
if (info->vginfo->next) {
if (!dm_hash_insert(_vgname_hash, info->vginfo->vgname, info->vginfo->next)) {
log_error("vg hash re-insertion failed: %s",
info->vginfo->vgname);
return 0;
}
}
if (info->vginfo->vgname)
dm_free(info->vginfo->vgname);
if (info->vginfo->creation_host)
dm_free(info->vginfo->creation_host);
if (*info->vginfo->vgid)
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
list_del(&info->vginfo->list);
@@ -315,6 +376,8 @@ static void _drop_vginfo(struct lvmcache_info *info)
}
info->vginfo = NULL;
return 1;
}
/* Unused
@@ -356,8 +419,10 @@ static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
if (info->vginfo && *info->vginfo->vgid)
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
if (!vgid)
if (!vgid) {
log_debug("lvmcache: %s: clearing VGID", dev_name(info->dev));
return 1;
}
strncpy(info->vginfo->vgid, vgid, sizeof(info->vginfo->vgid));
info->vginfo->vgid[sizeof(info->vginfo->vgid) - 1] = '\0';
@@ -367,19 +432,110 @@ static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
return 0;
}
log_debug("lvmcache: %s: setting %s VGID to %s", dev_name(info->dev),
info->vginfo->vgname, info->vginfo->vgid);
return 1;
}
int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
uint32_t vgstatus, const char *creation_host,
struct lvmcache_vginfo *primary_vginfo)
{
struct lvmcache_vginfo *vginfo;
struct lvmcache_vginfo *last_vginfo = primary_vginfo;
char uuid_primary[64], uuid_new[64];
int use_new = 0;
/* Pre-existing VG takes precedence. Unexported VG takes precedence. */
if (primary_vginfo) {
if (!id_write_format((struct id *)vgid, uuid_new, sizeof(uuid_new)))
return_0;
if (!id_write_format((struct id *)&primary_vginfo->vgid, uuid_primary,
sizeof(uuid_primary)))
return_0;
/*
* If Primary not exported, new exported => keep
* Else Primary exported, new not exported => change
* Else Primary has hostname for this machine => keep
* Else Primary has no hostname, new has one => change
* Else New has hostname for this machine => change
* Else Keep primary.
*/
if (!(primary_vginfo->status & EXPORTED_VG) &&
(vgstatus & EXPORTED_VG))
log_error("WARNING: Duplicate VG name %s: "
"Existing %s takes precedence over "
"exported %s", new_vginfo->vgname,
uuid_primary, uuid_new);
else if ((primary_vginfo->status & EXPORTED_VG) &&
!(vgstatus & EXPORTED_VG)) {
log_error("WARNING: Duplicate VG name %s: "
"%s takes precedence over exported %s",
new_vginfo->vgname, uuid_new,
uuid_primary);
use_new = 1;
} else if (primary_vginfo->creation_host &&
!strcmp(primary_vginfo->creation_host,
primary_vginfo->fmt->cmd->hostname))
log_error("WARNING: Duplicate VG name %s: "
"Existing %s (created here) takes precedence "
"over %s", new_vginfo->vgname, uuid_primary,
uuid_new);
else if (!primary_vginfo->creation_host && creation_host) {
log_error("WARNING: Duplicate VG name %s: "
"%s (with creation_host) takes precedence over %s",
new_vginfo->vgname, uuid_new,
uuid_primary);
use_new = 1;
} else if (creation_host &&
!strcmp(creation_host,
primary_vginfo->fmt->cmd->hostname)) {
log_error("WARNING: Duplicate VG name %s: "
"%s (created here) takes precedence over %s",
new_vginfo->vgname, uuid_new,
uuid_primary);
use_new = 1;
}
if (!use_new) {
while (last_vginfo->next)
last_vginfo = last_vginfo->next;
last_vginfo->next = new_vginfo;
return 1;
}
dm_hash_remove(_vgname_hash, primary_vginfo->vgname);
}
if (!dm_hash_insert(_vgname_hash, new_vginfo->vgname, new_vginfo)) {
log_error("cache_update: vg hash insertion failed: %s",
new_vginfo->vgname);
return 0;
}
if (primary_vginfo)
new_vginfo->next = primary_vginfo;
return 1;
}
static int _lvmcache_update_vgname(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *creation_host)
{
struct lvmcache_vginfo *vginfo, *primary_vginfo;
// struct lvmcache_vginfo *old_vginfo, *next;
/* If vgname is NULL and we don't already have a vgname,
* assume ORPHAN - we want every entry to have a vginfo
* attached for scanning reasons.
*/
if (!vgname && !info->vginfo)
if (!vgname && !info->vginfo) {
vgname = ORPHAN;
vgid = ORPHAN;
}
if (!vgname || (info->vginfo && !strcmp(info->vginfo->vgname, vgname)))
return 1;
@@ -388,7 +544,43 @@ int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
_drop_vginfo(info);
/* Get existing vginfo or create new one */
if (!(vginfo = vginfo_from_vgname(vgname))) {
if (!(vginfo = vginfo_from_vgname(vgname, vgid))) {
/*** FIXME - vginfo ends up duplicated instead of renamed.
// Renaming? This lookup fails.
if ((vginfo = vginfo_from_vgid(vgid))) {
next = vginfo->next;
old_vginfo = vginfo_from_vgname(vginfo->vgname, NULL);
if (old_vginfo == vginfo) {
dm_hash_remove(_vgname_hash, old_vginfo->vgname);
if (old_vginfo->next) {
if (!dm_hash_insert(_vgname_hash, old_vginfo->vgname, old_vginfo->next)) {
log_error("vg hash re-insertion failed: %s",
old_vginfo->vgname);
return 0;
}
}
} else do {
if (old_vginfo->next == vginfo) {
old_vginfo->next = vginfo->next;
break;
}
} while ((old_vginfo = old_vginfo->next));
vginfo->next = NULL;
dm_free(vginfo->vgname);
if (!(vginfo->vgname = dm_strdup(vgname))) {
log_error("cache vgname alloc failed for %s", vgname);
return 0;
}
// Rename so can assume new name does not already exist
if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo->next)) {
log_error("vg hash re-insertion failed: %s",
vginfo->vgname);
return 0;
}
} else {
***/
if (!(vginfo = dm_malloc(sizeof(*vginfo)))) {
log_error("lvmcache_update_vgname: list alloc failed");
return 0;
@@ -400,9 +592,9 @@ int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
return 0;
}
list_init(&vginfo->infos);
if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo)) {
log_error("cache_update: vg hash insertion failed: %s",
vginfo->vgname);
primary_vginfo = vginfo_from_vgname(vgname, NULL);
if (!_insert_vginfo(vginfo, vgid, vgstatus, creation_host,
primary_vginfo)) {
dm_free(vginfo->vgname);
dm_free(vginfo);
return 0;
@@ -412,6 +604,9 @@ int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
list_add(&_vginfos, &vginfo->list);
else
list_add_h(&_vginfos, &vginfo->list);
/***
}
***/
}
info->vginfo = vginfo;
@@ -420,8 +615,59 @@ int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
/* FIXME Check consistency of list! */
vginfo->fmt = info->fmt;
log_debug("lvmcache: %s now %s%s", dev_name(info->dev),
*vgname ? "in VG " : "orphaned", vgname);
log_debug("lvmcache: %s: now %s%s%s%s%s", dev_name(info->dev),
*vgname ? "in VG " : "orphaned", vgname,
vginfo->vgid[0] ? " (" : "",
vginfo->vgid[0] ? vginfo->vgid : "",
vginfo->vgid[0] ? ")" : "");
return 1;
}
static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstatus,
const char *creation_host)
{
if (!info || !info->vginfo)
return 1;
if ((info->vginfo->status & EXPORTED_VG) != (vgstatus & EXPORTED_VG))
log_debug("lvmcache: %s: VG %s %s exported",
dev_name(info->dev), info->vginfo->vgname,
vgstatus & EXPORTED_VG ? "now" : "no longer");
info->vginfo->status = vgstatus;
if (!creation_host)
return 1;
if (info->vginfo->creation_host && !strcmp(creation_host,
info->vginfo->creation_host))
return 1;
if (info->vginfo->creation_host)
dm_free(info->vginfo->creation_host);
if (!(info->vginfo->creation_host = dm_strdup(creation_host))) {
log_error("cache creation host alloc failed for %s",
creation_host);
return 0;
}
log_debug("lvmcache: %s: VG %s: Set creation host to %s.",
dev_name(info->dev), info->vginfo->vgname, creation_host);
return 1;
}
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *creation_host)
{
if (!_lvmcache_update_vgname(info, vgname, vgid, vgstatus,
creation_host) ||
!_lvmcache_update_vgid(info, vgid) ||
!_lvmcache_update_vgstatus(info, vgstatus, creation_host))
return_0;
return 1;
}
@@ -431,20 +677,17 @@ int lvmcache_update_vg(struct volume_group *vg)
struct pv_list *pvl;
struct lvmcache_info *info;
char pvid_s[ID_LEN + 1];
int vgid_updated = 0;
pvid_s[sizeof(pvid_s) - 1] = '\0';
list_iterate_items(pvl, &vg->pvs) {
strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1);
/* FIXME Could pvl->pv->dev->pvid ever be different? */
if ((info = info_from_pvid(pvid_s))) {
lvmcache_update_vgname(info, vg->name);
if (!vgid_updated) {
_lvmcache_update_vgid(info, (char *) &vg->id);
vgid_updated = 1;
}
}
if ((info = info_from_pvid(pvid_s)) &&
!lvmcache_update_vgname_and_id(info, vg->name,
(char *) &vg->id,
vg->status, NULL))
return_0;
}
return 1;
@@ -452,7 +695,8 @@ int lvmcache_update_vg(struct volume_group *vg)
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid)
const char *vgname, const char *vgid,
uint32_t vgstatus)
{
struct label *label;
struct lvmcache_info *existing, *info;
@@ -548,7 +792,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
return NULL;
}
if (!lvmcache_update_vgname(info, vgname)) {
if (!lvmcache_update_vgname_and_id(info, vgname, vgid, vgstatus, NULL)) {
if (!existing) {
dm_hash_remove(_pvid_hash, pvid_s);
strcpy(info->dev->pvid, "");
@@ -558,10 +802,6 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
return NULL;
}
if (!_lvmcache_update_vgid(info, vgid))
/* Non-critical */
stack;
return info;
}
@@ -576,9 +816,16 @@ static void _lvmcache_destroy_entry(struct lvmcache_info *info)
static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
{
if (vginfo->vgname)
dm_free(vginfo->vgname);
dm_free(vginfo);
struct lvmcache_vginfo *next;
do {
next = vginfo->next;
if (vginfo->vgname)
dm_free(vginfo->vgname);
if (vginfo->creation_host)
dm_free(vginfo->creation_host);
dm_free(vginfo);
} while ((vginfo = next));
}
static void _lvmcache_destroy_lockname(int present)

22
lib/cache/lvmcache.h vendored
View File

@@ -33,15 +33,20 @@ struct cmd_context;
struct format_type;
struct volume_group;
/* One per VG */
struct lvmcache_vginfo {
struct list list; /* Join these vginfos together */
struct list infos; /* List head for lvmcache_infos */
const struct format_type *fmt;
char *vgname; /* "" == orphan */
uint32_t status;
char vgid[ID_LEN + 1];
char _padding[7];
struct lvmcache_vginfo *next; /* Another VG with same name? */
char *creation_host;
};
/* One per device */
struct lvmcache_info {
struct list list; /* Join VG members together */
struct list mdas; /* list head for metadata areas */
@@ -64,21 +69,26 @@ 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);
const char *vgname, const char *vgid,
uint32_t vgstatus);
void lvmcache_del(struct lvmcache_info *info);
/* Update things */
int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname);
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *hostname);
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);
const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid);
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname,
const char *vgid);
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);
struct lvmcache_info *info_from_pvid(const char *pvid);
const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid);
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
int vgs_locked(void);
int vgname_is_locked(const char *vgname);
@@ -87,4 +97,8 @@ int vgname_is_locked(const char *vgname);
/* Set full_scan to 1 to reread every filtered device label */
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan);
/* Returns list of struct str_lists containing pool-allocated copy of vgids */
/* Set full_scan to 1 to reread every filtered device label */
struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan);
#endif

View File

@@ -657,7 +657,7 @@ static int _init_formats(struct cmd_context *cmd)
return 0;
}
if (!(lib = load_shared_library(cmd->cft, cv->v.str,
"format"))) {
"format", 0))) {
stack;
return 0;
}
@@ -753,7 +753,7 @@ static int _init_segtypes(struct cmd_context *cmd)
return 0;
}
if (!(lib = load_shared_library(cmd->cft, cv->v.str,
"segment type"))) {
"segment type", 0))) {
stack;
return 0;
}

View File

@@ -34,6 +34,8 @@
#define DEFAULT_LOCK_DIR "/var/lock/lvm"
#define DEFAULT_LOCKING_LIB "lvm2_locking.so"
#define DEFAULT_DMEVENTD_MIRROR_LIB "libdevmapper-event-lvm2mirror.so"
#define DEFAULT_UMASK 0077
#ifdef LVM1_FALLBACK

View File

@@ -107,7 +107,7 @@ void *btree_get_data(struct btree_iter *it)
return ((struct node *) it)->data;
}
static inline struct node *_left(struct node *n)
static struct node *_left(struct node *n)
{
while (n->l)
n = n->l;

View File

@@ -33,107 +33,61 @@ struct list {
* The list head's next and previous pointers point back to itself.
*/
#define LIST_INIT(name) struct list name = { &(name), &(name) }
static inline void list_init(struct list *head)
{
head->n = head->p = head;
}
void list_init(struct list *head);
/*
* Insert an element before 'head'.
* If 'head' is the list head, this adds an element to the end of the list.
*/
static inline void list_add(struct list *head, struct list *elem)
{
assert(head->n);
elem->n = head;
elem->p = head->p;
head->p->n = elem;
head->p = elem;
}
void list_add(struct list *head, struct list *elem);
/*
* Insert an element after 'head'.
* If 'head' is the list head, this adds an element to the front of the list.
*/
static inline void list_add_h(struct list *head, struct list *elem)
{
assert(head->n);
elem->n = head->n;
elem->p = head;
head->n->p = elem;
head->n = elem;
}
void list_add_h(struct list *head, struct list *elem);
/*
* Delete an element from its list.
* Note that this doesn't change the element itself - it may still be safe
* to follow its pointers.
*/
static inline void list_del(struct list *elem)
{
elem->n->p = elem->p;
elem->p->n = elem->n;
}
void list_del(struct list *elem);
/*
* Is the list empty?
*/
static inline int list_empty(struct list *head)
{
return head->n == head;
}
int list_empty(struct list *head);
/*
* Is this the first element of the list?
*/
static inline int list_start(struct list *head, struct list *elem)
{
return elem->p == head;
}
int list_start(struct list *head, struct list *elem);
/*
* Is this the last element of the list?
*/
static inline int list_end(struct list *head, struct list *elem)
{
return elem->n == head;
}
int list_end(struct list *head, struct list *elem);
/*
* Return first element of the list or NULL if empty
*/
static inline struct list *list_first(struct list *head)
{
return (list_empty(head) ? NULL : head->n);
}
struct list *list_first(struct list *head);
/*
* Return last element of the list or NULL if empty
*/
static inline struct list *list_last(struct list *head)
{
return (list_empty(head) ? NULL : head->p);
}
struct list *list_last(struct list *head);
/*
* Return the previous element of the list, or NULL if we've reached the start.
*/
static inline struct list *list_prev(struct list *head, struct list *elem)
{
return (list_start(head, elem) ? NULL : elem->p);
}
struct list *list_prev(struct list *head, struct list *elem);
/*
* Return the next element of the list, or NULL if we've reached the end.
*/
static inline struct list *list_next(struct list *head, struct list *elem)
{
return (list_end(head, elem) ? NULL : elem->n);
}
struct list *list_next(struct list *head, struct list *elem);
/*
* Given the address v of an instance of 'struct list' called 'head'
@@ -244,15 +198,6 @@ static inline struct list *list_next(struct list *head, struct list *elem)
/*
* Return the number of elements in a list by walking it.
*/
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;
}
unsigned int list_size(const struct list *head);
#endif

View File

@@ -479,7 +479,7 @@ static void _check_closed(struct device *dev)
log_err("Device '%s' has been left open.", dev_name(dev));
}
static inline void _check_for_open_devices(void)
static void _check_for_open_devices(void)
{
dm_hash_iter(_cache.names, (dm_hash_iterate_fn) _check_closed);
}
@@ -664,7 +664,7 @@ void dev_iter_destroy(struct dev_iter *iter)
dm_free(iter);
}
static inline struct device *_iter_next(struct dev_iter *iter)
static struct device *_iter_next(struct dev_iter *iter)
{
struct device *d = btree_get_data(iter->current);
iter->current = btree_next(iter->current);
@@ -682,3 +682,14 @@ struct device *dev_iter_get(struct dev_iter *iter)
return NULL;
}
int dev_fd(struct device *dev)
{
return dev->fd;
}
const char *dev_name(const struct device *dev)
{
return (dev) ? list_item(dev->aliases.n, struct str_list)->str :
"unknown device";
}

View File

@@ -418,7 +418,6 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
log_error("%s: fstat failed: Has device name changed?", name);
dev_close_immediate(dev);
dev->open_count = 0;
return 0;
}
@@ -509,11 +508,9 @@ static int _dev_close(struct device *dev, int immediate)
if (dev->open_count > 0)
dev->open_count--;
if (immediate && dev->open_count) {
if (immediate && dev->open_count)
log_debug("%s: Immediate close attempt while still referenced",
dev_name(dev));
dev->open_count = 0;
}
/* Close unless device is known to belong to a locked VG */
if (immediate ||

View File

@@ -74,10 +74,8 @@ int dev_close_immediate(struct device *dev);
void dev_close_all(void);
int dev_test_excl(struct device *dev);
static inline int dev_fd(struct device *dev)
{
return dev->fd;
}
int dev_fd(struct device *dev);
const char *dev_name(const struct device *dev);
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);
@@ -88,12 +86,6 @@ void dev_flush(struct device *dev);
struct device *dev_create_file(const char *filename, struct device *dev,
struct str_list *alias, int use_malloc);
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, int quiet);

View File

@@ -24,12 +24,12 @@
#include "lvm-string.h"
#include "activate.h"
static const char *_name(const struct lv_segment *seg)
static const char *_errseg_name(const struct lv_segment *seg)
{
return seg->segtype->name;
}
static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
static int _errseg_merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
{
seg1->len += seg2->len;
seg1->area_len += seg2->area_len;
@@ -38,7 +38,7 @@ static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
}
#ifdef DEVMAPPER_SUPPORT
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
static int _errseg_add_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg,
struct dm_tree_node *node, uint64_t len,
@@ -47,34 +47,34 @@ static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
return dm_tree_node_add_error_target(node, len);
}
static int _target_present(void)
static int _errseg_target_present(void)
{
static int checked = 0;
static int present = 0;
static int _errseg_checked = 0;
static int _errseg_present = 0;
/* Reported truncated in older kernels */
if (!checked &&
if (!_errseg_checked &&
(target_present("error", 0) || target_present("erro", 0)))
present = 1;
_errseg_present = 1;
checked = 1;
return present;
_errseg_checked = 1;
return _errseg_present;
}
#endif
static void _destroy(const struct segment_type *segtype)
static void _errseg_destroy(const struct segment_type *segtype)
{
dm_free((void *) segtype);
}
static struct segtype_handler _error_ops = {
name:_name,
merge_segments:_merge_segments,
name:_errseg_name,
merge_segments:_errseg_merge_segments,
#ifdef DEVMAPPER_SUPPORT
add_target_line:_add_target_line,
target_present:_target_present,
add_target_line:_errseg_add_target_line,
target_present:_errseg_target_present,
#endif
destroy:_destroy,
destroy:_errseg_destroy,
};
struct segment_type *init_error_segtype(struct cmd_context *cmd)

View File

@@ -33,7 +33,7 @@ static int _and_p(struct dev_filter *f, struct device *dev)
return 1;
}
static void _destroy(struct dev_filter *f)
static void _composite_destroy(struct dev_filter *f)
{
struct dev_filter **filters = (struct dev_filter **) f->private;
@@ -70,7 +70,7 @@ struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
}
cft->passes_filter = _and_p;
cft->destroy = _destroy;
cft->destroy = _composite_destroy;
cft->private = filters_copy;
return cft;

View File

@@ -217,7 +217,7 @@ static int _lookup_p(struct dev_filter *f, struct device *dev)
return (l == PF_BAD_DEVICE) ? 0 : 1;
}
static void _destroy(struct dev_filter *f)
static void _persistent_destroy(struct dev_filter *f)
{
struct pfilter *pf = (struct pfilter *) f->private;
@@ -258,7 +258,7 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
}
f->passes_filter = _lookup_p;
f->destroy = _destroy;
f->destroy = _persistent_destroy;
f->private = pf;
return f;

View File

@@ -191,7 +191,7 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
return !rejected;
}
static void _destroy(struct dev_filter *f)
static void _regex_destroy(struct dev_filter *f)
{
struct rfilter *rf = (struct rfilter *) f->private;
dm_pool_destroy(rf->mem);
@@ -226,7 +226,7 @@ struct dev_filter *regex_filter_create(struct config_value *patterns)
}
f->passes_filter = _accept_p;
f->destroy = _destroy;
f->destroy = _regex_destroy;
f->private = rf;
return f;

View File

@@ -88,7 +88,7 @@ static struct dev_set *_dev_set_create(struct dm_pool *mem, const char *sys_bloc
return ds;
}
static inline unsigned _hash_dev(dev_t dev)
static unsigned _hash_dev(dev_t dev)
{
return (major(dev) ^ minor(dev)) & (SET_BUCKETS - 1);
}

View File

@@ -223,11 +223,11 @@ static int _read_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
return 1;
}
static int _read_vgd(struct disk_list *data)
int read_vgd(struct device *dev, struct vg_disk *vgd, struct pv_disk *pvd)
{
struct vg_disk *vgd = &data->vgd;
uint64_t pos = data->pvd.vg_on_disk.base;
if (!dev_read(data->dev, pos, sizeof(*vgd), vgd))
uint64_t pos = pvd->vg_on_disk.base;
if (!dev_read(dev, pos, sizeof(*vgd), vgd))
fail;
_xlate_vgd(vgd);
@@ -269,7 +269,7 @@ static int _read_uuids(struct disk_list *data)
return 1;
}
static inline int _check_lvd(struct lv_disk *lvd)
static int _check_lvd(struct lv_disk *lvd)
{
return !(lvd->lv_name[0] == '\0');
}
@@ -319,13 +319,31 @@ static int _read_extents(struct disk_list *data)
return 1;
}
static void __update_lvmcache(const struct format_type *fmt,
struct disk_list *dl,
struct device *dev, const char *vgid,
int exported)
{
struct lvmcache_info *info;
if (!(info = lvmcache_add(fmt->labeller, dl->pvd.pv_uuid, dev,
dl->pvd.vg_name, vgid,
exported ? EXPORTED_VG : 0))) {
stack;
return;
}
info->device_size = xlate32(dl->pvd.pv_size) << SECTOR_SHIFT;
list_init(&info->mdas);
info->status &= ~CACHE_INVALID;
}
static struct disk_list *__read_disk(const struct format_type *fmt,
struct device *dev, struct dm_pool *mem,
const char *vg_name)
{
struct disk_list *dl = dm_pool_alloc(mem, sizeof(*dl));
struct disk_list *dl = dm_pool_zalloc(mem, sizeof(*dl));
const char *name = dev_name(dev);
struct lvmcache_info *info;
if (!dl) {
stack;
@@ -342,41 +360,32 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
goto bad;
}
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;
list_init(&info->mdas);
info->status &= ~CACHE_INVALID;
}
/*
* is it an orphan ?
*/
if (!*dl->pvd.vg_name) {
log_very_verbose("%s is not a member of any format1 VG", name);
/* Update VG cache */
/* vgcache_add(dl->pvd.vg_name, NULL, dev, fmt); */
__update_lvmcache(fmt, dl, dev, NULL, 0);
return (vg_name) ? NULL : dl;
}
if (!_read_vgd(dl)) {
if (!read_vgd(dl->dev, &dl->vgd, &dl->pvd)) {
log_error("Failed to read VG data from PV (%s)", name);
__update_lvmcache(fmt, dl, dev, NULL, 0);
goto bad;
}
/* Update VG cache with what we found */
/* vgcache_add(dl->pvd.vg_name, dl->vgd.vg_uuid, dev, fmt); */
if (vg_name && strcmp(vg_name, dl->pvd.vg_name)) {
log_very_verbose("%s is not a member of the VG %s",
name, vg_name);
__update_lvmcache(fmt, dl, dev, NULL, 0);
goto bad;
}
__update_lvmcache(fmt, dl, dev, dl->vgd.vg_uuid,
dl->vgd.vg_status & VG_EXPORTED);
if (!_read_uuids(dl)) {
log_error("Failed to read PV uuid list from %s", name);
goto bad;
@@ -461,7 +470,7 @@ int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
struct lvmcache_info *info;
/* Fast path if we already saw this VG and cached the list of PVs */
if (vg_name && (vginfo = vginfo_from_vgname(vg_name)) &&
if (vg_name && (vginfo = vginfo_from_vgname(vg_name, NULL)) &&
vginfo->infos.n) {
list_iterate_items(info, &vginfo->infos) {
dev = info->dev;

View File

@@ -204,7 +204,8 @@ int write_disks(const struct format_type *fmt, struct list *pvds);
*/
int import_pv(struct dm_pool *mem, struct device *dev,
struct volume_group *vg,
struct physical_volume *pv, struct pv_disk *pvd);
struct physical_volume *pv, struct pv_disk *pvd,
struct vg_disk *vgd);
int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
struct volume_group *vg,
struct pv_disk *pvd, struct physical_volume *pv);
@@ -237,6 +238,7 @@ void export_numbers(struct list *pvds, struct volume_group *vg);
void export_pv_act(struct list *pvds);
int munge_pvd(struct device *dev, struct pv_disk *pvd);
int read_vgd(struct device *dev, struct vg_disk *vgd, struct pv_disk *pvd);
/* blech */
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,

View File

@@ -173,7 +173,7 @@ static struct volume_group *_build_vg(struct format_instance *fid,
return NULL;
}
static struct volume_group *_vg_read(struct format_instance *fid,
static struct volume_group *_format1_vg_read(struct format_instance *fid,
const char *vg_name,
struct metadata_area *mda)
{
@@ -264,7 +264,7 @@ static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
return 1;
}
static int _vg_write(struct format_instance *fid, struct volume_group *vg,
static int _format1_vg_write(struct format_instance *fid, struct volume_group *vg,
struct metadata_area *mda)
{
struct dm_pool *mem = dm_pool_create("lvm1 vg_write", 1024 * 10);
@@ -287,7 +287,7 @@ static int _vg_write(struct format_instance *fid, struct volume_group *vg,
return r;
}
static int _pv_read(const struct format_type *fmt, const char *pv_name,
static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,
struct physical_volume *pv, struct list *mdas)
{
struct dm_pool *mem = dm_pool_create("lvm1 pv_read", 1024);
@@ -312,7 +312,7 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
goto out;
}
if (!import_pv(fmt->cmd->mem, dl->dev, NULL, pv, &dl->pvd)) {
if (!import_pv(fmt->cmd->mem, dl->dev, NULL, pv, &dl->pvd, &dl->vgd)) {
stack;
goto out;
}
@@ -326,7 +326,7 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
return r;
}
static int _pv_setup(const struct format_type *fmt,
static int _format1_pv_setup(const struct format_type *fmt,
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size,
int pvmetadatacopies,
@@ -364,7 +364,7 @@ static int _pv_setup(const struct format_type *fmt,
return 1;
}
static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
static int _format1_lv_setup(struct format_instance *fid, struct logical_volume *lv)
{
uint64_t max_size = UINT_MAX;
@@ -386,7 +386,7 @@ static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
return 1;
}
static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
static int _format1_pv_write(const struct format_type *fmt, struct physical_volume *pv,
struct list *mdas, int64_t sector)
{
struct dm_pool *mem;
@@ -396,7 +396,7 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
struct lvmcache_info *info;
if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
pv->vg_name, NULL))) {
pv->vg_name, NULL, 0))) {
stack;
return 0;
}
@@ -449,7 +449,7 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
return 0;
}
static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
static int _format1_vg_setup(struct format_instance *fid, struct volume_group *vg)
{
/* just check max_pv and max_lv */
if (!vg->max_lv || vg->max_lv >= MAX_LV)
@@ -484,7 +484,7 @@ static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
return 1;
}
static int _segtype_supported (struct format_instance *fid,
static int _format1_segtype_supported(struct format_instance *fid,
struct segment_type *segtype)
{
if (!(segtype->flags & SEG_FORMAT1_SUPPORT)) {
@@ -496,12 +496,13 @@ static int _segtype_supported (struct format_instance *fid,
}
static struct metadata_area_ops _metadata_format1_ops = {
vg_read:_vg_read,
vg_write:_vg_write,
vg_read:_format1_vg_read,
vg_write:_format1_vg_write,
};
static struct format_instance *_create_instance(const struct format_type *fmt,
static struct format_instance *_format1_create_instance(const struct format_type *fmt,
const char *vgname,
const char *vgid,
void *private)
{
struct format_instance *fid;
@@ -529,26 +530,26 @@ static struct format_instance *_create_instance(const struct format_type *fmt,
return fid;
}
static void _destroy_instance(struct format_instance *fid)
static void _format1_destroy_instance(struct format_instance *fid)
{
return;
}
static void _destroy(const struct format_type *fmt)
static void _format1_destroy(const struct format_type *fmt)
{
dm_free((void *) fmt);
}
static struct format_handler _format1_ops = {
pv_read:_pv_read,
pv_setup:_pv_setup,
pv_write:_pv_write,
lv_setup:_lv_setup,
vg_setup:_vg_setup,
segtype_supported:_segtype_supported,
create_instance:_create_instance,
destroy_instance:_destroy_instance,
destroy:_destroy,
pv_read:_format1_pv_read,
pv_setup:_format1_pv_setup,
pv_write:_format1_pv_write,
lv_setup:_format1_lv_setup,
vg_setup:_format1_vg_setup,
segtype_supported:_format1_segtype_supported,
create_instance:_format1_create_instance,
destroy_instance:_format1_destroy_instance,
destroy:_format1_destroy,
};
#ifdef LVM1_INTERNAL

View File

@@ -49,7 +49,8 @@ static char *_create_lv_name(struct dm_pool *mem, const char *full_name)
int import_pv(struct dm_pool *mem, struct device *dev,
struct volume_group *vg,
struct physical_volume *pv, struct pv_disk *pvd)
struct physical_volume *pv, struct pv_disk *pvd,
struct vg_disk *vgd)
{
memset(pv, 0, sizeof(*pv));
memcpy(&pv->id, pvd->pv_uuid, ID_LEN);
@@ -60,6 +61,8 @@ int import_pv(struct dm_pool *mem, struct device *dev,
return 0;
}
memcpy(&pv->vgid, vgd->vg_uuid, sizeof(vg->id));
/* Store system_id from first PV if PV belongs to a VG */
if (vg && !*vg->system_id)
strncpy(vg->system_id, pvd->system_id, NAME_LEN);
@@ -426,7 +429,7 @@ int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
return 0;
}
if (!import_pv(mem, dl->dev, vg, pvl->pv, &dl->pvd)) {
if (!import_pv(mem, dl->dev, vg, pvl->pv, &dl->pvd, &dl->vgd)) {
stack;
return 0;
}

View File

@@ -140,7 +140,12 @@ static int _fill_maps(struct dm_hash_table *maps, struct volume_group *vg,
lvm = lvms[lv_num];
if (!lvm) {
log_err("invalid lv in extent map");
log_error("Invalid LV in extent map "
"(PV %s, PE %" PRIu32
", LV %" PRIu32
", LE %" PRIu32 ")",
dev_name(pv->dev), i,
lv_num, e[i].le_num);
return 0;
}

View File

@@ -19,16 +19,18 @@
/*
* Only works with powers of 2.
*/
static inline uint32_t _round_up(uint32_t n, uint32_t size)
static uint32_t _round_up(uint32_t n, uint32_t size)
{
size--;
return (n + size) & ~size;
}
static inline uint32_t _div_up(uint32_t n, uint32_t size)
/* Unused.
static uint32_t _div_up(uint32_t n, uint32_t size)
{
return _round_up(n, size) / size;
}
*/
/*
* Each chunk of metadata should be aligned to

View File

@@ -30,7 +30,7 @@ static void _not_supported(const char *op)
op);
}
static int _can_handle(struct labeller *l, char *buf, uint64_t sector)
static int _lvm1_can_handle(struct labeller *l, char *buf, uint64_t sector)
{
struct pv_disk *pvd = (struct pv_disk *) buf;
uint32_t version;
@@ -48,21 +48,30 @@ static int _can_handle(struct labeller *l, char *buf, uint64_t sector)
return 0;
}
static int _write(struct label *label, char *buf)
static int _lvm1_write(struct label *label, char *buf)
{
_not_supported("write");
return 0;
}
static int _read(struct labeller *l, struct device *dev, char *buf,
static int _lvm1_read(struct labeller *l, struct device *dev, char *buf,
struct label **label)
{
struct pv_disk *pvd = (struct pv_disk *) buf;
struct vg_disk vgd;
struct lvmcache_info *info;
const char *vgid = NULL;
int exported = 0;
munge_pvd(dev, pvd);
if (!(info = lvmcache_add(l, pvd->pv_uuid, dev, pvd->vg_name, NULL))) {
if (*pvd->vg_name && read_vgd(dev, &vgd, pvd)) {
vgid = vgd.vg_uuid;
exported = pvd->pv_status & VG_EXPORTED;
}
if (!(info = lvmcache_add(l, pvd->pv_uuid, dev, pvd->vg_name, vgid,
exported))) {
stack;
return 0;
}
@@ -76,31 +85,31 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
return 1;
}
static int _initialise_label(struct labeller *l, struct label *label)
static int _lvm1_initialise_label(struct labeller *l, struct label *label)
{
strcpy(label->type, "LVM1");
return 1;
}
static void _destroy_label(struct labeller *l, struct label *label)
static void _lvm1_destroy_label(struct labeller *l, struct label *label)
{
return;
}
static void _destroy(struct labeller *l)
static void _lvm1_destroy(struct labeller *l)
{
dm_free(l);
}
struct label_ops _lvm1_ops = {
can_handle:_can_handle,
write:_write,
read:_read,
verify:_can_handle,
initialise_label:_initialise_label,
destroy_label:_destroy_label,
destroy:_destroy
can_handle:_lvm1_can_handle,
write:_lvm1_write,
read:_lvm1_read,
verify:_lvm1_can_handle,
initialise_label:_lvm1_initialise_label,
destroy_label:_lvm1_destroy_label,
destroy:_lvm1_destroy
};
struct labeller *lvm1_labeller_create(struct format_type *fmt)

View File

@@ -98,7 +98,7 @@ int read_pool_label(struct pool_list *pl, struct labeller *l,
log_debug("Calculated uuid %s for %s", uuid, pd->pl_pool_name);
if (!(info = lvmcache_add(l, (char *) &pvid, dev, pd->pl_pool_name,
(char *) &vgid))) {
(char *) &vgid, 0))) {
stack;
return 0;
}
@@ -314,7 +314,7 @@ int read_pool_pds(const struct format_type *fmt, const char *vg_name,
/*
* If the cache scanning doesn't work, this will never work
*/
if (vg_name && (vginfo = vginfo_from_vgname(vg_name)) &&
if (vg_name && (vginfo = vginfo_from_vgname(vg_name, NULL)) &&
vginfo->infos.n) {
if (_read_vg_pds(fmt, mem, vginfo, pdhead, &totaldevs)) {

View File

@@ -169,7 +169,7 @@ static struct volume_group *_build_vg_from_pds(struct format_instance
return vg;
}
static struct volume_group *_vg_read(struct format_instance *fid,
static struct volume_group *_pool_vg_read(struct format_instance *fid,
const char *vg_name,
struct metadata_area *mda)
{
@@ -206,7 +206,7 @@ static struct volume_group *_vg_read(struct format_instance *fid,
return vg;
}
static int _pv_setup(const struct format_type *fmt,
static int _pool_pv_setup(const struct format_type *fmt,
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size,
int pvmetadatacopies,
@@ -216,7 +216,7 @@ static int _pv_setup(const struct format_type *fmt,
return 1;
}
static int _pv_read(const struct format_type *fmt, const char *pv_name,
static int _pool_pv_read(const struct format_type *fmt, const char *pv_name,
struct physical_volume *pv, struct list *mdas)
{
struct dm_pool *mem = dm_pool_create("pool pv_read", 1024);
@@ -262,12 +262,13 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
/* *INDENT-OFF* */
static struct metadata_area_ops _metadata_format_pool_ops = {
vg_read:_vg_read,
vg_read:_pool_vg_read,
};
/* *INDENT-ON* */
static struct format_instance *_create_instance(const struct format_type *fmt,
static struct format_instance *_pool_create_instance(const struct format_type *fmt,
const char *vgname,
const char *vgid,
void *private)
{
struct format_instance *fid;
@@ -297,23 +298,23 @@ static struct format_instance *_create_instance(const struct format_type *fmt,
return fid;
}
static void _destroy_instance(struct format_instance *fid)
static void _pool_destroy_instance(struct format_instance *fid)
{
return;
}
static void _destroy(const struct format_type *fmt)
static void _pool_destroy(const struct format_type *fmt)
{
dm_free((void *) fmt);
}
/* *INDENT-OFF* */
static struct format_handler _format_pool_ops = {
pv_read:_pv_read,
pv_setup:_pv_setup,
create_instance:_create_instance,
destroy_instance:_destroy_instance,
destroy:_destroy,
pv_read:_pool_pv_read,
pv_setup:_pool_pv_setup,
create_instance:_pool_create_instance,
destroy_instance:_pool_destroy_instance,
destroy:_pool_destroy,
};
/* *INDENT-ON */

View File

@@ -165,6 +165,7 @@ int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem,
log_error("Unable to duplicate vg_name string");
return 0;
}
memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
pv->status = 0;
pv->size = pd->pl_blocks;
pv->pe_size = POOL_PE_SIZE;

View File

@@ -23,13 +23,13 @@
#include <sys/stat.h>
#include <fcntl.h>
static void _not_supported(const char *op)
static void _pool_not_supported(const char *op)
{
log_error("The '%s' operation is not supported for the pool labeller.",
op);
}
static int _can_handle(struct labeller *l, char *buf, uint64_t sector)
static int _pool_can_handle(struct labeller *l, char *buf, uint64_t sector)
{
struct pool_disk pd;
@@ -50,13 +50,13 @@ static int _can_handle(struct labeller *l, char *buf, uint64_t sector)
return 0;
}
static int _write(struct label *label, char *buf)
static int _pool_write(struct label *label, char *buf)
{
_not_supported("write");
_pool_not_supported("write");
return 0;
}
static int _read(struct labeller *l, struct device *dev, char *buf,
static int _pool_read(struct labeller *l, struct device *dev, char *buf,
struct label **label)
{
struct pool_list pl;
@@ -64,31 +64,31 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
return read_pool_label(&pl, l, dev, buf, label);
}
static int _initialise_label(struct labeller *l, struct label *label)
static int _pool_initialise_label(struct labeller *l, struct label *label)
{
strcpy(label->type, "POOL");
return 1;
}
static void _destroy_label(struct labeller *l, struct label *label)
static void _pool_destroy_label(struct labeller *l, struct label *label)
{
return;
}
static void _destroy(struct labeller *l)
static void _label_pool_destroy(struct labeller *l)
{
dm_free(l);
}
struct label_ops _pool_ops = {
can_handle:_can_handle,
write:_write,
read:_read,
verify:_can_handle,
initialise_label:_initialise_label,
destroy_label:_destroy_label,
destroy:_destroy
can_handle:_pool_can_handle,
write:_pool_write,
read:_pool_read,
verify:_pool_can_handle,
initialise_label:_pool_initialise_label,
destroy_label:_pool_destroy_label,
destroy:_label_pool_destroy
};
struct labeller *pool_labeller_create(struct format_type *fmt)

View File

@@ -87,7 +87,7 @@ static int _split_vg(const char *filename, char *vgname, size_t vg_size,
return 1;
}
static void _insert_file(struct list *head, struct archive_file *b)
static void _insert_archive_file(struct list *head, struct archive_file *b)
{
struct archive_file *bf = NULL;
@@ -107,7 +107,7 @@ static void _insert_file(struct list *head, struct archive_file *b)
list_add_h(&bf->list, &b->list);
}
static char *_join(struct dm_pool *mem, const char *dir, const char *name)
static char *_join_file_to_dir(struct dm_pool *mem, const char *dir, const char *name)
{
if (!dm_pool_begin_object(mem, 32) ||
!dm_pool_grow_object(mem, dir, strlen(dir)) ||
@@ -161,7 +161,7 @@ static struct list *_scan_archive(struct dm_pool *mem,
if (strcmp(vgname, vgname_found))
continue;
if (!(path = _join(mem, dir, dirent[i]->d_name))) {
if (!(path = _join_file_to_dir(mem, dir, dirent[i]->d_name))) {
stack;
goto out;
}
@@ -181,7 +181,7 @@ static struct list *_scan_archive(struct dm_pool *mem,
/*
* Insert it to the correct part of the list.
*/
_insert_file(results, af);
_insert_archive_file(results, af);
}
out:
@@ -207,8 +207,8 @@ static void _remove_expired(struct list *archives, uint32_t archives_size,
/* Convert retain_days into the time after which we must retain */
retain_time = time(NULL) - (time_t) retain_days *SECS_PER_DAY;
/* Assume list is ordered oldest first (by index) */
list_iterate_items(bf, archives) {
/* Assume list is ordered newest first (by index) */
list_iterate_back_items(bf, archives) {
/* Get the mtime of the file and unlink if too old */
if (stat(bf->path, &sb)) {
log_sys_error("stat", bf->path);
@@ -311,7 +311,7 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
if (!(context = create_text_context(cmd, af->path, NULL)) ||
!(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
context))) {
NULL, context))) {
log_error("Couldn't create text instance object.");
return;
}
@@ -360,7 +360,7 @@ 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))) {
if (!(af.path = _join_file_to_dir(cmd->mem, dir, vgname))) {
stack;
return 0;
}

View File

@@ -257,7 +257,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
if (!(context = create_text_context(cmd, file,
cmd->cmd_line)) ||
!(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
context))) {
NULL, context))) {
log_error("Couldn't create text format object.");
return NULL;
}
@@ -286,7 +286,7 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
/* Attempt to write out using currently active format */
if (!(vg->fid = cmd->fmt->ops->create_instance(cmd->fmt, vg->name,
NULL))) {
NULL, NULL))) {
log_error("Failed to allocate format instance");
return 0;
}
@@ -365,7 +365,7 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)
if (!(context = create_text_context(cmd, file, desc)) ||
!(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
context))) {
NULL, context))) {
log_error("Couldn't create backup object.");
return 0;
}

View File

@@ -354,8 +354,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
* Get the pv%d name from the formatters hash
* table.
*/
static inline const char *_get_pv_name(struct formatter *f,
struct physical_volume *pv)
static const char *_get_pv_name(struct formatter *f, struct physical_volume *pv)
{
return (pv) ? (const char *)
dm_hash_lookup(f->pv_names, dev_name(pv->dev)) : "Missing";

View File

@@ -39,8 +39,9 @@
#define FMT_TEXT_NAME "lvm2"
#define FMT_TEXT_ALIAS "text"
static struct format_instance *_create_text_instance(const struct format_type
static struct format_instance *_text_create_text_instance(const struct format_type
*fmt, const char *vgname,
const char *vgid,
void *context);
struct text_fid_context {
@@ -68,7 +69,7 @@ struct text_context {
* NOTE: Currently there can be only one vg per text file.
*/
static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
static int _text_vg_setup(struct format_instance *fid, struct volume_group *vg)
{
if (vg->extent_size & (vg->extent_size - 1)) {
log_error("Extent size must be power of 2");
@@ -78,7 +79,7 @@ static int _vg_setup(struct format_instance *fid, struct volume_group *vg)
return 1;
}
static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
static int _text_lv_setup(struct format_instance *fid, struct logical_volume *lv)
{
/******** FIXME Any LV size restriction?
uint64_t max_size = UINT_MAX;
@@ -219,7 +220,7 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
error:
if ((info = info_from_pvid(dev_area->dev->pvid)))
lvmcache_update_vgname(info, ORPHAN);
lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN, 0, NULL);
return NULL;
}
@@ -858,9 +859,11 @@ static int _scan_file(const struct format_type *fmt)
}
/* FIXME stat file to see if it's changed */
fid = _create_text_instance(fmt, NULL, NULL);
fid = _text_create_text_instance(fmt, NULL, NULL,
NULL);
if ((vg = _vg_read_file_name(fid, vgname,
path)))
/* FIXME Store creation host in vg */
lvmcache_update_vg(vg);
}
@@ -871,65 +874,92 @@ static int _scan_file(const struct format_type *fmt)
return 1;
}
int vgname_from_mda(const struct format_type *fmt, struct device_area *dev_area,
char *buf, uint32_t size)
const char *vgname_from_mda(const struct format_type *fmt,
struct device_area *dev_area, struct id *vgid,
uint32_t *vgstatus, char **creation_host)
{
struct raw_locn *rlocn;
struct mda_header *mdah;
unsigned int len;
int r = 0;
uint32_t wrap = 0;
const char *vgname = NULL;
unsigned int len = 0;
char buf[NAME_LEN + 1];
if (!dev_open(dev_area->dev)) {
stack;
return 0;
return NULL;
}
if (!(mdah = _raw_read_mda_header(fmt, dev_area))) {
stack;
if (!(mdah = _raw_read_mda_header(fmt, dev_area)))
goto_out;
/* FIXME Cope with returning a list */
rlocn = mdah->raw_locns;
/* Do quick check for a vgname */
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
NAME_LEN, buf))
goto_out;
while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
len < (NAME_LEN - 1))
len++;
buf[len] = '\0';
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(buf))
goto_out;
/* We found a VG - now check the metadata */
if (rlocn->offset + rlocn->size > mdah->size)
wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
if (wrap > rlocn->offset) {
log_error("%s: metadata too large for circular buffer",
dev_name(dev_area->dev));
goto out;
}
rlocn = mdah->raw_locns;
/* FIXME 64-bit */
if (!(vgname = text_vgname_import(fmt, dev_area->dev,
(off_t) (dev_area->start +
rlocn->offset),
(uint32_t) (rlocn->size - wrap),
(off_t) (dev_area->start +
MDA_HEADER_SIZE),
wrap, calc_crc, rlocn->checksum,
vgid, vgstatus, creation_host)))
goto_out;
while (rlocn->offset) {
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++;
buf[len] = '\0';
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(buf)) {
stack;
goto out;
}
r = 1;
break;
/* FIXME Cope with returning a list */
rlocn++;
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(vgname)) {
stack;
vgname = NULL;
goto out;
}
log_debug("%s: Found metadata at %" PRIu64 " size %" PRIu64
" for %s (%s)",
dev_name(dev_area->dev), dev_area->start + rlocn->offset,
rlocn->size, vgname, vgid->uuid);
out:
if (!dev_close(dev_area->dev))
stack;
return r;
return vgname;
}
static int _scan_raw(const struct format_type *fmt)
{
struct raw_list *rl;
struct list *raw_list;
char vgnamebuf[NAME_LEN + 2];
const char *vgname;
struct volume_group *vg;
struct format_instance fid;
struct id vgid;
uint32_t vgstatus;
raw_list = &((struct mda_lists *) fmt->private)->raws;
@@ -938,9 +968,9 @@ static int _scan_raw(const struct format_type *fmt)
list_iterate_items(rl, raw_list) {
/* FIXME We're reading mdah twice here... */
if (vgname_from_mda(fmt, &rl->dev_area, vgnamebuf,
sizeof(vgnamebuf))) {
if ((vg = _vg_read_raw_area(&fid, vgnamebuf,
if ((vgname = vgname_from_mda(fmt, &rl->dev_area, &vgid, &vgstatus,
NULL))) {
if ((vg = _vg_read_raw_area(&fid, vgname,
&rl->dev_area, 0)))
lvmcache_update_vg(vg);
}
@@ -949,7 +979,7 @@ static int _scan_raw(const struct format_type *fmt)
return 1;
}
static int _scan(const struct format_type *fmt)
static int _text_scan(const struct format_type *fmt)
{
return (_scan_file(fmt) & _scan_raw(fmt));
}
@@ -1095,7 +1125,7 @@ static int _mda_setup(const struct format_type *fmt,
/* Only for orphans */
/* Set label_sector to -1 if rewriting existing label into same sector */
static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
static int _text_pv_write(const struct format_type *fmt, struct physical_volume *pv,
struct list *mdas, int64_t label_sector)
{
struct label *label;
@@ -1109,7 +1139,7 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
/* FIXME Test mode don't update cache? */
if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
ORPHAN, NULL))) {
ORPHAN, NULL, 0))) {
stack;
return 0;
}
@@ -1220,7 +1250,7 @@ static int _add_raw(struct list *raw_list, struct device_area *dev_area)
return 1;
}
static int _pv_read(const struct format_type *fmt, const char *pv_name,
static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
struct physical_volume *pv, struct list *mdas)
{
struct label *label;
@@ -1245,7 +1275,7 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
/* Have we already cached vgname? */
if (info->vginfo && info->vginfo->vgname && *info->vginfo->vgname &&
get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
info->dev->pvid, pv)) {
info->vginfo->vgid, info->dev->pvid, pv)) {
return 1;
}
@@ -1256,6 +1286,7 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
if (info->vginfo && info->vginfo->vgname &&
*info->vginfo->vgname &&
get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
info->vginfo->vgid,
info->dev->pvid, pv)) {
return 1;
}
@@ -1301,7 +1332,7 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
return 1;
}
static void _destroy_instance(struct format_instance *fid)
static void _text_destroy_instance(struct format_instance *fid)
{
return;
}
@@ -1326,7 +1357,7 @@ static void _free_raws(struct list *raw_list)
}
}
static void _destroy(const struct format_type *fmt)
static void _text_destroy(const struct format_type *fmt)
{
if (fmt->private) {
_free_dirs(&((struct mda_lists *) fmt->private)->dirs);
@@ -1363,7 +1394,7 @@ static struct metadata_area_ops _metadata_text_raw_ops = {
};
/* pvmetadatasize in sectors */
static int _pv_setup(const struct format_type *fmt,
static int _text_pv_setup(const struct format_type *fmt,
uint64_t pe_start, uint32_t extent_count,
uint32_t extent_size,
int pvmetadatacopies,
@@ -1380,7 +1411,7 @@ static int _pv_setup(const struct format_type *fmt,
/* FIXME if vg, adjust start/end of pe area to avoid mdas! */
/* FIXME Cope with pvchange */
/* FIXME Merge code with _create_text_instance */
/* FIXME Merge code with _text_create_text_instance */
/* If new vg, add any further mdas on this PV to the fid's mda list */
if (vg) {
@@ -1448,8 +1479,9 @@ static int _pv_setup(const struct format_type *fmt,
}
/* NULL vgname means use only the supplied context e.g. an archive file */
static struct format_instance *_create_text_instance(const struct format_type
static struct format_instance *_text_create_text_instance(const struct format_type
*fmt, const char *vgname,
const char *vgid,
void *context)
{
struct format_instance *fid;
@@ -1535,7 +1567,7 @@ static struct format_instance *_create_text_instance(const struct format_type
/* Scan PVs in VG for any further MDAs */
lvmcache_label_scan(fmt->cmd, 0);
if (!(vginfo = vginfo_from_vgname(vgname))) {
if (!(vginfo = vginfo_from_vgname(vgname, vgid))) {
stack;
goto out;
}
@@ -1569,7 +1601,6 @@ static struct format_instance *_create_text_instance(const struct format_type
out:
return fid;
}
void *create_text_context(struct cmd_context *cmd, const char *path,
@@ -1618,15 +1649,15 @@ void *create_text_context(struct cmd_context *cmd, const char *path,
}
static struct format_handler _text_handler = {
scan:_scan,
pv_read:_pv_read,
pv_setup:_pv_setup,
pv_write:_pv_write,
vg_setup:_vg_setup,
lv_setup:_lv_setup,
create_instance:_create_text_instance,
destroy_instance:_destroy_instance,
destroy:_destroy
scan:_text_scan,
pv_read:_text_pv_read,
pv_setup:_text_pv_setup,
pv_write:_text_pv_write,
vg_setup:_text_vg_setup,
lv_setup:_text_lv_setup,
create_instance:_text_create_text_instance,
destroy_instance:_text_destroy_instance,
destroy:_text_destroy
};
static int _add_dir(const char *dir, struct list *dir_list)

View File

@@ -54,7 +54,8 @@ int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct list *mda
struct device *dev, uint64_t start, uint64_t size);
void del_mdas(struct list *mdas);
int vgname_from_mda(const struct format_type *fmt, struct device_area *dev_area,
char *buf, uint32_t size);
const char *vgname_from_mda(const struct format_type *fmt,
struct device_area *dev_area, struct id *vgid,
uint32_t *vgstatus, char **creation_host);
#endif

View File

@@ -47,6 +47,10 @@ struct text_vg_version_ops {
struct config_tree * cf);
void (*read_desc) (struct dm_pool * mem, struct config_tree * cf,
time_t *when, char **desc);
const char *(*read_vgname) (const struct format_type *fmt,
struct config_tree *cft,
struct id *vgid, uint32_t *vgstatus,
char **creation_host);
};
struct text_vg_version_ops *text_vg_vsn1_init(void);
@@ -70,5 +74,12 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
checksum_fn_t checksum_fn,
uint32_t checksum,
time_t *when, char **desc);
const char *text_vgname_import(const struct format_type *fmt,
struct device *dev,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn, uint32_t checksum,
struct id *vgid, uint32_t *vgstatus,
char **creation_host);
#endif

View File

@@ -23,6 +23,53 @@
/* FIXME Use tidier inclusion method */
static struct text_vg_version_ops *(_text_vsn_list[2]);
const char *text_vgname_import(const struct format_type *fmt,
struct device *dev,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn, uint32_t checksum,
struct id *vgid, uint32_t *vgstatus,
char **creation_host)
{
struct config_tree *cft;
struct text_vg_version_ops **vsn;
const char *vgname;
static int _text_import_initialised = 0;
if (!_text_import_initialised) {
_text_vsn_list[0] = text_vg_vsn1_init();
_text_vsn_list[1] = NULL;
_text_import_initialised = 1;
}
if (!(cft = create_config_tree(NULL)))
goto_out;
if ((!dev && !read_config_file(cft)) ||
(dev && !read_config_fd(cft, dev, offset, size,
offset2, size2, checksum_fn, checksum)))
goto_out;
/*
* Find a set of version functions that can read this file
*/
for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
if (!(*vsn)->check_version(cft))
continue;
if (!(vgname = (*vsn)->read_vgname(fmt, cft, vgid, vgstatus,
creation_host)))
goto_out;
break;
}
out:
destroy_config_tree(cft);
return vgname;
}
struct volume_group *text_vg_import_fd(struct format_instance *fid,
const char *file,
struct device *dev,
@@ -36,12 +83,12 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
struct config_tree *cft;
struct text_vg_version_ops **vsn;
static int _initialised = 0;
static int _text_vg_import_initialised = 0;
if (!_initialised) {
if (!_text_vg_import_initialised) {
_text_vsn_list[0] = text_vg_vsn1_init();
_text_vsn_list[1] = NULL;
_initialised = 1;
_text_vg_import_initialised = 1;
}
*desc = NULL;

View File

@@ -167,6 +167,8 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
return 0;
}
memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
if (!(cn = find_config_node(pvn, "status"))) {
log_error("Couldn't find status flags for physical volume.");
return 0;
@@ -798,10 +800,59 @@ static void _read_desc(struct dm_pool *mem,
*when = u;
}
static const char *_read_vgname(const struct format_type *fmt,
struct config_tree *cft, struct id *vgid,
uint32_t *vgstatus, char **creation_host)
{
struct config_node *vgn, *cn;
struct dm_pool *mem = fmt->cmd->mem;
char *vgname;
int old_suppress;
old_suppress = log_suppress(2);
*creation_host = dm_pool_strdup(mem,
find_config_str(cft->root,
"creation_host", ""));
log_suppress(old_suppress);
/* skip any top-level values */
for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) ;
if (!vgn) {
log_error("Couldn't find volume group in file.");
return 0;
}
if (!(vgname = dm_pool_strdup(mem, vgn->key)))
return_0;
vgn = vgn->child;
if (!_read_id(vgid, vgn, "id")) {
log_error("Couldn't read uuid for volume group %s.", vgname);
return 0;
}
if (!(cn = find_config_node(vgn, "status"))) {
log_error("Couldn't find status flags for volume group %s.",
vgname);
return 0;
}
if (!(read_flags(vgstatus, VG_FLAGS, cn->v))) {
log_error("Couldn't read status flags for volume group %s.",
vgname);
return 0;
}
return vgname;
}
static struct text_vg_version_ops _vsn1_ops = {
check_version:_check_version,
read_vg:_read_vg,
read_desc:_read_desc
read_desc:_read_desc,
read_vgname:_read_vgname
};
struct text_vg_version_ops *text_vg_vsn1_init(void)

View File

@@ -23,7 +23,7 @@
#include <sys/stat.h>
#include <fcntl.h>
static int _can_handle(struct labeller *l, char *buf, uint64_t sector)
static int _text_can_handle(struct labeller *l, char *buf, uint64_t sector)
{
struct label_header *lh = (struct label_header *) buf;
@@ -33,7 +33,7 @@ static int _can_handle(struct labeller *l, char *buf, uint64_t sector)
return 0;
}
static int _write(struct label *label, char *buf)
static int _text_write(struct label *label, char *buf)
{
struct label_header *lh = (struct label_header *) buf;
struct pv_header *pvhdr;
@@ -179,14 +179,14 @@ void del_mdas(struct list *mdas)
}
}
static int _initialise_label(struct labeller *l, struct label *label)
static int _text_initialise_label(struct labeller *l, struct label *label)
{
strncpy(label->type, LVM2_LABEL, sizeof(label->type));
return 1;
}
static int _read(struct labeller *l, struct device *dev, char *buf,
static int _text_read(struct labeller *l, struct device *dev, char *buf,
struct label **label)
{
struct label_header *lh = (struct label_header *) buf;
@@ -195,13 +195,16 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
struct disk_locn *dlocn_xl;
uint64_t offset;
struct metadata_area *mda;
char vgnamebuf[NAME_LEN + 2];
struct id vgid;
struct mda_context *mdac;
const char *vgname;
uint32_t vgstatus;
char *creation_host;
pvhdr = (struct pv_header *) ((void *) buf + xlate32(lh->offset_xl));
if (!(info = lvmcache_add(l, pvhdr->pv_uuid, dev, NULL, NULL)))
return 0;
if (!(info = lvmcache_add(l, pvhdr->pv_uuid, dev, NULL, NULL, 0)))
return_0;
*label = info->label;
info->device_size = xlate64(pvhdr->device_size_xl);
@@ -232,10 +235,12 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
list_iterate_items(mda, &info->mdas) {
mdac = (struct mda_context *) mda->metadata_locn;
if (vgname_from_mda(info->fmt, &mdac->area, vgnamebuf,
sizeof(vgnamebuf))) {
lvmcache_update_vgname(info, vgnamebuf);
}
if ((vgname = vgname_from_mda(info->fmt, &mdac->area,
&vgid, &vgstatus, &creation_host)) &&
!lvmcache_update_vgname_and_id(info, vgname,
(char *) &vgid, vgstatus,
creation_host))
return_0;
}
info->status &= ~CACHE_INVALID;
@@ -243,7 +248,7 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
return 1;
}
static void _destroy_label(struct labeller *l, struct label *label)
static void _text_destroy_label(struct labeller *l, struct label *label)
{
struct lvmcache_info *info = (struct lvmcache_info *) label->info;
@@ -253,19 +258,19 @@ static void _destroy_label(struct labeller *l, struct label *label)
del_das(&info->das);
}
static void _destroy(struct labeller *l)
static void _fmt_text_destroy(struct labeller *l)
{
dm_free(l);
}
struct label_ops _text_ops = {
can_handle:_can_handle,
write:_write,
read:_read,
verify:_can_handle,
initialise_label:_initialise_label,
destroy_label:_destroy_label,
destroy:_destroy
can_handle:_text_can_handle,
write:_text_write,
read:_text_read,
verify:_text_can_handle,
initialise_label:_text_initialise_label,
destroy_label:_text_destroy_label,
destroy:_fmt_text_destroy
};
struct labeller *text_labeller_create(const struct format_type *fmt)

View File

@@ -117,15 +117,6 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
int found = 0;
char readbuf[LABEL_SCAN_SIZE];
if (!dev_open(dev)) {
stack;
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname(info, ORPHAN);
return NULL;
}
if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, readbuf)) {
log_debug("%s: Failed to read label area", dev_name(dev));
goto out;
@@ -184,13 +175,11 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
out:
if (!found) {
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname(info, ORPHAN);
lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN,
0, NULL);
log_very_verbose("%s: No label detected", dev_name(dev));
}
if (!dev_close(dev))
stack;
return r;
}
@@ -272,16 +261,29 @@ int label_read(struct device *dev, struct label **result)
char buf[LABEL_SIZE];
struct labeller *l;
uint64_t sector;
int r;
struct lvmcache_info *info;
int r = 0;
if (!(l = _find_labeller(dev, buf, &sector))) {
if (!dev_open(dev)) {
stack;
return 0;
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN,
0, NULL);
goto out;
}
if (!(l = _find_labeller(dev, buf, &sector)))
goto_out;
if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result)
(*result)->sector = sector;
out:
if (!dev_close(dev))
stack;
return r;
}
@@ -335,18 +337,35 @@ int label_write(struct device *dev, struct label *label)
return r;
}
/* Unused */
int label_verify(struct device *dev)
{
struct labeller *l;
char buf[LABEL_SIZE];
uint64_t sector;
struct lvmcache_info *info;
int r = 0;
if (!(l = _find_labeller(dev, buf, &sector))) {
if (!dev_open(dev)) {
stack;
return 0;
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN,
0, NULL);
goto out;
}
return ((l->ops->verify) ? l->ops->verify(l, buf, sector) : 1);
if (!(l = _find_labeller(dev, buf, &sector)))
goto_out;
r = l->ops->verify ? l->ops->verify(l, buf, sector) : 1;
out:
if (!dev_close(dev))
stack;
return r;
}
void label_destroy(struct label *label)

View File

@@ -330,6 +330,9 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
args[0] = flags & 0x7F; /* Maskoff lock flags */
args[1] = flags & 0xC0; /* Bitmap flags */
if (partial_mode())
args[1] |= LCK_PARTIAL_MODE;
/*
* VG locks are just that: locks, and have no side effects
* so we only need to do them on the local node because all

View File

@@ -72,7 +72,7 @@ int init_external_locking(struct locking_type *locking, struct config_tree *cft)
libname = find_config_str(cft->root, "global/locking_library",
DEFAULT_LOCKING_LIB);
if (!(_locking_lib = load_shared_library(cft, libname, "locking"))) {
if (!(_locking_lib = load_shared_library(cft, libname, "locking", 1))) {
stack;
return 0;
}

View File

@@ -102,7 +102,7 @@ void reset_locking(void)
_unblock_signals();
}
static inline void _update_vg_lock_count(int flags)
static void _update_vg_lock_count(int flags)
{
if ((flags & LCK_SCOPE_MASK) != LCK_VG)
return;

View File

@@ -67,6 +67,11 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_LOCAL 0x00000040 /* Don't propagate to other nodes */
#define LCK_CLUSTER_VG 0x00000080 /* VG is clustered */
/*
* Additional lock bits for cluster communication
*/
#define LCK_PARTIAL_MODE 0x00000001 /* Running in partial mode */
/*
* Common combinations
*/

View File

@@ -90,9 +90,13 @@ void init_syslog(int facility)
_syslog = 1;
}
void log_suppress(int suppress)
int log_suppress(int suppress)
{
int old_suppress = _log_suppress;
_log_suppress = suppress;
return old_suppress;
}
void release_log_memory(void)
@@ -253,6 +257,9 @@ void print_log(int level, const char *file, int line, const char *format, ...)
const char *message;
const char *trformat; /* Translated format string */
if (_log_suppress == 2)
return;
trformat = _(format);
if (_lvm2_log_fn) {

View File

@@ -86,8 +86,9 @@ int ignorelockingfailure(void);
int lockingfailed(void);
int security_level(void);
/* Suppress messages to stdout/stderr */
void log_suppress(int suppress);
/* Suppress messages to stdout/stderr (1) or everywhere (2) */
/* Returns previous setting */
int log_suppress(int suppress);
/* Suppress messages to syslog */
void syslog_suppress(int suppress);

View File

@@ -52,7 +52,8 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
uint32_t mirrored_pe,
uint32_t status,
struct list *allocatable_pvs,
alloc_policy_t alloc);
alloc_policy_t alloc,
struct list *parallel_areas);
int lv_add_segment(struct alloc_handle *ah,
uint32_t first_area, uint32_t num_areas,
@@ -83,4 +84,7 @@ int lv_add_more_mirrored_areas(struct logical_volume *lv,
void alloc_destroy(struct alloc_handle *ah);
struct list *build_parallel_areas_from_lv(struct cmd_context *cmd,
struct logical_volume *lv);
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -24,6 +24,18 @@
#include "display.h"
#include "segtype.h"
/*
* PVs used by a segment of an LV
*/
struct seg_pvs {
struct list list;
struct list pvs; /* struct pv_list */
uint32_t le;
uint32_t len;
};
/*
* Find first unused LV number.
*/
@@ -342,13 +354,16 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
}
/*
* Empty an LV
* Empty an LV.
*/
int lv_empty(struct logical_volume *lv)
{
return _lv_reduce(lv, 0, lv->le_count);
return _lv_reduce(lv, lv->le_count, 0);
}
/*
* Remove given number of extents from LV.
*/
int lv_reduce(struct logical_volume *lv, uint32_t extents)
{
return _lv_reduce(lv, extents, 1);
@@ -391,6 +406,10 @@ struct alloc_handle {
uint32_t log_count; /* Number of parallel 1-extent logs */
uint32_t total_area_len; /* Total number of parallel extents */
struct physical_volume *mirrored_pv; /* FIXME Remove this */
uint32_t mirrored_pe; /* FIXME Remove this */
struct list *parallel_areas; /* PVs to avoid */
struct alloced_area log_area; /* Extent used for log */
struct list alloced_areas[0]; /* Lists of areas in each stripe */
};
@@ -404,7 +423,9 @@ static struct alloc_handle *_alloc_init(struct dm_pool *mem,
uint32_t mirrors,
uint32_t stripes,
uint32_t log_count,
struct physical_volume *mirrored_pv)
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe,
struct list *parallel_areas)
{
struct alloc_handle *ah;
uint32_t s, area_count;
@@ -458,6 +479,10 @@ static struct alloc_handle *_alloc_init(struct dm_pool *mem,
for (s = 0; s < ah->area_count; s++)
list_init(&ah->alloced_areas[s]);
ah->mirrored_pv = mirrored_pv;
ah->mirrored_pe = mirrored_pe;
ah->parallel_areas = parallel_areas;
return ah;
}
@@ -646,7 +671,6 @@ static int _check_contiguous(struct lv_segment *prev_lvseg,
/*
* Choose sets of parallel areas to use, respecting any constraints.
*/
/* FIXME Also accept existing areas new space must be parallel to */
static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
struct list *pvms, struct pv_area **areas,
uint32_t areas_size, unsigned can_split,
@@ -655,10 +679,15 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
{
struct pv_map *pvm;
struct pv_area *pva;
struct pv_list *pvl;
unsigned already_found_one = 0;
unsigned contiguous = 0, contiguous_count = 0;
unsigned ix;
unsigned ix_offset = 0; /* Offset for non-contiguous allocations */
uint32_t max_parallel; /* Maximum extents to allocate */
uint32_t next_le;
struct seg_pvs *spvs;
struct list *parallel_pvs;
/* FIXME Do calculations on free extent counts before selecting space */
/* FIXME Select log PV appropriately if there isn't one yet */
@@ -676,6 +705,25 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
do {
ix = 0;
parallel_pvs = NULL;
max_parallel = needed;
/*
* If there are existing parallel PVs, avoid them and reduce
* the maximum we can allocate in one go accordingly.
*/
if (ah->parallel_areas) {
list_iterate_items(spvs, ah->parallel_areas) {
next_le = (prev_lvseg ? prev_lvseg->le + prev_lvseg->len : 0) + *allocated;
if (next_le >= spvs->le) {
if (next_le + max_parallel > spvs->le + spvs->len)
max_parallel = (spvs->le + spvs->len - next_le) * ah->area_multiple;
parallel_pvs = &spvs->pvs;
break;
}
}
}
/*
* Put the smallest area of each PV that is at least the
* size we need into areas array. If there isn't one
@@ -686,10 +734,18 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
if (list_empty(&pvm->areas))
continue; /* Next PV */
/* Don't allocate onto the log pv */
if ((alloc != ALLOC_ANYWHERE) && ah->log_count &&
(pvm->pv == ah->log_area.pv))
continue; /* Next PV */
if (alloc != ALLOC_ANYWHERE) {
/* Don't allocate onto the log pv */
if (ah->log_count &&
pvm->pv == ah->log_area.pv)
continue; /* Next PV */
/* Avoid PVs used by existing parallel areas */
if (parallel_pvs)
list_iterate_items(pvl, parallel_pvs)
if (pvm->pv == pvl->pv)
goto next_pv;
}
already_found_one = 0;
/* First area in each list is the largest */
@@ -700,17 +756,17 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
pvm->pv,
pva, areas)) {
contiguous_count++;
break; /* Next PV */
goto next_pv;
}
continue;
}
/* Is it big enough on its own? */
if ((pva->count < needed - *allocated) &&
if ((pva->count < max_parallel - *allocated) &&
((!can_split && !ah->log_count) ||
(already_found_one &&
!(alloc == ALLOC_ANYWHERE))))
break; /* Next PV */
goto next_pv;
if (!already_found_one ||
alloc == ALLOC_ANYWHERE) {
@@ -720,8 +776,9 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
areas[ix + ix_offset - 1] = pva;
break; /* Next PV */
goto next_pv;
}
next_pv:
if (ix >= areas_size)
break;
}
@@ -743,7 +800,7 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
/* First time around, use smallest area as log_area */
/* FIXME decide which PV to use at top of function instead */
if (!_alloc_parallel_area(ah, needed, areas,
if (!_alloc_parallel_area(ah, max_parallel, areas,
allocated,
(ah->log_count && !ah->log_area.len) ?
*(areas + ix_offset + ix - 1) :
@@ -764,13 +821,11 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
*/
static int _allocate(struct alloc_handle *ah,
struct volume_group *vg,
struct logical_volume *lv, uint32_t status,
uint32_t new_extents,
struct list *allocatable_pvs,
uint32_t stripes, uint32_t mirrors,
struct segment_type *segtype,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe)
struct logical_volume *lv, uint32_t status,
uint32_t new_extents,
struct list *allocatable_pvs,
uint32_t stripes, uint32_t mirrors,
struct segment_type *segtype)
{
struct pv_area **areas;
uint32_t allocated = lv ? lv->le_count : 0;
@@ -781,12 +836,12 @@ static int _allocate(struct alloc_handle *ah,
struct list *pvms;
uint32_t areas_size;
if (allocated >= new_extents) {
if (allocated >= new_extents && !ah->log_count) {
log_error("_allocate called with no work to do!");
return 1;
}
if (mirrored_pv || (ah->alloc == ALLOC_CONTIGUOUS))
if (ah->mirrored_pv || (ah->alloc == ALLOC_CONTIGUOUS))
can_split = 0;
if (lv && !list_empty(&lv->segments))
@@ -906,7 +961,8 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
uint32_t mirrored_pe,
uint32_t status,
struct list *allocatable_pvs,
alloc_policy_t alloc)
alloc_policy_t alloc,
struct list *parallel_areas)
{
struct alloc_handle *ah;
@@ -929,15 +985,15 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
alloc = vg->alloc;
if (!(ah = _alloc_init(vg->cmd->mem, segtype, alloc, mirrors,
stripes, log_count, mirrored_pv))) {
stripes, log_count, mirrored_pv,
mirrored_pe, parallel_areas))) {
stack;
return NULL;
}
if (!segtype_is_virtual(segtype) &&
!_allocate(ah, vg, lv, status, (lv ? lv->le_count : 0) + extents,
allocatable_pvs,
stripes, mirrors, segtype, mirrored_pv, mirrored_pe)) {
allocatable_pvs, stripes, mirrors, segtype)) {
stack;
alloc_destroy(ah);
return NULL;
@@ -1098,8 +1154,7 @@ int lv_add_more_mirrored_areas(struct logical_volume *lv,
return 0;
}
list_iterate_items(seg, &lv->segments)
break;
seg = first_seg(lv);
old_area_count = seg->area_count;
new_area_count = old_area_count + num_extra_areas;
@@ -1139,7 +1194,7 @@ int lv_extend(struct logical_volume *lv,
if (!(ah = allocate_extents(lv->vg, lv, segtype, stripes, mirrors, 0,
extents, mirrored_pv, mirrored_pe, status,
allocatable_pvs, alloc))) {
allocatable_pvs, alloc, NULL))) {
stack;
return 0;
}
@@ -1272,3 +1327,116 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
return lv;
}
/* Recursively process each PV used by part of an LV */
static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t le, uint32_t len,
int (*fn)(struct cmd_context *cmd, struct pv_segment *peg, struct seg_pvs *spvs),
struct seg_pvs *spvs)
{
struct lv_segment *seg;
uint32_t s;
uint32_t remaining_seg_len, area_len, area_multiple;
if (!(seg = find_seg_by_le(lv, le))) {
log_error("Failed to find segment for %s extent %" PRIu32,
lv->name, le);
return 0;
}
/* Remaining logical length of segment */
remaining_seg_len = seg->len - (le - seg->le);
if (len > remaining_seg_len)
remaining_seg_len = len;
if (spvs->len > remaining_seg_len)
spvs->len = remaining_seg_len;
area_multiple = segtype_is_striped(seg->segtype) ? seg->area_count : 1;
area_len = remaining_seg_len / area_multiple;
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) == AREA_LV) {
if (!_for_each_pv(cmd, seg_lv(seg, s),
seg_le(seg, s) + (le - seg->le) / area_multiple,
area_len, fn, spvs)) {
stack;
return 0;
}
} else if (seg_type(seg, s) == AREA_PV) {
if (!fn(cmd, seg_pvseg(seg, s), spvs)) {
stack;
return 0;
}
}
}
return 1;
}
static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg, struct seg_pvs *spvs)
{
struct pv_list *pvl;
/* FIXME Don't add again if it's already on the list! */
if (!(pvl = dm_pool_alloc(cmd->mem, sizeof(*pvl)))) {
log_error("pv_list allocation failed");
return 0;
}
pvl->pv = peg->pv;
/* FIXME Use ordered list to facilitate comparison */
list_add(&spvs->pvs, &pvl->list);
/* FIXME Add mirror logs, snapshot cow LVs etc. */
return 1;
}
/*
* Construct list of segments of LVs showing which PVs they use.
*/
struct list *build_parallel_areas_from_lv(struct cmd_context *cmd,
struct logical_volume *lv)
{
struct list *parallel_areas;
struct seg_pvs *spvs;
uint32_t current_le = 0;
if (!(parallel_areas = dm_pool_alloc(cmd->mem, sizeof(*parallel_areas)))) {
log_error("parallel_areas allocation failed");
return NULL;
}
list_init(parallel_areas);
do {
if (!(spvs = dm_pool_zalloc(cmd->mem, sizeof(*spvs)))) {
log_error("allocation failed");
return NULL;
}
list_init(&spvs->pvs);
spvs->le = current_le;
spvs->len = lv->le_count - current_le;
list_add(parallel_areas, &spvs->list);
/* Find next segment end */
/* FIXME Unnecessary nesting! */
if (!_for_each_pv(cmd, lv, current_le, lv->le_count, _add_pvs, spvs)) {
stack;
return NULL;
}
current_le = spvs->le + spvs->len;
} while (current_le < lv->le_count);
/* FIXME Merge adjacent segments with identical PV lists (avoids need for contiguous allocation attempts between successful allocations) */
return parallel_areas;
}

View File

@@ -71,6 +71,8 @@ static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
return 0;
}
memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
/* Units of 512-byte sectors */
pv->pe_size = vg->extent_size;
@@ -143,13 +145,14 @@ static int _copy_pv(struct physical_volume *pv_to,
}
int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
const char *id, struct physical_volume *pv)
const char *vgid, const char *pvid,
struct physical_volume *pv)
{
struct volume_group *vg;
struct pv_list *pvl;
int consistent = 0;
if (!(vg = vg_read(fmt->cmd, vg_name, &consistent))) {
if (!(vg = vg_read(fmt->cmd, vg_name, vgid, &consistent))) {
log_error("get_pv_from_vg_by_id: vg_read failed to read VG %s",
vg_name);
return 0;
@@ -160,7 +163,7 @@ int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
vg_name);
list_iterate_items(pvl, &vg->pvs) {
if (id_equal(&pvl->pv->id, (const struct id *) id)) {
if (id_equal(&pvl->pv->id, (const struct id *) pvid)) {
if (!_copy_pv(pv, pvl->pv)) {
stack;
return 0;
@@ -239,7 +242,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
/* is this vg name already in use ? */
old_partial = partial_mode();
init_partial(1);
if (vg_read(cmd, vg_name, &consistent)) {
if (vg_read(cmd, vg_name, NULL, &consistent)) {
log_err("A volume group called '%s' already exists.", vg_name);
goto bad;
}
@@ -286,7 +289,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
list_init(&vg->tags);
if (!(vg->fid = cmd->fmt->ops->create_instance(cmd->fmt, vg_name,
NULL))) {
NULL, NULL))) {
log_error("Failed to create format instance");
goto bad;
}
@@ -496,7 +499,7 @@ struct physical_volume *pv_create(const struct format_type *fmt,
uint64_t pvmetadatasize, struct list *mdas)
{
struct dm_pool *mem = fmt->cmd->mem;
struct physical_volume *pv = dm_pool_alloc(mem, sizeof(*pv));
struct physical_volume *pv = dm_pool_zalloc(mem, sizeof(*pv));
if (!pv) {
stack;
@@ -862,7 +865,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
struct volume_group *vg;
struct physical_volume *pv;
if (!(vginfo = vginfo_from_vgname(ORPHAN))) {
if (!(vginfo = vginfo_from_vgname(ORPHAN, NULL))) {
stack;
return NULL;
}
@@ -907,6 +910,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
*/
static struct volume_group *_vg_read(struct cmd_context *cmd,
const char *vgname,
const char *vgid,
int *consistent, int precommitted)
{
struct format_instance *fid;
@@ -928,15 +932,15 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
/* Find the vgname in the cache */
/* If it's not there we must do full scan to be completely sure */
if (!(fmt = fmt_from_vgname(vgname))) {
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
lvmcache_label_scan(cmd, 0);
if (!(fmt = fmt_from_vgname(vgname))) {
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
if (memlock()) {
stack;
return NULL;
}
lvmcache_label_scan(cmd, 2);
if (!(fmt = fmt_from_vgname(vgname))) {
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
stack;
return NULL;
}
@@ -947,7 +951,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
use_precommitted = 0;
/* create format instance with appropriate metadata area */
if (!(fid = fmt->ops->create_instance(fmt, vgname, NULL))) {
if (!(fid = fmt->ops->create_instance(fmt, vgname, vgid, NULL))) {
log_error("Failed to create format instance");
return NULL;
}
@@ -978,7 +982,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
inconsistent = 0;
lvmcache_label_scan(cmd, 2);
if (!(fmt = fmt_from_vgname(vgname))) {
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
stack;
return NULL;
}
@@ -987,7 +991,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
use_precommitted = 0;
/* create format instance with appropriate metadata area */
if (!(fid = fmt->ops->create_instance(fmt, vgname, NULL))) {
if (!(fid = fmt->ops->create_instance(fmt, vgname, vgid, NULL))) {
log_error("Failed to create format instance");
return NULL;
}
@@ -1069,12 +1073,12 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
}
struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
int *consistent)
const char *vgid, int *consistent)
{
struct volume_group *vg;
struct lv_list *lvl;
if (!(vg = _vg_read(cmd, vgname, consistent, 0)))
if (!(vg = _vg_read(cmd, vgname, vgid, consistent, 0)))
return NULL;
if (!check_pv_segments(vg)) {
@@ -1112,7 +1116,7 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
/* Is corresponding vgname already cached? */
if ((vginfo = vginfo_from_vgid(vgid)) &&
vginfo->vgname && *vginfo->vgname) {
if ((vg = _vg_read(cmd, vginfo->vgname,
if ((vg = _vg_read(cmd, vginfo->vgname, vgid,
&consistent, precommitted)) &&
!strncmp(vg->id.uuid, vgid, ID_LEN)) {
if (!consistent) {
@@ -1143,7 +1147,7 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
if (!vgname || !*vgname)
continue; // FIXME Unnecessary?
consistent = 0;
if ((vg = _vg_read(cmd, vgname, &consistent,
if ((vg = _vg_read(cmd, vgname, vgid, &consistent,
precommitted)) &&
!strncmp(vg->id.uuid, vgid, ID_LEN)) {
if (!consistent) {
@@ -1245,13 +1249,18 @@ struct list *get_vgs(struct cmd_context *cmd, int full_scan)
return lvmcache_get_vgnames(cmd, full_scan);
}
struct list *get_vgids(struct cmd_context *cmd, int full_scan)
{
return lvmcache_get_vgids(cmd, full_scan);
}
struct list *get_pvs(struct cmd_context *cmd)
{
struct str_list *strl;
struct list *results;
const char *vgname;
const char *vgname, *vgid;
struct list *pvh, *tmp;
struct list *vgnames;
struct list *vgids;
struct volume_group *vg;
int consistent = 0;
int old_partial;
@@ -1267,7 +1276,7 @@ struct list *get_pvs(struct cmd_context *cmd)
list_init(results);
/* Get list of VGs */
if (!(vgnames = get_vgs(cmd, 0))) {
if (!(vgids = get_vgids(cmd, 0))) {
log_error("get_pvs: get_vgs failed");
return NULL;
}
@@ -1278,12 +1287,16 @@ struct list *get_pvs(struct cmd_context *cmd)
old_pvmove = pvmove_mode();
init_partial(1);
init_pvmove(1);
list_iterate_items(strl, vgnames) {
vgname = strl->str;
if (!vgname)
list_iterate_items(strl, vgids) {
vgid = strl->str;
if (!vgid)
continue; /* FIXME Unnecessary? */
consistent = 0;
if (!(vg = vg_read(cmd, vgname, &consistent))) {
if (!(vgname = vgname_from_vgid(NULL, vgid))) {
stack;
continue;
}
if (!(vg = vg_read(cmd, vgname, vgid, &consistent))) {
stack;
continue;
}

View File

@@ -23,9 +23,9 @@
#include "ctype.h"
#include "dev-cache.h"
#include "lvm-string.h"
#include "uuid.h"
#define NAME_LEN 128
#define MAX_STRIPES 128
#define SECTOR_SHIFT 9L
#define SECTOR_SIZE ( 1L << SECTOR_SHIFT )
@@ -122,6 +122,7 @@ struct physical_volume {
struct device *dev;
const struct format_type *fmt;
const char *vg_name;
struct id vgid;
uint32_t status;
uint64_t size;
@@ -382,6 +383,7 @@ struct format_handler {
*/
struct format_instance *(*create_instance) (const struct format_type *
fmt, const char *vgname,
const char *vgid,
void *context);
/*
@@ -403,7 +405,7 @@ int vg_write(struct volume_group *vg);
int vg_commit(struct volume_group *vg);
int vg_revert(struct volume_group *vg);
struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name,
int *consistent);
const char *vgid, int *consistent);
struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
struct list *mdas, uint64_t *label_sector,
int warnings);
@@ -411,6 +413,7 @@ struct list *get_pvs(struct cmd_context *cmd);
/* Set full_scan to 1 to re-read every (filtered) device label */
struct list *get_vgs(struct cmd_context *cmd, int full_scan);
struct list *get_vgids(struct cmd_context *cmd, int full_scan);
int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
struct list *mdas, int64_t label_sector);
@@ -478,7 +481,8 @@ struct pv_list *find_pv_in_vg(struct volume_group *vg, const char *pv_name);
struct physical_volume *find_pv_in_vg_by_uuid(struct volume_group *vg,
struct id *id);
int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
const char *id, struct physical_volume *pv);
const char *vgid, const char *pvid,
struct physical_volume *pv);
/* Find an LV within a given VG */
struct lv_list *find_lv_in_vg(struct volume_group *vg, const char *lv_name);
@@ -535,11 +539,16 @@ int lv_split_segment(struct logical_volume *lv, uint32_t le);
*/
int lv_is_origin(const struct logical_volume *lv);
int lv_is_cow(const struct logical_volume *lv);
int lv_is_visible(const struct logical_volume *lv);
int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv);
/* Given a cow LV, return return the snapshot lv_segment that uses it */
struct lv_segment *find_cow(const struct logical_volume *lv);
/* Given a cow LV, return its origin */
struct logical_volume *origin_from_cow(const struct logical_volume *lv);
int vg_add_snapshot(struct format_instance *fid, const char *name,
struct logical_volume *origin, struct logical_volume *cow,
union lvid *lvid, uint32_t extent_count,
@@ -561,8 +570,14 @@ int create_mirror_layers(struct alloc_handle *ah,
uint32_t status,
uint32_t region_size,
struct logical_volume *log_lv);
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors);
int remove_all_mirror_images(struct logical_volume *lv);
int add_mirror_layers(struct alloc_handle *ah,
uint32_t num_mirrors,
uint32_t existing_mirrors,
struct logical_volume *lv,
struct segment_type *segtype);
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct list *removable_pvs, int remove_log);
/*
* Given mirror image or mirror log segment, find corresponding mirror segment
*/
@@ -594,29 +609,4 @@ uint32_t find_free_lvnum(struct logical_volume *lv);
char *generate_lv_name(struct volume_group *vg, const char *format,
char *buffer, size_t len);
static inline int validate_name(const char *n)
{
register char c;
register int len = 0;
if (!n || !*n)
return 0;
/* Hyphen used as VG-LV separator - ambiguity if LV starts with it */
if (*n == '-')
return 0;
if (!strcmp(n, ".") || !strcmp(n, ".."))
return 0;
while ((len++, c = *n++))
if (!isalnum(c) && c != '.' && c != '_' && c != '-' && c != '+')
return 0;
if (len > NAME_LEN)
return 0;
return 1;
}
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -21,6 +21,7 @@
#include "activate.h"
#include "lv_alloc.h"
#include "lvm-string.h"
#include "locking.h" /* FIXME Should not be used in this file */
struct lv_segment *find_mirror_seg(struct lv_segment *seg)
{
@@ -62,6 +63,9 @@ static void _move_lv_segments(struct logical_volume *lv_to, struct logical_volum
list_init(&lv_from->segments);
lv_to->le_count = lv_from->le_count;
lv_to->size = lv_from->size;
lv_from->le_count = 0;
lv_from->size = 0;
}
@@ -69,65 +73,163 @@ static void _move_lv_segments(struct logical_volume *lv_to, struct logical_volum
/*
* Reduce mirrored_seg to num_mirrors images.
*/
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors)
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct list *removable_pvs, int remove_log)
{
uint32_t m;
uint32_t s, s1;
struct logical_volume *sub_lv;
struct logical_volume *log_lv = NULL;
struct logical_volume *lv1 = NULL;
struct physical_volume *pv;
struct lv_segment *seg;
struct lv_segment_area area;
int all_pvs_removable, pv_found;
struct pv_list *pvl;
uint32_t old_area_count = mirrored_seg->area_count;
uint32_t new_area_count = mirrored_seg->area_count;
log_very_verbose("Reducing mirror set from %" PRIu32 " to %"
PRIu32 " image(s)%s.",
old_area_count, num_mirrors,
remove_log ? " and no log volume" : "");
/* Move removable_pvs to end of array */
if (removable_pvs) {
for (s = 0; s < mirrored_seg->area_count; s++) {
all_pvs_removable = 1;
sub_lv = seg_lv(mirrored_seg, s);
list_iterate_items(seg, &sub_lv->segments) {
for (s1 = 0; s1 < seg->area_count; s1++) {
if (seg_type(seg, s1) != AREA_PV)
/* FIXME Recurse for AREA_LV */
continue;
pv = seg_pv(seg, s1);
pv_found = 0;
list_iterate_items(pvl, removable_pvs) {
if (pv->dev->dev == pvl->pv->dev->dev) {
pv_found = 1;
break;
}
}
if (!pv_found) {
all_pvs_removable = 0;
break;
}
}
if (!all_pvs_removable)
break;
}
if (all_pvs_removable) {
/* Swap segment to end */
new_area_count--;
area = mirrored_seg->areas[new_area_count];
mirrored_seg->areas[new_area_count] = mirrored_seg->areas[s];
mirrored_seg->areas[s] = area;
}
/* Found enough matches? */
if (new_area_count == num_mirrors)
break;
}
if (new_area_count == mirrored_seg->area_count) {
log_error("No mirror images found using specified PVs.");
return 0;
}
}
for (m = num_mirrors; m < mirrored_seg->area_count; m++) {
seg_lv(mirrored_seg, m)->status &= ~MIRROR_IMAGE;
seg_lv(mirrored_seg, m)->status |= VISIBLE_LV;
}
mirrored_seg->area_count = num_mirrors;
/* If no more mirrors, remove mirror layer */
if (num_mirrors == 1) {
lv1 = seg_lv(mirrored_seg, 0);
_move_lv_segments(mirrored_seg->lv, lv1);
mirrored_seg->lv->status &= ~MIRRORED;
remove_log = 1;
}
if (remove_log) {
log_lv = mirrored_seg->log_lv;
mirrored_seg->log_lv = NULL;
}
/*
* To successfully remove these unwanted LVs we need to
* remove the LVs from the mirror set, commit that metadata
* then deactivate and remove them fully.
*/
/* FIXME lv1 has no segments here so shouldn't be written to disk! */
if (!vg_write(mirrored_seg->lv->vg)) {
log_error("intermediate VG write failed.");
return 0;
}
if (!suspend_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
log_error("Failed to lock %s", mirrored_seg->lv->name);
vg_revert(mirrored_seg->lv->vg);
return 0;
}
if (!vg_commit(mirrored_seg->lv->vg)) {
resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv);
return 0;
}
log_very_verbose("Updating \"%s\" in kernel", mirrored_seg->lv->name);
if (!resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
log_error("Problem reactivating %s", mirrored_seg->lv->name);
return 0;
}
/* Delete the 'orphan' LVs */
for (m = num_mirrors; m < old_area_count; m++) {
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, seg_lv(mirrored_seg, m))) {
stack;
return 0;
}
if (!lv_remove(seg_lv(mirrored_seg, m))) {
stack;
return 0;
}
}
mirrored_seg->area_count = num_mirrors;
if (lv1) {
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, lv1)) {
stack;
return 0;
}
if (!lv_remove(lv1)) {
stack;
return 0;
}
}
if (log_lv) {
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, log_lv)) {
stack;
return 0;
}
if (!lv_remove(log_lv)) {
stack;
return 0;
}
}
return 1;
}
int remove_all_mirror_images(struct logical_volume *lv)
{
struct lv_segment *seg;
struct logical_volume *lv1;
seg = first_seg(lv);
if (!remove_mirror_images(seg, 1)) {
stack;
return 0;
}
if (seg->log_lv && !lv_remove(seg->log_lv)) {
stack;
return 0;
}
lv1 = seg_lv(seg, 0);
_move_lv_segments(lv, lv1);
if (!lv_remove(lv1)) {
stack;
return 0;
}
lv->status &= ~MIRRORED;
return 1;
}
/*
* Add mirror images to an existing mirror
*/
/* FIXME
int add_mirror_images(struct alloc_handle *ah,
uint32_t first_area,
uint32_t num_areas,
struct logical_volume *lv)
{
}
*/
static int _create_layers_for_mirror(struct alloc_handle *ah,
uint32_t first_area,
uint32_t num_mirrors,
@@ -161,7 +263,10 @@ static int _create_layers_for_mirror(struct alloc_handle *ah,
return 0;
}
if (!lv_add_segment(ah, m, 1, img_lvs[m],
if (m < first_area)
continue;
if (!lv_add_segment(ah, m - first_area, 1, img_lvs[m],
get_segtype_from_string(lv->vg->cmd,
"striped"),
0, NULL, 0, 0, 0, NULL)) {
@@ -219,6 +324,30 @@ int create_mirror_layers(struct alloc_handle *ah,
return 1;
}
int add_mirror_layers(struct alloc_handle *ah,
uint32_t num_mirrors,
uint32_t existing_mirrors,
struct logical_volume *lv,
struct segment_type *segtype)
{
struct logical_volume **img_lvs;
if (!(img_lvs = alloca(sizeof(*img_lvs) * num_mirrors))) {
log_error("img_lvs allocation failed. "
"Remove new LV and retry.");
return 0;
}
if (!_create_layers_for_mirror(ah, 0, num_mirrors,
lv, segtype,
img_lvs)) {
stack;
return 0;
}
return lv_add_more_mirrored_areas(lv, img_lvs, num_mirrors, 0);
}
/*
* Replace any LV segments on given PV with temporary mirror.
* Returns list of LVs changed.

View File

@@ -78,6 +78,12 @@ struct segtype_handler {
uint64_t *total_denominator, float *percent);
int (*target_present) (void);
void (*destroy) (const struct segment_type * segtype);
int (*target_register_events) (struct dm_pool *mem,
struct lv_segment *seg,
struct config_tree *cft, int events);
int (*target_unregister_events) (struct dm_pool *mem,
struct lv_segment *seg,
struct config_tree *cft, int events);
};
struct segment_type *get_segtype_from_string(struct cmd_context *cmd,

View File

@@ -28,12 +28,26 @@ int lv_is_cow(const struct logical_volume *lv)
return lv->snapshot ? 1 : 0;
}
int lv_is_visible(const struct logical_volume *lv)
{
if (lv_is_cow(lv))
return lv_is_visible(find_cow(lv)->lv);
return lv->status & VISIBLE_LV ? 1 : 0;
}
/* Given a cow LV, return the snapshot lv_segment that uses it */
struct lv_segment *find_cow(const struct logical_volume *lv)
{
return lv->snapshot;
}
/* Given a cow LV, return its origin */
struct logical_volume *origin_from_cow(const struct logical_volume *lv)
{
return lv->snapshot->origin;
}
int vg_add_snapshot(struct format_instance *fid, const char *name,
struct logical_volume *origin,
struct logical_volume *cow, union lvid *lvid,

View File

@@ -25,6 +25,13 @@
#include "lvm-string.h"
#include "targets.h"
#include "activate.h"
#include "sharedlib.h"
#ifdef DMEVENTD
# include <libdevmapper-event.h>
#endif
static int _block_on_error_available = 0;
enum {
MIRR_DISABLED,
@@ -36,12 +43,12 @@ struct mirror_state {
uint32_t default_region_size;
};
static const char *_name(const struct lv_segment *seg)
static const char *_mirrored_name(const struct lv_segment *seg)
{
return seg->segtype->name;
}
static void _display(const struct lv_segment *seg)
static void _mirrored_display(const struct lv_segment *seg)
{
const char *size;
uint32_t s;
@@ -66,7 +73,7 @@ static void _display(const struct lv_segment *seg)
log_print(" ");
}
static int _text_import_area_count(struct config_node *sn, uint32_t *area_count)
static int _mirrored_text_import_area_count(struct config_node *sn, uint32_t *area_count)
{
if (!get_config_uint32(sn, "mirror_count", area_count)) {
log_error("Couldn't read 'mirror_count' for "
@@ -77,7 +84,7 @@ static int _text_import_area_count(struct config_node *sn, uint32_t *area_count)
return 1;
}
static int _text_import(struct lv_segment *seg, const struct config_node *sn,
static int _mirrored_text_import(struct lv_segment *seg, const struct config_node *sn,
struct dm_hash_table *pv_hash)
{
const struct config_node *cn;
@@ -132,7 +139,7 @@ static int _text_import(struct lv_segment *seg, const struct config_node *sn,
return text_import_areas(seg, sn, cn, pv_hash, MIRROR_IMAGE);
}
static int _text_export(const struct lv_segment *seg, struct formatter *f)
static int _mirrored_text_export(const struct lv_segment *seg, struct formatter *f)
{
outf(f, "mirror_count = %u", seg->area_count);
if (seg->status & PVMOVE)
@@ -147,7 +154,7 @@ static int _text_export(const struct lv_segment *seg, struct formatter *f)
}
#ifdef DEVMAPPER_SUPPORT
static struct mirror_state *_init_target(struct dm_pool *mem,
static struct mirror_state *_mirrored_init_target(struct dm_pool *mem,
struct config_tree *cft)
{
struct mirror_state *mirr_state;
@@ -165,7 +172,7 @@ static struct mirror_state *_init_target(struct dm_pool *mem,
return mirr_state;
}
static int _target_percent(void **target_state, struct dm_pool *mem,
static int _mirrored_target_percent(void **target_state, struct dm_pool *mem,
struct config_tree *cft, struct lv_segment *seg,
char *params, uint64_t *total_numerator,
uint64_t *total_denominator, float *percent)
@@ -177,7 +184,7 @@ static int _target_percent(void **target_state, struct dm_pool *mem,
char *pos = params;
if (!*target_state)
*target_state = _init_target(mem, cft);
*target_state = _mirrored_init_target(mem, cft);
mirr_state = *target_state;
@@ -221,6 +228,7 @@ static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
{
unsigned clustered = 0;
char *log_dlid = NULL;
uint32_t log_flags = 0;
/*
* Use clustered mirror log for non-exclusive activation
@@ -237,11 +245,13 @@ static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
return 0;
}
/* FIXME Add sync parm? */
return dm_tree_node_add_mirror_target_log(node, region_size, clustered, log_dlid, area_count);
if (_block_on_error_available && !(seg->status & PVMOVE))
log_flags |= DM_BLOCK_ON_ERROR;
return dm_tree_node_add_mirror_target_log(node, region_size, clustered, log_dlid, area_count, log_flags);
}
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg,
struct dm_tree_node *node, uint64_t len,
@@ -255,7 +265,7 @@ static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
int r;
if (!*target_state)
*target_state = _init_target(mem, cft);
*target_state = _mirrored_init_target(mem, cft);
mirr_state = *target_state;
@@ -312,37 +322,141 @@ static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
return add_areas_line(dm, seg, node, start_area, area_count);
}
static int _target_present(void)
static int _mirrored_target_present(void)
{
static int checked = 0;
static int present = 0;
static int _mirrored_checked = 0;
static int _mirrored_present = 0;
uint32_t maj, min, patchlevel;
unsigned maj2, min2, patchlevel2;
char vsn[80];
if (!checked)
present = target_present("mirror", 1);
if (!_mirrored_checked) {
_mirrored_present = target_present("mirror", 1);
checked = 1;
/*
* block_on_error available with mirror target >= 1.1
* or with 1.0 in RHEL4U3 driver >= 4.5
*/
/* FIXME Move this into libdevmapper */
return present;
if (target_version("mirror", &maj, &min, &patchlevel) &&
maj == 1 &&
(min >= 1 ||
(min == 0 && driver_version(vsn, sizeof(vsn)) &&
sscanf(vsn, "%u.%u.%u", &maj2, &min2, &patchlevel2) == 3 &&
maj2 == 4 && min2 == 5 && patchlevel2 == 0))) /* RHEL4U3 */
_block_on_error_available = 1;
}
_mirrored_checked = 1;
return _mirrored_present;
}
#endif
static void _destroy(const struct segment_type *segtype)
#ifdef DMEVENTD
static int _setup_registration(struct dm_pool *mem, struct config_tree *cft,
char **dso)
{
char *path;
const char *libpath;
if (!(path = dm_pool_alloc(mem, PATH_MAX))) {
log_error("Failed to allocate dmeventd library path.");
return 0;
}
libpath = find_config_str(cft->root, "dmeventd/mirror_library",
DEFAULT_DMEVENTD_MIRROR_LIB);
get_shared_library_path(cft, libpath, path, PATH_MAX);
*dso = path;
return 1;
}
/* FIXME This gets run while suspended and performs banned operations. */
/* FIXME Merge these two functions */
static int _target_register_events(struct dm_pool *mem,
struct lv_segment *seg,
struct config_tree *cft, int events)
{
char *dso, *name;
struct logical_volume *lv;
struct volume_group *vg;
lv = seg->lv;
vg = lv->vg;
if (!_setup_registration(mem, cft, &dso)) {
stack;
return 0;
}
if (!(name = build_dm_name(mem, vg->name, lv->name, NULL)))
return_0;
/* FIXME Save a returned handle here so we can unregister it later */
if (!dm_event_register(dso, name, DM_EVENT_ALL_ERRORS))
return_0;
log_info("Registered %s for events", name);
return 1;
}
static int _target_unregister_events(struct dm_pool *mem,
struct lv_segment *seg,
struct config_tree *cft, int events)
{
char *dso;
char *name;
struct logical_volume *lv;
struct volume_group *vg;
lv = seg->lv;
vg = lv->vg;
/* FIXME Remove this and use handle to avoid config file race */
if (!_setup_registration(mem, cft, &dso))
return_0;
if (!(name = build_dm_name(mem, vg->name, lv->name, NULL)))
return_0;
/* FIXME Use handle returned by registration function instead of dso */
if (!dm_event_unregister(dso, name, DM_EVENT_ALL_ERRORS))
return_0;
log_info("Unregistered %s for events", name);
return 1;
}
#endif /* DMEVENTD */
#endif /* DEVMAPPER_SUPPORT */
static void _mirrored_destroy(const struct segment_type *segtype)
{
dm_free((void *) segtype);
}
static struct segtype_handler _mirrored_ops = {
name:_name,
display:_display,
text_import_area_count:_text_import_area_count,
text_import:_text_import,
text_export:_text_export,
name:_mirrored_name,
display:_mirrored_display,
text_import_area_count:_mirrored_text_import_area_count,
text_import:_mirrored_text_import,
text_export:_mirrored_text_export,
#ifdef DEVMAPPER_SUPPORT
add_target_line:_add_target_line,
target_percent:_target_percent,
target_present:_target_present,
add_target_line:_mirrored_add_target_line,
target_percent:_mirrored_target_percent,
target_present:_mirrored_target_present,
#ifdef DMEVENTD
target_register_events:_target_register_events,
target_unregister_events:_target_unregister_events,
#endif
destroy:_destroy,
#endif
destroy:_mirrored_destroy,
};
#ifdef MIRRORED_INTERNAL

View File

@@ -208,3 +208,27 @@ int split_dm_name(struct dm_pool *mem, const char *dmname,
return 1;
}
int validate_name(const char *n)
{
register char c;
register int len = 0;
if (!n || !*n)
return 0;
/* Hyphen used as VG-LV separator - ambiguity if LV starts with it */
if (*n == '-')
return 0;
if (!strcmp(n, ".") || !strcmp(n, ".."))
return 0;
while ((len++, c = *n++))
if (!isalnum(c) && c != '.' && c != '_' && c != '-' && c != '+')
return 0;
if (len > NAME_LEN)
return 0;
return 1;
}

View File

@@ -19,6 +19,8 @@
#include <stdio.h>
#include <stdarg.h>
#define NAME_LEN 128
struct pool;
/*
@@ -40,4 +42,6 @@ char *build_dm_name(struct dm_pool *mem, const char *vg,
int split_dm_name(struct dm_pool *mem, const char *dmname,
char **vgname, char **lvname, char **layer);
int validate_name(const char *n);
#endif

View File

@@ -22,8 +22,8 @@
#include <sys/stat.h>
#include <dlfcn.h>
static void _get_library_path(struct config_tree *cft, const char *libname,
char *path, int path_len)
void get_shared_library_path(struct config_tree *cft, const char *libname,
char *path, int path_len)
{
struct stat info;
const char *lib_dir;
@@ -38,17 +38,23 @@ static void _get_library_path(struct config_tree *cft, const char *libname,
}
void *load_shared_library(struct config_tree *cft, const char *libname,
const char *desc)
const char *desc, int silent)
{
char path[PATH_MAX];
void *library;
_get_library_path(cft, libname, path, sizeof(path));
get_shared_library_path(cft, libname, path, sizeof(path));
log_very_verbose("Opening shared %s library %s", desc, path);
if (!(library = dlopen(path, RTLD_LAZY)))
log_error("Unable to open external %s library %s", desc, path);
if (!(library = dlopen(path, RTLD_LAZY))) {
if (silent && ignorelockingfailure())
log_verbose("Unable to open external %s library %s",
desc, path);
else
log_error("Unable to open external %s library %s",
desc, path);
}
return library;
}

View File

@@ -16,5 +16,7 @@
#include "config.h"
#include <dlfcn.h>
void get_shared_library_path(struct config_tree *cft, const char *libname,
char *path, int path_len);
void *load_shared_library(struct config_tree *cf, const char *libname,
const char *what);
const char *what, int silent);

View File

@@ -90,7 +90,7 @@ static void _release_memory(void)
}
/* Stop memory getting swapped out */
static void _lock_memory(void)
static void _lock_mem(void)
{
#ifdef MCL_CURRENT
if (mlockall(MCL_CURRENT | MCL_FUTURE))
@@ -109,7 +109,7 @@ static void _lock_memory(void)
_default_priority, strerror(errno));
}
static void _unlock_memory(void)
static void _unlock_mem(void)
{
#ifdef MCL_CURRENT
if (munlockall())
@@ -126,14 +126,14 @@ static void _unlock_memory(void)
void memlock_inc(void)
{
if (!_memlock_count++)
_lock_memory();
_lock_mem();
log_debug("memlock_count inc to %d", _memlock_count);
}
void memlock_dec(void)
{
if (_memlock_count && (!--_memlock_count))
_unlock_memory();
_unlock_mem();
log_debug("memlock_count dec to %d", _memlock_count);
}

View File

@@ -166,7 +166,7 @@ static void _calc_functions(struct matcher *m)
}
}
static inline struct dfa_state *_create_dfa_state(struct dm_pool *mem)
static struct dfa_state *_create_dfa_state(struct dm_pool *mem)
{
return dm_pool_zalloc(mem, sizeof(struct dfa_state));
}
@@ -337,8 +337,7 @@ struct matcher *matcher_create(struct dm_pool *mem, const char **patterns,
return NULL;
}
static inline struct dfa_state *_step_matcher(int c,
struct dfa_state *cs, int *r)
static struct dfa_state *_step_matcher(int c, struct dfa_state *cs, int *r)
{
if (!(cs = cs->lookup[(unsigned char) c]))
return NULL;

View File

@@ -38,7 +38,7 @@ static void _single_char(struct parse_sp *ps, unsigned int c, const char *ptr)
* Get the next token from the regular expression.
* Returns: 1 success, 0 end of input, -1 error.
*/
static int _get_token(struct parse_sp *ps)
static int _rx_get_token(struct parse_sp *ps)
{
int neg = 0, range = 0;
char c, lc = 0;
@@ -230,17 +230,17 @@ static struct rx_node *_term(struct parse_sp *ps)
}
dm_bit_copy(n->charset, ps->charset);
_get_token(ps); /* match charset */
_rx_get_token(ps); /* match charset */
break;
case '(':
_get_token(ps); /* match '(' */
_rx_get_token(ps); /* match '(' */
n = _or_term(ps);
if (ps->type != ')') {
log_error("missing ')' in regular expression");
return 0;
}
_get_token(ps); /* match ')' */
_rx_get_token(ps); /* match ')' */
break;
default:
@@ -280,7 +280,7 @@ static struct rx_node *_closure_term(struct parse_sp *ps)
return NULL;
}
_get_token(ps);
_rx_get_token(ps);
l = n;
}
@@ -316,7 +316,7 @@ static struct rx_node *_or_term(struct parse_sp *ps)
if (ps->type != '|')
return l;
_get_token(ps); /* match '|' */
_rx_get_token(ps); /* match '|' */
if (!(r = _or_term(ps))) {
log_error("Badly formed 'or' expression");
@@ -344,7 +344,7 @@ struct rx_node *rx_parse_tok(struct dm_pool *mem,
ps->charset = dm_bitset_create(mem, 256);
ps->cursor = begin;
ps->rx_end = end;
_get_token(ps); /* load the first token */
_rx_get_token(ps); /* load the first token */
if (!(r = _or_term(ps))) {
log_error("Parse error in regex");

View File

@@ -59,7 +59,7 @@ void *ttree_lookup(struct ttree *tt, unsigned *key)
return *c ? (*c)->data : NULL;
}
static struct node *_node(struct dm_pool *mem, unsigned int k)
static struct node *_tree_node(struct dm_pool *mem, unsigned int k)
{
struct node *n = dm_pool_zalloc(mem, sizeof(*n));
@@ -86,7 +86,7 @@ int ttree_insert(struct ttree *tt, unsigned int *key, void *data)
count++;
while (count--) {
if (!(*c = _node(tt->mem, k))) {
if (!(*c = _tree_node(tt->mem, k))) {
stack;
return 0;
}

View File

@@ -324,7 +324,6 @@ static int _lvstatus_disp(struct report_handle *rh, struct field *field,
const struct logical_volume *lv = (const struct logical_volume *) data;
struct lvinfo info;
char *repstr;
struct lv_segment *snap_seg;
float snap_percent;
if (!(repstr = dm_pool_zalloc(rh->mem, 7))) {
@@ -344,7 +343,7 @@ static int _lvstatus_disp(struct report_handle *rh, struct field *field,
repstr[0] = 'v';
else if (lv_is_origin(lv))
repstr[0] = 'o';
else if (find_cow(lv))
else if (lv_is_cow(lv))
repstr[0] = 's';
else
repstr[0] = '-';
@@ -377,8 +376,8 @@ static int _lvstatus_disp(struct report_handle *rh, struct field *field,
repstr[4] = 'd'; /* Inactive without table */
/* Snapshot dropped? */
if (info.live_table && (snap_seg = find_cow(lv)) &&
(!lv_snapshot_percent(snap_seg->cow, &snap_percent) ||
if (info.live_table && lv_is_cow(lv) &&
(!lv_snapshot_percent(lv, &snap_percent) ||
snap_percent < 0 || snap_percent >= 100)) {
repstr[0] = toupper(repstr[0]);
if (info.suspended)
@@ -491,10 +490,9 @@ static int _origin_disp(struct report_handle *rh, struct field *field,
const void *data)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
struct lv_segment *snap_seg;
if ((snap_seg = find_cow(lv)))
return _string_disp(rh, field, &snap_seg->origin->name);
if (lv_is_cow(lv))
return _string_disp(rh, field, &origin_from_cow(lv)->name);
field->report_string = "";
field->sort_value = (const void *) field->report_string;
@@ -527,8 +525,7 @@ static int _lvname_disp(struct report_handle *rh, struct field *field,
char *repstr;
size_t len;
/* FIXME Remove need for snapshot special case */
if (lv->status & VISIBLE_LV || lv_is_cow(lv)) {
if (lv_is_visible(lv)) {
repstr = lv->name;
return _string_disp(rh, field, &repstr);
}
@@ -667,11 +664,10 @@ static int _chunksize_disp(struct report_handle *rh, struct field *field,
const void *data)
{
const struct lv_segment *seg = (const struct lv_segment *) data;
struct lv_segment *snap_seg;
uint64_t size;
if ((snap_seg = find_cow(seg->lv)))
size = (uint64_t) snap_seg->chunk_size;
if (lv_is_cow(seg->lv))
size = (uint64_t) find_cow(seg->lv)->chunk_size;
else
size = 0;
@@ -840,7 +836,6 @@ static int _snpercent_disp(struct report_handle *rh, struct field *field,
const void *data)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
struct lv_segment *snap_seg;
struct lvinfo info;
float snap_percent;
uint64_t *sortval;
@@ -851,16 +846,15 @@ static int _snpercent_disp(struct report_handle *rh, struct field *field,
return 0;
}
if (!(snap_seg = find_cow(lv)) ||
(lv_info(lv->vg->cmd, snap_seg->cow, &info, 0) && !info.exists)) {
if (!lv_is_cow(lv) ||
(lv_info(lv->vg->cmd, lv, &info, 0) && !info.exists)) {
field->report_string = "";
*sortval = UINT64_C(0);
field->sort_value = sortval;
return 1;
}
if (!lv_snapshot_percent(snap_seg->cow, &snap_percent)
|| snap_percent < 0) {
if (!lv_snapshot_percent(lv, &snap_percent) || snap_percent < 0) {
field->report_string = "100.00";
*sortval = UINT64_C(100);
field->sort_value = sortval;

View File

@@ -21,12 +21,12 @@
#include "config.h"
#include "activate.h"
static const char *_name(const struct lv_segment *seg)
static const char *_snap_name(const struct lv_segment *seg)
{
return seg->segtype->name;
}
static int _text_import(struct lv_segment *seg, const struct config_node *sn,
static int _snap_text_import(struct lv_segment *seg, const struct config_node *sn,
struct dm_hash_table *pv_hash)
{
uint32_t chunk_size;
@@ -77,7 +77,7 @@ static int _text_import(struct lv_segment *seg, const struct config_node *sn,
return 1;
}
static int _text_export(const struct lv_segment *seg, struct formatter *f)
static int _snap_text_export(const struct lv_segment *seg, struct formatter *f)
{
outf(f, "chunk_size = %u", seg->chunk_size);
outf(f, "origin = \"%s\"", seg->origin->name);
@@ -87,7 +87,7 @@ static int _text_export(const struct lv_segment *seg, struct formatter *f)
}
#ifdef DEVMAPPER_SUPPORT
static int _target_percent(void **target_state, struct dm_pool *mem,
static int _snap_target_percent(void **target_state, struct dm_pool *mem,
struct config_tree *cft, struct lv_segment *seg,
char *params, uint64_t *total_numerator,
uint64_t *total_denominator, float *percent)
@@ -109,35 +109,35 @@ static int _target_percent(void **target_state, struct dm_pool *mem,
return 1;
}
static int _target_present(void)
static int _snap_target_present(void)
{
static int checked = 0;
static int present = 0;
static int _snap_checked = 0;
static int _snap_present = 0;
if (!checked)
present = target_present("snapshot", 1) &&
if (!_snap_checked)
_snap_present = target_present("snapshot", 1) &&
target_present("snapshot-origin", 0);
checked = 1;
_snap_checked = 1;
return present;
return _snap_present;
}
#endif
static void _destroy(const struct segment_type *segtype)
static void _snap_destroy(const struct segment_type *segtype)
{
dm_free((void *) segtype);
}
static struct segtype_handler _snapshot_ops = {
name:_name,
text_import:_text_import,
text_export:_text_export,
name:_snap_name,
text_import:_snap_text_import,
text_export:_snap_text_export,
#ifdef DEVMAPPER_SUPPORT
target_percent:_target_percent,
target_present:_target_present,
target_percent:_snap_target_percent,
target_present:_snap_target_present,
#endif
destroy:_destroy,
destroy:_snap_destroy,
};
#ifdef SNAPSHOT_INTERNAL

View File

@@ -26,12 +26,12 @@
#include "activate.h"
#include "pv_alloc.h"
static const char *_name(const struct lv_segment *seg)
static const char *_striped_name(const struct lv_segment *seg)
{
return (seg->area_count == 1) ? "linear" : seg->segtype->name;
}
static void _display(const struct lv_segment *seg)
static void _striped_display(const struct lv_segment *seg)
{
uint32_t s;
@@ -49,7 +49,7 @@ static void _display(const struct lv_segment *seg)
log_print(" ");
}
static int _text_import_area_count(struct config_node *sn, uint32_t *area_count)
static int _striped_text_import_area_count(struct config_node *sn, uint32_t *area_count)
{
if (!get_config_uint32(sn, "stripe_count", area_count)) {
log_error("Couldn't read 'stripe_count' for "
@@ -60,7 +60,7 @@ static int _text_import_area_count(struct config_node *sn, uint32_t *area_count)
return 1;
}
static int _text_import(struct lv_segment *seg, const struct config_node *sn,
static int _striped_text_import(struct lv_segment *seg, const struct config_node *sn,
struct dm_hash_table *pv_hash)
{
struct config_node *cn;
@@ -83,7 +83,7 @@ static int _text_import(struct lv_segment *seg, const struct config_node *sn,
return text_import_areas(seg, sn, cn, pv_hash, 0);
}
static int _text_export(const struct lv_segment *seg, struct formatter *f)
static int _striped_text_export(const struct lv_segment *seg, struct formatter *f)
{
outf(f, "stripe_count = %u%s", seg->area_count,
@@ -99,7 +99,7 @@ static int _text_export(const struct lv_segment *seg, struct formatter *f)
/*
* Test whether two segments could be merged by the current merging code
*/
static int _segments_compatible(struct lv_segment *first,
static int _striped_segments_compatible(struct lv_segment *first,
struct lv_segment *second)
{
uint32_t width;
@@ -132,11 +132,11 @@ static int _segments_compatible(struct lv_segment *first,
return 1;
}
static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
static int _striped_merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
{
uint32_t s;
if (!_segments_compatible(seg1, seg2))
if (!_striped_segments_compatible(seg1, seg2))
return 0;
seg1->len += seg2->len;
@@ -151,7 +151,7 @@ static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
}
#ifdef DEVMAPPER_SUPPORT
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
static int _striped_add_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg,
struct dm_tree_node *node, uint64_t len,
@@ -172,37 +172,38 @@ static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
return add_areas_line(dm, seg, node, 0u, seg->area_count);
}
static int _target_present(void)
static int _striped_target_present(void)
{
static int checked = 0;
static int present = 0;
static int _striped_checked = 0;
static int _striped_present = 0;
if (!checked)
present = target_present("linear", 0) &&
if (!_striped_checked)
_striped_present = target_present("linear", 0) &&
target_present("striped", 0);
checked = 1;
return present;
_striped_checked = 1;
return _striped_present;
}
#endif
static void _destroy(const struct segment_type *segtype)
static void _striped_destroy(const struct segment_type *segtype)
{
dm_free((void *) segtype);
}
static struct segtype_handler _striped_ops = {
name:_name,
display:_display,
text_import_area_count:_text_import_area_count,
text_import:_text_import,
text_export:_text_export,
merge_segments:_merge_segments,
name:_striped_name,
display:_striped_display,
text_import_area_count:_striped_text_import_area_count,
text_import:_striped_text_import,
text_export:_striped_text_export,
merge_segments:_striped_merge_segments,
#ifdef DEVMAPPER_SUPPORT
add_target_line:_add_target_line,
target_present:_target_present,
add_target_line:_striped_add_target_line,
target_present:_striped_target_present,
#endif
destroy:_destroy,
destroy:_striped_destroy,
};
struct segment_type *init_striped_segtype(struct cmd_context *cmd)

View File

@@ -24,12 +24,12 @@
#include "lvm-string.h"
#include "activate.h"
static const char *_name(const struct lv_segment *seg)
static const char *_zero_name(const struct lv_segment *seg)
{
return seg->segtype->name;
}
static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
static int _zero_merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
{
seg1->len += seg2->len;
seg1->area_len += seg2->area_len;
@@ -38,7 +38,7 @@ static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
}
#ifdef DEVMAPPER_SUPPORT
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
static int _zero_add_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg,
struct dm_tree_node *node, uint64_t len,
@@ -47,32 +47,33 @@ static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
return dm_tree_node_add_zero_target(node, len);
}
static int _target_present(void)
static int _zero_target_present(void)
{
static int checked = 0;
static int present = 0;
static int _zero_checked = 0;
static int _zero_present = 0;
if (!checked)
present = target_present("zero", 0);
if (!_zero_checked)
_zero_present = target_present("zero", 0);
checked = 1;
return present;
_zero_checked = 1;
return _zero_present;
}
#endif
static void _destroy(const struct segment_type *segtype)
static void _zero_destroy(const struct segment_type *segtype)
{
dm_free((void *) segtype);
}
static struct segtype_handler _zero_ops = {
name:_name,
merge_segments:_merge_segments,
name:_zero_name,
merge_segments:_zero_merge_segments,
#ifdef DEVMAPPER_SUPPORT
add_target_line:_add_target_line,
target_present:_target_present,
add_target_line:_zero_add_target_line,
target_present:_zero_target_present,
#endif
destroy:_destroy,
destroy:_zero_destroy,
};
struct segment_type *init_zero_segtype(struct cmd_context *cmd)

View File

@@ -2,6 +2,7 @@ dm_lib_release
dm_lib_exit
dm_driver_version
dm_get_library_version
dm_log
dm_log_init
dm_log_init_verbose
dm_task_create
@@ -22,9 +23,14 @@ dm_task_set_major
dm_task_set_minor
dm_task_set_sector
dm_task_set_message
dm_task_set_uid
dm_task_set_gid
dm_task_set_mode
dm_task_suppress_identical_reload
dm_task_add_target
dm_task_no_open_count
dm_task_skip_lockfs
dm_task_update_nodes
dm_task_run
dm_get_next_target
dm_set_dev_dir
@@ -58,14 +64,16 @@ dm_tree_node_add_striped_target
dm_tree_node_add_mirror_target
dm_tree_node_add_mirror_target_log
dm_tree_node_add_target_area
dm_tree_skip_lockfs
dm_is_dm_major
dm_mknodes
dm_malloc_aux
dm_strdup
dm_malloc_aux_debug
dm_strdup_aux
dm_free_aux
dm_realloc_aux
dm_dump_memory
dm_bounds_check
dm_dump_memory_debug
dm_bounds_check_debug
dm_pool_create
dm_pool_destroy
dm_pool_alloc
@@ -100,3 +108,4 @@ dm_hash_get_data
dm_hash_get_first
dm_hash_get_next
dm_set_selinux_context
dm_task_set_geometry

View File

@@ -17,14 +17,6 @@ top_srcdir = @top_srcdir@
VPATH = @srcdir@
interface = @interface@
ifeq ("@DMEVENTD@", "yes")
SUBDIRS += event
endif
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS += event
endif
SOURCES =\
datastruct/bitset.c \
datastruct/hash.c \
@@ -50,8 +42,9 @@ CFLAGS += -DDEVICE_UID=@DEVICE_UID@ -DDEVICE_GID=@DEVICE_GID@ \
include ../make.tmpl
.PHONY: install_dynamic install_static \
install_fs install_ioctl install_ioctl_static
.PHONY: install_dynamic install_static install_include \
install_fs install_ioctl install_ioctl_static \
install_pkgconfig
INSTALL_TYPE = install_dynamic
@@ -59,18 +52,22 @@ ifeq ("@STATIC_LINK@", "yes")
INSTALL_TYPE += install_static
endif
install: $(INSTALL_TYPE)
ifeq ("@PKGCONFIG@", "yes")
INSTALL_TYPE += install_pkgconfig
endif
install: $(INSTALL_TYPE) install_include
install_include:
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper.h \
$(includedir)/libdevmapper.h
install_dynamic: install_@interface@
$(LN_S) -f libdevmapper.$(LIB_SUFFIX).$(LIB_VERSION) \
$(libdir)/libdevmapper.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper.h \
$(includedir)/libdevmapper.h
install_static: install_@interface@_static
$(LN_S) -f libdevmapper.a.$(LIB_VERSION) $(libdir)/libdevmapper.a
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper.h \
$(includedir)/libdevmapper.h
install_fs: fs/libdevmapper.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
@@ -80,6 +77,10 @@ install_ioctl: ioctl/libdevmapper.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/libdevmapper.$(LIB_SUFFIX).$(LIB_VERSION)
install_pkgconfig:
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper.pc \
$(usrlibdir)/pkgconfig/devmapper.pc
install_ioctl_static: ioctl/libdevmapper.a
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/libdevmapper.a.$(LIB_VERSION)
@@ -87,7 +88,7 @@ install_ioctl_static: ioctl/libdevmapper.a
.PHONY: distclean_lib distclean
distclean_lib:
$(RM) libdm-common.h
$(RM) libdm-common.h libdevmapper.pc
distclean: distclean_lib

View File

@@ -57,7 +57,7 @@ void dm_bit_union(dm_bitset_t out, dm_bitset_t in1, dm_bitset_t in2)
*/
static inline int _test_word(uint32_t test, int bit)
{
while (bit < DM_BITS_PER_INT) {
while (bit < (int) DM_BITS_PER_INT) {
if (test & (0x1 << bit))
return bit;
bit++;
@@ -73,7 +73,10 @@ int dm_bit_get_next(dm_bitset_t bs, int last_bit)
last_bit++; /* otherwise we'll return the same bit again */
while (last_bit < bs[0]) {
/*
* bs[0] holds number of bits
*/
while (last_bit < (int) bs[0]) {
word = last_bit >> INT_SHIFT;
test = bs[word + 1];
bit = last_bit & (DM_BITS_PER_INT - 1);

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