Message ID | 1436182244-31848-1-git-send-email-idryomov@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, 6 Jul 2015, Ilya Dryomov wrote: > 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> > --- > include/linux/ceph/messenger.h | 3 +++ > net/ceph/ceph_common.c | 14 +++++++++----- > net/ceph/messenger.c | 9 ++++++++- > 3 files changed, 20 insertions(+), 6 deletions(-) > > diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h > index e15499422fdc..37753278987a 100644 > --- a/include/linux/ceph/messenger.h > +++ b/include/linux/ceph/messenger.h > @@ -8,6 +8,7 @@ > #include <linux/radix-tree.h> > #include <linux/uio.h> > #include <linux/workqueue.h> > +#include <net/net_namespace.h> > > #include <linux/ceph/types.h> > #include <linux/ceph/buffer.h> > @@ -56,6 +57,7 @@ struct ceph_messenger { > struct ceph_entity_addr my_enc_addr; > > atomic_t stopping; > + possible_net_t net; > bool nocrc; > bool tcp_nodelay; > > @@ -267,6 +269,7 @@ extern void ceph_messenger_init(struct ceph_messenger *msgr, > u64 required_features, > bool nocrc, > bool tcp_nodelay); > +extern void ceph_messenger_fini(struct ceph_messenger *msgr); > > extern void ceph_con_init(struct ceph_connection *con, void *private, > const struct ceph_connection_operations *ops, > diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c > index cb7db320dd27..f1a63b17ba95 100644 > --- a/net/ceph/ceph_common.c > +++ b/net/ceph/ceph_common.c > @@ -17,7 +17,6 @@ > #include <linux/string.h> > #include <linux/vmalloc.h> > #include <linux/nsproxy.h> > -#include <net/net_namespace.h> > > > #include <linux/ceph/ceph_features.h> > @@ -131,6 +130,13 @@ int ceph_compare_options(struct ceph_options *new_opt, > int i; > 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); > if (ret) > return ret; > @@ -335,9 +341,6 @@ ceph_parse_options(char *options, const char *dev_name, > int err = -ENOMEM; > substring_t argstr[MAX_OPT_ARGS]; > > - if (current->nsproxy->net_ns != &init_net) > - return ERR_PTR(-EINVAL); > - > opt = kzalloc(sizeof(*opt), GFP_KERNEL); > if (!opt) > return ERR_PTR(-ENOMEM); > @@ -608,6 +611,7 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private, > fail_monc: > ceph_monc_stop(&client->monc); > fail: > + ceph_messenger_fini(&client->msgr); > kfree(client); > return ERR_PTR(err); > } > @@ -621,8 +625,8 @@ void ceph_destroy_client(struct ceph_client *client) > > /* unmount */ > ceph_osdc_stop(&client->osdc); > - > ceph_monc_stop(&client->monc); > + ceph_messenger_fini(&client->msgr); > > ceph_debugfs_client_cleanup(client); > > diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c > index 1679f47280e2..aadebf9c4acf 100644 > --- a/net/ceph/messenger.c > +++ b/net/ceph/messenger.c > @@ -479,7 +479,7 @@ static int ceph_tcp_connect(struct ceph_connection *con) > int ret; > > 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); > if (ret) > return ret; > @@ -2944,11 +2944,18 @@ void ceph_messenger_init(struct ceph_messenger *msgr, > msgr->tcp_nodelay = tcp_nodelay; > > atomic_set(&msgr->stopping, 0); > + write_pnet(&msgr->net, get_net(current->nsproxy->net_ns)); > > dout("%s %p\n", __func__, msgr); > } > 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) > { > /* come back from STANDBY? */ > -- > 1.9.3 > > -- > To unsubscribe from this list: send the line "unsubscribe ceph-devel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h index e15499422fdc..37753278987a 100644 --- a/include/linux/ceph/messenger.h +++ b/include/linux/ceph/messenger.h @@ -8,6 +8,7 @@ #include <linux/radix-tree.h> #include <linux/uio.h> #include <linux/workqueue.h> +#include <net/net_namespace.h> #include <linux/ceph/types.h> #include <linux/ceph/buffer.h> @@ -56,6 +57,7 @@ struct ceph_messenger { struct ceph_entity_addr my_enc_addr; atomic_t stopping; + possible_net_t net; bool nocrc; bool tcp_nodelay; @@ -267,6 +269,7 @@ extern void ceph_messenger_init(struct ceph_messenger *msgr, u64 required_features, bool nocrc, bool tcp_nodelay); +extern void ceph_messenger_fini(struct ceph_messenger *msgr); extern void ceph_con_init(struct ceph_connection *con, void *private, const struct ceph_connection_operations *ops, diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index cb7db320dd27..f1a63b17ba95 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -17,7 +17,6 @@ #include <linux/string.h> #include <linux/vmalloc.h> #include <linux/nsproxy.h> -#include <net/net_namespace.h> #include <linux/ceph/ceph_features.h> @@ -131,6 +130,13 @@ int ceph_compare_options(struct ceph_options *new_opt, int i; 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); if (ret) return ret; @@ -335,9 +341,6 @@ ceph_parse_options(char *options, const char *dev_name, int err = -ENOMEM; substring_t argstr[MAX_OPT_ARGS]; - if (current->nsproxy->net_ns != &init_net) - return ERR_PTR(-EINVAL); - opt = kzalloc(sizeof(*opt), GFP_KERNEL); if (!opt) return ERR_PTR(-ENOMEM); @@ -608,6 +611,7 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private, fail_monc: ceph_monc_stop(&client->monc); fail: + ceph_messenger_fini(&client->msgr); kfree(client); return ERR_PTR(err); } @@ -621,8 +625,8 @@ void ceph_destroy_client(struct ceph_client *client) /* unmount */ ceph_osdc_stop(&client->osdc); - ceph_monc_stop(&client->monc); + ceph_messenger_fini(&client->msgr); ceph_debugfs_client_cleanup(client); diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 1679f47280e2..aadebf9c4acf 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -479,7 +479,7 @@ static int ceph_tcp_connect(struct ceph_connection *con) int ret; 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); if (ret) return ret; @@ -2944,11 +2944,18 @@ void ceph_messenger_init(struct ceph_messenger *msgr, msgr->tcp_nodelay = tcp_nodelay; atomic_set(&msgr->stopping, 0); + write_pnet(&msgr->net, get_net(current->nsproxy->net_ns)); dout("%s %p\n", __func__, msgr); } 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) { /* come back from STANDBY? */
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> --- include/linux/ceph/messenger.h | 3 +++ net/ceph/ceph_common.c | 14 +++++++++----- net/ceph/messenger.c | 9 ++++++++- 3 files changed, 20 insertions(+), 6 deletions(-)