summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Aksola <aakso@iki.fi>2016-09-20 06:01:27 +0000
committerStephen Hemminger <stephen@networkplumber.org>2016-10-09 18:56:47 -0700
commite29a8e0537c419aa0a612db39b0feb45148a8350 (patch)
treeb724362b519f57627f7a008a1968005814dd9ac3
parentd99272470a0f691d592626d4d33fedf6cb647f92 (diff)
iproute2: build nsid-name cache only for commands that need it
The calling of netns_map_init() before command parsing introduced a performance issue with large number of namespaces. As commands such as add, del and exec do not need to iterate through /var/run/netns it would be good not no build the cache before executing these commands. Example: unpatched: time seq 1 1000 | xargs -n 1 ip netns add real 0m16.832s user 0m1.350s sys 0m15.029s patched: time seq 1 1000 | xargs -n 1 ip netns add real 0m3.859s user 0m0.132s sys 0m3.205s Signed-off-by: Anton Aksola <aakso@iki.fi> Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
-rw-r--r--ip/ip_common.h1
-rw-r--r--ip/ipmonitor.c1
-rw-r--r--ip/ipnetns.c31
-rwxr-xr-xtestsuite/tests/ip/netns/set_nsid.t22
-rwxr-xr-xtestsuite/tests/ip/netns/set_nsid_batch.t18
5 files changed, 64 insertions, 9 deletions
diff --git a/ip/ip_common.h b/ip/ip_common.h
index 1c1cbdf0..0147f45a 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -31,6 +31,7 @@ int print_netconf(const struct sockaddr_nl *who,
struct rtnl_ctrl_data *ctrl,
struct nlmsghdr *n, void *arg);
void netns_map_init(void);
+void netns_nsid_socket_init(void);
int print_nsid(const struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg);
int do_ipaddr(int argc, char **argv);
diff --git a/ip/ipmonitor.c b/ip/ipmonitor.c
index 2090a45d..c892b8f1 100644
--- a/ip/ipmonitor.c
+++ b/ip/ipmonitor.c
@@ -301,6 +301,7 @@ int do_ipmonitor(int argc, char **argv)
exit(1);
ll_init_map(&rth);
+ netns_nsid_socket_init();
netns_map_init();
if (rtnl_listen(&rth, accept_msg, stdout) < 0)
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index ccc652c1..bd1e9013 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -194,6 +194,18 @@ static void netns_map_del(struct nsid_cache *c)
free(c);
}
+void netns_nsid_socket_init(void)
+{
+ if (rtnsh.fd > -1 || !ipnetns_have_nsid())
+ return;
+
+ if (rtnl_open(&rtnsh, 0) < 0) {
+ fprintf(stderr, "Cannot open rtnetlink\n");
+ exit(1);
+ }
+
+}
+
void netns_map_init(void)
{
static int initialized;
@@ -204,11 +216,6 @@ void netns_map_init(void)
if (initialized || !ipnetns_have_nsid())
return;
- if (rtnl_open(&rtnsh, 0) < 0) {
- fprintf(stderr, "Cannot open rtnetlink\n");
- exit(1);
- }
-
dir = opendir(NETNS_RUN_DIR);
if (!dir)
return;
@@ -775,17 +782,23 @@ static int netns_monitor(int argc, char **argv)
int do_netns(int argc, char **argv)
{
- netns_map_init();
+ netns_nsid_socket_init();
- if (argc < 1)
+ if (argc < 1) {
+ netns_map_init();
return netns_list(0, NULL);
+ }
if ((matches(*argv, "list") == 0) || (matches(*argv, "show") == 0) ||
- (matches(*argv, "lst") == 0))
+ (matches(*argv, "lst") == 0)) {
+ netns_map_init();
return netns_list(argc-1, argv+1);
+ }
- if ((matches(*argv, "list-id") == 0))
+ if ((matches(*argv, "list-id") == 0)) {
+ netns_map_init();
return netns_list_id(argc-1, argv+1);
+ }
if (matches(*argv, "help") == 0)
return usage();
diff --git a/testsuite/tests/ip/netns/set_nsid.t b/testsuite/tests/ip/netns/set_nsid.t
new file mode 100755
index 00000000..606d45ab
--- /dev/null
+++ b/testsuite/tests/ip/netns/set_nsid.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+source lib/generic.sh
+
+ts_log "[Testing netns nsid]"
+
+NS=testnsid
+NSID=99
+
+ts_ip "$0" "Add new netns $NS" netns add $NS
+ts_ip "$0" "Set $NS nsid to $NSID" netns set $NS $NSID
+
+ts_ip "$0" "List netns" netns list
+test_on "$NS \(id: $NSID\)"
+
+ts_ip "$0" "List netns without explicit list or show" netns
+test_on "$NS \(id: $NSID\)"
+
+ts_ip "$0" "List nsid" netns list-id
+test_on "$NSID \(iproute2 netns name: $NS\)"
+
+ts_ip "$0" "Delete netns $NS" netns del $NS
diff --git a/testsuite/tests/ip/netns/set_nsid_batch.t b/testsuite/tests/ip/netns/set_nsid_batch.t
new file mode 100755
index 00000000..abb3f1bb
--- /dev/null
+++ b/testsuite/tests/ip/netns/set_nsid_batch.t
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+source lib/generic.sh
+
+ts_log "[Testing netns nsid in batch mode]"
+
+NS=testnsid
+NSID=99
+BATCHFILE=`mktemp`
+
+echo "netns add $NS" >> $BATCHFILE
+echo "netns set $NS $NSID" >> $BATCHFILE
+echo "netns list-id" >> $BATCHFILE
+ts_ip "$0" "Add ns, set nsid and list in batch mode" -b $BATCHFILE
+test_on "nsid $NSID \(iproute2 netns name: $NS\)"
+rm -f $BATCHFILE
+
+ts_ip "$0" "Delete netns $NS" netns del $NS