From: Benjamin Marzinski Date: Tue, 15 Jan 2008 22:59:04 +0000 (+0100) Subject: [libmultipath] fix the "too many files" error X-Git-Tag: 0.4.9~241 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4ced5657f5361cca01bf8a84abb226b28dc19f47;p=platform%2Fupstream%2Fmultipath-tools.git [libmultipath] fix the "too many files" error Added a max_fds parameter to /etc/multipath.conf. This allows you to set the maximum number of open fds that multipathd can use, like with ulimit -n. Also added some code so that multipath closes the file descriptor after it's used by the checker function, since multipath doesn't need to keep them always open like multipathd does. --- diff --git a/libmultipath/config.c b/libmultipath/config.c index 619b6e7..b6d4fb9 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c @@ -354,6 +354,7 @@ load_config (char * file) conf->dev_type = DEV_NONE; conf->minio = 1000; + conf->max_fds = 0; conf->bindings_file = DEFAULT_BINDINGS_FILE; /* diff --git a/libmultipath/config.h b/libmultipath/config.h index 7f7b2a9..7568d7b 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -66,6 +66,7 @@ struct config { int no_path_retry; int user_friendly_names; int pg_timeout; + int max_fds; char * dev; char * sysfs_dir; diff --git a/libmultipath/dict.c b/libmultipath/dict.c index 6ed5cfd..fa37ee8 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c @@ -140,6 +140,26 @@ def_minio_handler(vector strvec) } static int +max_fds_handler(vector strvec) +{ + char * buff; + + buff = set_value(strvec); + + if (!buff) + return 1; + + if (strlen(buff) == 9 && + !strcmp(buff, "unlimited")) + conf->max_fds = MAX_FDS_UNLIMITED; + else + conf->max_fds = atoi(buff); + FREE(buff); + + return 0; +} + +static int def_weight_handler(vector strvec) { char * buff; @@ -1416,6 +1436,17 @@ snprint_def_rr_min_io (char * buff, int len, void * data) } static int +snprint_max_fds (char * buff, int len, void * data) +{ + if (!conf->max_fds) + return 0; + + if (conf->max_fds < 0) + return snprintf(buff, len, "unlimited"); + return snprintf(buff, len, "%d", conf->max_fds); +} + +static int snprint_def_rr_weight (char * buff, int len, void * data) { if (!conf->rr_weight) @@ -1516,6 +1547,7 @@ init_keywords(void) 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("max_fds", &max_fds_handler, &snprint_max_fds); 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); diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index 805d0b6..a85a248 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -714,6 +714,10 @@ pathinfo (struct path *pp, vector hwtable, int mask) if (mask & DI_WWID && !strlen(pp->wwid)) get_uid(pp); +#ifndef DAEMON + close(pp->fd); + pp->fd = -1; +#endif return 0; blank: @@ -722,5 +726,11 @@ blank: */ memset(pp->wwid, 0, WWID_SIZE); pp->state = PATH_DOWN; +#ifndef DAEMON + if (pp->fd > 0){ + close(pp->fd); + pp->fd = -1; + } +#endif return 0; } diff --git a/libmultipath/structs.h b/libmultipath/structs.h index 8e9ac86..2517782 100644 --- a/libmultipath/structs.h +++ b/libmultipath/structs.h @@ -21,6 +21,8 @@ #define NO_PATH_RETRY_FAIL -1 #define NO_PATH_RETRY_QUEUE -2 +#define MAX_FDS_UNLIMITED -1 + enum free_path_switch { KEEP_PATHS, FREE_PATHS diff --git a/multipath.conf.annotated b/multipath.conf.annotated index f617876..dc7af77 100644 --- a/multipath.conf.annotated +++ b/multipath.conf.annotated @@ -80,6 +80,16 @@ # rr_min_io 100 # # # +# # name : max_fds +# # scope : multipathd +# # desc : Sets the maximum number of open file descriptors for the +# # multipathd process. +# # values : unlimited|n > 0 +# # default : None +# # +# max_fds 8192 +# +# # # # name : rr_weight # # scope : multipath # # desc : if set to priorities the multipath configurator will assign diff --git a/multipath.conf.synthetic b/multipath.conf.synthetic index 0c05b4c..33f820b 100644 --- a/multipath.conf.synthetic +++ b/multipath.conf.synthetic @@ -11,6 +11,7 @@ # prio const # path_checker directio # rr_min_io 100 +# max_fds 8192 # rr_weight priorities # failback immediate # no_path_retry fail diff --git a/multipathd/main.c b/multipathd/main.c index e65834a..d30ba83 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include /* * libcheckers @@ -1283,6 +1285,21 @@ child (void * param) conf->max_checkint = MAX_CHECKINT(conf->checkint); } + if (conf->max_fds) { + struct rlimit fd_limit; + if (conf->max_fds > 0) { + fd_limit.rlim_cur = conf->max_fds; + fd_limit.rlim_max = conf->max_fds; + } + else { + fd_limit.rlim_cur = RLIM_INFINITY; + fd_limit.rlim_max = RLIM_INFINITY; + } + if (setrlimit(RLIMIT_NOFILE, &fd_limit) < 0) + condlog(0, "can't set open fds limit to %d : %s\n", + conf->max_fds, strerror(errno)); + } + if (pidfile_create(DEFAULT_PIDFILE, getpid())) { if (logsink) log_thread_stop();