Commit 757856d2 authored by Ilya Dryomov's avatar Ilya Dryomov

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: default avatarIlya Dryomov <idryomov@gmail.com>
Reviewed-by: default avatarSage Weil <sage@redhat.com>
parent d770e558
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/radix-tree.h> #include <linux/radix-tree.h>
#include <linux/uio.h> #include <linux/uio.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <net/net_namespace.h>
#include <linux/ceph/types.h> #include <linux/ceph/types.h>
#include <linux/ceph/buffer.h> #include <linux/ceph/buffer.h>
...@@ -56,6 +57,7 @@ struct ceph_messenger { ...@@ -56,6 +57,7 @@ struct ceph_messenger {
struct ceph_entity_addr my_enc_addr; struct ceph_entity_addr my_enc_addr;
atomic_t stopping; atomic_t stopping;
possible_net_t net;
bool nocrc; bool nocrc;
bool tcp_nodelay; bool tcp_nodelay;
...@@ -267,6 +269,7 @@ extern void ceph_messenger_init(struct ceph_messenger *msgr, ...@@ -267,6 +269,7 @@ extern void ceph_messenger_init(struct ceph_messenger *msgr,
u64 required_features, u64 required_features,
bool nocrc, bool nocrc,
bool tcp_nodelay); bool tcp_nodelay);
extern void ceph_messenger_fini(struct ceph_messenger *msgr);
extern void ceph_con_init(struct ceph_connection *con, void *private, extern void ceph_con_init(struct ceph_connection *con, void *private,
const struct ceph_connection_operations *ops, const struct ceph_connection_operations *ops,
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <keys/ceph-type.h> #include <keys/ceph-type.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/nsproxy.h>
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
...@@ -16,8 +17,6 @@ ...@@ -16,8 +17,6 @@
#include <linux/statfs.h> #include <linux/statfs.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/nsproxy.h>
#include <net/net_namespace.h>
#include <linux/ceph/ceph_features.h> #include <linux/ceph/ceph_features.h>
...@@ -131,6 +130,13 @@ int ceph_compare_options(struct ceph_options *new_opt, ...@@ -131,6 +130,13 @@ int ceph_compare_options(struct ceph_options *new_opt,
int i; int i;
int ret; int ret;
/*
* Don't bother comparing options if network namespaces don't
* match.
*/
if (!net_eq(current->nsproxy->net_ns, read_pnet(&client->msgr.net)))
return -1;
ret = memcmp(opt1, opt2, ofs); ret = memcmp(opt1, opt2, ofs);
if (ret) if (ret)
return ret; return ret;
...@@ -335,9 +341,6 @@ ceph_parse_options(char *options, const char *dev_name, ...@@ -335,9 +341,6 @@ ceph_parse_options(char *options, const char *dev_name,
int err = -ENOMEM; int err = -ENOMEM;
substring_t argstr[MAX_OPT_ARGS]; substring_t argstr[MAX_OPT_ARGS];
if (current->nsproxy->net_ns != &init_net)
return ERR_PTR(-EINVAL);
opt = kzalloc(sizeof(*opt), GFP_KERNEL); opt = kzalloc(sizeof(*opt), GFP_KERNEL);
if (!opt) if (!opt)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -608,6 +611,7 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private, ...@@ -608,6 +611,7 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private,
fail_monc: fail_monc:
ceph_monc_stop(&client->monc); ceph_monc_stop(&client->monc);
fail: fail:
ceph_messenger_fini(&client->msgr);
kfree(client); kfree(client);
return ERR_PTR(err); return ERR_PTR(err);
} }
...@@ -621,8 +625,8 @@ void ceph_destroy_client(struct ceph_client *client) ...@@ -621,8 +625,8 @@ void ceph_destroy_client(struct ceph_client *client)
/* unmount */ /* unmount */
ceph_osdc_stop(&client->osdc); ceph_osdc_stop(&client->osdc);
ceph_monc_stop(&client->monc); ceph_monc_stop(&client->monc);
ceph_messenger_fini(&client->msgr);
ceph_debugfs_client_cleanup(client); ceph_debugfs_client_cleanup(client);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/net.h> #include <linux/net.h>
#include <linux/nsproxy.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -479,7 +480,7 @@ static int ceph_tcp_connect(struct ceph_connection *con) ...@@ -479,7 +480,7 @@ static int ceph_tcp_connect(struct ceph_connection *con)
int ret; int ret;
BUG_ON(con->sock); BUG_ON(con->sock);
ret = sock_create_kern(&init_net, con->peer_addr.in_addr.ss_family, ret = sock_create_kern(read_pnet(&con->msgr->net), paddr->ss_family,
SOCK_STREAM, IPPROTO_TCP, &sock); SOCK_STREAM, IPPROTO_TCP, &sock);
if (ret) if (ret)
return ret; return ret;
...@@ -2944,11 +2945,18 @@ void ceph_messenger_init(struct ceph_messenger *msgr, ...@@ -2944,11 +2945,18 @@ void ceph_messenger_init(struct ceph_messenger *msgr,
msgr->tcp_nodelay = tcp_nodelay; msgr->tcp_nodelay = tcp_nodelay;
atomic_set(&msgr->stopping, 0); atomic_set(&msgr->stopping, 0);
write_pnet(&msgr->net, get_net(current->nsproxy->net_ns));
dout("%s %p\n", __func__, msgr); dout("%s %p\n", __func__, msgr);
} }
EXPORT_SYMBOL(ceph_messenger_init); EXPORT_SYMBOL(ceph_messenger_init);
void ceph_messenger_fini(struct ceph_messenger *msgr)
{
put_net(read_pnet(&msgr->net));
}
EXPORT_SYMBOL(ceph_messenger_fini);
static void clear_standby(struct ceph_connection *con) static void clear_standby(struct ceph_connection *con)
{ {
/* come back from STANDBY? */ /* come back from STANDBY? */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment