* Generic node creation. Called by node initialisation for externally * instantiated nodes (e.g. hardware, sockets, etc ). * The returned node has a reference count of 1. */
| 643 | * The returned node has a reference count of 1. |
| 644 | */ |
| 645 | int |
| 646 | ng_make_node_common(struct ng_type *type, node_p *nodepp) |
| 647 | { |
| 648 | node_p node; |
| 649 | |
| 650 | /* Require the node type to have been already installed */ |
| 651 | if (ng_findtype(type->name) == NULL) { |
| 652 | TRAP_ERROR(); |
| 653 | return (EINVAL); |
| 654 | } |
| 655 | |
| 656 | /* Make a node and try attach it to the type */ |
| 657 | NG_ALLOC_NODE(node); |
| 658 | if (node == NULL) { |
| 659 | TRAP_ERROR(); |
| 660 | return (ENOMEM); |
| 661 | } |
| 662 | node->nd_type = type; |
| 663 | #ifdef VIMAGE |
| 664 | node->nd_vnet = curvnet; |
| 665 | #endif |
| 666 | NG_NODE_REF(node); /* note reference */ |
| 667 | type->refs++; |
| 668 | |
| 669 | NG_QUEUE_LOCK_INIT(&node->nd_input_queue); |
| 670 | STAILQ_INIT(&node->nd_input_queue.queue); |
| 671 | node->nd_input_queue.q_flags = 0; |
| 672 | |
| 673 | /* Initialize hook list for new node */ |
| 674 | LIST_INIT(&node->nd_hooks); |
| 675 | |
| 676 | /* Get an ID and put us in the hash chain. */ |
| 677 | IDHASH_WLOCK(); |
| 678 | for (;;) { /* wrap protection, even if silly */ |
| 679 | node_p node2 = NULL; |
| 680 | node->nd_ID = V_nextID++; /* 137/sec for 1 year before wrap */ |
| 681 | |
| 682 | /* Is there a problem with the new number? */ |
| 683 | NG_IDHASH_FIND(node->nd_ID, node2); /* already taken? */ |
| 684 | if ((node->nd_ID != 0) && (node2 == NULL)) { |
| 685 | break; |
| 686 | } |
| 687 | } |
| 688 | V_ng_nodes++; |
| 689 | if (V_ng_nodes * 2 > V_ng_ID_hmask) |
| 690 | ng_ID_rehash(); |
| 691 | LIST_INSERT_HEAD(&V_ng_ID_hash[NG_IDHASH_FN(node->nd_ID)], node, |
| 692 | nd_idnodes); |
| 693 | IDHASH_WUNLOCK(); |
| 694 | |
| 695 | /* Done */ |
| 696 | *nodepp = node; |
| 697 | return (0); |
| 698 | } |
| 699 | |
| 700 | /* |
| 701 | * Forceably start the shutdown process on a node. Either call |
no test coverage detected