1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-07 09:44:20 +03:00

Compare commits

..

1409 Commits

Author SHA1 Message Date
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
Alasdair Kergon
eff96d839e Revert to standard linux macros (for correct behaviour on rare architectures). 2002-05-21 12:37:07 +00:00
Alasdair Kergon
aa34c23807 Update version. 2002-05-21 12:14:05 +00:00
Andres Salomon
195acdac8c ack, missing include 2002-05-19 04:11:34 +00:00
Andres Salomon
903e03c56c update create_dir() comment 2002-05-19 03:52:38 +00:00
Andres Salomon
0892767b8a support recursive mkdir in create_dir() 2002-05-19 03:46:34 +00:00
Andres Salomon
83ebfa772c synch w/ -3 "oh shit" release 2002-05-14 03:56:40 +00:00
Joe Thornber
1583641322 Drop the default chunk size for snapshots down to 8k 2002-05-13 15:14:21 +00:00
Alasdair Kergon
9510e2c256 Rewrite missing/corrupt metadata in more cases. 2002-05-13 12:38:54 +00:00
AJ Lewis
a9dbabe07e o the _status fxns now take more arguments - this way i don't get the
preparsed status info, shove it all into a string, and then parse it
   again to get the info back out (which is what i was doing before)
 o basically that's it...i like this *much* better than the previous
   method and i think it makes the _status fxn more flexible if we need
   to use it to get other info out.
2002-05-10 16:06:06 +00:00
Alasdair Kergon
12884008fa Import snapshot status & persistence + indent etc. 2002-05-10 15:25:38 +00:00
AJ Lewis
02543bad1c o Actually read snapshot percentage from the kernel - what a pain! :)
o Not sure if the code in dev_manager is really optimal, but it works..
   will look at adjusting it a bit now.
 o I *think* it works right when one snapshot if full but others aren't,
   but I haven't really been able to test it because the full snapshot
   somehow resets itself and weird things start happening to the system...
2002-05-09 21:17:57 +00:00
Alasdair Kergon
a8c56a5251 Remove a no-op. 2002-05-09 12:03:55 +00:00
AJ Lewis
4e5a855f3f o header should only be printed once... 2002-05-08 17:58:52 +00:00
AJ Lewis
7e497a951e o Added function find_snapshots to snapshot_manip.c that returns a list
of snapshots whose origin is the lv passed in.
 o Used this new function to make lvdisplay properly display all snapshots
   attached to a origin.
2002-05-08 16:57:46 +00:00
Joe Thornber
cd08eabbfa i) Put back chunksize_ARG for lvcreate. 2002-05-08 14:36:10 +00:00
Alasdair Kergon
f7e62d9f81 Always call init_log() to initialise logging defaults. 2002-05-08 12:26:45 +00:00
Andres Salomon
9a3761e86e implement our own swabbing functions, instead of relying on the kernel's. 2002-05-07 15:28:59 +00:00
Alasdair Kergon
3619a68693 log/{prefix,command_names} use defaults.h & reset between shell cmds 2002-05-07 13:00:01 +00:00
Alasdair Kergon
efaf3c3bf9 Default values for some display output settings 2002-05-07 12:50:01 +00:00
Alasdair Kergon
0e4e6a6f67 Tweaks 2002-05-07 12:47:11 +00:00
Andres Salomon
42458e6278 updated. 2002-05-07 06:13:03 +00:00
Andres Salomon
41ec995377 Make lvm2 compile on big endian archs; use the kernel/glibc's endian
conversion stuff, instead of implementing our own.  Tested on a little
endian system (x86); I'll let the debian handle big endian testing.  :)
2002-05-07 05:54:14 +00:00
AJ Lewis
4f37599326 o Will now correctly remove expired achive files from the system when
archive_vg is called.
 o Added a #define to the top of the file - not sure if this is the
   appropriate place for it though
2002-05-03 19:28:07 +00:00
Patrick Caulfield
4144520e5c Add features to get table/status & wait for next event. 2002-05-03 11:55:58 +00:00
Andres Salomon
6c4800546c forgot to add Conflicts against lvm1 packages 2002-05-03 04:57:49 +00:00
Andres Salomon
733733c8a7 updated for 0.95.05-2. 2002-05-03 04:43:46 +00:00
Andres Salomon
2aa67cc946 ditto 2002-05-03 04:43:24 +00:00
Andres Salomon
9385981a9d dh_installinit makes a perfectly find postrm script.. 2002-05-03 04:13:02 +00:00
Alasdair Kergon
fff780035d Update. 2002-04-30 17:13:43 +00:00
Alasdair Kergon
46127e673d Some partial VG support with format_text. 2002-04-30 17:12:37 +00:00
Alasdair Kergon
70df59b224 get_vgs must check for text format VGs when no lvm1 format VGs present 2002-04-30 12:27:13 +00:00
AJ Lewis
0fdbaa803f o Updated *display output for LVM1 compatibility
o There is still a bit missing
   + all are missing the {PV,VG,LV} # - that is not applicable in LVM2
   + pvdisplay doesn't show how many LVs are contained on it
   + much of the snapshot information isn't available for lvdisplay
 o Look at the code for other potiential FIXMEs  :)
2002-04-29 21:43:14 +00:00
Heinz Mauelshagen
6af1830eff Changed DEFAULT_PV and DEFAULT_LV to 256 (has been fixed in LVM1 before) 2002-04-25 10:53:58 +00:00
Andres Salomon
6f860e2bd5 Updated for new release 2002-04-25 06:12:07 +00:00
Alasdair Kergon
20a492f7ee Update example config 2002-04-24 18:41:02 +00:00
Alasdair Kergon
63875e7591 Merge with text format branch.
Lots of changes/very little testing so far => there'll be bugs!

Use 'vgcreate -M text' to create a volume group with its metadata stored
in text files.  Text format metadata changes should be reasonably atomic,
with a (basic) automatic recovery mechanism if the system crashes while a
change is in progress.

Add a metadata section to lvm.conf to specify multiple directories if
you want (recommended) to keep multiple copies of the metadata (eg on
different filesystems).

e.g. metadata {
        dirs = ["/etc/lvm/metadata1","/usr/local/lvm/metadata2"]
}

Plenty of refinements still in the pipeline.
2002-04-24 18:20:51 +00:00
Patrick Caulfield
0ad98cabde add setlocale() call so that localisation of things like number entry
and display will work correctly.
2002-04-24 10:42:09 +00:00
Joe Thornber
668879d2e1 o Stop printing errors if flushing fails (could be an unconfigured device). 2002-04-24 08:37:34 +00:00
Alasdair Kergon
2e09783302 Prepare for another beta release. 2002-04-23 22:13:04 +00:00
Alasdair Kergon
49734114b3 Commit snapshot-related changes preparing for the next beta release. 2002-04-23 21:47:50 +00:00
Alasdair Kergon
950d9d6ee7 Missing seg->lv gives segfault when activating from text format. 2002-04-16 19:41:54 +00:00
Alasdair Kergon
f7974aee2e Allow deactivation of final snapshot. 2002-04-16 14:42:20 +00:00
Joe Thornber
c870a82621 o Added support for chunk_size to lvcreate. 2002-04-15 18:49:20 +00:00
Alasdair Kergon
984929a001 Missing VG lock when iterating through all LVs. 2002-04-15 16:27:39 +00:00
Patrick Caulfield
7f9e2c1db8 More memory leak plugging. 2002-04-15 13:24:14 +00:00
Joe Thornber
324e8389dc o Drop the default chunk size for snapshots down to 16k. 2002-04-15 08:41:00 +00:00
Alasdair Kergon
6f448c5a38 Implement a no_locking module that *does* attempt activation. 2002-04-11 14:10:32 +00:00
Patrick Caulfield
ec43efbb20 Rename device node during a DM_RENAME command. 2002-04-11 12:45:18 +00:00
Patrick Caulfield
3ed065de37 Return status from _lv_activate and friends.
Alasdair, I think this is right (and I need it) but you may like to check.
2002-04-11 09:14:04 +00:00
Patrick Caulfield
8152f0d72c Remove \n from log messages. 2002-04-10 15:49:47 +00:00
Joe Thornber
f8047f4736 o Perform a BLKFLSBUF ioctl whenever a block device is closed.
Patrick, can you see if this fixes your cluster syncing problem please ?
If so I'll make it so it only syncs if you have actually written to the
device.
2002-04-08 18:59:50 +00:00
Patrick Caulfield
b93c66dc2d Implement an external locking interface. 2002-04-08 16:04:50 +00:00
Patrick Caulfield
ac877b3065 Fix prototype. 2002-04-08 13:35:09 +00:00
Alasdair Kergon
dee8abfdde Fix lv_setup() not to generate a new lvid each time if asked to setup the
same LV more than once - subsequent times validate only.
2002-04-05 14:32:22 +00:00
Patrick Caulfield
cef3841d73 Make lock type numbers match the DLM numbers in use, and move UNLOCK out
of the way.
2002-04-04 13:31:21 +00:00
Alasdair Kergon
3cd5e8a041 Rename LCK_NONE to LCK_UNLOCK 2002-04-04 11:18:45 +00:00
Alasdair Kergon
515b5f866e Tidying. 2002-04-03 12:17:55 +00:00
Alasdair Kergon
321f62bf92 Cope with creation of additional snapshots while active.
(More work on suspension dependencies still needed.)
2002-03-27 18:17:43 +00:00
Alasdair Kergon
f94fa47b52 Snapshots are now attached to their origin device for locking purposes
so lock the origin instead of the snapshot itself when creating one.
2002-03-26 15:01:57 +00:00
Alasdair Kergon
c502f8a722 New-style persistent minor support. 2002-03-26 13:41:37 +00:00
Alasdair Kergon
59b4868ac3 o read-only device support
o name/uuid disambiguation
2002-03-25 18:54:59 +00:00
Alasdair Kergon
3634e12cce Fix typo. 2002-03-25 18:50:37 +00:00
Andres Salomon
6d45445391 all people to actually uninstall lvm2 (*grin*) 2002-03-23 08:23:15 +00:00
Alasdair Kergon
4f47e268cc Improve log messages. 2002-03-20 14:34:15 +00:00
Alasdair Kergon
0035b31cdb Better support for LVs with hyphens in names. 2002-03-19 16:41:44 +00:00
Alasdair Kergon
f2565aee03 Support device queries by uuid as well as by name. (Used by lvrename.) 2002-03-18 23:39:42 +00:00
Alasdair Kergon
5bd85668dd lvrename works on snapshots now 2002-03-18 23:25:50 +00:00
Alasdair Kergon
20f990b6ce Tie all snapshot (de)activation requests to (de)activation of origin device. 2002-03-18 13:09:27 +00:00
Alasdair Kergon
6821379586 s/Removing/Unloading/ in messages to reduce confusion 2002-03-15 23:01:59 +00:00
Alasdair Kergon
73b040eb49 Cut the number of device-mapper calls. 2002-03-15 22:59:12 +00:00
Alasdair Kergon
49aa4b2e1e New function to enable suppression of messages to stdout/stderr. 2002-03-15 22:54:04 +00:00
Alasdair Kergon
972241c74c Review locking: block signals instead of ignoring them and restore state
afterwards; avoid race condition with unlink; add LCK_HOLD to process_each_vg.
2002-03-15 16:07:38 +00:00
Alasdair Kergon
680750e3c2 Reduce the number of dm info calls. 2002-03-14 21:17:30 +00:00
Alasdair Kergon
5e7d4d9d15 distclean also to remove libdm-common.h 2002-03-14 16:56:02 +00:00
Alasdair Kergon
1e57e60613 Integrate suspend. 2002-03-14 15:36:07 +00:00
Alasdair Kergon
3ac7ce605a Suppress verbose/debug messages from libdevmapper. 2002-03-14 13:39:33 +00:00
Joe Thornber
b720dea9f0 o dev_manager_suspend, untested. 2002-03-14 10:56:09 +00:00
Alasdair Kergon
c80722aefe A missing free() found by Valgrind. ( http://developer.kde.org/~sewardj/ ) 2002-03-13 23:19:20 +00:00
Alasdair Kergon
a84fa69f28 dmsetup display uuid 2002-03-13 16:19:17 +00:00
Alasdair Kergon
e33781e59f Set LV uuid. 2002-03-13 15:11:29 +00:00
Joe Thornber
8824bc7ece o Mention that vgscan needs to be run after changing the filter var. 2002-03-13 14:25:53 +00:00
Patrick Caulfield
c2e3b0e448 Fix _align so it works on 64-bit machines. 2002-03-12 15:27:51 +00:00
Alasdair Kergon
f61a38e85a Let dmsetup store the uuid on device creation. 2002-03-11 22:44:36 +00:00
Alasdair Kergon
d23e948216 Move is_empty_dir to lvm-file 2002-03-11 22:23:24 +00:00
Joe Thornber
58bdaa31f0 o Actually check that the vg directory is empty rather than speculatively
rmdiring it.  Work around for devfs bug.
2002-03-11 20:43:58 +00:00
Joe Thornber
b6491d88a6 o This should complete the dev_manager alg. Please could people now
report any activation oddities they see.
2002-03-11 20:36:04 +00:00
Alasdair Kergon
f6061ba62e lv_info replaces lv_active etc. 2002-03-11 19:02:28 +00:00
Alasdair Kergon
427899ddce o activate/reactivate merge
o unlocking macro
2002-03-11 15:08:39 +00:00
Joe Thornber
c4ab7d2dbd o dm->active_list now filled in, ATM this is based on the layer name rather
than the uuid.
2002-03-11 11:27:48 +00:00
Joe Thornber
0fd2ba033f o Comment out some new code that was preventing pjc activating
snapshots.  This will go back in when the active_list is working.
2002-03-11 10:38:16 +00:00
Joe Thornber
ed38939a93 o knock out the offset for origin targets. 2002-03-08 10:45:01 +00:00
Joe Thornber
c7ee26ce5a o Add active_list to dev_manager
o  Origin layer is only added to snapshots if a snapshot is in the
   active_list.
2002-03-08 10:41:48 +00:00
Andres Salomon
909b8cb303 heh, whoops. s/device-mapper/LVM2/g. 2002-03-08 02:39:08 +00:00
Alasdair Kergon
b0277370cf o dm_destroy_all() called on exit - but doesn't touch suspended devices yet.
o 'dmsetup remove_all' calls dm_destroy_all() to provide a quick way to
  prepare for unloading the module
o Ran through indent again.
2002-03-07 20:56:10 +00:00
Joe Thornber
2ec8656bea o First cut at dev scanning.
o  Split up _expand_lv
2002-03-07 17:37:38 +00:00
Joe Thornber
b2ef256910 o Add comment describing what we're aiming for with dev_manager.
o  Remove dev_manager_reactivate, since it'll be the same as activate.

o  Merge the mark, visible and dirty fields into the same flags field.
2002-03-07 16:48:46 +00:00
Joe Thornber
63d6ce95db o Top level device is now just called <vg>-<lv> (there's no 'top'
layer appended).

o  Got rid of the unused layer->type field and enum.
2002-03-07 15:29:31 +00:00
Alasdair Kergon
a9532b189c Kernel functionality that returns device dependencies (ejt). 2002-03-06 19:42:23 +00:00
Joe Thornber
844545411f o Rename dmsetup dependencies -> dmsetup deps 2002-03-06 14:47:13 +00:00
Joe Thornber
4e23a2b9b8 o Add support for getting dependencies for a device.
o  dmsetup dependencies <dev>
2002-03-06 14:38:25 +00:00
Andres Salomon
5deba027eb convert from debian native package 2002-03-06 05:43:54 +00:00
Alasdair Kergon
fc8b7efc6f o Use new LCK_HOLD flag to indicate whether lock should be held on return
from lock_vol() - otherwise it now attempts to acquire the lock and then
  immediately releases it.
o Extend the id field in struct logical_volume to hold VG uuid + LV uuid
  for format1. This unique lvid can be used directly when calling lock_vol().
o Add the VG uuid to vgcache to make VG uuid lookups possible.  (Another
  step towards using them instead of VG names internally.)
2002-03-05 20:03:09 +00:00
Alasdair Kergon
a1c2d9c0f3 Fix activation for VG with more than one LV. 2002-03-04 18:50:34 +00:00
Alasdair Kergon
4ca49a0501 snapshot/zero logic 2002-03-04 15:25:52 +00:00
Joe Thornber
493c53d090 o Add a line to lvdisplay to say if the volume is a snapshot. 2002-03-04 15:12:30 +00:00
Joe Thornber
b27e956d35 o Bad dependency, meant the origin was always getting activated. 2002-03-04 15:10:30 +00:00
Alasdair Kergon
35ebed75c6 Remove unused fns. 2002-03-04 14:27:25 +00:00
Joe Thornber
7bfdb5f77f o I was tearing down device bottom-up instead of top down. Which
is why lvremove of snapshots wasn't working.
2002-03-04 14:26:43 +00:00
Joe Thornber
8d8c02317f o Break creating a snapshot down into:
i)   create cow
   ii)  activate cow
   iii) zero cow
   iv)  deactivate
   v)   add snapshot info
   vi)  reactivate
2002-03-04 13:46:37 +00:00
Andres Salomon
a34482feab proper /etc/lvm/lvm.conf now 2002-03-04 11:13:47 +00:00
Andres Salomon
cbdc8fd4a6 fix various issues 2002-03-04 11:12:57 +00:00
Alasdair Kergon
8d3afaa53c More use of LV locking. 2002-03-01 19:08:11 +00:00
Joe Thornber
7ced9ef3df o point snapshots at origin:real rather than origin:top, and *ping*
snapshots work.
2002-03-01 09:07:00 +00:00
Alasdair Kergon
e8a9ae7e80 Fix unlock parameter. 2002-02-27 14:48:42 +00:00
Alasdair Kergon
73a88ab3d3 o Lock mechanism for LV activation
o #defines for common lock flag combinations
o Try out hyphens instead of colons in device-mapper names - does this
  make messages containing filenames easier to read?
2002-02-27 12:26:41 +00:00
Alasdair Kergon
aaed82738a Running out of filehandles? Close /dev/device-mapper/control then. 2002-02-26 18:30:02 +00:00
Joe Thornber
de7f7b96db o Format1 wasn't recording the snapshot chunk size properly
o  Activation of snapshots now works - though the resulting device
   doesn't (pjc ?)

o  text format wasn't setting vg->cmd.
2002-02-26 16:48:52 +00:00
Alasdair Kergon
1a669b3e68 Clearer link pathname display. 2002-02-26 16:08:22 +00:00
Joe Thornber
333af9b13a o _build_name was allocating 1 byte too few, which meant the
terminating zero was falling off at some later point.

o Don't try and iterate from a deleted node in _prune_unmarked.
2002-02-26 14:44:13 +00:00
Joe Thornber
a5bca5e240 o Removed old files
o  rewrote activate.c to use dev-manager, I'm sure these two will merge
   at some point.

o  Rename is broken ATM

o  dev-manager puts the calls through to fs.c for layers that have the
   'visible' flag set.
2002-02-26 11:49:17 +00:00
Joe Thornber
c885633e02 o More dev_manager fns. 2002-02-25 16:53:12 +00:00
Heinz Mauelshagen
ca7e20b7ca pvresize command 2002-02-25 15:32:58 +00:00
Joe Thornber
545e11a3d7 o In go the populate functions. 2002-02-25 15:19:53 +00:00
Joe Thornber
44f5287664 o More dev_manager work. 2002-02-25 14:46:57 +00:00
Alasdair Kergon
cf510897f1 Begin conversion so LV id is passed to activation unit instead of
struct logical_volume.
2002-02-25 12:56:16 +00:00
Joe Thornber
1d171345f8 o Sync with cvs, dev_manager still needs to be wired into activate.c 2002-02-25 12:02:33 +00:00
Joe Thornber
4fa7e1cd49 o Remove the vg argument from find_cow 2002-02-25 11:55:39 +00:00
Joe Thornber
acd008298e o hash_iterate -> hash_iter 2002-02-25 11:54:15 +00:00
Joe Thornber
83a8021515 o Added a macro called hash_iterate, that is similar to list_iterate
o Renamed hash_iterate function, hash_iter.
2002-02-25 11:52:58 +00:00
Alasdair Kergon
cf88dfb1db indent 2002-02-24 22:31:55 +00:00
Heinz Mauelshagen
8937c4b481 lvmdiskscan 2002-02-22 13:17:46 +00:00
Patrick Caulfield
cc6af10a4d Fill in format_text functions.
Sort of seems to work.
2002-02-22 11:44:56 +00:00
Alasdair Kergon
6d94578955 o Convert lv->id back to lv_number when writing back to disk
o Use first unused lv_number when creating new LV
o Use lv_number for refs to snapshots
o Update persistent minor logic after the lvcreate restructure
o Reset all parameters before use in lvcreate.
2002-02-21 19:04:37 +00:00
Heinz Mauelshagen
08442ab71e Avoid ambigous volume_group argument in vg_add_snapshot() 2002-02-21 18:31:48 +00:00
Alasdair Kergon
10d91d213f Generate LV uuid from lv_number when reading in LVs. 2002-02-21 15:26:44 +00:00
Heinz Mauelshagen
b7a3b06994 Removed wrong 'lv->vg' argument from lv_is_cow() call. Is used in lv_is_cow internally. 2002-02-21 14:00:45 +00:00
Joe Thornber
5f12c37f23 o typo 2002-02-21 10:17:01 +00:00
Joe Thornber
585edebccd o add find_cow function. 2002-02-21 10:16:33 +00:00
Joe Thornber
9921c62234 o misc little fixes. 2002-02-21 10:15:54 +00:00
Andres Salomon
1ac76d2e16 ah, it was that "set -e" that was the culprit.. 2002-02-21 08:52:36 +00:00
Andres Salomon
6e983bf400 stop init script from returning w/ non-zero if not really an error 2002-02-21 08:30:14 +00:00
Alasdair Kergon
6a8fd4fa6e Try out using LV locking for reactivation. 2002-02-20 21:30:27 +00:00
Alasdair Kergon
3698eaa2d2 Remove lv_update_write_access: use lv_reactivate directly now instead. 2002-02-20 21:28:22 +00:00
Alasdair Kergon
8d97ca433c Suppress meaningless <backtrace> msg on screen (no prog/line number given) 2002-02-20 21:26:40 +00:00
Alasdair Kergon
23cc65e537 lvd->lv_access & LV_SNAPSHOT not lvd->lv_status 2002-02-20 21:24:45 +00:00
Alasdair Kergon
2f5a3c2bbe Remove VG arg from lv_is_cow() and lv_is_origin() - use lv->vg instead. 2002-02-20 19:04:55 +00:00
Alasdair Kergon
f6485616cd o Use 'pvcreate --setphysicalvolumesize' with no short form (instead of -s)
and add severe warning if it's used to make a device seem bigger than
  it really is.  This is not an option people should be using as it
  breaks metadata integrity.
o Use uint64_t throughout (rather than unsigned long long)
o Convert a few messages that contain pathnames into the more common form:
  pathname: message
2002-02-20 18:29:30 +00:00
Andres Salomon
6544fb43d9 initial lvm2 debian packages; still missing some manpages, but otherwise lintian passes
E: lvm2: binary-without-manpage e2fsadm
E: lvm2: binary-without-manpage lvmdiskscan
E: lvm2: binary-without-manpage lvmsadc
E: lvm2: binary-without-manpage lvmsar
E: lvm2: binary-without-manpage lvresize
E: lvm2: binary-without-manpage pvdata
E: lvm2: binary-without-manpage pvmove
E: lvm2: binary-without-manpage version
E: lvm2: binary-without-manpage vgcfgrestore
E: lvm2: binary-without-manpage vgexport
E: lvm2: binary-without-manpage vgimport
E: lvm2: binary-without-manpage vgmknodes
E: lvm2: binary-without-manpage vgsplit
2002-02-20 10:28:49 +00:00
Andres Salomon
a954b32dcc install all the manpages (another make-lintian-happy exercise) 2002-02-20 10:22:02 +00:00
Joe Thornber
426dc7836c o Removed the -z (suspend) option from the tools
o  New function: int lv_setup_cow_store(struct logical_volume *lv)
   This zeroes the start of the cow device.

o  Made lvcreate call above fn.
2002-02-18 15:52:48 +00:00
Joe Thornber
ff941ffc16 o small bug in the format1 export code for snapshots.
o  tidied newlines in the snapshot section of format text.
2002-02-18 11:25:43 +00:00
Joe Thornber
a063c201df o Add support for the -s and -c flags to lvcreate. 2002-02-18 10:59:51 +00:00
Heinz Mauelshagen
e2be3fa0aa Second path on "pvcreate -s" 2002-02-15 14:33:59 +00:00
Joe Thornber
609da6fb50 o split lvcreate into seperate functions for parsing the command line,
and creating the lv.  A lot of changes in here so be on the lookout
   for bugs.
2002-02-15 11:53:22 +00:00
Heinz Mauelshagen
fc9f3ccec3 Forgot to remove test printf :-) 2002-02-15 09:37:23 +00:00
Heinz Mauelshagen
f7baa67a0a First cut on "pvcreate -s" 2002-02-15 01:26:16 +00:00
Joe Thornber
e8d78c2cdb o Initialise the snapshot list properly in vgcreate. 2002-02-14 15:06:24 +00:00
Joe Thornber
9d33366092 o Define _read_uint32 2002-02-14 14:52:21 +00:00
Heinz Mauelshagen
f5d61515c2 test printf removed 2002-02-13 21:30:51 +00:00
Heinz Mauelshagen
711a04a972 LV maximum size limit of 2TB ensured in _lv_setup() 2002-02-13 21:28:56 +00:00
Heinz Mauelshagen
e5b470a3f1 spaces 2002-02-13 21:28:15 +00:00
Heinz Mauelshagen
31820e1e22 > 2TB numbers in vgdisplay_full 2002-02-13 20:21:13 +00:00
Joe Thornber
4849e8cd6d o snapshot support for the text format.
The logical_volumes, and snapshots sections of the text format are now
optional.
2002-02-13 13:29:16 +00:00
Joe Thornber
77e3b460aa o First pass at format1 snapshot support. 2002-02-13 11:43:29 +00:00
Joe Thornber
b5321001f8 o First changes to add snapshot support.
I'm taking a different route from LVM1 here in that snapshots are a
seperate entity from the logical volumes, I think of them as an
application of an LV (or two lvs rather).  As such there is a list of
snapshots held against the vg, and there is *not* a SNAPSHOT, or
SHAPSHOT_ORG flag in lv->status.
2002-02-12 16:31:31 +00:00
Patrick Caulfield
38eba9f5ea use portable <inttypes.h> macros for printing. 2002-02-12 14:12:13 +00:00
Joe Thornber
ea6f399454 o Turn the device_create_* functions into device_populate_*, they only
fill in an already created dm_task.  This allows common code, such
  as minor number selection, and read_only to be lifted.
2002-02-12 11:15:45 +00:00
Alasdair Kergon
f8bf2d7b7d Run through indent - no (intentional) changes to any code. 2002-02-11 21:00:35 +00:00
Alasdair Kergon
c4856caebb Preparation for an LVM2 liblvm - pass cmd_context into each tool and
link some globals that the tools need into that structure.
2002-02-11 20:50:53 +00:00
Alasdair Kergon
fc1030bb22 Now that most of the usage of 'stack' only occurs when there's an error,
don't suppress it from the screen output any longer.
2002-02-11 18:25:18 +00:00
Alasdair Kergon
9eb6cad8dc dbg_free(tc->desc) 2002-02-11 18:21:54 +00:00
Alasdair Kergon
0fa2a78dce Document return codes. 2002-02-11 17:42:02 +00:00
Joe Thornber
a56fa1558b o Split activate.c into a high level (remaining in activate.c) and low level (ll-activate.[hc]) API.
o  Creation of a device from an lv now lives in activate-lv.c
2002-02-11 15:48:34 +00:00
Alasdair Kergon
261c73a997 o Support locking with local lock files
o Disable control-c during updates (except if blocked waiting for a lock)
2002-02-11 15:42:34 +00:00
Joe Thornber
929c1333ca o Little recipe for testing LVM2 with loopback devices. 2002-02-11 12:01:59 +00:00
Joe Thornber
286a79d94d o Added functions to display what's in the archive.
o  For now vgcfgrestore -l <vg> displays this list.

A bit hacky, but it'll get better.
2002-02-11 11:43:17 +00:00
Alasdair Kergon
8b951f99da Locking prototypes. 2002-02-08 14:30:37 +00:00
Alasdair Kergon
abb449bca0 move defaults.h 2002-02-08 14:28:52 +00:00
Alasdair Kergon
bd084028d1 Move defaults.h 2002-02-08 14:28:14 +00:00
Joe Thornber
138a27570b o I decided that the archive_format shouldn't really be a format at
all since it only supports vg_write.  It has been replaced with:

int archive_vg(struct volume_group *vg,
	       const char *dir,
	       const char *desc,
	       uint32_t retain_days,
	       uint32_t min_archive);

which is now called directly by tools/archive.c
2002-02-08 11:58:18 +00:00
Joe Thornber
c2ed40a74f o Add cmd_line field to struct cmd_context
o  Text format now has a description and time field at the top level.

o  archiving and backup set the description appropriately. eg,

   for an archive:

     description = "Created *before* executing 'lvextend test_vg/lvol0 -l +1'."
     creation_time = 1013166332

   for a backup:

     description = "Created *after* executing 'lvextend test_vg/lvol0 -l +1'."
     creation_time = 1013166332

This is preparing the way for a simple vgcfgundo command.
2002-02-08 11:13:47 +00:00
Heinz Mauelshagen
a7e7a00cab Poor mans lvmdiskscan 2002-02-05 14:31:57 +00:00
Alasdair Kergon
64a31ab3cd Another release (includes some fixes from last week; persistent minors,
partial activation etc.)
2002-02-04 13:30:21 +00:00
Alasdair Kergon
71958bc0f1 lv->minor >= 0 (ejt) 2002-02-04 13:08:31 +00:00
Alasdair Kergon
366ec35612 Basic support for persistent minor numbers;
slightly different from the current LVM1 method.

  lvcreate --persistent y  --minor 10   (to specify when created)
  lvchange --persistent n  (to turn off)
  lvchange --persistent y  --minor 11   (to change)

--persistent uses a new LV status flag stored on disk
minor number is stored on disk the same way as LVM1 does
(but major number stored is 0; any LVM1 major/minor setting gets lost)

  lvchange -ay --minor 12 (to activate using minor 12, regardless of the
                           on-disk setting, which doesn't get changed)

--minor == -m
--persistent == -M
2002-02-01 17:54:39 +00:00
Alasdair Kergon
3738f6e8ae Failure signalled by -1 not 0; MAX_DEVICES 256 (was 64); change a '>' to '>='. 2002-02-01 17:39:20 +00:00
Alasdair Kergon
051a8e2af1 Display error when running unimplemented functions. 2002-01-31 20:37:26 +00:00
Alasdair Kergon
2f43f28d5e Remove gcc -D to support as different gcc versions handle it differently. 2002-01-31 20:15:26 +00:00
Alasdair Kergon
b64769754b "exit" means "quit" (lamer) 2002-01-31 20:08:52 +00:00
Joe Thornber
a97daa18d1 o Remove redundant dbg_free. 2002-01-31 15:28:30 +00:00
Alasdair Kergon
b6556dce8b Remove stray comma. 2002-01-30 17:25:51 +00:00
Alasdair Kergon
aa8d8bc8b5 Propagate volume group read-only setting down to its logical volumes.
(Might sometimes be safe to relax this restriction.)
2002-01-30 17:12:14 +00:00
Alasdair Kergon
0800dcfdc4 Basic support for (read-only) partial activation if any PVs are
missing from a VG.  (Linear targets use the device-mapper 'error' target
which returns ioerror; striped targets use '/dev/ioerror' for now - which must
already exist e.g. as a sufficiently large block device version of /dev/zero).
2002-01-30 15:33:12 +00:00
Heinz Mauelshagen
12b0101e94 quotes around names in output 2002-01-30 15:04:48 +00:00
Alasdair Kergon
021b391a02 Allocate fixed space for vg->system_id when vg is created, instead of
dynamically.
2002-01-30 12:47:29 +00:00
Alasdair Kergon
d11e2b6057 Correct statement order for case when 'stripes' parameter is not supplied. 2002-01-30 12:17:40 +00:00
Alasdair Kergon
264d90e7e5 add vgimport 2002-01-29 19:23:46 +00:00
Alasdair Kergon
f9f3da9e78 o A vgimport implementation
o Require -a or <list of vgs> parameters with vgexport/vgimport
o Allow pvcreate -ff to destroy exported/partial VGs
2002-01-29 19:19:37 +00:00
Alasdair Kergon
6435b49153 o Basic support for exporting (but importing not completed yet).
o When volume group does not have write flag set, prevent changes to it.
o Preparation for partial activation (not completed yet).
2002-01-29 17:23:33 +00:00
Alasdair Kergon
f9aa2941cf Display 'exported' status. 2002-01-29 16:30:18 +00:00
Alasdair Kergon
5a933d4bee Add list_iterate that's safe with deletions. 2002-01-29 16:28:52 +00:00
Heinz Mauelshagen
5536aea0df Date changed 2002-01-29 15:54:49 +00:00
Heinz Mauelshagen
976666d216 Zero gap after PV structure on write to disk in order to make non LVM tools happier (AED's idea and patch for LVM1) 2002-01-29 15:52:11 +00:00
Heinz Mauelshagen
9a5bcd4392 fixed div bug in calculation of end in calculate_extent_count 2002-01-29 15:43:04 +00:00
Heinz Mauelshagen
812060a118 Check that vgname doesn't already exits in dev_dir 2002-01-28 16:30:42 +00:00
Joe Thornber
089b5052e6 o There were some alignment problems with pool-debug which I've resolved
by allocating the data block with an additional dbg_malloc.

o  Added an assertion to check that no one is requesting alternate
   alignment for memory allocated from pool.  I can't see us needing this
   for LVM2.
2002-01-28 09:16:09 +00:00
Alasdair Kergon
874e5d72f4 *** empty log message *** 2002-01-27 21:48:05 +00:00
Alasdair Kergon
6b11de1329 Tweak some error message levels. 2002-01-27 21:30:47 +00:00
Alasdair Kergon
2245a7ad8d If lv isn't active, skip reactivation. 2002-01-25 22:58:01 +00:00
Alasdair Kergon
ee5ec1b870 Prevent lvextend from adding segments with different stripe characteristics
at the moment because the old LVM format doesn't support this.
2002-01-25 21:14:43 +00:00
Alasdair Kergon
74ccfe851b The latest attempt at making extended striped LVs work portably with LVM1. 2002-01-25 20:24:14 +00:00
Alasdair Kergon
e1c24bd5a2 Set pv->pe_size when reading in text-file backup.
Otherwise LVM1 decides the PV structure is corrupt.
But do we need to keep both pv->pe_size and vg->extent_size
in internal metadata or can we generate pvd->pe_size when writing out
a PV that belongs to a VG?
2002-01-25 20:21:13 +00:00
Alasdair Kergon
1349b79728 Only remove symbolic links when deactivating.
(if this code didn't create it, don't delete it)
2002-01-25 20:17:44 +00:00
Joe Thornber
d294d7604c o Tidy 2002-01-25 13:41:13 +00:00
Alasdair Kergon
01df2cf464 Have a pe_total check using theoretically big number instead of the
unnecessarily small limit LVM1 imposes in vgcreate (but not vgextend)
2002-01-24 23:35:56 +00:00
Alasdair Kergon
45b7322488 Don't bother to write out an empty cache. 2002-01-24 23:17:16 +00:00
Alasdair Kergon
b3055e992f Fix the device cache to cope reasonably safely with device name changes.
This should be a rare occurrence so the aim is to recover if it's
straightforward to do so, otherwise just to abort the operation.
If people *knowingly* change device names, they should always run vgscan
afterwards.

A few bytes of memory gets leaked inside a pool each time an alias
has to be discarded - it's not worth restructuring the code to reuse it.

More of LVM2 needs updating to pass device objects (or uuids) about
instead of pathnames so that resolution of pathname->object only happens
once per operation.

dev_cache_get() should now always return the *current* device at the path given

dev_name_confirmed() replaces dev_name() whenever it's important to
know that name for the device is still current (ie when opening it).
If the cache doesn't know a current name, the function fails.

dev_open() guarantees that the file descriptor returned is for the dev_t
of the device structure it was passed.
2002-01-24 23:16:19 +00:00
Alasdair Kergon
3da548565c Clear a FIXME about checking for identical devices by comparing dev_t
instead of name.
2002-01-24 22:37:24 +00:00
Heinz Mauelshagen
a975e85548 removed ~64limit for PEs per PV agk introduced 2002-01-24 19:20:35 +00:00
Joe Thornber
c4b5ade752 o Limit for number of extents should be 65534. 2002-01-24 17:32:56 +00:00
Alasdair Kergon
a4b61b0794 Improve allocation error messages when PVs in a VG have the allocatable
flag unset.
2002-01-24 17:26:00 +00:00
Alasdair Kergon
f6011184b8 Impose max PE limit for each PV. 2002-01-24 17:24:32 +00:00
Joe Thornber
74de118c6e o Add check for > 65k extents in a single lv. 2002-01-24 17:16:36 +00:00
Joe Thornber
9c25e77c17 o Add extra parameter to lv_manip fns 2002-01-24 17:15:49 +00:00
Joe Thornber
440113e67e o extra fid parameter to lv_manip fns 2002-01-24 17:15:24 +00:00
Joe Thornber
a11b60c445 o Remove pointless calculation. 2002-01-24 14:15:42 +00:00
Alasdair Kergon
a6052681ad Ignore all except one PV found with the same UUID. Use one which
has the md major number if there is such.
2002-01-24 13:36:33 +00:00
Alasdair Kergon
482d50536a Fix dev_close arg. 2002-01-24 13:31:18 +00:00
Alasdair Kergon
25c79a4fcd Remove any core files on distclean. 2002-01-24 13:30:40 +00:00
Joe Thornber
02946144ac o typo 2002-01-24 09:54:09 +00:00
Joe Thornber
71a360e9a3 o Cut and paste description of how pvmove works that I was mailing someone. 2002-01-24 09:26:13 +00:00
Alasdair Kergon
f7912d88b1 o Remove redundant symlink-handling code.
o When opening device, return error if its cached name is incorrect (eg if
  it's changed since the cache was generated).  This prevents use until
  the cache is rebuilt (eg with vgscan).  Doesn't catch every case.
2002-01-23 18:55:01 +00:00
Alasdair Kergon
975101d7d2 Avoid using VG metadata on PVs that are not in VGs. 2002-01-23 15:50:34 +00:00
Alasdair Kergon
ef58c5ff55 *** empty log message *** 2002-01-23 12:25:30 +00:00
Alasdair Kergon
e10221804a Silently remove any existing symlink before creating a new one. 2002-01-22 19:58:37 +00:00
Alasdair Kergon
284ed9ee0e Update with info on how to configure command output to look like LVM1 2002-01-22 19:20:46 +00:00
Alasdair Kergon
5d7b961997 Reviewed interaction with lib/activate now that the interface has settled down. 2002-01-22 19:11:12 +00:00
Alasdair Kergon
c699a5c4b4 New config options to customise message output. 2002-01-22 15:33:57 +00:00
Alasdair Kergon
1f4ceb89cf Customisable message output prefix / indentation. 2002-01-22 15:33:40 +00:00
Joe Thornber
0934ca0040 o added BUGS file. 2002-01-22 14:40:38 +00:00
Joe Thornber
4738f892c2 o Fix inverted logic in list_empty test. 2002-01-22 14:16:27 +00:00
Alasdair Kergon
33004fcf33 old file 2002-01-22 13:29:34 +00:00
Alasdair Kergon
34d214c166 Update. Ready to release? 2002-01-22 13:11:01 +00:00
Alasdair Kergon
a56cd92a1e No need for file output to default to stderr now that log file can be
specified in config file.
2002-01-21 19:05:00 +00:00
Alasdair Kergon
7251348507 Insert a missing hash_remove. 2002-01-21 19:04:13 +00:00
Joe Thornber
01cd5c84d6 o Allow fractional parts for size args. eg, lvcreate -L 34.4M
o  Fix a couple of bugs related to the earlier lv_list change
2002-01-21 17:43:10 +00:00
Joe Thornber
e210599fa6 o Similar changes for lv_list. 2002-01-21 16:49:32 +00:00
Joe Thornber
dbe7cee7e9 o fail if create_pv_list would produce an empty list. 2002-01-21 16:15:25 +00:00
Joe Thornber
7370d88ceb o Typo in comment 2002-01-21 16:10:36 +00:00
Joe Thornber
34458e0c57 o Changed
struct pv_list {
	struct list list;
	struct physical_volume pv;
   };

   to

   struct pv_list {
	struct list list;
	struct physical_volume *pv;
   };


o  New function in toollib 'create_pv_list', which creates a list of pv's
   from a given command line array of pv's.

o  Changed lvcreate/extend to use this (fixes lvextend [pv list] bug).
2002-01-21 16:05:23 +00:00
Alasdair Kergon
05c8c3abf2 Is this sufficient to fix make -j? 2002-01-21 16:02:55 +00:00
Patrick Caulfield
e9d464b4d3 Fixx OB1 error in max LV and max PV numbers 2002-01-21 14:53:47 +00:00
Joe Thornber
6968c3ab9b o Changed find_pv_in_vg, and find_lv_in_vg to return a struct pv_list * and
struct lv_list * respectively.
2002-01-21 14:28:12 +00:00
Joe Thornber
131a8a9650 o names.[hc] 2002-01-21 13:11:03 +00:00
Joe Thornber
379ecbf9a9 o lvdisplay now gives a segment map for the -m option. 2002-01-21 12:05:39 +00:00
Joe Thornber
7b9dfa9a28 o removed display_uuid
o use id_write_format from lib/uuid/uuid.h instead
2002-01-21 11:29:06 +00:00
Joe Thornber
fbd0f5eed2 o move the path building functions to lib/activate/names.c
o  Update activate.c and fs.c to use them

o  device names are now of the form <vg>:<lv>
2002-01-21 11:06:32 +00:00
Alasdair Kergon
5970f904ae Allow syslog facility to be set, or turned off, from the config file. 2002-01-18 21:26:37 +00:00
Alasdair Kergon
8cbcb2868d Display something in the "hypothetical" unknown log level case. 2002-01-18 19:38:19 +00:00
Alasdair Kergon
8ff2a4b026 Use same log levels as LVM2. 2002-01-18 19:37:26 +00:00
Alasdair Kergon
ae14d205a5 Allow compilation against a device-mapper that was installed into $DESTDIR
Always check for negative (error) return code from lv_active()
2002-01-18 16:43:19 +00:00
Alasdair Kergon
ec5d560ec5 More updates. 2002-01-18 13:45:12 +00:00
Heinz Mauelshagen
fb543b53c0 added before 2.1 item 2002-01-18 11:07:26 +00:00
Alasdair Kergon
39c16422e2 beta1-pre1 tagged, but there's still some documentation to update/write. 2002-01-17 18:48:08 +00:00
Alasdair Kergon
4d5b273ebe Support --version argument and 'version' shell command. 2002-01-17 16:39:24 +00:00
Alasdair Kergon
ed6a860fad Add function that returns the library version. 2002-01-17 14:13:25 +00:00
Alasdair Kergon
423e579292 Add another level of symlink to library name (like LVM1) so people who find
themselves running multiple incompatible kernel versions will just need
to swap symlinks at boot.
2002-01-17 13:37:09 +00:00
Alasdair Kergon
ee11aa9e75 Use additional version numbers.
Kernel driver has a version number (stored in kernel/VERSION).
  The first two components of this (0.94) give the version number of the
  ioctl interface.  This number must be changed whenever a change is
  made to the ioctl interface that breaks backwards compatibility.

  The library has a version number (stored in VERSION) which is
  used for linking.
  The first and/or second component of this must be changed whenever
  a change is made to the library API that breaks backwards
  compatibility.
2002-01-17 13:19:55 +00:00
Alasdair Kergon
c46d20fa92 o pvcreate --uuid to specify the uuid (required before using vgcfgrestore
onto a new device).  uuid specified must not already exist on the system.
o More message tidying.
o When checking for label, only read PV metadata.
o Add ataraid.  [Needs moving into config/defaults files.]
2002-01-16 18:10:08 +00:00
Joe Thornber
dc8d17574c o save before committing 2002-01-16 15:53:42 +00:00
Joe Thornber
5c17cd04c8 o lvm.conf file that contains the same settings that would be assumed if it
wasn't there.  A good starting point for tweaking.
2002-01-16 15:52:53 +00:00
Alasdair Kergon
67ada02076 Move test flag from log to global section of config file. 2002-01-16 15:20:51 +00:00
Alasdair Kergon
32d94c2eaf o Don't update vgcache when (not really) writing in test mode.
o Don't continue iterating through a possibly-deleted list.
2002-01-16 14:43:27 +00:00
Alasdair Kergon
687b39a12a Remove a duplicate disk read (can_handle). 2002-01-16 13:09:26 +00:00
Patrick Caulfield
705af407bf #include <string.h> 2002-01-16 12:02:06 +00:00
Joe Thornber
080052da2e o Set the segment counter back to 1, for a new LV. 2002-01-16 11:34:29 +00:00
Joe Thornber
ef735fd92a o Add pvmove to the stub file. 2002-01-16 11:27:19 +00:00
Joe Thornber
17c16dcafc o Knock out the "'%s' is not a block device" debug message. 2002-01-16 09:23:28 +00:00
Alasdair Kergon
a89b3018fb Reduce 'no label found' message severity to debug level. 2002-01-16 00:01:36 +00:00
Alasdair Kergon
851e2ebd32 Fix function typecasts. 2002-01-15 23:47:56 +00:00
Alasdair Kergon
1225ce7fe8 o More comprehensive config parameter debugging messages.
o Make /proc configurable.
 o Review hard-coded "/dev"s - made 2 more of them configurable.
2002-01-15 23:34:13 +00:00
Alasdair Kergon
7e77a31b96 o missing labeller free
o updated vgcfgrestore args
o change _check_for_open_devices only to check devices present in the hash
  table instead of using dev_iter which triggers a full scan even when only
  displaying command line help
2002-01-15 21:28:04 +00:00
Joe Thornber
d146b9002f o Actually check in vgcfgrestore. 2002-01-15 18:17:57 +00:00
Joe Thornber
1f9d567b23 o vgcfgrestore works ! (with the couple of examples I tried). 2002-01-15 17:37:23 +00:00
Alasdair Kergon
ed1b3a023c Another ioctl interface update:
Supply offset to start of variable data area (so struct size can change
without breaking backward compatibility)
  Add command that just returns the driver version
2002-01-15 15:21:57 +00:00
Joe Thornber
1ca18f501a o split the uuid -> device map out from vgcache
o  roll vgcache back to agk's implementation, we'll revisit this as part
   of the cluster integration.

o  change the extra_info field in a label to be a void *
2002-01-15 10:24:48 +00:00
Alasdair Kergon
49588ccd98 Some ioctl interface changes. (Do we want these?)
- use status bits (so we can add flags without changing the struct size)
  - use dev_t
2002-01-14 23:07:32 +00:00
Joe Thornber
098dedc092 o Non-caching implementation of new vgcache interface. 2002-01-14 11:43:52 +00:00
Joe Thornber
b06f6b9545 o LVM1 labeller. 2002-01-14 10:00:56 +00:00
Joe Thornber
ba3cb94999 o Reformat comment and correct typo. 2002-01-14 09:59:12 +00:00
Alasdair Kergon
74c67fbf4b o Add rename support to dmsetup.
o Add support to use specified minor number to library and dmsetup.
2002-01-11 12:12:46 +00:00
Patrick Caulfield
32b46e4910 Couple of typos fixed. 2002-01-11 11:34:53 +00:00
Joe Thornber
ecf5539ed2 o Put in the pv_hash which stores the pv section name -> pv struct mapping. 2002-01-11 11:09:12 +00:00
Joe Thornber
ac9db4e4d5 o label.c now compiles. 2002-01-11 10:43:32 +00:00
Patrick Caulfield
0eb96094b0 Change lvm2_label to use Joe's new label switch system. 2002-01-11 10:39:56 +00:00
Alasdair Kergon
30b3ac7dc5 Support the renaming of active mapped devices (ioctl interface only). 2002-01-10 23:29:16 +00:00
Alasdair Kergon
0092790c7d o ACTIVE is no longer a status flag - lv_active() used to check if an LV
is active in the device-mapper.
o Many operations can be carried out regardless of whether the VG is
  active or not.
o vgscan does not activate anything - use vgchange.
o Change lvrename to support renaming of active LVs.
o Remove '//' appearing in some pathnames.
o Dummy lv_check_segments() for compilation.
2002-01-10 23:21:07 +00:00
Joe Thornber
28909d8a51 o _read_id function for import.c 2002-01-10 18:12:26 +00:00
Alasdair Kergon
b20cfbb7b6 More steps towards successful compilation. 2002-01-10 16:48:28 +00:00
Alasdair Kergon
97639bd0a8 Add 'get' functions. 2002-01-10 16:47:58 +00:00
Alasdair Kergon
161ec73c96 More detail in error msgs. 2002-01-10 16:47:25 +00:00
Alasdair Kergon
957d6bea15 Separate constant fields from variable ones. 2002-01-10 16:47:04 +00:00
Alasdair Kergon
f8b6e5b414 Clarify terminology:
VG is resizeable  - PVs can be added or removed
  PV is allocatable - free extents on it may be allocated to LVs
2002-01-10 15:09:51 +00:00
Joe Thornber
1ab450870e o Moved the current label.[hc] sideways to lvm2_label.[hc]
o  First pass at low level labelling switch.  This allows us to
   register different label types (eg, lvm1, lvm2).
2002-01-10 15:01:58 +00:00
Alasdair Kergon
de45f4884c Allow for multiple spellings / backwards compatibility of renamed
command line options.
      vgchange --resizeable y
      pvchange --allocatable y
But --allocation is still allowed for both (as LVM1) and --resizable is OK.
2002-01-10 14:46:50 +00:00
Joe Thornber
5da1f3e7c8 o vgcfgrestore. 2002-01-10 14:27:47 +00:00
Alasdair Kergon
983014952b Temporary file creation & renaming. 2002-01-10 12:22:17 +00:00
Joe Thornber
55298019a3 o First pass at import.c. Still waiting for label code for the uuid->pv
mapping.
2002-01-10 11:18:08 +00:00
Joe Thornber
a1ffc3f271 o Put in the 'out of memory' log_err for pool. 2002-01-10 09:35:55 +00:00
Alasdair Kergon
2fb60aa997 Renamed to archive.c 2002-01-09 19:17:11 +00:00
Alasdair Kergon
f5ec76537a o Rename many occurrences of 'backup' to 'archive' to reduce confusion.
o Extract file creation/renaming code into a library and change backup code
  to use it too.
o Support umask.
o Bring lvm.conf man page up-to-date.
2002-01-09 19:16:48 +00:00
Alasdair Kergon
728491fd2b Accept octal values for numbers (such as umask). 2002-01-09 18:53:07 +00:00
Joe Thornber
d9d3f2b9e4 o Let the comment wars begin. 2002-01-09 14:14:07 +00:00
Joe Thornber
3fe4864f65 o new function backup_remove(const char *vg_name), to be called from vgremove. 2002-01-09 14:07:49 +00:00
Joe Thornber
0b156f22a4 o Reformat comments. 2002-01-09 13:56:11 +00:00
Alasdair Kergon
35b1d93813 Add archiving. 2002-01-09 13:17:14 +00:00
Alasdair Kergon
d770851ac0 o Try to improve NFS-safety for temporary file creation (unique name; O_APPEND
+ fcntl lock) and rename (using hard link), avoiding any "real" archive
  files ever being zero length.
o Fix filename parsing & ordered list handling.
2002-01-09 13:16:19 +00:00
Alasdair Kergon
989e7b1033 Explicitly close (=>flush) files. 2002-01-09 13:07:03 +00:00
Alasdair Kergon
c4e0eb7b49 Allow pool_begin_object in empty pool. 2002-01-09 13:06:02 +00:00
Alasdair Kergon
71f5d0dac7 Another attempt to support both readline versions. 2002-01-08 19:17:08 +00:00
Alasdair Kergon
561b0c4381 call archive_exit() & backup_exit() on exit 2002-01-08 18:14:04 +00:00
Joe Thornber
995fbc7330 o Remove anomalous punctuation. 2002-01-08 10:51:13 +00:00
Joe Thornber
10ab8949c4 o Introduction to pool for those without psychic powers. 2002-01-08 10:47:17 +00:00
Alasdair Kergon
c441202fea fixes for compilation 2002-01-07 23:28:25 +00:00
Alasdair Kergon
ca261b0bee Sync. 2002-01-07 23:04:48 +00:00
Alasdair Kergon
52f3709f67 Sync tidy. 2002-01-07 22:49:04 +00:00
Alasdair Kergon
c2ca6187fe If a device somehow became suspended, lvchange -ay now reactivates it. 2002-01-07 22:36:12 +00:00
Alasdair Kergon
671a13d295 Support for read-only. 2002-01-07 22:28:36 +00:00
Alasdair Kergon
14c3e2eccf Missing close() in error case. 2002-01-07 22:25:57 +00:00
Alasdair Kergon
08e5b852c2 tidying 2002-01-07 22:01:50 +00:00
Joe Thornber
1c9606c824 o vgcreate wasn't setting vg->cmd 2002-01-07 15:27:55 +00:00
Joe Thornber
3cd47b5c9b o New function 'merge_segments'
o  Call said function at end of lv_extend
2002-01-07 15:08:28 +00:00
Joe Thornber
aedc729087 o tidy up renaming of archive files. 2002-01-07 14:21:33 +00:00
Joe Thornber
5f7cfa3fa9 o sync tool changes for backup stuff. 2002-01-07 11:12:11 +00:00
Joe Thornber
0083f30af5 o Added find_config_bool 2002-01-07 10:23:52 +00:00
Joe Thornber
4a06f05ef5 o Get format-text.c compiling. 2002-01-07 09:16:20 +00:00
Joe Thornber
8f37cadce8 o sync laptop to test machine. 2002-01-07 09:05:31 +00:00
Alasdair Kergon
a11603ca6c Imported man pages from LVM1 with some quick LVM2 updates. 2002-01-04 20:35:19 +00:00
Alasdair Kergon
86274842e9 The start of an lvm man page. 2002-01-04 18:56:56 +00:00
Alasdair Kergon
cf9c955a44 Document remaining configuration file parameters. 2002-01-04 17:49:38 +00:00
Joe Thornber
55d828c35f o Revert to the 6-4-4-4-4-4-6 format for uuid's
o  When reading a uuid all -'s are stripped, wherever they are.
2002-01-04 16:55:14 +00:00
Alasdair Kergon
cdff28aca6 Put device name in quotes. 2002-01-03 17:47:48 +00:00
Joe Thornber
b9da39274f o High level archiving and backup functions.
I've split the old autobackup function into two seperate areas:

'archiving' is performed *before* a vg configuration is changed.  This
produces a numbered backup in /etc/lvm/archive.

A 'backup' is performed *after* a vg change.  So the directory /etc/lvm/backup
will hold the  a copy of the current configuration.
2002-01-03 15:46:48 +00:00
Alasdair Kergon
c379aa5782 stub for read-only functions with fs interface 2002-01-03 15:12:02 +00:00
Alasdair Kergon
9dcabac9dd Fix final comma in arrays. 2002-01-03 12:43:01 +00:00
Alasdair Kergon
794f3a2b9f *** empty log message *** 2002-01-03 12:39:04 +00:00
Joe Thornber
2066121b7c o Added -r, --read-only switch to dmsetup for use with create and reload. 2002-01-03 10:39:21 +00:00
Alasdair Kergon
0c4067f143 o Allow the definition of read-only devices (ioctl interface only) (Joe)
o Add version number to ioctl structure with error on kernel/library mismatch
2002-01-02 19:01:09 +00:00
Joe Thornber
8aa69243b7 o Added section on the syntax of the config file, with an informal grammar. 2002-01-02 17:54:57 +00:00
Alasdair Kergon
8697263bde Fix $DESTDIR support 2002-01-02 14:23:10 +00:00
Alasdair Kergon
ea25c4f65c Tidy makefiles - $DESTDIR & shared library version (like LVM1) 2002-01-02 13:40:49 +00:00
Alasdair Kergon
82ac3ebd7e Add test mode parm. 2001-12-31 22:12:03 +00:00
Alasdair Kergon
13cb94909c o Add autobackup support to tools (follows most vg_write calls).
o Skip autobackup when in test mode.
o Set test mode from config file.
o Create system/backup dirs if not present (unless LVM_SYSTEM_DIR holds "").
2001-12-31 21:27:39 +00:00
Alasdair Kergon
b57ca2a763 vgcache.h inclusion (avoid compiler warning) 2001-12-31 19:18:44 +00:00
Alasdair Kergon
83c49e9745 o Use lvm_snprintf wherever return value is used
o Add parameters to set retention limits for backups
2001-12-31 19:09:51 +00:00
Alasdair Kergon
e15771d78d Remove some old files. 2001-12-31 17:34:51 +00:00
Alasdair Kergon
6edc4920ba Redundant. 2001-12-31 17:26:42 +00:00
Alasdair Kergon
302bb1bd93 Document lvm.conf fields 2001-12-31 17:20:22 +00:00
Alasdair Kergon
529b1bceee Outline docs 2001-12-31 16:12:40 +00:00
Alasdair Kergon
42cd47d32e o Allow more default values to be overridden from config file.
o Cope with both the readline versions used around here.
2001-12-31 15:20:18 +00:00
Alasdair Kergon
711d884c2e Fix C99 error case handling (snprintf ret value >= buffer size). 2001-12-31 15:17:34 +00:00
Alasdair Kergon
183d1c4674 Fixes for compilation. 2001-12-31 15:14:44 +00:00
Alasdair Kergon
faed63a0bb Remove unused --with_kernel_dir
Current version of LVM2 instead relies on /usr/include/libdevmapper.h
which gets installed by the device mapper package.
(Should this location now be configurable?)
2001-12-31 15:13:42 +00:00
Alasdair Kergon
53bff262f8 Revised ioctl/dmfs merge with fixes for bugs found in tests. 2001-12-20 20:32:14 +00:00
Joe Thornber
3251a708e4 o Added a quick vgcfgbackup, needs parameters as yet. 2001-12-20 16:05:14 +00:00
Joe Thornber
b5dbdbf7b2 o Debug version of the pool_grow stuff. 2001-12-20 12:27:41 +00:00
Joe Thornber
a9649e92c9 o sync backup changes 2001-12-20 11:52:54 +00:00
Patrick Caulfield
b561f1fa8b Wipe the first label if writing the second one failed. 2001-12-18 14:39:32 +00:00
Joe Thornber
cecd7491b5 o sync the backup stuff 2001-12-17 19:46:10 +00:00
Joe Thornber
55a66322b5 o history is now saved in ~/.lvm_history 2001-12-17 17:59:58 +00:00
Joe Thornber
155c31a2d7 o Shuffled completion functions around so we dont have to declare them
at the top of the file.

o Changed completion_matches -> rl_completion_matches, and added some consts.

This will probably break things on pre readline 4.2 systems.
2001-12-17 17:18:47 +00:00
Joe Thornber
a89ce91089 o Changed the macro name in args.h from 'xx' to 'arg'
o  There is now a _default_debug, and _default_verbose level, when
   using lvm interactively -vv and -dd switches just effect the current
   command.

o  Added a --quiet switch which sets both verbose and debug to zero.
2001-12-17 16:58:17 +00:00
Joe Thornber
b897fe6700 o Use lvm_snprintf 2001-12-17 14:05:43 +00:00
Joe Thornber
548a351b06 o Add symlink for lvm-string.h 2001-12-17 14:04:33 +00:00
Joe Thornber
4b1da57ca1 o lvm_snprintf
Could everyone please use this from now on.
2001-12-17 14:04:10 +00:00
Joe Thornber
529aec7f25 o Remove LVM_CONFIG_FILE environment variable.
o  Introduced the LVM_SYSTEM_DIR variable.

This makes more sense because the persistent cache, and backup directories
are config specific.

eg, I use /etc/lvm for running my real LV's

    but I have another directory /dev/lvm_loops that contains a config
    that allows only loopback devices, I use this for testing.
2001-12-17 12:01:09 +00:00
Heinz Mauelshagen
1661e545cb Typos in error messages 2001-12-17 11:07:33 +00:00
Joe Thornber
ec71d08878 I had another look at the argument processing code:
o You must list long args with no short option (eg. --version) at the
  front of the args.h file.

o If an argument has no short option, set the short option in args.h to '\0'

o The index into the 'the_args' var is now stored as the option value
  for getopt, iff there is no short opt.
2001-12-17 10:08:27 +00:00
Alasdair Kergon
ac258b7dd7 o Include dmsetup man page in build
o Allow pathname in dmsetup device arg
o Generated patches for 0.90.02
2001-12-14 13:30:04 +00:00
Patrick Caulfield
0f57876233 Write the location of both labels in the labels so we can check them. I don't do
much with this ATM (apart from check that they all match up).
Use a different CRC routine.
2001-12-14 13:15:15 +00:00
Joe Thornber
1d25a3693d o I figure if I can't remember how to use my code, then I should add
a comment.  It's quite cool, wish I remember writing it.
2001-12-13 16:09:06 +00:00
Alasdair Kergon
45fa428bf1 Handle orphan PVs too, so hints remain valid after vgreduce. 2001-12-13 15:08:58 +00:00
Joe Thornber
177fa80f1a o Man page for dmsetup 2001-12-13 13:46:21 +00:00
Patrick Caulfield
3261261bfe made the hard-coded 512 into BLOCK_SIZE just for neatness sake.
log_error() if writing the label fails so someone knows which was in error.
2001-12-13 08:40:47 +00:00
Alasdair Kergon
d4de7934f8 Add internal cache holding a 'hint' list of the PVs belonging to each VG.
A substantial speed-up - particularly in readline mode.
If the hints turn out to be wrong, the relevant parts get thrown away.
vgscan destroys it totally.  In both cases it then rebuilds itself as
required.
2001-12-13 00:07:29 +00:00
Alasdair Kergon
c3475af809 fix for clean compilation 2001-12-12 16:25:53 +00:00
Joe Thornber
b12f707812 o silly bugs 2001-12-12 16:22:38 +00:00
Joe Thornber
22c0c34d60 o pool-debug version of end_object wasn't returning the object. 2001-12-12 16:05:52 +00:00
Joe Thornber
a60b66f230 o Add error checking in _new_chunk 2001-12-12 14:54:24 +00:00
Joe Thornber
83f6e93628 o pool-debug versions of begin_object, grow_object etc. 2001-12-12 14:25:20 +00:00
Patrick Caulfield
222b5f0229 Build label code into the library 2001-12-12 09:09:04 +00:00
Patrick Caulfield
30aa383e26 Use a proper CRC calculation. 2001-12-12 09:05:44 +00:00
Patrick Caulfield
676b401294 - Change label format to include a string disk_type and a version number.
- The iterator can find labels by string and also appropriate version number (==,
  <= or any) if you want.
- Add labels_match() call that compares the two labels and returns an error if
  they do not match.
- Write labels in sector 1 & last rather than 2 & last as per Joe.
2001-12-11 16:49:40 +00:00
Alasdair Kergon
ebf57159de Apply make distclean to test subdirs too. 2001-12-11 16:26:34 +00:00
Patrick Caulfield
199d2aafec Fix label filter. 2001-12-11 14:17:10 +00:00
Joe Thornber
81952f56fd o Add output_date 2001-12-11 12:29:25 +00:00
Joe Thornber
c5bac82b43 o flags.c reads and writes a status bitset 2001-12-11 12:18:56 +00:00
Joe Thornber
081b86109c o Split import-export.c into two files. 2001-12-11 12:16:58 +00:00
Joe Thornber
8ac2028a75 o Update sample to a format that supports multiple vg's per file. 2001-12-11 12:15:08 +00:00
Patrick Caulfield
264fed1c9f Label reading/writing code.
Not tested the filter yet.
2001-12-11 11:42:30 +00:00
Joe Thornber
dd59f7b2c7 o Pretty print and read for uuid's 2001-12-11 11:40:34 +00:00
Patrick Caulfield
9245a760db Add a dev_get_sectsize call. 2001-12-11 10:18:49 +00:00
Alasdair Kergon
b61b32bbc3 Fixes for allocation of striped volumes. 2001-12-07 21:17:12 +00:00
Alasdair Kergon
09b3914f5d Fixes for library compilation. 2001-12-07 21:15:33 +00:00
Alasdair Kergon
fe644e4c9e Moved across to device-mapper repository. 2001-12-06 14:20:38 +00:00
steve
7b09bf2156 o Updated projects.txt to remove the earlier error which turned out to be
a build error.
2001-12-05 18:04:55 +00:00
Alasdair Kergon
987d0aae66 Various fixes & restructure to extract common code. 2001-12-05 16:41:52 +00:00
steve
9cbcbc1c22 o Removed unused MOD_INC/DEC_USE_COUNT 2001-12-05 12:00:01 +00:00
steve
cfc4e2bc60 o Added a few more projects 2001-12-05 11:58:43 +00:00
steve
a03405fa81 o Initial merge attempt
There are still a few odd things going on, so more debugging remains to be
done.
2001-12-05 11:28:41 +00:00
Alasdair Kergon
d5c9ccbe6e Correct activation message. 2001-12-05 00:04:18 +00:00
Alasdair Kergon
e52772d65f Added more log messages. 2001-12-04 23:20:27 +00:00
Joe Thornber
1e3259e728 o sync 2001-12-04 14:14:07 +00:00
Alasdair Kergon
e905a20a60 Tweaks for make install. -m args replaces verbose to display maps. 2001-12-03 20:23:53 +00:00
Alasdair Kergon
88e2be7a33 More striping support & fixes. 2001-12-03 16:27:16 +00:00
Joe Thornber
8939131600 o Comparison function was sorting things in ascending rather than
descending order.

o free off the sort array when finished with it.
2001-11-30 09:19:46 +00:00
Joe Thornber
ba37ebff8b o Striped allocator
o  Changed pv_map.c to maintain the list of free areas in size order, which
   is more helpful to the allocators.  If you want to allocate a bit of an
   area call consume_area(area, size), this will adjust the area if there's
   some space left and shuffle it to the correct place in the list.


Not tested.
2001-11-29 18:45:35 +00:00
Joe Thornber
28f4cb7e07 o I was reading striped volumes incorrectly. 2001-11-29 14:13:43 +00:00
steve
db1e7102cd o Confusingly, dmfs-tdir isn't gone, its now called dmfs-lv.c and its the
old dmfs-lv.c thats gone.
 o Dropped out support for multiple tables in line with ioctl interface
 o Some reordering to better support the userland library
 o Updated to 2.4.16

I'm fairly happy with the way that this is working now, so the next job is
to start the integration with the ioctl interface so there is a single
common dm.[ch] and selectable interfaces (fs or ioctl).

Further improvements can be made even now, but I hope to wait until we've
got this going and integrated and the libdm parts working as well before
investigating other avenues.
2001-11-29 14:00:04 +00:00
steve
07eb7a5830 New patches for 2.4.16 2001-11-29 13:44:46 +00:00
Alasdair Kergon
b7c6c685fa configure --with-interface=ioctl (default) or =fs to choose kernel interface 2001-11-28 21:03:50 +00:00
Alasdair Kergon
212134df70 Add autoconf & makefile structure like LVM2. 2001-11-28 20:08:11 +00:00
Alasdair Kergon
6eeb5528f5 Add -t or --test arg to all tools that update metadata to avoid
committing metadata changes or (de)activating.
2001-11-28 18:03:11 +00:00
Joe Thornber
54fad845c9 o Output the correct format for the stripe target 2001-11-28 17:52:27 +00:00
Alasdair Kergon
d6c0de6fc7 Fix single stripe resizing. 2001-11-28 16:16:44 +00:00
Alasdair Kergon
649c8649f7 Make source files depend on makefiles. 2001-11-28 15:00:49 +00:00
Joe Thornber
da2f53d1b1 o pool_free was leaving one block hanging around. 2001-11-28 14:58:33 +00:00
Alasdair Kergon
405139e3b8 o Tool support for segments.
o vgmerge working.
2001-11-28 13:45:50 +00:00
Alasdair Kergon
4f8d347171 Use CFLAGS during make rule generation. 2001-11-28 12:28:03 +00:00
Joe Thornber
bf0db4876c o pool-debug.c contains an alternative implementation of pool that gets
a seperate chunk of memory from dbg_malloc for each pool_alloc.  This
   will allow the bounds checking code in dbg_malloc to do it's stuff.

o  The normal implementation moved to pool-fast.c

o  pool.c now just contains a #ifdef and includes the appropriate .c file.

Alasdair, could you make sure that gcc -MM get's passed all the
CFLAGS please, otherwise the dependencies get calculated incorrectly.
2001-11-28 09:13:00 +00:00
Joe Thornber
47a14884d6 o Turn on pool debugging by default (-DDEBUG_POOL) 2001-11-28 09:07:53 +00:00
Alasdair Kergon
3a7bbc8b08 Fix a memory smash. 2001-11-27 23:12:06 +00:00
Joe Thornber
1b1d65372c o extra error checking 2001-11-27 20:03:45 +00:00
Joe Thornber
fd2faaa16e o These now compile. 2001-11-27 17:39:15 +00:00
Joe Thornber
0609cdb9ea o Get format1 building. 2001-11-27 17:29:56 +00:00
Alasdair Kergon
d3bb140f89 vgmerge first cut 2001-11-27 17:02:24 +00:00
Joe Thornber
b31dc66628 o Sync up todays work on converting to the segmented representation of
logical volumes.  It includes:

   format1 changes.

   metadata.h changes.

   lv_manip.c changed (striped allocation still not done though).

   activate.c changes.

Nothing has been near a compiler as yet.

Alasdair can you look at changing display.c to use to output the mappings
in a more segment oriented format please ?

I haven't put the span list into struct physical_volume to represent allocated
extents.  I think the burden of maintaining it for things like lv_extend may
out weigh it's uses.
2001-11-27 16:37:33 +00:00
Alasdair Kergon
09476171a6 Tool support for multiple (striped) segments (incomplete). 2001-11-27 13:42:37 +00:00
Joe Thornber
33dee813b5 o change chunk_size to stripe_size 2001-11-26 16:30:43 +00:00
Joe Thornber
bb4e73c40b o More metadata changes. 2001-11-26 16:18:48 +00:00
Alasdair Kergon
b1f23ffa94 LV create/extend prototype changes for striping 2001-11-26 15:31:46 +00:00
Joe Thornber
b0e8cec1e7 o make it obvious that stripe_segment is variable sized. 2001-11-26 13:15:22 +00:00
Joe Thornber
5077ae19bc o segments will have to be held as an array of pointers since they're now
variable sized.
2001-11-26 13:03:36 +00:00
Joe Thornber
0d8447bf59 o sync the new in core rep. for Alasdair.
This will break everything !  Hopefully things will be working again by
   this evening.
2001-11-26 12:49:29 +00:00
Alasdair Kergon
c6cf08a274 additional patch required 2001-11-23 12:35:31 +00:00
steve
dc49ae519e o Revised seq_file usage after discussions on linux-fsdevel 2001-11-22 15:14:20 +00:00
Joe Thornber
904539476a o Make sure that every switch has a short option, even if it's
non-displayable so we can remove the pointer mangling that was
   breaking 64bit arch.s
2001-11-22 14:37:07 +00:00
Alasdair Kergon
3fbf02dc82 o activation & active status tests
o lvdisplay fields from kernel
o update lv->size on resize
2001-11-21 19:32:35 +00:00
Alasdair Kergon
c9392a840d dmdir path 2001-11-21 19:20:41 +00:00
Joe Thornber
d164e8ab72 o Remove an old debug statement 2001-11-21 18:24:22 +00:00
Joe Thornber
6dc62c9fb6 o Display major number 2001-11-21 18:12:41 +00:00
Joe Thornber
87a9684d66 o use the major number returned from dm_ioctl. 2001-11-21 17:57:57 +00:00
Joe Thornber
94525e2f44 o There's no need to prefix dm_dir() with /dev/ anymore 2001-11-21 17:20:49 +00:00
Joe Thornber
b408b1b3b9 o You can now specify the dev directory for libdm
o  dm_dir() returns the full path to the device-mapper dir (eg, /dev/device-mapper).

o  put stat in on _rm_node
2001-11-21 17:08:37 +00:00
Joe Thornber
27c2f09e32 o Removed _check_devfs
o  We now do a stat to see if the device node is there
2001-11-21 16:47:10 +00:00
Joe Thornber
19bc4d3349 o Remove hard coded path to /dev/device-mapper/control 2001-11-21 15:49:45 +00:00
Alasdair Kergon
f2b6c424d6 Tidy makefiles 2001-11-21 15:41:14 +00:00
Joe Thornber
a49d4453e9 o Change name of libdm.h 2001-11-21 15:15:37 +00:00
Joe Thornber
65e50087b9 o Use MKDEV to build the dev_t for mknod 2001-11-21 15:14:35 +00:00
Joe Thornber
2d90f759d9 o Don't use dmt->dmi until it has been initialised. 2001-11-21 14:52:16 +00:00
Joe Thornber
4230ac7674 o Migration of device-mapper from LVM_WORK to it's own (public) repository.
Please use this one from now on.
2001-11-21 12:47:42 +00:00
Joe Thornber
d96e9182e9 o Oops, I thought this was checked in ages ago. 2001-11-21 09:21:31 +00:00
Joe Thornber
68c87b9616 o Sync. only 2001-11-21 09:20:05 +00:00
Joe Thornber
7f8e9a0b6d o _emit_target wasn't spotting contiguous targets properly. 2001-11-19 15:44:06 +00:00
Joe Thornber
81a229f2a5 o Use new info interface to dm. 2001-11-19 15:38:39 +00:00
Alasdair Kergon
8be7ae2733 vgdisplay 2001-11-19 15:20:50 +00:00
Patrick Caulfield
846bca4cb1 file cmgr.h was initially added on branch CLUSTER_TAG. 2001-11-19 14:40:32 +00:00
Patrick Caulfield
f36f353789 file cmgr.c was initially added on branch CLUSTER_TAG. 2001-11-19 14:40:32 +00:00
Patrick Caulfield
939a2731ed file clvm.h was initially added on branch CLUSTER_TAG. 2001-11-19 14:40:32 +00:00
Alasdair Kergon
835dab97ff Zero first 4k of new LVs. 2001-11-16 15:38:52 +00:00
Patrick Caulfield
fa904b53be Don't need EXTRA_LIBS as autoconf fills in LIBS for us with all that is needed.
BTW if there are any *real* autoconf experts out there please feel free to flame
me.
2001-11-16 11:39:13 +00:00
Patrick Caulfield
0ec52dddce size_ts aren't really pointers but there are no format specifiers for them,
so this will just have to do.
2001-11-16 11:37:45 +00:00
Patrick Caulfield
c289355a3a Fix format characters for printing size_ts 2001-11-16 10:56:11 +00:00
Patrick Caulfield
02a13a5a18 Do substitution on LIBS so that those platforms that need -lncurses as well as
lreadline will work.
2001-11-16 10:40:16 +00:00
Alasdair Kergon
6cf2a0281b lvrename (without reactivation) 2001-11-15 17:27:45 +00:00
Patrick Caulfield
120d35f9af Use POSIX defined PRIu64 for formatting 64 bit unsigned integer types 2001-11-15 15:18:53 +00:00
Patrick Caulfield
2b15d5e7b3 Use FMT_64 to format 64bit types 2001-11-15 14:27:51 +00:00
Patrick Caulfield
fc167bd3f0 define FMT_64 to be the right format string for 64-bit types a la GFS 2001-11-15 14:27:34 +00:00
Alasdair Kergon
91b04abf05 Use inttypes.h 2001-11-15 14:14:03 +00:00
Patrick Caulfield
77faac8740 #include <string.h> for memset 2001-11-15 11:46:00 +00:00
Alasdair Kergon
43b3d54855 More LV-related tidying. lvdisplay without args now shows all LVs. 2001-11-14 18:38:07 +00:00
Alasdair Kergon
69e9b85700 Avoid generating duplicate lv names 2001-11-14 14:12:01 +00:00
Alasdair Kergon
0b6d132759 Miscellaneous tidying 2001-11-14 13:52:38 +00:00
Joe Thornber
7c233c6c0c o lvcreate no longer needs the explicit -n flag
o  disabled zeroing of lv until bug's worked out
2001-11-14 12:07:37 +00:00
Joe Thornber
c35b290fa4 o Prefix static var with '_' 2001-11-14 10:44:14 +00:00
Joe Thornber
3d95cfb367 o Added dev_open and dev_close functions
o  Changed disk-rep to use these

o  if NDEBUG is not defined the dev_cache will check for open devices on
   teardown.

I was hoping this would speed things up.  But I'm still getting:

reti:/home/joe/sistina/LVM2/tools# time ./lvm vgchange -a n
  Volume group vg0 successfully changed

real    0m5.751s
user    0m0.060s
sys     0m0.070s

even though I have only 1 device with the vg on it passing the filters.
2001-11-14 10:01:52 +00:00
Joe Thornber
b90fc3a56e o Deal with sparse lv arrays (on disk)
o  new fn. dev_zero which zero's an area of a device
2001-11-13 18:52:52 +00:00
Alasdair Kergon
1ef3fdccf5 o lvdisplay now shows LE / PV map
o fix LE allocation when first PV is full
o reduce VG free_count when removing PVs from VG
2001-11-13 17:53:06 +00:00
Joe Thornber
02b7f77bd8 o Put underscore between vg and lv name. 2001-11-13 16:14:54 +00:00
Alasdair Kergon
0ac7ead922 Merge lvreduce & lvextend into lvresize. 2001-11-13 14:17:50 +00:00
Joe Thornber
da9d0e03ce o Stuff 2001-11-12 19:28:50 +00:00
Joe Thornber
120f65f672 o Add ALLOC_SIMPLE 2001-11-12 17:55:05 +00:00
Alasdair Kergon
200a14caa4 Remove hard-coding and create device-mapper directory if required 2001-11-12 17:21:25 +00:00
Joe Thornber
35bf6da8e2 o if any pattern rejects a device, and there were no accepts then reject ! 2001-11-12 17:06:33 +00:00
Joe Thornber
f08f70276c o check result of an allocation 2001-11-12 16:00:52 +00:00
Alasdair Kergon
1ae50fd95b iospace restructured 2001-11-12 15:10:01 +00:00
Joe Thornber
40512beb47 o add fs.c to the Makefile 2001-11-12 13:02:06 +00:00
Joe Thornber
0d7f9b2c94 o add uplink from vg to cmd_context 2001-11-12 12:23:10 +00:00
Joe Thornber
52f42140a7 o Plug in fs_(add|del)_lv 2001-11-12 12:20:58 +00:00
Joe Thornber
3f6c50297f o Split struct io_space into:
struct format_handler - format methods
   struct format_instance - links instance data, methods, and cmd
   struct cmd_context - dev_dir, memory allocator, device filter
2001-11-12 12:16:57 +00:00
Joe Thornber
f72d80afc5 o Compile errors 2001-11-12 11:48:31 +00:00
Joe Thornber
7c5cb13b22 o Ready for testing 2001-11-12 11:42:29 +00:00
steve
d728750eb2 o Fix module ref counts so that you can actually unload dm-mod
N.B. This means that you have to take very great care in the event that
   you want to access the dcache tree from in kernel

 o Added extra field to allow out of memory conditions to result in the
   correct error code. (This hasn't received a lot of testing...)

I've ditched the final project (which would have cleared my whole list)
since its got other complications which I don't have time to fix right
now. Still as Meatloaf says, two out of three ain't bad!
2001-11-10 17:11:36 +00:00
Alasdair Kergon
02a70e5667 o Added lvextend
o Full signed arguments to lvreduce/lvextend
o Consistent lv_number/pe map use
o Populate pv->pe_allocated
o Fixes for allocation/writing of multiple LVs
2001-11-09 22:01:04 +00:00
Joe Thornber
44e51ea5fa sync only, not ready yet 2001-11-09 08:48:22 +00:00
Alasdair Kergon
87e201460a lvdisplay & lvreduce 2001-11-08 16:15:58 +00:00
Heinz Mauelshagen
039bd945e2 more todo 2001-11-08 08:19:06 +00:00
Alasdair Kergon
e9e52d2b4b o Always set LVM_READ.
o Avoid duplicate deallocation.
2001-11-07 22:47:43 +00:00
steve
2bf92e7399 Oops. Forgot to check this in earlier. Changes as per previous check in
comments.
2001-11-07 19:27:17 +00:00
Joe Thornber
5b0df241f0 o more todo 2001-11-07 17:38:25 +00:00
Joe Thornber
76f5b05eff o Lot's to do 2001-11-07 17:25:17 +00:00
Joe Thornber
40fb6c998f o Added lvs_in_vgs_opened 2001-11-07 15:02:07 +00:00
Joe Thornber
33f50a342d o pool_empty was very wrong 2001-11-07 14:11:20 +00:00
steve
81523ab68a Tidy and changes to make code smaller.
o Created dmfs.h as a private header for the filesystem code
 o Using seq_file.[ch] written by Al Viro as a generic mechanism for /proc
   style files which have one record per line. We use a slight modification
   here, so if you are using a recent -ac kernel you'll need to replace the
   existing seq_file.[ch] with  the ones here and do a bit of editing to make
   it work. I'll submit the changes to Al Viro shortly as they are very
   small and I think make sense generally.
 o Using fail_writepage()
 o Init code for filesystem now all in dmfs-super.c
 o Some common code reduction amoung the dmfs-*.c files
 o Auto allocation of major device number (default). You can specify a
   particular major by using a module argument. If built in then you don't
   get this option at the moment but it could be added if required.
 o Hotplug support
 o General tidying
 o Updated projects.txt file
 o Patches updated to 2.4.14
2001-11-07 12:12:56 +00:00
Joe Thornber
2bf8cc62cf o Another pass at the activation code 2001-11-07 11:51:42 +00:00
Heinz Mauelshagen
1ae8247af3 Added GPL disclaimer 2001-11-07 08:50:07 +00:00
Alasdair Kergon
5ef32227ec lvcreate 2001-11-06 19:02:26 +00:00
Joe Thornber
6456e773bd o lv_extend 2001-11-06 12:01:46 +00:00
Joe Thornber
234fe53ca3 o Factor _allocate out for use by lv_extend 2001-11-06 11:31:29 +00:00
Joe Thornber
7c93e7a7b3 o lv_reduce
o  pv_maps wasn't taking a list of acceptable pvs
2001-11-06 11:19:33 +00:00
Joe Thornber
8afc6c7f4b o Contiguous allocation 2001-11-06 10:55:01 +00:00
Joe Thornber
4609d0fa3a o lv_manip.c will contain the code for lv_create, lv_extend and lv_reduce. 2001-11-06 10:29:56 +00:00
Alasdair Kergon
d452c035c6 Reinstate size of lv 2001-11-05 18:07:44 +00:00
Joe Thornber
45113c8f5a o code for building free area lists on a pv. Compiles but not run. 2001-11-05 16:41:38 +00:00
Joe Thornber
0acdd3c62b o adjacent extents are now merged into a single target when activating. 2001-11-05 13:37:13 +00:00
Alasdair Kergon
96d7d0a33e lvcreate prototype 2001-11-05 13:06:03 +00:00
Joe Thornber
b6b280267b o build lv name from <vg>_<lv> 2001-11-02 16:45:44 +00:00
Alasdair Kergon
6e6d253b1a Link in the activation library. 2001-11-02 16:28:04 +00:00
Joe Thornber
d92c105db2 o First pass at activation 2001-11-02 13:45:05 +00:00
Alasdair Kergon
906db728d6 o Changes to activation interface
o Add pointer lv->vg
o Some naming tweaks to improve clarity
2001-10-31 17:59:52 +00:00
Joe Thornber
c4b7411565 o LGPL list implementation 2001-10-31 12:47:01 +00:00
Joe Thornber
de06396046 o random little fixes 2001-10-30 17:53:21 +00:00
Alasdair Kergon
ee6bfeb8e3 lvchange 2001-10-30 14:32:48 +00:00
Alasdair Kergon
058347321f basic lvscan 2001-10-29 18:23:35 +00:00
Joe Thornber
feefe49324 o Add read_ahead and stripes to struct logical_volume 2001-10-29 15:34:56 +00:00
Alasdair Kergon
187381a9a2 prefix & vgname in lvname 2001-10-29 15:28:00 +00:00
Alasdair Kergon
993dfa4368 lvremove 2001-10-29 13:52:23 +00:00
steve
7e35a16440 o Added two items which ought to be done when we update to 2.4.14-pre3 or
above.
2001-10-29 11:06:46 +00:00
steve
e4eeb15926 o Added a file containing a TODO list.
Please add to/edit this file as you think of new ideas or discover bugs. The
items in it are in no particular order. They are also only ideas and hence may
never get implemented depending on whether they turn out to be good ideas or
not.
2001-10-29 10:03:05 +00:00
Joe Thornber
634e0db26d o rfilter was no longer accepting by default 2001-10-25 18:12:44 +00:00
Alasdair Kergon
56855c23e1 o log/overwrite=1 in config file to overwrite instead of append to log 2001-10-25 17:25:48 +00:00
Joe Thornber
0b00f742e3 o was freeing memory from the wrong pool 2001-10-25 15:24:35 +00:00
Alasdair Kergon
b7ab3f673c o fopen error message
o debug options in makefile
2001-10-25 15:07:26 +00:00
Joe Thornber
be04ea1e35 o pfilter stores results for all aliases. 2001-10-25 14:51:51 +00:00
Joe Thornber
1f8e695802 o It's a bit of a hack, but the regex filter now makes sure a device path
that passed the filter is at the front of the aliases list.
2001-10-25 14:41:28 +00:00
Joe Thornber
2d82b2c64f o rfilter now checks all aliases for a match 2001-10-25 14:19:39 +00:00
Joe Thornber
d076caf473 o use dev_name(dev) to get the name of a device, this operation is cheap
since it just get's the first alias.
2001-10-25 14:04:18 +00:00
Joe Thornber
c7abdefa31 o Remove a couple of warnings, and one bug in ttree. Spotted by the optimiser 2001-10-25 13:08:29 +00:00
Joe Thornber
ba772c0bca o Shuffle the keys to stop degeneracy. 2001-10-25 12:38:18 +00:00
Joe Thornber
5bad234119 o Trivial binary tree 2001-10-25 11:38:19 +00:00
Joe Thornber
c7e7baaf23 o added aliases list to struct device. 2001-10-25 11:34:55 +00:00
steve
36658a671b o Correction in logic for write access to tables 2001-10-25 11:05:29 +00:00
steve
045f2e10ba o Fix typos from yesterday 2001-10-25 10:37:05 +00:00
Joe Thornber
fb5a7db66d o Merged common code between hash_destroy and hash_wipe. 2001-10-25 08:31:43 +00:00
Alasdair Kergon
ba7d33982e persistent cache fully incorporated. Goodbye to scanning /dev/cdrom :-) 2001-10-24 17:53:50 +00:00
Joe Thornber
c62279a755 o Updated 00_makefile
o 00_bh-async-3 has been merge with vanilla
2001-10-24 10:52:10 +00:00
steve
17fa1a7ffb o Error list handling now part of fs rather than part of table. 2001-10-24 08:26:10 +00:00
steve
e89ceac351 o Fix bug in dmfs-error.c where it could return too many bytes under some
circumstances.
 o Use sscanf() in dmfs-table.c
 o Use do_generic_file_read() instead of original hand made loop in dmfs-table.c
2001-10-24 07:51:42 +00:00
Alasdair Kergon
0b8c30c109 persistent filter & some log message changes 2001-10-23 18:20:27 +00:00
Joe Thornber
9ab0f463cc o removed old files 2001-10-23 14:17:07 +00:00
Joe Thornber
6433dda7b8 o forgot to use the path passed into _read_array. 2001-10-23 13:12:05 +00:00
Joe Thornber
fa7a2f4be4 o test program for the new persistent filter. 2001-10-23 13:11:28 +00:00
Alasdair Kergon
ba90e16505 deallocations 2001-10-23 12:33:57 +00:00
Joe Thornber
008f710203 o rethink of the persistent filter 2001-10-23 12:24:55 +00:00
Alasdair Kergon
df2740f126 filter integration into tools 2001-10-23 11:50:49 +00:00
Joe Thornber
2db89d143e o forgot to retry on EINTR or EAGAIN, doh ! 2001-10-23 11:16:30 +00:00
Joe Thornber
0525d49da3 o forgot 'static' 2001-10-22 14:40:31 +00:00
Joe Thornber
e2b0745882 o composite filter that allows us to merge filters. Think of it as &&'ing
filters in order.

eg,

	f = composite_filter_create(2, regex_filter, persistent_filter);

  ownership of the filters passes, they will be destroyed when f's
  destroy method is called.
2001-10-22 14:39:12 +00:00
Joe Thornber
92e804fc50 o Filter which caches valid devices in a file. Pass in init == 1 to the
constructor if you want it to ignore the existing cache and check every
  device again (eg, vgscan, pvscan).
2001-10-22 14:14:00 +00:00
Alasdair Kergon
67abf45576 reinstate a removed line 2001-10-22 13:44:09 +00:00
Joe Thornber
d2c9c814e7 o removed 00_latest since it never is. 2001-10-22 10:03:05 +00:00
Joe Thornber
22f8881a64 o tidying 2001-10-21 10:24:10 +00:00
Joe Thornber
4ab20322fe o Filter for the dev cache that takes values from config file:
devices {

        # first match is final, eg.  /dev/ide/cdrom
		        # get's rejected due to the first pattern

					filter=["r/cdrom/",         # don't touch the music !
							"a/hd[a-d][0-9]+/",
							"a/ide/",
							"a/sd/",
							"a/md/",
							"a|loop/[0-9]+|", # accept devfs style loop back
							"r/loop/",        # and reject old style
							"a/dasd/",
							"a/dac960/",
							"a/nbd/",
							"a/ida/",
							"a/cciss/",
							"a/ubd/",
							"r/.*/"] # reject all others
}


Alasdair this is ready to roll into the tools now.
2001-10-19 18:20:37 +00:00
Joe Thornber
5370eeecea o First pass at the regex code. lib/regex/matcher takes an array of regex's
and builds a *very* efficient engine that will tell you which regex a string
  matches with only a single pass through the string.  To be used in the config
  file when specifying devices.

o Anchor's aren't supported yet (^ and $) but that won't take long.

o Also when we get some realistic config files we may want to consider adding an
  extra level of indirection to the dfa state in order to compress the table.
  It all depends on how large typical tables get.
2001-10-19 14:36:57 +00:00
Alasdair Kergon
ba71cb5dd7 pvdisplay 2001-10-18 16:55:19 +00:00
steve
9aad6c2c52 o Remove unused variable. 2001-10-18 15:59:25 +00:00
Alasdair Kergon
4d9627f20c pvchange 2001-10-17 15:29:31 +00:00
steve
c142492e91 o Fix crash that Patrick reported 2001-10-17 15:03:00 +00:00
steve
6bf8d9e207 o Fix a typo. This should fix devfs support. 2001-10-17 14:34:53 +00:00
steve
4f9a6168c1 o Patches to go with earlier check in 2001-10-17 13:13:25 +00:00
steve
38397f99aa Ok. this is the big one.... the change to the new fs interface.
Things to note:

 o Changes to the dm-*.c files have been kept as small as possible during
   the development of the new fs interface and there are a few places where
   the new code does odd things to give the original code what it wants. These
   places will gradually go away during the next few days once we are sure the
   new code is sound.
 o I've spent most of my testing time looking at the parser since thats where
   a lot of the changes are, I've not checked the actual I/O very much, but
   then that code hasn't changed at all.
 o The print operation in the target type operations is there to help in
   debugging and will go away eventually
 o There are some other printk's which will also go away once we are sure that
   things are working correctly.
 o I've tagged the old code with PRE_DMFS if you want to use that until this is
   stable.
 o There are no kernel patches for this yet (will fix after lunch... :-)
      o Makefile needs some changes
      o need to EXPORT_SYMBOL(deny_write_access); in ksyms.c

How to use the new interface ?

 mount -t dmfs dmfs /mnt/dm
 cd /mnt/dm
 mkdir fish fish/tank
 cd fish/tank
 cat ~/my.table > table
 cd ..
 ln -s tank ACTIVE

Creates a logical volume called fish and activates a table called tank, if
there is a problem doing the link, look in /mnt/dm/fish/tank/errors to see
what is wrong.

If you see any odd things happening, let me know right away as I'm sure there'll
be one or two things that slipped through my testing.
2001-10-17 11:34:50 +00:00
steve
f8686d0e75 o Update to parser
o Extra checks in symlink routines
2001-10-17 11:09:43 +00:00
Alasdair Kergon
549e3c8f9d pvscan 2001-10-16 18:07:54 +00:00
steve
bb56225b95 o Fixed infinite loop in parser
o Fixed error handling whilst creating volumes
 o General tidy up
2001-10-16 17:09:27 +00:00
Alasdair Kergon
f00be261ba vgchange 2001-10-16 16:25:28 +00:00
steve
9cd94f26d0 o Get file size correct for table
o Make parser look at the right object
2001-10-16 12:17:54 +00:00
steve
4d8f5c80a7 o Fixes to parsing code 2001-10-16 11:56:55 +00:00
steve
24a23acc3d o Tidy up, removing debugging printk's no longer needed 2001-10-16 10:38:13 +00:00
steve
ca8703cfd8 o More bug fixes 2001-10-15 22:39:14 +00:00
Alasdair Kergon
6dcbb5b2f8 vgextend 2001-10-15 22:04:27 +00:00
Alasdair Kergon
a84fdddb2a vgcreate basic extent size validation 2001-10-15 20:29:15 +00:00
Alasdair Kergon
38bb2f8ceb More vgcreate error trapping 2001-10-15 18:39:40 +00:00
steve
23f5ef4345 o More fixes 2001-10-15 16:40:17 +00:00
Alasdair Kergon
ef8a2a9054 o lvm readline error-case tidy-up
o more vgcreate error cases
2001-10-15 12:49:58 +00:00
steve
96103d0e36 o Some bug fixes
o Added symlink ops
 o Some extra sanity checks
2001-10-15 11:31:00 +00:00
Joe Thornber
ff5f6748df o vgcreate 2001-10-12 14:25:53 +00:00
Alasdair Kergon
1c1fd6c366 vgcreate 2001-10-12 12:21:43 +00:00
Joe Thornber
32d37d00cb o make ios the first argument to pv_create 2001-10-12 10:52:32 +00:00
Joe Thornber
82f6cda966 o lift call to check out of pvcreate_single 2001-10-12 10:45:04 +00:00
Joe Thornber
f1ff8ff0d0 o rename _single pvcreate_signle 2001-10-12 10:43:36 +00:00
Joe Thornber
756c72902f o made _single static 2001-10-12 10:42:31 +00:00
Joe Thornber
73f8f0bbd0 o pvcreate
o added uuid unit

o stubbed partition stuff
2001-10-12 10:32:06 +00:00
steve
18ed528f5d o Further tidyups and fixes. 2001-10-12 10:06:40 +00:00
Alasdair Kergon
8fd2f136bc sync 2001-10-12 09:52:30 +00:00
Alasdair Kergon
0524b1bf67 vgreduce, vgremove, vgrename & vgscan 2001-10-11 21:35:55 +00:00
steve
15716f65ce Some more sync ups
o Error file routines (initial idea)
 o Various fixes for bugs
 o Tidy a few things
 o Added a bit of debugging code ready for when this gets tested
 o get_exclusive_write_access() function which will get moved into namei.c
   I hope (and rewritten accordingly), should this become the final version
   used.

Still a few more areas need thinking about, but in general much closer now I
think. Last area to sort out before testing is the symlink code which is
pretty close now... just a few more checks needed and the actual calls to
the core code.
2001-10-11 20:29:00 +00:00
Joe Thornber
d46bdba332 o try incrementing pv_number from 1 2001-10-11 16:31:09 +00:00
Joe Thornber
760728110a o if contained &= instad of & 2001-10-11 15:09:31 +00:00
Joe Thornber
12d0a194ca o initalise list_heads, initialise list_heads, initi .. 2001-10-11 14:21:38 +00:00
Joe Thornber
4104543508 o a very quick hack to get vg_number right 2001-10-11 14:10:18 +00:00
Joe Thornber
5c211db015 o set PV_ALLOCATABLE flag correctly 2001-10-11 13:34:17 +00:00
Joe Thornber
2dc6180f8d o pv->system_id 2001-10-11 13:22:51 +00:00
Joe Thornber
e222a34b69 o vg->pv_act 2001-10-11 13:05:55 +00:00
Joe Thornber
ef17d95063 o calculate pv_numbers and lv_numbers for LVM1 support 2001-10-11 10:55:19 +00:00
Joe Thornber
853502e5d7 o pe_start wasn't being set properly when exporting to disk
o added a check for lv's with null lv_name

o setup pv->lv_cur correctly

o test program for vg_write
2001-10-11 10:08:44 +00:00
steve
c18e297e77 o Everybody needs dm.h
o Fixed to work with highmem
 o Added dmfs private inode struct for lv and table directories
 o Fixed a number of errors/typos
 o Status file read returns 0 so we can leave this until we've actually got
   something to report in this now.
 o New locking on tables.... still some issues to be worked out here but
   closer now I think.
 o Now use mapping of table directory to hold pages rather than mapping of
   table file inode. Need to write a note to myself to fix issues with the
   file length at the same time....

Well thats enough for tonight I think. The error file will be part of
tomorrows work.
2001-10-10 21:49:21 +00:00
Joe Thornber
c5a49599ba o sync 2001-10-10 17:11:31 +00:00
Alasdair Kergon
df9da9edf5 standardise some log messages 2001-10-10 16:36:32 +00:00
Joe Thornber
e2200fd050 o builds a very sub-optimal table 2001-10-10 15:30:31 +00:00
Joe Thornber
c6207f5d9c o allocate and zero the extents before exporting the lv's 2001-10-10 14:56:53 +00:00
Joe Thornber
4302b7ff6b o zero all of uuid 2001-10-10 13:33:20 +00:00
Joe Thornber
50a7923438 o uuid_list->id should be NAME_LEN wide 2001-10-10 13:30:58 +00:00
Joe Thornber
ab416445c8 o sizeof(NAME_LEN), don't do that 2001-10-10 13:24:16 +00:00
Joe Thornber
a54698d43c o forgot to init a list head 2001-10-10 13:09:40 +00:00
Joe Thornber
c5a77cc1c0 o dev_write 2001-10-10 13:03:10 +00:00
Alasdair Kergon
a9ffa811fc Tidy metadata diagnostic messages. 2001-10-10 12:45:20 +00:00
Joe Thornber
080a2608e0 o return data not 1 in read_ov 2001-10-10 12:42:03 +00:00
Joe Thornber
57f2e83d6a o check for orphaned pv's when reading 2001-10-10 12:28:10 +00:00
Joe Thornber
5b030139d3 o pv_setup for format1, this is the last one ! 2001-10-10 10:55:55 +00:00
Joe Thornber
0da1ff42d1 o AC_INIT was pointing to an old file 2001-10-10 10:11:25 +00:00
Joe Thornber
2c599b7baa o metadata.h was in here twice 2001-10-10 10:09:12 +00:00
Joe Thornber
5c8af8d21a o pv_write for orphan pv's 2001-10-10 10:05:29 +00:00
Joe Thornber
026f3cfde2 o add munging for format1 and 2 2001-10-10 09:36:29 +00:00
Joe Thornber
f6349180e8 o Code to calculate the metadata layout. 2001-10-10 09:25:04 +00:00
Joe Thornber
aa6421921c o stub pv_write to stop tools crashing 2001-10-09 17:44:58 +00:00
Joe Thornber
7d41d2dab2 o fix seg fault while reading extents 2001-10-09 17:36:48 +00:00
Joe Thornber
f0b4d18f93 o remove another spurious error message 2001-10-09 17:30:20 +00:00
Alasdair Kergon
6750f06e10 o vgremove.
o filter devices by major.
2001-10-09 17:20:02 +00:00
Joe Thornber
b2bd38fa9e o spot empty list in build_vg 2001-10-09 17:09:46 +00:00
Joe Thornber
3482a01e22 o proposed interface to the kernel driver 2001-10-09 16:44:30 +00:00
Joe Thornber
6335467552 o dev-mgr disappears 2001-10-09 16:13:12 +00:00
Joe Thornber
4a39e65b62 o change pv_read to take a name rather than a device 2001-10-09 16:05:34 +00:00
Joe Thornber
c50a23e918 o remove spurious log message 2001-10-09 14:42:58 +00:00
Joe Thornber
1e76b72b98 o hack, hack, hack 2001-10-09 14:26:45 +00:00
Joe Thornber
b94cf39eef o vg_write compiles 2001-10-09 10:47:52 +00:00
Joe Thornber
fef254ffff o get_vgs works 2001-10-09 09:22:50 +00:00
Joe Thornber
e5495863a2 o pv_Read works 2001-10-09 08:58:52 +00:00
Joe Thornber
3b4df2abf0 o get_pvs now works for format 1 2001-10-09 08:11:52 +00:00
Alasdair Kergon
aef2aee6a4 vgrename & vgck 2001-10-08 18:44:22 +00:00
Joe Thornber
d0d9519149 o test program for get_pvs 2001-10-08 18:09:31 +00:00
Joe Thornber
685df1d2c5 o get_pvs for format 1
o fix vg_read if vg doesn't exist
2001-10-08 17:53:43 +00:00
Joe Thornber
08e6b6f2e7 o added pretty printing to read_vg_t, run this on your system
to see what vg's you've got

S: ----------------------------------------------------------------------
2001-10-08 17:28:49 +00:00
Joe Thornber
66c887d0f3 o read_vg works (or so it claims) 2001-10-08 16:08:16 +00:00
Joe Thornber
22e9960697 o dev_cache_t program works 2001-10-08 13:58:52 +00:00
Joe Thornber
64aa6e1f2d o sync 2001-10-08 12:11:33 +00:00
Joe Thornber
7a93ed9d04 o we were stuill building dev-mgr files 2001-10-08 10:35:59 +00:00
Joe Thornber
a905e922e9 o read_vg_t compiles 2001-10-08 10:20:25 +00:00
Joe Thornber
f9f08fc720 o makefile for read_vg_t 2001-10-08 09:50:00 +00:00
Joe Thornber
8d402d76d0 o get things compiling 2001-10-08 09:45:16 +00:00
Joe Thornber
46fda6281c o test program for reading a vg 2001-10-08 08:47:27 +00:00
Alasdair Kergon
a14dbe1ea6 Sync include file changes. 2001-10-05 21:39:30 +00:00
Joe Thornber
18810a4c16 o end of day sync 2001-10-05 16:36:53 +00:00
Joe Thornber
147bc80dba o replace {stack; return 0;}'s with a macro (just for this file). 2001-10-05 15:48:05 +00:00
Joe Thornber
c7a484195a o low level write path 2001-10-05 15:20:40 +00:00
Joe Thornber
4968eb6503 o finished writing extent reading code 2001-10-05 13:59:44 +00:00
Alasdair Kergon
a6f2d698a9 revised flags and comments 2001-10-05 13:03:03 +00:00
steve
ea5ed93ea5 Just a small sync of pending changes before I start looking at this again
more seriously.

 o Odds and ends
2001-10-05 10:00:13 +00:00
Alasdair Kergon
e1140134c6 metadata status flags regrouping & comments; misc tool changes 2001-10-04 22:53:37 +00:00
Joe Thornber
5ed11e012e o vg_read for format1 2001-10-04 17:48:55 +00:00
Alasdair Kergon
5380bd39ca makefile support for tests 2001-10-04 12:07:29 +00:00
Joe Thornber
2ee2685688 o define the uintN_t types 2001-10-04 11:40:13 +00:00
Joe Thornber
782002245b o forgot to add this before 2001-10-04 10:25:34 +00:00
Joe Thornber
7fc0905843 o got dbg_malloc_t working, Alasdair could you look at the Makefile.in it
seems to be having trouble with the dependencies.

o removed some files from the lib makefile that don't compile yet.
2001-10-04 10:13:07 +00:00
Joe Thornber
72ecb99e54 o Use the __alignof__ extension to set DEFAULT_ALIGNMENT to that required
for a 'double'.
2001-10-04 09:10:11 +00:00
Alasdair Kergon
c863507d08 vgcreate & lvmchange outlines 2001-10-03 20:38:07 +00:00
Alasdair Kergon
cff86c9093 vgrename & pvchange outlines 2001-10-03 17:03:25 +00:00
Joe Thornber
0479dfcc54 o added dev-cache.c, dev-io and sorted source files alphabetically 2001-10-03 12:46:17 +00:00
Joe Thornber
68dd67f21c o moved dev-cache to device dir 2001-10-03 12:43:29 +00:00
Joe Thornber
540f6858b5 o I've moved the dev-cache and dev-io into here since this directory has a
better name.  dev-mgr will be removed at some point.
2001-10-03 12:41:29 +00:00
Alasdair Kergon
b61e791a4f lvremove outline 2001-10-03 12:34:08 +00:00
Joe Thornber
d0986f9482 o code sync for dev-cache.c
o made copyright headers the same

o added __attribute ((format ... to print_log so we'll get better compile errors

o added iterator to the hash table
2001-10-03 11:06:31 +00:00
Alasdair Kergon
112cb0dc28 pvscan framework 2001-10-02 17:09:05 +00:00
Joe Thornber
0d3d7fdcf2 o test program for the device cache 2001-10-02 13:44:44 +00:00
Joe Thornber
5d6b89ef3b o test program for the hash table. 2001-10-02 12:46:04 +00:00
Joe Thornber
ed0b26c09e o Test program for dbg_malloc unit.
I'm postfixing test programs with _t, and benchmarks with _b
2001-10-02 12:27:55 +00:00
Alasdair Kergon
ae292bd920 Another step towards consistency & compilation. 2001-10-01 22:12:10 +00:00
Alasdair Kergon
6c85a90723 Misc structural changes. 2001-10-01 19:36:06 +00:00
Alasdair Kergon
852592066c Misc structural changes. 2001-10-01 19:29:52 +00:00
Joe Thornber
96e1bc9b44 o changed dev-manager to a dev_filter 2001-10-01 16:21:21 +00:00
Joe Thornber
b41d81ed31 o get block size moved to dev-io.c 2001-10-01 16:07:29 +00:00
Alasdair Kergon
e241ec2244 merge partition code 2001-10-01 15:59:40 +00:00
Alasdair Kergon
16e1f1a94c Tidy includes 2001-10-01 15:53:21 +00:00
Joe Thornber
7a68c42b26 o drop the reference counting in the devices. 2001-10-01 15:43:51 +00:00
Alasdair Kergon
37ccc2e118 Merge fixes 2001-10-01 15:29:39 +00:00
Joe Thornber
4192fe1ab2 o missing * 2001-10-01 15:28:28 +00:00
Joe Thornber
d5c743d7bb o added filter type. 2001-10-01 15:27:16 +00:00
Alasdair Kergon
11814d63e8 Tidy include files 2001-10-01 15:14:39 +00:00
Alasdair Kergon
b753656d50 Create symlinks to .h files in an include directory 2001-10-01 13:36:54 +00:00
Joe Thornber
f7e87611fc o I'm splitting dev-manager in two. dev-cache is the bottom layer that
handles devices.  Dev-manager will sit on this filtering the view.
2001-09-28 15:42:25 +00:00
Joe Thornber
1fb0e1900e o list.h from kernel for userland tools to use. 2001-09-28 13:19:17 +00:00
Joe Thornber
954a9731e0 o logical data structures 2001-09-28 13:15:30 +00:00
Joe Thornber
65c3364ad8 o generic hash table to store void *'s, not efficient, but adequate for LVM. 2001-09-28 13:08:44 +00:00
Joe Thornber
3d72b7dccc o rewrite of dm_user_bmap, not tested though. 2001-09-27 10:15:02 +00:00
Patrick Caulfield
13ee569f06 Fix prototype for malloc_aux 2001-09-27 10:01:17 +00:00
Patrick Caulfield
d79ef23a75 Don't include asm/* files 2001-09-27 10:00:47 +00:00
steve
5d0797d4ba o Kill write funcs for error/status files
o Redo write logic for table file
 o Relax rules for symlink content by removing the rewriting function

Well I probably won't get a chance to work on this tomorrow, so this is my
changeset to date.
2001-09-26 20:24:39 +00:00
Joe Thornber
47a8d7475f o table creation works again. 2001-09-26 19:48:20 +00:00
Joe Thornber
4939053121 o It should build now 2001-09-26 17:32:57 +00:00
Joe Thornber
b525bf554e o typos 2001-09-26 17:07:10 +00:00
Joe Thornber
f00285d2b2 o remove steve's insane ramblings from my code. 2001-09-26 14:32:07 +00:00
steve
040f8d6eda o Lunchtime. 2001-09-26 11:47:02 +00:00
steve
66d905325c o More updates 2001-09-26 09:26:10 +00:00
steve
8b0cd95e73 o Beginnings of new interface. 2001-09-26 08:06:46 +00:00
Alasdair Kergon
d867cca6d9 fix memory leak 2001-09-25 16:26:38 +00:00
Joe Thornber
a28f736369 o quick tidy up 2001-09-25 15:23:20 +00:00
Alasdair Kergon
5c3a71cc59 lvactivate checkpoint commit 2001-09-25 12:49:28 +00:00
Alasdair Kergon
cef6dadb08 Another missing dependency. 2001-09-24 22:44:06 +00:00
steve
36be817a3e o Check in case of setting up volumes before root is mounted. 2001-09-24 15:18:45 +00:00
steve
02f571f081 Well when things start looking so complicated that future direction becomes
non-obvious, its time to simplify :-)

 o Moving towards a simpler and more obviously correct interface
 o Removed some fs operations in directories representing volumes
 o Changed some file names
 o Made things cleaner

more changes to follow...
2001-09-24 15:10:33 +00:00
Alasdair Kergon
157159e487 Fix dependencies. 2001-09-24 12:05:04 +00:00
Alasdair Kergon
02ada9f800 Makefiles & autoconf. 2001-09-21 12:37:43 +00:00
Alasdair Kergon
6fcf9a97bb Initialise root node pointer. 2001-09-21 12:32:37 +00:00
Alasdair Kergon
17a5d8799f Unused variables. 2001-09-21 12:31:57 +00:00
steve
31f3fe7a22 o Sync up of todays changes .... nothing very important 2001-09-20 22:58:06 +00:00
steve
89e46d3d83 o Bug fix in error path 2001-09-20 20:22:15 +00:00
steve
885795e67d o Use ERR_PTR and PTR_ERR rather than an extra argument. 2001-09-20 19:25:58 +00:00
steve
92bfb53dd4 o Changed to use table->err_msg rather than passing functions around 2001-09-20 18:22:35 +00:00
steve
4cecbeb115 o Some new files (also part of new fs interface) 2001-09-19 21:28:25 +00:00
steve
5971480f55 o Further changes to new file system interface 2001-09-19 21:27:46 +00:00
steve
05bebea511 o Removed the error reporting function from the target constructor function
arguments. Errors are now reported by setting a pointer in the table to
   point to an error message.
2001-09-19 21:27:15 +00:00
Alasdair Kergon
76fa6c5cfb hardsect/blksize handling 2001-09-19 17:46:27 +00:00
steve
633b68b518 o Added ref counting to tables
o Further changes to new fs interface
2001-09-19 16:01:27 +00:00
steve
6913d8e995 o Fixed a bug where we were not holding a reference of the block devices
used by the targets correctly.
2001-09-19 14:54:44 +00:00
steve
f3654e6f8d o Change the deallocation of tables to match the vmalloc changes in my
previous commit
2001-09-19 11:02:02 +00:00
steve
d685dbcf22 o Cut down number of vmallocs to increase speed and efficiency 2001-09-19 10:59:10 +00:00
steve
6a57fa079e o More fs fiddling. Another check point commit. 2001-09-19 10:32:51 +00:00
steve
0a91d145ba o Bug fix to LV_BMAP ioctl()
o Account for I/O against tables rather than logical volume devices
2001-09-19 10:32:09 +00:00
Alasdair Kergon
c2866e799d Fix allocation & list-handling. 2001-09-18 20:03:00 +00:00
steve
d8cffcaae7 These files are now a bit closer towards what I'm aiming at. Still a lot
more to do though.
2001-09-18 16:54:14 +00:00
steve
30abca7be2 Should have been included in the previous commit. 2001-09-18 16:53:18 +00:00
steve
edce87f3fb o Changed dm_create() to return a struct mapped_device rather than an int
o Changed dm_remove() to accept a struct mapped_device argument rather than
   a name
 o We no longer have to look up devices by name, the dcache handles that
   nicely for us
 o Fixed a bug where we were freeing a structure before we'd finished with
   it.
 o The name field in struct mapped_device is now only used in a very few
   places in dm.c and will be replaced in future with a back reference to
   the dentry rather than keeping the name in two places.
2001-09-18 16:52:50 +00:00
steve
66bac98fc2 o New file dmfs-super.c
o dmfs-dir.c becomes dmfs-lv.c
 o dmfs-file.c becomes dmfs-table.c
 o A few tweeks and updates

The main reason for the slow progress on these files (which are not yet used
by the device mapper) is that we are working out what this interface should
look like as we go along.

Once this has evolved a bit further and in a state where it can be used we'll
announce it on the lists for further comment.
2001-09-18 15:38:54 +00:00
Alasdair Kergon
59156de92b Error checking: only allow block devices & test for 'nodev'. 2001-09-17 21:17:30 +00:00
steve
e0d7d10600 o Again, please ignore this for the time being. 2001-09-17 19:05:49 +00:00
Alasdair Kergon
daaf862257 o Arbitrary mount path.
o Name length 128.
2001-09-17 16:55:31 +00:00
steve
9de53d4b59 o Work in progress, please ignore these files for a day or two whilst I
get everything going.
2001-09-17 15:42:59 +00:00
steve
f1571e2d46 o Fixed code where return value of vmalloc wasn't checked 2001-09-17 11:23:13 +00:00
steve
bd28d06298 o Use count should be an atomic_t 2001-09-17 09:01:23 +00:00
steve
a24e4655eb o Targets now get rw passed through so they can do COW for example
o Added error handler (not sure that this is the "correct" way to do
   this at the moment, so its a bit exprimental for now)
2001-09-14 16:22:02 +00:00
steve
20a6c8d8e5 o Support /sbin/hotplug 2001-09-14 15:35:06 +00:00
steve
98d264faf4 o Made pending I/O wait uninterruptible 2001-09-14 14:03:02 +00:00
steve
321902a9b5 o New ioctl(): LV_BMAP which is compatible with LVM so that hopefully LILO
will work. I haven't actually tested that, but this support at least will
   be required.
2001-09-14 13:45:40 +00:00
Alasdair Kergon
8df5d06f9a Use dmfs_ function name prefix (in line with other file systems). 2001-09-14 13:27:58 +00:00
Patrick Caulfield
e69ea529cc lc->in->f_op->read expects its buffer to be in userspace so surround it in
set_fs() etc calls
2001-09-14 12:27:57 +00:00
steve
15405b1119 o As promised earlier, the device registration is now hashed and the
lists are private to dm-blkdev.c
2001-09-14 11:25:51 +00:00
Alasdair Kergon
d2f97ce2da Always truncate error file. 2001-09-14 11:15:54 +00:00
Patrick Caulfield
543ca631e9 Don't store things in _devs[-1] - it's not nice. 2001-09-14 10:54:08 +00:00
steve
f184886db1 o Forgot to create slab caches for dm-blkdev.c
o Misc code tidy
2001-09-14 10:40:20 +00:00
Alasdair Kergon
8432ab4324 o kmalloc error check
o error file mode
The 1st Jan 1970 date I'm seeing in /dev is a devfs issue I think.
2001-09-14 10:06:22 +00:00
steve
6c05b37ca3 Changes to device handling;
o Only one list of block devices for all tables
 o Locking to ensure that block devices only get opened once
 o Block device handling is now in dm-blkdev.c
 o We open block devices when we create the tables and hold them open until
   the table is destroyed (this prevents the module for the device being
   unloaded after table parsing and before the table is used)
 o We compute the hardsect size when the table is created rather than when
   someone requests it.

Still to fix/change:

 o Probably want to hash the device lists in dm-blkdev.c and also remove refs
   to struct dm_bdev outside this file.
 o Need to ensure that hardsect_size doesn't change when new tables are
   swapped in (maybe this ought to be a per volume parameter and the tables
   will only parse if they match the value for the volume?).

Things are changing fast here, so if you want a stable version of thic code
try checking out yesterdays.
2001-09-14 09:45:35 +00:00
steve
35f4beeb47 o New code for handling block device registration. Not yet used but checked
in for backup purposes.
2001-09-14 08:06:02 +00:00
Alasdair Kergon
cbad7caa68 is_identifier characters 2001-09-13 21:50:38 +00:00
steve
b0388a4012 o Two fixes which Alasdair pointed out. 2001-09-13 20:10:14 +00:00
steve
df3fab4d55 o Tidy in dm-fs.c
o Magic number is really magic
 o Check on directory names
2001-09-13 19:41:46 +00:00
steve
da49f88a03 o Forgot to add ref to module. 2001-09-13 19:36:40 +00:00
Alasdair Kergon
e28feceb06 Add dm-parse to makefile 2001-09-13 19:09:23 +00:00
steve
50496a164d o Now we handle target modules correctly
o Moved the linear target into its own module (not really because it needs to
   be there, but because its useful to have a simple example so people can see
   what we are doing)

Btw, this needs testing properly.
2001-09-13 18:30:05 +00:00
Alasdair Kergon
6f1dce1572 o Remove hard-coded mount point
o Fix macro for compilation
2001-09-13 16:52:50 +00:00
steve
6847776ae7 o Some structures change size with different configs, so always include
<linux/config.h> first.
2001-09-13 14:03:42 +00:00
steve
67bd53bdd8 o Some ioctl() commands. 2001-09-13 14:01:13 +00:00
Patrick Caulfield
e735abfdfd Fix includes so that string functions get prototyped 2001-09-13 12:38:31 +00:00
Patrick Caulfield
1de93a2d6d Fix includes so that string functions get prototyped.
Fix cast - repeat after me Joe: "I must not cast pointers to ints"!
2001-09-13 12:38:08 +00:00
steve
36f9e7c742 o I'm afraid that wu and wl etc. is just too confusing.... I've changed it
to up_write() and down_write() etc so that you can see what kind of a lock
   it is (otherwise it could be anything.. semaphore, spinlock, spinlock_bh,
   spinlock_irq, br_lock, etc.)
2001-09-13 11:29:38 +00:00
steve
9462763bbb o Use kmem_cache_destroy() to remove slab cache. 2001-09-13 11:07:08 +00:00
Patrick Caulfield
4ae0880ea6 Set DEFAULT_ALIGNMENT to 8 for Alpha.
If you think this is wasteful on other arches then stick some ifdefs in.
2001-09-13 09:03:42 +00:00
Alasdair Kergon
6ae2b6c835 Add dm-parse 2001-09-12 13:50:26 +00:00
Joe Thornber
a0f180fd48 o first sattab at custom fs. Very rough ATM.
Mount the dm-fs filesystem on /device-mapper (will fix later).  mkdir
to create a device, inside that directory every file you create is a table
file.  If there are errors <table>.err will appear automagically.  Mv a table
file to ACTIVE to activeate the device.  I'm not happy with mv being the
binding command, symlink would be better.
2001-09-07 11:34:46 +00:00
Joe Thornber
bf1cf89914 o more tidy ups from Clausen. 2001-09-05 07:48:11 +00:00
Joe Thornber
297a047fb4 o Added two new functions get_child [Andrew Clausen] and get_node. I think
this makes 'high()' a bit more understandable.
2001-09-04 10:17:28 +00:00
Joe Thornber
52ffc15ffc o added new constant CHILD_PER_NODE to make things clearer 2001-09-03 08:36:41 +00:00
Joe Thornber
e478c9c693 o Various tidy ups [Andrew Clausen] 2001-09-02 10:49:20 +00:00
Joe Thornber
d004f28074 o added global dm_table_lookup_device(path)
o changed linear target to : <device_path> <start>
2001-08-31 18:26:27 +00:00
Joe Thornber
bc68ed8b1d o added reference counting to the destination devices, make sure that the
destructor for any targets you write call dm_table_remove_device.
2001-08-31 16:36:56 +00:00
Joe Thornber
04555ae650 o split struct mapped_device into mapped_device and dm_table
o seperated loading of a table from binding a table to the device

These should allow multiple tables to be managed by dm-fs
2001-08-31 15:13:33 +00:00
Joe Thornber
e8f62085be o tidy ups 2001-08-31 12:49:31 +00:00
Joe Thornber
f430bffe2a o allocate io_hooks from a slab 2001-08-31 10:25:32 +00:00
Joe Thornber
1f0520634f o stray return -ENXIO in reuqest [Jens Axboe] 2001-08-31 09:43:35 +00:00
Joe Thornber
902d4c31fb o rebuilt 00_latest 2001-08-31 09:14:55 +00:00
Joe Thornber
17364ac09f o split uml part out 2001-08-29 14:23:40 +00:00
Joe Thornber
0b889f8f81 o various little tidy ups 2001-08-29 13:58:48 +00:00
Joe Thornber
40e349ff35 o change format of table line to <start> <len> <target> ... 2001-08-28 14:56:47 +00:00
AJ Lewis
c943b1b1df o Enable building dm modules (called dm-mod)
o split the patches into config and makefile specific.
2001-08-28 14:11:55 +00:00
Joe Thornber
912bc1d4e1 o more deferred io stuff 2001-08-28 14:05:22 +00:00
Joe Thornber
cacb1533a3 o added proper suspend/resume support, it now waits for all 'in flight' io's
to complete.

  
  moved comment to dm.h
2001-08-28 13:04:44 +00:00
Joe Thornber
f0feaca9d7 o ACtual source code patch 2001-08-24 09:50:16 +00:00
Joe Thornber
b6656f171b o a couple of patches we'll need for deviec-mapper 2001-08-24 09:39:32 +00:00
Joe Thornber
6206ab3931 o you can now load maps repeatedly without hanging
o tested multiple target map

Driver is now useable
2001-08-23 17:10:05 +00:00
Joe Thornber
c35fc58b1f o dm_add_target was returning 0 an error when it shouldn't
o reference count was being checked badly
2001-08-23 16:45:43 +00:00
Joe Thornber
deed8abed7 o map loads ok now
o request function appears to work, but something is segfaulting when i
  mke2fs
2001-08-23 12:35:02 +00:00
Alasdair Kergon
7151ad23f0 Tweak permissions - currently root-only. (no support for non-root ownership
in procfs except for PIDs)
2001-08-22 20:10:06 +00:00
Joe Thornber
0166d938af o chagngesd alloc to return 0 on success 2001-08-22 15:59:56 +00:00
Joe Thornber
6194aeddb0 o fs_add and fs_remove actually create/remove the device now 2001-08-22 15:33:08 +00:00
Joe Thornber
903dbf2c30 o added brackets to make t->name = (char *) (t + 1) more explicit 2001-08-22 15:12:31 +00:00
Alasdair Kergon
9380f9ff57 Return 0 on success now. 2001-08-22 15:02:55 +00:00
Joe Thornber
259ed95486 o wu macro was doing a read unlock
o added dm_fs_add/remveove
2001-08-22 15:01:09 +00:00
Joe Thornber
2ebc92681e o _tok_cpy was broken 2001-08-22 14:30:30 +00:00
Joe Thornber
195a1ffe13 o fix get_word
o capy name in when registering targets

o change _line_splitter so it expects the process functions to return zero
  on success
2001-08-22 14:13:26 +00:00
Joe Thornber
a8c2978185 o _get_workd was always returning the end on iput 2001-08-22 13:52:26 +00:00
Alasdair Kergon
140f97a457 o Initialisation tweaks.
o Use different major number so it can co-exist with LVM 1.
2001-08-22 13:46:58 +00:00
Joe Thornber
7f94445a1e o set permissions on /proc/device-mapper/control to -w-w-w 2001-08-22 13:45:28 +00:00
Joe Thornber
82a89aec65 o call dm_init_fs 2001-08-22 13:41:00 +00:00
AJ Lewis
7e95110232 o Ok, this seems to be a much better method for caching valid
devices based on /proc/devices
   + The dev_mgr structure now has a 256 element char array that is
     initially all 0s
   + When a match is found, the array element corresponding to the major
     number of the match is set to a non-zero value
   + to check for a match, all one has to do is check that the array
     element at the major number in question is non-zero.
 o I'm wondering if we should do this with bitwise operators instead?  Does
   anyone expect the major numbers to grow larger than 8-bits?
2001-08-21 20:40:37 +00:00
AJ Lewis
ec4aaaad89 o Quick and dirty *UGLY* hack of a /proc/devices cache using a linked list
o I don't like it, but I'm committing it so I can go back and laugh at
   myself later
 o I have a (hopefully) better idea that i'll try to commit yet today.
2001-08-21 19:51:04 +00:00
AJ Lewis
1b790fde24 o Quick and dirty hack to get lvm_check_dev code into the dev-manager
o I'm working on caching the /proc/devices entries now, and should have
   that in by the end of today or early tomorrow.
 o There will be much cleanup involved with that...
2001-08-21 18:20:14 +00:00
Joe Thornber
aaccea731e o quick hack to get the proc entry registering 2001-08-21 15:31:50 +00:00
Joe Thornber
29e31d7610 o dm-fs compiles, I've forgotten to register the device in /proc though 2001-08-21 15:24:02 +00:00
AJ Lewis
aa51f4a98f o Added a basic makefile to build liblvm.a again
o Modified source files so that this works
2001-08-21 15:23:45 +00:00
AJ Lewis
e6ccd12f00 o Brought hash table code over from experimental 2001-08-21 15:22:59 +00:00
Joe Thornber
b134315df1 o wasn't including dm-fs.o in the build 2001-08-21 14:52:54 +00:00
Joe Thornber
7f34dffa13 o dm-target compiles 2001-08-21 14:51:41 +00:00
Joe Thornber
fa239e78c9 o dm-table compiles 2001-08-21 14:47:42 +00:00
AJ Lewis
707a6c4d6a o Added _basic_ config file support to the device manager 2001-08-21 14:44:18 +00:00
Joe Thornber
e5da303b43 o make dm.c compile 2001-08-21 14:28:00 +00:00
Joe Thornber
84ccd66331 o 2.4.9 support
o new uml-lvm patch
2001-08-21 13:45:16 +00:00
AJ Lewis
ad8cc2baea o Populating with stuff from experimental 2001-08-21 13:22:16 +00:00
Joe Thornber
7c4cf70309 o Populating with stuff from experimental 2001-08-21 12:56:08 +00:00
Joe Thornber
c3211e9b4f o dm_activate/dm_close 2001-08-20 16:12:22 +00:00
steve
268d94c983 dec use count on close. corrects a typo.
Really the use counts on these modules should be handled at a higher level,
otherwise there are races I think.
2001-08-20 15:59:22 +00:00
Joe Thornber
0bcacbba58 o implemeted dm_start_table/dm_add_entry/dm_complete_table as used by
the /proc interface.
2001-08-20 15:22:44 +00:00
Joe Thornber
8cdc26add9 o changed _dev_lock to a rw_semaphore 2001-08-20 14:06:25 +00:00
Joe Thornber
e0b2238886 o proc interface is getting there. 2001-08-20 13:45:43 +00:00
Joe Thornber
369a2e4029 o missed one 2001-08-20 08:05:51 +00:00
Joe Thornber
c4089e3b51 Just syncing with the office.
o device-mapper.c has split
2001-08-20 08:03:02 +00:00
Joe Thornber
9e2e9bc5b8 o added a description 2001-08-16 15:14:07 +00:00
Joe Thornber
a9e44426ed o checked in the new driver, and the uml dir 2001-08-16 08:26:13 +00:00
893 changed files with 42742 additions and 181654 deletions

27
.gitignore vendored
View File

@@ -1,27 +0,0 @@
*.5
*.8
*.a
*.d
*.o
*.pc
*.pot
*.so
*.so.*
*.swp
*~
.export.sym
.exported_symbols_generated
.gdb_history
Makefile
make.tmpl
configure.h
version.h
/autom4te.cache/
/config.log
/config.status
/cscope.out
/tmp/

View File

@@ -1,14 +1,14 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
Preamble
@@ -17,109 +17,97 @@ freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
GNU LESSER GENERAL PUBLIC LICENSE
GNU LIBRARY GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
@@ -268,7 +256,7 @@ distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
@@ -295,31 +283,23 @@ of these things:
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
b) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
c) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
d) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
@@ -368,7 +348,7 @@ Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
You are not responsible for enforcing compliance by third parties to
this License.
11. If, as a consequence of a court judgment or allegation of patent
@@ -411,7 +391,7 @@ excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
@@ -457,7 +437,7 @@ DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
Appendix: How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
@@ -474,18 +454,19 @@ convey the exclusion of warranty; and each file should have at least the
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
version 2 of the License, or (at your option) any later version.
This 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
Lesser General Public License for more details.
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
Also add information on how to contact you by electronic and paper mail.
@@ -500,5 +481,3 @@ necessary. Here is a sample; alter the names:
Ty Coon, President of Vice
That's all there is to it!

34
INSTALL
View File

@@ -1,30 +1,44 @@
Installation
============
LVM2 installation
=================
1) Generate custom makefiles.
1) Install device-mapper
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
and libdevmapper.so should be present.
The device-mapper is available from:
ftp://ftp.sistina.com/pub/LVM2/device-mapper/
2) Generate custom makefiles.
Run the 'configure' script from the top directory.
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
Use ./configure --help to see other options.
2) Build and install.
3) Build and install LVM2.
Run 'make' from the top directory to build everything you configured.
Run 'make install' to build and install everything you configured.
Run 'make install' from the top directory.
If you only want the device-mapper libraries and tools use
'make device-mapper' or 'make install_device-mapper'.
3) If using LVM2, create a configuration file.
4) Create a configuration file
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 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.

View File

@@ -1,8 +1,8 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
# 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
@@ -14,58 +14,33 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
VPATH = @srcdir@
SUBDIRS = conf daemons include lib libdaemon libdm man scripts tools
ifeq ("@UDEV_RULES@", "yes")
SUBDIRS += udev
endif
SUBDIRS = doc include man
ifeq ("@INTL@", "yes")
SUBDIRS += po
endif
ifeq ("@APPLIB@", "yes")
SUBDIRS += liblvm
endif
SUBDIRS += lib tools daemons
ifeq ("@PYTHON_BINDINGS@", "yes")
SUBDIRS += python
endif
ifeq ($(MAKECMDGOALS),clean)
SUBDIRS += test
endif
# FIXME Should use intermediate Makefiles here!
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS = conf include man test scripts \
libdaemon lib tools daemons libdm \
udev po liblvm python \
unit-tests/datastruct unit-tests/mm unit-tests/regex
tools.distclean: test.distclean
SUBDIRS += daemons/clvmd \
lib/format1 \
lib/format_pool \
lib/locking \
lib/mirror \
lib/snapshot \
po \
test/mm test/device test/format1 test/regex test/filters
endif
DISTCLEAN_DIRS += lcov_reports*
DISTCLEAN_TARGETS += config.cache config.log config.status make.tmpl
include make.tmpl
libdm: include
libdaemon: include
lib: libdm libdaemon
liblvm: lib
daemons: lib libdaemon tools
tools: lib libdaemon device-mapper
daemons: lib
lib: include
tools: lib
po: tools daemons
scripts: liblvm libdm
lib.device-mapper: include.device-mapper
libdm.device-mapper: include.device-mapper
liblvm.device-mapper: include.device-mapper
daemons.device-mapper: libdm.device-mapper
tools.device-mapper: libdm.device-mapper
scripts.device-mapper: include.device-mapper
device-mapper: tools.device-mapper daemons.device-mapper man.device-mapper
ifeq ("@INTL@", "yes")
lib.pofile: include.pofile
@@ -75,112 +50,3 @@ po.pofile: tools.pofile daemons.pofile
pofile: po.pofile
endif
ifeq ("@PYTHON_BINDINGS@", "yes")
python: liblvm
endif
ifneq ("$(CFLOW_CMD)", "")
tools.cflow: libdm.cflow lib.cflow
daemons.cflow: tools.cflow
cflow: include.cflow
endif
ifneq ("@CSCOPE_CMD@", "")
cscope.out:
@CSCOPE_CMD@ -b -R -s$(top_srcdir)
all: cscope.out
endif
DISTCLEAN_TARGETS += cscope.out
check check_system check_cluster check_local check_lvmetad unit: all
$(MAKE) -C test $(@)
install_system_dirs:
$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_ARCHIVE_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_BACKUP_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_CACHE_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_LOCK_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_RUN_DIR)
$(INSTALL_ROOT_DATA) /dev/null $(DESTDIR)$(DEFAULT_CACHE_DIR)/.cache
install_initscripts:
$(MAKE) -C scripts install_initscripts
install_systemd_generators:
$(MAKE) -C scripts install_systemd_generators
$(MAKE) -C man install_systemd_generators
install_systemd_units:
$(MAKE) -C scripts install_systemd_units
ifeq ("@PYTHON_BINDINGS@", "yes")
install_python_bindings:
$(MAKE) -C liblvm/python install_python_bindings
endif
install_tmpfiles_configuration:
$(MAKE) -C scripts install_tmpfiles_configuration
LCOV_TRACES = libdm.info lib.info tools.info \
daemons/dmeventd.info daemons/clvmd.info
CLEAN_TARGETS += $(LCOV_TRACES)
ifneq ("$(LCOV)", "")
.PHONY: lcov-reset lcov lcov-dated $(LCOV_TRACES)
ifeq ($(MAKECMDGOALS),lcov-dated)
LCOV_REPORTS_DIR := lcov_reports-$(shell date +%Y%m%d%k%M%S)
lcov-dated: lcov
else
LCOV_REPORTS_DIR := lcov_reports
endif
lcov-reset:
$(LCOV) --zerocounters $(addprefix -d , $(basename $(LCOV_TRACES)))
# maybe use subdirs processing to create tracefiles...
$(LCOV_TRACES):
$(LCOV) -b $(basename $@) -d $(basename $@) \
--ignore-errors source -c -o - | $(SED) \
-e "s/\(dmeventd_lvm.[ch]\)/plugins\/lvm2\/\1/" \
-e "s/dmeventd_\(mirror\|snapshot\|thin\|raid\)\.c/plugins\/\1\/dmeventd_\1\.c/" \
>$@
ifneq ("$(GENHTML)", "")
lcov: $(LCOV_TRACES)
$(RM) -r $(LCOV_REPORTS_DIR)
$(MKDIR_P) $(LCOV_REPORTS_DIR)
for i in $(LCOV_TRACES); do \
test -s $$i && lc="$$lc $$i"; \
done; \
test -z "$$lc" || $(GENHTML) -p @abs_top_builddir@ \
-o $(LCOV_REPORTS_DIR) $$lc
endif
endif
ifeq ("$(TESTING)", "yes")
# testing and report generation
RUBY=ruby1.9 -Ireport-generators/lib -Ireport-generators/test
.PHONY: unit-test ruby-test test-programs
# FIXME: put dependencies on libdm and liblvm
# FIXME: Should be handled by Makefiles in subdirs, not here at top level.
test-programs:
cd unit-tests/regex && $(MAKE)
cd unit-tests/datastruct && $(MAKE)
cd unit-tests/mm && $(MAKE)
unit-test: test-programs
$(RUBY) report-generators/unit_test.rb $(shell find . -name TESTS)
$(RUBY) report-generators/title_page.rb
memcheck: test-programs
$(RUBY) report-generators/memcheck.rb $(shell find . -name TESTS)
$(RUBY) report-generators/title_page.rb
ruby-test:
$(RUBY) report-generators/test/ts.rb
endif

32
README
View File

@@ -1,33 +1,23 @@
This tree contains the LVM2 and device-mapper tools and libraries.
This directory contains LVM2, the new version of the userland LVM
tools designed for the new device-mapper for the Linux kernel.
For more information about LVM2 read the changelog in the WHATS_NEW file.
The device-mapper needs to be installed before compiling these LVM2 tools.
For more information about LVM2 read the WHATS_NEW file.
Installation instructions are in INSTALL.
There is no warranty - see COPYING and COPYING.LIB.
Tarballs are available from:
ftp://sources.redhat.com/pub/lvm2/
ftp://sources.redhat.com/pub/dm/
The source code is stored in git:
http://git.fedorahosted.org/git/lvm2.git
git clone git://git.fedorahosted.org/git/lvm2.git
To access the CVS tree use:
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 general discussion related to LVM2:
Mailing list for discussion/bug reports etc.
linux-lvm@redhat.com
Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
Mailing lists for LVM2 development, patches and commits:
lvm-devel@redhat.com
Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
lvm2-commits@lists.fedorahosted.org (Read-only archive of commits)
Subscribe from https://fedorahosted.org/mailman/listinfo/lvm2-commits
Mailing list for device-mapper development, including kernel patches
and multipath-tools:
dm-devel@redhat.com
Subscribe from https://www.redhat.com/mailman/listinfo/dm-devel
The source code repository used until 7th June 2012 is accessible here:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/?cvsroot=lvm2.

View File

@@ -1 +1 @@
2.02.112(2)-git (2014-09-01)
2.00.34-cvs (2005-01-07)

View File

@@ -1 +0,0 @@
1.02.91-git (2014-09-01)

3425
WHATS_NEW

File diff suppressed because it is too large Load Diff

View File

@@ -1,887 +1,5 @@
Version 1.02.91 -
====================================
Fix dm_is_dm_major to not issue error about missing /proc lines for dm module.
Version 1.02.90 - 1st September 2014
====================================
Restore proper buffer size for parsing mountinfo line (1.02.89)
Version 1.02.89 - 26th August 2014
==================================
Improve libdevmapper-event select() error handling.
Add extra check for matching transation_id after message submitting.
Add dm_report_field_string_list_unsorted for str. list report without sorting.
Support --deferred with dmsetup remove to defer removal of open devices.
Update dm-ioctl.h to include DM_DEFERRED_REMOVE flag.
Add support for selection to match string list subset, recognize { } operator.
Fix string list selection with '[value]' to not match list that's superset.
Fix string list selection to match whole words only, not prefixes.
Version 1.02.88 - 5th August 2014
=================================
Add dm_tree_set_optional_uuid_suffixes to handle upgrades.
Version 1.02.87 - 23rd July 2014
================================
Fix dm_report_field_string_list to handle delimiter with multiple chars.
Add dm_report_field_reserved_value for per-field reserved value definition.
Version 1.02.86 - 23rd June 2014
================================
Make "help" and "?" reporting fields implicit.
Recognize implicit "selected" field if using dm_report_init_with_selection.
Add support for implicit reporting fields which are predefined in libdm.
Add DM_REPORT_FIELD_TYPE_PERCENT: separate number and percent fields.
Add dm_percent_range_t,dm_percent_to_float,dm_make_percent to libdm for reuse.
Add dm_report_reserved_value to libdevmapper for reserved value definition.
Also display field types when listing all fields in selection help.
Recognize "help" keyword in selection string to show brief help for selection.
Always order items reported as string list field lexicographically.
Add dm_report_field_string_list to libdevmapper for direct string list report.
Add DM_REPORT_FIELD_TYPE_STRING_LIST: separate string and string list fields.
Add dm_str_list to libdevmapper for string list type definition and its reuse.
Add dmsetup -S/--select to define selection criteria for dmsetup reports.
Add dm_report_init_with_selection to intialize report with selection criteria.
Add DM_REPORT_FIELD_TYPE_SIZE: separate number and size reporting fields.
Use RemoveOnStop for dm-event.socket systemd unit.
Document env var 'DM_DEFAULT_NAME_MANGLING_MODE' in dmsetup man page.
Warn user about incorrect use of cookie with 'dmsetup remove --force'.
Also recognize 'help'/'?' as reserved sort key name to show help.
Add dm_units_to_factor for size unit parsing.
Increase bitset size for minors for thin dmeventd plugin.
Version 1.02.85 - 10th April 2014
=================================
Check for sprintf error when building internal device path.
Check for sprintf error when creating path for dm control node.
When buffer for dm_get_library_version() is too small, return error code.
Always reinitialize _name_mangling_mode in dm_lib_init().
Add tracking flag about implicitly added devices into dm_tree.
Stop timeout thread immediately when the last worker thread is finished.
Fix dmeventd logging with parallel wait event processing.
Reuse _node_send_messages() for validation of transaction_id in preload.
Transaction_id could be lower by one only when messages are prepared.
Do not call callback when preload fails.
Wrap is_selinux_enabled() to be called just once.
Use correctly signed 64b constant when working with raid volumes.
Exit dmeventd with pidfile cleanup instead of raising SIGKILL on DIE request.
Add new DM_EVENT_GET_PARAMETERS request to dmeventd protocol.
Do not use systemd's reload for dmeventd restart, use dmeventd -R instead.
Drop cryptsetup rules from 10-dm.rules - cryptsetup >= 1.1.3 sets them.
Version 1.02.84 - 20th January 2014
===================================
Revert activation of activated nodes if a node preload callback fails.
Avoid busy looping on CPU when dmeventd reads event DM_WAIT_RETRY.
Ensure global mutex is held when working with dmeventd thread.
Drop taking timeout mutex for un/registering dmeventd monitor.
Allow section names in config file data to be quoted strings.
Close fifos before exiting in dmeventd restart() error path.
Move printf format string directly into dm_asprintf args list.
Catch invalid use of string sort values when reporting numerical fields.
Version 1.02.83 - 13th November 2013
====================================
Consistently report on stderr when device is not found for dmsetup info.
Skip race errors when non-udev dmsetup build runs on udev-enabled system.
Skip error message when holders are not present in sysfs.
Use __linux__ instead of linux define to make libdevmapper.h C compliant.
Use mutex to avoid possible race while creating/destroying memory pools.
Require libpthread to build now.
Version 1.02.82 - 4th October 2013
==================================
Define symbolic names for subsystem udev flags in libdevmapper for easier use.
Make subsystem udev rules responsible for importing DM_SUBSYSTEM_UDEV_FLAG*.
Version 1.02.81 - 23rd September 2013
=====================================
Tidy dmeventd fifo initialisation.
Version 1.02.80 - 20th September 2013
=====================================
Detect invalid sector supplied to 'dmsetup message'.
Free any previously-set string if a dm_task_set_* function is called again.
Do not allow passing empty new name for dmsetup rename.
Display any output returned by 'dmsetup message'.
Add dm_task_get_message_response to libdevmapper.
Version 1.02.79 - 13th August 2013
==================================
Create dmeventd timeout threads as "detached" so exit status is freed.
Add DM_ABORT_ON_INTERNAL_ERRORS env var support to abort on internal errors.
Version 1.02.78 - 24th July 2013
================================
Process thin messages once to active thin pool target for dm_tree.
Optimize out setting the same value or read_ahead.
Add DM_ARRAY_SIZE public macro.
Move syslog code out of signal handle in dmeventd.
Add DM_TO_STRING public macro.
Always return success on dmeventd -V command call.
Fix parsing of 64bit snapshot status in dmeventd snapshot plugin.
Add dm_get_status_snapshot() for parsing snapshot status.
Detecte mounted fs also via reading /proc/self/mountinfo.
Add dm_mountinfo_read() for parsing /proc/self/mountinfo.
Report error for nonexisting devices in dmeventd communication.
Prevent double free error after dmeventd call of _fill_device_data().
Update dmevent structure message_data to simplify/fix error path handling.
Validate passed params to dm_get_status_raid/thin/thin_pool().
Fix 'dmsetup splitname -o' to not fail if used without '-c' switch (1.02.68).
Add dm_config_write_{node_out/one_node_out} for enhanced config output.
Add dm_config_value_is_bool to check for boolean value in supported formats.
Fix config node lookup inside empty sections to not return the section itself.
Append discards and read-only fields to exported struct dm_status_thin_pool.
Fix segfault for truncated string token in config file after the first '"'.
Close open dmeventd FIFO file descriptors on exec (FD_CLOEXEC).
Fix resource leak in error path of dmeventd's umount of thin volume.
Automatically deactivate failed preloaded dm tree node.
Add DM_DISABLE_UDEV environment variable to manage dev nodes by libdm only.
Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled.
Version 1.02.77 - 15th October 2012
===================================
Support unmount of thin volumes from pool above thin pool threshold.
Update man page to reflect that dm UUIDs are being mangled as well.
Apply 'dmsetup mangle' for dm UUIDs besides dm names.
Add 'mangled_uuid' and 'unmangled_uuid' fields to dmsetup info -c -o.
Mangle device UUID on dm_task_set_uuid/newuuid call if necessary.
Add dm_task_get_uuid_mangled/unmangled to libdevmapper.
Always reset delay_resume_if_new flag when stacking thin pool over anything.
Don't create value for dm_config_node and require dm_config_create_value call.
Check for existing new_name for dmsetup rename.
Fix memory leak in dmsetup _get_split_name() error path.
Version 1.02.76 - 7th August 2012
=================================
Add dm_vasprintf to libdevmapper.
Allow --noflush with dmsetup status and wait (for thin target).
Add dm_config_write_one_node to libdevmapper.
Support thin pool message release/reserve_metadata_snap in libdevmapper.
Support thin pool discards and external origin features in libdevmapper.
Add configure --enable-udev-rule-exec-detection to detect exec path in rules.
Use sbindir in udev rules by default and remove executable path detection.
Remove hard-coded paths for dmeventd fifos and use default-dm-run-dir.
Add configure --with-lvmetad-pidfile to remove hard-coded value.
Add configure --with-default-pid-dir for common directory with pid files.
Add configure --with-default-dm-run-dir to set run directory for dm tools.
Detect kernel_send() errors in cmirrord.
Add __attribute__ instrumentation to libdevmapper.h.
Print clean_bits instead of sync_bits in pull_state in cmirrord.
Add tests for errors from closedir(), close() in cmirrord.
Add documentation references in systemd units.
Remove veritysetup. Now maintained with cryptsetup.
Version 1.02.75 - 8th June 2012
===============================
Upstream source repo now fedorahosted.org git not sources.redhat.com CVS.
Remove unsupported udev_get_dev_path libudev call used for checking udev dir.
Set delay_resume_if_new on deptree snapshot origin.
Log value chosen in _find_config_bool like other variable types do.
Wait for dmeventd to exit after sending it DM_EVENT_CMD_DIE when restarting.
Append 'Used' to {Blk}DevNames/DevNos dmsetup report headers for clarity.
Add configure --with-veritysetup for independent veritysetup tool.
Properly support supplied dmevent path in dm_event_register_handler().
Remove dmeventd fifos on exit if they are not managed by systemd.
Use SD_ACTIVATION environment variable in systemd units to detect systemd.
Only start a new dmeventd instance on restart if one was already running.
Extend the time waited for input from dmeventd fifo to 5 secs. (1.02.73)
Version 1.02.74 - 6th March 2012
================================
Check for multiply-mangled names in auto mangling mode.
Fix dm_task_get_name_unmangled to not unmangle already unmangled name.
Check whether device names are properly mangled on ioctl return.
Deactivation of failed thin check on thin pool returns success.
Version 1.02.73 - 3rd March 2012
================================
Test _thread_registry list with holding mutex in dmeventd.
Add dm_tree_node_set_callback() for preload and deactivation hooks.
Drop unsupported TRIM message for thin pool.
Improve logging for fifo startup in dmeventd.
Better detection of missing dmeventd fifo connection (1.02.71).
Add a few pointer validations in dmsetup.
Support dm_task_get_driver_version() query without version string.
Log failure of pthread_join when cleaning unused threads in dmeventd.
Fix empty string warning logic in _find_config_str. (1.02.68)
Fix dm_task_set_name to properly resolve path to dm name (1.02.71).
Add dm_strncpy() function as a faster strncpy() replacement.
Version 1.02.72 - 23rd February 2012
====================================
Avoid memory reallocation for dm_asprintf.
Version 1.02.71 - 20th February 2012
====================================
Switch to using built-in blkid in 13-dm-disk.rules.
Add "watch" rule to 13-dm-disk.rules.
Detect failing fifo and skip 20s retry communication period.
Add DM_DEFAULT_NAME_MANGLING_MODE environment variable as an override.
Add dm_lib_init to automatically initialise device-mapper library on load.
Replace any '\' char with '\\' in dm table specification on input.
Add mangle command to dmsetup to provide renaming to correct mangled form.
Add 'mangled_name' and 'unmangled_name' fields to dmsetup info -c -o.
Add --manglename option to dmsetup to select the name mangling mode.
Add dm_task_get_name_mangled/unmangled to libdevmapper.
Mangle device name on dm_task_set_name/newname call if necessary.
Add dm_set/get_name_mangling_mode to set/get name mangling in libdevmapper.
Add configure --with-default-name-mangling for udev-friendly dev name charset.
Test for parsed words in _umount() dmeventd snapshot plugin.
Fix memory leak in fail path of parse_loop_device_name() in dmsetup.
Check for missing reply_uuid in dm_event_get_registered_device().
Check for allocation failure in dmeventd restart().
Add few missing allocation failures tests in dmsetup.
Fix potential risk of writing in front of buffer in _sysfs_get_dm_name().
Version 1.02.70 - 12th February 2012
====================================
Fix dm_event_get_version() check.
Add pointer test for dependency check in _add_dev().
Validate name and uuid params of dm_tree_add_new_dev_with_udev_flags().
Do not crash for dm_report_init() sort_key == NULL and behave like "".
Return error for failing allocation in dm_asprintf().
Add missing test for failing allocation in dm_realloc() code.
Add test for memory allocation failures in regex matcher code.
Simplify dm_task_set_geometry() and use dm_asprintf().
Set all parameters to 0 for dm_get_next_target() for NULL return.
Fix fd resource leak in error path for _udev_notify_sem_create().
Leave space for '\0' for readline() call in _sysfs_get_kernel_name().
Version 1.02.69 - 1st February 2012
===================================
Clean up dmeventd systemd unit ordering and requirements.
Version 1.02.68 - 26th January 2012
===================================
Reset all members of info struct in dm_tree_add_new_dev_with_udev_flags.
Add dmsetup wipe_table to replace table with one that uses error target.
Add 'blkdevname' and 'blkdevs_used' fields to dmsetup info -c -o.
Add 'blkdevname' option to dmsetup ls --tree to see block device names.
Add -o devno/blkdevname/devname to dmsetup deps and ls.
Add dm_device_get_name to get map name or block device name for given devno.
Remove empty devices when clearing left-over inactive tables in deptree.
Add dm_uuid_prefix/dm_set_uuid_prefix to override hard-coded LVM- prefix.
Improve dmsetup man page description of readahead parameter.
Use sysfs to set/get readahead if possible.
Fix lvm2-monitor init script to use normalized output when using vgs.
Add test for max length (DM_MAX_TYPE_NAME) of target type name.
Include a copy of kernel DM documentation in doc/kernel.
Improve man page style for dmsetup and mention more targets.
Fix _get_proc_number to be tolerant of malformed /proc/misc entries.
Fix missing thread list manipulation protection in dmeventd.
Add ExecReload to dm-event.service for systemd to reload dmeventd properly.
Add dm_config_tree_find_str_allow_empty and dm_config_find_str_allow_empty.
Fix compile-time pool memory locking with DEBUG_MEM.
Fix valgrind error reports in free of pool chunks with DEBUG_MEM.
Align size of structure chunk for fast pool allocator to 8 bytes.
Simplify some pointer operations in dm_free_aux() debug code.
Remove unused dbg_malloc.h file from source tree.
Cleanup backtraces for _create_and_load_v4().
Fix alignment warning in bitcount calculation for raid segment.
Allocate dm_tree structure from dm_tree pool.
Update debug logging for _resume_node.
Add functions to support thin provisioning target.
Improve libdm-config error path reporting.
Update dmsetup resume man with --addnodeonresume/create options.
Add dependency for dm man pages to man subdirectory make all target.
Add dm_tree_retry_remove to use retry logic for device removal in a dm_tree.
Add dm_device_has_mounted_fs fn to check mounted filesystem on a device.
Add dm_device_has_holders fn to to check use of the device by another device.
Add dm_sysfs_dir to libdevmapper to retrieve sysfs location set.
Add dm_set_sysfs_dir to libdevmapper to set sysfs location.
Add --retry option for dmsetup remove to retry removal if not successful.
Add dm_task_retry_remove fn to use retry logic for device removal.
Remove unused passed parameters for _mirror_emit_segment_line().
Add dm_config and string character escaping functions to libdevmapper.
Mark unreleased memory pools as internal error.
Version 1.02.67 - 19th August 2011
==================================
Add dm_tree_node_add_null_area for temporarily-missing raid devs tracked.
Version 1.02.66 - 12th August 2011
==================================
Release geometry buffer in dm_task_destroy.
Update udev rules to skip DM flags decoding for removed devices.
Add compile-time pool memory locking options (to debug shared VG structs).
Remove device name prefix from dmsetup line output if -j & -m or -u supplied.
Remove support for the original version 1 dm ioctls.
Add missing check for allocation failure _create_dir_recursive().
Add support for systemd file descriptor handover in dmeventd.
Fix memory leak in dmsetup _message() memory allocation error path.
Use new oom killer adjustment interface (oom_score_adj) when available.
Add systemd unit files for dmeventd.
Fix read-only identical table reload supression.
Version 1.02.65 - 8th July 2011
===============================
Remove dev name prefix from dmsetup line output if exactly one dev requested.
Report internal error if suspending a device using an already-suspended dev.
Report error if a table load requiring target parameters has none supplied.
Add dmsetup --checks and dm_task_enable_checks framework to validate ioctls.
Add age_in_minutes parameter to dmsetup udevcomplete_all.
Return immediately from dm_lib_exit() if called more than once.
Disable udev fallback by default and add --verifyudev option to dmsetup.
Report internal error if any table is loaded while any dev is known suspended.
Add dm_get_suspended_counter() for number of devs in suspended state by lib.
Fix "all" report field prefix matching to include label fields with pv_all.
Delay resuming new preloaded mirror devices with core logs in deptree code.
Accept new kernel version 3 uname formats in initialisation.
Version 1.02.64 - 29th April 2011
==================================
Require libudev >= 143 when compiling with udev support.
Use word alignment for dm_pool_strdup() and dm_pool_strndup().
Use dm_snprintf() to fix signedness warning in dm_set_dev_dir().
Use unsigned loop counter to fix signedness warning in _other_node_ops().
Fix const cast in dmsetup calls of dm_report_field_string().
Streamline /dev/mapper/control node code for common cases.
Use hard-coded dm control node device number for 2.6.36 kernels and above.
Improve stack debug reporting in dm_task_create().
Fallback to control node creation only if node doesn't exist yet.
Change dm_hash binary functions to take void *key instead of char *.
Fix uninitialised memory use with empty params in _reload_with_suppression_v4.
Lower severity of selabel_lookup and matchpathcon failure to log_debug.
Add test for failed allocation from dm_task_set_uuid() in dmeventd.
Add dm_event_get_version to dmeventd for use with -R.
Avoid dmeventd core dumps when handling request with unknown command ID.
Have dmeventd -R start up even when no existing copy is running.
Accept multiple mapped device names on many dmsetup command lines.
Fix dm_udev_wait calls in dmsetup to occur before readahead display not after.
Include an implicit dm_task_update_nodes() within dm_udev_wait().
Fix _create_and_load_v4 not to lose the --addnodeoncreate setting (1.02.62).
Add inactive table query support for kernel driver >= 4.11.6 (RHEL 5.7).
Log debug open_count in _node_has_closed_parents().
Add a const to dm_report_field_string() data parameter.
Version 1.02.63 - 9th February 2011
===================================
Reinstate DEBUG_MEM as it's part of the API. (1.02.62)
Version 1.02.62 - 4th February 2011
===================================
Add configure --with-device-nodes-on=create for previous behaviour.
Move creation of device nodes from 'create' to 'resume'.
Add --addnodeonresume and --addnodeoncreate options to dmsetup.
Add dm_task_set_add_node to libdevmapper to control dev node creation time.
Add dm_task_secure_data to libdevmapper to wipe ioctl buffers in kernel.
Log debug message when expected uevent is not generated.
Only compile memory debugging code when DEBUG_MEM is set.
Set DM_UDEV_DISABLE_OTHER_RULES_FLAG for suspended DM devices in udev rules.
Begin a new pool object for each row in _output_as_rows() correctly.
Version 1.02.61 - 10th January 2011
===================================
Add DM_COOKIE_AUTO_CREATE to libdevmapper.h.
Export DM_CONTROL_NODE_UMASK and use it while creating /dev/mapper/control.
Version 1.02.60 - 20th December 2010
====================================
Check for unlink failure in remove_lockfile() in dmeventd.
Use dm_free for dm_malloc-ed areas in _clog_ctr/_clog_dtr in cmirrord.
Use char* arithmetic in _process_all() & _targets() in dmsetup.
Change dm_regex_create() API to accept const char * const *patterns.
Add new dm_prepare_selinux_context fn to libdevmapper and use it throughout.
Detect existence of new SELinux selabel interface during configure.
Version 1.02.59 - 6th December 2010
===================================
Add backtraces to _process_mapper_dir and _create_and_load_v4 error paths.
Remove superfluous checks for NULL before calling dm_free.
Version 1.02.58 - 22nd November 2010
====================================
Fix _output_field crash from field_id free with DEBUG_MEM. (1.02.57)
Version 1.02.57 - 8th November 2010
===================================
Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common.
Add dmeventd -R to restart dmeventd without losing monitoring state. (1.02.56)
Fix memory leak of field_id in _output_field function.
Allocate buffer for reporting functions dynamically to support long outputs.
Version 1.02.56 - 25th October 2010
===================================
Return const pointer from dm_basename() in libdevmapper.
Implement dmeventd -R to restart without state loss.
Add dm_zalloc and use it and dm_pool_zalloc throughout.
Add --setuuid to dmsetup rename.
Add dm_task_set_newuuid to set uuid of mapped device post-creation.
Version 1.02.55 - 24th September 2010
=====================================
Fix the way regions are marked complete to avoid slow --nosync cmirror I/O.
Add DM_REPORT_FIELD_TYPE_ID_LEN to libdevmapper.h.
Version 1.02.54 - 18th August 2010
==================================
Fix dm-mod autoloading logic to not assume control node is set correctly.
Add dmeventd/executable to lvm.conf to test alternative dmeventd.
Export dm_event_handler_set_dmeventd_path to override built-in dmeventd path.
Generate libdevmapper-event exported symbols.
Remove superfluous NULL pointer tests before dm_free from dmeventd.
Assume dm-mod autoloading support is in kernel 2.6.36 and higher, not 2.6.35.
Fix udev rules to support udev database content generated by older rules.
Reinstate detection of inappropriate uevent with DISK_RO set and suppress it.
Fix regex ttree off-by-one error.
Add --enable-valgrind-pool to configure.
Fix segfault in regex matcher with characters of ordinal value > 127.
Fix 'void*' arithmetic warnings in dbg_malloc.c and libdm-iface.c.
Wait for node creation before displaying debug info in dmsetup.
Fix return status 0 for "dmsetup info -c -o help".
Add check for kernel semaphore support and disable udev_sync if not available.
Version 1.02.53 - 28th July 2010
================================
Revert failed table load preparation after "create, load and resume".
Switch dmeventd to use dm_create_lockfile and drop duplicate code.
Add dm_create_lockfile to libdm to handle pidfiles for all daemons.
Replace lookup with next in struct dfa_state & calculate states on demand.
Improve the regex matcher, reducing the number of charset nodes used.
Add dm_regex_fingerprint to facilitate regex testing.
Skip ffs(0) in _test_word in bitset functions.
Use "nowatch" udev rule for inappropriate devices.
Version 1.02.52 - 6th July 2010
===============================
Fix dmlosetup snprintf %llu compiler warning.
Add parentheses to some libdevmapper.h macro arguments.
Add printf format attributes to dm_{sn,as}printf and fix a caller.
Move dmeventd man page from install_lvm2 to install_device-mapper. (1.02.50)
Version 1.02.51 - 30th June 2010
================================
Generate libdevmapper exported symbols from header file.
Version 1.02.50 - 23rd June 2010
================================
Fix INTERNAL_ERROR typo in ioctl iface unknown task message.
Fix udev rules to handle spurious events properly.
Use C99 [] not [0] in dm_ulog_request struct to avoid abort when fortified.
Allow use of devmapper header file in C++ mode (extern "C" and __typeof__).
Add dmeventd man page.
Version 1.02.49 - 4th June 2010
===============================
Support autoloading of dm-mod module for kernels from 2.6.35.
Document 'clear' in dmsetup man page.
Fix semctl parameter (union) to avoid misaligned parameter on some arches.
Add dm_tree_node_set_presuspend_node() to presuspend child when deactivating.
Initial support for replicator target.
Version 1.02.48 - 17th May 2010
================================
Use -d to control level of messages sent to syslog by dmeventd.
Change -d to -f to run dmeventd in foreground.
Do not print encryption key in message debug output (cryptsetup luksResume).
Fix dmeventd static build library dependencies.
Fix udev flags on remove in create_and_load error path.
Version 1.02.47 - 30th April 2010
=================================
Add support for new IMPORT{db} udev rule.
Add DM_UDEV_PRIMARY_SOURCE_FLAG udev flag to recognize proper DM events.
Also include udev libs in libdevmapper.pc when udev_sync is enabled.
Cache bitset locations to speed up _calc_states.
Add a regex optimisation pass for shared prefixes and suffixes.
Add dm_bit_and and dm_bitset_equal to libdevmapper.
Simplify dm_bitset_create.
Speed up dm_bit_get_next with ffs().
Version 1.02.46 - 14th April 2010
=================================
Change dm_tree_deactivate_children to fail if device is open.
Wipe memory buffers for dm-ioctl parameters before releasing.
Strictly require libudev if udev_sync is used.
Add support for ioctl's DM_UEVENT_GENERATED_FLAG.
Version 1.02.45 - 9th March 2010
================================
Add --showkeys parameter description to dmsetup man page.
Add --help option as synonym for help command.
Version 1.02.44 - 15th February 2010
====================================
Add DM_UDEV_DISABLE_LIBRARY_FALLBACK udev flag to rely on udev only.
Export dm_udev_create_cookie function to create new cookies on demand.
Add --udevcookie, udevcreatecookie and udevreleasecookie to dmsetup.
Set udev state automatically instead of using DM_UDEV_DISABLE_CHECKING.
Version 1.02.43 - 21st January 2010
===================================
Remove bitset, hash and pool headers superceded by libdevmapper.h.
Fix off-by-one error causing bad cluster mirror table construction.
Version 1.02.42 - 14th January 2010
===================================
Add support for the "snapshot-merge" kernel target (2.6.33-rc1).
Introduce a third activation_priority level in dm_tree_activate_children.
Version 1.02.41 - 12th January 2010
===================================
If DM_UDEV_DISABLE_CHECKING is set in environment, disable udev warnings.
Add dm_tree_add_dev_with_udev_flags to provide wider support for udev flags.
Add --noudevrules option for dmsetup to disable /dev node management by udev.
Fix 'dmsetup info -c -o all' to show all fields.
Return errors if dm_tree_*_children functions fail.
Fix coredump and memory leak for 'dmsetup help -c'.
Disable udev rules for change events with DISK_RO set.
Version 1.02.40 - 19th November 2009
====================================
Fix install_device-mapper Makefile target to not build dmeventd plugins.
Support udev flags even when udev_sync is disabled or not compiled in.
Remove 'last_rule' from udev rules: honour DM_UDEV_DISABLE_OTHER_RULES_FLAG.
Add dmsetup --inactive support.
Add dm_task_query_inactive_table to libdevmapper for kernel driver >= 4.16.
Fix hash lookup segfault when keys compared are different lengths.
Version 1.02.39 - 26th October 2009
===================================
Remove strict default permissions for DM devices from 95-dm-notify.rules.
Add dmsetup udevflags command to decode udev flags in given cookie value.
Support udev flags in libdevmapper incl. dm_tree_add_new_dev_with_udev_flags.
Make libdm ABI consistent when built with/without selinux support.
Version 1.02.38 - 25th September 2009
=====================================
Export DM_DEV_DIR_UMASK, the default umask for /dev directories created.
Handle any path supplied to dm_task_set_name by looking up in /dev/mapper.
Add several examples to 12-dm-permissions.rules.
Add splitname and --yes to dmsetup man page.
Fix _mirror_emit_segment_line return code.
Fix dmeventd _temporary_log_fn parameters. (2.02.50)
Version 1.02.37 - 15th September 2009
=====================================
Add dmsetup manpage entries for udevcomplete_all and udevcookies.
Check udev is running when processing cookies and retain state internally.
Add y|--yes option to dmsetup for default 'yes' answer to prompts.
Fix tools Makefile to process dmsetup sources separately.
Restore umask when device node creation fails.
Check kernel vsn to use 'block_on_error' or 'handle_errors' in mirror table.
Add dm-log-userspace.h to tree for cmirrord builds.
Version 1.02.36 - 6th August 2009
=================================
Add udevcookies, udevcomplete, udevcomplete_all and --noudevwait to dmsetup.
Add libdevmapper functions to support synchronisation with udev.
Version 1.02.35 - 28th July 2009
================================
Add LOG_LINE_WITH_ERRNO macro.
Use log_error macro consistently throughout in place of log_err.
Version 1.02.34 - 15th July 2009
================================
Use _exit() not exit() after forking to avoid flushing libc buffers twice.
Rename plog macro to LOG_LINE & add LOG_MESG variant for dm_dump_memory_debug.
Change plog to use dm_log_with_errno unless deprecated dm_log_init was used.
Add dm_log_with_errno and dm_log_with_errno_init, deprecating the old fns.
Fix whitespace in linear target line to fix identical table line detection.
Add device number to more log messages during activation.
Version 1.02.33 - 30th June 2009
================================
Don't fallback to default major number: use dm_task_set_major_minor. (1.02.31)
Do not fork daemon when dmeventd cannot be found.
Add crypt target handling to libdevmapper tree nodes.
Add splitname command to dmsetup.
Add subsystem, vg_name, lv_name, lv_layer fields to dmsetup reports.
Make mempool optional in dm_split_lvm_name().
Version 1.02.32 - 21st May 2009
===============================
Only generate libdevmapper.a when configured to link statically.
Export dm_tree_node_size_changed() from libdevmapper.
Propagate the table size_changed property up the dm device tree.
Detect failure to free memory pools when releasing the library.
Fix segfault when getopt processes dmsetup -U, -G and -M options.
Version 1.02.31 - 3rd March 2009
================================
If kernel supports only one dm major number, use in place of any supplied.
Version 1.02.30 - 26th January 2009
====================================
Add "all" field to reports expanding to all fields of report type.
Enforce device name length and character limitations in libdm.
Replace _dm_snprintf with EMIT_PARAMS macro for creating target lines.
Version 1.02.29 - 10th November 2008
====================================
Merge device-mapper into the LVM2 tree.
Split out dm-logging.h from log.h.
Use lvm-types.h.
Add usrsbindir to configure.
Version 1.02.28 - 18th September 2008
=====================================
Only resume devices in dm_tree_preload_children if size changes.
Extend deptree buffers so the largest possible device numbers fit.
Generate versioned libdevmapper-event.so.
Underline longer report help text headings.
Version 1.02.27 - 25th June 2008
================================
Align struct memblock in dbg_malloc for sparc.
Add --unquoted and --rows to dmsetup.
Avoid compiler warning about cast in dmsetup.c's OFFSET_OF macro.
Fix inverted no_flush debug message.
Remove --enable-jobs from configure. (Set at runtime instead.)
Bring configure.in and list.h into line with the lvm2 versions.
Version 1.02.26 - 6th June 2008
===============================
Initialise params buffer to empty string in _emit_segment.
Skip add_dev_node when ioctls disabled.
Make dm_hash_iter safe against deletion.
Accept a NULL pointer to dm_free silently.
Add tables_loaded, readonly and suspended columns to reports.
Add --nameprefixes to dmsetup.
Add field name prefix option to reporting functions.
Calculate string size within dm_pool_grow_object.
Version 1.02.25 - 10th April 2008
=================================
Remove redundant if-before-free tests.
Use log_warn for reporting field help text instead of log_print.
Change cluster mirror log type name (s/clustered_/clustered-/)
Version 1.02.24 - 20th December 2007
====================================
Fix deptree to pass new name to _resume_node after a rename.
Suppress other node operations if node is deleted.
Add node operation stack debug messages.
Report error when empty device name passed to readahead functions.
Fix minimum readahead debug message.
Version 1.02.23 - 5th December 2007
===================================
Update dm-ioctl.h after removal of compat code.
Add readahead support to libdevmapper and dmsetup.
Fix double free in a libdevmapper-event error path.
Fix configure --with-dmeventd-path substitution.
Allow a DM_DEV_DIR environment variable to override /dev in dmsetup.
Create a libdevmapper.so.$LIB_VERSION symlink within the build tree.
Avoid static link failure with some SELinux libraries that require libpthread.
Remove obsolete dmfs code from tree and update INSTALL.
Version 1.02.22 - 21st August 2007
==================================
Fix inconsistent licence notices: executables are GPLv2; libraries LGPLv2.1.
Update to use autoconf 2.61, while still supporting 2.57.
Avoid repeated dm_task free on some dm_event_get_registered_device errors.
Introduce log_sys_* macros from LVM2.
Export dm_fclose and dm_create_dir; remove libdm-file.h.
Don't log EROFS mkdir failures in _create_dir_recursive (for LVM2).
Add fclose wrapper dm_fclose that catches write failures (using ferror).
Version 1.02.21 - 13th July 2007
================================
Introduce _LOG_STDERR to send log_warn() messages to stderr not stdout.
Fix dmsetup -o devno string termination. (1.02.20)
Version 1.02.20 - 15th June 2007
================================
Fix default dmsetup report buffering and add --unbuffered.
Add tree-based and dependency fields to dmsetup reports.
Version 1.02.19 - 27th April 2007
=================================
Standardise protective include file #defines.
Add regex functions to library.
Avoid trailing separator in reports when there are hidden sort fields.
Fix segfault in 'dmsetup status' without --showkeys against crypt target.
Deal with some more compiler warnings.
Introduce _add_field() and _is_same_field() to libdm-report.c.
Fix some libdevmapper-event and dmeventd memory leaks.
Remove unnecessary memset() return value checks.
Fix a few leaks in reporting error paths. [1.02.15+]
Version 1.02.18 - 13th February 2007
====================================
Improve dmeventd messaging protocol: drain pipe and tag messages.
Version 1.02.17 - 29th January 2007
===================================
Add recent reporting options to dmsetup man page.
Revise some report fields names.
Add dmsetup 'help' command and update usage text.
Use fixed-size fields in report interface and reorder.
Version 1.02.16 - 25th January 2007
===================================
Add some missing close() and fclose() return value checks.
Migrate dmsetup column-based output over to new libdevmapper report framework.
Add descriptions to reporting field definitions.
Add a dso-private variable to dmeventd dso interface.
Add dm_event_handler_[gs]et_timeout functions.
Streamline dm_report_field_* interface.
Add cmdline debug & version options to dmeventd.
Add DM_LIB_VERSION definition to configure.h.
Suppress 'Unrecognised field' error if report field is 'help'.
Add --separator and --sort to dmsetup (unused).
Make alignment flag optional when specifying report fields.
Version 1.02.15 - 17th January 2007
===================================
Add basic reporting functions to libdevmapper.
Fix a malloc error path in dmsetup message.
More libdevmapper-event interface changes and fixes.
Rename dm_saprintf() to dm_asprintf().
Report error if NULL pointer is supplied to dm_strdup_aux().
Reinstate dm_event_get_registered_device.
Version 1.02.14 - 11th January 2007
===================================
Add dm_saprintf().
Use CFLAGS when linking so mixed sparc builds can supply -m64.
Add dm_tree_use_no_flush_suspend().
Lots of dmevent changes including revised interface.
Export dm_basename().
Cope with a trailing space when comparing tables prior to possible reload.
Fix dmeventd to cope if monitored device disappears.
Version 1.02.13 - 28 Nov 2006
=============================
Update dmsetup man page (setgeometry & message).
Fix dmsetup free after getline with debug.
Suppress encryption key in 'dmsetup table' output unless --showkeys supplied.
Version 1.02.12 - 13 Oct 2006
=============================
Avoid deptree attempting to suspend a device that's already suspended.
Version 1.02.11 - 12 Oct 2006
==============================
Add suspend noflush support.
Add basic dmsetup loop support.
Switch dmsetup to use dm_malloc and dm_free.
Version 1.02.10 - 19 Sep 2006
=============================
Add dm_snprintf(), dm_split_words() and dm_split_lvm_name() to libdevmapper.
Reorder mm bounds_check code to reduce window for a dmeventd race.
Version 1.02.09 - 15 Aug 2006
=============================
Add --table argument to dmsetup for a one-line table.
Abort if errors are found during cmdline option processing.
Add lockfs indicator to debug output.
Version 1.02.08 - 17 July 2006
==============================
Append full patch to check in emails.
Avoid duplicate dmeventd subdir with 'make distclean'.
Update dmsetup man page.
Add --force to dmsetup remove* to load error target.
dmsetup remove_all also performs mknodes.
Don't suppress identical table reloads if permission changes.
Fix corelog segment line.
Suppress some compiler warnings.
Version 1.02.07 - 11 May 2006
=============================
Add DM_CORELOG flag to dm_tree_node_add_mirror_target().
Avoid a dmeventd compiler warning.
Version 1.02.06 - 10 May 2006
=============================
Move DEFS into configure.h.
Fix leaks in error paths found by coverity.
Remove dmsetup line buffer limitation.
Version 1.02.05 - 19 Apr 2006
=============================
Separate install_include target in makefiles.
Separate out DEFS from CFLAGS.
Support pkg-config.
Check for libsepol.
Version 1.02.04 - 14 Apr 2006
=============================
Bring dmsetup man page up-to-date.
Use name-based device refs if kernel doesn't support device number refs.
Fix memory leak (struct dm_ioctl) when struct dm_task is reused.
If _create_and_load_v4 fails part way through, revert the creation.
dmeventd thread/fifo fixes.
Add file & line to dm_strdup_aux().
Add setgeometry.
Version 1.02.03 - 7 Feb 2006
Version 1.01.00 -
============================
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
@@ -969,3 +87,4 @@ Version 1.00.08 - 27 Feb 2004
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.

View File

@@ -1,59 +0,0 @@
dnl AC_GCC_VERSION
dnl check for compiler version
dnl sets COMPILER_VERSION and GCC_VERSION
AC_DEFUN([AC_CC_VERSION],
[
AC_MSG_CHECKING([C compiler version])
COMPILER_VERSION=`$CC -v 2>&1 | grep version`
case "$COMPILER_VERSION" in
*gcc*)
dnl Ok, how to turn $3 into the real $3
GCC_VERSION=`echo $COMPILER_VERSION | \
sed -e 's/[[^ ]]*\ [[^ ]]*\ \([[^ ]]*\)\ .*/\1/'` ;;
*) GCC_VERSION=unknown ;;
esac
AC_MSG_RESULT($GCC_VERSION)
])
dnl AC_TRY_CCFLAG([CCFLAG], [VAR], [ACTION-IF-WORKS], [ACTION-IF-FAILS])
dnl check if $CC supports a given flag
AC_DEFUN([AC_TRY_CCFLAG],
[
AC_REQUIRE([AC_PROG_CC])
ac_save_CFLAGS=$CFLAGS
CFLAGS=$1
AC_CACHE_CHECK([whether $CC accepts $1 flag], [ac_cv_flag_$2],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
[AS_VAR_SET([ac_cv_flag_$2], [yes])],
[AS_VAR_SET([ac_cv_flag_$2], [no])])])
CFLAGS=$ac_save_CFLAGS
$2=AS_VAR_GET([ac_cv_flag_$2])
if test "$2" = yes; then
ifelse([$3], [], [:], [$3])
else
ifelse([$4], [], [:], [$4])
fi
])
dnl AC_TRY_LDFLAGS([LDFLAGS], [VAR], [ACTION-IF-WORKS], [ACTION-IF-FAILS])
dnl check if $CC supports given ld flags
AC_DEFUN([AC_TRY_LDFLAGS],
[
AC_REQUIRE([AC_PROG_CC])
ac_save_LDFLAGS=$LDFLAGS
LDFLAGS=$1
AC_CACHE_CHECK([whether $CC accepts $1 ld flags], [ac_cv_flag_$2],
[AC_LINK_IFELSE([AC_LANG_PROGRAM()],
[AS_VAR_SET([ac_cv_flag_$2], [yes])],
[AS_VAR_SET([ac_cv_flag_$2], [no])])])
LDFLAGS=$ac_save_LDFLAGS
$2=AS_VAR_GET([ac_cv_flag_$2])
if test "$2" = yes; then
ifelse([$3], [], [:], [$3])
else
ifelse([$4], [], [:], [$4])
fi
])

230
aclocal.m4 vendored
View File

@@ -1,230 +0,0 @@
# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 1 (pkg-config-0.24)
#
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# 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.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
# ----------------------------------
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])# PKG_PROG_PKG_CONFIG
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
#
# Check to see whether a particular set of modules exists. Similar
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
#
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
# only at the first occurence in configure.ac, so if the first place
# it's called might be skipped (such as if it is within an "if", you
# have to call PKG_CHECK_EXISTS manually
# --------------------------------------------------------------
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_default([$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
# ---------------------------------------------
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes ],
[pkg_failed=yes])
else
pkg_failed=untried
fi[]dnl
])# _PKG_CONFIG
# _PKG_SHORT_ERRORS_SUPPORTED
# -----------------------------
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi[]dnl
])# _PKG_SHORT_ERRORS_SUPPORTED
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
# [ACTION-IF-NOT-FOUND])
#
#
# Note that if there is a possibility the first call to
# PKG_CHECK_MODULES might not happen, you should be sure to include an
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
#
#
# --------------------------------------------------------------
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
fi[]dnl
])# PKG_CHECK_MODULES
# PKG_INSTALLDIR(DIRECTORY)
# -------------------------
# Substitutes the variable pkgconfigdir as the location where a module
# should install pkg-config .pc files. By default the directory is
# $libdir/pkgconfig, but the default can be changed by passing
# DIRECTORY. The user can override through the --with-pkgconfigdir
# parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
[with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_INSTALLDIR
# PKG_NOARCH_INSTALLDIR(DIRECTORY)
# -------------------------
# Substitutes the variable noarch_pkgconfigdir as the location where a
# module should install arch-independent pkg-config .pc files. By
# default the directory is $datadir/pkgconfig, but the default can be
# changed by passing DIRECTORY. The user can override through the
# --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
[with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_NOARCH_INSTALLDIR
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# -------------------------------------------
# Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])# PKG_CHECK_VAR
m4_include([acinclude.m4])

1120
autoconf/config.guess vendored

File diff suppressed because it is too large Load Diff

531
autoconf/config.sub vendored
View File

@@ -1,40 +1,42 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2014 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2014-01-01'
timestamp='2003-06-17'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# 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.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# the same distribution terms that you use for the rest of that program.
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
@@ -68,7 +70,8 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2014 Free Software Foundation, Inc.
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."
@@ -80,11 +83,11 @@ Try \`$me --help' for more information."
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit ;;
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit ;;
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
@@ -96,7 +99,7 @@ while test $# -gt 0 ; do
*local*)
# First pass through any local machine types.
echo $1
exit ;;
exit 0;;
* )
break ;;
@@ -115,18 +118,10 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -149,13 +144,10 @@ 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 | -axis | -knuth | -cray | -microblaze*)
-apple | -axis)
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
@@ -170,17 +162,13 @@ case $os in
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
;;
-hiux*)
os=-hiuxwe2
;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -197,10 +185,6 @@ case $os in
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -218,12 +202,6 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
;;
-lynx*5)
os=-lynxos5
;;
-lynx*)
os=-lynxos
;;
@@ -248,107 +226,55 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | c8051 | clipper \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| ip2k \
| m32r | m68000 | m68k | m88k | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| open8 \
| or1k | or32 \
| openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
| x86 | xscale | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
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)
;;
ms1)
basic_machine=mt-unknown
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xgate)
basic_machine=$basic_machine-unknown
os=-none
;;
xscaleeb)
basic_machine=armeb-unknown
;;
xscaleel)
basic_machine=armel-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
@@ -364,83 +290,58 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| c8051-* | clipper-* | craynv-* | cydra-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| ip2k-* \
| m32r-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| microblaze-* | microblazeel-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
| mips64r5900-* | mips64r5900el-* \
| mips64vr-* | mips64vrel-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| tahoe-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-* | z80-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -458,9 +359,6 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
@@ -478,9 +376,6 @@ case $basic_machine in
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@@ -504,10 +399,6 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -516,35 +407,10 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
bluegene*)
basic_machine=powerpc-ibm
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -569,27 +435,12 @@ case $basic_machine in
basic_machine=j90-cray
os=-unicos
;;
craynv)
basic_machine=craynv-cray
os=-unicosmp
;;
cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
basic_machine=m68k-crds
;;
crisv32 | crisv32-* | etraxfs*)
basic_machine=crisv32-axis
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
crx)
basic_machine=crx-unknown
os=-elf
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
@@ -612,14 +463,6 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
@@ -731,6 +574,7 @@ case $basic_machine in
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
@@ -769,14 +613,6 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -788,21 +624,10 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
microblaze*)
basic_machine=microblaze-xilinx
;;
mingw64)
basic_machine=x86_64-pc
os=-mingw64
;;
mingw32)
basic_machine=i686-pc
basic_machine=i386-pc
os=-mingw32
;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -816,6 +641,10 @@ case $basic_machine in
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
@@ -828,21 +657,10 @@ case $basic_machine in
basic_machine=i386-pc
os=-msdos
;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i686-pc
os=-msys
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
nacl)
basic_machine=le32-unknown
os=-nacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -907,11 +725,9 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
neo-tandem)
basic_machine=neo-tandem
;;
nse-tandem)
basic_machine=nse-tandem
nv1)
basic_machine=nv1-cray
os=-unicosmp
;;
nsr-tandem)
basic_machine=nsr-tandem
@@ -920,12 +736,9 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
openrisc | openrisc-*)
or32 | or32-*)
basic_machine=or32-unknown
;;
os400)
basic_machine=powerpc-ibm
os=-os400
os=-coff
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
@@ -943,14 +756,6 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
basic_machine=sparc-tti
;;
@@ -960,12 +765,6 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pc98)
basic_machine=i386-pc
;;
pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
@@ -995,10 +794,9 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
ppc | ppcbe) basic_machine=powerpc-unknown
ppc) basic_machine=powerpc-unknown
;;
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@@ -1023,14 +821,6 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
basic_machine=i386-pc
os=-rdos
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
@@ -1057,10 +847,6 @@ case $basic_machine in
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei)
basic_machine=mips-sei
os=-seiux
@@ -1072,9 +858,6 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
@@ -1096,9 +879,6 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
@@ -1155,9 +935,17 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
tile*)
basic_machine=$basic_machine-unknown
os=-linux-gnu
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
@@ -1172,10 +960,6 @@ case $basic_machine in
tower | tower-32)
basic_machine=m68k-ncr
;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k)
basic_machine=a29k-amd
os=-udi
@@ -1219,16 +1003,9 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
xbox)
basic_machine=i686-pc
os=-mingw32
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
@@ -1237,10 +1014,6 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
@@ -1260,9 +1033,6 @@ case $basic_machine in
romp)
basic_machine=romp-ibm
;;
mmix)
basic_machine=mmix-knuth
;;
rs6000)
basic_machine=rs6000-ibm
;;
@@ -1279,10 +1049,13 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
@@ -1326,12 +1099,9 @@ esac
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
@@ -1352,31 +1122,25 @@ case $os in
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -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* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
| -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1394,15 +1158,12 @@ case $os in
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
@@ -1415,9 +1176,6 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
os=-os400
;;
-wince*)
os=-wince
;;
@@ -1439,9 +1197,6 @@ case $os in
-atheos*)
os=-atheos
;;
-syllable*)
os=-syllable
;;
-386bsd)
os=-bsd
;;
@@ -1464,9 +1219,6 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
os=-tpf
;;
-triton*)
os=-sysv3
;;
@@ -1500,13 +1252,8 @@ case $os in
-aros*)
os=-aros
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-nacl*)
-kaos*)
os=-kaos
;;
-none)
;;
@@ -1530,12 +1277,6 @@ else
# system, and we'll never get to this point.
case $basic_machine in
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn)
os=-riscix1.2
;;
@@ -1545,24 +1286,9 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
c8051-*)
os=-elf
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
@@ -1581,22 +1307,19 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
m68*-cisco)
os=-aout
;;
mep-*)
os=-elf
;;
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
or1k-*)
os=-elf
;;
or32-*)
os=-coff
;;
@@ -1609,15 +1332,9 @@ case $basic_machine in
*-be)
os=-beos
;;
*-haiku)
os=-haiku
;;
*-ibm)
os=-aix
;;
*-knuth)
os=-mmixware
;;
*-wec)
os=-proelf
;;
@@ -1720,7 +1437,7 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
-cnk*|-aix*)
-aix*)
vendor=ibm
;;
-beos*)
@@ -1750,15 +1467,9 @@ case $basic_machine in
-mvs* | -opened*)
vendor=ibm
;;
-os400*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
@@ -1783,7 +1494,7 @@ case $basic_machine in
esac
echo $basic_machine$os
exit
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)

View File

@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2006-10-14.15
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
@@ -39,24 +39,15 @@ scriptversion=2006-10-14.15
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# 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-}"
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
@@ -67,13 +58,10 @@ stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
posix_glob=
posix_mkdir=
# Desired mode of installed file.
mode=0755
chmodcmd=$chmodprog
transformbasename=
transform_arg=
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
@@ -82,27 +70,22 @@ mvcmd="$mvprog"
src=
dst=
dir_arg=
dstarg=
no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
or: $0 -d DIR1 DIR2...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
In the second, create the directory path DIR.
Options:
-c (ignored)
-b=TRANSFORMBASENAME
-c copy source (using $cpprog) instead of moving (using $mvprog).
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
-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.
@@ -110,9 +93,14 @@ Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test $# -ne 0; do
while test -n "$1"; do
case $1 in
-c) shift
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
-c) instcmd=$cpprog
shift
continue;;
-d) dir_arg=true
@@ -124,17 +112,11 @@ while test $# -ne 0; do
shift
continue;;
--help) echo "$usage"; exit $?;;
--help) echo "$usage"; exit 0;;
-m) mode=$2
-m) chmodcmd="$chmodprog $2"
shift
shift
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
continue;;
-o) chowncmd="$chownprog $2"
@@ -146,358 +128,155 @@ while test $# -ne 0; do
shift
continue;;
-t) dstarg=$2
shift
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-T) no_target_directory=true
shift
continue;;
--version) echo "$0 $scriptversion"; exit 0;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
*) 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 test $# -ne 0 && test -z "$dir_arg$dstarg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
if test -z "$src"; then
echo "$0: no input file specified." >&2
exit 1
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
if test -z "$dst"; then
echo "$0: no destination specified." >&2
exit 1
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,^$,.,'`
# Make sure that the destination directory exists.
# (this part is taken from Noah Friedman's mkinstalldirs script.)
# Skip lots of stat calls in the usual case.
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
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
test -d "$pathcomp" || $mkdirprog "$pathcomp"
pathcomp=$pathcomp/
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
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 test -z "$dir_arg"; then
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
# don't allow the sed command to completely eliminate the filename.
test -z "$dstfile" && dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# 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
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
# Move or copy the file name to the temp name
$doit $instcmd "$src" "$dsttmp" &&
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
# 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"; } &&
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $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
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dstarg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix=/ ;;
-*) prefix=./ ;;
*) prefix= ;;
esac
case $posix_glob in
'')
if (set -f) 2>/dev/null; then
posix_glob=true
else
posix_glob=false
fi ;;
esac
oIFS=$IFS
IFS=/
$posix_glob && set -f
set fnord $dstdir
shift
$posix_glob && set +f
IFS=$oIFS
prefixes=
for d
do
test -z "$d" && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# 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 $cpprog $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 $mode "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
# 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 \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&
# 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 "$dst"; then
$doit $rmcmd -f "$dst" 2>/dev/null \
|| { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
&& { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
|| {
echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
fi &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
} || exit 1
trap '' 0
fi
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)

View File

@@ -1,40 +0,0 @@
#
# Copyright (C) 2004-2010 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CONFSRC=example.conf
CONFDEST=lvm.conf
PROFILE_TEMPLATES=command_profile_template.profile metadata_profile_template.profile
PROFILES=$(PROFILE_TEMPLATES) $(srcdir)/thin-generic.profile $(srcdir)/thin-performance.profile
include $(top_builddir)/make.tmpl
install_conf: $(CONFSRC)
@if [ ! -e $(confdir)/$(CONFDEST) ]; then \
echo "$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST)"; \
$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST); \
fi
install_profiles: $(PROFILES)
$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_PROFILE_DIR)
$(INSTALL_DATA) $(PROFILES) $(DESTDIR)$(DEFAULT_PROFILE_DIR)/
install_lvm2: install_conf install_profiles
install: install_lvm2
DISTCLEAN_TARGETS += $(CONFSRC) $(PROFILE_TEMPLATES)

View File

@@ -1,48 +0,0 @@
# This is a command profile template for the LVM2 system.
#
# It contains all configuration settings that are customizable by command
# profiles. To create a new command profile, select the settings you want
# to customize and add them in a new file named <profile_name>.profile.
# Then install the new profile in a directory as defined by config/profile_dir
# setting found in @DEFAULT_SYS_DIR@/lvm.conf file.
#
# Command profiles can be referenced by using the --commandprofile option then.
#
# Refer to 'man lvm.conf' for further information about profiles and
# general configuration file layout.
#
global {
units="h"
si_unit_consistency=1
suffix=1
lvdisplay_shows_full_device_path=0
}
report {
aligned=1
buffered=1
headings=1
separator=" "
list_item_separator=","
prefixes=0
quoted=1
colums_as_rows=0
binary_values_as_numeric=0
devtypes_sort="devtype_name"
devtypes_cols="devtype_name,devtype_max_partitions,devtype_description"
devtypes_cols_verbose="devtype_name,devtype_max_partitions,devtype_description"
lvs_sort="vg_name,lv_name"
lvs_cols="lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,metadata_percent,move_pv,mirror_log,copy_percent,convert_lv"
lvs_cols_verbose="lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,pool_lv,origin,data_percent,metadata_percent,move_pv,copy_percent,mirror_log,convert_lv,lv_uuid,lv_profile"
vgs_sort="vg_name"
vgs_cols="vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
vgs_cols_verbose="vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid,vg_profile"
pvs_sort="pv_name"
pvs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
pvs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
segs_sort="vg_name,lv_name,seg_start"
segs_cols="lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
segs_cols_verbose="lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
pvsegs_sort="pv_name,pvseg_start"
pvsegs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
pvsegs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +0,0 @@
# This is a metadata profile template for the LVM2 system.
#
# It contains all configuration settings that are customizable by metadata
# profiles. To create a new metadata profile, select the settings you want
# to customize and add them in a new file named <profile_name>.profile.
# Then install the new profile in a directory as defined by config/profile_dir
# setting found in @DEFAULT_SYS_DIR@/lvm.conf file.
#
# Metadata profiles can be referenced by using the --metadataprofile LVM2
# command line option.
#
# Refer to 'man lvm.conf' for further information about profiles and
# general configuration file layout.
#
allocation {
thin_pool_zero=1
thin_pool_discards="passdown"
thin_pool_chunk_size_policy="generic"
# thin_pool_chunk_size=64
}
activation {
thin_pool_autoextend_threshold=100
thin_pool_autoextend_percent=20
}

View File

@@ -1,4 +0,0 @@
allocation {
thin_pool_chunk_size_policy = "generic"
thin_pool_zero = 1
}

View File

@@ -1,4 +0,0 @@
allocation {
thin_pool_chunk_size_policy = "performance"
thin_pool_zero = 0
}

18836
configure vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
#
# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
# 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
@@ -13,35 +13,11 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
.PHONY: dmeventd clvmd cmirrord lvmetad
VPATH = @srcdir@
ifneq ("@CLVMD@", "none")
SUBDIRS += clvmd
SUBDIRS = clvmd
endif
ifeq ("@BUILD_CMIRRORD@", "yes")
SUBDIRS += cmirrord
endif
include $(top_srcdir)/make.tmpl
ifeq ("@BUILD_DMEVENTD@", "yes")
SUBDIRS += dmeventd
ifneq ("$(CFLOW_CMD)", "")
daemons.cflow: dmeventd.cflow
endif
endif
ifeq ("@BUILD_LVMETAD@", "yes")
SUBDIRS += lvmetad
endif
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS = clvmd cmirrord dmeventd lvmetad
endif
include $(top_builddir)/make.tmpl
ifeq ("@BUILD_DMEVENTD@", "yes")
device-mapper: dmeventd.device-mapper
endif

View File

@@ -1,7 +1,7 @@
#
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
# 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
@@ -13,95 +13,47 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CMAN_LIBS = @CMAN_LIBS@
CMAN_CFLAGS = @CMAN_CFLAGS@
CMAP_LIBS = @CMAP_LIBS@
CMAP_CFLAGS = @CMAP_CFLAGS@
CONFDB_LIBS = @CONFDB_LIBS@
CONFDB_CFLAGS = @CONFDB_CFLAGS@
CPG_LIBS = @CPG_LIBS@
CPG_CFLAGS = @CPG_CFLAGS@
DLM_LIBS = @DLM_LIBS@
DLM_CFLAGS = @DLM_CFLAGS@
QUORUM_LIBS = @QUORUM_LIBS@
QUORUM_CFLAGS = @QUORUM_CFLAGS@
SALCK_LIBS = @SALCK_LIBS@
SALCK_CFLAGS = @SALCK_CFLAGS@
VPATH = @srcdir@
SOURCES = \
clvmd-command.c \
clvmd.c \
libclvm.c \
lvm-functions.c \
refresh_clvmd.c
system-lv.c
ifeq ("@DEBUG@", "yes")
DEFS += -DDEBUG
ifeq ("@CLVMD@", "gulm")
SOURCES += clvmd-gulm.c tcp-comms.c
LMLIBS += -lccs -lgulm
CFLAGS += -DUSE_GULM
endif
ifneq (,$(findstring cman,, "@CLVMD@,"))
ifeq ("@CLVMD@", "cman")
SOURCES += clvmd-cman.c
LMLIBS += $(CMAN_LIBS) $(CONFDB_LIBS) $(DLM_LIBS)
CFLAGS += $(CMAN_CFLAGS) $(CONFDB_CFLAGS) $(DLM_CFLAGS)
DEFS += -DUSE_CMAN
endif
ifneq (,$(findstring openais,, "@CLVMD@,"))
SOURCES += clvmd-openais.c
LMLIBS += $(CONFDB_LIBS) $(CPG_LIBS) $(SALCK_LIBS)
CFLAGS += $(CONFDB_CFLAGS) $(CPG_CFLAGS) $(SALCK_CFLAGS)
DEFS += -DUSE_OPENAIS
endif
ifneq (,$(findstring corosync,, "@CLVMD@,"))
SOURCES += clvmd-corosync.c
LMLIBS += $(CMAP_LIBS) $(CONFDB_LIBS) $(CPG_LIBS) $(DLM_LIBS) $(QUORUM_LIBS)
CFLAGS += $(CMAP_CFLAGS) $(CONFDB_CFLAGS) $(CPG_CFLAGS) $(DLM_CFLAGS) $(QUORUM_CFLAGS)
DEFS += -DUSE_COROSYNC
endif
ifneq (,$(findstring singlenode,, &quot;@CLVMD@,&quot;))
SOURCES += clvmd-singlenode.c
DEFS += -DUSE_SINGLENODE
endif
ifeq ($(MAKECMDGOALS),distclean)
SOURCES += clvmd-cman.c
SOURCES += clvmd-openais.c
SOURCES += clvmd-corosync.c
SOURCES += clvmd-singlenode.c
LMLIBS += -ldlm
endif
TARGETS = \
clvmd
LVMLIBS = $(LVMINTERNAL_LIBS)
include $(top_srcdir)/make.tmpl
ifeq ("@DMEVENTD@", "yes")
LVMLIBS += -ldevmapper-event
endif
include $(top_builddir)/make.tmpl
LVMLIBS += -ldevmapper
LIBS += $(PTHREAD_LIBS)
CFLAGS += -fno-strict-aliasing $(EXTRA_EXEC_CFLAGS)
LDFLAGS += $(EXTRA_EXEC_LDFLAGS)
CFLAGS += -D_REENTRANT -fno-strict-aliasing
LIBS += -ldevmapper -llvm -lpthread
INSTALL_TARGETS = \
install_clvmd
clvmd: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
$(CC) $(CFLAGS) $(LDFLAGS) -o clvmd $(OBJECTS) \
$(LVMLIBS) $(LMLIBS) $(LIBS)
clvmd: $(OBJECTS) $(top_srcdir)/lib/liblvm.a
$(CC) -o clvmd $(OBJECTS) $(LDFLAGS) $(LVMLIBS) $(LMLIBS) $(LIBS)
.PHONY: install_clvmd
install_clvmd: $(TARGETS)
$(INSTALL_PROGRAM) -D clvmd $(usrsbindir)/clvmd
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) clvmd \
$(sbindir)/clvmd
install: $(INSTALL_TARGETS)
install_cluster: $(INSTALL_TARGETS)

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -22,40 +22,36 @@
#ifndef _CLVM_H
#define _CLVM_H
#include "configure.h"
#include <inttypes.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
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 or FLAG_REMOTE is also set. */
char args[1]; /* Arguments for the command follow the
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 */
#define CLVMD_FLAG_REMOTE 8 /* Do this on all nodes except for the local node */
#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 */
/* Name of the local socket to communicate between lvm and clvmd */
static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock";
/* 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
#define CLVMD_CMD_GOAWAY 3 /* Die if received this - we are running
an incompatible version */
#define CLVMD_CMD_TEST 4 /* Just for mucking about */
@@ -65,19 +61,5 @@ static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock";
/* Lock/Unlock commands */
#define CLVMD_CMD_LOCK_LV 50
#define CLVMD_CMD_LOCK_VG 51
#define CLVMD_CMD_LOCK_QUERY 52
/* Misc functions */
#define CLVMD_CMD_REFRESH 40
#define CLVMD_CMD_GET_CLUSTERNAME 41
#define CLVMD_CMD_SET_DEBUG 42
#define CLVMD_CMD_VG_BACKUP 43
#define CLVMD_CMD_RESTART 44
#define CLVMD_CMD_SYNC_NAMES 45
/* Used internally by some callers, but not part of the protocol.*/
#define NODE_ALL "*"
#define NODE_LOCAL "."
#define NODE_REMOTE "^"
#endif

View File

@@ -17,42 +17,48 @@
* CMAN communication layer for clvmd.
*/
#include "clvmd-common.h"
#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"
#include <libdlm.h>
#include <syslog.h>
#define LOCKSPACE_NAME "clvmd"
struct clvmd_node
{
struct cman_node *node;
int clvmd_up;
};
static int cluster_sock;
static int num_nodes;
static struct cman_node *nodes = NULL;
static struct cman_node this_node;
static struct cl_cluster_node *nodes = NULL;
static int count_nodes; /* size of allocated nodes array */
static struct dm_hash_table *node_updown_hash;
static int max_updown_nodes = 50; /* Current size of the allocated array */
/* Node up/down status, indexed by nodeid */
static int *node_updown = NULL;
static dlm_lshandle_t *lockspace;
static cman_handle_t c_handle;
static void count_clvmds_running(void);
static void get_members(void);
static int nodeid_from_csid(const char *csid);
static int nodeid_from_csid(char *csid);
static int name_from_nodeid(int nodeid, char *name);
static void event_callback(cman_handle_t handle, void *private, int reason, int arg);
static void data_callback(cman_handle_t handle, void *private,
char *buf, int len, uint8_t port, int nodeid);
struct lock_wait {
pthread_cond_t cond;
@@ -60,201 +66,235 @@ struct lock_wait {
struct dlm_lksb lksb;
};
static int _init_cluster(void)
int init_cluster()
{
node_updown_hash = dm_hash_create(100);
struct sockaddr_cl saddr;
int port = CLUSTER_PORT_CLVMD;
/* Open the cluster communication socket */
c_handle = cman_init(NULL);
if (!c_handle) {
cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT);
if (cluster_sock == -1) {
syslog(LOG_ERR, "Can't open cluster manager socket: %m");
return -1;
}
DEBUGLOG("Connected to CMAN\n");
if (cman_start_recv_data(c_handle, data_callback, CLUSTER_PORT_CLVMD)) {
/* 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;
}
if (cman_start_notification(c_handle, event_callback)) {
syslog(LOG_ERR, "Can't start cluster event listening");
return -1;
}
/* Get the cluster members list */
get_members();
count_clvmds_running();
DEBUGLOG("CMAN initialisation complete\n");
/* Create a lockspace for LV & VG locks to live in */
lockspace = dlm_open_lockspace(LOCKSPACE_NAME);
lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
if (!lockspace) {
lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
if (!lockspace) {
syslog(LOG_ERR, "Unable to create DLM lockspace for CLVM: %m");
return -1;
}
DEBUGLOG("Created DLM lockspace for CLVMD.\n");
} else
DEBUGLOG("Opened existing DLM lockspace for CLVMD.\n");
syslog(LOG_ERR, "Unable to create lockspace for CLVM: %m");
return -1;
}
dlm_ls_pthread_init(lockspace);
DEBUGLOG("DLM initialisation complete\n");
return 0;
}
static void _cluster_init_completed(void)
int get_main_cluster_fd()
{
clvmd_cluster_init_completed();
return cluster_sock;
}
static int _get_main_cluster_fd(void)
int get_num_nodes()
{
return cman_get_fd(c_handle);
}
static int _get_num_nodes(void)
{
int i;
int nnodes = 0;
/* return number of ACTIVE nodes */
for (i=0; i<num_nodes; i++) {
if (nodes[i].cn_member && nodes[i].cn_nodeid)
nnodes++;
}
return nnodes;
return num_nodes;
}
/* send_message with the fd check removed */
static int _cluster_send_message(const void *buf, int msglen, const char *csid,
const char *errtext)
int cluster_send_message(void *buf, int msglen, char *csid, const char *errtext)
{
int nodeid = 0;
struct iovec iov[2];
struct msghdr msg;
struct sockaddr_cl saddr;
int len = 0;
if (csid)
memcpy(&nodeid, csid, CMAN_MAX_CSID_LEN);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iovlen = 1;
msg.msg_iov = iov;
msg.msg_flags = 0;
iov[0].iov_len = msglen;
iov[0].iov_base = buf;
if (cman_send_data(c_handle, buf, msglen, 0, CLUSTER_PORT_CLVMD, nodeid) <= 0)
{
log_error("%s", errtext);
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, MAX_CSID_LEN);
} else { /* Cluster broadcast */
msg.msg_name = NULL;
msg.msg_namelen = 0;
}
return msglen;
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)
void get_our_csid(char *csid)
{
if (this_node.cn_nodeid == 0) {
cman_get_node(c_handle, 0, &this_node);
int i;
memset(csid, 0, MAX_CSID_LEN);
for (i = 0; i < num_nodes; i++) {
if (nodes[i].us)
memcpy(csid, &nodes[i].node_id, MAX_CSID_LEN);
}
memcpy(csid, &this_node.cn_nodeid, CMAN_MAX_CSID_LEN);
}
/* Call a callback routine for each node is that known (down means not running a clvmd) */
static int _cluster_do_node_callback(struct local_client *client,
void (*callback) (struct local_client *,
const char *,
int))
/* Call a callback routine for each node that known (down mean not running a clvmd) */
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++) {
if (nodes[i].cn_member && nodes[i].cn_nodeid) {
int up = (int)(long)dm_hash_lookup_binary(node_updown_hash, (char *)&nodes[i].cn_nodeid, sizeof(int));
callback(client, (char *)&nodes[i].cn_nodeid, up);
if (!up)
somedown = -1;
}
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 messages from the cluster socket */
static void event_callback(cman_handle_t handle, void *private, int reason, int arg)
/* 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[MAX_CLUSTER_MEMBER_NAME_LEN];
switch (reason) {
case CMAN_REASON_PORTCLOSED:
name_from_nodeid(arg, namebuf);
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 port closed message, removing node %s\n", namebuf);
DEBUGLOG("Got OOB message, removing node %s\n", namebuf);
dm_hash_insert_binary(node_updown_hash, (char *)&arg, sizeof(int), (void *)0);
node_updown[nodeid] = 0;
break;
case CMAN_REASON_STATECHANGE:
DEBUGLOG("Got state change message, re-reading members list\n");
case CLUSTER_OOB_MSG_STATECHANGE:
DEBUGLOG("Got OOB message, Cluster state change\n");
get_members();
break;
#if defined(LIBCMAN_VERSION) && LIBCMAN_VERSION >= 2
case CMAN_REASON_PORTOPENED:
/* Ignore this, wait for startup message from clvmd itself */
break;
case CMAN_REASON_TRY_SHUTDOWN:
DEBUGLOG("Got try shutdown, sending OK\n");
cman_replyto_shutdown(c_handle, 1);
break;
#endif
default:
/* ERROR */
DEBUGLOG("Got unknown event callback message: %d\n", reason);
break;
DEBUGLOG("Got unknown OOB message: %d\n", buf[0]);
}
}
static struct local_client *cman_client;
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
const char *csid,
struct local_client **new_client)
int cluster_fd_callback(struct local_client *client, char *buf, int len, char *csid,
struct local_client **new_client)
{
/* Save this for data_callback */
cman_client = fd;
struct iovec iov[2];
struct msghdr msg;
struct sockaddr_cl saddr;
/* We never return a new client */
*new_client = NULL;
return cman_dispatch(c_handle, 0);
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 data_callback(cman_handle_t handle, void *private,
char *buf, int len, uint8_t port, int nodeid)
{
/* Ignore looped back messages */
if (nodeid == this_node.cn_nodeid)
return;
process_message(cman_client, buf, len, (char *)&nodeid);
}
static void _add_up_node(const char *csid)
void add_up_node(char *csid)
{
/* It's up ! */
int nodeid = nodeid_from_csid(csid);
dm_hash_insert_binary(node_updown_hash, (char *)&nodeid, sizeof(int), (void *)1);
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(void)
void cluster_closedown()
{
unlock_all();
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
cman_finish(c_handle);
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 = cman_is_listening(c_handle, nodeid, CLUSTER_PORT_CLVMD);
status = ioctl(cluster_sock, SIOCCLUSTER_ISLISTENING, &rq);
if (status < 0 && errno == EBUSY) { /* Don't busywait */
sleep(1);
errno = EBUSY; /* In case sleep trashes it */
@@ -267,71 +307,72 @@ static int is_listening(int nodeid)
/* Populate the list of CLVMDs running.
called only at startup time */
static void count_clvmds_running(void)
void count_clvmds_running(void)
{
int i;
for (i = 0; i < num_nodes; i++) {
int nodeid = nodes[i].cn_nodeid;
if (is_listening(nodeid) == 1)
dm_hash_insert_binary(node_updown_hash, (void *)&nodeid, sizeof(int), (void*)1);
else
dm_hash_insert_binary(node_updown_hash, (void *)&nodeid, sizeof(int), (void*)0);
node_updown[nodes[i].node_id] = is_listening(nodes[i].node_id);
}
}
/* Get a list of active cluster members */
static void get_members(void)
static void get_members()
{
int retnodes;
int status;
int i;
int high_nodeid = 0;
struct cl_cluster_nodelist nodelist;
num_nodes = cman_get_node_count(c_handle);
num_nodes = ioctl(cluster_sock, SIOCCLUSTER_GETMEMBERS, 0);
if (num_nodes == -1) {
log_error("Unable to get node count");
return;
}
/* 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 cman_node));
if (!nodes) {
log_error("Unable to allocate nodes array\n");
exit(5);
} else {
/* Not enough room for new nodes list ? */
if (num_nodes > count_nodes && nodes) {
free(nodes);
nodes = NULL;
}
}
status = cman_get_nodes(c_handle, count_nodes, &retnodes, nodes);
if (status < 0) {
log_error("Unable to get node details");
exit(6);
}
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;
/* Get the highest nodeid */
for (i=0; i<retnodes; i++) {
if (nodes[i].cn_nodeid > high_nodeid)
high_nodeid = nodes[i].cn_nodeid;
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, const char *name)
int csid_from_name(char *csid, char *name)
{
int i;
for (i = 0; i < num_nodes; i++) {
if (strcmp(name, nodes[i].cn_name) == 0) {
memcpy(csid, &nodes[i].cn_nodeid, CMAN_MAX_CSID_LEN);
if (strcmp(name, nodes[i].name) == 0) {
memcpy(csid, &nodes[i].node_id, MAX_CSID_LEN);
return 0;
}
}
@@ -339,13 +380,13 @@ static int _csid_from_name(char *csid, const char *name)
}
/* Convert a CSID to a node name */
static int _name_from_csid(const char *csid, char *name)
int name_from_csid(char *csid, char *name)
{
int i;
for (i = 0; i < num_nodes; i++) {
if (memcmp(csid, &nodes[i].cn_nodeid, CMAN_MAX_CSID_LEN) == 0) {
strcpy(name, nodes[i].cn_name);
if (memcmp(csid, &nodes[i].node_id, MAX_CSID_LEN) == 0) {
strcpy(name, nodes[i].name);
return 0;
}
}
@@ -355,13 +396,13 @@ static int _name_from_csid(const char *csid, char *name)
}
/* Convert a node ID to a node name */
static int name_from_nodeid(int nodeid, char *name)
int name_from_nodeid(int nodeid, char *name)
{
int i;
for (i = 0; i < num_nodes; i++) {
if (nodeid == nodes[i].cn_nodeid) {
strcpy(name, nodes[i].cn_name);
if (nodeid == nodes[i].node_id) {
strcpy(name, nodes[i].name);
return 0;
}
}
@@ -371,18 +412,18 @@ static int name_from_nodeid(int nodeid, char *name)
}
/* Convert a CSID to a node ID */
static int nodeid_from_csid(const char *csid)
static int nodeid_from_csid(char *csid)
{
int nodeid;
memcpy(&nodeid, csid, CMAN_MAX_CSID_LEN);
memcpy(&nodeid, csid, MAX_CSID_LEN);
return nodeid;
}
static int _is_quorate(void)
int is_quorate()
{
return cman_is_quorate(c_handle);
return ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0);
}
static void sync_ast_routine(void *arg)
@@ -394,7 +435,7 @@ static void sync_ast_routine(void *arg)
pthread_mutex_unlock(&lwait->mutex);
}
static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
int sync_lock(const char *resource, int mode, int flags, int *lockid)
{
int status;
struct lock_wait lwait;
@@ -437,7 +478,7 @@ static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
return 0;
}
static int _sync_unlock(const char *resource /* UNUSED */, int lockid)
int sync_unlock(const char *resource /* UNUSED */, int lockid)
{
int status;
struct lock_wait lwait;
@@ -464,42 +505,3 @@ static int _sync_unlock(const char *resource /* UNUSED */, int lockid)
return 0;
}
static int _get_cluster_name(char *buf, int buflen)
{
cman_cluster_t cluster_info;
int status;
status = cman_get_cluster(c_handle, &cluster_info);
if (!status) {
strncpy(buf, cluster_info.ci_name, buflen);
}
return status;
}
static struct cluster_ops _cluster_cman_ops = {
.name = "cman",
.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,
.get_cluster_name = _get_cluster_name,
.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

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -50,19 +50,30 @@
*/
#include "clvmd-common.h"
#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 "list.h"
#include "hash.h"
#include "locking.h"
#include "log.h"
#include "lvm-functions.h"
#include "clvmd-comms.h"
#include "clvm.h"
#include "clvmd.h"
#include "lvm-globals.h"
#include "lvm-functions.h"
#include "locking.h"
#include <sys/utsname.h>
extern struct cluster_ops *clops;
static int restart_clvmd(void);
#include "libdlm.h"
/* This is where all the real work happens:
NOTE: client will be NULL when this is executed on a remote node */
@@ -73,7 +84,6 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
int arglen = msglen - sizeof(struct clvm_header) - strlen(msg->node);
int status = 0;
char *lockname;
const char *locktype;
struct utsname nodeinfo;
unsigned char lock_cmd;
unsigned char lock_flags;
@@ -83,33 +93,18 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
/* Just a test message */
case CLVMD_CMD_TEST:
if (arglen > buflen) {
char *new_buf;
buflen = arglen + 200;
new_buf = realloc(*buf, buflen);
if (new_buf == NULL) {
status = errno;
free (*buf);
}
*buf = new_buf;
}
if (*buf) {
if (uname(&nodeinfo))
memset(&nodeinfo, 0, sizeof(nodeinfo));
*retlen = 1 + dm_snprintf(*buf, buflen,
"TEST from %s: %s v%s",
nodeinfo.nodename, args,
nodeinfo.release);
*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:
lock_cmd = args[0];
lock_flags = args[1];
lockname = &args[2];
/* Check to see if the VG is in use by LVM1 */
status = do_check_lvm1(lockname);
do_lock_vg(lock_cmd, lock_flags, lockname);
status = do_check_lvm1(&args[2]);
break;
case CLVMD_CMD_LOCK_LV:
@@ -120,50 +115,13 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
status = do_lock_lv(lock_cmd, lock_flags, lockname);
/* Replace EIO with something less scary */
if (status == EIO) {
*retlen = 1 + dm_snprintf(*buf, buflen, "%s",
get_last_lvm_error());
*retlen =
1 + snprintf(*buf, buflen,
"Internal lvm error, check syslog");
return EIO;
}
break;
case CLVMD_CMD_LOCK_QUERY:
lockname = &args[2];
if (buflen < 3)
return EIO;
if ((locktype = do_lock_query(lockname)))
*retlen = 1 + dm_snprintf(*buf, buflen, "%s", locktype);
break;
case CLVMD_CMD_REFRESH:
do_refresh_cache();
break;
case CLVMD_CMD_SYNC_NAMES:
lvm_do_fs_unlock();
break;
case CLVMD_CMD_SET_DEBUG:
clvmd_set_debug((debug_t) args[0]);
break;
case CLVMD_CMD_RESTART:
status = restart_clvmd();
break;
case CLVMD_CMD_GET_CLUSTERNAME:
status = clops->get_cluster_name(*buf, buflen);
if (!status)
*retlen = strlen(*buf)+1;
break;
case CLVMD_CMD_VG_BACKUP:
/*
* Do not run backup on local node, caller should do that.
*/
if (!client)
lvm_do_backup(&args[2]);
break;
default:
/* Won't get here because command is validated in pre_command */
break;
@@ -171,63 +129,65 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
/* Check the status of the command and return the error text */
if (status) {
*retlen = 1 + ((*buf) ? dm_snprintf(*buf, buflen, "%s",
strerror(status)) : -1);
*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;
int lock_mode;
char *args = header->node + strlen(header->node) + 1;
int lkid;
int status;
char *lockname;
struct 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) {
if (!(lock_hash = dm_hash_create(3)))
return ENOMEM;
client->bits.localsock.private = (void *) lock_hash;
} else
lock_hash = (struct dm_hash_table *) client->bits.localsock.private;
/* 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 hash_table *)client->bits.localsock.private;
}
else {
lock_hash = hash_create(3);
if (!lock_hash)
return ENOMEM;
client->bits.localsock.private = (void *)lock_hash;
}
lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
lock_mode = ((int) lock_cmd & LCK_TYPE_MASK);
/* lock_flags = args[1]; */
lockname = &args[2];
DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
lock_cmd = args[0];
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_mode == LCK_UNLOCK) {
if (!(lkid = (int) (long) dm_hash_lookup(lock_hash, lockname)))
return EINVAL;
if (lock_cmd == LCK_UNLOCK) {
if ((status = sync_unlock(lockname, lkid)))
status = errno;
else
dm_hash_remove(lock_hash, lockname);
} else {
/* Read locks need to be PR; other modes get passed through */
if (lock_mode == LCK_READ)
lock_mode = LCK_PREAD;
lkid = (int)(long)hash_lookup(lock_hash, lockname);
if (lkid == 0)
return EINVAL;
if ((status = sync_lock(lockname, lock_mode, (lock_cmd & LCK_NONBLOCK) ? LCKF_NOQUEUE : 0, &lkid)))
status = errno;
else if (!dm_hash_insert(lock_hash, lockname, (void *) (long) lkid))
return ENOMEM;
}
status = sync_unlock(lockname, lkid);
if (status)
status = errno;
else
hash_remove(lock_hash, lockname);
}
else {
return status;
status = sync_lock(lockname, (int)lock_cmd, (int)lock_flags, &lkid);
if (status)
status = errno;
else
hash_insert(lock_hash, lockname, (void *)lkid);
}
return status;
}
@@ -241,22 +201,18 @@ int do_pre_command(struct local_client *client)
unsigned char lock_cmd;
unsigned char lock_flags;
char *args = header->node + strlen(header->node) + 1;
int lockid = 0;
int lockid;
int status = 0;
char *lockname;
switch (header->cmd) {
case CLVMD_CMD_TEST:
status = sync_lock("CLVMD_TEST", LCK_EXCL, 0, &lockid);
client->bits.localsock.private = (void *)(long)lockid;
status = sync_lock("CLVMD_TEST", LKM_EXMODE, 0, &lockid);
client->bits.localsock.private = (void *) lockid;
break;
case CLVMD_CMD_LOCK_VG:
lockname = &args[2];
/* We take out a real lock unless LCK_CACHE was set */
if (!strncmp(lockname, "V_", 2) ||
!strncmp(lockname, "P_#", 3))
status = lock_vg(client);
status = lock_vg(client);
break;
case CLVMD_CMD_LOCK_LV:
@@ -266,15 +222,6 @@ int do_pre_command(struct local_client *client)
status = pre_lock_lv(lock_cmd, lock_flags, lockname);
break;
case CLVMD_CMD_REFRESH:
case CLVMD_CMD_GET_CLUSTERNAME:
case CLVMD_CMD_SET_DEBUG:
case CLVMD_CMD_VG_BACKUP:
case CLVMD_CMD_SYNC_NAMES:
case CLVMD_CMD_LOCK_QUERY:
case CLVMD_CMD_RESTART:
break;
default:
log_error("Unknown command %d received\n", header->cmd);
status = EINVAL;
@@ -296,8 +243,13 @@ int do_post_command(struct local_client *client)
switch (header->cmd) {
case CLVMD_CMD_TEST:
status = sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
client->bits.localsock.private = NULL;
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:
@@ -306,10 +258,6 @@ int do_post_command(struct local_client *client)
lockname = &args[2];
status = post_lock_lv(lock_cmd, lock_flags, lockname);
break;
default:
/* Nothing to do here */
break;
}
return status;
}
@@ -318,97 +266,20 @@ int do_post_command(struct local_client *client)
/* Called when the client is about to be deleted */
void cmd_client_cleanup(struct local_client *client)
{
struct dm_hash_node *v;
struct dm_hash_table *lock_hash;
int lkid;
char *lockname;
if (client->bits.localsock.private) {
if (!client->bits.localsock.private)
return;
struct hash_node *v;
struct hash_table *lock_hash =
(struct hash_table *)client->bits.localsock.private;
lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
hash_iterate(v, lock_hash) {
int lkid = (int)(long)hash_get_data(lock_hash, v);
dm_hash_iterate(v, lock_hash) {
lkid = (int)(long)dm_hash_get_data(lock_hash, v);
lockname = dm_hash_get_key(lock_hash, v);
DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
(void) sync_unlock(lockname, lkid);
DEBUGLOG("cleanup: Unlocking lkid %x\n", lkid);
sync_unlock("DUMMY", lkid);
}
dm_hash_destroy(lock_hash);
client->bits.localsock.private = NULL;
}
static int restart_clvmd(void)
{
const char **argv;
char *lv_name;
int argc = 0, max_locks = 0;
struct dm_hash_node *hn = NULL;
char debug_arg[16];
const char *clvmd = getenv("LVM_CLVMD_BINARY") ? : CLVMD_PATH;
DEBUGLOG("clvmd restart requested\n");
/* Count exclusively-open LVs */
do {
hn = get_next_excl_lock(hn, &lv_name);
if (lv_name) {
max_locks++;
if (!*lv_name)
break; /* FIXME: Is this error ? */
}
} while (hn);
/* clvmd + locks (-E uuid) + debug (-d X) + NULL */
if (!(argv = malloc((max_locks * 2 + 6) * sizeof(*argv))))
goto_out;
/*
* Build the command-line
*/
argv[argc++] = "clvmd";
/* Propagate debug options */
if (clvmd_get_debug()) {
if (dm_snprintf(debug_arg, sizeof(debug_arg), "-d%u", clvmd_get_debug()) < 0)
goto_out;
argv[argc++] = debug_arg;
}
/* Propagate foreground options */
if (clvmd_get_foreground())
argv[argc++] = "-f";
argv[argc++] = "-I";
argv[argc++] = clops->name;
/* Now add the exclusively-open LVs */
hn = NULL;
do {
hn = get_next_excl_lock(hn, &lv_name);
if (lv_name) {
if (!*lv_name)
break; /* FIXME: Is this error ? */
argv[argc++] = "-E";
argv[argc++] = lv_name;
DEBUGLOG("excl lock: %s\n", lv_name);
}
} while (hn);
argv[argc] = NULL;
/* Exec new clvmd */
DEBUGLOG("--- Restarting %s ---\n", clvmd);
for (argc = 1; argv[argc]; argc++) DEBUGLOG("--- %d: %s\n", argc, argv[argc]);
/* NOTE: This will fail when downgrading! */
execvp(clvmd, (char **)argv);
out:
/* We failed */
DEBUGLOG("Restart of clvmd failed.\n");
free(argv);
return EIO;
hash_destroy(lock_hash);
client->bits.localsock.private = 0;
}
}

View File

@@ -1,32 +0,0 @@
/*
* Copyright (C) 2010 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
*/
/*
* This file must be included first by every clvmd source file.
*/
#ifndef _LVM_CLVMD_COMMON_H
#define _LVM_CLVMD_COMMON_H
#include "configure.h"
#define _REENTRANT
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include "libdevmapper.h"
#include "lvm-logging.h"
#include <unistd.h>
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -22,98 +22,34 @@
struct local_client;
struct cluster_ops {
const char *name;
void (*cluster_init_completed) (void);
extern int cluster_send_message(void *buf, int msglen, char *csid,
const char *errtext);
extern int name_from_csid(char *csid, char *name);
extern int csid_from_name(char *csid, char *name);
extern int get_num_nodes(void);
extern int cluster_fd_callback(struct local_client *fd, char *buf, int len,
char *csid, struct local_client **new_client);
extern int init_cluster(void);
extern int get_main_cluster_fd(void); /* gets accept FD or cman cluster socket */
extern int cluster_do_node_callback(struct local_client *client,
void (*callback) (struct local_client *,
char *csid, int node_up));
extern int is_quorate(void);
int (*cluster_send_message) (const void *buf, int msglen,
const char *csid,
const char *errtext);
int (*name_from_csid) (const char *csid, char *name);
int (*csid_from_name) (char *csid, const char *name);
int (*get_num_nodes) (void);
int (*cluster_fd_callback) (struct local_client *fd, char *buf, int len,
const 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 *,
const char *csid,
int node_up));
int (*is_quorate) (void);
extern void get_our_csid(char *csid);
extern void add_up_node(char *csid);
extern void cluster_closedown(void);
void (*get_our_csid) (char *csid);
void (*add_up_node) (const char *csid);
void (*reread_config) (void);
void (*cluster_closedown) (void);
extern int sync_lock(const char *resource, int mode, int flags, int *lockid);
extern int sync_unlock(const char *resource, int lockid);
int (*get_cluster_name)(char *buf, int buflen);
int (*sync_lock) (const char *resource, int mode,
int flags, int *lockid);
int (*sync_unlock) (const char *resource, int lockid);
};
#ifdef USE_CMAN
# include <netinet/in.h>
# include "libcman.h"
# define CMAN_MAX_CSID_LEN 4
# ifndef MAX_CSID_LEN
# define MAX_CSID_LEN CMAN_MAX_CSID_LEN
# endif
# undef MAX_CLUSTER_MEMBER_NAME_LEN
# define MAX_CLUSTER_MEMBER_NAME_LEN CMAN_MAX_NODENAME_LEN
# define CMAN_MAX_CLUSTER_MESSAGE 1500
# define CLUSTER_PORT_CLVMD 11
struct cluster_ops *init_cman_cluster(void);
#ifdef USE_GULM
#include "tcp-comms.h"
#else
/* cman */
#include "cnxman-socket.h"
#define MAX_CSID_LEN 4
#endif
#ifdef USE_OPENAIS
# include <openais/saAis.h>
# include <corosync/totem/totem.h>
# define OPENAIS_CSID_LEN (sizeof(int))
# define OPENAIS_MAX_CLUSTER_MESSAGE MESSAGE_SIZE_MAX
# define OPENAIS_MAX_CLUSTER_MEMBER_NAME_LEN SA_MAX_NAME_LENGTH
# ifndef MAX_CLUSTER_MEMBER_NAME_LEN
# define MAX_CLUSTER_MEMBER_NAME_LEN SA_MAX_NAME_LENGTH
# endif
# ifndef CMAN_MAX_CLUSTER_MESSAGE
# define CMAN_MAX_CLUSTER_MESSAGE MESSAGE_SIZE_MAX
# endif
# ifndef MAX_CSID_LEN
# define MAX_CSID_LEN sizeof(int)
# endif
struct cluster_ops *init_openais_cluster(void);
#endif
#ifdef USE_COROSYNC
# include <corosync/corotypes.h>
# define COROSYNC_CSID_LEN (sizeof(int))
# define COROSYNC_MAX_CLUSTER_MESSAGE 65535
# define COROSYNC_MAX_CLUSTER_MEMBER_NAME_LEN CS_MAX_NAME_LENGTH
# ifndef MAX_CLUSTER_MEMBER_NAME_LEN
# define MAX_CLUSTER_MEMBER_NAME_LEN CS_MAX_NAME_LENGTH
# endif
# ifndef CMAN_MAX_CLUSTER_MESSAGE
# define CMAN_MAX_CLUSTER_MESSAGE 65535
# endif
# ifndef MAX_CSID_LEN
# define MAX_CSID_LEN sizeof(int)
# endif
struct cluster_ops *init_corosync_cluster(void);
#endif
#ifdef USE_SINGLENODE
# define SINGLENODE_CSID_LEN (sizeof(int))
# ifndef MAX_CLUSTER_MEMBER_NAME_LEN
# define MAX_CLUSTER_MEMBER_NAME_LEN 64
# endif
# define SINGLENODE_MAX_CLUSTER_MESSAGE 65535
# ifndef MAX_CSID_LEN
# define MAX_CSID_LEN sizeof(int)
# endif
struct cluster_ops *init_singlenode_cluster(void);
#endif
#endif

View File

@@ -1,658 +0,0 @@
/*
* Copyright (C) 2009-2012 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
*/
/*
* This provides the interface between clvmd and corosync/DLM as the cluster
* and lock manager.
*/
#include "clvmd-common.h"
#include <pthread.h>
#include "clvm.h"
#include "clvmd-comms.h"
#include "clvmd.h"
#include "lvm-functions.h"
#include "locking.h"
#include <corosync/cpg.h>
#include <corosync/quorum.h>
#ifdef HAVE_COROSYNC_CONFDB_H
# include <corosync/confdb.h>
#elif defined HAVE_COROSYNC_CMAP_H
# include <corosync/cmap.h>
#else
# error "Either HAVE_COROSYNC_CONFDB_H or HAVE_COROSYNC_CMAP_H must be defined."
#endif
#include <libdlm.h>
#include <syslog.h>
/* Timeout value for several corosync calls */
#define LOCKSPACE_NAME "clvmd"
static void corosync_cpg_deliver_callback (cpg_handle_t handle,
const struct cpg_name *groupName,
uint32_t nodeid,
uint32_t pid,
void *msg,
size_t msg_len);
static void corosync_cpg_confchg_callback(cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list, size_t member_list_entries,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries);
static void _cluster_closedown(void);
/* Hash list of nodes in the cluster */
static struct dm_hash_table *node_hash;
/* Number of active nodes */
static int num_nodes;
static unsigned int our_nodeid;
static struct local_client *cluster_client;
/* Corosync handles */
static cpg_handle_t cpg_handle;
static quorum_handle_t quorum_handle;
/* DLM Handle */
static dlm_lshandle_t *lockspace;
static struct cpg_name cpg_group_name;
/* Corosync callback structs */
cpg_callbacks_t corosync_cpg_callbacks = {
.cpg_deliver_fn = corosync_cpg_deliver_callback,
.cpg_confchg_fn = corosync_cpg_confchg_callback,
};
quorum_callbacks_t quorum_callbacks = {
.quorum_notify_fn = NULL,
};
struct node_info
{
enum {NODE_DOWN, NODE_CLVMD} state;
int nodeid;
};
/* Set errno to something approximating the right value and return 0 or -1 */
static int cs_to_errno(cs_error_t err)
{
switch(err)
{
case CS_OK:
return 0;
case CS_ERR_LIBRARY:
errno = EINVAL;
break;
case CS_ERR_VERSION:
errno = EINVAL;
break;
case CS_ERR_INIT:
errno = EINVAL;
break;
case CS_ERR_TIMEOUT:
errno = ETIME;
break;
case CS_ERR_TRY_AGAIN:
errno = EAGAIN;
break;
case CS_ERR_INVALID_PARAM:
errno = EINVAL;
break;
case CS_ERR_NO_MEMORY:
errno = ENOMEM;
break;
case CS_ERR_BAD_HANDLE:
errno = EINVAL;
break;
case CS_ERR_BUSY:
errno = EBUSY;
break;
case CS_ERR_ACCESS:
errno = EPERM;
break;
case CS_ERR_NOT_EXIST:
errno = ENOENT;
break;
case CS_ERR_NAME_TOO_LONG:
errno = ENAMETOOLONG;
break;
case CS_ERR_EXIST:
errno = EEXIST;
break;
case CS_ERR_NO_SPACE:
errno = ENOSPC;
break;
case CS_ERR_INTERRUPT:
errno = EINTR;
break;
case CS_ERR_NAME_NOT_FOUND:
errno = ENOENT;
break;
case CS_ERR_NO_RESOURCES:
errno = ENOMEM;
break;
case CS_ERR_NOT_SUPPORTED:
errno = EOPNOTSUPP;
break;
case CS_ERR_BAD_OPERATION:
errno = EINVAL;
break;
case CS_ERR_FAILED_OPERATION:
errno = EIO;
break;
case CS_ERR_MESSAGE_ERROR:
errno = EIO;
break;
case CS_ERR_QUEUE_FULL:
errno = EXFULL;
break;
case CS_ERR_QUEUE_NOT_AVAILABLE:
errno = EINVAL;
break;
case CS_ERR_BAD_FLAGS:
errno = EINVAL;
break;
case CS_ERR_TOO_BIG:
errno = E2BIG;
break;
case CS_ERR_NO_SECTIONS:
errno = ENOMEM;
break;
default:
errno = EINVAL;
break;
}
return -1;
}
static char *print_corosync_csid(const char *csid)
{
static char buf[128];
int id;
memcpy(&id, csid, sizeof(int));
sprintf(buf, "%d", id);
return buf;
}
static void corosync_cpg_deliver_callback (cpg_handle_t handle,
const struct cpg_name *groupName,
uint32_t nodeid,
uint32_t pid,
void *msg,
size_t msg_len)
{
int target_nodeid;
memcpy(&target_nodeid, msg, COROSYNC_CSID_LEN);
DEBUGLOG("%u got message from nodeid %d for %d. len %zd\n",
our_nodeid, nodeid, target_nodeid, msg_len-4);
if (nodeid != our_nodeid)
if (target_nodeid == our_nodeid || target_nodeid == 0)
process_message(cluster_client, (char *)msg+COROSYNC_CSID_LEN,
msg_len-COROSYNC_CSID_LEN, (char*)&nodeid);
}
static void corosync_cpg_confchg_callback(cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list, size_t member_list_entries,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries)
{
int i;
struct node_info *ninfo;
DEBUGLOG("confchg callback. %zd joined, %zd left, %zd members\n",
joined_list_entries, left_list_entries, member_list_entries);
for (i=0; i<joined_list_entries; i++) {
ninfo = dm_hash_lookup_binary(node_hash,
(char *)&joined_list[i].nodeid,
COROSYNC_CSID_LEN);
if (!ninfo) {
ninfo = malloc(sizeof(struct node_info));
if (!ninfo) {
break;
}
else {
ninfo->nodeid = joined_list[i].nodeid;
dm_hash_insert_binary(node_hash,
(char *)&ninfo->nodeid,
COROSYNC_CSID_LEN, ninfo);
}
}
ninfo->state = NODE_CLVMD;
}
for (i=0; i<left_list_entries; i++) {
ninfo = dm_hash_lookup_binary(node_hash,
(char *)&left_list[i].nodeid,
COROSYNC_CSID_LEN);
if (ninfo)
ninfo->state = NODE_DOWN;
}
num_nodes = member_list_entries;
}
static int _init_cluster(void)
{
cs_error_t err;
#ifdef QUORUM_SET /* corosync/quorum.h */
uint32_t quorum_type;
#endif
node_hash = dm_hash_create(100);
err = cpg_initialize(&cpg_handle,
&corosync_cpg_callbacks);
if (err != CS_OK) {
syslog(LOG_ERR, "Cannot initialise Corosync CPG service: %d",
err);
DEBUGLOG("Cannot initialise Corosync CPG service: %d", err);
return cs_to_errno(err);
}
#ifdef QUORUM_SET
err = quorum_initialize(&quorum_handle,
&quorum_callbacks,
&quorum_type);
if (quorum_type != QUORUM_SET) {
syslog(LOG_ERR, "Corosync quorum service is not configured");
DEBUGLOG("Corosync quorum service is not configured");
return EINVAL;
}
#else
err = quorum_initialize(&quorum_handle,
&quorum_callbacks);
#endif
if (err != CS_OK) {
syslog(LOG_ERR, "Cannot initialise Corosync quorum service: %d",
err);
DEBUGLOG("Cannot initialise Corosync quorum service: %d", err);
return cs_to_errno(err);
}
/* Create a lockspace for LV & VG locks to live in */
lockspace = dlm_open_lockspace(LOCKSPACE_NAME);
if (!lockspace) {
lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
if (!lockspace) {
syslog(LOG_ERR, "Unable to create DLM lockspace for CLVM: %m");
return -1;
}
DEBUGLOG("Created DLM lockspace for CLVMD.\n");
} else
DEBUGLOG("Opened existing DLM lockspace for CLVMD.\n");
dlm_ls_pthread_init(lockspace);
DEBUGLOG("DLM initialisation complete\n");
/* Connect to the clvmd group */
strcpy((char *)cpg_group_name.value, "clvmd");
cpg_group_name.length = strlen((char *)cpg_group_name.value);
err = cpg_join(cpg_handle, &cpg_group_name);
if (err != CS_OK) {
cpg_finalize(cpg_handle);
quorum_finalize(quorum_handle);
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
syslog(LOG_ERR, "Cannot join clvmd process group");
DEBUGLOG("Cannot join clvmd process group: %d\n", err);
return cs_to_errno(err);
}
err = cpg_local_get(cpg_handle,
&our_nodeid);
if (err != CS_OK) {
cpg_finalize(cpg_handle);
quorum_finalize(quorum_handle);
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
syslog(LOG_ERR, "Cannot get local node id\n");
return cs_to_errno(err);
}
DEBUGLOG("Our local node id is %d\n", our_nodeid);
DEBUGLOG("Connected to Corosync\n");
return 0;
}
static void _cluster_closedown(void)
{
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
cpg_finalize(cpg_handle);
quorum_finalize(quorum_handle);
}
static void _get_our_csid(char *csid)
{
memcpy(csid, &our_nodeid, sizeof(int));
}
/* Corosync doesn't really have nmode names so we
just use the node ID in hex instead */
static int _csid_from_name(char *csid, const char *name)
{
int nodeid;
struct node_info *ninfo;
if (sscanf(name, "%x", &nodeid) == 1) {
ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
if (ninfo)
return nodeid;
}
return -1;
}
static int _name_from_csid(const char *csid, char *name)
{
struct node_info *ninfo;
ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
if (!ninfo)
{
sprintf(name, "UNKNOWN %s", print_corosync_csid(csid));
return -1;
}
sprintf(name, "%x", ninfo->nodeid);
return 0;
}
static int _get_num_nodes(void)
{
DEBUGLOG("num_nodes = %d\n", num_nodes);
return num_nodes;
}
/* Node is now known to be running a clvmd */
static void _add_up_node(const char *csid)
{
struct node_info *ninfo;
ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
if (!ninfo) {
DEBUGLOG("corosync_add_up_node no node_hash entry for csid %s\n",
print_corosync_csid(csid));
return;
}
DEBUGLOG("corosync_add_up_node %d\n", ninfo->nodeid);
ninfo->state = NODE_CLVMD;
return;
}
/* Call a callback for each node, so the caller knows whether it's up or down */
static int _cluster_do_node_callback(struct local_client *master_client,
void (*callback)(struct local_client *,
const char *csid, int node_up))
{
struct dm_hash_node *hn;
struct node_info *ninfo;
dm_hash_iterate(hn, node_hash)
{
char csid[COROSYNC_CSID_LEN];
ninfo = dm_hash_get_data(node_hash, hn);
memcpy(csid, dm_hash_get_key(node_hash, hn), COROSYNC_CSID_LEN);
DEBUGLOG("down_callback. node %d, state = %d\n", ninfo->nodeid,
ninfo->state);
if (ninfo->state == NODE_CLVMD)
callback(master_client, csid, 1);
}
return 0;
}
/* Real locking */
static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
{
struct dlm_lksb lksb;
int err;
DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
if (flags & LKF_CONVERT)
lksb.sb_lkid = *lockid;
err = dlm_ls_lock_wait(lockspace,
mode,
&lksb,
flags,
resource,
strlen(resource),
0,
NULL, NULL, NULL);
if (err != 0)
{
DEBUGLOG("dlm_ls_lock returned %d\n", errno);
return err;
}
if (lksb.sb_status != 0)
{
DEBUGLOG("dlm_ls_lock returns lksb.sb_status %d\n", lksb.sb_status);
errno = lksb.sb_status;
return -1;
}
DEBUGLOG("lock_resource returning %d, lock_id=%x\n", err, lksb.sb_lkid);
*lockid = lksb.sb_lkid;
return 0;
}
static int _unlock_resource(const char *resource, int lockid)
{
struct dlm_lksb lksb;
int err;
DEBUGLOG("unlock_resource: %s lockid: %x\n", resource, lockid);
lksb.sb_lkid = lockid;
err = dlm_ls_unlock_wait(lockspace,
lockid,
0,
&lksb);
if (err != 0)
{
DEBUGLOG("Unlock returned %d\n", err);
return err;
}
if (lksb.sb_status != EUNLOCK)
{
DEBUGLOG("dlm_ls_unlock_wait returns lksb.sb_status: %d\n", lksb.sb_status);
errno = lksb.sb_status;
return -1;
}
return 0;
}
static int _is_quorate(void)
{
int quorate;
if (quorum_getquorate(quorum_handle, &quorate) == CS_OK)
return quorate;
else
return 0;
}
static int _get_main_cluster_fd(void)
{
int select_fd;
cpg_fd_get(cpg_handle, &select_fd);
return select_fd;
}
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
const char *csid,
struct local_client **new_client)
{
cluster_client = fd;
*new_client = NULL;
cpg_dispatch(cpg_handle, CS_DISPATCH_ONE);
return 1;
}
static int _cluster_send_message(const void *buf, int msglen, const char *csid,
const char *errtext)
{
struct iovec iov[2];
cs_error_t err;
int target_node;
if (csid)
memcpy(&target_node, csid, COROSYNC_CSID_LEN);
else
target_node = 0;
iov[0].iov_base = &target_node;
iov[0].iov_len = sizeof(int);
iov[1].iov_base = (char *)buf;
iov[1].iov_len = msglen;
err = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 2);
return cs_to_errno(err);
}
#ifdef HAVE_COROSYNC_CONFDB_H
/*
* We are not necessarily connected to a Red Hat Cluster system,
* but if we are, this returns the cluster name from cluster.conf.
* I've used confdb rather than ccs to reduce the inter-package
* dependancies as well as to allow people to set a cluster name
* for themselves even if they are not running on RH cluster.
*/
static int _get_cluster_name(char *buf, int buflen)
{
confdb_handle_t handle;
int result;
size_t namelen = buflen;
hdb_handle_t cluster_handle;
confdb_callbacks_t callbacks = {
.confdb_key_change_notify_fn = NULL,
.confdb_object_create_change_notify_fn = NULL,
.confdb_object_delete_change_notify_fn = NULL
};
/* This is a default in case everything else fails */
strncpy(buf, "Corosync", buflen);
/* Look for a cluster name in confdb */
result = confdb_initialize (&handle, &callbacks);
if (result != CS_OK)
return 0;
result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
if (result != CS_OK)
goto out;
result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, (void *)"cluster", strlen("cluster"), &cluster_handle);
if (result != CS_OK)
goto out;
result = confdb_key_get(handle, cluster_handle, (void *)"name", strlen("name"), buf, &namelen);
if (result != CS_OK)
goto out;
buf[namelen] = '\0';
out:
confdb_finalize(handle);
return 0;
}
#elif defined HAVE_COROSYNC_CMAP_H
static int _get_cluster_name(char *buf, int buflen)
{
cmap_handle_t cmap_handle = 0;
int result;
char *name = NULL;
/* This is a default in case everything else fails */
strncpy(buf, "Corosync", buflen);
/* Look for a cluster name in cmap */
result = cmap_initialize(&cmap_handle);
if (result != CS_OK)
return 0;
result = cmap_get_string(cmap_handle, "totem.cluster_name", &name);
if (result != CS_OK)
goto out;
memset(buf, 0, buflen);
strncpy(buf, name, buflen - 1);
out:
if (name)
free(name);
cmap_finalize(cmap_handle);
return 0;
}
#endif
static struct cluster_ops _cluster_corosync_ops = {
.name = "corosync",
.cluster_init_completed = NULL,
.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,
.reread_config = NULL,
.cluster_closedown = _cluster_closedown,
.get_cluster_name = _get_cluster_name,
.sync_lock = _lock_resource,
.sync_unlock = _unlock_resource,
};
struct cluster_ops *init_corosync_cluster(void)
{
if (!_init_cluster())
return &_cluster_corosync_ops;
else
return NULL;
}

908
daemons/clvmd/clvmd-gulm.c Normal file
View File

@@ -0,0 +1,908 @@
/******************************************************************************
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved.
**
*******************************************************************************
******************************************************************************/
/* This provides the interface between clvmd and gulm as the cluster
* and lock manager.
*
* It also provides the "liblm" functions too as it's hard (and pointless)
* to seperate them out when using gulm.
*
* What it does /not/ provide is the communications between clvmd daemons
* on the cluster nodes. That is done in tcp-comms.c
*/
#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/file.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <utmpx.h>
#include <syslog.h>
#include <assert.h>
#include "ccs.h"
#include "list.h"
#include "locking.h"
#include "log.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "clvmd.h"
#include "hash.h"
#include "clvmd-gulm.h"
#include "libgulm.h"
#include "hash.h"
/* Hash list of nodes in the cluster */
static struct hash_table *node_hash;
/* hash list of outstanding lock requests */
static struct hash_table *lock_hash;
/* Copy of the current core state */
static uint8_t current_corestate;
/* Number of active nodes */
static int num_nodes;
static char *cluster_name;
static pthread_mutex_t lock_start_mutex;
static volatile int lock_start_flag;
struct node_info
{
enum {NODE_UNKNOWN, NODE_DOWN, NODE_UP, NODE_CLVMD} state;
char name[MAX_CLUSTER_MEMBER_NAME_LEN];
};
struct lock_wait
{
pthread_cond_t cond;
pthread_mutex_t mutex;
int status;
};
/* Forward */
static int read_from_core_sock(struct local_client *client, char *buf, int len, char *csid,
struct local_client **new_client);
static int read_from_lock_sock(struct local_client *client, char *buf, int len, char *csid,
struct local_client **new_client);
static int get_all_cluster_nodes(void);
/* In tcp-comms.c */
extern struct hash_table *sock_hash;
static int add_internal_client(int fd, fd_callback_t callback)
{
struct local_client *client;
DEBUGLOG("Add_internal_client, fd = %d\n", fd);
/* Add a GULM file descriptor it to the main loop */
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_INTERNAL;
client->callback = callback;
add_client(client);
return 0;
}
/* Gulm library handle */
static gulm_interface_p gulm_if;
static lg_core_callbacks_t core_callbacks;
static lg_lockspace_callbacks_t lock_callbacks;
static void badsig_handler(int sig)
{
DEBUGLOG("got sig %d\n", sig);
cluster_closedown();
exit(0);
}
static void sighup_handler(int sig)
{
DEBUGLOG("got SIGHUP\n");
/* Re-read CCS node list */
get_all_cluster_nodes();
}
int init_cluster()
{
int status;
int ccs_h;
int port = 0;
char *portstr;
/* Get cluster name from CCS */
ccs_h = ccs_force_connect(NULL, 0);
if (ccs_h < 0)
{
syslog(LOG_ERR, "Cannot login in to CCSD server\n");
return -1;
}
ccs_get(ccs_h, "//cluster/@name", &cluster_name);
DEBUGLOG("got cluster name %s\n", cluster_name);
if (!ccs_get(ccs_h, "//cluster/clvm/@port", &portstr))
{
port = atoi(portstr);
free(portstr);
DEBUGLOG("got port number %d\n", port);
if (port <= 0 && port >= 65536)
port = 0;
}
ccs_disconnect(ccs_h);
/* Block locking until we are logged in */
pthread_mutex_init(&lock_start_mutex, NULL);
pthread_mutex_lock(&lock_start_mutex);
lock_start_flag = 1;
node_hash = hash_create(100);
lock_hash = hash_create(10);
/* Get all nodes from CCS */
if (get_all_cluster_nodes())
return -1;
/* Initialise GULM library */
status = lg_initialize(&gulm_if, cluster_name, "clvmd");
if (status)
{
DEBUGLOG("lg_initialize failed: %d\n", status);
return status;
}
/* Connect to core - we are not "important" :-) */
status = lg_core_login(gulm_if, 0);
if (status)
{
DEBUGLOG("lg_core_login failed: %d\n", status);
return status;
}
/* Initialise the inter-node comms */
status = init_comms(port);
if (status)
return status;
/* Add core FD to the list */
status = add_internal_client(lg_core_selector(gulm_if), read_from_core_sock);
if (status)
{
DEBUGLOG("can't allocate client space\n");
return status;
}
/* Connect to the lock server */
if (lg_lock_login(gulm_if, "CLVM"))
{
syslog(LOG_ERR, "Cannot login in to LOCK server\n");
DEBUGLOG("Cannot login in to LOCK server\n");
exit(88);
}
/* Add lockspace FD to the list */
status = add_internal_client(lg_lock_selector(gulm_if), read_from_lock_sock);
if (status)
{
DEBUGLOG("can't allocate client space\n");
exit(status);
}
/* Request a list of nodes, we can;t really do anything until
this comes back */
status = lg_core_nodelist(gulm_if);
if (status)
{
DEBUGLOG("lg_core_nodelist failed: %d\n", status);
return status;
}
/* So I can kill it without taking GULM down too */
signal(SIGINT, badsig_handler);
signal(SIGTERM, badsig_handler);
/* Re-read the node list on SIGHUP */
signal(SIGHUP, sighup_handler);
return 0;
}
void cluster_closedown()
{
DEBUGLOG("cluster_closedown\n");
lg_lock_logout(gulm_if);
lg_core_logout(gulm_if);
lg_release(gulm_if);
}
/* Expire locks for a named node, or us */
#define GIO_KEY_SIZE 46
static void drop_expired_locks(char *nodename)
{
struct utsname nodeinfo;
uint8_t mask[GIO_KEY_SIZE];
memset(mask, 0xff, GIO_KEY_SIZE);
if (!nodename)
{
uname(&nodeinfo);
nodename = nodeinfo.nodename;
}
if (lg_lock_drop_exp(gulm_if, nodename, mask, GIO_KEY_SIZE))
{
DEBUGLOG("Error calling lg_lock_drop_exp()\n");
}
}
static int read_from_core_sock(struct local_client *client, char *buf, int len, char *csid,
struct local_client **new_client)
{
int status;
*new_client = NULL;
status = lg_core_handle_messages(gulm_if, &core_callbacks, NULL);
return status<0 ? status : 1;
}
static int read_from_lock_sock(struct local_client *client, char *buf, int len, char *csid,
struct local_client **new_client)
{
int status;
*new_client = NULL;
status = lg_lock_handle_messages(gulm_if, &lock_callbacks, NULL);
return status<0 ? status : 1;
}
/* CORE callback routines */
static int core_login_reply(void *misc, uint64_t gen, uint32_t error, uint32_t rank, uint8_t corestate)
{
DEBUGLOG("CORE Got a Login reply. gen:%lld err:%d rank:%d corestate:%d\n",
gen, error, rank, corestate);
if (error)
exit(error);
current_corestate = corestate;
return 0;
}
static void set_node_state(struct node_info *ninfo, char *csid, uint8_t nodestate)
{
if (nodestate == lg_core_Logged_in)
{
/* Don't clobber NODE_CLVMD state */
if (ninfo->state != NODE_CLVMD)
{
if (ninfo->state == NODE_UNKNOWN ||
ninfo->state == NODE_DOWN)
num_nodes++;
ninfo->state = NODE_UP;
}
}
else
{
if (nodestate == lg_core_Expired ||
nodestate == lg_core_Fenced ||
nodestate == lg_core_Logged_out)
{
if (ninfo->state != NODE_DOWN)
num_nodes--;
ninfo->state = NODE_DOWN;
tcp_remove_client(csid);
}
}
DEBUGLOG("set_node_state, '%s' state = %d, num_nodes=%d\n",
ninfo->name, ninfo->state, num_nodes);
}
static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_t state)
{
struct node_info *ninfo;
ninfo = hash_lookup_binary(node_hash, (char *)ip, MAX_CSID_LEN);
if (!ninfo)
{
/* If we can't find that node then re-read the config file in case it
was added after we were started */
DEBUGLOG("Node %s not found, re-reading config file\n", name);
get_all_cluster_nodes();
/* Now try again */
ninfo = hash_lookup_binary(node_hash, (char *)ip, MAX_CSID_LEN);
if (!ninfo)
{
DEBUGLOG("Ignoring node %s, not part of the SAN cluster\n", name);
return NULL;
}
}
set_node_state(ninfo, (char *)&ip, state);
return ninfo;
}
static int core_nodelist(void *misc, lglcb_t type, char *name, struct in6_addr *ip, uint8_t state)
{
DEBUGLOG("CORE nodelist\n");
if (type == lglcb_start)
{
DEBUGLOG("Got Nodelist, start\n");
}
else
{
if (type == lglcb_item)
{
DEBUGLOG("Got nodelist, item: %s, %#x\n", name, state);
add_or_set_node(name, ip, state);
}
else
{
if (type == lglcb_stop)
{
char ourcsid[MAX_CSID_LEN];
DEBUGLOG("Got Nodelist, stop\n");
clvmd_cluster_init_completed();
/* Mark ourself as up */
get_our_csid(ourcsid);
add_up_node(ourcsid);
}
else
{
DEBUGLOG("Unknown lglcb_t %#x\n", type);
}
}
}
return 0;
}
static int core_statechange(void *misc, uint8_t corestate, uint8_t quorate, struct in6_addr *masterip, char *mastername)
{
DEBUGLOG("CORE Got statechange corestate:%#x mastername:%s\n",
corestate, mastername);
current_corestate = corestate;
return 0;
}
static int core_nodechange(void *misc, char *nodename, struct in6_addr *nodeip, uint8_t nodestate)
{
struct node_info *ninfo;
DEBUGLOG("CORE node change, name=%s, state = %d\n", nodename, nodestate);
/* If we don't get nodeip here, try a lookup by name */
if (!nodeip)
csid_from_name((char *)nodeip, nodename);
if (!nodeip)
return 0;
ninfo = add_or_set_node(nodename, nodeip, nodestate);
if (!ninfo)
return 0;
/* Check if we need to drop any expired locks */
if (ninfo->state == NODE_DOWN)
{
drop_expired_locks(nodename);
}
return 0;
}
static int core_error(void *misc, uint32_t err)
{
DEBUGLOG("CORE error: %d\n", err);
// Not sure what happens here
return 0;
}
/* LOCK callback routines */
static int lock_login_reply(void *misc, uint32_t error, uint8_t which)
{
DEBUGLOG("LOCK Got a Login reply. err:%d which:%d\n",
error, which);
if (error)
exit(error);
/* Drop any expired locks for us that might be hanging around */
drop_expired_locks(NULL);
/* Enable locking operations in other threads */
if (lock_start_flag)
{
lock_start_flag = 0;
pthread_mutex_unlock(&lock_start_mutex);
}
return 0;
}
static int lock_lock_state(void *misc, uint8_t *key, uint16_t keylen,
uint64_t subid, uint64_t start, uint64_t stop,
uint8_t state, uint32_t flags, uint32_t error,
uint8_t *LVB, uint16_t LVBlen)
{
struct lock_wait *lwait;
DEBUGLOG("LOCK lock state: %s, error = %d\n", key, error);
lwait = hash_lookup(lock_hash, key);
if (!lwait)
{
DEBUGLOG("Can't find hash entry for resource %s\n", key);
return 0;
}
lwait->status = error;
pthread_mutex_lock(&lwait->mutex);
pthread_cond_signal(&lwait->cond);
pthread_mutex_unlock(&lwait->mutex);
return 0;
}
static int lock_error(void *misc, uint32_t err)
{
DEBUGLOG("LOCK error: %d\n", err);
// Not sure what happens here
return 0;
}
/* CORE callbacks */
static lg_core_callbacks_t core_callbacks = {
.login_reply = core_login_reply,
.nodelist = core_nodelist,
.statechange = core_statechange,
.nodechange = core_nodechange,
.error = core_error,
};
/* LOCK callbacks */
static lg_lockspace_callbacks_t lock_callbacks = {
.login_reply = lock_login_reply,
.lock_state = lock_lock_state,
.error = lock_error,
};
/* Allow tcp-comms to loop round the list of active nodes */
int get_next_node_csid(void **context, char *csid)
{
struct node_info *ninfo = NULL;
/* First node */
if (!*context)
{
*context = hash_get_first(node_hash);
}
else
{
*context = hash_get_next(node_hash, *context);
}
if (*context)
ninfo = hash_get_data(node_hash, *context);
/* Find a node that is UP */
while (*context && ninfo->state == NODE_DOWN)
{
*context = hash_get_next(node_hash, *context);
if (*context)
{
ninfo = hash_get_data(node_hash, *context);
}
}
if (!*context || ninfo->state == NODE_DOWN)
{
return 0;
}
memcpy(csid, hash_get_key(node_hash, *context), MAX_CSID_LEN);
return 1;
}
int name_from_csid(char *csid, char *name)
{
struct node_info *ninfo;
ninfo = hash_lookup_binary(node_hash, csid, MAX_CSID_LEN);
if (!ninfo)
{
sprintf(name, "UNKNOWN %s", print_csid(csid));
return -1;
}
strcpy(name, ninfo->name);
return 0;
}
int csid_from_name(char *csid, char *name)
{
struct hash_node *hn;
struct node_info *ninfo;
hash_iterate(hn, node_hash)
{
ninfo = hash_get_data(node_hash, hn);
if (strcmp(ninfo->name, name) == 0)
{
memcpy(csid, hash_get_key(node_hash, hn), MAX_CSID_LEN);
return 0;
}
}
return -1;
}
int get_num_nodes()
{
DEBUGLOG("num_nodes = %d\n", num_nodes);
return num_nodes;
}
/* Node is now known to be running a clvmd */
void add_up_node(char *csid)
{
struct node_info *ninfo;
ninfo = hash_lookup_binary(node_hash, csid, MAX_CSID_LEN);
if (!ninfo)
return;
ninfo->state = NODE_CLVMD;
return;
}
/* Node is now known to be NOT running a clvmd */
void add_down_node(char *csid)
{
struct node_info *ninfo;
ninfo = hash_lookup_binary(node_hash, csid, MAX_CSID_LEN);
if (!ninfo)
return;
/* Only set it to UP if it was previously known to be
running clvmd - gulm may set it DOWN quite soon */
if (ninfo->state == NODE_CLVMD)
ninfo->state = NODE_UP;
return;
}
/* Call a callback for each node, so the caller knows whether it's up or down */
int cluster_do_node_callback(struct local_client *master_client,
void (*callback)(struct local_client *, char *csid, int node_up))
{
struct hash_node *hn;
struct node_info *ninfo;
hash_iterate(hn, node_hash)
{
char csid[MAX_CSID_LEN];
struct local_client *client;
ninfo = hash_get_data(node_hash, hn);
memcpy(csid, hash_get_key(node_hash, hn), MAX_CSID_LEN);
DEBUGLOG("down_callback. node %s, state = %d\n", ninfo->name, ninfo->state);
client = hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN);
if (client)
callback(master_client, csid, ninfo->state == NODE_CLVMD);
}
return 0;
}
/* Convert gulm error codes to unix errno numbers */
static int gulm_to_errno(int gulm_ret)
{
switch (gulm_ret)
{
case lg_err_TryFailed:
errno = EAGAIN;
break;
case lg_err_AlreadyPend:
errno = EBUSY;
/* More?? */
default:
errno = EINVAL;
}
return gulm_ret ? -1 : 0;
}
/* Real locking */
static int _lock_resource(char *resource, int mode, int flags, int *lockid)
{
int status;
struct lock_wait lwait;
/* Wait until the lock module is ready */
if (lock_start_flag)
{
pthread_mutex_lock(&lock_start_mutex);
pthread_mutex_unlock(&lock_start_mutex);
}
pthread_cond_init(&lwait.cond, NULL);
pthread_mutex_init(&lwait.mutex, NULL);
pthread_mutex_lock(&lwait.mutex);
/* This needs to be converted from DLM/LVM2 value for GULM */
if (flags == LCK_NONBLOCK) flags = lg_lock_flag_Try;
hash_insert(lock_hash, resource, &lwait);
DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
status = lg_lock_state_req(gulm_if, resource, strlen(resource)+1,
0, 0, 0,
mode, flags, NULL, 0);
if (status)
{
DEBUGLOG("lg_lock_state returned %d\n", status);
return status;
}
/* Wait for it to complete */
pthread_cond_wait(&lwait.cond, &lwait.mutex);
pthread_mutex_unlock(&lwait.mutex);
hash_remove(lock_hash, resource);
DEBUGLOG("lock-resource returning %d\n", lwait.status);
return gulm_to_errno(lwait.status);
}
static int _unlock_resource(char *resource, int lockid)
{
int status;
struct lock_wait lwait;
pthread_cond_init(&lwait.cond, NULL);
pthread_mutex_init(&lwait.mutex, NULL);
pthread_mutex_lock(&lwait.mutex);
hash_insert(lock_hash, resource, &lwait);
DEBUGLOG("unlock_resource %s\n", resource);
status = lg_lock_state_req(gulm_if, resource, strlen(resource)+1,
0, 0, 0,
lg_lock_state_Unlock, 0, NULL, 0);
if (status)
{
DEBUGLOG("lg_lock_state(unlock) returned %d\n", status);
return status;
}
/* Wait for it to complete */
pthread_cond_wait(&lwait.cond, &lwait.mutex);
pthread_mutex_unlock(&lwait.mutex);
hash_remove(lock_hash, resource);
return gulm_to_errno(lwait.status);
}
/* These two locking functions MUST be called in a seperate thread from
the clvmd main loop because they expect to be woken up by it.
These are abstractions around the real locking functions (above)
as we need to emulate the DLM's EX/PW/CW interaction with GULM using
two locks.
To aid unlocking, we store the lock mode in the lockid (as GULM
doesn't use this).
*/
int sync_lock(const char *resource, int mode, int flags, int *lockid)
{
int status;
char lock1[strlen(resource)+3];
char lock2[strlen(resource)+3];
snprintf(lock1, sizeof(lock1), "%s-1", resource);
snprintf(lock2, sizeof(lock2), "%s-2", resource);
switch (mode)
{
case LCK_EXCL:
status = _lock_resource(lock1, lg_lock_state_Exclusive, flags, lockid);
if (status)
goto out;
/* If we can't get this lock then bail out */
status = _lock_resource(lock2, lg_lock_state_Exclusive, LCK_NONBLOCK, lockid);
if (status == lg_err_TryFailed)
{
_unlock_resource(lock1, *lockid);
status = -1;
errno = EAGAIN;
}
break;
case LCK_READ:
status = _lock_resource(lock1, lg_lock_state_Shared, flags, lockid);
break;
case LCK_WRITE:
status = _lock_resource(lock2, lg_lock_state_Exclusive, flags, lockid);
break;
default:
status = -1;
errno = EINVAL;
break;
}
out:
*lockid = mode;
return status;
}
int sync_unlock(const char *resource, int lockid)
{
int status = 0;
char lock1[strlen(resource)+3];
char lock2[strlen(resource)+3];
snprintf(lock1, sizeof(lock1), "%s-1", resource);
snprintf(lock2, sizeof(lock2), "%s-2", resource);
/* The held lock mode is in the lock id */
assert(lockid == LCK_EXCL ||
lockid == LCK_READ ||
lockid == LCK_WRITE);
switch (lockid)
{
case LCK_EXCL:
status = _unlock_resource(lock1, lockid);
if (status)
goto out;
status = _unlock_resource(lock2, lockid);
break;
case LCK_READ:
status = _unlock_resource(lock1, lockid);
break;
case LCK_WRITE:
status = _unlock_resource(lock2, lockid);
break;
}
out:
return status;
}
int is_quorate()
{
if (current_corestate == lg_core_Slave ||
current_corestate == lg_core_Master ||
current_corestate == lg_core_Client)
return 1;
else
return 0;
}
/* Get all the cluster node names & IPs from CCS and
add them to our node list so we know who to talk to.
Called when we start up and if we get sent SIGHUP.
*/
static int get_all_cluster_nodes()
{
int ctree;
char *nodename;
int error;
int i;
/* Open the config file */
ctree = ccs_force_connect(NULL, 1);
if (ctree < 0)
{
log_error("Error connecting to CCS");
return -1;
}
for (i=1;;i++)
{
char nodekey[256];
char nodeip[MAX_CSID_LEN];
int clvmflag = 1;
char *clvmflagstr;
char key[256];
sprintf(nodekey, "//cluster/clusternodes/clusternode[%d]/@name", i);
error = ccs_get(ctree, nodekey, &nodename);
if (error)
break;
sprintf(key, "//cluster/clusternodes/clusternode[@name=\"%s\"]/clvm", nodename);
if (!ccs_get(ctree, key, &clvmflagstr))
{
clvmflag = atoi(clvmflagstr);
free(clvmflagstr);
}
DEBUGLOG("Got node %s from ccs(clvmflag = %d)\n", nodename, clvmflag);
if ((get_ip_address(nodename, nodeip) == 0) && clvmflag)
{
struct node_info *ninfo;
/* If it's not in the list, then add it */
ninfo = hash_lookup_binary(node_hash, nodeip, MAX_CSID_LEN);
if (!ninfo)
{
ninfo = malloc(sizeof(struct node_info));
if (!ninfo)
{
syslog(LOG_ERR, "Cannot alloc memory for node info\n");
ccs_disconnect(ctree);
return -1;
}
strcpy(ninfo->name, nodename);
ninfo->state = NODE_DOWN;
hash_insert_binary(node_hash, nodeip, MAX_CSID_LEN, ninfo);
}
}
else
{
DEBUGLOG("node %s has clvm disabled\n", nodename);
}
free(nodename);
}
/* Finished with config file */
ccs_disconnect(ctree);
return 0;
}

View File

@@ -0,0 +1,9 @@
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);

View File

@@ -1,689 +0,0 @@
/*
* Copyright (C) 2007-2009 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
*/
/*
* This provides the interface between clvmd and OpenAIS as the cluster
* and lock manager.
*/
#include "clvmd-common.h"
#include <pthread.h>
#include <fcntl.h>
#include <syslog.h>
#include <openais/saAis.h>
#include <openais/saLck.h>
#include <corosync/corotypes.h>
#include <corosync/cpg.h>
#include "locking.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "lvm-functions.h"
#include "clvmd.h"
/* Timeout value for several openais calls */
#define TIMEOUT 10
static void openais_cpg_deliver_callback (cpg_handle_t handle,
const struct cpg_name *groupName,
uint32_t nodeid,
uint32_t pid,
void *msg,
size_t msg_len);
static void openais_cpg_confchg_callback(cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list, size_t member_list_entries,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries);
static void _cluster_closedown(void);
/* Hash list of nodes in the cluster */
static struct dm_hash_table *node_hash;
/* For associating lock IDs & resource handles */
static struct dm_hash_table *lock_hash;
/* Number of active nodes */
static int num_nodes;
static unsigned int our_nodeid;
static struct local_client *cluster_client;
/* OpenAIS handles */
static cpg_handle_t cpg_handle;
static SaLckHandleT lck_handle;
static struct cpg_name cpg_group_name;
/* Openais callback structs */
cpg_callbacks_t openais_cpg_callbacks = {
.cpg_deliver_fn = openais_cpg_deliver_callback,
.cpg_confchg_fn = openais_cpg_confchg_callback,
};
struct node_info
{
enum {NODE_UNKNOWN, NODE_DOWN, NODE_UP, NODE_CLVMD} state;
int nodeid;
};
struct lock_info
{
SaLckResourceHandleT res_handle;
SaLckLockIdT lock_id;
SaNameT lock_name;
};
/* Set errno to something approximating the right value and return 0 or -1 */
static int ais_to_errno(SaAisErrorT err)
{
switch(err)
{
case SA_AIS_OK:
return 0;
case SA_AIS_ERR_LIBRARY:
errno = EINVAL;
break;
case SA_AIS_ERR_VERSION:
errno = EINVAL;
break;
case SA_AIS_ERR_INIT:
errno = EINVAL;
break;
case SA_AIS_ERR_TIMEOUT:
errno = ETIME;
break;
case SA_AIS_ERR_TRY_AGAIN:
errno = EAGAIN;
break;
case SA_AIS_ERR_INVALID_PARAM:
errno = EINVAL;
break;
case SA_AIS_ERR_NO_MEMORY:
errno = ENOMEM;
break;
case SA_AIS_ERR_BAD_HANDLE:
errno = EINVAL;
break;
case SA_AIS_ERR_BUSY:
errno = EBUSY;
break;
case SA_AIS_ERR_ACCESS:
errno = EPERM;
break;
case SA_AIS_ERR_NOT_EXIST:
errno = ENOENT;
break;
case SA_AIS_ERR_NAME_TOO_LONG:
errno = ENAMETOOLONG;
break;
case SA_AIS_ERR_EXIST:
errno = EEXIST;
break;
case SA_AIS_ERR_NO_SPACE:
errno = ENOSPC;
break;
case SA_AIS_ERR_INTERRUPT:
errno = EINTR;
break;
case SA_AIS_ERR_NAME_NOT_FOUND:
errno = ENOENT;
break;
case SA_AIS_ERR_NO_RESOURCES:
errno = ENOMEM;
break;
case SA_AIS_ERR_NOT_SUPPORTED:
errno = EOPNOTSUPP;
break;
case SA_AIS_ERR_BAD_OPERATION:
errno = EINVAL;
break;
case SA_AIS_ERR_FAILED_OPERATION:
errno = EIO;
break;
case SA_AIS_ERR_MESSAGE_ERROR:
errno = EIO;
break;
case SA_AIS_ERR_QUEUE_FULL:
errno = EXFULL;
break;
case SA_AIS_ERR_QUEUE_NOT_AVAILABLE:
errno = EINVAL;
break;
case SA_AIS_ERR_BAD_FLAGS:
errno = EINVAL;
break;
case SA_AIS_ERR_TOO_BIG:
errno = E2BIG;
break;
case SA_AIS_ERR_NO_SECTIONS:
errno = ENOMEM;
break;
default:
errno = EINVAL;
break;
}
return -1;
}
static char *print_openais_csid(const char *csid)
{
static char buf[128];
int id;
memcpy(&id, csid, sizeof(int));
sprintf(buf, "%d", id);
return buf;
}
static int add_internal_client(int fd, fd_callback_t callback)
{
struct local_client *client;
DEBUGLOG("Add_internal_client, fd = %d\n", fd);
if (!(client = dm_zalloc(sizeof(*client)))) {
DEBUGLOG("malloc failed\n");
return -1;
}
client->fd = fd;
client->type = CLUSTER_INTERNAL;
client->callback = callback;
add_client(client);
/* Set Close-on-exec */
fcntl(fd, F_SETFD, 1);
return 0;
}
static void openais_cpg_deliver_callback (cpg_handle_t handle,
const struct cpg_name *groupName,
uint32_t nodeid,
uint32_t pid,
void *msg,
size_t msg_len)
{
int target_nodeid;
memcpy(&target_nodeid, msg, OPENAIS_CSID_LEN);
DEBUGLOG("%u got message from nodeid %d for %d. len %" PRIsize_t "\n",
our_nodeid, nodeid, target_nodeid, msg_len-4);
if (nodeid != our_nodeid)
if (target_nodeid == our_nodeid || target_nodeid == 0)
process_message(cluster_client, (char *)msg+OPENAIS_CSID_LEN,
msg_len-OPENAIS_CSID_LEN, (char*)&nodeid);
}
static void openais_cpg_confchg_callback(cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list, size_t member_list_entries,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries)
{
int i;
struct node_info *ninfo;
DEBUGLOG("confchg callback. %" PRIsize_t " joined, "
"%" PRIsize_t " left, %" PRIsize_t " members\n",
joined_list_entries, left_list_entries, member_list_entries);
for (i=0; i<joined_list_entries; i++) {
ninfo = dm_hash_lookup_binary(node_hash,
(char *)&joined_list[i].nodeid,
OPENAIS_CSID_LEN);
if (!ninfo) {
ninfo = malloc(sizeof(struct node_info));
if (!ninfo) {
break;
}
else {
ninfo->nodeid = joined_list[i].nodeid;
dm_hash_insert_binary(node_hash,
(char *)&ninfo->nodeid,
OPENAIS_CSID_LEN, ninfo);
}
}
ninfo->state = NODE_CLVMD;
}
for (i=0; i<left_list_entries; i++) {
ninfo = dm_hash_lookup_binary(node_hash,
(char *)&left_list[i].nodeid,
OPENAIS_CSID_LEN);
if (ninfo)
ninfo->state = NODE_DOWN;
}
for (i=0; i<member_list_entries; i++) {
if (member_list[i].nodeid == 0) continue;
ninfo = dm_hash_lookup_binary(node_hash,
(char *)&member_list[i].nodeid,
OPENAIS_CSID_LEN);
if (!ninfo) {
ninfo = malloc(sizeof(struct node_info));
if (!ninfo) {
break;
}
else {
ninfo->nodeid = member_list[i].nodeid;
dm_hash_insert_binary(node_hash,
(char *)&ninfo->nodeid,
OPENAIS_CSID_LEN, ninfo);
}
}
ninfo->state = NODE_CLVMD;
}
num_nodes = member_list_entries;
}
static int lck_dispatch(struct local_client *client, char *buf, int len,
const char *csid, struct local_client **new_client)
{
*new_client = NULL;
saLckDispatch(lck_handle, SA_DISPATCH_ONE);
return 1;
}
static int _init_cluster(void)
{
SaAisErrorT err;
SaVersionT ver = { 'B', 1, 1 };
int select_fd;
node_hash = dm_hash_create(100);
lock_hash = dm_hash_create(10);
err = cpg_initialize(&cpg_handle,
&openais_cpg_callbacks);
if (err != SA_AIS_OK) {
syslog(LOG_ERR, "Cannot initialise OpenAIS CPG service: %d",
err);
DEBUGLOG("Cannot initialise OpenAIS CPG service: %d", err);
return ais_to_errno(err);
}
err = saLckInitialize(&lck_handle,
NULL,
&ver);
if (err != SA_AIS_OK) {
cpg_initialize(&cpg_handle, &openais_cpg_callbacks);
syslog(LOG_ERR, "Cannot initialise OpenAIS lock service: %d",
err);
DEBUGLOG("Cannot initialise OpenAIS lock service: %d\n\n", err);
return ais_to_errno(err);
}
/* Connect to the clvmd group */
strcpy((char *)cpg_group_name.value, "clvmd");
cpg_group_name.length = strlen((char *)cpg_group_name.value);
err = cpg_join(cpg_handle, &cpg_group_name);
if (err != SA_AIS_OK) {
cpg_finalize(cpg_handle);
saLckFinalize(lck_handle);
syslog(LOG_ERR, "Cannot join clvmd process group");
DEBUGLOG("Cannot join clvmd process group: %d\n", err);
return ais_to_errno(err);
}
err = cpg_local_get(cpg_handle,
&our_nodeid);
if (err != SA_AIS_OK) {
cpg_finalize(cpg_handle);
saLckFinalize(lck_handle);
syslog(LOG_ERR, "Cannot get local node id\n");
return ais_to_errno(err);
}
DEBUGLOG("Our local node id is %d\n", our_nodeid);
saLckSelectionObjectGet(lck_handle, (SaSelectionObjectT *)&select_fd);
add_internal_client(select_fd, lck_dispatch);
DEBUGLOG("Connected to OpenAIS\n");
return 0;
}
static void _cluster_closedown(void)
{
saLckFinalize(lck_handle);
cpg_finalize(cpg_handle);
}
static void _get_our_csid(char *csid)
{
memcpy(csid, &our_nodeid, sizeof(int));
}
/* OpenAIS doesn't really have nmode names so we
just use the node ID in hex instead */
static int _csid_from_name(char *csid, const char *name)
{
int nodeid;
struct node_info *ninfo;
if (sscanf(name, "%x", &nodeid) == 1) {
ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
if (ninfo)
return nodeid;
}
return -1;
}
static int _name_from_csid(const char *csid, char *name)
{
struct node_info *ninfo;
ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
if (!ninfo)
{
sprintf(name, "UNKNOWN %s", print_openais_csid(csid));
return -1;
}
sprintf(name, "%x", ninfo->nodeid);
return 0;
}
static int _get_num_nodes()
{
DEBUGLOG("num_nodes = %d\n", num_nodes);
return num_nodes;
}
/* Node is now known to be running a clvmd */
static void _add_up_node(const char *csid)
{
struct node_info *ninfo;
ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
if (!ninfo) {
DEBUGLOG("openais_add_up_node no node_hash entry for csid %s\n",
print_openais_csid(csid));
return;
}
DEBUGLOG("openais_add_up_node %d\n", ninfo->nodeid);
ninfo->state = NODE_CLVMD;
return;
}
/* Call a callback for each node, so the caller knows whether it's up or down */
static int _cluster_do_node_callback(struct local_client *master_client,
void (*callback)(struct local_client *,
const char *csid, int node_up))
{
struct dm_hash_node *hn;
struct node_info *ninfo;
int somedown = 0;
dm_hash_iterate(hn, node_hash)
{
char csid[OPENAIS_CSID_LEN];
ninfo = dm_hash_get_data(node_hash, hn);
memcpy(csid, dm_hash_get_key(node_hash, hn), OPENAIS_CSID_LEN);
DEBUGLOG("down_callback. node %d, state = %d\n", ninfo->nodeid,
ninfo->state);
if (ninfo->state != NODE_DOWN)
callback(master_client, csid, ninfo->state == NODE_CLVMD);
if (ninfo->state != NODE_CLVMD)
somedown = -1;
}
return somedown;
}
/* Real locking */
static int _lock_resource(char *resource, int mode, int flags, int *lockid)
{
struct lock_info *linfo;
SaLckResourceHandleT res_handle;
SaAisErrorT err;
SaLckLockIdT lock_id;
SaLckLockStatusT lockStatus;
/* This needs to be converted from DLM/LVM2 value for OpenAIS LCK */
if (flags & LCK_NONBLOCK) flags = SA_LCK_LOCK_NO_QUEUE;
linfo = malloc(sizeof(struct lock_info));
if (!linfo)
return -1;
DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
linfo->lock_name.length = strlen(resource)+1;
strcpy((char *)linfo->lock_name.value, resource);
err = saLckResourceOpen(lck_handle, &linfo->lock_name,
SA_LCK_RESOURCE_CREATE, TIMEOUT, &res_handle);
if (err != SA_AIS_OK)
{
DEBUGLOG("ResourceOpen returned %d\n", err);
free(linfo);
return ais_to_errno(err);
}
err = saLckResourceLock(
res_handle,
&lock_id,
mode,
flags,
0,
SA_TIME_END,
&lockStatus);
if (err != SA_AIS_OK && lockStatus != SA_LCK_LOCK_GRANTED)
{
free(linfo);
saLckResourceClose(res_handle);
return ais_to_errno(err);
}
/* Wait for it to complete */
DEBUGLOG("lock_resource returning %d, lock_id=%" PRIx64 "\n",
err, lock_id);
linfo->lock_id = lock_id;
linfo->res_handle = res_handle;
dm_hash_insert(lock_hash, resource, linfo);
return ais_to_errno(err);
}
static int _unlock_resource(char *resource, int lockid)
{
SaAisErrorT err;
struct lock_info *linfo;
DEBUGLOG("unlock_resource %s\n", resource);
linfo = dm_hash_lookup(lock_hash, resource);
if (!linfo)
return 0;
DEBUGLOG("unlock_resource: lockid: %" PRIx64 "\n", linfo->lock_id);
err = saLckResourceUnlock(linfo->lock_id, SA_TIME_END);
if (err != SA_AIS_OK)
{
DEBUGLOG("Unlock returned %d\n", err);
return ais_to_errno(err);
}
/* Release the resource */
dm_hash_remove(lock_hash, resource);
saLckResourceClose(linfo->res_handle);
free(linfo);
return ais_to_errno(err);
}
static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
{
int status;
char lock1[strlen(resource)+3];
char lock2[strlen(resource)+3];
snprintf(lock1, sizeof(lock1), "%s-1", resource);
snprintf(lock2, sizeof(lock2), "%s-2", resource);
switch (mode)
{
case LCK_EXCL:
status = _lock_resource(lock1, SA_LCK_EX_LOCK_MODE, flags, lockid);
if (status)
goto out;
/* If we can't get this lock too then bail out */
status = _lock_resource(lock2, SA_LCK_EX_LOCK_MODE, LCK_NONBLOCK,
lockid);
if (status == SA_LCK_LOCK_NOT_QUEUED)
{
_unlock_resource(lock1, *lockid);
status = -1;
errno = EAGAIN;
}
break;
case LCK_PREAD:
case LCK_READ:
status = _lock_resource(lock1, SA_LCK_PR_LOCK_MODE, flags, lockid);
if (status)
goto out;
_unlock_resource(lock2, *lockid);
break;
case LCK_WRITE:
status = _lock_resource(lock2, SA_LCK_EX_LOCK_MODE, flags, lockid);
if (status)
goto out;
_unlock_resource(lock1, *lockid);
break;
default:
status = -1;
errno = EINVAL;
break;
}
out:
*lockid = mode;
return status;
}
static int _sync_unlock(const char *resource, int lockid)
{
int status = 0;
char lock1[strlen(resource)+3];
char lock2[strlen(resource)+3];
snprintf(lock1, sizeof(lock1), "%s-1", resource);
snprintf(lock2, sizeof(lock2), "%s-2", resource);
_unlock_resource(lock1, lockid);
_unlock_resource(lock2, lockid);
return status;
}
/* We are always quorate ! */
static int _is_quorate()
{
return 1;
}
static int _get_main_cluster_fd(void)
{
int select_fd;
cpg_fd_get(cpg_handle, &select_fd);
return select_fd;
}
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
const char *csid,
struct local_client **new_client)
{
cluster_client = fd;
*new_client = NULL;
cpg_dispatch(cpg_handle, SA_DISPATCH_ONE);
return 1;
}
static int _cluster_send_message(const void *buf, int msglen, const char *csid,
const char *errtext)
{
struct iovec iov[2];
SaAisErrorT err;
int target_node;
if (csid)
memcpy(&target_node, csid, OPENAIS_CSID_LEN);
else
target_node = 0;
iov[0].iov_base = &target_node;
iov[0].iov_len = sizeof(int);
iov[1].iov_base = (char *)buf;
iov[1].iov_len = msglen;
err = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 2);
return ais_to_errno(err);
}
/* We don't have a cluster name to report here */
static int _get_cluster_name(char *buf, int buflen)
{
strncpy(buf, "OpenAIS", buflen);
return 0;
}
static struct cluster_ops _cluster_openais_ops = {
.name = "openais",
.cluster_init_completed = NULL,
.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,
.reread_config = NULL,
.cluster_closedown = _cluster_closedown,
.get_cluster_name = _get_cluster_name,
.sync_lock = _sync_lock,
.sync_unlock = _sync_unlock,
};
struct cluster_ops *init_openais_cluster(void)
{
if (!_init_cluster())
return &_cluster_openais_ops;
return NULL;
}

View File

@@ -1,382 +0,0 @@
/*
* Copyright (C) 2009-2013 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 "clvmd-common.h"
#include <pthread.h>
#include "locking.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "clvmd.h"
#include <sys/un.h>
#include <sys/socket.h>
#include <fcntl.h>
static const char SINGLENODE_CLVMD_SOCKNAME[] = DEFAULT_RUN_DIR "/clvmd_singlenode.sock";
static int listen_fd = -1;
static struct dm_hash_table *_locks;
static int _lockid;
static pthread_mutex_t _lock_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Using one common condition for all locks for simplicity */
static pthread_cond_t _lock_cond = PTHREAD_COND_INITIALIZER;
struct lock {
struct dm_list list;
int lockid;
int mode;
};
static void close_comms(void)
{
if (listen_fd != -1 && close(listen_fd))
stack;
(void)unlink(SINGLENODE_CLVMD_SOCKNAME);
listen_fd = -1;
}
static int init_comms(void)
{
mode_t old_mask;
struct sockaddr_un addr = { .sun_family = AF_UNIX };
if (!dm_strncpy(addr.sun_path, SINGLENODE_CLVMD_SOCKNAME,
sizeof(addr.sun_path))) {
DEBUGLOG("%s: singlenode socket name too long.",
SINGLENODE_CLVMD_SOCKNAME);
return -1;
}
close_comms();
(void) dm_prepare_selinux_context(SINGLENODE_CLVMD_SOCKNAME, S_IFSOCK);
old_mask = umask(0077);
listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (listen_fd < 0) {
DEBUGLOG("Can't create local socket: %s\n", strerror(errno));
goto error;
}
/* Set Close-on-exec */
if (fcntl(listen_fd, F_SETFD, 1)) {
DEBUGLOG("Setting CLOEXEC on client fd failed: %s\n", strerror(errno));
goto error;
}
if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
DEBUGLOG("Can't bind local socket: %s\n", strerror(errno));
goto error;
}
if (listen(listen_fd, 10) < 0) {
DEBUGLOG("Can't listen local socket: %s\n", strerror(errno));
goto error;
}
umask(old_mask);
(void) dm_prepare_selinux_context(NULL, 0);
return 0;
error:
umask(old_mask);
(void) dm_prepare_selinux_context(NULL, 0);
close_comms();
return -1;
}
static int _init_cluster(void)
{
int r;
if (!(_locks = dm_hash_create(128))) {
DEBUGLOG("Failed to allocate single-node hash table.\n");
return 1;
}
r = init_comms();
if (r) {
dm_hash_destroy(_locks);
_locks = NULL;
return r;
}
DEBUGLOG("Single-node cluster initialised.\n");
return 0;
}
static void _cluster_closedown(void)
{
close_comms();
/* If there is any awaited resource, kill it softly */
pthread_mutex_lock(&_lock_mutex);
dm_hash_destroy(_locks);
_locks = NULL;
_lockid = 0;
pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */
pthread_mutex_unlock(&_lock_mutex);
}
static void _get_our_csid(char *csid)
{
int nodeid = 1;
memcpy(csid, &nodeid, sizeof(int));
}
static int _csid_from_name(char *csid, const char *name)
{
return 1;
}
static int _name_from_csid(const char *csid, char *name)
{
strcpy(name, "SINGLENODE");
return 0;
}
static int _get_num_nodes(void)
{
return 1;
}
/* Node is now known to be running a clvmd */
static void _add_up_node(const char *csid)
{
}
/* Call a callback for each node, so the caller knows whether it's up or down */
static int _cluster_do_node_callback(struct local_client *master_client,
void (*callback)(struct local_client *,
const char *csid, int node_up))
{
return 0;
}
int _lock_file(const char *file, uint32_t flags);
static const char *_get_mode(int mode)
{
switch (mode) {
case LCK_NULL: return "NULL";
case LCK_READ: return "READ";
case LCK_PREAD: return "PREAD";
case LCK_WRITE: return "WRITE";
case LCK_EXCL: return "EXCLUSIVE";
case LCK_UNLOCK: return "UNLOCK";
default: return "????";
}
}
/* Real locking */
static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
{
/* DLM table of allowed transition states */
static const int _dlm_table[6][6] = {
/* Mode NL CR CW PR PW EX */
/* NL */ { 1, 1, 1, 1, 1, 1},
/* CR */ { 1, 1, 1, 1, 1, 0},
/* CW */ { 1, 1, 1, 0, 0, 0},
/* PR */ { 1, 1, 0, 1, 0, 0},
/* PW */ { 1, 1, 0, 0, 0, 0},
/* EX */ { 1, 0, 0, 0, 0, 0}
};
struct lock *lck = NULL, *lckt;
struct dm_list *head;
DEBUGLOG("Locking resource %s, flags=0x%02x (%s%s%s), mode=%s (%d)\n",
resource, flags,
(flags & LCKF_NOQUEUE) ? "NOQUEUE" : "",
((flags & (LCKF_NOQUEUE | LCKF_CONVERT)) ==
(LCKF_NOQUEUE | LCKF_CONVERT)) ? "|" : "",
(flags & LCKF_CONVERT) ? "CONVERT" : "",
_get_mode(mode), mode);
mode &= LCK_TYPE_MASK;
pthread_mutex_lock(&_lock_mutex);
retry:
pthread_cond_broadcast(&_lock_cond); /* to wakeup waiters */
if (!(head = dm_hash_lookup(_locks, resource))) {
if (flags & LCKF_CONVERT) {
/* In real DLM, lock is identified only by lockid, resource is not used */
DEBUGLOG("Unlocked resource %s cannot be converted\n", resource);
goto_bad;
}
/* Add new locked resource */
if (!(head = dm_malloc(sizeof(struct dm_list))) ||
!dm_hash_insert(_locks, resource, head)) {
dm_free(head);
goto_bad;
}
dm_list_init(head);
} else /* Update/convert locked resource */
dm_list_iterate_items(lck, head) {
/* Check is all locks are compatible with requested lock */
if (flags & LCKF_CONVERT) {
if (lck->lockid != *lockid)
continue;
DEBUGLOG("Converting resource %s lockid=%d mode:%s -> %s...\n",
resource, lck->lockid, _get_mode(lck->mode), _get_mode(mode));
dm_list_iterate_items(lckt, head) {
if ((lckt->lockid != *lockid) &&
!_dlm_table[mode][lckt->mode]) {
if (!(flags & LCKF_NOQUEUE) &&
/* TODO: Real dlm uses here conversion queues */
!pthread_cond_wait(&_lock_cond, &_lock_mutex) &&
_locks) /* End of the game? */
goto retry;
goto bad;
}
}
lck->mode = mode; /* Lock is now converted */
goto out;
} else if (!_dlm_table[mode][lck->mode]) {
DEBUGLOG("Resource %s already locked lockid=%d, mode:%s\n",
resource, lck->lockid, _get_mode(lck->mode));
if (!(flags & LCKF_NOQUEUE) &&
!pthread_cond_wait(&_lock_cond, &_lock_mutex) &&
_locks) { /* End of the game? */
DEBUGLOG("Resource %s retrying lock in mode:%s...\n",
resource, _get_mode(mode));
goto retry;
}
goto bad;
}
}
if (!(flags & LCKF_CONVERT)) {
if (!(lck = dm_malloc(sizeof(struct lock))))
goto_bad;
*lockid = lck->lockid = ++_lockid;
lck->mode = mode;
dm_list_add(head, &lck->list);
}
out:
pthread_mutex_unlock(&_lock_mutex);
DEBUGLOG("Locked resource %s, lockid=%d, mode=%s\n",
resource, lck->lockid, _get_mode(lck->mode));
return 0;
bad:
pthread_mutex_unlock(&_lock_mutex);
DEBUGLOG("Failed to lock resource %s\n", resource);
return 1; /* fail */
}
static int _unlock_resource(const char *resource, int lockid)
{
struct lock *lck;
struct dm_list *head;
int r = 1;
if (lockid < 0) {
DEBUGLOG("Not tracking unlock of lockid -1: %s, lockid=%d\n",
resource, lockid);
return 1;
}
DEBUGLOG("Unlocking resource %s, lockid=%d\n", resource, lockid);
pthread_mutex_lock(&_lock_mutex);
pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */
if (!(head = dm_hash_lookup(_locks, resource))) {
pthread_mutex_unlock(&_lock_mutex);
DEBUGLOG("Resource %s is not locked.\n", resource);
return 1;
}
dm_list_iterate_items(lck, head)
if (lck->lockid == lockid) {
dm_list_del(&lck->list);
dm_free(lck);
r = 0;
goto out;
}
DEBUGLOG("Resource %s has wrong lockid %d.\n", resource, lockid);
out:
if (dm_list_empty(head)) {
//DEBUGLOG("Resource %s is no longer hashed (lockid=%d).\n", resource, lockid);
dm_hash_remove(_locks, resource);
dm_free(head);
}
pthread_mutex_unlock(&_lock_mutex);
return r;
}
static int _is_quorate(void)
{
return 1;
}
static int _get_main_cluster_fd(void)
{
return listen_fd;
}
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
const char *csid,
struct local_client **new_client)
{
return 1;
}
static int _cluster_send_message(const void *buf, int msglen,
const char *csid,
const char *errtext)
{
return 0;
}
static int _get_cluster_name(char *buf, int buflen)
{
return dm_strncpy(buf, "localcluster", buflen) ? 0 : 1;
}
static struct cluster_ops _cluster_singlenode_ops = {
.name = "singlenode",
.cluster_init_completed = NULL,
.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,
.reread_config = NULL,
.cluster_closedown = _cluster_closedown,
.get_cluster_name = _get_cluster_name,
.sync_lock = _lock_resource,
.sync_unlock = _unlock_resource,
};
struct cluster_ops *init_singlenode_cluster(void)
{
if (!_init_cluster())
return &_cluster_singlenode_ops;
return NULL;
}

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,9 @@
#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
@@ -32,8 +35,6 @@ struct node_reply {
struct node_reply *next;
};
typedef enum {DEBUG_OFF, DEBUG_STDERR, DEBUG_SYSLOG} debug_t;
/*
* These exist for the use of local sockets only when we are
* collecting responses from all cluster nodes
@@ -53,12 +54,13 @@ struct localsock_bits {
int finished; /* Flag to tell subthread to exit */
int all_success; /* Set to 0 if any node (or the pre_command)
failed */
int cleanup_needed; /* helper for cleanup_zombie */
struct local_client *pipe_client;
pthread_t threadid;
enum { PRE_COMMAND, POST_COMMAND } state;
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 */
@@ -74,8 +76,7 @@ struct netsock_bits {
};
typedef int (*fd_callback_t) (struct local_client * fd, char *buf, int len,
const char *csid,
struct local_client ** new_client);
char *csid, struct local_client ** new_client);
/* One of these for each fd we are listening on */
struct local_client {
@@ -85,7 +86,6 @@ struct local_client {
struct local_client *next;
unsigned short xid;
fd_callback_t callback;
uint8_t removeme;
union {
struct localsock_bits localsock;
@@ -94,7 +94,11 @@ struct local_client {
} bits;
};
#define DEBUGLOG(fmt, args...) debuglog(fmt, ## args)
#ifdef DEBUG
#define DEBUGLOG(fmt, args...) fprintf(stderr, "CLVMD[%d]: %ld ", getpid(), time(NULL) ); fprintf(stderr, fmt, ## args)
#else
#define DEBUGLOG(fmt, args...)
#endif
#ifndef max
#define max(a,b) ((a)>(b)?(a):(b))
@@ -111,16 +115,5 @@ 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, const char *csid);
extern void debuglog(const char *fmt, ... )
__attribute__ ((format(printf, 1, 2)));
void clvmd_set_debug(debug_t new_de);
debug_t clvmd_get_debug(void);
int clvmd_get_foreground(void);
int sync_lock(const char *resource, int mode, int flags, int *lockid);
int sync_unlock(const char *resource, int lockid);
extern void process_message(struct local_client *client, char *buf, int len, char *csid);
#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 MAX_CLUSTER_MESSAGE 1500
#define 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[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

446
daemons/clvmd/libclvm.c Normal file
View File

@@ -0,0 +1,446 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* library functions for Cluster LVM Daemon */
#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 <search.h>
#include <errno.h>
#include "clvm.h"
#include "libclvm.h"
/* CLVM in hex! */
#define LVM_SIGNATURE 0x434C564D
#define MAX_CLUSTER_MEMBER_NAME_LEN 255
/* NOTE: the LVMD uses the socket FD as the client ID, this means
that any client that calls fork() will inherit the context of
it's parent. */
static int clvmd_sock = -1;
static int open_local_sock(void)
{
int local_socket;
struct sockaddr_un sockaddr;
/* Open local socket */
local_socket = socket(PF_UNIX, SOCK_STREAM, 0);
if (local_socket < 0) {
perror("Can't create local socket");
return -1;
}
fcntl(local_socket, F_SETFD, !FD_CLOEXEC);
strcpy(sockaddr.sun_path, CLVMD_SOCKNAME);
sockaddr.sun_family = AF_UNIX;
if (connect
(local_socket, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
int saved_errno = errno;
close(local_socket);
errno = saved_errno;
return -1;
}
return local_socket;
}
/* Send a request and return the status */
static int send_request(char *inbuf, int inlen, char **retbuf)
{
char outbuf[PIPE_BUF];
struct clvm_header *outheader = (struct clvm_header *) outbuf;
int len;
int off;
fd_set fds;
FD_ZERO(&fds);
FD_SET(clvmd_sock, &fds);
/* Send it to CLVMD */
if (write(clvmd_sock, inbuf, inlen) != inlen) {
perror("Error writing to CLVMD");
return -1;
}
/* Get the response */
if ((len = read(clvmd_sock, outbuf, sizeof(struct clvm_header))) < 0) {
perror("Error reading CLVMD");
return -1;
}
if (len == 0) {
fprintf(stderr, "EOF reading CLVMD");
errno = ENOTCONN;
return -1;
}
/* Allocate buffer */
*retbuf = malloc(len + outheader->arglen);
if (!*retbuf) {
errno = ENOMEM;
return -1;
}
/* Copy the header */
memcpy(*retbuf, outbuf, len);
outheader = (struct clvm_header *) *retbuf;
/* Read the returned values */
off = 1; /* we've already read the first byte */
while (off < outheader->arglen && len > 0) {
len = read(clvmd_sock, outheader->args + off, PIPE_BUF);
if (len > 0)
off += len;
}
/* Was it an error ? */
if (outheader->status < 0) {
errno = -outheader->status;
return -2;
}
return 0;
}
/* Build the structure header and parse-out wildcard node names */
static void build_header(struct clvm_header *head, int cmd, const char *node,
void *data, int len)
{
head->cmd = cmd;
head->status = 0;
head->flags = 0;
head->clientid = 0;
head->arglen = len;
if (node) {
/* Allow a couple of special node names:
"*" for all nodes,
"." for the local node only
*/
if (strcmp(node, "*") == 0) {
head->node[0] = '\0';
} else if (strcmp(node, ".") == 0) {
head->node[0] = '\0';
head->flags = CLVMD_FLAG_LOCAL;
} else {
strcpy(head->node, node);
}
} else {
head->node[0] = '\0';
}
}
/* Send a message to a(or all) node(s) in the cluster */
int lvm_cluster_write(char cmd, char *node, void *data, int len)
{
char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
char *retbuf = NULL;
int status;
struct clvm_header *head = (struct clvm_header *) outbuf;
if (clvmd_sock == -1)
clvmd_sock = open_local_sock();
if (clvmd_sock == -1)
return -1;
build_header(head, cmd, node, data, len);
memcpy(head->node + strlen(head->node) + 1, data, len);
status =
send_request(outbuf,
sizeof(struct clvm_header) + strlen(head->node) + len,
&retbuf);
if (retbuf)
free(retbuf);
return status;
}
/* API: Send a message to a(or all) node(s) in the cluster
and wait for replies */
int lvm_cluster_request(char cmd, const char *node, void *data, int len,
lvm_response_t ** response, int *num)
{
char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
int *outptr;
char *inptr;
char *retbuf = NULL;
int status;
int i;
int num_responses = 0;
struct clvm_header *head = (struct clvm_header *) outbuf;
lvm_response_t *rarray;
*num = 0;
if (clvmd_sock == -1)
clvmd_sock = open_local_sock();
if (clvmd_sock == -1)
return -1;
build_header(head, cmd, node, data, len);
memcpy(head->node + strlen(head->node) + 1, data, len);
status =
send_request(outbuf,
sizeof(struct clvm_header) + strlen(head->node) + len,
&retbuf);
if (status == 0 || status == -2) {
/* Count the number of responses we got */
head = (struct clvm_header *) retbuf;
inptr = head->args;
while (inptr[0]) {
num_responses++;
inptr += strlen(inptr) + 1;
inptr += sizeof(int);
inptr += strlen(inptr) + 1;
}
/* Allocate response array. With an extra pair of INTs on the front to sanity
check the pointer when we are given it back to free */
outptr =
malloc(sizeof(lvm_response_t) * num_responses +
sizeof(int) * 2);
if (!outptr) {
if (retbuf)
free(retbuf);
errno = ENOMEM;
return -1;
}
*response = (lvm_response_t *) (outptr + 2);
outptr[0] = LVM_SIGNATURE;
outptr[1] = num_responses;
rarray = *response;
/* Unpack the response into an lvm_response_t array */
inptr = head->args;
i = 0;
while (inptr[0]) {
strcpy(rarray[i].node, inptr);
inptr += strlen(inptr) + 1;
rarray[i].status = *(int *) inptr;
inptr += sizeof(int);
rarray[i].response = malloc(strlen(inptr) + 1);
if (rarray[i].response == NULL) {
/* Free up everything else and return error */
int j;
for (j = 0; j < i; j++)
free(rarray[i].response);
free(outptr);
errno = ENOMEM;
return -1;
}
strcpy(rarray[i].response, inptr);
rarray[i].len = strlen(inptr);
inptr += strlen(inptr) + 1;
i++;
}
*num = num_responses;
*response = rarray;
}
if (retbuf)
free(retbuf);
return status;
}
/* API: Free reply array */
int lvm_cluster_free_request(lvm_response_t * response)
{
int *ptr = (int *) response - 2;
int i;
int num;
/* Check it's ours to free */
if (response == NULL || *ptr != LVM_SIGNATURE) {
errno = EINVAL;
return -1;
}
num = ptr[1];
for (i = 0; i < num; i++) {
free(response[i].response);
}
free(ptr);
return 0;
}
/* These are a "higher-level" API providing black-box lock/unlock
functions for cluster LVM...maybe */
/* Set by lock(), used by unlock() */
static int num_responses;
static lvm_response_t *response;
int lvm_lock_for_cluster(char scope, char *name, int verbosity)
{
int status;
int i;
char *args;
int len;
if (name) {
len = strlen(name) + 2;
args = alloca(len);
strcpy(args + 1, name);
} else {
len = 2;
args = alloca(len);
args[1] = '\0';
}
args[0] = scope;
status = lvm_cluster_request(CLVMD_CMD_LOCK,
"", args, len, &response, &num_responses);
/* If any nodes were down then display them and return an error */
for (i = 0; i < num_responses; i++) {
if (response[i].status == -EHOSTDOWN) {
if (verbosity)
fprintf(stderr,
"clvmd not running on node %s\n",
response[i].node);
status = -1;
}
}
/* If there was an error then free the memory now as the caller won't
want to do the unlock */
if (status) {
int saved_errno = errno;
lvm_cluster_free_request(response);
num_responses = 0;
errno = saved_errno;
}
return status;
}
int lvm_unlock_for_cluster(char scope, char *name, int verbosity)
{
int status;
int i;
int len;
int failed;
int num_unlock_responses;
char *args;
lvm_response_t *unlock_response;
/* We failed - this should not have been called */
if (num_responses == 0)
return 0;
if (name) {
len = strlen(name) + 2;
args = alloca(len);
strcpy(args + 1, name);
} else {
len = 2;
args = alloca(len);
args[1] = '\0';
}
args[0] = scope;
/* See if it failed anywhere */
failed = 0;
for (i = 0; i < num_responses; i++) {
if (response[i].status != 0)
failed++;
}
/* If it failed on any nodes then we only unlock on
the nodes that succeeded */
if (failed) {
for (i = 0; i < num_responses; i++) {
/* Unlock the ones that succeeded */
if (response[i].status == 0) {
status = lvm_cluster_request(CLVMD_CMD_UNLOCK,
response[i].node,
args, len,
&unlock_response,
&num_unlock_responses);
if (status) {
if (verbosity)
fprintf(stderr,
"cluster command to node %s failed: %s\n",
response[i].node,
strerror(errno));
} else if (unlock_response[0].status != 0) {
if (verbosity > 1)
fprintf(stderr,
"unlock on node %s failed: %s\n",
response[i].node,
strerror(unlock_response
[0].status));
}
lvm_cluster_free_request(unlock_response);
} else {
if (verbosity)
fprintf(stderr,
"command on node %s failed: '%s' - will be left locked\n",
response[i].node,
strerror(response[i].status));
}
}
} else {
/* All OK, we can do a full cluster unlock */
status = lvm_cluster_request(CLVMD_CMD_UNLOCK,
"",
args, len,
&unlock_response,
&num_unlock_responses);
if (status) {
if (verbosity > 1)
fprintf(stderr, "cluster command failed: %s\n",
strerror(errno));
} else {
for (i = 0; i < num_unlock_responses; i++) {
if (unlock_response[i].status != 0) {
if (verbosity > 1)
fprintf(stderr,
"unlock on node %s failed: %s\n",
response[i].node,
strerror(unlock_response
[0].status));
}
}
}
lvm_cluster_free_request(unlock_response);
}
lvm_cluster_free_request(response);
return 0;
}

36
daemons/clvmd/libclvm.h Normal file
View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LIBCLVM_H
#define _LIBCLVM_H
typedef struct lvm_response {
char node[255];
char *response;
int status;
int len;
} lvm_response_t;
extern int lvm_cluster_request(char cmd, const char *node, void *data, int len,
lvm_response_t ** response, int *num);
extern int lvm_cluster_write(char cmd, char *node, void *data, int len);
extern int lvm_cluster_free_request(lvm_response_t * response);
/* The "high-level" API */
extern int lvm_lock_for_cluster(char scope, char *name, int verbosity);
extern int lvm_unlock_for_cluster(char scope, char *name, int verbosity);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -22,20 +22,14 @@ 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 const char *do_lock_query(char *resource);
extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern int do_check_lvm1(const char *vgname);
extern int do_refresh_cache(void);
extern int init_clvm(struct dm_hash_table *excl_uuid);
extern void destroy_lvm(void);
extern int do_check_lvm1(char *vgname);
extern int init_lvm(void);
extern void init_lvhash(void);
extern void destroy_lvhash(void);
extern void lvm_do_backup(const char *vgname);
extern char *get_last_lvm_error(void);
extern void do_lock_vg(unsigned char command, unsigned char lock_flags,
char *resource);
extern struct dm_hash_node *get_next_excl_lock(struct dm_hash_node *v, char **name);
void lvm_do_fs_unlock(void);
extern int hold_unlock(char *resource);
extern int hold_lock(char *resource, int mode, int flags);
extern void unlock_all(void);
#endif

View File

@@ -1,382 +0,0 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2010 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
*/
/* FIXME Remove duplicated functions from this file. */
/*
* Send a command to a running clvmd from the command-line
*/
#include "clvmd-common.h"
#include "clvm.h"
#include "refresh_clvmd.h"
#include <stddef.h>
#include <sys/socket.h>
#include <sys/un.h>
typedef struct lvm_response {
char node[255];
char *response;
int status;
int len;
} lvm_response_t;
/*
* This gets stuck at the start of memory we allocate so we
* can sanity-check it at deallocation time
*/
#define LVM_SIGNATURE 0x434C564D
static int _clvmd_sock = -1;
/* Open connection to the clvm daemon */
static int _open_local_sock(void)
{
int local_socket;
struct sockaddr_un sockaddr = { .sun_family = AF_UNIX };
if (!dm_strncpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(sockaddr.sun_path))) {
fprintf(stderr, "%s: clvmd socket name too long.", CLVMD_SOCKNAME);
return -1;
}
/* Open local socket */
if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
fprintf(stderr, "Local socket creation failed: %s", strerror(errno));
return -1;
}
if (connect(local_socket,(struct sockaddr *) &sockaddr,
sizeof(sockaddr))) {
int saved_errno = errno;
fprintf(stderr, "connect() failed on local socket: %s\n",
strerror(errno));
if (close(local_socket))
return -1;
errno = saved_errno;
return -1;
}
return local_socket;
}
/* Send a request and return the status */
static int _send_request(const char *inbuf, int inlen, char **retbuf, int no_response)
{
char outbuf[PIPE_BUF];
struct clvm_header *outheader = (struct clvm_header *) outbuf;
int len;
unsigned off;
int buflen;
int err;
/* Send it to CLVMD */
rewrite:
if ( (err = write(_clvmd_sock, inbuf, inlen)) != inlen) {
if (err == -1 && errno == EINTR)
goto rewrite;
fprintf(stderr, "Error writing data to clvmd: %s", strerror(errno));
return 0;
}
if (no_response)
return 1;
/* Get the response */
reread:
if ((len = read(_clvmd_sock, outbuf, sizeof(struct clvm_header))) < 0) {
if (errno == EINTR)
goto reread;
fprintf(stderr, "Error reading data from clvmd: %s", strerror(errno));
return 0;
}
if (len == 0) {
fprintf(stderr, "EOF reading CLVMD");
errno = ENOTCONN;
return 0;
}
/* Allocate buffer */
buflen = len + outheader->arglen;
*retbuf = dm_malloc(buflen);
if (!*retbuf) {
errno = ENOMEM;
return 0;
}
/* Copy the header */
memcpy(*retbuf, outbuf, len);
outheader = (struct clvm_header *) *retbuf;
/* Read the returned values */
off = 1; /* we've already read the first byte */
while (off <= outheader->arglen && len > 0) {
len = read(_clvmd_sock, outheader->args + off,
buflen - off - offsetof(struct clvm_header, args));
if (len > 0)
off += len;
}
/* Was it an error ? */
if (outheader->status != 0) {
errno = outheader->status;
/* Only return an error here if there are no node-specific
errors present in the message that might have more detail */
if (!(outheader->flags & CLVMD_FLAG_NODEERRS)) {
fprintf(stderr, "cluster request failed: %s\n", strerror(errno));
return 0;
}
}
return 1;
}
/* Build the structure header and parse-out wildcard node names */
static void _build_header(struct clvm_header *head, int cmd, const char *node,
unsigned int len)
{
head->cmd = cmd;
head->status = 0;
head->flags = 0;
head->xid = 0;
head->clientid = 0;
if (len)
/* 1 byte is used from struct clvm_header.args[1], so -> len - 1 */
head->arglen = len - 1;
else {
head->arglen = 0;
*head->args = '\0';
}
/*
* Translate special node names.
*/
if (!node || !strcmp(node, NODE_ALL))
head->node[0] = '\0';
else if (!strcmp(node, NODE_LOCAL)) {
head->node[0] = '\0';
head->flags = CLVMD_FLAG_LOCAL;
} else
strcpy(head->node, node);
}
/*
* Send a message to a(or all) node(s) in the cluster and wait for replies
*/
static int _cluster_request(char cmd, const char *node, void *data, int len,
lvm_response_t ** response, int *num, int no_response)
{
char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
char *inptr;
char *retbuf = NULL;
int status;
int i;
int num_responses = 0;
struct clvm_header *head = (struct clvm_header *) outbuf;
lvm_response_t *rarray;
*num = 0;
if (_clvmd_sock == -1)
_clvmd_sock = _open_local_sock();
if (_clvmd_sock == -1)
return 0;
_build_header(head, cmd, node, len);
if (len)
memcpy(head->node + strlen(head->node) + 1, data, len);
status = _send_request(outbuf, sizeof(struct clvm_header) +
strlen(head->node) + len, &retbuf, no_response);
if (!status || no_response)
goto out;
/* Count the number of responses we got */
head = (struct clvm_header *) retbuf;
inptr = head->args;
while (inptr[0]) {
num_responses++;
inptr += strlen(inptr) + 1;
inptr += sizeof(int);
inptr += strlen(inptr) + 1;
}
/*
* Allocate response array.
* With an extra pair of INTs on the front to sanity
* check the pointer when we are given it back to free
*/
*response = NULL;
if (!(rarray = dm_malloc(sizeof(lvm_response_t) * num_responses +
sizeof(int) * 2))) {
errno = ENOMEM;
status = 0;
goto out;
}
/* Unpack the response into an lvm_response_t array */
inptr = head->args;
i = 0;
while (inptr[0]) {
strcpy(rarray[i].node, inptr);
inptr += strlen(inptr) + 1;
memcpy(&rarray[i].status, inptr, sizeof(int));
inptr += sizeof(int);
rarray[i].response = dm_malloc(strlen(inptr) + 1);
if (rarray[i].response == NULL) {
/* Free up everything else and return error */
int j;
for (j = 0; j < i; j++)
dm_free(rarray[i].response);
dm_free(rarray);
errno = ENOMEM;
status = 0;
goto out;
}
strcpy(rarray[i].response, inptr);
rarray[i].len = strlen(inptr);
inptr += strlen(inptr) + 1;
i++;
}
*num = num_responses;
*response = rarray;
out:
dm_free(retbuf);
return status;
}
/* Free reply array */
static int _cluster_free_request(lvm_response_t * response, int num)
{
int i;
for (i = 0; i < num; i++) {
dm_free(response[i].response);
}
dm_free(response);
return 1;
}
int refresh_clvmd(int all_nodes)
{
int num_responses;
char args[1]; // No args really.
lvm_response_t *response = NULL;
int saved_errno;
int status;
int i;
status = _cluster_request(CLVMD_CMD_REFRESH, all_nodes ? NODE_ALL : NODE_LOCAL, args, 0, &response, &num_responses, 0);
/* If any nodes were down then display them and return an error */
for (i = 0; i < num_responses; i++) {
if (response[i].status == EHOSTDOWN) {
fprintf(stderr, "clvmd not running on node %s",
response[i].node);
status = 0;
errno = response[i].status;
} else if (response[i].status) {
fprintf(stderr, "Error resetting node %s: %s",
response[i].node,
response[i].response[0] ?
response[i].response :
strerror(response[i].status));
status = 0;
errno = response[i].status;
}
}
saved_errno = errno;
_cluster_free_request(response, num_responses);
errno = saved_errno;
return status;
}
int restart_clvmd(int all_nodes)
{
int dummy, status;
status = _cluster_request(CLVMD_CMD_RESTART, all_nodes ? NODE_ALL : NODE_LOCAL, NULL, 0, NULL, &dummy, 1);
/*
* FIXME: we cannot receive response, clvmd re-exec before it.
* but also should not close socket too early (the whole rq is dropped then).
* FIXME: This should be handled this way:
* - client waits for RESTART ack (and socket close)
* - server restarts
* - client checks that server is ready again (VERSION command?)
*/
usleep(500000);
return status;
}
int debug_clvmd(int level, int clusterwide)
{
int num_responses;
char args[1];
const char *nodes;
lvm_response_t *response = NULL;
int saved_errno;
int status;
int i;
args[0] = level;
if (clusterwide)
nodes = NODE_ALL;
else
nodes = NODE_LOCAL;
status = _cluster_request(CLVMD_CMD_SET_DEBUG, nodes, args, 1, &response, &num_responses, 0);
/* If any nodes were down then display them and return an error */
for (i = 0; i < num_responses; i++) {
if (response[i].status == EHOSTDOWN) {
fprintf(stderr, "clvmd not running on node %s",
response[i].node);
status = 0;
errno = response[i].status;
} else if (response[i].status) {
fprintf(stderr, "Error setting debug on node %s: %s",
response[i].node,
response[i].response[0] ?
response[i].response :
strerror(response[i].status));
status = 0;
errno = response[i].status;
}
}
saved_errno = errno;
_cluster_free_request(response, num_responses);
errno = saved_errno;
return status;
}

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

@@ -0,0 +1,369 @@
/*
* 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 "clvmd-comms.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

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

@@ -0,0 +1,444 @@
/******************************************************************************
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 2002-2003 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 "clvm.h"
#include "clvmd-comms.h"
#include "clvmd.h"
#include "clvmd-gulm.h"
#include "hash.h"
#define DEFAULT_TCP_PORT 21064
static int listen_fd = -1;
static int tcp_port;
struct hash_table *sock_hash;
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 = 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));
}
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);
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 = hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN);
if (client)
{
hash_remove_binary(sock_hash, csid, MAX_CSID_LEN);
}
/* Look for a mangled one too */
csid[0] ^= 0x80;
client = hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN);
if (client)
{
hash_remove_binary(sock_hash, csid, MAX_CSID_LEN);
}
/* 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 (hash_lookup_binary(sock_hash, csid, 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 (hash_lookup_binary(sock_hash, csid, 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;
}
}
hash_insert_binary(sock_hash, csid, MAX_CSID_LEN, client);
return 0;
}
int get_main_cluster_fd()
{
return listen_fd;
}
/* Read on main comms (listen) socket, accept it */
int cluster_fd_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[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 (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;
}
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);
int status;
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, MAX_CSID_LEN);
status = read(client->fd, buf, len);
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[MAX_CSID_LEN];
memcpy(remcsid, csid, 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;
hash_remove_binary(sock_hash, remcsid, MAX_CSID_LEN);
/* Tell cluster manager layer */
add_down_node(remcsid);
}
else {
/* Send it back to clvmd */
process_message(client, buf, len, csid);
}
return status;
}
static int connect_csid(char *csid, struct local_client **newclient)
{
int fd;
struct sockaddr_in6 addr;
int status;
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, 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)
{
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;
}
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 */
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[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_csid(ourcsid);
if (memcmp(csid, ourcsid, MAX_CSID_LEN) == 0)
return msglen;
client = hash_lookup_binary(sock_hash, csid, MAX_CSID_LEN);
if (!client)
{
status = connect_csid(csid, &client);
if (status)
return -1;
}
DEBUGLOG("tcp_send_message, fd = %d\n", client->fd);
return write(client->fd, buf, msglen);
}
int 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[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_csid(char *csid)
{
static char our_csid[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, 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, 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;
}

View File

@@ -0,0 +1,8 @@
#include <netinet/in.h>
#define MAX_CLUSTER_MESSAGE 1600
#define MAX_CSID_LEN sizeof(struct in6_addr)
#define MAX_CLUSTER_MEMBER_NAME_LEN 128
extern int init_comms(unsigned short);
extern char *print_csid(char *);

View File

@@ -1,39 +0,0 @@
#
# Copyright (C) 2009-2010 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CPG_LIBS = @CPG_LIBS@
CPG_CFLAGS = @CPG_CFLAGS@
SACKPT_LIBS = @SACKPT_LIBS@
SACKPT_CFLAGS = @SACKPT_CFLAGS@
SOURCES = clogd.c cluster.c compat.c functions.c link_mon.c local.c logging.c
TARGETS = cmirrord
include $(top_builddir)/make.tmpl
LIBS += -ldevmapper
LMLIBS += $(CPG_LIBS) $(SACKPT_LIBS)
CFLAGS += $(CPG_CFLAGS) $(SACKPT_CFLAGS) $(EXTRA_EXEC_CFLAGS)
LDFLAGS += $(EXTRA_EXEC_LDFLAGS)
cmirrord: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
$(LVMLIBS) $(LMLIBS) $(LIBS)
install: $(TARGETS)
$(INSTALL_PROGRAM) -D cmirrord $(usrsbindir)/cmirrord

View File

@@ -1,256 +0,0 @@
/*
* Copyright (C) 2004-2009 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.
*
* 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 "logging.h"
#include "common.h"
#include "functions.h"
#include "link_mon.h"
#include "local.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
static volatile sig_atomic_t exit_now = 0;
/* FIXME Review signal handling. Should be volatile sig_atomic_t */
static sigset_t signal_mask;
static volatile sig_atomic_t signal_received;
static void process_signals(void);
static void daemonize(void);
static void init_all(void);
static void cleanup_all(void);
int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
{
daemonize();
init_all();
/* Parent can now exit, we're ready to handle requests */
kill(getppid(), SIGTERM);
LOG_PRINT("Starting cmirrord:");
LOG_PRINT(" Built: "__DATE__" "__TIME__"\n");
LOG_DBG(" Compiled with debugging.");
while (!exit_now) {
links_monitor();
links_issue_callbacks();
process_signals();
}
exit(EXIT_SUCCESS);
}
/*
* parent_exit_handler: exit the parent
* @sig: the signal
*
*/
static void parent_exit_handler(int sig __attribute__((unused)))
{
exit_now = 1;
}
static void sig_handler(int sig)
{
/* FIXME Races - don't touch signal_mask here. */
sigaddset(&signal_mask, sig);
signal_received = 1;
}
static void process_signal(int sig){
int r = 0;
switch(sig) {
case SIGINT:
case SIGQUIT:
case SIGTERM:
case SIGHUP:
r += log_status();
break;
case SIGUSR1:
case SIGUSR2:
log_debug();
/*local_debug();*/
cluster_debug();
return;
default:
LOG_PRINT("Unknown signal received... ignoring");
return;
}
if (!r) {
LOG_DBG("No current cluster logs... safe to exit.");
cleanup_all();
exit(EXIT_SUCCESS);
}
LOG_ERROR("Cluster logs exist. Refusing to exit.");
}
static void process_signals(void)
{
int x;
if (!signal_received)
return;
signal_received = 0;
for (x = 1; x < _NSIG; x++) {
if (sigismember(&signal_mask, x)) {
sigdelset(&signal_mask, x);
process_signal(x);
}
}
}
static void remove_lockfile(void)
{
if (unlink(CMIRRORD_PIDFILE))
LOG_ERROR("Unable to remove \"" CMIRRORD_PIDFILE "\" %s", strerror(errno));
}
/*
* daemonize
*
* Performs the steps necessary to become a daemon.
*/
static void daemonize(void)
{
int pid;
int status;
int devnull;
if ((devnull = open("/dev/null", O_RDWR)) == -1) {
LOG_ERROR("Can't open /dev/null: %s", strerror(errno));
exit(EXIT_FAILURE);
}
signal(SIGTERM, &parent_exit_handler);
pid = fork();
if (pid < 0) {
LOG_ERROR("Unable to fork()");
exit(EXIT_FAILURE);
}
if (pid) {
/* Parent waits here for child to get going */
while (!waitpid(pid, &status, WNOHANG) && !exit_now);
if (exit_now)
exit(EXIT_SUCCESS);
switch (WEXITSTATUS(status)) {
case EXIT_LOCKFILE:
LOG_ERROR("Failed to create lockfile");
LOG_ERROR("Process already running?");
break;
case EXIT_KERNEL_SOCKET:
LOG_ERROR("Unable to create netlink socket");
break;
case EXIT_KERNEL_BIND:
LOG_ERROR("Unable to bind to netlink socket");
break;
case EXIT_KERNEL_SETSOCKOPT:
LOG_ERROR("Unable to setsockopt on netlink socket");
break;
case EXIT_CLUSTER_CKPT_INIT:
LOG_ERROR("Unable to initialize checkpoint service");
LOG_ERROR("Has the cluster infrastructure been started?");
break;
case EXIT_FAILURE:
LOG_ERROR("Failed to start: Generic error");
break;
default:
LOG_ERROR("Failed to start: Unknown error");
break;
}
exit(EXIT_FAILURE);
}
setsid();
if (chdir("/")) {
LOG_ERROR("Failed to chdir /: %s", strerror(errno));
exit(EXIT_FAILURE);
}
umask(0);
if (close(0) || close(1) || close(2)) {
LOG_ERROR("Failed to close terminal FDs");
exit(EXIT_FAILURE);
}
if ((dup2(devnull, 0) < 0) || /* reopen stdin */
(dup2(devnull, 1) < 0) || /* reopen stdout */
(dup2(devnull, 2) < 0)) /* reopen stderr */
exit(EXIT_FAILURE);
if ((devnull > STDERR_FILENO) && close(devnull)) {
LOG_ERROR("Failed to close descriptor %d: %s",
devnull, strerror(errno));
exit(EXIT_FAILURE);
}
LOG_OPEN("cmirrord", LOG_PID, LOG_DAEMON);
(void) dm_prepare_selinux_context(CMIRRORD_PIDFILE, S_IFREG);
if (dm_create_lockfile(CMIRRORD_PIDFILE) == 0)
exit(EXIT_LOCKFILE);
(void) dm_prepare_selinux_context(NULL, 0);
atexit(remove_lockfile);
/* FIXME Replace with sigaction. (deprecated) */
signal(SIGINT, &sig_handler);
signal(SIGQUIT, &sig_handler);
signal(SIGTERM, &sig_handler);
signal(SIGHUP, &sig_handler);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1, &sig_handler);
signal(SIGUSR2, &sig_handler);
sigemptyset(&signal_mask);
signal_received = 0;
}
/*
* init_all
*
* Initialize modules. Exit on failure.
*/
static void init_all(void)
{
int r;
if ((r = init_local()) ||
(r = init_cluster())) {
exit(r);
}
}
/*
* cleanup_all
*
* Clean up before exiting
*/
static void cleanup_all(void)
{
cleanup_local();
cleanup_cluster();
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,76 +0,0 @@
/*
* Copyright (C) 2004-2009 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 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_CLOG_CLUSTER_H
#define _LVM_CLOG_CLUSTER_H
#include "dm-log-userspace.h"
#include "libdevmapper.h"
#define DM_ULOG_RESPONSE 0x1000U /* in last byte of 32-bit value */
#define DM_ULOG_CHECKPOINT_READY 21
#define DM_ULOG_MEMBER_JOIN 22
/*
* There is other information in addition to what can
* be found in the dm_ulog_request structure that we
* need for processing. 'clog_request' is the wrapping
* structure we use to make the additional fields
* available.
*/
struct clog_request {
/*
* If we don't use a union, the structure size will
* vary between 32-bit and 64-bit machines. So, we
* pack two 64-bit version numbers in there to force
* the size of the structure to be the same.
*
* The two version numbers also help us with endian
* issues. The first is always little endian, while
* the second is in native format of the sending
* machine. If the two are equal, there is no need
* to do endian conversions.
*/
union {
uint64_t version[2]; /* LE version and native version */
struct dm_list list;
} u;
/*
* 'originator' is the machine from which the requests
* was made.
*/
uint32_t originator;
/*
* 'pit_server' is the "point-in-time" server for the
* request. (I.e. The machine that was the server at
* the time the request was issued - only important during
* startup.
*/
uint32_t pit_server;
/*
* The request from the kernel that is being processed
*/
struct dm_ulog_request u_rq;
};
int init_cluster(void);
void cleanup_cluster(void);
void cluster_debug(void);
int create_cluster_cpg(char *uuid, uint64_t luid);
int destroy_cluster_cpg(char *uuid);
int cluster_send(struct clog_request *rq);
#endif /* _LVM_CLOG_CLUSTER_H */

View File

@@ -1,33 +0,0 @@
/*
* Copyright (C) 2004-2009 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 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_CLOG_COMMON_H
#define _LVM_CLOG_COMMON_H
/*
* If there are problems when forking off to become a daemon,
* the child will exist with one of these codes. This allows
* the parent to know the reason for the failure and print it
* to the launching terminal.
*
* #define EXIT_SUCCESS 0 (from stdlib.h)
* #define EXIT_FAILURE 1 (from stdlib.h)
*/
#define EXIT_LOCKFILE 2
#define EXIT_KERNEL_SOCKET 3 /* Failed netlink socket create */
#define EXIT_KERNEL_BIND 4
#define EXIT_KERNEL_SETSOCKOPT 5
#define EXIT_CLUSTER_CKPT_INIT 6 /* Failed to init checkpoint */
#define EXIT_QUEUE_NOMEM 7
#define DM_ULOG_REQUEST_SIZE 1024
#endif /* _LVM_CLOG_COMMON_H */

View File

@@ -1,211 +0,0 @@
/*
* Copyright (C) 2010 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 Lesser General Public License v.2.1.
*/
#include "logging.h"
#include "cluster.h"
#include "compat.h"
#include "xlate.h"
#include <errno.h>
/*
* Older versions of the log daemon communicate with different
* versions of the inter-machine communication structure, which
* varies in size and fields. The older versions append the
* standard upstream version of the structure to every request.
* COMPAT_OFFSET is where the upstream structure starts.
*/
#define COMPAT_OFFSET 256
static void v5_data_endian_switch(struct clog_request *rq, int to_network __attribute__((unused)))
{
int i, end;
int64_t *pi64;
uint64_t *pu64;
uint32_t rq_type = rq->u_rq.request_type & ~DM_ULOG_RESPONSE;
if (rq->u_rq.request_type & DM_ULOG_RESPONSE) {
switch (rq_type) {
case DM_ULOG_CTR:
case DM_ULOG_DTR:
LOG_ERROR("Invalid response type in endian switch");
exit(EXIT_FAILURE);
case DM_ULOG_PRESUSPEND:
case DM_ULOG_POSTSUSPEND:
case DM_ULOG_RESUME:
case DM_ULOG_FLUSH:
case DM_ULOG_MARK_REGION:
case DM_ULOG_CLEAR_REGION:
case DM_ULOG_SET_REGION_SYNC:
case DM_ULOG_CHECKPOINT_READY:
case DM_ULOG_MEMBER_JOIN:
case DM_ULOG_STATUS_INFO:
case DM_ULOG_STATUS_TABLE:
/* No outbound data */
break;
case DM_ULOG_GET_REGION_SIZE:
case DM_ULOG_GET_SYNC_COUNT:
pu64 = (uint64_t *)rq->u_rq.data;
*pu64 = xlate64(*pu64);
break;
case DM_ULOG_IS_CLEAN:
case DM_ULOG_IN_SYNC:
pi64 = (int64_t *)rq->u_rq.data;
*pi64 = xlate64(*pi64);
break;
case DM_ULOG_GET_RESYNC_WORK:
case DM_ULOG_IS_REMOTE_RECOVERING:
pi64 = (int64_t *)rq->u_rq.data;
pu64 = ((uint64_t *)rq->u_rq.data) + 1;
*pi64 = xlate64(*pi64);
*pu64 = xlate64(*pu64);
break;
default:
LOG_ERROR("Unknown request type, %u", rq_type);
return;
}
} else {
switch (rq_type) {
case DM_ULOG_CTR:
case DM_ULOG_DTR:
LOG_ERROR("Invalid request type in endian switch");
exit(EXIT_FAILURE);
case DM_ULOG_PRESUSPEND:
case DM_ULOG_POSTSUSPEND:
case DM_ULOG_RESUME:
case DM_ULOG_GET_REGION_SIZE:
case DM_ULOG_FLUSH:
case DM_ULOG_GET_RESYNC_WORK:
case DM_ULOG_GET_SYNC_COUNT:
case DM_ULOG_STATUS_INFO:
case DM_ULOG_STATUS_TABLE:
case DM_ULOG_CHECKPOINT_READY:
case DM_ULOG_MEMBER_JOIN:
/* No incoming data */
break;
case DM_ULOG_IS_CLEAN:
case DM_ULOG_IN_SYNC:
case DM_ULOG_IS_REMOTE_RECOVERING:
pu64 = (uint64_t *)rq->u_rq.data;
*pu64 = xlate64(*pu64);
break;
case DM_ULOG_MARK_REGION:
case DM_ULOG_CLEAR_REGION:
end = rq->u_rq.data_size/sizeof(uint64_t);
pu64 = (uint64_t *)rq->u_rq.data;
for (i = 0; i < end; i++)
pu64[i] = xlate64(pu64[i]);
break;
case DM_ULOG_SET_REGION_SYNC:
pu64 = (uint64_t *)rq->u_rq.data;
pi64 = ((int64_t *)rq->u_rq.data) + 1;
*pu64 = xlate64(*pu64);
*pi64 = xlate64(*pi64);
break;
default:
LOG_ERROR("Unknown request type, %u", rq_type);
exit(EXIT_FAILURE);
}
}
}
static int v5_endian_to_network(struct clog_request *rq)
{
int size;
struct dm_ulog_request *u_rq = &rq->u_rq;
size = sizeof(*rq) + u_rq->data_size;
u_rq->error = xlate32(u_rq->error);
u_rq->seq = xlate32(u_rq->seq);
rq->originator = xlate32(rq->originator);
v5_data_endian_switch(rq, 1);
u_rq->request_type = xlate32(u_rq->request_type);
u_rq->data_size = xlate32(u_rq->data_size);
return size;
}
int clog_request_to_network(struct clog_request *rq)
{
int r;
/* FIXME: Remove this safety check */
if (rq->u.version[0] != xlate64(rq->u.version[1])) {
LOG_ERROR("Programmer error: version[0] must be LE");
exit(EXIT_FAILURE);
}
/*
* Are we already running in the endian mode we send
* over the wire?
*/
if (rq->u.version[0] == rq->u.version[1])
return 0;
r = v5_endian_to_network(rq);
if (r < 0)
return r;
return 0;
}
static int v5_endian_from_network(struct clog_request *rq)
{
int size;
struct dm_ulog_request *u_rq = &rq->u_rq;
u_rq->error = xlate32(u_rq->error);
u_rq->seq = xlate32(u_rq->seq);
u_rq->request_type = xlate32(u_rq->request_type);
u_rq->data_size = xlate32(u_rq->data_size);
rq->originator = xlate32(rq->originator);
size = sizeof(*rq) + u_rq->data_size;
v5_data_endian_switch(rq, 0);
return size;
}
int clog_request_from_network(void *data, size_t data_len)
{
uint64_t *vp = data;
uint64_t version = xlate64(vp[0]);
uint64_t unconverted_version = vp[1];
struct clog_request *rq = data;
switch (version) {
case 5: /* Upstream */
if (version == vp[0])
return 0;
break;
case 4: /* RHEL 5.[45] */
case 3: /* RHEL 5.3 */
case 2: /* RHEL 5.2 */
/* FIXME: still need to account for payload */
if (data_len < (COMPAT_OFFSET + sizeof(*rq)))
return -ENOSPC;
rq = (struct clog_request *)((char *)data + COMPAT_OFFSET);
break;
default:
LOG_ERROR("Unable to process cluster message: "
"Incompatible version");
return -EINVAL;
}
v5_endian_from_network(rq);
return 0;
}

View File

@@ -1,25 +0,0 @@
/*
* Copyright (C) 2010 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 Lesser General Public License v.2.1.
*/
#ifndef _LVM_CLOG_COMPAT_H
#define _LVM_CLOG_COMPAT_H
/*
* The intermachine communication structure version are:
* 0: Unused
* 1: Never in the wild
* 2: RHEL 5.2
* 3: RHEL 5.3
* 4: RHEL 5.4, RHEL 5.5
* 5: RHEL 6, Current Upstream Format
*/
#define CLOG_TFR_VERSION 5
int clog_request_to_network(struct clog_request *rq);
int clog_request_from_network(void *data, size_t data_len);
#endif /* _LVM_CLOG_COMPAT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,34 +0,0 @@
/*
* Copyright (C) 2004-2009 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 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_CLOG_FUNCTIONS_H
#define _LVM_CLOG_FUNCTIONS_H
#include "dm-log-userspace.h"
#include "cluster.h"
#define LOG_RESUMED 1
#define LOG_SUSPENDED 2
int local_resume(struct dm_ulog_request *rq);
int cluster_postsuspend(char *, uint64_t);
int do_request(struct clog_request *rq, int server);
int push_state(const char *uuid, uint64_t luid,
const char *which, char **buf, uint32_t debug_who);
int pull_state(const char *uuid, uint64_t luid,
const char *which, char *buf, int size);
int log_get_state(struct dm_ulog_request *rq);
int log_status(void);
void log_debug(void);
#endif /* _LVM_CLOG_FUNCTIONS_H */

View File

@@ -1,151 +0,0 @@
/*
* Copyright (C) 2004-2009 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 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 "logging.h"
#include "link_mon.h"
#include <errno.h>
#include <poll.h>
#include <stdlib.h>
struct link_callback {
int fd;
const char *name;
void *data;
int (*callback)(void *data);
struct link_callback *next;
};
static unsigned used_pfds = 0;
static unsigned free_pfds = 0;
static struct pollfd *pfds = NULL;
static struct link_callback *callbacks = NULL;
int links_register(int fd, const char *name, int (*callback)(void *data), void *data)
{
unsigned i;
struct link_callback *lc;
for (i = 0; i < used_pfds; i++) {
if (fd == pfds[i].fd) {
LOG_ERROR("links_register: Duplicate file descriptor");
return -EINVAL;
}
}
lc = malloc(sizeof(*lc));
if (!lc)
return -ENOMEM;
lc->fd = fd;
lc->name = name;
lc->data = data;
lc->callback = callback;
if (!free_pfds) {
struct pollfd *tmp;
tmp = realloc(pfds, sizeof(struct pollfd) * ((used_pfds*2) + 1));
if (!tmp) {
free(lc);
return -ENOMEM;
}
pfds = tmp;
free_pfds = used_pfds + 1;
}
free_pfds--;
pfds[used_pfds].fd = fd;
pfds[used_pfds].events = POLLIN;
pfds[used_pfds].revents = 0;
used_pfds++;
lc->next = callbacks;
callbacks = lc;
LOG_DBG("Adding %s/%d", lc->name, lc->fd);
LOG_DBG(" used_pfds = %u, free_pfds = %u",
used_pfds, free_pfds);
return 0;
}
int links_unregister(int fd)
{
unsigned i;
struct link_callback *p, *c;
for (i = 0; i < used_pfds; i++)
if (fd == pfds[i].fd) {
/* entire struct is copied (overwritten) */
pfds[i] = pfds[used_pfds - 1];
used_pfds--;
free_pfds++;
}
for (p = NULL, c = callbacks; c; p = c, c = c->next)
if (fd == c->fd) {
LOG_DBG("Freeing up %s/%d", c->name, c->fd);
LOG_DBG(" used_pfds = %u, free_pfds = %u",
used_pfds, free_pfds);
if (p)
p->next = c->next;
else
callbacks = c->next;
free(c);
break;
}
return 0;
}
int links_monitor(void)
{
unsigned i;
int r;
for (i = 0; i < used_pfds; i++) {
pfds[i].revents = 0;
}
r = poll(pfds, used_pfds, -1);
if (r <= 0)
return r;
r = 0;
/* FIXME: handle POLLHUP */
for (i = 0; i < used_pfds; i++)
if (pfds[i].revents & POLLIN) {
LOG_DBG("Data ready on %d", pfds[i].fd);
/* FIXME: Add this back return 1;*/
r++;
}
return r;
}
int links_issue_callbacks(void)
{
unsigned i;
struct link_callback *lc;
for (i = 0; i < used_pfds; i++)
if (pfds[i].revents & POLLIN)
for (lc = callbacks; lc; lc = lc->next)
if (pfds[i].fd == lc->fd) {
LOG_DBG("Issuing callback on %s/%d",
lc->name, lc->fd);
lc->callback(lc->data);
break;
}
return 0;
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright (C) 2004-2009 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 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_CLOG_LINK_MON_H
#define _LVM_CLOG_LINK_MON_H
int links_register(int fd, const char *name, int (*callback)(void *data), void *data);
int links_unregister(int fd);
int links_monitor(void);
int links_issue_callbacks(void);
#endif /* _LVM_CLOG_LINK_MON_H */

View File

@@ -1,424 +0,0 @@
/*
* Copyright (C) 2004-2009 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 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 "logging.h"
#include "common.h"
#include "functions.h"
#include "link_mon.h"
#include "local.h"
#include <errno.h>
#include <sys/socket.h>
#include <linux/connector.h>
#include <linux/netlink.h>
#include <unistd.h>
#ifndef CN_IDX_DM
/* Kernel 2.6.31 is required to run this code */
#define CN_IDX_DM 0x7 /* Device Mapper */
#define CN_VAL_DM_USERSPACE_LOG 0x1
#endif
static int cn_fd = -1; /* Connector (netlink) socket fd */
static char recv_buf[2048];
static char send_buf[2048];
/* FIXME: merge this function with kernel_send_helper */
static int kernel_ack(uint32_t seq, int error)
{
int r;
struct nlmsghdr *nlh = (struct nlmsghdr *)send_buf;
struct cn_msg *msg = NLMSG_DATA(nlh);
if (error < 0) {
LOG_ERROR("Programmer error: error codes must be positive");
return -EINVAL;
}
memset(send_buf, 0, sizeof(send_buf));
nlh->nlmsg_seq = 0;
nlh->nlmsg_pid = getpid();
nlh->nlmsg_type = NLMSG_DONE;
nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct cn_msg));
nlh->nlmsg_flags = 0;
msg->len = 0;
msg->id.idx = CN_IDX_DM;
msg->id.val = CN_VAL_DM_USERSPACE_LOG;
msg->seq = seq;
msg->ack = error;
r = send(cn_fd, nlh, NLMSG_LENGTH(sizeof(struct cn_msg)), 0);
/* FIXME: do better error processing */
if (r <= 0)
return -EBADE;
return 0;
}
/*
* kernel_recv
* @rq: the newly allocated request from kernel
*
* Read requests from the kernel and allocate space for the new request.
* If there is no request from the kernel, *rq is NULL.
*
* This function is not thread safe due to returned stack pointer. In fact,
* the returned pointer must not be in-use when this function is called again.
*
* Returns: 0 on success, -EXXX on error
*/
static int kernel_recv(struct clog_request **rq)
{
int r = 0;
ssize_t len;
char *foo;
struct cn_msg *msg;
struct dm_ulog_request *u_rq;
struct nlmsghdr *nlmsg_h;
*rq = NULL;
memset(recv_buf, 0, sizeof(recv_buf));
len = recv(cn_fd, recv_buf, sizeof(recv_buf), 0);
if (len < 0) {
LOG_ERROR("Failed to recv message from kernel");
r = -errno;
goto fail;
}
nlmsg_h = (struct nlmsghdr *)recv_buf;
switch (nlmsg_h->nlmsg_type) {
case NLMSG_ERROR:
LOG_ERROR("Unable to recv message from kernel: NLMSG_ERROR");
r = -EBADE;
goto fail;
case NLMSG_DONE:
msg = (struct cn_msg *)NLMSG_DATA((struct nlmsghdr *)recv_buf);
len -= (ssize_t)sizeof(struct nlmsghdr);
if (len < (ssize_t)sizeof(struct cn_msg)) {
LOG_ERROR("Incomplete request from kernel received");
r = -EBADE;
goto fail;
}
if (msg->len > DM_ULOG_REQUEST_SIZE) {
LOG_ERROR("Not enough space to receive kernel request (%d/%d)",
msg->len, DM_ULOG_REQUEST_SIZE);
r = -EBADE;
goto fail;
}
if (!msg->len)
LOG_ERROR("Zero length message received");
len -= (ssize_t)sizeof(struct cn_msg);
if (len < msg->len)
LOG_ERROR("len = %zd, msg->len = %" PRIu16, len, msg->len);
msg->data[msg->len] = '\0'; /* Cleaner way to ensure this? */
u_rq = (struct dm_ulog_request *)msg->data;
if (!u_rq->request_type) {
LOG_DBG("Bad transmission, requesting resend [%u]",
msg->seq);
r = -EAGAIN;
if (kernel_ack(msg->seq, EAGAIN)) {
LOG_ERROR("Failed to NACK kernel transmission [%u]",
msg->seq);
r = -EBADE;
}
}
/*
* Now we've got sizeof(struct cn_msg) + sizeof(struct nlmsghdr)
* worth of space that precede the request structure from the
* kernel. Since that space isn't going to be used again, we
* can take it for our purposes; rather than allocating a whole
* new structure and doing a memcpy.
*
* We should really make sure 'clog_request' doesn't grow
* beyond what is available to us, but we need only check it
* once... perhaps at compile time?
*/
foo = (char *)u_rq;
foo -= (sizeof(struct clog_request) - sizeof(struct dm_ulog_request));
*rq = (struct clog_request *) foo;
/* Clear the wrapper container fields */
memset(*rq, 0, (size_t)((char *)u_rq - (char *)(*rq)));
break;
default:
LOG_ERROR("Unknown nlmsg_type");
r = -EBADE;
}
fail:
if (r)
*rq = NULL;
return (r == -EAGAIN) ? 0 : r;
}
static int kernel_send_helper(void *data, uint16_t out_size)
{
int r;
struct nlmsghdr *nlh;
struct cn_msg *msg;
memset(send_buf, 0, sizeof(send_buf));
nlh = (struct nlmsghdr *)send_buf;
nlh->nlmsg_seq = 0; /* FIXME: Is this used? */
nlh->nlmsg_pid = getpid();
nlh->nlmsg_type = NLMSG_DONE;
nlh->nlmsg_len = NLMSG_LENGTH(out_size + sizeof(struct cn_msg));
nlh->nlmsg_flags = 0;
msg = NLMSG_DATA(nlh);
memcpy(msg->data, data, out_size);
msg->len = out_size;
msg->id.idx = CN_IDX_DM;
msg->id.val = CN_VAL_DM_USERSPACE_LOG;
msg->seq = 0;
r = send(cn_fd, nlh, NLMSG_LENGTH(out_size + sizeof(struct cn_msg)), 0);
/* FIXME: do better error processing */
if (r <= 0)
return -EBADE;
return 0;
}
/*
* do_local_work
*
* Any processing errors are placed in the 'rq'
* structure to be reported back to the kernel.
* It may be pointless for this function to
* return an int.
*
* Returns: 0 on success, -EXXX on failure
*/
static int do_local_work(void *data __attribute__((unused)))
{
int r;
struct clog_request *rq;
struct dm_ulog_request *u_rq = NULL;
r = kernel_recv(&rq);
if (r)
return r;
if (!rq)
return 0;
u_rq = &rq->u_rq;
LOG_DBG("[%s] Request from kernel received: [%s/%u]",
SHORT_UUID(u_rq->uuid), RQ_TYPE(u_rq->request_type),
u_rq->seq);
switch (u_rq->request_type) {
case DM_ULOG_CTR:
case DM_ULOG_DTR:
case DM_ULOG_GET_REGION_SIZE:
case DM_ULOG_IN_SYNC:
case DM_ULOG_GET_SYNC_COUNT:
case DM_ULOG_STATUS_TABLE:
case DM_ULOG_PRESUSPEND:
/* We do not specify ourselves as server here */
r = do_request(rq, 0);
if (r)
LOG_DBG("Returning failed request to kernel [%s]",
RQ_TYPE(u_rq->request_type));
r = kernel_send(u_rq);
if (r)
LOG_ERROR("Failed to respond to kernel [%s]",
RQ_TYPE(u_rq->request_type));
break;
case DM_ULOG_RESUME:
/*
* Resume is a special case that requires a local
* component to join the CPG, and a cluster component
* to handle the request.
*/
r = local_resume(u_rq);
if (r) {
LOG_DBG("Returning failed request to kernel [%s]",
RQ_TYPE(u_rq->request_type));
r = kernel_send(u_rq);
if (r)
LOG_ERROR("Failed to respond to kernel [%s]",
RQ_TYPE(u_rq->request_type));
break;
}
/* ELSE, fall through */
case DM_ULOG_IS_CLEAN:
case DM_ULOG_FLUSH:
case DM_ULOG_MARK_REGION:
case DM_ULOG_GET_RESYNC_WORK:
case DM_ULOG_SET_REGION_SYNC:
case DM_ULOG_STATUS_INFO:
case DM_ULOG_IS_REMOTE_RECOVERING:
case DM_ULOG_POSTSUSPEND:
r = cluster_send(rq);
if (r) {
u_rq->data_size = 0;
u_rq->error = r;
if (kernel_send(u_rq))
LOG_ERROR("Failed to respond to kernel [%s]",
RQ_TYPE(u_rq->request_type));
}
break;
case DM_ULOG_CLEAR_REGION:
r = kernel_ack(u_rq->seq, 0);
r = cluster_send(rq);
if (r) {
/*
* FIXME: store error for delivery on flush
* This would allow us to optimize MARK_REGION
* too.
*/
}
break;
default:
LOG_ERROR("Invalid log request received (%u), ignoring.",
u_rq->request_type);
return 0;
}
if (r && !u_rq->error)
u_rq->error = r;
return r;
}
/*
* kernel_send
* @u_rq: result to pass back to kernel
*
* This function returns the u_rq structure
* (containing the results) to the kernel.
* It then frees the structure.
*
* WARNING: should the structure be freed if
* there is an error? I vote 'yes'. If the
* kernel doesn't get the response, it should
* resend the request.
*
* Returns: 0 on success, -EXXX on failure
*/
int kernel_send(struct dm_ulog_request *u_rq)
{
int r;
uint16_t size;
if (!u_rq)
return -EINVAL;
size = (uint16_t)(sizeof(struct dm_ulog_request) + u_rq->data_size);
if (!u_rq->data_size && !u_rq->error) {
/* An ACK is all that is needed */
/* FIXME: add ACK code */
} else if (size > DM_ULOG_REQUEST_SIZE) {
/*
* If we gotten here, we've already overrun
* our allotted space somewhere.
*
* We must do something, because the kernel
* is waiting for a response.
*/
LOG_ERROR("Not enough space to respond to server");
u_rq->error = -ENOSPC;
size = sizeof(struct dm_ulog_request);
}
r = kernel_send_helper(u_rq, size);
if (r)
LOG_ERROR("Failed to send msg to kernel.");
return r;
}
/*
* init_local
*
* Initialize kernel communication socket (netlink)
*
* Returns: 0 on success, values from common.h on failure
*/
int init_local(void)
{
int r = 0;
unsigned opt;
struct sockaddr_nl addr;
cn_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
if (cn_fd < 0)
return EXIT_KERNEL_SOCKET;
/* memset to fix valgrind complaint */
memset(&addr, 0, sizeof(struct sockaddr_nl));
addr.nl_family = AF_NETLINK;
addr.nl_groups = CN_IDX_DM;
addr.nl_pid = 0;
r = bind(cn_fd, (struct sockaddr *) &addr, sizeof(addr));
if (r < 0) {
if (close(cn_fd))
LOG_ERROR("Failed to close socket: %s",
strerror(errno));
return EXIT_KERNEL_BIND;
}
opt = addr.nl_groups;
r = setsockopt(cn_fd, 270, NETLINK_ADD_MEMBERSHIP, &opt, sizeof(opt));
if (r) {
if (close(cn_fd))
LOG_ERROR("Failed to close socket: %s",
strerror(errno));
return EXIT_KERNEL_SETSOCKOPT;
}
/*
r = fcntl(cn_fd, F_SETFL, FNDELAY);
*/
links_register(cn_fd, "local", do_local_work, NULL);
return 0;
}
/*
* cleanup_local
*
* Clean up before exiting
*/
void cleanup_local(void)
{
links_unregister(cn_fd);
if (cn_fd >= 0 && close(cn_fd))
LOG_ERROR("Failed to close socket: %s",
strerror(errno));
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright (C) 2004-2009 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 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_CLOG_LOCAL_H
#define _LVM_CLOG_LOCAL_H
int init_local(void);
void cleanup_local(void);
int kernel_send(struct dm_ulog_request *rq);
#endif /* _LVM_CLOG_LOCAL_H */

View File

@@ -1,57 +0,0 @@
/*
* Copyright (C) 2004-2009 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 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 "logging.h"
const char *__rq_types_off_by_one[] = {
"DM_ULOG_CTR",
"DM_ULOG_DTR",
"DM_ULOG_PRESUSPEND",
"DM_ULOG_POSTSUSPEND",
"DM_ULOG_RESUME",
"DM_ULOG_GET_REGION_SIZE",
"DM_ULOG_IS_CLEAN",
"DM_ULOG_IN_SYNC",
"DM_ULOG_FLUSH",
"DM_ULOG_MARK_REGION",
"DM_ULOG_CLEAR_REGION",
"DM_ULOG_GET_RESYNC_WORK",
"DM_ULOG_SET_REGION_SYNC",
"DM_ULOG_GET_SYNC_COUNT",
"DM_ULOG_STATUS_INFO",
"DM_ULOG_STATUS_TABLE",
"DM_ULOG_IS_REMOTE_RECOVERING",
NULL
};
int log_tabbing = 0;
int log_is_open = 0;
/*
* Variables for various conditional logging
*/
#ifdef MEMB
int log_membership_change = 1;
#else
int log_membership_change = 0;
#endif
#ifdef CKPT
int log_checkpoint = 1;
#else
int log_checkpoint = 0;
#endif
#ifdef RESEND
int log_resend_requests = 1;
#else
int log_resend_requests = 0;
#endif

View File

@@ -1,77 +0,0 @@
/*
* Copyright (C) 2004-2009 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 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_CLOG_LOGGING_H
#define _LVM_CLOG_LOGGING_H
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include "configure.h"
#include <stdio.h>
#include <stdint.h>
#include <syslog.h>
/* SHORT_UUID - print last 8 chars of a string */
#define SHORT_UUID(x) (strlen(x) > 8) ? ((x) + (strlen(x) - 8)) : (x)
extern const char *__rq_types_off_by_one[];
#define RQ_TYPE(x) __rq_types_off_by_one[(x) - 1]
extern int log_tabbing;
extern int log_is_open;
extern int log_membership_change;
extern int log_checkpoint;
extern int log_resend_requests;
#define LOG_OPEN(ident, option, facility) do { \
openlog(ident, option, facility); \
log_is_open = 1; \
} while (0)
#define LOG_CLOSE(void) do { \
log_is_open = 0; \
closelog(); \
} while (0)
#define LOG_OUTPUT(level, f, arg...) do { \
int __i; \
char __buffer[16]; \
FILE *fp = (level > LOG_NOTICE) ? stderr : stdout; \
if (log_is_open) { \
for (__i = 0; (__i < log_tabbing) && (__i < 15); __i++) \
__buffer[__i] = '\t'; \
__buffer[__i] = '\0'; \
syslog(level, "%s" f "\n", __buffer, ## arg); \
} else { \
for (__i = 0; __i < log_tabbing; __i++) \
fprintf(fp, "\t"); \
fprintf(fp, f "\n", ## arg); \
} \
} while (0)
#ifdef DEBUG
#define LOG_DBG(f, arg...) LOG_OUTPUT(LOG_DEBUG, f, ## arg)
#else /* DEBUG */
#define LOG_DBG(f, arg...) do {} while (0)
#endif /* DEBUG */
#define LOG_COND(__X, f, arg...) do {\
if (__X) { \
LOG_OUTPUT(LOG_NOTICE, f, ## arg); \
} \
} while (0)
#define LOG_PRINT(f, arg...) LOG_OUTPUT(LOG_NOTICE, f, ## arg)
#define LOG_ERROR(f, arg...) LOG_OUTPUT(LOG_ERR, f, ## arg)
#endif /* _LVM_CLOG_LOGGING_H */

View File

@@ -1,4 +0,0 @@
init_fifos
fini_fifos
daemon_talk
dm_event_get_version

View File

@@ -1,110 +0,0 @@
#
# Copyright (C) 2005-2011 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@
top_builddir = @top_builddir@
SOURCES = libdevmapper-event.c
SOURCES2 = dmeventd.c
TARGETS = dmeventd
.PHONY: install_lib_dynamic install_lib_static install_include \
install_pkgconfig install_dmeventd_dynamic install_dmeventd_static \
install_lib install_dmeventd
INSTALL_DMEVENTD_TARGETS = install_dmeventd_dynamic
INSTALL_LIB_TARGETS = install_lib_dynamic
LIB_NAME = libdevmapper-event
ifeq ("@STATIC_LINK@", "yes")
LIB_STATIC = $(LIB_NAME).a
TARGETS += $(LIB_STATIC) dmeventd.static
INSTALL_DMEVENTD_TARGETS += install_dmeventd_static
INSTALL_LIB_TARGETS += install_lib_static
endif
LIB_VERSION = $(LIB_VERSION_DM)
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
CLEAN_TARGETS = dmeventd.static $(LIB_NAME).a
ifneq ($(MAKECMDGOALS),device-mapper)
SUBDIRS+=plugins
endif
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
CFLOW_TARGET = dmeventd
EXPORTED_HEADER = $(srcdir)/libdevmapper-event.h
EXPORTED_FN_PREFIX = dm_event
include $(top_builddir)/make.tmpl
all: device-mapper
device-mapper: $(TARGETS)
LIBS += -ldevmapper
LVMLIBS += -ldevmapper-event $(PTHREAD_LIBS)
CFLAGS_dmeventd.o += $(EXTRA_EXEC_CFLAGS)
dmeventd: $(LIB_SHARED) dmeventd.o
$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) -L. -o $@ dmeventd.o \
$(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
dmeventd.static: $(LIB_STATIC) dmeventd.o $(interfacebuilddir)/libdevmapper.a
$(CC) $(CFLAGS) $(LDFLAGS) $(ELDFLAGS) -static -L. -L$(interfacebuilddir) -o $@ \
dmeventd.o $(DL_LIBS) $(LVMLIBS) $(LIBS) $(STATIC_LIBS)
ifeq ("@PKGCONFIG@", "yes")
INSTALL_LIB_TARGETS += install_pkgconfig
endif
ifneq ("$(CFLOW_CMD)", "")
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
-include $(top_builddir)/libdm/libdevmapper.cflow
-include $(top_builddir)/lib/liblvm-internal.cflow
-include $(top_builddir)/lib/liblvm2cmd.cflow
-include $(top_builddir)/daemons/dmeventd/$(LIB_NAME).cflow
-include $(top_builddir)/daemons/dmeventd/plugins/mirror/$(LIB_NAME)-lvm2mirror.cflow
endif
install_include: $(srcdir)/libdevmapper-event.h
$(INSTALL_DATA) -D $< $(includedir)/$(<F)
install_pkgconfig: libdevmapper-event.pc
$(INSTALL_DATA) -D $< $(pkgconfigdir)/devmapper-event.pc
install_lib_dynamic: install_lib_shared
install_lib_static: $(LIB_STATIC)
$(INSTALL_DATA) -D $< $(usrlibdir)/$(<F)
install_lib: $(INSTALL_LIB_TARGETS)
install_dmeventd_dynamic: dmeventd
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_dmeventd_static: dmeventd.static
$(INSTALL_PROGRAM) -D $< $(staticdir)/$(<F)
install_dmeventd: $(INSTALL_DMEVENTD_TARGETS)
install: install_include install_lib install_dmeventd
install_device-mapper: install_include install_lib install_dmeventd
DISTCLEAN_TARGETS += libdevmapper-event.pc

File diff suppressed because it is too large Load Diff

View File

@@ -1,76 +0,0 @@
/*
* Copyright (C) 2005-2007 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
*/
#ifndef __DMEVENTD_DOT_H__
#define __DMEVENTD_DOT_H__
/* FIXME This stuff must be configurable. */
#define DM_EVENT_FIFO_CLIENT DEFAULT_DM_RUN_DIR "/dmeventd-client"
#define DM_EVENT_FIFO_SERVER DEFAULT_DM_RUN_DIR "/dmeventd-server"
#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,
DM_EVENT_CMD_HELLO,
DM_EVENT_CMD_DIE,
DM_EVENT_CMD_GET_STATUS,
DM_EVENT_CMD_GET_PARAMETERS,
};
/* Message passed between client and daemon. */
struct dm_event_daemon_message {
uint32_t cmd;
uint32_t size;
char *data;
};
/* 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;
};
/* EXIT_SUCCESS 0 -- stdlib.h */
/* EXIT_FAILURE 1 -- stdlib.h */
/* EXIT_LOCKFILE_INUSE 2 -- obsoleted */
#define EXIT_DESC_CLOSE_FAILURE 3
#define EXIT_DESC_OPEN_FAILURE 4
/* EXIT_OPEN_PID_FAILURE 5 -- obsoleted */
#define EXIT_FIFO_FAILURE 6
#define EXIT_CHDIR_FAILURE 7
/* Implemented in libdevmapper-event.c, but not part of public API. */
// FIXME misuse of bitmask as enum
int daemon_talk(struct dm_event_fifos *fifos,
struct dm_event_daemon_message *msg, int cmd,
const char *dso_name, const char *dev_name,
enum dm_event_mask evmask, uint32_t timeout);
int init_fifos(struct dm_event_fifos *fifos);
void fini_fifos(struct dm_event_fifos *fifos);
int dm_event_get_version(struct dm_event_fifos *fifos, int *version);
#endif /* __DMEVENTD_DOT_H__ */

View File

@@ -1,875 +0,0 @@
/*
* Copyright (C) 2005-2007 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 "dmlib.h"
#include "libdevmapper-event.h"
//#include "libmultilog.h"
#include "dmeventd.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
#include <arpa/inet.h> /* for htonl, ntohl */
static int _sequence_nr = 0;
struct dm_event_handler {
char *dso;
char *dmeventd_path;
char *dev_name;
char *uuid;
int major;
int minor;
uint32_t timeout;
enum dm_event_mask mask;
};
static void _dm_event_handler_clear_dev_info(struct dm_event_handler *dmevh)
{
dm_free(dmevh->dev_name);
dm_free(dmevh->uuid);
dmevh->dev_name = dmevh->uuid = NULL;
dmevh->major = dmevh->minor = 0;
}
struct dm_event_handler *dm_event_handler_create(void)
{
struct dm_event_handler *dmevh;
if (!(dmevh = dm_zalloc(sizeof(*dmevh)))) {
log_error("Failed to allocate event handler.");
return NULL;
}
return dmevh;
}
void dm_event_handler_destroy(struct dm_event_handler *dmevh)
{
_dm_event_handler_clear_dev_info(dmevh);
dm_free(dmevh->dso);
dm_free(dmevh->dmeventd_path);
dm_free(dmevh);
}
int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path)
{
if (!dmeventd_path) /* noop */
return 0;
dm_free(dmevh->dmeventd_path);
if (!(dmevh->dmeventd_path = dm_strdup(dmeventd_path)))
return -ENOMEM;
return 0;
}
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path)
{
if (!path) /* noop */
return 0;
dm_free(dmevh->dso);
if (!(dmevh->dso = dm_strdup(path)))
return -ENOMEM;
return 0;
}
int dm_event_handler_set_dev_name(struct dm_event_handler *dmevh, const char *dev_name)
{
if (!dev_name)
return 0;
_dm_event_handler_clear_dev_info(dmevh);
if (!(dmevh->dev_name = dm_strdup(dev_name)))
return -ENOMEM;
return 0;
}
int dm_event_handler_set_uuid(struct dm_event_handler *dmevh, const char *uuid)
{
if (!uuid)
return 0;
_dm_event_handler_clear_dev_info(dmevh);
if (!(dmevh->uuid = dm_strdup(uuid)))
return -ENOMEM;
return 0;
}
void dm_event_handler_set_major(struct dm_event_handler *dmevh, int major)
{
int minor = dmevh->minor;
_dm_event_handler_clear_dev_info(dmevh);
dmevh->major = major;
dmevh->minor = minor;
}
void dm_event_handler_set_minor(struct dm_event_handler *dmevh, int minor)
{
int major = dmevh->major;
_dm_event_handler_clear_dev_info(dmevh);
dmevh->major = major;
dmevh->minor = minor;
}
void dm_event_handler_set_event_mask(struct dm_event_handler *dmevh,
enum dm_event_mask evmask)
{
dmevh->mask = evmask;
}
void dm_event_handler_set_timeout(struct dm_event_handler *dmevh, int timeout)
{
dmevh->timeout = timeout;
}
const char *dm_event_handler_get_dso(const struct dm_event_handler *dmevh)
{
return dmevh->dso;
}
const char *dm_event_handler_get_dev_name(const struct dm_event_handler *dmevh)
{
return dmevh->dev_name;
}
const char *dm_event_handler_get_uuid(const struct dm_event_handler *dmevh)
{
return dmevh->uuid;
}
int dm_event_handler_get_major(const struct dm_event_handler *dmevh)
{
return dmevh->major;
}
int dm_event_handler_get_minor(const struct dm_event_handler *dmevh)
{
return dmevh->minor;
}
int dm_event_handler_get_timeout(const struct dm_event_handler *dmevh)
{
return dmevh->timeout;
}
enum dm_event_mask dm_event_handler_get_event_mask(const struct dm_event_handler *dmevh)
{
return dmevh->mask;
}
static int _check_message_id(struct dm_event_daemon_message *msg)
{
int pid, seq_nr;
if ((sscanf(msg->data, "%d:%d", &pid, &seq_nr) != 2) ||
(pid != getpid()) || (seq_nr != _sequence_nr)) {
log_error("Ignoring out-of-sequence reply from dmeventd. "
"Expected %d:%d but received %s", getpid(),
_sequence_nr, msg->data);
return 0;
}
return 1;
}
/*
* 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, i;
fd_set fds;
size_t size = 2 * sizeof(uint32_t); /* status + size */
uint32_t *header = alloca(size);
char *buf = (char *)header;
while (bytes < size) {
for (i = 0, ret = 0; (i < 20) && (ret < 1); i++) {
/* Watch daemon read FIFO for input. */
struct timeval tval = { .tv_sec = 1 };
FD_ZERO(&fds);
FD_SET(fifos->server, &fds);
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
if (ret < 0 && errno != EINTR) {
log_error("Unable to read from event server");
return 0;
}
if ((ret == 0) && (i > 4) && !bytes) {
log_error("No input from event server.");
return 0;
}
}
if (ret < 1) {
log_error("Unable to read from event server.");
return 0;
}
ret = read(fifos->server, buf + bytes, size);
if (ret < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
else {
log_error("Unable to read from event server.");
return 0;
}
}
bytes += ret;
if (header && (bytes == 2 * sizeof(uint32_t))) {
msg->cmd = ntohl(header[0]);
msg->size = ntohl(header[1]);
buf = msg->data = dm_malloc(msg->size);
size = msg->size;
bytes = 0;
header = 0;
}
}
if (bytes != size) {
dm_free(msg->data);
msg->data = NULL;
}
return bytes == size;
}
/* Write message to daemon. */
static int _daemon_write(struct dm_event_fifos *fifos,
struct dm_event_daemon_message *msg)
{
int ret;
fd_set fds;
size_t bytes = 0;
size_t size = 2 * sizeof(uint32_t) + msg->size;
uint32_t *header = alloca(size);
char *buf = (char *)header;
char drainbuf[128];
header[0] = htonl(msg->cmd);
header[1] = htonl(msg->size);
memcpy(buf + 2 * sizeof(uint32_t), msg->data, msg->size);
/* drain the answer fifo */
while (1) {
struct timeval tval = { .tv_usec = 100 };
FD_ZERO(&fds);
FD_SET(fifos->server, &fds);
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
if (ret < 0) {
if (errno == EINTR)
continue;
log_error("Unable to talk to event daemon");
return 0;
}
if (ret == 0)
break;
ret = read(fifos->server, drainbuf, sizeof(drainbuf));
if (ret < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
log_error("Unable to talk to event daemon");
return 0;
}
}
while (bytes < size) {
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)) {
log_error("Unable to talk to event daemon");
return 0;
}
} while (ret < 1);
ret = write(fifos->client, buf + bytes, size - bytes);
if (ret < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
else {
log_error("Unable to talk to event daemon");
return 0;
}
}
bytes += ret;
}
return bytes == size;
}
int daemon_talk(struct dm_event_fifos *fifos,
struct dm_event_daemon_message *msg, int cmd,
const char *dso_name, const char *dev_name,
enum dm_event_mask evmask, uint32_t timeout)
{
int msg_size;
memset(msg, 0, sizeof(*msg));
/*
* Set command and pack the arguments
* into ASCII message string.
*/
if ((msg_size =
((cmd == DM_EVENT_CMD_HELLO) ?
dm_asprintf(&(msg->data), "%d:%d HELLO", getpid(), _sequence_nr) :
dm_asprintf(&(msg->data), "%d:%d %s %s %u %" PRIu32,
getpid(), _sequence_nr,
dso_name ? : "-", dev_name ? : "-", evmask, timeout)))
< 0) {
log_error("_daemon_talk: message allocation failed");
return -ENOMEM;
}
msg->cmd = cmd;
msg->size = msg_size;
/*
* Write command and message to and
* read status return code from daemon.
*/
if (!_daemon_write(fifos, msg)) {
stack;
dm_free(msg->data);
msg->data = NULL;
return -EIO;
}
do {
dm_free(msg->data);
msg->data = NULL;
if (!_daemon_read(fifos, msg)) {
stack;
return -EIO;
}
} while (!_check_message_id(msg));
_sequence_nr++;
return (int32_t) msg->cmd;
}
/*
* start_daemon
*
* This function forks off a process (dmeventd) that will handle
* the events. I am currently test opening one of the fifos to
* ensure that the daemon is running and listening... I thought
* this would be less expensive than fork/exec'ing every time.
* Perhaps there is an even quicker/better way (no, checking the
* lock file is _not_ a better way).
*
* Returns: 1 on success, 0 otherwise
*/
static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
{
int pid, ret = 0;
int status;
struct stat statbuf;
char default_dmeventd_path[] = DMEVENTD_PATH;
char *args[] = { dmeventd_path ? : default_dmeventd_path, NULL };
if (stat(fifos->client_path, &statbuf))
goto start_server;
if (!S_ISFIFO(statbuf.st_mode)) {
log_error("%s is not a fifo.", fifos->client_path);
return 0;
}
/* Anyone listening? If not, errno will be ENXIO */
fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK);
if (fifos->client >= 0) {
/* server is running and listening */
if (close(fifos->client))
log_sys_debug("close", fifos->client_path);
return 1;
} else if (errno != ENXIO) {
/* problem */
log_sys_error("open", fifos->client_path);
return 0;
}
start_server:
/* server is not running */
if ((args[0][0] == '/') && stat(args[0], &statbuf)) {
log_sys_error("stat", args[0]);
return 0;
}
pid = fork();
if (pid < 0)
log_sys_error("fork", "");
else if (!pid) {
execvp(args[0], args);
log_error("Unable to exec dmeventd: %s", strerror(errno));
_exit(EXIT_FAILURE);
} else {
if (waitpid(pid, &status, 0) < 0)
log_error("Unable to start dmeventd: %s",
strerror(errno));
else if (WEXITSTATUS(status))
log_error("Unable to start dmeventd.");
else
ret = 1;
}
return ret;
}
int init_fifos(struct dm_event_fifos *fifos)
{
/* FIXME? Is fifo the most suitable method? Why not share
comms/daemon code with something else e.g. multipath? */
/* Open the fifo used to read from the daemon. */
if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
log_sys_error("open", fifos->server_path);
return 0;
}
/* Lock out anyone else trying to do communication with the daemon. */
if (flock(fifos->server, LOCK_EX) < 0) {
log_sys_error("flock", fifos->server_path);
goto bad;
}
/* if ((fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK)) < 0) {*/
if ((fifos->client = open(fifos->client_path, O_RDWR | O_NONBLOCK)) < 0) {
log_sys_error("open", fifos->client_path);
goto bad;
}
return 1;
bad:
if (close(fifos->server))
log_sys_debug("close", fifos->server_path);
fifos->server = -1;
return 0;
}
/* Initialize client. */
static int _init_client(char *dmeventd_path, struct dm_event_fifos *fifos)
{
if (!_start_daemon(dmeventd_path, fifos))
return_0;
return init_fifos(fifos);
}
void fini_fifos(struct dm_event_fifos *fifos)
{
if (fifos->client >= 0 && close(fifos->client))
log_sys_debug("close", fifos->client_path);
if (fifos->server >= 0) {
if (flock(fifos->server, LOCK_UN))
log_sys_debug("flock unlock", fifos->server_path);
if (close(fifos->server))
log_sys_debug("close", fifos->server_path);
}
}
/* Get uuid of a device */
static struct dm_task *_get_device_info(const struct dm_event_handler *dmevh)
{
struct dm_task *dmt;
struct dm_info info;
if (!(dmt = dm_task_create(DM_DEVICE_INFO))) {
log_error("_get_device_info: dm_task creation for info failed");
return NULL;
}
if (dmevh->uuid) {
if (!dm_task_set_uuid(dmt, dmevh->uuid))
goto_bad;
} else if (dmevh->dev_name) {
if (!dm_task_set_name(dmt, dmevh->dev_name))
goto_bad;
} else if (dmevh->major && dmevh->minor) {
if (!dm_task_set_major(dmt, dmevh->major) ||
!dm_task_set_minor(dmt, dmevh->minor))
goto_bad;
}
/* FIXME Add name or uuid or devno to messages */
if (!dm_task_run(dmt)) {
log_error("_get_device_info: dm_task_run() failed");
goto bad;
}
if (!dm_task_get_info(dmt, &info)) {
log_error("_get_device_info: failed to get info for device");
goto bad;
}
if (!info.exists) {
log_error("_get_device_info: %s%s%s%.0d%s%.0d%s%s: device not found",
dmevh->uuid ? : "",
(!dmevh->uuid && dmevh->dev_name) ? dmevh->dev_name : "",
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? "(" : "",
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? dmevh->major : 0,
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? ":" : "",
(!dmevh->uuid && !dmevh->dev_name && dmevh->minor > 0) ? dmevh->minor : 0,
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) && dmevh->minor == 0 ? "0" : "",
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? ") " : "");
goto bad;
}
return dmt;
bad:
dm_task_destroy(dmt);
return NULL;
}
/* Handle the event (de)registration call and return negative error codes. */
static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_message *msg,
const char *dso_name, const char *dev_name,
enum dm_event_mask evmask, uint32_t timeout)
{
int ret;
struct dm_event_fifos fifos = {
.server = -1,
.client = -1,
/* FIXME Make these either configurable or depend directly on dmeventd_path */
.client_path = DM_EVENT_FIFO_CLIENT,
.server_path = DM_EVENT_FIFO_SERVER
};
if (!_init_client(dmeventd_path, &fifos)) {
stack;
return -ESRCH;
}
ret = daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0);
dm_free(msg->data);
msg->data = 0;
if (!ret)
ret = daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout);
/* what is the opposite of init? */
fini_fifos(&fifos);
return ret;
}
/* External library interface. */
int dm_event_register_handler(const struct dm_event_handler *dmevh)
{
int ret = 1, err;
const char *uuid;
struct dm_task *dmt;
struct dm_event_daemon_message msg = { 0 };
if (!(dmt = _get_device_info(dmevh)))
return_0;
uuid = dm_task_get_uuid(dmt);
if (!strstr(dmevh->dso, "libdevmapper-event-lvm2thin.so") &&
!strstr(dmevh->dso, "libdevmapper-event-lvm2snapshot.so") &&
!strstr(dmevh->dso, "libdevmapper-event-lvm2mirror.so") &&
!strstr(dmevh->dso, "libdevmapper-event-lvm2raid.so"))
log_warn("WARNING: %s: dmeventd plugins are deprecated", dmevh->dso);
if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
log_error("%s: event registration failed: %s",
dm_task_get_name(dmt),
msg.data ? msg.data : strerror(-err));
ret = 0;
}
dm_free(msg.data);
dm_task_destroy(dmt);
return ret;
}
int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
{
int ret = 1, err;
const char *uuid;
struct dm_task *dmt;
struct dm_event_daemon_message msg = { 0 };
if (!(dmt = _get_device_info(dmevh)))
return_0;
uuid = dm_task_get_uuid(dmt);
if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
log_error("%s: event deregistration failed: %s",
dm_task_get_name(dmt),
msg.data ? msg.data : strerror(-err));
ret = 0;
}
dm_free(msg.data);
dm_task_destroy(dmt);
return ret;
}
/* Fetch a string off src and duplicate it into *dest. */
/* FIXME: move to separate module to share with the daemon. */
static char *_fetch_string(char **src, const int delimiter)
{
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 **uuid, enum dm_event_mask *evmask)
{
char *id;
char *p = msg->data;
if ((id = _fetch_string(&p, ' ')) &&
(*dso_name = _fetch_string(&p, ' ')) &&
(*uuid = _fetch_string(&p, ' '))) {
*evmask = atoi(p);
dm_free(id);
return 0;
}
dm_free(id);
return -ENOMEM;
}
/*
* Returns 0 if handler found; error (-ENOMEM, -ENOENT) otherwise.
*/
int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
{
int ret = 0;
const char *uuid = NULL;
char *reply_dso = NULL, *reply_uuid = NULL;
enum dm_event_mask reply_mask = 0;
struct dm_task *dmt = NULL;
struct dm_event_daemon_message msg = { 0 };
struct dm_info info;
if (!(dmt = _get_device_info(dmevh))) {
log_debug("Device does not exists (uuid=%s, name=%s, %d:%d).",
dmevh->uuid, dmevh->dev_name,
dmevh->major, dmevh->minor);
ret = -ENODEV;
goto fail;
}
uuid = dm_task_get_uuid(dmt);
if (_do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
DM_EVENT_CMD_GET_REGISTERED_DEVICE, dmevh->dmeventd_path,
&msg, dmevh->dso, uuid, dmevh->mask, 0)) {
log_debug("%s: device not registered.", dm_task_get_name(dmt));
ret = -ENOENT;
goto fail;
}
/* FIXME this will probably horribly break if we get
ill-formatted reply */
ret = _parse_message(&msg, &reply_dso, &reply_uuid, &reply_mask);
dm_task_destroy(dmt);
dmt = NULL;
dm_free(msg.data);
msg.data = NULL;
_dm_event_handler_clear_dev_info(dmevh);
if (!reply_uuid) {
ret = -ENXIO; /* dmeventd probably gave us bogus uuid back */
goto fail;
}
if (!(dmevh->uuid = dm_strdup(reply_uuid))) {
ret = -ENOMEM;
goto fail;
}
if (!(dmt = _get_device_info(dmevh))) {
ret = -ENXIO; /* dmeventd probably gave us bogus uuid back */
goto fail;
}
dm_event_handler_set_dso(dmevh, reply_dso);
dm_event_handler_set_event_mask(dmevh, reply_mask);
dm_free(reply_dso);
reply_dso = NULL;
dm_free(reply_uuid);
reply_uuid = NULL;
if (!(dmevh->dev_name = dm_strdup(dm_task_get_name(dmt)))) {
ret = -ENOMEM;
goto fail;
}
if (!dm_task_get_info(dmt, &info)) {
ret = -1;
goto fail;
}
dmevh->major = info.major;
dmevh->minor = info.minor;
dm_task_destroy(dmt);
return ret;
fail:
dm_free(msg.data);
dm_free(reply_dso);
dm_free(reply_uuid);
_dm_event_handler_clear_dev_info(dmevh);
if (dmt)
dm_task_destroy(dmt);
return ret;
}
/*
* You can (and have to) call this at the stage of the protocol where
* daemon_talk(fifos, &msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0)
*
* would be normally sent. This call will parse the version reply from
* dmeventd, in addition to above call. It is not safe to call this at any
* other place in the protocol.
*
* This is an internal function, not exposed in the public API.
*/
int dm_event_get_version(struct dm_event_fifos *fifos, int *version) {
char *p;
struct dm_event_daemon_message msg = { 0 };
if (daemon_talk(fifos, &msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0))
return 0;
p = msg.data;
*version = 0;
if (!p || !(p = strchr(p, ' '))) /* Message ID */
return 0;
if (!(p = strchr(p + 1, ' '))) /* HELLO */
return 0;
if ((p = strchr(p + 1, ' '))) /* HELLO, once more */
*version = atoi(p);
return 1;
}
#if 0 /* left out for now */
static char *_skip_string(char *src, const int delimiter)
{
src = srtchr(src, delimiter);
if (src && *(src + 1))
return src + 1;
return NULL;
}
int dm_event_set_timeout(const char *device_path, uint32_t timeout)
{
struct dm_event_daemon_message msg = { 0 };
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(const char *device_path, uint32_t *timeout)
{
int ret;
struct dm_event_daemon_message msg = { 0 };
if (!device_exists(device_path))
return -ENODEV;
if (!(ret = _do_event(DM_EVENT_CMD_GET_TIMEOUT, &msg, NULL, device_path,
0, 0))) {
char *p = _skip_string(msg.data, ' ');
if (!p) {
log_error("malformed reply from dmeventd '%s'\n",
msg.data);
dm_free(msg.data);
return -EIO;
}
*timeout = atoi(p);
}
dm_free(msg.data);
return ret;
}
#endif

View File

@@ -1,116 +0,0 @@
/*
* Copyright (C) 2005-2007 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>
/*
* Event library interface.
*/
enum dm_event_mask {
DM_EVENT_SETTINGS_MASK = 0x0000FF,
DM_EVENT_SINGLE = 0x000001, /* Report multiple errors just once. */
DM_EVENT_MULTI = 0x000002, /* Report all of them. */
DM_EVENT_ERROR_MASK = 0x00FF00,
DM_EVENT_SECTOR_ERROR = 0x000100, /* Failure on a particular sector. */
DM_EVENT_DEVICE_ERROR = 0x000200, /* Device failure. */
DM_EVENT_PATH_ERROR = 0x000400, /* Failure on an io path. */
DM_EVENT_ADAPTOR_ERROR = 0x000800, /* Failure of a host adaptor. */
DM_EVENT_STATUS_MASK = 0xFF0000,
DM_EVENT_SYNC_STATUS = 0x010000, /* Mirror synchronization completed/failed. */
DM_EVENT_TIMEOUT = 0x020000, /* Timeout has occured */
DM_EVENT_REGISTRATION_PENDING = 0x1000000, /* Monitor thread is setting-up/shutting-down */
};
#define DM_EVENT_ALL_ERRORS DM_EVENT_ERROR_MASK
#define DM_EVENT_PROTOCOL_VERSION 2
struct dm_task;
struct dm_event_handler;
struct dm_event_handler *dm_event_handler_create(void);
void dm_event_handler_destroy(struct dm_event_handler *dmevh);
/*
* Path of shared library to handle events.
*
* All of dmeventd, dso, device_name and uuid strings are duplicated so
* you do not need to keep the pointers valid after the call succeeds.
* They may return -ENOMEM though.
*/
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path);
/*
* Path of dmeventd binary.
*/
int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path);
/*
* Identify the device to monitor by exactly one of device_name, uuid or
* device number. String arguments are duplicated, see above.
*/
int dm_event_handler_set_dev_name(struct dm_event_handler *dmevh, const char *device_name);
int dm_event_handler_set_uuid(struct dm_event_handler *dmevh, const char *uuid);
void dm_event_handler_set_major(struct dm_event_handler *dmevh, int major);
void dm_event_handler_set_minor(struct dm_event_handler *dmevh, int minor);
void dm_event_handler_set_timeout(struct dm_event_handler *dmevh, int timeout);
/*
* Specify mask for events to monitor.
*/
// FIXME misuse of bitmask as enum
void dm_event_handler_set_event_mask(struct dm_event_handler *dmevh,
enum dm_event_mask evmask);
const char *dm_event_handler_get_dso(const struct dm_event_handler *dmevh);
const char *dm_event_handler_get_dev_name(const struct dm_event_handler *dmevh);
const char *dm_event_handler_get_uuid(const struct dm_event_handler *dmevh);
int dm_event_handler_get_major(const struct dm_event_handler *dmevh);
int dm_event_handler_get_minor(const struct dm_event_handler *dmevh);
int dm_event_handler_get_timeout(const struct dm_event_handler *dmevh);
// FIXME misuse of bitmask as enum
enum dm_event_mask dm_event_handler_get_event_mask(const struct dm_event_handler *dmevh);
/* FIXME Review interface (what about this next thing?) */
int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next);
/*
* Initiate monitoring using dmeventd.
*/
int dm_event_register_handler(const struct dm_event_handler *dmevh);
int dm_event_unregister_handler(const struct dm_event_handler *dmevh);
/* Prototypes for DSO interface, see dmeventd.c, struct dso_data for
detailed descriptions. */
// FIXME misuse of bitmask as enum
void process_event(struct dm_task *dmt, enum dm_event_mask evmask, void **user);
int register_device(const char *device_name, const char *uuid, int major, int minor, void **user);
int unregister_device(const char *device_name, const char *uuid, int major,
int minor, void **user);
#endif

View File

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

View File

@@ -1,46 +0,0 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005, 2011 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SUBDIRS += lvm2
ifneq ("@MIRRORS@", "none")
SUBDIRS += mirror
endif
ifneq ("@SNAPSHOTS@", "none")
SUBDIRS += snapshot
endif
ifneq ("@RAID@", "none")
SUBDIRS += raid
endif
ifneq ("@THIN@", "none")
SUBDIRS += thin
endif
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS = lvm2 mirror snapshot raid thin
endif
include $(top_builddir)/make.tmpl
snapshot: lvm2
mirror: lvm2
raid: lvm2
thin: lvm2

View File

@@ -1,7 +0,0 @@
dmeventd_lvm2_init
dmeventd_lvm2_exit
dmeventd_lvm2_lock
dmeventd_lvm2_unlock
dmeventd_lvm2_pool
dmeventd_lvm2_run
dmeventd_lvm2_command

View File

@@ -1,31 +0,0 @@
#
# Copyright (C) 2010-2014 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CLDFLAGS += -L$(top_builddir)/tools
SOURCES = dmeventd_lvm.c
LIB_SHARED = libdevmapper-event-lvm2.$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
include $(top_builddir)/make.tmpl
LIBS += @LVM2CMD_LIB@ -ldevmapper $(PTHREAD_LIBS)
install_lvm2: install_lib_shared
install: install_lvm2

View File

@@ -1,176 +0,0 @@
/*
* Copyright (C) 2010 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 "log.h"
#include "lvm2cmd.h"
#include "dmeventd_lvm.h"
#include <pthread.h>
#include <syslog.h>
extern int dmeventd_debug;
/*
* register_device() is called first and performs initialisation.
* Only one device may be registered or unregistered at a time.
*/
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* Number of active registrations.
*/
static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
/*
* Currently only one event can be processed at a time.
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* FIXME Do not pass things directly to syslog, rather use the existing logging
* facilities to sort logging ... however that mechanism needs to be somehow
* configurable and we don't have that option yet
*/
static void _temporary_log_fn(int level,
const char *file __attribute__((unused)),
int line __attribute__((unused)),
int dm_errno __attribute__((unused)),
const char *message)
{
level &= ~(_LOG_STDERR | _LOG_ONCE);
switch (level) {
case _LOG_DEBUG:
if (dmeventd_debug >= 3)
syslog(LOG_DEBUG, "%s", message);
break;
case _LOG_INFO:
if (dmeventd_debug >= 2)
syslog(LOG_INFO, "%s", message);
break;
case _LOG_NOTICE:
if (dmeventd_debug >= 1)
syslog(LOG_NOTICE, "%s", message);
break;
case _LOG_WARN:
syslog(LOG_WARNING, "%s", message);
break;
case _LOG_ERR:
syslog(LOG_ERR, "%s", message);
break;
default:
syslog(LOG_CRIT, "%s", message);
}
}
void dmeventd_lvm2_lock(void)
{
pthread_mutex_lock(&_event_mutex);
}
void dmeventd_lvm2_unlock(void)
{
pthread_mutex_unlock(&_event_mutex);
}
int dmeventd_lvm2_init(void)
{
int r = 0;
pthread_mutex_lock(&_register_mutex);
/*
* 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)))
goto out;
if (!_lvm_handle) {
lvm2_log_fn(_temporary_log_fn);
if (!(_lvm_handle = lvm2_init())) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
goto out;
}
lvm2_disable_dmeventd_monitoring(_lvm_handle);
/* FIXME Temporary: move to dmeventd core */
lvm2_run(_lvm_handle, "_memlock_inc");
}
_register_count++;
r = 1;
out:
pthread_mutex_unlock(&_register_mutex);
return r;
}
void dmeventd_lvm2_exit(void)
{
pthread_mutex_lock(&_register_mutex);
if (!--_register_count) {
lvm2_run(_lvm_handle, "_memlock_dec");
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
}
pthread_mutex_unlock(&_register_mutex);
}
struct dm_pool *dmeventd_lvm2_pool(void)
{
return _mem_pool;
}
int dmeventd_lvm2_run(const char *cmdline)
{
return (lvm2_run(_lvm_handle, cmdline) == LVM2_COMMAND_SUCCEEDED);
}
int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
const char *cmd, const char *device)
{
char *vg = NULL, *lv = NULL, *layer;
int r;
if (!dm_split_lvm_name(mem, device, &vg, &lv, &layer)) {
syslog(LOG_ERR, "Unable to determine VG name from %s.\n",
device);
return 0;
}
/* strip off the mirror component designations */
if ((layer = strstr(lv, "_mimagetmp")) ||
(layer = strstr(lv, "_mlog")))
*layer = '\0';
r = dm_snprintf(buffer, size, "%s %s/%s", cmd, vg, lv);
dm_pool_free(mem, vg);
if (r < 0) {
syslog(LOG_ERR, "Unable to form LVM command. (too long).\n");
return 0;
}
return 1;
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2010 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
*/
/*
* Wrappers around liblvm2cmd functions for dmeventd plug-ins.
*
* liblvm2cmd is not thread-safe so the locking in this library helps dmeventd
* threads to co-operate in sharing a single instance.
*
* FIXME Either support this properly as a generic liblvm2cmd wrapper or make
* liblvm2cmd thread-safe so this can go away.
*/
#ifndef _DMEVENTD_LVMWRAP_H
#define _DMEVENTD_LVMWRAP_H
struct dm_pool;
int dmeventd_lvm2_init(void);
void dmeventd_lvm2_exit(void);
int dmeventd_lvm2_run(const char *cmdline);
void dmeventd_lvm2_lock(void);
void dmeventd_lvm2_unlock(void);
struct dm_pool *dmeventd_lvm2_pool(void);
int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
const char *cmd, const char *device);
#endif /* _DMEVENTD_LVMWRAP_H */

View File

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

View File

@@ -1,37 +0,0 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005, 2008-2014 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
SOURCES = dmeventd_mirror.c
LIB_NAME = libdevmapper-event-lvm2mirror
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
LIBS += -ldevmapper-event-lvm2 -ldevmapper
install_lvm2: install_dm_plugin
install: install_lvm2

View File

@@ -1,233 +0,0 @@
/*
* Copyright (C) 2005-2012 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 "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include "defaults.h"
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
/* FIXME Replace most syslogs with log_error() style messages and add complete context. */
/* FIXME Reformat to 80 char lines. */
#define ME_IGNORE 0
#define ME_INSYNC 1
#define ME_FAILURE 2
static int _process_status_code(const char status_code, const char *dev_name,
const char *dev_type, int r)
{
/*
* A => Alive - No failures
* D => Dead - A write failure occurred leaving mirror out-of-sync
* F => Flush failed.
* S => Sync - A sychronization failure occurred, mirror out-of-sync
* R => Read - A read failure occurred, mirror data unaffected
* U => Unclassified failure (bug)
*/
if (status_code == 'F') {
syslog(LOG_ERR, "%s device %s flush failed.",
dev_type, dev_name);
r = ME_FAILURE;
} else if (status_code == 'S')
syslog(LOG_ERR, "%s device %s sync failed.",
dev_type, dev_name);
else if (status_code == 'R')
syslog(LOG_ERR, "%s device %s read failed.",
dev_type, dev_name);
else if (status_code != 'A') {
syslog(LOG_ERR, "%s device %s has failed (%c).",
dev_type, dev_name, status_code);
r = ME_FAILURE;
}
return r;
}
static int _get_mirror_event(char *params)
{
int i, r = ME_INSYNC;
char **args = NULL;
char *dev_status_str;
char *log_status_str;
char *sync_str;
char *p = NULL;
int log_argc, num_devs;
/*
* dm core parms: 0 409600 mirror
* Mirror core parms: 2 253:4 253:5 400/400
* New-style failure params: 1 AA
* New-style log params: 3 cluster 253:3 A
* or 3 disk 253:3 A
* or 1 core
*/
/* number of devices */
if (!dm_split_words(params, 1, 0, &p))
goto out_parse;
if (!(num_devs = atoi(p)) ||
(num_devs > DEFAULT_MIRROR_MAX_IMAGES) || (num_devs < 0))
goto out_parse;
p += strlen(p) + 1;
/* devices names + "400/400" + "1 AA" + 1 or 3 log parms + NULL */
args = dm_malloc((num_devs + 7) * sizeof(char *));
if (!args || dm_split_words(p, num_devs + 7, 0, args) < num_devs + 5)
goto out_parse;
/* FIXME: Code differs from lib/mirror/mirrored.c */
dev_status_str = args[2 + num_devs];
log_argc = atoi(args[3 + num_devs]);
log_status_str = args[3 + num_devs + log_argc];
sync_str = args[num_devs];
/* Check for bad mirror devices */
for (i = 0; i < num_devs; i++)
r = _process_status_code(dev_status_str[i], args[i],
i ? "Secondary mirror" : "Primary mirror", r);
/* Check for bad disk log device */
if (log_argc > 1)
r = _process_status_code(log_status_str[0],
args[2 + num_devs + log_argc],
"Log", r);
if (r == ME_FAILURE)
goto out;
p = strstr(sync_str, "/");
if (p) {
p[0] = '\0';
if (strcmp(sync_str, p+1))
r = ME_IGNORE;
p[0] = '/';
} else
goto out_parse;
out:
dm_free(args);
return r;
out_parse:
dm_free(args);
syslog(LOG_ERR, "Unable to parse mirror status string.");
return ME_IGNORE;
}
static int _remove_failed_devices(const char *device)
{
int r;
#define CMD_SIZE 256 /* FIXME Use system restriction */
char cmd_str[CMD_SIZE];
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
"lvconvert --config devices{ignore_suspended_devices=1} "
"--repair --use-policies", device))
return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */
r = dmeventd_lvm2_run(cmd_str);
syslog(LOG_INFO, "Repair of mirrored device %s %s.", device,
(r) ? "finished successfully" : "failed");
return (r) ? 0 : -1;
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **unused __attribute__((unused)))
{
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
const char *device = dm_task_get_name(dmt);
dmeventd_lvm2_lock();
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (!target_type) {
syslog(LOG_INFO, "%s mapping lost.", device);
continue;
}
if (strcmp(target_type, "mirror")) {
syslog(LOG_INFO, "%s has unmirrored portion.", 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.", device);
break;
case ME_FAILURE:
syslog(LOG_ERR, "Device failure in %s.", device);
if (_remove_failed_devices(device))
/* FIXME Why are all the error return codes unused? Get rid of them? */
syslog(LOG_ERR, "Failed to remove faulty devices in %s.",
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:
/* FIXME Provide value then! */
syslog(LOG_INFO, "Unknown event received.");
}
} while (next);
dmeventd_lvm2_unlock();
}
int register_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
{
if (!dmeventd_lvm2_init())
return 0;
syslog(LOG_INFO, "Monitoring mirror device %s for events.", device);
return 1;
}
int unregister_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
{
syslog(LOG_INFO, "No longer monitoring mirror device %s for events.",
device);
dmeventd_lvm2_exit();
return 1;
}

View File

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

View File

@@ -1,36 +0,0 @@
#
# Copyright (C) 2011-2014 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
SOURCES = dmeventd_raid.c
LIB_NAME = libdevmapper-event-lvm2raid
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
LIBS += -ldevmapper-event-lvm2 -ldevmapper
install_lvm2: install_dm_plugin
install: install_lvm2

View File

@@ -1,180 +0,0 @@
/*
* Copyright (C) 2005-2011 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 "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
/* FIXME Replace most syslogs with log_error() style messages and add complete context. */
/* FIXME Reformat to 80 char lines. */
/*
* run_repair is a close copy to
* plugins/mirror/dmeventd_mirror.c:_remove_failed_devices()
*/
static int run_repair(const char *device)
{
int r;
#define CMD_SIZE 256 /* FIXME Use system restriction */
char cmd_str[CMD_SIZE];
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
"lvscan --cache", device))
return -1;
r = dmeventd_lvm2_run(cmd_str);
if (!r)
syslog(LOG_INFO, "Re-scan of RAID device %s failed.", device);
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
"lvconvert --config devices{ignore_suspended_devices=1} "
"--repair --use-policies", device))
return -1;
/* if repair goes OK, report success even if lvscan has failed */
r = dmeventd_lvm2_run(cmd_str);
if (!r)
syslog(LOG_INFO, "Repair of RAID device %s failed.", device);
return (r) ? 0 : -1;
}
static int _process_raid_event(char *params, const char *device)
{
int i, n, failure = 0;
char *p, *a[4];
char *raid_type;
char *num_devices;
char *health_chars;
char *resync_ratio;
/*
* RAID parms: <raid_type> <#raid_disks> \
* <health chars> <resync ratio>
*/
if (!dm_split_words(params, 4, 0, a)) {
syslog(LOG_ERR, "Failed to process status line for %s\n",
device);
return -EINVAL;
}
raid_type = a[0];
num_devices = a[1];
health_chars = a[2];
resync_ratio = a[3];
if (!(n = atoi(num_devices))) {
syslog(LOG_ERR, "Failed to parse number of devices for %s: %s",
device, num_devices);
return -EINVAL;
}
for (i = 0; i < n; i++) {
switch (health_chars[i]) {
case 'A':
/* Device is 'A'live and well */
case 'a':
/* Device is 'a'live, but not yet in-sync */
break;
case 'D':
syslog(LOG_ERR,
"Device #%d of %s array, %s, has failed.",
i, raid_type, device);
failure++;
break;
default:
/* Unhandled character returned from kernel */
break;
}
if (failure)
return run_repair(device);
}
p = strstr(resync_ratio, "/");
if (!p) {
syslog(LOG_ERR, "Failed to parse resync_ratio for %s: %s",
device, resync_ratio);
return -EINVAL;
}
p[0] = '\0';
syslog(LOG_INFO, "%s array, %s, is %s in-sync.",
raid_type, device, strcmp(resync_ratio, p+1) ? "not" : "now");
return 0;
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **unused __attribute__((unused)))
{
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
const char *device = dm_task_get_name(dmt);
dmeventd_lvm2_lock();
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (!target_type) {
syslog(LOG_INFO, "%s mapping lost.", device);
continue;
}
if (strcmp(target_type, "raid")) {
syslog(LOG_INFO, "%s has non-raid portion.", device);
continue;
}
if (_process_raid_event(params, device))
syslog(LOG_ERR, "Failed to process event for %s",
device);
} while (next);
dmeventd_lvm2_unlock();
}
int register_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
{
if (!dmeventd_lvm2_init())
return 0;
syslog(LOG_INFO, "Monitoring RAID device %s for events.", device);
return 1;
}
int unregister_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
{
syslog(LOG_INFO, "No longer monitoring RAID device %s for events.",
device);
dmeventd_lvm2_exit();
return 1;
}

View File

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

View File

@@ -1,33 +0,0 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2014 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@
top_builddir = @top_builddir@
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
SOURCES = dmeventd_snapshot.c
LIB_SHARED = libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
include $(top_builddir)/make.tmpl
LIBS += -ldevmapper-event-lvm2 -ldevmapper
install_lvm2: install_dm_plugin
install: install_lvm2

View File

@@ -1,247 +0,0 @@
/*
* Copyright (C) 2007-2011 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 "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include <sys/wait.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
#include <stdarg.h>
/* FIXME Missing openlog? */
/* First warning when snapshot is 80% full. */
#define WARNING_THRESH 80
/* Run a check every 5%. */
#define CHECK_STEP 5
/* Do not bother checking snapshots less than 50% full. */
#define CHECK_MINIMUM 50
#define UMOUNT_COMMAND "/bin/umount"
struct dso_state {
struct dm_pool *mem;
int percent_check;
uint64_t known_size;
char cmd_str[1024];
};
static int _run(const char *cmd, ...)
{
va_list ap;
int argc = 1; /* for argv[0], i.e. cmd */
int i = 0;
const char **argv;
pid_t pid = fork();
int status;
if (pid == 0) { /* child */
va_start(ap, cmd);
while (va_arg(ap, const char *))
++ argc;
va_end(ap);
/* + 1 for the terminating NULL */
argv = alloca(sizeof(const char *) * (argc + 1));
argv[0] = cmd;
va_start(ap, cmd);
while ((argv[++i] = va_arg(ap, const char *)));
va_end(ap);
execvp(cmd, (char **)argv);
syslog(LOG_ERR, "Failed to execute %s: %s.\n", cmd, strerror(errno));
exit(127);
}
if (pid > 0) { /* parent */
if (waitpid(pid, &status, 0) != pid)
return 0; /* waitpid failed */
if (!WIFEXITED(status) || WEXITSTATUS(status))
return 0; /* the child failed */
}
if (pid < 0)
return 0; /* fork failed */
return 1; /* all good */
}
static int _extend(const char *cmd)
{
return dmeventd_lvm2_run(cmd);
}
static void _umount(const char *device, int major, int minor)
{
FILE *mounts;
char buffer[4096];
char *words[3];
struct stat st;
if (!(mounts = fopen("/proc/mounts", "r"))) {
syslog(LOG_ERR, "Could not read /proc/mounts. Not umounting %s.\n", device);
return;
}
while (!feof(mounts)) {
/* read a line of /proc/mounts */
if (!fgets(buffer, sizeof(buffer), mounts))
break; /* eof, likely */
/* words[0] is the mount point and words[1] is the device path */
if (dm_split_words(buffer, 3, 0, words) < 2)
continue;
/* find the major/minor of the device */
if (stat(words[0], &st))
continue; /* can't stat, skip this one */
if (S_ISBLK(st.st_mode) &&
major(st.st_rdev) == major &&
minor(st.st_rdev) == minor) {
syslog(LOG_ERR, "Unmounting invalid snapshot %s from %s.\n", device, words[1]);
if (!_run(UMOUNT_COMMAND, "-fl", words[1], NULL))
syslog(LOG_ERR, "Failed to umount snapshot %s from %s: %s.\n",
device, words[1], strerror(errno));
}
}
if (fclose(mounts))
syslog(LOG_ERR, "Failed to close /proc/mounts.\n");
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **private)
{
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
struct dm_status_snapshot *status = NULL;
const char *device = dm_task_get_name(dmt);
int percent;
struct dso_state *state = *private;
/* No longer monitoring, waiting for remove */
if (!state->percent_check)
return;
dmeventd_lvm2_lock();
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (!target_type)
goto out;
if (!dm_get_status_snapshot(state->mem, params, &status))
goto out;
if (status->invalid) {
struct dm_info info;
if (dm_task_get_info(dmt, &info)) {
dmeventd_lvm2_unlock();
_umount(device, info.major, info.minor);
return;
} /* else; too bad, but this is best-effort thing... */
}
/* Snapshot size had changed. Clear the threshold. */
if (state->known_size != status->total_sectors) {
state->percent_check = CHECK_MINIMUM;
state->known_size = status->total_sectors;
}
/*
* If the snapshot has been invalidated or we failed to parse
* the status string. Report the full status string to syslog.
*/
if (status->invalid || !status->total_sectors) {
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
state->percent_check = 0;
goto out;
}
percent = (int) (100 * status->used_sectors / status->total_sectors);
if (percent >= state->percent_check) {
/* Usage has raised more than CHECK_STEP since the last
time. Run actions. */
state->percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
/* Try to extend the snapshot, in accord with user-set policies */
if (!_extend(state->cmd_str))
syslog(LOG_ERR, "Failed to extend snapshot %s.\n", device);
}
out:
if (status)
dm_pool_free(state->mem, status);
dmeventd_lvm2_unlock();
}
int register_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **private)
{
struct dm_pool *statemem = NULL;
struct dso_state *state;
if (!dmeventd_lvm2_init())
goto out;
if (!(statemem = dm_pool_create("snapshot_state", 512)) ||
!(state = dm_pool_zalloc(statemem, sizeof(*state))))
goto bad;
if (!dmeventd_lvm2_command(statemem, state->cmd_str,
sizeof(state->cmd_str),
"lvextend --use-policies", device))
goto bad;
state->mem = statemem;
state->percent_check = CHECK_MINIMUM;
*private = state;
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
return 1;
bad:
if (statemem)
dm_pool_destroy(statemem);
dmeventd_lvm2_exit();
out:
syslog(LOG_ERR, "Failed to monitor snapshot %s.\n", device);
return 0;
}
int unregister_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **private)
{
struct dso_state *state = *private;
syslog(LOG_INFO, "No longer monitoring snapshot %s\n", device);
dm_pool_destroy(state->mem);
dmeventd_lvm2_exit();
return 1;
}

View File

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

View File

@@ -1,36 +0,0 @@
#
# Copyright (C) 2011-2014 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
SOURCES = dmeventd_thin.c
LIB_NAME = libdevmapper-event-lvm2thin
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
LIBS += -ldevmapper-event-lvm2 -ldevmapper
install_lvm2: install_dm_plugin
install: install_lvm2

View File

@@ -1,401 +0,0 @@
/*
* Copyright (C) 2011-2013 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 "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include <sys/wait.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
#include <stdarg.h>
/* FIXME Missing openlog? */
/* First warning when thin is 80% full. */
#define WARNING_THRESH 80
/* Run a check every 5%. */
#define CHECK_STEP 5
/* Do not bother checking thins less than 50% full. */
#define CHECK_MINIMUM 50
#define UMOUNT_COMMAND "/bin/umount"
#define THIN_DEBUG 0
struct dso_state {
struct dm_pool *mem;
int metadata_percent_check;
int data_percent_check;
uint64_t known_metadata_size;
uint64_t known_data_size;
char cmd_str[1024];
};
/* TODO - move this mountinfo code into library to be reusable */
#ifdef __linux__
# include "kdev_t.h"
#else
# define MAJOR(x) major((x))
# define MINOR(x) minor((x))
# define MKDEV(x,y) makedev((x),(y))
#endif
/* Get dependencies for device, and try to find matching device */
static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_minor)
{
struct dm_task *dmt;
const struct dm_deps *deps;
struct dm_info info;
int major, minor;
int r = 0;
if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
return 0;
if (!dm_task_set_name(dmt, name))
goto out;
if (!dm_task_no_open_count(dmt))
goto out;
if (!dm_task_run(dmt))
goto out;
if (!dm_task_get_info(dmt, &info))
goto out;
if (!(deps = dm_task_get_deps(dmt)))
goto out;
if (!info.exists || deps->count != 1)
goto out;
major = (int) MAJOR(deps->device[0]);
minor = (int) MINOR(deps->device[0]);
if ((major != tp_major) || (minor != tp_minor))
goto out;
*dev_minor = info.minor;
#if THIN_DEBUG
{
char dev_name[PATH_MAX];
if (dm_device_get_name(major, minor, 0, dev_name, sizeof(dev_name)))
syslog(LOG_DEBUG, "Found %s (%u:%u) depends on %s",
name, major, *dev_minor, dev_name);
}
#endif
r = 1;
out:
dm_task_destroy(dmt);
return r;
}
/* Get all active devices */
static int _find_all_devs(dm_bitset_t bs, int tp_major, int tp_minor)
{
struct dm_task *dmt;
struct dm_names *names;
unsigned next = 0;
int minor, r = 1;
if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
return 0;
if (!dm_task_run(dmt)) {
r = 0;
goto out;
}
if (!(names = dm_task_get_names(dmt))) {
r = 0;
goto out;
}
if (!names->dev)
goto out;
do {
names = (struct dm_names *)((char *) names + next);
if (_has_deps(names->name, tp_major, tp_minor, &minor))
dm_bit_set(bs, minor);
next = names->next;
} while (next);
out:
dm_task_destroy(dmt);
return r;
}
static int _extend(struct dso_state *state)
{
#if THIN_DEBUG
syslog(LOG_INFO, "dmeventd executes: %s.\n", state->cmd_str);
#endif
return dmeventd_lvm2_run(state->cmd_str);
}
static int _run(const char *cmd, ...)
{
va_list ap;
int argc = 1; /* for argv[0], i.e. cmd */
int i = 0;
const char **argv;
pid_t pid = fork();
int status;
if (pid == 0) { /* child */
va_start(ap, cmd);
while (va_arg(ap, const char *))
++argc;
va_end(ap);
/* + 1 for the terminating NULL */
argv = alloca(sizeof(const char *) * (argc + 1));
argv[0] = cmd;
va_start(ap, cmd);
while ((argv[++i] = va_arg(ap, const char *)));
va_end(ap);
execvp(cmd, (char **)argv);
syslog(LOG_ERR, "Failed to execute %s: %s.\n", cmd, strerror(errno));
exit(127);
}
if (pid > 0) { /* parent */
if (waitpid(pid, &status, 0) != pid)
return 0; /* waitpid failed */
if (!WIFEXITED(status) || WEXITSTATUS(status))
return 0; /* the child failed */
}
if (pid < 0)
return 0; /* fork failed */
return 1; /* all good */
}
struct mountinfo_s {
struct dm_info info;
dm_bitset_t minors; /* Bitset for active thin pool minors */
const char *device;
};
static int _umount_device(char *buffer, unsigned major, unsigned minor,
char *target, void *cb_data)
{
struct mountinfo_s *data = cb_data;
if ((major == data->info.major) && dm_bit(data->minors, minor)) {
syslog(LOG_INFO, "Unmounting thin volume %s from %s.\n",
data->device, target);
if (!_run(UMOUNT_COMMAND, "-fl", target, NULL))
syslog(LOG_ERR, "Failed to umount thin %s from %s: %s.\n",
data->device, target, strerror(errno));
}
return 1;
}
/*
* Find all thin pool users and try to umount them.
* TODO: work with read-only thin pool support
*/
static void _umount(struct dm_task *dmt, const char *device)
{
/* TODO: Convert to use hash to reduce memory usage */
static const size_t MINORS = (1U << 20); /* 20 bit */
struct mountinfo_s data = {
.device = device,
};
if (!dm_task_get_info(dmt, &data.info))
return;
dmeventd_lvm2_unlock();
if (!(data.minors = dm_bitset_create(NULL, MINORS))) {
syslog(LOG_ERR, "Failed to allocate bitset. Not unmounting %s.\n", device);
goto out;
}
if (!_find_all_devs(data.minors, data.info.major, data.info.minor)) {
syslog(LOG_ERR, "Failed to detect mounted volumes for %s.\n", device);
goto out;
}
if (!dm_mountinfo_read(_umount_device, &data)) {
syslog(LOG_ERR, "Could not parse mountinfo file.\n");
goto out;
}
out:
if (data.minors)
dm_bitset_destroy(data.minors);
dmeventd_lvm2_lock();
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **private)
{
const char *device = dm_task_get_name(dmt);
int percent;
struct dso_state *state = *private;
struct dm_status_thin_pool *tps = NULL;
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
#if 0
/* No longer monitoring, waiting for remove */
if (!state->meta_percent_check && !state->data_percent_check)
return;
#endif
dmeventd_lvm2_lock();
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (!target_type || (strcmp(target_type, "thin-pool") != 0)) {
syslog(LOG_ERR, "Invalid target type.\n");
goto out;
}
if (!dm_get_status_thin_pool(state->mem, params, &tps)) {
syslog(LOG_ERR, "Failed to parse status.\n");
_umount(dmt, device);
goto out;
}
#if THIN_DEBUG
syslog(LOG_INFO, "%p: Got status %" PRIu64 " / %" PRIu64
" %" PRIu64 " / %" PRIu64 ".\n", state,
tps->used_metadata_blocks, tps->total_metadata_blocks,
tps->used_data_blocks, tps->total_data_blocks);
#endif
/* Thin pool size had changed. Clear the threshold. */
if (state->known_metadata_size != tps->total_metadata_blocks) {
state->metadata_percent_check = CHECK_MINIMUM;
state->known_metadata_size = tps->total_metadata_blocks;
}
if (state->known_data_size != tps->total_data_blocks) {
state->data_percent_check = CHECK_MINIMUM;
state->known_data_size = tps->total_data_blocks;
}
percent = 100 * tps->used_metadata_blocks / tps->total_metadata_blocks;
if (percent >= state->metadata_percent_check) {
/*
* Usage has raised more than CHECK_STEP since the last
* time. Run actions.
*/
state->metadata_percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
/* FIXME: extension of metadata needs to be written! */
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
syslog(LOG_WARNING, "Thin metadata %s is now %i%% full.\n",
device, percent);
/* Try to extend the metadata, in accord with user-set policies */
if (!_extend(state)) {
syslog(LOG_ERR, "Failed to extend thin metadata %s.\n",
device);
_umount(dmt, device);
}
/* FIXME: hmm READ-ONLY switch should happen in error path */
}
percent = 100 * tps->used_data_blocks / tps->total_data_blocks;
if (percent >= state->data_percent_check) {
/*
* Usage has raised more than CHECK_STEP since
* the last time. Run actions.
*/
state->data_percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
syslog(LOG_WARNING, "Thin %s is now %i%% full.\n", device, percent);
/* Try to extend the thin data, in accord with user-set policies */
if (!_extend(state)) {
syslog(LOG_ERR, "Failed to extend thin %s.\n", device);
state->data_percent_check = 0;
_umount(dmt, device);
}
/* FIXME: hmm READ-ONLY switch should happen in error path */
}
out:
if (tps)
dm_pool_free(state->mem, tps);
dmeventd_lvm2_unlock();
}
int register_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **private)
{
struct dm_pool *statemem = NULL;
struct dso_state *state;
if (!dmeventd_lvm2_init())
goto bad;
if (!(statemem = dm_pool_create("thin_pool_state", 2048)) ||
!(state = dm_pool_zalloc(statemem, sizeof(*state))) ||
!dmeventd_lvm2_command(statemem, state->cmd_str,
sizeof(state->cmd_str),
"lvextend --use-policies",
device)) {
if (statemem)
dm_pool_destroy(statemem);
dmeventd_lvm2_exit();
goto bad;
}
state->mem = statemem;
state->metadata_percent_check = CHECK_MINIMUM;
state->data_percent_check = CHECK_MINIMUM;
*private = state;
syslog(LOG_INFO, "Monitoring thin %s.\n", device);
return 1;
bad:
syslog(LOG_ERR, "Failed to monitor thin %s.\n", device);
return 0;
}
int unregister_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **private)
{
struct dso_state *state = *private;
syslog(LOG_INFO, "No longer monitoring thin %s.\n", device);
dm_pool_destroy(state->mem);
dmeventd_lvm2_exit();
return 1;
}

View File

@@ -1,60 +0,0 @@
#
# Copyright (C) 2011-2012 Red Hat, Inc.
#
# 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SOURCES = lvmetad-core.c
SOURCES2 = testclient.c
TARGETS = lvmetad lvmetad-testclient
.PHONY: install_lvmetad
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
CFLOW_TARGET = lvmetad
include $(top_builddir)/make.tmpl
INCLUDES += -I$(top_srcdir)/libdaemon/server
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
LIBS += $(PTHREAD_LIBS)
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS)
CLDFLAGS += -L$(top_builddir)/libdaemon/server
CFLAGS += $(EXTRA_EXEC_CFLAGS)
lvmetad: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
$(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
# TODO: No idea. No idea how to test either.
#ifneq ("$(CFLOW_CMD)", "")
#CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
#-include $(top_builddir)/libdm/libdevmapper.cflow
#-include $(top_builddir)/lib/liblvm-internal.cflow
#-include $(top_builddir)/lib/liblvm2cmd.cflow
#-include $(top_builddir)/daemons/dmeventd/$(LIB_NAME).cflow
#-include $(top_builddir)/daemons/dmeventd/plugins/mirror/$(LIB_NAME)-lvm2mirror.cflow
#endif
install_lvmetad: lvmetad
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_lvm2: install_lvmetad
install: install_lvm2

View File

@@ -1,83 +0,0 @@
/*
* Copyright (C) 2011-2012 Red Hat, Inc.
*
* 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_LVMETAD_CLIENT_H
#define _LVM_LVMETAD_CLIENT_H
#include "daemon-client.h"
#define LVMETAD_SOCKET DEFAULT_RUN_DIR "/lvmetad.socket"
struct volume_group;
/* Different types of replies we may get from lvmetad. */
typedef struct {
daemon_reply r;
const char **uuids; /* NULL terminated array */
} lvmetad_uuidlist;
typedef struct {
daemon_reply r;
struct dm_config_tree *cft;
} lvmetad_vg;
/* Get a list of VG UUIDs that match a given VG name. */
lvmetad_uuidlist lvmetad_lookup_vgname(daemon_handle h, const char *name);
/* Get the metadata of a single VG, identified by UUID. */
lvmetad_vg lvmetad_get_vg(daemon_handle h, const char *uuid);
/*
* Add and remove PVs on demand. Udev-driven systems will use this interface
* instead of scanning.
*/
daemon_reply lvmetad_add_pv(daemon_handle h, const char *pv_uuid, const char *mda_content);
daemon_reply lvmetad_remove_pv(daemon_handle h, const char *pv_uuid);
/* Trigger a full disk scan, throwing away all caches. XXX do we eventually want
* this? Probably not yet, anyway.
* daemon_reply lvmetad_rescan(daemon_handle h);
*/
/*
* Update the version of metadata of a volume group. The VG has to be locked for
* writing for this, and the VG metadata here has to match whatever has been
* written to the disk (under this lock). This initially avoids the requirement
* for lvmetad to write to disk (in later revisions, lvmetad_supersede_vg may
* also do the writing, or we probably add another function to do that).
*/
daemon_reply lvmetad_supersede_vg(daemon_handle h, struct volume_group *vg);
/* Wrappers to open/close connection */
static inline daemon_handle lvmetad_open(const char *socket)
{
daemon_info lvmetad_info = {
.path = "lvmetad",
.socket = socket ?: LVMETAD_SOCKET,
.protocol = "lvmetad",
.protocol_version = 1,
.autostart = 0
};
return daemon_open(lvmetad_info);
}
static inline void lvmetad_close(daemon_handle h)
{
return daemon_close(h);
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +0,0 @@
#!/bin/bash
export LD_LIBRARY_PATH="$1"
test -n "$2" && {
rm -f /var/run/lvmetad.{socket,pid}
chmod +rx lvmetad
valgrind ./lvmetad -f &
PID=$!
sleep 1
./testclient
kill $PID
exit 0
}
sudo ./test.sh "$1" .

View File

@@ -1,127 +0,0 @@
#include "lvmetad-client.h"
#include "label.h"
#include "lvmcache.h"
#include "metadata.h"
const char *uuid1 = "abcd-efgh";
const char *uuid2 = "bbcd-efgh";
const char *vgid = "yada-yada";
const char *uuid3 = "cbcd-efgh";
const char *metadata2 = "{\n"
"id = \"yada-yada\"\n"
"seqno = 15\n"
"status = [\"READ\", \"WRITE\"]\n"
"flags = []\n"
"extent_size = 8192\n"
"physical_volumes {\n"
" pv0 {\n"
" id = \"abcd-efgh\"\n"
" }\n"
" pv1 {\n"
" id = \"bbcd-efgh\"\n"
" }\n"
" pv2 {\n"
" id = \"cbcd-efgh\"\n"
" }\n"
"}\n"
"}\n";
void _handle_reply(daemon_reply reply) {
const char *repl = daemon_reply_str(reply, "response", NULL);
const char *status = daemon_reply_str(reply, "status", NULL);
const char *vgid = daemon_reply_str(reply, "vgid", NULL);
fprintf(stderr, "[C] REPLY: %s\n", repl);
if (!strcmp(repl, "failed"))
fprintf(stderr, "[C] REASON: %s\n", daemon_reply_str(reply, "reason", "unknown"));
if (vgid)
fprintf(stderr, "[C] VGID: %s\n", vgid);
if (status)
fprintf(stderr, "[C] STATUS: %s\n", status);
daemon_reply_destroy(reply);
}
void _pv_add(daemon_handle h, const char *uuid, const char *metadata)
{
daemon_reply reply = daemon_send_simple(h, "pv_add", "uuid = %s", uuid,
"metadata = %b", metadata,
NULL);
_handle_reply(reply);
}
int scan(daemon_handle h, char *fn) {
struct device *dev = dev_cache_get(fn, NULL);
struct label *label;
if (!label_read(dev, &label, 0)) {
fprintf(stderr, "[C] no label found on %s\n", fn);
return;
}
char uuid[64];
id_write_format(dev->pvid, uuid, 64);
fprintf(stderr, "[C] found PV: %s\n", uuid);
struct lvmcache_info *info = (struct lvmcache_info *) label->info;
struct physical_volume pv = { 0, };
if (!(info->fmt->ops->pv_read(info->fmt, dev_name(dev), &pv, 0))) {
fprintf(stderr, "[C] Failed to read PV %s", dev_name(dev));
return;
}
struct format_instance_ctx fic;
struct format_instance *fid = info->fmt->ops->create_instance(info->fmt, &fic);
struct metadata_area *mda;
struct volume_group *vg = NULL;
dm_list_iterate_items(mda, &info->mdas) {
struct volume_group *this = mda->ops->vg_read(fid, "", mda);
if (this && !vg || this->seqno > vg->seqno)
vg = this;
}
if (vg) {
char *buf = NULL;
/* TODO. This is not entirely correct, since export_vg_to_buffer
* adds trailing garbage to the buffer. We may need to use
* export_vg_to_config_tree and format the buffer ourselves. It
* does, however, work for now, since the garbage is well
* formatted and has no conflicting keys with the rest of the
* request. */
export_vg_to_buffer(vg, &buf);
daemon_reply reply =
daemon_send_simple(h, "pv_add", "uuid = %s", uuid,
"metadata = %b", strchr(buf, '{'),
NULL);
_handle_reply(reply);
}
}
void _dump_vg(daemon_handle h, const char *uuid)
{
daemon_reply reply = daemon_send_simple(h, "vg_by_uuid", "uuid = %s", uuid, NULL);
fprintf(stderr, "[C] reply buffer: %s\n", reply.buffer);
daemon_reply_destroy(reply);
}
int main(int argc, char **argv) {
daemon_handle h = lvmetad_open();
if (argc > 1) {
int i;
struct cmd_context *cmd = create_toolcontext(0, NULL, 0, 0);
for (i = 1; i < argc; ++i) {
const char *uuid = NULL;
scan(h, argv[i]);
}
destroy_toolcontext(cmd);
return 0;
}
_pv_add(h, uuid1, NULL);
_pv_add(h, uuid2, metadata2);
_dump_vg(h, vgid);
_pv_add(h, uuid3, NULL);
daemon_close(h);
return 0;
}

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.

82
debian/changelog vendored Normal file
View File

@@ -0,0 +1,82 @@
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)
-- Andres Salomon <dilinger@mp3revolution.net> Sun, 12 May 2002 04:39:06 -0500
lvm2 (0.95.05-2) unstable; urgency=low
* Use ${shlibs:Depends} in Depends.
* Get rid of postinst/postrm scripts, use debhelper's init script instead.
* Add Conflicts against lvm10, lvm-common.
* Fix endian issues on big-endian machines.
-- Andres Salomon <dilinger@mp3revolution.net> Thu, 2 May 2002 23:53:53 -0500
lvm2 (0.95.05-1) unstable; urgency=low
* New release (Beta2).
-- Andres Salomon <dilinger@mp3revolution.net> Thu, 25 Apr 2002 00:37:41 -0500
lvm2 (0.95.04cvs20020306-1) unstable; urgency=low
* CVS updated.
* Convert from debian native package.
-- Andres Salomon <dilinger@mp3revolution.net> Wed, 6 Mar 2002 00:43:21 -0500
lvm2 (0.95.04cvs20020304) unstable; urgency=low
* CVS updated.
* Enhance init script; create devmapper control device, etc.
* Add dmsetup as a suggestion.
* Add /etc/lvm/lvm.conf conffile.
* Add undocumented(7) for the commands missing manpages.
-- Andres Salomon <dilinger@mp3revolution.net> Mon, 4 Mar 2002 04:51:26 -0500
lvm2 (0.95.02cvs20020220) unstable; urgency=low
* Initial Release.
-- Andres Salomon <dilinger@mp3revolution.net> Wed, 20 Feb 2002 03:17:25 -0500

24
debian/control vendored Normal file
View File

@@ -0,0 +1,24 @@
Source: lvm2
Section: admin
Priority: optional
Maintainer: Andres Salomon <dilinger@mp3revolution.net>
Build-Depends: debhelper (>> 3.0.0), libdevmapper-dev (>= 0.96.04), libreadline4-dev
Standards-Version: 3.5.8.0
Package: lvm2
Architecture: any
Depends: ${shlibs:Depends}
Conflicts: lvm10, lvm-common
Replaces: lvm10, lvm-common
Provides: lvm-binaries
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.

25
debian/copyright vendored Normal file
View File

@@ -0,0 +1,25 @@
This package was debianized by Andres Salomon <dilinger@mp3revolution.net> on
Wed, 20 Feb 2002 03:17:25 -0500.
It was downloaded from http://www.sistina.com/products_lvm.htm
Upstream Author: LVM Development Team
Copyright (c) 2001-2002 LVM Development Team
LVM2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
LVM2 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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
On Debian systems, the full text of the GPL can be found in
/usr/share/common-licenses/GPL

4
debian/dirs vendored Normal file
View File

@@ -0,0 +1,4 @@
etc/lvm
usr/share/man/man5
usr/share/man/man8
sbin

5
debian/docs vendored Normal file
View File

@@ -0,0 +1,5 @@
BUGS
README
VERSION
WHATS_NEW
doc/*

64
debian/init.d vendored Normal file
View File

@@ -0,0 +1,64 @@
#! /bin/sh
#
# lvm2 This script handles LVM2 initialization/shutdown.
#
# Written by Andres Salomon <dilinger@mp3revolution.net>.
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=lvm2
DESC=LVM
test -x /sbin/vgchange || exit 0
modprobe dm-mod >/dev/null 2>&1
# Create necessary files in /dev for device-mapper
create_devfiles() {
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//')
if test ! -d $DIR; then
mkdir --mode=755 $DIR >/dev/null 2>&1
fi
if test ! -c $FILE -a ! -z "$minor"; then
mknod --mode=600 $FILE c $major $minor >/dev/null 2>&1
fi
}
case "$1" in
start)
echo -n "Initializing $DESC: "
create_devfiles
vgchange -a y
# # Mount all LVM devices
# for vg in $( vgchange -a y 2>/dev/null | grep active | awk -F\" '{print $2}' ); do
# MTPT=$( grep $vg /etc/fstab | awk '{print $2}' )
# mount $MTPT
# done
echo "$NAME."
;;
stop)
echo -n "Shutting down $DESC: "
# We don't really try all that hard to shut it down; far too many
# things that can keep it from successfully shutting down.
vgchange -a n
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
vgchange -a n
sleep 1
vgchange -a y
echo "$NAME."
;;
*)
echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0

26
debian/manpages vendored Normal file
View File

@@ -0,0 +1,26 @@
debian/lvm2/usr/share/man/man5/lvm.conf.5
debian/lvm2/usr/share/man/man8/lvchange.8
debian/lvm2/usr/share/man/man8/lvcreate.8
debian/lvm2/usr/share/man/man8/lvdisplay.8
debian/lvm2/usr/share/man/man8/lvextend.8
debian/lvm2/usr/share/man/man8/lvm.8
debian/lvm2/usr/share/man/man8/lvmchange.8
debian/lvm2/usr/share/man/man8/lvreduce.8
debian/lvm2/usr/share/man/man8/lvremove.8
debian/lvm2/usr/share/man/man8/lvrename.8
debian/lvm2/usr/share/man/man8/lvscan.8
debian/lvm2/usr/share/man/man8/pvchange.8
debian/lvm2/usr/share/man/man8/pvcreate.8
debian/lvm2/usr/share/man/man8/pvdisplay.8
debian/lvm2/usr/share/man/man8/pvscan.8
debian/lvm2/usr/share/man/man8/vgcfgbackup.8
debian/lvm2/usr/share/man/man8/vgchange.8
debian/lvm2/usr/share/man/man8/vgck.8
debian/lvm2/usr/share/man/man8/vgcreate.8
debian/lvm2/usr/share/man/man8/vgdisplay.8
debian/lvm2/usr/share/man/man8/vgextend.8
debian/lvm2/usr/share/man/man8/vgmerge.8
debian/lvm2/usr/share/man/man8/vgreduce.8
debian/lvm2/usr/share/man/man8/vgremove.8
debian/lvm2/usr/share/man/man8/vgrename.8
debian/lvm2/usr/share/man/man8/vgscan.8

119
debian/rules vendored Executable file
View File

@@ -0,0 +1,119 @@
#!/usr/bin/make -f
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 by Joey Hess.
#
# This version is for a hypothetical package that builds an
# architecture-dependant package, as well as an architecture-independent
# package.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# This is the debhelper compatibility version to use.
export DH_COMPAT=3
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
CFLAGS += -g
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
configure: configure-stamp
configure-stamp:
dh_testdir
# Add here commands to configure the package.
./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/ --mandir=\$${prefix}/usr/share/man --infodir=\$${prefix}/usr/share/info
touch configure-stamp
build-arch: configure-stamp build-arch-stamp
build-arch-stamp:
dh_testdir
# Add here command to compile/build the package.
$(MAKE)
touch build-arch-stamp
build-indep: configure-stamp build-indep-stamp
build-indep-stamp:
dh_testdir
# Add here command to compile/build the arch indep package.
# It's ok not to do anything here, if you don't need to build
# anything for this package.
#/usr/bin/docbook-to-man debian/lvm2.sgml > lvm2.1
touch build-indep-stamp
build: build-arch build-indep
clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
# Add here commands to clean up after the build process.
-$(MAKE) distclean
-test -r /usr/share/misc/config.sub && \
cp -f /usr/share/misc/config.sub config.sub
-test -r /usr/share/misc/config.guess && \
cp -f /usr/share/misc/config.guess config.guess
dh_clean
install: DH_OPTIONS=
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/lvm2.
$(MAKE) install prefix=$(CURDIR)/debian/lvm2
install -m 0644 doc/example.conf debian/lvm2/etc/lvm/lvm.conf
# Build architecture-independent files here.
# Pass -i to all debhelper commands in this target to reduce clutter.
binary-indep: build install
# nada.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
# dh_installdebconf
dh_installdocs
dh_installexamples
# dh_installlogrotate -a
# dh_installemacsen -a
# dh_installpam -a
# dh_installmime -a
dh_installinit --update-rcd-params="start 26 S . start 50 0 6 ."
dh_installcron
dh_installman
dh_installinfo
dh_installchangelogs
dh_strip
dh_link
dh_compress
dh_fixperms
dh_makeshlibs
dh_installdeb
# dh_perl -a
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure

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