1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-08 13:44:19 +03:00

Compare commits

...

985 Commits

Author SHA1 Message Date
Alasdair Kergon
ed43dc842b A setgeometry implementation. [untested] 2006-02-20 23:55:58 +00:00
Alasdair Kergon
49d4db6cd2 post-release 2006-02-08 23:24:02 +00:00
Alasdair Kergon
ea80ab2cae post-release
fix dmeventd build
2006-02-08 23:23:19 +00:00
Alasdair Kergon
382e808b8d fix mirror log parm count 2006-02-08 14:14:13 +00:00
Alasdair Kergon
846befa7e0 release 2006-02-07 16:33:48 +00:00
Alasdair Kergon
74dd29f843 add clustered log uuid 2006-02-06 20:18:10 +00:00
Alasdair Kergon
b0473bffcb remove a dmeventd_mirror syslog message 2006-02-06 19:34:45 +00:00
Alasdair Kergon
24dd9ab1a7 Change prefix for clustered log from "clustered " to "clustered_" 2006-02-06 19:32:18 +00:00
Alasdair Kergon
49d3037e87 fix tabs 2006-02-03 21:34:11 +00:00
Alasdair Kergon
37ad2bd4e8 tweak clvmd makefile 2006-02-03 21:31:00 +00:00
Alasdair Kergon
7d7b332b02 Temporary device_exists() fixes. 2006-02-03 19:44:59 +00:00
Alasdair Kergon
ac033b8612 Use supplied full dso name. 2006-02-03 19:41:34 +00:00
Alasdair Kergon
a7b98dfe25 suspend using existing LV metadata; vgreduce then needs partial flag 2006-02-03 19:36:20 +00:00
Alasdair Kergon
7fb7c86c46 fix libdevmapper-event-mirror liblvm2cmd link search path 2006-02-03 14:48:38 +00:00
Alasdair Kergon
ed036598a9 Add exported functions to set uid, gid and mode. [Bastian Blank] 2006-02-03 14:23:22 +00:00
Alasdair Kergon
160bb70cdf Add %.so: %.a make template rule. 2006-02-02 19:16:47 +00:00
Alasdair Kergon
c2e61f3c21 autoconf LIB_SUFFIX 2006-02-02 18:39:23 +00:00
Alasdair Kergon
18218467f3 remove unnecessary 0 in format string 2006-02-02 17:23:04 +00:00
Alasdair Kergon
17e298ad2a Only do lockfs filesystem sync when suspending snapshots.
Switchover library building to use LIB_SUFFIX.
2006-01-31 14:52:30 +00:00
Alasdair Kergon
d031a374f9 Rename _log to dm_log and export.
Fix misc compile-time warnings.
2006-01-31 14:50:38 +00:00
Alasdair Kergon
55f69c98cb Add dm_tree_skip_lockfs. 2006-01-30 23:36:04 +00:00
Alasdair Kergon
71f2e4306d Tidy some comments/messages. 2006-01-27 20:52:21 +00:00
Alasdair Kergon
f8af23a025 Fix renamed dso. 2006-01-27 20:51:36 +00:00
Alasdair Kergon
4ef55a6cd3 dmeventd thread termination fix 2006-01-27 20:50:01 +00:00
Alasdair Kergon
312f866723 some init_client cleanup 2006-01-27 20:49:13 +00:00
Alasdair Kergon
0ebe1f6dec More dmeventd mirror cleanups. 2006-01-27 20:48:19 +00:00
Alasdair Kergon
2ad92e0e6e Remove avoidable dmeventd mirror forking. 2006-01-27 20:47:20 +00:00
Alasdair Kergon
ac8823cdcf Fix libdevmapper event daemon_running status. 2006-01-27 20:46:06 +00:00
Alasdair Kergon
77565f7ee4 Replace deprecated signal functions. 2006-01-27 20:45:17 +00:00
Alasdair Kergon
d656d90fa8 Use split_dm_name in dmeventd mirror code. 2006-01-27 20:43:52 +00:00
Alasdair Kergon
175b3b0834 When suspending, dmeventd deregistration needs to use existing details
not precommitted ones.
2006-01-27 20:39:37 +00:00
Alasdair Kergon
7477e6b714 Fix dmeventd sharedlib path & start tidying registration code. 2006-01-27 20:13:12 +00:00
Alasdair Kergon
cd6568db69 fix dmevent registration return codes 2006-01-27 20:01:45 +00:00
Alasdair Kergon
6aff325fb2 Add config file setting: dmeventd/mirror_library 2006-01-27 19:05:05 +00:00
Alasdair Kergon
0d603cfe9c Rename register_dev; fix missing initialisation; reduce number of ifdefs. 2006-01-27 18:38:14 +00:00
Alasdair Kergon
34a1f14a17 Fix dm_strdup debug definition. 2006-01-11 15:40:54 +00:00
Alasdair Kergon
efe1c8a070 Fix dm_strdup debug definition. 2006-01-10 22:19:41 +00:00
Alasdair Kergon
1575844344 Fix hash function to avoid using a negative array offset. 2006-01-09 20:35:24 +00:00
Alasdair Kergon
221ac1c208 vgreduce remove mirror images
adjust block_on_error version no detection for RHEL4U3
2006-01-04 18:09:52 +00:00
Alasdair Kergon
57442db759 Don't inline _find in hash.c and tidy signed/unsigned etc. 2006-01-04 16:07:27 +00:00
Alasdair Kergon
5fdb3e7cd6 Fix libdevmapper.h #endif 2006-01-04 16:05:44 +00:00
Alasdair Kergon
96f259726c Fix dmsetup version driver version 2006-01-03 20:53:57 +00:00
Alasdair Kergon
4936efba5e Always print warning if activation is disabled. 2005-12-22 16:13:38 +00:00
Alasdair Kergon
d5a3559a2f Add --mirrorsonly arg to vgreduce. (Doesn't handle mirrors yet.) 2005-12-21 21:21:45 +00:00
Alasdair Kergon
114a1c7f52 some fixes 2005-12-21 20:24:22 +00:00
Alasdair Kergon
ce5265c203 fix libdevmapper-event include 2005-12-21 19:45:16 +00:00
Alasdair Kergon
1a575d926f vgreduce replaces active LVs with error segment before removing them. 2005-12-21 18:51:50 +00:00
Alasdair Kergon
85c818a39e read/write loop fixes 2005-12-19 22:56:47 +00:00
Alasdair Kergon
4ffa2defe4 fixme 2005-12-19 22:36:04 +00:00
Alasdair Kergon
8825157fbb Change dm_tree_node_add_mirror_target_log parm order 2005-12-19 21:03:17 +00:00
Alasdair Kergon
966d608dc5 Set block_on_error parameter if available.
Add target_version.
2005-12-19 21:01:39 +00:00
Alasdair Kergon
b808c89471 Add details to format1 'Invalid LV in extent map' error message. 2005-12-19 16:28:35 +00:00
Alasdair Kergon
75d4e6490f ability to pass log flags to libdevmapper 2005-12-13 15:57:32 +00:00
Alasdair Kergon
a82775f544 Add sync, nosync and block_on_error mirror log parameters.
Add hweight32.
2005-12-13 15:49:27 +00:00
Alasdair Kergon
6a22ad0171 comments 2005-12-13 13:34:31 +00:00
Alasdair Kergon
c854e88186 comment 2005-12-13 13:32:19 +00:00
Alasdair Kergon
d02203060c Fix lvscan snapshot full display.
dmeventd fixes
2005-12-08 17:49:34 +00:00
Alasdair Kergon
cf703b0433 Fix dmeventd build. 2005-12-05 11:16:48 +00:00
Alasdair Kergon
c0197a72d3 fix exports 2005-12-02 21:00:33 +00:00
Alasdair Kergon
e5a543e283 More dmeventd support. 2005-12-02 20:35:07 +00:00
Alasdair Kergon
b8b029b7d3 Add mirror dmeventd library 2005-12-02 19:52:06 +00:00
Alasdair Kergon
370f368b1a post-release 2005-12-02 17:24:06 +00:00
Alasdair Kergon
8288b45b4f 1.02.02 2005-12-02 15:44:18 +00:00
Alasdair Kergon
fe529faf8e dmeventd 2005-12-02 15:41:14 +00:00
Alasdair Kergon
ab931b177d dmeventd updates 2005-12-02 15:39:16 +00:00
Alasdair Kergon
9aa3465513 Export dm_task_update_nodes.
Use names instead of numbers in messages when ioctls fail.
2005-12-01 23:11:41 +00:00
Alasdair Kergon
6c70fc1a6c Add some FIXMEs to libdm-event. 2005-11-30 18:35:03 +00:00
Alasdair Kergon
1ccc39962a more lvconvert mirror code 2005-11-29 18:20:23 +00:00
Alasdair Kergon
99c941fc85 Allow signed mirrors arguments.
Move create_mirror_log() into toollib.
2005-11-28 21:00:37 +00:00
Alasdair Kergon
19729fdcc2 Determine parallel PVs to avoid with ALLOC_NORMAL allocation. (untested) 2005-11-28 20:01:00 +00:00
Alasdair Kergon
02e17998ce alloc avoids parallel pvs when supplied 2005-11-24 21:23:55 +00:00
Alasdair Kergon
459e00c67a preparation for parallel_areas changes to allocation code 2005-11-24 20:58:44 +00:00
Alasdair Kergon
292f665650 Fix lv_empty. 2005-11-24 18:46:51 +00:00
Alasdair Kergon
93bbb79569 _find_parallel_space -> _find_segment_space 2005-11-24 18:00:47 +00:00
Alasdair Kergon
273e724f2b post_release 2005-11-23 18:45:30 +00:00
Alasdair Kergon
5d2615c56f post-release 2005-11-23 18:44:59 +00:00
Alasdair Kergon
bfaaf21330 2.02.01 2005-11-23 18:42:45 +00:00
Alasdair Kergon
dcb8415b7a 1.02.01 2005-11-23 18:36:33 +00:00
Alasdair Kergon
699e1c75ce Fix lvdisplay cmdline to accept snapshots. 2005-11-23 16:16:39 +00:00
Alasdair Kergon
465b6e613e Fix open RO->RW promotions. 2005-11-23 16:07:40 +00:00
Alasdair Kergon
05fa105855 Resume snapshot-origins last. 2005-11-22 20:00:35 +00:00
Alasdair Kergon
d7a0cdebe5 Remove a resolved FIXME. 2005-11-22 19:37:14 +00:00
Alasdair Kergon
b049ab31eb Suppress unnecessary resumes. 2005-11-22 19:31:20 +00:00
Alasdair Kergon
6db4dcff7a Drop leading zeros from dm_format_dev.
Suppress attempt to reload identical table.
2005-11-22 18:43:12 +00:00
Alasdair Kergon
3eeaef00ec Additional LVM- prefix matching for transitional period. 2005-11-12 22:46:48 +00:00
Alasdair Kergon
8bf4c38a00 lvcreate vg_revert 2005-11-12 22:42:08 +00:00
Alasdair Kergon
3a32b09ad1 A missing vg_revert in an error path. 2005-11-12 22:00:50 +00:00
Alasdair Kergon
6315982752 more debug fixes 2005-11-11 16:16:37 +00:00
Alasdair Kergon
374a171e82 Fix selinux compile. 2005-11-10 18:31:17 +00:00
Alasdair Kergon
fc5d801f91 fix debug linking 2005-11-10 16:33:04 +00:00
Alasdair Kergon
5146641848 post-release 2005-11-10 16:06:29 +00:00
Alasdair Kergon
cdd0ac42cf pre-release 2005-11-10 15:27:19 +00:00
Alasdair Kergon
e5895500a2 remove a debugging line 2005-11-10 15:17:54 +00:00
Alasdair Kergon
9cb4dde3fa Extend allocation areas to avoid overflow with contiguous with other PVs.
Another pvmove fix.
2005-11-10 14:45:39 +00:00
Patrick Caulfield
3c2a4370a5 Make it compile with debug enabled. 2005-11-10 08:49:29 +00:00
Alasdair Kergon
e7a360dd6f revert - alternative pvmove fix, disabling preloading completely for now 2005-11-09 23:57:40 +00:00
Alasdair Kergon
c814c2fd35 workaround for pvmove with new activation code 2005-11-09 23:56:36 +00:00
Alasdair Kergon
fefa7fe262 more mirror fixing 2005-11-09 18:13:10 +00:00
Alasdair Kergon
26f01a29d1 some fixes for mirrors 2005-11-09 17:32:31 +00:00
Alasdair Kergon
169d4090ab fix last checkin 2005-11-09 15:41:42 +00:00
Alasdair Kergon
0b43754d60 rename deptree 2005-11-09 14:10:50 +00:00
Alasdair Kergon
8b3b26b813 rename deptree 2005-11-09 13:08:41 +00:00
Alasdair Kergon
5426af4f81 rename deptree 2005-11-09 13:05:17 +00:00
Alasdair Kergon
4e2c3a579d xen xvd 2005-11-09 12:47:16 +00:00
Patrick Caulfield
5ae2693241 Use hash functions in libdevmapper. 2005-11-09 09:24:10 +00:00
Alasdair Kergon
41c86b0d19 Replacement activation code. [Don't use this yet!] 2005-11-08 22:52:26 +00:00
Alasdair Kergon
40788e8c3d New activation code. [Not ready to be used yet.] 2005-11-08 22:50:11 +00:00
Alasdair Kergon
0d29120033 precommitted flag 2005-10-31 20:18:50 +00:00
Alasdair Kergon
4be598f865 Clear up precommitted metadata better on disk after use.
[Some activation-related features will stop working for a while now.
Some types of activation are getting split into two steps, with the
first step using the precommitted metadata.]
2005-10-31 20:15:28 +00:00
Alasdair Kergon
558a6d509e pvresize man 2005-10-31 15:49:07 +00:00
Alasdair Kergon
75cd02aad2 revert unfinished change 2005-10-31 15:46:29 +00:00
Alasdair Kergon
e4c4451482 missing vg_revert 2005-10-31 15:43:11 +00:00
Alasdair Kergon
0671632477 A pvresize implementation (Zak Kipling). 2005-10-31 02:37:29 +00:00
Alasdair Kergon
54c230c264 reorder commit 2005-10-28 14:38:20 +00:00
Alasdair Kergon
64ba878eda more mirror library functions 2005-10-28 12:48:50 +00:00
Alasdair Kergon
01acd6dd76 Fix contiguous allocation when there are no preceding segments. 2005-10-27 22:21:10 +00:00
Alasdair Kergon
9d819b52d3 Fix contiguous allocation without preceding segments. 2005-10-27 22:20:33 +00:00
Alasdair Kergon
37bac5cdc9 Fix new mirror_seg pointer. 2005-10-27 21:51:28 +00:00
Alasdair Kergon
78c718c591 Add mirror_seg pointer to lv_segment struct. (incomplete & untested) 2005-10-27 19:58:22 +00:00
Alasdair Kergon
284b8bf6ca Only keep a device open if it's known to belong to a locked VG. 2005-10-27 17:45:34 +00:00
Alasdair Kergon
5a5084b837 Only keep devices open if known to belong to a locked VG now. 2005-10-27 17:44:55 +00:00
Alasdair Kergon
3b8058e1f1 Export vgname_is_locked 2005-10-27 17:41:41 +00:00
Alasdair Kergon
2a3168e0d6 remove unused suspend code path 2005-10-26 19:50:00 +00:00
Alasdair Kergon
a8ac6e4a15 fix strncmps 2005-10-26 18:33:47 +00:00
Alasdair Kergon
6172cf9fba Fix incorrect checkin 2005-10-26 18:32:57 +00:00
Alasdair Kergon
b728ec3909 Fix strncmps. 2005-10-26 18:17:36 +00:00
Alasdair Kergon
61a53bbcff suppress status err mesg when LVM- uuid prefix is missing 2005-10-26 17:56:31 +00:00
Alasdair Kergon
17d13dd084 Also suppress error if device doesn't exist with DM_DEVICE_STATUS. 2005-10-26 17:51:10 +00:00
Alasdair Kergon
edcb28d591 also suppress error if device doesn't exist with STATUS 2005-10-26 17:50:15 +00:00
Alasdair Kergon
ad101119a7 remove remaining hard-coded prefix lengths 2005-10-26 17:31:12 +00:00
Alasdair Kergon
bc36676d31 Fix lvdisplay to show all mirror destinations. 2005-10-26 16:12:36 +00:00
Alasdair Kergon
d76fe120ab a missing lvid/dlid conversion 2005-10-26 15:54:50 +00:00
Alasdair Kergon
2e95949b80 attempt to cope with uuid transition 2005-10-26 15:21:13 +00:00
Alasdair Kergon
ae14d85e24 Attempt to cope with LVM- prefix transition. 2005-10-26 15:00:51 +00:00
Alasdair Kergon
fad6304c60 new suspend code 2005-10-26 14:14:30 +00:00
Alasdair Kergon
a4dd3c8ce9 switch in new suspend code (untested) 2005-10-26 14:13:52 +00:00
Alasdair Kergon
6d1a5d45e2 check parents suspended 2005-10-26 14:08:24 +00:00
Alasdair Kergon
a6c7043e03 unfinished suspend functions 2005-10-25 19:09:41 +00:00
Alasdair Kergon
bcc400dafa Use dm_is_dm_major instead of local copy.
Allow mapped devices to be used as PVs safely.
2005-10-25 19:08:21 +00:00
Alasdair Kergon
8fbedf3441 Add DEFS 2005-10-25 19:03:59 +00:00
Alasdair Kergon
2e8a9c9874 Export dm_set_selinux_context. 2005-10-25 17:30:00 +00:00
Alasdair Kergon
44fc41b3e5 Move set_selinux_context into libdevmapper 2005-10-25 17:28:46 +00:00
Alasdair Kergon
7212c20a1b Fix automatic text metadata buffer expansion (using macro). [stdarg usage bug]
Cache formatted text metadata buffer between metadata area writes.
  [improves write performance when lots of metadata area clones]
2005-10-23 00:14:48 +00:00
Alasdair Kergon
7ff142de1c Add pe_start to pvs. 2005-10-20 22:24:46 +00:00
Alasdair Kergon
e67efb199d Fix LVM2- prefix changes; export build_dlid. 2005-10-20 21:07:57 +00:00
Alasdair Kergon
20128bd04b zero suppress 2005-10-20 20:38:18 +00:00
Alasdair Kergon
c0fefdde28 fix dev no printf 2005-10-20 20:29:58 +00:00
Alasdair Kergon
f6ee160e66 Add 'LVM-' prefix to uuids. 2005-10-19 13:59:18 +00:00
Alasdair Kergon
06acc2004f cope with null uuid_prefix 2005-10-18 13:57:11 +00:00
Alasdair Kergon
43ac2ce4c8 use seg_type macro 2005-10-18 13:45:25 +00:00
Alasdair Kergon
b32bf72b5f Split lv_segment_area from lv_segment to permit extension. 2005-10-18 13:43:40 +00:00
Alasdair Kergon
c6880c957e Tidy some log mesgs. 2005-10-18 13:07:41 +00:00
Alasdair Kergon
095b71ed96 Move deactivation code into libdevmapper. 2005-10-18 12:39:20 +00:00
Alasdair Kergon
9160e496bc Add deactivation functions 2005-10-18 12:37:53 +00:00
Alasdair Kergon
2a7ac78f02 some deactivation fixes 2005-10-17 19:06:20 +00:00
Alasdair Kergon
64efa4627d Replacement deactivation code - untested. 2005-10-17 18:21:57 +00:00
Alasdair Kergon
f7e35569ce Only one dump_memory. 2005-10-17 18:21:05 +00:00
Alasdair Kergon
e8af32ec2b dm_driver_version 2005-10-17 18:05:39 +00:00
Alasdair Kergon
e092ce51f6 Attempt to load missing targets using modprobe.
Simplify dev_manager_info().
2005-10-17 18:00:02 +00:00
Alasdair Kergon
7b78edb1b7 Attempt to load missing targets using modprobe. 2005-10-17 17:56:27 +00:00
Alasdair Kergon
b332e7090e lvscan -a 2005-10-17 16:41:38 +00:00
Alasdair Kergon
67eb7723d6 Use hash, bitset, malloc, pool from libdevmapper. 2005-10-16 23:03:59 +00:00
Alasdair Kergon
251d138474 export bitset, pool, hash, malloc 2005-10-16 22:57:20 +00:00
Alasdair Kergon
1170dfac05 post-release 2005-10-16 20:09:42 +00:00
Alasdair Kergon
4157f141c7 pre-release 2005-10-16 20:06:54 +00:00
Alasdair Kergon
f569abd28a Code to build and display device dependency tree. 2005-10-16 14:33:22 +00:00
Alasdair Kergon
088f9687c0 Add dmsetup --nolockfs support for suspend/reload.
Requires kernel patches to have any effect.
Library version incremented.
2005-10-04 20:12:32 +00:00
Alasdair Kergon
e23df1f07a Refuse to run pvcreate/pvremove on devices we can't open exclusively. 2005-10-03 21:10:41 +00:00
Alasdair Kergon
c818540dfd Use ORPHAN lock definition throughout. 2005-10-03 18:16:44 +00:00
Alasdair Kergon
21365cbe1a Validate chunksize in lvcreate. 2005-09-30 22:21:01 +00:00
Alasdair Kergon
5471a80a96 Impose chunk size limitation. 2005-09-30 22:20:14 +00:00
Alasdair Kergon
d7b6fa9cd0 Reduce chunksize limit to 512k. 2005-09-29 15:50:51 +00:00
Alasdair Kergon
dfdc2e02ef post-release 2005-09-26 20:52:00 +00:00
Alasdair Kergon
893ec9a302 1.01.05 2005-09-26 20:44:12 +00:00
Alasdair Kergon
05f65c38e6 Fix chunksize field in reports. 2005-09-23 17:06:01 +00:00
Alasdair Kergon
2e9d062ec0 Don't hide snapshots from default 'lvs' output. 2005-09-23 16:22:17 +00:00
Alasdair Kergon
6b0b394e61 Resync list.h with LVM2. 2005-09-22 12:06:34 +00:00
Alasdair Kergon
25621396c9 Remember increased buffer size and use for subsequent calls. 2005-09-20 18:04:28 +00:00
Alasdair Kergon
82aa0271f3 Explicitly initialise no_open_count 2005-09-20 16:39:12 +00:00
Alasdair Kergon
653cab13f8 On 'buffer full' condition, double buffer size and repeat ioctl. [Untested] 2005-09-19 14:29:17 +00:00
Alasdair Kergon
b526f86b49 Add is_dm_major() for use in duplicate device detection in lvmcache_add(). 2005-09-16 18:53:01 +00:00
Alasdair Kergon
53c0f00888 Really switch device number in lvmcache when it says it is doing so. 2005-09-16 18:44:52 +00:00
Alasdair Kergon
f0c4d9de40 Option for bitset memory allocation using malloc as well as pool. 2005-09-16 18:40:53 +00:00
Alasdair Kergon
03ef8cec83 Don't assume exactly two mirrors when parsing mirror status 2005-09-02 16:59:46 +00:00
Alasdair Kergon
85f2a2e8c2 Suppress fsync() error message on filesystems that don't support it. 2005-09-01 18:37:22 +00:00
Alasdair Kergon
584b3e6642 Fix yes_no_prompt() error handling. 2005-08-31 19:32:10 +00:00
Alasdair Kergon
39b7ef841d add comments to example conf file to warn about common filter line mistakes 2005-08-31 15:05:47 +00:00
Alasdair Kergon
aa16a9098d Fix termination of getopt_long() option array. 2005-08-18 19:40:19 +00:00
Alasdair Kergon
7b8c2707bc lvmconf.sh 2005-08-16 20:42:28 +00:00
Alasdair Kergon
60e26a31a7 Add copyright notice to lvmconf.sh and use unique exit codes. 2005-08-16 20:38:33 +00:00
Alasdair Kergon
3473c25c14 Add format1 dev_write debug messages. 2005-08-16 19:00:55 +00:00
Patrick Caulfield
e52f022026 clvmd no longer takes out locks for non-clusteed LVs,
and non-clustered LVs are only activated on the local node.
2005-08-16 08:25:09 +00:00
Alasdair Kergon
b1a7df8e43 Add clustered VG attribute to report. 2005-08-15 23:34:11 +00:00
Alasdair Kergon
0fd2479b7c Move lvconvert parameters into struct lvconvert_params. 2005-08-15 14:10:28 +00:00
Alasdair Kergon
273857f914 Add clustered VG flag to LV lock requests. 2005-08-15 13:24:46 +00:00
Alasdair Kergon
a08b85dbc8 Change LV locking macros to take lv instead of lvid. 2005-08-15 12:00:04 +00:00
Alasdair Kergon
a0aedf299a Prepare tools to support clustered mirrors. 2005-08-14 23:18:28 +00:00
Alasdair Kergon
3c61426844 Factor out generate_log_name_format(). 2005-08-12 20:02:21 +00:00
Alasdair Kergon
786f228076 Factor out adjusted_mirror_region_size() 2005-08-12 19:23:08 +00:00
Alasdair Kergon
004da28792 Move compose_log_line() into mirror directory. 2005-08-10 17:19:46 +00:00
Alasdair Kergon
6e2be6efb6 Don't kill idling clvmd threads. 2005-08-09 17:29:04 +00:00
Alasdair Kergon
a994dfcfbc Factor out _get_library_path(). 2005-08-09 17:24:21 +00:00
Patrick Caulfield
7a8ea2ac93 Don't send a signal to kill threads that are idling nicely as it upsets them.
This seems to cure bz#159727 on SMP systems.

Alasdair, can you include this patch in the lvm2-cluster package please ?
2005-08-09 10:39:57 +00:00
Alasdair Kergon
0da3965d19 Report 'buffer full' condition with v4 ioctl as well as with v1. 2005-08-08 18:40:17 +00:00
Alasdair Kergon
885fd7bb46 aoe 2005-08-08 17:55:35 +00:00
Alasdair Kergon
08771f9c89 Recognise aoe devices. 2005-08-08 17:54:23 +00:00
Alasdair Kergon
8be48195a5 post-release 2005-08-04 02:07:34 +00:00
Alasdair Kergon
98ce2d650e update po 2005-08-04 02:02:37 +00:00
Alasdair Kergon
3af327116a Fix lvconvert PV parameter in help string. 2005-08-04 01:50:17 +00:00
Alasdair Kergon
b75434db93 fix last checkin 2005-08-04 01:29:18 +00:00
Alasdair Kergon
04e912aacd Prevent snapshots getting activated in a clustered VG. 2005-08-04 01:27:25 +00:00
Alasdair Kergon
d7be352f87 Separate out _build_dev_string. 2005-08-04 01:15:30 +00:00
Alasdair Kergon
96be3ec22c Move zero_lv to toollib. 2005-08-04 01:14:36 +00:00
Alasdair Kergon
32e7e0d790 post-release 2005-08-02 21:46:49 +00:00
Alasdair Kergon
becc320e62 update vsn 2005-08-02 18:00:32 +00:00
Alasdair Kergon
7666ed57d1 Fix dmsetup ls -j and status --target with empty table. 2005-07-29 16:11:23 +00:00
AJ Lewis
5e61d0955e fix pool format handler to work with pvseg code 2005-07-26 21:48:18 +00:00
Alasdair Kergon
e8a4662ae7 post-release 2005-07-13 19:28:09 +00:00
Alasdair Kergon
a48da3bd3b update po 2005-07-13 19:23:48 +00:00
Alasdair Kergon
5f1a5d7b99 2.01.13 2005-07-13 19:15:09 +00:00
Alasdair Kergon
3e28a9db8f Fix pvmove segment splitting.
Abstract vg_validate.
2005-07-12 19:40:59 +00:00
Alasdair Kergon
ebf6071d77 Only make one attempt at contiguous allocation. 2005-07-12 14:50:45 +00:00
Alasdair Kergon
47a35fb9fb Fix lvm1 format metadata read. 2005-06-22 15:31:29 +00:00
Alasdair Kergon
48e88aba44 fix lvm1 non-mirror lvcreate 2005-06-22 14:56:14 +00:00
Benjamin Marzinski
b85f99c140 Fixing some makesfiles, so that the correct things link against pthreads.
Also changed dmevent so that in no longer links against pthreads, and
dynamically loads libdmevent.so.  Everything seems to work just fine like this.
2005-06-14 19:06:26 +00:00
Alasdair Kergon
0a5e0e1f71 preset pl to NULL 2005-06-14 18:29:12 +00:00
Alasdair Kergon
85dc22ebb7 missing fn defs 2005-06-14 18:22:31 +00:00
Alasdair Kergon
5c21526009 post-release 2005-06-14 18:22:22 +00:00
Alasdair Kergon
14dff1cefc 2.01.12 2005-06-14 17:59:57 +00:00
Alasdair Kergon
39fbb844f9 Various allocation-related pvmove fixes. 2005-06-14 17:54:48 +00:00
Patrick Caulfield
ca4e0c973a Log an error if clvmd can't resolve a host name got from CCS
Fix potential spin loop in clvmd
2005-06-14 10:35:02 +00:00
Alasdair Kergon
ecb42bee80 post-release 2005-06-13 14:53:07 +00:00
Alasdair Kergon
674ed2a9f3 2.01.11 2005-06-13 14:43:28 +00:00
Alasdair Kergon
252daf9717 Use matchpathcon mode parameter. 2005-06-13 13:13:15 +00:00
Alasdair Kergon
196b8eaad3 Use matchpathcon mode parameter 2005-06-13 13:11:48 +00:00
Patrick Caulfield
8e526ba1bf Don't defer closing of FDs in clvmd as it can cause trouble. 2005-06-13 10:16:21 +00:00
Alasdair Kergon
19225828d9 update version 2005-06-10 22:00:44 +00:00
Alasdair Kergon
7e594126be fix configure script to reenable selinux 2005-06-10 21:57:49 +00:00
AJ Lewis
d2529e6334 o print the context along with the path when setting selinux context 2005-06-10 21:30:21 +00:00
AJ Lewis
97344f18e2 o set umask and make tempfiles a bit nicer to deal with 2005-06-10 19:10:45 +00:00
AJ Lewis
33934db629 o script to adjust items in lvm.conf file - currently only handles turning
cluster lvm on and off
2005-06-10 17:11:48 +00:00
Patrick Caulfield
6c6165c9f5 Be a bit smarter about reading stuff from the sockets 2005-06-10 09:11:01 +00:00
Benjamin Marzinski
853460b20d Timeout event implementation:
The daemon side of this is mostly the same as the patch I sent out.  To select
a timeout period different than the default and to get the timeout period,
I added two library calls, dm_set_event_timeout() and dm_get_event_timeout().
If people are against them, the other option is to tack extra arguments onto
dm_regiser_for_event() and dm_get_registered_device().  I also added a
-t option to dmevent, so people can try out timeouts.
2005-06-09 18:40:49 +00:00
Alasdair Kergon
cc4d9676c5 Remove hard-coded 64k text metadata writing restriction. 2005-06-07 11:00:07 +00:00
Alasdair Kergon
1cf1b819f4 Make VG name restrictions consistent. 2005-06-06 18:16:33 +00:00
Alasdair Kergon
f916c66d2b Introduce lvconvert. So far only removes mirror images. 2005-06-06 17:12:08 +00:00
Alasdair Kergon
550aa86b45 prevent active mirror resize for now 2005-06-03 22:26:09 +00:00
Alasdair Kergon
014e764758 Allow mirror images to be resized. 2005-06-03 19:48:19 +00:00
Alasdair Kergon
d1fc28432b Allow mirror images to have more than one segment. 2005-06-03 18:07:13 +00:00
Alasdair Kergon
879576f0a2 lvremove mirror images 2005-06-03 15:44:12 +00:00
Alasdair Kergon
69098210be Always insert an intermediate layer for mirrors.
Suppress hidden LVs from reports unless --all is given.
Use square brackets for hidden LVs in reports.
Centralise restrictions on LV names.
2005-06-03 14:49:51 +00:00
Alasdair Kergon
99df4f892d Basic support for mirrors. 2005-06-01 16:51:55 +00:00
AJ Lewis
7bc04fbad3 Change the multilog code to toggle between async and sync writes for all
log types.  This means the threaded_syslog type is no longer valid.  A new
fxn multilog_async is available to toggle between the two modes.  If an
app is compiled without pthreads and tries to use async logging, no logging
will occur while async is enabled.

dmeventd has been modified to use the new code

I'm not positive I like the way the async_logger code calls the log fxn,
but it works for now.  Suggestions for other ways to do it would be helpful
2005-05-25 21:08:36 +00:00
Alasdair Kergon
8a74ce578d Fix non-orphan pvchange -u. 2005-05-24 17:38:26 +00:00
Alasdair Kergon
0805e4e5de Fix mem allocs after archiver code move. 2005-05-24 17:37:39 +00:00
Heinz Mauelshagen
f1060fc88e Exit after last unregister_for_event() 2005-05-20 13:53:26 +00:00
Alasdair Kergon
7d3d3d0a3a Fix vgmerge to handle duplicate LVIDs. 2005-05-19 16:48:51 +00:00
Alasdair Kergon
40377032e3 1.01.02 2005-05-17 15:50:25 +00:00
Alasdair Kergon
b2971edd7d Start merging cloned allocation functions. 2005-05-17 13:49:45 +00:00
Alasdair Kergon
c37d723692 Move archiver code from tools into library. 2005-05-17 13:46:38 +00:00
Alasdair Kergon
30f9026e1d vgscan/change/display/vgs automatically create metadata backup if out-of-date or missing. 2005-05-17 13:44:02 +00:00
Alasdair Kergon
332286072e Add dmsetup ls --exec. 2005-05-16 20:46:46 +00:00
Alasdair Kergon
d6da172a2a Add --target to dmsetup ls. 2005-05-16 16:04:34 +00:00
Alasdair Kergon
ebfe584afc Call dm_lib_exit() and dm_lib_release() automatically now. 2005-05-16 15:15:34 +00:00
Alasdair Kergon
6250023583 Add --target <target_type> filter to dmsetup table/status.
Fix dmsetup getopt_long usage.
2005-05-16 14:53:23 +00:00
Alasdair Kergon
6b4f3d63b8 Fix contiguous allocations with linear. 2005-05-11 16:46:59 +00:00
AJ Lewis
56db773a09 more clvmd rhel4 initscript cleanup
- don't echo after an 'action' call - action does the echo itself
 - use vgdisplay/vgs to determine which VGs are marked clustered and only
   deactivate those VGs (unless the LVM_VGS var is set in
   /etc/sysconfig/cluster)
2005-05-11 15:21:44 +00:00
Alasdair Kergon
fc6c472401 Cope with missing format1 PVs again. 2005-05-11 15:04:06 +00:00
Alasdair Kergon
2cd42a6866 Remove lists of free PV segments.
Simplify pv_maps code and remove slow bitset algorithm.
2005-05-11 15:02:49 +00:00
AJ Lewis
36a90c345c updated to reflect clvmd rhel4 initscript being redhatified 2005-05-10 20:15:39 +00:00
AJ Lewis
ef1e82c72c Fixes bz#155478
Redhatify the rhel4 initscript (use /etc/init.d/functions)
2005-05-10 20:14:33 +00:00
AJ Lewis
88f9534685 o Changed the multilog API a bit (I warned you)
- multilog_add_type, multilog_del_type, multilog_custom, and
     multilog_init_verbose all have different arguments.
   - Primary change is that caller only passes in config info, and the
     lib keeps track of state internally.  No more exporting of
     'struct log_data'.
   - Custom callers now only get the custom data pointer passed into their
     log fxn (that is set with multilog_custom)
   - Added basic README that describes libmultilog
2005-05-09 18:44:35 +00:00
Alasdair Kergon
68254a052a %Zu->zu 2005-05-09 17:45:06 +00:00
Alasdair Kergon
2425b3a166 fix compiler warnings 2005-05-09 17:41:36 +00:00
Alasdair Kergon
5524ed753b Fix loopfiles mem alloc. 2005-05-09 17:02:52 +00:00
Alasdair Kergon
89711723da Un-inline dbg_strdup. 2005-05-09 17:01:06 +00:00
Alasdair Kergon
bed2740ffd lv_reduce tidying.
Remove some unnecessary parameters.
Introduce seg_is macros.
2005-05-09 16:59:01 +00:00
Alasdair Kergon
751d633c3d post-release 2005-05-09 16:41:48 +00:00
Benjamin Marzinski
45952cbdf2 oops. Those are char **'s not char *'s 2005-05-04 19:24:03 +00:00
Benjamin Marzinski
b355dd7b23 fixed dmevent so that it doesn't do a double free when you run
# dmevent -l

Also, changed the behaviour of dm_get_registered_device(), so that it doesn't
change the pointer you passed in without freeing the memory on a non-next call,
and doesn't free your pointer without setting it to NULL on a failed next call.
2005-05-04 18:53:28 +00:00
Heinz Mauelshagen
48a186f172 o libmultilog needs introducing of list locking in order to stand
multilog_add_type()/multilog_del_type cycles correctly.
o fixed segfault in multilog_add_type()
o fixed test-multilog.c
o cleaned up libmultilog (list macros, indentation, braces, comments)
2005-05-04 11:52:07 +00:00
Jonathan Earl Brassow
39dc7ec2ab - make noop use multilog
- add event_nr to thread_status struct and set appropriately so that the
  thread actually waits for an event
- essentially make error_detected return true.  Let the DSOs determine
  how to interpret the status info
2005-05-04 01:57:31 +00:00
AJ Lewis
2fedabd3b9 o stick multilog into the dm-event lib and dmeventd code again
o more tweaks to libmultilog calls - the api isn't set in stone yet, so
   don't get too comfortable.
 o not sure the dmeventd in device-mapper/dmeventd works - i've been using
   the one in lib/event/
 o currently both daemons are set to log only to syslog
2005-05-03 21:29:13 +00:00
Alasdair Kergon
6d719e9480 2.01.10 2005-05-03 17:43:47 +00:00
Alasdair Kergon
05e278afda Don't create backup and archive dirs till needed. 2005-05-03 17:31:56 +00:00
Alasdair Kergon
87dbf462cb Reinstate full PV size when removing from VG.
Support loopfiles for testing.
Complete the pv_segment support.
2005-05-03 17:28:23 +00:00
Heinz Mauelshagen
40e896bc5b working dm_get_registered_device(). dmevent.c update to use it. 2005-05-03 16:15:20 +00:00
Heinz Mauelshagen
3e940f80c7 more dm_get_registered_device() code 2005-05-03 13:50:42 +00:00
Benjamin Marzinski
dbf2888d43 dmeventd was looking for dsos with libdmeventd<name>.so
The Makefile turned noop.c into    libdmeventnoop.so
The Makefile now turns noop.c into libdmeventdnoop.so
2005-05-02 19:34:25 +00:00
Benjamin Marzinski
d412355324 stopped printing a string after we erased the pointer to it. 2005-05-02 18:43:23 +00:00
Benjamin Marzinski
178732217f removed the -lmultilog for now. 2005-05-02 18:42:07 +00:00
Benjamin Marzinski
de17b95c3d get the makefile to clean up the .o's 2005-05-02 17:41:54 +00:00
Heinz Mauelshagen
d14e774525 Introduce exit() in main() and cleanup signal settings for parent/child 2005-05-02 11:02:19 +00:00
Benjamin Marzinski
ca5402a7fa more variable initialization. 2005-04-29 22:12:09 +00:00
Benjamin Marzinski
7a6fa7c5b4 changed client_path and sever_path from 'char *' to 'const char *' to stop
compiler warning messages.
2005-04-29 21:52:46 +00:00
Heinz Mauelshagen
da36c286a6 o checking in instrumented code for AJ to follow up on comms and logging
o changed

  int dm_get_next_registered_device(char **dso_name, char **device,
                                    enum event_type *events);

  to

  int dm_get_registered_device(char **dso_name, char **device,
                               enum event_type *events, int next)

  so that the daemon is able to retrive the next one of the list without
  running into locking issues.

o changed dmevent.c to use dm_get_registered_device()

o couldn't test this yet because of the comms issues
  (daemon exits in do_process_request())
2005-04-29 14:56:35 +00:00
Heinz Mauelshagen
d3901bcf2e first changes to get comms back to work after flock changes 2005-04-29 13:41:25 +00:00
Heinz Mauelshagen
94c8d4fdfb minor cleanup 2005-04-29 10:58:34 +00:00
AJ Lewis
ab8bdc18bb o Build dmeventd against multilog 2005-04-28 22:47:52 +00:00
Alasdair Kergon
c9dcd7442a build libdmeventnoop.so for testing 2005-04-28 17:32:27 +00:00
Alasdair Kergon
34c8f13346 test.c->dmevent.c 2005-04-28 14:49:41 +00:00
Alasdair Kergon
7a8ccda95c o adds dm_get_next_registered_device() (not functional yet)
to retrieve which devices got registered with the daemon;
  needs locking changes as well
2005-04-28 14:02:30 +00:00
Alasdair Kergon
44a1448542 Prototype for a device-mapper event-handling daemon. 2005-04-27 22:32:00 +00:00
Alasdair Kergon
c87d89ffaf extend alloc_lv_segment 2005-04-22 15:44:00 +00:00
Alasdair Kergon
0868749d42 set_lv_segment_area_pv/lv 2005-04-22 15:43:02 +00:00
Alasdair Kergon
1d40ee23f0 Initial pv_segment code. 2005-04-19 20:58:25 +00:00
Alasdair Kergon
8893f32603 initial pv_segment defns 2005-04-19 20:52:35 +00:00
Alasdair Kergon
adcf7e8dc3 _copy_pv -> int 2005-04-19 20:44:21 +00:00
Patrick Caulfield
901f7c5c36 Tidy clvmd's SIGHUP handler so it doesn't do all that work. 2005-04-19 10:36:42 +00:00
Alasdair Kergon
775bb413b3 vgchange --physicalextentsize (but only if it's an exact fit - may need to
use pvmove first)
2005-04-18 14:56:42 +00:00
Alasdair Kergon
64cd5b5a46 extract compose_log_line 2005-04-17 23:59:04 +00:00
Alasdair Kergon
ae356609b1 get_pv_from_vg_by_id 2005-04-17 23:57:44 +00:00
Patrick Caulfield
6102a5d2b0 Make clvmd work around some "limitations" in gulm's node state notifications.
Also make clvmd debuglog timestamps a little more helpful.
2005-04-13 13:50:07 +00:00
Alasdair Kergon
f8782ee2d7 Internal snapshot code restructuring. 2005-04-07 12:39:44 +00:00
Alasdair Kergon
6181ec4c77 add lvid to lv_create_empty 2005-04-07 12:29:46 +00:00
Alasdair Kergon
e0e7a685ef Remove unused internal non-persistent snapshot option. 2005-04-07 12:27:57 +00:00
Alasdair Kergon
ae1f8cdad2 fix unused o_direct label 2005-04-07 12:25:33 +00:00
Alasdair Kergon
a4cf792e6d store snapshot id as lvid internally 2005-04-07 12:24:48 +00:00
Alasdair Kergon
89109ded53 Allow offline extension of snapshot volumes.
NB Requires kernel patch that is not upstream.
2005-04-07 12:17:46 +00:00
Alasdair Kergon
e20e52a4b2 Move from 2-step to 3-step on-disk metadata commit. 2005-04-06 18:59:55 +00:00
Alasdair Kergon
20c4b1cbec Add ramdisk. 2005-04-06 16:43:59 +00:00
Alasdair Kergon
5238b0241d _vg_posn -> _find_vg_rlocn 2005-04-06 16:35:33 +00:00
Alasdair Kergon
9cdf6c203d more refinements 2005-04-06 15:21:28 +00:00
Alasdair Kergon
839335cae6 Annotate, tidy and extend list.h. 2005-04-06 14:50:37 +00:00
Alasdair Kergon
a99b2ce167 Alignment tidying. 2005-04-06 13:47:41 +00:00
Alasdair Kergon
b695141d87 post-release 2005-04-04 15:46:14 +00:00
Alasdair Kergon
92d5c9f866 2.01.09 2005-04-04 15:41:51 +00:00
Alasdair Kergon
7f18a1ffe0 Add --ignorelockingfailure to vgmknodes. 2005-04-04 14:44:49 +00:00
Patrick Caulfield
8c3fdaaa62 set SO_KEEPALIVE on sockets 2005-04-01 16:03:00 +00:00
Patrick Caulfield
5ac1c69710 Don't allow user operations to start until the lvm thread is fully up.
Hopefully finally nails bz#146056
2005-04-01 13:01:01 +00:00
Alasdair Kergon
de2d5fba63 post-release 2005-03-29 18:10:57 +00:00
Alasdair Kergon
33d516748f 1.01.01 2005-03-29 14:47:39 +00:00
Alasdair Kergon
de17f6f0fd Update dmsetup man page. 2005-03-29 14:46:30 +00:00
Alasdair Kergon
756731fc02 Drop-in devmap_name replacement. 2005-03-27 11:37:46 +00:00
Alasdair Kergon
e46be0415f post-release 2005-03-22 16:50:17 +00:00
Alasdair Kergon
aa02fb50bf update pofile 2005-03-22 15:13:48 +00:00
Alasdair Kergon
8b6cd9c772 2.01.08 2005-03-22 15:12:37 +00:00
Alasdair Kergon
cdd0d3351a Add clustered attribute so vgchange can identify clustered VGs w/o locking. 2005-03-21 22:55:12 +00:00
Alasdair Kergon
8b6d584529 Improve detection of external changes affecting internal cache. 2005-03-21 22:40:35 +00:00
Alasdair Kergon
f49fdd4141 Add 'already in device cache' debug message. 2005-03-21 14:51:49 +00:00
Alasdair Kergon
b26e1be81a Add -a to pvdisplay -C. 2005-03-21 14:47:36 +00:00
Alasdair Kergon
bacab38d7f Avoid rmdir opendir error messsages when dir was already removed. 2005-03-21 14:43:02 +00:00
Alasdair Kergon
701c05ce96 Tighten signal handlers. 2005-03-21 14:16:16 +00:00
Alasdair Kergon
438c452585 Fix WHATS_NEW. 2005-03-10 23:04:42 +00:00
Alasdair Kergon
0a7a1eff3f Avoid some compiler warnings. 2005-03-10 22:34:17 +00:00
Alasdair Kergon
87e743e381 Additional rename failure error message. 2005-03-10 22:31:10 +00:00
Alasdair Kergon
a03f1b3d55 read/write may be macros 2005-03-10 20:23:36 +00:00
Alasdair Kergon
2d8dc3d243 post-release 2005-03-10 20:22:40 +00:00
Patrick Caulfield
b982232cc5 Don't take out the lvm_thread_lock at startup - it only protects the jobs list.
DEBUGLOG() message now print threadid rather than PID which is more useful.
2005-03-09 14:08:11 +00:00
Alasdair Kergon
61c8d728ac update pofile 2005-03-08 13:48:13 +00:00
Alasdair Kergon
851a2bf855 Cope with new devices appearing by rescanning /dev if a uuid can't be found. 2005-03-08 13:46:17 +00:00
Alasdair Kergon
e0bdde3630 Remove DESTDIR from LVM_SHARED_PATH. 2005-03-08 13:39:39 +00:00
Patrick Caulfield
6a0dcd7f0e make clvmd FDs close-on-exec, to avoid warnings when running lvm via popen.
clvmd-gulm unlocks VG & orphan locks at startup in case they are stale.
clvmd-gulm now unlocks VG & orphan locks if client dies.
2005-03-07 17:03:44 +00:00
Alasdair Kergon
75f0b4c879 post-release 2005-03-03 22:31:01 +00:00
Alasdair Kergon
db536a9504 2.01.06 2005-03-03 22:26:34 +00:00
Alasdair Kergon
0fb114dede Option to suppress warnings of file descriptors left open. 2005-03-03 22:09:20 +00:00
Alasdair Kergon
e703342179 Suppress 'open failed' error messages during scanning. 2005-03-03 21:54:35 +00:00
Alasdair Kergon
35c8f4a611 Fix default value of metadatacopies in documentation (2->1). 2005-03-03 21:52:58 +00:00
Patrick Caulfield
7c89ae44a9 Fix clvmd-gulm node up/down code so it actually works.
clvmd-gulm now releases locks when shut down.
2005-02-22 16:26:21 +00:00
Patrick Caulfield
84fe06da22 ./configure --enable-debug now enables debugging code in clvmd 2005-02-21 15:58:06 +00:00
Patrick Caulfield
806318c8b3 Always manipulate both locks in sync_lock() otherwise they get left
hanging around and cause trouble.
2005-02-21 14:36:09 +00:00
Alasdair Kergon
3aac2e1822 post-release 2005-02-18 19:06:16 +00:00
Alasdair Kergon
168baef433 Static binary invokes dynamic binary if appropriate. 2005-02-18 18:58:31 +00:00
Patrick Caulfield
6dba6cd78d Cope with more than one message arriving at the TCP socket, also
fix some instances where the length in the message was wrong (cman
code didn't notice this because it is packet-based comms anyway)
2005-02-18 15:31:32 +00:00
Patrick Caulfield
502250d08f Fix gulm->errno error number conversion. 2005-02-17 12:56:19 +00:00
Patrick Caulfield
7395f0e680 Make config check a little more tolerant of library names. 2005-02-14 09:07:14 +00:00
Alasdair Kergon
494d3fdaca post-release 2005-02-09 18:26:38 +00:00
Alasdair Kergon
7b86a157de Add fixed offset to imported pool minor numbers. 2005-02-09 17:49:36 +00:00
Adam Manthei
0988c41785 o cluster lvm requires that /usr/sbin/$TOOL is used instead of
/sbin/lvm.static $TOOL

o made variables LVDISPLAY, VGSCAN and VGCHANGE configurable in
  /etc/sysconfig/cluster
2005-02-08 17:20:24 +00:00
Patrick Caulfield
522db1bf01 Fix thread shutdown race which could cause clvmd to hang in pthread_join. 2005-02-08 09:05:58 +00:00
Patrick Caulfield
06f066f90d Revert last clvmd patch. More testing reveals that this just doesn't
work yet.
2005-02-07 14:45:38 +00:00
Patrick Caulfield
f37b20677b Make clvmd use the command library rather than popen() to
preload the lock state.
2005-02-07 10:04:27 +00:00
Alasdair Kergon
cd2eac1032 lvm2cmd.so should skip the check for open fds. 2005-02-03 16:34:53 +00:00
Alasdair Kergon
8ac38d58d7 Remove unused -f from pvmove 2005-02-02 14:31:48 +00:00
Patrick Caulfield
4c80cc313a Make clvmd do a quick sanity check on the clustering bits of lvm.conf 2005-02-02 11:42:29 +00:00
Patrick Caulfield
1c65fee9b4 Get rid of "connection refused" message because Corey doesn't like it. 2005-02-02 09:17:56 +00:00
Alasdair Kergon
90dda7edc1 post-release 2005-02-01 16:40:16 +00:00
Alasdair Kergon
da054fae20 pofile 2005-02-01 16:33:45 +00:00
Alasdair Kergon
bdb6611e30 2.01.03 2005-02-01 16:29:22 +00:00
Alasdair Kergon
9284f973f1 More 64-bit display/report fixes. 2005-02-01 16:19:48 +00:00
Alasdair Kergon
2bfd64c3c9 Add option to compile without ioctl for testing. 2005-01-27 16:16:54 +00:00
Alasdair Kergon
939d24cce5 Fix DM_LIB_VERSION sed 2005-01-27 15:53:28 +00:00
Alasdair Kergon
27b0183c46 More informative startup mesg if can't create /etc/lvm. 2005-01-27 15:50:34 +00:00
Alasdair Kergon
d14efacac7 Fix snapshot device size bug (since 2.01.01). 2005-01-27 15:48:49 +00:00
Patrick Caulfield
150a002c40 Don't print CMAN error if initial probe fails - we could be running with GULM. 2005-01-26 09:30:52 +00:00
Patrick Caulfield
ce0def3bd8 Remove superflous &
Gulm clvmd no longer hangs trying to talk to a rebooted node.
2005-01-25 16:46:29 +00:00
Patrick Caulfield
ee20fa97c2 Make clvmd announce it's startup and cluster connection in syslog. 2005-01-24 15:31:13 +00:00
Alasdair Kergon
7403b7d700 postrelease 2005-01-21 19:03:48 +00:00
Alasdair Kergon
87ef173e0a update pofile 2005-01-21 18:51:48 +00:00
Alasdair Kergon
52a3fb6bc7 pre-release 2005-01-21 18:49:06 +00:00
Patrick Caulfield
92e2a257a6 Get rid of libclvm as it's out-of-date and not used at all. 2005-01-21 11:56:30 +00:00
Patrick Caulfield
32e175752c Fix clvmd startup bug introduced in cman/gulm amalgamation. bz#145729
Improve reporting of node-specific locking errors so you'll get
somthing a little more helpfiul than "host is down" - it will now tell
you /which/ host it thinks is down.
2005-01-21 11:35:24 +00:00
Alasdair Kergon
d43f7180dc Update clvmd_init_rhel4: use lvm.static and don't load dlm. 2005-01-20 22:16:55 +00:00
Alasdair Kergon
0129c2b0fc Fix some size_t printing. 2005-01-20 18:14:04 +00:00
Alasdair Kergon
4ed1990001 Fix 64 bit xlate consts. 2005-01-20 18:13:17 +00:00
Alasdair Kergon
5bd6ab27ae Split out pool sptype_names to avoid unused const. 2005-01-20 18:12:41 +00:00
Alasdair Kergon
f3593b89fa Always fail if random id generation fails. 2005-01-20 18:11:53 +00:00
Alasdair Kergon
23d84b2310 Recognise gnbd. 2005-01-19 18:56:01 +00:00
Alasdair Kergon
fdc49402ec fix clvmd lv_info_by_lvid open_count 2005-01-19 18:10:09 +00:00
Alasdair Kergon
5457c133e1 Add some comments. 2005-01-19 17:31:51 +00:00
Alasdair Kergon
292e588ee3 move recover_vg 2005-01-19 17:30:50 +00:00
Alasdair Kergon
243494c25e Store snapshot and origin sizes separately. 2005-01-19 17:19:39 +00:00
Alasdair Kergon
e4365f3706 Update vgcreate man page. 2005-01-19 17:01:18 +00:00
Alasdair Kergon
310f3038d3 Post-2.01.00 2005-01-17 20:45:05 +00:00
Alasdair Kergon
4e6033273d update po 2005-01-17 20:16:37 +00:00
Alasdair Kergon
73718586d3 2.01.00 2005-01-17 20:13:01 +00:00
Alasdair Kergon
011abe61e8 post-1.01.00 2005-01-17 20:12:12 +00:00
Alasdair Kergon
fe3a37f89d 1.01.00 2005-01-17 20:00:28 +00:00
Alasdair Kergon
8aea44e77b Fix vgscan metadata auto-correction. 2005-01-17 18:24:28 +00:00
Patrick Caulfield
5529aec0d6 You can now build clvmd with cman & gulm support in the same binary.
./configure --with-clvmd
wil do this by default. Or you can choose which you want with
./configure --with-clvmd=gulm    or
./configure --with-clvmd=cman

When clvmd with both included is run, it will automatically detect the cluster
manager in use.
2005-01-13 13:24:02 +00:00
Alasdair Kergon
369549d23f Only ask libdevmapper for open_count when we need it. 2005-01-12 22:58:21 +00:00
Alasdair Kergon
181ea9a381 Add dm_task_no_open_count() to skip getting open_count. 2005-01-12 22:10:14 +00:00
Alasdair Kergon
76b8f2854e Adjust RHEL4 clvmd init script priority. 2005-01-11 22:00:36 +00:00
Alasdair Kergon
320e5198f9 post-2.00.33 2005-01-07 20:06:49 +00:00
Alasdair Kergon
e522539e2d 2.00.33 2005-01-07 19:50:54 +00:00
Alasdair Kergon
7c996b83d2 post-1.00.21 2005-01-07 17:10:16 +00:00
Alasdair Kergon
3dd354d7aa 1.00.21 2005-01-07 15:53:37 +00:00
Alasdair Kergon
f4ad6e2157 Fix /proc/devices parsing. 2005-01-07 15:39:53 +00:00
Patrick Caulfield
8b170dc2bf Fix off-by-one error in cluster_locking that could case read hangs. 2005-01-07 14:22:49 +00:00
Alasdair Kergon
dcb9d779bf post-1.00.20 2005-01-06 18:41:38 +00:00
Alasdair Kergon
80f736d670 1.00.20 2005-01-06 18:30:17 +00:00
Alasdair Kergon
8502c6da3c Attempt to fix /dev/mapper/control transparently if it's wrong. 2005-01-06 18:22:44 +00:00
Patrick Caulfield
b131449422 Some more gulm fixes from "Mr gulm" himself. 2005-01-06 11:48:25 +00:00
Alasdair Kergon
6eebc4a620 Configuration-time option for setting uid/gid/mode for /dev/mapper nodes. 2005-01-05 22:00:40 +00:00
Alasdair Kergon
4661ab1179 pvcreate wipes first 4 sectors unless given --zero n. 2005-01-05 17:25:25 +00:00
Patrick Caulfield
86046445ed Improve clvmd failure message if it's already running.
Allow user to kill clvmd during initialisation.
2005-01-05 14:41:54 +00:00
Patrick Caulfield
baea9bf944 Typo in "for" caused first node in ccs to be ignored. 2005-01-04 15:11:34 +00:00
Patrick Caulfield
0951ee9e63 Use new CCS key names for nodes in the GULM version of clvmd.
based on a patch from Mike Tilstra
2005-01-04 11:48:10 +00:00
Alasdair Kergon
5492528287 post-2.00.32 2004-12-22 22:04:03 +00:00
Alasdair Kergon
14dbd220c2 update pofile 2004-12-22 21:58:26 +00:00
Alasdair Kergon
babc890c59 Drop static/dl config restriction for now. 2004-12-22 21:55:36 +00:00
Alasdair Kergon
6f7b47ff40 update version 2004-12-22 21:47:50 +00:00
Alasdair Kergon
3991f03202 Fix an error fprintf. 2004-12-22 21:47:31 +00:00
Alasdair Kergon
27271d5da7 Fix vgdisplay -s. Breaks (undocumented) lvs/pvs/vgs -s instead for now. 2004-12-21 21:40:36 +00:00
Alasdair Kergon
627312e1de Fix device reference counting on re-opens. 2004-12-21 20:23:16 +00:00
Alasdair Kergon
bfc9550e4e Ignore sysfs symlinks when DT_UNKNOWN. 2004-12-21 18:29:46 +00:00
Alasdair Kergon
2b9c21268b Add RHEL4 clvmd init script. 2004-12-21 18:07:15 +00:00
Alasdair Kergon
3dce4ed6f1 Skip devices that are too small to be PVs. 2004-12-21 17:54:52 +00:00
Alasdair Kergon
0f16c2ea87 Add CONTRIBUTORS file. 2004-12-21 16:24:19 +00:00
Alasdair Kergon
9a635f0686 Fix pvchange -x segfault with lvm2-format orphan. 2004-12-21 16:12:02 +00:00
Alasdair Kergon
6a0d4b2baa Cope with empty msdos partition tables. 2004-12-21 16:10:25 +00:00
Alasdair Kergon
ac017098ad post-2.00.31 2004-12-12 21:55:46 +00:00
Alasdair Kergon
98fef2640d update pofile 2004-12-12 21:51:59 +00:00
Alasdair Kergon
8bb66e133a 2.00.31 2004-12-12 21:47:55 +00:00
Alasdair Kergon
68a582901d Reopen RO file descriptor RW if necessary. 2004-12-12 21:47:14 +00:00
Alasdair Kergon
c094f4c06e post-2.00.30 2004-12-10 18:01:49 +00:00
Alasdair Kergon
f7ca545544 update pofile 2004-12-10 16:07:37 +00:00
Alasdair Kergon
69b4716894 2.00.30 2004-12-10 16:02:35 +00:00
Alasdair Kergon
7e44dcc5bf Additional device-handling debug messages.
Additional verbosity level -vvvv includes line numbers and backtraces.
Verbose messages now go to stderr not stdout.
Close any stray file descriptors before starting.
Refine partitionable checks for certain device types.
Allow devices/types to override built-ins.
2004-12-10 16:01:35 +00:00
Alasdair Kergon
ab9843e183 Fix lvreduce man page .i->.I 2004-12-09 16:59:18 +00:00
Alasdair Kergon
01af706ade Fix vgsplit man page title. 2004-12-09 16:58:31 +00:00
Alasdair Kergon
9ebdb08e99 Fix clvmd man makefile. 2004-12-09 16:57:37 +00:00
Alasdair Kergon
a74ffe25d9 Extend dev_open logging. 2004-12-09 16:56:51 +00:00
Patrick Caulfield
7f95e27707 Make clvmd_fix_conf.sh UNDOable 2004-12-01 14:47:31 +00:00
Alasdair Kergon
1facf5bba3 post-29 2004-11-27 22:56:58 +00:00
Alasdair Kergon
03d77009eb xlate compilation fix 2004-11-27 22:07:41 +00:00
Alasdair Kergon
8afd6812b5 update version 2004-11-27 21:38:34 +00:00
Alasdair Kergon
ec9ad78fcf Endian fix to signature detection. 2004-11-27 21:37:54 +00:00
Alasdair Kergon
6f4e93dc90 Configure/makefile tidy. 2004-11-26 18:07:17 +00:00
Alasdair Kergon
a38e43862d fix partition table signature size 2004-11-26 14:40:34 +00:00
Alasdair Kergon
39294bb037 update pofile 2004-11-24 21:39:30 +00:00
Alasdair Kergon
edc5e59b78 Trap large memory allocation requests. 2004-11-24 21:34:56 +00:00
Alasdair Kergon
c00fd9fd37 Fix to partition table detection code. 2004-11-24 20:38:05 +00:00
Alasdair Kergon
b3e621dd9f Improve filter debug msgs. 2004-11-24 20:36:52 +00:00
Alasdair Kergon
6e8c49b978 post-release 2004-11-23 18:36:01 +00:00
Alasdair Kergon
398d57133d update po 2004-11-23 18:27:57 +00:00
Alasdair Kergon
16521a6feb pool debugging 2004-11-23 18:23:23 +00:00
Alasdair Kergon
3ca0b37a3e 2.00.26 2004-11-23 17:47:19 +00:00
Alasdair Kergon
cf2ec1229d fix a md filter log mesg 2004-11-23 17:45:48 +00:00
Alasdair Kergon
fe9b1e5f9b update pofile 2004-11-23 17:44:10 +00:00
Alasdair Kergon
f5b96ddf01 Detect partition table signature. 2004-11-23 11:44:04 +00:00
Alasdair Kergon
2fe076fb27 Only wipe signature bytes when destroying md superblock, so process
is reversible.
2004-11-19 19:32:09 +00:00
Alasdair Kergon
99249cff04 pvcreate wipes md superblocks. (With --uuid or --restorefile it prompts.) 2004-11-19 19:25:07 +00:00
Alasdair Kergon
0cdf7b0613 Separate out md superblock detection code. 2004-11-18 20:02:21 +00:00
Alasdair Kergon
90bcf4f157 Prevent snapshot origin resizing. 2004-11-18 19:49:48 +00:00
Alasdair Kergon
03c3ec4e12 Improve a vgremove error message. 2004-11-18 19:45:53 +00:00
Alasdair Kergon
ca9bb20d64 More tagging documentation, with some cluster examples. 2004-11-17 18:34:49 +00:00
Alasdair Kergon
c6bc078fd9 More lvm.conf and tagging documentation. 2004-11-17 17:49:32 +00:00
Alasdair Kergon
2f4bd6e52c More man page updates. 2004-11-16 18:09:32 +00:00
Patrick Caulfield
2affe53727 Tidy the socket callbacks so that all the work is done outside the
main loop.
2004-11-16 10:55:01 +00:00
Alasdair Kergon
09654d7dd8 update WHATS_NEW 2004-11-12 16:02:08 +00:00
Alasdair Kergon
90a4e37815 Update some man pages. 2004-11-12 15:59:09 +00:00
Alasdair Kergon
60889c0c79 Also accept y/n with -ae. 2004-11-12 15:58:26 +00:00
Patrick Caulfield
20f3408d96 Report detailed errors in cluster initialisation to syslog, and point the user
at syslog if clvmd fails to intialise.
2004-11-11 14:51:23 +00:00
Patrick Caulfield
e9d86789db Can now build a gulm version of clvmd instead of a cman one. use
./configure --with-clvmd=gulm

The default is still cman, and you can't have both - sorry.
2004-11-03 10:45:07 +00:00
Alasdair Kergon
5152b7c66c update 2004-10-15 17:31:37 +00:00
Alasdair Kergon
c494c4e12c Fixes to lvcreate vgname processing. 2004-10-15 15:53:18 +00:00
Alasdair Kergon
54d58ccb7e Add --noheadings option to dmsetup -c for colon-separated output. 2004-10-12 16:42:40 +00:00
Alasdair Kergon
714a77bfbe Fix size of dm_name string. 2004-10-11 15:59:23 +00:00
Patrick Caulfield
d48f8bf5cc Make clvmd -V display the lvm version number too rather than just
the protocol version (which is not that useful and doesn't change very often).
2004-10-06 12:36:47 +00:00
Patrick Caulfield
99d97754a6 Revert the fork back to where it was as it seems to confuse pthreads.
Instead, the parent now waits for the daemon to signal that it has
completed successfully (or not) so it can return status to the user.
2004-10-06 10:12:34 +00:00
Patrick Caulfield
b9d437de2a Change some perror() calls to log_error() so they'll appear in
syslog when we're a daemon.
2004-10-06 10:02:25 +00:00
Patrick Caulfield
11403f2019 Check the UUID length when readingthe output of the "lvs" command at startup.
This way we should not get quite so confused by any debugging output
that may come our way.
2004-10-04 09:23:52 +00:00
Alasdair Kergon
1ca102d639 Support device referencing by uuid or major/minor. 2004-10-01 19:11:37 +00:00
Alasdair Kergon
339ba55111 printf->fprintf 2004-10-01 19:07:41 +00:00
Patrick Caulfield
14ae59885a Make clvmd cope with large gaps in nodeIDs 2004-09-30 14:18:29 +00:00
Patrick Caulfield
e3ef54f99b Fork a little later in the startup sequence so that we can return
an error code if the cluster infrastructure isn't there.
2004-09-30 14:16:28 +00:00
Alasdair Kergon
001901f9a9 post-2.00.25 2004-09-29 15:25:43 +00:00
Alasdair Kergon
6a98f60e2e 2.00.25 2004-09-29 15:08:20 +00:00
Alasdair Kergon
6f2e24c47d Use macro in vgremove locking fix. 2004-09-27 10:32:36 +00:00
Patrick Caulfield
aafa368923 Hold VG lock while doing vgremove.
agk - you may want to check this.
2004-09-24 12:48:43 +00:00
Patrick Caulfield
eb783cab4c Remove spurious trailing dot in man page. 2004-09-24 10:34:53 +00:00
Patrick Caulfield
6533aa865a Keep client locks (VG locks usually) in their own hash table so
we can actually have more then one of them per client.
2004-09-24 09:39:57 +00:00
Patrick Caulfield
f1a1e1bc07 Update WHATS_NEW with latest clvmd change 2004-09-23 13:12:09 +00:00
Patrick Caulfield
953f4838dd Make the thread handling a little less cavalier. In particular, calling
pthread_exit in a signal handler was a /really/ bad idea.
2004-09-23 12:51:56 +00:00
Patrick Caulfield
130b892d34 Don't use hold_lock for VG locks as that doesn't stop processes contending
on the same node, only across the cluster.
2004-09-23 12:29:35 +00:00
Alasdair Kergon
6ad525c77e Fix return code from rm_link for vgmknodes. 2004-09-22 13:38:37 +00:00
Patrick Caulfield
d0ca74ad27 Put some locking round the LV hash table as it could be accessed by
different threads concurrently.
2004-09-22 12:10:34 +00:00
Alasdair Kergon
9806f69b4d post-2.00.24 2004-09-16 21:48:26 +00:00
Alasdair Kergon
34d9b5e3d7 2.00.24 2004-09-16 20:56:18 +00:00
Alasdair Kergon
3bf5189d86 Fix pool_empty so it really does empty the memory pool. 2004-09-16 20:09:55 +00:00
Alasdair Kergon
12e5b0681b Rename old segtypes files to segtype. 2004-09-16 18:40:56 +00:00
Alasdair Kergon
8c0285d608 Some fixes to memory debugging code.
Exclude internal commands formats & segtypes from install.
2004-09-16 16:53:39 +00:00
Alasdair Kergon
36558fa3b8 post-2.00.23 2004-09-15 15:59:19 +00:00
Alasdair Kergon
235f940cde 2.00.23 2004-09-15 15:32:21 +00:00
Alasdair Kergon
803d61fcbc Add formats & segtypes files. 2004-09-15 15:27:26 +00:00
Alasdair Kergon
ffbd7d8de4 Export dm name build & split functions. 2004-09-15 15:02:36 +00:00
Alasdair Kergon
4ed924d7c7 Use O_NOATIME on devices if available. 2004-09-14 22:23:23 +00:00
Alasdair Kergon
798dc9948b Write log message when each segtype/format gets initialised. 2004-09-14 17:37:51 +00:00
Alasdair Kergon
13515f7ee4 New commands 'segtypes' and 'formats'. 2004-09-14 16:42:46 +00:00
Alasdair Kergon
ef80824c26 Suppress pvmove abort message in test mode. 2004-09-14 15:23:42 +00:00
Alasdair Kergon
c8503fd65e Improve pvcreate/remove device not found error message. 2004-09-14 14:54:58 +00:00
Alasdair Kergon
b3c454fb1c Allow pvmove to move data within the same PV. 2004-09-14 13:59:17 +00:00
Alasdair Kergon
1d7723e873 Describe how pvmove works on man page. 2004-09-14 13:58:11 +00:00
Alasdair Kergon
77100b2365 Test for incompatible format/segtype combinations in lv_extend. 2004-09-14 13:56:18 +00:00
Patrick Caulfield
259a788134 Fix man page for lvchange. The example seems to have been lifted from pvchange. 2004-09-13 08:01:54 +00:00
Alasdair Kergon
39511455cb post 2.00.22 2004-09-03 19:18:23 +00:00
Alasdair Kergon
b04c16178e 2.00.22 2004-09-03 19:08:50 +00:00
Alasdair Kergon
49a959c06e Fix /dev/vgname mkdir perms. 2004-09-02 14:38:46 +00:00
Alasdair Kergon
096a8932b4 clvmd man page tweaks 2004-09-02 14:16:54 +00:00
Alasdair Kergon
e39e66df93 Restructure xlate.h 2004-09-02 13:53:25 +00:00
Patrick Caulfield
513633f49a clvmd man page. 2004-08-23 08:42:53 +00:00
Alasdair Kergon
eb3740daaf post-2.4.21 2004-08-19 17:13:49 +00:00
Alasdair Kergon
f7947b148a 2.00.21 2004-08-19 16:10:15 +00:00
Alasdair Kergon
9a2a702f3f Recognise iseries/vd devices. 2004-08-18 19:13:01 +00:00
Alasdair Kergon
c65d95bf29 Cluster-extension-only installation. 2004-08-18 18:57:40 +00:00
Alasdair Kergon
753a5edc4f Cope with DT_UNKNOWN in sysfs. 2004-08-18 18:50:21 +00:00
Alasdair Kergon
0b3f853c2d Update pvmove prototype. 2004-08-18 18:49:29 +00:00
Patrick Caulfield
3527fcf1d5 Updated file from cman. 2004-08-18 16:04:35 +00:00
Alasdair Kergon
4544a89c7a Support for PE ranges in pvmove source PV. 2004-08-17 22:09:02 +00:00
Alasdair Kergon
ffeae9005e Remove duplicate line in pvremove help text. 2004-08-17 22:06:06 +00:00
Alasdair Kergon
47217bcfb7 Change alloc_areas to pe_ranges and allow suppression of availability checks. 2004-08-17 21:55:23 +00:00
Alasdair Kergon
80ff58b57a Add a const. 2004-08-11 13:15:35 +00:00
Alasdair Kergon
d15dd368f1 Add dev_size column to pvs. 2004-08-11 13:15:05 +00:00
Alasdair Kergon
8a2ec32bd8 Add report columns for in-kernel device number. 2004-07-03 22:07:52 +00:00
Alasdair Kergon
410496ed52 update version 2004-07-03 18:29:48 +00:00
Alasdair Kergon
b7b07552e5 Misc autoconf fixes 2004-07-03 18:21:13 +00:00
Alasdair Kergon
44486e80d9 Fix ftp urls 2004-07-03 18:20:25 +00:00
Alasdair Kergon
7890c527d8 misc autoconf fixes 2004-07-03 18:17:32 +00:00
Alasdair Kergon
2c82ab79a7 fix a newline 2004-07-03 18:15:14 +00:00
Alasdair Kergon
e3ebe5fc53 set_selinux_context() return code fix 2004-07-03 18:14:12 +00:00
Alasdair Kergon
0ac430892e Fix device number handling for 2.6 kernels. 2004-07-01 15:14:29 +00:00
Alasdair Kergon
a7739c942c update version 2004-06-29 13:46:44 +00:00
Alasdair Kergon
24581482d0 make -O2 optimisation flag configurable. 2004-06-29 13:29:25 +00:00
Alasdair Kergon
0571c3b453 Reduce severity of setlocale failure message (ie suppress during boot). 2004-06-29 13:28:57 +00:00
Alasdair Kergon
73e7f5a0b0 Add initrd-lvm to list of recognised argv[0]s. [pld-linux] 2004-06-29 13:27:19 +00:00
Alasdair Kergon
20c0adb961 Fix LD_FLAGS->LDFLAGS. LD_DEPS->LDDEPS.
Update configure script: add --disable-selinux & some missing messages.
2004-06-28 14:01:24 +00:00
Patrick Caulfield
a01e03562f Make sure errors reach syslog(). 2004-06-28 10:26:42 +00:00
Alasdair Kergon
d184ed0130 update version 2004-06-25 10:31:04 +00:00
Alasdair Kergon
089e1c2aee Fix vgchange (de)activation of (open) LVs. 2004-06-24 14:48:01 +00:00
Alasdair Kergon
ebab0e91ee Missing .exported_symbols 2004-06-24 08:16:09 +00:00
Alasdair Kergon
858a2b1b88 Add cluster support. 2004-06-24 08:02:38 +00:00
Alasdair Kergon
02bd59827c Remove pv segments line from backport. 2004-06-20 15:14:31 +00:00
Alasdair Kergon
4991428510 Fix targets string size calc in driver.
Fix a uuid free in libdm-iface. [Eric Taylor]
Update version.
2004-06-20 13:50:42 +00:00
Alasdair Kergon
3b245f5dc1 fsadm configurable (default disabled as untested)
version update
2004-06-20 13:38:54 +00:00
Alasdair Kergon
c9c81da901 Display all filtered devices, not just PVs, with pvs -a. 2004-06-19 19:27:00 +00:00
Alasdair Kergon
4919cdc3fb Fix sync_dir() when no / in filename. 2004-06-19 19:24:33 +00:00
Alasdair Kergon
e90e1f577d vgcfgbackup -f accepts template with %s for VG name. 2004-06-19 18:55:29 +00:00
Alasdair Kergon
afd4284403 Extend hash functions to handle non-null-terminated data. 2004-06-18 15:08:22 +00:00
Alasdair Kergon
150b350d31 Add local activation support. 2004-06-16 17:13:41 +00:00
Alasdair Kergon
2818520bd1 Add dmsetup -C for column-based output. 2004-06-16 16:44:12 +00:00
Alasdair Kergon
2819952292 fsadm 2004-06-15 17:29:20 +00:00
Alasdair Kergon
5af71af51c tidy relative paths in makefile includes 2004-06-15 17:25:07 +00:00
Alasdair Kergon
07a55b51df lvresize + fsadm support - needs testing 2004-06-15 17:23:49 +00:00
Alasdair Kergon
66dd68b49d Clear message buffer before use. 2004-06-10 16:14:16 +00:00
Alasdair Kergon
9812657777 Support new target message ioctl. 2004-06-08 20:34:40 +00:00
Alasdair Kergon
0b09312fc6 mark pool support read-only; fix makefile typo 2004-06-07 19:26:13 +00:00
Alasdair Kergon
d0a7ac6b74 Add read-only GFS pool support. 2004-06-07 19:10:21 +00:00
Alasdair Kergon
ff9a238fbd lvm2create_initrd submitted by Jeff Layton <jtlayton@poochiereds.net>
sourced from http://poochiereds.net/svn/lvm2/
2004-06-07 16:20:05 +00:00
Alasdair Kergon
359fffa5f1 Fix rounding of large displayed sizes. 2004-06-07 15:22:43 +00:00
Alasdair Kergon
5bf92ced1a i2o_block 2004-06-01 18:33:50 +00:00
Alasdair Kergon
340bcc7b45 Suppress decimal point when using units of sectors/bytes. 2004-05-28 12:47:57 +00:00
Alasdair Kergon
ef03742bd4 Additional kernel target checks before pvmove & snapshot creation. 2004-05-24 20:51:56 +00:00
Alasdair Kergon
20431ec16d v2.00.16 2004-05-24 19:20:57 +00:00
Alasdair Kergon
becba8157b Set area_count within alloc_lv_segment 2004-05-24 17:30:00 +00:00
Alasdair Kergon
51fd3bb0eb Remove error labels. 2004-05-24 15:58:50 +00:00
Alasdair Kergon
4bbd3acb4e Fix a pvs error path. 2004-05-24 14:14:10 +00:00
Alasdair Kergon
3bc930ea7b xxchange -ae to activation exclusively 2004-05-24 13:44:10 +00:00
Alasdair Kergon
d1b26f8e86 Don't return non-zero status if there aren't any volume groups 2004-05-20 16:18:58 +00:00
Alasdair Kergon
fdf15caaff Rename allocation policies; add --alloc to cmdline; LV inherits from VG. 2004-05-18 22:12:53 +00:00
Alasdair Kergon
c7b4a53c0b Add reset_fn to external_locking. 2004-05-18 21:57:24 +00:00
Alasdair Kergon
af78dc0308 indent 2004-05-18 21:55:55 +00:00
Alasdair Kergon
5ad39493c4 Ensure presence of virtual targets before attempting activation. 2004-05-12 20:43:34 +00:00
Alasdair Kergon
61f597b408 Attempt to fix resizing of snapshot origins. 2004-05-12 20:40:34 +00:00
Alasdair Kergon
2162825240 Restructure lvresize, bringing it closer to lvcreate. 2004-05-11 18:47:40 +00:00
Alasdair Kergon
2b780e70d1 indent 2004-05-11 18:45:11 +00:00
Alasdair Kergon
a3823f818e update comment 2004-05-11 18:18:14 +00:00
Alasdair Kergon
1f7c47bcaf A quick sanity check on vg_disk struct when read in. More checks needed. 2004-05-11 17:18:42 +00:00
Alasdair Kergon
ec53c365a2 Only include visible LVs in active/open counts. 2004-05-11 17:09:09 +00:00
Alasdair Kergon
793ad1f2d4 Add --type to lvcreate/resize.
Add virtual segment types, zero and error.

A large sparse device can be constructed as a writeable snapshot of a large
zero device.
2004-05-11 16:01:58 +00:00
Alasdair Kergon
9bc733b76c Push lv_create & alloc policy up to tool level. 2004-05-05 18:49:21 +00:00
Alasdair Kergon
21b28f0217 fix return code 2004-05-05 18:39:30 +00:00
Alasdair Kergon
d3e23caa52 comments 2004-05-05 18:35:04 +00:00
Alasdair Kergon
9e7518de67 Skip mirror LV. Comments. 2004-05-05 18:33:01 +00:00
Alasdair Kergon
679f0047aa Detect invalid LV names in arg lists. 2004-05-05 18:31:38 +00:00
Alasdair Kergon
d77d5ce14b stray space 2004-05-05 18:27:56 +00:00
Alasdair Kergon
33ec22a2af Reporting uses line-at-a-time output. 2004-05-05 18:23:11 +00:00
Alasdair Kergon
353053225f lvm2 format sets unlimited_vols format flag. 2004-05-05 18:17:48 +00:00
Alasdair Kergon
b7f3d6f7f7 Internal-only metadata flag support. 2004-05-05 18:15:47 +00:00
Alasdair Kergon
e34577499d Some basic checking for presence of device-mapper targets. 2004-05-05 18:11:43 +00:00
Alasdair Kergon
4cf8960c0c Separate out polldaemon. 2004-05-05 17:56:20 +00:00
Alasdair Kergon
1f93ea0675 Revise internal locking semantics. 2004-05-05 12:03:07 +00:00
Alasdair Kergon
25b705c3a8 move find_pv_by_name to lib 2004-05-05 11:04:28 +00:00
Alasdair Kergon
0725588731 Add devices to segments report; some move->copy renaming. 2004-05-05 10:58:44 +00:00
Alasdair Kergon
fc5c61cc8b Begin to separate out segment types. 2004-05-04 21:25:57 +00:00
Alasdair Kergon
ac282e63c6 Compress any (obsolete) long LVM1 pvids encountered. 2004-05-04 18:38:11 +00:00
Alasdair Kergon
c3941941ce Support tagged config files. 2004-05-04 18:28:15 +00:00
Alasdair Kergon
46cdd53323 Don't abort operations if selinux is present but disabled. 2004-05-04 15:29:26 +00:00
Alasdair Kergon
3ff3e302c3 Missing $ => HAVE_LIBDL unset 2004-05-04 12:14:20 +00:00
Alasdair Kergon
f2ceecf95c fix selinux library linking 2004-04-19 14:01:23 +00:00
Alasdair Kergon
9314c7c881 config option to avoid using install -o -g 2004-04-19 13:10:06 +00:00
Alasdair Kergon
54abb2c572 Use 64-bit file functions. 2004-04-16 18:43:29 +00:00
Alasdair Kergon
8fa3bdd025 Set devices/md_component_detection = 1 to ignore devices containing md
superblocks. [Luca Berra]
2004-04-16 16:12:04 +00:00
Alasdair Kergon
5e7a308528 Ignore error setting selinux file context if fs doesn't support it. 2004-04-16 12:24:46 +00:00
Alasdair Kergon
7952177786 2.00.12 2004-04-14 20:09:25 +00:00
Alasdair Kergon
9afbe49c84 update 2004-04-14 18:31:35 +00:00
Alasdair Kergon
9f06ba2db3 fix selinux error mesg 2004-04-14 18:10:10 +00:00
Alasdair Kergon
fe55bfddcf lvm.static can be installed in different dir from rest of tools 2004-04-14 18:00:23 +00:00
Alasdair Kergon
c0842e6444 Install example config file by default if there isn't one already. 2004-04-14 17:39:55 +00:00
Alasdair Kergon
3fed20d06a Add power2 2004-04-14 17:33:51 +00:00
Alasdair Kergon
5e8f2e2c04 Fix lvs_in_vg_opened counting. 2004-04-14 17:33:04 +00:00
Alasdair Kergon
e4df99ea84 fix patch that misapplied 2004-04-08 17:21:01 +00:00
Alasdair Kergon
b3276f5f11 Update version 2004-04-08 17:14:00 +00:00
Alasdair Kergon
32667ca256 Option for auto-fallback to LVM1 tools if running 2.4 without device-mapper. 2004-04-08 15:23:23 +00:00
Alasdair Kergon
bed122a170 update for 2.00.10 2004-04-07 18:12:51 +00:00
Alasdair Kergon
14adc9b875 Basic selinux support 2004-04-07 14:08:22 +00:00
Alasdair Kergon
a8778bbc5a Fix status overflow check in kernel patches. 2004-04-07 12:39:59 +00:00
Alasdair Kergon
a54e641f44 fix static selinux build 2004-04-06 20:32:02 +00:00
Alasdair Kergon
5c99efe87a 1.00.13 2004-04-06 18:57:13 +00:00
Alasdair Kergon
7da1d731ff add some selinux support 2004-04-06 18:54:00 +00:00
Alasdair Kergon
af9828e819 Fix sysfs filter to check fs type. 2004-04-06 16:47:59 +00:00
Alasdair Kergon
7a27136142 Update to 2.00.10 2004-04-06 15:17:53 +00:00
Alasdair Kergon
012ad2d423 More build fixes 2004-04-06 15:14:23 +00:00
Alasdair Kergon
ef3bdbf4da Fix dmsetup.static install. 2004-04-06 12:06:55 +00:00
Alasdair Kergon
b3bb698f7b Version 1.00.11 2004-04-05 20:51:42 +00:00
Alasdair Kergon
1ed5d1e4c1 Combine static/dynamic build. 2004-04-05 20:48:14 +00:00
Alasdair Kergon
bdee01a03d Fix shared format1 build. 2004-04-05 16:29:37 +00:00
Alasdair Kergon
458f7376d7 accept argv[0] lvm.static 2004-04-05 16:24:17 +00:00
Alasdair Kergon
cb3a00e027 Move library targets definition into template. 2004-04-05 16:20:50 +00:00
Alasdair Kergon
482eb1f3fb update for 1.00.10 2004-04-02 16:47:43 +00:00
Alasdair Kergon
6e0f638f5e Build process fixes/tidy-ups. 2004-04-02 15:18:38 +00:00
Alasdair Kergon
bab349047d updates for release 2004-03-31 20:14:02 +00:00
Alasdair Kergon
28ea6b8de8 update text for release 2004-03-31 20:09:56 +00:00
Alasdair Kergon
9d51bbdae8 Update VERSION 2004-03-31 19:12:17 +00:00
Alasdair Kergon
d622f79533 Add 2.4 support for DM_LIST_VERSIONS (dmsetup targets).
Rebaseline patches to 2.4.26-rc1.
2004-03-31 18:54:17 +00:00
Alasdair Kergon
04c8515ad1 Missing dev_close_all()s 2004-03-31 18:41:39 +00:00
Alasdair Kergon
53bc4251d1 Update changelog. 2004-03-30 20:33:26 +00:00
Alasdair Kergon
a5a751f02f Example cmdlib program. 2004-03-30 19:54:59 +00:00
Alasdair Kergon
66ed5f82c4 Update copyright notices. 2004-03-30 19:35:44 +00:00
Alasdair Kergon
c802a9e6aa Update changelog. 2004-03-30 19:12:42 +00:00
Alasdair Kergon
880f210946 Update copyright messages. 2004-03-30 19:08:57 +00:00
Alasdair Kergon
4f9f7eb6a6 Fix vgmknodes to remove dud /dev/mapper entries 2004-03-30 14:40:03 +00:00
Alasdair Kergon
f910c4a8e7 Rename dev_manager_mknodes -> dev_manager_lv_mknodes etc. 2004-03-30 14:38:57 +00:00
Alasdair Kergon
529686d965 spelling corrections 2004-03-30 14:36:50 +00:00
Alasdair Kergon
84dfd1536f vgdisplay_colons 2004-03-30 14:35:40 +00:00
Alasdair Kergon
85dedc324c Move full mknodes functionality from dmsetup into libdevmapper. 2004-03-30 14:31:58 +00:00
Alasdair Kergon
d639237411 and another typo 2004-03-26 21:49:57 +00:00
Alasdair Kergon
449aaf75f1 typo 2004-03-26 21:47:43 +00:00
Alasdair Kergon
b1fda66caa missing definition 2004-03-26 21:46:01 +00:00
Alasdair Kergon
66a8e90fd9 lvchange --refresh 2004-03-26 21:24:03 +00:00
Alasdair Kergon
37b487d191 tweak memlock includes 2004-03-26 21:11:34 +00:00
Alasdair Kergon
6c59fe3577 Add string display to mem leak dump. 2004-03-26 21:09:44 +00:00
Alasdair Kergon
1cbb70c992 indent 2004-03-26 21:07:30 +00:00
Alasdair Kergon
e06b39f882 move lock_lvs; add lock memlock code 2004-03-26 20:49:35 +00:00
Alasdair Kergon
2602b1493e LV allocation variable renaming 2004-03-26 20:35:14 +00:00
Alasdair Kergon
989d14502d Add locking flags + memlock option. 2004-03-26 20:17:11 +00:00
Alasdair Kergon
f78a550282 makefile spacing 2004-03-26 20:03:58 +00:00
Alasdair Kergon
54a1abb284 Add list_versions to library 2004-03-26 19:52:09 +00:00
Alasdair Kergon
97b492a8e2 Ignore open hidden LVs when checking if deactivation is OK. 2004-03-26 19:13:39 +00:00
Alasdair Kergon
0873bd14a9 Suppress move percentage when inactive 2004-03-26 19:10:48 +00:00
Alasdair Kergon
eff6ba429a Tidy sysfs includes 2004-03-26 18:54:55 +00:00
Alasdair Kergon
8c18064be4 indent 2004-03-26 15:46:37 +00:00
Alasdair Kergon
44a1ac0cf3 lv_info_by_lvid 2004-03-26 15:35:01 +00:00
Alasdair Kergon
28dc8d88dd cmdlib prototypes 2004-03-26 14:56:41 +00:00
Alasdair Kergon
2c0c2b64ba .export.sym generation 2004-03-26 14:51:23 +00:00
Alasdair Kergon
bd3e0f5248 cmdlib logging function 2004-03-26 14:47:14 +00:00
Alasdair Kergon
cd52d98938 update configure for cmdlib 2004-03-26 14:17:14 +00:00
Alasdair Kergon
894c70e7f8 Update makefiles (incl. cmdlib). 2004-03-26 13:21:12 +00:00
Alasdair Kergon
51d70c2edd Rename some files to avoid duplicate filenames in tree. 2004-03-26 12:25:15 +00:00
Alasdair Kergon
7d4b355240 Add cmdlib code. 2004-03-26 12:21:24 +00:00
Alasdair Kergon
3b56193b98 Add --nolocking option for read operations if locking is failing/unavailable. 2004-03-26 12:09:33 +00:00
Alasdair Kergon
b16045b57d Move main() into separate file. 2004-03-26 12:00:24 +00:00
Alasdair Kergon
9e8b0fca5b Indent; _init -> _init_lvm 2004-03-26 11:49:07 +00:00
Alasdair Kergon
35cf1b3b5b Rebaseline internal verbose level. 2004-03-26 11:45:01 +00:00
Alasdair Kergon
83f788af57 Document metadata tagging. 2004-03-22 15:08:50 +00:00
Alasdair Kergon
2ffe378d3f Only print warning message once when compiled without libdevmapper. 2004-03-19 16:26:46 +00:00
Alasdair Kergon
38b33a4a5e Fix lvreduce pv extents calculations. 2004-03-19 16:19:41 +00:00
Alasdair Kergon
60bf9ed0a0 Avoid sscanf %as for uClibc 2004-03-19 15:52:22 +00:00
Alasdair Kergon
16adf4de1b Fix DESTDIR with configure path overrides. 2004-03-17 19:37:44 +00:00
Alasdair Kergon
80de983023 additional activation functions 2004-03-08 18:54:13 +00:00
Alasdair Kergon
8703ca623f rename config file vars & always use / as separator 2004-03-08 18:28:45 +00:00
Alasdair Kergon
286253a73f host tags 2004-03-08 18:13:22 +00:00
Alasdair Kergon
bd806a41df move hostname into global 2004-03-08 17:25:59 +00:00
Alasdair Kergon
b89c4e9002 tagging 2004-03-08 17:19:15 +00:00
Alasdair Kergon
6dbf31c0c3 More str_list fns. 2004-03-08 15:23:01 +00:00
Alasdair Kergon
060c45d8a1 Fix (rare) bug in recognition of long argument forms. 2004-03-08 13:54:45 +00:00
Alasdair Kergon
33d3e82e4d Detailed changelog. 2004-02-27 22:36:13 +00:00
Alasdair Kergon
4bb074514d Update man page incl. 'targets', event_nr. 2004-02-27 19:36:49 +00:00
Alasdair Kergon
e3f8892003 more syncing with lvm2 build process 2004-02-24 19:23:28 +00:00
Alasdair Kergon
9d00ad5f18 Extract log.h and tweak funcs to be like lvm2 ones. 2004-02-24 18:50:09 +00:00
Alasdair Kergon
dae4344850 more makefile syncing 2004-02-24 18:46:20 +00:00
Alasdair Kergon
aa7f3fabe2 File missed from last checkin. 2004-02-18 13:06:21 +00:00
Alasdair Kergon
f93434a8ce Basic internationalisation support. 2004-02-13 22:56:45 +00:00
Alasdair Kergon
25dee56be9 Don't recurse symlinked dirs such as /dev/fd on 2.6. 2004-02-13 18:55:43 +00:00
Alasdair Kergon
ce9a3f3797 Update autoconf files 2004-02-13 16:00:22 +00:00
Alasdair Kergon
11e384920a don't inline pool_zalloc(); lift duplicated pool_str(n)dup to pool.c 2004-02-13 15:38:54 +00:00
Alasdair Kergon
a0a1f1e536 Don't inline hash _find 2004-02-13 15:36:58 +00:00
Alasdair Kergon
3b3d0ea9eb Sysfs block device filtering option for 2.6. 2004-02-13 14:46:04 +00:00
Alasdair Kergon
2f4d78286d split_words() 2004-02-13 14:43:35 +00:00
Alasdair Kergon
677dc6f985 Update CVS info for move to sources.redhat.com. 2004-02-10 15:26:51 +00:00
Alasdair Kergon
d52057e732 Static build too. 2004-01-28 03:40:31 +00:00
Alasdair Kergon
fa2a1cb1fb Define BLKGETSIZE64 on systems with out-of-date header files. 2004-01-27 20:53:57 +00:00
Alasdair Kergon
19a0fb04ad Userspace support for LIST_VERSIONS ioctl. 2004-01-23 14:37:47 +00:00
Alasdair Kergon
947352f2fe Add event number arg to dmsetup wait. 2004-01-23 14:09:33 +00:00
Alasdair Kergon
adcbedb686 Document that sector size is always 512 bytes. [AJ] 2004-01-23 14:08:09 +00:00
Alasdair Kergon
7732f92acd pv/vgchange --uuid to change (non-random) UUIDs to random values 2004-01-13 18:42:05 +00:00
Alasdair Kergon
ad8a001688 If PV/VG uuids are missing, generate them from the pv/vg numbers.
[This situation could occur if the uuids were oritinally created by
LVM1 on a system without /dev/urandom.]
2004-01-09 19:18:20 +00:00
Alasdair Kergon
9121eada08 Log full details when "VG data differs between PVs" error message occurs. 2004-01-02 14:04:44 +00:00
Alasdair Kergon
49bd4d25a2 Option to revert to default logging function after using a custom one. 2003-12-21 16:08:20 +00:00
Alasdair Kergon
d80b4129c6 Change pvscan to show total of usable device size (instead of free data space). 2003-12-09 22:32:47 +00:00
Alasdair Kergon
7edb4172d5 Remove undocumented -m abbreviation. 2003-12-09 22:17:17 +00:00
Alasdair Kergon
c3a4677990 Relax restriction on pe_start location when re-writing LVM1 metadata. 2003-12-09 17:51:39 +00:00
Alasdair Kergon
5cbb893a3b Fix support for PVs on read only devices. [Still must set LVs read only] 2003-11-21 19:54:40 +00:00
Alasdair Kergon
f28a2a432b dumpconfig 2003-11-21 19:53:05 +00:00
Alasdair Kergon
03b75a2d27 Don't remove mirror LV until after other LVs reloaded. 2003-11-20 16:22:04 +00:00
Alasdair Kergon
859fe69083 Update dmsetup man. 2003-11-17 14:24:22 +00:00
Alasdair Kergon
f6f2205ddb Ready for another release. 2003-11-14 23:46:49 +00:00
Alasdair Kergon
0f9a03ef61 lvcreate should close the initialised snapshot device immediately. 2003-11-14 17:55:39 +00:00
Alasdair Kergon
9aa417c084 Add/update some man pages. 2003-11-14 16:17:55 +00:00
Alasdair Kergon
7b70952f5d vgscan --mknodes 2003-11-14 14:03:48 +00:00
Alasdair Kergon
edd3d07b49 Fix dev_zero() offset. 2003-11-13 23:55:03 +00:00
Alasdair Kergon
5293d0a4ec Immediate error on big memory allocations when --enable-debug. 2003-11-13 23:54:02 +00:00
Alasdair Kergon
3c8c7beae1 Missing include. 2003-11-13 18:47:22 +00:00
Alasdair Kergon
9c3ba9fdcd vgmknodes also creates necessary nodes in /dev/mapper 2003-11-13 14:11:41 +00:00
Alasdair Kergon
fb1748fb0f dmsetup mknodes 2003-11-13 13:14:28 +00:00
Alasdair Kergon
0a109fbd03 The LVM2 part of vgmknodes [still to do the non-devfs device-mapper bit]. 2003-11-12 19:16:48 +00:00
Alasdair Kergon
5cf64db74e Accept tables from stdin with dmsetup.
Update autoconf.
2003-11-12 17:30:32 +00:00
Alasdair Kergon
488cc94f36 Exclude v1 compatibility code when configured with --disable-compat
[Use this with 2.6 kernels + device-mapper V4 interface]
CVS ----------------------------------------------------------------------
2003-11-10 21:06:16 +00:00
Alasdair Kergon
e15846bf79 Default to unlimited number of LVs/PVs in lvm2 format. 2003-11-06 20:33:34 +00:00
Alasdair Kergon
752bd00674 Prevent PV allocation bit getting changed for format_text orphans. 2003-11-06 20:15:13 +00:00
Alasdair Kergon
7fadfcbe32 Fix vgremove 'all OK' check 2003-11-06 17:16:22 +00:00
Alasdair Kergon
41141e75bb Configuration-time O_DIRECT setting. 2003-11-06 17:14:06 +00:00
Alasdair Kergon
50f641e627 Add drbd. 2003-11-06 17:10:35 +00:00
Alasdair Kergon
c7883fd093 Fit locking bits into 1 byte. 2003-11-06 17:08:18 +00:00
Alasdair Kergon
4fcb24b2b1 Ban vgcreate -s 0 2003-11-06 17:07:19 +00:00
Alasdair Kergon
5003557935 Fix pvchange segfault with orphans. 2003-11-06 17:06:06 +00:00
Alasdair Kergon
bdf1ba84da Don't trigger error if changing PV allocation to the state it already is. 2003-11-06 17:04:35 +00:00
Alasdair Kergon
b0b4def983 Cope better with LVM1 minor numbers & LV numbers. 2003-11-06 16:58:38 +00:00
Alasdair Kergon
cc184bbe9e Fix exported format1 VG recognition. 2003-10-21 22:21:41 +00:00
Alasdair Kergon
ad30c830aa More consistent error code usage. 2003-10-21 22:06:07 +00:00
Alasdair Kergon
1d791a8af4 Check no fs mounted before deactivating. 2003-10-21 22:00:36 +00:00
Alasdair Kergon
e63c51cd97 Inherit CFLAGS at make time 2003-10-21 21:59:42 +00:00
Alasdair Kergon
f202e32908 Dump active configuration 2003-10-15 20:19:43 +00:00
Alasdair Kergon
26e1a08e82 dumpconfig to dump active configuration 2003-10-15 20:17:19 +00:00
Alasdair Kergon
4d5119d435 relax a scanning restriction 2003-10-15 20:10:11 +00:00
Alasdair Kergon
75e34ea62e Fix >32bit lvcreate size calculation. 2003-10-15 20:07:55 +00:00
Alasdair Kergon
0a183d6274 Prevent creation of MDA bigger than disk. 2003-10-15 20:06:37 +00:00
Alasdair Kergon
21d8060aea Don't forget to set 64-bit arg values too. 2003-10-15 20:05:30 +00:00
Alasdair Kergon
9cbe906f60 more str_list fns 2003-10-15 20:04:29 +00:00
Alasdair Kergon
8ce4137399 macro changes 2003-10-15 20:02:46 +00:00
Alasdair Kergon
5f8a139347 str_list_del 2003-10-15 20:01:12 +00:00
Alasdair Kergon
9bb009a3fe Extract some common functions. 2003-09-17 20:35:57 +00:00
Alasdair Kergon
726d65923f Update to incorporate most of version 4 interface changes. 2003-09-17 13:23:49 +00:00
Alasdair Kergon
8a6be4cb2d Remove incorrect comments. 2003-09-16 16:23:21 +00:00
Alasdair Kergon
10b06beb8e out-of-date 2003-09-16 16:18:50 +00:00
Alasdair Kergon
81318c7968 Update 2003-09-16 16:15:07 +00:00
Alasdair Kergon
47a2c1c6e5 Fix read-only snapshot creation. 2003-09-16 16:08:05 +00:00
Alasdair Kergon
39cee65c6b Make dev_name optional to show details for all devices.
e.g. 'dmsetup info', 'dmsetup status -v', 'dmsetup table'
2003-09-16 14:13:51 +00:00
Alasdair Kergon
8582ec724e Improve segment merge/split code. 2003-09-15 18:22:50 +00:00
Alasdair Kergon
b0139682e8 Don't install the pvdata stub; update built-in mesg. 2003-09-15 15:05:23 +00:00
Alasdair Kergon
d39c475a6d Ensure more args aren't negative. 2003-09-15 15:04:39 +00:00
Alasdair Kergon
48f38354c6 Missing vg_commit() 2003-09-15 15:03:54 +00:00
Alasdair Kergon
cd5a920ed5 vgcfgrestore -l lists backup file too 2003-09-15 15:03:22 +00:00
Alasdair Kergon
71bc1f378d Prevent cmdline flags that take args getting repeated. 2003-09-15 15:02:24 +00:00
Alasdair Kergon
0ee6c31cff Missing ] in pvmove usage display 2003-09-15 15:01:36 +00:00
Alasdair Kergon
af89a9971e Generalise 'invalid chars' error mesg to just say 'invalid' 2003-09-15 15:01:00 +00:00
Alasdair Kergon
c718a8ef72 Correct order of consistency/exists checks. 2003-09-15 15:00:01 +00:00
Alasdair Kergon
8c8ad0faf0 Don't use !# in randomly-generated uuids. 2003-09-15 14:58:43 +00:00
Alasdair Kergon
314d5bbb7f Fix makefile install mesg displayed for man5 2003-09-15 14:57:15 +00:00
Alasdair Kergon
102255757a Additional validation of LV segments read from metadata. [HM] 2003-09-01 19:55:16 +00:00
Alasdair Kergon
914067a0d0 Fix unsafe list iteration in segment merge code. [HM] 2003-08-27 15:30:39 +00:00
Alasdair Kergon
06e3ae2536 Remove unnecessary file. 2003-08-26 21:12:45 +00:00
Alasdair Kergon
7f9b252556 Cope better when format functions are missing. 2003-08-26 21:12:06 +00:00
Alasdair Kergon
3d700e243f Log each command & args. 2003-08-26 21:00:05 +00:00
Alasdair Kergon
bcfc78ce11 Update. 2003-08-20 15:48:46 +00:00
Alasdair Kergon
09241765d5 Some tidyups and minor fixes. 2003-08-20 15:48:27 +00:00
Alasdair Kergon
671c83c265 Remove small hard-coded activation target line parameter limit. 2003-08-20 12:53:57 +00:00
Alasdair Kergon
772d28b766 Also allow pvmove --abort when pvmove mirror not active (e.g. after a reboot). 2003-08-18 17:21:51 +00:00
Alasdair Kergon
c26fcea58d Missing check for inconsistent VG in pvmove. 2003-08-18 13:52:43 +00:00
Alasdair Kergon
1e5e26dbff update 2003-07-18 00:41:04 +00:00
Alasdair Kergon
742fc54864 Accept signed numbers in config file. 2003-07-15 16:32:20 +00:00
Alasdair Kergon
49738f43c0 update 2003-07-15 01:30:18 +00:00
Alasdair Kergon
9f85f61010 Fix vgimport fix to work outside debug mode. 2003-07-15 01:26:24 +00:00
Alasdair Kergon
239f422039 update 2003-07-13 11:07:50 +00:00
Alasdair Kergon
67af3c37be Fix detection of exported LVM1 volume groups. 2003-07-13 11:07:25 +00:00
Alasdair Kergon
a9442385c4 vsn 2.00.02 (rc3) 2003-07-12 12:02:12 +00:00
Alasdair Kergon
8c9cd10b8b Restrict active lvchange -My with -f 2003-07-11 17:10:19 +00:00
Alasdair Kergon
72542059dd Fix inactive snapshot display. 2003-07-11 17:09:21 +00:00
Alasdair Kergon
a843fc6d40 update 2003-07-05 23:27:17 +00:00
Alasdair Kergon
4beed60c08 Driver version 1 compatibility fix for snapshots. 2003-07-05 23:24:10 +00:00
Alasdair Kergon
4049c1e480 Backwards compatibility fix for version1 suspend/resume. 2003-07-05 23:20:43 +00:00
Alasdair Kergon
8449314da2 Another sync point - numerous fixes & clean ups. 2003-07-04 22:34:56 +00:00
Alasdair Kergon
63ad057028 Synchronise repository / 2.4.21 support 2003-07-04 19:38:49 +00:00
Alasdair Kergon
e720464330 Support for v4 interface 2003-07-01 21:20:58 +00:00
Alasdair Kergon
24036afef9 move functions 2003-05-06 12:22:24 +00:00
Alasdair Kergon
c78fa1a1bc remove global pvmove lock & poll for completion 2003-05-06 12:20:11 +00:00
Alasdair Kergon
faa8b9022c Check for locked LVs/pvmoves. 2003-05-06 12:14:36 +00:00
Alasdair Kergon
729bafef7a unsigned 2003-05-06 12:13:19 +00:00
Alasdair Kergon
590b028632 Prevent renaming active VGs for now. 2003-05-06 12:11:46 +00:00
Alasdair Kergon
8150d00f36 Don't process locked LVs 2003-05-06 12:10:18 +00:00
Alasdair Kergon
060065926f Store argv 2003-05-06 12:09:28 +00:00
Alasdair Kergon
70babe8a28 --abort --background 2003-05-06 12:08:58 +00:00
Alasdair Kergon
c36e09664f move fields 2003-05-06 12:06:02 +00:00
Alasdair Kergon
a9672246f3 reset_locking() 2003-05-06 12:03:13 +00:00
Alasdair Kergon
ff571884e9 Move fields. 2003-05-06 12:02:36 +00:00
Alasdair Kergon
475138bceb list_next 2003-05-06 12:01:13 +00:00
Alasdair Kergon
4a8af199c2 Add argv 2003-05-06 12:00:51 +00:00
Alasdair Kergon
bdabf5db72 Distinguish between visible & top level devices. 2003-05-06 12:00:29 +00:00
Alasdair Kergon
6a5f21b34e Missing 'make install' dependency. 2003-05-06 11:58:55 +00:00
Alasdair Kergon
d608be103c Update 2003-04-30 16:49:27 +00:00
Alasdair Kergon
374bb5d18a Don't move snapshots 2003-04-30 15:58:09 +00:00
Alasdair Kergon
031d6c25ff Add pvmove 2003-04-30 15:28:17 +00:00
Alasdair Kergon
223fb7b075 add region size & interval 2003-04-30 15:27:48 +00:00
Alasdair Kergon
a746741971 configurable region size 2003-04-30 15:26:54 +00:00
Alasdair Kergon
120faf2a58 pvmove support 2003-04-30 15:26:25 +00:00
Alasdair Kergon
990bca0dc6 use pvmove flag 2003-04-30 15:25:34 +00:00
Alasdair Kergon
3406472db7 Add mirror.c 2003-04-30 15:24:49 +00:00
Alasdair Kergon
1bd733c9f6 Outline pvmove man page 2003-04-30 15:24:08 +00:00
Alasdair Kergon
238c7f982e basic pvmove support 2003-04-30 15:23:43 +00:00
Alasdair Kergon
fcb81147cb pvmove flag 2003-04-30 15:22:52 +00:00
Alasdair Kergon
1915b73783 mirror type 2003-04-30 15:22:36 +00:00
Alasdair Kergon
ee79e621fb mirror display type 2003-04-30 15:21:43 +00:00
Alasdair Kergon
d203275a3b Add comment 2003-04-30 15:21:10 +00:00
Alasdair Kergon
9e8a996222 Up interface to major version number 4. 2003-04-30 13:48:53 +00:00
Alasdair Kergon
0126b0b3ed Up interface to major version number 4. 2003-04-29 22:52:11 +00:00
Alasdair Kergon
458928612c Display event number. 2003-04-29 11:34:40 +00:00
Alasdair Kergon
e33f88e28d Event number support. 2003-04-29 11:34:23 +00:00
Alasdair Kergon
be570bbf9e Try alternative syncs if BLKFLSBUF fails. 2003-04-28 16:20:39 +00:00
Alasdair Kergon
f59b4be110 Extra metadata-reading debug message. 2003-04-28 12:18:53 +00:00
Alasdair Kergon
37336e41be Revert to data_start 2003-04-28 11:55:58 +00:00
Alasdair Kergon
d24a1a3f0a Version 1.95.17 (new <PV>:<PE range list> allocation restriction feature). 2003-04-24 22:52:14 +00:00
Alasdair Kergon
f7258955bd Update segment area length when merging consecutive segments. 2003-04-24 22:46:47 +00:00
Alasdair Kergon
2a1eae5d6f o Metadata area struct change.
o Support physical extent restrictions on PV lists for allocations
    e.g. lvcreate -l 200 vg1 /dev/sda1:100-199:300-399
2003-04-24 22:23:24 +00:00
Alasdair Kergon
50ee0a4adb Stop more gracefully when in test mode. 2003-04-24 22:13:48 +00:00
Alasdair Kergon
955a26584e stripe filler parameter 2003-04-24 22:10:56 +00:00
Alasdair Kergon
1d3e407c8f o Rejig activation code device dependencies to make things a bit more robust
and further reduce the number of ioctl calls made.
o Metadata area struct change.
o Make config file accessible to activation functions & get stripe_filler
  from it.
o Allow kernel to return snapshot status as a fraction or a percentage.
2003-04-24 22:09:13 +00:00
Alasdair Kergon
cb809c4596 indent 2003-04-24 22:00:29 +00:00
Alasdair Kergon
53bbe2888e fix optind after last change to it 2003-04-24 21:59:42 +00:00
Alasdair Kergon
7246f476a5 Add pool_strndup 2003-04-24 21:58:34 +00:00
Alasdair Kergon
0785d1c390 DM_EXISTS_FLAG replaced by ENXIO 2003-04-24 16:08:18 +00:00
Alasdair Kergon
85d2c49d14 Some ioctl code tidying: removing duplicate internal buffers; making bounds
checks clearer (incl. variable renaming); using a flag to indicate when
output data doesn't fit into supplied buffer instead of returning an error etc.
2003-04-22 21:22:04 +00:00
Alasdair Kergon
8b77d62b7f Improve message for pvcreate of empty device. 2003-04-22 16:09:11 +00:00
Alasdair Kergon
373058a32a Improve build robustness. 2003-04-15 13:24:42 +00:00
Alasdair Kergon
e6293c2c8c Abort if any filter creation fails. 2003-04-15 13:22:43 +00:00
Alasdair Kergon
eff181c959 Cope with intentionally missing /proc. 2003-04-15 13:21:38 +00:00
Alasdair Kergon
54752c2305 Support snapshot status fraction. 2003-04-15 13:20:16 +00:00
Alasdair Kergon
b4753c044f Display read-only state. 2003-04-15 12:30:44 +00:00
Alasdair Kergon
26493424ae alignment fixes 2003-04-08 21:20:31 +00:00
Alasdair Kergon
0282fd1332 Add major arg 2003-04-04 13:22:58 +00:00
Alasdair Kergon
b9a019a08b Allow for specification of major number as well as minor. 2003-04-02 19:14:43 +00:00
Alasdair Kergon
66f6a0e687 size_t tidying 2003-04-02 19:11:23 +00:00
Alasdair Kergon
2dd1b9f97d Allow device major to be set too. 2003-04-02 19:03:00 +00:00
Alasdair Kergon
89615f3045 Reinstate lost vg_write() in lvchange --permission. 2003-04-02 13:01:04 +00:00
Alasdair Kergon
7e46192f67 Proposed changes to the ioctl interface to fix alignment issues on some
architectures and specify an explicit width for every numeric field.
2003-03-28 18:58:59 +00:00
Alasdair Kergon
e78d985cdf Avoid report segfault with non-partial inconsistent VG. 2003-03-24 18:22:48 +00:00
Alasdair Kergon
e8c4bf56fe Tidy various pre-processing incl. making libdl optional. 2003-03-24 18:08:53 +00:00
Alasdair Kergon
e6aa7d323d Fix incomplete munmap. (pjc) 2003-03-20 14:29:28 +00:00
Alasdair Kergon
fca8e25929 Fix typo. 2003-03-03 12:57:27 +00:00
Joe Thornber
8e8ac286b4 HAT_CHAR and DOLLAR_CHAR were defined to the same value ! 2003-02-20 14:53:56 +00:00
Alasdair Kergon
7d9770b9a2 Fix table output bug in last commit. 2003-02-20 13:30:03 +00:00
Andres Salomon
1996230460 Update packages. 2003-02-16 22:12:28 +00:00
Alasdair Kergon
de7897a864 LV name validation 2003-02-03 20:09:58 +00:00
Alasdair Kergon
e2884dcdb7 Identifiers may now start with digits etc. 2003-02-03 20:08:45 +00:00
Alasdair Kergon
544a53a42b Allow strings in single quotes too 2003-01-28 17:20:11 +00:00
Alasdair Kergon
2e4787bfc8 Treat 'section{' as equivalent to 'section {' 2003-01-28 16:07:04 +00:00
Alasdair Kergon
1829eeb171 merge back accidentally overwritten r1.2 change 2003-01-25 13:34:35 +00:00
Alasdair Kergon
c7488e3c4a Prepare for ioctl version number change. 2003-01-21 21:27:36 +00:00
Alasdair Kergon
3bf9606383 Allow optional verbose logging. 2003-01-21 21:25:51 +00:00
Alasdair Kergon
4f43f18f0a Allow optional verbose logging 2003-01-21 21:25:11 +00:00
Alasdair Kergon
5b7f197397 Add --enable-debug --disable-compat 2003-01-21 21:22:55 +00:00
Alasdair Kergon
018141c97f Indicate full (dropped) snapshot. 2003-01-21 18:50:50 +00:00
Alasdair Kergon
4d7813e57c vgreduce --removemissing to remove missing PVs & deps & make VG consistent 2003-01-17 21:04:26 +00:00
Alasdair Kergon
605c60208f Add success message; validate given VG name. 2003-01-17 21:02:04 +00:00
Alasdair Kergon
884fafcc30 Activation commands now return success in test mode. 2003-01-17 20:16:23 +00:00
Alasdair Kergon
56baa90320 Update 2003-01-10 22:51:18 +00:00
Alasdair Kergon
6bb20ee09e Fix (rare) cache bug on machines with large /dev directories. 2003-01-10 19:14:01 +00:00
Alasdair Kergon
541356430c Fix segfault in uuid display (substitution missed during bulk change) 2003-01-09 19:35:17 +00:00
Alasdair Kergon
2f4d91fd69 configure --disable-devmapper if you don't have libdevmapper 2003-01-08 22:44:07 +00:00
Alasdair Kergon
f58c5e6b30 o Additional device/filter-level debugging messages + duplicate alias fix
o 32/64-bit size_t fix (pjc)
2003-01-08 16:41:22 +00:00
Alasdair Kergon
0311d0132c Update date. 2003-01-07 17:06:58 +00:00
Alasdair Kergon
c946c97402 Detect duplicate PV uuids - select the one on an md device if appropriate. 2003-01-06 21:10:43 +00:00
Alasdair Kergon
84a6f51318 Ignore filter cache at startup if config file is newer than cache. 2003-01-06 21:09:04 +00:00
Alasdair Kergon
24a1501b0d More docn for filter changes. 2003-01-06 21:07:27 +00:00
Alasdair Kergon
383b6f5fcc Correct error message for non-snapshot activation failure. 2003-01-06 21:06:43 +00:00
Alasdair Kergon
633dd7ff9b When there are device name aliases, choose the "nicest" to display. 2003-01-03 21:11:23 +00:00
Alasdair Kergon
580624fad6 Also lock memory during LV updates. 2003-01-03 21:10:28 +00:00
Alasdair Kergon
a8190f7efa When activating an LV, remove any stray LVM1 /dev nodes and group file. 2003-01-03 13:50:47 +00:00
Alasdair Kergon
dd2157534b Default stripesize 64k & config file setting for it;
Clear many compiler warnings (i386) & associated bugs - hopefully without
introducing too many new bugs:-)  (Same exercise required for other archs.)
Default compilation has optimisation - or else use ./configure --enable-debug
2002-12-19 23:25:55 +00:00
Alasdair Kergon
38a90e7669 New column-based reporting tools: lvs, pvs & vgs. 2002-12-12 20:55:49 +00:00
Andres Salomon
6bfc526dcd close another bug 2002-12-09 08:59:34 +00:00
Andres Salomon
aadb8a7405 it's about that time again 2002-12-09 08:37:58 +00:00
Alasdair Kergon
27082bf77e Use sync_dir(). 2002-12-05 22:56:22 +00:00
Alasdair Kergon
a2903c80cd Add sync_dir() 2002-12-05 22:51:15 +00:00
Alasdair Kergon
9a77c5369c Fix display alignment of zero. 2002-12-05 22:42:31 +00:00
Alasdair Kergon
3c30741a19 Remove an unused .h file. 2002-12-05 22:37:36 +00:00
Alasdair Kergon
7028ad4ec0 Fix long arg processing. 2002-12-05 22:35:15 +00:00
Alasdair Kergon
8de750c6aa Maintain snapshot_count correctly. 2002-12-05 22:30:39 +00:00
Alasdair Kergon
04f98de9ee Keep certain versions of ld happy. 2002-12-05 22:28:18 +00:00
Alasdair Kergon
a1a019784b Keep some ld versions happy. 2002-12-05 22:27:43 +00:00
Alasdair Kergon
4aeeae77bd New devices/types config file entry to add new types of block devices. 2002-12-03 16:20:38 +00:00
Alasdair Kergon
651cfc2b78 tidy 2002-12-03 13:27:23 +00:00
Alasdair Kergon
2ef8af25e2 Show PV uuid; single stripe is 'linear'; suppress snapshot fields for origin. 2002-12-03 13:26:17 +00:00
Alasdair Kergon
0b13852a5b More restore hints. 2002-12-03 13:25:09 +00:00
Alasdair Kergon
13427578c9 Default size unit normally MB not KB. 2002-12-03 13:24:38 +00:00
Alasdair Kergon
d89ca2087e Suppress a (normally) unnecessary warning. 2002-12-03 13:23:50 +00:00
Alasdair Kergon
8b0ea9fba6 Further help text tidying & support for -?. 2002-11-29 15:02:57 +00:00
Heinz Mauelshagen
9f0b653d5a tiny tidying 2002-11-28 15:27:59 +00:00
Heinz Mauelshagen
659a339233 Corrected lvcreate synopsis.
Added --ignorelockingflag to synopsis where missing.
2002-11-28 15:27:29 +00:00
Alasdair Kergon
4c29f177a0 Show stripesize in KB. 2002-11-26 21:56:57 +00:00
Alasdair Kergon
d664e63d55 Skip config file reload attempt if no config file location. 2002-11-26 12:14:37 +00:00
Alasdair Kergon
2493509dbe Fix snapshot lvcreate activation check. 2002-11-22 14:19:56 +00:00
Alasdair Kergon
1c8b27f554 Remove 2 TB LV size restriction message. 2002-11-18 16:21:00 +00:00
Alasdair Kergon
68297b7186 Missing sector->k conversion in "logical volumes cannot be larger than" mesg. 2002-11-18 16:08:45 +00:00
Alasdair Kergon
34dd8d0a91 Some new features. 2002-11-18 14:04:08 +00:00
Alasdair Kergon
81c44790d5 Refactoring. 2002-11-18 14:01:16 +00:00
Alasdair Kergon
d557b335cf A new cache. 2002-11-18 13:53:58 +00:00
Alasdair Kergon
e2adc28cff Only functions listed in libdevmapper.h should get exported. 2002-11-14 19:26:28 +00:00
Alasdair Kergon
0fef6a6ecc Fix includes after DM_DIR definition move. 2002-11-14 14:44:42 +00:00
Alasdair Kergon
f2fd4b8a1f Don't let LVM2 access a VG if the original LVM driver appears to be using it. 2002-11-01 19:57:25 +00:00
Alasdair Kergon
95bd5605a8 Improve missing-kernel-driver error message. 2002-11-01 16:16:42 +00:00
Andres Salomon
497cca7eca agk, I recall you saying you had a massive commit pending; if you need me
to back this out so you can do that commit, let me know.  Also, if there's
an issue with the error message that's displayed, just change it in tools.h.

This causes a "device-mapper driver/module not loaded?" error message to
be displayed for the commands that require dm-mod, if the tools can't get
the driver version.  It's not done for commands that don't require dm-mod.
This should clear up some problems people have had attempting to use lvm2
without rtfm'ing.
2002-10-27 21:04:03 +00:00
Andres Salomon
54f78feedd synch w/ debian 2002-10-27 18:40:35 +00:00
Andres Salomon
76408e53ae Wow, learn something new every day. Apparently, the signed-ness of char is
implementation-dependent; some archs (s390, arm, and ppc) default to
an unsigned char.
2002-10-08 20:16:44 +00:00
Alasdair Kergon
be19e74d30 Support alternative lvrename syntax. 2002-09-05 12:49:23 +00:00
Andres Salomon
dac578a775 update, synch w/ debian 2002-09-01 23:08:17 +00:00
Joe Thornber
04732ce74b o inline _step_matcher 2002-08-29 15:05:16 +00:00
Joe Thornber
a6c95a2374 o Give an example filter that uses anchors. 2002-08-29 14:47:06 +00:00
Joe Thornber
f68622abe9 o Anchor support for the regex engine. 2002-08-29 14:46:30 +00:00
AJ Lewis
83a9a7bdb2 o This resolves bug #79
o added -D_REENTRANT to the CFLAGS so clvmd works properly with liblvm
   (I saw this problem with Redhat 7.3)
2002-08-15 15:31:33 +00:00
Patrick Caulfield
6500afc0ca Remove O_DIRECT as it causes problems with some systems.
Harumph.
2002-08-14 14:58:00 +00:00
Joe Thornber
c69b7ecc96 o Remove e2fsadm to stop people waiting expectantly for something that isn't going
to arrive.
2002-08-08 07:54:57 +00:00
Joe Thornber
615ef1e2d2 o Make sure the status parsing code can deal with an empty array. 2002-08-01 12:51:48 +00:00
Joe Thornber
cf69a0cd7f o Added new value type CFG_EMPTY_ARRAY, to indicate '[]', useful since we use
the arrays to hold a symbolic set of flags.
2002-08-01 12:46:52 +00:00
Joe Thornber
06e892fb33 o 0 was used rather than NULL in a couple of places.
o  Indent output with tabs rather than single spaces.
2002-08-01 08:22:09 +00:00
Joe Thornber
e6c5dd6865 o Test program for the config unit. Just reads a config and then writes it
out again.
2002-08-01 08:18:54 +00:00
Patrick Caulfield
247efdebdb Rename lock_resource to file_lock_resource to avoid name clashes 2002-07-25 09:04:30 +00:00
Patrick Caulfield
76f3792287 Use O_DIRECT for writing to devices.
Doesn't work on HPPA due to a kernel bug but other archs shuld be OK.
2002-07-22 08:10:54 +00:00
Alasdair Kergon
64d8e2c727 Remove hard-coded extent_size from snapshot target (field no longer used). 2002-07-17 17:00:54 +00:00
Alasdair Kergon
ead0bd9cb0 Improved snapshot-related arg validation 2002-07-17 16:04:05 +00:00
Joe Thornber
66fc13b2ec i) Add the VISIBLE flag to the text format. (Other changes are pending
for lib/activate.)
2002-07-11 15:28:49 +00:00
Joe Thornber
f3af4128b0 i) Added a little macro to aid defining the status flags. 2002-07-11 14:36:45 +00:00
Joe Thornber
0e43107c87 i) There's now a seperate field in struct logical_volume that stores the
allocation policy.  This can currently take one of three values:

   typedef enum {
        ALLOC_NEXT_FREE,
        ALLOC_STRICT,
        ALLOC_CONTIGUOUS
   } alloc_policy_t;

    Notice that 'SIMPLE' has turned into the slightly more meaningful NEXT_FREE.

ii) Put code into display.[hc] for converting one of these enums to a
    text representation and back again.

ii) Updated the text format so this also has the alloc_policy field.
2002-07-11 14:21:49 +00:00
Alasdair Kergon
1ee3e7997e tidy 2002-07-11 14:09:26 +00:00
Alasdair Kergon
50fd61d91f Add get_config_str 2002-07-11 14:07:43 +00:00
Patrick Caulfield
e4cdc051a9 Don't log an error if we can't write the cache file because the FS is read-only.
Gets rid of that annoying error at shutdown.
2002-07-11 09:23:29 +00:00
Alasdair Kergon
778e846e96 Add --ignorelockingfailure 2002-07-10 20:43:32 +00:00
Alasdair Kergon
a27759b647 Merge adjacent "Missing" segments. 2002-07-10 13:54:17 +00:00
Joe Thornber
b75eceab41 o Add version number to text format. 2002-07-02 18:47:43 +00:00
Alasdair Kergon
e748a5d5f4 Tidy up for another release: updated documentation; removed old files;
module build fix.
2002-06-26 21:50:53 +00:00
Patrick Caulfield
99c5a3ae46 Flush on open as well as close. 2002-06-25 14:02:28 +00:00
Alasdair Kergon
51da710f5a o Long-awaited ioctl interface clean-up. *** Not backwardly compatible ***
o Various other kernel side tidy-ups.
o Version number changes so we have the option of adding new ioctl commands
  in future without affecting the use of existing ones should you later
  revert to an older kernel but not revert the userspace library/tools.
o Better separation of kernel/userspace elements in the build process to
  prepare for independent distribution of the kernel driver.
2002-06-19 13:07:05 +00:00
Joe Thornber
569d69b3d2 o Knock the version check out of the makefile, Alasdair will no doubt put it back :)
o  Change to new ioctl names.
2002-06-17 15:50:17 +00:00
Patrick Caulfield
059a6b1d90 Get rid of compile warnings on 64bit platforms. 2002-06-07 08:37:07 +00:00
Alasdair Kergon
990af7548a Increment version. 2002-05-31 19:33:30 +00:00
Alasdair Kergon
a38aefdfc8 Add vgsplit. 2002-05-31 19:30:51 +00:00
Alasdair Kergon
3bcb12e7d1 Tidy/fix segment rounding. 2002-05-31 19:29:43 +00:00
Alasdair Kergon
7904ecb462 Tidy 2002-05-31 19:28:37 +00:00
Alasdair Kergon
9ba4d45109 Remember to update VG free_count when reducing size of an LV. 2002-05-30 16:08:19 +00:00
Alasdair Kergon
56b8afe19d Fix vgcfgrestore segfault (wrong variable used). 2002-05-30 16:03:26 +00:00
Alasdair Kergon
f7aed9a94c update 2002-05-27 13:00:18 +00:00
AJ Lewis
e12a7e881d o fix changed function names 2002-05-23 14:13:21 +00:00
Alasdair Kergon
5afb65325d Fix LVM1 backwards compatibility issue when LV with a low LV number is deleted. 2002-05-23 11:37:51 +00:00
Joe Thornber
135f520f32 o Remove ext3 incompatibility bug
o	Mention 2.4.18 VM problem
2002-05-23 08:20:44 +00:00
Andres Salomon
bc251f4ff6 update for .08 2002-05-23 07:49:25 +00:00
Alasdair Kergon
b8769751f6 Rename; add some FIXMEs. 2002-05-22 14:03:45 +00:00
385 changed files with 73461 additions and 16358 deletions

1
BUGS
View File

@@ -1 +0,0 @@
LVM2's device-mapper driver and ext3 are incompatible at the moment.

0
CONTRIBUTORS Normal file
View File

21
INSTALL
View File

@@ -6,8 +6,8 @@ LVM2 installation
Ensure the device-mapper has been installed on the machine.
The device-mapper should be in the kernel (look for 'device-mapper'
messages in the kernel logs) and /usr/include/libdevmapper.h should
be present.
messages in the kernel logs) and /usr/include/libdevmapper.h
and libdevmapper.so should be present.
The device-mapper is available from:
ftp://ftp.sistina.com/pub/LVM2/device-mapper/
@@ -17,9 +17,15 @@ LVM2 installation
Run the 'configure' script from the top directory.
If you do not have GNU readline (http://www.gnu.org/directory/readline.html)
installed use
./configure --disable-readline
If you wish to use the built-in LVM2 shell and have GNU readline
installed (http://www.gnu.org/directory/readline.html) use:
./configure --enable-readline
If you don't want to include the LVM1 backwards-compatibility code use:
./configure --with-lvm1=none
To separate the LVM1 support into a shared library loaded by lvm.conf use:
./configure --with-lvm1=shared
3) Build and install LVM2.
@@ -31,6 +37,9 @@ LVM2 installation
The tools will work fine without a configuration file being
present, but you ought to review the example file in doc/example.conf.
For example, specifying the devices that LVM2 is to use should
For example, specifying the devices that LVM2 is to use can
make the tools run more efficiently - and avoid scanning /dev/cdrom!
Please also refer to the WHATS_NEW file and the manual pages for the
individual commands.

18
INTRO
View File

@@ -1,18 +0,0 @@
An introduction to LVM2
=======================
Background
Compatibility with LVM1
New features
Missing features
Future enhancements

View File

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

22
README
View File

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

28
TODO
View File

@@ -1,28 +0,0 @@
before 2.0
-----------
vgexport
vgimport
snapshots
pvmove
device-mapper support for 2.5 kernel series
review FIXMEs
extra validation & full consistency checks in format1 with LVM1
partial activation (aka VG quorum)
error message review
locking during metadata changes
format2 with atomic transactions
bidirectional format1/format2 migration tool
persistent minors
statistics target and tool support
review tool exit codes for LVM1 compatibility
before 2.1
----------
e2fsadm
lvmsadc
lvmsar
pvdata
vgsplit
vgmknodes

View File

@@ -1 +1 @@
1.95.08-cvs (2002-05-21)
2.02.03-cvs (2006-02-08)

638
WHATS_NEW Normal file
View File

@@ -0,0 +1,638 @@
Version 2.02.03 -
===================================
Fix dmeventd build.
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
================================
Fix pvmove segment splitting.
Abstract vg_validate.
Only make one attempt at contiguous allocation.
Fix lvm1 format metadata read.
Fix lvm1 format non-mirror lvcreate.
Version 2.01.12 - 14th June 2005
================================
Various allocation-related pvmove fixes.
Log an error if clvmd can't resolve a host name got from CCS.
Fix potential spin loop in clvmd.
Version 2.01.11 - 13th June 2005
================================
Added lvmconf.sh.
Use matchpathcon mode parameter.
Don't defer closing dead FDs in clvmd.
Remove hard-coded 64k text metadata writing restriction.
Make VG name restrictions consistent.
Introduce lvconvert. So far only removes mirror images.
Allow mirror images to be resized.
Allow mirror images to have more than one segment.
Centralise restrictions on LV names.
Always insert an intermediate layer for mirrors.
Suppress hidden LVs from reports unless --all is given.
Use square brackets for hidden LVs in reports.
Allow the creation of mirrors with contiguous extents.
Always perform sanity checks against metadata before committing it to disk.
Split lv_extend into two steps: choosing extents + allocation to LV(s).
Add mirror log region size to metadata.
Use list_iterate_items throughout and add list*back macros.
Introduce seg_ macros to access areas.
Add segtype_is_ macros.
Support tiny metadata areas for pool conversions.
Mirror activation handles disk log as well as core.
Activation code recognises mirror log dependency.
Add mirror_log and regionsize fields to report.
Fix non-orphan pvchange -u.
Fix vgmerge to handle duplicate LVIDs.
Move archiver code from tools into library.
vgscan/change/display/vgs automatically create metadata backups if needed.
Merge cloned allocation functions.
Fix contiguous allocation policy with linear.
Cope with missing format1 PVs again.
Remove lists of free PV segments.
Simplify pv_maps code and remove slow bitset algorithm.
Red-Hat-ify the clvmd rhel4 initscript.
%Zu->%zu
Fix loopfiles alias alloc & mem debugging.
Un-inline dbg_strdup.
lv_reduce tidying.
Remove some unnecessary parameters.
Introduce seg_is macros.
Version 2.01.10 - 3rd May 2005
==============================
Don't create backup and archive dirs till needed.
Reinstate full PV size when removing from VG.
Support loopfiles for testing.
Tidy lv_segment interface.
pv_segment support.
vgchange --physicalextentsize
Internal snapshot restructuring.
Remove unused internal non-persistent snapshot option.
Allow offline extension of snapshot volumes.
Move from 2-step to 3-step on-disk metadata commit.
Scan ramdisks too and allow non-O_DIRECT fallback.
Annotate, tidy and extend list.h.
Alignment tidying.
Make clvmd work around some "bugs" in gulm's node state notifications.
Tidy clvmd's SIGHUP handler
Version 2.01.09 - 4th April 2005
================================
Add --ignorelockingfailure to vgmknodes.
clvmd: Don't allow user operations to start until the lvm thread is fully up.
clvmd-gulm: set KEEPALIVE on sockets.
Version 2.01.08 - 22nd March 2005
=================================
Add clustered attribute so vgchange can identify clustered VGs w/o locking.
Improve detection of external changes affecting internal cache.
Add 'already in device cache' debug message.
Add -a to pvdisplay -C.
Avoid rmdir opendir error messsages when dir was already removed.
Tighten signal handlers.
Avoid some compiler warnings.
Additional rename failure error message.
read/write may be macros.
clvmd: don't take out lvm thread lock at startup, it only protects jobs list.
Version 2.01.07 - 8th March 2005
================================
Cope with new devices appearing by rescanning /dev if a uuid can't be found.
Remove DESTDIR from LVM_SHARED_PATH.
clvmd fixes: make FDs close-on-exec
gulm unlocks VG & orphan locks at startup in case they are stale
gulm now unlocks VG & orphan locks if client dies.
Version 2.01.06 - 1st March 2005
================================
Suppress 'open failed' error messages during scanning.
Option to suppress warnings of file descriptors left open.
Fix default value of metadatacopies in documentation (2->1).
Fix clvmd-gulm locking.
./configure --enable-debug now enables debugging code in clvmd.
Fix clvmd-gulm node up/down code so it actually works.
clvmd-gulm now releases locks when shut down.
Version 2.01.05 - 18th February 2005
====================================
Static binary invokes dynamic binary if appropriate.
Make clvmd config check a little more tolerant.
gulm clvmd can now cope with >1 message arriving in a TCP message.
Version 2.01.04 - 9th February 2005
===================================
Add fixed offset to imported pool minor numbers.
Update binary pathnames in clvmd_init_rhel4.
lvm2cmd.so should skip the check for open fds.
Remove unused -f from pvmove.
Gulm clvmd doesn't report "connection refused" errors.
clvmd does a basic config file sanity check at startup.
Fix potential thread shutdown race in clvmd.
Version 2.01.03 - 1st February 2005
===================================
More 64-bit display/report fixes.
More informative startup mesg if can't create /etc/lvm.
Fix snapshot device size bug (since 2.01.01).
clvmd announces startup and cluster connection in syslog.
Gulm clvmd doesn't hang trying to talk to a rebooted node.
Gulm clvmd doesn't print cman error on startup.
Version 2.01.02 - 21st January 2005
===================================
Update clvmd_init_rhel4: use lvm.static and don't load dlm.
Fix some size_t printing.
Fix 64 bit xlate consts.
Split out pool sptype_names to avoid unused const.
Always fail if random id generation fails.
Recognise gnbd devices.
Fix clvmd startup bug introduced in cman/gulm amalgamation.
Improve reporting of node-specific locking errors.
Version 2.01.01 - 19th January 2005
===================================
Fix clvmd lv_info_by_lvid open_count.
Store snapshot and origin sizes separately.
Update vgcreate man page.
Version 2.01.00 - 17th January 2005
===================================
Fix vgscan metadata auto-correction.
Only ask libdevmapper for open_count when we need it.
Adjust RHEL4 clvmd init script priority.
Enable building of CMAN & GULM versions of clvmd into a single binary
Version 2.00.33 - 7th January 2005
==================================
pvcreate wipes first 4 sectors unless given --zero n.
gulm clvmd now uses new ccsd key names.
gulm clvmd now doesn't ignore the first node in cluster.conf
Improve clvmd failure message if it's already running.
Allow user to kill clvmd during initialisation.
Fix off-by-one error in cluster_locking that could cause read hangs.
Version 2.00.32 - 22nd December 2004
====================================
Drop static/dl restriction for now.
Fix an error fprintf.
Fix vgdisplay -s. Breaks (undocumented) lvs/pvs/vgs -s instead for now.
Fix device reference counting on re-opens.
Ignore sysfs symlinks when DT_UNKNOWN.
Add clvmd init script for RHEL4.
Skip devices that are too small to be PVs.
Fix pvchange -x segfault with lvm2-format orphan.
Cope with empty msdos partition tables.
Add CONTRIBUTORS file.
Version 2.00.31 - 12th December 2004
====================================
Reopen RO file descriptors RW if necessary.
Version 2.00.30 - 10th December 2004
====================================
Additional device-handling debug messages.
Additional verbosity level -vvvv includes line numbers and backtraces.
Verbose messages now go to stderr not stdout.
Close any stray file descriptors before starting.
Refine partitionable checks for certain device types.
Allow devices/types to override built-ins.
Fix lvreduce man page .i->.I
Fix vgsplit man page title.
Fix clvmd man makefile.
Extend dev_open logging.
Make clvmd_fix_conf.sh UNDOable.
Version 2.00.29 - 27th November 2004
====================================
xlate compilation fix.
Version 2.00.28 - 27th November 2004
====================================
Fix partition table & md signature detection.
Minor configure/makefile tidy.
Export version.h from tools for clvmd.
Version 2.00.27 - 24th November 2004
====================================
Trap large memory allocation requests.
Fix to partition table detection code.
Improve filter debug mesgs.
Make clvmd_fix_conf.sh UNDOable
Version 2.00.26 - 23rd November 2004
====================================
Improve pool debugging stats.
Detect partition table signature.
pvcreate wipes md superblocks. (With --uuid or --restorefile it prompts.)
Separate out md superblock detection code.
Prevent snapshot origin resizing.
Improve a vgremove error message.
Update some man pages.
Allow y/n with -ae args (exclusive activation).
Fixes to lvcreate vgname parsing.
Fix dm_name string size calculation.
Improve clvmd error reporting during startup.
Make clvmd cope with large gaps in node numbers IDs.
Make clvmd initialisation cope better with debugging output.
Tidy clvmd socket callbacks so all work happens outside main loop.
clvmd -V now displays lvm version too.
Add optional gulm build for clvmd
Version 2.00.25 - 29th September 2004
=====================================
Fix return code from rm_link for vgmknodes.
Make clvmd LV hash table thread-safe.
Fix clvmd locking so it will lock out multiple users on the same node.
Fix clvmd VG locking to it can cope with multiple VG locks.
Remove spurious trailing dot in lvreduce man page.
Fix vgremove locking.
Version 2.00.24 - 16th September 2004
=====================================
Fix pool_empty so it really does empty the memory pool.
Rename old segtypes files to segtype.
Some fixes to memory debugging code.
Exclude internal commands formats & segtypes from install.
Version 2.00.23 - 15th September 2004
=====================================
Export dm name build & split functions.
Use O_NOATIME on devices if available.
Write log message when each segtype/format gets initialised.
New commands 'segtypes' and 'formats'.
Suppress pvmove abort message in test mode.
Improve pvcreate/remove device not found error message.
Allow pvmove to move data within the same PV.
Describe how pvmove works on man page.
Test for incompatible format/segtype combinations in lv_extend.
Fix lvchange example on man page.
Version 2.00.22 - 3rd September 2004
====================================
Fix /dev/vgname perms.
Restructure xlate.h.
Add clvmd man page.
Version 2.00.21 - 19th August 2004
==================================
Update cnxman-socket.h from cman.
Recognise iseries/vd devices.
Use 'make install_cluster' to install cluster extensions only.
Cope with DT_UNKNOWN in sysfs.
Fix extents_moved metadata size comment.
Remove duplicate line in pvremove help text.
Support variable mirror region size.
Support PE ranges in pvmove source PV.
Fixes to as-yet-unused LV segment splitting code.
Change alloc_areas to pe_ranges and allow suppression of availability checks.
Add dev_size column to pvs.
Add report columns for in-kernel device number.
Version 2.00.20 - 3 July 2004
=============================
More autoconf fixes.
Fix device number handling for 2.6 kernels.
Version 2.00.19 - 29 June 2004
==============================
Reduce severity of setlocale failure message.
Recognise argv[0] "initrd-lvm" (pld-linux).
Make -O2 configurable.
Added --disable-selinux to configure script.
LD_FLAGS->LDFLAGS & LD_DEPS->LDDEPS in configure script.
Add init_debug to clvmd.
Version 2.00.18 - 24 June 2004
==============================
Fix vgchange activation.
Add cluster support.
Version 2.00.17 - 20 June 2004
==============================
configure --enable-fsadm to try out fsadm. fsadm is not tested yet.
Display all filtered devices, not just PVs, with pvs -a.
Fix sync_dir() when no / in filename
vgcfgbackup -f accepts template with %s for VG name.
Extend hash functions to handle non-null-terminated data.
Add local activation support.
Tidy relative paths in makefile includes.
fsadm support for fsck and resizing - needs testing.
Add read-only GFS pool support.
Add lvm2create_initrd script from http://poochiereds.net/svn/lvm2/
Fix rounding of large diplayed sizes.
Suppress decimal point when using units of sectors/bytes.
Additional kernel target checks before pvmove & snapshot creation.
Add i2o_block.
Version 2.00.16 - 24 May 2004
=============================
Set area_count within alloc_lv_segment.
Remove error labels from lvresize.
Fix a pvs error path.
xxchange -ae for exclusive activation.
Don't return non-zero status if there aren't any volume groups.
Add --alloc argument to tools.
Rename allocation policies to contiguous, normal, anywhere, inherit.
nextfree becomes normal; anywhere isn't implemented yet.
LV inherits allocation policy from VG. Defaults: LV - inherit; VG - normal
Additional status character added to vgs to indicate allocation policy.
Add reset_fn to external_locking.
Ensure presence of virtual targets before attempting activating.
Attempt to fix resizing of snapshot origins.
Restructure lvresize, bringing it closer to lvcreate.
A quick sanity check on vg_disk struct when read in. More checks needed.
Only include visible LVs in active/open counts.
Add virtual segment types, zero and error. A large sparse device can be
constructed as a writeable snapshot of a large zero segment.
Add --type to lvcreate/resize.
Push lv_create & alloc policy up to tool level.
Fix pvdisplay return code.
Detect invalid LV names in arg lists.
Reporting uses line-at-a-time output.
lvm2 format sets unlimited_vols format flag.
Internal-only metadata flag support.
Basic checking for presence of device-mapper targets.
Separate out polldaemon.
Revise internal locking semantics.
Move find_pv_by_name to library.
Rename move->copy.
Add devices to segments report.
Begin separating out segment code. There's a lot of change here.
Compress any (obsolete) long LVM1 pvids encountered.
Support for tagged config files.
Don't abort operations if selinux present but disabled.
Fix typo in configure which left HAVE_LIBDL unset.
Version 2.00.15 - 19 Apr 2004
=============================
configure --with-owner= --with-group= to avoid -o and -g args to 'install'
Version 2.00.14 - 16 Apr 2004
=============================
Use 64-bit file functions by default.
Version 2.00.13 - 16 Apr 2004
=============================
Set devices/md_component_detection = 1 to ignore devices containing md
superblocks. [Luca Berra]
Ignore error setting selinux file context if fs doesn't support it.
Version 2.00.12 - 14 Apr 2004
=============================
Install a default lvm.conf into /etc/lvm if there isn't one already.
Allow different installation dir for lvm.static (configure --staticdir=)
Fix inverted selinux error check.
Recognise power2 in /proc/devices.
Fix counting in lvs_in_vg_opened. [It ignored devices open more than once.]
Version 2.00.11 - 8 Apr 2004
============================
Set fallback_to_lvm1 in lvm.conf (or configure --enable-lvm1_fallback)
to run lvm1 binaries if running a 2.4 kernel without device-mapper.
Version 2.00.10 - 7 Apr 2004
============================
More fixes for static build.
Add basic selinux support.
Fix sysfs detection.
Version 2.00.09 - 31 Mar 2004
=============================
Update copyright notices for Red Hat.
Fix vgmknodes to remove dud /dev/mapper entries. (libdevmapper update reqd).
Add LVM1-style colon output to vgdisplay.
lvchange --refresh to reload active LVs.
Add string display to memory leak dump.
Add locking flags & memlock option.
Add list_versions to library.
Ignore open hidden LVs when checking if deactivation is OK.
Suppress move percentage when device inactive.
Add lv_info_by_lvid.
Various tidy-ups to the build process.
Rebaseline internal verbose level.
Add --nolocking option for read operations if locking is failing.
Add option to compile into a library.
When compiled without libdevmapper, only print warning message once.
Fix lvreduce PV extent calculations.
Fix DESTDIR to work with configure path overrides.
Always use / as config file separator & rename internal config file variables.
Add support for tagging PV/VG/LVs and hosts.
Fix rare bug in recognition of long cmdline argument forms.
Add basic internationalisation infrastructure.
Don't recurse symlinked dirs such as /dev/fd on 2.6 kernels.
Update autoconf files.
Add sysfs block device filtering for 2.6 kernels.
Update refs for move to sources.redhat.com.
Friday 14th November 2003
=========================
Some bug fixes & minor enhancements, including:
Backwards compatibility with LVM1 metadata improved.
Missing man pages written.
Tool error codes made more consistent.
vgmknodes written.
O_DIRECT can be turned off if it doesn't work in your kernel.
dumpconfig to display the active configuration file
You need to update libdevmapper before using 'vgmknodes' or 'vgscan --mknodes'.
If your root filesystem is on an LV, you should run one of those two
commands to fix up the special files in /dev in your real root filesystem
after finishing with your initrd. Also, remember you can use
'vgchange --ignorelockingfailure' on your initrd if the tool fails because
it can't write a lock file to a read-only filesystem.
Wednesday 30th April 2003
=========================
A pvmove implementation is now available for the new metadata format.
When running a command that allocates space (e.g. lvcreate), you can now
restrict not only which disk(s) may be used but also the Physical Extents
on those disks. e.g. lvcreate -L 10 vg1 /dev/hda6:1000-2000:3000-4000
Monday 18th November 2002
========================
The new format of LVM metadata is ready for you to test!
We expect it to be more efficient and more robust than the original format.
It's more compact and supports transactional changes and replication.
Should things go wrong on a system, it's human-readable (and editable).
Please report any problems you find to the mailing list,
linux-lvm@sistina.com. The software has NOT yet been thoroughly
tested and so quite possibly there'll still be some bugs in it.
Be aware of the disclaimer in the COPYING file.
While testing, we recommend turning logging on in the configuration file
to provide us with diagnostic information:
log {
file="/tmp/lvm2.log"
level=7
activation=1
}
You should schedule regular backups of your configuration file and
metadata backups and archives (normally kept under /etc/lvm).
Please read docs/example.conf and "man lvm.conf" to find out more about
the configuration file.
To convert an existing volume group called vg1 to the new format using
the default settings, use "vgconvert -M2 vg1". See "man vgconvert".
-M (or --metadatatype in its long form) is a new flag to indicate which
format of metadata the command should use for anything it creates.
Currently, the valid types are "lvm1" and "lvm2" and they can be
abbreviated to "1" and "2" respectively. The default value for this
flag can be changed in the global section in the config file.
Backwards-compatible support for the original LVM1 metadata format is
maintained, but it can be moved into a shared library or removed
completely with configure's --with-lvm1 option.
Under LVM2, the basic unit of metadata is the volume group. Different
volume groups can use different formats of metadata - vg1 could use
the original LVM1 format while vg2 used the new format - but you can't
mix formats within a volume group. So to add a PV to an LVM2-format
volume group you must run "pvcreate -M2" on it, followed by "vgextend".
With LVM2-format metadata, lvextend will let you specify striping
parameters. So an LV could consist of two or more "segments" - the
first segment could have 3 stripes while the second segment has just 2.
LVM2 maintains a backup of the current metadata for each volume group
in /etc/lvm/backup, and puts copies of previous versions in
/etc/lvm/archive. "vgcfgbackup" and "vgcfgrestore" can be used to
create and restore from these files. If you fully understand what
you're doing, metadata can be changed by editing a copy of a current
backup file and using vgcfgrestore to reload it.
Please read the pvcreate man page for more information on the new
format for metadata.
All tools that can change things have a --test flag which can be used
to check the effect of a set of cmdline args without really making the
changes.
What's not finished?
====================
The internal cache. If you turn on debugging output you'll see lots of
repeated messages, many of which will eventually get optimised out.
--test sometimes causes a command to fail (e.g. vgconvert --test) even
though the real command would work: again, fixing this is waiting for
the work on the cache.
Several of the tools do not yet contain the logic to handle full
recovery: combinations of pvcreate and vgcfgrestore may sometimes be
needed to restore metadata if a tool gets interrupted or crashes or
finds something unexpected. This applies particularly to tools that
work on more than one volume group at once (e.g. vgsplit).
Display output. Some metadata information cannot yet be displayed.
Recovery tools to salvage "lost" metadata directly from the disks:
but we hope the new format will mean such tools are hardly ever needed!

164
WHATS_NEW_DM Normal file
View File

@@ -0,0 +1,164 @@
Version 1.02.04 -
============================
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
=============================
Use matchpathcon mode parameter.
Fix configure script to re-enable selinux.
Version 1.01.02 - 17 May 2005
=============================
Call dm_lib_exit() and dm_lib_release() automatically now.
Add --target <target_type> filter to dmsetup table/status/ls.
Add --exec <command> to dmsetup ls.
Fix dmsetup getopt_long usage.
Version 1.01.01 - 29 Mar 2005
=============================
Update dmsetup man page.
Drop-in devmap_name replacement.
Add option to compile without ioctl for testing.
Fix DM_LIB_VERSION sed.
Version 1.01.00 - 17 Jan 2005
=============================
Add dm_task_no_open_count() to skip getting open_count.
Version 1.00.21 - 7 Jan 2005
============================
Fix /proc/devices parsing.
Version 1.00.20 - 6 Jan 2005
============================
Attempt to fix /dev/mapper/control transparently if it's wrong.
Configuration-time option for setting uid/gid/mode for /dev/mapper nodes.
Update kernel patches for 2.4.27/2.4.28-pre-4 (includes minor fixes).
Add --noheadings columns option for colon-separated dmsetup output.
Support device referencing by uuid or major/minor.
Warn if kernel data didn't fit in buffer.
Fix a printf.
Version 1.00.19 - 3 July 2004
=============================
More autoconf fixes.
Fix a dmsetup newline.
Fix device number handling for 2.6 kernels.
Version 1.00.18 - 20 Jun 2004
=============================
Fix a uuid free in libdm-iface.
Fix a targets string size calc in driver.
Add -c to dmsetup for column-based output.
Add target message-passing ioctl.
Version 1.00.17 - 17 Apr 2004
=============================
configure --with-owner= --with-group= to avoid -o and -g args to 'install'
Fix library selinux linking.
Version 1.00.16 - 16 Apr 2004
=============================
Ignore error setting selinux file context if fs doesn't support it.
Version 1.00.15 - 7 Apr 2004
============================
Fix status overflow check in kernel patches.
Version 1.00.14 - 6 Apr 2004
============================
Fix static selinux build.
Version 1.00.13 - 6 Apr 2004
============================
Add some basic selinux support.
Version 1.00.12 - 6 Apr 2004
============================
Fix dmsetup.static install.
Version 1.00.11 - 5 Apr 2004
============================
configure --enable-static_link does static build in addition to dynamic.
Moved Makefile library targets definition into template.
Version 1.00.10 - 2 Apr 2004
============================
Fix DESTDIR handling.
Static build installs to dmsetup.static.
Basic support for internationalisation.
Minor Makefile tidy-ups/fixes.
Version 1.00.09 - 31 Mar 2004
=============================
Update copyright notices to Red Hat.
Move full mknodes functionality from dmsetup into libdevmapper.
Avoid sscanf %as for uClibc compatibility.
Cope if DM_LIST_VERSIONS is not defined.
Add DM_LIST_VERSIONS functionality to kernel patches.
Generate new kernel patches for 2.4.26-rc1.
Version 1.00.08 - 27 Feb 2004
=============================
Added 'dmsetup targets'.
Added event_nr support to 'dmsetup wait'.
Updated dmsetup man page.
Allow logging function to be reset to use internal one.
Bring log macros in line with LVM2 ones.
Added 'make install_static_lib' which installs libdevmapper.a.
Made configure/makefiles closer to LVM2 versions.
Fixed DESTDIR for make install/install_static_lib.
Updated README/INSTALL to reflect move to sources.redhat.com.
Updated autoconf files to 2003-06-17.

1082
autoconf/config.guess vendored

File diff suppressed because it is too large Load Diff

560
autoconf/config.sub vendored
View File

@@ -1,6 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc.
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2003-06-17'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
@@ -25,6 +29,9 @@
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
@@ -45,30 +52,73 @@
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
if [ x$1 = x ]
then
echo Configuration name missing. 1>&2
echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
echo "or $0 ALIAS" 1>&2
echo where ALIAS is a recognized configuration type. 1>&2
exit 1
fi
me=`echo "$0" | sed -e 's,.*/,,'`
# First pass through any local machine types.
case $1 in
*local*)
echo $1
exit 0
;;
*)
;;
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS
$0 [OPTION] ALIAS
Canonicalize a configuration name.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help"
exit 1 ;;
*local*)
# First pass through any local machine types.
echo $1
exit 0;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
linux-gnu*)
nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -94,7 +144,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple)
-apple | -axis)
os=
basic_machine=$1
;;
@@ -105,9 +155,17 @@ case $os in
-scout)
;;
-wrs)
os=vxworks
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
@@ -156,33 +214,72 @@ case $os in
-psos*)
os=-psos
;;
-mint | -mint[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
| 580 | i960 | h8300 \
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
| alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \
| we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
| 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
| mips64vr5000 | miprs64vr5000el | mcore \
| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
| thumb | d10v)
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k \
| m32r | m68000 | m68k | m88k | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64vr | mips64vrel \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| msp430 \
| ns16k | ns32k \
| openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65)
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i[34567]86)
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
@@ -191,24 +288,60 @@ case $basic_machine in
exit 1
;;
# Recognize the basic CPU types with company name.
# FIXME: clean up the formatting here.
vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
| xmp-* | ymp-* \
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \
| alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
| clipper-* | orion-* \
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
| mipstx39-* | mipstx39el-* | mcore-* \
| f301-* | armv*-* | t3e-* \
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
| thumb-* | v850-* | d30v-* | tic30-* | c30-* )
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* \
| m32r-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64vr-* | mips64vrel-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| msp430-* \
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -240,19 +373,22 @@ case $basic_machine in
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-cbm
basic_machine=m68k-unknown
;;
amigaos | amigados)
basic_machine=m68k-cbm
basic_machine=m68k-unknown
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-cbm
basic_machine=m68k-unknown
os=-sysv4
;;
apollo68)
@@ -271,6 +407,10 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -291,27 +431,30 @@ case $basic_machine in
basic_machine=c38-convex
os=-bsd
;;
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
cray2)
basic_machine=cray2-cray
os=-unicos
;;
[ctj]90-cray)
basic_machine=c90-cray
cray | j90)
basic_machine=j90-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
@@ -353,6 +496,10 @@ case $basic_machine in
basic_machine=tron-gmicro
os=-sysv
;;
go32)
basic_machine=i386-pc
os=-go32
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
@@ -426,22 +573,21 @@ case $basic_machine in
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i[34567]86v32)
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i[34567]86v4*)
i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i[34567]86v)
i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i[34567]86sol2)
i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
@@ -453,14 +599,6 @@ case $basic_machine in
basic_machine=i386-unknown
os=-vsta
;;
i386-go32 | go32)
basic_machine=i386-unknown
os=-go32
;;
i386-mingw32 | mingw32)
basic_machine=i386-unknown
os=-mingw32
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
@@ -486,35 +624,43 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
mingw32)
basic_machine=i386-pc
os=-mingw32
;;
miniframe)
basic_machine=m68000-convergent
;;
*mint | *MiNT)
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
mipsel*-linux*)
basic_machine=mipsel-unknown
os=-linux-gnu
;;
mips*-linux*)
basic_machine=mips-unknown
os=-linux-gnu
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
mmix*)
basic_machine=mmix-knuth
os=-mmixware
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-unknown
basic_machine=i386-pc
os=-msdos
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -524,7 +670,7 @@ case $basic_machine in
os=-netbsd
;;
netwinder)
basic_machine=armv4l-corel
basic_machine=armv4l-rebel
os=-linux
;;
news | news700 | news800 | news900)
@@ -572,13 +718,28 @@ case $basic_machine in
basic_machine=i960-intel
os=-mon960
;;
nonstopux)
basic_machine=mips-compaq
os=-nonstopux
;;
np1)
basic_machine=np1-gould
;;
nv1)
basic_machine=nv1-cray
os=-unicosmp
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
;;
or32 | or32-*)
basic_machine=or32-unknown
os=-coff
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
@@ -601,45 +762,65 @@ case $basic_machine in
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexen)
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86)
pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
pentiumii | pentium2)
pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexen-*)
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-*)
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-*)
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=rs6000-ibm
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
pw32)
basic_machine=i586-unknown
os=-pw32
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
@@ -650,10 +831,26 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
@@ -661,7 +858,10 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sparclite-wrs)
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@@ -719,20 +919,44 @@ case $basic_machine in
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
basic_machine=sv1-cray
os=-unicos
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
t3e)
basic_machine=t3e-cray
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
@@ -757,8 +981,8 @@ case $basic_machine in
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -779,13 +1003,13 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
xmp)
basic_machine=xmp-cray
os=-unicos
;;
xps | xps100)
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
@@ -806,13 +1030,6 @@ case $basic_machine in
op60c)
basic_machine=hppa1.1-oki
;;
mips)
if [ x$os = x-linux-gnu ]; then
basic_machine=mips-unknown
else
basic_machine=mips-mips
fi
;;
romp)
basic_machine=romp-ibm
;;
@@ -822,16 +1039,26 @@ case $basic_machine in
vax)
basic_machine=vax-dec
;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sparc | sparcv9)
sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
cydra)
basic_machine=cydra-cydrome
;;
orion)
@@ -846,9 +1073,8 @@ case $basic_machine in
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
c4x*)
basic_machine=c4x-none
os=-coff
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
@@ -906,14 +1132,34 @@ case $os in
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*)
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
case $basic_machine in
x86-* | i*86-*)
;;
*)
os=-nto$os
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -macos* | -mpw* | -magic* | -mon960* | -lnews*)
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
@@ -927,6 +1173,12 @@ case $os in
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
;;
-wince*)
os=-wince
;;
-osfrose*)
os=-osfrose
;;
@@ -942,14 +1194,23 @@ case $os in
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
os=-nextstep2
;;
-nsk*)
os=-nsk
;;
# Preserve the version number of sinix5.
-sinix5.*)
@@ -985,8 +1246,14 @@ case $os in
-xenix)
os=-xenix
;;
-*mint | -*MiNT)
os=-mint
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-none)
;;
@@ -1013,13 +1280,20 @@ case $basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-corel)
arm*-rebel)
os=-linux
;;
arm*-semi)
os=-aout
;;
pdp11-*)
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
@@ -1046,6 +1320,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
@@ -1109,25 +1386,25 @@ case $basic_machine in
*-next)
os=-nextstep3
;;
*-gould)
*-gould)
os=-sysv
;;
*-highlevel)
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
*-sgi)
os=-irix
;;
*-siemens)
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
f301-fujitsu)
f30[01]-fujitsu | f700-fujitsu)
os=-uxpv
;;
*-rom68k)
@@ -1187,13 +1464,13 @@ case $basic_machine in
-genix*)
vendor=ns
;;
-mvs*)
-mvs* | -opened*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-vxsim* | -vxworks*)
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
@@ -1205,12 +1482,23 @@ case $basic_machine in
-mpw* | -macos*)
vendor=apple
;;
-*mint | -*MiNT)
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:

View File

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

11876
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,64 @@
################################################################################
##
## Copyright 1999-2000 Sistina Software, Inc.
## Copyright (C) 2000-2004 Sistina Software, Inc. All rights reserved.
## Copyright (C) 2004 Red Hat, Inc. All rights reserved.
##
## This is free software released under the GNU General Public License.
## There is no warranty for this software. See the file COPYING for
## details.
## This file is part of the LVM2.
##
## See the file CONTRIBUTORS for a list of contributors.
## This 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.
##
## This file is maintained by:
## AJ Lewis <lewis@sistina.com>
##
## File name: configure.in
##
## Description: Input file for autoconf. Generates the configure script
## that tries to keep everything nice and portable. It also
## simplifies distribution package building considerably.
## 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
################################################################################
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.53)
################################################################################
dnl -- Process this file with autoconf to produce a configure script.
AC_INIT(lib/device/dev-cache.h)
dnl setup the directory where autoconf has auxilary files
################################################################################
dnl -- Setup the directory where autoconf has auxilary files
AC_CONFIG_AUX_DIR(autoconf)
dnl Checks for programs.
################################################################################
dnl -- Get system type
AC_CANONICAL_SYSTEM
case "$host_os" in
linux*)
CFLAGS="$CFLAGS"
COPTIMISE_FLAG="-O2"
CLDFLAGS="$CLDFLAGS -Wl,--version-script,.export.sym"
CLDWHOLEARCHIVE="-Wl,-whole-archive"
CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive"
LDDEPS="$LDDEPS .export.sym"
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
LIB_SUFFIX="so"
DEVMAPPER=yes
ODIRECT=yes
SELINUX=yes
CLUSTER=internal
FSADM=no ;;
darwin*)
CFLAGS="$CFLAGS -no-cpp-precomp -fno-common"
COPTIMISE_FLAG="-O2"
CLDFLAGS="$CLDFLAGS"
CLDWHOLEARCHIVE="-all_load"
CLDNOWHOLEARCHIVE=
LDDEPS="$LDDEPS"
LDFLAGS="$LDFLAGS"
LIB_SUFFIX="dylib"
DEVMAPPER=yes
ODIRECT=no
SELINUX=no
CLUSTER=none
FSADM=no ;;
esac
################################################################################
dnl -- Checks for programs.
AC_PROG_AWK
AC_PROG_CC
AC_PROG_INSTALL
@@ -32,57 +66,327 @@ AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_RANLIB
dnl Checks for header files.
################################################################################
dnl -- Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h malloc.h sys/ioctl.h unistd.h)
AC_HEADER_SYS_WAIT
AC_HEADER_TIME
dnl Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADERS(fcntl.h limits.h locale.h stddef.h syslog.h sys/file.h sys/ioctl.h sys/param.h sys/time.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_HEADERS(assert.h ctype.h libgen.h signal.h stdio.h sys/mman.h sys/resource.h sys/stat.h sys/types.h sys/utsname.h sys/wait.h time.h,,AC_MSG_ERROR(bailing out))
case "$host_os" in
linux*)
AC_CHECK_HEADERS(asm/byteorder.h linux/fs.h malloc.h,,AC_MSG_ERROR(bailing out)) ;;
darwin*)
AC_CHECK_HEADERS(machine/endian.h sys/disk.h,,AC_MSG_ERROR(bailing out)) ;;
esac
################################################################################
dnl -- Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_MODE_T
AC_STRUCT_ST_RDEV
AC_HEADER_TIME
AC_STRUCT_TM
dnl -- prefix is /usr by default, the exec_prefix default is setup later
################################################################################
dnl -- Check for functions
AC_CHECK_FUNCS(gethostname getpagesize memset munmap setlocale strcasecmp strchr strdup strncasecmp strerror strrchr strstr strtol strtoul,,AC_MSG_ERROR(bailing out))
AC_FUNC_ALLOCA
AC_FUNC_CLOSEDIR_VOID
AC_FUNC_FORK
AC_FUNC_LSTAT
AC_FUNC_MALLOC
AC_FUNC_MEMCMP
AC_FUNC_MMAP
AC_FUNC_STAT
AC_FUNC_STRTOD
################################################################################
dnl -- Prefix is /usr by default, the exec_prefix default is setup later
AC_PREFIX_DEFAULT(/usr)
dnl -- setup the ownership of the files
################################################################################
dnl -- Parallel make jobs?
AC_ARG_ENABLE(jobs, [ --enable-jobs=NUM Number of jobs to run simultaneously], JOBS=-j$enableval, JOBS=-j2)
################################################################################
dnl -- Setup the ownership of the files
AC_MSG_CHECKING(file owner)
OWNER="root"
AC_ARG_WITH(user,
[ --with-user=USER Set the owner of installed files ],
[ OWNER="$withval" ],
[ OWNER="root" ])
[ OWNER="$withval" ])
AC_MSG_RESULT($OWNER)
dnl -- setup the group ownership of the files
if test x$OWNER != x; then
OWNER="-o $OWNER"
fi
################################################################################
dnl -- Setup the group ownership of the files
AC_MSG_CHECKING(group owner)
GROUP="root"
AC_ARG_WITH(group,
[ --with-group=GROUP Set the group owner of installed files ],
[ GROUP="$withval" ],
[ GROUP="root" ])
[ GROUP="$withval" ])
AC_MSG_RESULT($GROUP)
AC_ARG_ENABLE(jobs, [ --enable-jobs=NUM Number of jobs to run simultaneously], JOBS=-j$enableval, JOBS=)
if test x$GROUP != x; then
GROUP="-g $GROUP"
fi
dnl Enables staticly linked tools
AC_ARG_ENABLE(static_link, [ --enable-static_link Use this to link the tools to the liblvm library
################################################################################
dnl -- LVM1 tool fallback option
AC_MSG_CHECKING(whether to enable lvm1 fallback)
AC_ARG_ENABLE(lvm1_fallback, [ --enable-lvm1_fallback Use this to fall back and use LVM1 binaries if
device-mapper is missing from the kernel], LVM1_FALLBACK=$enableval, LVM1_FALLBACK=no)
AC_MSG_RESULT($LVM1_FALLBACK)
if test x$LVM1_FALLBACK = xyes; then
CFLAGS="$CFLAGS -DLVM1_FALLBACK"
fi
################################################################################
dnl -- format1 inclusion type
AC_MSG_CHECKING(whether to include support for lvm1 metadata)
AC_ARG_WITH(lvm1,
[ --with-lvm1=TYPE LVM1 metadata support: internal/shared/none
[TYPE=internal] ],
[ LVM1="$withval" ],
[ LVM1="internal" ])
AC_MSG_RESULT($LVM1)
if [[ "x$LVM1" != xnone -a "x$LVM1" != xinternal -a "x$LVM1" != xshared ]];
then AC_MSG_ERROR(
--with-lvm1 parameter invalid
)
fi;
if test x$LVM1 = xinternal; then
CFLAGS="$CFLAGS -DLVM1_INTERNAL"
fi
################################################################################
dnl -- format_pool inclusion type
AC_MSG_CHECKING(whether to include support for GFS pool metadata)
AC_ARG_WITH(pool,
[ --with-pool=TYPE GFS pool read-only support: internal/shared/none
[TYPE=internal] ],
[ POOL="$withval" ],
[ POOL="internal" ])
AC_MSG_RESULT($POOL)
if [[ "x$POOL" != xnone -a "x$POOL" != xinternal -a "x$POOL" != xshared ]];
then AC_MSG_ERROR(
--with-pool parameter invalid
)
fi;
if test x$POOL = xinternal; then
CFLAGS="$CFLAGS -DPOOL_INTERNAL"
fi
################################################################################
dnl -- cluster_locking inclusion type
AC_MSG_CHECKING(whether to include support for cluster locking)
AC_ARG_WITH(cluster,
[ --with-cluster=TYPE Cluster LVM locking support: internal/shared/none
[TYPE=internal] ],
[ CLUSTER="$withval" ])
AC_MSG_RESULT($CLUSTER)
if [[ "x$CLUSTER" != xnone -a "x$CLUSTER" != xinternal -a "x$CLUSTER" != xshared ]];
then AC_MSG_ERROR(
--with-cluster parameter invalid
)
fi;
if test x$CLUSTER = xinternal; then
CFLAGS="$CFLAGS -DCLUSTER_LOCKING_INTERNAL"
fi
################################################################################
dnl -- snapshots inclusion type
AC_MSG_CHECKING(whether to include snapshots)
AC_ARG_WITH(snapshots,
[ --with-snapshots=TYPE Snapshot support: internal/shared/none
[TYPE=internal] ],
[ SNAPSHOTS="$withval" ],
[ SNAPSHOTS="internal" ])
AC_MSG_RESULT($SNAPSHOTS)
if [[ "x$SNAPSHOTS" != xnone -a "x$SNAPSHOTS" != xinternal -a "x$SNAPSHOTS" != xshared ]];
then AC_MSG_ERROR(
--with-snapshots parameter invalid
)
fi;
if test x$SNAPSHOTS = xinternal; then
CFLAGS="$CFLAGS -DSNAPSHOT_INTERNAL"
fi
################################################################################
dnl -- mirrors inclusion type
AC_MSG_CHECKING(whether to include mirrors)
AC_ARG_WITH(mirrors,
[ --with-mirrors=TYPE Mirror support: internal/shared/none
[TYPE=internal] ],
[ MIRRORS="$withval" ],
[ MIRRORS="internal" ])
AC_MSG_RESULT($MIRRORS)
if [[ "x$MIRRORS" != xnone -a "x$MIRRORS" != xinternal -a "x$MIRRORS" != xshared ]];
then AC_MSG_ERROR(
--with-mirrors parameter invalid
)
fi;
if test x$MIRRORS = xinternal; then
CFLAGS="$CFLAGS -DMIRRORED_INTERNAL"
fi
################################################################################
dnl -- Enables staticly-linked tools
AC_MSG_CHECKING(whether to use static linking)
AC_ARG_ENABLE(static_link, [ --enable-static_link Use this to link the tools to their libraries
statically. Default is dynamic linking], STATIC_LINK=$enableval, STATIC_LINK=no)
AC_MSG_RESULT($STATIC_LINK)
dnl Disable readline
AC_ARG_ENABLE(readline, [ --disable-readline Disable readline support], \
READLINE=$enableval, READLINE=yes)
################################################################################
dnl -- Enable readline
AC_MSG_CHECKING(whether to enable readline)
AC_ARG_ENABLE(readline, [ --enable-readline Enable readline support],
READLINE=$enableval, READLINE=no)
AC_MSG_RESULT($READLINE)
dnl Mess with default exec_prefix
if test x$READLINE = xyes; then
CFLAGS="$CFLAGS -DREADLINE_SUPPORT"
fi
################################################################################
dnl -- Disable selinux
AC_MSG_CHECKING(whether to enable selinux support)
AC_ARG_ENABLE(selinux, [ --disable-selinux Disable selinux support],
SELINUX=$enableval)
AC_MSG_RESULT($SELINUX)
################################################################################
dnl -- Build cluster LVM daemon
AC_MSG_CHECKING(whether to build cluster LVM daemon)
AC_ARG_WITH(clvmd,
[ --with-clvmd=TYPE Build cluster LVM Daemon: cman/gulm/none/all
[TYPE=none] ],
[ CLVMD="$withval" ],
[ CLVMD="none" ])
if test x$CLVMD = xyes; then
CLVMD=all
fi
AC_MSG_RESULT($CLVMD)
dnl -- If clvmd enabled without cluster locking, automagically include it
if test x$CLVMD != xnone && test x$CLUSTER = xnone; then
CLUSTER=internal
fi
################################################################################
dnl -- Enable debugging
AC_MSG_CHECKING(whether to enable debugging)
AC_ARG_ENABLE(debug, [ --enable-debug Enable debugging],
DEBUG=$enableval, DEBUG=no)
AC_MSG_RESULT($DEBUG)
dnl -- Normally turn off optimisation for debug builds
if test x$DEBUG = xyes; then
COPTIMISE_FLAG=
fi
################################################################################
dnl -- Override optimisation
AC_MSG_CHECKING(for C optimisation flag)
AC_ARG_WITH(optimisation,
[ --with-optimisation=OPT C optimisation flag [OPT=-O2] ],
[ COPTIMISE_FLAG="$withval" ])
AC_MSG_RESULT($COPTIMISE_FLAG)
################################################################################
dnl -- Disable devmapper
AC_MSG_CHECKING(whether to use device-mapper)
AC_ARG_ENABLE(devmapper, [ --disable-devmapper Disable device-mapper interaction],
DEVMAPPER=$enableval)
AC_MSG_RESULT($DEVMAPPER)
if test x$DEVMAPPER = xyes; then
CFLAGS="$CFLAGS -DDEVMAPPER_SUPPORT"
fi
################################################################################
dnl -- Disable O_DIRECT
AC_MSG_CHECKING(whether to enable O_DIRECT)
AC_ARG_ENABLE(o_direct, [ --disable-o_direct Disable O_DIRECT],
ODIRECT=$enableval)
AC_MSG_RESULT($ODIRECT)
if test x$ODIRECT = xyes; then
CFLAGS="$CFLAGS -DO_DIRECT_SUPPORT"
fi
################################################################################
dnl -- Enable cmdlib
AC_MSG_CHECKING(whether to compile liblvm2cmd.so)
AC_ARG_ENABLE(cmdlib, [ --enable-cmdlib Build shared command library],
CMDLIB=$enableval, CMDLIB=no)
AC_MSG_RESULT($CMDLIB)
if test x$CMDLIB = xyes; then
CFLAGS="$CFLAGS -DCMDLIB"
fi
################################################################################
dnl -- Enable fsadm
AC_MSG_CHECKING(whether to build fsadm)
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
CFLAGS="$CFLAGS -DDMEVENTD"
fi
################################################################################
dnl -- Mess with default exec_prefix
if [[ "x$exec_prefix" = xNONE -a "x$prefix" = xNONE ]];
then exec_prefix="";
fi;
dnl Checks for library functions.
################################################################################
dnl -- Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(mkdir rmdir uname)
AC_CHECK_FUNCS(mkdir rmdir uname,,AC_MSG_ERROR(bailing out))
dnl check for termcap (Shamelessly copied from parted 1.4.17)
################################################################################
dnl -- Check for termcap (Shamelessly copied from parted 1.4.17)
if test x$READLINE = xyes; then
AC_SEARCH_LIBS(tgetent, ncurses curses termcap termlib, ,
AC_MSG_ERROR(
@@ -95,11 +399,51 @@ Note: if you are using precompiled packages you will also need the development
Note: (n)curses also seems to work as a substitute for termcap. This was
not found either - but you could try installing that as well.
)
exit
)
fi
dnl Check for readline (Shamelessly copied from parted 1.4.17)
################################################################################
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"
LIBS="-ldl $LIBS"
else
HAVE_LIBDL=no
fi
################################################################################
dnl -- Check for shared/static conflicts
if [[ \( "x$LVM1" = xshared -o "x$POOL" = xshared -o "x$CLUSTER" = xshared \
-o "x$SNAPSHOTS" = xshared -o "x$MIRRORS" = xshared \
\) -a "x$STATIC_LINK" = xyes ]];
then AC_MSG_ERROR(
Features cannot be 'shared' when building statically
)
fi
################################################################################
dnl -- Check for is_selinux_enabled
if test x$SELINUX = xyes; then
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"
LIBS="-lselinux $LIBS"
else
AC_MSG_WARN(Disabling selinux)
fi
fi
################################################################################
dnl -- Check for getopt
AC_CHECK_HEADERS(getopt.h, CFLAGS="$CFLAGS -DHAVE_GETOPTLONG")
################################################################################
dnl -- Check for readline (Shamelessly copied from parted 1.4.17)
if test x$READLINE = xyes; then
AC_CHECK_LIB(readline, readline, ,
AC_MSG_ERROR(
@@ -110,39 +454,172 @@ support with --disable-readline or download and install readline from:
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).
)
exit
)
AC_CHECK_FUNC(rl_completion_matches, HAVE_RL_COMPLETION_MATCHES=yes,
HAVE_RL_COMPLETION_MATCHES=no)
AC_CHECK_FUNC(rl_completion_matches, CFLAGS="$CFLAGS -DHAVE_RL_COMPLETION_MATCHES")
fi
################################################################################
dnl -- Internationalisation stuff
AC_MSG_CHECKING(whether to enable internationalisation)
AC_ARG_ENABLE(nls, [ --enable-nls Enable Native Language Support],
INTL=$enableval, INTL=no)
AC_MSG_RESULT($INTL)
if test x$INTL = xyes; then
INTL_PACKAGE="lvm2"
AC_PATH_PROG(MSGFMT, msgfmt)
if [[ "x$MSGFMT" == x ]];
then AC_MSG_ERROR(
msgfmt not found in path $PATH
)
fi;
AC_ARG_WITH(localedir,
[ --with-localedir=DIR Translation files in DIR [PREFIX/share/locale]],
[ LOCALEDIR="$withval" ],
[ LOCALEDIR='${prefix}/share/locale' ])
fi
################################################################################
AC_ARG_WITH(confdir,
[ --with-confdir=DIR Configuration files in DIR [/etc]],
[ CONFDIR="$withval" ],
[ CONFDIR='/etc' ])
AC_ARG_WITH(staticdir,
[ --with-staticdir=DIR Static binary in DIR [EXEC_PREFIX/sbin]],
[ STATICDIR="$withval" ],
[ STATICDIR='${exec_prefix}/sbin' ])
################################################################################
dnl -- Ensure additional headers required
if test x$READLINE = xyes; then
AC_CHECK_HEADERS(readline/readline.h readline/history.h,,AC_MSG_ERROR(bailing out))
fi
if test x$CLVMD != xnone; then
AC_CHECK_HEADERS(mntent.h netdb.h netinet/in.h pthread.h search.h sys/mount.h sys/socket.h sys/uio.h sys/un.h utmpx.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_FUNCS(dup2 getmntent memmove select socket,,AC_MSG_ERROR(bailing out))
AC_FUNC_GETMNTENT
# AC_FUNC_REALLOC
AC_FUNC_SELECT_ARGTYPES
fi
if test x$FSADM = xyes; then
AC_CHECK_HEADERS(fstab.h sys/mount.h sys/vfs.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_FUNCS(memmove,,AC_MSG_ERROR(bailing out))
fi
if test x$CLUSTER != xnone; then
AC_CHECK_HEADERS(sys/socket.h sys/un.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_FUNCS(socket,,AC_MSG_ERROR(bailing out))
fi
if test x$HAVE_LIBDL = xyes; then
AC_CHECK_HEADERS(dlfcn.h,,AC_MSG_ERROR(bailing out))
fi
if test x$INTL = xyes; then
AC_CHECK_HEADERS(libintl.h,,AC_MSG_ERROR(bailing out))
fi
if test x$DEVMAPPER = xyes; then
AC_CHECK_HEADERS(libdevmapper.h,,AC_MSG_ERROR(bailing out))
fi
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
CFLAGS="$CFLAGS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
fi
################################################################################
if test "-f VERSION"; then
LVM_VERSION="\"`cat VERSION`\""
else
LVM_VERSION="Unknown"
fi
################################################################################
AC_SUBST(JOBS)
AC_SUBST(STATIC_LINK)
AC_SUBST(READLINE)
AC_SUBST(HAVE_RL_COMPLETION_MATCHES)
AC_SUBST(LVM1)
AC_SUBST(POOL)
AC_SUBST(SNAPSHOTS)
AC_SUBST(MIRRORS)
AC_SUBST(OWNER)
AC_SUBST(GROUP)
AC_SUBST(CFLAGS)
AC_SUBST(COPTIMISE_FLAG)
AC_SUBST(CLDFLAGS)
AC_SUBST(CLDWHOLEARCHIVE)
AC_SUBST(CLDNOWHOLEARCHIVE)
AC_SUBST(LDDEPS)
AC_SUBST(LDFLAGS)
AC_SUBST(LIB_SUFFIX)
AC_SUBST(LIBS)
AC_SUBST(LVM_VERSION)
dnl First and last lines should not contain files to generate in order to
dnl keep utility scripts running properly
AC_SUBST(LVM1_FALLBACK)
AC_SUBST(DEBUG)
AC_SUBST(DEVMAPPER)
AC_SUBST(HAVE_LIBDL)
AC_SUBST(HAVE_SELINUX)
AC_SUBST(CMDLIB)
AC_SUBST(MSGFMT)
AC_SUBST(LOCALEDIR)
AC_SUBST(CONFDIR)
AC_SUBST(STATICDIR)
AC_SUBST(INTL_PACKAGE)
AC_SUBST(INTL)
AC_SUBST(CLVMD)
AC_SUBST(CLUSTER)
AC_SUBST(FSADM)
AC_SUBST(DMEVENTD)
################################################################################
dnl -- First and last lines should not contain files to generate in order to
dnl -- keep utility scripts running properly
AC_OUTPUT( \
Makefile \
make.tmpl \
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 \
)
if test x$ODIRECT != xyes; then
AC_MSG_WARN(Warning: O_DIRECT disabled: low-memory pvmove may lock up)
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

23
daemons/Makefile.in Normal file
View File

@@ -0,0 +1,23 @@
#
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
ifneq ("@CLVMD@", "none")
SUBDIRS = clvmd
endif
include $(top_srcdir)/make.tmpl

85
daemons/clvmd/Makefile.in Normal file
View File

@@ -0,0 +1,85 @@
#
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SOURCES = \
clvmd-command.c \
clvmd.c \
lvm-functions.c \
system-lv.c
ifeq ("@CLVMD@", "gulm")
GULM = yes
endif
ifeq ("@CLVMD@", "cman")
CMAN = yes
endif
ifeq ("@CLVMD@", "all")
GULM = yes
CMAN = yes
endif
ifeq ("@DEBUG@", "yes")
CFLAGS += -DDEBUG
endif
ifeq ("$(GULM)", "yes")
SOURCES += clvmd-gulm.c tcp-comms.c
LMLIBS += -lccs -lgulm
CFLAGS += -DUSE_GULM
endif
ifeq ("$(CMAN)", "yes")
SOURCES += clvmd-cman.c
LMLIBS += -ldlm
CFLAGS += -DUSE_CMAN
endif
TARGETS = \
clvmd
LVMLIBS = -llvm
ifeq ("@DMEVENTD@", "yes")
LVMLIBS += -ldevmapper-event -lpthread
endif
ifeq ("@DEVMAPPER@", "yes")
LVMLIBS += -ldevmapper
endif
CFLAGS += -D_REENTRANT -fno-strict-aliasing
include $(top_srcdir)/make.tmpl
INSTALL_TARGETS = \
install_clvmd
clvmd: $(OBJECTS) $(top_srcdir)/lib/liblvm.a
$(CC) -o clvmd $(OBJECTS) $(LDFLAGS) $(LVMLIBS) $(LMLIBS) $(LIBS)
.PHONY: install_clvmd
install_clvmd: $(TARGETS)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) clvmd \
$(sbindir)/clvmd
install: $(INSTALL_TARGETS)
install_cluster: $(INSTALL_TARGETS)

66
daemons/clvmd/clvm.h Normal file
View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Definitions for CLVMD server and clients */
/*
* The protocol spoken over the cluster and across the local socket.
*/
#ifndef _CLVM_H
#define _CLVM_H
struct clvm_header {
uint8_t cmd; /* See below */
uint8_t flags; /* See below */
uint16_t xid; /* Transaction ID */
uint32_t clientid; /* Only used in Daemon->Daemon comms */
int32_t status; /* For replies, whether request succeeded */
uint32_t arglen; /* Length of argument below.
If >1500 then it will be passed
around the cluster in the system LV */
char node[1]; /* Actually a NUL-terminated string, node name.
If this is empty then the command is
forwarded to all cluster nodes unless
FLAG_LOCAL is also set. */
char args[1]; /* Arguments for the command follow the
node name, This member is only
valid if the node name is empty */
} __attribute__ ((packed));
/* Flags */
#define CLVMD_FLAG_LOCAL 1 /* Only do this on the local node */
#define CLVMD_FLAG_SYSTEMLV 2 /* Data in system LV under my node name */
#define CLVMD_FLAG_NODEERRS 4 /* Reply has errors in node-specific portion */
/* Name of the local socket to communicate between libclvm and clvmd */
//static const char CLVMD_SOCKNAME[]="/var/run/clvmd";
static const char CLVMD_SOCKNAME[] = "\0clvmd";
/* Internal commands & replies */
#define CLVMD_CMD_REPLY 1
#define CLVMD_CMD_VERSION 2 /* Send version around cluster when we start */
#define CLVMD_CMD_GOAWAY 3 /* Die if received this - we are running
an incompatible version */
#define CLVMD_CMD_TEST 4 /* Just for mucking about */
#define CLVMD_CMD_LOCK 30
#define CLVMD_CMD_UNLOCK 31
/* Lock/Unlock commands */
#define CLVMD_CMD_LOCK_LV 50
#define CLVMD_CMD_LOCK_VG 51
#endif

540
daemons/clvmd/clvmd-cman.c Normal file
View File

@@ -0,0 +1,540 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* CMAN communication layer for clvmd.
*/
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <syslog.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
#include <errno.h>
#include "clvmd-comms.h"
#include "clvm.h"
#include "libdlm.h"
#include "log.h"
#include "clvmd.h"
#include "lvm-functions.h"
#define LOCKSPACE_NAME "clvmd"
static int cluster_sock;
static int num_nodes;
static struct cl_cluster_node *nodes = NULL;
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 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);
struct lock_wait {
pthread_cond_t cond;
pthread_mutex_t mutex;
struct dlm_lksb lksb;
};
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 */
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))) {
syslog(LOG_ERR, "Can't bind cluster socket: %m");
return -1;
}
/* Get the cluster members list */
get_members();
count_clvmds_running();
/* Create a lockspace for LV & VG locks to live in */
lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
if (!lockspace) {
syslog(LOG_ERR, "Unable to create lockspace for CLVM: %m");
return -1;
}
dlm_ls_pthread_init(lockspace);
return 0;
}
static void _cluster_init_completed(void)
{
clvmd_cluster_init_completed();
}
static int _get_main_cluster_fd()
{
return cluster_sock;
}
static int _get_num_nodes()
{
return num_nodes;
}
/* 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;
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;
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)
log_error(errtext);
} while (len == -1 && errno == EAGAIN);
return len;
}
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);
}
}
/* Call a callback routine for each node that known (down mean not running a clvmd) */
static int _cluster_do_node_callback(struct local_client *client,
void (*callback) (struct local_client *, char *,
int))
{
int i;
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])
somedown = -1;
}
return somedown;
}
/* 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)
{
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);
node_updown[nodeid] = 0;
break;
case CLUSTER_OOB_MSG_STATECHANGE:
DEBUGLOG("Got OOB message, Cluster state change\n");
get_members();
break;
default:
/* ERROR */
DEBUGLOG("Got unknown OOB message: %d\n", buf[0]);
}
}
static int _cluster_fd_callback(struct local_client *client, char *buf, int len, char *csid,
struct local_client **new_client)
{
struct iovec iov[2];
struct msghdr msg;
struct sockaddr_cl saddr;
/* 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;
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 _add_up_node(char *csid)
{
/* It's up ! */
int nodeid = nodeid_from_csid(csid);
if (nodeid >= max_updown_nodes) {
int new_size = nodeid + 10;
int *new_updown = realloc(node_updown, new_size);
if (new_updown) {
node_updown = new_updown;
max_updown_nodes = new_size;
DEBUGLOG("realloced more space for nodes. now %d\n",
max_updown_nodes);
} else {
log_error
("Realloc failed. Node status for clvmd will be wrong. quitting\n");
exit(999);
}
}
node_updown[nodeid] = 1;
DEBUGLOG("Added new node %d to updown list\n", nodeid);
}
static void _cluster_closedown()
{
unlock_all();
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
close(cluster_sock);
}
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);
if (status < 0 && errno == EBUSY) { /* Don't busywait */
sleep(1);
errno = EBUSY; /* In case sleep trashes it */
}
}
while (status < 0 && errno == EBUSY);
return status;
}
/* Populate the list of CLVMDs running.
called only at startup time */
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);
}
}
/* Get a list of active cluster members */
static void get_members()
{
struct cl_cluster_nodelist nodelist;
num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, 0);
if (num_nodes == -1) {
log_error("Unable to get node count");
} else {
/* Not enough room for new nodes list ? */
if (num_nodes > count_nodes && nodes) {
free(nodes);
nodes = NULL;
}
if (nodes == NULL) {
count_nodes = num_nodes + 10; /* Overallocate a little */
nodes = malloc(count_nodes * sizeof(struct cl_cluster_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) {
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) *
max(num_nodes, max_updown_nodes));
memset(node_updown, 0,
sizeof(int) * max(num_nodes, max_updown_nodes));
}
}
}
/* Convert a node name to a CSID */
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);
return 0;
}
}
return -1;
}
/* Convert a CSID to a node name */
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);
return 0;
}
}
/* Who?? */
strcpy(name, "Unknown");
return -1;
}
/* Convert a node ID to a node name */
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);
return 0;
}
}
/* Who?? */
strcpy(name, "Unknown");
return -1;
}
/* Convert a CSID to a node ID */
static int nodeid_from_csid(char *csid)
{
int nodeid;
memcpy(&nodeid, csid, CMAN_MAX_CSID_LEN);
return nodeid;
}
static int _is_quorate()
{
return ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0);
}
static void sync_ast_routine(void *arg)
{
struct lock_wait *lwait = arg;
pthread_mutex_lock(&lwait->mutex);
pthread_cond_signal(&lwait->cond);
pthread_mutex_unlock(&lwait->mutex);
}
static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
{
int status;
struct lock_wait lwait;
if (!lockid) {
errno = EINVAL;
return -1;
}
DEBUGLOG("sync_lock: '%s' mode:%d flags=%d\n", resource,mode,flags);
/* Conversions need the lockid in the LKSB */
if (flags & LKF_CONVERT)
lwait.lksb.sb_lkid = *lockid;
pthread_cond_init(&lwait.cond, NULL);
pthread_mutex_init(&lwait.mutex, NULL);
pthread_mutex_lock(&lwait.mutex);
status = dlm_ls_lock(lockspace,
mode,
&lwait.lksb,
flags,
resource,
strlen(resource),
0, sync_ast_routine, &lwait, NULL, NULL);
if (status)
return status;
/* Wait for it to complete */
pthread_cond_wait(&lwait.cond, &lwait.mutex);
pthread_mutex_unlock(&lwait.mutex);
*lockid = lwait.lksb.sb_lkid;
errno = lwait.lksb.sb_status;
DEBUGLOG("sync_lock: returning lkid %x\n", *lockid);
if (lwait.lksb.sb_status)
return -1;
else
return 0;
}
static int _sync_unlock(const char *resource /* UNUSED */, int lockid)
{
int status;
struct lock_wait lwait;
DEBUGLOG("sync_unlock: '%s' lkid:%x\n", resource, lockid);
pthread_cond_init(&lwait.cond, NULL);
pthread_mutex_init(&lwait.mutex, NULL);
pthread_mutex_lock(&lwait.mutex);
status = dlm_ls_unlock(lockspace, lockid, 0, &lwait.lksb, &lwait);
if (status)
return status;
/* Wait for it to complete */
pthread_cond_wait(&lwait.cond, &lwait.mutex);
pthread_mutex_unlock(&lwait.mutex);
errno = lwait.lksb.sb_status;
if (lwait.lksb.sb_status != EUNLOCK)
return -1;
else
return 0;
}
static struct cluster_ops _cluster_cman_ops = {
.cluster_init_completed = _cluster_init_completed,
.cluster_send_message = _cluster_send_message,
.name_from_csid = _name_from_csid,
.csid_from_name = _csid_from_name,
.get_num_nodes = _get_num_nodes,
.cluster_fd_callback = _cluster_fd_callback,
.get_main_cluster_fd = _get_main_cluster_fd,
.cluster_do_node_callback = _cluster_do_node_callback,
.is_quorate = _is_quorate,
.get_our_csid = _get_our_csid,
.add_up_node = _add_up_node,
.cluster_closedown = _cluster_closedown,
.sync_lock = _sync_lock,
.sync_unlock = _sync_unlock,
};
struct cluster_ops *init_cman_cluster(void)
{
if (!_init_cluster())
return &_cluster_cman_ops;
else
return NULL;
}

View File

@@ -0,0 +1,286 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
CLVMD Cluster LVM daemon command processor.
To add commands to the daemon simply add a processor in do_command and return
and messages back in buf and the length in *retlen. The initial value of
buflen is the maximum size of the buffer. if buf is not large enough then it
may be reallocated by the functions in here to a suitable size bearing in
mind that anything larger than the passed-in size will have to be returned
using the system LV and so performance will suffer.
The status return will be negated and passed back to the originating node.
pre- and post- command routines are called only on the local node. The
purpose is primarily to get and release locks, though the pre- routine should
also do any other local setups required by the command (if any) and can
return a failure code that prevents the command from being distributed around
the cluster
The pre- and post- routines are run in their own thread so can block as long
they like, do_command is run in the main clvmd thread so should not block for
too long. If the pre-command returns an error code (!=0) then the command
will not be propogated around the cluster but the post-command WILL be called
Also note that the pre and post routine are *always* called on the local
node, even if the command to be executed was only requested to run on a
remote node. It may peek inside the client structure to check the status of
the command.
The clients of the daemon must, naturally, understand the return messages and
codes.
Routines in here may only READ the values in the client structure passed in
apart from client->private which they are free to do what they like with.
*/
#include <pthread.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <string.h>
#include <stddef.h>
#include <unistd.h>
#include <errno.h>
#include "libdevmapper.h"
#include "list.h"
#include "locking.h"
#include "log.h"
#include "lvm-functions.h"
#include "clvmd-comms.h"
#include "clvm.h"
#include "clvmd.h"
#include "libdlm.h"
/* This is where all the real work happens:
NOTE: client will be NULL when this is executed on a remote node */
int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
char **buf, int buflen, int *retlen)
{
char *args = msg->node + strlen(msg->node) + 1;
int arglen = msglen - sizeof(struct clvm_header) - strlen(msg->node);
int status = 0;
char *lockname;
struct utsname nodeinfo;
unsigned char lock_cmd;
unsigned char lock_flags;
/* Do the command */
switch (msg->cmd) {
/* Just a test message */
case CLVMD_CMD_TEST:
if (arglen > buflen) {
buflen = arglen + 200;
*buf = realloc(*buf, buflen);
}
uname(&nodeinfo);
*retlen = 1 + snprintf(*buf, buflen, "TEST from %s: %s v%s",
nodeinfo.nodename, args,
nodeinfo.release);
break;
case CLVMD_CMD_LOCK_VG:
/* Check to see if the VG is in use by LVM1 */
status = do_check_lvm1(&args[2]);
break;
case CLVMD_CMD_LOCK_LV:
/* This is the biggie */
lock_cmd = args[0] & 0x3F;
lock_flags = args[1];
lockname = &args[2];
status = do_lock_lv(lock_cmd, lock_flags, lockname);
/* Replace EIO with something less scary */
if (status == EIO) {
*retlen =
1 + snprintf(*buf, buflen,
"Internal lvm error, check syslog");
return EIO;
}
break;
default:
/* Won't get here because command is validated in pre_command */
break;
}
/* Check the status of the command and return the error text */
if (status) {
*retlen = 1 + snprintf(*buf, buflen, strerror(status));
}
return status;
}
static int lock_vg(struct local_client *client)
{
struct dm_hash_table *lock_hash;
struct clvm_header *header =
(struct clvm_header *) client->bits.localsock.cmd;
unsigned char lock_cmd;
unsigned char lock_flags;
char *args = header->node + strlen(header->node) + 1;
int lkid;
int status = 0;
char *lockname;
/* Keep a track of VG locks in our own hash table. In current
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 dm_hash_table *)client->bits.localsock.private;
}
else {
lock_hash = dm_hash_create(3);
if (!lock_hash)
return ENOMEM;
client->bits.localsock.private = (void *)lock_hash;
}
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)dm_hash_lookup(lock_hash, lockname);
if (lkid == 0)
return EINVAL;
status = sync_unlock(lockname, lkid);
if (status)
status = errno;
else
dm_hash_remove(lock_hash, lockname);
}
else {
status = sync_lock(lockname, (int)lock_cmd, (int)lock_flags, &lkid);
if (status)
status = errno;
else
dm_hash_insert(lock_hash, lockname, (void *)lkid);
}
return status;
}
/* Pre-command is a good place to get locks that are needed only for the duration
of the commands around the cluster (don't forget to free them in post-command),
and to sanity check the command arguments */
int do_pre_command(struct local_client *client)
{
struct clvm_header *header =
(struct clvm_header *) client->bits.localsock.cmd;
unsigned char lock_cmd;
unsigned char lock_flags;
char *args = header->node + strlen(header->node) + 1;
int lockid;
int status = 0;
char *lockname;
switch (header->cmd) {
case CLVMD_CMD_TEST:
status = sync_lock("CLVMD_TEST", LKM_EXMODE, 0, &lockid);
client->bits.localsock.private = (void *) lockid;
break;
case CLVMD_CMD_LOCK_VG:
status = lock_vg(client);
break;
case CLVMD_CMD_LOCK_LV:
lock_cmd = args[0];
lock_flags = args[1];
lockname = &args[2];
status = pre_lock_lv(lock_cmd, lock_flags, lockname);
break;
default:
log_error("Unknown command %d received\n", header->cmd);
status = EINVAL;
}
return status;
}
/* Note that the post-command routine is called even if the pre-command or the real command
failed */
int do_post_command(struct local_client *client)
{
struct clvm_header *header =
(struct clvm_header *) client->bits.localsock.cmd;
int status = 0;
unsigned char lock_cmd;
unsigned char lock_flags;
char *args = header->node + strlen(header->node) + 1;
char *lockname;
switch (header->cmd) {
case CLVMD_CMD_TEST:
status =
sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
client->bits.localsock.private = 0;
break;
case CLVMD_CMD_LOCK_VG:
/* Nothing to do here */
break;
case CLVMD_CMD_LOCK_LV:
lock_cmd = args[0];
lock_flags = args[1];
lockname = &args[2];
status = post_lock_lv(lock_cmd, lock_flags, lockname);
break;
}
return status;
}
/* Called when the client is about to be deleted */
void cmd_client_cleanup(struct local_client *client)
{
if (client->bits.localsock.private) {
struct dm_hash_node *v;
struct dm_hash_table *lock_hash =
(struct dm_hash_table *)client->bits.localsock.private;
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);
}
dm_hash_destroy(lock_hash);
client->bits.localsock.private = 0;
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Abstraction layer for clvmd cluster communications
*/
#ifndef _CLVMD_COMMS_H
#define _CLVMD_COMMS_H
struct local_client;
struct cluster_ops {
void (*cluster_init_completed) (void);
int (*cluster_send_message) (void *buf, int msglen, char *csid,
const char *errtext);
int (*name_from_csid) (char *csid, char *name);
int (*csid_from_name) (char *csid, char *name);
int (*get_num_nodes) (void);
int (*cluster_fd_callback) (struct local_client *fd, char *buf, int len,
char *csid, struct local_client **new_client);
int (*get_main_cluster_fd) (void); /* gets accept FD or cman cluster socket */
int (*cluster_do_node_callback) (struct local_client *client,
void (*callback) (struct local_client *,
char *csid, int node_up));
int (*is_quorate) (void);
void (*get_our_csid) (char *csid);
void (*add_up_node) (char *csid);
void (*reread_config) (void);
void (*cluster_closedown) (void);
int (*sync_lock) (const char *resource, int mode, int flags, int *lockid);
int (*sync_unlock) (const char *resource, int lockid);
};
#ifdef USE_GULM
# include "tcp-comms.h"
struct cluster_ops *init_gulm_cluster(void);
#define MAX_CSID_LEN GULM_MAX_CSID_LEN
#define MAX_CLUSTER_MEMBER_NAME_LEN GULM_MAX_CLUSTER_MEMBER_NAME_LEN
#endif
#ifdef USE_CMAN
# include "cnxman-socket.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
struct cluster_ops *init_cman_cluster(void);
#endif
#endif

1000
daemons/clvmd/clvmd-gulm.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
extern int get_next_node_csid(void **context, char *csid);
extern void add_down_node(char *csid);
extern int gulm_fd(void);
extern int get_ip_address(char *node, char *addr);
extern void tcp_remove_client(char *csid);
extern int alloc_client(int fd, char *csid, struct local_client **new_client);
void gulm_add_up_node(char *csid);
int gulm_name_from_csid(char *csid, char *name);

1857
daemons/clvmd/clvmd.c Normal file

File diff suppressed because it is too large Load Diff

124
daemons/clvmd/clvmd.h Normal file
View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _CLVMD_H
#define _CLVMD_H
#define CLVMD_MAJOR_VERSION 0
#define CLVMD_MINOR_VERSION 2
#define CLVMD_PATCH_VERSION 1
/* Name of the cluster LVM admin lock */
#define ADMIN_LOCK_NAME "CLVMD_ADMIN"
/* Default time (in seconds) we will wait for all remote commands to execute
before declaring them dead */
#define DEFAULT_CMD_TIMEOUT 60
/* One of these for each reply we get from command execution on a node */
struct node_reply {
char node[MAX_CLUSTER_MEMBER_NAME_LEN];
char *replymsg;
int status;
struct node_reply *next;
};
/*
* These exist for the use of local sockets only when we are
* collecting responses from all cluster nodes
*/
struct localsock_bits {
struct node_reply *replies;
int num_replies;
int expected_replies;
time_t sent_time; /* So we can check for timeouts */
int in_progress; /* Only execute one cmd at a time per client */
int sent_out; /* Flag to indicate that a command was sent
to remote nodes */
void *private; /* Private area for command processor use */
void *cmd; /* Whole command as passed down local socket */
int cmd_len; /* Length of above */
int pipe; /* Pipe to send PRE completion status down */
int finished; /* Flag to tell subthread to exit */
int all_success; /* Set to 0 if any node (or the pre_command)
failed */
struct local_client *pipe_client;
pthread_t threadid;
enum { PRE_COMMAND, POST_COMMAND, QUIT } state;
pthread_mutex_t mutex; /* Main thread and worker synchronisation */
pthread_cond_t cond;
pthread_mutex_t reply_mutex; /* Protect reply structure */
};
/* Entries for PIPE clients */
struct pipe_bits {
struct local_client *client; /* Actual (localsock) client */
pthread_t threadid; /* Our own copy of the thread id */
};
/* Entries for Network socket clients */
struct netsock_bits {
void *private;
int flags;
};
typedef int (*fd_callback_t) (struct local_client * fd, char *buf, int len,
char *csid, struct local_client ** new_client);
/* One of these for each fd we are listening on */
struct local_client {
int fd;
enum { CLUSTER_MAIN_SOCK, CLUSTER_DATA_SOCK, LOCAL_RENDEZVOUS,
LOCAL_SOCK, THREAD_PIPE, CLUSTER_INTERNAL } type;
struct local_client *next;
unsigned short xid;
fd_callback_t callback;
uint8_t removeme;
union {
struct localsock_bits localsock;
struct pipe_bits pipe;
struct netsock_bits net;
} bits;
};
#ifdef DEBUG
#define DEBUGLOG(fmt, args...) {time_t P; time(&P); fprintf(stderr, "CLVMD[%x]: %.15s ", (int)pthread_self(), ctime(&P)+4 ); fprintf(stderr, fmt, ## args);}
#else
#define DEBUGLOG(fmt, args...)
#endif
#ifndef max
#define max(a,b) ((a)>(b)?(a):(b))
#endif
/* The real command processor is in clvmd-command.c */
extern int do_command(struct local_client *client, struct clvm_header *msg,
int msglen, char **buf, int buflen, int *retlen);
/* Pre and post command routines are called only on the local node */
extern int do_pre_command(struct local_client *client);
extern int do_post_command(struct local_client *client);
extern void cmd_client_cleanup(struct local_client *client);
extern int add_client(struct local_client *new_client);
extern void clvmd_cluster_init_completed(void);
extern void process_message(struct local_client *client, char *buf, int len, char *csid);
int sync_lock(const char *resource, int mode, int flags, int *lockid);
int sync_unlock(const char *resource, int lockid);
#endif

View File

@@ -0,0 +1,226 @@
/******************************************************************************
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
** Copyright (C) 2004 Red Hat, Inc. All rights reserved.
**
** This 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.
**
*******************************************************************************
******************************************************************************/
/* CMAN socket interface header,
may be include by user or kernel code */
#ifndef __CNXMAN_SOCKET_H
#define __CNXMAN_SOCKET_H
/* A currently unused number. TIPC also uses this number and you're unlikely
to be using both.
*/
#define AF_CLUSTER 30
#define PF_CLUSTER AF_CLUSTER
/* Protocol(socket) types */
#define CLPROTO_MASTER 2
#define CLPROTO_CLIENT 3
/* ioctls -- should register these properly */
#define SIOCCLUSTER_NOTIFY _IOW('x', 0x01, int)
#define SIOCCLUSTER_REMOVENOTIFY _IO( 'x', 0x02)
#define SIOCCLUSTER_GETMEMBERS _IOR('x', 0x03, struct cl_cluster_nodelist)
#define SIOCCLUSTER_SETEXPECTED_VOTES _IOW('x', 0x04, int)
#define SIOCCLUSTER_ISQUORATE _IO( 'x', 0x05)
#define SIOCCLUSTER_ISLISTENING _IOW('x', 0x06, struct cl_listen_request)
#define SIOCCLUSTER_GETALLMEMBERS _IOR('x', 0x07, struct cl_cluster_nodelist)
#define SIOCCLUSTER_SET_VOTES _IOW('x', 0x08, int)
#define SIOCCLUSTER_GET_VERSION _IOR('x', 0x09, struct cl_version)
#define SIOCCLUSTER_SET_VERSION _IOW('x', 0x0a, struct cl_version)
#define SIOCCLUSTER_ISACTIVE _IO( 'x', 0x0b)
#define SIOCCLUSTER_KILLNODE _IOW('x', 0x0c, int)
#define SIOCCLUSTER_GET_JOINCOUNT _IO( 'x', 0x0d)
#define SIOCCLUSTER_SERVICE_REGISTER _IOW('x', 0x0e, char)
#define SIOCCLUSTER_SERVICE_UNREGISTER _IO('x', 0x0f)
#define SIOCCLUSTER_SERVICE_JOIN _IO( 'x', 0x10)
#define SIOCCLUSTER_SERVICE_LEAVE _IO( 'x', 0x20)
#define SIOCCLUSTER_SERVICE_SETSIGNAL _IOW('x', 0x30, int)
#define SIOCCLUSTER_SERVICE_STARTDONE _IOW('x', 0x40, unsigned int)
#define SIOCCLUSTER_SERVICE_GETEVENT _IOR('x', 0x50, struct cl_service_event)
#define SIOCCLUSTER_SERVICE_GETMEMBERS _IOR('x', 0x60, struct cl_cluster_nodelist)
#define SIOCCLUSTER_SERVICE_GLOBALID _IOR('x', 0x70, uint32_t)
#define SIOCCLUSTER_SERVICE_SETLEVEL _IOR('x', 0x80, int)
#define SIOCCLUSTER_GETNODE _IOWR('x', 0x90, struct cl_cluster_node)
#define SIOCCLUSTER_BARRIER _IOW('x', 0x0a0, struct cl_barrier_info)
/* These were setsockopts */
#define SIOCCLUSTER_PASS_SOCKET _IOW('x', 0x0b0, struct cl_passed_sock)
#define SIOCCLUSTER_SET_NODENAME _IOW('x', 0x0b1, char *)
#define SIOCCLUSTER_SET_NODEID _IOW('x', 0x0b2, int)
#define SIOCCLUSTER_JOIN_CLUSTER _IOW('x', 0x0b3, struct cl_join_cluster_info)
#define SIOCCLUSTER_LEAVE_CLUSTER _IOW('x', 0x0b4, int)
/* Maximum size of a cluster message */
#define CMAN_MAX_CLUSTER_MESSAGE 1500
#define CMAN_MAX_CLUSTER_MEMBER_NAME_LEN 255
#define MAX_BARRIER_NAME_LEN 33
#define MAX_SA_ADDR_LEN 12
#define MAX_CLUSTER_NAME_LEN 16
/* Well-known cluster port numbers */
#define CLUSTER_PORT_MEMBERSHIP 1 /* Mustn't block during cluster
* transitions! */
#define CLUSTER_PORT_SERVICES 2
#define CLUSTER_PORT_SYSMAN 10 /* Remote execution daemon */
#define CLUSTER_PORT_CLVMD 11 /* Cluster LVM daemon */
#define CLUSTER_PORT_SLM 12 /* LVM SLM (simple lock manager) */
/* Port numbers above this will be blocked when the cluster is inquorate or in
* transition */
#define HIGH_PROTECTED_PORT 9
/* Reasons for leaving the cluster */
#define CLUSTER_LEAVEFLAG_DOWN 0 /* Normal shutdown */
#define CLUSTER_LEAVEFLAG_KILLED 1
#define CLUSTER_LEAVEFLAG_PANIC 2
#define CLUSTER_LEAVEFLAG_REMOVED 3 /* This one can reduce quorum */
#define CLUSTER_LEAVEFLAG_REJECTED 4 /* Not allowed into the cluster in the
* first place */
#define CLUSTER_LEAVEFLAG_INCONSISTENT 5 /* Our view of the cluster is
* in a minority */
#define CLUSTER_LEAVEFLAG_DEAD 6 /* Discovered to be dead */
#define CLUSTER_LEAVEFLAG_FORCE 0x10 /* Forced by command-line */
/* OOB messages sent to a local socket */
#define CLUSTER_OOB_MSG_PORTCLOSED 1
#define CLUSTER_OOB_MSG_STATECHANGE 2
#define CLUSTER_OOB_MSG_SERVICEEVENT 3
/* Sendmsg flags, these are above the normal sendmsg flags so they don't
* interfere */
#define MSG_NOACK 0x010000 /* Don't need an ACK for this message */
#define MSG_QUEUE 0x020000 /* Queue the message for sending later */
#define MSG_MULTICAST 0x080000 /* Message was sent to all nodes in the cluster
*/
#define MSG_ALLINT 0x100000 /* Send out of all interfaces */
#define MSG_REPLYEXP 0x200000 /* Reply is expected */
typedef enum { NODESTATE_REMOTEMEMBER, NODESTATE_JOINING, NODESTATE_MEMBER,
NODESTATE_DEAD } nodestate_t;
struct sockaddr_cl {
unsigned short scl_family;
unsigned char scl_flags;
unsigned char scl_port;
int scl_nodeid;
};
/*
* This is how we pass the multicast & receive sockets into kernel space.
*/
struct cl_passed_sock {
int fd; /* FD of master socket to do multicast on */
int number; /* Socket number, to match up recvonly & bcast
* sockets */
int multicast; /* Is it multicast or receive ? */
};
/* Cluster configuration info passed when we join the cluster */
struct cl_join_cluster_info {
unsigned char votes;
unsigned int expected_votes;
unsigned int two_node;
unsigned int config_version;
char cluster_name[17];
};
/* This is the structure, per node, returned from the membership ioctl */
struct cl_cluster_node {
unsigned int size;
unsigned int node_id;
unsigned int us;
unsigned int leave_reason;
unsigned int incarnation;
nodestate_t state;
char name[CMAN_MAX_CLUSTER_MEMBER_NAME_LEN];
unsigned char votes;
};
/* The struct passed to the membership ioctls */
struct cl_cluster_nodelist {
uint32_t max_members;
struct cl_cluster_node *nodes;
};
/* Structure passed to SIOCCLUSTER_ISLISTENING */
struct cl_listen_request {
unsigned char port;
int nodeid;
};
/* A Cluster PORTCLOSED message - received by a local user as an OOB message */
struct cl_portclosed_oob {
unsigned char cmd; /* CLUSTER_OOB_MSG_PORTCLOSED */
unsigned char port;
};
/* Get all version numbers or set the config version */
struct cl_version {
unsigned int major;
unsigned int minor;
unsigned int patch;
unsigned int config;
};
/* structure passed to barrier ioctls */
struct cl_barrier_info {
char cmd;
char name[MAX_BARRIER_NAME_LEN];
unsigned int flags;
unsigned long arg;
};
typedef enum { SERVICE_EVENT_STOP, SERVICE_EVENT_START, SERVICE_EVENT_FINISH,
SERVICE_EVENT_LEAVEDONE } service_event_t;
typedef enum { SERVICE_START_FAILED, SERVICE_START_JOIN, SERVICE_START_LEAVE }
service_start_t;
struct cl_service_event {
service_event_t type;
service_start_t start_type;
unsigned int event_id;
unsigned int last_stop;
unsigned int last_start;
unsigned int last_finish;
unsigned int node_count;
};
/* Commands to the barrier ioctl */
#define BARRIER_IOCTL_REGISTER 1
#define BARRIER_IOCTL_CHANGE 2
#define BARRIER_IOCTL_DELETE 3
#define BARRIER_IOCTL_WAIT 4
/* Attributes of a barrier - bitmask */
#define BARRIER_ATTR_AUTODELETE 1
#define BARRIER_ATTR_MULTISTEP 2
#define BARRIER_ATTR_MANUAL 4
#define BARRIER_ATTR_ENABLED 8
#define BARRIER_ATTR_CALLBACK 16
/* Attribute setting commands */
#define BARRIER_SETATTR_AUTODELETE 1
#define BARRIER_SETATTR_MULTISTEP 2
#define BARRIER_SETATTR_ENABLED 3
#define BARRIER_SETATTR_NODES 4
#define BARRIER_SETATTR_CALLBACK 5
#define BARRIER_SETATTR_TIMEOUT 6
#endif

View File

@@ -0,0 +1,542 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <pthread.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#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"
#include "clvmd.h"
#include "lvm-functions.h"
/* LVM2 headers */
#include "toolcontext.h"
#include "log.h"
#include "activate.h"
#include "locking.h"
static struct cmd_context *cmd = NULL;
static struct dm_hash_table *lv_hash = NULL;
static pthread_mutex_t lv_hash_lock;
struct lv_info {
int lock_id;
int lock_mode;
};
/* Return the mode a lock is currently held at (or -1 if not held) */
static int get_current_lock(char *resource)
{
struct lv_info *lvi;
pthread_mutex_lock(&lv_hash_lock);
lvi = dm_hash_lookup(lv_hash, resource);
pthread_mutex_unlock(&lv_hash_lock);
if (lvi) {
return lvi->lock_mode;
} else {
return -1;
}
}
/* Called at shutdown to tidy the lockspace */
void unlock_all()
{
struct dm_hash_node *v;
pthread_mutex_lock(&lv_hash_lock);
dm_hash_iterate(v, lv_hash) {
struct lv_info *lvi = dm_hash_get_data(lv_hash, v);
sync_unlock(dm_hash_get_key(lv_hash, v), lvi->lock_id);
}
pthread_mutex_unlock(&lv_hash_lock);
}
/* Gets a real lock and keeps the info in the hash table */
int hold_lock(char *resource, int mode, int flags)
{
int status;
int saved_errno;
struct lv_info *lvi;
flags &= LKF_NOQUEUE; /* Only LKF_NOQUEUE is valid here */
pthread_mutex_lock(&lv_hash_lock);
lvi = dm_hash_lookup(lv_hash, resource);
pthread_mutex_unlock(&lv_hash_lock);
if (lvi) {
/* Already exists - convert it */
status =
sync_lock(resource, mode, LKF_CONVERT | flags,
&lvi->lock_id);
saved_errno = errno;
if (!status)
lvi->lock_mode = mode;
if (status) {
DEBUGLOG("hold_lock. convert to %d failed: %s\n", mode,
strerror(errno));
}
errno = saved_errno;
} else {
lvi = malloc(sizeof(struct lv_info));
if (!lvi)
return -1;
lvi->lock_mode = mode;
status = sync_lock(resource, mode, flags, &lvi->lock_id);
saved_errno = errno;
if (status) {
free(lvi);
DEBUGLOG("hold_lock. lock at %d failed: %s\n", mode,
strerror(errno));
} else {
pthread_mutex_lock(&lv_hash_lock);
dm_hash_insert(lv_hash, resource, lvi);
pthread_mutex_unlock(&lv_hash_lock);
}
errno = saved_errno;
}
return status;
}
/* Unlock and remove it from the hash table */
int hold_unlock(char *resource)
{
struct lv_info *lvi;
int status;
int saved_errno;
pthread_mutex_lock(&lv_hash_lock);
lvi = dm_hash_lookup(lv_hash, resource);
pthread_mutex_unlock(&lv_hash_lock);
if (!lvi) {
DEBUGLOG("hold_unlock, lock not already held\n");
return 0;
}
status = sync_unlock(resource, lvi->lock_id);
saved_errno = errno;
if (!status) {
pthread_mutex_lock(&lv_hash_lock);
dm_hash_remove(lv_hash, resource);
pthread_mutex_unlock(&lv_hash_lock);
free(lvi);
} else {
DEBUGLOG("hold_unlock. unlock failed(%d): %s\n", status,
strerror(errno));
}
errno = saved_errno;
return status;
}
/* Watch the return codes here.
liblvm API functions return 1(true) for success, 0(false) for failure and don't set errno.
libdlm API functions return 0 for success, -1 for failure and do set errno.
These functions here return 0 for success or >0 for failure (where the retcode is errno)
*/
/* Activate LV exclusive or non-exclusive */
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 ? */
oldmode = get_current_lock(resource);
if (oldmode == mode) {
return 0; /* Nothing to do */
}
/* Does the config file want us to activate this LV ? */
if (!lv_activation_filter(cmd, resource, &activate_lv))
return EIO;
if (!activate_lv)
return 0; /* Success, we did nothing! */
/* Do we need to activate exclusively? */
if ((activate_lv == 2) || (mode == LKM_EXMODE)) {
exclusive = 1;
mode = LKM_EXMODE;
}
/* 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))
return EIO;
if (lvi.suspended)
if (!lv_resume(cmd, resource))
return EIO;
/* Now activate it */
if (!lv_activate(cmd, resource, exclusive))
return EIO;
return 0;
}
/* Resume the LV if it was active */
static int do_resume_lv(char *resource)
{
int oldmode;
/* Is it open ? */
oldmode = get_current_lock(resource);
if (oldmode == -1) {
DEBUGLOG("do_deactivate_lock, lock not already held\n");
return 0; /* We don't need to do anything */
}
if (!lv_resume_if_active(cmd, resource))
return EIO;
return 0;
}
/* Suspend the device if active */
static int do_suspend_lv(char *resource)
{
int oldmode;
struct lvinfo lvi;
/* Is it open ? */
oldmode = get_current_lock(resource);
if (oldmode == -1) {
DEBUGLOG("do_suspend_lv, lock held at %d\n", oldmode);
return 0; /* Not active, so it's OK */
}
/* Only suspend it if it exists */
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
return EIO;
if (lvi.exists) {
if (!lv_suspend_if_active(cmd, resource)) {
return EIO;
}
}
return 0;
}
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 && (lock_flags & LCK_CLUSTER_VG)) {
DEBUGLOG("do_deactivate_lock, lock not already held\n");
return 0; /* We don't need to do anything */
}
if (!lv_deactivate(cmd, resource))
return EIO;
if (lock_flags & LCK_CLUSTER_VG) {
status = hold_unlock(resource);
if (status)
return errno;
}
return 0;
}
/* This is the LOCK_LV part that happens on all nodes in the cluster -
it is responsible for the interaction with device-mapper and LVM */
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 = %x\n",
resource, command, lock_flags);
if (!cmd->config_valid || config_files_changed(cmd)) {
/* Reinitialise various settings inc. logging, filters */
if (!refresh_toolcontext(cmd)) {
log_error("Updated config file invalid. Aborting.");
return EINVAL;
}
}
switch (command) {
case LCK_LV_EXCLUSIVE:
status = do_activate_lv(resource, lock_flags, LKM_EXMODE);
break;
case LCK_LV_SUSPEND:
status = do_suspend_lv(resource);
break;
case LCK_UNLOCK:
case LCK_LV_RESUME: /* if active */
status = do_resume_lv(resource);
break;
case LCK_LV_ACTIVATE:
status = do_activate_lv(resource, lock_flags, LKM_CRMODE);
break;
case LCK_LV_DEACTIVATE:
status = do_deactivate_lv(resource, lock_flags);
break;
default:
DEBUGLOG("Invalid LV command 0x%x\n", command);
status = EINVAL;
break;
}
/* clean the pool for another command */
dm_pool_empty(cmd->mem);
DEBUGLOG("Command return is %d\n", status);
return status;
}
/* Functions to do on the local node only BEFORE the cluster-wide stuff above happens */
int pre_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
{
/* Nearly all the stuff happens cluster-wide. Apart from SUSPEND. Here we get the
lock out on this node (because we are the node modifying the metadata)
before suspending cluster-wide.
*/
if (command == LCK_LV_SUSPEND) {
DEBUGLOG("pre_lock_lv: resource '%s', cmd = 0x%x, flags = %d\n",
resource, command, lock_flags);
if (hold_lock(resource, LKM_PWMODE, LKF_NOQUEUE))
return errno;
}
return 0;
}
/* Functions to do on the local node only AFTER the cluster-wide stuff above happens */
int post_lock_lv(unsigned char command, unsigned char lock_flags,
char *resource)
{
/* Opposite of above, done on resume after a metadata update */
if (command == LCK_LV_RESUME) {
int oldmode;
DEBUGLOG
("post_lock_lv: resource '%s', cmd = 0x%x, flags = %d\n",
resource, command, lock_flags);
/* If the lock state is PW then restore it to what it was */
oldmode = get_current_lock(resource);
if (oldmode == LKM_PWMODE) {
struct lvinfo lvi;
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
return EIO;
if (lvi.exists) {
if (hold_lock(resource, LKM_CRMODE, 0))
return errno;
} else {
if (hold_unlock(resource))
return errno;
}
}
}
return 0;
}
/* Check if a VG is un use by LVM1 so we don't stomp on it */
int do_check_lvm1(char *vgname)
{
int status;
status = check_lvm1_vg_inactive(cmd, vgname);
return status == 1 ? 0 : EBUSY;
}
/* Only called at gulm startup. Drop any leftover VG or P_orphan locks
that might be hanging around if we died for any reason
*/
static void drop_vg_locks()
{
char vg[128];
char line[255];
FILE *vgs =
popen
("lvm pvs --nolocking --noheadings -o vg_name", "r");
sync_unlock("P_orphans", LCK_EXCL);
if (!vgs)
return;
while (fgets(line, sizeof(line), vgs)) {
char *vgend;
char *vgstart;
if (line[strlen(line)-1] == '\n')
line[strlen(line)-1] = '\0';
vgstart = line + strspn(line, " ");
vgend = vgstart + strcspn(vgstart, " ");
*vgend = '\0';
if (strncmp(vgstart, "WARNING:", 8) == 0)
continue;
sprintf(vg, "V_%s", vgstart);
sync_unlock(vg, LCK_EXCL);
}
fclose(vgs);
}
/*
* Ideally, clvmd should be started before any LVs are active
* but this may not be the case...
* I suppose this also comes in handy if clvmd crashes, not that it would!
*/
static void *get_initial_state()
{
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,vg_attr",
"r");
if (!lvs)
return NULL;
while (fgets(line, sizeof(line), lvs)) {
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? */
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);
memcpy(&uuid[10], &vg[12], 4);
memcpy(&uuid[14], &vg[17], 4);
memcpy(&uuid[18], &vg[22], 4);
memcpy(&uuid[22], &vg[27], 4);
memcpy(&uuid[26], &vg[32], 6);
memcpy(&uuid[32], &lv[0], 6);
memcpy(&uuid[38], &lv[7], 4);
memcpy(&uuid[42], &lv[12], 4);
memcpy(&uuid[46], &lv[17], 4);
memcpy(&uuid[50], &lv[22], 4);
memcpy(&uuid[54], &lv[27], 4);
memcpy(&uuid[58], &lv[32], 6);
uuid[64] = '\0';
DEBUGLOG("getting initial lock for %s\n", uuid);
hold_lock(uuid, LKM_CRMODE, LKF_NOQUEUE);
}
}
}
fclose(lvs);
return NULL;
}
/* This checks some basic cluster-LVM configuration stuff */
static void check_config()
{
int locking_type;
locking_type = find_config_int(cmd->cft->root, "global/locking_type", 1);
if (locking_type == 3) /* compiled-in cluster support */
return;
if (locking_type == 2) { /* External library, check name */
const char *libname;
libname = find_config_str(cmd->cft->root, "global/locking_library",
"");
if (strstr(libname, "liblvm2clusterlock.so"))
return;
log_error("Incorrect LVM locking library specified in lvm.conf, cluster operations may not work.");
return;
}
log_error("locking_type not set correctly in lvm.conf, cluster operations will not work.");
}
void init_lvhash()
{
/* Create hash table for keeping LV locks & status */
lv_hash = dm_hash_create(100);
pthread_mutex_init(&lv_hash_lock, NULL);
}
/* Called to initialise the LVM context of the daemon */
int init_lvm(int using_gulm)
{
if (!(cmd = create_toolcontext(NULL))) {
log_error("Failed to allocate command context");
return 0;
}
/* Use LOG_DAEMON for syslog messages instead of LOG_USER */
init_syslog(LOG_DAEMON);
init_debug(_LOG_ERR);
/* Check lvm.conf is setup for cluster-LVM */
check_config();
/* Remove any non-LV locks that may have been left around */
if (using_gulm)
drop_vg_locks();
get_initial_state();
return 1;
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Functions in lvm-functions.c */
#ifndef _LVM_FUNCTIONS_H
#define _LVM_FUNCTIONS_H
extern int pre_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern int do_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern int do_check_lvm1(char *vgname);
extern int init_lvm(int using_gulm);
extern void init_lvhash(void);
extern int hold_unlock(char *resource);
extern int hold_lock(char *resource, int mode, int flags);
extern void unlock_all(void);
#endif

371
daemons/clvmd/system-lv.c Normal file
View File

@@ -0,0 +1,371 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Routines dealing with the System LV */
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/utsname.h>
#include <syslog.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <mntent.h>
#include "libdlm.h"
#include "log.h"
#include "list.h"
#include "locking.h"
#include "system-lv.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "clvmd.h"
#ifdef HAVE_CCS
#include "ccs.h"
#endif
#define SYSTEM_LV_FILESYSTEM "ext2"
#define SYSTEM_LV_MOUNTPOINT "/tmp/.clvmd-XXXXXX"
extern char *config_filename(void);
static char system_lv_name[PATH_MAX] = { '\0' };
static char mount_point[PATH_MAX] = { '\0' };
static int mounted = 0;
static int mounted_rw = 0;
static int lockid;
static const char *lock_name = "CLVM_SYSTEM_LV";
/* Look in /proc/mounts or (as a last resort) /etc/mtab to
see if the system-lv is mounted. If it is mounted and we
think it's not then abort because we don't have the right
lock status and we don't know what other processes are doing with it.
Returns 1 for mounted, 0 for not mounted so it matches the condition
of the "mounted" static variable above.
*/
static int is_really_mounted(void)
{
FILE *mountfile;
struct mntent *ment;
mountfile = setmntent("/proc/mounts", "r");
if (!mountfile) {
mountfile = setmntent("/etc/mtab", "r");
if (!mountfile) {
log_error("Unable to open /proc/mounts or /etc/mtab");
return -1;
}
}
/* Look for system LV name in the file */
do {
ment = getmntent(mountfile);
if (ment) {
if (strcmp(ment->mnt_fsname, system_lv_name) == 0) {
endmntent(mountfile);
return 1;
}
}
}
while (ment);
endmntent(mountfile);
return 0;
}
/* Get the system LV name from the config file */
static int find_system_lv(void)
{
if (system_lv_name[0] == '\0') {
#ifdef HAVE_CCS
int error;
ccs_node_t *ctree;
/* Read the cluster config file */
/* Open the config file */
error = open_ccs_file(&ctree, "clvm.ccs");
if (error) {
perror("reading config file");
return -1;
}
strcpy(system_lv_name, find_ccs_str(ctree,
"cluster/systemlv", '/',
"/dev/vg/system_lv"));
/* Finished with config file */
close_ccs_file(ctree);
#else
if (getenv("CLVMD_SYSTEM_LV"))
strcpy(system_lv_name, getenv("CLVMD_SYSTEM_LV"));
else
return -1;
#endif
}
/* See if it has been mounted outside our control */
if (is_really_mounted() != mounted) {
log_error
("The system LV state has been mounted/umounted outside the control of clvmd\n"
"it cannot not be used for cluster communications until this is fixed.\n");
return -1;
}
return 0;
}
/* No prizes */
int system_lv_umount(void)
{
if (!mounted)
return 0;
if (umount(mount_point) < 0) {
log_error("umount of system LV (%s) failed: %m\n",
system_lv_name);
return -1;
}
sync_unlock(lock_name, lockid);
mounted = 0;
/* Remove the mount point */
rmdir(mount_point);
return 0;
}
int system_lv_mount(int readwrite)
{
int status;
int saved_errno;
int fd;
if (find_system_lv()) {
errno = EBUSY;
return -1;
}
/* Is it already mounted suitably? */
if (mounted) {
if (!readwrite || (readwrite && mounted_rw)) {
return 0;
} else {
/* Mounted RO and we need RW */
if (system_lv_umount() < 0)
return -1;
}
}
/* Randomize the mount point */
strcpy(mount_point, SYSTEM_LV_MOUNTPOINT);
fd = mkstemp(mount_point);
if (fd < 0) {
log_error("mkstemp for system LV mount point failed: %m\n");
return -1;
}
/* Race condition here but there's no mkstemp for directories */
close(fd);
unlink(mount_point);
mkdir(mount_point, 0600);
/* Make sure we have a system-lv lock */
status =
sync_lock(lock_name, (readwrite) ? LKM_EXMODE : LKM_CRMODE, 0,
&lockid);
if (status < 0)
return -1;
/* Mount it */
if (mount(system_lv_name, mount_point, SYSTEM_LV_FILESYSTEM,
MS_MGC_VAL | MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_SYNCHRONOUS
| (readwrite ? 0 : MS_RDONLY), NULL) < 0) {
/* mount(2) returns EINVAL if the volume has no FS on it. So, if we want to
write to it we try to make a filesystem in it and retry the mount */
if (errno == EINVAL && readwrite) {
char cmd[256];
log_error("Attempting mkfs on system LV device %s\n",
system_lv_name);
snprintf(cmd, sizeof(cmd), "/sbin/mkfs -t %s %s",
SYSTEM_LV_FILESYSTEM, system_lv_name);
system(cmd);
if (mount
(system_lv_name, mount_point, SYSTEM_LV_FILESYSTEM,
MS_MGC_VAL | MS_NOSUID | MS_NODEV | MS_NOEXEC |
MS_SYNCHRONOUS | (readwrite ? 0 : MS_RDONLY),
NULL) == 0)
goto mounted;
}
saved_errno = errno;
log_error("mount of system LV (%s, %s, %s) failed: %m\n",
system_lv_name, mount_point, SYSTEM_LV_FILESYSTEM);
sync_unlock(lock_name, lockid);
errno = saved_errno;
return -1;
}
mounted:
/* Set the internal flags */
mounted = 1;
mounted_rw = readwrite;
return 0;
}
/* Erase *all* files in the root directory of the system LV.
This *MUST* be called with an appropriate lock held!
The LV is left mounted RW because it is assumed that the
caller wants to write something here after clearing some space */
int system_lv_eraseall(void)
{
DIR *dir;
struct dirent *ent;
char fname[PATH_MAX];
/* Must be mounted R/W */
system_lv_mount(1);
dir = opendir(mount_point);
if (!dir)
return -1;
while ((ent = readdir(dir))) {
struct stat st;
snprintf(fname, sizeof(fname), "%s/%s", mount_point,
ent->d_name);
if (stat(fname, &st)) {
if (S_ISREG(st.st_mode))
unlink(fname);
}
}
closedir(dir);
return 0;
}
/* This is a "high-level" routine - it mounts the system LV, writes
the data into a file named after this node and then umounts the LV
again */
int system_lv_write_data(char *data, ssize_t len)
{
struct utsname nodeinfo;
char fname[PATH_MAX];
int outfile;
ssize_t thiswrite;
ssize_t written;
if (system_lv_mount(1))
return -1;
/* Build the file name we are goingto use. */
uname(&nodeinfo);
snprintf(fname, sizeof(fname), "%s/%s", mount_point, nodeinfo.nodename);
/* Open the file for output */
outfile = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (outfile < 0) {
int saved_errno = errno;
system_lv_umount();
errno = saved_errno;
return -1;
}
written = 0;
do {
thiswrite = write(outfile, data + written, len - written);
if (thiswrite > 0)
written += thiswrite;
} while (written < len && thiswrite > 0);
close(outfile);
system_lv_umount();
return (thiswrite < 0) ? -1 : 0;
}
/* This is a "high-level" routine - it mounts the system LV, reads
the data from a named file and then umounts the LV
again */
int system_lv_read_data(char *fname_base, char *data, ssize_t *len)
{
char fname[PATH_MAX];
int outfile;
struct stat st;
ssize_t filesize;
ssize_t thisread;
ssize_t readbytes;
if (system_lv_mount(0))
return -1;
/* Build the file name we are going to use. */
snprintf(fname, sizeof(fname), "%s/%s", mount_point, fname_base);
/* Get the file size and stuff. Actually we only need the file size but
this will also check that the file exists */
if (stat(fname, &st) < 0) {
int saved_errno = errno;
log_error("stat of file %s on system LV failed: %m\n", fname);
system_lv_umount();
errno = saved_errno;
return -1;
}
filesize = st.st_size;
outfile = open(fname, O_RDONLY);
if (outfile < 0) {
int saved_errno = errno;
log_error("open of file %s on system LV failed: %m\n", fname);
system_lv_umount();
errno = saved_errno;
return -1;
}
readbytes = 0;
do {
thisread =
read(outfile, data + readbytes, filesize - readbytes);
if (thisread > 0)
readbytes += thisread;
} while (readbytes < filesize && thisread > 0);
close(outfile);
system_lv_umount();
*len = readbytes;
return (thisread < 0) ? -1 : 0;
}

30
daemons/clvmd/system-lv.h Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _CLVM_SYSTEM_LV_H
#define _CLVM_SYSTEM_LV_H
/* Prototypes for System-LV functions */
/* "low-level" functions */
extern int system_lv_umount(void);
extern int system_lv_mount(int readwrite);
extern int system_lv_eraseall(void);
/* "high-level" functions */
extern int system_lv_write_data(char *data, ssize_t len);
extern int system_lv_read_data(char *fname_base, char *data, ssize_t *len);
#endif

505
daemons/clvmd/tcp-comms.c Normal file
View File

@@ -0,0 +1,505 @@
/******************************************************************************
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved.
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
**
*******************************************************************************
******************************************************************************/
/* This provides the inter-clvmd communications for a system without CMAN.
There is a listening TCP socket which accepts new connections in the
normal way.
It can also make outgoing connnections to the other clvmd nodes.
*/
#include <pthread.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <netdb.h>
#include <assert.h>
#include "libdevmapper.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "clvmd.h"
#include "clvmd-gulm.h"
#define DEFAULT_TCP_PORT 21064
static int listen_fd = -1;
static int tcp_port;
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,
struct local_client **new_client);
/* Called by init_cluster() to open up the listening socket */
int init_comms(unsigned short port)
{
struct sockaddr_in6 addr;
sock_hash = dm_hash_create(100);
tcp_port = port ? port : DEFAULT_TCP_PORT;
listen_fd = socket(AF_INET6, SOCK_STREAM, 0);
if (listen_fd < 0)
{
return -1;
}
else
{
int one = 1;
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
setsockopt(listen_fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));
}
memset(&addr, 0, sizeof(addr)); // Bind to INADDR_ANY
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(tcp_port);
if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
DEBUGLOG("Can't bind to port: %s\n", strerror(errno));
syslog(LOG_ERR, "Can't bind to port %d, is clvmd already running ?", tcp_port);
close(listen_fd);
return -1;
}
listen(listen_fd, 5);
/* Set Close-on-exec */
fcntl(listen_fd, F_SETFD, 1);
return 0;
}
void tcp_remove_client(char *csid)
{
struct local_client *client;
DEBUGLOG("tcp_remove_client\n");
/* Don't actually close the socket here - that's the
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 = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
if (client)
{
dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
client->removeme = 1;
close(client->fd);
}
/* Look for a mangled one too */
csid[0] ^= 0x80;
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
if (client)
{
dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
client->removeme = 1;
close(client->fd);
}
/* Put it back as we found it */
csid[0] ^= 0x80;
}
int alloc_client(int fd, char *csid, struct local_client **new_client)
{
struct local_client *client;
DEBUGLOG("alloc_client %d csid = %s\n", fd, print_csid(csid));
/* Create a local_client and return it */
client = malloc(sizeof(struct local_client));
if (!client)
{
DEBUGLOG("malloc failed\n");
return -1;
}
memset(client, 0, sizeof(struct local_client));
client->fd = fd;
client->type = CLUSTER_DATA_SOCK;
client->callback = read_from_tcpsock;
if (new_client)
*new_client = client;
/* Add to our list of node sockets */
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
the other end may already have started sending.
So, we mangle the IP address and keep it, all sending will
go out of the main FD
*/
csid[0] ^= 0x80;
client->bits.net.flags = 1; /* indicate mangled CSID */
/* If it still exists then kill the connection as we should only
ever have one incoming connection from each node */
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]);
free(client);
errno = ECONNREFUSED;
return -1;
}
}
dm_hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);
return 0;
}
int get_main_gulm_cluster_fd()
{
return listen_fd;
}
/* Read on main comms (listen) socket, accept it */
int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, char *csid,
struct local_client **new_client)
{
int newfd;
struct sockaddr_in6 addr;
socklen_t addrlen = sizeof(addr);
int status;
char name[GULM_MAX_CLUSTER_MEMBER_NAME_LEN];
DEBUGLOG("cluster_fd_callback\n");
*new_client = NULL;
newfd = accept(listen_fd, (struct sockaddr *)&addr, &addrlen);
DEBUGLOG("cluster_fd_callback, newfd=%d (errno=%d)\n", newfd, errno);
if (!newfd)
{
syslog(LOG_ERR, "error in accept: %m");
errno = EAGAIN;
return -1; /* Don't return an error or clvmd will close the listening FD */
}
/* Check that the client is a member of the cluster
and reject if not.
*/
if (gulm_name_from_csid((char *)&addr.sin6_addr, name) < 0)
{
syslog(LOG_ERR, "Got connect from non-cluster node %s\n",
print_csid((char *)&addr.sin6_addr));
DEBUGLOG("Got connect from non-cluster node %s\n",
print_csid((char *)&addr.sin6_addr));
close(newfd);
errno = EAGAIN;
return -1;
}
status = alloc_client(newfd, (char *)&addr.sin6_addr, new_client);
if (status)
{
DEBUGLOG("cluster_fd_callback, alloc_client failed, status = %d\n", status);
close(newfd);
/* See above... */
errno = EAGAIN;
return -1;
}
DEBUGLOG("cluster_fd_callback, returning %d, %p\n", newfd, *new_client);
return newfd;
}
/* Try to get at least 'len' bytes from the socket */
static int really_read(int fd, char *buf, int len)
{
int got, offset;
got = offset = 0;
do {
got = read(fd, buf+offset, len-offset);
DEBUGLOG("really_read. got %d bytes\n", got);
offset += got;
} while (got > 0 && offset < len);
if (got < 0)
return got;
else
return offset;
}
static int read_from_tcpsock(struct local_client *client, char *buf, int len, char *csid,
struct local_client **new_client)
{
struct sockaddr_in6 addr;
socklen_t slen = sizeof(addr);
struct clvm_header *header = (struct clvm_header *)buf;
int status;
uint32_t arglen;
DEBUGLOG("read_from_tcpsock fd %d\n", client->fd);
*new_client = NULL;
/* Get "csid" */
getpeername(client->fd, (struct sockaddr *)&addr, &slen);
memcpy(csid, &addr.sin6_addr, GULM_MAX_CSID_LEN);
/* Read just the header first, then get the rest if there is any.
* Stream sockets, sigh.
*/
status = really_read(client->fd, buf, sizeof(struct clvm_header));
if (status > 0)
{
int status2;
arglen = ntohl(header->arglen);
/* Get the rest */
if (arglen && arglen < GULM_MAX_CLUSTER_MESSAGE)
{
status2 = really_read(client->fd, buf+status, arglen);
if (status2 > 0)
status += status2;
else
status = status2;
}
}
DEBUGLOG("read_from_tcpsock, status = %d(errno = %d)\n", status, errno);
/* Remove it from the hash table if there's an error, clvmd will
remove the socket from its lists and free the client struct */
if (status == 0 ||
(status < 0 && errno != EAGAIN && errno != EINTR))
{
char remcsid[GULM_MAX_CSID_LEN];
memcpy(remcsid, csid, GULM_MAX_CSID_LEN);
close(client->fd);
/* If the csid was mangled, then make sure we remove the right entry */
if (client->bits.net.flags)
remcsid[0] ^= 0x80;
dm_hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);
/* Tell cluster manager layer */
add_down_node(remcsid);
}
else {
gulm_add_up_node(csid);
/* Send it back to clvmd */
process_message(client, buf, status, csid);
}
return status;
}
int gulm_connect_csid(char *csid, struct local_client **newclient)
{
int fd;
struct sockaddr_in6 addr;
int status;
int one = 1;
DEBUGLOG("Connecting socket\n");
fd = socket(PF_INET6, SOCK_STREAM, 0);
if (fd < 0)
{
syslog(LOG_ERR, "Unable to create new socket: %m");
return -1;
}
addr.sin6_family = AF_INET6;
memcpy(&addr.sin6_addr, csid, GULM_MAX_CSID_LEN);
addr.sin6_port = htons(tcp_port);
DEBUGLOG("Connecting socket %d\n", fd);
if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) < 0)
{
/* "Connection refused" is "normal" because clvmd may not yet be running
* on that node.
*/
if (errno != ECONNREFUSED)
{
syslog(LOG_ERR, "Unable to connect to remote node: %m");
}
DEBUGLOG("Unable to connect to remote node: %s\n", strerror(errno));
close(fd);
return -1;
}
/* Set Close-on-exec */
fcntl(fd, F_SETFD, 1);
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));
status = alloc_client(fd, csid, newclient);
if (status)
close(fd);
else
add_client(*newclient);
/* If we can connect to it, it must be running a clvmd */
gulm_add_up_node(csid);
return status;
}
/* Send a message to a known CSID */
static int tcp_send_message(void *buf, int msglen, unsigned char *csid, const char *errtext)
{
int status;
struct local_client *client;
char ourcsid[GULM_MAX_CSID_LEN];
assert(csid);
DEBUGLOG("tcp_send_message, csid = %s, msglen = %d\n", print_csid(csid), msglen);
/* Don't connect to ourself */
get_our_gulm_csid(ourcsid);
if (memcmp(csid, ourcsid, GULM_MAX_CSID_LEN) == 0)
return msglen;
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
if (!client)
{
status = gulm_connect_csid(csid, &client);
if (status)
return -1;
}
DEBUGLOG("tcp_send_message, fd = %d\n", client->fd);
return write(client->fd, buf, msglen);
}
int gulm_cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
{
int status=0;
DEBUGLOG("cluster send message, csid = %p, msglen = %d\n", csid, msglen);
/* If csid is NULL then send to all known (not just connected) nodes */
if (!csid)
{
void *context = NULL;
char loop_csid[GULM_MAX_CSID_LEN];
/* Loop round all gulm-known nodes */
while (get_next_node_csid(&context, loop_csid))
{
status = tcp_send_message(buf, msglen, loop_csid, errtext);
if (status == 0 ||
(status < 0 && (errno == EAGAIN || errno == EINTR)))
break;
}
}
else
{
status = tcp_send_message(buf, msglen, csid, errtext);
}
return status;
}
/* To get our own IP address we get the locally bound address of the
socket that's talking to GULM in the assumption(eek) that it will
be on the "right" network in a multi-homed system */
static int get_our_ip_address(char *addr, int *family)
{
struct utsname info;
uname(&info);
get_ip_address(info.nodename, addr);
return 0;
}
/* Public version of above for those that don't care what protocol
we're using */
void get_our_gulm_csid(char *csid)
{
static char our_csid[GULM_MAX_CSID_LEN];
static int got_csid = 0;
if (!got_csid)
{
int family;
memset(our_csid, 0, sizeof(our_csid));
if (get_our_ip_address(our_csid, &family))
{
got_csid = 1;
}
}
memcpy(csid, our_csid, GULM_MAX_CSID_LEN);
}
static void map_v4_to_v6(struct in_addr *ip4, struct in6_addr *ip6)
{
ip6->s6_addr32[0] = 0;
ip6->s6_addr32[1] = 0;
ip6->s6_addr32[2] = htonl(0xffff);
ip6->s6_addr32[3] = ip4->s_addr;
}
/* Get someone else's IP address from DNS */
int get_ip_address(char *node, char *addr)
{
struct hostent *he;
memset(addr, 0, GULM_MAX_CSID_LEN);
// TODO: what do we do about multi-homed hosts ???
// CCSs ip_interfaces solved this but some bugger removed it.
/* Try IPv6 first. The man page for gethostbyname implies that
it will lookup ip6 & ip4 names, but it seems not to */
he = gethostbyname2(node, AF_INET6);
if (he)
{
memcpy(addr, he->h_addr_list[0],
he->h_length);
}
else
{
he = gethostbyname2(node, AF_INET);
if (!he)
return -1;
map_v4_to_v6((struct in_addr *)he->h_addr_list[0], (struct in6_addr *)addr);
}
return 0;
}
char *print_csid(char *csid)
{
static char buf[128];
int *icsid = (int *)csid;
sprintf(buf, "[%x.%x.%x.%x]",
icsid[0],icsid[1],icsid[2],icsid[3]);
return buf;
}

13
daemons/clvmd/tcp-comms.h Normal file
View File

@@ -0,0 +1,13 @@
#include <netinet/in.h>
#define GULM_MAX_CLUSTER_MESSAGE 1600
#define GULM_MAX_CSID_LEN sizeof(struct in6_addr)
#define GULM_MAX_CLUSTER_MEMBER_NAME_LEN 128
extern int init_comms(unsigned short);
extern char *print_csid(char *);
int get_main_gulm_cluster_fd(void);
int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, char *csid, struct local_client **new_client);
int gulm_cluster_send_message(void *buf, int msglen, char *csid, const char *errtext);
void get_our_gulm_csid(char *csid);
int gulm_connect_csid(char *csid, struct local_client **newclient);

View File

@@ -0,0 +1,5 @@
dm_event_register
dm_event_unregister
dm_event_get_registered_device
dm_event_set_timeout
dm_event_get_timeout

View File

@@ -0,0 +1,55 @@
#
# 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SOURCES = libdevmapper-event.c \
dmeventd.c
LIB_STATIC = libdevmapper-event.a
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event.dylib
else
LIB_SHARED = libdevmapper-event.so
endif
include ../make.tmpl
CLDFLAGS += -ldl -ldevmapper -lpthread
.PHONY: install_dynamic install_static
INSTALL_TYPE = install_dynamic
ifeq ("@STATIC_LINK@", "yes")
INSTALL_TYPE += install_static
endif
install: $(INSTALL_TYPE)
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) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.h \
$(includedir)/libdevmapper-event.h
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

1318
daemons/dmeventd/dmeventd.c Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,22 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SUBDIRS += mirror
include $(top_srcdir)/make.tmpl

View File

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

View File

@@ -0,0 +1,36 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper -llvm2cmd
SOURCES = dmeventd_mirror.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2mirror.dylib
else
LIB_SHARED = libdevmapper-event-lvm2mirror.so
endif
include $(top_srcdir)/make.tmpl
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View File

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

6
debian/README.Debian vendored Normal file
View File

@@ -0,0 +1,6 @@
LVM2 requires the device-mapper kernel module (dm-mod). This is
available as a kernel patch for 2.4 (in kernel-patch-device-mapper), and
is distributed with linux 2.5 and above. The LVM1 kernel module (lvm-mod)
will not work with lvm2 packages. dm-mod and lvm-mod may both be loaded
in the kernel at the same time with no problems. Without dm-mod, this
package is pretty useless.

38
debian/changelog vendored
View File

@@ -1,3 +1,41 @@
lvm2 (1.95.15-1) unstable; urgency=low
* New upstream release.
* Remove undocumented manpage symlinks.
* Update description to be more informative. (Closes: #173499)
* Add kernel-patch-device-mapper suggestion.
* Update standards version.
-- Andres Salomon <dilinger@mp3revolution.net> Sun, 16 Feb 2002 04:21:26 -0400
lvm2 (1.95.11-1) unstable; urgency=low
* New upstream release. (Closes: #171436)
* Removed TODO and INTRO from debian/docs; added WHATS_NEW.
* Remove vgcfgrestore.8 undocumented symlink.
* Added a README.Debian, mentioning the device-mapper kernel module
requirement that lvm2 has. (Closes: #171674, #163020)
* Get rid of debian/conffiles (debhelper's smart enough to figure that out).
* debian/copyright fix to appease lintian.
* Fix typo in tools/commands.h that caused /usr/sbin/; to be created.
-- Andres Salomon <dilinger@mp3revolution.net> Mon, 9 Dec 2002 02:51:02 -0400
lvm2 (1.95.10-2) unstable; urgency=low
* Fix software raid problems by ensuring lvm init script runs after
raidtools init script. (Closes: #152569)
-- Andres Salomon <dilinger@mp3revolution.net> Tue, 3 Sep 2002 04:05:43 -0400
lvm2 (1.95.10-1) unstable; urgency=low
* New upstream release (Beta 3.2).
* Change all references to /dev/device-mapper/control to
/dev/mapper/control.
-- Andres Salomon <dilinger@mp3revolution.net> Sun, 1 Sep 2002 18:55:12 -0400
lvm2 (0.95.05-3) unstable; urgency=low
* Get rid of awk dependency in init script. (Closes: #146257)

2
debian/conffiles vendored
View File

@@ -1,2 +0,0 @@
/etc/lvm/lvm.conf
/etc/init.d/lvm2

10
debian/control vendored
View File

@@ -2,8 +2,8 @@ Source: lvm2
Section: admin
Priority: optional
Maintainer: Andres Salomon <dilinger@mp3revolution.net>
Build-Depends: debhelper (>> 3.0.0), libdevmapper-dev, libreadline4-dev
Standards-Version: 3.5.2
Build-Depends: debhelper (>> 3.0.0), libdevmapper-dev (>= 0.96.04), libreadline4-dev
Standards-Version: 3.5.8.0
Package: lvm2
Architecture: any
@@ -11,10 +11,14 @@ Depends: ${shlibs:Depends}
Conflicts: lvm10, lvm-common
Replaces: lvm10, lvm-common
Provides: lvm-binaries
Suggests: dmsetup
Suggests: dmsetup, kernel-patch-device-mapper
Description: The Linux Logical Volume Manager
This is LVM2, the rewrite of The Linux Logical Volume Manager. LVM
supports enterprise level volume management of disk and disk subsystems
by grouping arbitrary disks into volume groups. The total capacity of
volume groups can be allocated to logical volumes, which are accessed as
regular block devices.
.
LVM2 is currently stable, but has some unimplemented features (most notably,
pvmove and e2fsadm). It is not yet recommended for production use. It is
backwards-compatible with LVM1 (lvm10), and requires Linux kernel 2.4.

2
debian/copyright vendored
View File

@@ -3,7 +3,7 @@ Wed, 20 Feb 2002 03:17:25 -0500.
It was downloaded from http://www.sistina.com/products_lvm.htm
Upstream Author(s): LVM Development Team
Upstream Author: LVM Development Team
Copyright (c) 2001-2002 LVM Development Team

3
debian/docs vendored
View File

@@ -1,6 +1,5 @@
BUGS
INTRO
README
TODO
VERSION
WHATS_NEW
doc/*

2
debian/init.d vendored
View File

@@ -14,7 +14,7 @@ modprobe dm-mod >/dev/null 2>&1
# Create necessary files in /dev for device-mapper
create_devfiles() {
DIR="/dev/device-mapper"
DIR="/dev/mapper"
FILE="$DIR/control"
major=$(grep "[0-9] misc$" /proc/devices | sed 's/[ ]\+misc//')
minor=$(grep "[0-9] device-mapper$" /proc/misc | sed 's/[ ]\+device-mapper//')

3
debian/rules vendored
View File

@@ -98,11 +98,10 @@ binary-arch: build install
# dh_installemacsen -a
# dh_installpam -a
# dh_installmime -a
dh_installinit --update-rcd-params="start 25 S . start 50 0 6 ."
dh_installinit --update-rcd-params="start 26 S . start 50 0 6 ."
dh_installcron
dh_installman
dh_installinfo
dh_undocumented
dh_installchangelogs
dh_strip
dh_link

14
debian/undocumented vendored
View File

@@ -1,14 +0,0 @@
e2fsadm.8
lvmdiskscan.8
lvmsadc.8
lvmsar.8
lvresize.8
pvdata.8
pvmove.8
pvresize.8
version.8
vgcfgrestore.8
vgexport.8
vgimport.8
vgmknodes.8
vgsplit.8

22
dmeventd/Makefile.in Normal file
View File

@@ -0,0 +1,22 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SUBDIRS += mirror
include $(top_srcdir)/make.tmpl

View File

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

View File

@@ -0,0 +1,36 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper -llvm2cmd
SOURCES = dmeventd_mirror.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2mirror.dylib
else
LIB_SHARED = libdevmapper-event-lvm2mirror.so
endif
include $(top_srcdir)/make.tmpl
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View File

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

29
doc/Makefile.in Normal file
View File

@@ -0,0 +1,29 @@
#
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
CONFSRC=example.conf
CONFDEST=lvm.conf
include $(top_srcdir)/make.tmpl
install:
@if [ ! -e $(confdir)/$(CONFDEST) ]; then \
echo "Installing $(CONFSRC) as $(confdir)/$(CONFDEST)"; \
@INSTALL@ -D $(OWNER) $(GROUP) -m 644 $(CONFSRC) \
$(confdir)/$(CONFDEST); \
fi

View File

@@ -1,74 +1,112 @@
# This is an example configuration file for the LVM2 system. It
# contains the default settings that would be used if there was no
# This is an example configuration file for the LVM2 system.
# It contains the default settings that would be used if there was no
# /etc/lvm/lvm.conf file.
# Refer to 'man lvm.conf' for further information.
#
# Refer to 'man lvm.conf' for further information including the file layout.
#
# To put this file in a different directory and override /etc/lvm set
# the environment variable LVM_SYSTEM_DIR before running the tools.
# This section allows the user to configure which block devices should
# This section allows you to configure which block devices should
# be used by the LVM system.
devices {
# where do you want your volume groups to appear ?
# Where do you want your volume groups to appear ?
dir = "/dev"
# An array of directories that contain the device nodes you wish
# to use with LVM2.
scan = "/dev"
# A very important option, that allows you to tune the LVM2 system
# to just look at a restricted set of devices that you're
# interested in.
scan = [ "/dev" ]
# A filter that tells LVM2 to only use a restricted set of devices.
# The filter consists of an array of regular expressions. These
# expressions can be delimited by a character of your choice, and
# prefixed with either an 'a' (for accept) or 'r' (for reject).
# ATM you cannot use anchors (^ or $) in your regular expression.
# The first expression found to match a device name determines if
# the device will be accepted or rejected (ignored). Devices that
# don't match any patterns are accepted.
# Be careful if there there are symbolic links or multiple filesystem
# entries for the same device as each name is checked separately against
# the list of patterns. The effect is that if any name matches any 'a'
# pattern, the device is accepted; otherwise if any name matches any 'r'
# pattern it is rejected; otherwise it is accepted.
# 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'.
# Remember to run vgscan after you change this parameter.
# By default we accept every block device:
filter = "a/.*/"
filter = [ "a/.*/" ]
# Exclude the cdrom drive
# filter = [ "r|/dev/cdrom|" ]
# When testing I like to work with just loopback devices:
# filter = ["a/loop/", "r/.*/"]
# filter = [ "a/loop/", "r/.*/" ]
# Or maybe all loops and ide drives except hdc:
# filter =["a|loop|", "r|/dev/hdc|", "a|/dev/ide|", "r|.*|"]
# filter =[ "a|loop|", "r|/dev/hdc|", "a|/dev/ide|", "r|.*|" ]
# The results of all the filtering are cached on disk to avoid
# Use anchors if you want to be really specific
# filter = [ "a|^/dev/hda8$|", "r/.*/" ]
# The results of the filtering are cached on disk to avoid
# rescanning dud devices (which can take a very long time). By
# default this cache file is hidden in the /etc/lvm directory, it
# is human readable to aid filter debugging.
# default this cache file is hidden in the /etc/lvm directory.
# It is safe to delete this file: the tools regenerate it.
cache = "/etc/lvm/.cache"
# You can turn off writing this cache file by setting this to 0.
write_cache_state = 1
# Advanced settings.
# List of pairs of additional acceptable block device types found
# in /proc/devices with maximum (non-zero) number of partitions.
# types = [ "fd", 16 ]
# If sysfs is mounted (2.6 kernels) restrict device scanning to
# the block devices it believes are valid.
# 1 enables; 0 disables.
sysfs_scan = 1
# By default, LVM2 will ignore devices used as components of
# software RAID (md) devices by looking for md superblocks.
# 1 enables; 0 disables.
md_component_detection = 1
}
# A section that allows the user to configure the nature of the
# This section that allows you to configure the nature of the
# information that LVM2 reports.
log {
# Where should the log of error and debug messages go ? By
# default there is no log.
#file = "/var/log/lvm2.log"
# Should we overwrite the last log. By default we append.
overwrite = 0
# There are 9 log levels, with 9 being the most verbose.
level = 3
# Controls the messages sent to stdout or stderr while running
# LVM2. There are three levels of verbosity, 3 being the most
# verbose.
# Controls the messages sent to stdout or stderr.
# There are three levels of verbosity, 3 being the most verbose.
verbose = 0
# Should we send log messages through syslog?
# 1 is yes; 0 is no.
syslog = 1
# Choose format of output messages
# Should we log error and debug messages to a file?
# By default there is no log file.
#file = "/var/log/lvm2.log"
# Should we overwrite the log file each time the program is run?
# By default we append.
overwrite = 0
# What level of log messages should we send to the log file and/or syslog?
# There are 6 syslog-like log levels currently in use - 2 to 7 inclusive.
# 7 is the most verbose (LOG_DEBUG).
level = 0
# Format of output messages
# Whether or not (1 or 0) to indent messages according to their severity
indent = 1
@@ -76,13 +114,18 @@ log {
command_names = 0
# A prefix to use before the message text (but after the command name,
# if selected)
# if selected). Default is two spaces, so you can see/grep the severity
# of each message.
prefix = " "
# To make the messages look similar to the original LVM use:
# To make the messages look similar to the original LVM tools use:
# indent = 0
# command_names = 1
# prefix = " -- "
# Set this if you want log messages during activation.
# Don't use this in low memory situations (can deadlock).
# activation = 0
}
# Configuration of metadata backups and archiving. In LVM2 when we
@@ -93,19 +136,20 @@ backup {
# Should we maintain a backup of the current metadata configuration ?
# Use 1 for Yes; 0 for No.
# Think very hard before turning this off.
# Think very hard before turning this off!
backup = 1
# Where shall we keep it ?
# Remember to back up this directory regularly!
backup_dir = "/etc/lvm/backup"
# Should we maintain an archive of old metadata configurations.
# Use 1 for Yes; 0 for No.
# On by default. Think very hard before turning this off.
archive = 1
# Where should archived files go ?
# Remember to back up this directory regularly!
archive_dir = "/etc/lvm/archive"
# What is the minimum number of archive files you wish to keep ?
@@ -115,20 +159,15 @@ backup {
retain_days = 30
}
# Settings for the running LVM2 in shell mode.
# Settings for the running LVM2 in shell (readline) mode.
shell {
# Number of lines of history to store in ~/.lvm_history
history_size = 100
}
# Metadata settings
metadata {
# List of directories holding copies of text format metadata
dirs = [ "/etc/lvm/metadata" ]
}
# Miscellaneous global settings
# Miscellaneous global LVM2 settings
global {
# The file creation mask for any files and directories created.
@@ -143,10 +182,116 @@ global {
# command. Defaults to off.
test = 0
# Default metadata format commands use - "lvm1" (default) or "text"
format = "lvm1"
# Whether or not to communicate with the kernel device-mapper.
# Set to 0 if you want to use the tools to manipulate LVM metadata
# without activating any logical volumes.
# If the device-mapper kernel driver is not present in your kernel
# setting this to 0 should suppress the error messages.
activation = 1
# If we can't communicate with device-mapper, should we try running
# the LVM1 tools?
# This option only applies to 2.4 kernels and is provided to help you
# switch between device-mapper kernels and LVM1 kernels.
# The LVM1 tools need to be installed with .lvm1 suffices
# e.g. vgscan.lvm1 and they will stop working after you start using
# the new lvm2 on-disk metadata format.
# The default value is set when the tools are built.
# fallback_to_lvm1 = 0
# The default metadata format that commands should use - "lvm1" or "lvm2".
# The command line override is -M1 or -M2.
# Defaults to "lvm1" if compiled in, else "lvm2".
# format = "lvm1"
# Location of proc filesystem
proc = "/proc"
# Type of locking to use. Defaults to file-based locking (1).
# Turn locking off by setting to 0 (dangerous: risks metadata corruption
# if LVM2 commands get run concurrently).
locking_type = 1
# Local non-LV directory that holds file-based locks while commands are
# in progress. A directory like /tmp that may get wiped on reboot is OK.
locking_dir = "/var/lock/lvm"
# Other entries can go here to allow you to load shared libraries
# e.g. if support for LVM1 metadata was compiled as a shared library use
# format_libraries = "liblvm2format1.so"
# Full pathnames can be given.
# Search this directory first for shared libraries.
# library_dir = "/lib"
}
activation {
# Device used in place of missing stripes if activating incomplete volume.
# For now, you need to set this up yourself first (e.g. with 'dmsetup')
# For example, you could make it return I/O errors using the 'error'
# target or make it return zeros.
missing_stripe_filler = "/dev/ioerror"
# Size (in KB) of each copy operation when mirroring
mirror_region_size = 512
# How much stack (in KB) to reserve for use while devices suspended
reserved_stack = 256
# How much memory (in KB) to reserve for use while devices suspended
reserved_memory = 8192
# Nice value used while devices suspended
process_priority = -18
# If volume_list is defined, each LV is only activated if there is a
# match against the list.
# "vgname" and "vgname/lvname" are matched exactly.
# "@tag" matches any tag set in the LV or VG.
# "@*" matches if any tag defined on the host is also set in the LV or VG
#
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
}
####################
# Advanced section #
####################
# Metadata settings
#
# metadata {
# Default number of copies of metadata to hold on each PV. 0, 1 or 2.
# You might want to override it from the command line with 0
# when running pvcreate on new PVs which are to be added to large VGs.
# pvmetadatacopies = 1
# Approximate default size of on-disk metadata areas in sectors.
# You should increase this if you have large volume groups or
# you want to retain a large on-disk history of your metadata changes.
# pvmetadatasize = 255
# List of directories holding live copies of text format metadata.
# These directories must not be on logical volumes!
# It's possible to use LVM2 with a couple of directories here,
# preferably on different (non-LV) filesystems, and with no other
# on-disk metadata (pvmetadatacopies = 0). Or this can be in
# addition to on-disk metadata areas.
# The feature was originally added to simplify testing and is not
# supported under low memory situations - the machine could lock up.
#
# Never edit any files in these directories by hand unless you
# you are absolutely sure you know what you are doing! Use
# the supplied toolset to make changes (e.g. vgcfgrestore).
# dirs = [ "/etc/lvm/metadata", "/mnt/disk2/lvm/metadata2" ]
#}
# Event daemon
#
#dmeventd {
# mirror_library = "libdevmapper-event-lvm2mirror.so"
#}

47
doc/example_cmdlib.c Normal file
View File

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

165
doc/tagging.txt Normal file
View File

@@ -0,0 +1,165 @@
Tagging aims
============
1) Ability to attach an unordered list of tags to LVM metadata objects.
2) Ability to add or remove tags easily.
3) Ability to select LVM objects for processing according to presence/absence
of specific tags.
4) Ability to control through the config file which VGs/LVs are activated
on different machines using names or tags.
5) Ability to overlay settings from different config files e.g. override
some settings in a global config file locally.
Clarifications
==============
1) Tag character set: A-Za-z0-9_+.-
Can't start with hyphen & max length is 128 (NAME_LEN).
2) LVM object types that can be tagged:
VG, LV, LV segment
PV - tags are stored in VG metadata so disappear when PV becomes orphaned
Snapshots can't be tagged, but their origin may be.
3) A tag can be used in place of any command line LVM object reference that
accepts (a) a list of objects; or (b) a single object as long as the
tag expands to a single object. This is not supported everywhere yet.
Duplicate arguments in a list after argument expansion may get removed
retaining the first copy of each argument.
4) Wherever there may be ambiguity of argument type, a tag must be prefixed
by '@'; elsewhere an '@' prefix is optional.
5) LVM1 objects cannot be tagged, as the disk format doesn't support it.
6) Tags can be added or removed with --addtag or --deltag.
Config file Extensions
======================
To define host tags in config file:
tags {
# Set a tag with the hostname
hosttags = 1
tag1 { }
tag2 {
# If no exact match, tag is not set.
host_list = [ "hostname", "dbase" ]
}
}
Activation config file example
==============================
activation {
volume_list = [ "vg1/lvol0", "@database" ]
}
Matches against vgname, vgname/lvname or @tag set in *metadata*.
@* matches exactly against *any* tag set on the host.
The VG or LV only gets activated if a metadata tag matches.
The default if there is no match is not to activate.
If volume_list is not present and any tags are defined on the host
then it only activates if a host tag matches a metadata tag.
If volume_list is not present and no tags are defined on the host
then it does activate.
Multiple config files
=====================
(a) lvm.conf
(b) lvm_<host_tag>.conf
At startup, load lvm.conf.
Process tag settings.
If any host tags were defined, load lvm_tag.conf for each tag, if present.
When searching for a specific config file entry, search order is (b)
then (a), stopping at the first match.
Within (b) use reverse order tags got set, so file for last tag set is
searched first.
New tags set in (b) *do* trigger additional config file loads.
Usage Examples
==============
1) Simple activation control via metadata with static config files
lvm.conf: (Identical on every machine - global settings)
tags {
hostname_tags = 1
}
From any machine in the cluster, add db1 to the list of machines that
activate vg1/lvol2:
lvchange --tag @db1 vg1/lvol2
(followed by lvchange -ay to actually activate it)
2) Multiple hosts.
Activate vg1 only on the database hosts, db1 and db2.
Activate vg2 only on the fileserver host fs1.
Activate nothing initially on the fileserver backup host fsb1, but be
prepared for it to take over from fs1.
Option (i) - centralised admin, static configuration replicated between hosts
# Add @database tag to vg1's metadata
vgchange --tag @database vg1
# Add @fileserver tag to vg2's metadata
vgchange --tag @fileserver vg2
lvm.conf: (Identical on every machine)
tags {
database {
host_list = [ "db1", "db2" ]
}
fileserver {
host_list = [ "fs1" ]
}
fileserverbackup {
host_list = [ "fsb1" ]
}
}
activation {
# Only activate if host has a tag that matches a metadata tag
volume_list = [ "@*" ]
}
In the event of the fileserver host going down, vg2 can be brought up
on fsb1 by running *on any node* 'vgchange --tag @fileserverbackup vg2'
followed by 'vgchange -ay vg2'
Option (ii) - localised admin & configuation
(i.e. each host holds *locally* which classes of volumes to activate)
# Add @database tag to vg1's metadata
vgchange --tag @database vg1
# Add @fileserver tag to vg2's metadata
vgchange --tag @fileserver vg2
lvm.conf: (Identical on every machine - global settings)
tags {
hosttags = 1
}
lvm_db1.conf: (only needs to be on db1 - could be symlink to lvm_db.conf)
activation {
volume_list = [ "@database" ]
}
lvm_db2.conf: (only needs to be on db2 - could be symlink to lvm_db.conf)
activation {
volume_list = [ "@database" ]
}
lvm_fs1.conf: (only needs to be on fs1 - could be symlink to lvm_fs.conf)
activation {
volume_list = [ "@fileserver" ]
}
If fileserver goes down, to bring a spare machine fsb1 in as fileserver,
create lvm_fsb1.conf on fsb1 (or symlink to lvm_fs.conf):
activation {
volume_list = [ "@fileserver" ]
}
and run 'vgchange -ay vg2' or 'vgchange -ay @fileserver'

View File

@@ -1,33 +1,48 @@
../daemons/clvmd/clvm.h
../lib/activate/activate.h
../lib/activate/targets.h
../lib/cache/lvmcache.h
../lib/commands/errors.h
../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
../lib/device/dev-cache.h
../lib/device/device.h
../lib/display/display.h
../lib/filters/filter-composite.h
../lib/filters/filter-md.h
../lib/filters/filter-persistent.h
../lib/filters/filter-regex.h
../lib/filters/filter-sysfs.h
../lib/filters/filter.h
../lib/format1/format1.h
../lib/format1/lvm1_label.h
../lib/format_pool/format_pool.h
../lib/format_text/archiver.h
../lib/format_text/format-text.h
../lib/format_text/text_export.h
../lib/format_text/text_import.h
../lib/label/label.h
../lib/label/uuid-map.h
../lib/locking/locking.h
../lib/log/log.h
../lib/metadata/lv_alloc.h
../lib/metadata/metadata.h
../lib/mm/dbg_malloc.h
../lib/mm/pool.h
../lib/metadata/pv_alloc.h
../lib/metadata/segtype.h
../lib/mm/memlock.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/sharedlib.h
../lib/regex/matcher.h
../lib/report/report.h
../lib/uuid/uuid.h
../lib/vgcache/vgcache.h
../po/pogen.h
../tools/version.h

View File

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

View File

@@ -1,44 +1,66 @@
#
# Copyright (C) 2001 Sistina Software (UK) Limited
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
#
# This file is released under the GPL.
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SOURCES=\
ifeq ("@LVM1@", "shared")
SUBDIRS = format1
endif
ifeq ("@POOL@", "shared")
SUBDIRS += format_pool
endif
ifeq ("@SNAPSHOTS@", "shared")
SUBDIRS += snapshot
endif
ifeq ("@MIRRORS@", "shared")
SUBDIRS += mirror
endif
SOURCES =\
activate/activate.c \
activate/dev_manager.c \
activate/fs.c \
cache/lvmcache.c \
commands/toolcontext.c \
config/config.c \
datastruct/bitset.c \
datastruct/btree.c \
datastruct/hash.c \
datastruct/str_list.c \
device/dev-cache.c \
device/dev-io.c \
device/dev-md.c \
device/device.c \
display/display.c \
error/errseg.c \
filters/filter-composite.c \
filters/filter-persistent.c \
filters/filter-regex.c \
filters/filter-sysfs.c \
filters/filter-md.c \
filters/filter.c \
format1/disk-rep.c \
format1/format1.c \
format1/import-export.c \
format1/import-extents.c \
format1/layout.c \
format1/lvm1_label.c \
format1/vg_number.c \
format_text/archive.c \
format_text/archiver.c \
format_text/export.c \
format_text/flags.c \
format_text/format-text.c \
format_text/import.c \
format_text/import_vsn1.c \
format_text/tags.c \
format_text/text_label.c \
label/label.c \
label/uuid-map.c \
locking/external_locking.c \
locking/file_locking.c \
locking/locking.c \
locking/no_locking.c \
@@ -46,23 +68,78 @@ SOURCES=\
metadata/lv_manip.c \
metadata/merge.c \
metadata/metadata.c \
metadata/mirror.c \
metadata/pv_manip.c \
metadata/pv_map.c \
metadata/segtype.c \
metadata/snapshot_manip.c \
misc/crc.c \
misc/lvm-exec.c \
misc/lvm-file.c \
mm/dbg_malloc.c \
mm/pool.c \
misc/lvm-string.c \
mm/memlock.c \
regex/matcher.c \
regex/parse_rx.c \
regex/ttree.c \
report/report.c \
striped/striped.c \
uuid/uuid.c \
vgcache/vgcache.c
zero/zero.c
TARGETS=liblvm.a
ifeq ("@LVM1@", "internal")
SOURCES +=\
format1/disk-rep.c \
format1/format1.c \
format1/import-export.c \
format1/import-extents.c \
format1/layout.c \
format1/lvm1-label.c \
format1/vg_number.c
endif
include ../make.tmpl
ifeq ("@POOL@", "internal")
SOURCES +=\
format_pool/disk_rep.c \
format_pool/format_pool.c \
format_pool/import_export.c \
format_pool/pool_label.c
endif
liblvm.a: $(OBJECTS)
$(RM) $@
$(AR) r $@ $(OBJECTS)
$(RANLIB) $@
ifeq ("@CLUSTER@", "internal")
SOURCES += locking/cluster_locking.c
endif
ifeq ("@CLUSTER@", "shared")
SUBDIRS += locking
endif
ifeq ("@SNAPSHOTS@", "internal")
SOURCES += snapshot/snapshot.c
endif
ifeq ("@MIRRORS@", "internal")
SOURCES += mirror/mirrored.c
endif
ifeq ("@DEVMAPPER@", "yes")
SOURCES +=\
activate/dev_manager.c \
activate/fs.c
endif
ifeq ("@HAVE_LIBDL@", "yes")
SOURCES +=\
locking/external_locking.c \
misc/sharedlib.c
endif
ifeq ("@DMEVENTD@", "yes")
CLDFLAGS += -ldevmapper-event
endif
LIB_STATIC = liblvm.a
$(SUBDIRS): $(LIB_STATIC)
include $(top_srcdir)/make.tmpl

File diff suppressed because it is too large Load Diff

View File

@@ -1,39 +1,78 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef LVM_ACTIVATE_H
#define LVM_ACTIVATE_H
#include <libdevmapper.h>
#include "metadata.h"
struct lvinfo {
int exists;
int suspended;
unsigned int open_count;
int major;
int minor;
int read_only;
int live_table;
int inactive_table;
};
void set_activation(int activation);
int activation(void);
int driver_version(char *version, size_t size);
int library_version(char *version, size_t size);
int lvm1_present(struct cmd_context *cmd);
int target_present(const char *target_name, int use_modprobe);
int target_version(const char *target_name, uint32_t *maj,
uint32_t *min, uint32_t *patchlevel);
void activation_exit(void);
int lv_suspend(struct cmd_context *cmd, const char *lvid_s);
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s);
int lv_resume(struct cmd_context *cmd, const char *lvid_s);
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s);
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int 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);
/*
* Returns 1 if info structure has been populated, else 0.
*/
int lv_info(struct logical_volume *lv, struct dm_info *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);
/*
* Returns 1 if activate_lv has been set: 1 = activate; 0 = don't.
*/
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv);
/*
* Returns 1 if percent has been set, else 0.
*/
int lv_snapshot_percentage(struct logical_volume *lv, float *percent);
/*
* These should eventually use config file
* to determine whether or not to activate
*/
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s);
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s);
int lv_activate(struct cmd_context *cmd, const char *lvid_s);
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s);
/*
* FIXME:
* I don't like the *lvs_in_vg* function names.
*/
int lv_snapshot_percent(struct logical_volume *lv, float *percent);
int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, int wait, float *percent,
uint32_t *event_nr);
/*
* Return number of LVs in the VG that are active.
@@ -41,6 +80,10 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s);
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

View File

@@ -1,23 +1,35 @@
/*
* Copyright (C) 2002 Sistina Software (UK) Limited.
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_DEV_MANAGER_H
#define _LVM_DEV_MANAGER_H
#include "metadata.h"
#include <libdevmapper.h>
struct logical_volume;
struct volume_group;
struct cmd_context;
struct dev_manager;
struct dm_info;
struct device;
/*
* Constructor and destructor.
*/
struct dev_manager *dev_manager_create(const char *vg_name);
struct dev_manager *dev_manager_create(struct cmd_context *cmd,
const char *vg_name);
void dev_manager_destroy(struct dev_manager *dm);
void dev_manager_exit(void);
/*
* The device handler is responsible for creating all the layered
@@ -25,18 +37,28 @@ void dev_manager_destroy(struct dev_manager *dm);
* (eg, an origin is created before its snapshot, but is not
* unsuspended until the snapshot is also created.)
*/
int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
struct dm_info *info);
int dev_manager_get_snapshot_use(struct dev_manager *dm,
struct logical_volume *lv, float *percent);
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);
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);
/*
* 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

View File

@@ -1,31 +1,37 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "fs.h"
#include "log.h"
#include "toolcontext.h"
#include "lvm-string.h"
#include "lvm-file.h"
#include "memlock.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <libdevmapper.h>
static int _mk_dir(struct volume_group *vg)
static int _mk_dir(const char *dev_dir, const char *vg_name)
{
char vg_path[PATH_MAX];
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
vg->cmd->dev_dir, vg->name) == -1) {
dev_dir, vg_name) == -1) {
log_error("Couldn't construct name of volume "
"group directory.");
return 0;
@@ -35,7 +41,7 @@ static int _mk_dir(struct volume_group *vg)
return 1;
log_very_verbose("Creating directory %s", vg_path);
if (mkdir(vg_path, 0555)) {
if (mkdir(vg_path, 0777)) {
log_sys_error("mkdir", vg_path);
return 0;
}
@@ -43,51 +49,119 @@ static int _mk_dir(struct volume_group *vg)
return 1;
}
static int _rm_dir(struct volume_group *vg)
static int _rm_dir(const char *dev_dir, const char *vg_name)
{
char vg_path[PATH_MAX];
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
vg->cmd->dev_dir, vg->name) == -1) {
dev_dir, vg_name) == -1) {
log_error("Couldn't construct name of volume "
"group directory.");
return 0;
}
log_very_verbose("Removing directory %s", vg_path);
if (is_empty_dir(vg_path))
if (dir_exists(vg_path) && is_empty_dir(vg_path)) {
log_very_verbose("Removing directory %s", vg_path);
rmdir(vg_path);
}
return 1;
}
static int _mk_link(struct logical_volume *lv, const char *dev)
static void _rm_blks(const char *dir)
{
char lv_path[PATH_MAX], link_path[PATH_MAX];
const char *name;
char path[PATH_MAX];
struct dirent *dirent;
struct stat buf;
DIR *d;
if (!(d = opendir(dir))) {
log_sys_error("opendir", dir);
return;
}
while ((dirent = readdir(d))) {
name = dirent->d_name;
if (!strcmp(name, ".") || !strcmp(name, ".."))
continue;
if (lvm_snprintf(path, sizeof(path), "%s/%s", dir, name) == -1) {
log_error("Couldn't create path for %s", name);
continue;
}
if (!lstat(path, &buf)) {
if (!S_ISBLK(buf.st_mode))
continue;
log_very_verbose("Removing %s", path);
if (unlink(path) < 0)
log_sys_error("unlink", path);
}
}
}
static int _mk_link(const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev)
{
char lv_path[PATH_MAX], link_path[PATH_MAX], lvm1_group_path[PATH_MAX];
char vg_path[PATH_MAX];
struct stat buf;
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
lv->vg->cmd->dev_dir, lv->vg->name, lv->name) == -1) {
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
dev_dir, vg_name) == -1) {
log_error("Couldn't create path for volume group dir %s",
vg_name);
return 0;
}
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s/%s", vg_path,
lv_name) == -1) {
log_error("Couldn't create source pathname for "
"logical volume link %s", lv->name);
"logical volume link %s", lv_name);
return 0;
}
if (lvm_snprintf(link_path, sizeof(link_path), "%s/%s",
dm_dir(), dev) == -1) {
log_error("Couldn't create destination pathname for "
"logical volume link for %s", lv->name);
"logical volume link for %s", lv_name);
return 0;
}
if (lvm_snprintf(lvm1_group_path, sizeof(lvm1_group_path), "%s/group",
vg_path) == -1) {
log_error("Couldn't create pathname for LVM1 group file for %s",
vg_name);
return 0;
}
/* To reach this point, the VG must have been locked.
* As locking fails if the VG is active under LVM1, it's
* now safe to remove any LVM1 devices we find here
* (as well as any existing LVM2 symlink). */
if (!lstat(lvm1_group_path, &buf)) {
if (!S_ISCHR(buf.st_mode)) {
log_error("Non-LVM1 character device found at %s",
lvm1_group_path);
} else {
_rm_blks(vg_path);
log_very_verbose("Removing %s", lvm1_group_path);
if (unlink(lvm1_group_path) < 0)
log_sys_error("unlink", lvm1_group_path);
}
}
if (!lstat(lv_path, &buf)) {
if (!S_ISLNK(buf.st_mode)) {
if (!S_ISLNK(buf.st_mode) && !S_ISBLK(buf.st_mode)) {
log_error("Symbolic link %s not created: file exists",
link_path);
return 0;
}
log_very_verbose("Removing %s", lv_path);
if (unlink(lv_path) < 0) {
log_sys_error("unlink", lv_path);
return 0;
@@ -100,26 +174,36 @@ static int _mk_link(struct logical_volume *lv, const char *dev)
return 0;
}
#ifdef HAVE_SELINUX
if (!dm_set_selinux_context(lv_path, S_IFLNK)) {
stack;
return 0;
}
#endif
return 1;
}
static int _rm_link(struct logical_volume *lv, const char *lv_name)
static int _rm_link(const char *dev_dir, const char *vg_name,
const char *lv_name)
{
struct stat buf;
char lv_path[PATH_MAX];
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
lv->vg->cmd->dev_dir, lv->vg->name, lv_name) == -1) {
dev_dir, vg_name, lv_name) == -1) {
log_error("Couldn't determine link pathname.");
return 0;
}
log_very_verbose("Removing link %s", lv_path);
if (lstat(lv_path, &buf) || !S_ISLNK(buf.st_mode)) {
if (errno == ENOENT)
return 1;
log_error("%s not symbolic link - not removing", lv_path);
return 0;
}
log_very_verbose("Removing link %s", lv_path);
if (unlink(lv_path) < 0) {
log_sys_error("unlink", lv_path);
return 0;
@@ -128,35 +212,143 @@ static int _rm_link(struct logical_volume *lv, const char *lv_name)
return 1;
}
int fs_add_lv(struct logical_volume *lv, const char *dev)
typedef enum {
FS_ADD,
FS_DEL,
FS_RENAME
} fs_op_t;
static int _do_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev,
const char *old_lv_name)
{
if (!_mk_dir(lv->vg) || !_mk_link(lv, dev)) {
stack;
return 0;
switch (type) {
case FS_ADD:
if (!_mk_dir(dev_dir, vg_name) ||
!_mk_link(dev_dir, vg_name, lv_name, dev)) {
stack;
return 0;
}
break;
case FS_DEL:
if (!_rm_link(dev_dir, vg_name, lv_name) ||
!_rm_dir(dev_dir, vg_name)) {
stack;
return 0;
}
break;
/* FIXME Use rename() */
case FS_RENAME:
if (old_lv_name && !_rm_link(dev_dir, vg_name, old_lv_name))
stack;
if (!_mk_link(dev_dir, vg_name, lv_name, dev))
stack;
}
return 1;
}
int fs_del_lv(struct logical_volume *lv)
static LIST_INIT(_fs_ops);
struct fs_op_parms {
struct list list;
fs_op_t type;
char *dev_dir;
char *vg_name;
char *lv_name;
char *dev;
char *old_lv_name;
char names[0];
};
static void _store_str(char **pos, char **ptr, const char *str)
{
if (!_rm_link(lv, lv->name) || !_rm_dir(lv->vg)) {
stack;
strcpy(*pos, str);
*ptr = *pos;
*pos += strlen(*ptr) + 1;
}
static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev,
const char *old_lv_name)
{
struct fs_op_parms *fsp;
size_t len = strlen(dev_dir) + strlen(vg_name) + strlen(lv_name) +
strlen(dev) + strlen(old_lv_name) + 5;
char *pos;
if (!(fsp = dm_malloc(sizeof(*fsp) + len))) {
log_error("No space to stack fs operation");
return 0;
}
pos = fsp->names;
fsp->type = type;
_store_str(&pos, &fsp->dev_dir, dev_dir);
_store_str(&pos, &fsp->vg_name, vg_name);
_store_str(&pos, &fsp->lv_name, lv_name);
_store_str(&pos, &fsp->dev, dev);
_store_str(&pos, &fsp->old_lv_name, old_lv_name);
list_add(&_fs_ops, &fsp->list);
return 1;
}
/* FIXME Use rename() */
static void _pop_fs_ops(void)
{
struct list *fsph, *fspht;
struct fs_op_parms *fsp;
list_iterate_safe(fsph, fspht, &_fs_ops) {
fsp = list_item(fsph, struct fs_op_parms);
_do_fs_op(fsp->type, fsp->dev_dir, fsp->vg_name, fsp->lv_name,
fsp->dev, fsp->old_lv_name);
list_del(&fsp->list);
dm_free(fsp);
}
}
static int _fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev, const char *old_lv_name)
{
if (memlock()) {
if (!_stack_fs_op(type, dev_dir, vg_name, lv_name, dev,
old_lv_name)) {
stack;
return 0;
}
return 1;
}
return _do_fs_op(type, dev_dir, vg_name, lv_name, dev, old_lv_name);
}
int fs_add_lv(const struct logical_volume *lv, const char *dev)
{
return _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, "");
}
int fs_del_lv(const struct logical_volume *lv)
{
return _fs_op(FS_DEL, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
"", "");
}
int fs_rename_lv(struct logical_volume *lv,
const char *dev, const char *old_name)
{
if (old_name && !_rm_link(lv, old_name))
stack;
if (!_mk_link(lv, dev))
stack;
return 1;
return _fs_op(FS_RENAME, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, old_name);
}
void fs_unlock(void)
{
if (!memlock()) {
dm_lib_release();
_pop_fs_ops();
}
}

View File

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

34
lib/activate/targets.h Normal file
View File

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

620
lib/cache/lvmcache.c vendored Normal file
View File

@@ -0,0 +1,620 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "lib.h"
#include "lvmcache.h"
#include "toolcontext.h"
#include "dev-cache.h"
#include "metadata.h"
#include "filter.h"
#include "memlock.h"
#include "str_list.h"
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;
int lvmcache_init(void)
{
list_init(&_vginfos);
if (!(_vgname_hash = dm_hash_create(128)))
return 0;
if (!(_vgid_hash = dm_hash_create(128)))
return 0;
if (!(_pvid_hash = dm_hash_create(128)))
return 0;
if (!(_lock_hash = dm_hash_create(128)))
return 0;
return 1;
}
void lvmcache_lock_vgname(const char *vgname, int read_only)
{
if (!_lock_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
return;
}
if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
log_error("Cache locking failure for %s", vgname);
_vgs_locked++;
}
int vgname_is_locked(const char *vgname)
{
if (!_lock_hash)
return 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 */
dm_hash_remove(_lock_hash, vgname);
/* FIXME Do this per-VG */
if (!--_vgs_locked)
dev_close_all();
}
int vgs_locked(void)
{
return _vgs_locked;
}
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname)
{
struct lvmcache_vginfo *vginfo;
if (!_vgname_hash)
return NULL;
if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname)))
return NULL;
return vginfo;
}
const struct format_type *fmt_from_vgname(const char *vgname)
{
struct lvmcache_vginfo *vginfo;
struct lvmcache_info *info;
struct label *label;
struct list *devh, *tmp;
struct list devs;
struct device_list *devl;
if (!(vginfo = vginfo_from_vgname(vgname)))
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 = dm_malloc(sizeof(*devl));
devl->dev = info->dev;
list_add(&devs, &devl->list);
}
list_iterate_safe(devh, tmp, &devs) {
devl = list_item(devh, struct device_list);
label_read(devl->dev, &label);
list_del(&devl->list);
dm_free(devl);
}
return vginfo->fmt;
}
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid)
{
struct lvmcache_vginfo *vginfo;
char id[ID_LEN + 1];
if (!_vgid_hash || !vgid)
return NULL;
/* vgid not necessarily NULL-terminated */
strncpy(&id[0], vgid, ID_LEN);
id[ID_LEN] = '\0';
if (!(vginfo = dm_hash_lookup(_vgid_hash, id)))
return NULL;
return vginfo;
}
struct lvmcache_info *info_from_pvid(const char *pvid)
{
struct lvmcache_info *info;
char id[ID_LEN + 1];
if (!_pvid_hash || !pvid)
return NULL;
strncpy(&id[0], pvid, ID_LEN);
id[ID_LEN] = '\0';
if (!(info = dm_hash_lookup(_pvid_hash, id)))
return NULL;
return info;
}
static void _rescan_entry(struct lvmcache_info *info)
{
struct label *label;
if (info->status & CACHE_INVALID)
label_read(info->dev, &label);
}
static int _scan_invalid(void)
{
dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _rescan_entry);
return 1;
}
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
{
struct label *label;
struct dev_iter *iter;
struct device *dev;
struct format_type *fmt;
static int _scanning_in_progress = 0;
int r = 0;
/* Avoid recursion when a PVID can't be found! */
if (_scanning_in_progress)
return 0;
_scanning_in_progress = 1;
if (!_vgname_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
goto out;
}
if (_has_scanned && !full_scan) {
r = _scan_invalid();
goto out;
}
if (!(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1: 0))) {
log_error("dev_iter creation failed");
goto out;
}
while ((dev = dev_iter_get(iter)))
label_read(dev, &label);
dev_iter_destroy(iter);
_has_scanned = 1;
/* Perform any format-specific scanning e.g. text files */
list_iterate_items(fmt, &cmd->formats) {
if (fmt->ops->scan && !fmt->ops->scan(fmt))
goto out;
}
r = 1;
out:
_scanning_in_progress = 0;
return r;
}
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
{
struct list *vgnames;
struct lvmcache_vginfo *vgi;
lvmcache_label_scan(cmd, full_scan);
if (!(vgnames = str_list_create(cmd->mem))) {
log_error("vgnames list allocation failed");
return NULL;
}
list_iterate_items(vgi, &_vginfos) {
if (!str_list_add(cmd->mem, vgnames,
dm_pool_strdup(cmd->mem, vgi->vgname))) {
log_error("strlist allocation failed");
return NULL;
}
}
return vgnames;
}
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
{
struct label *label;
struct lvmcache_info *info;
/* Already cached ? */
if ((info = info_from_pvid((char *) pvid))) {
if (label_read(info->dev, &label)) {
info = (struct lvmcache_info *) label->info;
if (id_equal(pvid, (struct id *) &info->dev->pvid))
return info->dev;
}
}
lvmcache_label_scan(cmd, 0);
/* Try again */
if ((info = info_from_pvid((char *) pvid))) {
if (label_read(info->dev, &label)) {
info = (struct lvmcache_info *) label->info;
if (id_equal(pvid, (struct id *) &info->dev->pvid))
return info->dev;
}
}
if (memlock())
return NULL;
lvmcache_label_scan(cmd, 2);
/* Try again */
if ((info = info_from_pvid((char *) pvid))) {
if (label_read(info->dev, &label)) {
info = (struct lvmcache_info *) label->info;
if (id_equal(pvid, (struct id *) &info->dev->pvid))
return info->dev;
}
}
return NULL;
}
static void _drop_vginfo(struct lvmcache_info *info)
{
if (!list_empty(&info->list)) {
list_del(&info->list);
list_init(&info->list);
}
if (info->vginfo && list_empty(&info->vginfo->infos)) {
dm_hash_remove(_vgname_hash, info->vginfo->vgname);
if (info->vginfo->vgname)
dm_free(info->vginfo->vgname);
if (*info->vginfo->vgid)
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
list_del(&info->vginfo->list);
dm_free(info->vginfo);
}
info->vginfo = NULL;
}
/* Unused
void lvmcache_del(struct lvmcache_info *info)
{
if (info->dev->pvid[0] && _pvid_hash)
dm_hash_remove(_pvid_hash, info->dev->pvid);
_drop_vginfo(info);
info->label->labeller->ops->destroy_label(info->label->labeller,
info->label);
dm_free(info);
return;
} */
static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
{
if (!strcmp(info->dev->pvid, pvid))
return 1;
if (*info->dev->pvid) {
dm_hash_remove(_pvid_hash, info->dev->pvid);
}
strncpy(info->dev->pvid, pvid, sizeof(info->dev->pvid));
if (!dm_hash_insert(_pvid_hash, pvid, info)) {
log_error("_lvmcache_update: pvid insertion failed: %s", pvid);
return 0;
}
return 1;
}
static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
{
if (!vgid || !info->vginfo || !strncmp(info->vginfo->vgid, vgid,
sizeof(info->vginfo->vgid)))
return 1;
if (info->vginfo && *info->vginfo->vgid)
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
if (!vgid)
return 1;
strncpy(info->vginfo->vgid, vgid, sizeof(info->vginfo->vgid));
info->vginfo->vgid[sizeof(info->vginfo->vgid) - 1] = '\0';
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;
}
return 1;
}
int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
{
struct lvmcache_vginfo *vginfo;
/* If vgname is NULL and we don't already have a vgname,
* assume ORPHAN - we want every entry to have a vginfo
* attached for scanning reasons.
*/
if (!vgname && !info->vginfo)
vgname = ORPHAN;
if (!vgname || (info->vginfo && !strcmp(info->vginfo->vgname, vgname)))
return 1;
/* Remove existing vginfo entry */
_drop_vginfo(info);
/* Get existing vginfo or create new one */
if (!(vginfo = vginfo_from_vgname(vgname))) {
if (!(vginfo = dm_malloc(sizeof(*vginfo)))) {
log_error("lvmcache_update_vgname: list alloc failed");
return 0;
}
memset(vginfo, 0, sizeof(*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 (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo)) {
log_error("cache_update: vg hash insertion failed: %s",
vginfo->vgname);
dm_free(vginfo->vgname);
dm_free(vginfo);
return 0;
}
/* Ensure orphans appear last on list_iterate */
if (!*vgname)
list_add(&_vginfos, &vginfo->list);
else
list_add_h(&_vginfos, &vginfo->list);
}
info->vginfo = vginfo;
list_add(&vginfo->infos, &info->list);
/* 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);
return 1;
}
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;
}
}
}
return 1;
}
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid)
{
struct label *label;
struct lvmcache_info *existing, *info;
char pvid_s[ID_LEN + 1];
if (!_vgname_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
return NULL;
}
strncpy(pvid_s, pvid, sizeof(pvid_s));
pvid_s[sizeof(pvid_s) - 1] = '\0';
if (!(existing = info_from_pvid(pvid_s)) &&
!(existing = info_from_pvid(dev->pvid))) {
if (!(label = label_create(labeller))) {
stack;
return NULL;
}
if (!(info = dm_malloc(sizeof(*info)))) {
log_error("lvmcache_info allocation failed");
label_destroy(label);
return NULL;
}
memset(info, 0, sizeof(*info));
label->info = info;
info->label = label;
list_init(&info->list);
info->dev = dev;
} else {
if (existing->dev != dev) {
/* Is the existing entry a duplicate pvid e.g. md ? */
if (MAJOR(existing->dev->dev) == md_major() &&
MAJOR(dev->dev) != md_major()) {
log_very_verbose("Ignoring duplicate PV %s on "
"%s - using md %s",
pvid, dev_name(dev),
dev_name(existing->dev));
return NULL;
} else if (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) {
label_destroy(info->label);
if (!(info->label = label_create(labeller))) {
/* FIXME leaves info without label! */
stack;
return NULL;
}
info->label->info = info;
}
label = info->label;
}
info->fmt = (const struct format_type *) labeller->private;
info->status |= CACHE_INVALID;
if (!_lvmcache_update_pvid(info, pvid_s)) {
if (!existing) {
dm_free(info);
label_destroy(label);
}
return NULL;
}
if (!lvmcache_update_vgname(info, vgname)) {
if (!existing) {
dm_hash_remove(_pvid_hash, pvid_s);
strcpy(info->dev->pvid, "");
dm_free(info);
label_destroy(label);
}
return NULL;
}
if (!_lvmcache_update_vgid(info, vgid))
/* Non-critical */
stack;
return info;
}
static void _lvmcache_destroy_entry(struct lvmcache_info *info)
{
if (!list_empty(&info->list))
list_del(&info->list);
strcpy(info->dev->pvid, "");
label_destroy(info->label);
dm_free(info);
}
static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
{
if (vginfo->vgname)
dm_free(vginfo->vgname);
dm_free(vginfo);
}
static void _lvmcache_destroy_lockname(int present)
{
/* Nothing to do */
}
void lvmcache_destroy(void)
{
log_verbose("Wiping internal VG cache");
_has_scanned = 0;
if (_vgid_hash) {
dm_hash_destroy(_vgid_hash);
_vgid_hash = NULL;
}
if (_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) {
dm_hash_iter(_vgname_hash,
(dm_hash_iterate_fn) _lvmcache_destroy_vgnamelist);
dm_hash_destroy(_vgname_hash);
_vgname_hash = NULL;
}
if (_lock_hash) {
dm_hash_iter(_lock_hash, (dm_hash_iterate_fn) _lvmcache_destroy_lockname);
dm_hash_destroy(_lock_hash);
_lock_hash = NULL;
}
list_init(&_vginfos);
}

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

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _LVM_CACHE_H
#define _LVM_CACHE_H
#include "dev-cache.h"
#include "uuid.h"
#include "label.h"
#define ORPHAN ""
#define CACHE_INVALID 0x00000001
#define CACHE_LOCKED 0x00000002
/* LVM specific per-volume info */
/* Eventual replacement for struct physical_volume perhaps? */
struct cmd_context;
struct format_type;
struct volume_group;
struct lvmcache_vginfo {
struct list list; /* Join these vginfos together */
struct list infos; /* List head for lvmcache_infos */
const struct format_type *fmt;
char *vgname; /* "" == orphan */
char vgid[ID_LEN + 1];
char _padding[7];
};
struct lvmcache_info {
struct list list; /* Join VG members together */
struct list mdas; /* list head for metadata areas */
struct list das; /* list head for data areas */
struct lvmcache_vginfo *vginfo; /* NULL == unknown */
struct label *label;
const struct format_type *fmt;
struct device *dev;
uint64_t device_size; /* Bytes */
uint32_t status;
};
int lvmcache_init(void);
void lvmcache_destroy(void);
/* Set full_scan to 1 to reread every filtered device label or
* 2 to rescan /dev for new devices */
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan);
/* Add/delete a device */
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid);
void lvmcache_del(struct lvmcache_info *info);
/* Update things */
int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname);
int lvmcache_update_vg(struct volume_group *vg);
void lvmcache_lock_vgname(const char *vgname, int read_only);
void lvmcache_unlock_vgname(const char *vgname);
/* Queries */
const struct format_type *fmt_from_vgname(const char *vgname);
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname);
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);
struct lvmcache_info *info_from_pvid(const char *pvid);
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
int vgs_locked(void);
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);
#endif

View File

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

1101
lib/commands/toolcontext.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +1,94 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_TOOLCONTEXT_H
#define _LVM_TOOLCONTEXT_H
#include "dev-cache.h"
#include "config.h"
#include "pool.h"
#include "metadata.h"
/* command-instance-related variables needed by library */
struct cmd_context {
/* format handler allocates all objects from here */
struct pool *mem;
#include <stdio.h>
#include <limits.h>
struct format_type *fmt; /* Current format to use by default */
/* FIXME Move into dynamic list */
struct format_type *fmt1; /* Format1 */
struct format_type *fmtt; /* Format_text */
char *cmd_line;
char *dev_dir;
struct dev_filter *filter;
struct config_file *cf;
struct command *command;
struct uuid_map *um;
struct arg *args;
/*
* Config options that can be changed while commands are processed
*/
struct config_info {
int debug;
int verbose;
int test;
int syslog;
int activation;
int suffix;
int archive; /* should we archive ? */
int backup; /* should we backup ? */
const char *msg_prefix;
struct format_type *fmt;
uint64_t unit_factor;
int cmd_name; /* Show command name? */
mode_t umask;
char unit_type;
char _padding[1];
};
struct config_tree;
struct archive_params;
struct backup_params;
/* FIXME Split into tool & library contexts */
/* command-instance-related variables needed by library */
struct cmd_context {
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 */
struct list formats; /* Available formats */
struct list segtypes; /* Available segment types */
const char *hostname;
const char *kernel_vsn;
char *cmd_line;
struct command *command;
struct arg *args;
char **argv;
struct dev_filter *filter;
int dump_filter; /* Dump filter when exiting? */
struct list config_files;
int config_valid;
struct config_tree *cft;
struct config_info default_settings;
struct config_info current_settings;
struct archive_params *archive_params;
struct backup_params *backup_params;
/* List of defined tags */
struct list tags;
int hosttags;
char sys_dir[PATH_MAX];
char dev_dir[PATH_MAX];
char proc_dir[PATH_MAX];
};
struct cmd_context *create_toolcontext(struct arg *the_args);
void destroy_toolcontext(struct cmd_context *cmd);
int refresh_toolcontext(struct cmd_context *cmd);
int config_files_changed(struct cmd_context *cmd);
#endif

View File

@@ -1,21 +1,30 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <sys/types.h>
#include "lib.h"
#include "config.h"
#include "crc.h"
#include "device.h"
#include "str_list.h"
#include "toolcontext.h"
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include "config.h"
#include "pool.h"
#include "log.h"
enum {
TOK_INT,
@@ -32,23 +41,26 @@ enum {
};
struct parser {
const char *fb, *fe; /* file limits */
char *fb, *fe; /* file limits */
int t; /* token limits and type */
const char *tb, *te;
char *tb, *te;
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_file cf;
struct pool *mem;
struct config_tree cft;
struct dm_pool *mem;
time_t timestamp;
char *filename;
int exists;
};
static void _get_token(struct parser *p);
static void _get_token(struct parser *p, int tok_prev);
static void _eat_space(struct parser *p);
static struct config_node *_file(struct parser *p);
static struct config_node *_section(struct parser *p);
@@ -59,6 +71,8 @@ static struct config_value *_create_value(struct parser *p);
static struct config_node *_create_node(struct parser *p);
static char *_dup_tok(struct parser *p);
static const int sep = '/';
#define MAX_INDENT 32
#define match(t) do {\
@@ -81,89 +95,213 @@ static int _tok_match(const char *str, const char *b, const char *e)
/*
* public interface
*/
struct config_file *create_config_file(void)
struct config_tree *create_config_tree(const char *filename)
{
struct cs *c;
struct pool *mem = pool_create(10 * 1024);
struct dm_pool *mem = dm_pool_create("config", 10 * 1024);
if (!mem) {
stack;
return 0;
}
if (!(c = pool_alloc(mem, sizeof(*c)))) {
if (!(c = dm_pool_zalloc(mem, sizeof(*c)))) {
stack;
pool_destroy(mem);
dm_pool_destroy(mem);
return 0;
}
c->mem = mem;
c->cf.root = (struct config_node *) NULL;
return &c->cf;
c->cft.root = (struct config_node *) NULL;
c->timestamp = 0;
c->exists = 0;
if (filename)
c->filename = dm_pool_strdup(c->mem, filename);
return &c->cft;
}
void destroy_config_file(struct config_file *cf)
void destroy_config_tree(struct config_tree *cft)
{
pool_destroy(((struct cs *) cf)->mem);
dm_pool_destroy(((struct cs *) cft)->mem);
}
int read_config(struct config_file *cf, const char *file)
int read_config_fd(struct config_tree *cft, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum)
{
struct cs *c = (struct cs *) cf;
struct cs *c = (struct cs *) cft;
struct parser *p;
struct stat info;
int r = 1, fd;
int r = 0;
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;
}
p->mem = c->mem;
/* memory map the file */
if (stat(file, &info) || S_ISDIR(info.st_mode)) {
log_sys_error("stat", file);
return 0;
/* Only use mmap with regular files */
if (!(dev->flags & DEV_REGULAR) || size2)
use_mmap = 0;
if (use_mmap) {
mmap_offset = offset % getpagesize();
/* memory map the file */
p->fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
MAP_PRIVATE, dev_fd(dev), offset - mmap_offset);
if (p->fb == (caddr_t) (-1)) {
log_sys_error("mmap", dev_name(dev));
goto out;
}
p->fb = p->fb + mmap_offset;
} else {
if (!(p->fb = dm_malloc(size + size2))) {
stack;
return 0;
}
if (!dev_read(dev, (uint64_t) offset, size, p->fb)) {
log_error("Read from %s failed", dev_name(dev));
goto out;
}
if (size2) {
if (!dev_read(dev, (uint64_t) offset2, size2,
p->fb + size)) {
log_error("Circular read from %s failed",
dev_name(dev));
goto out;
}
}
}
if (info.st_size == 0) {
log_verbose("%s is empty", file);
return 1;
if (checksum_fn && checksum !=
(checksum_fn(checksum_fn(INITIAL_CRC, p->fb, size),
p->fb + size, size2))) {
log_error("%s: Checksum error", dev_name(dev));
goto out;
}
if ((fd = open(file, O_RDONLY)) < 0) {
log_sys_error("open", file);
return 0;
}
p->fb = mmap((caddr_t) 0, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (p->fb == (caddr_t) (-1)) {
log_sys_error("mmap", file);
close(fd);
return 0;
}
p->fe = p->fb + info.st_size;
p->fe = p->fb + size + size2;
/* parse */
p->tb = p->te = p->fb;
p->line = 1;
_get_token(p);
if (!(cf->root = _file(p))) {
_get_token(p, TOK_SECTION_E);
if (!(cft->root = _file(p))) {
stack;
r = 0;
goto out;
}
/* unmap the file */
if (munmap((char *) p->fb, info.st_size)) {
log_sys_error("munmap", file);
r = 0;
r = 1;
out:
if (!use_mmap)
dm_free(p->fb);
else {
/* unmap the file */
if (munmap((char *) (p->fb - mmap_offset), size + mmap_offset)) {
log_sys_error("munmap", dev_name(dev));
r = 0;
}
}
close(fd);
return r;
}
static void _write_value(FILE * fp, struct config_value *v)
int read_config_file(struct config_tree *cft)
{
struct cs *c = (struct cs *) cft;
struct stat info;
struct device *dev;
int r = 1;
if (stat(c->filename, &info)) {
log_sys_error("stat", c->filename);
c->exists = 0;
return 0;
}
if (!S_ISREG(info.st_mode)) {
log_error("%s is not a regular file", c->filename);
c->exists = 0;
return 0;
}
c->exists = 1;
if (info.st_size == 0) {
log_verbose("%s is empty", c->filename);
return 1;
}
if (!(dev = dev_create_file(c->filename, NULL, NULL, 1))) {
stack;
return 0;
}
if (!dev_open_flags(dev, O_RDONLY, 0, 0)) {
stack;
return 0;
}
r = read_config_fd(cft, dev, 0, (size_t) info.st_size, 0, 0,
(checksum_fn_t) NULL, 0);
dev_close(dev);
c->timestamp = info.st_mtime;
return r;
}
time_t config_file_timestamp(struct config_tree *cft)
{
struct cs *c = (struct cs *) cft;
return c->timestamp;
}
/*
* Return 1 if config files ought to be reloaded
*/
int config_file_changed(struct config_tree *cft)
{
struct cs *c = (struct cs *) cft;
struct stat info;
if (!c->filename)
return 0;
if (stat(c->filename, &info) == -1) {
/* Ignore a deleted config file: still use original data */
if (errno == ENOENT) {
if (!c->exists)
return 0;
log_very_verbose("Config file %s has disappeared!",
c->filename);
goto reload;
}
log_sys_error("stat", c->filename);
log_error("Failed to reload configuration files");
return 0;
}
if (!S_ISREG(info.st_mode)) {
log_error("Configuration file %s is not a regular file",
c->filename);
goto reload;
}
/* Unchanged? */
if (c->timestamp == info.st_mtime)
return 0;
reload:
log_verbose("Detected config file change to %s", c->filename);
return 1;
}
static void _write_value(FILE *fp, struct config_value *v)
{
switch (v->type) {
case CFG_STRING:
@@ -177,10 +315,18 @@ static void _write_value(FILE * fp, struct config_value *v)
case CFG_INT:
fprintf(fp, "%d", v->v.i);
break;
case CFG_EMPTY_ARRAY:
fprintf(fp, "[]");
break;
default:
log_error("_write_value: Unknown value type: %d", v->type);
}
}
static int _write_config(struct config_node *n, FILE * fp, int level)
static int _write_config(struct config_node *n, FILE *fp, int level)
{
char space[MAX_INDENT + 1];
int l = (level < MAX_INDENT) ? level : MAX_INDENT;
@@ -190,7 +336,7 @@ static int _write_config(struct config_node *n, FILE * fp, int level)
return 1;
for (i = 0; i < l; i++)
space[i] = ' ';
space[i] = '\t';
space[i] = '\0';
while (n) {
@@ -223,20 +369,28 @@ static int _write_config(struct config_node *n, FILE * fp, int level)
return 1;
}
int write_config(struct config_file *cf, const char *file)
int write_config_file(struct config_tree *cft, const char *file)
{
int r = 1;
FILE *fp = fopen(file, "w");
if (!fp) {
FILE *fp;
if (!file) {
fp = stdout;
file = "stdout";
} else if (!(fp = fopen(file, "w"))) {
log_sys_error("open", file);
return 0;
}
if (!_write_config(cf->root, fp, 0)) {
stack;
log_verbose("Dumping configuration to %s", file);
if (!_write_config(cft->root, fp, 0)) {
log_error("Failure while writing configuration");
r = 0;
}
fclose(fp);
if (fp != stdout)
fclose(fp);
return r;
}
@@ -306,7 +460,7 @@ static struct config_node *_section(struct parser *p)
static struct config_value *_value(struct parser *p)
{
/* '[' TYPE* ']' | TYPE */
struct config_value *h = 0, *l, *ll = 0;
struct config_value *h = NULL, *l, *ll = NULL;
if (p->t == TOK_ARRAY_B) {
match(TOK_ARRAY_B);
while (p->t != TOK_ARRAY_E) {
@@ -325,6 +479,16 @@ static struct config_value *_value(struct parser *p)
match(TOK_COMMA);
}
match(TOK_ARRAY_E);
/*
* Special case for an empty array.
*/
if (!h) {
if (!(h = _create_value(p)))
return NULL;
h->type = CFG_EMPTY_ARRAY;
}
} else
h = _type(p);
@@ -333,19 +497,22 @@ static struct config_value *_value(struct parser *p)
static struct config_value *_type(struct parser *p)
{
/* [0-9]+ | [0-9]*\.[0-9]* | ".*" */
/* [+-]{0,1}[0-9]+ | [0-9]*\.[0-9]* | ".*" */
struct config_value *v = _create_value(p);
if (!v)
return NULL;
switch (p->t) {
case TOK_INT:
v->type = CFG_INT;
v->v.i = strtol(p->tb, 0, 0); /* FIXME: check error */
v->v.i = strtol(p->tb, NULL, 0); /* FIXME: check error */
match(TOK_INT);
break;
case TOK_FLOAT:
v->type = CFG_FLOAT;
v->v.r = strtod(p->tb, 0); /* FIXME: check error */
v->v.r = strtod(p->tb, NULL); /* FIXME: check error */
match(TOK_FLOAT);
break;
@@ -373,22 +540,29 @@ static int _match_aux(struct parser *p, int t)
if (p->t != t)
return 0;
_get_token(p);
_get_token(p, t);
return 1;
}
/*
* tokeniser
*/
static void _get_token(struct parser *p)
static void _get_token(struct parser *p, int tok_prev)
{
int values_allowed = 0;
p->tb = p->te;
_eat_space(p);
if (p->tb == p->fe) {
if (p->tb == p->fe || !*p->tb) {
p->t = TOK_EOF;
return;
}
/* Should next token be interpreted as value instead of identifier? */
if (tok_prev == TOK_EQ || tok_prev == TOK_ARRAY_B ||
tok_prev == TOK_COMMA)
values_allowed = 1;
p->t = TOK_INT; /* fudge so the fall through for
floats works */
switch (*p->te) {
@@ -425,13 +599,24 @@ static void _get_token(struct parser *p)
case '"':
p->t = TOK_STRING;
p->te++;
while ((p->te != p->fe) && (*p->te != '"')) {
if ((*p->te == '\\') && (p->te + 1 != p->fe))
while ((p->te != p->fe) && (*p->te) && (*p->te != '"')) {
if ((*p->te == '\\') && (p->te + 1 != p->fe) &&
*(p->te + 1))
p->te++;
p->te++;
}
if (p->te != p->fe)
if ((p->te != p->fe) && (*p->te))
p->te++;
break;
case '\'':
p->t = TOK_STRING;
p->te++;
while ((p->te != p->fe) && (*p->te) && (*p->te != '\''))
p->te++;
if ((p->te != p->fe) && (*p->te))
p->te++;
break;
@@ -447,22 +632,27 @@ static void _get_token(struct parser *p)
case '7':
case '8':
case '9':
p->te++;
while (p->te != p->fe) {
if (*p->te == '.') {
if (p->t == TOK_FLOAT)
break;
p->t = TOK_FLOAT;
} else if (!isdigit((int) *p->te))
break;
case '+':
case '-':
if (values_allowed) {
p->te++;
while ((p->te != p->fe) && (*p->te)) {
if (*p->te == '.') {
if (p->t == TOK_FLOAT)
break;
p->t = TOK_FLOAT;
} else if (!isdigit((int) *p->te))
break;
p->te++;
}
break;
}
break;
default:
p->t = TOK_IDENTIFIER;
while ((p->te != p->fe) && !isspace(*p->te) &&
(*p->te != '#') && (*p->te != '='))
while ((p->te != p->fe) && (*p->te) && !isspace(*p->te) &&
(*p->te != '#') && (*p->te != '=') && (*p->te != '{') &&
(*p->te != '}'))
p->te++;
break;
}
@@ -470,15 +660,15 @@ static void _get_token(struct parser *p)
static void _eat_space(struct parser *p)
{
while (p->tb != p->fe) {
while ((p->tb != p->fe) && (*p->tb)) {
if (*p->te == '#') {
while ((p->te != p->fe) && (*p->te != '\n'))
while ((p->te != p->fe) && (*p->te) && (*p->te != '\n'))
p->te++;
p->line++;
}
else if (isspace(*p->te)) {
while ((p->te != p->fe) && isspace(*p->te)) {
while ((p->te != p->fe) && (*p->te) && isspace(*p->te)) {
if (*p->te == '\n')
p->line++;
p->te++;
@@ -497,22 +687,22 @@ 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;
}
static char *_dup_tok(struct parser *p)
{
int len = p->te - p->tb;
char *str = pool_alloc(p->mem, len + 1);
size_t len = p->te - p->tb;
char *str = dm_pool_alloc(p->mem, len + 1);
if (!str) {
stack;
return 0;
@@ -525,8 +715,8 @@ static char *_dup_tok(struct parser *p)
/*
* utility functions
*/
struct config_node *find_config_node(struct config_node *cn,
const char *path, char sep)
struct config_node *find_config_node(const struct config_node *cn,
const char *path)
{
const char *e;
@@ -554,13 +744,13 @@ struct config_node *find_config_node(struct config_node *cn,
path = e;
}
return cn;
return (struct config_node *) cn;
}
const char *find_config_str(struct config_node *cn,
const char *path, char sep, const char *fail)
const char *find_config_str(const struct config_node *cn,
const char *path, const char *fail)
{
struct config_node *n = find_config_node(cn, path, sep);
const struct config_node *n = find_config_node(cn, path);
if (n && n->v->type == CFG_STRING) {
if (*n->v->v.str)
@@ -574,10 +764,9 @@ const char *find_config_str(struct config_node *cn,
return fail;
}
int find_config_int(struct config_node *cn, const char *path,
char sep, int fail)
int find_config_int(const struct config_node *cn, const char *path, int fail)
{
struct config_node *n = find_config_node(cn, path, sep);
const struct config_node *n = find_config_node(cn, path);
if (n && n->v->type == CFG_INT) {
log_very_verbose("Setting %s to %d", path, n->v->v.i);
@@ -589,10 +778,10 @@ int find_config_int(struct config_node *cn, const char *path,
return fail;
}
float find_config_float(struct config_node *cn, const char *path,
char sep, float fail)
float find_config_float(const struct config_node *cn, const char *path,
float fail)
{
struct config_node *n = find_config_node(cn, path, sep);
const struct config_node *n = find_config_node(cn, path);
if (n && n->v->type == CFG_FLOAT) {
log_very_verbose("Setting %s to %f", path, n->v->v.r);
@@ -632,10 +821,9 @@ static int _str_to_bool(const char *str, int fail)
return fail;
}
int find_config_bool(struct config_node *cn, const char *path,
char sep, int fail)
int find_config_bool(const struct config_node *cn, const char *path, int fail)
{
struct config_node *n = find_config_node(cn, path, sep);
const struct config_node *n = find_config_node(cn, path);
struct config_value *v;
if (!n)
@@ -654,12 +842,12 @@ int find_config_bool(struct config_node *cn, const char *path,
return fail;
}
int get_config_uint32(struct config_node *cn, const char *path,
char sep, uint32_t * result)
int get_config_uint32(const struct config_node *cn, const char *path,
uint32_t *result)
{
struct config_node *n;
const struct config_node *n;
n = find_config_node(cn, path, sep);
n = find_config_node(cn, path);
if (!n || !n->v || n->v->type != CFG_INT)
return 0;
@@ -668,12 +856,12 @@ int get_config_uint32(struct config_node *cn, const char *path,
return 1;
}
int get_config_uint64(struct config_node *cn, const char *path,
char sep, uint64_t * result)
int get_config_uint64(const struct config_node *cn, const char *path,
uint64_t *result)
{
struct config_node *n;
const struct config_node *n;
n = find_config_node(cn, path, sep);
n = find_config_node(cn, path);
if (!n || !n->v || n->v->type != CFG_INT)
return 0;
@@ -682,3 +870,129 @@ int get_config_uint64(struct config_node *cn, const char *path,
*result = (uint64_t) n->v->v.i;
return 1;
}
int get_config_str(const struct config_node *cn, const char *path,
char **result)
{
const struct config_node *n;
n = find_config_node(cn, path);
if (!n || !n->v || n->v->type != CFG_STRING)
return 0;
*result = n->v->v.str;
return 1;
}
/* Insert cn2 after cn1 */
static void _insert_config_node(struct config_node **cn1,
struct config_node *cn2)
{
if (!*cn1) {
*cn1 = cn2;
cn2->sib = NULL;
} else {
cn2->sib = (*cn1)->sib;
(*cn1)->sib = cn2;
}
}
/*
* Merge section cn2 into section cn1 (which has the same name)
* overwriting any existing cn1 nodes with matching names.
*/
static void _merge_section(struct config_node *cn1, struct config_node *cn2)
{
struct config_node *cn, *nextn, *oldn;
struct config_value *cv;
for (cn = cn2->child; cn; cn = nextn) {
nextn = cn->sib;
/* Skip "tags" */
if (!strcmp(cn->key, "tags"))
continue;
/* Subsection? */
if (!cn->v)
/* Ignore - we don't have any of these yet */
continue;
/* Not already present? */
if (!(oldn = find_config_node(cn1->child, cn->key))) {
_insert_config_node(&cn1->child, cn);
continue;
}
/* Merge certain value lists */
if ((!strcmp(cn1->key, "activation") &&
!strcmp(cn->key, "volume_list")) ||
(!strcmp(cn1->key, "devices") &&
(!strcmp(cn->key, "filter") || !strcmp(cn->key, "types")))) {
cv = cn->v;
while (cv->next)
cv = cv->next;
cv->next = oldn->v;
}
/* Replace values */
oldn->v = cn->v;
}
}
static int _match_host_tags(struct list *tags, struct config_node *tn)
{
struct config_value *tv;
const char *str;
for (tv = tn->v; tv; tv = tv->next) {
if (tv->type != CFG_STRING)
continue;
str = tv->v.str;
if (*str == '@')
str++;
if (!*str)
continue;
if (str_list_match_item(tags, str))
return 1;
}
return 0;
}
/* Destructively merge a new config tree into an existing one */
int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft,
struct config_tree *newdata)
{
struct config_node *root = cft->root;
struct config_node *cn, *nextn, *oldn, *tn, *cn2;
for (cn = newdata->root; cn; cn = nextn) {
nextn = cn->sib;
/* Ignore tags section */
if (!strcmp(cn->key, "tags"))
continue;
/* If there's a tags node, skip if host tags don't match */
if ((tn = find_config_node(cn->child, "tags"))) {
if (!_match_host_tags(&cmd->tags, tn))
continue;
}
if (!(oldn = find_config_node(root, cn->key))) {
_insert_config_node(&cft->root, cn);
/* Remove any "tags" nodes */
for (cn2 = cn->child; cn2; cn2 = cn2->sib) {
if (!strcmp(cn2->key, "tags")) {
cn->child = cn2->sib;
continue;
}
if (cn2->sib && !strcmp(cn2->sib->key, "tags")) {
cn2->sib = cn2->sib->sib;
continue;
}
}
continue;
}
_merge_section(oldn, cn);
}
return 1;
}

View File

@@ -1,72 +1,98 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_CONFIG_H
#define _LVM_CONFIG_H
#include <inttypes.h>
#include "lvm-types.h"
struct device;
struct cmd_context;
enum {
CFG_STRING,
CFG_FLOAT,
CFG_INT,
CFG_STRING,
CFG_FLOAT,
CFG_INT,
CFG_EMPTY_ARRAY
};
struct config_value {
int type;
union {
int i;
float r;
char *str;
} v;
struct config_value *next; /* for arrays */
int type;
union {
int i;
float r;
char *str;
} v;
struct config_value *next; /* for arrays */
};
struct config_node {
char *key;
struct config_node *sib, *child;
struct config_value *v;
char *key;
struct config_node *sib, *child;
struct config_value *v;
};
struct config_file {
struct config_node *root;
struct config_tree {
struct config_node *root;
};
struct config_file *create_config_file(void);
void destroy_config_file(struct config_file *cf);
struct config_tree_list {
struct list list;
struct config_tree *cft;
};
int read_config(struct config_file *cf, const char *file);
int write_config(struct config_file *cf, const char *file);
struct config_tree *create_config_tree(const char *filename);
void destroy_config_tree(struct config_tree *cft);
struct config_node *find_config_node(struct config_node *cn,
const char *path, char seperator);
typedef uint32_t (*checksum_fn_t) (uint32_t initial, void *buf, uint32_t size);
const char *find_config_str(struct config_node *cn,
const char *path, char sep, const char *fail);
int read_config_fd(struct config_tree *cft, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum);
int find_config_int(struct config_node *cn, const char *path,
char sep, int fail);
int read_config_file(struct config_tree *cft);
int write_config_file(struct config_tree *cft, const char *file);
time_t config_file_timestamp(struct config_tree *cft);
int config_file_changed(struct config_tree *cft);
int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft,
struct config_tree *newdata);
float find_config_float(struct config_node *cn, const char *path,
char sep, float fail);
struct config_node *find_config_node(const struct config_node *cn,
const char *path);
const char *find_config_str(const struct config_node *cn, const char *path,
const char *fail);
int find_config_int(const struct config_node *cn, const char *path, int fail);
float find_config_float(const struct config_node *cn, const char *path,
float fail);
/*
* Understands (0, ~0), (y, n), (yes, no), (on,
* off), (true, false).
*/
int find_config_bool(struct config_node *cn, const char *path,
char sep, int fail);
int find_config_bool(const struct config_node *cn, const char *path, int fail);
int get_config_uint32(const struct config_node *cn, const char *path,
uint32_t *result);
int get_config_uint64(const struct config_node *cn, const char *path,
uint64_t *result);
int get_config_uint32(struct config_node *cn, const char *path,
char sep, uint32_t *result);
int get_config_uint64(struct config_node *cn, const char *path,
char sep, uint64_t *result);
int get_config_str(const struct config_node *cn, const char *path,
char **result);
#endif

View File

@@ -1,15 +1,21 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_DEFAULTS_H
#define _LVM_DEFAULTS_H
#define DEFAULT_SYS_DIR "/etc/lvm"
#define DEFAULT_ARCHIVE_ENABLED 1
#define DEFAULT_BACKUP_ENABLED 1
@@ -19,22 +25,90 @@
#define DEFAULT_ARCHIVE_DAYS 30
#define DEFAULT_ARCHIVE_NUMBER 10
#define DEFAULT_SYS_DIR "/etc/lvm"
#define DEFAULT_DEV_DIR "/dev"
#define DEFAULT_PROC_DIR "/proc"
#define DEFAULT_SYSFS_SCAN 1
#define DEFAULT_MD_COMPONENT_DETECTION 1
#define DEFAULT_LOCK_DIR "/var/lock/lvm"
#define DEFAULT_LOCKING_LIB "lvm2_locking.so"
#define DEFAULT_DMEVENTD_MIRROR_LIB "libdevmapper-event-lvm2mirror.so"
#define DEFAULT_UMASK 0077
#define DEFAULT_FORMAT "lvm1"
#define DEFAULT_MSG_PREFIX " "
#define DEFAULT_CMD_NAME 0
#ifdef READLINE_SUPPORT
#define DEFAULT_MAX_HISTORY 100
#ifdef LVM1_FALLBACK
# define DEFAULT_FALLBACK_TO_LVM1 1
#else
# define DEFAULT_FALLBACK_TO_LVM1 0
#endif
#ifdef LVM1_SUPPORT
# define DEFAULT_FORMAT "lvm1"
#else
# define DEFAULT_FORMAT "lvm2"
#endif
#endif /* _LVM_DEFAULTS_H */
#define DEFAULT_STRIPESIZE 64 /* KB */
#define DEFAULT_PVMETADATASIZE 255
#define DEFAULT_PVMETADATACOPIES 1
#define DEFAULT_LABELSECTOR UINT64_C(1)
#define DEFAULT_MSG_PREFIX " "
#define DEFAULT_CMD_NAME 0
#define DEFAULT_OVERWRITE 0
#ifndef DEFAULT_LOG_FACILITY
# define DEFAULT_LOG_FACILITY LOG_USER
#endif
#define DEFAULT_SYSLOG 1
#define DEFAULT_VERBOSE 0
#define DEFAULT_LOGLEVEL 0
#define DEFAULT_INDENT 1
#define DEFAULT_UNITS "h"
#define DEFAULT_SUFFIX 1
#define DEFAULT_HOSTTAGS 0
#ifdef DEVMAPPER_SUPPORT
# define DEFAULT_ACTIVATION 1
# define DEFAULT_RESERVED_MEMORY 8192
# define DEFAULT_RESERVED_STACK 256
# define DEFAULT_PROCESS_PRIORITY -18
#else
# define DEFAULT_ACTIVATION 0
#endif
#define DEFAULT_STRIPE_FILLER "/dev/ioerror"
#define DEFAULT_MIRROR_REGION_SIZE 512 /* KB */
#define DEFAULT_INTERVAL 15
#ifdef READLINE_SUPPORT
# define DEFAULT_MAX_HISTORY 100
#endif
#define DEFAULT_REP_ALIGNED 1
#define DEFAULT_REP_BUFFERED 1
#define DEFAULT_REP_HEADINGS 1
#define DEFAULT_REP_SEPARATOR " "
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,mirror_log,copy_percent"
#define DEFAULT_VGS_COLS "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
#define DEFAULT_PVS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
#define DEFAULT_SEGS_COLS "lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
#define DEFAULT_PVSEGS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,origin,snap_percent,move_pv,copy_percent,mirror_log,lv_uuid"
#define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid"
#define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
#define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
#define DEFAULT_PVSEGS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
#define DEFAULT_LVS_SORT "vg_name,lv_name"
#define DEFAULT_VGS_SORT "vg_name"
#define DEFAULT_PVS_SORT "pv_name"
#define DEFAULT_SEGS_SORT "vg_name,lv_name,seg_start"
#define DEFAULT_PVSEGS_SORT "pv_name,pvseg_start"
#endif /* _LVM_DEFAULTS_H */

View File

@@ -1,79 +0,0 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the LGPL.
*/
#include "bitset.h"
#include "dbg_malloc.h"
#include <stdlib.h>
/* FIXME: calculate this. */
#define INT_SHIFT 5
bitset_t bitset_create(struct pool * mem, unsigned num_bits)
{
int n = (num_bits / BITS_PER_INT) + 2;
int size = sizeof(int) * n;
unsigned *bs = pool_zalloc(mem, size);
if (!bs)
return NULL;
*bs = num_bits;
return bs;
}
void bitset_destroy(bitset_t bs)
{
dbg_free(bs);
}
void bit_union(bitset_t out, bitset_t in1, bitset_t in2)
{
int i;
for (i = (in1[0] / BITS_PER_INT) + 1; i; i--)
out[i] = in1[i] | in2[i];
}
/*
* FIXME: slow
*/
static inline int _test_word(uint32_t test, int bit)
{
while (bit < BITS_PER_INT) {
if (test & (0x1 << bit))
return bit;
bit++;
}
return -1;
}
int bit_get_next(bitset_t bs, int last_bit)
{
int bit, word;
uint32_t test;
last_bit++; /* otherwise we'll return the same bit again */
while (last_bit < bs[0]) {
word = last_bit >> INT_SHIFT;
test = bs[word + 1];
bit = last_bit & (BITS_PER_INT - 1);
if ((bit = _test_word(test, bit)) >= 0)
return (word * BITS_PER_INT) + bit;
last_bit = last_bit - (last_bit & (BITS_PER_INT - 1)) +
BITS_PER_INT;
}
return -1;
}
int bit_get_first(bitset_t bs)
{
return bit_get_next(bs, -1);
}

View File

@@ -1,11 +1,20 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "btree.h"
#include "log.h"
struct node {
uint32_t key;
@@ -15,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;
@@ -46,7 +55,7 @@ static uint32_t _shuffle(uint32_t k)
#endif
}
struct node **_lookup(struct node **c, uint32_t key, struct node **p)
static struct node **_lookup(struct node **c, uint32_t key, struct node **p)
{
*p = NULL;
while (*c) {
@@ -77,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;
}

View File

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

View File

@@ -1,232 +0,0 @@
/*
* Copyright (C) 2001 Sistina Software
*
* This file is released under the LGPL.
*/
#include "dbg_malloc.h"
#include "hash.h"
#include "log.h"
struct hash_node {
struct hash_node *next;
void *data;
char key[1];
};
struct hash_table {
int num_nodes;
int num_slots;
struct hash_node **slots;
};
/* Permutation of the Integers 0 through 255 */
static unsigned char _nums[] = {
1, 14, 110, 25, 97, 174, 132, 119, 138, 170, 125, 118, 27, 233, 140, 51,
87, 197, 177, 107, 234, 169, 56, 68, 30, 7, 173, 73, 188, 40, 36, 65,
49, 213, 104, 190, 57, 211, 148, 223, 48, 115, 15, 2, 67, 186, 210, 28,
12, 181, 103, 70, 22, 58, 75, 78, 183, 167, 238, 157, 124, 147, 172,
144,
176, 161, 141, 86, 60, 66, 128, 83, 156, 241, 79, 46, 168, 198, 41, 254,
178, 85, 253, 237, 250, 154, 133, 88, 35, 206, 95, 116, 252, 192, 54,
221,
102, 218, 255, 240, 82, 106, 158, 201, 61, 3, 89, 9, 42, 155, 159, 93,
166, 80, 50, 34, 175, 195, 100, 99, 26, 150, 16, 145, 4, 33, 8, 189,
121, 64, 77, 72, 208, 245, 130, 122, 143, 55, 105, 134, 29, 164, 185,
194,
193, 239, 101, 242, 5, 171, 126, 11, 74, 59, 137, 228, 108, 191, 232,
139,
6, 24, 81, 20, 127, 17, 91, 92, 251, 151, 225, 207, 21, 98, 113, 112,
84, 226, 18, 214, 199, 187, 13, 32, 94, 220, 224, 212, 247, 204, 196,
43,
249, 236, 45, 244, 111, 182, 153, 136, 129, 90, 217, 202, 19, 165, 231,
71,
230, 142, 96, 227, 62, 179, 246, 114, 162, 53, 160, 215, 205, 180, 47,
109,
44, 38, 31, 149, 135, 0, 216, 52, 63, 23, 37, 69, 39, 117, 146, 184,
163, 200, 222, 235, 248, 243, 219, 10, 152, 131, 123, 229, 203, 76, 120,
209
};
static struct hash_node *_create_node(const char *str)
{
/* remember sizeof(n) includes an extra char from key[1],
so not adding 1 to the strlen as you would expect */
struct hash_node *n = dbg_malloc(sizeof(*n) + strlen(str));
if (n)
strcpy(n->key, str);
return n;
}
static unsigned _hash(const char *str)
{
unsigned long int h = 0, g;
while (*str) {
h <<= 4;
h += _nums[(int) *str++];
g = h & ((unsigned long) 0xf << 16u);
if (g) {
h ^= g >> 16u;
h ^= g >> 5u;
}
}
return h;
}
struct hash_table *hash_create(unsigned size_hint)
{
size_t len;
unsigned new_size = 16u;
struct hash_table *hc = dbg_malloc(sizeof(*hc));
if (!hc) {
stack;
return 0;
}
memset(hc, 0, sizeof(*hc));
/* round size hint up to a power of two */
while (new_size < size_hint)
new_size = new_size << 1;
hc->num_slots = new_size;
len = sizeof(*(hc->slots)) * new_size;
if (!(hc->slots = dbg_malloc(len))) {
stack;
goto bad;
}
memset(hc->slots, 0, len);
return hc;
bad:
dbg_free(hc->slots);
dbg_free(hc);
return 0;
}
static void _free_nodes(struct hash_table *t)
{
struct hash_node *c, *n;
int i;
for (i = 0; i < t->num_slots; i++)
for (c = t->slots[i]; c; c = n) {
n = c->next;
dbg_free(c);
}
}
void hash_destroy(struct hash_table *t)
{
_free_nodes(t);
dbg_free(t->slots);
dbg_free(t);
}
static inline struct hash_node **_find(struct hash_table *t, const char *key)
{
unsigned h = _hash(key) & (t->num_slots - 1);
struct hash_node **c;
for (c = &t->slots[h]; *c; c = &((*c)->next))
if (!strcmp(key, (*c)->key))
break;
return c;
}
void *hash_lookup(struct hash_table *t, const char *key)
{
struct hash_node **c = _find(t, key);
return *c ? (*c)->data : 0;
}
int hash_insert(struct hash_table *t, const char *key, void *data)
{
struct hash_node **c = _find(t, key);
if (*c)
(*c)->data = data;
else {
struct hash_node *n = _create_node(key);
if (!n)
return 0;
n->data = data;
n->next = 0;
*c = n;
t->num_nodes++;
}
return 1;
}
void hash_remove(struct hash_table *t, const char *key)
{
struct hash_node **c = _find(t, key);
if (*c) {
struct hash_node *old = *c;
*c = (*c)->next;
dbg_free(old);
t->num_nodes--;
}
}
unsigned hash_get_num_entries(struct hash_table *t)
{
return t->num_nodes;
}
void hash_iter(struct hash_table *t, iterate_fn f)
{
struct hash_node *c;
int i;
for (i = 0; i < t->num_slots; i++)
for (c = t->slots[i]; c; c = c->next)
f(c->data);
}
void hash_wipe(struct hash_table *t)
{
_free_nodes(t);
memset(t->slots, 0, sizeof(struct hash_node *) * t->num_slots);
t->num_nodes = 0;
}
char *hash_get_key(struct hash_table *t, struct hash_node *n)
{
return n->key;
}
void *hash_get_data(struct hash_table *t, struct hash_node *n)
{
return n->data;
}
static struct hash_node *_next_slot(struct hash_table *t, unsigned int s)
{
struct hash_node *c = NULL;
int i;
for (i = s; i < t->num_slots && !c; i++)
c = t->slots[i];
return c;
}
struct hash_node *hash_get_first(struct hash_table *t)
{
return _next_slot(t, 0);
}
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
{
unsigned int h = _hash(n->key) & (t->num_slots - 1);
return n->next ? n->next : _next_slot(t, h + 1);
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright (C) 2001 Sistina Software
*
* This file is released under the GPL.
*/
#ifndef _LVM_HASH_H
#define _LVM_HASH_H
struct hash_table;
struct hash_node;
typedef void (*iterate_fn)(void *data);
struct hash_table *hash_create(unsigned size_hint);
void hash_destroy(struct hash_table *t);
void hash_wipe(struct hash_table *t);
void *hash_lookup(struct hash_table *t, const char *key);
int hash_insert(struct hash_table *t, const char *key, void *data);
void hash_remove(struct hash_table *t, const char *key);
unsigned hash_get_num_entries(struct hash_table *t);
void hash_iter(struct hash_table *t, iterate_fn f);
char *hash_get_key(struct hash_table *t, struct hash_node *n);
void *hash_get_data(struct hash_table *t, struct hash_node *n);
struct hash_node *hash_get_first(struct hash_table *t);
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n);
#define hash_iterate(v, h) \
for (v = hash_get_first(h); v; \
v = hash_get_next(h, v))
#endif

View File

@@ -1,7 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_LIST_H
@@ -9,15 +18,32 @@
#include <assert.h>
/*
* A list consists of a list head plus elements.
* Each element has 'next' and 'previous' pointers.
* The list head's pointers point to the first and the last element.
*/
struct list {
struct list *n, *p;
};
static inline void list_init(struct list *head) {
/*
* Initialise a list before use.
* 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;
}
static inline void list_add(struct list *head, struct list *elem) {
/*
* 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;
@@ -27,7 +53,12 @@ static inline void list_add(struct list *head, struct list *elem) {
head->p = elem;
}
static inline void list_add_h(struct list *head, struct list *elem) {
/*
* 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;
@@ -37,36 +68,191 @@ static inline void list_add_h(struct list *head, struct list *elem) {
head->n = elem;
}
static inline void list_del(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;
}
static inline int list_empty(struct list *head) {
/*
* Is the list empty?
*/
static inline int list_empty(struct list *head)
{
return head->n == head;
}
/*
* Is this the first element of the list?
*/
static inline int list_start(struct list *head, struct list *elem)
{
return elem->p == head;
}
/*
* Is this the last element of the list?
*/
static inline int list_end(struct list *head, struct list *elem)
{
return elem->n == head;
}
/*
* 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);
}
/*
* 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);
}
/*
* 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);
}
/*
* 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);
}
/*
* Given the address v of an instance of 'struct list' called 'head'
* contained in a structure of type t, return the containing structure.
*/
#define list_struct_base(v, t, head) \
((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->head))
/*
* Given the address v of an instance of 'struct list list' contained in
* a structure of type t, return the containing structure.
*/
#define list_item(v, t) list_struct_base((v), t, list)
/*
* Given the address v of one known element e in a known structure of type t,
* return another element f.
*/
#define struct_field(v, t, e, f) \
(((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f)
/*
* Given the address v of a known element e in a known structure of type t,
* return the list head 'list'
*/
#define list_head(v, t, e) struct_field(v, t, e, list)
/*
* Set v to each element of a list in turn.
*/
#define list_iterate(v, head) \
for (v = (head)->n; v != head; v = v->n)
/*
* Set v to each element in a list in turn, starting from the element
* in front of 'start'.
* You can use this to 'unwind' a list_iterate and back out actions on
* already-processed elements.
* If 'start' is 'head' it walks the list backwards.
*/
#define list_uniterate(v, head, start) \
for (v = (start)->p; v != head; v = v->p)
/*
* A safe way to walk a list and delete and free some elements along
* the way.
* t must be defined as a temporary variable of the same type as v.
*/
#define list_iterate_safe(v, t, head) \
for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
static inline int list_size(struct list *head) {
int s = 0;
struct list *v;
/*
* 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'.
*/
#define list_iterate_items_gen(v, head, field) \
for (v = list_struct_base((head)->n, typeof(*v), field); \
&v->field != (head); \
v = 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.
*/
#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.
* The containing structure should be the same type as 'v'.
* The 'struct list' variable within the containing structure is 'field'.
*/
#define list_iterate_back_items_gen(v, head, field) \
for (v = list_struct_base((head)->p, typeof(*v), field); \
&v->field != (head); \
v = list_struct_base(v->field.p, typeof(*v), field))
/*
* Walk a list backwards, 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.
*/
#define list_iterate_back_items(v, head) list_iterate_back_items_gen(v, (head), list)
/*
* 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++;
s++;
return s;
}
#define list_item(v, t) \
((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list))
/* Given a known element in a known structure, locate the struct list */
#define list_head(v, t, e) \
(((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->list)
#endif

View File

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

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

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

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

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

View File

@@ -1,30 +1,28 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "dev-cache.h"
#include "log.h"
#include "pool.h"
#include "hash.h"
#include "list.h"
#include "lvm-types.h"
#include "btree.h"
#include "dbg_malloc.h"
#include "filter.h"
#include "filter-persistent.h"
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/param.h>
#include <dirent.h>
#include <linux/kdev_t.h>
/*
* FIXME: really need to seperate names from the devices since
* multiple names can point to the same device.
*/
struct dev_iter {
struct btree_iter *current;
@@ -37,50 +35,200 @@ 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;
struct list dirs;
struct list files;
} _cache;
#define _alloc(x) pool_alloc(_cache.mem, (x))
#define _free(x) pool_free(_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);
static struct device *_create_dev(dev_t d)
struct device *dev_create_file(const char *filename, struct device *dev,
struct str_list *alias, int use_malloc)
{
int allocate = !dev;
if (allocate) {
if (use_malloc) {
if (!(dev = dm_malloc(sizeof(*dev)))) {
log_error("struct device allocation failed");
return NULL;
}
if (!(alias = dm_malloc(sizeof(*alias)))) {
log_error("struct str_list allocation failed");
dm_free(dev);
return NULL;
}
if (!(alias->str = dm_strdup(filename))) {
log_error("filename strdup failed");
dm_free(dev);
dm_free(alias);
return NULL;
}
dev->flags = DEV_ALLOCED;
} else {
if (!(dev = _alloc(sizeof(*dev)))) {
log_error("struct device allocation failed");
return NULL;
}
if (!(alias = _alloc(sizeof(*alias)))) {
log_error("struct str_list allocation failed");
_free(dev);
return NULL;
}
if (!(alias->str = _strdup(filename))) {
log_error("filename strdup failed");
return NULL;
}
}
} else if (!(alias->str = dm_strdup(filename))) {
log_error("filename strdup failed");
return NULL;
}
dev->flags |= DEV_REGULAR;
list_init(&dev->aliases);
list_add(&dev->aliases, &alias->list);
dev->end = UINT64_C(0);
dev->dev = 0;
dev->fd = -1;
dev->open_count = 0;
dev->block_size = -1;
memset(dev->pvid, 0, sizeof(dev->pvid));
list_init(&dev->open_list);
return dev;
}
static struct device *_dev_create(dev_t d)
{
struct device *dev;
if (!(dev = _alloc(sizeof(*dev)))) {
stack;
log_error("struct device allocation failed");
return NULL;
}
dev->flags = 0;
list_init(&dev->aliases);
dev->dev = d;
dev->fd = -1;
dev->open_count = 0;
dev->block_size = -1;
dev->end = UINT64_C(0);
memset(dev->pvid, 0, sizeof(dev->pvid));
list_init(&dev->open_list);
return dev;
}
/* Return 1 if we prefer path1 else return 0 */
static int _compare_paths(const char *path0, const char *path1)
{
int slash0 = 0, slash1 = 0;
const char *p;
char p0[PATH_MAX], p1[PATH_MAX];
char *s0, *s1;
struct stat stat0, stat1;
/* Return the path with fewer slashes */
for (p = path0; p++; p = (const char *) strchr(p, '/'))
slash0++;
for (p = path1; p++; p = (const char *) strchr(p, '/'))
slash1++;
if (slash0 < slash1)
return 0;
if (slash1 < slash0)
return 1;
strncpy(p0, path0, PATH_MAX);
strncpy(p1, path1, PATH_MAX);
s0 = &p0[0] + 1;
s1 = &p1[0] + 1;
/* We prefer symlinks - they exist for a reason!
* So we prefer a shorter path before the first symlink in the name.
* FIXME Configuration option to invert this? */
while (s0) {
s0 = strchr(s0, '/');
s1 = strchr(s1, '/');
if (s0) {
*s0 = '\0';
*s1 = '\0';
}
if (lstat(p0, &stat0)) {
log_sys_error("lstat", p0);
return 1;
}
if (lstat(p1, &stat1)) {
log_sys_error("lstat", p1);
return 0;
}
if (S_ISLNK(stat0.st_mode) && !S_ISLNK(stat1.st_mode))
return 0;
if (!S_ISLNK(stat0.st_mode) && S_ISLNK(stat1.st_mode))
return 1;
if (s0) {
*s0++ = '/';
*s1++ = '/';
}
}
/* ASCII comparison */
if (strcmp(path0, path1) < 0)
return 0;
else
return 1;
}
static int _add_alias(struct device *dev, const char *path)
{
struct str_list *sl = _alloc(sizeof(*sl));
struct str_list *strl;
const char *oldpath;
int prefer_old = 1;
if (!sl) {
stack;
return 0;
}
if (!(sl->str = pool_strdup(_cache.mem, path))) {
/* Is name already there? */
list_iterate_items(strl, &dev->aliases) {
if (!strcmp(strl->str, path)) {
log_debug("%s: Already in device cache", path);
return 1;
}
}
if (!(sl->str = dm_pool_strdup(_cache.mem, path))) {
stack;
return 0;
}
list_add(&dev->aliases, &sl->list);
if (!list_empty(&dev->aliases)) {
oldpath = list_item(dev->aliases.n, struct str_list)->str;
prefer_old = _compare_paths(path, oldpath);
log_debug("%s: Aliased to %s in device cache%s",
path, oldpath, prefer_old ? "" : " (preferred name)");
} else
log_debug("%s: Added to device cache", path);
if (prefer_old)
list_add(&dev->aliases, &sl->list);
else
list_add_h(&dev->aliases, &sl->list);
return 1;
}
@@ -91,28 +239,44 @@ static int _add_alias(struct device *dev, const char *path)
static int _insert_dev(const char *path, dev_t d)
{
struct device *dev;
static dev_t loopfile_count = 0;
int loopfile = 0;
/* Generate pretend device numbers for loopfiles */
if (!d) {
if (dm_hash_lookup(_cache.names, path))
return 1;
d = ++loopfile_count;
loopfile = 1;
}
/* is this device already registered ? */
if (!(dev = (struct device *) btree_lookup(_cache.devices, d))) {
if (!(dev = (struct device *) btree_lookup(_cache.devices,
(uint32_t) d))) {
/* create new device */
if (!(dev = _create_dev(d))) {
if (loopfile) {
if (!(dev = dev_create_file(path, NULL, NULL, 0))) {
stack;
return 0;
}
} else if (!(dev = _dev_create(d))) {
stack;
return 0;
}
if (!(btree_insert(_cache.devices, d, dev))) {
if (!(btree_insert(_cache.devices, (uint32_t) d, dev))) {
log_err("Couldn't insert device into binary tree.");
_free(dev);
return 0;
}
}
if (!_add_alias(dev, path)) {
if (!loopfile && !_add_alias(dev, path)) {
log_err("Couldn't add alias to dev cache.");
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;
}
@@ -122,8 +286,8 @@ static int _insert_dev(const char *path, dev_t d)
static char *_join(const char *dir, const char *name)
{
int len = strlen(dir) + strlen(name) + 2;
char *r = dbg_malloc(len);
size_t len = strlen(dir) + strlen(name) + 2;
char *r = dm_malloc(len);
if (r)
snprintf(r, len, "%s/%s", dir, name);
@@ -173,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]);
}
@@ -183,6 +347,28 @@ static int _insert_dir(const char *dir)
return r;
}
static int _insert_file(const char *path)
{
struct stat info;
if (stat(path, &info) < 0) {
log_sys_very_verbose("stat", path);
return 0;
}
if (!S_ISREG(info.st_mode)) {
log_debug("%s: Not a regular file", path);
return 0;
}
if (!_insert_dev(path, 0)) {
stack;
return 0;
}
return 1;
}
static int _insert(const char *path, int rec)
{
struct stat info;
@@ -194,6 +380,17 @@ static int _insert(const char *path, int rec)
}
if (S_ISDIR(info.st_mode)) { /* add a directory */
/* check it's not a symbolic link */
if (lstat(path, &info) < 0) {
log_sys_very_verbose("lstat", path);
return 0;
}
if (S_ISLNK(info.st_mode)) {
log_debug("%s: Symbolic link to directory", path);
return 0;
}
if (rec)
r = _insert_dir(path);
@@ -214,33 +411,49 @@ static int _insert(const char *path, int rec)
return r;
}
static void _full_scan(void)
static void _full_scan(int dev_scan)
{
struct list *dh;
struct dir_list *dl;
if (_cache.has_scanned)
if (_cache.has_scanned && !dev_scan)
return;
list_iterate(dh, &_cache.dirs) {
struct dir_list *dl = list_item(dh, struct dir_list);
list_iterate_items(dl, &_cache.dirs)
_insert_dir(dl->dir);
};
list_iterate_items(dl, &_cache.files)
_insert_file(dl->dir);
_cache.has_scanned = 1;
init_full_scan_done(1);
}
int dev_cache_has_scanned(void)
{
return _cache.has_scanned;
}
void dev_cache_scan(int do_scan)
{
if (!do_scan)
_cache.has_scanned = 1;
else
_full_scan(1);
}
int dev_cache_init(void)
{
_cache.names = NULL;
_cache.has_scanned = 0;
if (!(_cache.mem = pool_create(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;
}
@@ -251,6 +464,7 @@ int dev_cache_init(void)
}
list_init(&_cache.dirs);
list_init(&_cache.files);
return 1;
@@ -259,7 +473,7 @@ int dev_cache_init(void)
return 0;
}
void _check_closed(struct device *dev)
static void _check_closed(struct device *dev)
{
if (dev->fd >= 0)
log_err("Device '%s' has been left open.", dev_name(dev));
@@ -267,16 +481,28 @@ void _check_closed(struct device *dev)
static inline 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)
{
_check_for_open_devices();
pool_destroy(_cache.mem);
if (_cache.names)
hash_destroy(_cache.names);
_check_for_open_devices();
if (_cache.mem) {
dm_pool_destroy(_cache.mem);
_cache.mem = NULL;
}
if (_cache.names) {
dm_hash_destroy(_cache.names);
_cache.names = NULL;
}
_cache.devices = NULL;
_cache.has_scanned = 0;
list_init(&_cache.dirs);
list_init(&_cache.files);
}
int dev_cache_add_dir(const char *path)
@@ -295,33 +521,75 @@ int dev_cache_add_dir(const char *path)
return 1;
}
if (!(dl = _alloc(sizeof(*dl) + strlen(path) + 1)))
if (!(dl = _alloc(sizeof(*dl) + strlen(path) + 1))) {
log_error("dir_list allocation failed");
return 0;
}
strcpy(dl->dir, path);
list_add(&_cache.dirs, &dl->list);
return 1;
}
int dev_cache_add_loopfile(const char *path)
{
struct dir_list *dl;
struct stat st;
if (stat(path, &st)) {
log_error("Ignoring %s: %s", path, strerror(errno));
/* But don't fail */
return 1;
}
if (!S_ISREG(st.st_mode)) {
log_error("Ignoring %s: Not a regular file", path);
return 1;
}
if (!(dl = _alloc(sizeof(*dl) + strlen(path) + 1))) {
log_error("dir_list allocation failed for file");
return 0;
}
strcpy(dl->dir, path);
list_add(&_cache.files, &dl->list);
return 1;
}
/* Check cached device name is still valid before returning it */
/* This should be a rare occurrence */
/* set quiet if the cache is expected to be out-of-date */
/* FIXME Make rest of code pass/cache struct device instead of dev_name */
const char *dev_name_confirmed(struct device *dev)
const char *dev_name_confirmed(struct device *dev, int quiet)
{
struct stat buf;
char *name;
const char *name;
int r;
if ((dev->flags & DEV_REGULAR))
return dev_name(dev);
while ((r = stat(name = list_item(dev->aliases.n,
struct str_list)->str, &buf)) ||
(buf.st_rdev != dev->dev)) {
if (r < 0)
log_sys_error("stat", name);
log_error("Path %s no longer valid for device(%d,%d)",
name, (int) MAJOR(dev->dev), (int) MINOR(dev->dev));
if (r < 0) {
if (quiet)
log_sys_debug("stat", name);
else
log_sys_error("stat", name);
}
if (quiet)
log_debug("Path %s no longer valid for device(%d,%d)",
name, (int) MAJOR(dev->dev),
(int) MINOR(dev->dev));
else
log_error("Path %s no longer valid for device(%d,%d)",
name, (int) MAJOR(dev->dev),
(int) MINOR(dev->dev));
/* Remove the incorrect hash entry */
hash_remove(_cache.names, name);
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. */
@@ -344,30 +612,47 @@ const char *dev_name_confirmed(struct device *dev)
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 *) dm_hash_lookup(_cache.names, name);
}
}
return (d && (!f || f->passes_filter(f, d))) ? d : NULL;
return (d && (!f || (d->flags & DEV_REGULAR) ||
f->passes_filter(f, d))) ? d : NULL;
}
struct dev_iter *dev_iter_create(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)
if (!di) {
log_error("dev_iter allocation failed");
return NULL;
}
if (dev_scan) {
/* Flag gets reset between each command */
if (!full_scan_done())
persistent_filter_wipe(f); /* Calls _full_scan(1) */
} else
_full_scan(0);
_full_scan();
di->current = btree_first(_cache.devices);
di->filter = f;
@@ -376,7 +661,7 @@ struct dev_iter *dev_iter_create(struct dev_filter *f)
void dev_iter_destroy(struct dev_iter *iter)
{
dbg_free(iter);
dm_free(iter);
}
static inline struct device *_iter_next(struct dev_iter *iter)
@@ -390,7 +675,7 @@ struct device *dev_iter_get(struct dev_iter *iter)
{
while (iter->current) {
struct device *d = _iter_next(iter);
if (!iter->filter ||
if (!iter->filter || (d->flags & DEV_REGULAR) ||
iter->filter->passes_filter(iter->filter, d))
return d;
}

View File

@@ -1,41 +1,51 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_DEV_CACHE_H
#define _LVM_DEV_CACHE_H
#include <sys/types.h>
#include "lvm-types.h"
#include "device.h"
/*
* predicate for devices.
*/
struct dev_filter {
int (*passes_filter)(struct dev_filter *f, struct device *dev);
void (*destroy)(struct dev_filter *f);
int (*passes_filter) (struct dev_filter * f, struct device * dev);
void (*destroy) (struct dev_filter * f);
void *private;
};
/*
* The global device cache.
*/
int dev_cache_init(void);
void dev_cache_exit(void);
int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(const char *name, struct dev_filter *f);
/* Trigger(1) or avoid(0) a scan */
void dev_cache_scan(int do_scan);
int dev_cache_has_scanned(void);
int dev_cache_add_dir(const char *path);
int dev_cache_add_loopfile(const char *path);
struct device *dev_cache_get(const char *name, struct dev_filter *f);
/*
* Object for iterating through the cache.
*/
struct dev_iter;
struct dev_iter *dev_iter_create(struct dev_filter *f);
struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan);
void dev_iter_destroy(struct dev_iter *iter);
struct device *dev_iter_get(struct dev_iter *iter);

View File

@@ -1,51 +1,290 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "device.h"
#include "lib.h"
#include "lvm-types.h"
#include "log.h"
#include "device.h"
#include "metadata.h"
#include "lvmcache.h"
#include "memlock.h"
#include "locking.h"
#include <sys/types.h>
#include <limits.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fs.h> // UGH!!! for BLKSSZGET
int dev_get_size(struct device *dev, uint64_t * size)
#ifdef linux
# define u64 uint64_t /* Missing without __KERNEL__ */
# undef WNOHANG /* Avoid redefinition */
# undef WUNTRACED /* Avoid redefinition */
# include <linux/fs.h> /* For block ioctl definitions */
# define BLKSIZE_SHIFT SECTOR_SHIFT
# ifndef BLKGETSIZE64 /* fs.h out-of-date */
# define BLKGETSIZE64 _IOR(0x12, 114, size_t)
# endif /* BLKGETSIZE64 */
#else
# include <sys/disk.h>
# define BLKBSZGET DKIOCGETBLOCKSIZE
# define BLKSSZGET DKIOCGETBLOCKSIZE
# define BLKGETSIZE64 DKIOCGETBLOCKCOUNT
# define BLKFLSBUF DKIOCSYNCHRONIZECACHE
# define BLKSIZE_SHIFT 0
#endif
#ifdef O_DIRECT_SUPPORT
# ifndef O_DIRECT
# error O_DIRECT support configured but O_DIRECT definition not found in headers
# endif
#endif
static LIST_INIT(_open_devices);
/*-----------------------------------------------------------------
* The standard io loop that keeps submitting an io until it's
* all gone.
*---------------------------------------------------------------*/
static int _io(struct device_area *where, void *buffer, int should_write)
{
int fd = dev_fd(where->dev);
ssize_t n = 0;
size_t total = 0;
if (fd < 0) {
log_error("Attempt to read an unopened device (%s).",
dev_name(where->dev));
return 0;
}
/*
* Skip all writes in test mode.
*/
if (should_write && test_mode())
return 1;
if (where->size > SSIZE_MAX) {
log_error("Read size too large: %" PRIu64, where->size);
return 0;
}
if (lseek(fd, (off_t) where->start, SEEK_SET) < 0) {
log_error("%s: lseek %" PRIu64 " failed: %s",
dev_name(where->dev), (uint64_t) where->start,
strerror(errno));
return 0;
}
while (total < (size_t) where->size) {
do
n = should_write ?
write(fd, buffer, (size_t) where->size - total) :
read(fd, buffer, (size_t) where->size - total);
while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (n < 0)
log_error("%s: %s failed after %" PRIu64 " of %" PRIu64
" at %" PRIu64 ": %s", dev_name(where->dev),
should_write ? "write" : "read",
(uint64_t) total,
(uint64_t) where->size,
(uint64_t) where->start, strerror(errno));
if (n <= 0)
break;
total += n;
buffer += n;
}
return (total == (size_t) where->size);
}
/*-----------------------------------------------------------------
* LVM2 uses O_DIRECT when performing metadata io, which requires
* block size aligned accesses. If any io is not aligned we have
* to perform the io via a bounce buffer, obviously this is quite
* inefficient.
*---------------------------------------------------------------*/
/*
* Get the sector size from an _open_ device.
*/
static int _get_block_size(struct device *dev, unsigned int *size)
{
int fd;
long s;
const char *name = dev_name(dev);
log_very_verbose("Getting size of %s", name);
if ((dev->block_size == -1)) {
if (ioctl(dev_fd(dev), BLKBSZGET, &dev->block_size) < 0) {
log_sys_error("ioctl BLKBSZGET", name);
return 0;
}
log_debug("%s: block size is %u bytes", name, dev->block_size);
}
*size = (unsigned int) dev->block_size;
return 1;
}
/*
* Widens a region to be an aligned region.
*/
static void _widen_region(unsigned int block_size, struct device_area *region,
struct device_area *result)
{
uint64_t mask = block_size - 1, delta;
memcpy(result, region, sizeof(*result));
/* adjust the start */
delta = result->start & mask;
if (delta) {
result->start -= delta;
result->size += delta;
}
/* adjust the end */
delta = (result->start + result->size) & mask;
if (delta)
result->size += block_size - delta;
}
static int _aligned_io(struct device_area *where, void *buffer,
int should_write)
{
void *bounce;
unsigned int block_size = 0;
uintptr_t mask;
struct device_area widened;
if (!(where->dev->flags & DEV_REGULAR) &&
!_get_block_size(where->dev, &block_size)) {
stack;
return 0;
}
if (!block_size)
block_size = getpagesize();
_widen_region(block_size, where, &widened);
/* Do we need to use a bounce buffer? */
mask = block_size - 1;
if (!memcmp(where, &widened, sizeof(widened)) &&
!((uintptr_t) buffer & mask))
return _io(where, buffer, should_write);
/* Allocate a bounce buffer with an extra block */
if (!(bounce = alloca((size_t) widened.size + block_size))) {
log_error("Bounce buffer alloca failed");
return 0;
}
/*
* Realign start of bounce buffer (using the extra sector)
*/
if (((uintptr_t) bounce) & mask)
bounce = (void *) ((((uintptr_t) bounce) + mask) & ~mask);
/* channel the io through the bounce buffer */
if (!_io(&widened, bounce, 0)) {
if (!should_write) {
stack;
return 0;
}
/* FIXME pre-extend the file */
memset(bounce, '\n', widened.size);
}
if (should_write) {
memcpy(bounce + (where->start - widened.start), buffer,
(size_t) where->size);
/* ... then we write */
return _io(&widened, bounce, 1);
}
memcpy(buffer, bounce + (where->start - widened.start),
(size_t) where->size);
return 1;
}
static int _dev_get_size_file(const struct device *dev, uint64_t *size)
{
const char *name = dev_name(dev);
struct stat info;
if (stat(name, &info)) {
log_sys_error("stat", name);
return 0;
}
*size = info.st_size;
*size >>= SECTOR_SHIFT; /* Convert to sectors */
log_very_verbose("%s: size is %" PRIu64 " sectors", name, *size);
return 1;
}
static int _dev_get_size_dev(const struct device *dev, uint64_t *size)
{
int fd;
const char *name = dev_name(dev);
if ((fd = open(name, O_RDONLY)) < 0) {
log_sys_error("open", name);
return 0;
}
/* FIXME: add 64 bit ioctl */
if (ioctl(fd, BLKGETSIZE, &s) < 0) {
log_sys_error("ioctl BLKGETSIZE", name);
close(fd);
if (ioctl(fd, BLKGETSIZE64, size) < 0) {
log_sys_error("ioctl BLKGETSIZE64", name);
if (close(fd))
log_sys_error("close", name);
return 0;
}
close(fd);
*size = (uint64_t) s;
*size >>= BLKSIZE_SHIFT; /* Convert to sectors */
if (close(fd))
log_sys_error("close", name);
log_very_verbose("%s: size is %" PRIu64 " sectors", name, *size);
return 1;
}
int dev_get_sectsize(struct device *dev, uint32_t * size)
/*-----------------------------------------------------------------
* Public functions
*---------------------------------------------------------------*/
int dev_get_size(const struct device *dev, uint64_t *size)
{
if ((dev->flags & DEV_REGULAR))
return _dev_get_size_file(dev, size);
else
return _dev_get_size_dev(dev, size);
}
/* FIXME Unused
int dev_get_sectsize(struct device *dev, uint32_t *size)
{
int fd;
int s;
const char *name = dev_name(dev);
log_very_verbose("Getting size of %s", name);
if ((fd = open(name, O_RDONLY)) < 0) {
log_sys_error("open", name);
return 0;
@@ -59,191 +298,345 @@ int dev_get_sectsize(struct device *dev, uint32_t * size)
close(fd);
*size = (uint32_t) s;
log_very_verbose("%s: sector size is %" PRIu32 " bytes", name, *size);
return 1;
}
*/
int dev_open(struct device *dev, int flags)
void dev_flush(struct device *dev)
{
if (!(dev->flags & DEV_REGULAR) && ioctl(dev->fd, BLKFLSBUF, 0) >= 0)
return;
if (fsync(dev->fd) >= 0)
return;
sync();
}
int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
{
struct stat buf;
const char *name = dev_name_confirmed(dev);
const char *name;
int need_excl = 0, need_rw = 0;
if (!name) {
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) || !need_rw) &&
((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
dev->open_count++;
return 1;
}
if (dev->open_count && !need_excl) {
/* FIXME Ensure we never get here */
log_debug("WARNING: %s already opened read-only",
dev_name(dev));
dev->open_count++;
}
dev_close_immediate(dev);
}
if (memlock())
log_error("WARNING: dev_open(%s) called while suspended",
dev_name(dev));
if (dev->flags & DEV_REGULAR)
name = dev_name(dev);
else if (!(name = dev_name_confirmed(dev, quiet))) {
stack;
return 0;
}
if (dev->fd >= 0) {
log_error("Device '%s' has already been opened", name);
return 0;
}
if ((stat(name, &buf) < 0) || (buf.st_rdev != dev->dev)) {
if (!(dev->flags & DEV_REGULAR) &&
((stat(name, &buf) < 0) || (buf.st_rdev != dev->dev))) {
log_error("%s: stat failed: Has device name changed?", name);
return 0;
}
if ((dev->fd = open(name, flags)) < 0) {
log_sys_error("open", name);
#ifdef O_DIRECT_SUPPORT
if (direct) {
if (!(dev->flags & DEV_O_DIRECT_TESTED))
dev->flags |= DEV_O_DIRECT;
if ((dev->flags & DEV_O_DIRECT))
flags |= O_DIRECT;
}
#endif
#ifdef O_NOATIME
/* Don't update atime on device inodes */
if (!(dev->flags & DEV_REGULAR))
flags |= O_NOATIME;
#endif
if ((dev->fd = open(name, flags, 0777)) < 0) {
#ifdef O_DIRECT_SUPPORT
if (direct && !(dev->flags & DEV_O_DIRECT_TESTED)) {
flags &= ~O_DIRECT;
if ((dev->fd = open(name, flags, 0777)) >= 0) {
dev->flags &= ~DEV_O_DIRECT;
log_debug("%s: Not using O_DIRECT", name);
goto opened;
}
}
#endif
if (quiet)
log_sys_debug("open", name);
else
log_sys_error("open", name);
return 0;
}
if ((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev)) {
#ifdef O_DIRECT_SUPPORT
opened:
if (direct)
dev->flags |= DEV_O_DIRECT_TESTED;
#endif
dev->open_count++;
dev->flags &= ~DEV_ACCESSED_W;
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(dev);
dev_close_immediate(dev);
return 0;
}
dev->flags = 0;
#ifndef O_DIRECT_SUPPORT
if (!(dev->flags & DEV_REGULAR))
dev_flush(dev);
#endif
if ((flags & O_CREAT) && !(flags & O_TRUNC))
dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
list_add(&_open_devices, &dev->open_list);
log_debug("Opened %s %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;
}
static void _flush(int fd)
int dev_open_quiet(struct device *dev)
{
ioctl(fd, BLKFLSBUF, 0);
int flags;
flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
return dev_open_flags(dev, flags, 1, 1);
}
int dev_close(struct device *dev)
int dev_open(struct device *dev)
{
int flags;
flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
return dev_open_flags(dev, flags, 1, 0);
}
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))
log_sys_error("close", dev_name(dev));
dev->fd = -1;
dev->block_size = -1;
list_del(&dev->open_list);
log_debug("Closed %s", dev_name(dev));
if (dev->flags & DEV_ALLOCED) {
dm_free((void *) list_item(dev->aliases.n, struct str_list)->
str);
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));
return 0;
}
#ifndef O_DIRECT_SUPPORT
if (dev->flags & DEV_ACCESSED_W)
_flush(dev->fd);
dev_flush(dev);
#endif
if (close(dev->fd))
log_sys_error("close", dev_name(dev));
if (dev->open_count > 0)
dev->open_count--;
dev->fd = -1;
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;
}
/*
* FIXME: factor common code out.
int dev_close(struct device *dev)
{
return _dev_close(dev, 0);
}
int dev_close_immediate(struct device *dev)
{
return _dev_close(dev, 1);
}
void dev_close_all(void)
{
struct list *doh, *doht;
struct device *dev;
list_iterate_safe(doh, doht, &_open_devices) {
dev = list_struct_base(doh, struct device, open_list);
if (dev->open_count < 1)
_close(dev);
}
}
int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer)
{
struct device_area where;
if (!dev->open_count) {
stack;
return 0;
}
where.dev = dev;
where.start = offset;
where.size = len;
return _aligned_io(&where, buffer, 0);
}
/* FIXME If O_DIRECT can't extend file, dev_extend first; dev_truncate after.
* But fails if concurrent processes writing
*/
int _read(int fd, void *buf, size_t count)
/* FIXME pre-extend the file */
int dev_append(struct device *dev, size_t len, void *buffer)
{
size_t n = 0;
int tot = 0;
int r;
while (tot < count) {
do
n = read(fd, buf, count - tot);
while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (n <= 0)
return tot ? tot : n;
tot += n;
buf += n;
if (!dev->open_count) {
stack;
return 0;
}
return tot;
r = dev_write(dev, dev->end, len, buffer);
dev->end += (uint64_t) len;
#ifndef O_DIRECT_SUPPORT
dev_flush(dev);
#endif
return r;
}
int64_t dev_read(struct device * dev, uint64_t offset,
int64_t len, void *buffer)
int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer)
{
const char *name = dev_name(dev);
int fd = dev->fd;
struct device_area where;
if (fd < 0) {
log_err("Attempt to read an unopened device (%s).", name);
if (!dev->open_count) {
stack;
return 0;
}
if (lseek(fd, offset, SEEK_SET) < 0) {
log_sys_error("lseek", name);
return 0;
}
return _read(fd, buffer, len);
}
int _write(int fd, const void *buf, size_t count)
{
size_t n = 0;
int tot = 0;
/* Skip all writes */
if (test_mode())
return count;
while (tot < count) {
do
n = write(fd, buf, count - tot);
while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (n <= 0)
return tot ? tot : n;
tot += n;
buf += n;
}
return tot;
}
int64_t dev_write(struct device * dev, uint64_t offset,
int64_t len, void *buffer)
{
const char *name = dev_name(dev);
int fd = dev->fd;
if (fd < 0) {
log_error("Attempt to write to unopened device %s", name);
return 0;
}
if (lseek(fd, offset, SEEK_SET) < 0) {
log_sys_error("lseek", name);
return 0;
}
where.dev = dev;
where.start = offset;
where.size = len;
dev->flags |= DEV_ACCESSED_W;
return _write(fd, buffer, len);
return _aligned_io(&where, buffer, 1);
}
int dev_zero(struct device *dev, uint64_t offset, int64_t len)
int dev_zero(struct device *dev, uint64_t offset, size_t len)
{
int64_t r, s;
size_t s;
char buffer[4096];
const char *name = dev_name(dev);
int fd = dev->fd;
if (fd < 0) {
log_error("Attempt to zero part of an unopened device %s",
name);
if (!dev_open(dev)) {
stack;
return 0;
}
if (lseek(fd, offset, SEEK_SET) < 0) {
log_sys_error("lseek", name);
return 0;
}
if ((offset % SECTOR_SIZE) || (len % SECTOR_SIZE))
log_debug("Wiping %s at %" PRIu64 " length %" PRIsize_t,
dev_name(dev), offset, len);
else
log_debug("Wiping %s at sector %" PRIu64 " length %" PRIsize_t
" sectors", dev_name(dev), offset >> SECTOR_SHIFT,
len >> SECTOR_SHIFT);
memset(buffer, 0, sizeof(buffer));
while (1) {
s = len > sizeof(buffer) ? sizeof(buffer) : len;
r = _write(fd, buffer, s);
if (r <= 0)
if (!dev_write(dev, offset, s, buffer))
break;
len -= r;
if (!len) {
r = 1;
len -= s;
if (!len)
break;
}
offset += s;
}
dev->flags |= DEV_ACCESSED_W;
/* FIXME: Always display error */
if (!dev_close(dev))
stack;
return (len == 0);
}

69
lib/device/dev-md.c Normal file
View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2004 Luca Berra
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU 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 "metadata.h"
#include "xlate.h"
/* Lifted from <linux/raid/md_p.h> because of difficulty including it */
#define MD_SB_MAGIC 0xa92b4efc
#define MD_RESERVED_BYTES (64 * 1024)
#define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512)
#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) \
- MD_RESERVED_SECTORS)
/*
* Returns -1 on error
*/
int dev_is_md(struct device *dev, uint64_t *sb)
{
int ret = 0;
#ifdef linux
uint64_t size, sb_offset;
uint32_t md_magic;
if (!dev_get_size(dev, &size)) {
stack;
return -1;
}
if (size < MD_RESERVED_SECTORS * 2)
return 0;
if (!dev_open(dev)) {
stack;
return -1;
}
sb_offset = MD_NEW_SIZE_SECTORS(size) << SECTOR_SHIFT;
/* Check if it is an md component device. */
if (dev_read(dev, sb_offset, sizeof(uint32_t), &md_magic) &&
(md_magic == xlate32(MD_SB_MAGIC))) {
if (sb)
*sb = sb_offset;
ret = 1;
}
if (!dev_close(dev))
stack;
#endif
return ret;
}

View File

@@ -1,56 +1,126 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This file is part of LVM2.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <sys/types.h>
#include "lib.h"
#include "lvm-types.h"
#include "device.h"
#include "metadata.h"
#include "filter.h"
#include "xlate.h"
/* See linux/genhd.h and fs/partitions/msdos */
#define PART_MAGIC 0xAA55
#define PART_MAGIC_OFFSET UINT64_C(0x1FE)
#define PART_OFFSET UINT64_C(0x1BE)
struct partition {
uint8_t boot_ind;
uint8_t head;
uint8_t sector;
uint8_t cyl;
uint8_t sys_ind; /* partition type */
uint8_t end_head;
uint8_t end_sector;
uint8_t end_cyl;
uint32_t start_sect;
uint32_t nr_sects;
} __attribute__((packed));
static int _is_partitionable(struct device *dev)
{
int parts = max_partitions(MAJOR(dev->dev));
if ((parts <= 1) || (MINOR(dev->dev) % parts))
return 0;
return 1;
}
static int _has_partition_table(struct device *dev)
{
int ret = 0;
unsigned p;
uint8_t buf[SECTOR_SIZE];
uint16_t *part_magic;
struct partition *part;
if (!dev_open(dev)) {
stack;
return -1;
}
if (!dev_read(dev, 0, sizeof(buf), &buf)) {
stack;
goto out;
}
/* FIXME Check for other types of partition table too */
/* Check for msdos partition table */
part_magic = (uint16_t *)(buf + PART_MAGIC_OFFSET);
if ((*part_magic == xlate16(PART_MAGIC))) {
part = (struct partition *) (buf + PART_OFFSET);
for (p = 0; p < 4; p++, part++) {
/* Table is invalid if boot indicator not 0 or 0x80 */
if ((part->boot_ind & 0x7f)) {
ret = 0;
break;
}
/* Must have at least one non-empty partition */
if (part->nr_sects)
ret = 1;
}
}
out:
if (!dev_close(dev))
stack;
return ret;
}
int is_partitioned_dev(struct device *dev)
{
if (!_is_partitionable(dev))
return 0;
return _has_partition_table(dev);
}
#if 0
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include "dbg_malloc.h"
#include "log.h"
#include "dev-cache.h"
#include "metadata.h"
#include "device.h"
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/genhd.h>
#if 0
int _get_partition_type(struct dev_filter *filter, struct device *d);
#define MINOR_PART(dm, d) (MINOR((d)->dev) % dev_max_partitions(dm, (d)->dev))
#define MINOR_PART(dev) (MINOR((dev)->dev) % max_partitions(MINOR((dev)->dev)))
int is_whole_disk(struct dev_filter *filter, struct device *d)
int is_extended_partition(struct device *d)
{
return (MINOR_PART(dm, d)) ? 0 : 1;
}
int is_extended_partition(struct dev_mgr *dm, struct device *d)
{
return (MINOR_PART(dm, d) > 4) ? 1 : 0;
return (MINOR_PART(d) > 4) ? 1 : 0;
}
struct device *dev_primary(struct dev_mgr *dm, struct device *d)
@@ -132,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;
}

View File

@@ -1,28 +1,51 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the GPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_DEVICE_H
#define _LVM_DEVICE_H
#include "lvm-types.h"
#include "list.h"
#include "uuid.h"
#include <fcntl.h>
#define DEV_ACCESSED_W 0x00000001 /* Device written to? */
#define DEV_REGULAR 0x00000002 /* Regular file? */
#define DEV_ALLOCED 0x00000004 /* dm_malloc used */
#define DEV_OPENED_RW 0x00000008 /* Opened RW */
#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.
* pointer comparisons are valid.
*/
struct device {
struct list aliases; /* struct str_list from lvm-types.h */
struct list aliases; /* struct str_list from lvm-types.h */
dev_t dev;
/* private */
int fd;
int open_count;
int block_size;
uint32_t flags;
uint64_t end;
struct list open_list;
char pvid[ID_LEN + 1];
char _padding[7];
};
struct device_list {
@@ -30,33 +53,58 @@ struct device_list {
struct device *dev;
};
struct device_area {
struct device *dev;
uint64_t start; /* Bytes */
uint64_t size; /* Bytes */
};
/*
* All io should use these routines.
*/
int dev_get_size(struct device *dev, uint64_t *size);
int dev_get_size(const struct device *dev, uint64_t *size);
int dev_get_sectsize(struct device *dev, uint32_t *size);
int dev_open(struct device *dev, int flags);
/* Use quiet version if device number could change e.g. when opening LV */
int dev_open(struct device *dev);
int dev_open_quiet(struct device *dev);
int dev_open_flags(struct device *dev, int flags, int 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);
int64_t dev_read(struct device *dev,
uint64_t offset, int64_t len, void *buffer);
int64_t dev_write(struct device *dev,
uint64_t offset, int64_t len, void *buffer);
int dev_zero(struct device *dev, uint64_t offset, int64_t len);
static inline int dev_fd(struct device *dev)
{
return dev->fd;
}
int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer);
int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer);
int dev_append(struct device *dev, size_t len, void *buffer);
int dev_zero(struct device *dev, uint64_t offset, size_t len);
void dev_flush(struct device *dev);
static inline const char *dev_name(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";
"unknown device";
}
/* Return a valid device name from the alias list; NULL otherwise */
const char *dev_name_confirmed(struct device *dev);
const char *dev_name_confirmed(struct device *dev, int quiet);
static inline int is_lvm_partition(const char *name) {
return 1;
}
/* Does device contain md superblock? If so, where? */
int dev_is_md(struct device *dev, uint64_t *sb);
/* FIXME Check partition type if appropriate */
#define is_lvm_partition(a) 1
/* int is_lvm_partition(const char *name); */
int is_partitioned_dev(struct device *dev);
#endif

View File

@@ -1,65 +1,202 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This file is part of LVM2.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "metadata.h"
#include "dbg_malloc.h"
#include "log.h"
#include "display.h"
#include "activate.h"
#include "uuid.h"
#include "toolcontext.h"
#include <sys/types.h>
#include <string.h>
#include "segtype.h"
#define SIZE_BUF 128
char *display_size(uint64_t size, size_len_t sl)
static struct {
alloc_policy_t alloc;
const char *str;
} _policies[] = {
{
ALLOC_CONTIGUOUS, "contiguous"}, {
ALLOC_NORMAL, "normal"}, {
ALLOC_ANYWHERE, "anywhere"}, {
ALLOC_INHERIT, "inherit"}
};
static int _num_policies = sizeof(_policies) / sizeof(*_policies);
uint64_t units_to_bytes(const char *units, char *unit_type)
{
char *ptr = NULL;
uint64_t v;
if (isdigit(*units)) {
v = (uint64_t) strtod(units, &ptr);
if (ptr == units)
return 0;
units = ptr;
} else
v = 1;
if (v == 1)
*unit_type = *units;
else
*unit_type = 'U';
switch (*units) {
case 'h':
case 'H':
v = UINT64_C(1);
*unit_type = *units;
break;
case 's':
v *= SECTOR_SIZE;
break;
case 'b':
case 'B':
v *= UINT64_C(1);
break;
#define KILO UINT64_C(1024)
case 'k':
v *= KILO;
break;
case 'm':
v *= KILO * KILO;
break;
case 'g':
v *= KILO * KILO * KILO;
break;
case 't':
v *= KILO * KILO * KILO * KILO;
break;
#undef KILO
#define KILO UINT64_C(1000)
case 'K':
v *= KILO;
break;
case 'M':
v *= KILO * KILO;
break;
case 'G':
v *= KILO * KILO * KILO;
break;
case 'T':
v *= KILO * KILO * KILO * KILO;
break;
#undef KILO
default:
return 0;
}
if (*(units + 1))
return 0;
return v;
}
const char *get_alloc_string(alloc_policy_t alloc)
{
int i;
for (i = 0; i < _num_policies; i++)
if (_policies[i].alloc == alloc)
return _policies[i].str;
return NULL;
}
alloc_policy_t get_alloc_from_string(const char *str)
{
int i;
for (i = 0; i < _num_policies; i++)
if (!strcmp(_policies[i].str, str))
return _policies[i].alloc;
/* Special case for old metadata */
if(!strcmp("next free", str))
return ALLOC_NORMAL;
log_error("Unrecognised allocation policy %s", str);
return ALLOC_INVALID;
}
/* Size supplied in sectors */
const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl)
{
int s;
ulong byte = 1024 * 1024 * 1024;
int suffix = 1, precision;
uint64_t byte = UINT64_C(0);
uint64_t units = UINT64_C(1024);
char *size_buf = NULL;
char *size_str[][2] = {
{"Terabyte", "TB"},
{"Gigabyte", "GB"},
{"Megabyte", "MB"},
{"Kilobyte", "KB"},
{"", ""}
const char *size_str[][3] = {
{" Terabyte", " TB", "T"},
{" Gigabyte", " GB", "G"},
{" Megabyte", " MB", "M"},
{" Kilobyte", " KB", "K"},
{"", "", ""},
{" Byte ", " B ", "B"},
{" Units ", " Un", "U"},
{" Sectors ", " Se", "S"},
{" ", " ", " "},
};
if (!(size_buf = dbg_malloc(SIZE_BUF))) {
if (!(size_buf = dm_pool_alloc(cmd->mem, SIZE_BUF))) {
log_error("no memory for size display buffer");
return NULL;
return "";
}
if (size == 0LL)
sprintf(size_buf, "0");
else {
suffix = cmd->current_settings.suffix;
for (s = 0; s < 8; s++)
if (toupper((int) cmd->current_settings.unit_type) ==
*size_str[s][2])
break;
if (size == UINT64_C(0)) {
sprintf(size_buf, "0%s", suffix ? size_str[s][sl] : "");
return size_buf;
}
if (s < 8) {
byte = cmd->current_settings.unit_factor;
size *= UINT64_C(512);
} else {
size /= 2;
suffix = 1;
if (cmd->current_settings.unit_type == 'H')
units = UINT64_C(1000);
else
units = UINT64_C(1024);
byte = units * units * units;
s = 0;
while (size_str[s] && size < byte)
s++, byte /= 1024;
snprintf(size_buf, SIZE_BUF - 1,
"%.2f %s", (float) size / byte, size_str[s][sl]);
s++, byte /= units;
}
/* Caller to deallocate */
/* FIXME Make precision configurable */
switch(toupper((int) cmd->current_settings.unit_type)) {
case 'B':
case 'S':
precision = 0;
break;
default:
precision = 2;
}
snprintf(size_buf, SIZE_BUF - 1, "%.*f%s", precision,
(double) size / byte, suffix ? size_str[s][sl] : "");
return size_buf;
}
@@ -75,7 +212,7 @@ void pvdisplay_colons(struct physical_volume *pv)
return;
}
log_print("%s:%s:%" PRIu64 ":-1:%u:%u:-1:%" PRIu64 ":%u:%u:%u:%s",
log_print("%s:%s:%" PRIu64 ":-1:%u:%u:-1:%" PRIu32 ":%u:%u:%u:%s",
dev_name(pv->dev), pv->vg_name, pv->size,
/* FIXME pv->pv_number, Derive or remove? */
pv->status, /* FIXME Support old or new format here? */
@@ -89,12 +226,14 @@ void pvdisplay_colons(struct physical_volume *pv)
return;
}
void pvdisplay_full(struct physical_volume *pv)
/* FIXME Include label fields */
void pvdisplay_full(struct cmd_context *cmd, struct physical_volume *pv,
void *handle)
{
char uuid[64];
char *size, *size1; /*, *size2; */
const char *size;
uint64_t pe_free;
uint32_t pe_free;
if (!pv)
return;
@@ -104,49 +243,30 @@ void pvdisplay_full(struct physical_volume *pv)
return;
}
/* Compat */
if(!pv->pe_size) {
size = display_size((uint64_t) pv->size / 2, SIZE_SHORT);
log_print("\"%s\" is a new physical volume of %s", dev_name(pv->dev), size);
dbg_free(size);
return;
}
set_cmd_name("");
init_msg_prefix("");
/****** FIXME Do we really need this conditional here? */
log_print("--- %sPhysical volume ---", pv->pe_size ? "" : "NEW ");
log_print("PV Name %s", dev_name(pv->dev));
log_print("VG Name %s%s", pv->vg_name,
pv->status & EXPORTED_VG ? " (exported)" : "");
size = display_size((uint64_t) pv->size / 2, SIZE_SHORT);
size = display_size(cmd, (uint64_t) pv->size, SIZE_SHORT);
if (pv->pe_size && pv->pe_count) {
size1 = display_size((pv->size - pv->pe_count * pv->pe_size)
/ 2, SIZE_SHORT);
/******** FIXME display LVM on-disk data size - static for now...
size2 = display_size(pv->size / 2, SIZE_SHORT);
/******** FIXME display LVM on-disk data size
size2 = display_size(pv->size, SIZE_SHORT);
********/
log_print("PV Size %s [%llu secs]" " / not "
"usable %s [LVM: %s]",
size, (uint64_t) pv->size, size1, "151 KB");
/* , size2); */
log_print("PV Size %s" " / not usable %s", /* [LVM: %s]", */
size,
display_size(cmd, (pv->size -
(uint64_t) pv->pe_count * pv->pe_size),
SIZE_SHORT));
dbg_free(size1);
/* dbg_free(size2); */
} else
log_print("PV Size %s", size);
dbg_free(size);
/******** FIXME anytime this *isn't* available? */
log_print("PV Status available");
/*********FIXME Anything use this?
log_print("PV# %u", pv->pv_number);
**********/
/* PV number not part of LVM2 design
log_print("PV# %u", pv->pv_number);
*/
pe_free = pv->pe_count - pv->pe_alloc_count;
if (pv->pe_count && (pv->status & ALLOCATABLE_PV))
@@ -155,18 +275,13 @@ void pvdisplay_full(struct physical_volume *pv)
else
log_print("Allocatable NO");
/*********FIXME Erm...where is this stored?
log_print("Cur LV %u", vg->lv_count);
*/
log_print("PE Size (KByte) %" PRIu64, pv->pe_size / 2);
/* LV count is no longer available when displaying PV
log_print("Cur LV %u", vg->lv_count);
*/
log_print("PE Size (KByte) %" PRIu32, pv->pe_size / 2);
log_print("Total PE %u", pv->pe_count);
log_print("Free PE %" PRIu64, pe_free);
log_print("Free PE %" PRIu32, pe_free);
log_print("Allocated PE %u", pv->pe_alloc_count);
#ifdef LVM_FUTURE
printf("Stale PE %u", pv->pe_stale);
#endif
log_print("PV UUID %s", *uuid ? uuid : "none");
log_print(" ");
@@ -174,13 +289,21 @@ void pvdisplay_full(struct physical_volume *pv)
}
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv)
struct physical_volume *pv, void *handle)
{
char uuid[64];
if (!pv)
return 0;
if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
stack;
return 0;
}
log_print("PV Name %s ", dev_name(pv->dev));
/* FIXME pv->pv_number); */
log_print("PV UUID %s", *uuid ? uuid : "none");
log_print("PV Status %sallocatable",
(pv->status & ALLOCATABLE_PV) ? "" : "NOT ");
log_print("Total PE / Free PE %u / %u",
@@ -190,13 +313,11 @@ int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
return 0;
}
void lvdisplay_colons(struct logical_volume *lv)
{
int inkernel;
struct dm_info info;
inkernel = lv_info(lv, &info) && info.exists;
struct lvinfo info;
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,
@@ -207,35 +328,26 @@ void lvdisplay_colons(struct logical_volume *lv)
/* FIXME lv->lv_number, */
inkernel ? info.open_count : 0, lv->size, lv->le_count,
/* FIXME Add num allocated to struct! lv->lv_allocated_le, */
((lv->status & ALLOC_STRICT) +
(lv->status & ALLOC_CONTIGUOUS) * 2), lv->read_ahead,
(lv->alloc == ALLOC_CONTIGUOUS ? 2 : 0), lv->read_ahead,
inkernel ? info.major : -1, inkernel ? info.minor : -1);
return;
}
int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
char *size;
uint32_t alloc;
struct dm_info info;
int inkernel;
struct lvinfo info;
int inkernel, snap_active = 0;
char uuid[64];
struct snapshot *snap;
struct stripe_segment *seg;
struct list *lvseg;
struct logical_volume *origin;
float snap_percent;
int snap_active;
struct lv_segment *snap_seg = NULL;
float snap_percent; /* fused, fsize; */
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) {
stack;
return 0;
}
inkernel = lv_info(lv, &info) && info.exists;
set_cmd_name("");
init_msg_prefix("");
inkernel = lv_info(cmd, lv, &info, 1) && info.exists;
log_print("--- Logical volume ---");
@@ -243,161 +355,88 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
lv->vg->name, lv->name);
log_print("VG Name %s", lv->vg->name);
/* Not in LVM1 format
log_print("LV UUID %s", uuid);
**/
log_print("LV Write Access %s",
(lv->status & LVM_WRITE) ? "read/write" : "read only");
/* see if this LV is an origin for a snapshot */
if ((snap = find_origin(lv))) {
struct list *slh, *snaplist = find_snapshots(lv);
if (lv_is_origin(lv)) {
log_print("LV snapshot status source of");
list_iterate(slh, snaplist) {
snap = list_item(slh, struct snapshot_list)->snapshot;
snap_active = lv_snapshot_percentage(snap->cow,
&snap_percent);
log_print(" %s%s/%s [%s]",
lv->vg->cmd->dev_dir, lv->vg->name,
snap->cow->name,
(snap_active > 0) ? "active" : "INACTIVE");
}
/* reset so we don't try to use this to display other snapshot
* related information. */
snap = NULL;
snap_active = 0;
}
/* Check to see if this LV is a COW target for a snapshot */
else if ((snap = find_cow(lv))) {
snap_active = lv_snapshot_percentage(lv, &snap_percent);
log_print("LV snapshot status %s destination for %s%s/%s",
(snap_active > 0) ? "active" : "INACTIVE",
lv->vg->cmd->dev_dir, lv->vg->name,
snap->origin->name);
}
list_iterate_items_gen(snap_seg, &lv->snapshot_segs,
origin_list) {
if (inkernel &&
(snap_active = lv_snapshot_percent(snap_seg->cow,
&snap_percent)))
if (snap_percent < 0 || snap_percent >= 100)
snap_active = 0;
log_print(" %s%s/%s [%s]",
lv->vg->cmd->dev_dir, lv->vg->name,
snap_seg->cow->name,
(snap_active > 0) ? "active" : "INACTIVE");
}
snap_seg = NULL;
} else if ((snap_seg = find_cow(lv))) {
if (inkernel &&
(snap_active = lv_snapshot_percent(snap_seg->cow,
&snap_percent)))
if (snap_percent < 0 || snap_percent >= 100)
snap_active = 0;
log_print("LV snapshot status %s destination for %s%s/%s",
(snap_active > 0) ? "active" : "INACTIVE",
lv->vg->cmd->dev_dir, lv->vg->name,
snap_seg->origin->name);
}
if (inkernel && info.suspended)
log_print("LV Status suspended");
else
log_print("LV Status %savailable",
!inkernel || (snap && (snap_active < 1))
? "NOT " : "");
inkernel ? "" : "NOT ");
/********* FIXME lv_number - not sure that we're going to bother with this
/********* FIXME lv_number
log_print("LV # %u", lv->lv_number + 1);
************/
/* LVM1 lists the number of LVs open in this field, therefore, so do we. */
log_print("# open %u", lvs_in_vg_opened(lv->vg));
/* We're not going to use this count ATM, 'cause it's not what LVM1 does
if (inkernel)
log_print("# open %u", info.open_count);
*/
/********
#ifdef LVM_FUTURE
printf("Mirror copies %u\n", lv->lv_mirror_copies);
printf("Consistency recovery ");
if (lv->lv_recovery | LV_BADBLOCK_ON)
printf("bad blocks\n");
else
printf("none\n");
printf("Schedule %u\n", lv->lv_schedule);
#endif
********/
if(snap)
origin = snap->origin;
else
origin = lv;
size = display_size(origin->size / 2, SIZE_SHORT);
log_print("LV Size %s", size);
dbg_free(size);
log_print("LV Size %s",
display_size(cmd,
snap_seg ? snap_seg->origin->size : lv->size,
SIZE_SHORT));
log_print("Current LE %u", origin->le_count);
/********** FIXME allocation - is there anytime the allocated LEs will not
* equal the current LEs? */
log_print("Allocated LE %u", origin->le_count);
/**********/
log_print("Current LE %u",
snap_seg ? snap_seg->origin->le_count : lv->le_count);
list_iterate(lvseg, &lv->segments) {
seg = list_item(lvseg, struct stripe_segment);
if(seg->stripes > 1) {
log_print("Stripes %u", seg->stripes);
log_print("Stripe size (KByte) %u",
seg->stripe_size/2);
}
/* only want the first segment for LVM1 format output */
break;
if (snap_seg) {
log_print("COW-table size %s",
display_size(cmd, (uint64_t) lv->size, SIZE_SHORT));
log_print("COW-table LE %u", lv->le_count);
if (snap_active)
log_print("Allocated to snapshot %.2f%% ", snap_percent);
log_print("Snapshot chunk size %s",
display_size(cmd, (uint64_t) snap_seg->chunk_size,
SIZE_SHORT));
}
if(snap) {
float fused, fsize;
if(snap_percent == -1)
snap_percent=100;
size = display_size(snap->chunk_size / 2, SIZE_SHORT);
log_print("snapshot chunk size %s", size);
dbg_free(size);
size = display_size(lv->size / 2, SIZE_SHORT);
sscanf(size, "%f", &fsize);
fused = fsize * ( snap_percent / 100 );
log_print("Allocated to snapshot %2.2f%% [%2.2f/%s]",
snap_percent, fused, size);
dbg_free(size);
/* FIXME: Think this'll make them wonder?? */
log_print("Allocated to COW-table %s", "00.01 KB");
}
/** Not in LVM1 format output **
log_print("Segments %u", list_size(&lv->segments));
***/
/********* FIXME Stripes & stripesize for each segment
log_print("Stripe size (KByte) %u", lv->stripesize / 2);
***********/
/**************
#ifdef LVM_FUTURE
printf("Bad block ");
if (lv->lv_badblock == LV_BADBLOCK_ON)
printf("on\n");
else
printf("off\n");
#endif
***************/
/* FIXME next free == ALLOC_SIMPLE */
alloc = lv->status & (ALLOC_STRICT | ALLOC_CONTIGUOUS);
log_print("Allocation %s%s%s%s",
!(alloc & (ALLOC_STRICT | ALLOC_CONTIGUOUS)) ? "next free" :
"", (alloc == ALLOC_STRICT) ? "strict" : "",
(alloc == ALLOC_CONTIGUOUS) ? "contiguous" : "",
(alloc ==
(ALLOC_STRICT | ALLOC_CONTIGUOUS)) ? "strict/contiguous" :
"");
log_print("Allocation %s", get_alloc_string(lv->alloc));
log_print("Read ahead sectors %u", lv->read_ahead);
if (lv->status & FIXED_MINOR)
if (lv->status & FIXED_MINOR) {
if (lv->major >= 0)
log_print("Persistent major %d", lv->major);
log_print("Persistent minor %d", lv->minor);
/****************
#ifdef LVM_FUTURE
printf("IO Timeout (seconds) ");
if (lv->lv_io_timeout == 0)
printf("default\n\n");
else
printf("%lu\n\n", lv->lv_io_timeout);
#endif
*************/
}
if (inkernel)
log_print("Block device %d:%d", info.major,
@@ -408,45 +447,50 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
return 0;
}
void _display_stripe(struct stripe_segment *seg, int s, const char *pre)
void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre)
{
uint32_t len = seg->len / seg->stripes;
switch (seg_type(seg, s)) {
case AREA_PV:
/* FIXME Re-check the conditions for 'Missing' */
log_print("%sPhysical volume\t%s", pre,
seg_pv(seg, s) ?
dev_name(seg_dev(seg, s)) :
"Missing");
log_print("%sphysical volume\t%s", pre,
seg->area[s].pv ? dev_name(seg->area[s].pv->dev) : "Missing");
if (seg_pv(seg, s))
log_print("%sPhysical extents\t%d to %d", pre,
seg_pe(seg, s),
seg_pe(seg, s) + seg->area_len - 1);
break;
case AREA_LV:
log_print("%sLogical volume\t%s", pre,
seg_lv(seg, s) ?
seg_lv(seg, s)->name : "Missing");
if (seg->area[s].pv)
log_print("%sphysical extents\t%d to %d", pre,
seg->area[s].pe, seg->area[s].pe + len - 1);
if (seg_lv(seg, s))
log_print("%sLogical extents\t%d to %d", pre,
seg_le(seg, s),
seg_le(seg, s) + seg->area_len - 1);
break;
case AREA_UNASSIGNED:
log_print("%sUnassigned area", pre);
}
}
int lvdisplay_segments(struct logical_volume *lv)
{
int s;
struct list *segh;
struct stripe_segment *seg;
struct lv_segment *seg;
log_print("--- Segments ---");
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct stripe_segment);
log_print("logical extent %d to %d:",
list_iterate_items(seg, &lv->segments) {
log_print("Logical extent %u to %u:",
seg->le, seg->le + seg->len - 1);
if (seg->stripes == 1)
_display_stripe(seg, 0, " ");
log_print(" Type\t\t%s", seg->segtype->ops->name(seg));
else {
log_print(" stripes\t\t%d", seg->stripes);
log_print(" stripe size\t\t%d", seg->stripe_size);
for (s = 0; s < seg->stripes; s++) {
log_print(" stripe %d:", s);
_display_stripe(seg, s, " ");
}
}
log_print(" ");
if (seg->segtype->ops->display)
seg->segtype->ops->display(seg);
}
log_print(" ");
@@ -461,29 +505,23 @@ void vgdisplay_extents(struct volume_group *vg)
void vgdisplay_full(struct volume_group *vg)
{
uint32_t access;
char *s1;
char uuid[64];
uint32_t active_pvs;
struct list *pvlist;
char uuid[64];
set_cmd_name("");
init_msg_prefix("");
/* get the number of active PVs */
if(vg->status & PARTIAL_VG) {
active_pvs=0;
list_iterate(pvlist, &(vg->pvs)) {
active_pvs++;
}
}
if (vg->status & PARTIAL_VG)
active_pvs = list_size(&vg->pvs);
else
active_pvs=vg->pv_count;
active_pvs = vg->pv_count;
log_print("--- Volume group ---");
log_print("VG Name %s", vg->name);
/****** Not in LVM1 output, so we aren't outputing it here:
log_print("System ID %s", vg->system_id);
*******/
log_print("Format %s", vg->fid->fmt->name);
if (vg->fid->fmt->features & FMT_MDAS) {
log_print("Metadata Areas %d",
list_size(&vg->fid->metadata_areas));
log_print("Metadata Sequence No %d", vg->seqno);
}
access = vg->status & (LVM_READ | LVM_WRITE);
log_print("VG Access %s%s%s%s",
access == (LVM_READ | LVM_WRITE) ? "read/write" : "",
@@ -491,49 +529,49 @@ void vgdisplay_full(struct volume_group *vg)
access == LVM_WRITE ? "write" : "",
access == 0 ? "error" : "");
log_print("VG Status %s%sresizable",
vg->status & EXPORTED_VG ? "exported/" : "available/",
vg->status & EXPORTED_VG ? "exported/" : "",
vg->status & RESIZEABLE_VG ? "" : "NOT ");
/* vg number not part of LVM2 design
log_print ("VG # %u\n", vg->vg_number);
*/
if (vg->status & CLUSTERED) {
log_print("Clustered yes");
log_print("Shared %s",
vg->status & SHARED ? "yes" : "no");
}
/****** FIXME VG # - we aren't implementing this because people should
* use the UUID for this anyway
log_print("VG # %u", vg->vg_number);
*******/
log_print("MAX LV %u", vg->max_lv);
log_print("Cur LV %u", vg->lv_count);
log_print("Open LV %u", lvs_in_vg_opened(vg));
log_print("MAX LV Size 256 TB");
log_print("Cur LV %u", vg->lv_count + vg->snapshot_count);
log_print("Open LV %u", lvs_in_vg_opened(vg));
/****** FIXME Max LV Size
log_print ( "MAX LV Size %s",
( s1 = display_size ( LVM_LV_SIZE_MAX(vg), SIZE_SHORT)));
free ( s1);
*********/
log_print("Max PV %u", vg->max_pv);
log_print("Cur PV %u", vg->pv_count);
log_print("Act PV %u", active_pvs);
log_print("Act PV %u", active_pvs);
s1 =
display_size((uint64_t) vg->extent_count * (vg->extent_size / 2),
SIZE_SHORT);
log_print("VG Size %s", s1);
dbg_free(s1);
log_print("VG Size %s",
display_size(vg->cmd,
(uint64_t) vg->extent_count * vg->extent_size,
SIZE_SHORT));
s1 = display_size(vg->extent_size / 2, SIZE_SHORT);
log_print("PE Size %s", s1);
dbg_free(s1);
log_print("PE Size %s",
display_size(vg->cmd, (uint64_t) vg->extent_size,
SIZE_SHORT));
log_print("Total PE %u", vg->extent_count);
s1 = display_size(((uint64_t)
vg->extent_count - vg->free_count) *
(vg->extent_size / 2), SIZE_SHORT);
log_print("Alloc PE / Size %u / %s",
vg->extent_count - vg->free_count, s1);
dbg_free(s1);
vg->extent_count - vg->free_count,
display_size(vg->cmd,
((uint64_t) vg->extent_count - vg->free_count) *
vg->extent_size, SIZE_SHORT));
s1 =
display_size((uint64_t) vg->free_count * (vg->extent_size / 2),
SIZE_SHORT);
log_print("Free PE / Size %u / %s", vg->free_count, s1);
dbg_free(s1);
log_print("Free PE / Size %u / %s", vg->free_count,
display_size(vg->cmd,
(uint64_t) vg->free_count * vg->extent_size,
SIZE_SHORT));
if (!id_write_format(&vg->id, uuid, sizeof(uuid))) {
stack;
@@ -548,22 +586,88 @@ void vgdisplay_full(struct volume_group *vg)
void vgdisplay_colons(struct volume_group *vg)
{
uint32_t active_pvs;
const char *access;
char uuid[64];
if (vg->status & PARTIAL_VG)
active_pvs = list_size(&vg->pvs);
else
active_pvs = vg->pv_count;
switch (vg->status & (LVM_READ | LVM_WRITE)) {
case LVM_READ | LVM_WRITE:
access = "r/w";
break;
case LVM_READ:
access = "r";
break;
case LVM_WRITE:
access = "w";
break;
default:
access = "";
}
if (!id_write_format(&vg->id, uuid, sizeof(uuid))) {
stack;
return;
}
log_print("%s:%s:%d:-1:%u:%u:%u:-1:%u:%u:%u:%" PRIu64 ":%" PRIu32
":%u:%u:%u:%s",
vg->name,
access,
vg->status,
/* internal volume group number; obsolete */
vg->max_lv,
vg->lv_count,
lvs_in_vg_opened(vg),
/* FIXME: maximum logical volume size */
vg->max_pv,
vg->pv_count,
active_pvs,
(uint64_t) vg->extent_count * (vg->extent_size / 2),
vg->extent_size / 2,
vg->extent_count,
vg->extent_count - vg->free_count,
vg->free_count,
uuid[0] ? uuid : "none");
return;
}
void vgdisplay_short(struct volume_group *vg)
{
char *s1, *s2, *s3;
s1 = display_size(vg->extent_count * vg->extent_size / 2, SIZE_SHORT);
s2 =
display_size((vg->extent_count - vg->free_count) * vg->extent_size /
2, SIZE_SHORT);
s3 = display_size(vg->free_count * vg->extent_size / 2, SIZE_SHORT);
log_print("\"%s\" %-9s [%-9s used / %s free]", vg->name,
/********* FIXME if "open" print "/used" else print "/idle"??? ******/
s1, s2, s3);
dbg_free(s1);
dbg_free(s2);
dbg_free(s3);
display_size(vg->cmd,
(uint64_t) vg->extent_count * vg->extent_size,
SIZE_SHORT),
display_size(vg->cmd,
((uint64_t) vg->extent_count -
vg->free_count) * vg->extent_size,
SIZE_SHORT),
display_size(vg->cmd,
(uint64_t) vg->free_count * vg->extent_size,
SIZE_SHORT));
return;
}
void display_formats(struct cmd_context *cmd)
{
struct format_type *fmt;
list_iterate_items(fmt, &cmd->formats) {
log_print("%s", fmt->name);
}
}
void display_segtypes(struct cmd_context *cmd)
{
struct segment_type *segtype;
list_iterate_items(segtype, &cmd->segtypes) {
log_print("%s", segtype->name);
}
}

View File

@@ -1,21 +1,16 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This file is part of LVM2.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_DISPLAY_H
@@ -25,23 +20,38 @@
#include <stdint.h>
typedef enum {SIZE_LONG=0, SIZE_SHORT=1} size_len_t;
typedef enum { SIZE_LONG = 0, SIZE_SHORT = 1, SIZE_UNIT = 2 } size_len_t;
uint64_t units_to_bytes(const char *units, char *unit_type);
/* Specify size in KB */
char *display_size(uint64_t size, size_len_t sl);
const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl);
char *display_uuid(char *uuidstr);
void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre);
void pvdisplay_colons(struct physical_volume *pv);
void pvdisplay_full(struct physical_volume *pv);
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg, struct physical_volume *pv);
void pvdisplay_full(struct cmd_context *cmd, struct physical_volume *pv,
void *handle);
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv, void *handle);
void lvdisplay_colons(struct logical_volume *lv);
int lvdisplay_segments(struct logical_volume *lv);
int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv);
int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
void *handle);
void vgdisplay_extents(struct volume_group *vg);
void vgdisplay_full(struct volume_group *vg);
void vgdisplay_colons(struct volume_group *vg);
void vgdisplay_short(struct volume_group *vg);
void display_formats(struct cmd_context *cmd);
void display_segtypes(struct cmd_context *cmd);
/*
* Allocation policy display conversion routines.
*/
const char *get_alloc_string(alloc_policy_t alloc);
alloc_policy_t get_alloc_from_string(const char *str);
#endif

96
lib/error/errseg.c Normal file
View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "toolcontext.h"
#include "segtype.h"
#include "display.h"
#include "text_export.h"
#include "text_import.h"
#include "config.h"
#include "str_list.h"
#include "targets.h"
#include "lvm-string.h"
#include "activate.h"
static const char *_name(const struct lv_segment *seg)
{
return seg->segtype->name;
}
static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
{
seg1->len += seg2->len;
seg1->area_len += seg2->area_len;
return 1;
}
#ifdef DEVMAPPER_SUPPORT
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg,
struct dm_tree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count)
{
return dm_tree_node_add_error_target(node, len);
}
static int _target_present(void)
{
static int checked = 0;
static int present = 0;
/* Reported truncated in older kernels */
if (!checked &&
(target_present("error", 0) || target_present("erro", 0)))
present = 1;
checked = 1;
return present;
}
#endif
static void _destroy(const struct segment_type *segtype)
{
dm_free((void *) segtype);
}
static struct segtype_handler _error_ops = {
name:_name,
merge_segments:_merge_segments,
#ifdef DEVMAPPER_SUPPORT
add_target_line:_add_target_line,
target_present:_target_present,
#endif
destroy:_destroy,
};
struct segment_type *init_error_segtype(struct cmd_context *cmd)
{
struct segment_type *segtype = dm_malloc(sizeof(*segtype));
if (!segtype)
return_NULL;
segtype->cmd = cmd;
segtype->ops = &_error_ops;
segtype->name = "error";
segtype->private = NULL;
segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
log_very_verbose("Initialised segtype: %s", segtype->name);
return segtype;
}

View File

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

View File

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

80
lib/filters/filter-md.c Normal file
View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2004 Luca Berra
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "filter-md.h"
#include "metadata.h"
#ifdef linux
/* Lifted from <linux/raid/md_p.h> because of difficulty including it */
#define MD_SB_MAGIC 0xa92b4efc
#define MD_RESERVED_BYTES (64 * 1024)
#define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512)
#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) \
- MD_RESERVED_SECTORS)
static int _ignore_md(struct dev_filter *f, struct device *dev)
{
int ret;
if (!md_filtering())
return 1;
ret = dev_is_md(dev, NULL);
if (ret == 1) {
log_debug("%s: Skipping md component device", dev_name(dev));
return 0;
}
if (ret < 0) {
log_debug("%s: Skipping: error in md component detection",
dev_name(dev));
return 0;
}
return 1;
}
static void _destroy(struct dev_filter *f)
{
dm_free(f);
}
struct dev_filter *md_filter_create(void)
{
struct dev_filter *f;
if (!(f = dm_malloc(sizeof(*f)))) {
log_error("md filter allocation failed");
return NULL;
}
f->passes_filter = _ignore_md;
f->destroy = _destroy;
f->private = NULL;
return f;
}
#else
struct dev_filter *md_filter_create(void)
{
return NULL;
}
#endif

23
lib/filters/filter-md.h Normal file
View File

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

View File

@@ -1,24 +1,30 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "config.h"
#include "dev-cache.h"
#include "hash.h"
#include "dbg_malloc.h"
#include "log.h"
#include "filter-persistent.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
struct pfilter {
char *file;
struct hash_table *devices;
struct dm_hash_table *devices;
struct dev_filter *real;
};
@@ -32,27 +38,36 @@ struct pfilter {
static int _init_hash(struct pfilter *pf)
{
if (pf->devices)
hash_destroy(pf->devices);
dm_hash_destroy(pf->devices);
pf->devices = hash_create(128);
return pf->devices ? 1 : 0;
if (!(pf->devices = dm_hash_create(128))) {
stack;
return 0;
}
return 1;
}
int persistent_filter_wipe(struct dev_filter *f)
{
struct pfilter *pf = (struct pfilter *) f->private;
hash_wipe(pf->devices);
log_verbose("Wiping cache of LVM-capable devices");
dm_hash_wipe(pf->devices);
/* Trigger complete device scan */
dev_cache_scan(1);
return 1;
}
static int _read_array(struct pfilter *pf, struct config_file *cf,
static int _read_array(struct pfilter *pf, struct config_tree *cft,
const char *path, void *data)
{
struct config_node *cn;
const struct config_node *cn;
struct config_value *cv;
if (!(cn = find_config_node(cf->root, path, '/'))) {
if (!(cn = find_config_node(cft->root, path))) {
log_very_verbose("Couldn't find %s array in '%s'",
path, pf->file);
return 0;
@@ -69,9 +84,11 @@ static int _read_array(struct pfilter *pf, struct config_file *cf,
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 */
dev_cache_get(cv->v.str, NULL);
}
return 1;
}
@@ -81,41 +98,48 @@ int persistent_filter_load(struct dev_filter *f)
struct pfilter *pf = (struct pfilter *) f->private;
int r = 0;
struct config_file *cf;
struct config_tree *cft;
if (!(cf = create_config_file())) {
if (!(cft = create_config_tree(pf->file))) {
stack;
return 0;
}
if (!read_config(cf, pf->file)) {
if (!read_config_file(cft)) {
stack;
goto out;
}
_read_array(pf, cf, "persistent_filter_cache/valid_devices",
_read_array(pf, cft, "persistent_filter_cache/valid_devices",
PF_GOOD_DEVICE);
_read_array(pf, cf, "persistent_filter_cache/invalid_devices",
PF_BAD_DEVICE);
/* We don't gain anything by holding invalid devices */
/* _read_array(pf, cft, "persistent_filter_cache/invalid_devices",
PF_BAD_DEVICE); */
if (hash_get_num_entries(pf->devices))
/* Did we find anything? */
if (dm_hash_get_num_entries(pf->devices)) {
/* We populated dev_cache ourselves */
dev_cache_scan(0);
r = 1;
}
log_very_verbose("Loaded persistent filter cache from %s", pf->file);
out:
destroy_config_file(cf);
destroy_config_tree(cft);
return r;
}
static void _write_array(struct pfilter *pf, FILE * fp, const char *path,
static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
void *data)
{
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;
@@ -127,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)
@@ -142,16 +166,23 @@ 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;
}
if (!dev_cache_has_scanned()) {
log_very_verbose("Device cache incomplete - not writing "
"to %s", pf->file);
return 0;
}
log_very_verbose("Dumping persistent device cache to %s", pf->file);
fp = fopen(pf->file, "w");
if (!fp) {
log_sys_error("fopen", pf->file);
if (errno != EROFS)
log_sys_error("fopen", pf->file);
return 0;
}
@@ -159,7 +190,8 @@ int persistent_filter_dump(struct dev_filter *f)
fprintf(fp, "persistent_filter_cache {\n");
_write_array(pf, fp, "valid_devices", PF_GOOD_DEVICE);
_write_array(pf, fp, "invalid_devices", PF_BAD_DEVICE);
/* We don't gain anything by remembering invalid devices */
/* _write_array(pf, fp, "invalid_devices", PF_BAD_DEVICE); */
fprintf(fp, "}\n");
fclose(fp);
@@ -169,32 +201,31 @@ 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;
struct list *ah;
if (!l) {
l = pf->real->passes_filter(pf->real, dev) ?
PF_GOOD_DEVICE : PF_BAD_DEVICE;
list_iterate(ah, &dev->aliases) {
sl = list_item(ah, struct str_list);
hash_insert(pf->devices, sl->str, l);
}
}
list_iterate_items(sl, &dev->aliases)
dm_hash_insert(pf->devices, sl->str, l);
return l == PF_GOOD_DEVICE;
} else if (l == PF_BAD_DEVICE)
log_debug("%s: Skipping (cached)", dev_name(dev));
return (l == PF_BAD_DEVICE) ? 0 : 1;
}
static void _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,
@@ -203,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;
}
@@ -221,7 +252,7 @@ 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;
}
@@ -233,10 +264,10 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
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;
}

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