summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2009-05-13 23:38:28 -0500
committerChristophe Varoqui <christophe.varoqui@free.fr>2009-05-14 23:02:08 +0200
commit827b267616cab50d04aa9e117e10819687d63084 (patch)
tree18922786b889c22f33a285b67e625d39dc42a01c
parent69d094b4b8b2801cbe4e41d8adc12bce296d6d4d (diff)
downloadmultipath-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.c40
-rw-r--r--libmultipath/structs.h1
-rw-r--r--multipath.conf.annotated2
-rw-r--r--multipath/main.c11
-rw-r--r--multipath/multipath.conf.58
-rw-r--r--multipathd/main.c11
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));