diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-06-14 12:28:09 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-08 10:57:46 -0500 |
commit | 089c075d88ac9407b8d7c5c8fc4b21c0d940bd82 (patch) | |
tree | c68e1a24d7813abe883702255a37dc704f2ea8fd | |
parent | 44e52cfaa22e44a0197b44cd72c3440bc2a6e1ed (diff) |
drbd: Convert the generic netlink interface to accept connection endpoints
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 7 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 21 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 158 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 21 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_state.c | 2 | ||||
-rw-r--r-- | include/linux/drbd_genl.h | 62 |
6 files changed, 164 insertions, 107 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index c3019730a24f..6d6d1056d824 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -836,6 +836,11 @@ struct drbd_tconn { /* is a resource from the config file */ | |||
836 | wait_queue_head_t ping_wait; /* Woken upon reception of a ping, and a state change */ | 836 | wait_queue_head_t ping_wait; /* Woken upon reception of a ping, and a state change */ |
837 | struct res_opts res_opts; | 837 | struct res_opts res_opts; |
838 | 838 | ||
839 | struct sockaddr_storage my_addr; | ||
840 | int my_addr_len; | ||
841 | struct sockaddr_storage peer_addr; | ||
842 | int peer_addr_len; | ||
843 | |||
839 | struct drbd_socket data; /* data/barrier/cstate/parameter packets */ | 844 | struct drbd_socket data; /* data/barrier/cstate/parameter packets */ |
840 | struct drbd_socket meta; /* ping/ack (metadata) packets */ | 845 | struct drbd_socket meta; /* ping/ack (metadata) packets */ |
841 | int agreed_pro_version; /* actually used protocol version */ | 846 | int agreed_pro_version; /* actually used protocol version */ |
@@ -1377,6 +1382,8 @@ extern void drbd_minor_destroy(struct kref *kref); | |||
1377 | struct drbd_tconn *conn_create(const char *name); | 1382 | struct drbd_tconn *conn_create(const char *name); |
1378 | extern void conn_destroy(struct kref *kref); | 1383 | extern void conn_destroy(struct kref *kref); |
1379 | struct drbd_tconn *conn_get_by_name(const char *name); | 1384 | struct drbd_tconn *conn_get_by_name(const char *name); |
1385 | extern struct drbd_tconn *conn_get_by_addrs(void *my_addr, int my_addr_len, | ||
1386 | void *peer_addr, int peer_addr_len); | ||
1380 | extern void conn_free_crypto(struct drbd_tconn *tconn); | 1387 | extern void conn_free_crypto(struct drbd_tconn *tconn); |
1381 | 1388 | ||
1382 | extern int proc_details; | 1389 | extern int proc_details; |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 178c711bc4af..79f275dc43a4 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -2420,6 +2420,27 @@ found: | |||
2420 | return tconn; | 2420 | return tconn; |
2421 | } | 2421 | } |
2422 | 2422 | ||
2423 | struct drbd_tconn *conn_get_by_addrs(void *my_addr, int my_addr_len, | ||
2424 | void *peer_addr, int peer_addr_len) | ||
2425 | { | ||
2426 | struct drbd_tconn *tconn; | ||
2427 | |||
2428 | rcu_read_lock(); | ||
2429 | list_for_each_entry_rcu(tconn, &drbd_tconns, all_tconn) { | ||
2430 | if (tconn->my_addr_len == my_addr_len && | ||
2431 | tconn->peer_addr_len == peer_addr_len && | ||
2432 | !memcmp(&tconn->my_addr, my_addr, my_addr_len) && | ||
2433 | !memcmp(&tconn->peer_addr, peer_addr, peer_addr_len)) { | ||
2434 | kref_get(&tconn->kref); | ||
2435 | goto found; | ||
2436 | } | ||
2437 | } | ||
2438 | tconn = NULL; | ||
2439 | found: | ||
2440 | rcu_read_unlock(); | ||
2441 | return tconn; | ||
2442 | } | ||
2443 | |||
2423 | static int drbd_alloc_socket(struct drbd_socket *socket) | 2444 | static int drbd_alloc_socket(struct drbd_socket *socket) |
2424 | { | 2445 | { |
2425 | socket->rbuf = (void *) __get_free_page(GFP_KERNEL); | 2446 | socket->rbuf = (void *) __get_free_page(GFP_KERNEL); |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 352be132b4be..e7933e04e7b8 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -94,6 +94,8 @@ static struct drbd_config_context { | |||
94 | /* pointer into the request skb, | 94 | /* pointer into the request skb, |
95 | * limited lifetime! */ | 95 | * limited lifetime! */ |
96 | char *resource_name; | 96 | char *resource_name; |
97 | struct nlattr *my_addr; | ||
98 | struct nlattr *peer_addr; | ||
97 | 99 | ||
98 | /* reply buffer */ | 100 | /* reply buffer */ |
99 | struct sk_buff *reply_skb; | 101 | struct sk_buff *reply_skb; |
@@ -142,6 +144,7 @@ int drbd_msg_put_info(const char *info) | |||
142 | */ | 144 | */ |
143 | #define DRBD_ADM_NEED_MINOR 1 | 145 | #define DRBD_ADM_NEED_MINOR 1 |
144 | #define DRBD_ADM_NEED_RESOURCE 2 | 146 | #define DRBD_ADM_NEED_RESOURCE 2 |
147 | #define DRBD_ADM_NEED_CONNECTION 4 | ||
145 | static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, | 148 | static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, |
146 | unsigned flags) | 149 | unsigned flags) |
147 | { | 150 | { |
@@ -174,6 +177,7 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, | |||
174 | adm_ctx.reply_dh->minor = d_in->minor; | 177 | adm_ctx.reply_dh->minor = d_in->minor; |
175 | adm_ctx.reply_dh->ret_code = NO_ERROR; | 178 | adm_ctx.reply_dh->ret_code = NO_ERROR; |
176 | 179 | ||
180 | adm_ctx.volume = VOLUME_UNSPECIFIED; | ||
177 | if (info->attrs[DRBD_NLA_CFG_CONTEXT]) { | 181 | if (info->attrs[DRBD_NLA_CFG_CONTEXT]) { |
178 | struct nlattr *nla; | 182 | struct nlattr *nla; |
179 | /* parse and validate only */ | 183 | /* parse and validate only */ |
@@ -191,12 +195,21 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, | |||
191 | 195 | ||
192 | /* and assign stuff to the global adm_ctx */ | 196 | /* and assign stuff to the global adm_ctx */ |
193 | nla = nested_attr_tb[__nla_type(T_ctx_volume)]; | 197 | nla = nested_attr_tb[__nla_type(T_ctx_volume)]; |
194 | adm_ctx.volume = nla ? nla_get_u32(nla) : VOLUME_UNSPECIFIED; | 198 | if (nla) |
199 | adm_ctx.volume = nla_get_u32(nla); | ||
195 | nla = nested_attr_tb[__nla_type(T_ctx_resource_name)]; | 200 | nla = nested_attr_tb[__nla_type(T_ctx_resource_name)]; |
196 | if (nla) | 201 | if (nla) |
197 | adm_ctx.resource_name = nla_data(nla); | 202 | adm_ctx.resource_name = nla_data(nla); |
198 | } else | 203 | adm_ctx.my_addr = nested_attr_tb[__nla_type(T_ctx_my_addr)]; |
199 | adm_ctx.volume = VOLUME_UNSPECIFIED; | 204 | adm_ctx.peer_addr = nested_attr_tb[__nla_type(T_ctx_peer_addr)]; |
205 | if ((adm_ctx.my_addr && | ||
206 | nla_len(adm_ctx.my_addr) > sizeof(adm_ctx.tconn->my_addr)) || | ||
207 | (adm_ctx.peer_addr && | ||
208 | nla_len(adm_ctx.peer_addr) > sizeof(adm_ctx.tconn->peer_addr))) { | ||
209 | err = -EINVAL; | ||
210 | goto fail; | ||
211 | } | ||
212 | } | ||
200 | 213 | ||
201 | adm_ctx.minor = d_in->minor; | 214 | adm_ctx.minor = d_in->minor; |
202 | adm_ctx.mdev = minor_to_mdev(d_in->minor); | 215 | adm_ctx.mdev = minor_to_mdev(d_in->minor); |
@@ -211,6 +224,26 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, | |||
211 | return ERR_INVALID_REQUEST; | 224 | return ERR_INVALID_REQUEST; |
212 | } | 225 | } |
213 | 226 | ||
227 | if (flags & DRBD_ADM_NEED_CONNECTION) { | ||
228 | if (adm_ctx.tconn && !(flags & DRBD_ADM_NEED_RESOURCE)) { | ||
229 | drbd_msg_put_info("no resource name expected"); | ||
230 | return ERR_INVALID_REQUEST; | ||
231 | } | ||
232 | if (adm_ctx.mdev) { | ||
233 | drbd_msg_put_info("no minor number expected"); | ||
234 | return ERR_INVALID_REQUEST; | ||
235 | } | ||
236 | if (adm_ctx.my_addr && adm_ctx.peer_addr) | ||
237 | adm_ctx.tconn = conn_get_by_addrs(nla_data(adm_ctx.my_addr), | ||
238 | nla_len(adm_ctx.my_addr), | ||
239 | nla_data(adm_ctx.peer_addr), | ||
240 | nla_len(adm_ctx.peer_addr)); | ||
241 | if (!adm_ctx.tconn) { | ||
242 | drbd_msg_put_info("unknown connection"); | ||
243 | return ERR_INVALID_REQUEST; | ||
244 | } | ||
245 | } | ||
246 | |||
214 | /* some more paranoia, if the request was over-determined */ | 247 | /* some more paranoia, if the request was over-determined */ |
215 | if (adm_ctx.mdev && adm_ctx.tconn && | 248 | if (adm_ctx.mdev && adm_ctx.tconn && |
216 | adm_ctx.mdev->tconn != adm_ctx.tconn) { | 249 | adm_ctx.mdev->tconn != adm_ctx.tconn) { |
@@ -268,30 +301,28 @@ static int drbd_adm_finish(struct genl_info *info, int retcode) | |||
268 | static void setup_khelper_env(struct drbd_tconn *tconn, char **envp) | 301 | static void setup_khelper_env(struct drbd_tconn *tconn, char **envp) |
269 | { | 302 | { |
270 | char *afs; | 303 | char *afs; |
271 | struct net_conf *nc; | ||
272 | 304 | ||
273 | rcu_read_lock(); | 305 | /* FIXME: A future version will not allow this case. */ |
274 | nc = rcu_dereference(tconn->net_conf); | 306 | if (tconn->my_addr_len == 0 || tconn->peer_addr_len == 0) |
275 | if (nc) { | 307 | return; |
276 | switch (((struct sockaddr *)nc->peer_addr)->sa_family) { | 308 | |
277 | case AF_INET6: | 309 | switch (((struct sockaddr *)&tconn->peer_addr)->sa_family) { |
278 | afs = "ipv6"; | 310 | case AF_INET6: |
279 | snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI6", | 311 | afs = "ipv6"; |
280 | &((struct sockaddr_in6 *)nc->peer_addr)->sin6_addr); | 312 | snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI6", |
281 | break; | 313 | &((struct sockaddr_in6 *)&tconn->peer_addr)->sin6_addr); |
282 | case AF_INET: | 314 | break; |
283 | afs = "ipv4"; | 315 | case AF_INET: |
284 | snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI4", | 316 | afs = "ipv4"; |
285 | &((struct sockaddr_in *)nc->peer_addr)->sin_addr); | 317 | snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI4", |
286 | break; | 318 | &((struct sockaddr_in *)&tconn->peer_addr)->sin_addr); |
287 | default: | 319 | break; |
288 | afs = "ssocks"; | 320 | default: |
289 | snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI4", | 321 | afs = "ssocks"; |
290 | &((struct sockaddr_in *)nc->peer_addr)->sin_addr); | 322 | snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI4", |
291 | } | 323 | &((struct sockaddr_in *)&tconn->peer_addr)->sin_addr); |
292 | snprintf(envp[3], 20, "DRBD_PEER_AF=%s", afs); | ||
293 | } | 324 | } |
294 | rcu_read_unlock(); | 325 | snprintf(envp[3], 20, "DRBD_PEER_AF=%s", afs); |
295 | } | 326 | } |
296 | 327 | ||
297 | int drbd_khelper(struct drbd_conf *mdev, char *cmd) | 328 | int drbd_khelper(struct drbd_conf *mdev, char *cmd) |
@@ -1874,7 +1905,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) | |||
1874 | int rsr; /* re-sync running */ | 1905 | int rsr; /* re-sync running */ |
1875 | struct crypto crypto = { }; | 1906 | struct crypto crypto = { }; |
1876 | 1907 | ||
1877 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); | 1908 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONNECTION); |
1878 | if (!adm_ctx.reply_skb) | 1909 | if (!adm_ctx.reply_skb) |
1879 | return retcode; | 1910 | return retcode; |
1880 | if (retcode != NO_ERROR) | 1911 | if (retcode != NO_ERROR) |
@@ -1986,18 +2017,39 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) | |||
1986 | struct drbd_conf *mdev; | 2017 | struct drbd_conf *mdev; |
1987 | struct net_conf *old_conf, *new_conf = NULL; | 2018 | struct net_conf *old_conf, *new_conf = NULL; |
1988 | struct crypto crypto = { }; | 2019 | struct crypto crypto = { }; |
1989 | struct drbd_tconn *oconn; | ||
1990 | struct drbd_tconn *tconn; | 2020 | struct drbd_tconn *tconn; |
1991 | struct sockaddr *new_my_addr, *new_peer_addr, *taken_addr; | ||
1992 | enum drbd_ret_code retcode; | 2021 | enum drbd_ret_code retcode; |
1993 | int i; | 2022 | int i; |
1994 | int err; | 2023 | int err; |
1995 | 2024 | ||
1996 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); | 2025 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); |
2026 | |||
1997 | if (!adm_ctx.reply_skb) | 2027 | if (!adm_ctx.reply_skb) |
1998 | return retcode; | 2028 | return retcode; |
1999 | if (retcode != NO_ERROR) | 2029 | if (retcode != NO_ERROR) |
2000 | goto out; | 2030 | goto out; |
2031 | if (!(adm_ctx.my_addr && adm_ctx.peer_addr)) { | ||
2032 | drbd_msg_put_info("connection endpoint(s) missing"); | ||
2033 | retcode = ERR_INVALID_REQUEST; | ||
2034 | goto out; | ||
2035 | } | ||
2036 | |||
2037 | /* No need for _rcu here. All reconfiguration is | ||
2038 | * strictly serialized on genl_lock(). We are protected against | ||
2039 | * concurrent reconfiguration/addition/deletion */ | ||
2040 | list_for_each_entry(tconn, &drbd_tconns, all_tconn) { | ||
2041 | if (nla_len(adm_ctx.my_addr) == tconn->my_addr_len && | ||
2042 | !memcmp(nla_data(adm_ctx.my_addr), &tconn->my_addr, tconn->my_addr_len)) { | ||
2043 | retcode = ERR_LOCAL_ADDR; | ||
2044 | goto out; | ||
2045 | } | ||
2046 | |||
2047 | if (nla_len(adm_ctx.peer_addr) == tconn->peer_addr_len && | ||
2048 | !memcmp(nla_data(adm_ctx.peer_addr), &tconn->peer_addr, tconn->peer_addr_len)) { | ||
2049 | retcode = ERR_PEER_ADDR; | ||
2050 | goto out; | ||
2051 | } | ||
2052 | } | ||
2001 | 2053 | ||
2002 | tconn = adm_ctx.tconn; | 2054 | tconn = adm_ctx.tconn; |
2003 | conn_reconfig_start(tconn); | 2055 | conn_reconfig_start(tconn); |
@@ -2027,37 +2079,6 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) | |||
2027 | if (retcode != NO_ERROR) | 2079 | if (retcode != NO_ERROR) |
2028 | goto fail; | 2080 | goto fail; |
2029 | 2081 | ||
2030 | retcode = NO_ERROR; | ||
2031 | |||
2032 | new_my_addr = (struct sockaddr *)&new_conf->my_addr; | ||
2033 | new_peer_addr = (struct sockaddr *)&new_conf->peer_addr; | ||
2034 | |||
2035 | /* No need for _rcu here. All reconfiguration is | ||
2036 | * strictly serialized on genl_lock(). We are protected against | ||
2037 | * concurrent reconfiguration/addition/deletion */ | ||
2038 | list_for_each_entry(oconn, &drbd_tconns, all_tconn) { | ||
2039 | struct net_conf *nc; | ||
2040 | if (oconn == tconn) | ||
2041 | continue; | ||
2042 | |||
2043 | rcu_read_lock(); | ||
2044 | nc = rcu_dereference(oconn->net_conf); | ||
2045 | if (nc) { | ||
2046 | taken_addr = (struct sockaddr *)&nc->my_addr; | ||
2047 | if (new_conf->my_addr_len == nc->my_addr_len && | ||
2048 | !memcmp(new_my_addr, taken_addr, new_conf->my_addr_len)) | ||
2049 | retcode = ERR_LOCAL_ADDR; | ||
2050 | |||
2051 | taken_addr = (struct sockaddr *)&nc->peer_addr; | ||
2052 | if (new_conf->peer_addr_len == nc->peer_addr_len && | ||
2053 | !memcmp(new_peer_addr, taken_addr, new_conf->peer_addr_len)) | ||
2054 | retcode = ERR_PEER_ADDR; | ||
2055 | } | ||
2056 | rcu_read_unlock(); | ||
2057 | if (retcode != NO_ERROR) | ||
2058 | goto fail; | ||
2059 | } | ||
2060 | |||
2061 | retcode = alloc_crypto(&crypto, new_conf); | 2082 | retcode = alloc_crypto(&crypto, new_conf); |
2062 | if (retcode != NO_ERROR) | 2083 | if (retcode != NO_ERROR) |
2063 | goto fail; | 2084 | goto fail; |
@@ -2083,6 +2104,11 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) | |||
2083 | tconn->csums_tfm = crypto.csums_tfm; | 2104 | tconn->csums_tfm = crypto.csums_tfm; |
2084 | tconn->verify_tfm = crypto.verify_tfm; | 2105 | tconn->verify_tfm = crypto.verify_tfm; |
2085 | 2106 | ||
2107 | tconn->my_addr_len = nla_len(adm_ctx.my_addr); | ||
2108 | memcpy(&tconn->my_addr, nla_data(adm_ctx.my_addr), tconn->my_addr_len); | ||
2109 | tconn->peer_addr_len = nla_len(adm_ctx.peer_addr); | ||
2110 | memcpy(&tconn->peer_addr, nla_data(adm_ctx.peer_addr), tconn->peer_addr_len); | ||
2111 | |||
2086 | mutex_unlock(&tconn->conf_update); | 2112 | mutex_unlock(&tconn->conf_update); |
2087 | 2113 | ||
2088 | rcu_read_lock(); | 2114 | rcu_read_lock(); |
@@ -2170,7 +2196,7 @@ int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info) | |||
2170 | enum drbd_ret_code retcode; | 2196 | enum drbd_ret_code retcode; |
2171 | int err; | 2197 | int err; |
2172 | 2198 | ||
2173 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE); | 2199 | retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONNECTION); |
2174 | if (!adm_ctx.reply_skb) | 2200 | if (!adm_ctx.reply_skb) |
2175 | return retcode; | 2201 | return retcode; |
2176 | if (retcode != NO_ERROR) | 2202 | if (retcode != NO_ERROR) |
@@ -2529,7 +2555,7 @@ int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info) | |||
2529 | return drbd_adm_simple_request_state(skb, info, NS(disk, D_OUTDATED)); | 2555 | return drbd_adm_simple_request_state(skb, info, NS(disk, D_OUTDATED)); |
2530 | } | 2556 | } |
2531 | 2557 | ||
2532 | int nla_put_drbd_cfg_context(struct sk_buff *skb, const char *resource_name, unsigned vnr) | 2558 | int nla_put_drbd_cfg_context(struct sk_buff *skb, struct drbd_tconn *tconn, unsigned vnr) |
2533 | { | 2559 | { |
2534 | struct nlattr *nla; | 2560 | struct nlattr *nla; |
2535 | nla = nla_nest_start(skb, DRBD_NLA_CFG_CONTEXT); | 2561 | nla = nla_nest_start(skb, DRBD_NLA_CFG_CONTEXT); |
@@ -2537,7 +2563,11 @@ int nla_put_drbd_cfg_context(struct sk_buff *skb, const char *resource_name, uns | |||
2537 | goto nla_put_failure; | 2563 | goto nla_put_failure; |
2538 | if (vnr != VOLUME_UNSPECIFIED) | 2564 | if (vnr != VOLUME_UNSPECIFIED) |
2539 | NLA_PUT_U32(skb, T_ctx_volume, vnr); | 2565 | NLA_PUT_U32(skb, T_ctx_volume, vnr); |
2540 | NLA_PUT_STRING(skb, T_ctx_resource_name, resource_name); | 2566 | NLA_PUT_STRING(skb, T_ctx_resource_name, tconn->name); |
2567 | if (tconn->my_addr_len) | ||
2568 | NLA_PUT(skb, T_ctx_my_addr, tconn->my_addr_len, &tconn->my_addr); | ||
2569 | if (tconn->peer_addr_len) | ||
2570 | NLA_PUT(skb, T_ctx_peer_addr, tconn->peer_addr_len, &tconn->peer_addr); | ||
2541 | nla_nest_end(skb, nla); | 2571 | nla_nest_end(skb, nla); |
2542 | return 0; | 2572 | return 0; |
2543 | 2573 | ||
@@ -2574,7 +2604,7 @@ int nla_put_status_info(struct sk_buff *skb, struct drbd_conf *mdev, | |||
2574 | 2604 | ||
2575 | /* We need to add connection name and volume number information still. | 2605 | /* We need to add connection name and volume number information still. |
2576 | * Minor number is in drbd_genlmsghdr. */ | 2606 | * Minor number is in drbd_genlmsghdr. */ |
2577 | if (nla_put_drbd_cfg_context(skb, mdev->tconn->name, mdev->vnr)) | 2607 | if (nla_put_drbd_cfg_context(skb, mdev->tconn, mdev->vnr)) |
2578 | goto nla_put_failure; | 2608 | goto nla_put_failure; |
2579 | 2609 | ||
2580 | if (res_opts_to_skb(skb, &mdev->tconn->res_opts, exclude_sensitive)) | 2610 | if (res_opts_to_skb(skb, &mdev->tconn->res_opts, exclude_sensitive)) |
@@ -2736,7 +2766,7 @@ next_tconn: | |||
2736 | /* this is a tconn without a single volume */ | 2766 | /* this is a tconn without a single volume */ |
2737 | dh->minor = -1U; | 2767 | dh->minor = -1U; |
2738 | dh->ret_code = NO_ERROR; | 2768 | dh->ret_code = NO_ERROR; |
2739 | if (nla_put_drbd_cfg_context(skb, tconn->name, VOLUME_UNSPECIFIED)) | 2769 | if (nla_put_drbd_cfg_context(skb, tconn, VOLUME_UNSPECIFIED)) |
2740 | genlmsg_cancel(skb, dh); | 2770 | genlmsg_cancel(skb, dh); |
2741 | else | 2771 | else |
2742 | genlmsg_end(skb, dh); | 2772 | genlmsg_end(skb, dh); |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 4ba097293278..ab1d36cb6214 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -626,23 +626,21 @@ static struct socket *drbd_try_connect(struct drbd_tconn *tconn) | |||
626 | rcu_read_unlock(); | 626 | rcu_read_unlock(); |
627 | return NULL; | 627 | return NULL; |
628 | } | 628 | } |
629 | |||
630 | sndbuf_size = nc->sndbuf_size; | 629 | sndbuf_size = nc->sndbuf_size; |
631 | rcvbuf_size = nc->rcvbuf_size; | 630 | rcvbuf_size = nc->rcvbuf_size; |
632 | connect_int = nc->connect_int; | 631 | connect_int = nc->connect_int; |
632 | rcu_read_unlock(); | ||
633 | 633 | ||
634 | my_addr_len = min_t(int, nc->my_addr_len, sizeof(src_in6)); | 634 | my_addr_len = min_t(int, tconn->my_addr_len, sizeof(src_in6)); |
635 | memcpy(&src_in6, nc->my_addr, my_addr_len); | 635 | memcpy(&src_in6, &tconn->my_addr, my_addr_len); |
636 | 636 | ||
637 | if (((struct sockaddr *)nc->my_addr)->sa_family == AF_INET6) | 637 | if (((struct sockaddr *)&tconn->my_addr)->sa_family == AF_INET6) |
638 | src_in6.sin6_port = 0; | 638 | src_in6.sin6_port = 0; |
639 | else | 639 | else |
640 | ((struct sockaddr_in *)&src_in6)->sin_port = 0; /* AF_INET & AF_SCI */ | 640 | ((struct sockaddr_in *)&src_in6)->sin_port = 0; /* AF_INET & AF_SCI */ |
641 | 641 | ||
642 | peer_addr_len = min_t(int, nc->peer_addr_len, sizeof(src_in6)); | 642 | peer_addr_len = min_t(int, tconn->peer_addr_len, sizeof(src_in6)); |
643 | memcpy(&peer_in6, nc->peer_addr, peer_addr_len); | 643 | memcpy(&peer_in6, &tconn->peer_addr, peer_addr_len); |
644 | |||
645 | rcu_read_unlock(); | ||
646 | 644 | ||
647 | what = "sock_create_kern"; | 645 | what = "sock_create_kern"; |
648 | err = sock_create_kern(((struct sockaddr *)&src_in6)->sa_family, | 646 | err = sock_create_kern(((struct sockaddr *)&src_in6)->sa_family, |
@@ -714,15 +712,14 @@ static struct socket *drbd_wait_for_connect(struct drbd_tconn *tconn) | |||
714 | rcu_read_unlock(); | 712 | rcu_read_unlock(); |
715 | return NULL; | 713 | return NULL; |
716 | } | 714 | } |
717 | |||
718 | sndbuf_size = nc->sndbuf_size; | 715 | sndbuf_size = nc->sndbuf_size; |
719 | rcvbuf_size = nc->rcvbuf_size; | 716 | rcvbuf_size = nc->rcvbuf_size; |
720 | connect_int = nc->connect_int; | 717 | connect_int = nc->connect_int; |
721 | |||
722 | my_addr_len = min_t(int, nc->my_addr_len, sizeof(struct sockaddr_in6)); | ||
723 | memcpy(&my_addr, nc->my_addr, my_addr_len); | ||
724 | rcu_read_unlock(); | 718 | rcu_read_unlock(); |
725 | 719 | ||
720 | my_addr_len = min_t(int, tconn->my_addr_len, sizeof(struct sockaddr_in6)); | ||
721 | memcpy(&my_addr, &tconn->my_addr, my_addr_len); | ||
722 | |||
726 | what = "sock_create_kern"; | 723 | what = "sock_create_kern"; |
727 | err = sock_create_kern(((struct sockaddr *)&my_addr)->sa_family, | 724 | err = sock_create_kern(((struct sockaddr *)&my_addr)->sa_family, |
728 | SOCK_STREAM, IPPROTO_TCP, &s_listen); | 725 | SOCK_STREAM, IPPROTO_TCP, &s_listen); |
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index cd55f46d5c55..d978e4d98a15 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c | |||
@@ -1418,6 +1418,8 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused) | |||
1418 | 1418 | ||
1419 | mutex_lock(&tconn->conf_update); | 1419 | mutex_lock(&tconn->conf_update); |
1420 | old_conf = tconn->net_conf; | 1420 | old_conf = tconn->net_conf; |
1421 | tconn->my_addr_len = 0; | ||
1422 | tconn->peer_addr_len = 0; | ||
1421 | rcu_assign_pointer(tconn->net_conf, NULL); | 1423 | rcu_assign_pointer(tconn->net_conf, NULL); |
1422 | conn_free_crypto(tconn); | 1424 | conn_free_crypto(tconn); |
1423 | mutex_unlock(&tconn->conf_update); | 1425 | mutex_unlock(&tconn->conf_update); |
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h index 0c2102c05384..b93db6c83882 100644 --- a/include/linux/drbd_genl.h +++ b/include/linux/drbd_genl.h | |||
@@ -97,6 +97,8 @@ GENL_struct(DRBD_NLA_CFG_REPLY, 1, drbd_cfg_reply, | |||
97 | GENL_struct(DRBD_NLA_CFG_CONTEXT, 2, drbd_cfg_context, | 97 | GENL_struct(DRBD_NLA_CFG_CONTEXT, 2, drbd_cfg_context, |
98 | __u32_field(1, DRBD_GENLA_F_MANDATORY, ctx_volume) | 98 | __u32_field(1, DRBD_GENLA_F_MANDATORY, ctx_volume) |
99 | __str_field(2, DRBD_GENLA_F_MANDATORY, ctx_resource_name, 128) | 99 | __str_field(2, DRBD_GENLA_F_MANDATORY, ctx_resource_name, 128) |
100 | __bin_field(3, DRBD_GENLA_F_MANDATORY, ctx_my_addr, 128) | ||
101 | __bin_field(4, DRBD_GENLA_F_MANDATORY, ctx_peer_addr, 128) | ||
100 | ) | 102 | ) |
101 | 103 | ||
102 | GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf, | 104 | GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf, |
@@ -134,38 +136,36 @@ GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts, | |||
134 | ) | 136 | ) |
135 | 137 | ||
136 | GENL_struct(DRBD_NLA_NET_CONF, 5, net_conf, | 138 | GENL_struct(DRBD_NLA_NET_CONF, 5, net_conf, |
137 | __bin_field(1, DRBD_F_REQUIRED | DRBD_F_INVARIANT, my_addr, 128) | 139 | __str_field_def(1, DRBD_GENLA_F_MANDATORY | DRBD_F_SENSITIVE, |
138 | __bin_field(2, DRBD_F_REQUIRED | DRBD_F_INVARIANT, peer_addr, 128) | ||
139 | __str_field_def(3, DRBD_GENLA_F_MANDATORY | DRBD_F_SENSITIVE, | ||
140 | shared_secret, SHARED_SECRET_MAX) | 140 | shared_secret, SHARED_SECRET_MAX) |
141 | __str_field_def(4, DRBD_GENLA_F_MANDATORY, cram_hmac_alg, SHARED_SECRET_MAX) | 141 | __str_field_def(2, DRBD_GENLA_F_MANDATORY, cram_hmac_alg, SHARED_SECRET_MAX) |
142 | __str_field_def(5, DRBD_GENLA_F_MANDATORY, integrity_alg, SHARED_SECRET_MAX) | 142 | __str_field_def(3, DRBD_GENLA_F_MANDATORY, integrity_alg, SHARED_SECRET_MAX) |
143 | __str_field_def(6, DRBD_GENLA_F_MANDATORY, verify_alg, SHARED_SECRET_MAX) | 143 | __str_field_def(4, DRBD_GENLA_F_MANDATORY, verify_alg, SHARED_SECRET_MAX) |
144 | __str_field_def(7, DRBD_GENLA_F_MANDATORY, csums_alg, SHARED_SECRET_MAX) | 144 | __str_field_def(5, DRBD_GENLA_F_MANDATORY, csums_alg, SHARED_SECRET_MAX) |
145 | __u32_field_def(8, DRBD_GENLA_F_MANDATORY, wire_protocol, DRBD_PROTOCOL_DEF) | 145 | __u32_field_def(6, DRBD_GENLA_F_MANDATORY, wire_protocol, DRBD_PROTOCOL_DEF) |
146 | __u32_field_def(9, DRBD_GENLA_F_MANDATORY, connect_int, DRBD_CONNECT_INT_DEF) | 146 | __u32_field_def(7, DRBD_GENLA_F_MANDATORY, connect_int, DRBD_CONNECT_INT_DEF) |
147 | __u32_field_def(10, DRBD_GENLA_F_MANDATORY, timeout, DRBD_TIMEOUT_DEF) | 147 | __u32_field_def(8, DRBD_GENLA_F_MANDATORY, timeout, DRBD_TIMEOUT_DEF) |
148 | __u32_field_def(11, DRBD_GENLA_F_MANDATORY, ping_int, DRBD_PING_INT_DEF) | 148 | __u32_field_def(9, DRBD_GENLA_F_MANDATORY, ping_int, DRBD_PING_INT_DEF) |
149 | __u32_field_def(12, DRBD_GENLA_F_MANDATORY, ping_timeo, DRBD_PING_TIMEO_DEF) | 149 | __u32_field_def(10, DRBD_GENLA_F_MANDATORY, ping_timeo, DRBD_PING_TIMEO_DEF) |
150 | __u32_field_def(13, DRBD_GENLA_F_MANDATORY, sndbuf_size, DRBD_SNDBUF_SIZE_DEF) | 150 | __u32_field_def(11, DRBD_GENLA_F_MANDATORY, sndbuf_size, DRBD_SNDBUF_SIZE_DEF) |
151 | __u32_field_def(14, DRBD_GENLA_F_MANDATORY, rcvbuf_size, DRBD_RCVBUF_SIZE_DEF) | 151 | __u32_field_def(12, DRBD_GENLA_F_MANDATORY, rcvbuf_size, DRBD_RCVBUF_SIZE_DEF) |
152 | __u32_field_def(15, DRBD_GENLA_F_MANDATORY, ko_count, DRBD_KO_COUNT_DEF) | 152 | __u32_field_def(13, DRBD_GENLA_F_MANDATORY, ko_count, DRBD_KO_COUNT_DEF) |
153 | __u32_field_def(16, DRBD_GENLA_F_MANDATORY, max_buffers, DRBD_MAX_BUFFERS_DEF) | 153 | __u32_field_def(14, DRBD_GENLA_F_MANDATORY, max_buffers, DRBD_MAX_BUFFERS_DEF) |
154 | __u32_field_def(17, DRBD_GENLA_F_MANDATORY, max_epoch_size, DRBD_MAX_EPOCH_SIZE_DEF) | 154 | __u32_field_def(15, DRBD_GENLA_F_MANDATORY, max_epoch_size, DRBD_MAX_EPOCH_SIZE_DEF) |
155 | __u32_field_def(18, DRBD_GENLA_F_MANDATORY, unplug_watermark, DRBD_UNPLUG_WATERMARK_DEF) | 155 | __u32_field_def(16, DRBD_GENLA_F_MANDATORY, unplug_watermark, DRBD_UNPLUG_WATERMARK_DEF) |
156 | __u32_field_def(19, DRBD_GENLA_F_MANDATORY, after_sb_0p, DRBD_AFTER_SB_0P_DEF) | 156 | __u32_field_def(17, DRBD_GENLA_F_MANDATORY, after_sb_0p, DRBD_AFTER_SB_0P_DEF) |
157 | __u32_field_def(20, DRBD_GENLA_F_MANDATORY, after_sb_1p, DRBD_AFTER_SB_1P_DEF) | 157 | __u32_field_def(18, DRBD_GENLA_F_MANDATORY, after_sb_1p, DRBD_AFTER_SB_1P_DEF) |
158 | __u32_field_def(21, DRBD_GENLA_F_MANDATORY, after_sb_2p, DRBD_AFTER_SB_2P_DEF) | 158 | __u32_field_def(19, DRBD_GENLA_F_MANDATORY, after_sb_2p, DRBD_AFTER_SB_2P_DEF) |
159 | __u32_field_def(22, DRBD_GENLA_F_MANDATORY, rr_conflict, DRBD_RR_CONFLICT_DEF) | 159 | __u32_field_def(20, DRBD_GENLA_F_MANDATORY, rr_conflict, DRBD_RR_CONFLICT_DEF) |
160 | __u32_field_def(23, DRBD_GENLA_F_MANDATORY, on_congestion, DRBD_ON_CONGESTION_DEF) | 160 | __u32_field_def(21, DRBD_GENLA_F_MANDATORY, on_congestion, DRBD_ON_CONGESTION_DEF) |
161 | __u32_field_def(24, DRBD_GENLA_F_MANDATORY, cong_fill, DRBD_CONG_FILL_DEF) | 161 | __u32_field_def(22, DRBD_GENLA_F_MANDATORY, cong_fill, DRBD_CONG_FILL_DEF) |
162 | __u32_field_def(25, DRBD_GENLA_F_MANDATORY, cong_extents, DRBD_CONG_EXTENTS_DEF) | 162 | __u32_field_def(23, DRBD_GENLA_F_MANDATORY, cong_extents, DRBD_CONG_EXTENTS_DEF) |
163 | __flg_field_def(26, DRBD_GENLA_F_MANDATORY, two_primaries, DRBD_ALLOW_TWO_PRIMARIES_DEF) | 163 | __flg_field_def(24, DRBD_GENLA_F_MANDATORY, two_primaries, DRBD_ALLOW_TWO_PRIMARIES_DEF) |
164 | __flg_field(27, DRBD_GENLA_F_MANDATORY | DRBD_F_INVARIANT, discard_my_data) | 164 | __flg_field(25, DRBD_GENLA_F_MANDATORY | DRBD_F_INVARIANT, discard_my_data) |
165 | __flg_field_def(28, DRBD_GENLA_F_MANDATORY, tcp_cork, DRBD_TCP_CORK_DEF) | 165 | __flg_field_def(26, DRBD_GENLA_F_MANDATORY, tcp_cork, DRBD_TCP_CORK_DEF) |
166 | __flg_field_def(29, DRBD_GENLA_F_MANDATORY, always_asbp, DRBD_ALWAYS_ASBP_DEF) | 166 | __flg_field_def(27, DRBD_GENLA_F_MANDATORY, always_asbp, DRBD_ALWAYS_ASBP_DEF) |
167 | __flg_field(30, DRBD_GENLA_F_MANDATORY | DRBD_F_INVARIANT, dry_run) | 167 | __flg_field(28, DRBD_GENLA_F_MANDATORY | DRBD_F_INVARIANT, dry_run) |
168 | __flg_field_def(31, DRBD_GENLA_F_MANDATORY, use_rle, DRBD_USE_RLE_DEF) | 168 | __flg_field_def(29, DRBD_GENLA_F_MANDATORY, use_rle, DRBD_USE_RLE_DEF) |
169 | ) | 169 | ) |
170 | 170 | ||
171 | GENL_struct(DRBD_NLA_SET_ROLE_PARMS, 6, set_role_parms, | 171 | GENL_struct(DRBD_NLA_SET_ROLE_PARMS, 6, set_role_parms, |