-mach_node_register(mach_node_t node)
-{
- assert(MACH_NODE_VALID(node));
- mach_node_id_t nid = node->info.node_id;
- assert(MACH_NODE_ID_VALID(nid));
-
- kern_return_t kr;
- ipc_space_t proxy_space = IS_NULL;
- ipc_pset_t pp_set = IPS_NULL; // pset for proxy ports
- ipc_port_t bs_port = MACH_PORT_NULL;
- ipc_port_t ack_port = MACH_PORT_NULL;
-
- printf("mach_node_register(%d)\n", nid);
-
- /* TODO: Support non-native byte order and data models */
- if ((node->info.byteorder != OSHostByteOrder()) ||
- (node->info.datamodel != LOCAL_DATA_MODEL)) {
- printf("mach_node_register: unsupported byte order (%d) or width (%d)",
- node->info.byteorder, node->info.datamodel);
- return KERN_INVALID_ARGUMENT;
- }
-
- /* Create the space that holds all local rights assigned to <nid> */
- kr = ipc_space_create_special(&proxy_space);
- if (kr != KERN_SUCCESS)
- goto out;
- proxy_space->is_node_id = nid;
-
- /* Create the bootstrap proxy port for this remote node */
- bs_port = ipc_port_alloc_special(proxy_space);
- if (bs_port == MACH_PORT_NULL) {
- kr = KERN_RESOURCE_SHORTAGE;
- goto out;
- }
-
- /* Create the control (ack) port for this remote node */
- ack_port = ipc_port_alloc_special(proxy_space);
- if (ack_port == MACH_PORT_NULL) {
- kr = KERN_RESOURCE_SHORTAGE;
- goto out;
- }
-
- /* Create the set that holds all proxy ports for this remote node */
- pp_set = ipc_pset_alloc_special(proxy_space);
- if (pp_set == IPS_NULL) {
- kr = KERN_RESOURCE_SHORTAGE;
- goto out;
- }
-
- /* Add the bootstrap port to the proxy port set */
- uint64_t wq_link_id = waitq_link_reserve(NULL);
- uint64_t wq_reserved_prepost = waitq_prepost_reserve(NULL, 10,
- WAITQ_DONT_LOCK);
- ips_lock(pp_set);
- ip_lock(bs_port);
- ipc_pset_add(pp_set,
- bs_port,
- &wq_link_id,
- &wq_reserved_prepost);
- ip_unlock(bs_port);
- ips_unlock(pp_set);
-
- waitq_link_release(wq_link_id);
- waitq_prepost_release_reserve(wq_reserved_prepost);
-
- /* Add the control port to the proxy port set */
- wq_link_id = waitq_link_reserve(NULL);
- wq_reserved_prepost = waitq_prepost_reserve(NULL, 10,
- WAITQ_DONT_LOCK);
- ips_lock(pp_set);
- ip_lock(ack_port);
- ipc_pset_add(pp_set,
- ack_port,
- &wq_link_id,
- &wq_reserved_prepost);
- ip_unlock(ack_port);
- ips_unlock(pp_set);
-
- waitq_link_release(wq_link_id);
- waitq_prepost_release_reserve(wq_reserved_prepost);
-
- // Setup mach_node struct
- node->published = 0;
- node->active = 1;
- node->proxy_space = proxy_space;
- node->proxy_port_set = pp_set;
- node->bootstrap_port = bs_port;
- node->proto_vers = node->info.proto_vers_max;
- node->control_port = ack_port;
-
- // Place new mach_node struct into node table
- MACH_NODE_TABLE_LOCK();
-
- mach_node_t old_node = mach_node_table[nid];
- if (!MACH_NODE_VALID(old_node) || (old_node->dead)) {
- node->antecedent = old_node;
- flipc_node_prepare(node);
- mach_node_table[nid] = node;
- mach_nodes_to_publish++;
- mach_node_publish(node);
- kr = KERN_SUCCESS;
- } else {
- printf("mach_node_register: id %d already active!", nid);
- kr = KERN_FAILURE;
- }
- MACH_NODE_TABLE_UNLOCK();
+mach_node_register(mach_node_t node)
+{
+ assert(MACH_NODE_VALID(node));
+ mach_node_id_t nid = node->info.node_id;
+ assert(MACH_NODE_ID_VALID(nid));
+
+ kern_return_t kr;
+ ipc_space_t proxy_space = IS_NULL;
+ ipc_pset_t pp_set = IPS_NULL; // pset for proxy ports
+ ipc_port_t bs_port = MACH_PORT_NULL;
+ ipc_port_t ack_port = MACH_PORT_NULL;
+
+ printf("mach_node_register(%d)\n", nid);
+
+ /* TODO: Support non-native byte order and data models */
+ if ((node->info.byteorder != OSHostByteOrder()) ||
+ (node->info.datamodel != LOCAL_DATA_MODEL)) {
+ printf("mach_node_register: unsupported byte order (%d) or width (%d)",
+ node->info.byteorder, node->info.datamodel);
+ return KERN_INVALID_ARGUMENT;
+ }
+
+ /* Create the space that holds all local rights assigned to <nid> */
+ kr = ipc_space_create_special(&proxy_space);
+ if (kr != KERN_SUCCESS) {
+ goto out;
+ }
+ proxy_space->is_node_id = nid;
+
+ /* Create the bootstrap proxy port for this remote node */
+ bs_port = ipc_port_alloc_special(proxy_space, IPC_PORT_INIT_MESSAGE_QUEUE);
+ if (bs_port == MACH_PORT_NULL) {
+ kr = KERN_RESOURCE_SHORTAGE;
+ goto out;
+ }
+
+ /* Create the control (ack) port for this remote node */
+ ack_port = ipc_port_alloc_special(proxy_space, IPC_PORT_INIT_MESSAGE_QUEUE);
+ if (ack_port == MACH_PORT_NULL) {
+ kr = KERN_RESOURCE_SHORTAGE;
+ goto out;
+ }
+
+ /* Create the set that holds all proxy ports for this remote node */
+ pp_set = ipc_pset_alloc_special(proxy_space);
+ if (pp_set == IPS_NULL) {
+ kr = KERN_RESOURCE_SHORTAGE;
+ goto out;
+ }
+
+ waitq_set_lazy_init_link(pp_set);
+ /* Add the bootstrap port to the proxy port set */
+ uint64_t wq_link_id = waitq_link_reserve(NULL);
+ uint64_t wq_reserved_prepost = waitq_prepost_reserve(NULL, 10,
+ WAITQ_DONT_LOCK);
+ ips_lock(pp_set);
+ ip_lock(bs_port);
+ ipc_pset_add(pp_set,
+ bs_port,
+ &wq_link_id,
+ &wq_reserved_prepost);
+ ip_unlock(bs_port);
+ ips_unlock(pp_set);
+
+ waitq_link_release(wq_link_id);
+ waitq_prepost_release_reserve(wq_reserved_prepost);
+
+ /* Add the control port to the proxy port set */
+ wq_link_id = waitq_link_reserve(NULL);
+ wq_reserved_prepost = waitq_prepost_reserve(NULL, 10,
+ WAITQ_DONT_LOCK);
+ ips_lock(pp_set);
+ ip_lock(ack_port);
+ ipc_pset_add(pp_set,
+ ack_port,
+ &wq_link_id,
+ &wq_reserved_prepost);
+ ip_unlock(ack_port);
+ ips_unlock(pp_set);
+
+ waitq_link_release(wq_link_id);
+ waitq_prepost_release_reserve(wq_reserved_prepost);
+
+ // Setup mach_node struct
+ node->published = 0;
+ node->active = 1;
+ node->proxy_space = proxy_space;
+ node->proxy_port_set = pp_set;
+ node->bootstrap_port = bs_port;
+ node->proto_vers = node->info.proto_vers_max;
+ node->control_port = ack_port;
+
+ // Place new mach_node struct into node table
+ MACH_NODE_TABLE_LOCK();
+
+ mach_node_t old_node = mach_node_table[nid];
+ if (!MACH_NODE_VALID(old_node) || (old_node->dead)) {
+ node->antecedent = old_node;
+ flipc_node_prepare(node);
+ mach_node_table[nid] = node;
+ mach_nodes_to_publish++;
+ mach_node_publish(node);
+ kr = KERN_SUCCESS;
+ } else {
+ printf("mach_node_register: id %d already active!", nid);
+ kr = KERN_FAILURE;
+ }
+ MACH_NODE_TABLE_UNLOCK();