1 /*	$NetBSD: toolcontext.c,v 1.7 2009/12/05 01:52:44 haad Exp $	*/
2 
3 /*
4  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5  * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
6  *
7  * This file is part of LVM2.
8  *
9  * This copyrighted material is made available to anyone wishing to use,
10  * modify, copy, or redistribute it subject to the terms and conditions
11  * of the GNU Lesser General Public License v.2.1.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, write to the Free Software Foundation,
15  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17 
18 #include "lib.h"
19 #include "toolcontext.h"
20 #include "metadata.h"
21 #include "defaults.h"
22 #include "lvm-string.h"
23 #include "activate.h"
24 #include "filter.h"
25 #include "filter-composite.h"
26 #include "filter-md.h"
27 #include "filter-persistent.h"
28 #include "filter-regex.h"
29 #include "filter-sysfs.h"
30 #include "label.h"
31 #include "lvm-file.h"
32 #include "format-text.h"
33 #include "display.h"
34 #include "memlock.h"
35 #include "str_list.h"
36 #include "segtype.h"
37 #include "lvmcache.h"
38 #include "dev-cache.h"
39 #include "archiver.h"
40 
41 #ifdef HAVE_LIBDL
42 #include "sharedlib.h"
43 #endif
44 
45 #ifdef LVM1_INTERNAL
46 #include "format1.h"
47 #endif
48 
49 #ifdef POOL_INTERNAL
50 #include "format_pool.h"
51 #endif
52 
53 #include <locale.h>
54 #include <sys/stat.h>
55 #include <sys/utsname.h>
56 #include <syslog.h>
57 #include <time.h>
58 #include <unistd.h>
59 
60 #ifdef linux
61 #  include <malloc.h>
62 #endif
63 
64 static int _get_env_vars(struct cmd_context *cmd)
65 {
66 	const char *e;
67 
68 	/* Set to "" to avoid using any system directory */
69 	if ((e = getenv("LVM_SYSTEM_DIR"))) {
70 		if (dm_snprintf(cmd->system_dir, sizeof(cmd->system_dir),
71 				 "%s", e) < 0) {
72 			log_error("LVM_SYSTEM_DIR environment variable "
73 				  "is too long.");
74 			return 0;
75 		}
76 	}
77 
78 	return 1;
79 }
80 
81 static void _get_sysfs_dir(struct cmd_context *cmd)
82 {
83 	static char proc_mounts[PATH_MAX];
84 	static char *split[4], buffer[PATH_MAX + 16];
85 	FILE *fp;
86 	char *sys_mnt = NULL;
87 
88 	cmd->sysfs_dir[0] = '\0';
89 	if (!*cmd->proc_dir) {
90 		log_debug("No proc filesystem found: skipping sysfs detection");
91 		return;
92 	}
93 
94 	if (dm_snprintf(proc_mounts, sizeof(proc_mounts),
95 			 "%s/mounts", cmd->proc_dir) < 0) {
96 		log_error("Failed to create /proc/mounts string for sysfs detection");
97 		return;
98 	}
99 
100 	if (!(fp = fopen(proc_mounts, "r"))) {
101 		log_sys_error("_get_sysfs_dir: fopen %s", proc_mounts);
102 		return;
103 	}
104 
105 	while (fgets(buffer, sizeof(buffer), fp)) {
106 		if (dm_split_words(buffer, 4, 0, split) == 4 &&
107 		    !strcmp(split[2], "sysfs")) {
108 			sys_mnt = split[1];
109 			break;
110 		}
111 	}
112 
113 	if (fclose(fp))
114 		log_sys_error("fclose", proc_mounts);
115 
116 	if (!sys_mnt) {
117 		log_error("Failed to find sysfs mount point");
118 		return;
119 	}
120 
121 	strncpy(cmd->sysfs_dir, sys_mnt, sizeof(cmd->sysfs_dir));
122 }
123 
124 static void _init_logging(struct cmd_context *cmd)
125 {
126 	int append = 1;
127 	time_t t;
128 
129 	const char *log_file;
130 	char timebuf[26];
131 
132 	/* Syslog */
133 	cmd->default_settings.syslog =
134 	    find_config_tree_int(cmd, "log/syslog", DEFAULT_SYSLOG);
135 	if (cmd->default_settings.syslog != 1)
136 		fin_syslog();
137 
138 	if (cmd->default_settings.syslog > 1)
139 		init_syslog(cmd->default_settings.syslog);
140 
141 	/* Debug level for log file output */
142 	cmd->default_settings.debug =
143 	    find_config_tree_int(cmd, "log/level", DEFAULT_LOGLEVEL);
144 	init_debug(cmd->default_settings.debug);
145 
146 	/* Verbose level for tty output */
147 	cmd->default_settings.verbose =
148 	    find_config_tree_int(cmd, "log/verbose", DEFAULT_VERBOSE);
149 	init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL);
150 
151 	/* Log message formatting */
152 	init_indent(find_config_tree_int(cmd, "log/indent",
153 				    DEFAULT_INDENT));
154 
155 	cmd->default_settings.msg_prefix = find_config_tree_str(cmd,
156 							   "log/prefix",
157 							   DEFAULT_MSG_PREFIX);
158 	init_msg_prefix(cmd->default_settings.msg_prefix);
159 
160 	cmd->default_settings.cmd_name = find_config_tree_int(cmd,
161 							 "log/command_names",
162 							 DEFAULT_CMD_NAME);
163 	init_cmd_name(cmd->default_settings.cmd_name);
164 
165 	/* Test mode */
166 	cmd->default_settings.test =
167 	    find_config_tree_int(cmd, "global/test", 0);
168 	init_test(cmd->default_settings.test);
169 
170 	/* Settings for logging to file */
171 	if (find_config_tree_int(cmd, "log/overwrite", DEFAULT_OVERWRITE))
172 		append = 0;
173 
174 	log_file = find_config_tree_str(cmd, "log/file", 0);
175 
176 	if (log_file) {
177 		release_log_memory();
178 		fin_log();
179 		init_log_file(log_file, append);
180 	}
181 
182 	log_file = find_config_tree_str(cmd, "log/activate_file", 0);
183 	if (log_file)
184 		init_log_direct(log_file, append);
185 
186 	init_log_while_suspended(find_config_tree_int(cmd,
187 						 "log/activation", 0));
188 
189 	t = time(NULL);
190 	ctime_r(&t, &timebuf[0]);
191 	timebuf[24] = '\0';
192 	log_verbose("Logging initialised at %s", timebuf);
193 
194 	/* Tell device-mapper about our logging */
195 #ifdef DEVMAPPER_SUPPORT
196 	dm_log_with_errno_init(print_log);
197 #endif
198 }
199 
200 static int _process_config(struct cmd_context *cmd)
201 {
202 	mode_t old_umask;
203 	const char *read_ahead;
204 	struct stat st;
205 
206 	/* umask */
207 	cmd->default_settings.umask = find_config_tree_int(cmd,
208 						      "global/umask",
209 						      DEFAULT_UMASK);
210 
211 	if ((old_umask = umask((mode_t) cmd->default_settings.umask)) !=
212 	    (mode_t) cmd->default_settings.umask)
213 		log_verbose("Set umask to %04o", cmd->default_settings.umask);
214 
215 	/* dev dir */
216 	if (dm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/",
217 			 find_config_tree_str(cmd, "devices/dir",
218 					 DEFAULT_DEV_DIR)) < 0) {
219 		log_error("Device directory given in config file too long");
220 		return 0;
221 	}
222 #ifdef DEVMAPPER_SUPPORT
223 	dm_set_dev_dir(cmd->dev_dir);
224 #endif
225 #if !defined(__NetBSD__) && !defined(__DragonFly__)
226 	/* proc dir */
227 	if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
228 			 find_config_tree_str(cmd, "global/proc",
229 					 DEFAULT_PROC_DIR)) < 0) {
230 		log_error("Device directory given in config file too long");
231 		return 0;
232 	}
233 #endif
234 	if (*cmd->proc_dir && !dir_exists(cmd->proc_dir)) {
235 		log_error("WARNING: proc dir %s not found - some checks will be bypassed",
236 			  cmd->proc_dir);
237 		*cmd->proc_dir = '\0';
238 	}
239 
240 	_get_sysfs_dir(cmd);
241 
242 	/* activation? */
243 	cmd->default_settings.activation = find_config_tree_int(cmd,
244 							   "global/activation",
245 							   DEFAULT_ACTIVATION);
246 	set_activation(cmd->default_settings.activation);
247 
248 	cmd->default_settings.suffix = find_config_tree_int(cmd,
249 						       "global/suffix",
250 						       DEFAULT_SUFFIX);
251 
252 	if (!(cmd->default_settings.unit_factor =
253 	      units_to_bytes(find_config_tree_str(cmd,
254 					     "global/units",
255 					     DEFAULT_UNITS),
256 			     &cmd->default_settings.unit_type))) {
257 		log_error("Invalid units specification");
258 		return 0;
259 	}
260 
261 	read_ahead = find_config_tree_str(cmd, "activation/readahead", DEFAULT_READ_AHEAD);
262 	if (!strcasecmp(read_ahead, "auto"))
263 		cmd->default_settings.read_ahead = DM_READ_AHEAD_AUTO;
264 	else if (!strcasecmp(read_ahead, "none"))
265 		cmd->default_settings.read_ahead = DM_READ_AHEAD_NONE;
266 	else {
267 		log_error("Invalid readahead specification");
268 		return 0;
269 	}
270 
271 	cmd->default_settings.udev_sync = find_config_tree_int(cmd,
272 								"activation/udev_sync",
273 								DEFAULT_UDEV_SYNC);
274 
275 	cmd->stripe_filler = find_config_tree_str(cmd,
276 						  "activation/missing_stripe_filler",
277 						  DEFAULT_STRIPE_FILLER);
278 
279 	/* 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)? */
280 	if (!strcmp(cmd->stripe_filler, "/dev/ioerror") &&
281 	    stat(cmd->stripe_filler, &st))
282 		cmd->stripe_filler = "error";
283 
284 	if (strcmp(cmd->stripe_filler, "error")) {
285 		if (stat(cmd->stripe_filler, &st)) {
286 			log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
287 				 "is invalid,", cmd->stripe_filler);
288 			log_warn("         stat failed: %s", strerror(errno));
289 			log_warn("Falling back to \"error\" missing_stripe_filler.");
290 			cmd->stripe_filler = "error";
291 		} else if (!S_ISBLK(st.st_mode)) {
292 			log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
293 				 "is not a block device.", cmd->stripe_filler);
294 			log_warn("Falling back to \"error\" missing_stripe_filler.");
295 			cmd->stripe_filler = "error";
296 		}
297 	}
298 
299 	cmd->si_unit_consistency = find_config_tree_int(cmd,
300 						  "global/si_unit_consistency",
301 						  DEFAULT_SI_UNIT_CONSISTENCY);
302 
303 	return 1;
304 }
305 
306 static int _set_tag(struct cmd_context *cmd, const char *tag)
307 {
308 	log_very_verbose("Setting host tag: %s", dm_pool_strdup(cmd->libmem, tag));
309 
310 	if (!str_list_add(cmd->libmem, &cmd->tags, tag)) {
311 		log_error("_set_tag: str_list_add %s failed", tag);
312 		return 0;
313 	}
314 
315 	return 1;
316 }
317 
318 static int _check_host_filters(struct cmd_context *cmd, struct config_node *hn,
319 			       int *passes)
320 {
321 	struct config_node *cn;
322 	struct config_value *cv;
323 
324 	*passes = 1;
325 
326 	for (cn = hn; cn; cn = cn->sib) {
327 		if (!cn->v)
328 			continue;
329 		if (!strcmp(cn->key, "host_list")) {
330 			*passes = 0;
331 			if (cn->v->type == CFG_EMPTY_ARRAY)
332 				continue;
333 			for (cv = cn->v; cv; cv = cv->next) {
334 				if (cv->type != CFG_STRING) {
335 					log_error("Invalid hostname string "
336 						  "for tag %s", cn->key);
337 					return 0;
338 				}
339 				if (!strcmp(cv->v.str, cmd->hostname)) {
340 					*passes = 1;
341 					return 1;
342 				}
343 			}
344 		}
345 		if (!strcmp(cn->key, "host_filter")) {
346 			log_error("host_filter not supported yet");
347 			return 0;
348 		}
349 	}
350 
351 	return 1;
352 }
353 
354 static int _init_tags(struct cmd_context *cmd, struct config_tree *cft)
355 {
356 	const struct config_node *tn, *cn;
357 	const char *tag;
358 	int passes;
359 
360 	if (!(tn = find_config_node(cft->root, "tags")) || !tn->child)
361 		return 1;
362 
363 	/* NB hosttags 0 when already 1 intentionally does not delete the tag */
364 	if (!cmd->hosttags && find_config_int(cft->root, "tags/hosttags",
365 					      DEFAULT_HOSTTAGS)) {
366 		/* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
367 		if (!_set_tag(cmd, cmd->hostname))
368 			return_0;
369 		cmd->hosttags = 1;
370 	}
371 
372 	for (cn = tn->child; cn; cn = cn->sib) {
373 		if (cn->v)
374 			continue;
375 		tag = cn->key;
376 		if (*tag == '@')
377 			tag++;
378 		if (!validate_name(tag)) {
379 			log_error("Invalid tag in config file: %s", cn->key);
380 			return 0;
381 		}
382 		if (cn->child) {
383 			passes = 0;
384 			if (!_check_host_filters(cmd, cn->child, &passes))
385 				return_0;
386 			if (!passes)
387 				continue;
388 		}
389 		if (!_set_tag(cmd, tag))
390 			return_0;
391 	}
392 
393 	return 1;
394 }
395 
396 static int _load_config_file(struct cmd_context *cmd, const char *tag)
397 {
398 	char config_file[PATH_MAX] = "";
399 	const char *filler = "";
400 	struct stat info;
401 	struct config_tree_list *cfl;
402 
403 	if (*tag)
404 		filler = "_";
405 
406 	if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
407 			 cmd->system_dir, filler, tag) < 0) {
408 		log_error("LVM_SYSTEM_DIR or tag was too long");
409 		return 0;
410 	}
411 
412 	if (!(cfl = dm_pool_alloc(cmd->libmem, sizeof(*cfl)))) {
413 		log_error("config_tree_list allocation failed");
414 		return 0;
415 	}
416 
417 	if (!(cfl->cft = create_config_tree(config_file, 0))) {
418 		log_error("config_tree allocation failed");
419 		return 0;
420 	}
421 
422 	/* Is there a config file? */
423 	if (stat(config_file, &info) == -1) {
424 		if (errno == ENOENT) {
425 			dm_list_add(&cmd->config_files, &cfl->list);
426 			goto out;
427 		}
428 		log_sys_error("stat", config_file);
429 		destroy_config_tree(cfl->cft);
430 		return 0;
431 	}
432 
433 	log_very_verbose("Loading config file: %s", config_file);
434 	if (!read_config_file(cfl->cft)) {
435 		log_error("Failed to load config file %s", config_file);
436 		destroy_config_tree(cfl->cft);
437 		return 0;
438 	}
439 
440 	dm_list_add(&cmd->config_files, &cfl->list);
441 
442       out:
443 	if (*tag)
444 		_init_tags(cmd, cfl->cft);
445 	else
446 		/* Use temporary copy of lvm.conf while loading other files */
447 		cmd->cft = cfl->cft;
448 
449 	return 1;
450 }
451 
452 /* Find and read first config file */
453 static int _init_lvm_conf(struct cmd_context *cmd)
454 {
455 	/* No config file if LVM_SYSTEM_DIR is empty */
456 	if (!*cmd->system_dir) {
457 		if (!(cmd->cft = create_config_tree(NULL, 0))) {
458 			log_error("Failed to create config tree");
459 			return 0;
460 		}
461 		return 1;
462 	}
463 
464 	if (!_load_config_file(cmd, ""))
465 		return_0;
466 
467 	return 1;
468 }
469 
470 /* Read any additional config files */
471 static int _init_tag_configs(struct cmd_context *cmd)
472 {
473 	struct str_list *sl;
474 
475 	/* Tag list may grow while inside this loop */
476 	dm_list_iterate_items(sl, &cmd->tags) {
477 		if (!_load_config_file(cmd, sl->str))
478 			return_0;
479 	}
480 
481 	return 1;
482 }
483 
484 static int _merge_config_files(struct cmd_context *cmd)
485 {
486 	struct config_tree_list *cfl;
487 
488 	/* Replace temporary duplicate copy of lvm.conf */
489 	if (cmd->cft->root) {
490 		if (!(cmd->cft = create_config_tree(NULL, 0))) {
491 			log_error("Failed to create config tree");
492 			return 0;
493 		}
494 	}
495 
496 	dm_list_iterate_items(cfl, &cmd->config_files) {
497 		/* Merge all config trees into cmd->cft using merge/tag rules */
498 		if (!merge_config_tree(cmd, cmd->cft, cfl->cft))
499 			return_0;
500 	}
501 
502 	return 1;
503 }
504 
505 static void _destroy_tags(struct cmd_context *cmd)
506 {
507 	struct dm_list *slh, *slht;
508 
509 	dm_list_iterate_safe(slh, slht, &cmd->tags) {
510 		dm_list_del(slh);
511 	}
512 }
513 
514 int config_files_changed(struct cmd_context *cmd)
515 {
516 	struct config_tree_list *cfl;
517 
518 	dm_list_iterate_items(cfl, &cmd->config_files) {
519 		if (config_file_changed(cfl->cft))
520 			return 1;
521 	}
522 
523 	return 0;
524 }
525 
526 static void _destroy_tag_configs(struct cmd_context *cmd)
527 {
528 	struct config_tree_list *cfl;
529 
530 	dm_list_iterate_items(cfl, &cmd->config_files) {
531 		if (cfl->cft == cmd->cft)
532 			cmd->cft = NULL;
533 		destroy_config_tree(cfl->cft);
534 	}
535 
536 	if (cmd->cft) {
537 		destroy_config_tree(cmd->cft);
538 		cmd->cft = NULL;
539 	}
540 
541 	dm_list_init(&cmd->config_files);
542 }
543 
544 static int _init_dev_cache(struct cmd_context *cmd)
545 {
546 	const struct config_node *cn;
547 	struct config_value *cv;
548 
549 	if (!dev_cache_init(cmd))
550 		return_0;
551 
552 	if (!(cn = find_config_tree_node(cmd, "devices/scan"))) {
553 		if (!dev_cache_add_dir("/dev")) {
554 			log_error("Failed to add /dev to internal "
555 				  "device cache");
556 			return 0;
557 		}
558 		log_verbose("device/scan not in config file: "
559 			    "Defaulting to /dev");
560 		return 1;
561 	}
562 
563 	for (cv = cn->v; cv; cv = cv->next) {
564 		if (cv->type != CFG_STRING) {
565 			log_error("Invalid string in config file: "
566 				  "devices/scan");
567 			return 0;
568 		}
569 
570 		if (!dev_cache_add_dir(cv->v.str)) {
571 			log_error("Failed to add %s to internal device cache",
572 				  cv->v.str);
573 			return 0;
574 		}
575 	}
576 
577 	if (!(cn = find_config_tree_node(cmd, "devices/loopfiles")))
578 		return 1;
579 
580 	for (cv = cn->v; cv; cv = cv->next) {
581 		if (cv->type != CFG_STRING) {
582 			log_error("Invalid string in config file: "
583 				  "devices/loopfiles");
584 			return 0;
585 		}
586 
587 		if (!dev_cache_add_loopfile(cv->v.str)) {
588 			log_error("Failed to add loopfile %s to internal "
589 				  "device cache", cv->v.str);
590 			return 0;
591 		}
592 	}
593 
594 
595 	return 1;
596 }
597 
598 #define MAX_FILTERS 4
599 
600 static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
601 {
602 	unsigned nr_filt = 0;
603 	const struct config_node *cn;
604 	struct dev_filter *filters[MAX_FILTERS];
605 
606 	memset(filters, 0, sizeof(filters));
607 
608 	/*
609 	 * Filters listed in order: top one gets applied first.
610 	 * Failure to initialise some filters is not fatal.
611 	 * Update MAX_FILTERS definition above when adding new filters.
612 	 */
613 
614 	/*
615 	 * sysfs filter. Only available on 2.6 kernels.  Non-critical.
616 	 * Listed first because it's very efficient at eliminating
617 	 * unavailable devices.
618 	 */
619 	if (find_config_tree_bool(cmd, "devices/sysfs_scan",
620 			     DEFAULT_SYSFS_SCAN)) {
621 		if ((filters[nr_filt] = sysfs_filter_create(cmd->sysfs_dir)))
622 			nr_filt++;
623 	}
624 
625 	/* regex filter. Optional. */
626 	if (!(cn = find_config_tree_node(cmd, "devices/filter")))
627 		log_very_verbose("devices/filter not found in config file: "
628 				 "no regex filter installed");
629 
630 	else if (!(filters[nr_filt++] = regex_filter_create(cn->v))) {
631 		log_error("Failed to create regex device filter");
632 		return NULL;
633 	}
634 
635 	/* device type filter. Required. */
636 	cn = find_config_tree_node(cmd, "devices/types");
637 	if (!(filters[nr_filt++] = lvm_type_filter_create(cmd->proc_dir, cn))) {
638 		log_error("Failed to create lvm type filter");
639 		return NULL;
640 	}
641 
642 	/* md component filter. Optional, non-critical. */
643 	if (find_config_tree_bool(cmd, "devices/md_component_detection",
644 			     DEFAULT_MD_COMPONENT_DETECTION)) {
645 		init_md_filtering(1);
646 		if ((filters[nr_filt] = md_filter_create()))
647 			nr_filt++;
648 	}
649 
650 	/* Only build a composite filter if we really need it. */
651 	return (nr_filt == 1) ?
652 	    filters[0] : composite_filter_create(nr_filt, filters);
653 }
654 
655 static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
656 {
657 	const char *dev_cache = NULL, *cache_dir, *cache_file_prefix;
658 	struct dev_filter *f3, *f4;
659 	struct stat st;
660 	char cache_file[PATH_MAX];
661 
662 	cmd->dump_filter = 0;
663 
664 	if (!(f3 = _init_filter_components(cmd)))
665 		return 0;
666 
667 	init_ignore_suspended_devices(find_config_tree_int(cmd,
668 	    "devices/ignore_suspended_devices", DEFAULT_IGNORE_SUSPENDED_DEVICES));
669 
670 	/*
671 	 * If 'cache_dir' or 'cache_file_prefix' is set, ignore 'cache'.
672 	 */
673 	cache_dir = find_config_tree_str(cmd, "devices/cache_dir", NULL);
674 	cache_file_prefix = find_config_tree_str(cmd, "devices/cache_file_prefix", NULL);
675 
676 	if (cache_dir || cache_file_prefix) {
677 		if (dm_snprintf(cache_file, sizeof(cache_file),
678 		    "%s%s%s/%s.cache",
679 		    cache_dir ? "" : cmd->system_dir,
680 		    cache_dir ? "" : "/",
681 		    cache_dir ? : DEFAULT_CACHE_SUBDIR,
682 		    cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) {
683 			log_error("Persistent cache filename too long.");
684 			return 0;
685 		}
686 	} else if (!(dev_cache = find_config_tree_str(cmd, "devices/cache", NULL)) &&
687 		   (dm_snprintf(cache_file, sizeof(cache_file),
688 				"%s/%s/%s.cache",
689 				cmd->system_dir, DEFAULT_CACHE_SUBDIR,
690 				DEFAULT_CACHE_FILE_PREFIX) < 0)) {
691 		log_error("Persistent cache filename too long.");
692 		return 0;
693 	}
694 
695 	if (!dev_cache)
696 		dev_cache = cache_file;
697 
698 	if (!(f4 = persistent_filter_create(f3, dev_cache))) {
699 		log_error("Failed to create persistent device filter");
700 		return 0;
701 	}
702 
703 	/* Should we ever dump persistent filter state? */
704 	if (find_config_tree_int(cmd, "devices/write_cache_state", 1))
705 		cmd->dump_filter = 1;
706 
707 	if (!*cmd->system_dir)
708 		cmd->dump_filter = 0;
709 
710 	/*
711 	 * Only load persistent filter device cache on startup if it is newer
712 	 * than the config file and this is not a long-lived process.
713 	 */
714 	if (load_persistent_cache && !cmd->is_long_lived &&
715 	    !stat(dev_cache, &st) &&
716 	    (st.st_ctime > config_file_timestamp(cmd->cft)) &&
717 	    !persistent_filter_load(f4, NULL))
718 		log_verbose("Failed to load existing device cache from %s",
719 			    dev_cache);
720 
721 	cmd->filter = f4;
722 
723 	return 1;
724 }
725 
726 static int _init_formats(struct cmd_context *cmd)
727 {
728 	const char *format;
729 
730 	struct format_type *fmt;
731 
732 #ifdef HAVE_LIBDL
733 	const struct config_node *cn;
734 #endif
735 
736 	label_init();
737 
738 #ifdef LVM1_INTERNAL
739 	if (!(fmt = init_lvm1_format(cmd)))
740 		return 0;
741 	fmt->library = NULL;
742 	dm_list_add(&cmd->formats, &fmt->list);
743 #endif
744 
745 #ifdef POOL_INTERNAL
746 	if (!(fmt = init_pool_format(cmd)))
747 		return 0;
748 	fmt->library = NULL;
749 	dm_list_add(&cmd->formats, &fmt->list);
750 #endif
751 
752 #ifdef HAVE_LIBDL
753 	/* Load any formats in shared libs if not static */
754 	if (!is_static() &&
755 	    (cn = find_config_tree_node(cmd, "global/format_libraries"))) {
756 
757 		struct config_value *cv;
758 		struct format_type *(*init_format_fn) (struct cmd_context *);
759 		void *lib;
760 
761 		for (cv = cn->v; cv; cv = cv->next) {
762 			if (cv->type != CFG_STRING) {
763 				log_error("Invalid string in config file: "
764 					  "global/format_libraries");
765 				return 0;
766 			}
767 			if (!(lib = load_shared_library(cmd, cv->v.str,
768 							"format", 0)))
769 				return_0;
770 
771 			if (!(init_format_fn = dlsym(lib, "init_format"))) {
772 				log_error("Shared library %s does not contain "
773 					  "format functions", cv->v.str);
774 				dlclose(lib);
775 				return 0;
776 			}
777 
778 			if (!(fmt = init_format_fn(cmd)))
779 				return 0;
780 			fmt->library = lib;
781 			dm_list_add(&cmd->formats, &fmt->list);
782 		}
783 	}
784 #endif
785 
786 	if (!(fmt = create_text_format(cmd)))
787 		return 0;
788 	fmt->library = NULL;
789 	dm_list_add(&cmd->formats, &fmt->list);
790 
791 	cmd->fmt_backup = fmt;
792 
793 	format = find_config_tree_str(cmd, "global/format",
794 				 DEFAULT_FORMAT);
795 
796 	dm_list_iterate_items(fmt, &cmd->formats) {
797 		if (!strcasecmp(fmt->name, format) ||
798 		    (fmt->alias && !strcasecmp(fmt->alias, format))) {
799 			cmd->default_settings.fmt = fmt;
800 			cmd->fmt = cmd->default_settings.fmt;
801 			return 1;
802 		}
803 	}
804 
805 	log_error("_init_formats: Default format (%s) not found", format);
806 	return 0;
807 }
808 
809 int init_lvmcache_orphans(struct cmd_context *cmd)
810 {
811 	struct format_type *fmt;
812 
813 	dm_list_iterate_items(fmt, &cmd->formats)
814 		if (!lvmcache_add_orphan_vginfo(fmt->orphan_vg_name, fmt))
815 			return_0;
816 
817 	return 1;
818 }
819 
820 struct segtype_library {
821 	struct cmd_context *cmd;
822 	void *lib;
823 	const char *libname;
824 };
825 
826 int lvm_register_segtype(struct segtype_library *seglib,
827 			 struct segment_type *segtype)
828 {
829 	struct segment_type *segtype2;
830 
831 	segtype->library = seglib->lib;
832 	segtype->cmd = seglib->cmd;
833 
834 	dm_list_iterate_items(segtype2, &seglib->cmd->segtypes) {
835 		if (strcmp(segtype2->name, segtype->name))
836 			continue;
837 		log_error("Duplicate segment type %s: "
838 			  "unloading shared library %s",
839 			  segtype->name, seglib->libname);
840 		segtype->ops->destroy(segtype);
841 		return 0;
842 	}
843 
844 	dm_list_add(&seglib->cmd->segtypes, &segtype->list);
845 
846 	return 1;
847 }
848 
849 #if defined(__NetBSD__) || defined(__DragonFly__)
850 #include <dlfcn.h>
851 #endif
852 
853 static int _init_single_segtype(struct cmd_context *cmd,
854 				struct segtype_library *seglib)
855 {
856 	struct segment_type *(*init_segtype_fn) (struct cmd_context *);
857 	struct segment_type *segtype;
858 
859 	if (!(init_segtype_fn = dlsym(seglib->lib, "init_segtype"))) {
860 		log_error("Shared library %s does not contain segment type "
861 			  "functions", seglib->libname);
862 		return 0;
863 	}
864 
865 	if (!(segtype = init_segtype_fn(seglib->cmd)))
866 		return_0;
867 
868 	return lvm_register_segtype(seglib, segtype);
869 }
870 
871 static int _init_segtypes(struct cmd_context *cmd)
872 {
873 	struct segment_type *segtype;
874 	struct segtype_library seglib = { .cmd = cmd };
875 
876 #ifdef HAVE_LIBDL
877 	const struct config_node *cn;
878 #endif
879 
880 	if (!(segtype = init_striped_segtype(cmd)))
881 		return 0;
882 	segtype->library = NULL;
883 	dm_list_add(&cmd->segtypes, &segtype->list);
884 
885 	if (!(segtype = init_zero_segtype(cmd)))
886 		return 0;
887 	segtype->library = NULL;
888 	dm_list_add(&cmd->segtypes, &segtype->list);
889 
890 	if (!(segtype = init_error_segtype(cmd)))
891 		return 0;
892 	segtype->library = NULL;
893 	dm_list_add(&cmd->segtypes, &segtype->list);
894 
895 	if (!(segtype = init_free_segtype(cmd)))
896 		return 0;
897 	segtype->library = NULL;
898 	dm_list_add(&cmd->segtypes, &segtype->list);
899 
900 #ifdef SNAPSHOT_INTERNAL
901 	if (!(segtype = init_snapshot_segtype(cmd)))
902 		return 0;
903 	segtype->library = NULL;
904 	dm_list_add(&cmd->segtypes, &segtype->list);
905 #endif
906 
907 #ifdef MIRRORED_INTERNAL
908 	if (!(segtype = init_mirrored_segtype(cmd)))
909 		return 0;
910 	segtype->library = NULL;
911 	dm_list_add(&cmd->segtypes, &segtype->list);
912 #endif
913 
914 #ifdef HAVE_LIBDL
915 	/* Load any formats in shared libs unless static */
916 	if (!is_static() &&
917 	    (cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
918 
919 		struct config_value *cv;
920 		int (*init_multiple_segtypes_fn) (struct cmd_context *,
921 						  struct segtype_library *);
922 
923 		for (cv = cn->v; cv; cv = cv->next) {
924 			if (cv->type != CFG_STRING) {
925 				log_error("Invalid string in config file: "
926 					  "global/segment_libraries");
927 				return 0;
928 			}
929 			seglib.libname = cv->v.str;
930 			if (!(seglib.lib = load_shared_library(cmd,
931 							seglib.libname,
932 							"segment type", 0)))
933 				return_0;
934 
935 			if ((init_multiple_segtypes_fn =
936 			    dlsym(seglib.lib, "init_multiple_segtypes"))) {
937 				if (dlsym(seglib.lib, "init_segtype"))
938 					log_warn("WARNING: Shared lib %s has "
939 						 "conflicting init fns.  Using"
940 						 " init_multiple_segtypes().",
941 						 seglib.libname);
942 			} else
943 				init_multiple_segtypes_fn =
944 				    _init_single_segtype;
945 
946 			if (!init_multiple_segtypes_fn(cmd, &seglib)) {
947 				struct dm_list *sgtl, *tmp;
948 				log_error("init_multiple_segtypes() failed: "
949 					  "Unloading shared library %s",
950 					  seglib.libname);
951 				dm_list_iterate_safe(sgtl, tmp, &cmd->segtypes) {
952 					segtype = dm_list_item(sgtl, struct segment_type);
953 					if (segtype->library == seglib.lib) {
954 						dm_list_del(&segtype->list);
955 						segtype->ops->destroy(segtype);
956 					}
957 				}
958 				dlclose(seglib.lib);
959 				return_0;
960 			}
961 		}
962 	}
963 #endif
964 
965 	return 1;
966 }
967 
968 static int _init_hostname(struct cmd_context *cmd)
969 {
970 	struct utsname uts;
971 
972 	if (uname(&uts)) {
973 		log_sys_error("uname", "_init_hostname");
974 		return 0;
975 	}
976 
977 	if (!(cmd->hostname = dm_pool_strdup(cmd->libmem, uts.nodename))) {
978 		log_error("_init_hostname: dm_pool_strdup failed");
979 		return 0;
980 	}
981 
982 	if (!(cmd->kernel_vsn = dm_pool_strdup(cmd->libmem, uts.release))) {
983 		log_error("_init_hostname: dm_pool_strdup kernel_vsn failed");
984 		return 0;
985 	}
986 
987 	return 1;
988 }
989 
990 static int _init_backup(struct cmd_context *cmd)
991 {
992 	uint32_t days, min;
993 	char default_dir[PATH_MAX];
994 	const char *dir;
995 
996 	if (!cmd->system_dir) {
997 		log_warn("WARNING: Metadata changes will NOT be backed up");
998 		backup_init(cmd, "", 0);
999 		archive_init(cmd, "", 0, 0, 0);
1000 		return 1;
1001 	}
1002 
1003 	/* set up archiving */
1004 	cmd->default_settings.archive =
1005 	    find_config_tree_bool(cmd, "backup/archive",
1006 			     DEFAULT_ARCHIVE_ENABLED);
1007 
1008 	days = (uint32_t) find_config_tree_int(cmd, "backup/retain_days",
1009 					  DEFAULT_ARCHIVE_DAYS);
1010 
1011 	min = (uint32_t) find_config_tree_int(cmd, "backup/retain_min",
1012 					 DEFAULT_ARCHIVE_NUMBER);
1013 
1014 	if (dm_snprintf
1015 	    (default_dir, sizeof(default_dir), "%s/%s", cmd->system_dir,
1016 	     DEFAULT_ARCHIVE_SUBDIR) == -1) {
1017 		log_error("Couldn't create default archive path '%s/%s'.",
1018 			  cmd->system_dir, DEFAULT_ARCHIVE_SUBDIR);
1019 		return 0;
1020 	}
1021 
1022 	dir = find_config_tree_str(cmd, "backup/archive_dir",
1023 			      default_dir);
1024 
1025 	if (!archive_init(cmd, dir, days, min,
1026 			  cmd->default_settings.archive)) {
1027 		log_debug("archive_init failed.");
1028 		return 0;
1029 	}
1030 
1031 	/* set up the backup */
1032 	cmd->default_settings.backup =
1033 	    find_config_tree_bool(cmd, "backup/backup",
1034 			     DEFAULT_BACKUP_ENABLED);
1035 
1036 	if (dm_snprintf
1037 	    (default_dir, sizeof(default_dir), "%s/%s", cmd->system_dir,
1038 	     DEFAULT_BACKUP_SUBDIR) == -1) {
1039 		log_error("Couldn't create default backup path '%s/%s'.",
1040 			  cmd->system_dir, DEFAULT_BACKUP_SUBDIR);
1041 		return 0;
1042 	}
1043 
1044 	dir = find_config_tree_str(cmd, "backup/backup_dir", default_dir);
1045 
1046 	if (!backup_init(cmd, dir, cmd->default_settings.backup)) {
1047 		log_debug("backup_init failed.");
1048 		return 0;
1049 	}
1050 
1051 	return 1;
1052 }
1053 
1054 static void _init_rand(struct cmd_context *cmd)
1055 {
1056 	if (read_urandom(&cmd->rand_seed, sizeof(cmd->rand_seed)))
1057 		return;
1058 
1059 	cmd->rand_seed = (unsigned) time(NULL) + (unsigned) getpid();
1060 }
1061 
1062 static void _init_globals(struct cmd_context *cmd)
1063 {
1064 	init_full_scan_done(0);
1065 	init_mirror_in_sync(0);
1066 
1067 }
1068 
1069 /* Entry point */
1070 struct cmd_context *create_toolcontext(unsigned is_long_lived,
1071 				       const char *system_dir)
1072 {
1073 	struct cmd_context *cmd;
1074 
1075 #ifdef M_MMAP_MAX
1076 	mallopt(M_MMAP_MAX, 0);
1077 #endif
1078 
1079 	if (!setlocale(LC_ALL, ""))
1080 		log_very_verbose("setlocale failed");
1081 
1082 #ifdef INTL_PACKAGE
1083 	bindtextdomain(INTL_PACKAGE, LOCALEDIR);
1084 #endif
1085 
1086 	init_syslog(DEFAULT_LOG_FACILITY);
1087 
1088 	if (!(cmd = dm_malloc(sizeof(*cmd)))) {
1089 		log_error("Failed to allocate command context");
1090 		return NULL;
1091 	}
1092 	memset(cmd, 0, sizeof(*cmd));
1093 	cmd->is_long_lived = is_long_lived;
1094 	cmd->handles_missing_pvs = 0;
1095 	cmd->handles_unknown_segments = 0;
1096 	cmd->hosttags = 0;
1097 	dm_list_init(&cmd->formats);
1098 	dm_list_init(&cmd->segtypes);
1099 	dm_list_init(&cmd->tags);
1100 	dm_list_init(&cmd->config_files);
1101 
1102 	/* FIXME Make this configurable? */
1103 	reset_lvm_errno(1);
1104 
1105 	/*
1106 	 * Environment variable LVM_SYSTEM_DIR overrides this below.
1107 	 */
1108         if (system_dir)
1109 		strncpy(cmd->system_dir, system_dir, sizeof(cmd->system_dir) - 1);
1110 	else
1111 		strcpy(cmd->system_dir, DEFAULT_SYS_DIR);
1112 
1113 	if (!_get_env_vars(cmd))
1114 		goto_out;
1115 
1116 	/* Create system directory if it doesn't already exist */
1117 	if (*cmd->system_dir && !dm_create_dir(cmd->system_dir)) {
1118 		log_error("Failed to create LVM2 system dir for metadata backups, config "
1119 			  "files and internal cache.");
1120 		log_error("Set environment variable LVM_SYSTEM_DIR to alternative location "
1121 			  "or empty string.");
1122 		goto out;
1123 	}
1124 
1125 	if (!(cmd->libmem = dm_pool_create("library", 4 * 1024))) {
1126 		log_error("Library memory pool creation failed");
1127 		goto out;
1128 	}
1129 
1130 	if (!_init_lvm_conf(cmd))
1131 		goto_out;
1132 
1133 	_init_logging(cmd);
1134 
1135 	if (!_init_hostname(cmd))
1136 		goto_out;
1137 
1138 	if (!_init_tags(cmd, cmd->cft))
1139 		goto_out;
1140 
1141 	if (!_init_tag_configs(cmd))
1142 		goto_out;
1143 
1144 	if (!_merge_config_files(cmd))
1145 		goto_out;
1146 
1147 	if (!_process_config(cmd))
1148 		goto_out;
1149 
1150 	if (!_init_dev_cache(cmd))
1151 		goto_out;
1152 
1153 	if (!_init_filters(cmd, 1))
1154 		goto_out;
1155 
1156 	if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
1157 		log_error("Command memory pool creation failed");
1158 		goto out;
1159 	}
1160 
1161 	memlock_init(cmd);
1162 
1163 	if (!_init_formats(cmd))
1164 		goto_out;
1165 
1166 	if (!init_lvmcache_orphans(cmd))
1167 		goto_out;
1168 
1169 	if (!_init_segtypes(cmd))
1170 		goto_out;
1171 
1172 	if (!_init_backup(cmd))
1173 		goto_out;
1174 
1175 	_init_rand(cmd);
1176 
1177 	_init_globals(cmd);
1178 
1179 	cmd->default_settings.cache_vgmetadata = 1;
1180 	cmd->current_settings = cmd->default_settings;
1181 
1182 	cmd->config_valid = 1;
1183 out:
1184 	return cmd;
1185 }
1186 
1187 static void _destroy_formats(struct dm_list *formats)
1188 {
1189 	struct dm_list *fmtl, *tmp;
1190 	struct format_type *fmt;
1191 	void *lib;
1192 
1193 	dm_list_iterate_safe(fmtl, tmp, formats) {
1194 		fmt = dm_list_item(fmtl, struct format_type);
1195 		dm_list_del(&fmt->list);
1196 		lib = fmt->library;
1197 		fmt->ops->destroy(fmt);
1198 #ifdef HAVE_LIBDL
1199 		if (lib)
1200 			dlclose(lib);
1201 #endif
1202 	}
1203 }
1204 
1205 static void _destroy_segtypes(struct dm_list *segtypes)
1206 {
1207 	struct dm_list *sgtl, *tmp;
1208 	struct segment_type *segtype;
1209 	void *lib;
1210 
1211 	dm_list_iterate_safe(sgtl, tmp, segtypes) {
1212 		segtype = dm_list_item(sgtl, struct segment_type);
1213 		dm_list_del(&segtype->list);
1214 		lib = segtype->library;
1215 		segtype->ops->destroy(segtype);
1216 #ifdef HAVE_LIBDL
1217 		/*
1218 		 * If no segtypes remain from this library, close it.
1219 		 */
1220 		if (lib) {
1221 			struct segment_type *segtype2;
1222 			dm_list_iterate_items(segtype2, segtypes)
1223 				if (segtype2->library == lib)
1224 					goto skip_dlclose;
1225 			dlclose(lib);
1226 skip_dlclose:
1227 			;
1228 		}
1229 #endif
1230 	}
1231 }
1232 
1233 int refresh_filters(struct cmd_context *cmd)
1234 {
1235 	if (cmd->filter) {
1236 		cmd->filter->destroy(cmd->filter);
1237 		cmd->filter = NULL;
1238 	}
1239 
1240 	return _init_filters(cmd, 0);
1241 }
1242 
1243 int refresh_toolcontext(struct cmd_context *cmd)
1244 {
1245 	log_verbose("Reloading config files");
1246 
1247 	/*
1248 	 * Don't update the persistent filter cache as we will
1249 	 * perform a full rescan.
1250 	 */
1251 
1252 	activation_release();
1253 	lvmcache_destroy(cmd, 0);
1254 	label_exit();
1255 	_destroy_segtypes(&cmd->segtypes);
1256 	_destroy_formats(&cmd->formats);
1257 	if (cmd->filter) {
1258 		cmd->filter->destroy(cmd->filter);
1259 		cmd->filter = NULL;
1260 	}
1261 	dev_cache_exit();
1262 	_destroy_tags(cmd);
1263 	_destroy_tag_configs(cmd);
1264 
1265 	cmd->config_valid = 0;
1266 
1267 	cmd->hosttags = 0;
1268 
1269 	if (!_init_lvm_conf(cmd))
1270 		return 0;
1271 
1272 	_init_logging(cmd);
1273 
1274 	if (!_init_tags(cmd, cmd->cft))
1275 		return 0;
1276 
1277 	if (!_init_tag_configs(cmd))
1278 		return 0;
1279 
1280 	if (!_merge_config_files(cmd))
1281 		return 0;
1282 
1283 	if (!_process_config(cmd))
1284 		return 0;
1285 
1286 	if (!_init_dev_cache(cmd))
1287 		return 0;
1288 
1289 	if (!_init_filters(cmd, 0))
1290 		return 0;
1291 
1292 	if (!_init_formats(cmd))
1293 		return 0;
1294 
1295 	if (!init_lvmcache_orphans(cmd))
1296 		return 0;
1297 
1298 	if (!_init_segtypes(cmd))
1299 		return 0;
1300 
1301 	cmd->config_valid = 1;
1302 
1303 	reset_lvm_errno(1);
1304 	return 1;
1305 }
1306 
1307 void destroy_toolcontext(struct cmd_context *cmd)
1308 {
1309 	if (cmd->dump_filter)
1310 		persistent_filter_dump(cmd->filter);
1311 
1312 	archive_exit(cmd);
1313 	backup_exit(cmd);
1314 	lvmcache_destroy(cmd, 0);
1315 	label_exit();
1316 	_destroy_segtypes(&cmd->segtypes);
1317 	_destroy_formats(&cmd->formats);
1318 	if (cmd->filter)
1319 		cmd->filter->destroy(cmd->filter);
1320 	if (cmd->mem)
1321 		dm_pool_destroy(cmd->mem);
1322 	dev_cache_exit();
1323 	_destroy_tags(cmd);
1324 	_destroy_tag_configs(cmd);
1325 	if (cmd->libmem)
1326 		dm_pool_destroy(cmd->libmem);
1327 	dm_free(cmd);
1328 
1329 	release_log_memory();
1330 	activation_exit();
1331 	fin_log();
1332 	fin_syslog();
1333 	reset_lvm_errno(0);
1334 }
1335