diff --git a/WHATS_NEW b/WHATS_NEW index 48784574e..8c81d623e 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,12 @@ -Version 2.02.07 - -=============================== +Version 2.02.07 - +================================= + Fix lvcreate corelog validation. + Add --config for overriding most config file settings from cmdline. + Quote arguments when printing command line. + Remove linefeed from 'initialising logging' message. + Add 'Completed' debug message. + Don't attempt library exit after reloading config files. + Always compile with libdevmapper, even if device-mapper is disabled. Version 2.02.06 - 12th May 2006 =============================== diff --git a/configure b/configure index a7adcf200..f176e49fd 100755 --- a/configure +++ b/configure @@ -10699,7 +10699,6 @@ done fi -if test x$DEVMAPPER = xyes; then for ac_header in libdevmapper.h do @@ -10854,7 +10853,6 @@ fi done -fi if test x$HAVE_SELINUX = xyes; then @@ -11053,45 +11051,6 @@ else echo "${ECHO_T}no" >&6 fi -# Extract the first word of "ifconfig", so it can be a program name with args. -set dummy ifconfig; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_MODPROBE_CMD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $MODPROBE_CMD in - [\\/]* | ?:[\\/]*) - ac_cv_path_MODPROBE_CMD="$MODPROBE_CMD" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_MODPROBE_CMD="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - ;; -esac -fi -MODPROBE_CMD=$ac_cv_path_MODPROBE_CMD - -if test -n "$MODPROBE_CMD"; then - echo "$as_me:$LINENO: result: $MODPROBE_CMD" >&5 -echo "${ECHO_T}$MODPROBE_CMD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - if test x$MODPROBE_CMD != x; then diff --git a/configure.in b/configure.in index f09923b4f..874a72e8d 100644 --- a/configure.in +++ b/configure.in @@ -538,9 +538,7 @@ if test x$INTL = xyes; then AC_CHECK_HEADERS(libintl.h,,AC_MSG_ERROR(bailing out)) fi -if test x$DEVMAPPER = xyes; then - AC_CHECK_HEADERS(libdevmapper.h,,AC_MSG_ERROR(bailing out)) -fi +AC_CHECK_HEADERS(libdevmapper.h,,AC_MSG_ERROR(bailing out)) if test x$HAVE_SELINUX = xyes; then AC_CHECK_HEADERS(selinux/selinux.h,,AC_MSG_ERROR(bailing out)) diff --git a/daemons/clvmd/Makefile.in b/daemons/clvmd/Makefile.in index 2fcc44285..209078f1b 100644 --- a/daemons/clvmd/Makefile.in +++ b/daemons/clvmd/Makefile.in @@ -59,9 +59,7 @@ ifeq ("@DMEVENTD@", "yes") LVMLIBS += -ldevmapper-event endif -ifeq ("@DEVMAPPER@", "yes") - LVMLIBS += -ldevmapper -endif +LVMLIBS += -ldevmapper DEFS += -D_REENTRANT CFLAGS += -fno-strict-aliasing diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c index 62d5911f3..1c525aef1 100644 --- a/daemons/clvmd/lvm-functions.c +++ b/daemons/clvmd/lvm-functions.c @@ -510,7 +510,7 @@ static void check_config() { int locking_type; - locking_type = find_config_int(cmd->cft->root, "global/locking_type", 1); + locking_type = find_config_tree_int(cmd, "global/locking_type", 1); if (locking_type == 3) /* compiled-in cluster support */ return; @@ -518,7 +518,7 @@ static void check_config() if (locking_type == 2) { /* External library, check name */ const char *libname; - libname = find_config_str(cmd->cft->root, "global/locking_library", + libname = find_config_tree_str(cmd, "global/locking_library", ""); if (strstr(libname, "liblvm2clusterlock.so")) return; diff --git a/lib/activate/activate.c b/lib/activate/activate.c index d27c31bc4..ce397bdda 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -157,6 +157,11 @@ int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv, return 0; } +void activation_release(void) +{ + return; +} + void activation_exit(void) { return; @@ -193,7 +198,7 @@ static int _passes_activation_filter(struct cmd_context *cmd, char *str; char path[PATH_MAX]; - if (!(cn = find_config_node(cmd->cft->root, "activation/volume_list"))) { + if (!(cn = find_config_tree_node(cmd, "activation/volume_list"))) { /* If no host tags defined, activate */ if (list_empty(&cmd->tags)) return 1; @@ -894,6 +899,11 @@ int pv_uses_vg(struct physical_volume *pv, return dev_manager_device_uses_vg(pv->dev, vg); } +void activation_release(void) +{ + dev_manager_release(); +} + void activation_exit(void) { dev_manager_exit(); diff --git a/lib/activate/activate.h b/lib/activate/activate.h index f8a602269..16bcb7be1 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -40,6 +40,7 @@ int target_present(const char *target_name, int use_modprobe); int target_version(const char *target_name, uint32_t *maj, uint32_t *min, uint32_t *patchlevel); +void activation_release(void); void activation_exit(void); int lv_suspend(struct cmd_context *cmd, const char *lvid_s); diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 37cbbd9ba..8610012ba 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -401,7 +401,7 @@ struct dev_manager *dev_manager_create(struct cmd_context *cmd, dm->mem = mem; if (!stripe_filler) { - stripe_filler = find_config_str(cmd->cft->root, + stripe_filler = find_config_tree_str(cmd, "activation/missing_stripe_filler", DEFAULT_STRIPE_FILLER); } @@ -426,6 +426,11 @@ void dev_manager_destroy(struct dev_manager *dm) dm_pool_destroy(dm->mem); } +void dev_manager_release(void) +{ + dm_lib_release(); +} + void dev_manager_exit(void) { dm_lib_exit(); @@ -758,7 +763,7 @@ static int _add_target_to_dtree(struct dev_manager *dm, return 0; } - return seg->segtype->ops->add_target_line(dm, dm->mem, dm->cmd->cft, + return seg->segtype->ops->add_target_line(dm, dm->mem, dm->cmd, &dm->target_state, seg, dnode, extent_size * seg->len, diff --git a/lib/activate/dev_manager.h b/lib/activate/dev_manager.h index 910daa2b8..6eb82788a 100644 --- a/lib/activate/dev_manager.h +++ b/lib/activate/dev_manager.h @@ -29,6 +29,7 @@ struct device; struct dev_manager *dev_manager_create(struct cmd_context *cmd, const char *vg_name); void dev_manager_destroy(struct dev_manager *dm); +void dev_manager_release(void); void dev_manager_exit(void); /* diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c index ad84a1d18..547b6721e 100644 --- a/lib/commands/toolcontext.c +++ b/lib/commands/toolcontext.c @@ -84,10 +84,11 @@ static void _init_logging(struct cmd_context *cmd) time_t t; const char *log_file; + char timebuf[26]; /* Syslog */ cmd->default_settings.syslog = - find_config_int(cmd->cft->root, "log/syslog", DEFAULT_SYSLOG); + find_config_tree_int(cmd, "log/syslog", DEFAULT_SYSLOG); if (cmd->default_settings.syslog != 1) fin_syslog(); @@ -96,37 +97,37 @@ static void _init_logging(struct cmd_context *cmd) /* Debug level for log file output */ cmd->default_settings.debug = - find_config_int(cmd->cft->root, "log/level", DEFAULT_LOGLEVEL); + find_config_tree_int(cmd, "log/level", DEFAULT_LOGLEVEL); init_debug(cmd->default_settings.debug); /* Verbose level for tty output */ cmd->default_settings.verbose = - find_config_int(cmd->cft->root, "log/verbose", DEFAULT_VERBOSE); + find_config_tree_int(cmd, "log/verbose", DEFAULT_VERBOSE); init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL); /* Log message formatting */ - init_indent(find_config_int(cmd->cft->root, "log/indent", + init_indent(find_config_tree_int(cmd, "log/indent", DEFAULT_INDENT)); - cmd->default_settings.msg_prefix = find_config_str(cmd->cft->root, + cmd->default_settings.msg_prefix = find_config_tree_str(cmd, "log/prefix", DEFAULT_MSG_PREFIX); init_msg_prefix(cmd->default_settings.msg_prefix); - cmd->default_settings.cmd_name = find_config_int(cmd->cft->root, + cmd->default_settings.cmd_name = find_config_tree_int(cmd, "log/command_names", DEFAULT_CMD_NAME); init_cmd_name(cmd->default_settings.cmd_name); /* Test mode */ cmd->default_settings.test = - find_config_int(cmd->cft->root, "global/test", 0); + find_config_tree_int(cmd, "global/test", 0); /* Settings for logging to file */ - if (find_config_int(cmd->cft->root, "log/overwrite", DEFAULT_OVERWRITE)) + if (find_config_tree_int(cmd, "log/overwrite", DEFAULT_OVERWRITE)) append = 0; - log_file = find_config_str(cmd->cft->root, "log/file", 0); + log_file = find_config_tree_str(cmd, "log/file", 0); if (log_file) { release_log_memory(); @@ -134,15 +135,17 @@ static void _init_logging(struct cmd_context *cmd) init_log_file(log_file, append); } - log_file = find_config_str(cmd->cft->root, "log/activate_file", 0); + log_file = find_config_tree_str(cmd, "log/activate_file", 0); if (log_file) init_log_direct(log_file, append); - init_log_while_suspended(find_config_int(cmd->cft->root, + init_log_while_suspended(find_config_tree_int(cmd, "log/activation", 0)); t = time(NULL); - log_verbose("Logging initialised at %s", ctime(&t)); + ctime_r(&t, &timebuf[0]); + timebuf[24] = '\0'; + log_verbose("Logging initialised at %s", timebuf); /* Tell device-mapper about our logging */ #ifdef DEVMAPPER_SUPPORT @@ -155,7 +158,7 @@ static int _process_config(struct cmd_context *cmd) mode_t old_umask; /* umask */ - cmd->default_settings.umask = find_config_int(cmd->cft->root, + cmd->default_settings.umask = find_config_tree_int(cmd, "global/umask", DEFAULT_UMASK); @@ -165,7 +168,7 @@ static int _process_config(struct cmd_context *cmd) /* dev dir */ if (lvm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/", - find_config_str(cmd->cft->root, "devices/dir", + find_config_tree_str(cmd, "devices/dir", DEFAULT_DEV_DIR)) < 0) { log_error("Device directory given in config file too long"); return 0; @@ -176,7 +179,7 @@ static int _process_config(struct cmd_context *cmd) /* proc dir */ if (lvm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s", - find_config_str(cmd->cft->root, "global/proc", + find_config_tree_str(cmd, "global/proc", DEFAULT_PROC_DIR)) < 0) { log_error("Device directory given in config file too long"); return 0; @@ -189,17 +192,17 @@ static int _process_config(struct cmd_context *cmd) } /* activation? */ - cmd->default_settings.activation = find_config_int(cmd->cft->root, + cmd->default_settings.activation = find_config_tree_int(cmd, "global/activation", DEFAULT_ACTIVATION); set_activation(cmd->default_settings.activation); - cmd->default_settings.suffix = find_config_int(cmd->cft->root, + cmd->default_settings.suffix = find_config_tree_int(cmd, "global/suffix", DEFAULT_SUFFIX); if (!(cmd->default_settings.unit_factor = - units_to_bytes(find_config_str(cmd->cft->root, + units_to_bytes(find_config_tree_str(cmd, "global/units", DEFAULT_UNITS), &cmd->default_settings.unit_type))) { @@ -469,7 +472,7 @@ static int _init_dev_cache(struct cmd_context *cmd) return 0; } - if (!(cn = find_config_node(cmd->cft->root, "devices/scan"))) { + if (!(cn = find_config_tree_node(cmd, "devices/scan"))) { if (!dev_cache_add_dir("/dev")) { log_error("Failed to add /dev to internal " "device cache"); @@ -494,7 +497,7 @@ static int _init_dev_cache(struct cmd_context *cmd) } } - if (!(cn = find_config_node(cmd->cft->root, "devices/loopfiles"))) + if (!(cn = find_config_tree_node(cmd, "devices/loopfiles"))) return 1; for (cv = cn->v; cv; cv = cv->next) { @@ -536,14 +539,14 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd) * Listed first because it's very efficient at eliminating * unavailable devices. */ - if (find_config_bool(cmd->cft->root, "devices/sysfs_scan", + if (find_config_tree_bool(cmd, "devices/sysfs_scan", DEFAULT_SYSFS_SCAN)) { if ((filters[nr_filt] = sysfs_filter_create(cmd->proc_dir))) nr_filt++; } /* regex filter. Optional. */ - if (!(cn = find_config_node(cmd->cft->root, "devices/filter"))) + if (!(cn = find_config_tree_node(cmd, "devices/filter"))) log_very_verbose("devices/filter not found in config file: " "no regex filter installed"); @@ -553,14 +556,14 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd) } /* device type filter. Required. */ - cn = find_config_node(cmd->cft->root, "devices/types"); + cn = find_config_tree_node(cmd, "devices/types"); if (!(filters[nr_filt++] = lvm_type_filter_create(cmd->proc_dir, cn))) { log_error("Failed to create lvm type filter"); return NULL; } /* md component filter. Optional, non-critical. */ - if (find_config_bool(cmd->cft->root, "devices/md_component_detection", + if (find_config_tree_bool(cmd, "devices/md_component_detection", DEFAULT_MD_COMPONENT_DETECTION)) { init_md_filtering(1); if ((filters[nr_filt] = md_filter_create())) @@ -591,7 +594,7 @@ static int _init_filters(struct cmd_context *cmd) return 0; } - dev_cache = find_config_str(cmd->cft->root, "devices/cache", + dev_cache = find_config_tree_str(cmd, "devices/cache", cache_file); if (!(f4 = persistent_filter_create(f3, dev_cache))) { log_error("Failed to create persistent device filter"); @@ -599,7 +602,7 @@ static int _init_filters(struct cmd_context *cmd) } /* Should we ever dump persistent filter state? */ - if (find_config_int(cmd->cft->root, "devices/write_cache_state", 1)) + if (find_config_tree_int(cmd, "devices/write_cache_state", 1)) cmd->dump_filter = 1; if (!*cmd->sys_dir) @@ -644,7 +647,7 @@ static int _init_formats(struct cmd_context *cmd) #ifdef HAVE_LIBDL /* Load any formats in shared libs */ - if ((cn = find_config_node(cmd->cft->root, "global/format_libraries"))) { + if ((cn = find_config_tree_node(cmd, "global/format_libraries"))) { struct config_value *cv; struct format_type *(*init_format_fn) (struct cmd_context *); @@ -656,7 +659,7 @@ static int _init_formats(struct cmd_context *cmd) "global/format_libraries"); return 0; } - if (!(lib = load_shared_library(cmd->cft, cv->v.str, + if (!(lib = load_shared_library(cmd, cv->v.str, "format", 0))) { stack; return 0; @@ -684,7 +687,7 @@ static int _init_formats(struct cmd_context *cmd) cmd->fmt_backup = fmt; - format = find_config_str(cmd->cft->root, "global/format", + format = find_config_tree_str(cmd, "global/format", DEFAULT_FORMAT); list_iterate_items(fmt, &cmd->formats) { @@ -738,7 +741,7 @@ static int _init_segtypes(struct cmd_context *cmd) #ifdef HAVE_LIBDL /* Load any formats in shared libs */ - if ((cn = find_config_node(cmd->cft->root, "global/segment_libraries"))) { + if ((cn = find_config_tree_node(cmd, "global/segment_libraries"))) { struct config_value *cv; struct segment_type *(*init_segtype_fn) (struct cmd_context *); @@ -752,7 +755,7 @@ static int _init_segtypes(struct cmd_context *cmd) "global/segment_libraries"); return 0; } - if (!(lib = load_shared_library(cmd->cft, cv->v.str, + if (!(lib = load_shared_library(cmd, cv->v.str, "segment type", 0))) { stack; return 0; @@ -827,13 +830,13 @@ static int _init_backup(struct cmd_context *cmd) /* set up archiving */ cmd->default_settings.archive = - find_config_bool(cmd->cft->root, "backup/archive", + find_config_tree_bool(cmd, "backup/archive", DEFAULT_ARCHIVE_ENABLED); - days = (uint32_t) find_config_int(cmd->cft->root, "backup/retain_days", + days = (uint32_t) find_config_tree_int(cmd, "backup/retain_days", DEFAULT_ARCHIVE_DAYS); - min = (uint32_t) find_config_int(cmd->cft->root, "backup/retain_min", + min = (uint32_t) find_config_tree_int(cmd, "backup/retain_min", DEFAULT_ARCHIVE_NUMBER); if (lvm_snprintf @@ -844,7 +847,7 @@ static int _init_backup(struct cmd_context *cmd) return 0; } - dir = find_config_str(cmd->cft->root, "backup/archive_dir", + dir = find_config_tree_str(cmd, "backup/archive_dir", default_dir); if (!archive_init(cmd, dir, days, min)) { @@ -854,7 +857,7 @@ static int _init_backup(struct cmd_context *cmd) /* set up the backup */ cmd->default_settings.backup = - find_config_bool(cmd->cft->root, "backup/backup", + find_config_tree_bool(cmd, "backup/backup", DEFAULT_BACKUP_ENABLED); if (lvm_snprintf @@ -865,7 +868,7 @@ static int _init_backup(struct cmd_context *cmd) return 0; } - dir = find_config_str(cmd->cft->root, "backup/backup_dir", default_dir); + dir = find_config_tree_str(cmd, "backup/backup_dir", default_dir); if (!backup_init(cmd, dir)) { log_debug("backup_init failed."); @@ -1021,7 +1024,7 @@ int refresh_toolcontext(struct cmd_context *cmd) persistent_filter_dump(cmd->filter); } - activation_exit(); + activation_release(); lvmcache_destroy(); label_exit(); _destroy_segtypes(&cmd->segtypes); diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h index 8a43fd88d..e35c2fe06 100644 --- a/lib/commands/toolcontext.h +++ b/lib/commands/toolcontext.h @@ -71,6 +71,7 @@ struct cmd_context { struct list config_files; int config_valid; struct config_tree *cft; + struct config_tree *cft_override; struct config_info default_settings; struct config_info current_settings; diff --git a/lib/config/config.c b/lib/config/config.c index 33ba929ff..99d7f2e70 100644 --- a/lib/config/config.c +++ b/lib/config/config.c @@ -41,10 +41,10 @@ enum { }; struct parser { - char *fb, *fe; /* file limits */ + const char *fb, *fe; /* file limits */ int t; /* token limits and type */ - char *tb, *te; + const char *tb, *te; int fd; /* descriptor for file being parsed */ int line; /* line number we are on */ @@ -77,7 +77,7 @@ static const int sep = '/'; #define match(t) do {\ if (!_match_aux(p, (t))) {\ - log_error("Parse error at line %d: unexpected token", p->line); \ + log_error("Parse error at byte %d (line %d): unexpected token", p->tb - p->fb + 1, p->line); \ return 0;\ } \ } while(0); @@ -101,12 +101,12 @@ struct config_tree *create_config_tree(const char *filename) struct dm_pool *mem = dm_pool_create("config", 10 * 1024); if (!mem) { - stack; + log_error("Failed to allocate config pool."); return 0; } if (!(c = dm_pool_zalloc(mem, sizeof(*c)))) { - stack; + log_error("Failed to allocate config tree."); dm_pool_destroy(mem); return 0; } @@ -125,6 +125,46 @@ void destroy_config_tree(struct config_tree *cft) dm_pool_destroy(((struct cs *) cft)->mem); } +static int _parse_config_file(struct parser *p, struct config_tree *cft) +{ + p->tb = p->te = p->fb; + p->line = 1; + _get_token(p, TOK_SECTION_E); + if (!(cft->root = _file(p))) + return_0; + + return 1; +} + +struct config_tree *create_config_tree_from_string(struct cmd_context *cmd, + const char *config_settings) +{ + struct cs *c; + struct config_tree *cft; + struct parser *p; + + if (!(cft = create_config_tree(NULL))) + return_NULL; + + c = (struct cs *) cft; + if (!(p = dm_pool_alloc(c->mem, sizeof(*p)))) { + log_error("Failed to allocate config tree parser."); + destroy_config_tree(cft); + return NULL; + } + + p->mem = c->mem; + p->fb = config_settings; + p->fe = config_settings + strlen(config_settings); + + if (!_parse_config_file(p, cft)) { + destroy_config_tree(cft); + return_NULL; + } + + return cft; +} + int read_config_fd(struct config_tree *cft, struct device *dev, off_t offset, size_t size, off_t offset2, size_t size2, checksum_fn_t checksum_fn, uint32_t checksum) @@ -134,6 +174,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev, int r = 0; int use_mmap = 1; off_t mmap_offset = 0; + char *buf; if (!(p = dm_pool_alloc(c->mem, sizeof(*p)))) { stack; @@ -156,22 +197,23 @@ int read_config_fd(struct config_tree *cft, struct device *dev, } p->fb = p->fb + mmap_offset; } else { - if (!(p->fb = dm_malloc(size + size2))) { + if (!(buf = dm_malloc(size + size2))) { stack; return 0; } - if (!dev_read(dev, (uint64_t) offset, size, p->fb)) { + if (!dev_read(dev, (uint64_t) offset, size, buf)) { log_error("Read from %s failed", dev_name(dev)); goto out; } if (size2) { if (!dev_read(dev, (uint64_t) offset2, size2, - p->fb + size)) { + buf + size)) { log_error("Circular read from %s failed", dev_name(dev)); goto out; } } + p->fb = buf; } if (checksum_fn && checksum != @@ -183,11 +225,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev, p->fe = p->fb + size + size2; - /* parse */ - p->tb = p->te = p->fb; - p->line = 1; - _get_token(p, TOK_SECTION_E); - if (!(cft->root = _file(p))) { + if (!_parse_config_file(p, cft)) { stack; goto out; } @@ -196,7 +234,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev, out: if (!use_mmap) - dm_free(p->fb); + dm_free(buf); else { /* unmap the file */ if (munmap((char *) (p->fb - mmap_offset), size + mmap_offset)) { @@ -529,7 +567,7 @@ static struct config_value *_type(struct parser *p) break; default: - log_error("Parse error at line %d: expected a value", p->line); + log_error("Parse error at byte %d (line %d): expected a value", p->tb - p->fb + 1, p->line); return 0; } return v; @@ -721,8 +759,8 @@ static char *_dup_tok(struct parser *p) /* * utility functions */ -struct config_node *find_config_node(const struct config_node *cn, - const char *path) +static struct config_node *_find_config_node(const struct config_node *cn, + const char *path) { const char *e; @@ -753,10 +791,32 @@ struct config_node *find_config_node(const struct config_node *cn, return (struct config_node *) cn; } -const char *find_config_str(const struct config_node *cn, - const char *path, const char *fail) +static struct config_node *_find_first_config_node(const struct config_node *cn1, + const struct config_node *cn2, + const char *path) { - const struct config_node *n = find_config_node(cn, path); + struct config_node *cn; + + if (cn1 && (cn = _find_config_node(cn1, path))) + return cn; + + if (cn2 && (cn = _find_config_node(cn2, path))) + return cn; + + return NULL; +} + +struct config_node *find_config_node(const struct config_node *cn, + const char *path) +{ + return _find_config_node(cn, path); +} + +static const char *_find_config_str(const struct config_node *cn1, + const struct config_node *cn2, + const char *path, const char *fail) +{ + const struct config_node *n = _find_first_config_node(cn1, cn2, path); /* Empty strings are ignored */ if ((n && n->v->type == CFG_STRING) && (*n->v->v.str)) { @@ -770,9 +830,17 @@ const char *find_config_str(const struct config_node *cn, return fail; } -int find_config_int(const struct config_node *cn, const char *path, int fail) +const char *find_config_str(const struct config_node *cn, + const char *path, const char *fail) { - const struct config_node *n = find_config_node(cn, path); + return _find_config_str(cn, NULL, path, fail); +} + +static int _find_config_int(const struct config_node *cn1, + const struct config_node *cn2, + const char *path, int fail) +{ + const struct config_node *n = _find_first_config_node(cn1, cn2, path); if (n && n->v->type == CFG_INT) { log_very_verbose("Setting %s to %d", path, n->v->v.i); @@ -784,10 +852,16 @@ int find_config_int(const struct config_node *cn, const char *path, int fail) return fail; } -float find_config_float(const struct config_node *cn, const char *path, - float fail) +int find_config_int(const struct config_node *cn, const char *path, int fail) { - const struct config_node *n = find_config_node(cn, path); + return _find_config_int(cn, NULL, path, fail); +} + +static float _find_config_float(const struct config_node *cn1, + const struct config_node *cn2, + const char *path, float fail) +{ + const struct config_node *n = _find_first_config_node(cn1, cn2, path); if (n && n->v->type == CFG_FLOAT) { log_very_verbose("Setting %s to %f", path, n->v->v.r); @@ -801,6 +875,36 @@ float find_config_float(const struct config_node *cn, const char *path, } +float find_config_float(const struct config_node *cn, const char *path, + float fail) +{ + return _find_config_float(cn, NULL, path, fail); +} + +struct config_node *find_config_tree_node(struct cmd_context *cmd, + const char *path) +{ + return _find_first_config_node(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path); +} + +const char *find_config_tree_str(struct cmd_context *cmd, + const char *path, const char *fail) +{ + return _find_config_str(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail); +} + +int find_config_tree_int(struct cmd_context *cmd, const char *path, + int fail) +{ + return _find_config_int(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail); +} + +float find_config_tree_float(struct cmd_context *cmd, const char *path, + float fail) +{ + return _find_config_float(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail); +} + static int _str_in_array(const char *str, const char *values[]) { int i; @@ -827,9 +931,11 @@ static int _str_to_bool(const char *str, int fail) return fail; } -int find_config_bool(const struct config_node *cn, const char *path, int fail) +static int _find_config_bool(const struct config_node *cn1, + const struct config_node *cn2, + const char *path, int fail) { - const struct config_node *n = find_config_node(cn, path); + const struct config_node *n = _find_first_config_node(cn1, cn2, path); struct config_value *v; if (!n) @@ -848,6 +954,16 @@ int find_config_bool(const struct config_node *cn, const char *path, int fail) return fail; } +int find_config_bool(const struct config_node *cn, const char *path, int fail) +{ + return _find_config_bool(cn, NULL, path, fail); +} + +int find_config_tree_bool(struct cmd_context *cmd, const char *path, int fail) +{ + return _find_config_bool(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail); +} + int get_config_uint32(const struct config_node *cn, const char *path, uint32_t *result) { diff --git a/lib/config/config.h b/lib/config/config.h index 1855d08f8..32ae593b3 100644 --- a/lib/config/config.h +++ b/lib/config/config.h @@ -54,9 +54,11 @@ struct config_tree_list { }; struct config_tree *create_config_tree(const char *filename); +struct config_tree *create_config_tree_from_string(struct cmd_context *cmd, + const char *config_settings); void destroy_config_tree(struct config_tree *cft); -typedef uint32_t (*checksum_fn_t) (uint32_t initial, void *buf, uint32_t size); +typedef uint32_t (*checksum_fn_t) (uint32_t initial, const void *buf, uint32_t size); int read_config_fd(struct config_tree *cft, struct device *dev, off_t offset, size_t size, off_t offset2, size_t size2, @@ -71,20 +73,30 @@ int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft, struct config_node *find_config_node(const struct config_node *cn, const char *path); - const char *find_config_str(const struct config_node *cn, const char *path, const char *fail); - int find_config_int(const struct config_node *cn, const char *path, int fail); - float find_config_float(const struct config_node *cn, const char *path, float fail); +/* + * These versions check an override tree, if present, first. + */ +struct config_node *find_config_tree_node(struct cmd_context *cmd, + const char *path); +const char *find_config_tree_str(struct cmd_context *cmd, + const char *path, const char *fail); +int find_config_tree_int(struct cmd_context *cmd, const char *path, + int fail); +float find_config_tree_float(struct cmd_context *cmd, const char *path, + float fail); + /* * Understands (0, ~0), (y, n), (yes, no), (on, * off), (true, false). */ int find_config_bool(const struct config_node *cn, const char *path, int fail); +int find_config_tree_bool(struct cmd_context *cmd, const char *path, int fail); int get_config_uint32(const struct config_node *cn, const char *path, uint32_t *result); diff --git a/lib/error/errseg.c b/lib/error/errseg.c index f0cf2c3be..cef9d7f79 100644 --- a/lib/error/errseg.c +++ b/lib/error/errseg.c @@ -40,7 +40,7 @@ static int _errseg_merge_segments(struct lv_segment *seg1, struct lv_segment *se #ifdef DEVMAPPER_SUPPORT static int _errseg_add_target_line(struct dev_manager *dm __attribute((unused)), struct dm_pool *mem __attribute((unused)), - struct config_tree *cft __attribute((unused)), + struct cmd_context *cmd __attribute((unused)), void **target_state __attribute((unused)), struct lv_segment *seg __attribute((unused)), struct dm_tree_node *node, uint64_t len, diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c index f831e1a47..1ce29fe37 100644 --- a/lib/format_text/format-text.c +++ b/lib/format_text/format-text.c @@ -1783,7 +1783,7 @@ struct format_type *create_text_format(struct cmd_context *cmd) return NULL; } - if ((cn = find_config_node(cmd->cft->root, "metadata/dirs"))) { + if ((cn = find_config_tree_node(cmd, "metadata/dirs"))) { for (cv = cn->v; cv; cv = cv->next) { if (cv->type != CFG_STRING) { log_error("Invalid string in config file: " @@ -1799,7 +1799,7 @@ struct format_type *create_text_format(struct cmd_context *cmd) } } - if ((cn = find_config_node(cmd->cft->root, "metadata/disk_areas"))) { + if ((cn = find_config_tree_node(cmd, "metadata/disk_areas"))) { for (cn = cn->child; cn; cn = cn->sib) { if (!_get_config_disk_area(cmd, cn, &mda_lists->raws)) goto err; diff --git a/lib/locking/cluster_locking.c b/lib/locking/cluster_locking.c index ce16e660b..6f3fbad94 100644 --- a/lib/locking/cluster_locking.c +++ b/lib/locking/cluster_locking.c @@ -452,7 +452,7 @@ void reset_locking(void) } #ifdef CLUSTER_LOCKING_INTERNAL -int init_cluster_locking(struct locking_type *locking, struct config_tree *cft) +int init_cluster_locking(struct locking_type *locking, struct cmd_context *cmd) { locking->lock_resource = _lock_resource; locking->fin_locking = _locking_end; diff --git a/lib/locking/external_locking.c b/lib/locking/external_locking.c index a93923f8c..66c259d77 100644 --- a/lib/locking/external_locking.c +++ b/lib/locking/external_locking.c @@ -17,6 +17,7 @@ #include "locking_types.h" #include "defaults.h" #include "sharedlib.h" +#include "toolcontext.h" static void *_locking_lib = NULL; static void (*_reset_fn) (void) = NULL; @@ -55,7 +56,7 @@ static void _reset_external_locking(void) _reset_fn(); } -int init_external_locking(struct locking_type *locking, struct config_tree *cft) +int init_external_locking(struct locking_type *locking, struct cmd_context *cmd) { const char *libname; @@ -69,10 +70,10 @@ int init_external_locking(struct locking_type *locking, struct config_tree *cft) locking->reset_locking = _reset_external_locking; locking->flags = 0; - libname = find_config_str(cft->root, "global/locking_library", - DEFAULT_LOCKING_LIB); + libname = find_config_tree_str(cmd, "global/locking_library", + DEFAULT_LOCKING_LIB); - if (!(_locking_lib = load_shared_library(cft, libname, "locking", 1))) { + if (!(_locking_lib = load_shared_library(cmd, libname, "locking", 1))) { stack; return 0; } @@ -90,5 +91,5 @@ int init_external_locking(struct locking_type *locking, struct config_tree *cft) } log_verbose("Loaded external locking library %s", libname); - return _init_fn(2, cft, &locking->flags); + return _init_fn(2, cmd->cft, &locking->flags); } diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c index 62aa7f2f1..b0f23d6f0 100644 --- a/lib/locking/file_locking.c +++ b/lib/locking/file_locking.c @@ -271,7 +271,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource, return 1; } -int init_file_locking(struct locking_type *locking, struct config_tree *cft) +int init_file_locking(struct locking_type *locking, struct cmd_context *cmd) { locking->lock_resource = _file_lock_resource; locking->reset_locking = _reset_file_locking; @@ -279,8 +279,8 @@ int init_file_locking(struct locking_type *locking, struct config_tree *cft) locking->flags = 0; /* Get lockfile directory from config file */ - strncpy(_lock_dir, find_config_str(cft->root, "global/locking_dir", - DEFAULT_LOCK_DIR), + strncpy(_lock_dir, find_config_tree_str(cmd, "global/locking_dir", + DEFAULT_LOCK_DIR), sizeof(_lock_dir)); if (!create_dir(_lock_dir)) diff --git a/lib/locking/locking.c b/lib/locking/locking.c index 961af4fc0..7170adc66 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -122,26 +122,26 @@ static void _update_vg_lock_count(int flags) /* * Select a locking type */ -int init_locking(int type, struct config_tree *cft) +int init_locking(int type, struct cmd_context *cmd) { init_lockingfailed(0); switch (type) { case 0: - init_no_locking(&_locking, cft); + init_no_locking(&_locking, cmd); log_print("WARNING: Locking disabled. Be careful! " "This could corrupt your metadata."); return 1; case 1: - if (!init_file_locking(&_locking, cft)) + if (!init_file_locking(&_locking, cmd)) break; log_very_verbose("File-based locking enabled."); return 1; #ifdef HAVE_LIBDL case 2: - if (!init_external_locking(&_locking, cft)) + if (!init_external_locking(&_locking, cmd)) break; log_very_verbose("External locking enabled."); return 1; @@ -149,7 +149,7 @@ int init_locking(int type, struct config_tree *cft) #ifdef CLUSTER_LOCKING_INTERNAL case 3: - if (!init_cluster_locking(&_locking, cft)) + if (!init_cluster_locking(&_locking, cmd)) break; log_very_verbose("Cluster locking enabled."); return 1; @@ -166,7 +166,7 @@ int init_locking(int type, struct config_tree *cft) /* FIXME Ensure only read ops are permitted */ log_verbose("Locking disabled - only read operations permitted."); - init_no_locking(&_locking, cft); + init_no_locking(&_locking, cmd); init_lockingfailed(1); return 1; diff --git a/lib/locking/locking.h b/lib/locking/locking.h index 245de5f54..af339f7d0 100644 --- a/lib/locking/locking.h +++ b/lib/locking/locking.h @@ -19,7 +19,7 @@ #include "uuid.h" #include "config.h" -int init_locking(int type, struct config_tree *cf); +int init_locking(int type, struct cmd_context *cmd); void fin_locking(void); void reset_locking(void); int vg_write_lock_held(void); diff --git a/lib/locking/locking_types.h b/lib/locking/locking_types.h index 2d5a0ba5b..c13412aa1 100644 --- a/lib/locking/locking_types.h +++ b/lib/locking/locking_types.h @@ -36,10 +36,10 @@ struct locking_type { /* * Locking types */ -int init_no_locking(struct locking_type *locking, struct config_tree *cf); +int init_no_locking(struct locking_type *locking, struct cmd_context *cmd); -int init_file_locking(struct locking_type *locking, struct config_tree *cf); +int init_file_locking(struct locking_type *locking, struct cmd_context *cmd); -int init_external_locking(struct locking_type *locking, struct config_tree *cf); +int init_external_locking(struct locking_type *locking, struct cmd_context *cmd); -int init_cluster_locking(struct locking_type *locking, struct config_tree *cf); +int init_cluster_locking(struct locking_type *locking, struct cmd_context *cmd); diff --git a/lib/locking/no_locking.c b/lib/locking/no_locking.c index b377a6282..8e7f32ffb 100644 --- a/lib/locking/no_locking.c +++ b/lib/locking/no_locking.c @@ -76,7 +76,7 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource, return 1; } -int init_no_locking(struct locking_type *locking, struct config_tree *cft) +int init_no_locking(struct locking_type *locking, struct cmd_context *cmd) { locking->lock_resource = _no_lock_resource; locking->reset_locking = _no_reset_locking; diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h index 426384079..0a21ef8b7 100644 --- a/lib/metadata/segtype.h +++ b/lib/metadata/segtype.h @@ -67,23 +67,23 @@ struct segtype_handler { int (*merge_segments) (struct lv_segment * seg1, struct lv_segment * seg2); int (*add_target_line) (struct dev_manager *dm, struct dm_pool *mem, - struct config_tree *cft, void **target_state, + struct cmd_context *cmd, void **target_state, struct lv_segment *seg, struct dm_tree_node *node, uint64_t len, uint32_t *pvmove_mirror_count); int (*target_percent) (void **target_state, struct dm_pool * mem, - struct config_tree * cft, - struct lv_segment * seg, char *params, + struct config_tree *cft, + struct lv_segment *seg, char *params, uint64_t *total_numerator, uint64_t *total_denominator, float *percent); int (*target_present) (void); void (*destroy) (const struct segment_type * segtype); int (*target_register_events) (struct dm_pool *mem, struct lv_segment *seg, - struct config_tree *cft, int events); + struct cmd_context *cmd, int events); int (*target_unregister_events) (struct dm_pool *mem, struct lv_segment *seg, - struct config_tree *cft, int events); + struct cmd_context *cmd, int events); }; struct segment_type *get_segtype_from_string(struct cmd_context *cmd, diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c index f9038c988..89128d48d 100644 --- a/lib/mirror/mirrored.c +++ b/lib/mirror/mirrored.c @@ -154,7 +154,7 @@ static int _mirrored_text_export(const struct lv_segment *seg, struct formatter #ifdef DEVMAPPER_SUPPORT static struct mirror_state *_mirrored_init_target(struct dm_pool *mem, - struct config_tree *cft) + struct cmd_context *cmd) { struct mirror_state *mirr_state; @@ -164,7 +164,7 @@ static struct mirror_state *_mirrored_init_target(struct dm_pool *mem, } mirr_state->default_region_size = 2 * - find_config_int(cft->root, + find_config_tree_int(cmd, "activation/mirror_region_size", DEFAULT_MIRROR_REGION_SIZE); @@ -172,7 +172,7 @@ static struct mirror_state *_mirrored_init_target(struct dm_pool *mem, } static int _mirrored_target_percent(void **target_state, struct dm_pool *mem, - struct config_tree *cft, struct lv_segment *seg, + struct cmd_context *cmd, struct lv_segment *seg, char *params, uint64_t *total_numerator, uint64_t *total_denominator, float *percent __attribute((unused))) @@ -184,7 +184,7 @@ static int _mirrored_target_percent(void **target_state, struct dm_pool *mem, char *pos = params; if (!*target_state) - *target_state = _mirrored_init_target(mem, cft); + *target_state = _mirrored_init_target(mem, cmd); mirr_state = *target_state; @@ -265,7 +265,7 @@ static int _add_log(struct dev_manager *dm, struct lv_segment *seg, } static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem, - struct config_tree *cft, void **target_state, + struct cmd_context *cmd, void **target_state, struct lv_segment *seg, struct dm_tree_node *node, uint64_t len, uint32_t *pvmove_mirror_count) @@ -278,7 +278,7 @@ static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem int r; if (!*target_state) - *target_state = _mirrored_init_target(mem, cft); + *target_state = _mirrored_init_target(mem, cmd); mirr_state = *target_state; @@ -367,7 +367,7 @@ static int _mirrored_target_present(void) } #ifdef DMEVENTD -static int _setup_registration(struct dm_pool *mem, struct config_tree *cft, +static int _setup_registration(struct dm_pool *mem, struct cmd_context *cmd, char **dso) { char *path; @@ -378,10 +378,10 @@ static int _setup_registration(struct dm_pool *mem, struct config_tree *cft, return 0; } - libpath = find_config_str(cft->root, "dmeventd/mirror_library", - DEFAULT_DMEVENTD_MIRROR_LIB); + libpath = find_config_tree_str(cmd, "dmeventd/mirror_library", + DEFAULT_DMEVENTD_MIRROR_LIB); - get_shared_library_path(cft, libpath, path, PATH_MAX); + get_shared_library_path(cmd, libpath, path, PATH_MAX); *dso = path; @@ -390,9 +390,10 @@ static int _setup_registration(struct dm_pool *mem, struct config_tree *cft, /* FIXME This gets run while suspended and performs banned operations. */ /* FIXME Merge these two functions */ -static int _target_register_events(struct dm_pool *mem, +static int _target_register_events(struct cmd_context *cmd, + struct dm_pool *mem, struct lv_segment *seg, - struct config_tree *cft, int events) + int events) { char *dso, *name; struct logical_volume *lv; @@ -401,7 +402,7 @@ static int _target_register_events(struct dm_pool *mem, lv = seg->lv; vg = lv->vg; - if (!_setup_registration(mem, cft, &dso)) { + if (!_setup_registration(mem, cmd, &dso)) { stack; return 0; } @@ -418,9 +419,10 @@ static int _target_register_events(struct dm_pool *mem, return 1; } -static int _target_unregister_events(struct dm_pool *mem, +static int _target_unregister_events(struct cmd_context *cmd, + struct dm_pool *mem, struct lv_segment *seg, - struct config_tree *cft, int events) + int events) { char *dso; char *name; @@ -431,7 +433,7 @@ static int _target_unregister_events(struct dm_pool *mem, vg = lv->vg; /* FIXME Remove this and use handle to avoid config file race */ - if (!_setup_registration(mem, cft, &dso)) + if (!_setup_registration(mem, cmd, &dso)) return_0; if (!(name = build_dm_name(mem, vg->name, lv->name, NULL))) diff --git a/lib/misc/crc.c b/lib/misc/crc.c index ad29c8f67..1e5265eae 100644 --- a/lib/misc/crc.c +++ b/lib/misc/crc.c @@ -18,7 +18,7 @@ #include "crc.h" /* Calculate an endian-independent CRC of supplied buffer */ -uint32_t calc_crc(uint32_t initial, void *buf, uint32_t size) +uint32_t calc_crc(uint32_t initial, const void *buf, uint32_t size) { static const uint32_t crctab[] = { 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, @@ -27,7 +27,7 @@ uint32_t calc_crc(uint32_t initial, void *buf, uint32_t size) 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; uint32_t i, crc = initial; - uint8_t *data = (uint8_t *) buf; + const uint8_t *data = (const uint8_t *) buf; for (i = 0; i < size; i++) { crc ^= *data++; diff --git a/lib/misc/crc.h b/lib/misc/crc.h index 59ea0a2f8..2cd2d9acf 100644 --- a/lib/misc/crc.h +++ b/lib/misc/crc.h @@ -18,6 +18,6 @@ #define INITIAL_CRC 0xf597a6cf -uint32_t calc_crc(uint32_t initial, void *buf, uint32_t size); +uint32_t calc_crc(uint32_t initial, const void *buf, uint32_t size); #endif diff --git a/lib/misc/sharedlib.c b/lib/misc/sharedlib.c index b38ede7da..96d90a8f1 100644 --- a/lib/misc/sharedlib.c +++ b/lib/misc/sharedlib.c @@ -22,7 +22,7 @@ #include #include -void get_shared_library_path(struct config_tree *cft, const char *libname, +void get_shared_library_path(struct cmd_context *cmd, const char *libname, char *path, size_t path_len) { struct stat info; @@ -31,19 +31,19 @@ void get_shared_library_path(struct config_tree *cft, const char *libname, /* If libname doesn't begin with '/' then use lib_dir/libname, * if present */ if (libname[0] == '/' || - !(lib_dir = find_config_str(cft->root, "global/library_dir", 0)) || + !(lib_dir = find_config_tree_str(cmd, "global/library_dir", 0)) || (lvm_snprintf(path, path_len, "%s/%s", lib_dir, libname) == -1) || stat(path, &info) == -1) strncpy(path, libname, path_len); } -void *load_shared_library(struct config_tree *cft, const char *libname, +void *load_shared_library(struct cmd_context *cmd, const char *libname, const char *desc, int silent) { char path[PATH_MAX]; void *library; - get_shared_library_path(cft, libname, path, sizeof(path)); + get_shared_library_path(cmd, libname, path, sizeof(path)); log_very_verbose("Opening shared %s library %s", desc, path); diff --git a/lib/misc/sharedlib.h b/lib/misc/sharedlib.h index 3fa6afff5..9ffdbee66 100644 --- a/lib/misc/sharedlib.h +++ b/lib/misc/sharedlib.h @@ -19,9 +19,9 @@ #include "config.h" #include -void get_shared_library_path(struct config_tree *cft, const char *libname, +void get_shared_library_path(struct cmd_context *cmd, const char *libname, char *path, size_t path_len); -void *load_shared_library(struct config_tree *cf, const char *libname, +void *load_shared_library(struct cmd_context *cmd, const char *libname, const char *what, int silent); #endif diff --git a/lib/mm/memlock.c b/lib/mm/memlock.c index 7a463a83c..3c5039b02 100644 --- a/lib/mm/memlock.c +++ b/lib/mm/memlock.c @@ -144,13 +144,13 @@ int memlock(void) void memlock_init(struct cmd_context *cmd) { - _size_stack = find_config_int(cmd->cft->root, + _size_stack = find_config_tree_int(cmd, "activation/reserved_stack", DEFAULT_RESERVED_STACK) * 1024; - _size_malloc_tmp = find_config_int(cmd->cft->root, + _size_malloc_tmp = find_config_tree_int(cmd, "activation/reserved_memory", DEFAULT_RESERVED_MEMORY) * 1024; - _default_priority = find_config_int(cmd->cft->root, + _default_priority = find_config_tree_int(cmd, "activation/process_priority", DEFAULT_PROCESS_PRIORITY); } diff --git a/lib/striped/striped.c b/lib/striped/striped.c index f875bdf2c..2b83c77ab 100644 --- a/lib/striped/striped.c +++ b/lib/striped/striped.c @@ -153,7 +153,7 @@ static int _striped_merge_segments(struct lv_segment *seg1, struct lv_segment *s #ifdef DEVMAPPER_SUPPORT static int _striped_add_target_line(struct dev_manager *dm, struct dm_pool *mem __attribute((unused)), - struct config_tree *cft __attribute((unused)), + struct cmd_context *cmd __attribute((unused)), void **target_state __attribute((unused)), struct lv_segment *seg, struct dm_tree_node *node, uint64_t len, diff --git a/lib/zero/zero.c b/lib/zero/zero.c index e791a2eb0..f577cb67f 100644 --- a/lib/zero/zero.c +++ b/lib/zero/zero.c @@ -40,7 +40,7 @@ static int _zero_merge_segments(struct lv_segment *seg1, struct lv_segment *seg2 #ifdef DEVMAPPER_SUPPORT static int _zero_add_target_line(struct dev_manager *dm __attribute((unused)), struct dm_pool *mem __attribute((unused)), - struct config_tree *cft __attribute((unused)), + struct cmd_context *cmd __attribute((unused)), void **target_state __attribute((unused)), struct lv_segment *seg __attribute((unused)), struct dm_tree_node *node,uint64_t len, diff --git a/tools/Makefile.in b/tools/Makefile.in index 23c5267cf..83f1fcd4e 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -91,9 +91,7 @@ ifeq ("@DMEVENTD@", "yes") LVMLIBS += -ldevmapper-event -lpthread endif -ifeq ("@DEVMAPPER@", "yes") - LVMLIBS += -ldevmapper -endif +LVMLIBS += -ldevmapper DEFS += -DLVM_SHARED_PATH=\"$(exec_prefix)/sbin/lvm\" diff --git a/tools/args.h b/tools/args.h index a0f32446d..1b22d4c51 100644 --- a/tools/args.h +++ b/tools/args.h @@ -48,6 +48,7 @@ arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL) arg(nosync_ARG, '\0', "nosync", NULL) arg(corelog_ARG, '\0', "corelog", NULL) arg(monitor_ARG, '\0', "monitor", yes_no_arg) +arg(config_ARG, '\0', "config", string_arg) /* Allow some variations */ arg(resizable_ARG, '\0', "resizable", yes_no_arg) diff --git a/tools/lvconvert.c b/tools/lvconvert.c index 2a3a39aa8..cb3b56e1a 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -177,7 +177,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd, lp->region_size = 2 * arg_uint_value(cmd, regionsize_ARG, 0); } else { - region_size = 2 * find_config_int(cmd->cft->root, + region_size = 2 * find_config_tree_int(cmd, "activation/mirror_region_size", DEFAULT_MIRROR_REGION_SIZE); if (region_size < 0) { diff --git a/tools/lvcreate.c b/tools/lvcreate.c index 476ba4041..e8ece1656 100644 --- a/tools/lvcreate.c +++ b/tools/lvcreate.c @@ -213,7 +213,7 @@ static int _read_stripe_params(struct lvcreate_params *lp, } if (lp->stripes > 1 && !lp->stripe_size) { - lp->stripe_size = find_config_int(cmd->cft->root, + lp->stripe_size = find_config_tree_int(cmd, "metadata/stripesize", DEFAULT_STRIPESIZE) * 2; log_print("Using default stripesize %s", @@ -264,7 +264,7 @@ static int _read_mirror_params(struct lvcreate_params *lp, } lp->region_size = 2 * arg_uint_value(cmd, regionsize_ARG, 0); } else { - region_size = 2 * find_config_int(cmd->cft->root, + region_size = 2 * find_config_tree_int(cmd, "activation/mirror_region_size", DEFAULT_MIRROR_REGION_SIZE); if (region_size < 0) { @@ -668,7 +668,8 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) status |= MIRROR_NOTSYNCED; } - if (!(log_lv = create_mirror_log(cmd, vg, ah, lp->alloc, + if (!lp->corelog && + !(log_lv = create_mirror_log(cmd, vg, ah, lp->alloc, lv_name, lp->nosync))) { log_error("Failed to create mirror log."); return 0; diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c index 8310db8bf..2ea28a954 100644 --- a/tools/lvmcmdline.c +++ b/tools/lvmcmdline.c @@ -449,7 +449,7 @@ static void _register_commands() driverloaded_ARG, \ debug_ARG, help_ARG, help2_ARG, \ version_ARG, verbose_ARG, \ - quiet_ARG, -1); + quiet_ARG, config_ARG, -1); #include "commands.h" #undef xx } @@ -713,8 +713,6 @@ static int _get_settings(struct cmd_context *cmd) !_merge_synonym(cmd, allocation_ARG, resizeable_ARG)) return EINVALID_CMD_LINE; - init_mirror_in_sync(0); - /* Zero indicates success */ return 0; } @@ -762,12 +760,23 @@ int help(struct cmd_context *cmd __attribute((unused)), int argc, char **argv) return 0; } +static int _override_settings(struct cmd_context *cmd) +{ + if (!(cmd->cft_override = create_config_tree_from_string(cmd, arg_str_value(cmd, config_ARG, "")))) { + log_error("Failed to set overridden configuration entries."); + return EINVALID_CMD_LINE; + } + + return 0; +} + static void _apply_settings(struct cmd_context *cmd) { init_debug(cmd->current_settings.debug); init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL); init_test(cmd->current_settings.test); init_full_scan_done(0); + init_mirror_in_sync(0); init_msg_prefix(cmd->default_settings.msg_prefix); init_cmd_name(cmd->default_settings.cmd_name); @@ -783,7 +792,7 @@ static void _apply_settings(struct cmd_context *cmd) static char *_copy_command_line(struct cmd_context *cmd, int argc, char **argv) { - int i; + int i, space; /* * Build up the complete command line, used as a @@ -793,9 +802,17 @@ static char *_copy_command_line(struct cmd_context *cmd, int argc, char **argv) goto bad; for (i = 0; i < argc; i++) { + space = strchr(argv[i], ' ') ? 1 : 0; + + if (space && !dm_pool_grow_object(cmd->mem, "'", 1)) + goto bad; + if (!dm_pool_grow_object(cmd->mem, argv[i], strlen(argv[i]))) goto bad; + if (space && !dm_pool_grow_object(cmd->mem, "'", 1)) + goto bad; + if (i < (argc - 1)) if (!dm_pool_grow_object(cmd->mem, " ", 1)) goto bad; @@ -835,7 +852,11 @@ static int _run_command(struct cmd_context *cmd, int argc, char **argv) set_cmd_name(cmd->command->name); - if (!cmd->config_valid || config_files_changed(cmd)) { + if (arg_count(cmd, config_ARG)) + if ((ret = _override_settings(cmd))) + goto_out; + + if (arg_count(cmd, config_ARG) || !cmd->config_valid || config_files_changed(cmd)) { /* Reinitialise various settings inc. logging, filters */ if (!refresh_toolcontext(cmd)) { log_error("Updated config file invalid. Aborting."); @@ -844,7 +865,7 @@ static int _run_command(struct cmd_context *cmd, int argc, char **argv) } if ((ret = _get_settings(cmd))) - goto out; + goto_out; _apply_settings(cmd); log_debug("Processing: %s", cmd->cmd_line); @@ -854,15 +875,15 @@ static int _run_command(struct cmd_context *cmd, int argc, char **argv) #endif if ((ret = _process_common_commands(cmd))) - goto out; + goto_out; if (arg_count(cmd, nolocking_ARG)) locking_type = 0; else - locking_type = find_config_int(cmd->cft->root, + locking_type = find_config_tree_int(cmd, "global/locking_type", 1); - if (!init_locking(locking_type, cmd->cft)) { + if (!init_locking(locking_type, cmd)) { log_error("Locking type %d initialisation failed.", locking_type); ret = ECMD_FAILED; @@ -879,6 +900,15 @@ static int _run_command(struct cmd_context *cmd, int argc, char **argv) lvmcache_destroy(); } + if (cmd->cft_override) { + destroy_config_tree(cmd->cft_override); + cmd->cft_override = NULL; + /* Move this? */ + if (!refresh_toolcontext(cmd)) + stack; + } + + /* FIXME Move this? */ cmd->current_settings = cmd->default_settings; _apply_settings(cmd); @@ -890,6 +920,8 @@ static int _run_command(struct cmd_context *cmd, int argc, char **argv) if (ret == EINVALID_CMD_LINE && !_interactive) _usage(cmd->command->name); + log_debug("Completed: %s", cmd->cmd_line); + return ret; } @@ -1163,7 +1195,7 @@ static void _read_history(struct cmd_context *cmd) if (read_history(hist_file)) log_very_verbose("Couldn't read history from %s.", hist_file); - stifle_history(find_config_int(cmd->cft->root, "shell/history_size", + stifle_history(find_config_tree_int(cmd, "shell/history_size", DEFAULT_MAX_HISTORY)); } @@ -1335,7 +1367,7 @@ static int _lvm1_fallback(struct cmd_context *cmd) char vsn[80]; int dm_present; - if (!find_config_int(cmd->cft->root, "global/fallback_to_lvm1", + if (!find_config_tree_int(cmd, "global/fallback_to_lvm1", DEFAULT_FALLBACK_TO_LVM1) || strncmp(cmd->kernel_vsn, "2.4.", 4)) return 0; diff --git a/tools/lvresize.c b/tools/lvresize.c index 41eb6de4a..207f34bd6 100644 --- a/tools/lvresize.c +++ b/tools/lvresize.c @@ -301,7 +301,7 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp) lp->stripe_size = seg_stripesize; } else { lp->stripe_size = - find_config_int(cmd->cft->root, + find_config_tree_int(cmd, "metadata/stripesize", DEFAULT_STRIPESIZE) * 2; log_print("Using default stripesize %s", diff --git a/tools/pvcreate.c b/tools/pvcreate.c index ddc28b198..5a3cb4ddd 100644 --- a/tools/pvcreate.c +++ b/tools/pvcreate.c @@ -185,13 +185,13 @@ static int pvcreate_single(struct cmd_context *cmd, const char *pv_name, pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, UINT64_C(0)) * 2; if (!pvmetadatasize) - pvmetadatasize = find_config_int(cmd->cft->root, + pvmetadatasize = find_config_tree_int(cmd, "metadata/pvmetadatasize", DEFAULT_PVMETADATASIZE); pvmetadatacopies = arg_int_value(cmd, metadatacopies_ARG, -1); if (pvmetadatacopies < 0) - pvmetadatacopies = find_config_int(cmd->cft->root, + pvmetadatacopies = find_config_tree_int(cmd, "metadata/pvmetadatacopies", DEFAULT_PVMETADATACOPIES); diff --git a/tools/reporter.c b/tools/reporter.c index 9d734440d..5bfd50cb4 100644 --- a/tools/reporter.c +++ b/tools/reporter.c @@ -134,73 +134,73 @@ static int _report(struct cmd_context *cmd, int argc, char **argv, int aligned, buffered, headings; - aligned = find_config_int(cmd->cft->root, "report/aligned", + aligned = find_config_tree_int(cmd, "report/aligned", DEFAULT_REP_ALIGNED); - buffered = find_config_int(cmd->cft->root, "report/buffered", + buffered = find_config_tree_int(cmd, "report/buffered", DEFAULT_REP_BUFFERED); - headings = find_config_int(cmd->cft->root, "report/headings", + headings = find_config_tree_int(cmd, "report/headings", DEFAULT_REP_HEADINGS); - separator = find_config_str(cmd->cft->root, "report/separator", + separator = find_config_tree_str(cmd, "report/separator", DEFAULT_REP_SEPARATOR); switch (report_type) { case LVS: - keys = find_config_str(cmd->cft->root, "report/lvs_sort", + keys = find_config_tree_str(cmd, "report/lvs_sort", DEFAULT_LVS_SORT); if (!arg_count(cmd, verbose_ARG)) - options = find_config_str(cmd->cft->root, + options = find_config_tree_str(cmd, "report/lvs_cols", DEFAULT_LVS_COLS); else - options = find_config_str(cmd->cft->root, + options = find_config_tree_str(cmd, "report/lvs_cols_verbose", DEFAULT_LVS_COLS_VERB); break; case VGS: - keys = find_config_str(cmd->cft->root, "report/vgs_sort", + keys = find_config_tree_str(cmd, "report/vgs_sort", DEFAULT_VGS_SORT); if (!arg_count(cmd, verbose_ARG)) - options = find_config_str(cmd->cft->root, + options = find_config_tree_str(cmd, "report/vgs_cols", DEFAULT_VGS_COLS); else - options = find_config_str(cmd->cft->root, + options = find_config_tree_str(cmd, "report/vgs_cols_verbose", DEFAULT_VGS_COLS_VERB); break; case PVS: - keys = find_config_str(cmd->cft->root, "report/pvs_sort", + keys = find_config_tree_str(cmd, "report/pvs_sort", DEFAULT_PVS_SORT); if (!arg_count(cmd, verbose_ARG)) - options = find_config_str(cmd->cft->root, + options = find_config_tree_str(cmd, "report/pvs_cols", DEFAULT_PVS_COLS); else - options = find_config_str(cmd->cft->root, + options = find_config_tree_str(cmd, "report/pvs_cols_verbose", DEFAULT_PVS_COLS_VERB); break; case SEGS: - keys = find_config_str(cmd->cft->root, "report/segs_sort", + keys = find_config_tree_str(cmd, "report/segs_sort", DEFAULT_SEGS_SORT); if (!arg_count(cmd, verbose_ARG)) - options = find_config_str(cmd->cft->root, + options = find_config_tree_str(cmd, "report/segs_cols", DEFAULT_SEGS_COLS); else - options = find_config_str(cmd->cft->root, + options = find_config_tree_str(cmd, "report/segs_cols_verbose", DEFAULT_SEGS_COLS_VERB); break; case PVSEGS: - keys = find_config_str(cmd->cft->root, "report/pvsegs_sort", + keys = find_config_tree_str(cmd, "report/pvsegs_sort", DEFAULT_PVSEGS_SORT); if (!arg_count(cmd, verbose_ARG)) - options = find_config_str(cmd->cft->root, + options = find_config_tree_str(cmd, "report/pvsegs_cols", DEFAULT_PVSEGS_COLS); else - options = find_config_str(cmd->cft->root, + options = find_config_tree_str(cmd, "report/pvsegs_cols_verbose", DEFAULT_PVSEGS_COLS_VERB); break; diff --git a/tools/vgconvert.c b/tools/vgconvert.c index ad81d01a6..e6e5b530a 100644 --- a/tools/vgconvert.c +++ b/tools/vgconvert.c @@ -71,14 +71,14 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name, UINT64_C(0)) * 2; if (!pvmetadatasize) pvmetadatasize = - find_config_int(cmd->cft->root, + find_config_tree_int(cmd, "metadata/pvmetadatasize", DEFAULT_PVMETADATASIZE); pvmetadatacopies = arg_int_value(cmd, metadatacopies_ARG, -1); if (pvmetadatacopies < 0) pvmetadatacopies = - find_config_int(cmd->cft->root, + find_config_tree_int(cmd, "metadata/pvmetadatacopies", DEFAULT_PVMETADATACOPIES); }