diff options
author | Benjamin Marzinski <bmarzins@redhat.com> | 2009-05-13 23:38:28 -0500 |
---|---|---|
committer | Christophe Varoqui <christophe.varoqui@free.fr> | 2009-05-14 23:02:08 +0200 |
commit | 827b267616cab50d04aa9e117e10819687d63084 (patch) | |
tree | 18922786b889c22f33a285b67e625d39dc42a01c | |
parent | 69d094b4b8b2801cbe4e41d8adc12bce296d6d4d (diff) | |
download | multipath-tools-827b267616cab50d04aa9e117e10819687d63084.tar.gz multipath-tools-827b267616cab50d04aa9e117e10819687d63084.tar.bz2 multipath-tools-827b267616cab50d04aa9e117e10819687d63084.zip |
multipath-tools: Improvement to max_fds
Setting max_fds to unlimited doesn't actually work. In the kernel, there is a
fixed limit to the maximum number of open fds a process can have. If you try
to set max_fds to greater than this, it fails. This patch replaces the special
value "unlimited" with a new special value, "max". If you set max_fds to "max",
multipath will use the actual system limit, which it looks up from
/proc/sys/fs/nr_open.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
-rw-r--r-- | libmultipath/dict.c | 40 | ||||
-rw-r--r-- | libmultipath/structs.h | 1 | ||||
-rw-r--r-- | multipath.conf.annotated | 2 | ||||
-rw-r--r-- | multipath/main.c | 11 | ||||
-rw-r--r-- | multipath/multipath.conf.5 | 8 | ||||
-rw-r--r-- | multipathd/main.c | 11 |
6 files changed, 49 insertions, 24 deletions
diff --git a/libmultipath/dict.c b/libmultipath/dict.c index 2902e89..ee4de68 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c @@ -19,6 +19,7 @@ #include "blacklist.h" #include "defaults.h" #include "prio.h" +#include "errno.h" /* * default block handlers @@ -156,23 +157,52 @@ def_minio_handler(vector strvec) } static int +get_sys_max_fds(int *max_fds) +{ + FILE *file; + int nr_open; + int ret = 1; + + file = fopen("/proc/sys/fs/nr_open", "r"); + if (!file) { + fprintf(stderr, "Cannot open /proc/sys/fs/nr_open : %s\n", + strerror(errno)); + return 1; + } + if (fscanf(file, "%d", &nr_open) != 1) { + fprintf(stderr, "Cannot read max open fds from /proc/sys/fs/nr_open"); + if (ferror(file)) + fprintf(stderr, " : %s\n", strerror(errno)); + else + fprintf(stderr, "\n"); + } else { + *max_fds = nr_open; + ret = 0; + } + fclose(file); + return ret; +} + + +static int max_fds_handler(vector strvec) { char * buff; + int r = 0; buff = set_value(strvec); if (!buff) return 1; - if (strlen(buff) == 9 && - !strcmp(buff, "unlimited")) - conf->max_fds = MAX_FDS_UNLIMITED; + if (strlen(buff) == 3 && + !strcmp(buff, "max")) + r = get_sys_max_fds(&conf->max_fds); else conf->max_fds = atoi(buff); FREE(buff); - return 0; + return r; } static int @@ -1755,8 +1785,6 @@ 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); } diff --git a/libmultipath/structs.h b/libmultipath/structs.h index f7eca60..aafadba 100644 --- a/libmultipath/structs.h +++ b/libmultipath/structs.h @@ -24,7 +24,6 @@ #define NO_PATH_RETRY_FAIL -1 #define NO_PATH_RETRY_QUEUE -2 -#define MAX_FDS_UNLIMITED -1 enum free_path_switch { KEEP_PATHS, diff --git a/multipath.conf.annotated b/multipath.conf.annotated index 1b8f7cc..2374d56 100644 --- a/multipath.conf.annotated +++ b/multipath.conf.annotated @@ -113,7 +113,7 @@ # # scope : multipathd # # desc : Sets the maximum number of open file descriptors for the # # multipathd process. -# # values : unlimited|n > 0 +# # values : max|n > 0 # # default : None # # # max_fds 8192 diff --git a/multipath/main.c b/multipath/main.c index 707e2b9..d72e242 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -428,14 +428,9 @@ main (int argc, char *argv[]) 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; - } + + fd_limit.rlim_cur = conf->max_fds; + fd_limit.rlim_max = conf->max_fds; if (setrlimit(RLIMIT_NOFILE, &fd_limit) < 0) condlog(0, "can't set open fds limit to %d : %s\n", conf->max_fds, strerror(errno)); diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 index 6b1be81..df1f3b4 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 @@ -230,6 +230,14 @@ use the WWID as the alias. In either case this be will be overriden by any specific aliases in the \fImultipaths\fR section. Default is .I no +.TP +.B max_fds +Specify the maximum number of file descriptors that can be opened by multipath +and multipathd. This is equivalent to ulimit -n. A value of \fImax\fR will set +this to the system limit from /proc/sys/fs/nr_open. If this is not set, the +maximum number of open fds is taken from the calling process. It is usually +1024. To be safe, this should be set to the maximum number of paths plus 32, +if that number is greated than 1024. . .SH "blacklist section" The diff --git a/multipathd/main.c b/multipathd/main.c index dfa1098..41a9bd0 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -1373,14 +1373,9 @@ child (void * param) 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; - } + + fd_limit.rlim_cur = conf->max_fds; + fd_limit.rlim_max = conf->max_fds; if (setrlimit(RLIMIT_NOFILE, &fd_limit) < 0) condlog(0, "can't set open fds limit to %d : %s\n", conf->max_fds, strerror(errno)); |