Merge lp:~gandelman-a/ubuntu/saucy/lvm2/lp1223576 into lp:ubuntu/saucy/lvm2

Proposed by Adam Gandelman on 2013-09-13
Status: Merged
Merge reported by: Dimitri John Ledkov
Merged at revision: not available
Proposed branch: lp:~gandelman-a/ubuntu/saucy/lvm2/lp1223576
Merge into: lp:ubuntu/saucy/lvm2
Diff against target: 19303 lines (+290/-18358)
50 files modified
.pc/applied-patches (+0/-9)
.pc/avoid-dev-block.patch/lib/device/dev-cache.c (+0/-1037)
.pc/dirs.patch/daemons/dmeventd/Makefile.in (+0/-108)
.pc/dirs.patch/daemons/dmeventd/dmeventd.c (+0/-2026)
.pc/dirs.patch/doc/example.conf.in (+0/-816)
.pc/dirs.patch/lib/commands/toolcontext.c (+0/-1688)
.pc/dm-event-api.patch/daemons/dmeventd/.exported_symbols (+0/-4)
.pc/dm-event-api.patch/daemons/dmeventd/dmeventd.c (+0/-2035)
.pc/dm-event-api.patch/daemons/dmeventd/libdevmapper-event.c (+0/-870)
.pc/force-modprobe.patch/configure.in (+0/-1632)
.pc/implicit-pointer.patch/tools/lvm.c (+0/-253)
.pc/install.patch/daemons/dmeventd/plugins/lvm2/Makefile.in (+0/-31)
.pc/install.patch/daemons/dmeventd/plugins/mirror/Makefile.in (+0/-37)
.pc/install.patch/daemons/dmeventd/plugins/raid/Makefile.in (+0/-36)
.pc/install.patch/daemons/dmeventd/plugins/snapshot/Makefile.in (+0/-33)
.pc/install.patch/daemons/dmeventd/plugins/thin/Makefile.in (+0/-36)
.pc/install.patch/make.tmpl.in (+0/-412)
.pc/libs-cleanup.patch/configure.in (+0/-1685)
.pc/missing-dmeventd.patch/daemons/dmeventd/libdevmapper-event.c (+0/-870)
.pc/missing-dmeventd.patch/lib/activate/activate.c (+0/-1954)
.pc/monitoring-default-off.patch/doc/example.conf.in (+0/-816)
.pc/monitoring-default-off.patch/lib/config/defaults.h (+0/-180)
.pc/monitoring-default-off.patch/tools/toollib.c (+0/-1632)
configure.in (+65/-8)
daemons/dmeventd/.exported_symbols (+3/-3)
daemons/dmeventd/Makefile.in (+0/-1)
daemons/dmeventd/dmeventd.c (+8/-17)
daemons/dmeventd/libdevmapper-event.c (+13/-25)
daemons/dmeventd/plugins/lvm2/Makefile.in (+1/-1)
daemons/dmeventd/plugins/mirror/Makefile.in (+0/-1)
daemons/dmeventd/plugins/raid/Makefile.in (+0/-1)
daemons/dmeventd/plugins/snapshot/Makefile.in (+0/-1)
daemons/dmeventd/plugins/thin/Makefile.in (+0/-1)
debian/changelog (+110/-0)
debian/clvm.defaults (+9/-0)
debian/clvm.init (+1/-1)
debian/control (+2/-1)
debian/lvm2.init (+2/-12)
debian/rules (+1/-1)
debian/tree/dmsetup/lib/udev/rules.d/55-dm.rules (+3/-3)
debian/tree/lvm2/lib/udev/rules.d/56-lvm.rules (+10/-2)
debian/tree/lvm2/lib/udev/rules.d/60-persistent-storage-lvm.rules (+0/-12)
doc/example.conf.in (+3/-3)
lib/activate/activate.c (+20/-27)
lib/commands/toolcontext.c (+6/-4)
lib/config/defaults.h (+1/-1)
lib/device/dev-cache.c (+0/-15)
make.tmpl.in (+21/-10)
tools/lvm.c (+3/-0)
tools/toollib.c (+8/-7)
To merge this branch: bzr merge lp:~gandelman-a/ubuntu/saucy/lvm2/lp1223576
Reviewer Review Type Date Requested Status
Dimitri John Ledkov 2013-09-13 Approve on 2013-09-16
Review via email: mp+185573@code.launchpad.net

Description of the change

This merges Debian 2.02.98-6, which contains a number of fixes to udev rules that seem to fix many strange issue's I've been hitting on Saucy wrt LVM snapshot deletion.

