mirror of
git://sourceware.org/git/lvm2.git
synced 2025-12-24 16:23:50 +03:00
Compare commits
253 Commits
dm_v1_01_0
...
old-dm_v1_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f95dbff71f | ||
|
|
098f6830a6 | ||
|
|
d1ecebdb52 | ||
|
|
590b654251 | ||
|
|
3bf190c8ab | ||
|
|
dcca7638e0 | ||
|
|
70e45ad37b | ||
|
|
db88210289 | ||
|
|
d2e0d96cc3 | ||
|
|
3feba82ccc | ||
|
|
db924da231 | ||
|
|
fc55ae7e6d | ||
|
|
86e757a6ad | ||
|
|
4790715cd3 | ||
|
|
e7e9c60042 | ||
|
|
1c3bc52cc4 | ||
|
|
5227dff0e1 | ||
|
|
33f0b5b7c2 | ||
|
|
0a02968303 | ||
|
|
f7bf658c07 | ||
|
|
8d16a0abad | ||
|
|
c974b97ca3 | ||
|
|
b8025bfebd | ||
|
|
30323b253f | ||
|
|
535c3ede96 | ||
|
|
89fed8ca33 | ||
|
|
f43c77aaed | ||
|
|
96c676b371 | ||
|
|
113047e1a2 | ||
|
|
abed57cb53 | ||
|
|
c01a800a6b | ||
|
|
d648832a2d | ||
|
|
f06833fbd2 | ||
|
|
c561addc94 | ||
|
|
702f5f1f4c | ||
|
|
1273f179e8 | ||
|
|
5d02f60bde | ||
|
|
4cf7a108e8 | ||
|
|
42635c3938 | ||
|
|
ed43dc842b | ||
|
|
49d4db6cd2 | ||
|
|
ea80ab2cae | ||
|
|
382e808b8d | ||
|
|
846befa7e0 | ||
|
|
74dd29f843 | ||
|
|
b0473bffcb | ||
|
|
24dd9ab1a7 | ||
|
|
49d3037e87 | ||
|
|
37ad2bd4e8 | ||
|
|
7d7b332b02 | ||
|
|
ac033b8612 | ||
|
|
a7b98dfe25 | ||
|
|
7fb7c86c46 | ||
|
|
ed036598a9 | ||
|
|
160bb70cdf | ||
|
|
c2e61f3c21 | ||
|
|
18218467f3 | ||
|
|
17e298ad2a | ||
|
|
d031a374f9 | ||
|
|
55f69c98cb | ||
|
|
71f2e4306d | ||
|
|
f8af23a025 | ||
|
|
4ef55a6cd3 | ||
|
|
312f866723 | ||
|
|
0ebe1f6dec | ||
|
|
2ad92e0e6e | ||
|
|
ac8823cdcf | ||
|
|
77565f7ee4 | ||
|
|
d656d90fa8 | ||
|
|
175b3b0834 | ||
|
|
7477e6b714 | ||
|
|
cd6568db69 | ||
|
|
6aff325fb2 | ||
|
|
0d603cfe9c | ||
|
|
34a1f14a17 | ||
|
|
efe1c8a070 | ||
|
|
1575844344 | ||
|
|
221ac1c208 | ||
|
|
57442db759 | ||
|
|
5fdb3e7cd6 | ||
|
|
96f259726c | ||
|
|
4936efba5e | ||
|
|
d5a3559a2f | ||
|
|
114a1c7f52 | ||
|
|
ce5265c203 | ||
|
|
1a575d926f | ||
|
|
85c818a39e | ||
|
|
4ffa2defe4 | ||
|
|
8825157fbb | ||
|
|
966d608dc5 | ||
|
|
b808c89471 | ||
|
|
75d4e6490f | ||
|
|
a82775f544 | ||
|
|
6a22ad0171 | ||
|
|
c854e88186 | ||
|
|
d02203060c | ||
|
|
cf703b0433 | ||
|
|
c0197a72d3 | ||
|
|
e5a543e283 | ||
|
|
b8b029b7d3 | ||
|
|
370f368b1a | ||
|
|
8288b45b4f | ||
|
|
fe529faf8e | ||
|
|
ab931b177d | ||
|
|
9aa3465513 | ||
|
|
6c70fc1a6c | ||
|
|
1ccc39962a | ||
|
|
99c941fc85 | ||
|
|
19729fdcc2 | ||
|
|
02e17998ce | ||
|
|
459e00c67a | ||
|
|
292f665650 | ||
|
|
93bbb79569 | ||
|
|
273e724f2b | ||
|
|
5d2615c56f | ||
|
|
bfaaf21330 | ||
|
|
dcb8415b7a | ||
|
|
699e1c75ce | ||
|
|
465b6e613e | ||
|
|
05fa105855 | ||
|
|
d7a0cdebe5 | ||
|
|
b049ab31eb | ||
|
|
6db4dcff7a | ||
|
|
3eeaef00ec | ||
|
|
8bf4c38a00 | ||
|
|
3a32b09ad1 | ||
|
|
6315982752 | ||
|
|
374a171e82 | ||
|
|
fc5d801f91 | ||
|
|
5146641848 | ||
|
|
cdd0ac42cf | ||
|
|
e5895500a2 | ||
|
|
9cb4dde3fa | ||
|
|
3c2a4370a5 | ||
|
|
e7a360dd6f | ||
|
|
c814c2fd35 | ||
|
|
fefa7fe262 | ||
|
|
26f01a29d1 | ||
|
|
169d4090ab | ||
|
|
0b43754d60 | ||
|
|
8b3b26b813 | ||
|
|
5426af4f81 | ||
|
|
4e2c3a579d | ||
|
|
5ae2693241 | ||
|
|
41c86b0d19 | ||
|
|
40788e8c3d | ||
|
|
0d29120033 | ||
|
|
4be598f865 | ||
|
|
558a6d509e | ||
|
|
75cd02aad2 | ||
|
|
e4c4451482 | ||
|
|
0671632477 | ||
|
|
54c230c264 | ||
|
|
64ba878eda | ||
|
|
01acd6dd76 | ||
|
|
9d819b52d3 | ||
|
|
37bac5cdc9 | ||
|
|
78c718c591 | ||
|
|
284b8bf6ca | ||
|
|
5a5084b837 | ||
|
|
3b8058e1f1 | ||
|
|
2a3168e0d6 | ||
|
|
a8ac6e4a15 | ||
|
|
6172cf9fba | ||
|
|
b728ec3909 | ||
|
|
61a53bbcff | ||
|
|
17d13dd084 | ||
|
|
edcb28d591 | ||
|
|
ad101119a7 | ||
|
|
bc36676d31 | ||
|
|
d76fe120ab | ||
|
|
2e95949b80 | ||
|
|
ae14d85e24 | ||
|
|
fad6304c60 | ||
|
|
a4dd3c8ce9 | ||
|
|
6d1a5d45e2 | ||
|
|
a6c7043e03 | ||
|
|
bcc400dafa | ||
|
|
8fbedf3441 | ||
|
|
2e8a9c9874 | ||
|
|
44fc41b3e5 | ||
|
|
7212c20a1b | ||
|
|
7ff142de1c | ||
|
|
e67efb199d | ||
|
|
20128bd04b | ||
|
|
c0fefdde28 | ||
|
|
f6ee160e66 | ||
|
|
06acc2004f | ||
|
|
43ac2ce4c8 | ||
|
|
b32bf72b5f | ||
|
|
c6880c957e | ||
|
|
095b71ed96 | ||
|
|
9160e496bc | ||
|
|
2a7ac78f02 | ||
|
|
64efa4627d | ||
|
|
f7e35569ce | ||
|
|
e8af32ec2b | ||
|
|
e092ce51f6 | ||
|
|
7b78edb1b7 | ||
|
|
b332e7090e | ||
|
|
67eb7723d6 | ||
|
|
251d138474 | ||
|
|
1170dfac05 | ||
|
|
4157f141c7 | ||
|
|
f569abd28a | ||
|
|
088f9687c0 | ||
|
|
e23df1f07a | ||
|
|
c818540dfd | ||
|
|
21365cbe1a | ||
|
|
5471a80a96 | ||
|
|
d7b6fa9cd0 | ||
|
|
dfdc2e02ef | ||
|
|
893ec9a302 | ||
|
|
05f65c38e6 | ||
|
|
2e9d062ec0 | ||
|
|
6b0b394e61 | ||
|
|
25621396c9 | ||
|
|
82aa0271f3 | ||
|
|
653cab13f8 | ||
|
|
b526f86b49 | ||
|
|
53c0f00888 | ||
|
|
f0c4d9de40 | ||
|
|
03ef8cec83 | ||
|
|
85f2a2e8c2 | ||
|
|
584b3e6642 | ||
|
|
39b7ef841d | ||
|
|
aa16a9098d | ||
|
|
7b8c2707bc | ||
|
|
60e26a31a7 | ||
|
|
3473c25c14 | ||
|
|
e52f022026 | ||
|
|
b1a7df8e43 | ||
|
|
0fd2479b7c | ||
|
|
273857f914 | ||
|
|
a08b85dbc8 | ||
|
|
a0aedf299a | ||
|
|
3c61426844 | ||
|
|
786f228076 | ||
|
|
004da28792 | ||
|
|
6e2be6efb6 | ||
|
|
a994dfcfbc | ||
|
|
7a8ea2ac93 | ||
|
|
0da3965d19 | ||
|
|
885fd7bb46 | ||
|
|
08771f9c89 | ||
|
|
8be48195a5 | ||
|
|
98ce2d650e | ||
|
|
3af327116a | ||
|
|
b75434db93 | ||
|
|
04e912aacd | ||
|
|
d7be352f87 | ||
|
|
96be3ec22c | ||
|
|
32e7e0d790 |
21
Makefile.in
21
Makefile.in
@@ -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
|
||||
|
||||
132
WHATS_NEW
132
WHATS_NEW
@@ -1,6 +1,132 @@
|
||||
Version 2.01.14 -
|
||||
================================
|
||||
Fix pool format handler to work with pv segment code
|
||||
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.
|
||||
Separated out activation preload.
|
||||
Moved activation functions into libdevmapper.
|
||||
Fixed build_dm_name.
|
||||
Add return macros.
|
||||
Added xen xvd devices.
|
||||
Clear up precommitted metadata better.
|
||||
A pvresize implementation.
|
||||
Fix contiguous allocation when there are no preceding segments.
|
||||
Add mirror_seg pointer to lv_segment struct.
|
||||
Only keep a device open if it's known to belong to a locked VG.
|
||||
Fix lvdisplay to show all mirror destinations.
|
||||
Replacement suspend code using libdevmapper dependency tree.
|
||||
Add DEFS to make.tmpl.
|
||||
Use dm_is_dm_major instead of local copy.
|
||||
Allow mapped devices to be used as PVs.
|
||||
Move set_selinux_context into libdevmapper.
|
||||
Fix automatic text metadata buffer expansion (using macro).
|
||||
Cache formatted text metadata buffer between metadata area writes.
|
||||
Add pe_start field to pvs.
|
||||
Add 'LVM-' prefix to uuids.
|
||||
Split lv_segment_area from lv_segment to permit extension.
|
||||
Replacement deactivation code using libdevmapper dependency tree.
|
||||
Simplify dev_manager_info().
|
||||
Attempt to load missing targets using modprobe.
|
||||
Add -a to lvscan.
|
||||
Move mknodes into libdevmapper.
|
||||
Move bitset, hash, pool and dbg_malloc into libdevmapper.
|
||||
|
||||
Version 2.01.15 - 16th October 2005
|
||||
===================================
|
||||
Refuse to run pvcreate/pvremove on devices we can't open exclusively.
|
||||
Use ORPHAN lock definition throughout.
|
||||
Validate chunksize in lvcreate.
|
||||
Reduce chunksize limit to 512k.
|
||||
Fix chunksize field in reports.
|
||||
Don't hide snapshots from default 'lvs' output.
|
||||
Add is_dm_major() for use in duplicate device detection in lvmcache_add().
|
||||
Really switch device number in lvmcache when it says it is doing so.
|
||||
Option for bitset memory allocation using malloc as well as pool.
|
||||
Don't assume exactly two mirrors when parsing mirror status.
|
||||
Suppress fsync() error message on filesystems that don't support it.
|
||||
Fix yes_no_prompt() error handling.
|
||||
Add lvm.conf comment warning against multiple filter lines.
|
||||
Tidy lvmconf.sh.
|
||||
Add format1 dev_write debug messages.
|
||||
Add clustered VG attribute to report.
|
||||
Move lvconvert parameters into struct lvconvert_params.
|
||||
Add clustered VG flag to LV lock requests.
|
||||
Change LV locking macros to take lv instead of lvid.
|
||||
Prepend 'cluster' activation parameter to mirror log when appropriate.
|
||||
Pass exclusive flag to lv_activate and on to target activation code.
|
||||
Prevent snapshot creation in a clustered VG for now.
|
||||
Factor out adjusted_mirror_region_size() and generate_log_name_format().
|
||||
Move compose_log_line() into mirror directory.
|
||||
Factor out _get_library_path().
|
||||
Don't kill idling clvmd threads.
|
||||
clvmd no longer takes out locks for non-clustered LVs.
|
||||
Recognise ATA over Ethernet (aoe) devices.
|
||||
|
||||
Version 2.01.14 - 4th August 2005
|
||||
=================================
|
||||
Fix lvconvert PV parameter in help string.
|
||||
Prevent snapshots getting activated in a clustered VG.
|
||||
Separate out _build_dev_string.
|
||||
Move zero_lv to toollib.
|
||||
Fix pool format handler to work with pv segment code.
|
||||
|
||||
Version 2.01.13 - 13th July 2005
|
||||
================================
|
||||
|
||||
69
WHATS_NEW_DM
69
WHATS_NEW_DM
@@ -1,5 +1,72 @@
|
||||
Version 1.01.04 - 2 Aug 2005
|
||||
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.
|
||||
Also suppress error if device doesn't exist with DM_DEVICE_STATUS.
|
||||
Export dm_set_selinux_context().
|
||||
Add dm_driver_version().
|
||||
Added dependency tree functions to library.
|
||||
Added hash, bitset, pool, dbg_malloc to library.
|
||||
Added ls --tree to dmsetup.
|
||||
Added dmsetup --nolockfs support for suspend/reload.
|
||||
|
||||
Version 1.01.05 - 26 Sep 2005
|
||||
=============================
|
||||
Resync list.h with LVM2.
|
||||
Remember increased buffer size and use for subsequent calls.
|
||||
On 'buffer full' condition, double buffer size and repeat ioctl.
|
||||
Fix termination of getopt_long() option array.
|
||||
Report 'buffer full' condition with v4 ioctl as well as with v1.
|
||||
|
||||
Version 1.01.04 - 2 Aug 2005
|
||||
============================
|
||||
Fix dmsetup ls -j and status --target with empty table.
|
||||
|
||||
Version 1.01.03 - 13 Jun 2005
|
||||
|
||||
283
configure
vendored
283
configure
vendored
@@ -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 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,8 +1465,8 @@ case "$host_os" in
|
||||
CLDNOWHOLEARCHIVE=
|
||||
LDDEPS="$LDDEPS"
|
||||
LDFLAGS="$LDFLAGS"
|
||||
SOFLAG="-dynamiclib"
|
||||
DEVMAPPER=no
|
||||
LIB_SUFFIX="dylib"
|
||||
DEVMAPPER=yes
|
||||
ODIRECT=no
|
||||
SELINUX=no
|
||||
CLUSTER=none
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -10768,6 +10950,51 @@ done
|
||||
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
# Extract the first word of "modprobe", so it can be a program name with args.
|
||||
set dummy modprobe; 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_MODPROBE_CMD+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
case $MODPROBE_CMD in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_MODPROBE_CMD="$MODPROBE_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_MODPROBE_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
|
||||
MODPROBE_CMD=$ac_cv_path_MODPROBE_CMD
|
||||
|
||||
if test -n "$MODPROBE_CMD"; then
|
||||
echo "$as_me:$LINENO: result: $MODPROBE_CMD" >&5
|
||||
echo "${ECHO_T}$MODPROBE_CMD" >&6
|
||||
else
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
fi
|
||||
|
||||
|
||||
if test x$MODPROBE_CMD != x; then
|
||||
LVM_DEFS="$LVM_DEFS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test "-f VERSION"; then
|
||||
LVM_VERSION="\"`cat VERSION`\""
|
||||
@@ -10805,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
|
||||
@@ -11367,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" ;;
|
||||
@@ -11495,12 +11728,15 @@ 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
|
||||
s,@LIBOBJS@,$LIBOBJS,;t t
|
||||
s,@POW_LIB@,$POW_LIB,;t t
|
||||
s,@MSGFMT@,$MSGFMT,;t t
|
||||
s,@MODPROBE_CMD@,$MODPROBE_CMD,;t t
|
||||
s,@JOBS@,$JOBS,;t t
|
||||
s,@STATIC_LINK@,$STATIC_LINK,;t t
|
||||
s,@LVM1@,$LVM1,;t t
|
||||
@@ -11509,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
|
||||
@@ -11530,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
|
||||
|
||||
@@ -11809,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
|
||||
|
||||
84
configure.in
84
configure.in
@@ -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,8 +49,8 @@ case "$host_os" in
|
||||
CLDNOWHOLEARCHIVE=
|
||||
LDDEPS="$LDDEPS"
|
||||
LDFLAGS="$LDFLAGS"
|
||||
SOFLAG="-dynamiclib"
|
||||
DEVMAPPER=no
|
||||
LIB_SUFFIX="dylib"
|
||||
DEVMAPPER=yes
|
||||
ODIRECT=no
|
||||
SELINUX=no
|
||||
CLUSTER=none
|
||||
@@ -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
|
||||
|
||||
@@ -515,6 +544,13 @@ if test x$HAVE_SELINUX = xyes; then
|
||||
AC_CHECK_HEADERS(selinux/selinux.h,,AC_MSG_ERROR(bailing out))
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
AC_PATH_PROG(MODPROBE_CMD, modprobe)
|
||||
|
||||
if test x$MODPROBE_CMD != x; then
|
||||
LVM_DEFS="$LVM_DEFS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test "-f VERSION"; then
|
||||
LVM_VERSION="\"`cat VERSION`\""
|
||||
@@ -532,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)
|
||||
@@ -556,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
|
||||
@@ -565,6 +605,8 @@ Makefile \
|
||||
make.tmpl \
|
||||
daemons/Makefile \
|
||||
daemons/clvmd/Makefile \
|
||||
dmeventd/Makefile \
|
||||
dmeventd/mirror/Makefile \
|
||||
doc/Makefile \
|
||||
include/Makefile \
|
||||
lib/Makefile \
|
||||
@@ -592,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libdevmapper.h"
|
||||
#include "list.h"
|
||||
#include "hash.h"
|
||||
#include "locking.h"
|
||||
#include "log.h"
|
||||
#include "lvm-functions.h"
|
||||
@@ -109,7 +109,7 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
||||
|
||||
case CLVMD_CMD_LOCK_LV:
|
||||
/* This is the biggie */
|
||||
lock_cmd = args[0];
|
||||
lock_cmd = args[0] & 0x3F;
|
||||
lock_flags = args[1];
|
||||
lockname = &args[2];
|
||||
status = do_lock_lv(lock_cmd, lock_flags, lockname);
|
||||
@@ -138,7 +138,7 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
||||
|
||||
static int lock_vg(struct local_client *client)
|
||||
{
|
||||
struct hash_table *lock_hash;
|
||||
struct dm_hash_table *lock_hash;
|
||||
struct clvm_header *header =
|
||||
(struct clvm_header *) client->bits.localsock.cmd;
|
||||
unsigned char lock_cmd;
|
||||
@@ -152,23 +152,23 @@ static int lock_vg(struct local_client *client)
|
||||
practice there should only ever be more than two VGs locked
|
||||
if a user tries to merge lots of them at once */
|
||||
if (client->bits.localsock.private) {
|
||||
lock_hash = (struct hash_table *)client->bits.localsock.private;
|
||||
lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
|
||||
}
|
||||
else {
|
||||
lock_hash = hash_create(3);
|
||||
lock_hash = dm_hash_create(3);
|
||||
if (!lock_hash)
|
||||
return ENOMEM;
|
||||
client->bits.localsock.private = (void *)lock_hash;
|
||||
}
|
||||
|
||||
lock_cmd = args[0];
|
||||
lock_cmd = args[0] & 0x3F;
|
||||
lock_flags = args[1];
|
||||
lockname = &args[2];
|
||||
DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
|
||||
|
||||
if (lock_cmd == LCK_UNLOCK) {
|
||||
|
||||
lkid = (int)(long)hash_lookup(lock_hash, lockname);
|
||||
lkid = (int)(long)dm_hash_lookup(lock_hash, lockname);
|
||||
if (lkid == 0)
|
||||
return EINVAL;
|
||||
|
||||
@@ -176,7 +176,7 @@ static int lock_vg(struct local_client *client)
|
||||
if (status)
|
||||
status = errno;
|
||||
else
|
||||
hash_remove(lock_hash, lockname);
|
||||
dm_hash_remove(lock_hash, lockname);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -184,7 +184,7 @@ static int lock_vg(struct local_client *client)
|
||||
if (status)
|
||||
status = errno;
|
||||
else
|
||||
hash_insert(lock_hash, lockname, (void *)lkid);
|
||||
dm_hash_insert(lock_hash, lockname, (void *)lkid);
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -268,19 +268,19 @@ void cmd_client_cleanup(struct local_client *client)
|
||||
{
|
||||
if (client->bits.localsock.private) {
|
||||
|
||||
struct hash_node *v;
|
||||
struct hash_table *lock_hash =
|
||||
(struct hash_table *)client->bits.localsock.private;
|
||||
struct dm_hash_node *v;
|
||||
struct dm_hash_table *lock_hash =
|
||||
(struct dm_hash_table *)client->bits.localsock.private;
|
||||
|
||||
hash_iterate(v, lock_hash) {
|
||||
int lkid = (int)(long)hash_get_data(lock_hash, v);
|
||||
char *lockname = hash_get_key(lock_hash, v);
|
||||
dm_hash_iterate(v, lock_hash) {
|
||||
int lkid = (int)(long)dm_hash_get_data(lock_hash, v);
|
||||
char *lockname = dm_hash_get_key(lock_hash, v);
|
||||
|
||||
DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
|
||||
sync_unlock(lockname, lkid);
|
||||
}
|
||||
|
||||
hash_destroy(lock_hash);
|
||||
dm_hash_destroy(lock_hash);
|
||||
client->bits.localsock.private = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <syslog.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libdevmapper.h"
|
||||
#include "ccs.h"
|
||||
#include "list.h"
|
||||
#include "locking.h"
|
||||
@@ -49,16 +50,14 @@
|
||||
#include "clvmd-comms.h"
|
||||
#include "lvm-functions.h"
|
||||
#include "clvmd.h"
|
||||
#include "hash.h"
|
||||
#include "clvmd-gulm.h"
|
||||
#include "libgulm.h"
|
||||
#include "hash.h"
|
||||
|
||||
/* Hash list of nodes in the cluster */
|
||||
static struct hash_table *node_hash;
|
||||
static struct dm_hash_table *node_hash;
|
||||
|
||||
/* hash list of outstanding lock requests */
|
||||
static struct hash_table *lock_hash;
|
||||
static struct dm_hash_table *lock_hash;
|
||||
|
||||
/* Copy of the current quorate state */
|
||||
static uint8_t gulm_quorate = 0;
|
||||
@@ -96,7 +95,7 @@ static int _csid_from_name(char *csid, char *name);
|
||||
static void _cluster_closedown(void);
|
||||
|
||||
/* In tcp-comms.c */
|
||||
extern struct hash_table *sock_hash;
|
||||
extern struct dm_hash_table *sock_hash;
|
||||
|
||||
static int add_internal_client(int fd, fd_callback_t callback)
|
||||
{
|
||||
@@ -178,8 +177,8 @@ static int _init_cluster(void)
|
||||
pthread_mutex_lock(&lock_start_mutex);
|
||||
lock_start_flag = 1;
|
||||
|
||||
node_hash = hash_create(100);
|
||||
lock_hash = hash_create(10);
|
||||
node_hash = dm_hash_create(100);
|
||||
lock_hash = dm_hash_create(10);
|
||||
|
||||
/* Get all nodes from CCS */
|
||||
if (get_all_cluster_nodes())
|
||||
@@ -317,8 +316,6 @@ static int core_login_reply(void *misc, uint64_t gen, uint32_t error, uint32_t r
|
||||
|
||||
static void set_node_state(struct node_info *ninfo, char *csid, uint8_t nodestate)
|
||||
{
|
||||
int oldstate = ninfo->state;
|
||||
|
||||
if (nodestate == lg_core_Logged_in)
|
||||
{
|
||||
/* Don't clobber NODE_CLVMD state */
|
||||
@@ -349,15 +346,15 @@ static void set_node_state(struct node_info *ninfo, char *csid, uint8_t nodestat
|
||||
*/
|
||||
tcp_remove_client(csid);
|
||||
|
||||
DEBUGLOG("set_node_state, '%s' state = %d (oldstate=%d), num_nodes=%d\n",
|
||||
ninfo->name, ninfo->state, oldstate, num_nodes);
|
||||
DEBUGLOG("set_node_state, '%s' state = %d num_nodes=%d\n",
|
||||
ninfo->name, ninfo->state, num_nodes);
|
||||
}
|
||||
|
||||
static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_t state)
|
||||
{
|
||||
struct node_info *ninfo;
|
||||
|
||||
ninfo = hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo)
|
||||
{
|
||||
/* If we can't find that node then re-read the config file in case it
|
||||
@@ -366,7 +363,7 @@ static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_
|
||||
get_all_cluster_nodes();
|
||||
|
||||
/* Now try again */
|
||||
ninfo = hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo)
|
||||
{
|
||||
DEBUGLOG("Ignoring node %s, not part of the SAN cluster\n", name);
|
||||
@@ -512,7 +509,7 @@ static int lock_lock_state(void *misc, uint8_t *key, uint16_t keylen,
|
||||
if (in_shutdown)
|
||||
return 0;
|
||||
|
||||
lwait = hash_lookup(lock_hash, key);
|
||||
lwait = dm_hash_lookup(lock_hash, key);
|
||||
if (!lwait)
|
||||
{
|
||||
DEBUGLOG("Can't find hash entry for resource %s\n", key);
|
||||
@@ -557,22 +554,22 @@ int get_next_node_csid(void **context, char *csid)
|
||||
/* First node */
|
||||
if (!*context)
|
||||
{
|
||||
*context = hash_get_first(node_hash);
|
||||
*context = dm_hash_get_first(node_hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
*context = hash_get_next(node_hash, *context);
|
||||
*context = dm_hash_get_next(node_hash, *context);
|
||||
}
|
||||
if (*context)
|
||||
ninfo = hash_get_data(node_hash, *context);
|
||||
ninfo = dm_hash_get_data(node_hash, *context);
|
||||
|
||||
/* Find a node that is UP */
|
||||
while (*context && ninfo->state == NODE_DOWN)
|
||||
{
|
||||
*context = hash_get_next(node_hash, *context);
|
||||
*context = dm_hash_get_next(node_hash, *context);
|
||||
if (*context)
|
||||
{
|
||||
ninfo = hash_get_data(node_hash, *context);
|
||||
ninfo = dm_hash_get_data(node_hash, *context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,7 +578,7 @@ int get_next_node_csid(void **context, char *csid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(csid, hash_get_key(node_hash, *context), GULM_MAX_CSID_LEN);
|
||||
memcpy(csid, dm_hash_get_key(node_hash, *context), GULM_MAX_CSID_LEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -589,7 +586,7 @@ int gulm_name_from_csid(char *csid, char *name)
|
||||
{
|
||||
struct node_info *ninfo;
|
||||
|
||||
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo)
|
||||
{
|
||||
sprintf(name, "UNKNOWN %s", print_csid(csid));
|
||||
@@ -603,15 +600,15 @@ int gulm_name_from_csid(char *csid, char *name)
|
||||
|
||||
static int _csid_from_name(char *csid, char *name)
|
||||
{
|
||||
struct hash_node *hn;
|
||||
struct dm_hash_node *hn;
|
||||
struct node_info *ninfo;
|
||||
|
||||
hash_iterate(hn, node_hash)
|
||||
dm_hash_iterate(hn, node_hash)
|
||||
{
|
||||
ninfo = hash_get_data(node_hash, hn);
|
||||
ninfo = dm_hash_get_data(node_hash, hn);
|
||||
if (strcmp(ninfo->name, name) == 0)
|
||||
{
|
||||
memcpy(csid, hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
|
||||
memcpy(csid, dm_hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -629,7 +626,7 @@ void gulm_add_up_node(char *csid)
|
||||
{
|
||||
struct node_info *ninfo;
|
||||
|
||||
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo) {
|
||||
DEBUGLOG("gulm_add_up_node no node_hash entry for csid %s\n", print_csid(csid));
|
||||
return;
|
||||
@@ -649,7 +646,7 @@ void add_down_node(char *csid)
|
||||
{
|
||||
struct node_info *ninfo;
|
||||
|
||||
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo)
|
||||
return;
|
||||
|
||||
@@ -666,27 +663,27 @@ void add_down_node(char *csid)
|
||||
static int _cluster_do_node_callback(struct local_client *master_client,
|
||||
void (*callback)(struct local_client *, char *csid, int node_up))
|
||||
{
|
||||
struct hash_node *hn;
|
||||
struct dm_hash_node *hn;
|
||||
struct node_info *ninfo;
|
||||
|
||||
hash_iterate(hn, node_hash)
|
||||
dm_hash_iterate(hn, node_hash)
|
||||
{
|
||||
char csid[GULM_MAX_CSID_LEN];
|
||||
struct local_client *client;
|
||||
|
||||
ninfo = hash_get_data(node_hash, hn);
|
||||
memcpy(csid, hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_get_data(node_hash, hn);
|
||||
memcpy(csid, dm_hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
|
||||
|
||||
DEBUGLOG("down_callback. node %s, state = %d\n", ninfo->name, ninfo->state);
|
||||
|
||||
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (!client)
|
||||
{
|
||||
/* If it's up but not connected, try to make contact */
|
||||
if (ninfo->state == NODE_UP)
|
||||
gulm_connect_csid(csid, &client);
|
||||
|
||||
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
|
||||
}
|
||||
if (ninfo->state != NODE_DOWN)
|
||||
@@ -735,7 +732,7 @@ static int _lock_resource(char *resource, int mode, int flags, int *lockid)
|
||||
/* This needs to be converted from DLM/LVM2 value for GULM */
|
||||
if (flags == LCK_NONBLOCK) flags = lg_lock_flag_Try;
|
||||
|
||||
hash_insert(lock_hash, resource, &lwait);
|
||||
dm_hash_insert(lock_hash, resource, &lwait);
|
||||
DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
|
||||
|
||||
status = lg_lock_state_req(gulm_if, resource, strlen(resource)+1,
|
||||
@@ -751,7 +748,7 @@ static int _lock_resource(char *resource, int mode, int flags, int *lockid)
|
||||
pthread_cond_wait(&lwait.cond, &lwait.mutex);
|
||||
pthread_mutex_unlock(&lwait.mutex);
|
||||
|
||||
hash_remove(lock_hash, resource);
|
||||
dm_hash_remove(lock_hash, resource);
|
||||
DEBUGLOG("lock-resource returning %d\n", lwait.status);
|
||||
|
||||
return gulm_to_errno(lwait.status);
|
||||
@@ -767,7 +764,7 @@ static int _unlock_resource(char *resource, int lockid)
|
||||
pthread_mutex_init(&lwait.mutex, NULL);
|
||||
pthread_mutex_lock(&lwait.mutex);
|
||||
|
||||
hash_insert(lock_hash, resource, &lwait);
|
||||
dm_hash_insert(lock_hash, resource, &lwait);
|
||||
|
||||
DEBUGLOG("unlock_resource %s\n", resource);
|
||||
status = lg_lock_state_req(gulm_if, resource, strlen(resource)+1,
|
||||
@@ -790,7 +787,7 @@ static int _unlock_resource(char *resource, int lockid)
|
||||
pthread_cond_wait(&lwait.cond, &lwait.mutex);
|
||||
pthread_mutex_unlock(&lwait.mutex);
|
||||
|
||||
hash_remove(lock_hash, resource);
|
||||
dm_hash_remove(lock_hash, resource);
|
||||
|
||||
return gulm_to_errno(lwait.status);
|
||||
}
|
||||
@@ -926,7 +923,7 @@ static int get_all_cluster_nodes()
|
||||
struct node_info *ninfo;
|
||||
|
||||
/* If it's not in the list, then add it */
|
||||
ninfo = hash_lookup_binary(node_hash, nodeip, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, nodeip, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo)
|
||||
{
|
||||
ninfo = malloc(sizeof(struct node_info));
|
||||
@@ -939,7 +936,7 @@ static int get_all_cluster_nodes()
|
||||
strcpy(ninfo->name, nodename);
|
||||
|
||||
ninfo->state = NODE_DOWN;
|
||||
hash_insert_binary(node_hash, nodeip, GULM_MAX_CSID_LEN, ninfo);
|
||||
dm_hash_insert_binary(node_hash, nodeip, GULM_MAX_CSID_LEN, ninfo);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -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) {
|
||||
@@ -747,6 +748,7 @@ static int read_from_local_sock(struct local_client *thisfd)
|
||||
|
||||
/* If the client went away in mid command then tidy up */
|
||||
if (thisfd->bits.localsock.in_progress) {
|
||||
pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
|
||||
pthread_mutex_lock(&thisfd->bits.localsock.mutex);
|
||||
thisfd->bits.localsock.state = POST_COMMAND;
|
||||
pthread_cond_signal(&thisfd->bits.localsock.cond);
|
||||
@@ -763,7 +765,6 @@ static int read_from_local_sock(struct local_client *thisfd)
|
||||
thisfd->bits.localsock.state = PRE_COMMAND;
|
||||
pthread_cond_signal(&thisfd->bits.localsock.cond);
|
||||
pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
|
||||
pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
|
||||
|
||||
jstat =
|
||||
pthread_join(thisfd->bits.localsock.threadid,
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#include <syslog.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libdevmapper.h"
|
||||
#include "list.h"
|
||||
#include "lvm-types.h"
|
||||
#include "libdlm.h"
|
||||
#include "clvm.h"
|
||||
#include "clvmd-comms.h"
|
||||
@@ -41,11 +44,10 @@
|
||||
#include "toolcontext.h"
|
||||
#include "log.h"
|
||||
#include "activate.h"
|
||||
#include "hash.h"
|
||||
#include "locking.h"
|
||||
|
||||
static struct cmd_context *cmd = NULL;
|
||||
static struct hash_table *lv_hash = NULL;
|
||||
static struct dm_hash_table *lv_hash = NULL;
|
||||
static pthread_mutex_t lv_hash_lock;
|
||||
|
||||
struct lv_info {
|
||||
@@ -59,7 +61,7 @@ static int get_current_lock(char *resource)
|
||||
struct lv_info *lvi;
|
||||
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
lvi = hash_lookup(lv_hash, resource);
|
||||
lvi = dm_hash_lookup(lv_hash, resource);
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
if (lvi) {
|
||||
return lvi->lock_mode;
|
||||
@@ -71,13 +73,13 @@ static int get_current_lock(char *resource)
|
||||
/* Called at shutdown to tidy the lockspace */
|
||||
void unlock_all()
|
||||
{
|
||||
struct hash_node *v;
|
||||
struct dm_hash_node *v;
|
||||
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
hash_iterate(v, lv_hash) {
|
||||
struct lv_info *lvi = hash_get_data(lv_hash, v);
|
||||
dm_hash_iterate(v, lv_hash) {
|
||||
struct lv_info *lvi = dm_hash_get_data(lv_hash, v);
|
||||
|
||||
sync_unlock(hash_get_key(lv_hash, v), lvi->lock_id);
|
||||
sync_unlock(dm_hash_get_key(lv_hash, v), lvi->lock_id);
|
||||
}
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
}
|
||||
@@ -92,7 +94,7 @@ int hold_lock(char *resource, int mode, int flags)
|
||||
flags &= LKF_NOQUEUE; /* Only LKF_NOQUEUE is valid here */
|
||||
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
lvi = hash_lookup(lv_hash, resource);
|
||||
lvi = dm_hash_lookup(lv_hash, resource);
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
if (lvi) {
|
||||
/* Already exists - convert it */
|
||||
@@ -122,7 +124,7 @@ int hold_lock(char *resource, int mode, int flags)
|
||||
strerror(errno));
|
||||
} else {
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
hash_insert(lv_hash, resource, lvi);
|
||||
dm_hash_insert(lv_hash, resource, lvi);
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
}
|
||||
errno = saved_errno;
|
||||
@@ -138,7 +140,7 @@ int hold_unlock(char *resource)
|
||||
int saved_errno;
|
||||
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
lvi = hash_lookup(lv_hash, resource);
|
||||
lvi = dm_hash_lookup(lv_hash, resource);
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
if (!lvi) {
|
||||
DEBUGLOG("hold_unlock, lock not already held\n");
|
||||
@@ -149,7 +151,7 @@ int hold_unlock(char *resource)
|
||||
saved_errno = errno;
|
||||
if (!status) {
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
hash_remove(lv_hash, resource);
|
||||
dm_hash_remove(lv_hash, resource);
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
free(lvi);
|
||||
} else {
|
||||
@@ -168,11 +170,12 @@ int hold_unlock(char *resource)
|
||||
*/
|
||||
|
||||
/* Activate LV exclusive or non-exclusive */
|
||||
static int do_activate_lv(char *resource, int mode)
|
||||
static int do_activate_lv(char *resource, unsigned char lock_flags, int mode)
|
||||
{
|
||||
int oldmode;
|
||||
int status;
|
||||
int activate_lv;
|
||||
int exclusive = 0;
|
||||
struct lvinfo lvi;
|
||||
|
||||
/* Is it already open ? */
|
||||
@@ -189,13 +192,17 @@ static int do_activate_lv(char *resource, int mode)
|
||||
return 0; /* Success, we did nothing! */
|
||||
|
||||
/* Do we need to activate exclusively? */
|
||||
if (activate_lv == 2)
|
||||
if ((activate_lv == 2) || (mode == LKM_EXMODE)) {
|
||||
exclusive = 1;
|
||||
mode = LKM_EXMODE;
|
||||
}
|
||||
|
||||
/* OK, try to get the lock */
|
||||
status = hold_lock(resource, mode, LKF_NOQUEUE);
|
||||
if (status)
|
||||
return errno;
|
||||
/* Try to get the lock if it's a clustered volume group */
|
||||
if (lock_flags & LCK_CLUSTER_VG) {
|
||||
status = hold_lock(resource, mode, LKF_NOQUEUE);
|
||||
if (status)
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* If it's suspended then resume it */
|
||||
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
|
||||
@@ -206,7 +213,7 @@ static int do_activate_lv(char *resource, int mode)
|
||||
return EIO;
|
||||
|
||||
/* Now activate it */
|
||||
if (!lv_activate(cmd, resource))
|
||||
if (!lv_activate(cmd, resource, exclusive))
|
||||
return EIO;
|
||||
|
||||
return 0;
|
||||
@@ -255,14 +262,14 @@ static int do_suspend_lv(char *resource)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_deactivate_lv(char *resource)
|
||||
static int do_deactivate_lv(char *resource, unsigned char lock_flags)
|
||||
{
|
||||
int oldmode;
|
||||
int status;
|
||||
|
||||
/* Is it open ? */
|
||||
oldmode = get_current_lock(resource);
|
||||
if (oldmode == -1) {
|
||||
if (oldmode == -1 && (lock_flags & LCK_CLUSTER_VG)) {
|
||||
DEBUGLOG("do_deactivate_lock, lock not already held\n");
|
||||
return 0; /* We don't need to do anything */
|
||||
}
|
||||
@@ -270,9 +277,11 @@ static int do_deactivate_lv(char *resource)
|
||||
if (!lv_deactivate(cmd, resource))
|
||||
return EIO;
|
||||
|
||||
status = hold_unlock(resource);
|
||||
if (status)
|
||||
return errno;
|
||||
if (lock_flags & LCK_CLUSTER_VG) {
|
||||
status = hold_unlock(resource);
|
||||
if (status)
|
||||
return errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -283,7 +292,7 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
DEBUGLOG("do_lock_lv: resource '%s', cmd = 0x%x, flags = %d\n",
|
||||
DEBUGLOG("do_lock_lv: resource '%s', cmd = 0x%x, flags = %x\n",
|
||||
resource, command, lock_flags);
|
||||
|
||||
if (!cmd->config_valid || config_files_changed(cmd)) {
|
||||
@@ -294,9 +303,12 @@ 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, LKM_EXMODE);
|
||||
status = do_activate_lv(resource, lock_flags, LKM_EXMODE);
|
||||
break;
|
||||
|
||||
case LCK_LV_SUSPEND:
|
||||
@@ -309,11 +321,11 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
break;
|
||||
|
||||
case LCK_LV_ACTIVATE:
|
||||
status = do_activate_lv(resource, LKM_CRMODE);
|
||||
status = do_activate_lv(resource, lock_flags, LKM_CRMODE);
|
||||
break;
|
||||
|
||||
case LCK_LV_DEACTIVATE:
|
||||
status = do_deactivate_lv(resource);
|
||||
status = do_deactivate_lv(resource, lock_flags);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -322,8 +334,11 @@ 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 */
|
||||
pool_empty(cmd->mem);
|
||||
dm_pool_empty(cmd->mem);
|
||||
|
||||
DEBUGLOG("Command return is %d\n", status);
|
||||
return status;
|
||||
@@ -433,23 +448,24 @@ static void drop_vg_locks()
|
||||
*/
|
||||
static void *get_initial_state()
|
||||
{
|
||||
char lv[64], vg[64], flags[25];
|
||||
char lv[64], vg[64], flags[25], vg_flags[25];
|
||||
char uuid[65];
|
||||
char line[255];
|
||||
FILE *lvs =
|
||||
popen
|
||||
("lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr",
|
||||
("lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
|
||||
"r");
|
||||
|
||||
if (!lvs)
|
||||
return NULL;
|
||||
|
||||
while (fgets(line, sizeof(line), lvs)) {
|
||||
if (sscanf(line, "%s %s %s\n", vg, lv, flags) == 3) {
|
||||
if (sscanf(line, "%s %s %s %s\n", vg, lv, flags, vg_flags) == 4) {
|
||||
|
||||
/* States: s:suspended a:active S:dropped snapshot I:invalid snapshot */
|
||||
if (strlen(vg) == 38 && /* is is a valid UUID ? */
|
||||
(flags[4] == 'a' || flags[4] == 's')) { /* is it active or suspended? */
|
||||
(flags[4] == 'a' || flags[4] == 's') && /* is it active or suspended? */
|
||||
vg_flags[5] == 'c') { /* is it clustered ? */
|
||||
/* Convert hyphen-separated UUIDs into one */
|
||||
memcpy(&uuid[0], &vg[0], 6);
|
||||
memcpy(&uuid[6], &vg[7], 4);
|
||||
@@ -503,7 +519,7 @@ static void check_config()
|
||||
void init_lvhash()
|
||||
{
|
||||
/* Create hash table for keeping LV locks & status */
|
||||
lv_hash = hash_create(100);
|
||||
lv_hash = dm_hash_create(100);
|
||||
pthread_mutex_init(&lv_hash_lock, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,17 +35,17 @@
|
||||
#include <netdb.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libdevmapper.h"
|
||||
#include "clvm.h"
|
||||
#include "clvmd-comms.h"
|
||||
#include "clvmd.h"
|
||||
#include "clvmd-gulm.h"
|
||||
#include "hash.h"
|
||||
|
||||
#define DEFAULT_TCP_PORT 21064
|
||||
|
||||
static int listen_fd = -1;
|
||||
static int tcp_port;
|
||||
struct hash_table *sock_hash;
|
||||
struct dm_hash_table *sock_hash;
|
||||
|
||||
static int get_our_ip_address(char *addr, int *family);
|
||||
static int read_from_tcpsock(struct local_client *fd, char *buf, int len, char *csid,
|
||||
@@ -56,7 +56,7 @@ int init_comms(unsigned short port)
|
||||
{
|
||||
struct sockaddr_in6 addr;
|
||||
|
||||
sock_hash = hash_create(100);
|
||||
sock_hash = dm_hash_create(100);
|
||||
tcp_port = port ? port : DEFAULT_TCP_PORT;
|
||||
|
||||
listen_fd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
@@ -101,10 +101,10 @@ void tcp_remove_client(char *csid)
|
||||
job of clvmd.c whch will do the job when it notices the
|
||||
other end has gone. We just need to remove the client(s) from
|
||||
the hash table so we don't try to use it for sending any more */
|
||||
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (client)
|
||||
{
|
||||
hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client->removeme = 1;
|
||||
close(client->fd);
|
||||
}
|
||||
@@ -112,10 +112,10 @@ void tcp_remove_client(char *csid)
|
||||
/* Look for a mangled one too */
|
||||
csid[0] ^= 0x80;
|
||||
|
||||
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (client)
|
||||
{
|
||||
hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client->removeme = 1;
|
||||
close(client->fd);
|
||||
}
|
||||
@@ -146,7 +146,7 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
|
||||
*new_client = client;
|
||||
|
||||
/* Add to our list of node sockets */
|
||||
if (hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
|
||||
if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
|
||||
{
|
||||
DEBUGLOG("alloc_client mangling CSID for second connection\n");
|
||||
/* This is a duplicate connection but we can't close it because
|
||||
@@ -159,7 +159,7 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
|
||||
|
||||
/* If it still exists then kill the connection as we should only
|
||||
ever have one incoming connection from each node */
|
||||
if (hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
|
||||
if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
|
||||
{
|
||||
DEBUGLOG("Multiple incoming connections from node\n");
|
||||
syslog(LOG_ERR, " Bogus incoming connection from %d.%d.%d.%d\n", csid[0],csid[1],csid[2],csid[3]);
|
||||
@@ -169,7 +169,7 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);
|
||||
dm_hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -302,7 +302,7 @@ static int read_from_tcpsock(struct local_client *client, char *buf, int len, ch
|
||||
/* If the csid was mangled, then make sure we remove the right entry */
|
||||
if (client->bits.net.flags)
|
||||
remcsid[0] ^= 0x80;
|
||||
hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);
|
||||
dm_hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);
|
||||
|
||||
/* Tell cluster manager layer */
|
||||
add_down_node(remcsid);
|
||||
@@ -381,7 +381,7 @@ static int tcp_send_message(void *buf, int msglen, unsigned char *csid, const ch
|
||||
if (memcmp(csid, ourcsid, GULM_MAX_CSID_LEN) == 0)
|
||||
return msglen;
|
||||
|
||||
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (!client)
|
||||
{
|
||||
status = gulm_connect_csid(csid, &client);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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, ®, &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
13
daemons/dmeventd/dmeventd.h
Normal file
13
daemons/dmeventd/dmeventd.h
Normal 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__ */
|
||||
510
daemons/dmeventd/libdevmapper-event.c
Normal file
510
daemons/dmeventd/libdevmapper-event.c
Normal 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:
|
||||
*/
|
||||
108
daemons/dmeventd/libdevmapper-event.h
Normal file
108
daemons/dmeventd/libdevmapper-event.h
Normal 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
|
||||
12
daemons/dmeventd/libdevmapper-event.pc.in
Normal file
12
daemons/dmeventd/libdevmapper-event.pc.in
Normal 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
|
||||
@@ -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 $$
|
||||
@@ -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;
|
||||
}
|
||||
22
daemons/dmeventd/plugins/Makefile.in
Normal file
22
daemons/dmeventd/plugins/Makefile.in
Normal 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
|
||||
|
||||
3
daemons/dmeventd/plugins/mirror/.exported_symbols
Normal file
3
daemons/dmeventd/plugins/mirror/.exported_symbols
Normal file
@@ -0,0 +1,3 @@
|
||||
process_event
|
||||
register_device
|
||||
unregister_device
|
||||
36
daemons/dmeventd/plugins/mirror/Makefile.in
Normal file
36
daemons/dmeventd/plugins/mirror/Makefile.in
Normal 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)/$<
|
||||
|
||||
246
daemons/dmeventd/plugins/mirror/dmeventd_mirror.c
Normal file
246
daemons/dmeventd/plugins/mirror/dmeventd_mirror.c
Normal 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, ¶ms);
|
||||
|
||||
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
22
dmeventd/Makefile.in
Normal 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
|
||||
|
||||
3
dmeventd/mirror/.exported_symbols
Normal file
3
dmeventd/mirror/.exported_symbols
Normal file
@@ -0,0 +1,3 @@
|
||||
process_event
|
||||
register_device
|
||||
unregister_device
|
||||
36
dmeventd/mirror/Makefile.in
Normal file
36
dmeventd/mirror/Makefile.in
Normal 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)/$<
|
||||
|
||||
246
dmeventd/mirror/dmeventd_mirror.c
Normal file
246
dmeventd/mirror/dmeventd_mirror.c
Normal 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, ¶ms);
|
||||
|
||||
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:
|
||||
*/
|
||||
@@ -33,8 +33,12 @@ devices {
|
||||
# pattern, the device is accepted; otherwise if any name matches any 'r'
|
||||
# pattern it is rejected; otherwise it is accepted.
|
||||
|
||||
# Remember to run vgscan after you change this parameter to ensure
|
||||
# that the cache file gets regenerated (see below).
|
||||
# Don't have more than one filter line active at once: only one gets used.
|
||||
|
||||
# Run vgscan after you change this parameter to ensure that
|
||||
# the cache file gets regenerated (see below).
|
||||
# If it doesn't do what you expect, check the output of 'vgscan -vvvv'.
|
||||
|
||||
|
||||
# By default we accept every block device:
|
||||
filter = [ "a/.*/" ]
|
||||
@@ -285,4 +289,9 @@ activation {
|
||||
# dirs = [ "/etc/lvm/metadata", "/mnt/disk2/lvm/metadata2" ]
|
||||
#}
|
||||
|
||||
# Event daemon
|
||||
#
|
||||
#dmeventd {
|
||||
# mirror_library = "libdevmapper-event-lvm2mirror.so"
|
||||
#}
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
../lib/commands/toolcontext.h
|
||||
../lib/config/config.h
|
||||
../lib/config/defaults.h
|
||||
../lib/datastruct/bitset.h
|
||||
../lib/datastruct/btree.h
|
||||
../lib/datastruct/hash.h
|
||||
../lib/datastruct/list.h
|
||||
../lib/datastruct/lvm-types.h
|
||||
../lib/datastruct/str_list.h
|
||||
@@ -34,16 +32,14 @@
|
||||
../lib/metadata/metadata.h
|
||||
../lib/metadata/pv_alloc.h
|
||||
../lib/metadata/segtype.h
|
||||
../lib/mm/dbg_malloc.h
|
||||
../lib/mm/memlock.h
|
||||
../lib/mm/pool.h
|
||||
../lib/mm/xlate.h
|
||||
../lib/misc/crc.h
|
||||
../lib/misc/intl.h
|
||||
../lib/misc/lib.h
|
||||
../lib/misc/lvm-exec.h
|
||||
../lib/misc/lvm-file.h
|
||||
../lib/misc/lvm-string.h
|
||||
../lib/misc/selinux.h
|
||||
../lib/misc/sharedlib.h
|
||||
../lib/regex/matcher.h
|
||||
../lib/report/report.h
|
||||
|
||||
@@ -41,3 +41,5 @@ install:
|
||||
|
||||
install_cluster:
|
||||
|
||||
cflow:
|
||||
|
||||
|
||||
@@ -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 the LVM2.
|
||||
#
|
||||
@@ -37,9 +37,8 @@ SOURCES =\
|
||||
cache/lvmcache.c \
|
||||
commands/toolcontext.c \
|
||||
config/config.c \
|
||||
datastruct/bitset.c \
|
||||
datastruct/btree.c \
|
||||
datastruct/hash.c \
|
||||
datastruct/list.c \
|
||||
datastruct/str_list.c \
|
||||
device/dev-cache.c \
|
||||
device/dev-io.c \
|
||||
@@ -76,11 +75,10 @@ SOURCES =\
|
||||
metadata/segtype.c \
|
||||
metadata/snapshot_manip.c \
|
||||
misc/crc.c \
|
||||
misc/lvm-exec.c \
|
||||
misc/lvm-file.c \
|
||||
misc/lvm-string.c \
|
||||
mm/dbg_malloc.c \
|
||||
mm/memlock.c \
|
||||
mm/pool.c \
|
||||
regex/matcher.c \
|
||||
regex/parse_rx.c \
|
||||
regex/ttree.c \
|
||||
@@ -136,13 +134,22 @@ ifeq ("@HAVE_LIBDL@", "yes")
|
||||
misc/sharedlib.c
|
||||
endif
|
||||
|
||||
ifeq ("@HAVE_SELINUX@", "yes")
|
||||
SOURCES += misc/selinux.c
|
||||
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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
@@ -19,13 +19,15 @@
|
||||
#include "memlock.h"
|
||||
#include "display.h"
|
||||
#include "fs.h"
|
||||
#include "lvm-exec.h"
|
||||
#include "lvm-file.h"
|
||||
#include "lvm-string.h"
|
||||
#include "pool.h"
|
||||
#include "toolcontext.h"
|
||||
#include "dev_manager.h"
|
||||
#include "str_list.h"
|
||||
#include "config.h"
|
||||
#include "filter.h"
|
||||
#include "segtype.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
@@ -74,11 +76,16 @@ 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;
|
||||
}
|
||||
int lv_info(const struct logical_volume *lv, struct lvinfo *info,
|
||||
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
|
||||
int with_open_count)
|
||||
{
|
||||
return 0;
|
||||
@@ -88,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;
|
||||
}
|
||||
@@ -130,11 +137,11 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -144,6 +151,12 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void activation_exit(void)
|
||||
{
|
||||
return;
|
||||
@@ -163,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)
|
||||
@@ -257,53 +270,29 @@ int library_version(char *version, size_t size)
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!dm_get_library_version(version, size))
|
||||
return 0;
|
||||
return 1;
|
||||
return dm_get_library_version(version, size);
|
||||
}
|
||||
|
||||
int driver_version(char *version, size_t size)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_task *dmt;
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
log_very_verbose("Getting driver version");
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dm_task_run(dmt))
|
||||
log_error("Failed to get driver version");
|
||||
|
||||
if (!dm_task_get_driver_version(dmt, version, size))
|
||||
goto out;
|
||||
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
return r;
|
||||
return dm_driver_version(version, size);
|
||||
}
|
||||
|
||||
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;
|
||||
struct dm_versions *target, *last_target;
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
log_very_verbose("Getting target version for %s", target_name);
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
|
||||
return_0;
|
||||
|
||||
if (!dm_task_run(dmt)) {
|
||||
log_debug("Failed to get %s target version", target_name);
|
||||
@@ -318,6 +307,9 @@ 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;
|
||||
}
|
||||
|
||||
@@ -330,26 +322,57 @@ int target_present(const char *target_name)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if info structure populated, else 0 on failure.
|
||||
*/
|
||||
static int _lv_info(const struct logical_volume *lv, int mknodes,
|
||||
struct lvinfo *info, int with_open_count)
|
||||
int target_present(const char *target_name, int use_modprobe)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
struct dm_info dminfo;
|
||||
uint32_t maj, min, patchlevel;
|
||||
#ifdef MODPROBE_CMD
|
||||
char module[128];
|
||||
#endif
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
#ifdef MODPROBE_CMD
|
||||
if (use_modprobe) {
|
||||
if (target_version(target_name, &maj, &min, &patchlevel))
|
||||
return 1;
|
||||
|
||||
if (!(r = dev_manager_info(dm, lv, mknodes, with_open_count, &dminfo)))
|
||||
stack;
|
||||
if (lvm_snprintf(module, sizeof(module), "dm-%s", target_name)
|
||||
< 0) {
|
||||
log_error("target_present module name too long: %s",
|
||||
target_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!exec_cmd(MODPROBE_CMD, module, "", ""))
|
||||
return_0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return target_version(target_name, &maj, &min, &patchlevel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if info structure populated, else 0 on failure.
|
||||
*/
|
||||
static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int with_mknodes,
|
||||
struct lvinfo *info, int with_open_count)
|
||||
{
|
||||
struct dm_info dminfo;
|
||||
char *name;
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!(name = build_dm_name(cmd->mem, lv->vg->name, lv->name, NULL)))
|
||||
return_0;
|
||||
|
||||
log_debug("Getting device info for %s", name);
|
||||
if (!dev_manager_info(lv->vg->cmd->mem, name, lv, with_mknodes,
|
||||
with_open_count, &dminfo)) {
|
||||
dm_pool_free(cmd->mem, name);
|
||||
return_0;
|
||||
}
|
||||
|
||||
info->exists = dminfo.exists;
|
||||
info->suspended = dminfo.suspended;
|
||||
@@ -357,15 +380,17 @@ static int _lv_info(const struct logical_volume *lv, int mknodes,
|
||||
info->major = dminfo.major;
|
||||
info->minor = dminfo.minor;
|
||||
info->read_only = dminfo.read_only;
|
||||
info->live_table = dminfo.live_table;
|
||||
info->inactive_table = dminfo.inactive_table;
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
return r;
|
||||
dm_pool_free(cmd->mem, name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lv_info(const struct logical_volume *lv, struct lvinfo *info,
|
||||
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
|
||||
int with_open_count)
|
||||
{
|
||||
return _lv_info(lv, 0, info, with_open_count);
|
||||
return _lv_info(cmd, lv, 0, info, with_open_count);
|
||||
}
|
||||
|
||||
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
|
||||
@@ -373,16 +398,16 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
return _lv_info(lv, 0, info, with_open_count);
|
||||
return _lv_info(cmd, lv, 0, info, with_open_count);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
@@ -390,10 +415,8 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_snapshot_percent(dm, lv, percent)))
|
||||
stack;
|
||||
@@ -404,8 +427,8 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
|
||||
}
|
||||
|
||||
/* FIXME Merge with snapshot_percent */
|
||||
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)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
@@ -414,18 +437,14 @@ int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!lv_info(lv, &info, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
return_0;
|
||||
|
||||
if (!info.exists)
|
||||
return 0;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
|
||||
stack;
|
||||
@@ -435,11 +454,11 @@ int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _lv_active(struct logical_volume *lv)
|
||||
static int _lv_active(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
{
|
||||
struct lvinfo info;
|
||||
|
||||
if (!lv_info(lv, &info, 0)) {
|
||||
if (!lv_info(cmd, lv, &info, 0)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
@@ -447,11 +466,11 @@ static int _lv_active(struct logical_volume *lv)
|
||||
return info.exists;
|
||||
}
|
||||
|
||||
static int _lv_open_count(struct logical_volume *lv)
|
||||
static int _lv_open_count(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
{
|
||||
struct lvinfo info;
|
||||
|
||||
if (!lv_info(lv, &info, 1)) {
|
||||
if (!lv_info(cmd, lv, &info, 1)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
@@ -459,16 +478,13 @@ static int _lv_open_count(struct logical_volume *lv)
|
||||
return info.open_count;
|
||||
}
|
||||
|
||||
/* FIXME Need to detect and handle an lv rename */
|
||||
static int _lv_activate_lv(struct logical_volume *lv)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_activate(dm, lv)))
|
||||
stack;
|
||||
@@ -477,15 +493,28 @@ static int _lv_activate_lv(struct logical_volume *lv)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _lv_preload(struct logical_volume *lv)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_preload(dm, lv)))
|
||||
stack;
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _lv_deactivate(struct logical_volume *lv)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_deactivate(dm, lv)))
|
||||
stack;
|
||||
@@ -499,10 +528,8 @@ static int _lv_suspend_lv(struct logical_volume *lv)
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_suspend(dm, lv)))
|
||||
stack;
|
||||
@@ -525,7 +552,7 @@ int lvs_in_vg_activated(struct volume_group *vg)
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
if (lvl->lv->status & VISIBLE_LV)
|
||||
count += (_lv_active(lvl->lv) == 1);
|
||||
count += (_lv_active(vg->cmd, lvl->lv) == 1);
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -541,37 +568,82 @@ int lvs_in_vg_opened(struct volume_group *vg)
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
if (lvl->lv->status & VISIBLE_LV)
|
||||
count += (_lv_open_count(lvl->lv) > 0);
|
||||
count += (_lv_open_count(vg->cmd, lvl->lv) > 0);
|
||||
}
|
||||
|
||||
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)))
|
||||
return 0;
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return_0;
|
||||
|
||||
/* Use precommitted metadata if present */
|
||||
if (!(lv_pre = lv_from_lvid(cmd, lvid_s, 1)))
|
||||
return_0;
|
||||
|
||||
if (test_mode()) {
|
||||
_skip("Suspending '%s'.", lv->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(lv, &info, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
return_0;
|
||||
|
||||
if (!info.exists || info.suspended)
|
||||
return error_if_not_suspended ? 0 : 1;
|
||||
|
||||
/* If VG was precommitted, preload devices for the 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();
|
||||
@@ -602,7 +674,7 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
||||
if (!activation())
|
||||
return 1;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
if (test_mode()) {
|
||||
@@ -610,10 +682,8 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(lv, &info, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
return_0;
|
||||
|
||||
if (!info.exists || !info.suspended)
|
||||
return error_if_not_active ? 0 : 1;
|
||||
@@ -624,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;
|
||||
}
|
||||
|
||||
@@ -647,7 +720,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
|
||||
if (!activation())
|
||||
return 1;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
if (test_mode()) {
|
||||
@@ -655,20 +728,21 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(lv, &info, 1)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!lv_info(cmd, lv, &info, 1))
|
||||
return_0;
|
||||
|
||||
if (!info.exists)
|
||||
return 1;
|
||||
|
||||
if (info.open_count && (lv->status & VISIBLE_LV)) {
|
||||
log_error("LV %s/%s in use: not removing", lv->vg->name,
|
||||
log_error("LV %s/%s in use: not deactivating", lv->vg->name,
|
||||
lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_register_dev_for_events(cmd, lv, 0))
|
||||
stack;
|
||||
|
||||
memlock_inc();
|
||||
r = _lv_deactivate(lv);
|
||||
memlock_dec();
|
||||
@@ -686,7 +760,7 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
|
||||
if (!activation())
|
||||
goto activate;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
if (!_passes_activation_filter(cmd, lv)) {
|
||||
@@ -701,7 +775,8 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
|
||||
static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
int exclusive, int filter)
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
struct lvinfo info;
|
||||
@@ -710,7 +785,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
|
||||
if (!activation())
|
||||
return 1;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
if (filter && !_passes_activation_filter(cmd, lv)) {
|
||||
@@ -724,32 +799,36 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(lv, &info, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
return_0;
|
||||
|
||||
if (info.exists && !info.suspended)
|
||||
if (info.exists && !info.suspended && info.live_table)
|
||||
return 1;
|
||||
|
||||
if (exclusive)
|
||||
lv->status |= ACTIVATE_EXCL;
|
||||
|
||||
memlock_inc();
|
||||
r = _lv_activate_lv(lv);
|
||||
memlock_dec();
|
||||
fs_unlock();
|
||||
|
||||
if (!_register_dev_for_events(cmd, lv, 1))
|
||||
stack;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Activate LV */
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
|
||||
{
|
||||
return _lv_activate(cmd, lvid_s, 0);
|
||||
return _lv_activate(cmd, lvid_s, exclusive, 0);
|
||||
}
|
||||
|
||||
/* Activate LV only if it passes filter */
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
|
||||
{
|
||||
return _lv_activate(cmd, lvid_s, 1);
|
||||
return _lv_activate(cmd, lvid_s, exclusive, 1);
|
||||
}
|
||||
|
||||
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
@@ -758,15 +837,13 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
int r = 1;
|
||||
|
||||
if (!lv) {
|
||||
r = dev_manager_mknodes();
|
||||
r = dm_mknodes(NULL);
|
||||
fs_unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!_lv_info(lv, 1, &info, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_lv_info(cmd, lv, 1, &info, 0))
|
||||
return_0;
|
||||
|
||||
if (info.exists)
|
||||
r = dev_manager_lv_mknodes(lv);
|
||||
@@ -778,6 +855,34 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does PV use VG somewhere in its construction?
|
||||
* Returns 1 on failure.
|
||||
*/
|
||||
int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
struct dev_manager *dm;
|
||||
int r;
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!dm_is_dm_major(MAJOR(pv->dev->dev)))
|
||||
return 0;
|
||||
|
||||
if (!(dm = dev_manager_create(cmd, vg->name))) {
|
||||
stack;
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = dev_manager_device_uses_vg(dm, pv->dev, vg);
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void activation_exit(void)
|
||||
{
|
||||
dev_manager_exit();
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
|
||||
#include "metadata.h"
|
||||
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
# include <libdevmapper.h>
|
||||
#endif
|
||||
|
||||
struct lvinfo {
|
||||
int exists;
|
||||
int suspended;
|
||||
@@ -29,6 +25,8 @@ struct lvinfo {
|
||||
int major;
|
||||
int minor;
|
||||
int read_only;
|
||||
int live_table;
|
||||
int inactive_table;
|
||||
};
|
||||
|
||||
void set_activation(int activation);
|
||||
@@ -38,7 +36,9 @@ int driver_version(char *version, size_t size);
|
||||
int library_version(char *version, size_t size);
|
||||
int lvm1_present(struct cmd_context *cmd);
|
||||
|
||||
int target_present(const char *target_name);
|
||||
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);
|
||||
|
||||
@@ -46,8 +46,9 @@ int lv_suspend(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_resume(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive);
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s,
|
||||
int exclusive);
|
||||
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s);
|
||||
|
||||
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
|
||||
@@ -55,7 +56,7 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
|
||||
/*
|
||||
* Returns 1 if info structure has been populated, else 0.
|
||||
*/
|
||||
int lv_info(const struct logical_volume *lv, struct lvinfo *info,
|
||||
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
|
||||
int with_open_count);
|
||||
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
|
||||
struct lvinfo *info, int with_open_count);
|
||||
@@ -69,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 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.
|
||||
@@ -79,6 +80,10 @@ int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
|
||||
int lvs_in_vg_activated(struct volume_group *vg);
|
||||
int lvs_in_vg_opened(struct volume_group *vg);
|
||||
|
||||
int lv_setup_cow_store(struct logical_volume *lv);
|
||||
/*
|
||||
* Returns 1 if PV has a dependency tree that uses anything in VG.
|
||||
*/
|
||||
int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
struct volume_group *vg);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,9 +17,11 @@
|
||||
#define _LVM_DEV_MANAGER_H
|
||||
|
||||
struct logical_volume;
|
||||
struct volume_group;
|
||||
struct cmd_context;
|
||||
struct dev_manager;
|
||||
struct dm_info;
|
||||
struct device;
|
||||
|
||||
/*
|
||||
* Constructor and destructor.
|
||||
@@ -35,24 +37,29 @@ void dev_manager_exit(void);
|
||||
* (eg, an origin is created before its snapshot, but is not
|
||||
* unsuspended until the snapshot is also created.)
|
||||
*/
|
||||
int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
|
||||
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);
|
||||
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
|
||||
|
||||
int dev_manager_lv_mknodes(const struct logical_volume *lv);
|
||||
int dev_manager_lv_rmnodes(const struct logical_volume *lv);
|
||||
int dev_manager_mknodes(void);
|
||||
|
||||
/*
|
||||
* Put the desired changes into effect.
|
||||
*/
|
||||
int dev_manager_execute(struct dev_manager *dm);
|
||||
|
||||
int dev_manager_device_uses_vg(struct dev_manager *dm, struct device *dev,
|
||||
struct volume_group *vg);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,16 +20,11 @@
|
||||
#include "lvm-file.h"
|
||||
#include "memlock.h"
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
# include "selinux.h"
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
#include <libdevmapper.h>
|
||||
|
||||
static int _mk_dir(const char *dev_dir, const char *vg_name)
|
||||
{
|
||||
@@ -180,7 +175,7 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
|
||||
}
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
if (!set_selinux_context(lv_path, S_IFLNK)) {
|
||||
if (!dm_set_selinux_context(lv_path, S_IFLNK)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -283,7 +278,7 @@ static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
|
||||
strlen(dev) + strlen(old_lv_name) + 5;
|
||||
char *pos;
|
||||
|
||||
if (!(fsp = dbg_malloc(sizeof(*fsp) + len))) {
|
||||
if (!(fsp = dm_malloc(sizeof(*fsp) + len))) {
|
||||
log_error("No space to stack fs operation");
|
||||
return 0;
|
||||
}
|
||||
@@ -312,7 +307,7 @@ static void _pop_fs_ops(void)
|
||||
_do_fs_op(fsp->type, fsp->dev_dir, fsp->vg_name, fsp->lv_name,
|
||||
fsp->dev, fsp->old_lv_name);
|
||||
list_del(&fsp->list);
|
||||
dbg_free(fsp);
|
||||
dm_free(fsp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,12 @@ int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
char *params, size_t paramsize, int *pos,
|
||||
int start_area, int areas);
|
||||
|
||||
int compose_log_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
char *params, size_t paramsize, int *pos, int areas,
|
||||
uint32_t region_size);
|
||||
int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
struct dm_tree_node *node, int start_area, int areas);
|
||||
|
||||
int build_dev_string(struct dev_manager *dm, char *dlid, char *devbuf,
|
||||
size_t bufsize, const char *desc);
|
||||
|
||||
char *build_dlid(struct dev_manager *dm, const char *lvid, const char *layer);
|
||||
|
||||
#endif
|
||||
|
||||
428
lib/cache/lvmcache.c
vendored
428
lib/cache/lvmcache.c
vendored
@@ -16,7 +16,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "lvmcache.h"
|
||||
#include "hash.h"
|
||||
#include "toolcontext.h"
|
||||
#include "dev-cache.h"
|
||||
#include "metadata.h"
|
||||
@@ -24,10 +23,10 @@
|
||||
#include "memlock.h"
|
||||
#include "str_list.h"
|
||||
|
||||
static struct hash_table *_pvid_hash = NULL;
|
||||
static struct hash_table *_vgid_hash = NULL;
|
||||
static struct hash_table *_vgname_hash = NULL;
|
||||
static struct hash_table *_lock_hash = NULL;
|
||||
static struct dm_hash_table *_pvid_hash = NULL;
|
||||
static struct dm_hash_table *_vgid_hash = NULL;
|
||||
static struct dm_hash_table *_vgname_hash = NULL;
|
||||
static struct dm_hash_table *_lock_hash = NULL;
|
||||
static struct list _vginfos;
|
||||
static int _has_scanned = 0;
|
||||
static int _vgs_locked = 0;
|
||||
@@ -36,16 +35,16 @@ int lvmcache_init(void)
|
||||
{
|
||||
list_init(&_vginfos);
|
||||
|
||||
if (!(_vgname_hash = hash_create(128)))
|
||||
if (!(_vgname_hash = dm_hash_create(128)))
|
||||
return 0;
|
||||
|
||||
if (!(_vgid_hash = hash_create(128)))
|
||||
if (!(_vgid_hash = dm_hash_create(128)))
|
||||
return 0;
|
||||
|
||||
if (!(_pvid_hash = hash_create(128)))
|
||||
if (!(_pvid_hash = dm_hash_create(128)))
|
||||
return 0;
|
||||
|
||||
if (!(_lock_hash = hash_create(128)))
|
||||
if (!(_lock_hash = dm_hash_create(128)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@@ -58,25 +57,24 @@ void lvmcache_lock_vgname(const char *vgname, int read_only)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hash_insert(_lock_hash, vgname, (void *) 1))
|
||||
if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
|
||||
log_error("Cache locking failure for %s", vgname);
|
||||
|
||||
_vgs_locked++;
|
||||
}
|
||||
|
||||
static int _vgname_is_locked(const char *vgname) __attribute__ ((unused));
|
||||
static int _vgname_is_locked(const char *vgname)
|
||||
int vgname_is_locked(const char *vgname)
|
||||
{
|
||||
if (!_lock_hash)
|
||||
return 0;
|
||||
|
||||
return hash_lookup(_lock_hash, vgname) ? 1 : 0;
|
||||
return dm_hash_lookup(_lock_hash, vgname) ? 1 : 0;
|
||||
}
|
||||
|
||||
void lvmcache_unlock_vgname(const char *vgname)
|
||||
{
|
||||
/* FIXME: Clear all CACHE_LOCKED flags in this vg */
|
||||
hash_remove(_lock_hash, vgname);
|
||||
dm_hash_remove(_lock_hash, vgname);
|
||||
|
||||
/* FIXME Do this per-VG */
|
||||
if (!--_vgs_locked)
|
||||
@@ -88,20 +86,27 @@ 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;
|
||||
|
||||
if (!_vgname_hash)
|
||||
return NULL;
|
||||
|
||||
if (!(vginfo = hash_lookup(_vgname_hash, 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;
|
||||
@@ -109,26 +114,34 @@ 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
|
||||
* we check cached labels here. Unfortunately vginfo is volatile. */
|
||||
list_init(&devs);
|
||||
list_iterate_items(info, &vginfo->infos) {
|
||||
devl = dbg_malloc(sizeof(*devl));
|
||||
devl = dm_malloc(sizeof(*devl));
|
||||
devl->dev = info->dev;
|
||||
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);
|
||||
list_del(&devl->list);
|
||||
dbg_free(devl);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -144,12 +157,25 @@ struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid)
|
||||
strncpy(&id[0], vgid, ID_LEN);
|
||||
id[ID_LEN] = '\0';
|
||||
|
||||
if (!(vginfo = hash_lookup(_vgid_hash, id)))
|
||||
if (!(vginfo = dm_hash_lookup(_vgid_hash, id)))
|
||||
return NULL;
|
||||
|
||||
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;
|
||||
@@ -161,7 +187,7 @@ struct lvmcache_info *info_from_pvid(const char *pvid)
|
||||
strncpy(&id[0], pvid, ID_LEN);
|
||||
id[ID_LEN] = '\0';
|
||||
|
||||
if (!(info = hash_lookup(_pvid_hash, id)))
|
||||
if (!(info = dm_hash_lookup(_pvid_hash, id)))
|
||||
return NULL;
|
||||
|
||||
return info;
|
||||
@@ -177,7 +203,7 @@ static void _rescan_entry(struct lvmcache_info *info)
|
||||
|
||||
static int _scan_invalid(void)
|
||||
{
|
||||
hash_iter(_pvid_hash, (iterate_fn) _rescan_entry);
|
||||
dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _rescan_entry);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -234,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);
|
||||
|
||||
@@ -246,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,
|
||||
pool_strdup(cmd->mem, vgi->vgname))) {
|
||||
dm_pool_strdup(cmd->mem, vginfo->vgname))) {
|
||||
log_error("strlist allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -299,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);
|
||||
@@ -307,29 +356,41 @@ static void _drop_vginfo(struct lvmcache_info *info)
|
||||
}
|
||||
|
||||
if (info->vginfo && list_empty(&info->vginfo->infos)) {
|
||||
hash_remove(_vgname_hash, info->vginfo->vgname);
|
||||
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)
|
||||
dbg_free(info->vginfo->vgname);
|
||||
dm_free(info->vginfo->vgname);
|
||||
if (info->vginfo->creation_host)
|
||||
dm_free(info->vginfo->creation_host);
|
||||
if (*info->vginfo->vgid)
|
||||
hash_remove(_vgid_hash, info->vginfo->vgid);
|
||||
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
|
||||
list_del(&info->vginfo->list);
|
||||
dbg_free(info->vginfo);
|
||||
dm_free(info->vginfo);
|
||||
}
|
||||
|
||||
info->vginfo = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Unused
|
||||
void lvmcache_del(struct lvmcache_info *info)
|
||||
{
|
||||
if (info->dev->pvid[0] && _pvid_hash)
|
||||
hash_remove(_pvid_hash, info->dev->pvid);
|
||||
dm_hash_remove(_pvid_hash, info->dev->pvid);
|
||||
|
||||
_drop_vginfo(info);
|
||||
|
||||
info->label->labeller->ops->destroy_label(info->label->labeller,
|
||||
info->label);
|
||||
dbg_free(info);
|
||||
dm_free(info);
|
||||
|
||||
return;
|
||||
} */
|
||||
@@ -339,10 +400,10 @@ static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
|
||||
if (!strcmp(info->dev->pvid, pvid))
|
||||
return 1;
|
||||
if (*info->dev->pvid) {
|
||||
hash_remove(_pvid_hash, info->dev->pvid);
|
||||
dm_hash_remove(_pvid_hash, info->dev->pvid);
|
||||
}
|
||||
strncpy(info->dev->pvid, pvid, sizeof(info->dev->pvid));
|
||||
if (!hash_insert(_pvid_hash, pvid, info)) {
|
||||
if (!dm_hash_insert(_pvid_hash, pvid, info)) {
|
||||
log_error("_lvmcache_update: pvid insertion failed: %s", pvid);
|
||||
return 0;
|
||||
}
|
||||
@@ -357,31 +418,124 @@ static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
|
||||
return 1;
|
||||
|
||||
if (info->vginfo && *info->vginfo->vgid)
|
||||
hash_remove(_vgid_hash, info->vginfo->vgid);
|
||||
if (!vgid)
|
||||
dm_hash_remove(_vgid_hash, info->vginfo->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';
|
||||
if (!hash_insert(_vgid_hash, info->vginfo->vgid, info->vginfo)) {
|
||||
if (!dm_hash_insert(_vgid_hash, info->vginfo->vgid, info->vginfo)) {
|
||||
log_error("_lvmcache_update: vgid hash insertion failed: %s",
|
||||
info->vginfo->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;
|
||||
@@ -390,23 +544,59 @@ 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 = dbg_malloc(sizeof(*vginfo)))) {
|
||||
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;
|
||||
}
|
||||
memset(vginfo, 0, sizeof(*vginfo));
|
||||
if (!(vginfo->vgname = dbg_strdup(vgname))) {
|
||||
dbg_free(vginfo);
|
||||
if (!(vginfo->vgname = dm_strdup(vgname))) {
|
||||
dm_free(vginfo);
|
||||
log_error("cache vgname alloc failed for %s", vgname);
|
||||
return 0;
|
||||
}
|
||||
list_init(&vginfo->infos);
|
||||
if (!hash_insert(_vgname_hash, vginfo->vgname, vginfo)) {
|
||||
log_error("cache_update: vg hash insertion failed: %s",
|
||||
vginfo->vgname);
|
||||
dbg_free(vginfo->vgname);
|
||||
dbg_free(vginfo);
|
||||
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;
|
||||
}
|
||||
/* Ensure orphans appear last on list_iterate */
|
||||
@@ -414,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;
|
||||
@@ -422,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;
|
||||
}
|
||||
@@ -433,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;
|
||||
@@ -454,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;
|
||||
@@ -474,7 +716,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(info = dbg_malloc(sizeof(*info)))) {
|
||||
if (!(info = dm_malloc(sizeof(*info)))) {
|
||||
log_error("lvmcache_info allocation failed");
|
||||
label_destroy(label);
|
||||
return NULL;
|
||||
@@ -495,17 +737,36 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
pvid, dev_name(dev),
|
||||
dev_name(existing->dev));
|
||||
return NULL;
|
||||
} else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
|
||||
!dm_is_dm_major(MAJOR(dev->dev))) {
|
||||
log_very_verbose("Ignoring duplicate PV %s on "
|
||||
"%s - using dm %s",
|
||||
pvid, dev_name(dev),
|
||||
dev_name(existing->dev));
|
||||
return NULL;
|
||||
} else if (MAJOR(existing->dev->dev) != md_major() &&
|
||||
MAJOR(dev->dev) == md_major())
|
||||
log_very_verbose("Duplicate PV %s on %s - "
|
||||
"using md %s", pvid,
|
||||
dev_name(existing->dev),
|
||||
dev_name(dev));
|
||||
else if (!dm_is_dm_major(MAJOR(existing->dev->dev)) &&
|
||||
dm_is_dm_major(MAJOR(dev->dev)))
|
||||
log_very_verbose("Duplicate PV %s on %s - "
|
||||
"using dm %s", pvid,
|
||||
dev_name(existing->dev),
|
||||
dev_name(dev));
|
||||
/* FIXME If both dm, check dependencies */
|
||||
//else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
|
||||
//dm_is_dm_major(MAJOR(dev->dev)))
|
||||
//
|
||||
else
|
||||
log_error("Found duplicate PV %s: using %s not "
|
||||
"%s", pvid, dev_name(dev),
|
||||
dev_name(existing->dev));
|
||||
}
|
||||
/* Switch over to new preferred device */
|
||||
existing->dev = dev;
|
||||
info = existing;
|
||||
/* Has labeller changed? */
|
||||
if (info->label->labeller != labeller) {
|
||||
@@ -525,26 +786,22 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
|
||||
if (!_lvmcache_update_pvid(info, pvid_s)) {
|
||||
if (!existing) {
|
||||
dbg_free(info);
|
||||
dm_free(info);
|
||||
label_destroy(label);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!lvmcache_update_vgname(info, vgname)) {
|
||||
if (!lvmcache_update_vgname_and_id(info, vgname, vgid, vgstatus, NULL)) {
|
||||
if (!existing) {
|
||||
hash_remove(_pvid_hash, pvid_s);
|
||||
dm_hash_remove(_pvid_hash, pvid_s);
|
||||
strcpy(info->dev->pvid, "");
|
||||
dbg_free(info);
|
||||
dm_free(info);
|
||||
label_destroy(label);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_lvmcache_update_vgid(info, vgid))
|
||||
/* Non-critical */
|
||||
stack;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -554,14 +811,21 @@ static void _lvmcache_destroy_entry(struct lvmcache_info *info)
|
||||
list_del(&info->list);
|
||||
strcpy(info->dev->pvid, "");
|
||||
label_destroy(info->label);
|
||||
dbg_free(info);
|
||||
dm_free(info);
|
||||
}
|
||||
|
||||
static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
|
||||
{
|
||||
if (vginfo->vgname)
|
||||
dbg_free(vginfo->vgname);
|
||||
dbg_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)
|
||||
@@ -576,26 +840,26 @@ void lvmcache_destroy(void)
|
||||
_has_scanned = 0;
|
||||
|
||||
if (_vgid_hash) {
|
||||
hash_destroy(_vgid_hash);
|
||||
dm_hash_destroy(_vgid_hash);
|
||||
_vgid_hash = NULL;
|
||||
}
|
||||
|
||||
if (_pvid_hash) {
|
||||
hash_iter(_pvid_hash, (iterate_fn) _lvmcache_destroy_entry);
|
||||
hash_destroy(_pvid_hash);
|
||||
dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _lvmcache_destroy_entry);
|
||||
dm_hash_destroy(_pvid_hash);
|
||||
_pvid_hash = NULL;
|
||||
}
|
||||
|
||||
if (_vgname_hash) {
|
||||
hash_iter(_vgname_hash,
|
||||
(iterate_fn) _lvmcache_destroy_vgnamelist);
|
||||
hash_destroy(_vgname_hash);
|
||||
dm_hash_iter(_vgname_hash,
|
||||
(dm_hash_iterate_fn) _lvmcache_destroy_vgnamelist);
|
||||
dm_hash_destroy(_vgname_hash);
|
||||
_vgname_hash = NULL;
|
||||
}
|
||||
|
||||
if (_lock_hash) {
|
||||
hash_iter(_lock_hash, (iterate_fn) _lvmcache_destroy_lockname);
|
||||
hash_destroy(_lock_hash);
|
||||
dm_hash_iter(_lock_hash, (dm_hash_iterate_fn) _lvmcache_destroy_lockname);
|
||||
dm_hash_destroy(_lock_hash);
|
||||
_lock_hash = NULL;
|
||||
}
|
||||
|
||||
|
||||
23
lib/cache/lvmcache.h
vendored
23
lib/cache/lvmcache.h
vendored
@@ -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,26 +69,36 @@ 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);
|
||||
|
||||
/* Returns list of struct str_lists containing pool-allocated copy of vgnames */
|
||||
/* Set full_scan to 1 to reread every filtered device label */
|
||||
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan);
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "toolcontext.h"
|
||||
#include "pool.h"
|
||||
#include "metadata.h"
|
||||
#include "defaults.h"
|
||||
#include "lvm-string.h"
|
||||
@@ -213,7 +212,7 @@ static int _process_config(struct cmd_context *cmd)
|
||||
|
||||
static int _set_tag(struct cmd_context *cmd, const char *tag)
|
||||
{
|
||||
log_very_verbose("Setting host tag: %s", pool_strdup(cmd->libmem, tag));
|
||||
log_very_verbose("Setting host tag: %s", dm_pool_strdup(cmd->libmem, tag));
|
||||
|
||||
if (!str_list_add(cmd->libmem, &cmd->tags, tag)) {
|
||||
log_error("_set_tag: str_list_add %s failed", tag);
|
||||
@@ -323,7 +322,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cfl = pool_alloc(cmd->libmem, sizeof(*cfl)))) {
|
||||
if (!(cfl = dm_pool_alloc(cmd->libmem, sizeof(*cfl)))) {
|
||||
log_error("config_tree_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -658,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;
|
||||
}
|
||||
@@ -754,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;
|
||||
}
|
||||
@@ -800,13 +799,13 @@ static int _init_hostname(struct cmd_context *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cmd->hostname = pool_strdup(cmd->libmem, uts.nodename))) {
|
||||
log_error("_init_hostname: pool_strdup failed");
|
||||
if (!(cmd->hostname = dm_pool_strdup(cmd->libmem, uts.nodename))) {
|
||||
log_error("_init_hostname: dm_pool_strdup failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cmd->kernel_vsn = pool_strdup(cmd->libmem, uts.release))) {
|
||||
log_error("_init_hostname: pool_strdup kernel_vsn failed");
|
||||
if (!(cmd->kernel_vsn = dm_pool_strdup(cmd->libmem, uts.release))) {
|
||||
log_error("_init_hostname: dm_pool_strdup kernel_vsn failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -894,7 +893,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
|
||||
init_syslog(DEFAULT_LOG_FACILITY);
|
||||
|
||||
if (!(cmd = dbg_malloc(sizeof(*cmd)))) {
|
||||
if (!(cmd = dm_malloc(sizeof(*cmd)))) {
|
||||
log_error("Failed to allocate command context");
|
||||
return NULL;
|
||||
}
|
||||
@@ -920,7 +919,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(cmd->libmem = pool_create("library", 4 * 1024))) {
|
||||
if (!(cmd->libmem = dm_pool_create("library", 4 * 1024))) {
|
||||
log_error("Library memory pool creation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -951,7 +950,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
if (!_init_filters(cmd))
|
||||
goto error;
|
||||
|
||||
if (!(cmd->mem = pool_create("command", 4 * 1024))) {
|
||||
if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
|
||||
log_error("Command memory pool creation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -973,7 +972,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
return cmd;
|
||||
|
||||
error:
|
||||
dbg_free(cmd);
|
||||
dm_free(cmd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1079,21 +1078,20 @@ void destroy_toolcontext(struct cmd_context *cmd)
|
||||
|
||||
archive_exit(cmd);
|
||||
backup_exit(cmd);
|
||||
activation_exit();
|
||||
lvmcache_destroy();
|
||||
label_exit();
|
||||
_destroy_segtypes(&cmd->segtypes);
|
||||
_destroy_formats(&cmd->formats);
|
||||
cmd->filter->destroy(cmd->filter);
|
||||
pool_destroy(cmd->mem);
|
||||
dm_pool_destroy(cmd->mem);
|
||||
dev_cache_exit();
|
||||
_destroy_tags(cmd);
|
||||
_destroy_tag_configs(cmd);
|
||||
pool_destroy(cmd->libmem);
|
||||
dbg_free(cmd);
|
||||
dm_pool_destroy(cmd->libmem);
|
||||
dm_free(cmd);
|
||||
|
||||
release_log_memory();
|
||||
dump_memory();
|
||||
activation_exit();
|
||||
fin_log();
|
||||
fin_syslog();
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#define _LVM_TOOLCONTEXT_H
|
||||
|
||||
#include "dev-cache.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
@@ -50,8 +49,8 @@ struct backup_params;
|
||||
/* FIXME Split into tool & library contexts */
|
||||
/* command-instance-related variables needed by library */
|
||||
struct cmd_context {
|
||||
struct pool *libmem; /* For permanent config data */
|
||||
struct pool *mem; /* Transient: Cleared between each command */
|
||||
struct dm_pool *libmem; /* For permanent config data */
|
||||
struct dm_pool *mem; /* Transient: Cleared between each command */
|
||||
|
||||
const struct format_type *fmt; /* Current format to use by default */
|
||||
struct format_type *fmt_backup; /* Format to use for backups */
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "lib.h"
|
||||
#include "config.h"
|
||||
#include "crc.h"
|
||||
#include "pool.h"
|
||||
#include "device.h"
|
||||
#include "str_list.h"
|
||||
#include "toolcontext.h"
|
||||
@@ -50,12 +49,12 @@ struct parser {
|
||||
int fd; /* descriptor for file being parsed */
|
||||
int line; /* line number we are on */
|
||||
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
};
|
||||
|
||||
struct cs {
|
||||
struct config_tree cft;
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
time_t timestamp;
|
||||
char *filename;
|
||||
int exists;
|
||||
@@ -99,16 +98,16 @@ static int _tok_match(const char *str, const char *b, const char *e)
|
||||
struct config_tree *create_config_tree(const char *filename)
|
||||
{
|
||||
struct cs *c;
|
||||
struct pool *mem = pool_create("config", 10 * 1024);
|
||||
struct dm_pool *mem = dm_pool_create("config", 10 * 1024);
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(c = pool_zalloc(mem, sizeof(*c)))) {
|
||||
if (!(c = dm_pool_zalloc(mem, sizeof(*c)))) {
|
||||
stack;
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -117,13 +116,13 @@ struct config_tree *create_config_tree(const char *filename)
|
||||
c->timestamp = 0;
|
||||
c->exists = 0;
|
||||
if (filename)
|
||||
c->filename = pool_strdup(c->mem, filename);
|
||||
c->filename = dm_pool_strdup(c->mem, filename);
|
||||
return &c->cft;
|
||||
}
|
||||
|
||||
void destroy_config_tree(struct config_tree *cft)
|
||||
{
|
||||
pool_destroy(((struct cs *) cft)->mem);
|
||||
dm_pool_destroy(((struct cs *) cft)->mem);
|
||||
}
|
||||
|
||||
int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
@@ -136,7 +135,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
int use_mmap = 1;
|
||||
off_t mmap_offset = 0;
|
||||
|
||||
if (!(p = pool_alloc(c->mem, sizeof(*p)))) {
|
||||
if (!(p = dm_pool_alloc(c->mem, sizeof(*p)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -157,7 +156,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
}
|
||||
p->fb = p->fb + mmap_offset;
|
||||
} else {
|
||||
if (!(p->fb = dbg_malloc(size + size2))) {
|
||||
if (!(p->fb = dm_malloc(size + size2))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -197,7 +196,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
|
||||
out:
|
||||
if (!use_mmap)
|
||||
dbg_free(p->fb);
|
||||
dm_free(p->fb);
|
||||
else {
|
||||
/* unmap the file */
|
||||
if (munmap((char *) (p->fb - mmap_offset), size + mmap_offset)) {
|
||||
@@ -688,14 +687,14 @@ static void _eat_space(struct parser *p)
|
||||
*/
|
||||
static struct config_value *_create_value(struct parser *p)
|
||||
{
|
||||
struct config_value *v = pool_alloc(p->mem, sizeof(*v));
|
||||
struct config_value *v = dm_pool_alloc(p->mem, sizeof(*v));
|
||||
memset(v, 0, sizeof(*v));
|
||||
return v;
|
||||
}
|
||||
|
||||
static struct config_node *_create_node(struct parser *p)
|
||||
{
|
||||
struct config_node *n = pool_alloc(p->mem, sizeof(*n));
|
||||
struct config_node *n = dm_pool_alloc(p->mem, sizeof(*n));
|
||||
memset(n, 0, sizeof(*n));
|
||||
return n;
|
||||
}
|
||||
@@ -703,7 +702,7 @@ static struct config_node *_create_node(struct parser *p)
|
||||
static char *_dup_tok(struct parser *p)
|
||||
{
|
||||
size_t len = p->te - p->tb;
|
||||
char *str = pool_alloc(p->mem, len + 1);
|
||||
char *str = dm_pool_alloc(p->mem, len + 1);
|
||||
if (!str) {
|
||||
stack;
|
||||
return 0;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#ifndef _LVM_CONFIG_H
|
||||
#define _LVM_CONFIG_H
|
||||
|
||||
#include "lvm-types.h"
|
||||
|
||||
struct device;
|
||||
struct cmd_context;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -24,13 +24,13 @@ struct node {
|
||||
};
|
||||
|
||||
struct btree {
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
struct node *root;
|
||||
};
|
||||
|
||||
struct btree *btree_create(struct pool *mem)
|
||||
struct btree *btree_create(struct dm_pool *mem)
|
||||
{
|
||||
struct btree *t = pool_alloc(mem, sizeof(*t));
|
||||
struct btree *t = dm_pool_alloc(mem, sizeof(*t));
|
||||
|
||||
if (t) {
|
||||
t->mem = mem;
|
||||
@@ -86,7 +86,7 @@ int btree_insert(struct btree *t, uint32_t k, void *data)
|
||||
struct node *p, **c = _lookup(&t->root, key, &p), *n;
|
||||
|
||||
if (!*c) {
|
||||
if (!(n = pool_alloc(t->mem, sizeof(*n)))) {
|
||||
if (!(n = dm_pool_alloc(t->mem, sizeof(*n)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -16,11 +16,9 @@
|
||||
#ifndef _LVM_BTREE_H
|
||||
#define _LVM_BTREE_H
|
||||
|
||||
#include "pool.h"
|
||||
|
||||
struct btree;
|
||||
|
||||
struct btree *btree_create(struct pool *mem);
|
||||
struct btree *btree_create(struct dm_pool *mem);
|
||||
|
||||
void *btree_lookup(struct btree *t, uint32_t k);
|
||||
int btree_insert(struct btree *t, uint32_t k, void *data);
|
||||
|
||||
@@ -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'
|
||||
@@ -202,6 +156,26 @@ static inline struct list *list_next(struct list *head, struct list *elem)
|
||||
*/
|
||||
#define list_iterate_items(v, head) list_iterate_items_gen(v, (head), list)
|
||||
|
||||
/*
|
||||
* Walk a list, setting 'v' in turn to the containing structure of each item.
|
||||
* The containing structure should be the same type as 'v'.
|
||||
* The 'struct list' variable within the containing structure is 'field'.
|
||||
* t must be defined as a temporary variable of the same type as v.
|
||||
*/
|
||||
#define list_iterate_items_gen_safe(v, t, head, field) \
|
||||
for (v = list_struct_base((head)->n, typeof(*v), field), \
|
||||
t = list_struct_base(v->field.n, typeof(*v), field); \
|
||||
&v->field != (head); \
|
||||
v = t, t = list_struct_base(v->field.n, typeof(*v), field))
|
||||
/*
|
||||
* Walk a list, setting 'v' in turn to the containing structure of each item.
|
||||
* The containing structure should be the same type as 'v'.
|
||||
* The list should be 'struct list list' within the containing structure.
|
||||
* t must be defined as a temporary variable of the same type as v.
|
||||
*/
|
||||
#define list_iterate_items_safe(v, t, head) \
|
||||
list_iterate_items_gen_safe(v, t, (head), list)
|
||||
|
||||
/*
|
||||
* Walk a list backwards, setting 'v' in turn to the containing structure
|
||||
* of each item.
|
||||
@@ -224,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
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#include "lib.h"
|
||||
#include "str_list.h"
|
||||
|
||||
struct list *str_list_create(struct pool *mem)
|
||||
struct list *str_list_create(struct dm_pool *mem)
|
||||
{
|
||||
struct list *sl;
|
||||
|
||||
if (!(sl = pool_alloc(mem, sizeof(struct list)))) {
|
||||
if (!(sl = dm_pool_alloc(mem, sizeof(struct list)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ struct list *str_list_create(struct pool *mem)
|
||||
return sl;
|
||||
}
|
||||
|
||||
int str_list_add(struct pool *mem, struct list *sll, const char *str)
|
||||
int str_list_add(struct dm_pool *mem, struct list *sll, const char *str)
|
||||
{
|
||||
struct str_list *sln;
|
||||
|
||||
@@ -43,7 +43,7 @@ int str_list_add(struct pool *mem, struct list *sll, const char *str)
|
||||
if (str_list_match_item(sll, str))
|
||||
return 1;
|
||||
|
||||
if (!(sln = pool_alloc(mem, sizeof(*sln)))) {
|
||||
if (!(sln = dm_pool_alloc(mem, sizeof(*sln)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ int str_list_del(struct list *sll, const char *str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int str_list_dup(struct pool *mem, struct list *sllnew, struct list *sllold)
|
||||
int str_list_dup(struct dm_pool *mem, struct list *sllnew, struct list *sllold)
|
||||
{
|
||||
struct str_list *sl;
|
||||
|
||||
|
||||
@@ -16,14 +16,12 @@
|
||||
#ifndef _LVM_STR_LIST_H
|
||||
#define _LVM_STR_LIST_H
|
||||
|
||||
#include "pool.h"
|
||||
|
||||
struct list *str_list_create(struct pool *mem);
|
||||
int str_list_add(struct pool *mem, struct list *sll, const char *str);
|
||||
struct list *str_list_create(struct dm_pool *mem);
|
||||
int str_list_add(struct dm_pool *mem, struct list *sll, const char *str);
|
||||
int str_list_del(struct list *sll, const char *str);
|
||||
int str_list_match_item(struct list *sll, const char *str);
|
||||
int str_list_match_list(struct list *sll, struct list *sll2);
|
||||
int str_list_lists_equal(struct list *sll, struct list *sll2);
|
||||
int str_list_dup(struct pool *mem, struct list *sllnew, struct list *sllold);
|
||||
int str_list_dup(struct dm_pool *mem, struct list *sllnew, struct list *sllold);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "dev-cache.h"
|
||||
#include "pool.h"
|
||||
#include "hash.h"
|
||||
#include "list.h"
|
||||
#include "lvm-types.h"
|
||||
#include "btree.h"
|
||||
#include "filter.h"
|
||||
@@ -38,8 +35,8 @@ struct dir_list {
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct pool *mem;
|
||||
struct hash_table *names;
|
||||
struct dm_pool *mem;
|
||||
struct dm_hash_table *names;
|
||||
struct btree *devices;
|
||||
|
||||
int has_scanned;
|
||||
@@ -48,9 +45,9 @@ static struct {
|
||||
|
||||
} _cache;
|
||||
|
||||
#define _alloc(x) pool_zalloc(_cache.mem, (x))
|
||||
#define _free(x) pool_free(_cache.mem, (x))
|
||||
#define _strdup(x) pool_strdup(_cache.mem, (x))
|
||||
#define _alloc(x) dm_pool_zalloc(_cache.mem, (x))
|
||||
#define _free(x) dm_pool_free(_cache.mem, (x))
|
||||
#define _strdup(x) dm_pool_strdup(_cache.mem, (x))
|
||||
|
||||
static int _insert(const char *path, int rec);
|
||||
|
||||
@@ -61,19 +58,19 @@ struct device *dev_create_file(const char *filename, struct device *dev,
|
||||
|
||||
if (allocate) {
|
||||
if (use_malloc) {
|
||||
if (!(dev = dbg_malloc(sizeof(*dev)))) {
|
||||
if (!(dev = dm_malloc(sizeof(*dev)))) {
|
||||
log_error("struct device allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
if (!(alias = dbg_malloc(sizeof(*alias)))) {
|
||||
if (!(alias = dm_malloc(sizeof(*alias)))) {
|
||||
log_error("struct str_list allocation failed");
|
||||
dbg_free(dev);
|
||||
dm_free(dev);
|
||||
return NULL;
|
||||
}
|
||||
if (!(alias->str = dbg_strdup(filename))) {
|
||||
if (!(alias->str = dm_strdup(filename))) {
|
||||
log_error("filename strdup failed");
|
||||
dbg_free(dev);
|
||||
dbg_free(alias);
|
||||
dm_free(dev);
|
||||
dm_free(alias);
|
||||
return NULL;
|
||||
}
|
||||
dev->flags = DEV_ALLOCED;
|
||||
@@ -92,7 +89,7 @@ struct device *dev_create_file(const char *filename, struct device *dev,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else if (!(alias->str = dbg_strdup(filename))) {
|
||||
} else if (!(alias->str = dm_strdup(filename))) {
|
||||
log_error("filename strdup failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -213,7 +210,7 @@ static int _add_alias(struct device *dev, const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
if (!(sl->str = pool_strdup(_cache.mem, path))) {
|
||||
if (!(sl->str = dm_pool_strdup(_cache.mem, path))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -247,7 +244,7 @@ static int _insert_dev(const char *path, dev_t d)
|
||||
|
||||
/* Generate pretend device numbers for loopfiles */
|
||||
if (!d) {
|
||||
if (hash_lookup(_cache.names, path))
|
||||
if (dm_hash_lookup(_cache.names, path))
|
||||
return 1;
|
||||
d = ++loopfile_count;
|
||||
loopfile = 1;
|
||||
@@ -279,7 +276,7 @@ static int _insert_dev(const char *path, dev_t d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hash_insert(_cache.names, path, dev)) {
|
||||
if (!dm_hash_insert(_cache.names, path, dev)) {
|
||||
log_err("Couldn't add name to hash in dev cache.");
|
||||
return 0;
|
||||
}
|
||||
@@ -290,7 +287,7 @@ static int _insert_dev(const char *path, dev_t d)
|
||||
static char *_join(const char *dir, const char *name)
|
||||
{
|
||||
size_t len = strlen(dir) + strlen(name) + 2;
|
||||
char *r = dbg_malloc(len);
|
||||
char *r = dm_malloc(len);
|
||||
if (r)
|
||||
snprintf(r, len, "%s/%s", dir, name);
|
||||
|
||||
@@ -340,7 +337,7 @@ static int _insert_dir(const char *dir)
|
||||
|
||||
_collapse_slashes(path);
|
||||
r &= _insert(path, 1);
|
||||
dbg_free(path);
|
||||
dm_free(path);
|
||||
|
||||
free(dirent[n]);
|
||||
}
|
||||
@@ -449,14 +446,14 @@ int dev_cache_init(void)
|
||||
_cache.names = NULL;
|
||||
_cache.has_scanned = 0;
|
||||
|
||||
if (!(_cache.mem = pool_create("dev_cache", 10 * 1024))) {
|
||||
if (!(_cache.mem = dm_pool_create("dev_cache", 10 * 1024))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(_cache.names = hash_create(128))) {
|
||||
if (!(_cache.names = dm_hash_create(128))) {
|
||||
stack;
|
||||
pool_destroy(_cache.mem);
|
||||
dm_pool_destroy(_cache.mem);
|
||||
_cache.mem = 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -482,9 +479,9 @@ 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)
|
||||
{
|
||||
hash_iter(_cache.names, (iterate_fn) _check_closed);
|
||||
dm_hash_iter(_cache.names, (dm_hash_iterate_fn) _check_closed);
|
||||
}
|
||||
|
||||
void dev_cache_exit(void)
|
||||
@@ -493,12 +490,12 @@ void dev_cache_exit(void)
|
||||
_check_for_open_devices();
|
||||
|
||||
if (_cache.mem) {
|
||||
pool_destroy(_cache.mem);
|
||||
dm_pool_destroy(_cache.mem);
|
||||
_cache.mem = NULL;
|
||||
}
|
||||
|
||||
if (_cache.names) {
|
||||
hash_destroy(_cache.names);
|
||||
dm_hash_destroy(_cache.names);
|
||||
_cache.names = NULL;
|
||||
}
|
||||
|
||||
@@ -592,7 +589,7 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
|
||||
(int) MINOR(dev->dev));
|
||||
|
||||
/* Remove the incorrect hash entry */
|
||||
hash_remove(_cache.names, name);
|
||||
dm_hash_remove(_cache.names, name);
|
||||
|
||||
/* Leave list alone if there isn't an alternative name */
|
||||
/* so dev_name will always find something to return. */
|
||||
@@ -615,23 +612,23 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
|
||||
struct device *dev_cache_get(const char *name, struct dev_filter *f)
|
||||
{
|
||||
struct stat buf;
|
||||
struct device *d = (struct device *) hash_lookup(_cache.names, name);
|
||||
struct device *d = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||
|
||||
if (d && (d->flags & DEV_REGULAR))
|
||||
return d;
|
||||
|
||||
/* If the entry's wrong, remove it */
|
||||
if (d && (stat(name, &buf) || (buf.st_rdev != d->dev))) {
|
||||
hash_remove(_cache.names, name);
|
||||
dm_hash_remove(_cache.names, name);
|
||||
d = NULL;
|
||||
}
|
||||
|
||||
if (!d) {
|
||||
_insert(name, 0);
|
||||
d = (struct device *) hash_lookup(_cache.names, name);
|
||||
d = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||
if (!d) {
|
||||
_full_scan(0);
|
||||
d = (struct device *) hash_lookup(_cache.names, name);
|
||||
d = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -641,7 +638,7 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
|
||||
|
||||
struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
|
||||
{
|
||||
struct dev_iter *di = dbg_malloc(sizeof(*di));
|
||||
struct dev_iter *di = dm_malloc(sizeof(*di));
|
||||
|
||||
if (!di) {
|
||||
log_error("dev_iter allocation failed");
|
||||
@@ -664,10 +661,10 @@ struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
|
||||
|
||||
void dev_iter_destroy(struct dev_iter *iter)
|
||||
{
|
||||
dbg_free(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);
|
||||
@@ -685,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";
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#ifndef _LVM_DEV_CACHE_H
|
||||
#define _LVM_DEV_CACHE_H
|
||||
|
||||
#include "lvm-types.h"
|
||||
#include "device.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -320,15 +320,22 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
{
|
||||
struct stat buf;
|
||||
const char *name;
|
||||
int need_excl = 0, need_rw = 0;
|
||||
|
||||
if ((flags & O_ACCMODE) == O_RDWR)
|
||||
need_rw = 1;
|
||||
|
||||
if ((flags & O_EXCL))
|
||||
need_excl = 1;
|
||||
|
||||
if (dev->fd >= 0) {
|
||||
if ((dev->flags & DEV_OPENED_RW) ||
|
||||
((flags & O_ACCMODE) != O_RDWR)) {
|
||||
if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
|
||||
((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
|
||||
dev->open_count++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dev->open_count) {
|
||||
if (dev->open_count && !need_excl) {
|
||||
/* FIXME Ensure we never get here */
|
||||
log_debug("WARNING: %s already opened read-only",
|
||||
dev_name(dev));
|
||||
@@ -397,16 +404,20 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
dev->open_count++;
|
||||
dev->flags &= ~DEV_ACCESSED_W;
|
||||
|
||||
if ((flags & O_ACCMODE) == O_RDWR)
|
||||
if (need_rw)
|
||||
dev->flags |= DEV_OPENED_RW;
|
||||
else
|
||||
dev->flags &= ~DEV_OPENED_RW;
|
||||
|
||||
if (need_excl)
|
||||
dev->flags |= DEV_OPENED_EXCL;
|
||||
else
|
||||
dev->flags &= ~DEV_OPENED_EXCL;
|
||||
|
||||
if (!(dev->flags & DEV_REGULAR) &&
|
||||
((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
|
||||
log_error("%s: fstat failed: Has device name changed?", name);
|
||||
dev_close_immediate(dev);
|
||||
dev->open_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -420,8 +431,9 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
|
||||
list_add(&_open_devices, &dev->open_list);
|
||||
|
||||
log_debug("Opened %s %s%s", dev_name(dev),
|
||||
log_debug("Opened %s %s%s%s", dev_name(dev),
|
||||
dev->flags & DEV_OPENED_RW ? "RW" : "RO",
|
||||
dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
|
||||
dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
|
||||
|
||||
return 1;
|
||||
@@ -445,6 +457,21 @@ int dev_open(struct device *dev)
|
||||
return dev_open_flags(dev, flags, 1, 0);
|
||||
}
|
||||
|
||||
int dev_test_excl(struct device *dev)
|
||||
{
|
||||
int flags;
|
||||
int r;
|
||||
|
||||
flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
|
||||
flags |= O_EXCL;
|
||||
|
||||
r = dev_open_flags(dev, flags, 1, 1);
|
||||
if (r)
|
||||
dev_close_immediate(dev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void _close(struct device *dev)
|
||||
{
|
||||
if (close(dev->fd))
|
||||
@@ -456,15 +483,17 @@ static void _close(struct device *dev)
|
||||
log_debug("Closed %s", dev_name(dev));
|
||||
|
||||
if (dev->flags & DEV_ALLOCED) {
|
||||
dbg_free((void *) list_item(dev->aliases.n, struct str_list)->
|
||||
dm_free((void *) list_item(dev->aliases.n, struct str_list)->
|
||||
str);
|
||||
dbg_free(dev->aliases.n);
|
||||
dbg_free(dev);
|
||||
dm_free(dev->aliases.n);
|
||||
dm_free(dev);
|
||||
}
|
||||
}
|
||||
|
||||
static int _dev_close(struct device *dev, int immediate)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
|
||||
if (dev->fd < 0) {
|
||||
log_error("Attempt to close device '%s' "
|
||||
"which is not open.", dev_name(dev));
|
||||
@@ -479,8 +508,16 @@ static int _dev_close(struct device *dev, int immediate)
|
||||
if (dev->open_count > 0)
|
||||
dev->open_count--;
|
||||
|
||||
/* FIXME lookup device in cache to get vgname and see if it's locked? */
|
||||
if (immediate || (dev->open_count < 1 && !vgs_locked()))
|
||||
if (immediate && dev->open_count)
|
||||
log_debug("%s: Immediate close attempt while still referenced",
|
||||
dev_name(dev));
|
||||
|
||||
/* Close unless device is known to belong to a locked VG */
|
||||
if (immediate ||
|
||||
(dev->open_count < 1 &&
|
||||
(!(info = info_from_pvid(dev->pvid)) ||
|
||||
!info->vginfo ||
|
||||
!vgname_is_locked(info->vginfo->vgname))))
|
||||
_close(dev);
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -202,7 +202,7 @@ int _get_partition_type(struct dev_mgr *dm, struct device *d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(buffer = dbg_malloc(SECTOR_SIZE))) {
|
||||
if (!(buffer = dm_malloc(SECTOR_SIZE))) {
|
||||
log_error("Failed to allocate partition table buffer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -17,14 +17,16 @@
|
||||
#define _LVM_DEVICE_H
|
||||
|
||||
#include "uuid.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#define DEV_ACCESSED_W 0x00000001 /* Device written to? */
|
||||
#define DEV_REGULAR 0x00000002 /* Regular file? */
|
||||
#define DEV_ALLOCED 0x00000004 /* dbg_malloc used */
|
||||
#define DEV_ALLOCED 0x00000004 /* dm_malloc used */
|
||||
#define DEV_OPENED_RW 0x00000008 /* Opened RW */
|
||||
#define DEV_O_DIRECT 0x00000010 /* Use O_DIRECT */
|
||||
#define DEV_O_DIRECT_TESTED 0x00000020 /* DEV_O_DIRECT is reliable */
|
||||
#define DEV_OPENED_EXCL 0x00000010 /* Opened EXCL */
|
||||
#define DEV_O_DIRECT 0x00000020 /* Use O_DIRECT */
|
||||
#define DEV_O_DIRECT_TESTED 0x00000040 /* DEV_O_DIRECT is reliable */
|
||||
|
||||
/*
|
||||
* All devices in LVM will be represented by one of these.
|
||||
@@ -70,11 +72,10 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet);
|
||||
int dev_close(struct device *dev);
|
||||
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);
|
||||
@@ -85,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);
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl)
|
||||
{" ", " ", " "},
|
||||
};
|
||||
|
||||
if (!(size_buf = pool_alloc(cmd->mem, SIZE_BUF))) {
|
||||
if (!(size_buf = dm_pool_alloc(cmd->mem, SIZE_BUF))) {
|
||||
log_error("no memory for size display buffer");
|
||||
return "";
|
||||
}
|
||||
@@ -317,7 +317,7 @@ void lvdisplay_colons(struct logical_volume *lv)
|
||||
{
|
||||
int inkernel;
|
||||
struct lvinfo info;
|
||||
inkernel = lv_info(lv, &info, 1) && info.exists;
|
||||
inkernel = lv_info(lv->vg->cmd, lv, &info, 1) && info.exists;
|
||||
|
||||
log_print("%s%s/%s:%s:%d:%d:-1:%d:%" PRIu64 ":%d:-1:%d:%d:%d:%d",
|
||||
lv->vg->cmd->dev_dir,
|
||||
@@ -347,7 +347,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
inkernel = lv_info(lv, &info, 1) && info.exists;
|
||||
inkernel = lv_info(cmd, lv, &info, 1) && info.exists;
|
||||
|
||||
log_print("--- Logical volume ---");
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "list.h"
|
||||
#include "toolcontext.h"
|
||||
#include "segtype.h"
|
||||
#include "display.h"
|
||||
@@ -26,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;
|
||||
@@ -40,62 +38,57 @@ static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
|
||||
}
|
||||
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
static int _compose_target_line(struct dev_manager *dm, struct 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, char *params,
|
||||
size_t paramsize, const char **target, int *pos,
|
||||
struct lv_segment *seg,
|
||||
struct dm_tree_node *node, uint64_t len,
|
||||
uint32_t *pvmove_mirror_count)
|
||||
{
|
||||
/* error */
|
||||
|
||||
*target = "error";
|
||||
*params = '\0';
|
||||
|
||||
return 1;
|
||||
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;
|
||||
|
||||
if (!checked)
|
||||
present = target_present("error");
|
||||
/* Reported truncated in older kernels */
|
||||
if (!_errseg_checked &&
|
||||
(target_present("error", 0) || target_present("erro", 0)))
|
||||
_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)
|
||||
{
|
||||
dbg_free((void *) 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
|
||||
compose_target_line:_compose_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)
|
||||
{
|
||||
struct segment_type *segtype = dbg_malloc(sizeof(*segtype));
|
||||
struct segment_type *segtype = dm_malloc(sizeof(*segtype));
|
||||
|
||||
if (!segtype) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!segtype)
|
||||
return_NULL;
|
||||
|
||||
segtype->cmd = cmd;
|
||||
segtype->ops = &_error_ops;
|
||||
segtype->name = "error";
|
||||
segtype->private = NULL;
|
||||
segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL;
|
||||
segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
|
||||
|
||||
log_very_verbose("Initialised segtype: %s", segtype->name);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -42,8 +42,8 @@ static void _destroy(struct dev_filter *f)
|
||||
filters++;
|
||||
}
|
||||
|
||||
dbg_free(f->private);
|
||||
dbg_free(f);
|
||||
dm_free(f->private);
|
||||
dm_free(f);
|
||||
}
|
||||
|
||||
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
|
||||
@@ -55,7 +55,7 @@ struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(filters_copy = dbg_malloc(sizeof(*filters) * (n + 1)))) {
|
||||
if (!(filters_copy = dm_malloc(sizeof(*filters) * (n + 1)))) {
|
||||
log_error("composite filters allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -63,14 +63,14 @@ struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
|
||||
memcpy(filters_copy, filters, sizeof(*filters) * n);
|
||||
filters_copy[n] = NULL;
|
||||
|
||||
if (!(cft = dbg_malloc(sizeof(*cft)))) {
|
||||
if (!(cft = dm_malloc(sizeof(*cft)))) {
|
||||
log_error("compsoite filters allocation failed");
|
||||
dbg_free(filters_copy);
|
||||
dm_free(filters_copy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cft->passes_filter = _and_p;
|
||||
cft->destroy = _destroy;
|
||||
cft->destroy = _composite_destroy;
|
||||
cft->private = filters_copy;
|
||||
|
||||
return cft;
|
||||
|
||||
@@ -51,14 +51,14 @@ static int _ignore_md(struct dev_filter *f, struct device *dev)
|
||||
|
||||
static void _destroy(struct dev_filter *f)
|
||||
{
|
||||
dbg_free(f);
|
||||
dm_free(f);
|
||||
}
|
||||
|
||||
struct dev_filter *md_filter_create(void)
|
||||
{
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(*f)))) {
|
||||
if (!(f = dm_malloc(sizeof(*f)))) {
|
||||
log_error("md filter allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "lib.h"
|
||||
#include "config.h"
|
||||
#include "dev-cache.h"
|
||||
#include "hash.h"
|
||||
#include "filter-persistent.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -25,7 +24,7 @@
|
||||
|
||||
struct pfilter {
|
||||
char *file;
|
||||
struct hash_table *devices;
|
||||
struct dm_hash_table *devices;
|
||||
struct dev_filter *real;
|
||||
};
|
||||
|
||||
@@ -39,9 +38,9 @@ struct pfilter {
|
||||
static int _init_hash(struct pfilter *pf)
|
||||
{
|
||||
if (pf->devices)
|
||||
hash_destroy(pf->devices);
|
||||
dm_hash_destroy(pf->devices);
|
||||
|
||||
if (!(pf->devices = hash_create(128))) {
|
||||
if (!(pf->devices = dm_hash_create(128))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -54,7 +53,7 @@ int persistent_filter_wipe(struct dev_filter *f)
|
||||
struct pfilter *pf = (struct pfilter *) f->private;
|
||||
|
||||
log_verbose("Wiping cache of LVM-capable devices");
|
||||
hash_wipe(pf->devices);
|
||||
dm_hash_wipe(pf->devices);
|
||||
|
||||
/* Trigger complete device scan */
|
||||
dev_cache_scan(1);
|
||||
@@ -85,7 +84,7 @@ static int _read_array(struct pfilter *pf, struct config_tree *cft,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hash_insert(pf->devices, cv->v.str, data))
|
||||
if (!dm_hash_insert(pf->devices, cv->v.str, data))
|
||||
log_verbose("Couldn't add '%s' to filter ... ignoring",
|
||||
cv->v.str);
|
||||
/* Populate dev_cache ourselves */
|
||||
@@ -118,7 +117,7 @@ int persistent_filter_load(struct dev_filter *f)
|
||||
PF_BAD_DEVICE); */
|
||||
|
||||
/* Did we find anything? */
|
||||
if (hash_get_num_entries(pf->devices)) {
|
||||
if (dm_hash_get_num_entries(pf->devices)) {
|
||||
/* We populated dev_cache ourselves */
|
||||
dev_cache_scan(0);
|
||||
r = 1;
|
||||
@@ -136,11 +135,11 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
|
||||
{
|
||||
void *d;
|
||||
int first = 1;
|
||||
struct hash_node *n;
|
||||
struct dm_hash_node *n;
|
||||
|
||||
for (n = hash_get_first(pf->devices); n;
|
||||
n = hash_get_next(pf->devices, n)) {
|
||||
d = hash_get_data(pf->devices, n);
|
||||
for (n = dm_hash_get_first(pf->devices); n;
|
||||
n = dm_hash_get_next(pf->devices, n)) {
|
||||
d = dm_hash_get_data(pf->devices, n);
|
||||
|
||||
if (d != data)
|
||||
continue;
|
||||
@@ -152,7 +151,7 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
|
||||
first = 0;
|
||||
}
|
||||
|
||||
fprintf(fp, "\t\t\"%s\"", hash_get_key(pf->devices, n));
|
||||
fprintf(fp, "\t\t\"%s\"", dm_hash_get_key(pf->devices, n));
|
||||
}
|
||||
|
||||
if (!first)
|
||||
@@ -167,7 +166,7 @@ int persistent_filter_dump(struct dev_filter *f)
|
||||
|
||||
FILE *fp;
|
||||
|
||||
if (!hash_get_num_entries(pf->devices)) {
|
||||
if (!dm_hash_get_num_entries(pf->devices)) {
|
||||
log_very_verbose("Internal persistent device cache empty "
|
||||
"- not writing to %s", pf->file);
|
||||
return 0;
|
||||
@@ -202,7 +201,7 @@ int persistent_filter_dump(struct dev_filter *f)
|
||||
static int _lookup_p(struct dev_filter *f, struct device *dev)
|
||||
{
|
||||
struct pfilter *pf = (struct pfilter *) f->private;
|
||||
void *l = hash_lookup(pf->devices, dev_name(dev));
|
||||
void *l = dm_hash_lookup(pf->devices, dev_name(dev));
|
||||
struct str_list *sl;
|
||||
|
||||
if (!l) {
|
||||
@@ -210,7 +209,7 @@ static int _lookup_p(struct dev_filter *f, struct device *dev)
|
||||
PF_GOOD_DEVICE : PF_BAD_DEVICE;
|
||||
|
||||
list_iterate_items(sl, &dev->aliases)
|
||||
hash_insert(pf->devices, sl->str, l);
|
||||
dm_hash_insert(pf->devices, sl->str, l);
|
||||
|
||||
} else if (l == PF_BAD_DEVICE)
|
||||
log_debug("%s: Skipping (cached)", dev_name(dev));
|
||||
@@ -218,15 +217,15 @@ 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;
|
||||
|
||||
hash_destroy(pf->devices);
|
||||
dbg_free(pf->file);
|
||||
dm_hash_destroy(pf->devices);
|
||||
dm_free(pf->file);
|
||||
pf->real->destroy(pf->real);
|
||||
dbg_free(pf);
|
||||
dbg_free(f);
|
||||
dm_free(pf);
|
||||
dm_free(f);
|
||||
}
|
||||
|
||||
struct dev_filter *persistent_filter_create(struct dev_filter *real,
|
||||
@@ -235,13 +234,13 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
|
||||
struct pfilter *pf;
|
||||
struct dev_filter *f = NULL;
|
||||
|
||||
if (!(pf = dbg_malloc(sizeof(*pf)))) {
|
||||
if (!(pf = dm_malloc(sizeof(*pf)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
memset(pf, 0, sizeof(*pf));
|
||||
|
||||
if (!(pf->file = dbg_malloc(strlen(file) + 1))) {
|
||||
if (!(pf->file = dm_malloc(strlen(file) + 1))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -253,22 +252,22 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(*f)))) {
|
||||
if (!(f = dm_malloc(sizeof(*f)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
f->passes_filter = _lookup_p;
|
||||
f->destroy = _destroy;
|
||||
f->destroy = _persistent_destroy;
|
||||
f->private = pf;
|
||||
|
||||
return f;
|
||||
|
||||
bad:
|
||||
dbg_free(pf->file);
|
||||
dm_free(pf->file);
|
||||
if (pf->devices)
|
||||
hash_destroy(pf->devices);
|
||||
dbg_free(pf);
|
||||
dbg_free(f);
|
||||
dm_hash_destroy(pf->devices);
|
||||
dm_free(pf);
|
||||
dm_free(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -14,21 +14,18 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "filter-regex.h"
|
||||
#include "matcher.h"
|
||||
#include "device.h"
|
||||
#include "bitset.h"
|
||||
#include "list.h"
|
||||
|
||||
struct rfilter {
|
||||
struct pool *mem;
|
||||
bitset_t accept;
|
||||
struct dm_pool *mem;
|
||||
dm_bitset_t accept;
|
||||
struct matcher *engine;
|
||||
};
|
||||
|
||||
static int _extract_pattern(struct pool *mem, const char *pat,
|
||||
char **regex, bitset_t accept, int ix)
|
||||
static int _extract_pattern(struct dm_pool *mem, const char *pat,
|
||||
char **regex, dm_bitset_t accept, int ix)
|
||||
{
|
||||
char sep, *r, *ptr;
|
||||
|
||||
@@ -37,11 +34,11 @@ static int _extract_pattern(struct pool *mem, const char *pat,
|
||||
*/
|
||||
switch (*pat) {
|
||||
case 'a':
|
||||
bit_set(accept, ix);
|
||||
dm_bit_set(accept, ix);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
bit_clear(accept, ix);
|
||||
dm_bit_clear(accept, ix);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -74,7 +71,7 @@ static int _extract_pattern(struct pool *mem, const char *pat,
|
||||
/*
|
||||
* copy the regex
|
||||
*/
|
||||
if (!(r = pool_strdup(mem, pat))) {
|
||||
if (!(r = dm_pool_strdup(mem, pat))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -95,13 +92,13 @@ static int _extract_pattern(struct pool *mem, const char *pat,
|
||||
|
||||
static int _build_matcher(struct rfilter *rf, struct config_value *val)
|
||||
{
|
||||
struct pool *scratch;
|
||||
struct dm_pool *scratch;
|
||||
struct config_value *v;
|
||||
char **regex;
|
||||
unsigned count = 0;
|
||||
int i, r = 0;
|
||||
|
||||
if (!(scratch = pool_create("filter matcher", 1024))) {
|
||||
if (!(scratch = dm_pool_create("filter matcher", 1024))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -122,7 +119,7 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
|
||||
/*
|
||||
* allocate space for them
|
||||
*/
|
||||
if (!(regex = pool_alloc(scratch, sizeof(*regex) * count))) {
|
||||
if (!(regex = dm_pool_alloc(scratch, sizeof(*regex) * count))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -130,7 +127,7 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
|
||||
/*
|
||||
* create the accept/reject bitset
|
||||
*/
|
||||
rf->accept = bitset_create(rf->mem, count);
|
||||
rf->accept = dm_bitset_create(rf->mem, count);
|
||||
|
||||
/*
|
||||
* fill the array back to front because we
|
||||
@@ -152,7 +149,7 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
pool_destroy(scratch);
|
||||
dm_pool_destroy(scratch);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -166,7 +163,7 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
|
||||
m = matcher_run(rf->engine, sl->str);
|
||||
|
||||
if (m >= 0) {
|
||||
if (bit(rf->accept, m)) {
|
||||
if (dm_bit(rf->accept, m)) {
|
||||
|
||||
if (!first) {
|
||||
log_debug("%s: New preferred name",
|
||||
@@ -194,15 +191,15 @@ 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;
|
||||
pool_destroy(rf->mem);
|
||||
dm_pool_destroy(rf->mem);
|
||||
}
|
||||
|
||||
struct dev_filter *regex_filter_create(struct config_value *patterns)
|
||||
{
|
||||
struct pool *mem = pool_create("filter regex", 10 * 1024);
|
||||
struct dm_pool *mem = dm_pool_create("filter regex", 10 * 1024);
|
||||
struct rfilter *rf;
|
||||
struct dev_filter *f;
|
||||
|
||||
@@ -211,7 +208,7 @@ struct dev_filter *regex_filter_create(struct config_value *patterns)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(rf = pool_alloc(mem, sizeof(*rf)))) {
|
||||
if (!(rf = dm_pool_alloc(mem, sizeof(*rf)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -223,17 +220,17 @@ struct dev_filter *regex_filter_create(struct config_value *patterns)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(f = pool_zalloc(mem, sizeof(*f)))) {
|
||||
if (!(f = dm_pool_zalloc(mem, sizeof(*f)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
f->passes_filter = _accept_p;
|
||||
f->destroy = _destroy;
|
||||
f->destroy = _regex_destroy;
|
||||
f->private = rf;
|
||||
return f;
|
||||
|
||||
bad:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "lib.h"
|
||||
#include "filter-sysfs.h"
|
||||
#include "lvm-string.h"
|
||||
#include "pool.h"
|
||||
|
||||
#ifdef linux
|
||||
|
||||
@@ -69,27 +68,27 @@ struct entry {
|
||||
|
||||
#define SET_BUCKETS 64
|
||||
struct dev_set {
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
const char *sys_block;
|
||||
int initialised;
|
||||
struct entry *slots[SET_BUCKETS];
|
||||
};
|
||||
|
||||
static struct dev_set *_dev_set_create(struct pool *mem, const char *sys_block)
|
||||
static struct dev_set *_dev_set_create(struct dm_pool *mem, const char *sys_block)
|
||||
{
|
||||
struct dev_set *ds;
|
||||
|
||||
if (!(ds = pool_zalloc(mem, sizeof(*ds))))
|
||||
if (!(ds = dm_pool_zalloc(mem, sizeof(*ds))))
|
||||
return NULL;
|
||||
|
||||
ds->mem = mem;
|
||||
ds->sys_block = pool_strdup(mem, sys_block);
|
||||
ds->sys_block = dm_pool_strdup(mem, sys_block);
|
||||
ds->initialised = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -102,7 +101,7 @@ static int _set_insert(struct dev_set *ds, dev_t dev)
|
||||
struct entry *e;
|
||||
unsigned h = _hash_dev(dev);
|
||||
|
||||
if (!(e = pool_alloc(ds->mem, sizeof(*e))))
|
||||
if (!(e = dm_pool_alloc(ds->mem, sizeof(*e))))
|
||||
return 0;
|
||||
|
||||
e->next = ds->slots[h];
|
||||
@@ -258,20 +257,20 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
|
||||
static void _destroy(struct dev_filter *f)
|
||||
{
|
||||
struct dev_set *ds = (struct dev_set *) f->private;
|
||||
pool_destroy(ds->mem);
|
||||
dm_pool_destroy(ds->mem);
|
||||
}
|
||||
|
||||
struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
{
|
||||
char sys_block[PATH_MAX];
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
struct dev_set *ds;
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!_locate_sysfs_blocks(proc, sys_block, sizeof(sys_block)))
|
||||
return NULL;
|
||||
|
||||
if (!(mem = pool_create("sysfs", 256))) {
|
||||
if (!(mem = dm_pool_create("sysfs", 256))) {
|
||||
log_error("sysfs pool creation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -281,7 +280,7 @@ struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(f = pool_zalloc(mem, sizeof(*f)))) {
|
||||
if (!(f = dm_pool_zalloc(mem, sizeof(*f)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -292,7 +291,7 @@ struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
return f;
|
||||
|
||||
bad:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#define NUMBER_OF_MAJORS 4096
|
||||
|
||||
/* FIXME Make this sparse */
|
||||
/* 0 means LVM won't use this major number. */
|
||||
static int _max_partitions_by_major[NUMBER_OF_MAJORS];
|
||||
|
||||
@@ -71,6 +70,9 @@ static const device_info_t device_info[] = {
|
||||
{"iseries/vd", 8}, /* iSeries disks */
|
||||
{"gnbd", 1}, /* Network block device */
|
||||
{"ramdisk", 1}, /* RAM disk */
|
||||
{"aoe", 16}, /* ATA over Ethernet */
|
||||
{"device-mapper", 1}, /* Other mapped devices */
|
||||
{"xvd", 16}, /* Xen virtual block device */
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
@@ -241,7 +243,7 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
|
||||
{
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(struct dev_filter)))) {
|
||||
if (!(f = dm_malloc(sizeof(struct dev_filter)))) {
|
||||
log_error("LVM type filter allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -260,6 +262,6 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
|
||||
|
||||
void lvm_type_filter_destroy(struct dev_filter *f)
|
||||
{
|
||||
dbg_free(f);
|
||||
dm_free(f);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
|
||||
void lvm_type_filter_destroy(struct dev_filter *f);
|
||||
|
||||
int md_major(void);
|
||||
|
||||
int max_partitions(int major);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "disk-rep.h"
|
||||
#include "pool.h"
|
||||
#include "xlate.h"
|
||||
#include "filter.h"
|
||||
#include "lvmcache.h"
|
||||
@@ -224,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);
|
||||
@@ -255,7 +254,7 @@ static int _read_uuids(struct disk_list *data)
|
||||
if (!dev_read(data->dev, pos, sizeof(buffer), buffer))
|
||||
fail;
|
||||
|
||||
if (!(ul = pool_alloc(data->mem, sizeof(*ul))))
|
||||
if (!(ul = dm_pool_alloc(data->mem, sizeof(*ul))))
|
||||
fail;
|
||||
|
||||
memcpy(ul->uuid, buffer, NAME_LEN);
|
||||
@@ -270,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');
|
||||
}
|
||||
@@ -284,7 +283,7 @@ static int _read_lvs(struct disk_list *data)
|
||||
|
||||
for (i = 0; (i < vgd->lv_max) && (read < vgd->lv_cur); i++) {
|
||||
pos = data->pvd.lv_on_disk.base + (i * sizeof(struct lv_disk));
|
||||
ll = pool_alloc(data->mem, sizeof(*ll));
|
||||
ll = dm_pool_alloc(data->mem, sizeof(*ll));
|
||||
|
||||
if (!ll)
|
||||
fail;
|
||||
@@ -305,7 +304,7 @@ static int _read_lvs(struct disk_list *data)
|
||||
static int _read_extents(struct disk_list *data)
|
||||
{
|
||||
size_t len = sizeof(struct pe_disk) * data->pvd.pe_total;
|
||||
struct pe_disk *extents = pool_alloc(data->mem, len);
|
||||
struct pe_disk *extents = dm_pool_alloc(data->mem, len);
|
||||
uint64_t pos = data->pvd.pe_on_disk.base;
|
||||
|
||||
if (!extents)
|
||||
@@ -320,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 pool *mem,
|
||||
struct device *dev, struct dm_pool *mem,
|
||||
const char *vg_name)
|
||||
{
|
||||
struct disk_list *dl = 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;
|
||||
@@ -343,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;
|
||||
@@ -400,12 +408,12 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
|
||||
return dl;
|
||||
|
||||
bad:
|
||||
pool_free(dl->mem, dl);
|
||||
dm_pool_free(dl->mem, dl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
|
||||
struct pool *mem, const char *vg_name)
|
||||
struct dm_pool *mem, const char *vg_name)
|
||||
{
|
||||
struct disk_list *r;
|
||||
|
||||
@@ -452,7 +460,7 @@ static void _add_pv_to_list(struct list *head, struct disk_list *data)
|
||||
* so we can free off all the memory if something goes wrong.
|
||||
*/
|
||||
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
struct dev_filter *filter, struct pool *mem,
|
||||
struct dev_filter *filter, struct dm_pool *mem,
|
||||
struct list *head)
|
||||
{
|
||||
struct dev_iter *iter;
|
||||
@@ -462,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;
|
||||
@@ -506,6 +514,9 @@ static int _write_vgd(struct disk_list *data)
|
||||
struct vg_disk *vgd = &data->vgd;
|
||||
uint64_t pos = data->pvd.vg_on_disk.base;
|
||||
|
||||
log_debug("Writing %s VG metadata to %s at %" PRIu64 " len %" PRIsize_t,
|
||||
data->pvd.vg_name, dev_name(data->dev), pos, sizeof(*vgd));
|
||||
|
||||
_xlate_vgd(vgd);
|
||||
if (!dev_write(data->dev, pos, sizeof(*vgd), vgd))
|
||||
fail;
|
||||
@@ -528,6 +539,10 @@ static int _write_uuids(struct disk_list *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug("Writing %s uuidlist to %s at %" PRIu64 " len %d",
|
||||
data->pvd.vg_name, dev_name(data->dev),
|
||||
pos, NAME_LEN);
|
||||
|
||||
if (!dev_write(data->dev, pos, NAME_LEN, ul->uuid))
|
||||
fail;
|
||||
|
||||
@@ -539,6 +554,10 @@ static int _write_uuids(struct disk_list *data)
|
||||
|
||||
static int _write_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
|
||||
{
|
||||
log_debug("Writing %s LV %s metadata to %s at %" PRIu64 " len %"
|
||||
PRIsize_t, disk->vg_name, disk->lv_name, dev_name(dev),
|
||||
pos, sizeof(*disk));
|
||||
|
||||
_xlate_lvd(disk);
|
||||
if (!dev_write(dev, pos, sizeof(*disk), disk))
|
||||
fail;
|
||||
@@ -581,6 +600,10 @@ static int _write_extents(struct disk_list *data)
|
||||
struct pe_disk *extents = data->extents;
|
||||
uint64_t pos = data->pvd.pe_on_disk.base;
|
||||
|
||||
log_debug("Writing %s extents metadata to %s at %" PRIu64 " len %"
|
||||
PRIsize_t, data->pvd.vg_name, dev_name(data->dev),
|
||||
pos, len);
|
||||
|
||||
_xlate_extents(extents, data->pvd.pe_total);
|
||||
if (!dev_write(data->dev, pos, len, extents))
|
||||
fail;
|
||||
@@ -604,7 +627,7 @@ static int _write_pvd(struct disk_list *data)
|
||||
/* Make sure that the gap between the PV structure and
|
||||
the next one is zeroed in order to make non LVM tools
|
||||
happy (idea from AED) */
|
||||
buf = dbg_malloc(size);
|
||||
buf = dm_malloc(size);
|
||||
if (!buf) {
|
||||
log_err("Couldn't allocate temporary PV buffer.");
|
||||
return 0;
|
||||
@@ -613,13 +636,17 @@ static int _write_pvd(struct disk_list *data)
|
||||
memset(buf, 0, size);
|
||||
memcpy(buf, &data->pvd, sizeof(struct pv_disk));
|
||||
|
||||
log_debug("Writing %s PV metadata to %s at %" PRIu64 " len %"
|
||||
PRIsize_t, data->pvd.vg_name, dev_name(data->dev),
|
||||
pos, size);
|
||||
|
||||
_xlate_pvd((struct pv_disk *) buf);
|
||||
if (!dev_write(data->dev, pos, size, buf)) {
|
||||
dbg_free(buf);
|
||||
dm_free(buf);
|
||||
fail;
|
||||
}
|
||||
|
||||
dbg_free(buf);
|
||||
dm_free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include "lvm-types.h"
|
||||
#include "metadata.h"
|
||||
#include "pool.h"
|
||||
#include "toolcontext.h"
|
||||
|
||||
#define MAX_PV 256
|
||||
@@ -159,7 +158,7 @@ struct lvd_list {
|
||||
|
||||
struct disk_list {
|
||||
struct list list;
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
struct device *dev;
|
||||
|
||||
struct pv_disk pvd;
|
||||
@@ -191,11 +190,11 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
*/
|
||||
|
||||
struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
|
||||
struct pool *mem, const char *vg_name);
|
||||
struct dm_pool *mem, const char *vg_name);
|
||||
|
||||
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
struct dev_filter *filter,
|
||||
struct pool *mem, struct list *results);
|
||||
struct dm_pool *mem, struct list *results);
|
||||
|
||||
int write_disks(const struct format_type *fmt, struct list *pvds);
|
||||
|
||||
@@ -203,33 +202,34 @@ int write_disks(const struct format_type *fmt, struct list *pvds);
|
||||
* Functions to translate to between disk and in
|
||||
* core structures.
|
||||
*/
|
||||
int import_pv(struct pool *mem, struct device *dev,
|
||||
int import_pv(struct dm_pool *mem, struct device *dev,
|
||||
struct volume_group *vg,
|
||||
struct physical_volume *pv, struct pv_disk *pvd);
|
||||
int export_pv(struct cmd_context *cmd, struct pool *mem,
|
||||
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);
|
||||
|
||||
int import_vg(struct pool *mem,
|
||||
int import_vg(struct dm_pool *mem,
|
||||
struct volume_group *vg, struct disk_list *dl, int partial);
|
||||
int export_vg(struct vg_disk *vgd, struct volume_group *vg);
|
||||
|
||||
int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd);
|
||||
int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lvd);
|
||||
|
||||
int import_extents(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct list *pvds);
|
||||
int export_extents(struct disk_list *dl, uint32_t lv_num,
|
||||
struct logical_volume *lv, struct physical_volume *pv);
|
||||
|
||||
int import_pvs(const struct format_type *fmt, struct pool *mem,
|
||||
int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct list *pvds, struct list *results, int *count);
|
||||
|
||||
int import_lvs(struct pool *mem, struct volume_group *vg, struct list *pvds);
|
||||
int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct list *pvds);
|
||||
int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
struct physical_volume *pv, const char *dev_dir);
|
||||
|
||||
int import_snapshots(struct pool *mem, struct volume_group *vg,
|
||||
int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct list *pvds);
|
||||
|
||||
int export_uuids(struct disk_list *dl, struct volume_group *vg);
|
||||
@@ -238,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,
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "disk-rep.h"
|
||||
#include "pool.h"
|
||||
#include "hash.h"
|
||||
#include "limits.h"
|
||||
#include "list.h"
|
||||
#include "display.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
@@ -128,8 +125,8 @@ static int _check_vgs(struct list *pvs, int *partial)
|
||||
static struct volume_group *_build_vg(struct format_instance *fid,
|
||||
struct list *pvs)
|
||||
{
|
||||
struct pool *mem = fid->fmt->cmd->mem;
|
||||
struct volume_group *vg = pool_alloc(mem, sizeof(*vg));
|
||||
struct dm_pool *mem = fid->fmt->cmd->mem;
|
||||
struct volume_group *vg = dm_pool_alloc(mem, sizeof(*vg));
|
||||
struct disk_list *dl;
|
||||
int partial;
|
||||
|
||||
@@ -172,15 +169,15 @@ static struct volume_group *_build_vg(struct format_instance *fid,
|
||||
|
||||
bad:
|
||||
stack;
|
||||
pool_free(mem, vg);
|
||||
dm_pool_free(mem, vg);
|
||||
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)
|
||||
{
|
||||
struct pool *mem = pool_create("lvm1 vg_read", 1024 * 10);
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_read", 1024 * 10);
|
||||
struct list pvs;
|
||||
struct volume_group *vg = NULL;
|
||||
list_init(&pvs);
|
||||
@@ -205,16 +202,16 @@ static struct volume_group *_vg_read(struct format_instance *fid,
|
||||
}
|
||||
|
||||
bad:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return vg;
|
||||
}
|
||||
|
||||
static struct disk_list *_flatten_pv(struct format_instance *fid,
|
||||
struct pool *mem, struct volume_group *vg,
|
||||
struct dm_pool *mem, struct volume_group *vg,
|
||||
struct physical_volume *pv,
|
||||
const char *dev_dir)
|
||||
{
|
||||
struct disk_list *dl = pool_alloc(mem, sizeof(*dl));
|
||||
struct disk_list *dl = dm_pool_alloc(mem, sizeof(*dl));
|
||||
|
||||
if (!dl) {
|
||||
stack;
|
||||
@@ -232,14 +229,14 @@ static struct disk_list *_flatten_pv(struct format_instance *fid,
|
||||
!export_uuids(dl, vg) ||
|
||||
!export_lvs(dl, vg, pv, dev_dir) || !calculate_layout(dl)) {
|
||||
stack;
|
||||
pool_free(mem, dl);
|
||||
dm_pool_free(mem, dl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dl;
|
||||
}
|
||||
|
||||
static int _flatten_vg(struct format_instance *fid, struct pool *mem,
|
||||
static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct list *pvds, const char *dev_dir,
|
||||
struct dev_filter *filter)
|
||||
@@ -267,10 +264,10 @@ static int _flatten_vg(struct format_instance *fid, struct 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 pool *mem = pool_create("lvm1 vg_write", 1024 * 10);
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_write", 1024 * 10);
|
||||
struct list pvds;
|
||||
int r = 0;
|
||||
|
||||
@@ -286,14 +283,14 @@ static int _vg_write(struct format_instance *fid, struct volume_group *vg,
|
||||
write_disks(fid->fmt, &pvds));
|
||||
|
||||
lvmcache_update_vg(vg);
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
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 pool *mem = pool_create("lvm1 pv_read", 1024);
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 pv_read", 1024);
|
||||
struct disk_list *dl;
|
||||
struct device *dev;
|
||||
int r = 0;
|
||||
@@ -315,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;
|
||||
}
|
||||
@@ -325,11 +322,11 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
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,
|
||||
@@ -367,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;
|
||||
|
||||
@@ -389,17 +386,17 @@ 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 pool *mem;
|
||||
struct dm_pool *mem;
|
||||
struct disk_list *dl;
|
||||
struct list pvs;
|
||||
struct label *label;
|
||||
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;
|
||||
}
|
||||
@@ -415,12 +412,12 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
|
||||
pv->pe_size = pv->pe_count = 0;
|
||||
pv->pe_start = PE_ALIGN;
|
||||
|
||||
if (!(mem = pool_create("lvm1 pv_write", 1024))) {
|
||||
if (!(mem = dm_pool_create("lvm1 pv_write", 1024))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dl = pool_alloc(mem, sizeof(*dl)))) {
|
||||
if (!(dl = dm_pool_alloc(mem, sizeof(*dl)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -444,15 +441,15 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return 1;
|
||||
|
||||
bad:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
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)
|
||||
@@ -487,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)) {
|
||||
@@ -499,18 +496,19 @@ 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;
|
||||
struct metadata_area *mda;
|
||||
|
||||
if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -519,9 +517,9 @@ static struct format_instance *_create_instance(const struct format_type *fmt,
|
||||
list_init(&fid->metadata_areas);
|
||||
|
||||
/* Define a NULL metadata area */
|
||||
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
stack;
|
||||
pool_free(fmt->cmd->mem, fid);
|
||||
dm_pool_free(fmt->cmd->mem, fid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -532,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)
|
||||
{
|
||||
dbg_free((void *) 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
|
||||
@@ -561,7 +559,7 @@ struct format_type *init_format(struct cmd_context *cmd);
|
||||
struct format_type *init_format(struct cmd_context *cmd)
|
||||
#endif
|
||||
{
|
||||
struct format_type *fmt = dbg_malloc(sizeof(*fmt));
|
||||
struct format_type *fmt = dm_malloc(sizeof(*fmt));
|
||||
|
||||
if (!fmt) {
|
||||
stack;
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "disk-rep.h"
|
||||
#include "pool.h"
|
||||
#include "hash.h"
|
||||
#include "list.h"
|
||||
#include "lvm-string.h"
|
||||
#include "filter.h"
|
||||
#include "toolcontext.h"
|
||||
@@ -38,7 +35,7 @@ static int _check_vg_name(const char *name)
|
||||
/*
|
||||
* Extracts the last part of a path.
|
||||
*/
|
||||
static char *_create_lv_name(struct pool *mem, const char *full_name)
|
||||
static char *_create_lv_name(struct dm_pool *mem, const char *full_name)
|
||||
{
|
||||
const char *ptr = strrchr(full_name, '/');
|
||||
|
||||
@@ -47,22 +44,25 @@ static char *_create_lv_name(struct pool *mem, const char *full_name)
|
||||
else
|
||||
ptr++;
|
||||
|
||||
return pool_strdup(mem, ptr);
|
||||
return dm_pool_strdup(mem, ptr);
|
||||
}
|
||||
|
||||
int import_pv(struct pool *mem, struct device *dev,
|
||||
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);
|
||||
|
||||
pv->dev = dev;
|
||||
if (!(pv->vg_name = pool_strdup(mem, pvd->vg_name))) {
|
||||
if (!(pv->vg_name = dm_pool_strdup(mem, pvd->vg_name))) {
|
||||
stack;
|
||||
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);
|
||||
@@ -112,7 +112,7 @@ static int _system_id(struct cmd_context *cmd, char *s, const char *prefix)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int export_pv(struct cmd_context *cmd, struct pool *mem,
|
||||
int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct pv_disk *pvd, struct physical_volume *pv)
|
||||
{
|
||||
@@ -198,7 +198,7 @@ int export_pv(struct cmd_context *cmd, struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_vg(struct pool *mem,
|
||||
int import_vg(struct dm_pool *mem,
|
||||
struct volume_group *vg, struct disk_list *dl, int partial)
|
||||
{
|
||||
struct vg_disk *vgd = &dl->vgd;
|
||||
@@ -209,12 +209,12 @@ int import_vg(struct pool *mem,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(vg->name = pool_strdup(mem, dl->pvd.vg_name))) {
|
||||
if (!(vg->name = dm_pool_strdup(mem, dl->pvd.vg_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(vg->system_id = pool_alloc(mem, NAME_LEN))) {
|
||||
if (!(vg->system_id = dm_pool_alloc(mem, NAME_LEN))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -288,7 +288,7 @@ int export_vg(struct vg_disk *vgd, struct volume_group *vg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
|
||||
int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
|
||||
{
|
||||
lvid_from_lvnum(&lv->lvid, &lv->vg->id, lvd->lv_number);
|
||||
|
||||
@@ -414,7 +414,7 @@ int export_extents(struct disk_list *dl, uint32_t lv_num,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pvs(const struct format_type *fmt, struct pool *mem,
|
||||
int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct list *pvds, struct list *results, int *count)
|
||||
{
|
||||
@@ -423,13 +423,13 @@ int import_pvs(const struct format_type *fmt, struct pool *mem,
|
||||
|
||||
*count = 0;
|
||||
list_iterate_items(dl, pvds) {
|
||||
if (!(pvl = pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = pool_alloc(mem, sizeof(*pvl->pv)))) {
|
||||
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = dm_pool_alloc(mem, sizeof(*pvl->pv)))) {
|
||||
stack;
|
||||
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;
|
||||
}
|
||||
@@ -442,15 +442,15 @@ int import_pvs(const struct format_type *fmt, struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct logical_volume *_add_lv(struct pool *mem,
|
||||
static struct logical_volume *_add_lv(struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct lv_disk *lvd)
|
||||
{
|
||||
struct lv_list *ll;
|
||||
struct logical_volume *lv;
|
||||
|
||||
if (!(ll = pool_zalloc(mem, sizeof(*ll))) ||
|
||||
!(ll->lv = pool_zalloc(mem, sizeof(*ll->lv)))) {
|
||||
if (!(ll = dm_pool_zalloc(mem, sizeof(*ll))) ||
|
||||
!(ll->lv = dm_pool_zalloc(mem, sizeof(*ll->lv)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -468,7 +468,7 @@ static struct logical_volume *_add_lv(struct pool *mem,
|
||||
return lv;
|
||||
}
|
||||
|
||||
int import_lvs(struct pool *mem, struct volume_group *vg, struct list *pvds)
|
||||
int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct list *pvds)
|
||||
{
|
||||
struct disk_list *dl;
|
||||
struct lvd_list *ll;
|
||||
@@ -498,14 +498,14 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
struct lvd_list *lvdl;
|
||||
size_t len;
|
||||
uint32_t lv_num;
|
||||
struct hash_table *lvd_hash;
|
||||
struct dm_hash_table *lvd_hash;
|
||||
|
||||
if (!_check_vg_name(vg->name)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(lvd_hash = hash_create(32))) {
|
||||
if (!(lvd_hash = dm_hash_create(32))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -514,7 +514,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
* setup the pv's extents array
|
||||
*/
|
||||
len = sizeof(struct pe_disk) * dl->pvd.pe_total;
|
||||
if (!(dl->extents = pool_alloc(dl->mem, len))) {
|
||||
if (!(dl->extents = dm_pool_alloc(dl->mem, len))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -524,7 +524,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
if (ll->lv->status & SNAPSHOT)
|
||||
continue;
|
||||
|
||||
if (!(lvdl = pool_alloc(dl->mem, sizeof(*lvdl)))) {
|
||||
if (!(lvdl = dm_pool_alloc(dl->mem, sizeof(*lvdl)))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -534,7 +534,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
lv_num = lvnum_from_lvid(&ll->lv->lvid);
|
||||
lvdl->lvd.lv_number = lv_num;
|
||||
|
||||
if (!hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) {
|
||||
if (!dm_hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -561,14 +561,14 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
hash_destroy(lvd_hash);
|
||||
dm_hash_destroy(lvd_hash);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: More inefficient code.
|
||||
*/
|
||||
int import_snapshots(struct pool *mem, struct volume_group *vg,
|
||||
int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct list *pvds)
|
||||
{
|
||||
struct logical_volume *lvs[MAX_LV];
|
||||
@@ -642,7 +642,7 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg)
|
||||
struct pv_list *pvl;
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
if (!(ul = pool_alloc(dl->mem, sizeof(*ul)))) {
|
||||
if (!(ul = dm_pool_alloc(dl->mem, sizeof(*ul)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "metadata.h"
|
||||
#include "hash.h"
|
||||
#include "pool.h"
|
||||
#include "disk-rep.h"
|
||||
#include "lv_alloc.h"
|
||||
#include "display.h"
|
||||
@@ -44,10 +42,10 @@ struct lv_map {
|
||||
struct pe_specifier *map;
|
||||
};
|
||||
|
||||
static struct hash_table *_create_lv_maps(struct pool *mem,
|
||||
static struct dm_hash_table *_create_lv_maps(struct dm_pool *mem,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
struct hash_table *maps = hash_create(32);
|
||||
struct dm_hash_table *maps = dm_hash_create(32);
|
||||
struct lv_list *ll;
|
||||
struct lv_map *lvm;
|
||||
|
||||
@@ -61,19 +59,19 @@ static struct hash_table *_create_lv_maps(struct pool *mem,
|
||||
if (ll->lv->status & SNAPSHOT)
|
||||
continue;
|
||||
|
||||
if (!(lvm = pool_alloc(mem, sizeof(*lvm)))) {
|
||||
if (!(lvm = dm_pool_alloc(mem, sizeof(*lvm)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
lvm->lv = ll->lv;
|
||||
if (!(lvm->map = pool_zalloc(mem, sizeof(*lvm->map)
|
||||
if (!(lvm->map = dm_pool_zalloc(mem, sizeof(*lvm->map)
|
||||
* ll->lv->le_count))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!hash_insert(maps, ll->lv->name, lvm)) {
|
||||
if (!dm_hash_insert(maps, ll->lv->name, lvm)) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -82,12 +80,12 @@ static struct hash_table *_create_lv_maps(struct pool *mem,
|
||||
return maps;
|
||||
|
||||
bad:
|
||||
hash_destroy(maps);
|
||||
dm_hash_destroy(maps);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _fill_lv_array(struct lv_map **lvs,
|
||||
struct hash_table *maps, struct disk_list *dl)
|
||||
struct dm_hash_table *maps, struct disk_list *dl)
|
||||
{
|
||||
struct lvd_list *ll;
|
||||
struct lv_map *lvm;
|
||||
@@ -95,7 +93,7 @@ static int _fill_lv_array(struct lv_map **lvs,
|
||||
memset(lvs, 0, sizeof(*lvs) * MAX_LV);
|
||||
|
||||
list_iterate_items(ll, &dl->lvds) {
|
||||
if (!(lvm = hash_lookup(maps, strrchr(ll->lvd.lv_name, '/')
|
||||
if (!(lvm = dm_hash_lookup(maps, strrchr(ll->lvd.lv_name, '/')
|
||||
+ 1))) {
|
||||
log_err("Physical volume (%s) contains an "
|
||||
"unknown logical volume (%s).",
|
||||
@@ -112,7 +110,7 @@ static int _fill_lv_array(struct lv_map **lvs,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _fill_maps(struct hash_table *maps, struct volume_group *vg,
|
||||
static int _fill_maps(struct dm_hash_table *maps, struct volume_group *vg,
|
||||
struct list *pvds)
|
||||
{
|
||||
struct disk_list *dl;
|
||||
@@ -142,7 +140,12 @@ static int _fill_maps(struct 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;
|
||||
}
|
||||
|
||||
@@ -184,13 +187,13 @@ static int _check_single_map(struct lv_map *lvm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _check_maps_are_complete(struct hash_table *maps)
|
||||
static int _check_maps_are_complete(struct dm_hash_table *maps)
|
||||
{
|
||||
struct hash_node *n;
|
||||
struct dm_hash_node *n;
|
||||
struct lv_map *lvm;
|
||||
|
||||
for (n = hash_get_first(maps); n; n = hash_get_next(maps, n)) {
|
||||
lvm = (struct lv_map *) hash_get_data(maps, n);
|
||||
for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) {
|
||||
lvm = (struct lv_map *) dm_hash_get_data(maps, n);
|
||||
|
||||
if (!_check_single_map(lvm)) {
|
||||
stack;
|
||||
@@ -327,13 +330,13 @@ static int _build_segments(struct cmd_context *cmd, struct lv_map *lvm)
|
||||
_read_linear(cmd, lvm));
|
||||
}
|
||||
|
||||
static int _build_all_segments(struct cmd_context *cmd, struct hash_table *maps)
|
||||
static int _build_all_segments(struct cmd_context *cmd, struct dm_hash_table *maps)
|
||||
{
|
||||
struct hash_node *n;
|
||||
struct dm_hash_node *n;
|
||||
struct lv_map *lvm;
|
||||
|
||||
for (n = hash_get_first(maps); n; n = hash_get_next(maps, n)) {
|
||||
lvm = (struct lv_map *) hash_get_data(maps, n);
|
||||
for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) {
|
||||
lvm = (struct lv_map *) dm_hash_get_data(maps, n);
|
||||
if (!_build_segments(cmd, lvm)) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -347,8 +350,8 @@ int import_extents(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct list *pvds)
|
||||
{
|
||||
int r = 0;
|
||||
struct pool *scratch = pool_create("lvm1 import_extents", 10 * 1024);
|
||||
struct hash_table *maps;
|
||||
struct dm_pool *scratch = dm_pool_create("lvm1 import_extents", 10 * 1024);
|
||||
struct dm_hash_table *maps;
|
||||
|
||||
if (!scratch) {
|
||||
stack;
|
||||
@@ -378,7 +381,7 @@ int import_extents(struct cmd_context *cmd, struct volume_group *vg,
|
||||
|
||||
out:
|
||||
if (maps)
|
||||
hash_destroy(maps);
|
||||
pool_destroy(scratch);
|
||||
dm_hash_destroy(maps);
|
||||
dm_pool_destroy(scratch);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -117,7 +119,7 @@ int calculate_layout(struct disk_list *dl)
|
||||
int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
uint32_t max_extent_count, uint64_t pe_start)
|
||||
{
|
||||
struct pv_disk *pvd = dbg_malloc(sizeof(*pvd));
|
||||
struct pv_disk *pvd = dm_malloc(sizeof(*pvd));
|
||||
uint32_t end;
|
||||
|
||||
if (!pvd) {
|
||||
@@ -138,7 +140,7 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
if (pvd->pe_total < PE_SIZE_PV_SIZE_REL) {
|
||||
log_error("Too few extents on %s. Try smaller extent size.",
|
||||
dev_name(pv->dev));
|
||||
dbg_free(pvd);
|
||||
dm_free(pvd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -160,13 +162,13 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
log_error("Metadata extent limit (%u) exceeded for %s - "
|
||||
"%u required", MAX_PE_TOTAL, dev_name(pv->dev),
|
||||
pvd->pe_total);
|
||||
dbg_free(pvd);
|
||||
dm_free(pvd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pv->pe_count = pvd->pe_total;
|
||||
pv->pe_start = pvd->pe_start;
|
||||
/* We can't set pe_size here without breaking LVM1 compatibility */
|
||||
dbg_free(pvd);
|
||||
dm_free(pvd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -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,38 +85,38 @@ 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)
|
||||
{
|
||||
dbg_free(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)
|
||||
{
|
||||
struct labeller *l;
|
||||
|
||||
if (!(l = dbg_malloc(sizeof(*l)))) {
|
||||
if (!(l = dm_malloc(sizeof(*l)))) {
|
||||
log_err("Couldn't allocate labeller object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "disk-rep.h"
|
||||
|
||||
/*
|
||||
@@ -29,7 +28,7 @@ int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
|
||||
{
|
||||
struct list all_pvs;
|
||||
struct disk_list *dl;
|
||||
struct pool *mem = pool_create("lvm1 vg_number", 10 * 1024);
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_number", 10 * 1024);
|
||||
int numbers[MAX_VG], i, r = 0;
|
||||
|
||||
list_init(&all_pvs);
|
||||
@@ -62,6 +61,6 @@ int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
|
||||
}
|
||||
|
||||
out:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -14,12 +14,10 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "lvmcache.h"
|
||||
#include "filter.h"
|
||||
#include "list.h"
|
||||
#include "xlate.h"
|
||||
|
||||
#include "disk_rep.h"
|
||||
@@ -35,7 +33,7 @@
|
||||
#define CPOUT_64(x, y) {(y) = xlate64_be((x));}
|
||||
|
||||
static int __read_pool_disk(const struct format_type *fmt, struct device *dev,
|
||||
struct pool *mem, struct pool_list *pl,
|
||||
struct dm_pool *mem, struct pool_list *pl,
|
||||
const char *vg_name)
|
||||
{
|
||||
char buf[512];
|
||||
@@ -100,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;
|
||||
}
|
||||
@@ -240,13 +238,13 @@ void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid)
|
||||
|
||||
}
|
||||
|
||||
static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
static int _read_vg_pds(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct lvmcache_vginfo *vginfo, struct list *head,
|
||||
uint32_t *devcount)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
struct pool_list *pl = NULL;
|
||||
struct pool *tmpmem;
|
||||
struct dm_pool *tmpmem;
|
||||
|
||||
uint32_t sp_count = 0;
|
||||
uint32_t *sp_devs = NULL;
|
||||
@@ -254,7 +252,7 @@ static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
|
||||
/* FIXME: maybe should return a different error in memory
|
||||
* allocation failure */
|
||||
if (!(tmpmem = pool_create("pool read_vg", 512))) {
|
||||
if (!(tmpmem = dm_pool_create("pool read_vg", 512))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -271,11 +269,11 @@ static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
/* FIXME pl left uninitialised if !info->dev */
|
||||
sp_count = pl->pd.pl_subpools;
|
||||
if (!(sp_devs =
|
||||
pool_zalloc(tmpmem,
|
||||
dm_pool_zalloc(tmpmem,
|
||||
sizeof(uint32_t) * sp_count))) {
|
||||
log_error("Unable to allocate %d 32-bit uints",
|
||||
sp_count);
|
||||
pool_destroy(tmpmem);
|
||||
dm_pool_destroy(tmpmem);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -296,7 +294,7 @@ static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
for (i = 0; i < sp_count; i++)
|
||||
*devcount += sp_devs[i];
|
||||
|
||||
pool_destroy(tmpmem);
|
||||
dm_pool_destroy(tmpmem);
|
||||
|
||||
if (pl && *pl->pd.pl_pool_name)
|
||||
return 1;
|
||||
@@ -306,7 +304,7 @@ static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
}
|
||||
|
||||
int read_pool_pds(const struct format_type *fmt, const char *vg_name,
|
||||
struct pool *mem, struct list *pdhead)
|
||||
struct dm_pool *mem, struct list *pdhead)
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
uint32_t totaldevs;
|
||||
@@ -316,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)) {
|
||||
@@ -351,7 +349,7 @@ int read_pool_pds(const struct format_type *fmt, const char *vg_name,
|
||||
}
|
||||
|
||||
struct pool_list *read_pool_disk(const struct format_type *fmt,
|
||||
struct device *dev, struct pool *mem,
|
||||
struct device *dev, struct dm_pool *mem,
|
||||
const char *vg_name)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
@@ -361,7 +359,7 @@ struct pool_list *read_pool_disk(const struct format_type *fmt,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(pl = pool_zalloc(mem, sizeof(*pl)))) {
|
||||
if (!(pl = dm_pool_zalloc(mem, sizeof(*pl)))) {
|
||||
log_error("Unable to allocate pool list structure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "pool.h"
|
||||
|
||||
#define MINOR_OFFSET 65536
|
||||
|
||||
@@ -138,20 +137,20 @@ int read_pool_label(struct pool_list *pl, struct labeller *l,
|
||||
void pool_label_out(struct pool_disk *pl, char *buf);
|
||||
void pool_label_in(struct pool_disk *pl, char *buf);
|
||||
void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid);
|
||||
int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls);
|
||||
int import_pool_lvs(struct volume_group *vg, struct pool *mem,
|
||||
int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pls);
|
||||
int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem,
|
||||
struct list *pls);
|
||||
int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
|
||||
struct list *pvs, struct pool *mem, struct list *pls);
|
||||
int import_pool_pv(const struct format_type *fmt, struct pool *mem,
|
||||
struct list *pvs, struct dm_pool *mem, struct list *pls);
|
||||
int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct physical_volume *pv,
|
||||
struct pool_list *pl);
|
||||
int import_pool_segments(struct list *lvs, struct pool *mem,
|
||||
int import_pool_segments(struct list *lvs, struct dm_pool *mem,
|
||||
struct user_subpool *usp, int sp_count);
|
||||
int read_pool_pds(const struct format_type *fmt, const char *vgname,
|
||||
struct pool *mem, struct list *head);
|
||||
struct dm_pool *mem, struct list *head);
|
||||
struct pool_list *read_pool_disk(const struct format_type *fmt,
|
||||
struct device *dev, struct pool *mem,
|
||||
struct device *dev, struct dm_pool *mem,
|
||||
const char *vg_name);
|
||||
|
||||
#endif /* DISK_REP_POOL_FORMAT_H */
|
||||
|
||||
@@ -14,12 +14,9 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "hash.h"
|
||||
#include "limits.h"
|
||||
#include "list.h"
|
||||
#include "display.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
@@ -30,7 +27,7 @@
|
||||
#define FMT_POOL_NAME "pool"
|
||||
|
||||
/* Must be called after pvs are imported */
|
||||
static struct user_subpool *_build_usp(struct list *pls, struct pool *mem,
|
||||
static struct user_subpool *_build_usp(struct list *pls, struct dm_pool *mem,
|
||||
int *sps)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
@@ -43,7 +40,7 @@ static struct user_subpool *_build_usp(struct list *pls, struct pool *mem,
|
||||
*/
|
||||
list_iterate_items(pl, pls) {
|
||||
*sps = pl->pd.pl_subpools;
|
||||
if (!usp && (!(usp = pool_zalloc(mem, sizeof(*usp) * (*sps))))) {
|
||||
if (!usp && (!(usp = dm_pool_zalloc(mem, sizeof(*usp) * (*sps))))) {
|
||||
log_error("Unable to allocate %d subpool structures",
|
||||
*sps);
|
||||
return 0;
|
||||
@@ -61,7 +58,7 @@ static struct user_subpool *_build_usp(struct list *pls, struct pool *mem,
|
||||
|
||||
if (!cur_sp->devs &&
|
||||
(!(cur_sp->devs =
|
||||
pool_zalloc(mem,
|
||||
dm_pool_zalloc(mem,
|
||||
sizeof(*usp->devs) * pl->pd.pl_sp_devs)))) {
|
||||
|
||||
log_error("Unable to allocate %d pool_device "
|
||||
@@ -103,15 +100,15 @@ static int _check_usp(char *vgname, struct user_subpool *usp, int sp_count)
|
||||
}
|
||||
|
||||
static struct volume_group *_build_vg_from_pds(struct format_instance
|
||||
*fid, struct pool *mem,
|
||||
*fid, struct dm_pool *mem,
|
||||
struct list *pds)
|
||||
{
|
||||
struct pool *smem = fid->fmt->cmd->mem;
|
||||
struct dm_pool *smem = fid->fmt->cmd->mem;
|
||||
struct volume_group *vg = NULL;
|
||||
struct user_subpool *usp = NULL;
|
||||
int sp_count;
|
||||
|
||||
if (!(vg = pool_zalloc(smem, sizeof(*vg)))) {
|
||||
if (!(vg = dm_pool_zalloc(smem, sizeof(*vg)))) {
|
||||
log_error("Unable to allocate volume group structure");
|
||||
return NULL;
|
||||
}
|
||||
@@ -172,11 +169,11 @@ 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)
|
||||
{
|
||||
struct pool *mem = pool_create("pool vg_read", 1024);
|
||||
struct dm_pool *mem = dm_pool_create("pool vg_read", 1024);
|
||||
struct list pds;
|
||||
struct volume_group *vg = NULL;
|
||||
|
||||
@@ -205,11 +202,11 @@ static struct volume_group *_vg_read(struct format_instance *fid,
|
||||
}
|
||||
|
||||
out:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
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,
|
||||
@@ -219,10 +216,10 @@ 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 pool *mem = pool_create("pool pv_read", 1024);
|
||||
struct dm_pool *mem = dm_pool_create("pool pv_read", 1024);
|
||||
struct pool_list *pl;
|
||||
struct device *dev;
|
||||
int r = 0;
|
||||
@@ -259,24 +256,25 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* *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;
|
||||
struct metadata_area *mda;
|
||||
|
||||
if (!(fid = pool_zalloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
if (!(fid = dm_pool_zalloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
log_error("Unable to allocate format instance structure for "
|
||||
"pool format");
|
||||
return NULL;
|
||||
@@ -286,10 +284,10 @@ static struct format_instance *_create_instance(const struct format_type *fmt,
|
||||
list_init(&fid->metadata_areas);
|
||||
|
||||
/* Define a NULL metadata area */
|
||||
if (!(mda = pool_zalloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
if (!(mda = dm_pool_zalloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
log_error("Unable to allocate metadata area structure "
|
||||
"for pool format");
|
||||
pool_free(fmt->cmd->mem, fid);
|
||||
dm_pool_free(fmt->cmd->mem, fid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -300,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)
|
||||
{
|
||||
dbg_free((void *) 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 */
|
||||
|
||||
@@ -327,7 +325,7 @@ struct format_type *init_format(struct cmd_context *cmd);
|
||||
struct format_type *init_format(struct cmd_context *cmd)
|
||||
#endif
|
||||
{
|
||||
struct format_type *fmt = dbg_malloc(sizeof(*fmt));
|
||||
struct format_type *fmt = dm_malloc(sizeof(*fmt));
|
||||
|
||||
if (!fmt) {
|
||||
log_error("Unable to allocate format type structure for pool "
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "lvmcache.h"
|
||||
@@ -28,7 +27,7 @@
|
||||
|
||||
/* This file contains only imports at the moment... */
|
||||
|
||||
int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pls)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
|
||||
@@ -41,7 +40,7 @@ int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
if (vg->name)
|
||||
continue;
|
||||
|
||||
vg->name = pool_strdup(mem, pl->pd.pl_pool_name);
|
||||
vg->name = dm_pool_strdup(mem, pl->pd.pl_pool_name);
|
||||
get_pool_vg_uuid(&vg->id, &pl->pd);
|
||||
vg->extent_size = POOL_PE_SIZE;
|
||||
vg->status |= LVM_READ | LVM_WRITE | CLUSTERED | SHARED;
|
||||
@@ -55,10 +54,10 @@ int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *pls)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
struct lv_list *lvl = pool_zalloc(mem, sizeof(*lvl));
|
||||
struct lv_list *lvl = dm_pool_zalloc(mem, sizeof(*lvl));
|
||||
struct logical_volume *lv;
|
||||
|
||||
if (!lvl) {
|
||||
@@ -66,7 +65,7 @@ int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(lvl->lv = pool_zalloc(mem, sizeof(*lvl->lv)))) {
|
||||
if (!(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv)))) {
|
||||
log_error("Unable to allocate logical volume structure");
|
||||
return 0;
|
||||
}
|
||||
@@ -90,7 +89,7 @@ int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
if (lv->name)
|
||||
continue;
|
||||
|
||||
if (!(lv->name = pool_strdup(mem, pl->pd.pl_pool_name))) {
|
||||
if (!(lv->name = dm_pool_strdup(mem, pl->pd.pl_pool_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -124,17 +123,17 @@ int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
}
|
||||
|
||||
int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
|
||||
struct list *pvs, struct pool *mem, struct list *pls)
|
||||
struct list *pvs, struct dm_pool *mem, struct list *pls)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
struct pool_list *pl;
|
||||
|
||||
list_iterate_items(pl, pls) {
|
||||
if (!(pvl = pool_zalloc(mem, sizeof(*pvl)))) {
|
||||
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) {
|
||||
log_error("Unable to allocate pv list structure");
|
||||
return 0;
|
||||
}
|
||||
if (!(pvl->pv = pool_zalloc(mem, sizeof(*pvl->pv)))) {
|
||||
if (!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv)))) {
|
||||
log_error("Unable to allocate pv structure");
|
||||
return 0;
|
||||
}
|
||||
@@ -150,7 +149,7 @@ int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pool_pv(const struct format_type *fmt, struct pool *mem,
|
||||
int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct physical_volume *pv,
|
||||
struct pool_list *pl)
|
||||
{
|
||||
@@ -162,10 +161,11 @@ int import_pool_pv(const struct format_type *fmt, struct pool *mem,
|
||||
pv->fmt = fmt;
|
||||
|
||||
pv->dev = pl->dev;
|
||||
if (!(pv->vg_name = pool_strdup(mem, pd->pl_pool_name))) {
|
||||
if (!(pv->vg_name = dm_pool_strdup(mem, pd->pl_pool_name))) {
|
||||
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;
|
||||
@@ -197,7 +197,7 @@ static const char *_cvt_sptype(uint32_t sptype)
|
||||
return sptype_names[i].name;
|
||||
}
|
||||
|
||||
static int _add_stripe_seg(struct pool *mem,
|
||||
static int _add_stripe_seg(struct dm_pool *mem,
|
||||
struct user_subpool *usp, struct logical_volume *lv,
|
||||
uint32_t *le_cur)
|
||||
{
|
||||
@@ -243,7 +243,7 @@ static int _add_stripe_seg(struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _add_linear_seg(struct pool *mem,
|
||||
static int _add_linear_seg(struct dm_pool *mem,
|
||||
struct user_subpool *usp, struct logical_volume *lv,
|
||||
uint32_t *le_cur)
|
||||
{
|
||||
@@ -284,7 +284,7 @@ static int _add_linear_seg(struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pool_segments(struct list *lvs, struct pool *mem,
|
||||
int import_pool_segments(struct list *lvs, struct dm_pool *mem,
|
||||
struct user_subpool *usp, int subpools)
|
||||
{
|
||||
struct lv_list *lvl;
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "xlate.h"
|
||||
@@ -24,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;
|
||||
@@ -51,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;
|
||||
@@ -65,38 +64,38 @@ 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)
|
||||
{
|
||||
dbg_free(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)
|
||||
{
|
||||
struct labeller *l;
|
||||
|
||||
if (!(l = dbg_malloc(sizeof(*l)))) {
|
||||
if (!(l = dm_malloc(sizeof(*l)))) {
|
||||
log_error("Couldn't allocate labeller object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
#include "lib.h"
|
||||
#include "format-text.h"
|
||||
|
||||
#include "pool.h"
|
||||
#include "config.h"
|
||||
#include "hash.h"
|
||||
#include "import-export.h"
|
||||
#include "lvm-string.h"
|
||||
#include "lvm-file.h"
|
||||
@@ -89,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;
|
||||
|
||||
@@ -109,24 +107,24 @@ static void _insert_file(struct list *head, struct archive_file *b)
|
||||
list_add_h(&bf->list, &b->list);
|
||||
}
|
||||
|
||||
static char *_join(struct 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 (!pool_begin_object(mem, 32) ||
|
||||
!pool_grow_object(mem, dir, strlen(dir)) ||
|
||||
!pool_grow_object(mem, "/", 1) ||
|
||||
!pool_grow_object(mem, name, strlen(name)) ||
|
||||
!pool_grow_object(mem, "\0", 1)) {
|
||||
if (!dm_pool_begin_object(mem, 32) ||
|
||||
!dm_pool_grow_object(mem, dir, strlen(dir)) ||
|
||||
!dm_pool_grow_object(mem, "/", 1) ||
|
||||
!dm_pool_grow_object(mem, name, strlen(name)) ||
|
||||
!dm_pool_grow_object(mem, "\0", 1)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pool_end_object(mem);
|
||||
return dm_pool_end_object(mem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a list of archive_files.
|
||||
*/
|
||||
static struct list *_scan_archive(struct pool *mem,
|
||||
static struct list *_scan_archive(struct dm_pool *mem,
|
||||
const char *vgname, const char *dir)
|
||||
{
|
||||
int i, count;
|
||||
@@ -136,7 +134,7 @@ static struct list *_scan_archive(struct pool *mem,
|
||||
struct archive_file *af;
|
||||
struct list *results;
|
||||
|
||||
if (!(results = pool_alloc(mem, sizeof(*results)))) {
|
||||
if (!(results = dm_pool_alloc(mem, sizeof(*results)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -163,7 +161,7 @@ static struct list *_scan_archive(struct 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;
|
||||
}
|
||||
@@ -171,7 +169,7 @@ static struct list *_scan_archive(struct pool *mem,
|
||||
/*
|
||||
* Create a new archive_file.
|
||||
*/
|
||||
if (!(af = pool_alloc(mem, sizeof(*af)))) {
|
||||
if (!(af = dm_pool_alloc(mem, sizeof(*af)))) {
|
||||
log_err("Couldn't create new archive file.");
|
||||
results = NULL;
|
||||
goto out;
|
||||
@@ -183,7 +181,7 @@ static struct list *_scan_archive(struct pool *mem,
|
||||
/*
|
||||
* Insert it to the correct part of the list.
|
||||
*/
|
||||
_insert_file(results, af);
|
||||
_insert_archive_file(results, af);
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -209,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);
|
||||
@@ -313,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;
|
||||
}
|
||||
@@ -333,7 +331,7 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
|
||||
log_print("Description:\t%s", desc ? desc : "<No description>");
|
||||
log_print("Backup Time:\t%s", ctime(&when));
|
||||
|
||||
pool_free(cmd->mem, vg);
|
||||
dm_pool_free(cmd->mem, vg);
|
||||
tf->fmt->ops->destroy_instance(tf);
|
||||
}
|
||||
|
||||
@@ -353,7 +351,7 @@ int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
|
||||
list_iterate_back_items(af, archives)
|
||||
_display_archive(cmd, af);
|
||||
|
||||
pool_free(cmd->mem, archives);
|
||||
dm_pool_free(cmd->mem, archives);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -362,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;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ struct backup_params {
|
||||
int archive_init(struct cmd_context *cmd, const char *dir,
|
||||
unsigned int keep_days, unsigned int keep_min)
|
||||
{
|
||||
if (!(cmd->archive_params = pool_zalloc(cmd->libmem,
|
||||
if (!(cmd->archive_params = dm_pool_zalloc(cmd->libmem,
|
||||
sizeof(*cmd->archive_params)))) {
|
||||
log_error("archive_params alloc failed");
|
||||
return 0;
|
||||
@@ -49,7 +49,7 @@ int archive_init(struct cmd_context *cmd, const char *dir,
|
||||
if (!*dir)
|
||||
return 1;
|
||||
|
||||
if (!(cmd->archive_params->dir = dbg_strdup(dir))) {
|
||||
if (!(cmd->archive_params->dir = dm_strdup(dir))) {
|
||||
log_error("Couldn't copy archive directory name.");
|
||||
return 0;
|
||||
}
|
||||
@@ -64,7 +64,7 @@ int archive_init(struct cmd_context *cmd, const char *dir,
|
||||
void archive_exit(struct cmd_context *cmd)
|
||||
{
|
||||
if (cmd->archive_params->dir)
|
||||
dbg_free(cmd->archive_params->dir);
|
||||
dm_free(cmd->archive_params->dir);
|
||||
memset(cmd->archive_params, 0, sizeof(*cmd->archive_params));
|
||||
}
|
||||
|
||||
@@ -73,12 +73,12 @@ void archive_enable(struct cmd_context *cmd, int flag)
|
||||
cmd->archive_params->enabled = flag;
|
||||
}
|
||||
|
||||
static char *_build_desc(struct pool *mem, const char *line, int before)
|
||||
static char *_build_desc(struct dm_pool *mem, const char *line, int before)
|
||||
{
|
||||
size_t len = strlen(line) + 32;
|
||||
char *buffer;
|
||||
|
||||
if (!(buffer = pool_zalloc(mem, strlen(line) + 32))) {
|
||||
if (!(buffer = dm_pool_zalloc(mem, strlen(line) + 32))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -150,7 +150,7 @@ int archive_display(struct cmd_context *cmd, const char *vg_name)
|
||||
|
||||
int backup_init(struct cmd_context *cmd, const char *dir)
|
||||
{
|
||||
if (!(cmd->backup_params = pool_zalloc(cmd->libmem,
|
||||
if (!(cmd->backup_params = dm_pool_zalloc(cmd->libmem,
|
||||
sizeof(*cmd->archive_params)))) {
|
||||
log_error("archive_params alloc failed");
|
||||
return 0;
|
||||
@@ -160,7 +160,7 @@ int backup_init(struct cmd_context *cmd, const char *dir)
|
||||
if (!*dir)
|
||||
return 1;
|
||||
|
||||
if (!(cmd->backup_params->dir = dbg_strdup(dir))) {
|
||||
if (!(cmd->backup_params->dir = dm_strdup(dir))) {
|
||||
log_error("Couldn't copy backup directory name.");
|
||||
return 0;
|
||||
}
|
||||
@@ -171,7 +171,7 @@ int backup_init(struct cmd_context *cmd, const char *dir)
|
||||
void backup_exit(struct cmd_context *cmd)
|
||||
{
|
||||
if (cmd->backup_params->dir)
|
||||
dbg_free(cmd->backup_params->dir);
|
||||
dm_free(cmd->backup_params->dir);
|
||||
memset(cmd->backup_params, 0, sizeof(*cmd->backup_params));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#include "lib.h"
|
||||
#include "import-export.h"
|
||||
#include "metadata.h"
|
||||
#include "hash.h"
|
||||
#include "pool.h"
|
||||
#include "display.h"
|
||||
#include "lvm-string.h"
|
||||
#include "segtype.h"
|
||||
@@ -31,13 +29,26 @@ struct formatter;
|
||||
typedef int (*out_with_comment_fn) (struct formatter * f, const char *comment,
|
||||
const char *fmt, va_list ap);
|
||||
typedef int (*nl_fn) (struct formatter * f);
|
||||
|
||||
/*
|
||||
* Macro for formatted output.
|
||||
* out_with_comment_fn returns -1 if data didn't fit and buffer was expanded.
|
||||
* Then argument list is reset and out_with_comment_fn is called again.
|
||||
*/
|
||||
#define _out_with_comment(f, buffer, fmt, ap) \
|
||||
do { \
|
||||
va_start(ap, fmt); \
|
||||
r = f->out_with_comment(f, buffer, fmt, ap); \
|
||||
va_end(ap); \
|
||||
} while (r == -1)
|
||||
|
||||
/*
|
||||
* The first half of this file deals with
|
||||
* exporting the vg, ie. writing it to a file.
|
||||
*/
|
||||
struct formatter {
|
||||
struct pool *mem; /* pv names allocated from here */
|
||||
struct hash_table *pv_names; /* dev_name -> pv_name (eg, pv1) */
|
||||
struct dm_pool *mem; /* pv names allocated from here */
|
||||
struct dm_hash_table *pv_names; /* dev_name -> pv_name (eg, pv1) */
|
||||
|
||||
union {
|
||||
FILE *fp; /* where we're writing to */
|
||||
@@ -102,19 +113,30 @@ static int _nl_file(struct formatter *f)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _nl_raw(struct formatter *f)
|
||||
static int _extend_buffer(struct formatter *f)
|
||||
{
|
||||
char *newbuf;
|
||||
|
||||
/* If metadata doesn't fit, double the buffer size */
|
||||
if (f->data.buf.used + 2 > f->data.buf.size) {
|
||||
if (!(newbuf = dbg_realloc(f->data.buf.start,
|
||||
f->data.buf.size * 2))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
f->data.buf.start = newbuf;
|
||||
f->data.buf.size *= 2;
|
||||
log_debug("Doubling metadata output buffer to %" PRIu32,
|
||||
f->data.buf.size * 2);
|
||||
if (!(newbuf = dm_realloc(f->data.buf.start,
|
||||
f->data.buf.size * 2))) {
|
||||
log_error("Buffer reallocation failed.");
|
||||
return 0;
|
||||
}
|
||||
f->data.buf.start = newbuf;
|
||||
f->data.buf.size *= 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _nl_raw(struct formatter *f)
|
||||
{
|
||||
/* If metadata doesn't fit, extend buffer */
|
||||
if ((f->data.buf.used + 2 > f->data.buf.size) &&
|
||||
(!_extend_buffer(f))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*(f->data.buf.start + f->data.buf.used) = '\n';
|
||||
@@ -165,22 +187,17 @@ static int _out_with_comment_raw(struct formatter *f, const char *comment,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
int n;
|
||||
char *newbuf;
|
||||
|
||||
retry:
|
||||
n = vsnprintf(f->data.buf.start + f->data.buf.used,
|
||||
f->data.buf.size - f->data.buf.used, fmt, ap);
|
||||
|
||||
/* If metadata doesn't fit, double the buffer size */
|
||||
/* If metadata doesn't fit, extend buffer */
|
||||
if (n < 0 || (n + f->data.buf.used + 2 > f->data.buf.size)) {
|
||||
if (!(newbuf = dbg_realloc(f->data.buf.start,
|
||||
f->data.buf.size * 2))) {
|
||||
if (!_extend_buffer(f)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
f->data.buf.start = newbuf;
|
||||
f->data.buf.size *= 2;
|
||||
goto retry;
|
||||
return -1; /* Retry */
|
||||
}
|
||||
|
||||
f->data.buf.used += n;
|
||||
@@ -231,9 +248,7 @@ int out_size(struct formatter *f, uint64_t size, const char *fmt, ...)
|
||||
if (!_sectors_to_units(size, buffer, sizeof(buffer)))
|
||||
return 0;
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = f->out_with_comment(f, buffer, fmt, ap);
|
||||
va_end(ap);
|
||||
_out_with_comment(f, buffer, fmt, ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -247,9 +262,7 @@ int out_hint(struct formatter *f, const char *fmt, ...)
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = f->out_with_comment(f, "# Hint only", fmt, ap);
|
||||
va_end(ap);
|
||||
_out_with_comment(f, "# Hint only", fmt, ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -262,9 +275,7 @@ int out_text(struct formatter *f, const char *fmt, ...)
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = f->out_with_comment(f, NULL, fmt, ap);
|
||||
va_end(ap);
|
||||
_out_with_comment(f, NULL, fmt, ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -343,11 +354,10 @@ 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 *)
|
||||
hash_lookup(f->pv_names, dev_name(pv->dev)) : "Missing";
|
||||
dm_hash_lookup(f->pv_names, dev_name(pv->dev)) : "Missing";
|
||||
}
|
||||
|
||||
static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||
@@ -602,12 +612,12 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
||||
struct physical_volume *pv;
|
||||
char buffer[32], *name;
|
||||
|
||||
if (!(f->mem = pool_create("text pv_names", 512))) {
|
||||
if (!(f->mem = dm_pool_create("text pv_names", 512))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(f->pv_names = hash_create(128))) {
|
||||
if (!(f->pv_names = dm_hash_create(128))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -621,12 +631,12 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(name = pool_strdup(f->mem, buffer))) {
|
||||
if (!(name = dm_pool_strdup(f->mem, buffer))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!hash_insert(f->pv_names, dev_name(pv->dev), name)) {
|
||||
if (!dm_hash_insert(f->pv_names, dev_name(pv->dev), name)) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -636,10 +646,10 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
||||
|
||||
bad:
|
||||
if (f->mem)
|
||||
pool_destroy(f->mem);
|
||||
dm_pool_destroy(f->mem);
|
||||
|
||||
if (f->pv_names)
|
||||
hash_destroy(f->pv_names);
|
||||
dm_hash_destroy(f->pv_names);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -686,10 +696,10 @@ static int _text_vg_export(struct formatter *f,
|
||||
|
||||
out:
|
||||
if (f->mem)
|
||||
pool_destroy(f->mem);
|
||||
dm_pool_destroy(f->mem);
|
||||
|
||||
if (f->pv_names)
|
||||
hash_destroy(f->pv_names);
|
||||
dm_hash_destroy(f->pv_names);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -701,7 +711,7 @@ int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp)
|
||||
|
||||
_init();
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(*f)))) {
|
||||
if (!(f = dm_malloc(sizeof(*f)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -716,7 +726,7 @@ int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp)
|
||||
r = _text_vg_export(f, vg, desc);
|
||||
if (r)
|
||||
r = !ferror(f->data.fp);
|
||||
dbg_free(f);
|
||||
dm_free(f);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -728,7 +738,7 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
|
||||
_init();
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(*f)))) {
|
||||
if (!(f = dm_malloc(sizeof(*f)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -736,7 +746,7 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
memset(f, 0, sizeof(*f));
|
||||
|
||||
f->data.buf.size = 65536; /* Initial metadata limit */
|
||||
if (!(f->data.buf.start = dbg_malloc(f->data.buf.size))) {
|
||||
if (!(f->data.buf.start = dm_malloc(f->data.buf.size))) {
|
||||
log_error("text_export buffer allocation failed");
|
||||
goto out;
|
||||
}
|
||||
@@ -748,7 +758,7 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
|
||||
if (!_text_vg_export(f, vg, desc)) {
|
||||
stack;
|
||||
dbg_free(f->data.buf.start);
|
||||
dm_free(f->data.buf.start);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -756,7 +766,7 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
*buf = f->data.buf.start;
|
||||
|
||||
out:
|
||||
dbg_free(f);
|
||||
dm_free(f);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ static struct flag _vg_flags[] = {
|
||||
{LVM_WRITE, "WRITE"},
|
||||
{CLUSTERED, "CLUSTERED"},
|
||||
{SHARED, "SHARED"},
|
||||
{PRECOMMITTED, NULL},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
@@ -57,6 +58,7 @@ static struct flag _lv_flags[] = {
|
||||
{MIRRORED, NULL},
|
||||
{VIRTUAL, NULL},
|
||||
{SNAPSHOT, NULL},
|
||||
{ACTIVATE_EXCL, NULL},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
#include "import-export.h"
|
||||
#include "device.h"
|
||||
#include "lvm-file.h"
|
||||
#include "pool.h"
|
||||
#include "config.h"
|
||||
#include "hash.h"
|
||||
#include "display.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvm-string.h"
|
||||
@@ -41,10 +39,16 @@
|
||||
#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 {
|
||||
char *raw_metadata_buf;
|
||||
uint32_t raw_metadata_buf_size;
|
||||
};
|
||||
|
||||
struct dir_list {
|
||||
struct list list;
|
||||
char dir[0];
|
||||
@@ -65,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");
|
||||
@@ -75,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;
|
||||
@@ -83,7 +87,7 @@ static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
|
||||
if (lv->size > max_size) {
|
||||
char *dummy = display_size(max_size, SIZE_SHORT);
|
||||
log_error("logical volumes cannot be larger than %s", dummy);
|
||||
dbg_free(dummy);
|
||||
dm_free(dummy);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
@@ -119,14 +123,14 @@ static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
|
||||
{
|
||||
struct mda_header *mdah;
|
||||
|
||||
if (!(mdah = pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
|
||||
if (!(mdah = dm_pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
|
||||
log_error("struct mda_header allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah)) {
|
||||
stack;
|
||||
pool_free(fmt->cmd->mem, mdah);
|
||||
dm_pool_free(fmt->cmd->mem, mdah);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -174,7 +178,7 @@ static int _raw_write_mda_header(const struct format_type *fmt,
|
||||
|
||||
if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) {
|
||||
stack;
|
||||
pool_free(fmt->cmd->mem, mdah);
|
||||
dm_pool_free(fmt->cmd->mem, mdah);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -184,17 +188,22 @@ static int _raw_write_mda_header(const struct format_type *fmt,
|
||||
static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
|
||||
struct mda_header *mdah,
|
||||
const char *vgname,
|
||||
int precommit)
|
||||
int *precommitted)
|
||||
{
|
||||
size_t len;
|
||||
char vgnamebuf[NAME_LEN + 2];
|
||||
struct raw_locn *rlocn;
|
||||
struct raw_locn *rlocn, *rlocn_precommitted;
|
||||
struct lvmcache_info *info;
|
||||
|
||||
rlocn = mdah->raw_locns; /* Slot 0 */
|
||||
rlocn_precommitted = rlocn + 1; /* Slot 1 */
|
||||
|
||||
if (precommit)
|
||||
rlocn++; /* Slot 1 */
|
||||
/* Should we use precommitted metadata? */
|
||||
if (*precommitted && rlocn_precommitted->size &&
|
||||
(rlocn_precommitted->offset != rlocn->offset)) {
|
||||
rlocn = rlocn_precommitted;
|
||||
} else
|
||||
*precommitted = 0;
|
||||
|
||||
/* FIXME Loop through rlocns two-at-a-time. List null-terminated. */
|
||||
/* FIXME Ignore if checksum incorrect!!! */
|
||||
@@ -211,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;
|
||||
}
|
||||
@@ -238,6 +247,7 @@ static int _raw_holds_vgname(struct format_instance *fid,
|
||||
struct device_area *dev_area, const char *vgname)
|
||||
{
|
||||
int r = 0;
|
||||
int noprecommit = 0;
|
||||
struct mda_header *mdah;
|
||||
|
||||
if (!dev_open(dev_area->dev)) {
|
||||
@@ -250,7 +260,7 @@ static int _raw_holds_vgname(struct format_instance *fid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_find_vg_rlocn(dev_area, mdah, vgname, 0))
|
||||
if (_find_vg_rlocn(dev_area, mdah, vgname, &noprecommit))
|
||||
r = 1;
|
||||
|
||||
if (!dev_close(dev_area->dev))
|
||||
@@ -262,7 +272,7 @@ static int _raw_holds_vgname(struct format_instance *fid,
|
||||
static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
|
||||
const char *vgname,
|
||||
struct device_area *area,
|
||||
int precommit)
|
||||
int precommitted)
|
||||
{
|
||||
struct volume_group *vg = NULL;
|
||||
struct raw_locn *rlocn;
|
||||
@@ -281,7 +291,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, precommit))) {
|
||||
if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, &precommitted))) {
|
||||
log_debug("VG %s not found on %s", vgname, dev_name(area->dev));
|
||||
goto out;
|
||||
}
|
||||
@@ -306,10 +316,13 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
|
||||
goto out;
|
||||
}
|
||||
log_debug("Read %s %smetadata (%u) from %s at %" PRIu64 " size %"
|
||||
PRIu64, vg->name, precommit ? "pre-commit " : "",
|
||||
PRIu64, vg->name, precommitted ? "pre-commit " : "",
|
||||
vg->seqno, dev_name(area->dev),
|
||||
area->start + rlocn->offset, rlocn->size);
|
||||
|
||||
if (precommitted)
|
||||
vg->status |= PRECOMMITTED;
|
||||
|
||||
out:
|
||||
if (!dev_close(area->dev))
|
||||
stack;
|
||||
@@ -339,13 +352,14 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
struct metadata_area *mda)
|
||||
{
|
||||
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
||||
struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
|
||||
struct raw_locn *rlocn;
|
||||
struct mda_header *mdah;
|
||||
struct pv_list *pvl;
|
||||
int r = 0;
|
||||
uint32_t new_wrap = 0, old_wrap = 0;
|
||||
char *buf = NULL;
|
||||
int found = 0;
|
||||
int noprecommit = 0;
|
||||
|
||||
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
@@ -368,14 +382,18 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
goto out;
|
||||
}
|
||||
|
||||
rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0);
|
||||
rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit);
|
||||
mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
|
||||
|
||||
if (!(mdac->rlocn.size = text_vg_export_raw(vg, "", &buf))) {
|
||||
if (!fidtc->raw_metadata_buf &&
|
||||
!(fidtc->raw_metadata_buf_size =
|
||||
text_vg_export_raw(vg, "", &fidtc->raw_metadata_buf))) {
|
||||
log_error("VG %s metadata writing failed", vg->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
mdac->rlocn.size = fidtc->raw_metadata_buf_size;
|
||||
|
||||
if (mdac->rlocn.offset + mdac->rlocn.size > mdah->size)
|
||||
new_wrap = (mdac->rlocn.offset + mdac->rlocn.size) - mdah->size;
|
||||
|
||||
@@ -398,7 +416,8 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
|
||||
/* Write text out, circularly */
|
||||
if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
|
||||
(size_t) (mdac->rlocn.size - new_wrap), buf)) {
|
||||
(size_t) (mdac->rlocn.size - new_wrap),
|
||||
fidtc->raw_metadata_buf)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -411,18 +430,20 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
if (!dev_write(mdac->area.dev,
|
||||
mdac->area.start + MDA_HEADER_SIZE,
|
||||
(size_t) new_wrap,
|
||||
buf + mdac->rlocn.size - new_wrap)) {
|
||||
fidtc->raw_metadata_buf +
|
||||
mdac->rlocn.size - new_wrap)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
mdac->rlocn.checksum = calc_crc(INITIAL_CRC, buf,
|
||||
mdac->rlocn.checksum = calc_crc(INITIAL_CRC, fidtc->raw_metadata_buf,
|
||||
(uint32_t) (mdac->rlocn.size -
|
||||
new_wrap));
|
||||
if (new_wrap)
|
||||
mdac->rlocn.checksum = calc_crc(mdac->rlocn.checksum,
|
||||
buf + mdac->rlocn.size -
|
||||
fidtc->raw_metadata_buf +
|
||||
mdac->rlocn.size -
|
||||
new_wrap, new_wrap);
|
||||
|
||||
r = 1;
|
||||
@@ -431,8 +452,6 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
if (!r && !dev_close(mdac->area.dev))
|
||||
stack;
|
||||
|
||||
if (buf)
|
||||
dbg_free(buf);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -442,11 +461,13 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
||||
int precommit)
|
||||
{
|
||||
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
||||
struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
|
||||
struct mda_header *mdah;
|
||||
struct raw_locn *rlocn;
|
||||
struct pv_list *pvl;
|
||||
int r = 0;
|
||||
int found = 0;
|
||||
int noprecommit = 0;
|
||||
|
||||
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
@@ -464,23 +485,41 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0))) {
|
||||
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
|
||||
mdah->raw_locns[0].offset = 0;
|
||||
mdah->raw_locns[0].size = 0;
|
||||
mdah->raw_locns[0].checksum = 0;
|
||||
mdah->raw_locns[1].offset = 0;
|
||||
mdah->raw_locns[1].size = 0;
|
||||
mdah->raw_locns[1].checksum = 0;
|
||||
mdah->raw_locns[2].offset = 0;
|
||||
mdah->raw_locns[2].size = 0;
|
||||
mdah->raw_locns[2].checksum = 0;
|
||||
rlocn = &mdah->raw_locns[0];
|
||||
}
|
||||
|
||||
if (precommit)
|
||||
rlocn++;
|
||||
else {
|
||||
/* If not precommitting, wipe the precommitted rlocn */
|
||||
mdah->raw_locns[1].offset = 0;
|
||||
mdah->raw_locns[1].size = 0;
|
||||
mdah->raw_locns[1].checksum = 0;
|
||||
}
|
||||
|
||||
rlocn->offset = mdac->rlocn.offset;
|
||||
rlocn->size = mdac->rlocn.size;
|
||||
rlocn->checksum = mdac->rlocn.checksum;
|
||||
/* Is there new metadata to commit? */
|
||||
if (mdac->rlocn.size) {
|
||||
rlocn->offset = mdac->rlocn.offset;
|
||||
rlocn->size = mdac->rlocn.size;
|
||||
rlocn->checksum = mdac->rlocn.checksum;
|
||||
log_debug("%sCommitting %s metadata (%u) to %s header at %"
|
||||
PRIu64, precommit ? "Pre-" : "", vg->name, vg->seqno,
|
||||
dev_name(mdac->area.dev), mdac->area.start);
|
||||
} else
|
||||
log_debug("Wiping pre-committed %s metadata from %s "
|
||||
"header at %" PRIu64, vg->name,
|
||||
dev_name(mdac->area.dev), mdac->area.start);
|
||||
|
||||
log_debug("%sCommitting %s metadata (%u) to %s header at %" PRIu64,
|
||||
precommit ? "Pre-" : "", vg->name, vg->seqno,
|
||||
dev_name(mdac->area.dev), mdac->area.start);
|
||||
if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
|
||||
mdah)) {
|
||||
log_error("Failed to write metadata area header");
|
||||
@@ -490,8 +529,14 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
if (!precommit && !dev_close(mdac->area.dev))
|
||||
stack;
|
||||
if (!precommit) {
|
||||
if (!dev_close(mdac->area.dev))
|
||||
stack;
|
||||
if (fidtc->raw_metadata_buf) {
|
||||
dm_free(fidtc->raw_metadata_buf);
|
||||
fidtc->raw_metadata_buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -528,10 +573,9 @@ static int _vg_revert_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
if (!found)
|
||||
return 1;
|
||||
|
||||
if (!dev_close(mdac->area.dev))
|
||||
stack;
|
||||
|
||||
return 1;
|
||||
/* Wipe pre-committed metadata */
|
||||
mdac->rlocn.size = 0;
|
||||
return _vg_commit_raw_rlocn(fid, vg, mda, 0);
|
||||
}
|
||||
|
||||
static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
@@ -541,6 +585,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
struct mda_header *mdah;
|
||||
struct raw_locn *rlocn;
|
||||
int r = 0;
|
||||
int noprecommit = 0;
|
||||
|
||||
if (!dev_open(mdac->area.dev)) {
|
||||
stack;
|
||||
@@ -552,7 +597,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0))) {
|
||||
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
|
||||
rlocn = &mdah->raw_locns[0];
|
||||
mdah->raw_locns[1].offset = 0;
|
||||
}
|
||||
@@ -595,7 +640,7 @@ static struct volume_group *_vg_read_file_name(struct format_instance *fid,
|
||||
* check that it contains the correct volume group.
|
||||
*/
|
||||
if (vgname && strcmp(vgname, vg->name)) {
|
||||
pool_free(fid->fmt->cmd->mem, vg);
|
||||
dm_pool_free(fid->fmt->cmd->mem, vg);
|
||||
log_err("'%s' does not contain volume group '%s'.",
|
||||
read_path, vgname);
|
||||
return NULL;
|
||||
@@ -619,8 +664,14 @@ static struct volume_group *_vg_read_precommit_file(struct format_instance *fid,
|
||||
struct metadata_area *mda)
|
||||
{
|
||||
struct text_context *tc = (struct text_context *) mda->metadata_locn;
|
||||
struct volume_group *vg;
|
||||
|
||||
return _vg_read_file_name(fid, vgname, tc->path_edit);
|
||||
if ((vg = _vg_read_file_name(fid, vgname, tc->path_edit)))
|
||||
vg->status |= PRECOMMITTED;
|
||||
else
|
||||
vg = _vg_read_file_name(fid, vgname, tc->path_live);
|
||||
|
||||
return vg;
|
||||
}
|
||||
|
||||
static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
|
||||
@@ -666,7 +717,7 @@ static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fsync(fd)) {
|
||||
if (fsync(fd) && (errno != EROFS) && (errno != EINVAL)) {
|
||||
log_sys_error("fsync", tc->path_edit);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
@@ -808,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);
|
||||
}
|
||||
|
||||
@@ -821,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;
|
||||
|
||||
@@ -888,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);
|
||||
}
|
||||
@@ -899,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));
|
||||
}
|
||||
@@ -1045,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;
|
||||
@@ -1059,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;
|
||||
}
|
||||
@@ -1160,7 +1240,7 @@ static int _add_raw(struct list *raw_list, struct device_area *dev_area)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(rl = dbg_malloc(sizeof(struct raw_list)))) {
|
||||
if (!(rl = dm_malloc(sizeof(struct raw_list)))) {
|
||||
log_error("_add_raw allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -1170,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;
|
||||
@@ -1195,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;
|
||||
}
|
||||
|
||||
@@ -1206,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;
|
||||
}
|
||||
@@ -1234,11 +1315,11 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
/* Add copy of mdas to supplied list */
|
||||
list_iterate_items(mda, &info->mdas) {
|
||||
mdac = (struct mda_context *) mda->metadata_locn;
|
||||
if (!(mda_new = pool_alloc(fmt->cmd->mem, sizeof(*mda_new)))) {
|
||||
if (!(mda_new = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda_new)))) {
|
||||
log_error("metadata_area allocation failed");
|
||||
return 0;
|
||||
}
|
||||
if (!(mdac_new = pool_alloc(fmt->cmd->mem, sizeof(*mdac_new)))) {
|
||||
if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac_new)))) {
|
||||
log_error("metadata_area allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -1251,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;
|
||||
}
|
||||
@@ -1262,7 +1343,7 @@ static void _free_dirs(struct list *dir_list)
|
||||
|
||||
list_iterate_safe(dl, tmp, dir_list) {
|
||||
list_del(dl);
|
||||
dbg_free(dl);
|
||||
dm_free(dl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1272,19 +1353,19 @@ static void _free_raws(struct list *raw_list)
|
||||
|
||||
list_iterate_safe(rl, tmp, raw_list) {
|
||||
list_del(rl);
|
||||
dbg_free(rl);
|
||||
dm_free(rl);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
_free_raws(&((struct mda_lists *) fmt->private)->raws);
|
||||
dbg_free(fmt->private);
|
||||
dm_free(fmt->private);
|
||||
}
|
||||
|
||||
dbg_free((void *) fmt);
|
||||
dm_free((void *) fmt);
|
||||
}
|
||||
|
||||
static struct metadata_area_ops _metadata_text_file_ops = {
|
||||
@@ -1313,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,
|
||||
@@ -1330,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) {
|
||||
@@ -1361,13 +1442,13 @@ static int _pv_setup(const struct format_type *fmt,
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
if (!(mda_new = pool_alloc(fmt->cmd->mem,
|
||||
if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
|
||||
sizeof(*mda_new)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(mdac_new = pool_alloc(fmt->cmd->mem,
|
||||
if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
|
||||
sizeof(*mdac_new)))) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -1398,11 +1479,13 @@ 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;
|
||||
struct text_fid_context *fidtc;
|
||||
struct metadata_area *mda, *mda_new;
|
||||
struct mda_context *mdac, *mdac_new;
|
||||
struct dir_list *dl;
|
||||
@@ -1412,17 +1495,25 @@ static struct format_instance *_create_text_instance(const struct format_type
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
struct lvmcache_info *info;
|
||||
|
||||
if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
log_error("Couldn't allocate format instance object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fid->fmt = fmt;
|
||||
if (!(fidtc = (struct text_fid_context *)
|
||||
dm_pool_zalloc(fmt->cmd->mem,sizeof(*fidtc)))) {
|
||||
log_error("Couldn't allocate text_fid_context.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fidtc->raw_metadata_buf = NULL;
|
||||
fid->private = (void *) fidtc;
|
||||
|
||||
fid->fmt = fmt;
|
||||
list_init(&fid->metadata_areas);
|
||||
|
||||
if (!vgname) {
|
||||
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1441,7 +1532,7 @@ static struct format_instance *_create_text_instance(const struct format_type
|
||||
}
|
||||
|
||||
context = create_text_context(fmt->cmd, path, NULL);
|
||||
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1457,12 +1548,12 @@ static struct format_instance *_create_text_instance(const struct format_type
|
||||
if (!_raw_holds_vgname(fid, &rl->dev_area, vgname))
|
||||
continue;
|
||||
|
||||
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(mdac = pool_alloc(fmt->cmd->mem, sizeof(*mdac)))) {
|
||||
if (!(mdac = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1476,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;
|
||||
}
|
||||
@@ -1487,13 +1578,13 @@ static struct format_instance *_create_text_instance(const struct format_type
|
||||
(struct mda_context *) mda->metadata_locn;
|
||||
|
||||
/* FIXME Check it holds this VG */
|
||||
if (!(mda_new = pool_alloc(fmt->cmd->mem,
|
||||
if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
|
||||
sizeof(*mda_new)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(mdac_new = pool_alloc(fmt->cmd->mem,
|
||||
if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
|
||||
sizeof(*mdac_new)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
@@ -1510,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,
|
||||
@@ -1525,17 +1615,17 @@ void *create_text_context(struct cmd_context *cmd, const char *path,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(tc = pool_alloc(cmd->mem, sizeof(*tc)))) {
|
||||
if (!(tc = dm_pool_alloc(cmd->mem, sizeof(*tc)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(tc->path_live = pool_strdup(cmd->mem, path))) {
|
||||
if (!(tc->path_live = dm_pool_strdup(cmd->mem, path))) {
|
||||
stack;
|
||||
goto no_mem;
|
||||
}
|
||||
|
||||
if (!(tc->path_edit = pool_alloc(cmd->mem, strlen(path) + 5))) {
|
||||
if (!(tc->path_edit = dm_pool_alloc(cmd->mem, strlen(path) + 5))) {
|
||||
stack;
|
||||
goto no_mem;
|
||||
}
|
||||
@@ -1544,7 +1634,7 @@ void *create_text_context(struct cmd_context *cmd, const char *path,
|
||||
if (!desc)
|
||||
desc = "";
|
||||
|
||||
if (!(tc->desc = pool_strdup(cmd->mem, desc))) {
|
||||
if (!(tc->desc = dm_pool_strdup(cmd->mem, desc))) {
|
||||
stack;
|
||||
goto no_mem;
|
||||
}
|
||||
@@ -1552,22 +1642,22 @@ void *create_text_context(struct cmd_context *cmd, const char *path,
|
||||
return (void *) tc;
|
||||
|
||||
no_mem:
|
||||
pool_free(cmd->mem, tc);
|
||||
dm_pool_free(cmd->mem, tc);
|
||||
|
||||
log_err("Couldn't allocate text format context object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -1575,7 +1665,7 @@ static int _add_dir(const char *dir, struct list *dir_list)
|
||||
struct dir_list *dl;
|
||||
|
||||
if (create_dir(dir)) {
|
||||
if (!(dl = dbg_malloc(sizeof(struct list) + strlen(dir) + 1))) {
|
||||
if (!(dl = dm_malloc(sizeof(struct list) + strlen(dir) + 1))) {
|
||||
log_error("_add_dir allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -1647,7 +1737,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
|
||||
struct config_value *cv;
|
||||
struct mda_lists *mda_lists;
|
||||
|
||||
if (!(fmt = dbg_malloc(sizeof(*fmt)))) {
|
||||
if (!(fmt = dm_malloc(sizeof(*fmt)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1657,9 +1747,9 @@ struct format_type *create_text_format(struct cmd_context *cmd)
|
||||
fmt->name = FMT_TEXT_NAME;
|
||||
fmt->alias = FMT_TEXT_ALIAS;
|
||||
fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT |
|
||||
FMT_UNLIMITED_VOLS;
|
||||
FMT_UNLIMITED_VOLS | FMT_RESIZE_PV;
|
||||
|
||||
if (!(mda_lists = dbg_malloc(sizeof(struct mda_lists)))) {
|
||||
if (!(mda_lists = dm_malloc(sizeof(struct mda_lists)))) {
|
||||
log_error("Failed to allocate dir_list");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1710,6 +1800,6 @@ struct format_type *create_text_format(struct cmd_context *cmd)
|
||||
err:
|
||||
_free_dirs(&mda_lists->dirs);
|
||||
|
||||
dbg_free(fmt);
|
||||
dm_free(fmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include "lvm-types.h"
|
||||
#include "metadata.h"
|
||||
#include "pool.h"
|
||||
|
||||
/*
|
||||
* Archives a vg config. 'retain_days' is the minimum number of
|
||||
@@ -47,15 +46,16 @@ struct labeller *text_labeller_create(const struct format_type *fmt);
|
||||
|
||||
int pvhdr_read(struct device *dev, char *buf);
|
||||
|
||||
int add_da(const struct format_type *fmt, struct pool *mem, struct list *das,
|
||||
int add_da(const struct format_type *fmt, struct dm_pool *mem, struct list *das,
|
||||
uint64_t start, uint64_t size);
|
||||
void del_das(struct list *das);
|
||||
|
||||
int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
|
||||
int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct list *mdas,
|
||||
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
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "config.h"
|
||||
#include "lvm-types.h"
|
||||
#include "metadata.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -46,8 +45,12 @@ struct text_vg_version_ops {
|
||||
int (*check_version) (struct config_tree * cf);
|
||||
struct volume_group *(*read_vg) (struct format_instance * fid,
|
||||
struct config_tree * cf);
|
||||
void (*read_desc) (struct pool * mem, 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);
|
||||
@@ -56,7 +59,7 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size);
|
||||
int read_flags(uint32_t *status, int type, struct config_value *cv);
|
||||
|
||||
int print_tags(struct list *tags, char *buffer, size_t size);
|
||||
int read_tags(struct pool *mem, struct list *tags, struct config_value *cv);
|
||||
int read_tags(struct dm_pool *mem, struct list *tags, struct config_value *cv);
|
||||
|
||||
int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp);
|
||||
int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf);
|
||||
@@ -71,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
|
||||
|
||||
@@ -16,15 +16,60 @@
|
||||
#include "lib.h"
|
||||
#include "metadata.h"
|
||||
#include "import-export.h"
|
||||
#include "pool.h"
|
||||
#include "display.h"
|
||||
#include "hash.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
|
||||
/* 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,
|
||||
@@ -38,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;
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
#include "lib.h"
|
||||
#include "metadata.h"
|
||||
#include "import-export.h"
|
||||
#include "pool.h"
|
||||
#include "display.h"
|
||||
#include "hash.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
#include "lv_alloc.h"
|
||||
@@ -26,10 +24,10 @@
|
||||
#include "segtype.h"
|
||||
#include "text_import.h"
|
||||
|
||||
typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
|
||||
typedef int (*section_fn) (struct format_instance * fid, struct dm_pool * mem,
|
||||
struct volume_group * vg, struct config_node * pvn,
|
||||
struct config_node * vgn,
|
||||
struct hash_table * pv_hash);
|
||||
struct dm_hash_table * pv_hash);
|
||||
|
||||
#define _read_int32(root, path, result) \
|
||||
get_config_uint32(root, path, (uint32_t *) result)
|
||||
@@ -111,16 +109,16 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_pv(struct format_instance *fid, struct pool *mem,
|
||||
static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *pvn,
|
||||
struct config_node *vgn, struct hash_table *pv_hash)
|
||||
struct config_node *vgn, struct dm_hash_table *pv_hash)
|
||||
{
|
||||
struct physical_volume *pv;
|
||||
struct pv_list *pvl;
|
||||
struct config_node *cn;
|
||||
|
||||
if (!(pvl = pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = pool_zalloc(mem, sizeof(*pvl->pv)))) {
|
||||
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -131,7 +129,7 @@ static int _read_pv(struct format_instance *fid, struct pool *mem,
|
||||
* Add the pv to the pv hash for quick lookup when we read
|
||||
* the lv segments.
|
||||
*/
|
||||
if (!hash_insert(pv_hash, pvn->key, pv)) {
|
||||
if (!dm_hash_insert(pv_hash, pvn->key, pv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -164,11 +162,13 @@ static int _read_pv(struct format_instance *fid, struct pool *mem,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pv->vg_name = pool_strdup(mem, vg->name))) {
|
||||
if (!(pv->vg_name = dm_pool_strdup(mem, vg->name))) {
|
||||
stack;
|
||||
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;
|
||||
@@ -236,9 +236,9 @@ static void _insert_segment(struct logical_volume *lv, struct lv_segment *seg)
|
||||
list_add(&lv->segments, &seg->list);
|
||||
}
|
||||
|
||||
static int _read_segment(struct pool *mem, struct volume_group *vg,
|
||||
static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct logical_volume *lv, struct config_node *sn,
|
||||
struct hash_table *pv_hash)
|
||||
struct dm_hash_table *pv_hash)
|
||||
{
|
||||
uint32_t area_count = 0u;
|
||||
struct lv_segment *seg;
|
||||
@@ -323,7 +323,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
|
||||
}
|
||||
|
||||
int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
|
||||
const struct config_node *cn, struct hash_table *pv_hash,
|
||||
const struct config_node *cn, struct dm_hash_table *pv_hash,
|
||||
uint32_t flags)
|
||||
{
|
||||
unsigned int s;
|
||||
@@ -359,7 +359,7 @@ int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
|
||||
}
|
||||
|
||||
/* FIXME Cope if LV not yet read in */
|
||||
if ((pv = hash_lookup(pv_hash, cv->v.str))) {
|
||||
if ((pv = dm_hash_lookup(pv_hash, cv->v.str))) {
|
||||
if (!set_lv_segment_area_pv(seg, s, pv, cv->next->v.i)) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -389,9 +389,9 @@ int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_segments(struct pool *mem, struct volume_group *vg,
|
||||
static int _read_segments(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct logical_volume *lv, struct config_node *lvn,
|
||||
struct hash_table *pv_hash)
|
||||
struct dm_hash_table *pv_hash)
|
||||
{
|
||||
struct config_node *sn;
|
||||
int count = 0, seg_count;
|
||||
@@ -430,7 +430,7 @@ static int _read_segments(struct pool *mem, struct volume_group *vg,
|
||||
/*
|
||||
* Check there are no gaps or overlaps in the lv.
|
||||
*/
|
||||
if (!check_lv_segments(lv)) {
|
||||
if (!check_lv_segments(lv, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -446,23 +446,23 @@ static int _read_segments(struct pool *mem, struct volume_group *vg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_lvnames(struct format_instance *fid, struct pool *mem,
|
||||
static int _read_lvnames(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *lvn,
|
||||
struct config_node *vgn, struct hash_table *pv_hash)
|
||||
struct config_node *vgn, struct dm_hash_table *pv_hash)
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
struct lv_list *lvl;
|
||||
struct config_node *cn;
|
||||
|
||||
if (!(lvl = pool_zalloc(mem, sizeof(*lvl))) ||
|
||||
!(lvl->lv = pool_zalloc(mem, sizeof(*lvl->lv)))) {
|
||||
if (!(lvl = dm_pool_zalloc(mem, sizeof(*lvl))) ||
|
||||
!(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
lv = lvl->lv;
|
||||
|
||||
if (!(lv->name = pool_strdup(mem, lvn->key))) {
|
||||
if (!(lv->name = dm_pool_strdup(mem, lvn->key))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -521,9 +521,9 @@ static int _read_lvnames(struct format_instance *fid, struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_lvsegs(struct format_instance *fid, struct pool *mem,
|
||||
static int _read_lvsegs(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *lvn,
|
||||
struct config_node *vgn, struct hash_table *pv_hash)
|
||||
struct config_node *vgn, struct dm_hash_table *pv_hash)
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
struct lv_list *lvl;
|
||||
@@ -586,9 +586,9 @@ static int _read_lvsegs(struct format_instance *fid, struct pool *mem,
|
||||
|
||||
static int _read_sections(struct format_instance *fid,
|
||||
const char *section, section_fn fn,
|
||||
struct pool *mem,
|
||||
struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *vgn,
|
||||
struct hash_table *pv_hash, int optional)
|
||||
struct dm_hash_table *pv_hash, int optional)
|
||||
{
|
||||
struct config_node *n;
|
||||
|
||||
@@ -616,8 +616,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
{
|
||||
struct config_node *vgn, *cn;
|
||||
struct volume_group *vg;
|
||||
struct hash_table *pv_hash = NULL;
|
||||
struct pool *mem = fid->fmt->cmd->mem;
|
||||
struct dm_hash_table *pv_hash = NULL;
|
||||
struct dm_pool *mem = fid->fmt->cmd->mem;
|
||||
|
||||
/* skip any top-level values */
|
||||
for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) ;
|
||||
@@ -627,7 +627,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(vg = pool_zalloc(mem, sizeof(*vg)))) {
|
||||
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -637,12 +637,12 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
/* eg Set to instance of fmt1 here if reading a format1 backup? */
|
||||
vg->fid = fid;
|
||||
|
||||
if (!(vg->name = pool_strdup(mem, vgn->key))) {
|
||||
if (!(vg->name = dm_pool_strdup(mem, vgn->key))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(vg->system_id = pool_zalloc(mem, NAME_LEN))) {
|
||||
if (!(vg->system_id = dm_pool_zalloc(mem, NAME_LEN))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -722,7 +722,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
* The pv hash memoises the pv section names -> pv
|
||||
* structures.
|
||||
*/
|
||||
if (!(pv_hash = hash_create(32))) {
|
||||
if (!(pv_hash = dm_hash_create(32))) {
|
||||
log_error("Couldn't create hash table.");
|
||||
goto bad;
|
||||
}
|
||||
@@ -759,7 +759,13 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
hash_destroy(pv_hash);
|
||||
if (!fixup_imported_mirrors(vg)) {
|
||||
log_error("Failed to fixup mirror pointers after import for "
|
||||
"volume group %s.", vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
dm_hash_destroy(pv_hash);
|
||||
|
||||
if (vg->status & PARTIAL_VG) {
|
||||
vg->status &= ~LVM_WRITE;
|
||||
@@ -773,13 +779,13 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
|
||||
bad:
|
||||
if (pv_hash)
|
||||
hash_destroy(pv_hash);
|
||||
dm_hash_destroy(pv_hash);
|
||||
|
||||
pool_free(mem, vg);
|
||||
dm_pool_free(mem, vg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _read_desc(struct pool *mem,
|
||||
static void _read_desc(struct dm_pool *mem,
|
||||
struct config_tree *cft, time_t *when, char **desc)
|
||||
{
|
||||
const char *d;
|
||||
@@ -788,16 +794,65 @@ static void _read_desc(struct pool *mem,
|
||||
log_suppress(1);
|
||||
d = find_config_str(cft->root, "description", "");
|
||||
log_suppress(0);
|
||||
*desc = pool_strdup(mem, d);
|
||||
*desc = dm_pool_strdup(mem, d);
|
||||
|
||||
get_config_uint32(cft->root, "creation_time", &u);
|
||||
*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)
|
||||
|
||||
@@ -37,6 +37,8 @@ struct data_area_list {
|
||||
/* On disk */
|
||||
struct pv_header {
|
||||
uint8_t pv_uuid[ID_LEN];
|
||||
|
||||
/* This size can be overridden if PV belongs to a VG */
|
||||
uint64_t device_size_xl; /* Bytes */
|
||||
|
||||
/* NULL-terminated list of data areas followed by */
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "lib.h"
|
||||
#include "metadata.h"
|
||||
#include "import-export.h"
|
||||
#include "pool.h"
|
||||
#include "str_list.h"
|
||||
#include "lvm-string.h"
|
||||
|
||||
@@ -53,7 +52,7 @@ int print_tags(struct list *tags, char *buffer, size_t size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int read_tags(struct pool *mem, struct list *tags, struct config_value *cv)
|
||||
int read_tags(struct dm_pool *mem, struct list *tags, struct config_value *cv)
|
||||
{
|
||||
if (cv->type == CFG_EMPTY_ARRAY)
|
||||
return 1;
|
||||
@@ -64,7 +63,7 @@ int read_tags(struct pool *mem, struct list *tags, struct config_value *cv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!str_list_add(mem, tags, pool_strdup(mem, cv->v.str))) {
|
||||
if (!str_list_add(mem, tags, dm_pool_strdup(mem, cv->v.str))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ struct lv_segment;
|
||||
struct config_node;
|
||||
|
||||
int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
|
||||
const struct config_node *cn, struct hash_table *pv_hash,
|
||||
const struct config_node *cn, struct dm_hash_table *pv_hash,
|
||||
uint32_t flags);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
@@ -86,18 +86,18 @@ static int _write(struct label *label, char *buf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int add_da(const struct format_type *fmt, struct pool *mem, struct list *das,
|
||||
int add_da(const struct format_type *fmt, struct dm_pool *mem, struct list *das,
|
||||
uint64_t start, uint64_t size)
|
||||
{
|
||||
struct data_area_list *dal;
|
||||
|
||||
if (!mem) {
|
||||
if (!(dal = dbg_malloc(sizeof(*dal)))) {
|
||||
if (!(dal = dm_malloc(sizeof(*dal)))) {
|
||||
log_error("struct data_area_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!(dal = pool_alloc(mem, sizeof(*dal)))) {
|
||||
if (!(dal = dm_pool_alloc(mem, sizeof(*dal)))) {
|
||||
log_error("struct data_area_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -119,11 +119,11 @@ void del_das(struct list *das)
|
||||
list_iterate_safe(dah, tmp, das) {
|
||||
da = list_item(dah, struct data_area_list);
|
||||
list_del(&da->list);
|
||||
dbg_free(da);
|
||||
dm_free(da);
|
||||
}
|
||||
}
|
||||
|
||||
int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
|
||||
int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct list *mdas,
|
||||
struct device *dev, uint64_t start, uint64_t size)
|
||||
{
|
||||
/* FIXME List size restricted by pv_header SECTOR_SIZE */
|
||||
@@ -132,23 +132,23 @@ int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
|
||||
struct mda_context *mdac;
|
||||
|
||||
if (!mem) {
|
||||
if (!(mdal = dbg_malloc(sizeof(struct metadata_area)))) {
|
||||
if (!(mdal = dm_malloc(sizeof(struct metadata_area)))) {
|
||||
log_error("struct mda_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(mdac = dbg_malloc(sizeof(struct mda_context)))) {
|
||||
if (!(mdac = dm_malloc(sizeof(struct mda_context)))) {
|
||||
log_error("struct mda_context allocation failed");
|
||||
dbg_free(mdal);
|
||||
dm_free(mdal);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!(mdal = pool_alloc(mem, sizeof(struct metadata_area)))) {
|
||||
if (!(mdal = dm_pool_alloc(mem, sizeof(struct metadata_area)))) {
|
||||
log_error("struct mda_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(mdac = pool_alloc(mem, sizeof(struct mda_context)))) {
|
||||
if (!(mdac = dm_pool_alloc(mem, sizeof(struct mda_context)))) {
|
||||
log_error("struct mda_context allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -173,20 +173,20 @@ void del_mdas(struct list *mdas)
|
||||
|
||||
list_iterate_safe(mdah, tmp, mdas) {
|
||||
mda = list_item(mdah, struct metadata_area);
|
||||
dbg_free(mda->metadata_locn);
|
||||
dm_free(mda->metadata_locn);
|
||||
list_del(&mda->list);
|
||||
dbg_free(mda);
|
||||
dm_free(mda);
|
||||
}
|
||||
}
|
||||
|
||||
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,26 +258,26 @@ 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)
|
||||
{
|
||||
dbg_free(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)
|
||||
{
|
||||
struct labeller *l;
|
||||
|
||||
if (!(l = dbg_malloc(sizeof(*l)))) {
|
||||
if (!(l = dm_malloc(sizeof(*l)))) {
|
||||
log_err("Couldn't allocate labeller object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "label.h"
|
||||
#include "list.h"
|
||||
#include "crc.h"
|
||||
#include "xlate.h"
|
||||
#include "lvmcache.h"
|
||||
@@ -46,7 +45,7 @@ static struct labeller_i *_alloc_li(const char *name, struct labeller *l)
|
||||
|
||||
len = sizeof(*li) + strlen(name) + 1;
|
||||
|
||||
if (!(li = dbg_malloc(len))) {
|
||||
if (!(li = dm_malloc(len))) {
|
||||
log_error("Couldn't allocate memory for labeller list object.");
|
||||
return NULL;
|
||||
}
|
||||
@@ -59,7 +58,7 @@ static struct labeller_i *_alloc_li(const char *name, struct labeller *l)
|
||||
|
||||
static void _free_li(struct labeller_i *li)
|
||||
{
|
||||
dbg_free(li);
|
||||
dm_free(li);
|
||||
}
|
||||
|
||||
int label_init(void)
|
||||
@@ -118,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;
|
||||
@@ -185,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;
|
||||
}
|
||||
|
||||
@@ -273,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, §or))) {
|
||||
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, §or)))
|
||||
goto_out;
|
||||
|
||||
if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result)
|
||||
(*result)->sector = sector;
|
||||
|
||||
out:
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -336,31 +337,48 @@ 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, §or))) {
|
||||
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, §or)))
|
||||
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)
|
||||
{
|
||||
label->labeller->ops->destroy_label(label->labeller, label);
|
||||
dbg_free(label);
|
||||
dm_free(label);
|
||||
}
|
||||
|
||||
struct label *label_create(struct labeller *labeller)
|
||||
{
|
||||
struct label *label;
|
||||
|
||||
if (!(label = dbg_malloc(sizeof(*label)))) {
|
||||
if (!(label = dm_malloc(sizeof(*label)))) {
|
||||
log_error("label allocaction failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ static int _send_request(char *inbuf, int inlen, char **retbuf)
|
||||
|
||||
/* Allocate buffer */
|
||||
buflen = len + outheader->arglen;
|
||||
*retbuf = dbg_malloc(buflen);
|
||||
*retbuf = dm_malloc(buflen);
|
||||
if (!*retbuf) {
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
@@ -236,7 +236,7 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
||||
* With an extra pair of INTs on the front to sanity
|
||||
* check the pointer when we are given it back to free
|
||||
*/
|
||||
outptr = dbg_malloc(sizeof(lvm_response_t) * num_responses +
|
||||
outptr = dm_malloc(sizeof(lvm_response_t) * num_responses +
|
||||
sizeof(int) * 2);
|
||||
if (!outptr) {
|
||||
errno = ENOMEM;
|
||||
@@ -259,12 +259,12 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
||||
rarray[i].status = *(int *) inptr;
|
||||
inptr += sizeof(int);
|
||||
|
||||
rarray[i].response = dbg_malloc(strlen(inptr) + 1);
|
||||
rarray[i].response = dm_malloc(strlen(inptr) + 1);
|
||||
if (rarray[i].response == NULL) {
|
||||
/* Free up everything else and return error */
|
||||
int j;
|
||||
for (j = 0; j < i; j++)
|
||||
dbg_free(rarray[i].response);
|
||||
dm_free(rarray[i].response);
|
||||
free(outptr);
|
||||
errno = ENOMEM;
|
||||
status = -1;
|
||||
@@ -281,7 +281,7 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
||||
|
||||
out:
|
||||
if (retbuf)
|
||||
dbg_free(retbuf);
|
||||
dm_free(retbuf);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -302,10 +302,10 @@ static int _cluster_free_request(lvm_response_t * response)
|
||||
num = ptr[1];
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
dbg_free(response[i].response);
|
||||
dm_free(response[i].response);
|
||||
}
|
||||
|
||||
dbg_free(ptr);
|
||||
dm_free(ptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -327,8 +327,11 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
|
||||
args = alloca(len);
|
||||
strcpy(args + 2, name);
|
||||
|
||||
args[0] = flags & 0xBF; /* Maskoff LOCAL flag */
|
||||
args[1] = 0; /* Not used now */
|
||||
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
|
||||
@@ -339,7 +342,8 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
|
||||
*/
|
||||
if (cmd == CLVMD_CMD_LOCK_VG ||
|
||||
(flags & LCK_TYPE_MASK) == LCK_EXCL ||
|
||||
(flags & LCK_LOCAL))
|
||||
(flags & LCK_LOCAL) ||
|
||||
!(flags & LCK_CLUSTER_VG))
|
||||
node = ".";
|
||||
|
||||
status = _cluster_request(cmd, node, args, len,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ static int _release_lock(const char *file, int unlock)
|
||||
if (close(ll->lf) < 0)
|
||||
log_sys_error("close", ll->res);
|
||||
|
||||
dbg_free(ll->res);
|
||||
dbg_free(llh);
|
||||
dm_free(ll->res);
|
||||
dm_free(llh);
|
||||
|
||||
if (file)
|
||||
return 1;
|
||||
@@ -150,11 +150,11 @@ static int _lock_file(const char *file, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(ll = dbg_malloc(sizeof(struct lock_list))))
|
||||
if (!(ll = dm_malloc(sizeof(struct lock_list))))
|
||||
return 0;
|
||||
|
||||
if (!(ll->res = dbg_strdup(file))) {
|
||||
dbg_free(ll);
|
||||
if (!(ll->res = dm_strdup(file))) {
|
||||
dm_free(ll);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -197,8 +197,8 @@ static int _lock_file(const char *file, int flags)
|
||||
return 1;
|
||||
|
||||
err:
|
||||
dbg_free(ll->res);
|
||||
dbg_free(ll);
|
||||
dm_free(ll->res);
|
||||
dm_free(ll);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
break;
|
||||
case LCK_READ:
|
||||
log_debug("Locking LV %s (R)", resource);
|
||||
if (!lv_activate_with_filter(cmd, resource))
|
||||
if (!lv_activate_with_filter(cmd, resource, 0))
|
||||
return 0;
|
||||
break;
|
||||
case LCK_WRITE:
|
||||
@@ -253,7 +253,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
break;
|
||||
case LCK_EXCL:
|
||||
log_debug("Locking LV %s (EX)", resource);
|
||||
if (!lv_activate_with_filter(cmd, resource))
|
||||
if (!lv_activate_with_filter(cmd, resource, 1))
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -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;
|
||||
@@ -268,7 +268,7 @@ int resume_lvs(struct cmd_context *cmd, struct list *lvs)
|
||||
struct lv_list *lvl;
|
||||
|
||||
list_iterate_items(lvl, lvs)
|
||||
resume_lv(cmd, lvl->lv->lvid.s);
|
||||
resume_lv(cmd, lvl->lv);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -280,11 +280,11 @@ int suspend_lvs(struct cmd_context *cmd, struct list *lvs)
|
||||
struct lv_list *lvl;
|
||||
|
||||
list_iterate_items(lvl, lvs) {
|
||||
if (!suspend_lv(cmd, lvl->lv->lvid.s)) {
|
||||
if (!suspend_lv(cmd, lvl->lv)) {
|
||||
log_error("Failed to suspend %s", lvl->lv->name);
|
||||
list_uniterate(lvh, lvs, &lvl->list) {
|
||||
lvl = list_item(lvh, struct lv_list);
|
||||
resume_lv(cmd, lvl->lv->lvid.s);
|
||||
resume_lv(cmd, lvl->lv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -301,11 +301,11 @@ int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs)
|
||||
struct lv_list *lvl;
|
||||
|
||||
list_iterate_items(lvl, lvs) {
|
||||
if (!activate_lv_excl(cmd, lvl->lv->lvid.s)) {
|
||||
if (!activate_lv_excl(cmd, lvl->lv)) {
|
||||
log_error("Failed to activate %s", lvl->lv->name);
|
||||
list_uniterate(lvh, lvs, &lvl->list) {
|
||||
lvl = list_item(lvh, struct lv_list);
|
||||
activate_lv(cmd, lvl->lv->lvid.s);
|
||||
activate_lv(cmd, lvl->lv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -65,6 +65,12 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
|
||||
#define LCK_NONBLOCK 0x00000010 /* Don't block waiting for lock? */
|
||||
#define LCK_HOLD 0x00000020 /* Hold lock when lock_vol returns? */
|
||||
#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
|
||||
@@ -79,22 +85,27 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
|
||||
#define LCK_LV_ACTIVATE (LCK_LV | LCK_READ | LCK_NONBLOCK)
|
||||
#define LCK_LV_DEACTIVATE (LCK_LV | LCK_NULL | LCK_NONBLOCK)
|
||||
|
||||
#define LCK_LV_CLUSTERED(lv) \
|
||||
(((lv)->vg->status & CLUSTERED) ? LCK_CLUSTER_VG : 0)
|
||||
|
||||
#define lock_lv_vol(cmd, lv, flags) \
|
||||
lock_vol(cmd, (lv)->lvid.s, flags | LCK_LV_CLUSTERED(lv))
|
||||
|
||||
#define unlock_vg(cmd, vol) lock_vol(cmd, vol, LCK_VG_UNLOCK)
|
||||
|
||||
#define resume_lv(cmd, vol) lock_vol(cmd, vol, LCK_LV_RESUME)
|
||||
#define suspend_lv(cmd, vol) lock_vol(cmd, vol, LCK_LV_SUSPEND | LCK_HOLD)
|
||||
#define deactivate_lv(cmd, vol) lock_vol(cmd, vol, LCK_LV_DEACTIVATE)
|
||||
#define activate_lv(cmd, vol) lock_vol(cmd, vol, LCK_LV_ACTIVATE | LCK_HOLD)
|
||||
#define activate_lv_excl(cmd, vol) \
|
||||
lock_vol(cmd, vol, LCK_LV_EXCLUSIVE | LCK_HOLD)
|
||||
#define activate_lv_local(cmd, vol) \
|
||||
lock_vol(cmd, vol, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
|
||||
#define deactivate_lv_local(cmd, vol) \
|
||||
lock_vol(cmd, vol, LCK_LV_DEACTIVATE | LCK_LOCAL)
|
||||
#define resume_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_RESUME)
|
||||
#define suspend_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD)
|
||||
#define deactivate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE)
|
||||
#define activate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
|
||||
#define activate_lv_excl(cmd, lv) \
|
||||
lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD)
|
||||
#define activate_lv_local(cmd, lv) \
|
||||
lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
|
||||
#define deactivate_lv_local(cmd, lv) \
|
||||
lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
|
||||
|
||||
/* Process list of LVs */
|
||||
int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
|
||||
int resume_lvs(struct cmd_context *cmd, struct list *lvs);
|
||||
int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs);
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user