X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=net%2Ftipc%2Fconfig.c;fp=net%2Ftipc%2Fconfig.c;h=3c8e6740e5aee653151580dd67d5df4bcd09a492;hp=285e1bc2d8808502f53e952eed76a1dd72308534;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c diff --git a/net/tipc/config.c b/net/tipc/config.c index 285e1bc2d..3c8e6740e 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -63,7 +63,7 @@ struct manager { static struct manager mng = { 0}; -static DEFINE_SPINLOCK(config_lock); +static spinlock_t config_lock = SPIN_LOCK_UNLOCKED; static const void *req_tlv_area; /* request message TLV area */ static int req_tlv_space; /* request message TLV area size */ @@ -291,22 +291,13 @@ static struct sk_buff *cfg_set_own_addr(void) if (!tipc_addr_node_valid(addr)) return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE " (node address)"); - if (tipc_mode == TIPC_NET_MODE) + if (tipc_own_addr) return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED " (cannot change node address once assigned)"); - tipc_own_addr = addr; - - /* - * Must release all spinlocks before calling start_net() because - * Linux version of TIPC calls eth_media_start() which calls - * register_netdevice_notifier() which may block! - * - * Temporarily releasing the lock should be harmless for non-Linux TIPC, - * but Linux version of eth_media_start() should really be reworked - * so that it can be called with spinlocks held. - */ spin_unlock_bh(&config_lock); + tipc_core_stop_net(); + tipc_own_addr = addr; tipc_core_start_net(); spin_lock_bh(&config_lock); return tipc_cfg_reply_none(); @@ -359,21 +350,50 @@ static struct sk_buff *cfg_set_max_subscriptions(void) static struct sk_buff *cfg_set_max_ports(void) { + int orig_mode; u32 value; if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); value = *(u32 *)TLV_DATA(req_tlv_area); value = ntohl(value); - if (value == tipc_max_ports) - return tipc_cfg_reply_none(); if (value != delimit(value, 127, 65535)) return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE " (max ports must be 127-65535)"); - if (tipc_mode != TIPC_NOT_RUNNING) + + if (value == tipc_max_ports) + return tipc_cfg_reply_none(); + + if (atomic_read(&tipc_user_count) > 2) return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change max ports while TIPC is active)"); + " (cannot change max ports while TIPC users exist)"); + + spin_unlock_bh(&config_lock); + orig_mode = tipc_get_mode(); + if (orig_mode == TIPC_NET_MODE) + tipc_core_stop_net(); + tipc_core_stop(); tipc_max_ports = value; + tipc_core_start(); + if (orig_mode == TIPC_NET_MODE) + tipc_core_start_net(); + spin_lock_bh(&config_lock); + return tipc_cfg_reply_none(); +} + +static struct sk_buff *set_net_max(int value, int *parameter) +{ + int orig_mode; + + if (value != *parameter) { + orig_mode = tipc_get_mode(); + if (orig_mode == TIPC_NET_MODE) + tipc_core_stop_net(); + *parameter = value; + if (orig_mode == TIPC_NET_MODE) + tipc_core_start_net(); + } + return tipc_cfg_reply_none(); } @@ -385,16 +405,10 @@ static struct sk_buff *cfg_set_max_zones(void) return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); value = *(u32 *)TLV_DATA(req_tlv_area); value = ntohl(value); - if (value == tipc_max_zones) - return tipc_cfg_reply_none(); if (value != delimit(value, 1, 255)) return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE " (max zones must be 1-255)"); - if (tipc_mode == TIPC_NET_MODE) - return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change max zones once TIPC has joined a network)"); - tipc_max_zones = value; - return tipc_cfg_reply_none(); + return set_net_max(value, &tipc_max_zones); } static struct sk_buff *cfg_set_max_clusters(void) @@ -405,8 +419,8 @@ static struct sk_buff *cfg_set_max_clusters(void) return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); value = *(u32 *)TLV_DATA(req_tlv_area); value = ntohl(value); - if (value != delimit(value, 1, 1)) - return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE + if (value != 1) + return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED " (max clusters fixed at 1)"); return tipc_cfg_reply_none(); } @@ -419,16 +433,10 @@ static struct sk_buff *cfg_set_max_nodes(void) return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); value = *(u32 *)TLV_DATA(req_tlv_area); value = ntohl(value); - if (value == tipc_max_nodes) - return tipc_cfg_reply_none(); if (value != delimit(value, 8, 2047)) return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE " (max nodes must be 8-2047)"); - if (tipc_mode == TIPC_NET_MODE) - return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change max nodes once TIPC has joined a network)"); - tipc_max_nodes = value; - return tipc_cfg_reply_none(); + return set_net_max(value, &tipc_max_nodes); } static struct sk_buff *cfg_set_max_slaves(void) @@ -453,16 +461,15 @@ static struct sk_buff *cfg_set_netid(void) return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); value = *(u32 *)TLV_DATA(req_tlv_area); value = ntohl(value); - if (value == tipc_net_id) - return tipc_cfg_reply_none(); if (value != delimit(value, 1, 9999)) return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE " (network id must be 1-9999)"); - if (tipc_mode == TIPC_NET_MODE) + + if (tipc_own_addr) return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change network id once TIPC has joined a network)"); - tipc_net_id = value; - return tipc_cfg_reply_none(); + " (cannot change network id once part of network)"); + + return set_net_max(value, &tipc_net_id); } struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area, @@ -642,7 +649,7 @@ static void cfg_named_msg_event(void *userdata, if ((size < sizeof(*req_hdr)) || (size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) || (ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) { - warn("Invalid configuration message discarded\n"); + warn("discarded invalid configuration message\n"); return; } @@ -676,11 +683,11 @@ int tipc_cfg_init(void) memset(&mng, 0, sizeof(mng)); INIT_LIST_HEAD(&mng.link_subscribers); - res = tipc_attach(&mng.user_ref, NULL, NULL); + res = tipc_attach(&mng.user_ref, 0, 0); if (res) goto failed; - res = tipc_createport(mng.user_ref, NULL, TIPC_CRITICAL_IMPORTANCE, + res = tipc_createport(mng.user_ref, 0, TIPC_CRITICAL_IMPORTANCE, NULL, NULL, NULL, NULL, cfg_named_msg_event, NULL, NULL, &mng.port_ref);