lib/libdmsg/msg_lnk.c
void
dmsg_lnk_span(dmsg_msg_t *msg)
{
	dmsg_state_t *state = msg->state;
	h2span_cluster_t dummy_cls;
	h2span_node_t dummy_node;
	h2span_cluster_t *cls;
	h2span_node_t *node;
	h2span_link_t *slink;
	h2span_relay_t *relay;
	char *alloc = NULL;

	assert((msg->any.head.cmd & DMSGF_REPLY) == 0);

	pthread_mutex_lock(&cluster_mtx);

	/*
	 * On transaction start we initialize the tracking infrastructure
	 */
	if (msg->any.head.cmd & DMSGF_CREATE) {
		assert(state->func == NULL);
		state->func = dmsg_lnk_span;

		dmsg_termstr(msg->any.lnk_span.cl_label);
		dmsg_termstr(msg->any.lnk_span.fs_label);

		/*
		 * Find the cluster
		 */
		dummy_cls.pfs_clid = msg->any.lnk_span.pfs_clid;
		dummy_cls.peer_type = msg->any.lnk_span.peer_type;
		bcopy(msg->any.lnk_span.cl_label,
		      dummy_cls.cl_label,
		      sizeof(dummy_cls.cl_label));
		cls = RB_FIND(h2span_cluster_tree, &cluster_tree, &dummy_cls);
		if (cls == NULL) {
			cls = dmsg_alloc(sizeof(*cls));
			cls->pfs_clid = msg->any.lnk_span.pfs_clid;
			cls->peer_type = msg->any.lnk_span.peer_type;
			bcopy(msg->any.lnk_span.cl_label,
			      cls->cl_label,
			      sizeof(cls->cl_label));
			RB_INIT(&cls->tree);
			RB_INSERT(h2span_cluster_tree, &cluster_tree, cls);
		}

		/*
		 * Find the node
		 */
		dummy_node.pfs_fsid = msg->any.lnk_span.pfs_fsid;
		bcopy(msg->any.lnk_span.fs_label, dummy_node.fs_label,
		      sizeof(dummy_node.fs_label));
		node = RB_FIND(h2span_node_tree, &cls->tree, &dummy_node);
		if (node == NULL) {
			node = dmsg_alloc(sizeof(*node));
			node->pfs_fsid = msg->any.lnk_span.pfs_fsid;
			node->pfs_type = msg->any.lnk_span.pfs_type;
			bcopy(msg->any.lnk_span.fs_label,
			      node->fs_label,
			      sizeof(node->fs_label));
			node->cls = cls;
			RB_INIT(&node->tree);
			RB_INSERT(h2span_node_tree, &cls->tree, node);
			if (dmsg_node_handler) {
				dmsg_node_handler(&node->opaque, msg,
						  DMSG_NODEOP_ADD);
			}
		}

		/*
		 * Create the link
		 */
		assert(state->any.link == NULL);
		slink = dmsg_alloc(sizeof(*slink));
		TAILQ_INIT(&slink->relayq);
		slink->node = node;
		slink->dist = msg->any.lnk_span.dist;
		slink->rnss = msg->any.lnk_span.rnss;
		slink->state = state;
		state->any.link = slink;

		RB_INSERT(h2span_link_tree, &node->tree, slink);

		fprintf(stderr,
			"LNK_SPAN(thr %p): %p %s cl=%s fs=%s dist=%d\n",
			msg->iocom,
			slink,
			dmsg_uuid_to_str(&msg->any.lnk_span.pfs_clid, &alloc),
			msg->any.lnk_span.cl_label,
			msg->any.lnk_span.fs_label,
			msg->any.lnk_span.dist);
		free(alloc);
#if 0
		dmsg_relay_scan(NULL, node);
#endif
		dmsg_iocom_signal(msg->iocom);
	}

	/*
	 * On transaction terminate we remove the tracking infrastructure.
	 */
	if (msg->any.head.cmd & DMSGF_DELETE) {
		slink = state->any.link;
		assert(slink != NULL);
		node = slink->node;
		cls = node->cls;

		fprintf(stderr, "LNK_DELE(thr %p): %p %s cl=%s fs=%s dist=%d\n",
			msg->iocom,
			slink,
			dmsg_uuid_to_str(&cls->pfs_clid, &alloc),
			state->msg->any.lnk_span.cl_label,
			state->msg->any.lnk_span.fs_label,
			state->msg->any.lnk_span.dist);
		free(alloc);

		/*
		 * Clean out all relays.  This requires terminating each
		 * relay transaction.
		 */
		while ((relay = TAILQ_FIRST(&slink->relayq)) != NULL) {
			dmsg_relay_delete(relay);
		}

		/*
		 * Clean out the topology
		 */
		RB_REMOVE(h2span_link_tree, &node->tree, slink);
		if (RB_EMPTY(&node->tree)) {
			RB_REMOVE(h2span_node_tree, &cls->tree, node);
			if (dmsg_node_handler) {
				dmsg_node_handler(&node->opaque, msg,
						  DMSG_NODEOP_DEL);
			}
			if (RB_EMPTY(&cls->tree) && cls->refs == 0) {
				RB_REMOVE(h2span_cluster_tree,
					  &cluster_tree, cls);
				dmsg_free(cls);
			}
			node->cls = NULL;
			dmsg_free(node);
			node = NULL;
		}
		state->any.link = NULL;
		slink->state = NULL;
		slink->node = NULL;
		dmsg_free(slink);

		/*
		 * We have to terminate the transaction
		 */
		dmsg_state_reply(state, 0);
		/* state invalid after reply */

		/*
		 * If the node still exists issue any required updates.  If
		 * it doesn't then all related relays have already been
		 * removed and there's nothing left to do.
		 */
#if 0
		if (node)
			dmsg_relay_scan(NULL, node);
#endif
		if (node)
			dmsg_iocom_signal(msg->iocom);
	}

	pthread_mutex_unlock(&cluster_mtx);
}
/*
 * LNK_SPAN - Spanning tree protocol message reception
 *	      (incoming iocom lock not held)
 *
 * Receive a spanning tree transactional message, creating or destroying
 * a SPAN and propagating it to other iocoms.
 */
Spanning tree protocol message reception
(incoming iocom lock not held)

Receive a spanning tree transactional message, creating or destroying
a SPAN and propagating it to other iocoms.
Spanning tree protocol message reception ( incoming iocom lock not held ) Receive a spanning tree transactional message creating or destroying a SPAN and propagating it to other iocoms .
void
dmsg_lnk_span(dmsg_msg_t *msg)
{
	dmsg_state_t *state = msg->state;
	h2span_cluster_t dummy_cls;
	h2span_node_t dummy_node;
	h2span_cluster_t *cls;
	h2span_node_t *node;
	h2span_link_t *slink;
	h2span_relay_t *relay;
	char *alloc = NULL;
	assert((msg->any.head.cmd & DMSGF_REPLY) == 0);
	pthread_mutex_lock(&cluster_mtx);
	if (msg->any.head.cmd & DMSGF_CREATE) {
		assert(state->func == NULL);
		state->func = dmsg_lnk_span;
		dmsg_termstr(msg->any.lnk_span.cl_label);
		dmsg_termstr(msg->any.lnk_span.fs_label);
		dummy_cls.pfs_clid = msg->any.lnk_span.pfs_clid;
		dummy_cls.peer_type = msg->any.lnk_span.peer_type;
		bcopy(msg->any.lnk_span.cl_label,
		      dummy_cls.cl_label,
		      sizeof(dummy_cls.cl_label));
		cls = RB_FIND(h2span_cluster_tree, &cluster_tree, &dummy_cls);
		if (cls == NULL) {
			cls = dmsg_alloc(sizeof(*cls));
			cls->pfs_clid = msg->any.lnk_span.pfs_clid;
			cls->peer_type = msg->any.lnk_span.peer_type;
			bcopy(msg->any.lnk_span.cl_label,
			      cls->cl_label,
			      sizeof(cls->cl_label));
			RB_INIT(&cls->tree);
			RB_INSERT(h2span_cluster_tree, &cluster_tree, cls);
		}
		dummy_node.pfs_fsid = msg->any.lnk_span.pfs_fsid;
		bcopy(msg->any.lnk_span.fs_label, dummy_node.fs_label,
		      sizeof(dummy_node.fs_label));
		node = RB_FIND(h2span_node_tree, &cls->tree, &dummy_node);
		if (node == NULL) {
			node = dmsg_alloc(sizeof(*node));
			node->pfs_fsid = msg->any.lnk_span.pfs_fsid;
			node->pfs_type = msg->any.lnk_span.pfs_type;
			bcopy(msg->any.lnk_span.fs_label,
			      node->fs_label,
			      sizeof(node->fs_label));
			node->cls = cls;
			RB_INIT(&node->tree);
			RB_INSERT(h2span_node_tree, &cls->tree, node);
			if (dmsg_node_handler) {
				dmsg_node_handler(&node->opaque, msg,
						  DMSG_NODEOP_ADD);
			}
		}
		assert(state->any.link == NULL);
		slink = dmsg_alloc(sizeof(*slink));
		TAILQ_INIT(&slink->relayq);
		slink->node = node;
		slink->dist = msg->any.lnk_span.dist;
		slink->rnss = msg->any.lnk_span.rnss;
		slink->state = state;
		state->any.link = slink;
		RB_INSERT(h2span_link_tree, &node->tree, slink);
		fprintf(stderr,
			"LNK_SPAN(thr %p): %p %s cl=%s fs=%s dist=%d\n",
			msg->iocom,
			slink,
			dmsg_uuid_to_str(&msg->any.lnk_span.pfs_clid, &alloc),
			msg->any.lnk_span.cl_label,
			msg->any.lnk_span.fs_label,
			msg->any.lnk_span.dist);
		free(alloc);
#if 0
		dmsg_relay_scan(NULL, node);
#endif
		dmsg_iocom_signal(msg->iocom);
	}
	if (msg->any.head.cmd & DMSGF_DELETE) {
		slink = state->any.link;
		assert(slink != NULL);
		node = slink->node;
		cls = node->cls;
		fprintf(stderr, "LNK_DELE(thr %p): %p %s cl=%s fs=%s dist=%d\n",
			msg->iocom,
			slink,
			dmsg_uuid_to_str(&cls->pfs_clid, &alloc),
			state->msg->any.lnk_span.cl_label,
			state->msg->any.lnk_span.fs_label,
			state->msg->any.lnk_span.dist);
		free(alloc);
		while ((relay = TAILQ_FIRST(&slink->relayq)) != NULL) {
			dmsg_relay_delete(relay);
		}
		RB_REMOVE(h2span_link_tree, &node->tree, slink);
		if (RB_EMPTY(&node->tree)) {
			RB_REMOVE(h2span_node_tree, &cls->tree, node);
			if (dmsg_node_handler) {
				dmsg_node_handler(&node->opaque, msg,
						  DMSG_NODEOP_DEL);
			}
			if (RB_EMPTY(&cls->tree) && cls->refs == 0) {
				RB_REMOVE(h2span_cluster_tree,
					  &cluster_tree, cls);
				dmsg_free(cls);
			}
			node->cls = NULL;
			dmsg_free(node);
			node = NULL;
		}
		state->any.link = NULL;
		slink->state = NULL;
		slink->node = NULL;
		dmsg_free(slink);
		dmsg_state_reply(state, 0);
#if 0
		if (node)
			dmsg_relay_scan(NULL, node);
#endif
		if (node)
			dmsg_iocom_signal(msg->iocom);
	}
	pthread_mutex_unlock(&cluster_mtx);
}
void dmsg_lnk_span ( dmsg_msg_t * msg ) { dmsg_state_t * state = msg -> state ; h2span_cluster_t dummy_cls ; h2span_node_t dummy_node ; h2span_cluster_t * cls ; h2span_node_t * node ; h2span_link_t * slink ; h2span_relay_t * relay ; char * alloc = NULL ; assert ( ( msg -> any . head . cmd & DMSGF_REPLY ) == 0 ) ; pthread_mutex_lock ( & cluster_mtx ) ; if ( msg -> any . head . cmd & DMSGF_CREATE ) { assert ( state -> func == NULL ) ; state -> func = dmsg_lnk_span ; dmsg_termstr ( msg -> any . lnk_span . cl_label ) ; dmsg_termstr ( msg -> any . lnk_span . fs_label ) ; dummy_cls . pfs_clid = msg -> any . lnk_span . pfs_clid ; dummy_cls . peer_type = msg -> any . lnk_span . peer_type ; bcopy ( msg -> any . lnk_span . cl_label , dummy_cls . cl_label , sizeof ( dummy_cls . cl_label ) ) ; cls = RB_FIND ( h2span_cluster_tree , & cluster_tree , & dummy_cls ) ; if ( cls == NULL ) { cls = dmsg_alloc ( sizeof ( * cls ) ) ; cls -> pfs_clid = msg -> any . lnk_span . pfs_clid ; cls -> peer_type = msg -> any . lnk_span . peer_type ; bcopy ( msg -> any . lnk_span . cl_label , cls -> cl_label , sizeof ( cls -> cl_label ) ) ; RB_INIT ( & cls -> tree ) ; RB_INSERT ( h2span_cluster_tree , & cluster_tree , cls ) ; } dummy_node . pfs_fsid = msg -> any . lnk_span . pfs_fsid ; bcopy ( msg -> any . lnk_span . fs_label , dummy_node . fs_label , sizeof ( dummy_node . fs_label ) ) ; node = RB_FIND ( h2span_node_tree , & cls -> tree , & dummy_node ) ; if ( node == NULL ) { node = dmsg_alloc ( sizeof ( * node ) ) ; node -> pfs_fsid = msg -> any . lnk_span . pfs_fsid ; node -> pfs_type = msg -> any . lnk_span . pfs_type ; bcopy ( msg -> any . lnk_span . fs_label , node -> fs_label , sizeof ( node -> fs_label ) ) ; node -> cls = cls ; RB_INIT ( & node -> tree ) ; RB_INSERT ( h2span_node_tree , & cls -> tree , node ) ; if ( dmsg_node_handler ) { dmsg_node_handler ( & node -> opaque , msg , DMSG_NODEOP_ADD ) ; } } assert ( state -> any . link == NULL ) ; slink = dmsg_alloc ( sizeof ( * slink ) ) ; TAILQ_INIT ( & slink -> relayq ) ; slink -> node = node ; slink -> dist = msg -> any . lnk_span . dist ; slink -> rnss = msg -> any . lnk_span . rnss ; slink -> state = state ; state -> any . link = slink ; RB_INSERT ( h2span_link_tree , & node -> tree , slink ) ; fprintf ( stderr , " \n " , msg -> iocom , slink , dmsg_uuid_to_str ( & msg -> any . lnk_span . pfs_clid , & alloc ) , msg -> any . lnk_span . cl_label , msg -> any . lnk_span . fs_label , msg -> any . lnk_span . dist ) ; free ( alloc ) ; #if 0 dmsg_relay_scan ( NULL , node ) ; #endif dmsg_iocom_signal ( msg -> iocom ) ; } if ( msg -> any . head . cmd & DMSGF_DELETE ) { slink = state -> any . link ; assert ( slink != NULL ) ; node = slink -> node ; cls = node -> cls ; fprintf ( stderr , " \n " , msg -> iocom , slink , dmsg_uuid_to_str ( & cls -> pfs_clid , & alloc ) , state -> msg -> any . lnk_span . cl_label , state -> msg -> any . lnk_span . fs_label , state -> msg -> any . lnk_span . dist ) ; free ( alloc ) ; while ( ( relay = TAILQ_FIRST ( & slink -> relayq ) ) != NULL ) { dmsg_relay_delete ( relay ) ; } RB_REMOVE ( h2span_link_tree , & node -> tree , slink ) ; if ( RB_EMPTY ( & node -> tree ) ) { RB_REMOVE ( h2span_node_tree , & cls -> tree , node ) ; if ( dmsg_node_handler ) { dmsg_node_handler ( & node -> opaque , msg , DMSG_NODEOP_DEL ) ; } if ( RB_EMPTY ( & cls -> tree ) && cls -> refs == 0 ) { RB_REMOVE ( h2span_cluster_tree , & cluster_tree , cls ) ; dmsg_free ( cls ) ; } node -> cls = NULL ; dmsg_free ( node ) ; node = NULL ; } state -> any . link = NULL ; slink -> state = NULL ; slink -> node = NULL ; dmsg_free ( slink ) ; dmsg_state_reply ( state , 0 ) ; #if 0 if ( node ) dmsg_relay_scan ( NULL , node ) ; #endif if ( node ) dmsg_iocom_signal ( msg -> iocom ) ; } pthread_mutex_unlock ( & cluster_mtx ) ; }
LNK_SPAN - Spanning tree protocol message reception
            (incoming iocom lock not held)
LNK_SPAN - Spanning tree protocol message reception ( incoming iocom lock not held )
/*
	 * On transaction start we initialize the tracking infrastructure
	 */ /*
		 * Find the cluster
		 */ /*
		 * Find the node
		 */ /*
		 * Create the link
		 */ /*
	 * On transaction terminate we remove the tracking infrastructure.
	 */ /*
		 * Clean out all relays.  This requires terminating each
		 * relay transaction.
		 */ /*
		 * Clean out the topology
		 */ /*
		 * We have to terminate the transaction
		 */ /* state invalid after reply */ /*
		 * If the node still exists issue any required updates.  If
		 * it doesn't then all related relays have already been
		 * removed and there's nothing left to do.
		 */