summaryrefslogtreecommitdiff
path: root/libmultipath
diff options
context:
space:
mode:
authorChristophe Varoqui <root@xa-s05.(none)>2006-01-17 10:08:49 +0100
committerChristophe Varoqui <root@xa-s05.(none)>2006-01-17 10:08:49 +0100
commit315288471f44c0fc8df9b9906443b8b7da671696 (patch)
treec4fd68973ca24c7d8b980854b6b5cef148a1e057 /libmultipath
parentc769721a2fd8204eb1e52dc8dcbb6cc49c2309af (diff)
downloadmultipath-tools-315288471f44c0fc8df9b9906443b8b7da671696.tar.gz
multipath-tools-315288471f44c0fc8df9b9906443b8b7da671696.tar.bz2
multipath-tools-315288471f44c0fc8df9b9906443b8b7da671696.zip
[multipathd] add "show config" CLI command
This commands dumps a multipath.conf config file. The "defaults" section is factorized : settings in sync with the internal defaults are not printed. The "devices" section lists the internal hwtable, plus mods and adds from the actual config file. The layout is factorized : settings in sync with the "defaults" section are not printed. The "devnode_blacklist" section is ommited for now, as this requires a bit more infrastructure. The "multipaths" section is not factorized as we can not reliably guess the hardware a multipath is parented to. Multipath entries are just clones of their actual config file equivalent.
Diffstat (limited to 'libmultipath')
-rw-r--r--libmultipath/dict.c588
-rw-r--r--libmultipath/dict.h2
-rw-r--r--libmultipath/discovery.c2
-rw-r--r--libmultipath/parser.c87
-rw-r--r--libmultipath/parser.h21
-rw-r--r--libmultipath/print.c185
-rw-r--r--libmultipath/print.h5
7 files changed, 822 insertions, 68 deletions
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
index 4231991..9b782de 100644
--- a/libmultipath/dict.c
+++ b/libmultipath/dict.c
@@ -1,6 +1,6 @@
/*
* Based on Alexandre Cassen template for keepalived
- * Copyright (c) 2004, 2005 Christophe Varoqui
+ * Copyright (c) 2004, 2005, 2006 Christophe Varoqui
* Copyright (c) 2005 Benjamin Marzinski, Redhat
* Copyright (c) 2005 Kiyoshi Ueda, NEC
*/
@@ -719,70 +719,558 @@ mp_minio_handler(vector strvec)
return 0;
}
-vector
-init_keywords(void)
+/*
+ * config file keywords printing
+ */
+static int
+snprint_mp_wwid (char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ return snprintf(buff, len, "%s", mpe->wwid);
+}
+
+static int
+snprint_mp_alias (char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ if (!mpe->alias)
+ return 0;
+
+ if (conf->user_friendly_names &&
+ (strlen(mpe->alias) == strlen("mpath")) &&
+ !strcmp(mpe->alias, "mpath"))
+ return 0;
+
+ return snprintf(buff, len, "%s", mpe->alias);
+}
+
+static int
+snprint_mp_path_grouping_policy (char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+ char str[POLICY_NAME_SIZE];
+
+ if (!mpe->pgpolicy)
+ return 0;
+ get_pgpolicy_name(str, POLICY_NAME_SIZE, mpe->pgpolicy);
+
+ return snprintf(buff, len, "%s", str);
+}
+
+static int
+snprint_mp_selector (char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ if (!mpe->selector)
+ return 0;
+
+ return snprintf(buff, len, "%s", mpe->selector);
+}
+
+static int
+snprint_mp_failback (char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ if (!mpe->pgfailback)
+ return 0;
+
+ switch(mpe->pgfailback) {
+ case FAILBACK_UNDEF:
+ break;
+ case -FAILBACK_MANUAL:
+ return snprintf(buff, len, "manual");
+ case -FAILBACK_IMMEDIATE:
+ return snprintf(buff, len, "immediate");
+ default:
+ return snprintf(buff, len, "%i", mpe->pgfailback);
+ }
+ return 0;
+}
+
+static int
+snprint_mp_rr_weight (char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ if (!mpe->rr_weight)
+ return 0;
+ if (mpe->rr_weight == RR_WEIGHT_PRIO)
+ return snprintf(buff, len, "priorities");
+
+ return 0;
+}
+
+static int
+snprint_mp_no_path_retry (char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ if (!mpe->no_path_retry)
+ return 0;
+
+ switch(mpe->no_path_retry) {
+ case NO_PATH_RETRY_UNDEF:
+ break;
+ case NO_PATH_RETRY_FAIL:
+ return snprintf(buff, len, "fail");
+ case NO_PATH_RETRY_QUEUE:
+ return snprintf(buff, len, "queue");
+ default:
+ return snprintf(buff, len, "%i",
+ mpe->no_path_retry);
+ }
+ return 0;
+}
+
+static int
+snprint_mp_rr_min_io (char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ if (!mpe->minio)
+ return 0;
+
+ return snprintf(buff, len, "%u", mpe->minio);
+}
+
+static int
+snprint_hw_vendor (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->vendor)
+ return 0;
+
+ return snprintf(buff, len, "%s", hwe->vendor);
+}
+
+static int
+snprint_hw_product (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->product)
+ return 0;
+
+ return snprintf(buff, len, "%s", hwe->product);
+}
+
+static int
+snprint_hw_getuid_callout (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->getuid)
+ return 0;
+ if (strlen(hwe->getuid) == strlen(conf->default_getuid) &&
+ !strcmp(hwe->getuid, conf->default_getuid))
+ return 0;
+
+ return snprintf(buff, len, "%s", hwe->getuid);
+}
+
+static int
+snprint_hw_prio_callout (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->getprio)
+ return 0;
+ if (strlen(hwe->getprio) == strlen(conf->default_getprio) &&
+ !strcmp(hwe->getprio, conf->default_getprio))
+ return 0;
+
+ return snprintf(buff, len, "%s", hwe->getprio);
+}
+
+static int
+snprint_hw_features (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->features)
+ return 0;
+ if (strlen(hwe->features) == strlen(conf->features) &&
+ !strcmp(hwe->features, conf->features))
+ return 0;
+
+ return snprintf(buff, len, "%s", hwe->features);
+}
+
+static int
+snprint_hw_hardware_handler (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->hwhandler)
+ return 0;
+ if (strlen(hwe->hwhandler) == strlen(conf->default_hwhandler) &&
+ !strcmp(hwe->hwhandler, conf->default_hwhandler))
+ return 0;
+
+ return snprintf(buff, len, "%s", hwe->hwhandler);
+}
+
+static int
+snprint_hw_selector (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->selector)
+ return 0;
+ if (strlen(hwe->selector) == strlen(conf->selector) &&
+ !strcmp(hwe->selector, conf->selector))
+ return 0;
+
+ return snprintf(buff, len, "%s", hwe->selector);
+}
+
+static int
+snprint_hw_path_grouping_policy (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ char str[POLICY_NAME_SIZE];
+
+ if (!hwe->pgpolicy)
+ return 0;
+ if (hwe->pgpolicy == conf->default_pgpolicy)
+ return 0;
+
+ get_pgpolicy_name(str, POLICY_NAME_SIZE, hwe->pgpolicy);
+
+ return snprintf(buff, len, "%s", str);
+}
+
+static int
+snprint_hw_failback (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->pgfailback)
+ return 0;
+ if (hwe->pgfailback == conf->pgfailback)
+ return 0;
+
+ switch(hwe->pgfailback) {
+ case FAILBACK_UNDEF:
+ break;
+ case -FAILBACK_MANUAL:
+ return snprintf(buff, len, "manual");
+ case -FAILBACK_IMMEDIATE:
+ return snprintf(buff, len, "immediate");
+ default:
+ return snprintf(buff, len, "%i", hwe->pgfailback);
+ }
+ return 0;
+}
+
+static int
+snprint_hw_rr_weight (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->rr_weight)
+ return 0;
+ if (hwe->rr_weight == conf->rr_weight)
+ return 0;
+ if (hwe->rr_weight == RR_WEIGHT_PRIO)
+ return snprintf(buff, len, "priorities");
+
+ return 0;
+}
+
+static int
+snprint_hw_no_path_retry (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->no_path_retry)
+ return 0;
+ if (hwe->no_path_retry == conf->no_path_retry)
+ return 0;
+
+ switch(hwe->no_path_retry) {
+ case NO_PATH_RETRY_UNDEF:
+ break;
+ case NO_PATH_RETRY_FAIL:
+ return snprintf(buff, len, "fail");
+ case NO_PATH_RETRY_QUEUE:
+ return snprintf(buff, len, "queue");
+ default:
+ return snprintf(buff, len, "%i",
+ hwe->no_path_retry);
+ }
+ return 0;
+}
+
+static int
+snprint_hw_rr_min_io (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->minio)
+ return 0;
+ if (hwe->minio == conf->minio)
+ return 0;
+
+ return snprintf(buff, len, "%u", hwe->minio);
+}
+
+static int
+snprint_hw_path_checker (char * buff, int len, void * data)
+{
+ char str[CHECKER_NAME_SIZE];
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->checker_index)
+ return 0;
+ if (hwe->checker_index == conf->default_checker_index)
+ return 0;
+ get_checker_name(str, CHECKER_NAME_SIZE, hwe->checker_index);
+
+ return snprintf(buff, len, "%s", str);
+}
+
+static int
+snprint_def_polling_interval (char * buff, int len, void * data)
+{
+ if (conf->checkint == DEFAULT_CHECKINT)
+ return 0;
+ return snprintf(buff, len, "%i", conf->checkint);
+}
+
+static int
+snprint_def_udev_dir (char * buff, int len, void * data)
+{
+ if (!conf->udev_dir)
+ return 0;
+ if (strlen(DEFAULT_UDEVDIR) == strlen(conf->udev_dir) &&
+ !strcmp(conf->udev_dir, DEFAULT_UDEVDIR))
+ return 0;
+
+ return snprintf(buff, len, "%s", conf->udev_dir);
+}
+
+static int
+snprint_def_selector (char * buff, int len, void * data)
+{
+ if (!conf->selector)
+ return 0;
+ if (strlen(conf->selector) == strlen(DEFAULT_SELECTOR) &&
+ !strcmp(conf->selector, DEFAULT_SELECTOR))
+ return 0;
+
+ return snprintf(buff, len, "%s", conf->selector);
+}
+
+static int
+snprint_def_path_grouping_policy (char * buff, int len, void * data)
+{
+ char str[POLICY_NAME_SIZE];
+
+ if (!conf->default_pgpolicy)
+ return 0;
+ if (conf->default_pgpolicy == DEFAULT_PGPOLICY)
+ return 0;
+
+ get_pgpolicy_name(str, POLICY_NAME_SIZE, conf->default_pgpolicy);
+
+ return snprintf(buff, len, "%s", str);
+}
+
+static int
+snprint_def_getuid_callout (char * buff, int len, void * data)
+{
+ if (!conf->default_getuid)
+ return 0;
+ if (strlen(conf->default_getuid) == strlen(DEFAULT_GETUID) &&
+ !strcmp(conf->default_getuid, DEFAULT_GETUID))
+ return 0;
+
+ return snprintf(buff, len, "%s", conf->default_getuid);
+}
+
+static int
+snprint_def_getprio_callout (char * buff, int len, void * data)
+{
+ if (!conf->default_getprio)
+ return 0;
+#if 0 /* default is NULL */
+ if (strlen(conf->default_getprio) == strlen(DEFAULT_GETPRIO) &&
+ !strcmp(conf->default_getprio, DEFAULT_GETPRIO))
+ return 0;
+#endif
+
+ return snprintf(buff, len, "%s", conf->default_getprio);
+}
+
+static int
+snprint_def_features (char * buff, int len, void * data)
+{
+ if (!conf->features)
+ return 0;
+ if (strlen(conf->features) == strlen(DEFAULT_FEATURES) &&
+ !strcmp(conf->features, DEFAULT_FEATURES))
+ return 0;
+
+ return snprintf(buff, len, "%s", conf->features);
+}
+
+static int
+snprint_def_path_checker (char * buff, int len, void * data)
+{
+ char str[CHECKER_NAME_SIZE];
+
+ if (!conf->default_checker_index)
+ return 0;
+ if (conf->default_checker_index == DEFAULT_CHECKER_ID)
+ return 0;
+ get_checker_name(str, CHECKER_NAME_SIZE, conf->default_checker_index);
+
+ return snprintf(buff, len, "%s", str);
+}
+
+static int
+snprint_def_failback (char * buff, int len, void * data)
+{
+ if (!conf->pgfailback)
+ return 0;
+ if (conf->pgfailback == DEFAULT_FAILBACK)
+ return 0;
+
+ switch(conf->pgfailback) {
+ case FAILBACK_UNDEF:
+ break;
+ case -FAILBACK_MANUAL:
+ return snprintf(buff, len, "manual");
+ case -FAILBACK_IMMEDIATE:
+ return snprintf(buff, len, "immediate");
+ default:
+ return snprintf(buff, len, "%i", conf->pgfailback);
+ }
+ return 0;
+}
+
+static int
+snprint_def_rr_min_io (char * buff, int len, void * data)
+{
+ if (!conf->minio)
+ return 0;
+ if (conf->minio == DEFAULT_MINIO)
+ return 0;
+
+ return snprintf(buff, len, "%u", conf->minio);
+}
+
+static int
+snprint_def_rr_weight (char * buff, int len, void * data)
{
- keywords = vector_alloc();
+ if (!conf->rr_weight)
+ return 0;
+ if (conf->rr_weight == DEFAULT_RR_WEIGHT)
+ return 0;
+ if (conf->rr_weight == RR_WEIGHT_PRIO)
+ return snprintf(buff, len, "priorities");
+ return 0;
+}
+
+static int
+snprint_def_no_path_retry (char * buff, int len, void * data)
+{
+ if (conf->no_path_retry == DEFAULT_NO_PATH_RETRY)
+ return 0;
+
+ switch(conf->no_path_retry) {
+ case NO_PATH_RETRY_UNDEF:
+ break;
+ case NO_PATH_RETRY_FAIL:
+ return snprintf(buff, len, "fail");
+ case NO_PATH_RETRY_QUEUE:
+ return snprintf(buff, len, "queue");
+ default:
+ return snprintf(buff, len, "%i",
+ conf->no_path_retry);
+ }
+ return 0;
+}
+
+static int
+snprint_def_user_friendly_names (char * buff, int len, void * data)
+{
+ if (conf->user_friendly_names == DEFAULT_USER_FRIENDLY_NAMES)
+ return 0;
+ if (!conf->user_friendly_names)
+ return snprintf(buff, len, "no");
+
+ return snprintf(buff, len, "yes");
+}
+
+void
+init_keywords(void)
+{
install_keyword_root("defaults", NULL);
- install_keyword("polling_interval", &polling_interval_handler);
- install_keyword("udev_dir", &udev_dir_handler);
- install_keyword("selector", &def_selector_handler);
- install_keyword("path_grouping_policy", &def_pgpolicy_handler);
- install_keyword("getuid_callout", &def_getuid_callout_handler);
- install_keyword("prio_callout", &def_prio_callout_handler);
- install_keyword("features", &def_features_handler);
- install_keyword("path_checker", &def_path_checker_handler);
- install_keyword("failback", &default_failback_handler);
- install_keyword("rr_min_io", &def_minio_handler);
- install_keyword("rr_weight", &def_weight_handler);
- install_keyword("no_path_retry", &def_no_path_retry_handler);
- install_keyword("user_friendly_names", &names_handler);
+ install_keyword("polling_interval", &polling_interval_handler, &snprint_def_polling_interval);
+ install_keyword("udev_dir", &udev_dir_handler, &snprint_def_udev_dir);
+ install_keyword("selector", &def_selector_handler, &snprint_def_selector);
+ install_keyword("path_grouping_policy", &def_pgpolicy_handler, &snprint_def_path_grouping_policy);
+ install_keyword("getuid_callout", &def_getuid_callout_handler, &snprint_def_getuid_callout);
+ install_keyword("prio_callout", &def_prio_callout_handler, &snprint_def_getprio_callout);
+ install_keyword("features", &def_features_handler, &snprint_def_features);
+ install_keyword("path_checker", &def_path_checker_handler, &snprint_def_path_checker);
+ install_keyword("failback", &default_failback_handler, &snprint_def_failback);
+ install_keyword("rr_min_io", &def_minio_handler, &snprint_def_rr_min_io);
+ install_keyword("rr_weight", &def_weight_handler, &snprint_def_rr_weight);
+ install_keyword("no_path_retry", &def_no_path_retry_handler, &snprint_def_no_path_retry);
+ install_keyword("user_friendly_names", &names_handler, &snprint_def_user_friendly_names);
/*
* deprecated synonyms
*/
- install_keyword("default_selector", &def_selector_handler);
- install_keyword("default_path_grouping_policy", &def_pgpolicy_handler);
- install_keyword("default_getuid_callout", &def_getuid_callout_handler);
- install_keyword("default_prio_callout", &def_prio_callout_handler);
- install_keyword("default_features", &def_features_handler);
- install_keyword("default_path_checker", &def_path_checker_handler);
+ install_keyword("default_selector", &def_selector_handler, NULL);
+ install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
+ install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL);
+ install_keyword("default_prio_callout", &def_prio_callout_handler, NULL);
+ install_keyword("default_features", &def_features_handler, NULL);
+ install_keyword("default_path_checker", &def_path_checker_handler, NULL);
install_keyword_root("devnode_blacklist", &blacklist_handler);
- install_keyword("devnode", &ble_handler);
- install_keyword("wwid", &ble_handler);
+ install_keyword("devnode", &ble_handler, NULL);
+ install_keyword("wwid", &ble_handler, NULL);
install_keyword_root("devices", &devices_handler);
- install_keyword("device", &device_handler);
+ install_keyword("device", &device_handler, NULL);
install_sublevel();
- install_keyword("vendor", &vendor_handler);
- install_keyword("product", &product_handler);
- install_keyword("path_grouping_policy", &hw_pgpolicy_handler);
- install_keyword("getuid_callout", &hw_getuid_callout_handler);
- install_keyword("path_selector", &hw_selector_handler);
- install_keyword("path_checker", &hw_path_checker_handler);
- install_keyword("features", &hw_features_handler);
- install_keyword("hardware_handler", &hw_handler_handler);
- install_keyword("prio_callout", &prio_callout_handler);
- install_keyword("failback", &hw_failback_handler);
- install_keyword("rr_weight", &hw_weight_handler);
- install_keyword("no_path_retry", &hw_no_path_retry_handler);
- install_keyword("rr_min_io", &hw_minio_handler);
+ install_keyword("vendor", &vendor_handler, &snprint_hw_vendor);
+ install_keyword("product", &product_handler, &snprint_hw_product);
+ install_keyword("path_grouping_policy", &hw_pgpolicy_handler, &snprint_hw_path_grouping_policy);
+ install_keyword("getuid_callout", &hw_getuid_callout_handler, &snprint_hw_getuid_callout);
+ install_keyword("path_selector", &hw_selector_handler, &snprint_hw_selector);
+ install_keyword("path_checker", &hw_path_checker_handler, &snprint_hw_path_checker);
+ install_keyword("features", &hw_features_handler, &snprint_hw_features);
+ install_keyword("hardware_handler", &hw_handler_handler, &snprint_hw_hardware_handler);
+ install_keyword("prio_callout", &prio_callout_handler, &snprint_hw_prio_callout);
+ install_keyword("failback", &hw_failback_handler, &snprint_hw_failback);
+ install_keyword("rr_weight", &hw_weight_handler, &snprint_hw_rr_weight);
+ install_keyword("no_path_retry", &hw_no_path_retry_handler, &snprint_hw_no_path_retry);
+ install_keyword("rr_min_io", &hw_minio_handler, &snprint_hw_rr_min_io);
install_sublevel_end();
install_keyword_root("multipaths", &multipaths_handler);
- install_keyword("multipath", &multipath_handler);
+ install_keyword("multipath", &multipath_handler, NULL);
install_sublevel();
- install_keyword("wwid", &wwid_handler);
- install_keyword("alias", &alias_handler);
- install_keyword("path_grouping_policy", &mp_pgpolicy_handler);
- install_keyword("path_selector", &mp_selector_handler);
- install_keyword("failback", &mp_failback_handler);
- install_keyword("rr_weight", &mp_weight_handler);
- install_keyword("no_path_retry", &mp_no_path_retry_handler);
- install_keyword("rr_min_io", &mp_minio_handler);
+ install_keyword("wwid", &wwid_handler, &snprint_mp_wwid);
+ install_keyword("alias", &alias_handler, &snprint_mp_alias);
+ install_keyword("path_grouping_policy", &mp_pgpolicy_handler, &snprint_mp_path_grouping_policy);
+ install_keyword("path_selector", &mp_selector_handler, &snprint_mp_selector);
+ install_keyword("failback", &mp_failback_handler, &snprint_mp_failback);
+ install_keyword("rr_weight", &mp_weight_handler, &snprint_mp_rr_weight);
+ install_keyword("no_path_retry", &mp_no_path_retry_handler, &snprint_mp_no_path_retry);
+ install_keyword("rr_min_io", &mp_minio_handler, &snprint_mp_rr_min_io);
install_sublevel_end();
-
- return keywords;
}
diff --git a/libmultipath/dict.h b/libmultipath/dict.h
index ac35edc..5f77473 100644
--- a/libmultipath/dict.h
+++ b/libmultipath/dict.h
@@ -5,6 +5,6 @@
#include "vector.h"
#endif
-vector init_keywords(void);
+void init_keywords(void);
#endif /* _DICT_H */
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 7abda4e..ff6a12d 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -689,6 +689,8 @@ pathinfo (struct path *pp, vector hwtable, int mask)
if (mask & DI_CHECKER) {
if (!pp->checkfn)
select_checkfn(pp);
+ if (!pp->checkfn)
+ goto out;
pp->state = pp->checkfn(pp->fd, NULL, NULL);
condlog(3, "state = %i", pp->state);
diff --git a/libmultipath/parser.c b/libmultipath/parser.c
index ebb14cd..9b0b5c2 100644
--- a/libmultipath/parser.c
+++ b/libmultipath/parser.c
@@ -24,9 +24,11 @@
/* local vars */
static int sublevel = 0;
+vector keywords = NULL;
int
-keyword_alloc(vector keywords, char *string, int (*handler) (vector))
+keyword_alloc(vector keywords, char *string, int (*handler) (vector),
+ int (*print) (char *, int, void *))
{
struct keyword *keyword;
@@ -41,6 +43,7 @@ keyword_alloc(vector keywords, char *string, int (*handler) (vector))
}
keyword->string = string;
keyword->handler = handler;
+ keyword->print = print;
vector_set_slot(keywords, keyword);
@@ -50,7 +53,7 @@ keyword_alloc(vector keywords, char *string, int (*handler) (vector))
int
install_keyword_root(char *string, int (*handler) (vector))
{
- return keyword_alloc(keywords, string, handler);
+ return keyword_alloc(keywords, string, handler, NULL);
}
void
@@ -66,7 +69,8 @@ install_sublevel_end(void)
}
int
-install_keyword(char *string, int (*handler) (vector))
+install_keyword(char *string, int (*handler) (vector),
+ int (*print) (char *, int, void *))
{
int i = 0;
struct keyword *keyword;
@@ -87,7 +91,7 @@ install_keyword(char *string, int (*handler) (vector))
return 1;
/* add new sub keyword */
- return keyword_alloc(keyword->sub, string, handler);
+ return keyword_alloc(keyword->sub, string, handler, print);
}
void
@@ -105,6 +109,73 @@ free_keywords(vector keywords)
vector_free(keywords);
}
+struct keyword *
+find_keyword(vector v, char * name)
+{
+ struct keyword *keyword;
+ int i;
+ int len;
+
+ if (!name || !keywords)
+ return NULL;
+
+ if (!v)
+ v = keywords;
+
+ len = strlen(name);
+
+ for (i = 0; i < VECTOR_SIZE(v); i++) {
+ keyword = VECTOR_SLOT(v, i);
+ if ((strlen(keyword->string) == len) &&
+ !strcmp(keyword->string, name))
+ return keyword;
+ if (keyword->sub) {
+ keyword = find_keyword(keyword->sub, name);
+ if (keyword)
+ return keyword;
+ }
+ }
+ return NULL;
+}
+
+int
+snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, void *data)
+{
+ int r;
+ int fwd = 0;
+ char *f = fmt;
+
+ if (!kw || !kw->print)
+ return 0;
+
+ do {
+ if (fwd == len || *f == '\0')
+ break;
+ if (*f != '%') {
+ *(buff + fwd) = *f;
+ fwd++;
+ continue;
+ }
+ f++;
+ switch(*f) {
+ case 'k':
+ fwd += snprintf(buff + fwd, len - fwd, kw->string);
+ break;
+ case 'v':
+ r = kw->print(buff + fwd, len - fwd, data);
+ if (!r) { /* no output if no value */
+ buff = '\0';
+ return 0;
+ }
+ fwd += r;
+ break;
+ }
+ if (fwd > len)
+ fwd = len;
+ } while (*f++);
+ return fwd;
+}
+
vector
alloc_strvec(char *string)
{
@@ -373,10 +444,14 @@ process_stream(vector keywords)
/* Data initialization */
int
-init_data(char *conf_file, vector (*init_keywords) (void))
+init_data(char *conf_file, void (*init_keywords) (void))
{
int r;
+ if (!keywords)
+ keywords = vector_alloc();
+ if (!keywords)
+ return 1;
stream = fopen(conf_file, "r");
if (!stream) {
syslog(LOG_WARNING, "Configuration file open problem");
@@ -394,7 +469,7 @@ init_data(char *conf_file, vector (*init_keywords) (void))
/* Stream handling */
r = process_stream(keywords);
fclose(stream);
- free_keywords(keywords);
+ //free_keywords(keywords);
return r;
}
diff --git a/libmultipath/parser.h b/libmultipath/parser.h
index 7a6dd18..f0fdd94 100644
--- a/libmultipath/parser.h
+++ b/libmultipath/parser.h
@@ -42,24 +42,30 @@
struct keyword {
char *string;
int (*handler) (vector);
+ int (*print) (char *, int, void *);
vector sub;
};
+/* global var exported */
+FILE *stream;
+
/* Reloading helpers */
#define SET_RELOAD (reload = 1)
#define UNSET_RELOAD (reload = 0)
#define RELOAD_DELAY 5
-/* global var exported */
-vector keywords;
-FILE *stream;
+/* iterator helper */
+#define iterate_sub_keywords(k,p,i) \
+ for (i = 0; i < (k)->sub->allocated && ((p) = (k)->sub->slot[i]); i++)
/* Prototypes */
-extern int keyword_alloc(vector keywords, char *string, int (*handler) (vector));
+extern int keyword_alloc(vector keywords, char *string, int (*handler) (vector),
+ int (*print) (char *, int, void *));
extern int install_keyword_root(char *string, int (*handler) (vector));
extern void install_sublevel(void);
extern void install_sublevel_end(void);
-extern int install_keyword(char *string, int (*handler) (vector));
+extern int install_keyword(char *string, int (*handler) (vector),
+ int (*print) (char *, int, void *));
extern void dump_keywords(vector keydump, int level);
extern void free_keywords(vector keywords);
extern vector alloc_strvec(char *string);
@@ -68,6 +74,9 @@ extern vector read_value_block(void);
extern int alloc_value_block(vector strvec, void (*alloc_func) (vector));
extern void *set_value(vector strvec);
extern int process_stream(vector keywords);
-extern int init_data(char *conf_file, vector (*init_keywords) (void));
+extern int init_data(char *conf_file, void (*init_keywords) (void));
+extern struct keyword * find_keyword(vector v, char * name);
+int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw,
+ void *data);
#endif
diff --git a/libmultipath/print.c b/libmultipath/print.c
index 0cdf936..430aacb 100644
--- a/libmultipath/print.c
+++ b/libmultipath/print.c
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <string.h>
#include <libdevmapper.h>
+#include <stdarg.h>
#include "vector.h"
#include "structs.h"
@@ -11,9 +12,13 @@
#include "print.h"
#include "dmparser.h"
#include "configure.h"
+#include "config.h"
+#include "pgpolicies.h"
#include "defaults.h"
+#include "parser.h"
#include "../libcheckers/path_state.h"
+#include "../libcheckers/checkers.h"
#define MAX(x,y) (x > y) ? x : y
#define TAIL (line + len - 1 - c)
@@ -647,10 +652,8 @@ snprint_multipath_topology (char * buff, int len, struct multipath * mpp,
if (verbosity <= 0)
return fwd;
- if (verbosity == 1) {
- fwd += snprint_multipath(buff + fwd, len - fwd, "%n", mpp);
- return fwd;
- }
+ if (verbosity == 1)
+ return snprint_multipath(buff, len, "%n", mpp);
if (verbosity > 1 &&
mpp->action != ACT_NOTHING &&
@@ -663,8 +666,12 @@ snprint_multipath_topology (char * buff, int len, struct multipath * mpp,
c += sprintf(c, " (%%w)");
fwd += snprint_multipath(buff + fwd, len - fwd, style, mpp);
+ if (fwd > len)
+ return len;
fwd += snprint_multipath(buff + fwd, len - fwd,
"[size=%S][features=%f][hwhandler=%h]", mpp);
+ if (fwd > len)
+ return len;
if (!mpp->pg)
return fwd;
@@ -673,14 +680,182 @@ snprint_multipath_topology (char * buff, int len, struct multipath * mpp,
pgp->selector = mpp->selector; /* hack */
fwd += snprint_pathgroup(buff + fwd, len - fwd,
PRINT_PG_INDENT, pgp);
+ if (fwd > len)
+ return len;
- vector_foreach_slot (pgp->paths, pp, i)
+ vector_foreach_slot (pgp->paths, pp, i) {
fwd += snprint_path(buff + fwd, len - fwd,
PRINT_PATH_INDENT, pp);
+ if (fwd > len)
+ return len;
+ }
+ }
+ return fwd;
+}
+
+static int
+snprint_hwentry (char * buff, int len, struct hwentry * hwe)
+{
+ int i;
+ int fwd = 0;
+ struct keyword * kw;
+ struct keyword * rootkw;
+
+ rootkw = find_keyword(NULL, "device");
+
+ if (!rootkw)
+ return 0;
+
+ fwd += snprintf(buff + fwd, len - fwd, "\tdevice {\n");
+ if (fwd > len)
+ return len;
+ iterate_sub_keywords(rootkw, kw, i) {
+ fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
+ kw, hwe);
+ if (fwd > len)
+ return len;
+ }
+ fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
+ if (fwd > len)
+ return len;
+ return fwd;
+}
+
+extern int
+snprint_hwtable (char * buff, int len, vector hwtable)
+{
+ int fwd = 0;
+ int i;
+ struct hwentry * hwe;
+ struct keyword * rootkw;
+
+ rootkw = find_keyword(NULL, "devices");
+ if (!rootkw)
+ return 0;
+
+ fwd += snprintf(buff + fwd, len - fwd, "devices {\n");
+ if (fwd > len)
+ return len;
+ vector_foreach_slot (hwtable, hwe, i) {
+ fwd += snprint_hwentry(buff + fwd, len - fwd, hwe);
+ if (fwd > len)
+ return len;
+ }
+ fwd += snprintf(buff + fwd, len - fwd, "}\n");
+ if (fwd > len)
+ return len;
+ return fwd;
+}
+
+static int
+snprint_mpentry (char * buff, int len, struct mpentry * mpe)
+{
+ int i;
+ int fwd = 0;
+ struct keyword * kw;
+ struct keyword * rootkw;
+
+ rootkw = find_keyword(NULL, "multipath");
+ if (!rootkw)
+ return 0;
+
+ fwd += snprintf(buff + fwd, len - fwd, "\tmultipath {\n");
+ if (fwd > len)
+ return len;
+ iterate_sub_keywords(rootkw, kw, i) {
+ fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
+ kw, mpe);
+ if (fwd > len)
+ return len;
}
+ fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
+ if (fwd > len)
+ return len;
return fwd;
}
+extern int
+snprint_mptable (char * buff, int len, vector mptable)
+{
+ int fwd = 0;
+ int i;
+ struct mpentry * mpe;
+ struct keyword * rootkw;
+
+ rootkw = find_keyword(NULL, "multipaths");
+ if (!rootkw)
+ return 0;
+
+ fwd += snprintf(buff + fwd, len - fwd, "multipaths {\n");
+ if (fwd > len)
+ return len;
+ vector_foreach_slot (mptable, mpe, i) {
+ fwd += snprint_mpentry(buff + fwd, len - fwd, mpe);
+ if (fwd > len)
+ return len;
+ }
+ fwd += snprintf(buff + fwd, len - fwd, "}\n");
+ if (fwd > len)
+ return len;
+ return fwd;
+}
+
+extern int
+snprint_defaults (char * buff, int len)
+{
+ int fwd = 0;
+ int i;
+ struct keyword *rootkw;
+ struct keyword *kw;
+
+ rootkw = find_keyword(NULL, "defaults");
+ if (!rootkw)
+ return 0;
+
+ fwd += snprintf(buff + fwd, len - fwd, "defaults {\n");
+ if (fwd > len)
+ return len;
+
+ iterate_sub_keywords(rootkw, kw, i) {
+ fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
+ kw, NULL);
+ if (fwd > len)
+ return len;
+ }
+ fwd += snprintf(buff + fwd, len - fwd, "}\n");
+ if (fwd > len)
+ return len;
+ return fwd;
+
+}
+
+extern int
+snprint_blacklist (char * buff, int len)
+{
+ int fwd = 0;
+ struct keyword *rootkw;
+
+ rootkw = find_keyword(NULL, "devnode_blacklist");
+ if (!rootkw)
+ return 0;
+
+ fwd += snprintf(buff + fwd, len - fwd, "devnode_blacklist {\n");
+ if (fwd > len)
+ return len;
+
+ fwd += snprintf(buff + fwd, len - fwd, "}\n");
+ if (fwd > len)
+ return len;
+ return fwd;
+
+}
+
+extern int
+snprint_config (char * buff, int len)
+{
+ return 0;
+}
+
/*
* stdout printing helpers
*/
diff --git a/libmultipath/print.h b/libmultipath/print.h
index ea7f3ba..dd97cea 100644
--- a/libmultipath/print.h
+++ b/libmultipath/print.h
@@ -40,6 +40,9 @@ int snprint_path (char *, int, char *, struct path *);
int snprint_multipath (char *, int, char *, struct multipath *);
int snprint_multipath_topology (char *, int, struct multipath * mpp,
int verbosity);
+int snprint_defaults (char *, int);
+int snprint_hwtable (char *, int, vector);
+int snprint_mptable (char *, int, vector);
void print_multipath_topology (struct multipath * mpp, int verbosity);
void print_path (struct path * pp, char * style);
@@ -47,3 +50,5 @@ void print_multipath (struct multipath * mpp, char * style);
void print_pathgroup (struct pathgroup * pgp, char * style);
void print_map (struct multipath * mpp);
void print_all_paths (vector pathvec, int banner);
+void print_hwtable (vector hwtable);
+