summaryrefslogtreecommitdiffstats
path: root/net/ceph
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2015-06-25 10:47:45 -0400
committerIlya Dryomov <idryomov@gmail.com>2015-07-09 13:30:34 -0400
commit757856d2b9568a701df9ea6a4be68effbb9d6f44 (patch)
treec6f943fd91a6e1901745f114a1387e98b8031eed /net/ceph
parentd770e558e21961ad6cfdf0ff7df0eb5d7d4f0754 (diff)
libceph: enable ceph in a non-default network namespace
Grab a reference on a network namespace of the 'rbd map' (in case of rbd) or 'mount' (in case of ceph) process and use that to open sockets instead of always using init_net and bailing if network namespace is anything but init_net. Be careful to not share struct ceph_client instances between different namespaces and don't add any code in the !CONFIG_NET_NS case. This is based on a patch from Hong Zhiguo <zhiguohong@tencent.com>. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Sage Weil <sage@redhat.com>
Diffstat (limited to 'net/ceph')
-rw-r--r--net/ceph/ceph_common.c16
-rw-r--r--net/ceph/messenger.c10
2 files changed, 19 insertions, 7 deletions
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index cb7db320dd27..f30329f72641 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -9,6 +9,7 @@
9#include <keys/ceph-type.h> 9#include <keys/ceph-type.h>
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/mount.h> 11#include <linux/mount.h>
12#include <linux/nsproxy.h>
12#include <linux/parser.h> 13#include <linux/parser.h>
13#include <linux/sched.h> 14#include <linux/sched.h>
14#include <linux/seq_file.h> 15#include <linux/seq_file.h>
@@ -16,8 +17,6 @@
16#include <linux/statfs.h> 17#include <linux/statfs.h>
17#include <linux/string.h> 18#include <linux/string.h>
18#include <linux/vmalloc.h> 19#include <linux/vmalloc.h>
19#include <linux/nsproxy.h>
20#include <net/net_namespace.h>
21 20
22 21
23#include <linux/ceph/ceph_features.h> 22#include <linux/ceph/ceph_features.h>
@@ -131,6 +130,13 @@ int ceph_compare_options(struct ceph_options *new_opt,
131 int i; 130 int i;
132 int ret; 131 int ret;
133 132
133 /*
134 * Don't bother comparing options if network namespaces don't
135 * match.
136 */
137 if (!net_eq(current->nsproxy->net_ns, read_pnet(&client->msgr.net)))
138 return -1;
139
134 ret = memcmp(opt1, opt2, ofs); 140 ret = memcmp(opt1, opt2, ofs);
135 if (ret) 141 if (ret)
136 return ret; 142 return ret;
@@ -335,9 +341,6 @@ ceph_parse_options(char *options, const char *dev_name,
335 int err = -ENOMEM; 341 int err = -ENOMEM;
336 substring_t argstr[MAX_OPT_ARGS]; 342 substring_t argstr[MAX_OPT_ARGS];
337 343
338 if (current->nsproxy->net_ns != &init_net)
339 return ERR_PTR(-EINVAL);
340
341 opt = kzalloc(sizeof(*opt), GFP_KERNEL); 344 opt = kzalloc(sizeof(*opt), GFP_KERNEL);
342 if (!opt) 345 if (!opt)
343 return ERR_PTR(-ENOMEM); 346 return ERR_PTR(-ENOMEM);
@@ -608,6 +611,7 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private,
608fail_monc: 611fail_monc:
609 ceph_monc_stop(&client->monc); 612 ceph_monc_stop(&client->monc);
610fail: 613fail:
614 ceph_messenger_fini(&client->msgr);
611 kfree(client); 615 kfree(client);
612 return ERR_PTR(err); 616 return ERR_PTR(err);
613} 617}
@@ -621,8 +625,8 @@ void ceph_destroy_client(struct ceph_client *client)
621 625
622 /* unmount */ 626 /* unmount */
623 ceph_osdc_stop(&client->osdc); 627 ceph_osdc_stop(&client->osdc);
624
625 ceph_monc_stop(&client->monc); 628 ceph_monc_stop(&client->monc);
629 ceph_messenger_fini(&client->msgr);
626 630
627 ceph_debugfs_client_cleanup(client); 631 ceph_debugfs_client_cleanup(client);
628 632
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 1679f47280e2..5c1f98ea6741 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -6,6 +6,7 @@
6#include <linux/inet.h> 6#include <linux/inet.h>
7#include <linux/kthread.h> 7#include <linux/kthread.h>
8#include <linux/net.h> 8#include <linux/net.h>
9#include <linux/nsproxy.h>
9#include <linux/slab.h> 10#include <linux/slab.h>
10#include <linux/socket.h> 11#include <linux/socket.h>
11#include <linux/string.h> 12#include <linux/string.h>
@@ -479,7 +480,7 @@ static int ceph_tcp_connect(struct ceph_connection *con)
479 int ret; 480 int ret;
480 481
481 BUG_ON(con->sock); 482 BUG_ON(con->sock);
482 ret = sock_create_kern(&init_net, con->peer_addr.in_addr.ss_family, 483 ret = sock_create_kern(read_pnet(&con->msgr->net), paddr->ss_family,
483 SOCK_STREAM, IPPROTO_TCP, &sock); 484 SOCK_STREAM, IPPROTO_TCP, &sock);
484 if (ret) 485 if (ret)
485 return ret; 486 return ret;
@@ -2944,11 +2945,18 @@ void ceph_messenger_init(struct ceph_messenger *msgr,
2944 msgr->tcp_nodelay = tcp_nodelay; 2945 msgr->tcp_nodelay = tcp_nodelay;
2945 2946
2946 atomic_set(&msgr->stopping, 0); 2947 atomic_set(&msgr->stopping, 0);
2948 write_pnet(&msgr->net, get_net(current->nsproxy->net_ns));
2947 2949
2948 dout("%s %p\n", __func__, msgr); 2950 dout("%s %p\n", __func__, msgr);
2949} 2951}
2950EXPORT_SYMBOL(ceph_messenger_init); 2952EXPORT_SYMBOL(ceph_messenger_init);
2951 2953
2954void ceph_messenger_fini(struct ceph_messenger *msgr)
2955{
2956 put_net(read_pnet(&msgr->net));
2957}
2958EXPORT_SYMBOL(ceph_messenger_fini);
2959
2952static void clear_standby(struct ceph_connection *con) 2960static void clear_standby(struct ceph_connection *con)
2953{ 2961{
2954 /* come back from STANDBY? */ 2962 /* come back from STANDBY? */