Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:Test
multipath-tools
multipath-tools-implement-dev_loss_tmo
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File multipath-tools-implement-dev_loss_tmo of Package multipath-tools
From 4c6e3b7eff9825353610bfc3130276e6f5233247 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke <hare@suse.de> Date: Tue, 13 Jan 2009 16:01:30 +0100 Subject: [PATCH] Implement dev_loss_tmo and fast_io_fail_tmo When using multipath the 'dev_loss_tmo' and 'fast_io_fail_tmo' settings should be as small as possible to avoid any stalls in multipathd. So we should be able to configure both from within mulitpath. Signed-off-by: Hannes Reinecke <hare@suse.de> --- libmultipath/config.c | 2 + libmultipath/config.h | 4 + libmultipath/dict.c | 144 ++++++++++++++++++++++++++++++++++++++++++++ libmultipath/discovery.c | 104 +++++++++++++++++++++++++++++++ libmultipath/discovery.h | 1 + libmultipath/structs_vec.c | 6 ++ multipath/multipath.conf.5 | 12 ++++ 7 files changed, 273 insertions(+), 0 deletions(-) diff --git a/libmultipath/config.c b/libmultipath/config.c index 83da6e7..ea7ad99 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c @@ -463,6 +463,8 @@ load_config (char * file) conf->dev_type = DEV_NONE; conf->minio = 1000; conf->max_fds = 0; + conf->dev_loss_tmo = 0; + conf->fast_io_fail_tmo = 0; conf->multipath_dir = set_default(DEFAULT_MULTIPATHDIR); /* diff --git a/libmultipath/config.h b/libmultipath/config.h index fc0e22d..7d23927 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -29,6 +29,8 @@ struct hwentry { int no_path_retry; int minio; int pg_timeout; + int dev_loss_tmo; + int fast_io_fail_tmo; char * bl_product; }; @@ -67,6 +69,8 @@ struct config { int pg_timeout; int max_fds; int force_reload; + int dev_loss_tmo; + int fast_io_fail_tmo; char * dev; char * sysfs_dir; diff --git a/libmultipath/dict.c b/libmultipath/dict.c index 09ecf51..ed77000 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c @@ -189,6 +189,46 @@ max_fds_handler(vector strvec) } static int +def_dev_loss_tmo_handler(vector strvec) +{ + char * buff; + + buff = set_value(strvec); + + if (!buff) + return 1; + + if (strlen(buff) == 9 && + !strcmp(buff, "off")) + conf->dev_loss_tmo = -1; + else + conf->dev_loss_tmo = atoi(buff); + FREE(buff); + + return 0; +} + +static int +def_fast_io_fail_tmo_handler(vector strvec) +{ + char * buff; + + buff = set_value(strvec); + + if (!buff) + return 1; + + if (strlen(buff) == 9 && + !strcmp(buff, "off")) + conf->fast_io_fail_tmo = -1; + else + conf->fast_io_fail_tmo = atoi(buff); + FREE(buff); + + return 0; +} + +static int def_weight_handler(vector strvec) { char * buff; @@ -779,6 +819,54 @@ hw_pg_timeout_handler(vector strvec) return 0; } +static int +hw_dev_loss_tmo_handler(vector strvec) +{ + struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); + char * buff; + + if (!hwe) + return 1; + + buff = set_value(strvec); + + if (!buff) + return 1; + + if (strlen(buff) == 9 && + !strcmp(buff, "off")) + hwe->dev_loss_tmo = -1; + else + hwe->dev_loss_tmo = atoi(buff); + FREE(buff); + + return 0; +} + +static int +hw_fast_io_fail_tmo_handler(vector strvec) +{ + struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); + char * buff; + + if (!hwe) + return 1; + + buff = set_value(strvec); + + if (!buff) + return 1; + + if (strlen(buff) == 9 && + !strcmp(buff, "off")) + hwe->fast_io_fail_tmo = -1; + else + hwe->fast_io_fail_tmo = atoi(buff); + FREE(buff); + + return 0; +} + /* * multipaths block handlers */ @@ -1406,6 +1494,36 @@ snprint_hw_path_checker (char * buff, int len, void * data) } static int +snprint_hw_dev_loss_tmo (char * buff, int len, void * data) +{ + struct hwentry * hwe = (struct hwentry *)data; + + if (!hwe->dev_loss_tmo) + return 0; + if (hwe->dev_loss_tmo == conf->dev_loss_tmo) + return 0; + + if (hwe->dev_loss_tmo < 0) + return snprintf(buff, len, "off"); + return snprintf(buff, len, "%u", hwe->dev_loss_tmo); +} + +static int +snprint_hw_fast_io_fail_tmo (char * buff, int len, void * data) +{ + struct hwentry * hwe = (struct hwentry *)data; + + if (!hwe->fast_io_fail_tmo) + return 0; + if (hwe->fast_io_fail_tmo == conf->fast_io_fail_tmo) + return 0; + + if (hwe->fast_io_fail_tmo < 0) + return snprintf(buff, len, "off"); + return snprintf(buff, len, "%u", hwe->fast_io_fail_tmo); +} + +static int snprint_def_polling_interval (char * buff, int len, void * data) { if (conf->checkint == DEFAULT_CHECKINT) @@ -1565,6 +1683,28 @@ snprint_max_fds (char * buff, int len, void * data) } static int +snprint_def_dev_loss_tmo (char * buff, int len, void * data) +{ + if (!conf->dev_loss_tmo) + return 0; + + if (conf->dev_loss_tmo < 0) + return snprintf(buff, len, "off"); + return snprintf(buff, len, "%d", conf->dev_loss_tmo); +} + +static int +snprint_def_fast_io_fail_tmo (char * buff, int len, void * data) +{ + if (!conf->fast_io_fail_tmo) + return 0; + + if (conf->fast_io_fail_tmo < 0) + return snprintf(buff, len, "off"); + return snprintf(buff, len, "%d", conf->fast_io_fail_tmo); +} + +static int snprint_def_rr_weight (char * buff, int len, void * data) { if (!conf->rr_weight) @@ -1681,6 +1821,8 @@ init_keywords(void) install_keyword("failback", &default_failback_handler, &snprint_def_failback); install_keyword("rr_min_io", &def_minio_handler, &snprint_def_rr_min_io); install_keyword("max_fds", &max_fds_handler, &snprint_max_fds); + install_keyword("dev_loss_tmo", &def_dev_loss_tmo_handler, &snprint_def_dev_loss_tmo); + install_keyword("fast_io_fail_tmo", &def_fast_io_fail_tmo_handler, &snprint_def_fast_io_fail_tmo); 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("pg_timeout", &def_pg_timeout_handler, &snprint_def_pg_timeout); @@ -1739,6 +1881,8 @@ init_keywords(void) 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_keyword("pg_timeout", &hw_pg_timeout_handler, &snprint_hw_pg_timeout); + install_keyword("dev_loss_tmo", &hw_dev_loss_tmo_handler, &snprint_hw_dev_loss_tmo); + install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_tmo_handler, &snprint_hw_fast_io_fail_tmo); install_sublevel_end(); install_keyword_root("multipaths", &multipaths_handler); diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index afd247d..6e4ce1e 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -209,6 +209,110 @@ sysfs_get_fc_nodename (struct sysfs_device * dev, char * node, return 1; } +int +sysfs_set_fc_values (struct path *pp, int dev_loss_tmo, int fast_io_fail_tmo) +{ + char attr_path[SYSFS_PATH_SIZE]; + char host_path[SYSFS_PATH_SIZE]; + char attr_value[NAME_SIZE]; + DIR *host_dir, *rport_dir; + struct dirent *host_ent, *rport_ent; + int host, channel, lun, port, num; + int rport_channel = -1; + int rport_id = -1; + + if (dev_loss_tmo == 0 || fast_io_fail_tmo == 0) { + condlog(4, "%s: no FC settings", pp->dev); + return 0; + } + + if (safe_sprintf(host_path, "/sys/class/fc_host/host%i/device", + pp->sg_id.host_no)) { + condlog(0, "host_path too small"); + return 1; + } + if (!(host_dir = opendir(host_path))) { + condlog(3, "host %d not a FC HBA", pp->sg_id.host_no); + return 0; + } + + while (rport_channel < 0 && rport_id < 0 && + (host_ent = readdir(host_dir))) { + if (sscanf(host_ent->d_name, "rport-%d:%d-%d", + &host, &port, &num) != 3) + continue; + + if (host != pp->sg_id.host_no) + continue; + + if (safe_sprintf(attr_path, "%s/%s", + host_path, host_ent->d_name)) { + condlog(0, "target_path too small"); + continue; + } + + if (!(rport_dir = opendir(attr_path))) { + condlog(1, "cannot open rport path '%s'", attr_path); + continue; + } + + while ((rport_ent = readdir(rport_dir))) { + if (sscanf(rport_ent->d_name, "target%d:%d:%d", + &host, &channel, &lun) != 3) + continue; + + if (host != pp->sg_id.host_no && + channel != pp->sg_id.channel && + lun != pp->sg_id.scsi_id) + continue; + + rport_channel = port; + rport_id = num; + break; + } + } + + if (rport_channel < 0 && rport_id < 0) { + condlog(1, "No rport found"); + return 0; + } + + if (safe_sprintf(attr_path, + "/class/fc_remote_ports/rport-%d:%d-%d", + pp->sg_id.host_no, rport_channel, rport_id)) { + condlog(0, "attr_path too small"); + return 0; + } + + if (dev_loss_tmo < 0) + sprintf(attr_value, "%d", 0); + else + sprintf(attr_value, "%d", dev_loss_tmo); + num = sysfs_attr_set_value(attr_path, "dev_loss_tmo", + attr_value, strlen(attr_value)); + if (num > 0) + condlog(4, "%s: set dev_loss_tmo to %d", pp->dev, + dev_loss_tmo); + else + condlog(4, "%s: failed to set dev_loss_tmo (%d)", + pp->dev, errno); + + if (fast_io_fail_tmo < 0) + sprintf(attr_value, "%d", 0); + else + sprintf(attr_value, "%d", fast_io_fail_tmo); + num = sysfs_attr_set_value(attr_path, "fast_io_fail_tmo", + attr_value, strlen(attr_value)); + if (num > 0) + condlog(4, "%s: set fast_io_fail_tmo to %d", pp->dev, + fast_io_fail_tmo); + else + condlog(4, "%s: failed to set fast_io_fail_tmo (%d)", + pp->dev, errno); + + return num == strlen(attr_value) ? 0 : 1; +} + static int opennode (char * dev, int mode) { diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h index 05b1cfe..3749674 100644 --- a/libmultipath/discovery.h +++ b/libmultipath/discovery.h @@ -32,6 +32,7 @@ int devt2devname (char *, char *); int pathinfo (struct path *, vector hwtable, int mask); struct path * store_pathinfo (vector pathvec, vector hwtable, char * devname, int flag); +int sysfs_set_fc_values (struct path *pp, int dev_loss_tmo, int fast_io_fail_tmo); /* * discovery bitmask diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c index a1d9632..1632c9d 100644 --- a/libmultipath/structs_vec.c +++ b/libmultipath/structs_vec.c @@ -479,6 +479,12 @@ verify_paths(struct multipath * mpp, struct vectors * vecs, vector rpvec) free_path(pp); } } else { + if (pp->hwe) + sysfs_set_fc_values(pp, pp->hwe->dev_loss_tmo, + pp->hwe->fast_io_fail_tmo); + else + sysfs_set_fc_values(pp, conf->dev_loss_tmo, + conf->fast_io_fail_tmo); condlog(4, "%s: verified path %s dev_t %s", mpp->alias, pp->dev, pp->dev_t); } diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 index 8ac1f1c..926ff69 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 @@ -263,6 +263,14 @@ Default is .B bindings_file The full pathname of the binding file to be used when the user_friendly_names option is set. Defaults to .I /var/lib/multipath/bindings +.TP +.B dev_loss_tmo +The default dev_loss_tmo setting for an FC remote port in seconds. If an rport has vanished from the fabric all devices on that port will be removed from sysfs after this timeout. +.TP +.B fast_io_fail_tmo +The default fast_io_fail_tmo setting for an FC remote port in seconds. If an rport has vanished from the fabric all I/O to the devices on that port will be terminated after this timeout. Should be smaller than +.B dev_loss_tmo +setting. . .SH "blacklist section" The @@ -413,6 +421,10 @@ section: .B no_path_retry .TP .B rr_min_io +.TP +.B dev_loss_tmo +.TP +.B fast_io_fail_tmo .RE .PD .LP -- 1.5.3.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor