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>
This commit is contained in:
parent
d770e558e2
commit
757856d2b9
@ -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 {
|
|||||||
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,
|
|||||||
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 @@
|
|||||||
#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 @@
|
|||||||
#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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
|
|
||||||
/* 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 @@
|
|||||||
#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)
|
|||||||
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,
|
|||||||
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? */
|
||||||
|
Loading…
Reference in New Issue
Block a user