Skip to content
Snippets Groups Projects
tcp.c 56.3 KiB
Newer Older
	for (i = 0; i < ARRAY_SIZE(o2net_nodes); i++) {
		struct o2nm_node *node = o2nm_get_node_by_num(i);
		if (node) {
			o2net_disconnect_node(node);
			o2nm_node_put(node);
		}
	}

	/* finish all work and tear down the work queue */
	mlog(ML_KTHREAD, "waiting for o2net thread to exit....\n");
	destroy_workqueue(o2net_wq);
	o2net_wq = NULL;

	sock_release(o2net_listen_sock);
	o2net_listen_sock = NULL;

	o2quo_conn_err(node->nd_num);
}

/* ------------------------------------------------------------ */

int o2net_init(void)
{
	unsigned long i;

	o2quo_init();

	if (o2net_debugfs_init())
		return -ENOMEM;

	o2net_hand = kzalloc(sizeof(struct o2net_handshake), GFP_KERNEL);
	o2net_keep_req = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
	o2net_keep_resp = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
	if (!o2net_hand || !o2net_keep_req || !o2net_keep_resp) {
		kfree(o2net_hand);
		kfree(o2net_keep_req);
		kfree(o2net_keep_resp);
		return -ENOMEM;
	}

	o2net_hand->protocol_version = cpu_to_be64(O2NET_PROTOCOL_VERSION);
	o2net_hand->connector_id = cpu_to_be64(1);

	o2net_keep_req->magic = cpu_to_be16(O2NET_MSG_KEEP_REQ_MAGIC);
	o2net_keep_resp->magic = cpu_to_be16(O2NET_MSG_KEEP_RESP_MAGIC);

	for (i = 0; i < ARRAY_SIZE(o2net_nodes); i++) {
		struct o2net_node *nn = o2net_nn_from_num(i);

		atomic_set(&nn->nn_timeout, 0);
		spin_lock_init(&nn->nn_lock);
		INIT_DELAYED_WORK(&nn->nn_connect_work, o2net_start_connect);
		INIT_DELAYED_WORK(&nn->nn_connect_expired,
				  o2net_connect_expired);
		INIT_DELAYED_WORK(&nn->nn_still_up, o2net_still_up);
		/* until we see hb from a node we'll return einval */
		nn->nn_persistent_error = -ENOTCONN;
		init_waitqueue_head(&nn->nn_sc_wq);
		idr_init(&nn->nn_status_idr);
		INIT_LIST_HEAD(&nn->nn_status_list);
	}

	return 0;
}

void o2net_exit(void)
{
	o2quo_exit();
	kfree(o2net_hand);
	kfree(o2net_keep_req);
	kfree(o2net_keep_resp);
	o2net_debugfs_exit();