lvm2 (2.02.98-6ubuntu1) saucy; urgency=low

  * Merge from Debian unstable (LP: #1223576), remaining changes:
    - Only build clvm support for corosync:
      - debian/control: Drop Build-Depends on libcman-dev, openais-dev
      - debian/rules: Remove openais + cman from --with-clvmd build option.
    - debian/patches/avoid-dev-block.patch: Prefer any other device name over
      names in /dev/block/ since lvm.conf won't handle this.
    - debian/rules:
      - copy .po file to .pot file for Rosetta (Ubuntu specific).
    - debian/{dmsetup,lvm2}-udeb.install:
      - install initramfs and udev hooks in udebs (Debian bug 504341).
    - auto-start VGs as their PVs are discovered (Ubuntu specific):
      - add debian/tree/lvm2/lib/udev/rules.d/85-lvm2.rules: use watershed plus
        the sledgehammer of vgscan/vgchange to turn on VGs as they come online.
      - debian/tree/lvm2/usr/share/initramfs-tools/scripts/hooks/lvm2:
        - add 85-lvm2.rules to the list of udev rules to copy.
        - depend on udev.
      - debian/control:
        - add versioned Depend on watershed in lvm2 for udev rules.
        - add Depends on watershed-udeb in lvm2-udeb for udev rules.
        - add versioned Depend/Breaks on udev in dmsetup for udev rules.
        - add Depend on initramfs-tools in dmsetup so system is not potentially
          rendered unbootable by out-of-order dpkg configuration.
        - In libdevmapper-event1.02.1 add Breaks: dmeventd
          (<< 2.02.95-4ubuntu1) due to debian symbol rename
      - debian/rules:
        - do not install local-top scripts since Ubuntu mounts root using udev.
        - do not install init scripts for lvm2, since udev starts LVM.
        - continue to build clvm support.
      - debian/lvm2.postinst: handle missing lvm2 init script.
      - debian/tree/dmsetup/lib/udev/rules.d/60-persistent-storage-dm.rules:
        watch dm devices for changes with inotify
    - add mountroot failure hooks to help fix bad boots (Debian bug 468115):
      - debian/tree/lvm2/usr/share/initramfs-tools/scripts/init-premount/lvm2
    - remaining changes to upstream event manager packages (Debian bug 514706):
      - debian/rules:
        - enable dmeventd during configure.
      - debian/dmeventd.{8,manpages}: install dmeventd files.
    - rename debian/clvm.defaults to debian/clvm.default so it is installed
      correctly.
    - debian/control: add dmsetup-udeb to libdevmapper1.02.1-udeb recommends.
    - debian/rules: make sure dmsetup and lvm2 initramfs-tools scripts are
      executable. When the Ubuntu-specific ones are added with a patch,
      they may lose their executable bit.
    - Add and install clvmd resource agent
    - Add dependency on libudev-dev to libdevmapper-dev so that the .pc file
      works.
    - debian/{clvmd.ra,clvm.init}:
      - create /run/lvm if it doesn't exist.
    - debian/clvm.init:
      - exit 3 if not running on status action.
    - Call dh_installman so that our dmeventd manpage actually gets installed
    - Install the missing fsadm manpage.
    - Complete libdevmapper-dev multiarch:
      - move .so symlinks and pkgconfig files to multiarched locations.
      - mark libdevmapper-dev M-A: same

 -- Adam Gandelman <email address hidden> Thu, 12 Sep 2013 16:03:09 -0700

To post a comment you must log in.
85. By Adam Gandelman on 2013-09-13

Add merge bug ref.

Dimitri John Ledkov (xnox) wrote :

review on the bug report.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed file '.pc/applied-patches'
2--- .pc/applied-patches 2013-05-30 11:02:10 +0000
3+++ .pc/applied-patches 1970-01-01 00:00:00 +0000
4@@ -1,9 +0,0 @@
5-install.patch
6-libs-cleanup.patch
7-dirs.patch
8-force-modprobe.patch
9-implicit-pointer.patch
10-avoid-dev-block.patch
11-dm-event-api.patch
12-monitoring-default-off.patch
13-missing-dmeventd.patch
14
15=== removed directory '.pc/avoid-dev-block.patch'
16=== removed directory '.pc/avoid-dev-block.patch/lib'
17=== removed directory '.pc/avoid-dev-block.patch/lib/device'
18=== removed file '.pc/avoid-dev-block.patch/lib/device/dev-cache.c'
19--- .pc/avoid-dev-block.patch/lib/device/dev-cache.c 2013-05-30 11:02:10 +0000
20+++ .pc/avoid-dev-block.patch/lib/device/dev-cache.c 1970-01-01 00:00:00 +0000
21@@ -1,1037 +0,0 @@
22-/*
23- * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
24- * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
25- *
26- * This file is part of LVM2.
27- *
28- * This copyrighted material is made available to anyone wishing to use,
29- * modify, copy, or redistribute it subject to the terms and conditions
30- * of the GNU Lesser General Public License v.2.1.
31- *
32- * You should have received a copy of the GNU Lesser General Public License
33- * along with this program; if not, write to the Free Software Foundation,
34- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35- */
36-
37-#include "lib.h"
38-#include "dev-cache.h"
39-#include "lvm-types.h"
40-#include "btree.h"
41-#include "filter.h"
42-#include "toolcontext.h"
43-
44-#include <unistd.h>
45-#include <sys/param.h>
46-#include <dirent.h>
47-
48-struct dev_iter {
49- struct btree_iter *current;
50- struct dev_filter *filter;
51-};
52-
53-struct dir_list {
54- struct dm_list list;
55- char dir[0];
56-};
57-
58-static struct {
59- struct dm_pool *mem;
60- struct dm_hash_table *names;
61- struct btree *devices;
62- struct dm_regex *preferred_names_matcher;
63- const char *dev_dir;
64-
65- int has_scanned;
66- struct dm_list dirs;
67- struct dm_list files;
68-
69-} _cache;
70-
71-#define _zalloc(x) dm_pool_zalloc(_cache.mem, (x))
72-#define _free(x) dm_pool_free(_cache.mem, (x))
73-#define _strdup(x) dm_pool_strdup(_cache.mem, (x))
74-
75-static int _insert(const char *path, int rec, int check_with_udev_db);
76-
77-/* Setup non-zero members of passed zeroed 'struct device' */
78-static void _dev_init(struct device *dev, int max_error_count)
79-{
80- dev->block_size = -1;
81- dev->fd = -1;
82- dev->read_ahead = -1;
83- dev->max_error_count = max_error_count;
84-
85- dm_list_init(&dev->aliases);
86- dm_list_init(&dev->open_list);
87-}
88-
89-struct device *dev_create_file(const char *filename, struct device *dev,
90- struct str_list *alias, int use_malloc)
91-{
92- int allocate = !dev;
93-
94- if (allocate) {
95- if (use_malloc) {
96- if (!(dev = dm_zalloc(sizeof(*dev)))) {
97- log_error("struct device allocation failed");
98- return NULL;
99- }
100- if (!(alias = dm_zalloc(sizeof(*alias)))) {
101- log_error("struct str_list allocation failed");
102- dm_free(dev);
103- return NULL;
104- }
105- if (!(alias->str = dm_strdup(filename))) {
106- log_error("filename strdup failed");
107- dm_free(dev);
108- dm_free(alias);
109- return NULL;
110- }
111- } else {
112- if (!(dev = _zalloc(sizeof(*dev)))) {
113- log_error("struct device allocation failed");
114- return NULL;
115- }
116- if (!(alias = _zalloc(sizeof(*alias)))) {
117- log_error("struct str_list allocation failed");
118- _free(dev);
119- return NULL;
120- }
121- if (!(alias->str = _strdup(filename))) {
122- log_error("filename strdup failed");
123- return NULL;
124- }
125- }
126- } else if (!(alias->str = dm_strdup(filename))) {
127- log_error("filename strdup failed");
128- return NULL;
129- }
130-
131- _dev_init(dev, NO_DEV_ERROR_COUNT_LIMIT);
132- dev->flags = DEV_REGULAR | ((use_malloc) ? DEV_ALLOCED : 0);
133- dm_list_add(&dev->aliases, &alias->list);
134-
135- return dev;
136-}
137-
138-static struct device *_dev_create(dev_t d)
139-{
140- struct device *dev;
141-
142- if (!(dev = _zalloc(sizeof(*dev)))) {
143- log_error("struct device allocation failed");
144- return NULL;
145- }
146-
147- _dev_init(dev, dev_disable_after_error_count());
148- dev->dev = d;
149-
150- return dev;
151-}
152-
153-void dev_set_preferred_name(struct str_list *sl, struct device *dev)
154-{
155- /*
156- * Don't interfere with ordering specified in config file.
157- */
158- if (_cache.preferred_names_matcher)
159- return;
160-
161- log_debug("%s: New preferred name", sl->str);
162- dm_list_del(&sl->list);
163- dm_list_add_h(&dev->aliases, &sl->list);
164-}
165-
166-/*
167- * Check whether path0 or path1 contains the subpath. The path that
168- * *does not* contain the subpath wins (return 0 or 1). If both paths
169- * contain the subpath, return -1. If none of them contains the subpath,
170- * return -2.
171- */
172-static int _builtin_preference(const char *path0, const char *path1,
173- size_t skip_prefix_count, const char *subpath)
174-{
175- size_t subpath_len;
176- int r0, r1;
177-
178- subpath_len = strlen(subpath);
179-
180- r0 = !strncmp(path0 + skip_prefix_count, subpath, subpath_len);
181- r1 = !strncmp(path1 + skip_prefix_count, subpath, subpath_len);
182-
183- if (!r0 && r1)
184- /* path0 does not have the subpath - it wins */
185- return 0;
186- else if (r0 && !r1)
187- /* path1 does not have the subpath - it wins */
188- return 1;
189- else if (r0 && r1)
190- /* both of them have the subpath */
191- return -1;
192-
193- /* no path has the subpath */
194- return -2;
195-}
196-
197-static int _apply_builtin_path_preference_rules(const char *path0, const char *path1)
198-{
199- size_t devdir_len;
200- int r;
201-
202- devdir_len = strlen(_cache.dev_dir);
203-
204- if (!strncmp(path0, _cache.dev_dir, devdir_len) &&
205- !strncmp(path1, _cache.dev_dir, devdir_len)) {
206- /*
207- * We're trying to achieve the ordering:
208- * /dev/block/ < /dev/dm-* < /dev/disk/ < /dev/mapper/ < anything else
209- */
210-
211- /* Prefer any other path over /dev/block/ path. */
212- if ((r = _builtin_preference(path0, path1, devdir_len, "block/")) >= -1)
213- return r;
214-
215- /* Prefer any other path over /dev/dm-* path. */
216- if ((r = _builtin_preference(path0, path1, devdir_len, "dm-")) >= -1)
217- return r;
218-
219- /* Prefer any other path over /dev/disk/ path. */
220- if ((r = _builtin_preference(path0, path1, devdir_len, "disk/")) >= -1)
221- return r;
222-
223- /* Prefer any other path over /dev/mapper/ path. */
224- if ((r = _builtin_preference(path0, path1, 0, dm_dir())) >= -1)
225- return r;
226- }
227-
228- return -1;
229-}
230-
231-/* Return 1 if we prefer path1 else return 0 */
232-static int _compare_paths(const char *path0, const char *path1)
233-{
234- int slash0 = 0, slash1 = 0;
235- int m0, m1;
236- const char *p;
237- char p0[PATH_MAX], p1[PATH_MAX];
238- char *s0, *s1;
239- struct stat stat0, stat1;
240- int r;
241-
242- /*
243- * FIXME Better to compare patterns one-at-a-time against all names.
244- */
245- if (_cache.preferred_names_matcher) {
246- m0 = dm_regex_match(_cache.preferred_names_matcher, path0);
247- m1 = dm_regex_match(_cache.preferred_names_matcher, path1);
248-
249- if (m0 != m1) {
250- if (m0 < 0)
251- return 1;
252- if (m1 < 0)
253- return 0;
254- if (m0 < m1)
255- return 1;
256- if (m1 < m0)
257- return 0;
258- }
259- }
260-
261- /* Apply built-in preference rules first. */
262- if ((r = _apply_builtin_path_preference_rules(path0, path1)) >= 0)
263- return r;
264-
265- /* Return the path with fewer slashes */
266- for (p = path0; p++; p = (const char *) strchr(p, '/'))
267- slash0++;
268-
269- for (p = path1; p++; p = (const char *) strchr(p, '/'))
270- slash1++;
271-
272- if (slash0 < slash1)
273- return 0;
274- if (slash1 < slash0)
275- return 1;
276-
277- strncpy(p0, path0, sizeof(p0) - 1);
278- p0[sizeof(p0) - 1] = '\0';
279- strncpy(p1, path1, sizeof(p1) - 1);
280- p1[sizeof(p1) - 1] = '\0';
281- s0 = p0 + 1;
282- s1 = p1 + 1;
283-
284- /*
285- * If we reach here, both paths are the same length.
286- * Now skip past identical path components.
287- */
288- while (*s0 && *s0 == *s1)
289- s0++, s1++;
290-
291- /* We prefer symlinks - they exist for a reason!
292- * So we prefer a shorter path before the first symlink in the name.
293- * FIXME Configuration option to invert this? */
294- while (s0) {
295- s0 = strchr(s0, '/');
296- s1 = strchr(s1, '/');
297- if (s0) {
298- *s0 = '\0';
299- *s1 = '\0';
300- }
301- if (lstat(p0, &stat0)) {
302- log_sys_very_verbose("lstat", p0);
303- return 1;
304- }
305- if (lstat(p1, &stat1)) {
306- log_sys_very_verbose("lstat", p1);
307- return 0;
308- }
309- if (S_ISLNK(stat0.st_mode) && !S_ISLNK(stat1.st_mode))
310- return 0;
311- if (!S_ISLNK(stat0.st_mode) && S_ISLNK(stat1.st_mode))
312- return 1;
313- if (s0) {
314- *s0++ = '/';
315- *s1++ = '/';
316- }
317- }
318-
319- /* ASCII comparison */
320- if (strcmp(path0, path1) < 0)
321- return 0;
322- else
323- return 1;
324-}
325-
326-static int _add_alias(struct device *dev, const char *path)
327-{
328- struct str_list *sl = _zalloc(sizeof(*sl));
329- struct str_list *strl;
330- const char *oldpath;
331- int prefer_old = 1;
332-
333- if (!sl)
334- return_0;
335-
336- /* Is name already there? */
337- dm_list_iterate_items(strl, &dev->aliases) {
338- if (!strcmp(strl->str, path)) {
339- log_debug("%s: Already in device cache", path);
340- return 1;
341- }
342- }
343-
344- sl->str = path;
345-
346- if (!dm_list_empty(&dev->aliases)) {
347- oldpath = dm_list_item(dev->aliases.n, struct str_list)->str;
348- prefer_old = _compare_paths(path, oldpath);
349- log_debug("%s: Aliased to %s in device cache%s",
350- path, oldpath, prefer_old ? "" : " (preferred name)");
351-
352- } else
353- log_debug("%s: Added to device cache", path);
354-
355- if (prefer_old)
356- dm_list_add(&dev->aliases, &sl->list);
357- else
358- dm_list_add_h(&dev->aliases, &sl->list);
359-
360- return 1;
361-}
362-
363-/*
364- * Either creates a new dev, or adds an alias to
365- * an existing dev.
366- */
367-static int _insert_dev(const char *path, dev_t d)
368-{
369- struct device *dev;
370- static dev_t loopfile_count = 0;
371- int loopfile = 0;
372- char *path_copy;
373-
374- /* Generate pretend device numbers for loopfiles */
375- if (!d) {
376- if (dm_hash_lookup(_cache.names, path))
377- return 1;
378- d = ++loopfile_count;
379- loopfile = 1;
380- }
381-
382- /* is this device already registered ? */
383- if (!(dev = (struct device *) btree_lookup(_cache.devices,
384- (uint32_t) d))) {
385- /* create new device */
386- if (loopfile) {
387- if (!(dev = dev_create_file(path, NULL, NULL, 0)))
388- return_0;
389- } else if (!(dev = _dev_create(d)))
390- return_0;
391-
392- if (!(btree_insert(_cache.devices, (uint32_t) d, dev))) {
393- log_error("Couldn't insert device into binary tree.");
394- _free(dev);
395- return 0;
396- }
397- }
398-
399- if (!(path_copy = dm_pool_strdup(_cache.mem, path))) {
400- log_error("Failed to duplicate path string.");
401- return 0;
402- }
403-
404- if (!loopfile && !_add_alias(dev, path_copy)) {
405- log_error("Couldn't add alias to dev cache.");
406- return 0;
407- }
408-
409- if (!dm_hash_insert(_cache.names, path_copy, dev)) {
410- log_error("Couldn't add name to hash in dev cache.");
411- return 0;
412- }
413-
414- return 1;
415-}
416-
417-static char *_join(const char *dir, const char *name)
418-{
419- size_t len = strlen(dir) + strlen(name) + 2;
420- char *r = dm_malloc(len);
421- if (r)
422- snprintf(r, len, "%s/%s", dir, name);
423-
424- return r;
425-}
426-
427-/*
428- * Get rid of extra slashes in the path string.
429- */
430-static void _collapse_slashes(char *str)
431-{
432- char *ptr;
433- int was_slash = 0;
434-
435- for (ptr = str; *ptr; ptr++) {
436- if (*ptr == '/') {
437- if (was_slash)
438- continue;
439-
440- was_slash = 1;
441- } else
442- was_slash = 0;
443- *str++ = *ptr;
444- }
445-
446- *str = *ptr;
447-}
448-
449-static int _insert_dir(const char *dir)
450-{
451- int n, dirent_count, r = 1;
452- struct dirent **dirent;
453- char *path;
454-
455- dirent_count = scandir(dir, &dirent, NULL, alphasort);
456- if (dirent_count > 0) {
457- for (n = 0; n < dirent_count; n++) {
458- if (dirent[n]->d_name[0] == '.') {
459- free(dirent[n]);
460- continue;
461- }
462-
463- if (!(path = _join(dir, dirent[n]->d_name)))
464- return_0;
465-
466- _collapse_slashes(path);
467- r &= _insert(path, 1, 0);
468- dm_free(path);
469-
470- free(dirent[n]);
471- }
472- free(dirent);
473- }
474-
475- return r;
476-}
477-
478-static int _insert_file(const char *path)
479-{
480- struct stat info;
481-
482- if (stat(path, &info) < 0) {
483- log_sys_very_verbose("stat", path);
484- return 0;
485- }
486-
487- if (!S_ISREG(info.st_mode)) {
488- log_debug("%s: Not a regular file", path);
489- return 0;
490- }
491-
492- if (!_insert_dev(path, 0))
493- return_0;
494-
495- return 1;
496-}
497-
498-#ifdef UDEV_SYNC_SUPPORT
499-
500-static int _device_in_udev_db(const dev_t d)
501-{
502- struct udev *udev;
503- struct udev_device *udev_device;
504-
505- if (!(udev = udev_get_library_context()))
506- return_0;
507-
508- if ((udev_device = udev_device_new_from_devnum(udev, 'b', d))) {
509- udev_device_unref(udev_device);
510- return 1;
511- }
512-
513- return 0;
514-}
515-
516-static int _insert_udev_dir(struct udev *udev, const char *dir)
517-{
518- struct udev_enumerate *udev_enum = NULL;
519- struct udev_list_entry *device_entry, *symlink_entry;
520- const char *entry_name, *node_name, *symlink_name;
521- struct udev_device *device;
522- int r = 1;
523-
524- if (!(udev_enum = udev_enumerate_new(udev)))
525- goto bad;
526-
527- if (udev_enumerate_add_match_subsystem(udev_enum, "block") ||
528- udev_enumerate_scan_devices(udev_enum))
529- goto bad;
530-
531- /*
532- * Report any missing information as "log_very_verbose" only, do not
533- * report it as a "warning" or "error" - the record could be removed
534- * by the time we ask for more info (node name, symlink name...).
535- * Whatever removes *any* block device in the system (even unrelated
536- * to our operation), we would have a warning/error on output then.
537- * That could be misleading. If there's really any problem with missing
538- * information from udev db, we can still have a look at the verbose log.
539- */
540- udev_list_entry_foreach(device_entry, udev_enumerate_get_list_entry(udev_enum)) {
541- entry_name = udev_list_entry_get_name(device_entry);
542-
543- if (!(device = udev_device_new_from_syspath(udev, entry_name))) {
544- log_very_verbose("udev failed to return a device for entry %s.",
545- entry_name);
546- continue;
547- }
548-
549- if (!(node_name = udev_device_get_devnode(device)))
550- log_very_verbose("udev failed to return a device node for entry %s.",
551- entry_name);
552- else
553- r &= _insert(node_name, 0, 0);
554-
555- udev_list_entry_foreach(symlink_entry, udev_device_get_devlinks_list_entry(device)) {
556- if (!(symlink_name = udev_list_entry_get_name(symlink_entry)))
557- log_very_verbose("udev failed to return a symlink name for entry %s.",
558- entry_name);
559- else
560- r &= _insert(symlink_name, 0, 0);
561- }
562-
563- udev_device_unref(device);
564- }
565-
566- udev_enumerate_unref(udev_enum);
567- return r;
568-
569-bad:
570- log_error("Failed to enumerate udev device list.");
571- udev_enumerate_unref(udev_enum);
572- return 0;
573-}
574-
575-static void _insert_dirs(struct dm_list *dirs)
576-{
577- struct dir_list *dl;
578- struct udev *udev;
579- int with_udev;
580-
581- with_udev = obtain_device_list_from_udev() &&
582- (udev = udev_get_library_context());
583-
584- dm_list_iterate_items(dl, &_cache.dirs) {
585- if (with_udev) {
586- if (!_insert_udev_dir(udev, dl->dir))
587- log_debug("%s: Failed to insert devices from "
588- "udev-managed directory to device "
589- "cache fully", dl->dir);
590- }
591- else if (!_insert_dir(dl->dir))
592- log_debug("%s: Failed to insert devices to "
593- "device cache fully", dl->dir);
594- }
595-}
596-
597-#else /* UDEV_SYNC_SUPPORT */
598-
599-static int _device_in_udev_db(const dev_t d)
600-{
601- return 0;
602-}
603-
604-static void _insert_dirs(struct dm_list *dirs)
605-{
606- struct dir_list *dl;
607-
608- dm_list_iterate_items(dl, &_cache.dirs)
609- _insert_dir(dl->dir);
610-}
611-
612-#endif /* UDEV_SYNC_SUPPORT */
613-
614-static int _insert(const char *path, int rec, int check_with_udev_db)
615-{
616- struct stat info;
617- int r = 0;
618-
619- if (stat(path, &info) < 0) {
620- log_sys_very_verbose("stat", path);
621- return 0;
622- }
623-
624- if (check_with_udev_db && !_device_in_udev_db(info.st_rdev)) {
625- log_very_verbose("%s: Not in udev db", path);
626- return 0;
627- }
628-
629- if (S_ISDIR(info.st_mode)) { /* add a directory */
630- /* check it's not a symbolic link */
631- if (lstat(path, &info) < 0) {
632- log_sys_very_verbose("lstat", path);
633- return 0;
634- }
635-
636- if (S_ISLNK(info.st_mode)) {
637- log_debug("%s: Symbolic link to directory", path);
638- return 0;
639- }
640-
641- if (rec)
642- r = _insert_dir(path);
643-
644- } else { /* add a device */
645- if (!S_ISBLK(info.st_mode)) {
646- log_debug("%s: Not a block device", path);
647- return 0;
648- }
649-
650- if (!_insert_dev(path, info.st_rdev))
651- return_0;
652-
653- r = 1;
654- }
655-
656- return r;
657-}
658-
659-static void _full_scan(int dev_scan)
660-{
661- struct dir_list *dl;
662-
663- if (_cache.has_scanned && !dev_scan)
664- return;
665-
666- _insert_dirs(&_cache.dirs);
667-
668- dm_list_iterate_items(dl, &_cache.files)
669- _insert_file(dl->dir);
670-
671- _cache.has_scanned = 1;
672- init_full_scan_done(1);
673-}
674-
675-int dev_cache_has_scanned(void)
676-{
677- return _cache.has_scanned;
678-}
679-
680-void dev_cache_scan(int do_scan)
681-{
682- if (!do_scan)
683- _cache.has_scanned = 1;
684- else
685- _full_scan(1);
686-}
687-
688-static int _init_preferred_names(struct cmd_context *cmd)
689-{
690- const struct dm_config_node *cn;
691- const struct dm_config_value *v;
692- struct dm_pool *scratch = NULL;
693- const char **regex;
694- unsigned count = 0;
695- int i, r = 0;
696-
697- _cache.preferred_names_matcher = NULL;
698-
699- if (!(cn = find_config_tree_node(cmd, "devices/preferred_names")) ||
700- cn->v->type == DM_CFG_EMPTY_ARRAY) {
701- log_very_verbose("devices/preferred_names not found in config file: "
702- "using built-in preferences");
703- return 1;
704- }
705-
706- for (v = cn->v; v; v = v->next) {
707- if (v->type != DM_CFG_STRING) {
708- log_error("preferred_names patterns must be enclosed in quotes");
709- return 0;
710- }
711-
712- count++;
713- }
714-
715- if (!(scratch = dm_pool_create("preferred device name matcher", 1024)))
716- return_0;
717-
718- if (!(regex = dm_pool_alloc(scratch, sizeof(*regex) * count))) {
719- log_error("Failed to allocate preferred device name "
720- "pattern list.");
721- goto out;
722- }
723-
724- for (v = cn->v, i = count - 1; v; v = v->next, i--) {
725- if (!(regex[i] = dm_pool_strdup(scratch, v->v.str))) {
726- log_error("Failed to allocate a preferred device name "
727- "pattern.");
728- goto out;
729- }
730- }
731-
732- if (!(_cache.preferred_names_matcher =
733- dm_regex_create(_cache.mem, regex, count))) {
734- log_error("Preferred device name pattern matcher creation failed.");
735- goto out;
736- }
737-
738- r = 1;
739-
740-out:
741- dm_pool_destroy(scratch);
742-
743- return r;
744-}
745-
746-int dev_cache_init(struct cmd_context *cmd)
747-{
748- _cache.names = NULL;
749- _cache.has_scanned = 0;
750-
751- if (!(_cache.mem = dm_pool_create("dev_cache", 10 * 1024)))
752- return_0;
753-
754- if (!(_cache.names = dm_hash_create(128))) {
755- dm_pool_destroy(_cache.mem);
756- _cache.mem = 0;
757- return_0;
758- }
759-
760- if (!(_cache.devices = btree_create(_cache.mem))) {
761- log_error("Couldn't create binary tree for dev-cache.");
762- goto bad;
763- }
764-
765- if (!(_cache.dev_dir = _strdup(cmd->dev_dir))) {
766- log_error("strdup dev_dir failed.");
767- goto bad;
768- }
769-
770- dm_list_init(&_cache.dirs);
771- dm_list_init(&_cache.files);
772-
773- if (!_init_preferred_names(cmd))
774- goto_bad;
775-
776- return 1;
777-
778- bad:
779- dev_cache_exit();
780- return 0;
781-}
782-
783-static void _check_closed(struct device *dev)
784-{
785- if (dev->fd >= 0)
786- log_error("Device '%s' has been left open.", dev_name(dev));
787-}
788-
789-static void _check_for_open_devices(void)
790-{
791- dm_hash_iter(_cache.names, (dm_hash_iterate_fn) _check_closed);
792-}
793-
794-void dev_cache_exit(void)
795-{
796- if (_cache.names)
797- _check_for_open_devices();
798-
799- if (_cache.preferred_names_matcher)
800- _cache.preferred_names_matcher = NULL;
801-
802- if (_cache.mem) {
803- dm_pool_destroy(_cache.mem);
804- _cache.mem = NULL;
805- }
806-
807- if (_cache.names) {
808- dm_hash_destroy(_cache.names);
809- _cache.names = NULL;
810- }
811-
812- _cache.devices = NULL;
813- _cache.has_scanned = 0;
814- dm_list_init(&_cache.dirs);
815- dm_list_init(&_cache.files);
816-}
817-
818-int dev_cache_add_dir(const char *path)
819-{
820- struct dir_list *dl;
821- struct stat st;
822-
823- if (stat(path, &st)) {
824- log_error("Ignoring %s: %s", path, strerror(errno));
825- /* But don't fail */
826- return 1;
827- }
828-
829- if (!S_ISDIR(st.st_mode)) {
830- log_error("Ignoring %s: Not a directory", path);
831- return 1;
832- }
833-
834- if (!(dl = _zalloc(sizeof(*dl) + strlen(path) + 1))) {
835- log_error("dir_list allocation failed");
836- return 0;
837- }
838-
839- strcpy(dl->dir, path);
840- dm_list_add(&_cache.dirs, &dl->list);
841- return 1;
842-}
843-
844-int dev_cache_add_loopfile(const char *path)
845-{
846- struct dir_list *dl;
847- struct stat st;
848-
849- if (stat(path, &st)) {
850- log_error("Ignoring %s: %s", path, strerror(errno));
851- /* But don't fail */
852- return 1;
853- }
854-
855- if (!S_ISREG(st.st_mode)) {
856- log_error("Ignoring %s: Not a regular file", path);
857- return 1;
858- }
859-
860- if (!(dl = _zalloc(sizeof(*dl) + strlen(path) + 1))) {
861- log_error("dir_list allocation failed for file");
862- return 0;
863- }
864-
865- strcpy(dl->dir, path);
866- dm_list_add(&_cache.files, &dl->list);
867- return 1;
868-}
869-
870-/* Check cached device name is still valid before returning it */
871-/* This should be a rare occurrence */
872-/* set quiet if the cache is expected to be out-of-date */
873-/* FIXME Make rest of code pass/cache struct device instead of dev_name */
874-const char *dev_name_confirmed(struct device *dev, int quiet)
875-{
876- struct stat buf;
877- const char *name;
878- int r;
879-
880- if ((dev->flags & DEV_REGULAR))
881- return dev_name(dev);
882-
883- while ((r = stat(name = dm_list_item(dev->aliases.n,
884- struct str_list)->str, &buf)) ||
885- (buf.st_rdev != dev->dev)) {
886- if (r < 0) {
887- if (quiet)
888- log_sys_debug("stat", name);
889- else
890- log_sys_error("stat", name);
891- }
892- if (quiet)
893- log_debug("Path %s no longer valid for device(%d,%d)",
894- name, (int) MAJOR(dev->dev),
895- (int) MINOR(dev->dev));
896- else
897- log_error("Path %s no longer valid for device(%d,%d)",
898- name, (int) MAJOR(dev->dev),
899- (int) MINOR(dev->dev));
900-
901- /* Remove the incorrect hash entry */
902- dm_hash_remove(_cache.names, name);
903-
904- /* Leave list alone if there isn't an alternative name */
905- /* so dev_name will always find something to return. */
906- /* Otherwise add the name to the correct device. */
907- if (dm_list_size(&dev->aliases) > 1) {
908- dm_list_del(dev->aliases.n);
909- if (!r)
910- _insert(name, 0, obtain_device_list_from_udev());
911- continue;
912- }
913-
914- /* Scanning issues this inappropriately sometimes. */
915- log_debug("Aborting - please provide new pathname for what "
916- "used to be %s", name);
917- return NULL;
918- }
919-
920- return dev_name(dev);
921-}
922-
923-struct device *dev_cache_get(const char *name, struct dev_filter *f)
924-{
925- struct stat buf;
926- struct device *d = (struct device *) dm_hash_lookup(_cache.names, name);
927-
928- if (d && (d->flags & DEV_REGULAR))
929- return d;
930-
931- /* If the entry's wrong, remove it */
932- if (d && (stat(name, &buf) || (buf.st_rdev != d->dev))) {
933- dm_hash_remove(_cache.names, name);
934- d = NULL;
935- }
936-
937- if (!d) {
938- _insert(name, 0, obtain_device_list_from_udev());
939- d = (struct device *) dm_hash_lookup(_cache.names, name);
940- if (!d) {
941- _full_scan(0);
942- d = (struct device *) dm_hash_lookup(_cache.names, name);
943- }
944- }
945-
946- return (d && (!f || (d->flags & DEV_REGULAR) ||
947- f->passes_filter(f, d))) ? d : NULL;
948-}
949-
950-static struct device *_dev_cache_seek_devt(dev_t dev)
951-{
952- struct device *d = NULL;
953- struct dm_hash_node *n = dm_hash_get_first(_cache.names);
954- while (n) {
955- d = dm_hash_get_data(_cache.names, n);
956- if (d->dev == dev)
957- return d;
958- n = dm_hash_get_next(_cache.names, n);
959- }
960- return NULL;
961-}
962-
963-/*
964- * TODO This is very inefficient. We probably want a hash table indexed by
965- * major:minor for keys to speed up these lookups.
966- */
967-struct device *dev_cache_get_by_devt(dev_t dev, struct dev_filter *f)
968-{
969- struct device *d = _dev_cache_seek_devt(dev);
970-
971- if (d && (d->flags & DEV_REGULAR))
972- return d;
973-
974- if (!d) {
975- _full_scan(0);
976- d = _dev_cache_seek_devt(dev);
977- }
978-
979- return (d && (!f || (d->flags & DEV_REGULAR) ||
980- f->passes_filter(f, d))) ? d : NULL;
981-}
982-
983-struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
984-{
985- struct dev_iter *di = dm_malloc(sizeof(*di));
986-
987- if (!di) {
988- log_error("dev_iter allocation failed");
989- return NULL;
990- }
991-
992- if (dev_scan && !trust_cache()) {
993- /* Flag gets reset between each command */
994- if (!full_scan_done()) {
995- if (f && f->wipe)
996- f->wipe(f); /* Calls _full_scan(1) */
997- else
998- _full_scan(1);
999- }
1000- } else
1001- _full_scan(0);
1002-
1003- di->current = btree_first(_cache.devices);
1004- di->filter = f;
1005- if (di->filter)
1006- di->filter->use_count++;
1007-
1008- return di;
1009-}
1010-
1011-void dev_iter_destroy(struct dev_iter *iter)
1012-{
1013- if (iter->filter)
1014- iter->filter->use_count--;
1015- dm_free(iter);
1016-}
1017-
1018-static struct device *_iter_next(struct dev_iter *iter)
1019-{
1020- struct device *d = btree_get_data(iter->current);
1021- iter->current = btree_next(iter->current);
1022- return d;
1023-}
1024-
1025-struct device *dev_iter_get(struct dev_iter *iter)
1026-{
1027- while (iter->current) {
1028- struct device *d = _iter_next(iter);
1029- if (!iter->filter || (d->flags & DEV_REGULAR) ||
1030- iter->filter->passes_filter(iter->filter, d))
1031- return d;
1032- }
1033-
1034- return NULL;
1035-}
1036-
1037-void dev_reset_error_count(struct cmd_context *cmd)
1038-{
1039- struct dev_iter iter;
1040-
1041- if (!_cache.devices)
1042- return;
1043-
1044- iter.current = btree_first(_cache.devices);
1045- while (iter.current)
1046- _iter_next(&iter)->error_count = 0;
1047-}
1048-
1049-int dev_fd(struct device *dev)
1050-{
1051- return dev->fd;
1052-}
1053-
1054-const char *dev_name(const struct device *dev)
1055-{
1056- return (dev) ? dm_list_item(dev->aliases.n, struct str_list)->str :
1057- "unknown device";
1058-}
1059
1060=== removed directory '.pc/dirs.patch'
1061=== removed directory '.pc/dirs.patch/daemons'
1062=== removed directory '.pc/dirs.patch/daemons/dmeventd'
1063=== removed file '.pc/dirs.patch/daemons/dmeventd/Makefile.in'
1064--- .pc/dirs.patch/daemons/dmeventd/Makefile.in 2012-05-27 19:05:21 +0000
1065+++ .pc/dirs.patch/daemons/dmeventd/Makefile.in 1970-01-01 00:00:00 +0000
1066@@ -1,108 +0,0 @@
1067-#
1068-# Copyright (C) 2005-2011 Red Hat, Inc. All rights reserved.
1069-#
1070-# This file is part of the device-mapper userspace tools.
1071-#
1072-# This copyrighted material is made available to anyone wishing to use,
1073-# modify, copy, or redistribute it subject to the terms and conditions
1074-# of the GNU Lesser General Public License v.2.1.
1075-#
1076-# You should have received a copy of the GNU Lesser General Public License
1077-# along with this program; if not, write to the Free Software Foundation,
1078-# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1079-
1080-srcdir = @srcdir@
1081-top_srcdir = @top_srcdir@
1082-top_builddir = @top_builddir@
1083-
1084-SOURCES = libdevmapper-event.c
1085-SOURCES2 = dmeventd.c
1086-
1087-TARGETS = dmeventd
1088-
1089-.PHONY: install_lib_dynamic install_lib_static install_include \
1090- install_pkgconfig install_dmeventd_dynamic install_dmeventd_static \
1091- install_lib install_dmeventd
1092-
1093-INSTALL_DMEVENTD_TARGETS = install_dmeventd_dynamic
1094-INSTALL_LIB_TARGETS = install_lib_dynamic
1095-
1096-LIB_NAME = libdevmapper-event
1097-ifeq ("@STATIC_LINK@", "yes")
1098- LIB_STATIC = $(LIB_NAME).a
1099- TARGETS += $(LIB_STATIC) dmeventd.static
1100- INSTALL_DMEVENTD_TARGETS += install_dmeventd_static
1101- INSTALL_LIB_TARGETS += install_lib_static
1102-endif
1103-
1104-LIB_VERSION = $(LIB_VERSION_DM)
1105-LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
1106-
1107-CLEAN_TARGETS = dmeventd.static $(LIB_NAME).a
1108-
1109-ifneq ($(MAKECMDGOALS),device-mapper)
1110- SUBDIRS+=plugins
1111-endif
1112-
1113-CFLOW_LIST = $(SOURCES)
1114-CFLOW_LIST_TARGET = $(LIB_NAME).cflow
1115-CFLOW_TARGET = dmeventd
1116-
1117-EXPORTED_HEADER = $(srcdir)/libdevmapper-event.h
1118-EXPORTED_FN_PREFIX = dm_event
1119-
1120-include $(top_builddir)/make.tmpl
1121-
1122-all: device-mapper
1123-device-mapper: $(TARGETS)
1124-
1125-LIBS += -ldevmapper
1126-LVMLIBS += -ldevmapper-event $(PTHREAD_LIBS)
1127-
1128-dmeventd: $(LIB_SHARED) dmeventd.o
1129- $(CC) $(CFLAGS) $(LDFLAGS) $(ELDFLAGS) -L. -o $@ dmeventd.o \
1130- $(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
1131-
1132-dmeventd.static: $(LIB_STATIC) dmeventd.o $(interfacebuilddir)/libdevmapper.a
1133- $(CC) $(CFLAGS) $(LDFLAGS) $(ELDFLAGS) -static -L. -L$(interfacebuilddir) -o $@ \
1134- dmeventd.o $(DL_LIBS) $(LVMLIBS) $(LIBS) $(STATIC_LIBS)
1135-
1136-ifeq ("@PKGCONFIG@", "yes")
1137- INSTALL_LIB_TARGETS += install_pkgconfig
1138-endif
1139-
1140-ifneq ("$(CFLOW_CMD)", "")
1141-CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
1142--include $(top_builddir)/libdm/libdevmapper.cflow
1143--include $(top_builddir)/lib/liblvm-internal.cflow
1144--include $(top_builddir)/lib/liblvm2cmd.cflow
1145--include $(top_builddir)/daemons/dmeventd/$(LIB_NAME).cflow
1146--include $(top_builddir)/daemons/dmeventd/plugins/mirror/$(LIB_NAME)-lvm2mirror.cflow
1147-endif
1148-
1149-install_include: $(srcdir)/libdevmapper-event.h
1150- $(INSTALL_DATA) -D $< $(includedir)/$(<F)
1151-
1152-install_pkgconfig: libdevmapper-event.pc
1153- $(INSTALL_DATA) -D $< $(pkgconfigdir)/devmapper-event.pc
1154-
1155-install_lib_dynamic: install_lib_shared
1156-
1157-install_lib_static: $(LIB_STATIC)
1158- $(INSTALL_DATA) -D $< $(usrlibdir)/$(<F)
1159-
1160-install_lib: $(INSTALL_LIB_TARGETS)
1161-
1162-install_dmeventd_dynamic: dmeventd
1163- $(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
1164-
1165-install_dmeventd_static: dmeventd.static
1166- $(INSTALL_PROGRAM) -D $< $(staticdir)/$(<F)
1167-
1168-install_dmeventd: $(INSTALL_DMEVENTD_TARGETS)
1169-
1170-install: install_include install_lib install_dmeventd
1171-
1172-install_device-mapper: install_include install_lib install_dmeventd
1173-
1174-DISTCLEAN_TARGETS += libdevmapper-event.pc
1175
1176=== removed file '.pc/dirs.patch/daemons/dmeventd/dmeventd.c'
1177--- .pc/dirs.patch/daemons/dmeventd/dmeventd.c 2013-03-03 12:33:47 +0000
1178+++ .pc/dirs.patch/daemons/dmeventd/dmeventd.c 1970-01-01 00:00:00 +0000
1179@@ -1,2026 +0,0 @@
1180-/*
1181- * Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
1182- *
1183- * This file is part of the device-mapper userspace tools.
1184- *
1185- * This copyrighted material is made available to anyone wishing to use,
1186- * modify, copy, or redistribute it subject to the terms and conditions
1187- * of the GNU Lesser General Public License v.2.1.
1188- *
1189- * You should have received a copy of the GNU Lesser General Public License
1190- * along with this program; if not, write to the Free Software Foundation,
1191- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1192- */
1193-
1194-/*
1195- * dmeventd - dm event daemon to monitor active mapped devices
1196- */
1197-
1198-#define _GNU_SOURCE
1199-#define _FILE_OFFSET_BITS 64
1200-
1201-#include "configure.h"
1202-#include "libdevmapper.h"
1203-#include "libdevmapper-event.h"
1204-#include "dmeventd.h"
1205-//#include "libmultilog.h"
1206-#include "dm-logging.h"
1207-
1208-#include <dlfcn.h>
1209-#include <errno.h>
1210-#include <pthread.h>
1211-#include <sys/file.h>
1212-#include <sys/stat.h>
1213-#include <sys/wait.h>
1214-#include <sys/time.h>
1215-#include <sys/resource.h>
1216-#include <unistd.h>
1217-#include <signal.h>
1218-#include <arpa/inet.h> /* for htonl, ntohl */
1219-
1220-#ifdef linux
1221-/*
1222- * Kernel version 2.6.36 and higher has
1223- * new OOM killer adjustment interface.
1224- */
1225-# define OOM_ADJ_FILE_OLD "/proc/self/oom_adj"
1226-# define OOM_ADJ_FILE "/proc/self/oom_score_adj"
1227-
1228-/* From linux/oom.h */
1229-/* Old interface */
1230-# define OOM_DISABLE (-17)
1231-# define OOM_ADJUST_MIN (-16)
1232-/* New interface */
1233-# define OOM_SCORE_ADJ_MIN (-1000)
1234-
1235-/* Systemd on-demand activation support */
1236-# define SD_ACTIVATION_ENV_VAR_NAME "SD_ACTIVATION"
1237-# define SD_LISTEN_PID_ENV_VAR_NAME "LISTEN_PID"
1238-# define SD_LISTEN_FDS_ENV_VAR_NAME "LISTEN_FDS"
1239-# define SD_LISTEN_FDS_START 3
1240-# define SD_FD_FIFO_SERVER SD_LISTEN_FDS_START
1241-# define SD_FD_FIFO_CLIENT (SD_LISTEN_FDS_START + 1)
1242-
1243-#endif
1244-
1245-/* FIXME We use syslog for now, because multilog is not yet implemented */
1246-#include <syslog.h>
1247-
1248-static volatile sig_atomic_t _exit_now = 0; /* set to '1' when signal is given to exit */
1249-static volatile sig_atomic_t _thread_registries_empty = 1; /* registries are empty initially */
1250-
1251-/* List (un)link macros. */
1252-#define LINK(x, head) dm_list_add(head, &(x)->list)
1253-#define LINK_DSO(dso) LINK(dso, &_dso_registry)
1254-#define LINK_THREAD(thread) LINK(thread, &_thread_registry)
1255-
1256-#define UNLINK(x) dm_list_del(&(x)->list)
1257-#define UNLINK_DSO(x) UNLINK(x)
1258-#define UNLINK_THREAD(x) UNLINK(x)
1259-
1260-#define DAEMON_NAME "dmeventd"
1261-
1262-/*
1263- Global mutex for thread list access. Has to be held when:
1264- - iterating thread list
1265- - adding or removing elements from thread list
1266- - changing or reading thread_status's fields:
1267- processing, status, events
1268- Use _lock_mutex() and _unlock_mutex() to hold/release it
1269-*/
1270-static pthread_mutex_t _global_mutex;
1271-
1272-/*
1273- There are three states a thread can attain (see struct
1274- thread_status, field int status):
1275-
1276- - DM_THREAD_RUNNING: thread has started up and is either working or
1277- waiting for events... transitions to either SHUTDOWN or DONE
1278- - DM_THREAD_SHUTDOWN: thread is still doing something, but it is
1279- supposed to terminate (and transition to DONE) as soon as it
1280- finishes whatever it was doing at the point of flipping state to
1281- SHUTDOWN... the thread is still on the thread list
1282- - DM_THREAD_DONE: thread has terminated and has been moved over to
1283- unused thread list, cleanup pending
1284- */
1285-#define DM_THREAD_RUNNING 0
1286-#define DM_THREAD_SHUTDOWN 1
1287-#define DM_THREAD_DONE 2
1288-
1289-#define THREAD_STACK_SIZE (300*1024)
1290-
1291-int dmeventd_debug = 0;
1292-static int _systemd_activation = 0;
1293-static int _foreground = 0;
1294-static int _restart = 0;
1295-static char **_initial_registrations = 0;
1296-
1297-/* Data kept about a DSO. */
1298-struct dso_data {
1299- struct dm_list list;
1300-
1301- char *dso_name; /* DSO name (eg, "evms", "dmraid", "lvm2"). */
1302-
1303- void *dso_handle; /* Opaque handle as returned from dlopen(). */
1304- unsigned int ref_count; /* Library reference count. */
1305-
1306- /*
1307- * Event processing.
1308- *
1309- * The DSO can do whatever appropriate steps if an event
1310- * happens such as changing the mapping in case a mirror
1311- * fails, update the application metadata etc.
1312- *
1313- * This function gets a dm_task that is a result of
1314- * DM_DEVICE_WAITEVENT ioctl (results equivalent to
1315- * DM_DEVICE_STATUS). It should not destroy it.
1316- * The caller must dispose of the task.
1317- */
1318- void (*process_event)(struct dm_task *dmt, enum dm_event_mask event, void **user);
1319-
1320- /*
1321- * Device registration.
1322- *
1323- * When an application registers a device for an event, the DSO
1324- * can carry out appropriate steps so that a later call to
1325- * the process_event() function is sane (eg, read metadata
1326- * and activate a mapping).
1327- */
1328- int (*register_device)(const char *device, const char *uuid, int major,
1329- int minor, void **user);
1330-
1331- /*
1332- * Device unregistration.
1333- *
1334- * In case all devices of a mapping (eg, RAID10) are unregistered
1335- * for events, the DSO can recognize this and carry out appropriate
1336- * steps (eg, deactivate mapping, metadata update).
1337- */
1338- int (*unregister_device)(const char *device, const char *uuid,
1339- int major, int minor, void **user);
1340-};
1341-static DM_LIST_INIT(_dso_registry);
1342-
1343-/* Structure to keep parsed register variables from client message. */
1344-struct message_data {
1345- char *id;
1346- char *dso_name; /* Name of DSO. */
1347- char *device_uuid; /* Mapped device path. */
1348- union {
1349- char *str; /* Events string as fetched from message. */
1350- enum dm_event_mask field; /* Events bitfield. */
1351- } events;
1352- union {
1353- char *str;
1354- uint32_t secs;
1355- } timeout;
1356- struct dm_event_daemon_message *msg; /* Pointer to message buffer. */
1357-};
1358-
1359-/*
1360- * Housekeeping of thread+device states.
1361- *
1362- * One thread per mapped device which can block on it until an event
1363- * occurs and the event processing function of the DSO gets called.
1364- */
1365-struct thread_status {
1366- struct dm_list list;
1367-
1368- pthread_t thread;
1369-
1370- struct dso_data *dso_data; /* DSO this thread accesses. */
1371-
1372- struct {
1373- char *uuid;
1374- char *name;
1375- int major, minor;
1376- } device;
1377- uint32_t event_nr; /* event number */
1378- int processing; /* Set when event is being processed */
1379-
1380- int status; /* see DM_THREAD_{RUNNING,SHUTDOWN,DONE}
1381- constants above */
1382- enum dm_event_mask events; /* bitfield for event filter. */
1383- enum dm_event_mask current_events; /* bitfield for occured events. */
1384- struct dm_task *current_task;
1385- time_t next_time;
1386- uint32_t timeout;
1387- struct dm_list timeout_list;
1388- void *dso_private; /* dso per-thread status variable */
1389-};
1390-static DM_LIST_INIT(_thread_registry);
1391-static DM_LIST_INIT(_thread_registry_unused);
1392-
1393-static int _timeout_running;
1394-static DM_LIST_INIT(_timeout_registry);
1395-static pthread_mutex_t _timeout_mutex = PTHREAD_MUTEX_INITIALIZER;
1396-static pthread_cond_t _timeout_cond = PTHREAD_COND_INITIALIZER;
1397-
1398-/* Allocate/free the status structure for a monitoring thread. */
1399-static struct thread_status *_alloc_thread_status(struct message_data *data,
1400- struct dso_data *dso_data)
1401-{
1402- struct thread_status *ret = (typeof(ret)) dm_zalloc(sizeof(*ret));
1403-
1404- if (!ret)
1405- return NULL;
1406-
1407- if (!(ret->device.uuid = dm_strdup(data->device_uuid))) {
1408- dm_free(ret);
1409- return NULL;
1410- }
1411-
1412- ret->current_task = NULL;
1413- ret->device.name = NULL;
1414- ret->device.major = ret->device.minor = 0;
1415- ret->dso_data = dso_data;
1416- ret->events = data->events.field;
1417- ret->timeout = data->timeout.secs;
1418- dm_list_init(&ret->timeout_list);
1419-
1420- return ret;
1421-}
1422-
1423-static void _lib_put(struct dso_data *data);
1424-static void _free_thread_status(struct thread_status *thread)
1425-{
1426- _lib_put(thread->dso_data);
1427- if (thread->current_task)
1428- dm_task_destroy(thread->current_task);
1429- dm_free(thread->device.uuid);
1430- dm_free(thread->device.name);
1431- dm_free(thread);
1432-}
1433-
1434-/* Allocate/free DSO data. */
1435-static struct dso_data *_alloc_dso_data(struct message_data *data)
1436-{
1437- struct dso_data *ret = (typeof(ret)) dm_zalloc(sizeof(*ret));
1438-
1439- if (!ret)
1440- return NULL;
1441-
1442- if (!(ret->dso_name = dm_strdup(data->dso_name))) {
1443- dm_free(ret);
1444- return NULL;
1445- }
1446-
1447- return ret;
1448-}
1449-
1450-/* Create a device monitoring thread. */
1451-static int _pthread_create_smallstack(pthread_t *t, void *(*fun)(void *), void *arg)
1452-{
1453- pthread_attr_t attr;
1454- pthread_attr_init(&attr);
1455- /*
1456- * We use a smaller stack since it gets preallocated in its entirety
1457- */
1458- pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
1459- return pthread_create(t, &attr, fun, arg);
1460-}
1461-
1462-static void _free_dso_data(struct dso_data *data)
1463-{
1464- dm_free(data->dso_name);
1465- dm_free(data);
1466-}
1467-
1468-/*
1469- * Fetch a string off src and duplicate it into *ptr.
1470- * Pay attention to zero-length strings.
1471- */
1472-/* FIXME? move to libdevmapper to share with the client lib (need to
1473- make delimiter a parameter then) */
1474-static int _fetch_string(char **ptr, char **src, const int delimiter)
1475-{
1476- int ret = 0;
1477- char *p;
1478- size_t len;
1479-
1480- if ((p = strchr(*src, delimiter)))
1481- *p = 0;
1482-
1483- if ((*ptr = dm_strdup(*src))) {
1484- if ((len = strlen(*ptr)))
1485- *src += len;
1486- else {
1487- dm_free(*ptr);
1488- *ptr = NULL;
1489- }
1490-
1491- (*src)++;
1492- ret = 1;
1493- }
1494-
1495- if (p)
1496- *p = delimiter;
1497-
1498- return ret;
1499-}
1500-
1501-/* Free message memory. */
1502-static void _free_message(struct message_data *message_data)
1503-{
1504- dm_free(message_data->id);
1505- dm_free(message_data->dso_name);
1506-
1507- dm_free(message_data->device_uuid);
1508-
1509-}
1510-
1511-/* Parse a register message from the client. */
1512-static int _parse_message(struct message_data *message_data)
1513-{
1514- int ret = 0;
1515- char *p = message_data->msg->data;
1516- struct dm_event_daemon_message *msg = message_data->msg;
1517-
1518- if (!msg->data)
1519- return 0;
1520-
1521- /*
1522- * Retrieve application identifier, mapped device
1523- * path and events # string from message.
1524- */
1525- if (_fetch_string(&message_data->id, &p, ' ') &&
1526- _fetch_string(&message_data->dso_name, &p, ' ') &&
1527- _fetch_string(&message_data->device_uuid, &p, ' ') &&
1528- _fetch_string(&message_data->events.str, &p, ' ') &&
1529- _fetch_string(&message_data->timeout.str, &p, ' ')) {
1530- if (message_data->events.str) {
1531- enum dm_event_mask i = atoi(message_data->events.str);
1532-
1533- /*
1534- * Free string representaion of events.
1535- * Not needed an more.
1536- */
1537- dm_free(message_data->events.str);
1538- message_data->events.field = i;
1539- }
1540- if (message_data->timeout.str) {
1541- uint32_t secs = atoi(message_data->timeout.str);
1542- dm_free(message_data->timeout.str);
1543- message_data->timeout.secs = secs ? secs :
1544- DM_EVENT_DEFAULT_TIMEOUT;
1545- }
1546-
1547- ret = 1;
1548- }
1549-
1550- dm_free(msg->data);
1551- msg->data = NULL;
1552- msg->size = 0;
1553- return ret;
1554-};
1555-
1556-/* Global mutex to lock access to lists et al. See _global_mutex
1557- above. */
1558-static int _lock_mutex(void)
1559-{
1560- return pthread_mutex_lock(&_global_mutex);
1561-}
1562-
1563-static int _unlock_mutex(void)
1564-{
1565- return pthread_mutex_unlock(&_global_mutex);
1566-}
1567-
1568-/* Check, if a device exists. */
1569-static int _fill_device_data(struct thread_status *ts)
1570-{
1571- struct dm_task *dmt;
1572- struct dm_info dmi;
1573-
1574- if (!ts->device.uuid)
1575- return 0;
1576-
1577- ts->device.name = NULL;
1578- ts->device.major = ts->device.minor = 0;
1579-
1580- dmt = dm_task_create(DM_DEVICE_INFO);
1581- if (!dmt)
1582- return 0;
1583-
1584- if (!dm_task_set_uuid(dmt, ts->device.uuid))
1585- goto fail;
1586-
1587- if (!dm_task_run(dmt))
1588- goto fail;
1589-
1590- ts->device.name = dm_strdup(dm_task_get_name(dmt));
1591- if (!ts->device.name)
1592- goto fail;
1593-
1594- if (!dm_task_get_info(dmt, &dmi))
1595- goto fail;
1596-
1597- ts->device.major = dmi.major;
1598- ts->device.minor = dmi.minor;
1599-
1600- dm_task_destroy(dmt);
1601- return 1;
1602-
1603- fail:
1604- dm_task_destroy(dmt);
1605- dm_free(ts->device.name);
1606- return 0;
1607-}
1608-
1609-/*
1610- * Find an existing thread for a device.
1611- *
1612- * Mutex must be held when calling this.
1613- */
1614-static struct thread_status *_lookup_thread_status(struct message_data *data)
1615-{
1616- struct thread_status *thread;
1617-
1618- dm_list_iterate_items(thread, &_thread_registry)
1619- if (!strcmp(data->device_uuid, thread->device.uuid))
1620- return thread;
1621-
1622- return NULL;
1623-}
1624-
1625-static int _get_status(struct message_data *message_data)
1626-{
1627- struct dm_event_daemon_message *msg = message_data->msg;
1628- struct thread_status *thread;
1629- int i, j;
1630- int ret = -1;
1631- int count = dm_list_size(&_thread_registry);
1632- int size = 0, current = 0;
1633- char *buffers[count];
1634- char *message;
1635-
1636- dm_free(msg->data);
1637-
1638- for (i = 0; i < count; ++i)
1639- buffers[i] = NULL;
1640-
1641- i = 0;
1642- _lock_mutex();
1643- dm_list_iterate_items(thread, &_thread_registry) {
1644- if ((current = dm_asprintf(buffers + i, "0:%d %s %s %u %" PRIu32 ";",
1645- i, thread->dso_data->dso_name,
1646- thread->device.uuid, thread->events,
1647- thread->timeout)) < 0) {
1648- _unlock_mutex();
1649- goto out;
1650- }
1651- ++ i;
1652- size += current;
1653- }
1654- _unlock_mutex();
1655-
1656- msg->size = size + strlen(message_data->id) + 1;
1657- msg->data = dm_malloc(msg->size);
1658- if (!msg->data)
1659- goto out;
1660- *msg->data = 0;
1661-
1662- message = msg->data;
1663- strcpy(message, message_data->id);
1664- message += strlen(message_data->id);
1665- *message = ' ';
1666- message ++;
1667- for (j = 0; j < i; ++j) {
1668- strcpy(message, buffers[j]);
1669- message += strlen(buffers[j]);
1670- }
1671-
1672- ret = 0;
1673- out:
1674- for (j = 0; j < i; ++j)
1675- dm_free(buffers[j]);
1676- return ret;
1677-
1678-}
1679-
1680-/* Cleanup at exit. */
1681-static void _exit_dm_lib(void)
1682-{
1683- dm_lib_release();
1684- dm_lib_exit();
1685-}
1686-
1687-static void _exit_timeout(void *unused __attribute__((unused)))
1688-{
1689- _timeout_running = 0;
1690- pthread_mutex_unlock(&_timeout_mutex);
1691-}
1692-
1693-/* Wake up monitor threads every so often. */
1694-static void *_timeout_thread(void *unused __attribute__((unused)))
1695-{
1696- struct timespec timeout;
1697- time_t curr_time;
1698-
1699- timeout.tv_nsec = 0;
1700- pthread_cleanup_push(_exit_timeout, NULL);
1701- pthread_mutex_lock(&_timeout_mutex);
1702-
1703- while (!dm_list_empty(&_timeout_registry)) {
1704- struct thread_status *thread;
1705-
1706- timeout.tv_sec = 0;
1707- curr_time = time(NULL);
1708-
1709- dm_list_iterate_items_gen(thread, &_timeout_registry, timeout_list) {
1710- if (thread->next_time <= curr_time) {
1711- thread->next_time = curr_time + thread->timeout;
1712- pthread_kill(thread->thread, SIGALRM);
1713- }
1714-
1715- if (thread->next_time < timeout.tv_sec || !timeout.tv_sec)
1716- timeout.tv_sec = thread->next_time;
1717- }
1718-
1719- pthread_cond_timedwait(&_timeout_cond, &_timeout_mutex,
1720- &timeout);
1721- }
1722-
1723- pthread_cleanup_pop(1);
1724-
1725- return NULL;
1726-}
1727-
1728-static int _register_for_timeout(struct thread_status *thread)
1729-{
1730- int ret = 0;
1731-
1732- pthread_mutex_lock(&_timeout_mutex);
1733-
1734- thread->next_time = time(NULL) + thread->timeout;
1735-
1736- if (dm_list_empty(&thread->timeout_list)) {
1737- dm_list_add(&_timeout_registry, &thread->timeout_list);
1738- if (_timeout_running)
1739- pthread_cond_signal(&_timeout_cond);
1740- }
1741-
1742- if (!_timeout_running) {
1743- pthread_t timeout_id;
1744-
1745- if (!(ret = -_pthread_create_smallstack(&timeout_id, _timeout_thread, NULL)))
1746- _timeout_running = 1;
1747- }
1748-
1749- pthread_mutex_unlock(&_timeout_mutex);
1750-
1751- return ret;
1752-}
1753-
1754-static void _unregister_for_timeout(struct thread_status *thread)
1755-{
1756- pthread_mutex_lock(&_timeout_mutex);
1757- if (!dm_list_empty(&thread->timeout_list)) {
1758- dm_list_del(&thread->timeout_list);
1759- dm_list_init(&thread->timeout_list);
1760- }
1761- pthread_mutex_unlock(&_timeout_mutex);
1762-}
1763-
1764-__attribute__((format(printf, 4, 5)))
1765-static void _no_intr_log(int level, const char *file, int line,
1766- const char *f, ...)
1767-{
1768- va_list ap;
1769-
1770- if (errno == EINTR)
1771- return;
1772- if (level > _LOG_WARN)
1773- return;
1774-
1775- va_start(ap, f);
1776-
1777- if (level < _LOG_WARN)
1778- vfprintf(stderr, f, ap);
1779- else
1780- vprintf(f, ap);
1781-
1782- va_end(ap);
1783-
1784- if (level < _LOG_WARN)
1785- fprintf(stderr, "\n");
1786- else
1787- fprintf(stdout, "\n");
1788-}
1789-
1790-static sigset_t _unblock_sigalrm(void)
1791-{
1792- sigset_t set, old;
1793-
1794- sigemptyset(&set);
1795- sigaddset(&set, SIGALRM);
1796- pthread_sigmask(SIG_UNBLOCK, &set, &old);
1797- return old;
1798-}
1799-
1800-#define DM_WAIT_RETRY 0
1801-#define DM_WAIT_INTR 1
1802-#define DM_WAIT_FATAL 2
1803-
1804-/* Wait on a device until an event occurs. */
1805-static int _event_wait(struct thread_status *thread, struct dm_task **task)
1806-{
1807- sigset_t set;
1808- int ret = DM_WAIT_RETRY;
1809- struct dm_task *dmt;
1810- struct dm_info info;
1811-
1812- *task = 0;
1813-
1814- if (!(dmt = dm_task_create(DM_DEVICE_WAITEVENT)))
1815- return DM_WAIT_RETRY;
1816-
1817- thread->current_task = dmt;
1818-
1819- if (!dm_task_set_uuid(dmt, thread->device.uuid) ||
1820- !dm_task_set_event_nr(dmt, thread->event_nr))
1821- goto out;
1822-
1823- /*
1824- * This is so that you can break out of waiting on an event,
1825- * either for a timeout event, or to cancel the thread.
1826- */
1827- set = _unblock_sigalrm();
1828- dm_log_init(_no_intr_log);
1829- errno = 0;
1830- if (dm_task_run(dmt)) {
1831- thread->current_events |= DM_EVENT_DEVICE_ERROR;
1832- ret = DM_WAIT_INTR;
1833-
1834- if ((ret = dm_task_get_info(dmt, &info)))
1835- thread->event_nr = info.event_nr;
1836- } else if (thread->events & DM_EVENT_TIMEOUT && errno == EINTR) {
1837- thread->current_events |= DM_EVENT_TIMEOUT;
1838- ret = DM_WAIT_INTR;
1839- } else if (thread->status == DM_THREAD_SHUTDOWN && errno == EINTR) {
1840- ret = DM_WAIT_FATAL;
1841- } else {
1842- syslog(LOG_NOTICE, "dm_task_run failed, errno = %d, %s",
1843- errno, strerror(errno));
1844- if (errno == ENXIO) {
1845- syslog(LOG_ERR, "%s disappeared, detaching",
1846- thread->device.name);
1847- ret = DM_WAIT_FATAL;
1848- }
1849- }
1850-
1851- pthread_sigmask(SIG_SETMASK, &set, NULL);
1852- dm_log_init(NULL);
1853-
1854- out:
1855- if (ret == DM_WAIT_FATAL || ret == DM_WAIT_RETRY) {
1856- dm_task_destroy(dmt);
1857- thread->current_task = NULL;
1858- } else
1859- *task = dmt;
1860-
1861- return ret;
1862-}
1863-
1864-/* Register a device with the DSO. */
1865-static int _do_register_device(struct thread_status *thread)
1866-{
1867- return thread->dso_data->register_device(thread->device.name,
1868- thread->device.uuid,
1869- thread->device.major,
1870- thread->device.minor,
1871- &(thread->dso_private));
1872-}
1873-
1874-/* Unregister a device with the DSO. */
1875-static int _do_unregister_device(struct thread_status *thread)
1876-{
1877- return thread->dso_data->unregister_device(thread->device.name,
1878- thread->device.uuid,
1879- thread->device.major,
1880- thread->device.minor,
1881- &(thread->dso_private));
1882-}
1883-
1884-/* Process an event in the DSO. */
1885-static void _do_process_event(struct thread_status *thread, struct dm_task *task)
1886-{
1887- thread->dso_data->process_event(task, thread->current_events, &(thread->dso_private));
1888-}
1889-
1890-/* Thread cleanup handler to unregister device. */
1891-static void _monitor_unregister(void *arg)
1892-{
1893- struct thread_status *thread = arg, *thread_iter;
1894-
1895- if (!_do_unregister_device(thread))
1896- syslog(LOG_ERR, "%s: %s unregister failed\n", __func__,
1897- thread->device.name);
1898- if (thread->current_task)
1899- dm_task_destroy(thread->current_task);
1900- thread->current_task = NULL;
1901-
1902- _lock_mutex();
1903- if (thread->events & DM_EVENT_TIMEOUT) {
1904- /* _unregister_for_timeout locks another mutex, we
1905- don't want to deadlock so we release our mutex for
1906- a bit */
1907- _unlock_mutex();
1908- _unregister_for_timeout(thread);
1909- _lock_mutex();
1910- }
1911- /* we may have been relinked to unused registry since we were
1912- called, so check that */
1913- dm_list_iterate_items(thread_iter, &_thread_registry_unused)
1914- if (thread_iter == thread) {
1915- thread->status = DM_THREAD_DONE;
1916- _unlock_mutex();
1917- return;
1918- }
1919- thread->status = DM_THREAD_DONE;
1920- pthread_mutex_lock(&_timeout_mutex);
1921- UNLINK_THREAD(thread);
1922- LINK(thread, &_thread_registry_unused);
1923- pthread_mutex_unlock(&_timeout_mutex);
1924- _unlock_mutex();
1925-}
1926-
1927-static struct dm_task *_get_device_status(struct thread_status *ts)
1928-{
1929- struct dm_task *dmt = dm_task_create(DM_DEVICE_STATUS);
1930-
1931- if (!dmt)
1932- return NULL;
1933-
1934- if (!dm_task_set_uuid(dmt, ts->device.uuid)) {
1935- dm_task_destroy(dmt);
1936- return NULL;
1937- }
1938-
1939- if (!dm_task_run(dmt)) {
1940- dm_task_destroy(dmt);
1941- return NULL;
1942- }
1943-
1944- return dmt;
1945-}
1946-
1947-/* Device monitoring thread. */
1948-static void *_monitor_thread(void *arg)
1949-{
1950- struct thread_status *thread = arg;
1951- int wait_error = 0;
1952- struct dm_task *task;
1953-
1954- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
1955- pthread_cleanup_push(_monitor_unregister, thread);
1956-
1957- /* Wait for do_process_request() to finish its task. */
1958- _lock_mutex();
1959- thread->status = DM_THREAD_RUNNING;
1960- _unlock_mutex();
1961-
1962- /* Loop forever awaiting/analyzing device events. */
1963- while (1) {
1964- thread->current_events = 0;
1965-
1966- wait_error = _event_wait(thread, &task);
1967- if (wait_error == DM_WAIT_RETRY)
1968- continue;
1969-
1970- if (wait_error == DM_WAIT_FATAL)
1971- break;
1972-
1973- /* Timeout occurred, task is not filled properly.
1974- * We get device status here for processing it in DSO.
1975- */
1976- if (wait_error == DM_WAIT_INTR &&
1977- thread->current_events & DM_EVENT_TIMEOUT) {
1978- dm_task_destroy(task);
1979- task = _get_device_status(thread);
1980- /* FIXME: syslog fail here ? */
1981- if (!(thread->current_task = task))
1982- continue;
1983- }
1984-
1985- /*
1986- * We know that wait succeeded and stored a
1987- * pointer to dm_task with device status into task.
1988- */
1989-
1990- /*
1991- * Check against filter.
1992- *
1993- * If there's current events delivered from _event_wait() AND
1994- * the device got registered for those events AND
1995- * those events haven't been processed yet, call
1996- * the DSO's process_event() handler.
1997- */
1998- _lock_mutex();
1999- if (thread->status == DM_THREAD_SHUTDOWN) {
2000- _unlock_mutex();
2001- break;
2002- }
2003- _unlock_mutex();
2004-
2005- if (thread->events & thread->current_events) {
2006- _lock_mutex();
2007- thread->processing = 1;
2008- _unlock_mutex();
2009-
2010- _do_process_event(thread, task);
2011- dm_task_destroy(task);
2012- thread->current_task = NULL;
2013-
2014- _lock_mutex();
2015- thread->processing = 0;
2016- _unlock_mutex();
2017- } else {
2018- dm_task_destroy(task);
2019- thread->current_task = NULL;
2020- }
2021- }
2022-
2023- pthread_cleanup_pop(1);
2024-
2025- return NULL;
2026-}
2027-
2028-/* Create a device monitoring thread. */
2029-static int _create_thread(struct thread_status *thread)
2030-{
2031- return _pthread_create_smallstack(&thread->thread, _monitor_thread, thread);
2032-}
2033-
2034-static int _terminate_thread(struct thread_status *thread)
2035-{
2036- return pthread_kill(thread->thread, SIGALRM);
2037-}
2038-
2039-/* DSO reference counting. Call with _global_mutex locked! */
2040-static void _lib_get(struct dso_data *data)
2041-{
2042- data->ref_count++;
2043-}
2044-
2045-static void _lib_put(struct dso_data *data)
2046-{
2047- if (!--data->ref_count) {
2048- dlclose(data->dso_handle);
2049- UNLINK_DSO(data);
2050- _free_dso_data(data);
2051- }
2052-}
2053-
2054-/* Find DSO data. */
2055-static struct dso_data *_lookup_dso(struct message_data *data)
2056-{
2057- struct dso_data *dso_data, *ret = NULL;
2058-
2059- dm_list_iterate_items(dso_data, &_dso_registry)
2060- if (!strcmp(data->dso_name, dso_data->dso_name)) {
2061- _lib_get(dso_data);
2062- ret = dso_data;
2063- break;
2064- }
2065-
2066- return ret;
2067-}
2068-
2069-/* Lookup DSO symbols we need. */
2070-static int _lookup_symbol(void *dl, void **symbol, const char *name)
2071-{
2072- if ((*symbol = dlsym(dl, name)))
2073- return 1;
2074-
2075- return 0;
2076-}
2077-
2078-static int lookup_symbols(void *dl, struct dso_data *data)
2079-{
2080- return _lookup_symbol(dl, (void *) &data->process_event,
2081- "process_event") &&
2082- _lookup_symbol(dl, (void *) &data->register_device,
2083- "register_device") &&
2084- _lookup_symbol(dl, (void *) &data->unregister_device,
2085- "unregister_device");
2086-}
2087-
2088-/* Load an application specific DSO. */
2089-static struct dso_data *_load_dso(struct message_data *data)
2090-{
2091- void *dl;
2092- struct dso_data *ret = NULL;
2093-
2094- if (!(dl = dlopen(data->dso_name, RTLD_NOW))) {
2095- const char *dlerr = dlerror();
2096- syslog(LOG_ERR, "dmeventd %s dlopen failed: %s", data->dso_name,
2097- dlerr);
2098- data->msg->size =
2099- dm_asprintf(&(data->msg->data), "%s %s dlopen failed: %s",
2100- data->id, data->dso_name, dlerr);
2101- return NULL;
2102- }
2103-
2104- if (!(ret = _alloc_dso_data(data))) {
2105- dlclose(dl);
2106- return NULL;
2107- }
2108-
2109- if (!(lookup_symbols(dl, ret))) {
2110- _free_dso_data(ret);
2111- dlclose(dl);
2112- return NULL;
2113- }
2114-
2115- /*
2116- * Keep handle to close the library once
2117- * we've got no references to it any more.
2118- */
2119- ret->dso_handle = dl;
2120- _lib_get(ret);
2121-
2122- _lock_mutex();
2123- LINK_DSO(ret);
2124- _unlock_mutex();
2125-
2126- return ret;
2127-}
2128-
2129-/* Return success on daemon active check. */
2130-static int _active(struct message_data *message_data)
2131-{
2132- return 0;
2133-}
2134-
2135-/*
2136- * Register for an event.
2137- *
2138- * Only one caller at a time here, because we use
2139- * a FIFO and lock it against multiple accesses.
2140- */
2141-static int _register_for_event(struct message_data *message_data)
2142-{
2143- int ret = 0;
2144- struct thread_status *thread, *thread_new = NULL;
2145- struct dso_data *dso_data;
2146-
2147- if (!(dso_data = _lookup_dso(message_data)) &&
2148- !(dso_data = _load_dso(message_data))) {
2149- stack;
2150-#ifdef ELIBACC
2151- ret = -ELIBACC;
2152-#else
2153- ret = -ENODEV;
2154-#endif
2155- goto out;
2156- }
2157-
2158- /* Preallocate thread status struct to avoid deadlock. */
2159- if (!(thread_new = _alloc_thread_status(message_data, dso_data))) {
2160- stack;
2161- ret = -ENOMEM;
2162- goto out;
2163- }
2164-
2165- if (!_fill_device_data(thread_new)) {
2166- stack;
2167- ret = -ENODEV;
2168- goto out;
2169- }
2170-
2171- _lock_mutex();
2172-
2173- /* If creation of timeout thread fails (as it may), we fail
2174- here completely. The client is responsible for either
2175- retrying later or trying to register without timeout
2176- events. However, if timeout thread cannot be started, it
2177- usually means we are so starved on resources that we are
2178- almost as good as dead already... */
2179- if (thread_new->events & DM_EVENT_TIMEOUT) {
2180- ret = -_register_for_timeout(thread_new);
2181- if (ret)
2182- goto outth;
2183- }
2184-
2185- if (!(thread = _lookup_thread_status(message_data))) {
2186- _unlock_mutex();
2187-
2188- if (!(ret = _do_register_device(thread_new)))
2189- goto out;
2190-
2191- thread = thread_new;
2192- thread_new = NULL;
2193-
2194- /* Try to create the monitoring thread for this device. */
2195- _lock_mutex();
2196- if ((ret = -_create_thread(thread))) {
2197- _unlock_mutex();
2198- _do_unregister_device(thread);
2199- _free_thread_status(thread);
2200- goto out;
2201- } else
2202- LINK_THREAD(thread);
2203- }
2204-
2205- /* Or event # into events bitfield. */
2206- thread->events |= message_data->events.field;
2207-
2208- outth:
2209- _unlock_mutex();
2210-
2211- out:
2212- /*
2213- * Deallocate thread status after releasing
2214- * the lock in case we haven't used it.
2215- */
2216- if (thread_new)
2217- _free_thread_status(thread_new);
2218-
2219- return ret;
2220-}
2221-
2222-/*
2223- * Unregister for an event.
2224- *
2225- * Only one caller at a time here as with register_for_event().
2226- */
2227-static int _unregister_for_event(struct message_data *message_data)
2228-{
2229- int ret = 0;
2230- struct thread_status *thread;
2231-
2232- /*
2233- * Clear event in bitfield and deactivate
2234- * monitoring thread in case bitfield is 0.
2235- */
2236- _lock_mutex();
2237-
2238- if (!(thread = _lookup_thread_status(message_data))) {
2239- _unlock_mutex();
2240- ret = -ENODEV;
2241- goto out;
2242- }
2243-
2244- if (thread->status == DM_THREAD_DONE) {
2245- /* the thread has terminated while we were not
2246- watching */
2247- _unlock_mutex();
2248- return 0;
2249- }
2250-
2251- thread->events &= ~message_data->events.field;
2252-
2253- if (!(thread->events & DM_EVENT_TIMEOUT))
2254- _unregister_for_timeout(thread);
2255- /*
2256- * In case there's no events to monitor on this device ->
2257- * unlink and terminate its monitoring thread.
2258- */
2259- if (!thread->events) {
2260- pthread_mutex_lock(&_timeout_mutex);
2261- UNLINK_THREAD(thread);
2262- LINK(thread, &_thread_registry_unused);
2263- pthread_mutex_unlock(&_timeout_mutex);
2264- }
2265- _unlock_mutex();
2266-
2267- out:
2268- return ret;
2269-}
2270-
2271-/*
2272- * Get registered device.
2273- *
2274- * Only one caller at a time here as with register_for_event().
2275- */
2276-static int _registered_device(struct message_data *message_data,
2277- struct thread_status *thread)
2278-{
2279- struct dm_event_daemon_message *msg = message_data->msg;
2280-
2281- const char *fmt = "%s %s %s %u";
2282- const char *id = message_data->id;
2283- const char *dso = thread->dso_data->dso_name;
2284- const char *dev = thread->device.uuid;
2285- int r;
2286- unsigned events = ((thread->status == DM_THREAD_RUNNING)
2287- && (thread->events)) ? thread->events : thread->
2288- events | DM_EVENT_REGISTRATION_PENDING;
2289-
2290- dm_free(msg->data);
2291-
2292- if ((r = dm_asprintf(&(msg->data), fmt, id, dso, dev, events)) < 0) {
2293- msg->size = 0;
2294- return -ENOMEM;
2295- }
2296-
2297- msg->size = (uint32_t) r;
2298-
2299- return 0;
2300-}
2301-
2302-static int _want_registered_device(char *dso_name, char *device_uuid,
2303- struct thread_status *thread)
2304-{
2305- /* If DSO names and device paths are equal. */
2306- if (dso_name && device_uuid)
2307- return !strcmp(dso_name, thread->dso_data->dso_name) &&
2308- !strcmp(device_uuid, thread->device.uuid) &&
2309- (thread->status == DM_THREAD_RUNNING ||
2310- (thread->events & DM_EVENT_REGISTRATION_PENDING));
2311-
2312- /* If DSO names are equal. */
2313- if (dso_name)
2314- return !strcmp(dso_name, thread->dso_data->dso_name) &&
2315- (thread->status == DM_THREAD_RUNNING ||
2316- (thread->events & DM_EVENT_REGISTRATION_PENDING));
2317-
2318- /* If device paths are equal. */
2319- if (device_uuid)
2320- return !strcmp(device_uuid, thread->device.uuid) &&
2321- (thread->status == DM_THREAD_RUNNING ||
2322- (thread->events & DM_EVENT_REGISTRATION_PENDING));
2323-
2324- return 1;
2325-}
2326-
2327-static int _get_registered_dev(struct message_data *message_data, int next)
2328-{
2329- struct thread_status *thread, *hit = NULL;
2330- int ret = -ENOENT;
2331-
2332- _lock_mutex();
2333-
2334- /* Iterate list of threads checking if we want a particular one. */
2335- dm_list_iterate_items(thread, &_thread_registry)
2336- if (_want_registered_device(message_data->dso_name,
2337- message_data->device_uuid,
2338- thread)) {
2339- hit = thread;
2340- break;
2341- }
2342-
2343- /*
2344- * If we got a registered device and want the next one ->
2345- * fetch next conforming element off the list.
2346- */
2347- if (hit && !next)
2348- goto reg;
2349-
2350- if (!hit)
2351- goto out;
2352-
2353- while (1) {
2354- if (dm_list_end(&_thread_registry, &thread->list))
2355- goto out;
2356-
2357- thread = dm_list_item(thread->list.n, struct thread_status);
2358- if (_want_registered_device(message_data->dso_name, NULL, thread)) {
2359- hit = thread;
2360- break;
2361- }
2362- }
2363-
2364- reg:
2365- ret = _registered_device(message_data, hit);
2366-
2367- out:
2368- _unlock_mutex();
2369-
2370- return ret;
2371-}
2372-
2373-static int _get_registered_device(struct message_data *message_data)
2374-{
2375- return _get_registered_dev(message_data, 0);
2376-}
2377-
2378-static int _get_next_registered_device(struct message_data *message_data)
2379-{
2380- return _get_registered_dev(message_data, 1);
2381-}
2382-
2383-static int _set_timeout(struct message_data *message_data)
2384-{
2385- struct thread_status *thread;
2386-
2387- _lock_mutex();
2388- if ((thread = _lookup_thread_status(message_data)))
2389- thread->timeout = message_data->timeout.secs;
2390- _unlock_mutex();
2391-
2392- return thread ? 0 : -ENODEV;
2393-}
2394-
2395-static int _get_timeout(struct message_data *message_data)
2396-{
2397- struct thread_status *thread;
2398- struct dm_event_daemon_message *msg = message_data->msg;
2399-
2400- dm_free(msg->data);
2401-
2402- _lock_mutex();
2403- if ((thread = _lookup_thread_status(message_data))) {
2404- msg->size =
2405- dm_asprintf(&(msg->data), "%s %" PRIu32, message_data->id,
2406- thread->timeout);
2407- } else {
2408- msg->data = NULL;
2409- msg->size = 0;
2410- }
2411- _unlock_mutex();
2412-
2413- return thread ? 0 : -ENODEV;
2414-}
2415-
2416-/* Initialize a fifos structure with path names. */
2417-static void _init_fifos(struct dm_event_fifos *fifos)
2418-{
2419- memset(fifos, 0, sizeof(*fifos));
2420-
2421- fifos->client_path = DM_EVENT_FIFO_CLIENT;
2422- fifos->server_path = DM_EVENT_FIFO_SERVER;
2423-}
2424-
2425-/* Open fifos used for client communication. */
2426-static int _open_fifos(struct dm_event_fifos *fifos)
2427-{
2428- struct stat st;
2429-
2430- /* Create client fifo. */
2431- (void) dm_prepare_selinux_context(fifos->client_path, S_IFIFO);
2432- if ((mkfifo(fifos->client_path, 0600) == -1) && errno != EEXIST) {
2433- syslog(LOG_ERR, "%s: Failed to create client fifo %s: %m.\n",
2434- __func__, fifos->client_path);
2435- (void) dm_prepare_selinux_context(NULL, 0);
2436- return 0;
2437- }
2438-
2439- /* Create server fifo. */
2440- (void) dm_prepare_selinux_context(fifos->server_path, S_IFIFO);
2441- if ((mkfifo(fifos->server_path, 0600) == -1) && errno != EEXIST) {
2442- syslog(LOG_ERR, "%s: Failed to create server fifo %s: %m.\n",
2443- __func__, fifos->server_path);
2444- (void) dm_prepare_selinux_context(NULL, 0);
2445- return 0;
2446- }
2447-
2448- (void) dm_prepare_selinux_context(NULL, 0);
2449-
2450- /* Warn about wrong permissions if applicable */
2451- if ((!stat(fifos->client_path, &st)) && (st.st_mode & 0777) != 0600)
2452- syslog(LOG_WARNING, "Fixing wrong permissions on %s: %m.\n",
2453- fifos->client_path);
2454-
2455- if ((!stat(fifos->server_path, &st)) && (st.st_mode & 0777) != 0600)
2456- syslog(LOG_WARNING, "Fixing wrong permissions on %s: %m.\n",
2457- fifos->server_path);
2458-
2459- /* If they were already there, make sure permissions are ok. */
2460- if (chmod(fifos->client_path, 0600)) {
2461- syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n",
2462- fifos->client_path);
2463- return 0;
2464- }
2465-
2466- if (chmod(fifos->server_path, 0600)) {
2467- syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n",
2468- fifos->server_path);
2469- return 0;
2470- }
2471-
2472- /* Need to open read+write or we will block or fail */
2473- if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
2474- syslog(LOG_ERR, "Failed to open fifo server %s: %m.\n",
2475- fifos->server_path);
2476- return 0;
2477- }
2478-
2479- /* Need to open read+write for select() to work. */
2480- if ((fifos->client = open(fifos->client_path, O_RDWR)) < 0) {
2481- syslog(LOG_ERR, "Failed to open fifo client %s: %m", fifos->client_path);
2482- if (close(fifos->server))
2483- syslog(LOG_ERR, "Failed to close fifo server %s: %m", fifos->server_path);
2484- return 0;
2485- }
2486-
2487- return 1;
2488-}
2489-
2490-/*
2491- * Read message from client making sure that data is available
2492- * and a complete message is read. Must not block indefinitely.
2493- */
2494-static int _client_read(struct dm_event_fifos *fifos,
2495- struct dm_event_daemon_message *msg)
2496-{
2497- struct timeval t;
2498- unsigned bytes = 0;
2499- int ret = 0;
2500- fd_set fds;
2501- size_t size = 2 * sizeof(uint32_t); /* status + size */
2502- uint32_t *header = alloca(size);
2503- char *buf = (char *)header;
2504-
2505- msg->data = NULL;
2506-
2507- errno = 0;
2508- while (bytes < size && errno != EOF) {
2509- /* Watch client read FIFO for input. */
2510- FD_ZERO(&fds);
2511- FD_SET(fifos->client, &fds);
2512- t.tv_sec = 1;
2513- t.tv_usec = 0;
2514- ret = select(fifos->client + 1, &fds, NULL, NULL, &t);
2515-
2516- if (!ret && !bytes) /* nothing to read */
2517- return 0;
2518-
2519- if (!ret) /* trying to finish read */
2520- continue;
2521-
2522- if (ret < 0) /* error */
2523- return 0;
2524-
2525- ret = read(fifos->client, buf + bytes, size - bytes);
2526- bytes += ret > 0 ? ret : 0;
2527- if (header && (bytes == 2 * sizeof(uint32_t))) {
2528- msg->cmd = ntohl(header[0]);
2529- msg->size = ntohl(header[1]);
2530- buf = msg->data = dm_malloc(msg->size);
2531- size = msg->size;
2532- bytes = 0;
2533- header = 0;
2534- }
2535- }
2536-
2537- if (bytes != size) {
2538- dm_free(msg->data);
2539- msg->data = NULL;
2540- msg->size = 0;
2541- }
2542-
2543- return bytes == size;
2544-}
2545-
2546-/*
2547- * Write a message to the client making sure that it is ready to write.
2548- */
2549-static int _client_write(struct dm_event_fifos *fifos,
2550- struct dm_event_daemon_message *msg)
2551-{
2552- unsigned bytes = 0;
2553- int ret = 0;
2554- fd_set fds;
2555-
2556- size_t size = 2 * sizeof(uint32_t) + msg->size;
2557- uint32_t *header = alloca(size);
2558- char *buf = (char *)header;
2559-
2560- header[0] = htonl(msg->cmd);
2561- header[1] = htonl(msg->size);
2562- if (msg->data)
2563- memcpy(buf + 2 * sizeof(uint32_t), msg->data, msg->size);
2564-
2565- errno = 0;
2566- while (bytes < size && errno != EIO) {
2567- do {
2568- /* Watch client write FIFO to be ready for output. */
2569- FD_ZERO(&fds);
2570- FD_SET(fifos->server, &fds);
2571- } while (select(fifos->server + 1, NULL, &fds, NULL, NULL) !=
2572- 1);
2573-
2574- ret = write(fifos->server, buf + bytes, size - bytes);
2575- bytes += ret > 0 ? ret : 0;
2576- }
2577-
2578- return bytes == size;
2579-}
2580-
2581-/*
2582- * Handle a client request.
2583- *
2584- * We put the request handling functions into
2585- * a list because of the growing number.
2586- */
2587-static int _handle_request(struct dm_event_daemon_message *msg,
2588- struct message_data *message_data)
2589-{
2590- static struct request {
2591- unsigned int cmd;
2592- int (*f)(struct message_data *);
2593- } requests[] = {
2594- { DM_EVENT_CMD_REGISTER_FOR_EVENT, _register_for_event},
2595- { DM_EVENT_CMD_UNREGISTER_FOR_EVENT, _unregister_for_event},
2596- { DM_EVENT_CMD_GET_REGISTERED_DEVICE, _get_registered_device},
2597- { DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE,
2598- _get_next_registered_device},
2599- { DM_EVENT_CMD_SET_TIMEOUT, _set_timeout},
2600- { DM_EVENT_CMD_GET_TIMEOUT, _get_timeout},
2601- { DM_EVENT_CMD_ACTIVE, _active},
2602- { DM_EVENT_CMD_GET_STATUS, _get_status},
2603- }, *req;
2604-
2605- for (req = requests; req < requests + sizeof(requests) / sizeof(struct request); req++)
2606- if (req->cmd == msg->cmd)
2607- return req->f(message_data);
2608-
2609- return -EINVAL;
2610-}
2611-
2612-/* Process a request passed from the communication thread. */
2613-static int _do_process_request(struct dm_event_daemon_message *msg)
2614-{
2615- int ret;
2616- char *answer;
2617- struct message_data message_data = { .msg = msg };
2618-
2619- /* Parse the message. */
2620- if (msg->cmd == DM_EVENT_CMD_HELLO || msg->cmd == DM_EVENT_CMD_DIE) {
2621- ret = 0;
2622- answer = msg->data;
2623- if (answer) {
2624- msg->size = dm_asprintf(&(msg->data), "%s %s %d", answer,
2625- msg->cmd == DM_EVENT_CMD_DIE ? "DYING" : "HELLO",
2626- DM_EVENT_PROTOCOL_VERSION);
2627- dm_free(answer);
2628- } else {
2629- msg->size = 0;
2630- msg->data = NULL;
2631- }
2632- } else if (msg->cmd != DM_EVENT_CMD_ACTIVE && !_parse_message(&message_data)) {
2633- stack;
2634- ret = -EINVAL;
2635- } else
2636- ret = _handle_request(msg, &message_data);
2637-
2638- msg->cmd = ret;
2639- if (!msg->data)
2640- msg->size = dm_asprintf(&(msg->data), "%s %s", message_data.id, strerror(-ret));
2641-
2642- _free_message(&message_data);
2643-
2644- return ret;
2645-}
2646-
2647-/* Only one caller at a time. */
2648-static void _process_request(struct dm_event_fifos *fifos)
2649-{
2650- int die = 0;
2651- struct dm_event_daemon_message msg = { 0 };
2652-
2653- /*
2654- * Read the request from the client (client_read, client_write
2655- * give true on success and false on failure).
2656- */
2657- if (!_client_read(fifos, &msg))
2658- return;
2659-
2660- if (msg.cmd == DM_EVENT_CMD_DIE)
2661- die = 1;
2662-
2663- /* _do_process_request fills in msg (if memory allows for
2664- data, otherwise just cmd and size = 0) */
2665- _do_process_request(&msg);
2666-
2667- if (!_client_write(fifos, &msg))
2668- stack;
2669-
2670- dm_free(msg.data);
2671-
2672- if (die) raise(9);
2673-}
2674-
2675-static void _process_initial_registrations(void)
2676-{
2677- int i = 0;
2678- char *reg;
2679- struct dm_event_daemon_message msg = { 0, 0, NULL };
2680-
2681- while ((reg = _initial_registrations[i])) {
2682- msg.cmd = DM_EVENT_CMD_REGISTER_FOR_EVENT;
2683- if ((msg.size = strlen(reg))) {
2684- msg.data = reg;
2685- _do_process_request(&msg);
2686- }
2687- ++ i;
2688- }
2689-}
2690-
2691-static void _cleanup_unused_threads(void)
2692-{
2693- int ret;
2694- struct dm_list *l;
2695- struct thread_status *thread;
2696- int join_ret = 0;
2697-
2698- _lock_mutex();
2699- while ((l = dm_list_first(&_thread_registry_unused))) {
2700- thread = dm_list_item(l, struct thread_status);
2701- if (thread->processing)
2702- break; /* cleanup on the next round */
2703-
2704- if (thread->status == DM_THREAD_RUNNING) {
2705- thread->status = DM_THREAD_SHUTDOWN;
2706- break;
2707- }
2708-
2709- if (thread->status == DM_THREAD_SHUTDOWN) {
2710- if (!thread->events) {
2711- /* turn codes negative -- should we be returning this? */
2712- ret = _terminate_thread(thread);
2713-
2714- if (ret == ESRCH) {
2715- thread->status = DM_THREAD_DONE;
2716- } else if (ret) {
2717- syslog(LOG_ERR,
2718- "Unable to terminate thread: %s\n",
2719- strerror(-ret));
2720- stack;
2721- }
2722- break;
2723- }
2724-
2725- dm_list_del(l);
2726- syslog(LOG_ERR,
2727- "thread can't be on unused list unless !thread->events");
2728- thread->status = DM_THREAD_RUNNING;
2729- LINK_THREAD(thread);
2730-
2731- continue;
2732- }
2733-
2734- if (thread->status == DM_THREAD_DONE) {
2735- dm_list_del(l);
2736- join_ret = pthread_join(thread->thread, NULL);
2737- _free_thread_status(thread);
2738- }
2739- }
2740-
2741- _unlock_mutex();
2742-
2743- if (join_ret)
2744- syslog(LOG_ERR, "Failed pthread_join: %s\n", strerror(join_ret));
2745-}
2746-
2747-static void _sig_alarm(int signum __attribute__((unused)))
2748-{
2749- pthread_testcancel();
2750-}
2751-
2752-/* Init thread signal handling. */
2753-static void _init_thread_signals(void)
2754-{
2755- sigset_t my_sigset;
2756- struct sigaction act = { .sa_handler = _sig_alarm };
2757-
2758- sigaction(SIGALRM, &act, NULL);
2759- sigfillset(&my_sigset);
2760-
2761- /* These are used for exiting */
2762- sigdelset(&my_sigset, SIGTERM);
2763- sigdelset(&my_sigset, SIGINT);
2764- sigdelset(&my_sigset, SIGHUP);
2765- sigdelset(&my_sigset, SIGQUIT);
2766-
2767- pthread_sigmask(SIG_BLOCK, &my_sigset, NULL);
2768-}
2769-
2770-/*
2771- * exit_handler
2772- * @sig
2773- *
2774- * Set the global variable which the process should
2775- * be watching to determine when to exit.
2776- */
2777-static void _exit_handler(int sig __attribute__((unused)))
2778-{
2779- /*
2780- * We exit when '_exit_now' is set.
2781- * That is, when a signal has been received.
2782- *
2783- * We can not simply set '_exit_now' unless all
2784- * threads are done processing.
2785- */
2786- if (!_thread_registries_empty) {
2787- syslog(LOG_ERR, "There are still devices being monitored.");
2788- syslog(LOG_ERR, "Refusing to exit.");
2789- } else
2790- _exit_now = 1;
2791-
2792-}
2793-
2794-#ifdef linux
2795-static int _set_oom_adj(const char *oom_adj_path, int val)
2796-{
2797- FILE *fp;
2798-
2799- if (!(fp = fopen(oom_adj_path, "w"))) {
2800- perror("oom_adj: fopen failed");
2801- return 0;
2802- }
2803-
2804- fprintf(fp, "%i", val);
2805-
2806- if (dm_fclose(fp))
2807- perror("oom_adj: fclose failed");
2808-
2809- return 1;
2810-}
2811-
2812-/*
2813- * Protection against OOM killer if kernel supports it
2814- */
2815-static int _protect_against_oom_killer(void)
2816-{
2817- struct stat st;
2818-
2819- if (stat(OOM_ADJ_FILE, &st) == -1) {
2820- if (errno != ENOENT)
2821- perror(OOM_ADJ_FILE ": stat failed");
2822-
2823- /* Try old oom_adj interface as a fallback */
2824- if (stat(OOM_ADJ_FILE_OLD, &st) == -1) {
2825- if (errno == ENOENT)
2826- perror(OOM_ADJ_FILE_OLD " not found");
2827- else
2828- perror(OOM_ADJ_FILE_OLD ": stat failed");
2829- return 1;
2830- }
2831-
2832- return _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_DISABLE) ||
2833- _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_ADJUST_MIN);
2834- }
2835-
2836- return _set_oom_adj(OOM_ADJ_FILE, OOM_SCORE_ADJ_MIN);
2837-}
2838-
2839-static int _handle_preloaded_fifo(int fd, const char *path)
2840-{
2841- struct stat st_fd, st_path;
2842- int flags;
2843-
2844- if ((flags = fcntl(fd, F_GETFD)) < 0)
2845- return 0;
2846-
2847- if (flags & FD_CLOEXEC)
2848- return 0;
2849-
2850- if (fstat(fd, &st_fd) < 0 || !S_ISFIFO(st_fd.st_mode))
2851- return 0;
2852-
2853- if (stat(path, &st_path) < 0 ||
2854- st_path.st_dev != st_fd.st_dev ||
2855- st_path.st_ino != st_fd.st_ino)
2856- return 0;
2857-
2858- if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
2859- return 0;
2860-
2861- return 1;
2862-}
2863-
2864-static int _systemd_handover(struct dm_event_fifos *fifos)
2865-{
2866- const char *e;
2867- char *p;
2868- unsigned long env_pid, env_listen_fds;
2869- int r = 0;
2870-
2871- memset(fifos, 0, sizeof(*fifos));
2872-
2873- /* SD_ACTIVATION must be set! */
2874- if (!(e = getenv(SD_ACTIVATION_ENV_VAR_NAME)) || strcmp(e, "1"))
2875- goto out;
2876-
2877- /* LISTEN_PID must be equal to our PID! */
2878- if (!(e = getenv(SD_LISTEN_PID_ENV_VAR_NAME)))
2879- goto out;
2880-
2881- errno = 0;
2882- env_pid = strtoul(e, &p, 10);
2883- if (errno || !p || *p || env_pid <= 0 ||
2884- getpid() != (pid_t) env_pid)
2885- goto out;
2886-
2887- /* LISTEN_FDS must be 2 and the fds must be FIFOSs! */
2888- if (!(e = getenv(SD_LISTEN_FDS_ENV_VAR_NAME)))
2889- goto out;
2890-
2891- errno = 0;
2892- env_listen_fds = strtoul(e, &p, 10);
2893- if (errno || !p || *p || env_listen_fds != 2)
2894- goto out;
2895-
2896- /* Check and handle the FIFOs passed in */
2897- r = (_handle_preloaded_fifo(SD_FD_FIFO_SERVER, DM_EVENT_FIFO_SERVER) &&
2898- _handle_preloaded_fifo(SD_FD_FIFO_CLIENT, DM_EVENT_FIFO_CLIENT));
2899-
2900- if (r) {
2901- fifos->server = SD_FD_FIFO_SERVER;
2902- fifos->server_path = DM_EVENT_FIFO_SERVER;
2903- fifos->client = SD_FD_FIFO_CLIENT;
2904- fifos->client_path = DM_EVENT_FIFO_CLIENT;
2905- }
2906-
2907-out:
2908- unsetenv(SD_ACTIVATION_ENV_VAR_NAME);
2909- unsetenv(SD_LISTEN_PID_ENV_VAR_NAME);
2910- unsetenv(SD_LISTEN_FDS_ENV_VAR_NAME);
2911- return r;
2912-}
2913-#endif
2914-
2915-static void _remove_files_on_exit(void)
2916-{
2917- if (unlink(DMEVENTD_PIDFILE))
2918- perror(DMEVENTD_PIDFILE ": unlink failed");
2919-
2920- if (!_systemd_activation) {
2921- if (unlink(DM_EVENT_FIFO_CLIENT))
2922- perror(DM_EVENT_FIFO_CLIENT " : unlink failed");
2923-
2924- if (unlink(DM_EVENT_FIFO_SERVER))
2925- perror(DM_EVENT_FIFO_SERVER " : unlink failed");
2926- }
2927-}
2928-
2929-static void _daemonize(void)
2930-{
2931- int child_status;
2932- int fd;
2933- pid_t pid;
2934- struct rlimit rlim;
2935- struct timeval tval;
2936- sigset_t my_sigset;
2937-
2938- sigemptyset(&my_sigset);
2939- if (sigprocmask(SIG_SETMASK, &my_sigset, NULL) < 0) {
2940- fprintf(stderr, "Unable to restore signals.\n");
2941- exit(EXIT_FAILURE);
2942- }
2943- signal(SIGTERM, &_exit_handler);
2944-
2945- switch (pid = fork()) {
2946- case -1:
2947- perror("fork failed:");
2948- exit(EXIT_FAILURE);
2949-
2950- case 0: /* Child */
2951- break;
2952-
2953- default:
2954- /* Wait for response from child */
2955- while (!waitpid(pid, &child_status, WNOHANG) && !_exit_now) {
2956- tval.tv_sec = 0;
2957- tval.tv_usec = 250000; /* .25 sec */
2958- select(0, NULL, NULL, NULL, &tval);
2959- }
2960-
2961- if (_exit_now) /* Child has signaled it is ok - we can exit now */
2962- exit(EXIT_SUCCESS);
2963-
2964- /* Problem with child. Determine what it is by exit code */
2965- switch (WEXITSTATUS(child_status)) {
2966- case EXIT_DESC_CLOSE_FAILURE:
2967- case EXIT_DESC_OPEN_FAILURE:
2968- case EXIT_FIFO_FAILURE:
2969- case EXIT_CHDIR_FAILURE:
2970- default:
2971- fprintf(stderr, "Child exited with code %d\n", WEXITSTATUS(child_status));
2972- break;
2973- }
2974-
2975- exit(WEXITSTATUS(child_status));
2976- }
2977-
2978- if (chdir("/"))
2979- exit(EXIT_CHDIR_FAILURE);
2980-
2981- if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
2982- fd = 256; /* just have to guess */
2983- else
2984- fd = rlim.rlim_cur;
2985-
2986- for (--fd; fd >= 0; fd--) {
2987-#ifdef linux
2988- /* Do not close fds preloaded by systemd! */
2989- if (_systemd_activation &&
2990- (fd == SD_FD_FIFO_SERVER || fd == SD_FD_FIFO_CLIENT))
2991- continue;
2992-#endif
2993- (void) close(fd);
2994- }
2995-
2996- if ((open("/dev/null", O_RDONLY) < 0) ||
2997- (open("/dev/null", O_WRONLY) < 0) ||
2998- (open("/dev/null", O_WRONLY) < 0))
2999- exit(EXIT_DESC_OPEN_FAILURE);
3000-
3001- setsid();
3002-}
3003-
3004-static void restart(void)
3005-{
3006- struct dm_event_fifos fifos;
3007- struct dm_event_daemon_message msg = { 0, 0, NULL };
3008- int i, count = 0;
3009- char *message;
3010- int length;
3011- int version;
3012-
3013- /* Get the list of registrations from the running daemon. */
3014-
3015- if (!init_fifos(&fifos)) {
3016- fprintf(stderr, "WARNING: Could not initiate communication with existing dmeventd.\n");
3017- exit(EXIT_FAILURE);
3018- }
3019-
3020- if (!dm_event_get_version(&fifos, &version)) {
3021- fprintf(stderr, "WARNING: Could not communicate with existing dmeventd.\n");
3022- fini_fifos(&fifos);
3023- exit(EXIT_FAILURE);
3024- }
3025-
3026- if (version < 1) {
3027- fprintf(stderr, "WARNING: The running dmeventd instance is too old.\n"
3028- "Protocol version %d (required: 1). Action cancelled.\n",
3029- version);
3030- exit(EXIT_FAILURE);
3031- }
3032-
3033- if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_GET_STATUS, "-", "-", 0, 0)) {
3034- exit(EXIT_FAILURE);
3035- }
3036-
3037- message = msg.data;
3038- message = strchr(message, ' ');
3039- ++ message;
3040- length = strlen(msg.data);
3041- for (i = 0; i < length; ++i) {
3042- if (msg.data[i] == ';') {
3043- msg.data[i] = 0;
3044- ++count;
3045- }
3046- }
3047-
3048- if (!(_initial_registrations = dm_malloc(sizeof(char*) * (count + 1)))) {
3049- fprintf(stderr, "Memory allocation registration failed.\n");
3050- exit(EXIT_FAILURE);
3051- }
3052-
3053- for (i = 0; i < count; ++i) {
3054- if (!(_initial_registrations[i] = dm_strdup(message))) {
3055- fprintf(stderr, "Memory allocation for message failed.\n");
3056- exit(EXIT_FAILURE);
3057- }
3058- message += strlen(message) + 1;
3059- }
3060- _initial_registrations[count] = 0;
3061-
3062- if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_DIE, "-", "-", 0, 0)) {
3063- fprintf(stderr, "Old dmeventd refused to die.\n");
3064- exit(EXIT_FAILURE);
3065- }
3066-
3067- /*
3068- * Wait for daemon to die, detected by sending further DIE messages
3069- * until one fails.
3070- */
3071- for (i = 0; i < 10; ++i) {
3072- if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_DIE, "-", "-", 0, 0))
3073- break; /* yep, it's dead probably */
3074- usleep(10);
3075- }
3076-
3077- fini_fifos(&fifos);
3078-}
3079-
3080-static void usage(char *prog, FILE *file)
3081-{
3082- fprintf(file, "Usage:\n"
3083- "%s [-d [-d [-d]]] [-f] [-h] [-R] [-V] [-?]\n\n"
3084- " -d Log debug messages to syslog (-d, -dd, -ddd)\n"
3085- " -f Don't fork, run in the foreground\n"
3086- " -h -? Show this help information\n"
3087- " -R Restart dmeventd\n"
3088- " -V Show version of dmeventd\n\n", prog);
3089-}
3090-
3091-int main(int argc, char *argv[])
3092-{
3093- signed char opt;
3094- struct dm_event_fifos fifos;
3095- //struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
3096-
3097- opterr = 0;
3098- optind = 0;
3099-
3100- while ((opt = getopt(argc, argv, "?fhVdR")) != EOF) {
3101- switch (opt) {
3102- case 'h':
3103- usage(argv[0], stdout);
3104- exit(0);
3105- case '?':
3106- usage(argv[0], stderr);
3107- exit(0);
3108- case 'R':
3109- _restart++;
3110- break;
3111- case 'f':
3112- _foreground++;
3113- break;
3114- case 'd':
3115- dmeventd_debug++;
3116- break;
3117- case 'V':
3118- printf("dmeventd version: %s\n", DM_LIB_VERSION);
3119- exit(1);
3120- }
3121- }
3122-
3123- /*
3124- * Switch to C locale to avoid reading large locale-archive file
3125- * used by some glibc (on some distributions it takes over 100MB).
3126- * Daemon currently needs to use mlockall().
3127- */
3128- if (setenv("LANG", "C", 1))
3129- perror("Cannot set LANG to C");
3130-
3131- if (_restart)
3132- restart();
3133-
3134-#ifdef linux
3135- _systemd_activation = _systemd_handover(&fifos);
3136-#endif
3137-
3138- if (!_foreground)
3139- _daemonize();
3140-
3141- openlog("dmeventd", LOG_PID, LOG_DAEMON);
3142-
3143- (void) dm_prepare_selinux_context(DMEVENTD_PIDFILE, S_IFREG);
3144- if (dm_create_lockfile(DMEVENTD_PIDFILE) == 0)
3145- exit(EXIT_FAILURE);
3146-
3147- atexit(_remove_files_on_exit);
3148- (void) dm_prepare_selinux_context(NULL, 0);
3149-
3150- /* Set the rest of the signals to cause '_exit_now' to be set */
3151- signal(SIGTERM, &_exit_handler);
3152- signal(SIGINT, &_exit_handler);
3153- signal(SIGHUP, &_exit_handler);
3154- signal(SIGQUIT, &_exit_handler);
3155-
3156-#ifdef linux
3157- /* Systemd has adjusted oom killer for us already */
3158- if (!_systemd_activation && !_protect_against_oom_killer())
3159- syslog(LOG_ERR, "Failed to protect against OOM killer");
3160-#endif
3161-
3162- _init_thread_signals();
3163-
3164- //multilog_clear_logging();
3165- //multilog_add_type(std_syslog, &logdata);
3166- //multilog_init_verbose(std_syslog, _LOG_DEBUG);
3167- //multilog_async(1);
3168-
3169- if (!_systemd_activation)
3170- _init_fifos(&fifos);
3171-
3172- pthread_mutex_init(&_global_mutex, NULL);
3173-
3174- if (!_systemd_activation && !_open_fifos(&fifos))
3175- exit(EXIT_FIFO_FAILURE);
3176-
3177- /* Signal parent, letting them know we are ready to go. */
3178- if (!_foreground)
3179- kill(getppid(), SIGTERM);
3180- syslog(LOG_NOTICE, "dmeventd ready for processing.");
3181-
3182- if (_initial_registrations)
3183- _process_initial_registrations();
3184-
3185- while (!_exit_now) {
3186- _process_request(&fifos);
3187- _cleanup_unused_threads();
3188- _lock_mutex();
3189- if (!dm_list_empty(&_thread_registry)
3190- || !dm_list_empty(&_thread_registry_unused))
3191- _thread_registries_empty = 0;
3192- else
3193- _thread_registries_empty = 1;
3194- _unlock_mutex();
3195- }
3196-
3197- _exit_dm_lib();
3198-
3199- pthread_mutex_destroy(&_global_mutex);
3200-
3201- syslog(LOG_NOTICE, "dmeventd shutting down.");
3202- closelog();
3203-
3204- exit(EXIT_SUCCESS);
3205-}
3206
3207=== removed directory '.pc/dirs.patch/doc'
3208=== removed file '.pc/dirs.patch/doc/example.conf.in'
3209--- .pc/dirs.patch/doc/example.conf.in 2013-05-30 11:02:10 +0000
3210+++ .pc/dirs.patch/doc/example.conf.in 1970-01-01 00:00:00 +0000
3211@@ -1,816 +0,0 @@
3212-# This is an example configuration file for the LVM2 system.
3213-# It contains the default settings that would be used if there was no
3214-# @DEFAULT_SYS_DIR@/lvm.conf file.
3215-#
3216-# Refer to 'man lvm.conf' for further information including the file layout.
3217-#
3218-# To put this file in a different directory and override @DEFAULT_SYS_DIR@ set
3219-# the environment variable LVM_SYSTEM_DIR before running the tools.
3220-#
3221-# N.B. Take care that each setting only appears once if uncommenting
3222-# example settings in this file.
3223-
3224-
3225-# This section allows you to configure which block devices should
3226-# be used by the LVM system.
3227-devices {
3228-
3229- # Where do you want your volume groups to appear ?
3230- dir = "/dev"
3231-
3232- # An array of directories that contain the device nodes you wish
3233- # to use with LVM2.
3234- scan = [ "/dev" ]
3235-
3236- # If set, the cache of block device nodes with all associated symlinks
3237- # will be constructed out of the existing udev database content.
3238- # This avoids using and opening any inapplicable non-block devices or
3239- # subdirectories found in the device directory. This setting is applied
3240- # to udev-managed device directory only, other directories will be scanned
3241- # fully. LVM2 needs to be compiled with udev support for this setting to
3242- # take effect. N.B. Any device node or symlink not managed by udev in
3243- # udev directory will be ignored with this setting on.
3244- obtain_device_list_from_udev = 1
3245-
3246- # If several entries in the scanned directories correspond to the
3247- # same block device and the tools need to display a name for device,
3248- # all the pathnames are matched against each item in the following
3249- # list of regular expressions in turn and the first match is used.
3250- preferred_names = [ ]
3251-
3252- # Try to avoid using undescriptive /dev/dm-N names, if present.
3253- # preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
3254-
3255- # A filter that tells LVM2 to only use a restricted set of devices.
3256- # The filter consists of an array of regular expressions. These
3257- # expressions can be delimited by a character of your choice, and
3258- # prefixed with either an 'a' (for accept) or 'r' (for reject).
3259- # The first expression found to match a device name determines if
3260- # the device will be accepted or rejected (ignored). Devices that
3261- # don't match any patterns are accepted.
3262-
3263- # Be careful if there there are symbolic links or multiple filesystem
3264- # entries for the same device as each name is checked separately against
3265- # the list of patterns. The effect is that if the first pattern in the
3266- # list to match a name is an 'a' pattern for any of the names, the device
3267- # is accepted; otherwise if the first pattern in the list to match a name
3268- # is an 'r' pattern for any of the names it is rejected; otherwise it is
3269- # accepted.
3270-
3271- # Don't have more than one filter line active at once: only one gets used.
3272-
3273- # Run vgscan after you change this parameter to ensure that
3274- # the cache file gets regenerated (see below).
3275- # If it doesn't do what you expect, check the output of 'vgscan -vvvv'.
3276-
3277-
3278- # By default we accept every block device:
3279- filter = [ "a/.*/" ]
3280-
3281- # Exclude the cdrom drive
3282- # filter = [ "r|/dev/cdrom|" ]
3283-
3284- # When testing I like to work with just loopback devices:
3285- # filter = [ "a/loop/", "r/.*/" ]
3286-
3287- # Or maybe all loops and ide drives except hdc:
3288- # filter =[ "a|loop|", "r|/dev/hdc|", "a|/dev/ide|", "r|.*|" ]
3289-
3290- # Use anchors if you want to be really specific
3291- # filter = [ "a|^/dev/hda8$|", "r/.*/" ]
3292-
3293- # Since "filter" is often overriden from command line, it is not suitable
3294- # for system-wide device filtering (udev rules, lvmetad). To hide devices
3295- # from LVM-specific udev processing and/or from lvmetad, you need to set
3296- # global_filter. The syntax is the same as for normal "filter"
3297- # above. Devices that fail the global_filter are not even opened by LVM.
3298-
3299- # global_filter = []
3300-
3301- # The results of the filtering are cached on disk to avoid
3302- # rescanning dud devices (which can take a very long time).
3303- # By default this cache is stored in the @DEFAULT_SYS_DIR@/@DEFAULT_CACHE_SUBDIR@ directory
3304- # in a file called '.cache'.
3305- # It is safe to delete the contents: the tools regenerate it.
3306- # (The old setting 'cache' is still respected if neither of
3307- # these new ones is present.)
3308- # N.B. If obtain_device_list_from_udev is set to 1 the list of
3309- # devices is instead obtained from udev and any existing .cache
3310- # file is removed.
3311- cache_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_CACHE_SUBDIR@"
3312- cache_file_prefix = ""
3313-
3314- # You can turn off writing this cache file by setting this to 0.
3315- write_cache_state = 1
3316-
3317- # Advanced settings.
3318-
3319- # List of pairs of additional acceptable block device types found
3320- # in /proc/devices with maximum (non-zero) number of partitions.
3321- # types = [ "fd", 16 ]
3322-
3323- # If sysfs is mounted (2.6 kernels) restrict device scanning to
3324- # the block devices it believes are valid.
3325- # 1 enables; 0 disables.
3326- sysfs_scan = 1
3327-
3328- # By default, LVM2 will ignore devices used as component paths
3329- # of device-mapper multipath devices.
3330- # 1 enables; 0 disables.
3331- multipath_component_detection = 1
3332-
3333- # By default, LVM2 will ignore devices used as components of
3334- # software RAID (md) devices by looking for md superblocks.
3335- # 1 enables; 0 disables.
3336- md_component_detection = 1
3337-
3338- # By default, if a PV is placed directly upon an md device, LVM2
3339- # will align its data blocks with the md device's stripe-width.
3340- # 1 enables; 0 disables.
3341- md_chunk_alignment = 1
3342-
3343- # Default alignment of the start of a data area in MB. If set to 0,
3344- # a value of 64KB will be used. Set to 1 for 1MiB, 2 for 2MiB, etc.
3345- # default_data_alignment = @DEFAULT_DATA_ALIGNMENT@
3346-
3347- # By default, the start of a PV's data area will be a multiple of
3348- # the 'minimum_io_size' or 'optimal_io_size' exposed in sysfs.
3349- # - minimum_io_size - the smallest request the device can perform
3350- # w/o incurring a read-modify-write penalty (e.g. MD's chunk size)
3351- # - optimal_io_size - the device's preferred unit of receiving I/O
3352- # (e.g. MD's stripe width)
3353- # minimum_io_size is used if optimal_io_size is undefined (0).
3354- # If md_chunk_alignment is enabled, that detects the optimal_io_size.
3355- # This setting takes precedence over md_chunk_alignment.
3356- # 1 enables; 0 disables.
3357- data_alignment_detection = 1
3358-
3359- # Alignment (in KB) of start of data area when creating a new PV.
3360- # md_chunk_alignment and data_alignment_detection are disabled if set.
3361- # Set to 0 for the default alignment (see: data_alignment_default)
3362- # or page size, if larger.
3363- data_alignment = 0
3364-
3365- # By default, the start of the PV's aligned data area will be shifted by
3366- # the 'alignment_offset' exposed in sysfs. This offset is often 0 but
3367- # may be non-zero; e.g.: certain 4KB sector drives that compensate for
3368- # windows partitioning will have an alignment_offset of 3584 bytes
3369- # (sector 7 is the lowest aligned logical block, the 4KB sectors start
3370- # at LBA -1, and consequently sector 63 is aligned on a 4KB boundary).
3371- # But note that pvcreate --dataalignmentoffset will skip this detection.
3372- # 1 enables; 0 disables.
3373- data_alignment_offset_detection = 1
3374-
3375- # If, while scanning the system for PVs, LVM2 encounters a device-mapper
3376- # device that has its I/O suspended, it waits for it to become accessible.
3377- # Set this to 1 to skip such devices. This should only be needed
3378- # in recovery situations.
3379- ignore_suspended_devices = 0
3380-
3381- # During each LVM operation errors received from each device are counted.
3382- # If the counter of a particular device exceeds the limit set here, no
3383- # further I/O is sent to that device for the remainder of the respective
3384- # operation. Setting the parameter to 0 disables the counters altogether.
3385- disable_after_error_count = 0
3386-
3387- # Allow use of pvcreate --uuid without requiring --restorefile.
3388- require_restorefile_with_uuid = 1
3389-
3390- # Minimum size (in KB) of block devices which can be used as PVs.
3391- # In a clustered environment all nodes must use the same value.
3392- # Any value smaller than 512KB is ignored.
3393-
3394- # Ignore devices smaller than 2MB such as floppy drives.
3395- pv_min_size = 2048
3396-
3397- # The original built-in setting was 512 up to and including version 2.02.84.
3398- # pv_min_size = 512
3399-
3400- # Issue discards to a logical volumes's underlying physical volume(s) when
3401- # the logical volume is no longer using the physical volumes' space (e.g.
3402- # lvremove, lvreduce, etc). Discards inform the storage that a region is
3403- # no longer in use. Storage that supports discards advertise the protocol
3404- # specific way discards should be issued by the kernel (TRIM, UNMAP, or
3405- # WRITE SAME with UNMAP bit set). Not all storage will support or benefit
3406- # from discards but SSDs and thinly provisioned LUNs generally do. If set
3407- # to 1, discards will only be issued if both the storage and kernel provide
3408- # support.
3409- # 1 enables; 0 disables.
3410- issue_discards = 0
3411-}
3412-
3413-# This section allows you to configure the way in which LVM selects
3414-# free space for its Logical Volumes.
3415-allocation {
3416-
3417- # When searching for free space to extend an LV, the "cling"
3418- # allocation policy will choose space on the same PVs as the last
3419- # segment of the existing LV. If there is insufficient space and a
3420- # list of tags is defined here, it will check whether any of them are
3421- # attached to the PVs concerned and then seek to match those PV tags
3422- # between existing extents and new extents.
3423- # Use the special tag "@*" as a wildcard to match any PV tag.
3424-
3425- # Example: LVs are mirrored between two sites within a single VG.
3426- # PVs are tagged with either @site1 or @site2 to indicate where
3427- # they are situated.
3428-
3429- # cling_tag_list = [ "@site1", "@site2" ]
3430- # cling_tag_list = [ "@*" ]
3431-
3432- # Changes made in version 2.02.85 extended the reach of the 'cling'
3433- # policies to detect more situations where data can be grouped
3434- # onto the same disks. Set this to 0 to revert to the previous
3435- # algorithm.
3436- maximise_cling = 1
3437-
3438- # Set to 1 to guarantee that mirror logs will always be placed on
3439- # different PVs from the mirror images. This was the default
3440- # until version 2.02.85.
3441- mirror_logs_require_separate_pvs = 0
3442-
3443- # Set to 1 to guarantee that thin pool metadata will always
3444- # be placed on different PVs from the pool data.
3445- thin_pool_metadata_require_separate_pvs = 0
3446-}
3447-
3448-# This section that allows you to configure the nature of the
3449-# information that LVM2 reports.
3450-log {
3451-
3452- # Controls the messages sent to stdout or stderr.
3453- # There are three levels of verbosity, 3 being the most verbose.
3454- verbose = 0
3455-
3456- # Set to 1 to suppress all non-essential messages from stdout.
3457- # This has the same effect as -qq.
3458- # When this is set, the following commands still produce output:
3459- # dumpconfig, lvdisplay, lvmdiskscan, lvs, pvck, pvdisplay,
3460- # pvs, version, vgcfgrestore -l, vgdisplay, vgs.
3461- # Non-essential messages are shifted from log level 4 to log level 5
3462- # for syslog and lvm2_log_fn purposes.
3463- # Any 'yes' or 'no' questions not overridden by other arguments
3464- # are suppressed and default to 'no'.
3465- silent = 0
3466-
3467- # Should we send log messages through syslog?
3468- # 1 is yes; 0 is no.
3469- syslog = 1
3470-
3471- # Should we log error and debug messages to a file?
3472- # By default there is no log file.
3473- #file = "/var/log/lvm2.log"
3474-
3475- # Should we overwrite the log file each time the program is run?
3476- # By default we append.
3477- overwrite = 0
3478-
3479- # What level of log messages should we send to the log file and/or syslog?
3480- # There are 6 syslog-like log levels currently in use - 2 to 7 inclusive.
3481- # 7 is the most verbose (LOG_DEBUG).
3482- level = 0
3483-
3484- # Format of output messages
3485- # Whether or not (1 or 0) to indent messages according to their severity
3486- indent = 1
3487-
3488- # Whether or not (1 or 0) to display the command name on each line output
3489- command_names = 0
3490-
3491- # A prefix to use before the message text (but after the command name,
3492- # if selected). Default is two spaces, so you can see/grep the severity
3493- # of each message.
3494- prefix = " "
3495-
3496- # To make the messages look similar to the original LVM tools use:
3497- # indent = 0
3498- # command_names = 1
3499- # prefix = " -- "
3500-
3501- # Set this if you want log messages during activation.
3502- # Don't use this in low memory situations (can deadlock).
3503- # activation = 0
3504-}
3505-
3506-# Configuration of metadata backups and archiving. In LVM2 when we
3507-# talk about a 'backup' we mean making a copy of the metadata for the
3508-# *current* system. The 'archive' contains old metadata configurations.
3509-# Backups are stored in a human readeable text format.
3510-backup {
3511-
3512- # Should we maintain a backup of the current metadata configuration ?
3513- # Use 1 for Yes; 0 for No.
3514- # Think very hard before turning this off!
3515- backup = 1
3516-
3517- # Where shall we keep it ?
3518- # Remember to back up this directory regularly!
3519- backup_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_BACKUP_SUBDIR@"
3520-
3521- # Should we maintain an archive of old metadata configurations.
3522- # Use 1 for Yes; 0 for No.
3523- # On by default. Think very hard before turning this off.
3524- archive = 1
3525-
3526- # Where should archived files go ?
3527- # Remember to back up this directory regularly!
3528- archive_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_ARCHIVE_SUBDIR@"
3529-
3530- # What is the minimum number of archive files you wish to keep ?
3531- retain_min = 10
3532-
3533- # What is the minimum time you wish to keep an archive file for ?
3534- retain_days = 30
3535-}
3536-
3537-# Settings for the running LVM2 in shell (readline) mode.
3538-shell {
3539-
3540- # Number of lines of history to store in ~/.lvm_history
3541- history_size = 100
3542-}
3543-
3544-
3545-# Miscellaneous global LVM2 settings
3546-global {
3547-
3548- # The file creation mask for any files and directories created.
3549- # Interpreted as octal if the first digit is zero.
3550- umask = 077
3551-
3552- # Allow other users to read the files
3553- #umask = 022
3554-
3555- # Enabling test mode means that no changes to the on disk metadata
3556- # will be made. Equivalent to having the -t option on every
3557- # command. Defaults to off.
3558- test = 0
3559-
3560- # Default value for --units argument
3561- units = "h"
3562-
3563- # Since version 2.02.54, the tools distinguish between powers of
3564- # 1024 bytes (e.g. KiB, MiB, GiB) and powers of 1000 bytes (e.g.
3565- # KB, MB, GB).
3566- # If you have scripts that depend on the old behaviour, set this to 0
3567- # temporarily until you update them.
3568- si_unit_consistency = 1
3569-
3570- # Whether or not to communicate with the kernel device-mapper.
3571- # Set to 0 if you want to use the tools to manipulate LVM metadata
3572- # without activating any logical volumes.
3573- # If the device-mapper kernel driver is not present in your kernel
3574- # setting this to 0 should suppress the error messages.
3575- activation = 1
3576-
3577- # If we can't communicate with device-mapper, should we try running
3578- # the LVM1 tools?
3579- # This option only applies to 2.4 kernels and is provided to help you
3580- # switch between device-mapper kernels and LVM1 kernels.
3581- # The LVM1 tools need to be installed with .lvm1 suffices
3582- # e.g. vgscan.lvm1 and they will stop working after you start using
3583- # the new lvm2 on-disk metadata format.
3584- # The default value is set when the tools are built.
3585- # fallback_to_lvm1 = 0
3586-
3587- # The default metadata format that commands should use - "lvm1" or "lvm2".
3588- # The command line override is -M1 or -M2.
3589- # Defaults to "lvm2".
3590- # format = "lvm2"
3591-
3592- # Location of proc filesystem
3593- proc = "/proc"
3594-
3595- # Type of locking to use. Defaults to local file-based locking (1).
3596- # Turn locking off by setting to 0 (dangerous: risks metadata corruption
3597- # if LVM2 commands get run concurrently).
3598- # Type 2 uses the external shared library locking_library.
3599- # Type 3 uses built-in clustered locking.
3600- # Type 4 uses read-only locking which forbids any operations that might
3601- # change metadata.
3602- locking_type = 1
3603-
3604- # Set to 0 to fail when a lock request cannot be satisfied immediately.
3605- wait_for_locks = 1
3606-
3607- # If using external locking (type 2) and initialisation fails,
3608- # with this set to 1 an attempt will be made to use the built-in
3609- # clustered locking.
3610- # If you are using a customised locking_library you should set this to 0.
3611- fallback_to_clustered_locking = 1
3612-
3613- # If an attempt to initialise type 2 or type 3 locking failed, perhaps
3614- # because cluster components such as clvmd are not running, with this set
3615- # to 1 an attempt will be made to use local file-based locking (type 1).
3616- # If this succeeds, only commands against local volume groups will proceed.
3617- # Volume Groups marked as clustered will be ignored.
3618- fallback_to_local_locking = 1
3619-
3620- # Local non-LV directory that holds file-based locks while commands are
3621- # in progress. A directory like /tmp that may get wiped on reboot is OK.
3622- locking_dir = "@DEFAULT_LOCK_DIR@"
3623-
3624- # Whenever there are competing read-only and read-write access requests for
3625- # a volume group's metadata, instead of always granting the read-only
3626- # requests immediately, delay them to allow the read-write requests to be
3627- # serviced. Without this setting, write access may be stalled by a high
3628- # volume of read-only requests.
3629- # NB. This option only affects locking_type = 1 viz. local file-based
3630- # locking.
3631- prioritise_write_locks = 1
3632-
3633- # Other entries can go here to allow you to load shared libraries
3634- # e.g. if support for LVM1 metadata was compiled as a shared library use
3635- # format_libraries = "liblvm2format1.so"
3636- # Full pathnames can be given.
3637-
3638- # Search this directory first for shared libraries.
3639- # library_dir = "/lib"
3640-
3641- # The external locking library to load if locking_type is set to 2.
3642- # locking_library = "liblvm2clusterlock.so"
3643-
3644- # Treat any internal errors as fatal errors, aborting the process that
3645- # encountered the internal error. Please only enable for debugging.
3646- abort_on_internal_errors = 0
3647-
3648- # Check whether CRC is matching when parsed VG is used multiple times.
3649- # This is useful to catch unexpected internal cached volume group
3650- # structure modification. Please only enable for debugging.
3651- detect_internal_vg_cache_corruption = 0
3652-
3653- # If set to 1, no operations that change on-disk metadata will be permitted.
3654- # Additionally, read-only commands that encounter metadata in need of repair
3655- # will still be allowed to proceed exactly as if the repair had been
3656- # performed (except for the unchanged vg_seqno).
3657- # Inappropriate use could mess up your system, so seek advice first!
3658- metadata_read_only = 0
3659-
3660- # 'mirror_segtype_default' defines which segtype will be used when the
3661- # shorthand '-m' option is used for mirroring. The possible options are:
3662- #
3663- # "mirror" - The original RAID1 implementation provided by LVM2/DM. It is
3664- # characterized by a flexible log solution (core, disk, mirrored)
3665- # and by the necessity to block I/O while reconfiguring in the
3666- # event of a failure.
3667- #
3668- # There is an inherent race in the dmeventd failure handling
3669- # logic with snapshots of devices using this type of RAID1 that
3670- # in the worst case could cause a deadlock.
3671- # Ref: https://bugzilla.redhat.com/show_bug.cgi?id=817130#c10
3672- #
3673- # "raid1" - This implementation leverages MD's RAID1 personality through
3674- # device-mapper. It is characterized by a lack of log options.
3675- # (A log is always allocated for every device and they are placed
3676- # on the same device as the image - no separate devices are
3677- # required.) This mirror implementation does not require I/O
3678- # to be blocked in the kernel in the event of a failure.
3679- # This mirror implementation is not cluster-aware and cannot be
3680- # used in a shared (active/active) fashion in a cluster.
3681- #
3682- # Specify the '--type <mirror|raid1>' option to override this default
3683- # setting.
3684- mirror_segtype_default = "mirror"
3685-
3686- # The default format for displaying LV names in lvdisplay was changed
3687- # in version 2.02.89 to show the LV name and path separately.
3688- # Previously this was always shown as /dev/vgname/lvname even when that
3689- # was never a valid path in the /dev filesystem.
3690- # Set to 1 to reinstate the previous format.
3691- #
3692- # lvdisplay_shows_full_device_path = 0
3693-
3694- # Whether to use (trust) a running instance of lvmetad. If this is set to
3695- # 0, all commands fall back to the usual scanning mechanisms. When set to 1
3696- # *and* when lvmetad is running (it is not auto-started), the volume group
3697- # metadata and PV state flags are obtained from the lvmetad instance and no
3698- # scanning is done by the individual commands. In a setup with lvmetad,
3699- # lvmetad udev rules *must* be set up for LVM to work correctly. Without
3700- # proper udev rules, all changes in block device configuration will be
3701- # *ignored* until a manual 'pvscan --cache' is performed.
3702- #
3703- # If lvmetad has been running while use_lvmetad was 0, it MUST be stopped
3704- # before changing use_lvmetad to 1 and started again afterwards.
3705- use_lvmetad = 0
3706-
3707- # Full path of the utility called to check that a thin metadata device
3708- # is in a state that allows it to be used.
3709- # Each time a thin pool needs to be activated or after it is deactivated
3710- # this utility is executed. The activation will only proceed if the utility
3711- # has an exit status of 0.
3712- # Set to "" to skip this check. (Not recommended.)
3713- # The thin tools are available as part of the device-mapper-persistent-data
3714- # package from https://github.com/jthornber/thin-provisioning-tools.
3715- #
3716- thin_check_executable = "@THIN_CHECK_CMD@"
3717-
3718- # String with options passed with thin_check command. By default,
3719- # option '-q' is for quiet output.
3720- thin_check_options = [ "-q" ]
3721-}
3722-
3723-activation {
3724- # Set to 1 to perform internal checks on the operations issued to
3725- # libdevmapper. Useful for debugging problems with activation.
3726- # Some of the checks may be expensive, so it's best to use this
3727- # only when there seems to be a problem.
3728- checks = 0
3729-
3730- # Set to 0 to disable udev synchronisation (if compiled into the binaries).
3731- # Processes will not wait for notification from udev.
3732- # They will continue irrespective of any possible udev processing
3733- # in the background. You should only use this if udev is not running
3734- # or has rules that ignore the devices LVM2 creates.
3735- # The command line argument --nodevsync takes precedence over this setting.
3736- # If set to 1 when udev is not running, and there are LVM2 processes
3737- # waiting for udev, run 'dmsetup udevcomplete_all' manually to wake them up.
3738- udev_sync = 1
3739-
3740- # Set to 0 to disable the udev rules installed by LVM2 (if built with
3741- # --enable-udev_rules). LVM2 will then manage the /dev nodes and symlinks
3742- # for active logical volumes directly itself.
3743- # N.B. Manual intervention may be required if this setting is changed
3744- # while any logical volumes are active.
3745- udev_rules = 1
3746-
3747- # Set to 1 for LVM2 to verify operations performed by udev. This turns on
3748- # additional checks (and if necessary, repairs) on entries in the device
3749- # directory after udev has completed processing its events.
3750- # Useful for diagnosing problems with LVM2/udev interactions.
3751- verify_udev_operations = 0
3752-
3753- # If set to 1 and if deactivation of an LV fails, perhaps because
3754- # a process run from a quick udev rule temporarily opened the device,
3755- # retry the operation for a few seconds before failing.
3756- retry_deactivation = 1
3757-
3758- # How to fill in missing stripes if activating an incomplete volume.
3759- # Using "error" will make inaccessible parts of the device return
3760- # I/O errors on access. You can instead use a device path, in which
3761- # case, that device will be used to in place of missing stripes.
3762- # But note that using anything other than "error" with mirrored
3763- # or snapshotted volumes is likely to result in data corruption.
3764- missing_stripe_filler = "error"
3765-
3766- # The linear target is an optimised version of the striped target
3767- # that only handles a single stripe. Set this to 0 to disable this
3768- # optimisation and always use the striped target.
3769- use_linear_target = 1
3770-
3771- # How much stack (in KB) to reserve for use while devices suspended
3772- # Prior to version 2.02.89 this used to be set to 256KB
3773- reserved_stack = 64
3774-
3775- # How much memory (in KB) to reserve for use while devices suspended
3776- reserved_memory = 8192
3777-
3778- # Nice value used while devices suspended
3779- process_priority = -18
3780-
3781- # If volume_list is defined, each LV is only activated if there is a
3782- # match against the list.
3783- # "vgname" and "vgname/lvname" are matched exactly.
3784- # "@tag" matches any tag set in the LV or VG.
3785- # "@*" matches if any tag defined on the host is also set in the LV or VG
3786- #
3787- # volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
3788-
3789- # If auto_activation_volume_list is defined, each LV that is to be
3790- # activated is checked against the list while using the autoactivation
3791- # option (--activate ay/-a ay), and if it matches, it is activated.
3792- # "vgname" and "vgname/lvname" are matched exactly.
3793- # "@tag" matches any tag set in the LV or VG.
3794- # "@*" matches if any tag defined on the host is also set in the LV or VG
3795- #
3796- # auto_activation_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
3797-
3798- # If read_only_volume_list is defined, each LV that is to be activated
3799- # is checked against the list, and if it matches, it as activated
3800- # in read-only mode. (This overrides '--permission rw' stored in the
3801- # metadata.)
3802- # "vgname" and "vgname/lvname" are matched exactly.
3803- # "@tag" matches any tag set in the LV or VG.
3804- # "@*" matches if any tag defined on the host is also set in the LV or VG
3805- #
3806- # read_only_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
3807-
3808- # Size (in KB) of each copy operation when mirroring
3809- mirror_region_size = 512
3810-
3811- # Setting to use when there is no readahead value stored in the metadata.
3812- #
3813- # "none" - Disable readahead.
3814- # "auto" - Use default value chosen by kernel.
3815- readahead = "auto"
3816-
3817- # 'raid_fault_policy' defines how a device failure in a RAID logical
3818- # volume is handled. This includes logical volumes that have the following
3819- # segment types: raid1, raid4, raid5*, and raid6*.
3820- #
3821- # In the event of a failure, the following policies will determine what
3822- # actions are performed during the automated response to failures (when
3823- # dmeventd is monitoring the RAID logical volume) and when 'lvconvert' is
3824- # called manually with the options '--repair' and '--use-policies'.
3825- #
3826- # "warn" - Use the system log to warn the user that a device in the RAID
3827- # logical volume has failed. It is left to the user to run
3828- # 'lvconvert --repair' manually to remove or replace the failed
3829- # device. As long as the number of failed devices does not
3830- # exceed the redundancy of the logical volume (1 device for
3831- # raid4/5, 2 for raid6, etc) the logical volume will remain
3832- # usable.
3833- #
3834- # "allocate" - Attempt to use any extra physical volumes in the volume
3835- # group as spares and replace faulty devices.
3836- #
3837- raid_fault_policy = "warn"
3838-
3839- # 'mirror_image_fault_policy' and 'mirror_log_fault_policy' define
3840- # how a device failure affecting a mirror (of "mirror" segment type) is
3841- # handled. A mirror is composed of mirror images (copies) and a log.
3842- # A disk log ensures that a mirror does not need to be re-synced
3843- # (all copies made the same) every time a machine reboots or crashes.
3844- #
3845- # In the event of a failure, the specified policy will be used to determine
3846- # what happens. This applies to automatic repairs (when the mirror is being
3847- # monitored by dmeventd) and to manual lvconvert --repair when
3848- # --use-policies is given.
3849- #
3850- # "remove" - Simply remove the faulty device and run without it. If
3851- # the log device fails, the mirror would convert to using
3852- # an in-memory log. This means the mirror will not
3853- # remember its sync status across crashes/reboots and
3854- # the entire mirror will be re-synced. If a
3855- # mirror image fails, the mirror will convert to a
3856- # non-mirrored device if there is only one remaining good
3857- # copy.
3858- #
3859- # "allocate" - Remove the faulty device and try to allocate space on
3860- # a new device to be a replacement for the failed device.
3861- # Using this policy for the log is fast and maintains the
3862- # ability to remember sync state through crashes/reboots.
3863- # Using this policy for a mirror device is slow, as it
3864- # requires the mirror to resynchronize the devices, but it
3865- # will preserve the mirror characteristic of the device.
3866- # This policy acts like "remove" if no suitable device and
3867- # space can be allocated for the replacement.
3868- #
3869- # "allocate_anywhere" - Not yet implemented. Useful to place the log device
3870- # temporarily on same physical volume as one of the mirror
3871- # images. This policy is not recommended for mirror devices
3872- # since it would break the redundant nature of the mirror. This
3873- # policy acts like "remove" if no suitable device and space can
3874- # be allocated for the replacement.
3875-
3876- mirror_log_fault_policy = "allocate"
3877- mirror_image_fault_policy = "remove"
3878-
3879- # 'snapshot_autoextend_threshold' and 'snapshot_autoextend_percent' define
3880- # how to handle automatic snapshot extension. The former defines when the
3881- # snapshot should be extended: when its space usage exceeds this many
3882- # percent. The latter defines how much extra space should be allocated for
3883- # the snapshot, in percent of its current size.
3884- #
3885- # For example, if you set snapshot_autoextend_threshold to 70 and
3886- # snapshot_autoextend_percent to 20, whenever a snapshot exceeds 70% usage,
3887- # it will be extended by another 20%. For a 1G snapshot, using up 700M will
3888- # trigger a resize to 1.2G. When the usage exceeds 840M, the snapshot will
3889- # be extended to 1.44G, and so on.
3890- #
3891- # Setting snapshot_autoextend_threshold to 100 disables automatic
3892- # extensions. The minimum value is 50 (A setting below 50 will be treated
3893- # as 50).
3894-
3895- snapshot_autoextend_threshold = 100
3896- snapshot_autoextend_percent = 20
3897-
3898- # 'thin_pool_autoextend_threshold' and 'thin_pool_autoextend_percent' define
3899- # how to handle automatic pool extension. The former defines when the
3900- # pool should be extended: when its space usage exceeds this many
3901- # percent. The latter defines how much extra space should be allocated for
3902- # the pool, in percent of its current size.
3903- #
3904- # For example, if you set thin_pool_autoextend_threshold to 70 and
3905- # thin_pool_autoextend_percent to 20, whenever a pool exceeds 70% usage,
3906- # it will be extended by another 20%. For a 1G pool, using up 700M will
3907- # trigger a resize to 1.2G. When the usage exceeds 840M, the pool will
3908- # be extended to 1.44G, and so on.
3909- #
3910- # Setting thin_pool_autoextend_threshold to 100 disables automatic
3911- # extensions. The minimum value is 50 (A setting below 50 will be treated
3912- # as 50).
3913-
3914- thin_pool_autoextend_threshold = 100
3915- thin_pool_autoextend_percent = 20
3916-
3917- # While activating devices, I/O to devices being (re)configured is
3918- # suspended, and as a precaution against deadlocks, LVM2 needs to pin
3919- # any memory it is using so it is not paged out. Groups of pages that
3920- # are known not to be accessed during activation need not be pinned
3921- # into memory. Each string listed in this setting is compared against
3922- # each line in /proc/self/maps, and the pages corresponding to any
3923- # lines that match are not pinned. On some systems locale-archive was
3924- # found to make up over 80% of the memory used by the process.
3925- # mlock_filter = [ "locale/locale-archive", "gconv/gconv-modules.cache" ]
3926-
3927- # Set to 1 to revert to the default behaviour prior to version 2.02.62
3928- # which used mlockall() to pin the whole process's memory while activating
3929- # devices.
3930- use_mlockall = 0
3931-
3932- # Monitoring is enabled by default when activating logical volumes.
3933- # Set to 0 to disable monitoring or use the --ignoremonitoring option.
3934- monitoring = 1
3935-
3936- # When pvmove or lvconvert must wait for the kernel to finish
3937- # synchronising or merging data, they check and report progress
3938- # at intervals of this number of seconds. The default is 15 seconds.
3939- # If this is set to 0 and there is only one thing to wait for, there
3940- # are no progress reports, but the process is awoken immediately the
3941- # operation is complete.
3942- polling_interval = 15
3943-}
3944-
3945-
3946-####################
3947-# Advanced section #
3948-####################
3949-
3950-# Metadata settings
3951-#
3952-# metadata {
3953- # Default number of copies of metadata to hold on each PV. 0, 1 or 2.
3954- # You might want to override it from the command line with 0
3955- # when running pvcreate on new PVs which are to be added to large VGs.
3956-
3957- # pvmetadatacopies = 1
3958-
3959- # Default number of copies of metadata to maintain for each VG.
3960- # If set to a non-zero value, LVM automatically chooses which of
3961- # the available metadata areas to use to achieve the requested
3962- # number of copies of the VG metadata. If you set a value larger
3963- # than the the total number of metadata areas available then
3964- # metadata is stored in them all.
3965- # The default value of 0 ("unmanaged") disables this automatic
3966- # management and allows you to control which metadata areas
3967- # are used at the individual PV level using 'pvchange
3968- # --metadataignore y/n'.
3969-
3970- # vgmetadatacopies = 0
3971-
3972- # Approximate default size of on-disk metadata areas in sectors.
3973- # You should increase this if you have large volume groups or
3974- # you want to retain a large on-disk history of your metadata changes.
3975-
3976- # pvmetadatasize = 255
3977-
3978- # List of directories holding live copies of text format metadata.
3979- # These directories must not be on logical volumes!
3980- # It's possible to use LVM2 with a couple of directories here,
3981- # preferably on different (non-LV) filesystems, and with no other
3982- # on-disk metadata (pvmetadatacopies = 0). Or this can be in
3983- # addition to on-disk metadata areas.
3984- # The feature was originally added to simplify testing and is not
3985- # supported under low memory situations - the machine could lock up.
3986- #
3987- # Never edit any files in these directories by hand unless you
3988- # you are absolutely sure you know what you are doing! Use
3989- # the supplied toolset to make changes (e.g. vgcfgrestore).
3990-
3991- # dirs = [ "/etc/lvm/metadata", "/mnt/disk2/lvm/metadata2" ]
3992-#}
3993-
3994-# Event daemon
3995-#
3996-dmeventd {
3997- # mirror_library is the library used when monitoring a mirror device.
3998- #
3999- # "libdevmapper-event-lvm2mirror.so" attempts to recover from
4000- # failures. It removes failed devices from a volume group and
4001- # reconfigures a mirror as necessary. If no mirror library is
4002- # provided, mirrors are not monitored through dmeventd.
4003-
4004- mirror_library = "libdevmapper-event-lvm2mirror.so"
4005-
4006- # snapshot_library is the library used when monitoring a snapshot device.
4007- #
4008- # "libdevmapper-event-lvm2snapshot.so" monitors the filling of
4009- # snapshots and emits a warning through syslog when the use of
4010- # the snapshot exceeds 80%. The warning is repeated when 85%, 90% and
4011- # 95% of the snapshot is filled.
4012-
4013- snapshot_library = "libdevmapper-event-lvm2snapshot.so"
4014-
4015- # thin_library is the library used when monitoring a thin device.
4016- #
4017- # "libdevmapper-event-lvm2thin.so" monitors the filling of
4018- # pool and emits a warning through syslog when the use of
4019- # the pool exceeds 80%. The warning is repeated when 85%, 90% and
4020- # 95% of the pool is filled.
4021-
4022- thin_library = "libdevmapper-event-lvm2thin.so"
4023-
4024- # Full path of the dmeventd binary.
4025- #
4026- # executable = "@DMEVENTD_PATH@"
4027-}
4028
4029=== removed directory '.pc/dirs.patch/lib'
4030=== removed directory '.pc/dirs.patch/lib/commands'
4031=== removed file '.pc/dirs.patch/lib/commands/toolcontext.c'
4032--- .pc/dirs.patch/lib/commands/toolcontext.c 2013-05-30 11:02:10 +0000
4033+++ .pc/dirs.patch/lib/commands/toolcontext.c 1970-01-01 00:00:00 +0000
4034@@ -1,1688 +0,0 @@
4035-/*
4036- * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
4037- * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
4038- *
4039- * This file is part of LVM2.
4040- *
4041- * This copyrighted material is made available to anyone wishing to use,
4042- * modify, copy, or redistribute it subject to the terms and conditions
4043- * of the GNU Lesser General Public License v.2.1.
4044- *
4045- * You should have received a copy of the GNU Lesser General Public License
4046- * along with this program; if not, write to the Free Software Foundation,
4047- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4048- */
4049-
4050-#include "lib.h"
4051-#include "toolcontext.h"
4052-#include "metadata.h"
4053-#include "defaults.h"
4054-#include "lvm-string.h"
4055-#include "activate.h"
4056-#include "filter.h"
4057-#include "filter-composite.h"
4058-#include "filter-md.h"
4059-#include "filter-mpath.h"
4060-#include "filter-persistent.h"
4061-#include "filter-regex.h"
4062-#include "filter-sysfs.h"
4063-#include "label.h"
4064-#include "lvm-file.h"
4065-#include "format-text.h"
4066-#include "display.h"
4067-#include "memlock.h"
4068-#include "str_list.h"
4069-#include "segtype.h"
4070-#include "lvmcache.h"
4071-#include "lvmetad.h"
4072-#include "dev-cache.h"
4073-#include "archiver.h"
4074-
4075-#ifdef HAVE_LIBDL
4076-#include "sharedlib.h"
4077-#endif
4078-
4079-#ifdef LVM1_INTERNAL
4080-#include "format1.h"
4081-#endif
4082-
4083-#ifdef POOL_INTERNAL
4084-#include "format_pool.h"
4085-#endif
4086-
4087-#include <locale.h>
4088-#include <sys/stat.h>
4089-#include <sys/utsname.h>
4090-#include <syslog.h>
4091-#include <time.h>
4092-
4093-#ifdef linux
4094-# include <malloc.h>
4095-#endif
4096-
4097-static const size_t linebuffer_size = 4096;
4098-
4099-static int _get_env_vars(struct cmd_context *cmd)
4100-{
4101- const char *e;
4102-
4103- /* Set to "" to avoid using any system directory */
4104- if ((e = getenv("LVM_SYSTEM_DIR"))) {
4105- if (dm_snprintf(cmd->system_dir, sizeof(cmd->system_dir),
4106- "%s", e) < 0) {
4107- log_error("LVM_SYSTEM_DIR environment variable "
4108- "is too long.");
4109- return 0;
4110- }
4111- }
4112-
4113- return 1;
4114-}
4115-
4116-static void _get_sysfs_dir(struct cmd_context *cmd)
4117-{
4118- static char proc_mounts[PATH_MAX];
4119- static char *split[4], buffer[PATH_MAX + 16];
4120- FILE *fp;
4121- char *sys_mnt = NULL;
4122-
4123- cmd->sysfs_dir[0] = '\0';
4124- if (!*cmd->proc_dir) {
4125- log_debug("No proc filesystem found: skipping sysfs detection");
4126- return;
4127- }
4128-
4129- if (dm_snprintf(proc_mounts, sizeof(proc_mounts),
4130- "%s/mounts", cmd->proc_dir) < 0) {
4131- log_error("Failed to create /proc/mounts string for sysfs detection");
4132- return;
4133- }
4134-
4135- if (!(fp = fopen(proc_mounts, "r"))) {
4136- log_sys_error("_get_sysfs_dir fopen", proc_mounts);
4137- return;
4138- }
4139-
4140- while (fgets(buffer, sizeof(buffer), fp)) {
4141- if (dm_split_words(buffer, 4, 0, split) == 4 &&
4142- !strcmp(split[2], "sysfs")) {
4143- sys_mnt = split[1];
4144- break;
4145- }
4146- }
4147-
4148- if (fclose(fp))
4149- log_sys_error("fclose", proc_mounts);
4150-
4151- if (!sys_mnt) {
4152- log_error("Failed to find sysfs mount point");
4153- return;
4154- }
4155-
4156- strncpy(cmd->sysfs_dir, sys_mnt, sizeof(cmd->sysfs_dir));
4157-}
4158-
4159-static void _init_logging(struct cmd_context *cmd)
4160-{
4161- int append = 1;
4162- time_t t;
4163-
4164- const char *log_file;
4165- char timebuf[26];
4166-
4167- /* Syslog */
4168- cmd->default_settings.syslog =
4169- find_config_tree_int(cmd, "log/syslog", DEFAULT_SYSLOG);
4170- if (cmd->default_settings.syslog != 1)
4171- fin_syslog();
4172-
4173- if (cmd->default_settings.syslog > 1)
4174- init_syslog(cmd->default_settings.syslog);
4175-
4176- /* Debug level for log file output */
4177- cmd->default_settings.debug =
4178- find_config_tree_int(cmd, "log/level", DEFAULT_LOGLEVEL);
4179- init_debug(cmd->default_settings.debug);
4180-
4181- /*
4182- * Suppress all non-essential stdout?
4183- * -qq can override the default of 0 to 1 later.
4184- * Once set to 1, there is no facility to change it back to 0.
4185- */
4186- cmd->default_settings.silent = silent_mode() ? :
4187- find_config_tree_int(cmd, "log/silent", DEFAULT_SILENT);
4188- init_silent(cmd->default_settings.silent);
4189-
4190- /* Verbose level for tty output */
4191- cmd->default_settings.verbose =
4192- find_config_tree_int(cmd, "log/verbose", DEFAULT_VERBOSE);
4193- init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL);
4194-
4195- /* Log message formatting */
4196- init_indent(find_config_tree_int(cmd, "log/indent",
4197- DEFAULT_INDENT));
4198- init_abort_on_internal_errors(find_config_tree_int(cmd, "global/abort_on_internal_errors",
4199- DEFAULT_ABORT_ON_INTERNAL_ERRORS));
4200-
4201- cmd->default_settings.msg_prefix =
4202- find_config_tree_str_allow_empty(cmd, "log/prefix", DEFAULT_MSG_PREFIX);
4203-
4204- init_msg_prefix(cmd->default_settings.msg_prefix);
4205-
4206- cmd->default_settings.cmd_name = find_config_tree_int(cmd,
4207- "log/command_names",
4208- DEFAULT_CMD_NAME);
4209- init_cmd_name(cmd->default_settings.cmd_name);
4210-
4211- /* Test mode */
4212- cmd->default_settings.test =
4213- find_config_tree_int(cmd, "global/test", 0);
4214- init_test(cmd->default_settings.test);
4215-
4216- /* Settings for logging to file */
4217- if (find_config_tree_int(cmd, "log/overwrite", DEFAULT_OVERWRITE))
4218- append = 0;
4219-
4220- log_file = find_config_tree_str(cmd, "log/file", 0);
4221-
4222- if (log_file) {
4223- release_log_memory();
4224- fin_log();
4225- init_log_file(log_file, append);
4226- }
4227-
4228- log_file = find_config_tree_str(cmd, "log/activate_file", 0);
4229- if (log_file)
4230- init_log_direct(log_file, append);
4231-
4232- init_log_while_suspended(find_config_tree_int(cmd,
4233- "log/activation", 0));
4234-
4235- t = time(NULL);
4236- ctime_r(&t, &timebuf[0]);
4237- timebuf[24] = '\0';
4238- log_verbose("Logging initialised at %s", timebuf);
4239-
4240- /* Tell device-mapper about our logging */
4241-#ifdef DEVMAPPER_SUPPORT
4242- dm_log_with_errno_init(print_log);
4243-#endif
4244- reset_log_duplicated();
4245- reset_lvm_errno(1);
4246-}
4247-
4248-#ifdef UDEV_SYNC_SUPPORT
4249-/*
4250- * Until the DM_UEVENT_GENERATED_FLAG was introduced in kernel patch
4251- * 856a6f1dbd8940e72755af145ebcd806408ecedd
4252- * some operations could not be performed by udev, requiring our fallback code.
4253- */
4254-static int _dm_driver_has_stable_udev_support(void)
4255-{
4256- char vsn[80];
4257- unsigned maj, min, patchlevel;
4258-
4259- return driver_version(vsn, sizeof(vsn)) &&
4260- (sscanf(vsn, "%u.%u.%u", &maj, &min, &patchlevel) == 3) &&
4261- (maj == 4 ? min >= 18 : maj > 4);
4262-}
4263-#endif
4264-
4265-static int _process_config(struct cmd_context *cmd)
4266-{
4267- mode_t old_umask;
4268- const char *read_ahead;
4269- struct stat st;
4270- const struct dm_config_node *cn;
4271- const struct dm_config_value *cv;
4272- int64_t pv_min_kb;
4273- const char *lvmetad_socket;
4274-
4275- /* umask */
4276- cmd->default_settings.umask = find_config_tree_int(cmd,
4277- "global/umask",
4278- DEFAULT_UMASK);
4279-
4280- if ((old_umask = umask((mode_t) cmd->default_settings.umask)) !=
4281- (mode_t) cmd->default_settings.umask)
4282- log_verbose("Set umask from %04o to %04o",
4283- old_umask, cmd->default_settings.umask);
4284-
4285- /* dev dir */
4286- if (dm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/",
4287- find_config_tree_str(cmd, "devices/dir",
4288- DEFAULT_DEV_DIR)) < 0) {
4289- log_error("Device directory given in config file too long");
4290- return 0;
4291- }
4292-#ifdef DEVMAPPER_SUPPORT
4293- dm_set_dev_dir(cmd->dev_dir);
4294-
4295- if (!dm_set_uuid_prefix("LVM-"))
4296- return_0;
4297-#endif
4298-
4299- /* proc dir */
4300- if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
4301- find_config_tree_str(cmd, "global/proc",
4302- DEFAULT_PROC_DIR)) < 0) {
4303- log_error("Device directory given in config file too long");
4304- return 0;
4305- }
4306-
4307- if (*cmd->proc_dir && !dir_exists(cmd->proc_dir)) {
4308- log_warn("WARNING: proc dir %s not found - some checks will be bypassed",
4309- cmd->proc_dir);
4310- cmd->proc_dir[0] = '\0';
4311- }
4312-
4313- /* FIXME Use global value of sysfs_dir everywhere instead cmd->sysfs_dir. */
4314- _get_sysfs_dir(cmd);
4315- set_sysfs_dir_path(cmd->sysfs_dir);
4316- dm_set_sysfs_dir(cmd->sysfs_dir);
4317-
4318- /* activation? */
4319- cmd->default_settings.activation = find_config_tree_int(cmd,
4320- "global/activation",
4321- DEFAULT_ACTIVATION);
4322- set_activation(cmd->default_settings.activation);
4323-
4324- cmd->default_settings.suffix = find_config_tree_int(cmd,
4325- "global/suffix",
4326- DEFAULT_SUFFIX);
4327-
4328- if (!(cmd->default_settings.unit_factor =
4329- units_to_bytes(find_config_tree_str(cmd,
4330- "global/units",
4331- DEFAULT_UNITS),
4332- &cmd->default_settings.unit_type))) {
4333- log_error("Invalid units specification");
4334- return 0;
4335- }
4336-
4337- read_ahead = find_config_tree_str(cmd, "activation/readahead", DEFAULT_READ_AHEAD);
4338- if (!strcasecmp(read_ahead, "auto"))
4339- cmd->default_settings.read_ahead = DM_READ_AHEAD_AUTO;
4340- else if (!strcasecmp(read_ahead, "none"))
4341- cmd->default_settings.read_ahead = DM_READ_AHEAD_NONE;
4342- else {
4343- log_error("Invalid readahead specification");
4344- return 0;
4345- }
4346-
4347- cmd->default_settings.udev_rules = find_config_tree_int(cmd,
4348- "activation/udev_rules",
4349- DEFAULT_UDEV_RULES);
4350-
4351- cmd->default_settings.udev_sync = find_config_tree_int(cmd,
4352- "activation/udev_sync",
4353- DEFAULT_UDEV_SYNC);
4354-
4355- init_retry_deactivation(find_config_tree_int(cmd, "activation/retry_deactivation",
4356- DEFAULT_RETRY_DEACTIVATION));
4357-
4358- init_activation_checks(find_config_tree_int(cmd, "activation/checks",
4359- DEFAULT_ACTIVATION_CHECKS));
4360-
4361-#ifdef UDEV_SYNC_SUPPORT
4362- /*
4363- * We need udev rules to be applied, otherwise we would end up with no
4364- * nodes and symlinks! However, we can disable the synchronization itself
4365- * in runtime and still have only udev to create the nodes and symlinks
4366- * without any fallback.
4367- */
4368- cmd->default_settings.udev_fallback = cmd->default_settings.udev_rules ?
4369- find_config_tree_int(cmd, "activation/verify_udev_operations",
4370- DEFAULT_VERIFY_UDEV_OPERATIONS) : 1;
4371-
4372- /* Do not rely fully on udev if the udev support is known to be incomplete. */
4373- if (!cmd->default_settings.udev_fallback && !_dm_driver_has_stable_udev_support()) {
4374- log_very_verbose("Kernel driver has incomplete udev support so "
4375- "LVM will check and perform some operations itself.");
4376- cmd->default_settings.udev_fallback = 1;
4377- }
4378-
4379-#else
4380- /* We must use old node/symlink creation code if not compiled with udev support at all! */
4381- cmd->default_settings.udev_fallback = 1;
4382-#endif
4383-
4384- cmd->use_linear_target = find_config_tree_int(cmd,
4385- "activation/use_linear_target",
4386- DEFAULT_USE_LINEAR_TARGET);
4387-
4388- cmd->stripe_filler = find_config_tree_str(cmd,
4389- "activation/missing_stripe_filler",
4390- DEFAULT_STRIPE_FILLER);
4391-
4392- /* FIXME Missing error code checks from the stats, not log_warn?, notify if setting overridden, delay message/check till it is actually used (eg consider if lvm shell - file could appear later after this check)? */
4393- if (!strcmp(cmd->stripe_filler, "/dev/ioerror") &&
4394- stat(cmd->stripe_filler, &st))
4395- cmd->stripe_filler = "error";
4396-
4397- if (strcmp(cmd->stripe_filler, "error")) {
4398- if (stat(cmd->stripe_filler, &st)) {
4399- log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
4400- "is invalid,", cmd->stripe_filler);
4401- log_warn(" stat failed: %s", strerror(errno));
4402- log_warn("Falling back to \"error\" missing_stripe_filler.");
4403- cmd->stripe_filler = "error";
4404- } else if (!S_ISBLK(st.st_mode)) {
4405- log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
4406- "is not a block device.", cmd->stripe_filler);
4407- log_warn("Falling back to \"error\" missing_stripe_filler.");
4408- cmd->stripe_filler = "error";
4409- }
4410- }
4411-
4412- cmd->si_unit_consistency = find_config_tree_int(cmd,
4413- "global/si_unit_consistency",
4414- DEFAULT_SI_UNIT_CONSISTENCY);
4415-
4416- if ((cn = find_config_tree_node(cmd, "activation/mlock_filter")))
4417- for (cv = cn->v; cv; cv = cv->next)
4418- if ((cv->type != DM_CFG_STRING) || !cv->v.str[0])
4419- log_error("Ignoring invalid activation/mlock_filter entry in config file");
4420-
4421- cmd->metadata_read_only = find_config_tree_int(cmd, "global/metadata_read_only",
4422- DEFAULT_METADATA_READ_ONLY);
4423-
4424- pv_min_kb = find_config_tree_int64(cmd, "devices/pv_min_size", DEFAULT_PV_MIN_SIZE_KB);
4425- if (pv_min_kb < PV_MIN_SIZE_KB) {
4426- log_warn("Ignoring too small pv_min_size %" PRId64 "KB, using default %dKB.",
4427- pv_min_kb, PV_MIN_SIZE_KB);
4428- pv_min_kb = PV_MIN_SIZE_KB;
4429- }
4430- /* LVM stores sizes internally in units of 512-byte sectors. */
4431- init_pv_min_size((uint64_t)pv_min_kb * (1024 >> SECTOR_SHIFT));
4432-
4433- init_detect_internal_vg_cache_corruption
4434- (find_config_tree_int(cmd, "global/detect_internal_vg_cache_corruption",
4435- DEFAULT_DETECT_INTERNAL_VG_CACHE_CORRUPTION));
4436-
4437- lvmetad_disconnect();
4438-
4439- lvmetad_socket = getenv("LVM_LVMETAD_SOCKET");
4440- if (!lvmetad_socket)
4441- lvmetad_socket = DEFAULT_RUN_DIR "/lvmetad.socket";
4442-
4443- /* TODO?
4444- lvmetad_socket = find_config_tree_str(cmd, "lvmetad/socket_path",
4445- DEFAULT_RUN_DIR "/lvmetad.socket");
4446- */
4447- lvmetad_set_socket(lvmetad_socket);
4448- cn = find_config_tree_node(cmd, "devices/global_filter");
4449- lvmetad_set_token(cn ? cn->v : NULL);
4450- lvmetad_set_active(find_config_tree_int(cmd, "global/use_lvmetad", 0));
4451- lvmetad_init(cmd);
4452-
4453- return 1;
4454-}
4455-
4456-static int _set_tag(struct cmd_context *cmd, const char *tag)
4457-{
4458- log_very_verbose("Setting host tag: %s", dm_pool_strdup(cmd->libmem, tag));
4459-
4460- if (!str_list_add(cmd->libmem, &cmd->tags, tag)) {
4461- log_error("_set_tag: str_list_add %s failed", tag);
4462- return 0;
4463- }
4464-
4465- return 1;
4466-}
4467-
4468-static int _check_host_filters(struct cmd_context *cmd, const struct dm_config_node *hn,
4469- int *passes)
4470-{
4471- const struct dm_config_node *cn;
4472- const struct dm_config_value *cv;
4473-
4474- *passes = 1;
4475-
4476- for (cn = hn; cn; cn = cn->sib) {
4477- if (!cn->v)
4478- continue;
4479- if (!strcmp(cn->key, "host_list")) {
4480- *passes = 0;
4481- if (cn->v->type == DM_CFG_EMPTY_ARRAY)
4482- continue;
4483- for (cv = cn->v; cv; cv = cv->next) {
4484- if (cv->type != DM_CFG_STRING) {
4485- log_error("Invalid hostname string "
4486- "for tag %s", cn->key);
4487- return 0;
4488- }
4489- if (!strcmp(cv->v.str, cmd->hostname)) {
4490- *passes = 1;
4491- return 1;
4492- }
4493- }
4494- }
4495- if (!strcmp(cn->key, "host_filter")) {
4496- log_error("host_filter not supported yet");
4497- return 0;
4498- }
4499- }
4500-
4501- return 1;
4502-}
4503-
4504-static int _init_tags(struct cmd_context *cmd, struct dm_config_tree *cft)
4505-{
4506- const struct dm_config_node *tn, *cn;
4507- const char *tag;
4508- int passes;
4509-
4510- if (!(tn = dm_config_find_node(cft->root, "tags")) || !tn->child)
4511- return 1;
4512-
4513- /* NB hosttags 0 when already 1 intentionally does not delete the tag */
4514- if (!cmd->hosttags && dm_config_find_int(cft->root, "tags/hosttags",
4515- DEFAULT_HOSTTAGS)) {
4516- /* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
4517- if (!_set_tag(cmd, cmd->hostname))
4518- return_0;
4519- cmd->hosttags = 1;
4520- }
4521-
4522- for (cn = tn->child; cn; cn = cn->sib) {
4523- if (cn->v)
4524- continue;
4525- tag = cn->key;
4526- if (*tag == '@')
4527- tag++;
4528- if (!validate_name(tag)) {
4529- log_error("Invalid tag in config file: %s", cn->key);
4530- return 0;
4531- }
4532- if (cn->child) {
4533- passes = 0;
4534- if (!_check_host_filters(cmd, cn->child, &passes))
4535- return_0;
4536- if (!passes)
4537- continue;
4538- }
4539- if (!_set_tag(cmd, tag))
4540- return_0;
4541- }
4542-
4543- return 1;
4544-}
4545-
4546-static int _load_config_file(struct cmd_context *cmd, const char *tag)
4547-{
4548- static char config_file[PATH_MAX] = "";
4549- const char *filler = "";
4550- struct stat info;
4551- struct config_tree_list *cfl;
4552-
4553- if (*tag)
4554- filler = "_";
4555-
4556- if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
4557- cmd->system_dir, filler, tag) < 0) {
4558- log_error("LVM_SYSTEM_DIR or tag was too long");
4559- return 0;
4560- }
4561-
4562- if (!(cfl = dm_pool_alloc(cmd->libmem, sizeof(*cfl)))) {
4563- log_error("config_tree_list allocation failed");
4564- return 0;
4565- }
4566-
4567- if (!(cfl->cft = config_file_open(config_file, 0))) {
4568- log_error("config_tree allocation failed");
4569- return 0;
4570- }
4571-
4572- /* Is there a config file? */
4573- if (stat(config_file, &info) == -1) {
4574- if (errno == ENOENT) {
4575- dm_list_add(&cmd->config_files, &cfl->list);
4576- goto out;
4577- }
4578- log_sys_error("stat", config_file);
4579- config_file_destroy(cfl->cft);
4580- return 0;
4581- }
4582-
4583- log_very_verbose("Loading config file: %s", config_file);
4584- if (!config_file_read(cfl->cft)) {
4585- log_error("Failed to load config file %s", config_file);
4586- config_file_destroy(cfl->cft);
4587- return 0;
4588- }
4589-
4590- dm_list_add(&cmd->config_files, &cfl->list);
4591-
4592- out:
4593- if (*tag) {
4594- if (!_init_tags(cmd, cfl->cft))
4595- return_0;
4596- } else
4597- /* Use temporary copy of lvm.conf while loading other files */
4598- cmd->cft = cfl->cft;
4599-
4600- return 1;
4601-}
4602-
4603-/* Find and read first config file */
4604-static int _init_lvm_conf(struct cmd_context *cmd)
4605-{
4606- /* No config file if LVM_SYSTEM_DIR is empty */
4607- if (!*cmd->system_dir) {
4608- if (!(cmd->cft = config_file_open(NULL, 0))) {
4609- log_error("Failed to create config tree");
4610- return 0;
4611- }
4612- return 1;
4613- }
4614-
4615- if (!_load_config_file(cmd, ""))
4616- return_0;
4617-
4618- return 1;
4619-}
4620-
4621-/* Read any additional config files */
4622-static int _init_tag_configs(struct cmd_context *cmd)
4623-{
4624- struct str_list *sl;
4625-
4626- /* Tag list may grow while inside this loop */
4627- dm_list_iterate_items(sl, &cmd->tags) {
4628- if (!_load_config_file(cmd, sl->str))
4629- return_0;
4630- }
4631-
4632- return 1;
4633-}
4634-
4635-static struct dm_config_tree *_merge_config_files(struct cmd_context *cmd, struct dm_config_tree *cft)
4636-{
4637- struct config_tree_list *cfl;
4638-
4639- /* Replace temporary duplicate copy of lvm.conf */
4640- if (cft->root) {
4641- if (!(cft = config_file_open(NULL, 0))) {
4642- log_error("Failed to create config tree");
4643- return 0;
4644- }
4645- }
4646-
4647- dm_list_iterate_items(cfl, &cmd->config_files) {
4648- /* Merge all config trees into cmd->cft using merge/tag rules */
4649- if (!merge_config_tree(cmd, cft, cfl->cft))
4650- return_0;
4651- }
4652-
4653- return cft;
4654-}
4655-
4656-static void _destroy_tags(struct cmd_context *cmd)
4657-{
4658- struct dm_list *slh, *slht;
4659-
4660- dm_list_iterate_safe(slh, slht, &cmd->tags) {
4661- dm_list_del(slh);
4662- }
4663-}
4664-
4665-int config_files_changed(struct cmd_context *cmd)
4666-{
4667- struct config_tree_list *cfl;
4668-
4669- dm_list_iterate_items(cfl, &cmd->config_files) {
4670- if (config_file_changed(cfl->cft))
4671- return 1;
4672- }
4673-
4674- return 0;
4675-}
4676-
4677-/*
4678- * Returns cmdline config_tree that overrides all others, if present.
4679- */
4680-static struct dm_config_tree *_destroy_tag_configs(struct cmd_context *cmd)
4681-{
4682- struct config_tree_list *cfl;
4683- struct dm_config_tree *cft_cmdline = NULL, *cft;
4684-
4685- cft = dm_config_remove_cascaded_tree(cmd->cft);
4686- if (cft) {
4687- cft_cmdline = cmd->cft;
4688- cmd->cft = cft;
4689- }
4690-
4691- dm_list_iterate_items(cfl, &cmd->config_files) {
4692- if (cfl->cft == cmd->cft)
4693- cmd->cft = NULL;
4694- config_file_destroy(cfl->cft);
4695- }
4696-
4697- if (cmd->cft) {
4698- config_file_destroy(cmd->cft);
4699- cmd->cft = NULL;
4700- }
4701-
4702- dm_list_init(&cmd->config_files);
4703-
4704- return cft_cmdline;
4705-}
4706-
4707-static int _init_dev_cache(struct cmd_context *cmd)
4708-{
4709- const struct dm_config_node *cn;
4710- const struct dm_config_value *cv;
4711- size_t len, udev_dir_len = strlen(DM_UDEV_DEV_DIR);
4712- int len_diff;
4713- int device_list_from_udev;
4714-
4715- init_dev_disable_after_error_count(
4716- find_config_tree_int(cmd, "devices/disable_after_error_count",
4717- DEFAULT_DISABLE_AFTER_ERROR_COUNT));
4718-
4719- if (!dev_cache_init(cmd))
4720- return_0;
4721-
4722- device_list_from_udev = udev_is_running() ?
4723- find_config_tree_bool(cmd, "devices/obtain_device_list_from_udev",
4724- DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV) : 0;
4725- init_obtain_device_list_from_udev(device_list_from_udev);
4726-
4727- if (!(cn = find_config_tree_node(cmd, "devices/scan"))) {
4728- if (!dev_cache_add_dir("/dev")) {
4729- log_error("Failed to add /dev to internal "
4730- "device cache");
4731- return 0;
4732- }
4733- log_verbose("device/scan not in config file: "
4734- "Defaulting to /dev");
4735- return 1;
4736- }
4737-
4738- for (cv = cn->v; cv; cv = cv->next) {
4739- if (cv->type != DM_CFG_STRING) {
4740- log_error("Invalid string in config file: "
4741- "devices/scan");
4742- return 0;
4743- }
4744-
4745- if (device_list_from_udev) {
4746- len = strlen(cv->v.str);
4747-
4748- /*
4749- * DM_UDEV_DEV_DIR always has '/' at its end.
4750- * If the item in the conf does not have it, be sure
4751- * to make the right comparison without the '/' char!
4752- */
4753- len_diff = len && cv->v.str[len - 1] != '/' ?
4754- udev_dir_len - 1 != len :
4755- udev_dir_len != len;
4756-
4757- if (len_diff || strncmp(DM_UDEV_DEV_DIR, cv->v.str, len)) {
4758- device_list_from_udev = 0;
4759- init_obtain_device_list_from_udev(0);
4760- }
4761- }
4762-
4763- if (!dev_cache_add_dir(cv->v.str)) {
4764- log_error("Failed to add %s to internal device cache",
4765- cv->v.str);
4766- return 0;
4767- }
4768- }
4769-
4770- if (!(cn = find_config_tree_node(cmd, "devices/loopfiles")))
4771- return 1;
4772-
4773- for (cv = cn->v; cv; cv = cv->next) {
4774- if (cv->type != DM_CFG_STRING) {
4775- log_error("Invalid string in config file: "
4776- "devices/loopfiles");
4777- return 0;
4778- }
4779-
4780- if (!dev_cache_add_loopfile(cv->v.str)) {
4781- log_error("Failed to add loopfile %s to internal "
4782- "device cache", cv->v.str);
4783- return 0;
4784- }
4785- }
4786-
4787-
4788- return 1;
4789-}
4790-
4791-#define MAX_FILTERS 5
4792-
4793-static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
4794-{
4795- int nr_filt = 0;
4796- const struct dm_config_node *cn;
4797- struct dev_filter *filters[MAX_FILTERS] = { 0 };
4798- struct dev_filter *composite;
4799-
4800- /*
4801- * Filters listed in order: top one gets applied first.
4802- * Failure to initialise some filters is not fatal.
4803- * Update MAX_FILTERS definition above when adding new filters.
4804- */
4805-
4806- /*
4807- * sysfs filter. Only available on 2.6 kernels. Non-critical.
4808- * Listed first because it's very efficient at eliminating
4809- * unavailable devices.
4810- */
4811- if (find_config_tree_bool(cmd, "devices/sysfs_scan",
4812- DEFAULT_SYSFS_SCAN)) {
4813- if ((filters[nr_filt] = sysfs_filter_create(cmd->sysfs_dir)))
4814- nr_filt++;
4815- }
4816-
4817- /* regex filter. Optional. */
4818- if (!(cn = find_config_tree_node(cmd, "devices/filter")))
4819- log_very_verbose("devices/filter not found in config file: "
4820- "no regex filter installed");
4821-
4822- else if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
4823- log_error("Failed to create regex device filter");
4824- goto bad;
4825- } else
4826- nr_filt++;
4827-
4828- /* device type filter. Required. */
4829- cn = find_config_tree_node(cmd, "devices/types");
4830- if (!(filters[nr_filt] = lvm_type_filter_create(cmd->proc_dir, cn))) {
4831- log_error("Failed to create lvm type filter");
4832- goto bad;
4833- }
4834- nr_filt++;
4835-
4836- /* md component filter. Optional, non-critical. */
4837- if (find_config_tree_bool(cmd, "devices/md_component_detection",
4838- DEFAULT_MD_COMPONENT_DETECTION)) {
4839- init_md_filtering(1);
4840- if ((filters[nr_filt] = md_filter_create()))
4841- nr_filt++;
4842- }
4843-
4844- /* mpath component filter. Optional, non-critical. */
4845- if (find_config_tree_bool(cmd, "devices/multipath_component_detection",
4846- DEFAULT_MULTIPATH_COMPONENT_DETECTION)) {
4847- if ((filters[nr_filt] = mpath_filter_create(cmd->sysfs_dir)))
4848- nr_filt++;
4849- }
4850-
4851- /* Only build a composite filter if we really need it. */
4852- if (nr_filt == 1)
4853- return filters[0];
4854-
4855- if (!(composite = composite_filter_create(nr_filt, filters)))
4856- goto_bad;
4857-
4858- return composite;
4859-bad:
4860- while (--nr_filt >= 0)
4861- filters[nr_filt]->destroy(filters[nr_filt]);
4862-
4863- return NULL;
4864-}
4865-
4866-static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
4867-{
4868- static char cache_file[PATH_MAX];
4869- const char *dev_cache = NULL, *cache_dir, *cache_file_prefix;
4870- struct dev_filter *f3 = NULL, *f4 = NULL, *toplevel_components[2] = { 0 };
4871- struct stat st;
4872- const struct dm_config_node *cn;
4873-
4874- cmd->dump_filter = 0;
4875-
4876- if (!(f3 = _init_filter_components(cmd)))
4877- goto_bad;
4878-
4879- init_ignore_suspended_devices(find_config_tree_int(cmd,
4880- "devices/ignore_suspended_devices", DEFAULT_IGNORE_SUSPENDED_DEVICES));
4881-
4882- /*
4883- * If 'cache_dir' or 'cache_file_prefix' is set, ignore 'cache'.
4884- */
4885- cache_dir = find_config_tree_str(cmd, "devices/cache_dir", NULL);
4886- cache_file_prefix = find_config_tree_str(cmd, "devices/cache_file_prefix", NULL);
4887-
4888- if (cache_dir || cache_file_prefix) {
4889- if (dm_snprintf(cache_file, sizeof(cache_file),
4890- "%s%s%s/%s.cache",
4891- cache_dir ? "" : cmd->system_dir,
4892- cache_dir ? "" : "/",
4893- cache_dir ? : DEFAULT_CACHE_SUBDIR,
4894- cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) {
4895- log_error("Persistent cache filename too long.");
4896- goto bad;
4897- }
4898- } else if (!(dev_cache = find_config_tree_str(cmd, "devices/cache", NULL)) &&
4899- (dm_snprintf(cache_file, sizeof(cache_file),
4900- "%s/%s/%s.cache",
4901- cmd->system_dir, DEFAULT_CACHE_SUBDIR,
4902- DEFAULT_CACHE_FILE_PREFIX) < 0)) {
4903- log_error("Persistent cache filename too long.");
4904- goto bad;
4905- }
4906-
4907- if (!dev_cache)
4908- dev_cache = cache_file;
4909-
4910- if (!(f4 = persistent_filter_create(f3, dev_cache))) {
4911- log_verbose("Failed to create persistent device filter.");
4912- f3->destroy(f3);
4913- return_0;
4914- }
4915-
4916- /* Should we ever dump persistent filter state? */
4917- if (find_config_tree_int(cmd, "devices/write_cache_state", 1))
4918- cmd->dump_filter = 1;
4919-
4920- if (!*cmd->system_dir)
4921- cmd->dump_filter = 0;
4922-
4923- /*
4924- * Only load persistent filter device cache on startup if it is newer
4925- * than the config file and this is not a long-lived process.
4926- */
4927- if (load_persistent_cache && !cmd->is_long_lived &&
4928- !stat(dev_cache, &st) &&
4929- (st.st_ctime > config_file_timestamp(cmd->cft)) &&
4930- !persistent_filter_load(f4, NULL))
4931- log_verbose("Failed to load existing device cache from %s",
4932- dev_cache);
4933-
4934- if (!(cn = find_config_tree_node(cmd, "devices/global_filter"))) {
4935- cmd->filter = f4;
4936- } else if (!(cmd->lvmetad_filter = regex_filter_create(cn->v)))
4937- goto_bad;
4938- else {
4939- toplevel_components[0] = cmd->lvmetad_filter;
4940- toplevel_components[1] = f4;
4941- if (!(cmd->filter = composite_filter_create(2, toplevel_components)))
4942- goto_bad;
4943- }
4944-
4945- return 1;
4946-bad:
4947- if (f3)
4948- f3->destroy(f3);
4949- if (f4)
4950- f4->destroy(f4);
4951- if (toplevel_components[0])
4952- toplevel_components[0]->destroy(toplevel_components[0]);
4953- return 0;
4954-}
4955-
4956-struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format)
4957-{
4958- struct format_type *fmt;
4959-
4960- dm_list_iterate_items(fmt, &cmd->formats)
4961- if (!strcasecmp(fmt->name, format) ||
4962- !strcasecmp(fmt->name + 3, format) ||
4963- (fmt->alias && !strcasecmp(fmt->alias, format)))
4964- return fmt;
4965-
4966- return NULL;
4967-}
4968-
4969-static int _init_formats(struct cmd_context *cmd)
4970-{
4971- const char *format;
4972-
4973- struct format_type *fmt;
4974-
4975-#ifdef HAVE_LIBDL
4976- const struct dm_config_node *cn;
4977-#endif
4978-
4979-#ifdef LVM1_INTERNAL
4980- if (!(fmt = init_lvm1_format(cmd)))
4981- return 0;
4982- fmt->library = NULL;
4983- dm_list_add(&cmd->formats, &fmt->list);
4984-#endif
4985-
4986-#ifdef POOL_INTERNAL
4987- if (!(fmt = init_pool_format(cmd)))
4988- return 0;
4989- fmt->library = NULL;
4990- dm_list_add(&cmd->formats, &fmt->list);
4991-#endif
4992-
4993-#ifdef HAVE_LIBDL
4994- /* Load any formats in shared libs if not static */
4995- if (!is_static() &&
4996- (cn = find_config_tree_node(cmd, "global/format_libraries"))) {
4997-
4998- const struct dm_config_value *cv;
4999- struct format_type *(*init_format_fn) (struct cmd_context *);
5000- void *lib;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches