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 */
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();
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();
}
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)
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();
}
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)
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,
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;
}
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);