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