⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dlmdomain.c

📁 ocfs1.4.1 oracle分布式文件系统
💻 C
📖 第 1 页 / 共 4 页
字号:
	memset(&cancel_msg, 0, sizeof(cancel_msg));	cancel_msg.node_idx = dlm->node_num;	cancel_msg.name_len = strlen(dlm->name);	memcpy(cancel_msg.domain, dlm->name, cancel_msg.name_len);	status = o2net_send_message(DLM_CANCEL_JOIN_MSG, DLM_MOD_KEY,				    &cancel_msg, sizeof(cancel_msg), node,				    NULL);	if (status < 0) {		mlog_errno(status);		goto bail;	}bail:	return status;}/* map_size should be in bytes. */static int dlm_send_join_cancels(struct dlm_ctxt *dlm,				 unsigned long *node_map,				 unsigned int map_size){	int status, tmpstat;	unsigned int node;	if (map_size != (BITS_TO_LONGS(O2NM_MAX_NODES) *			 sizeof(unsigned long))) {		mlog(ML_ERROR,		     "map_size %u != BITS_TO_LONGS(O2NM_MAX_NODES) %u\n",		     map_size, (unsigned)BITS_TO_LONGS(O2NM_MAX_NODES));		return -EINVAL;	}	status = 0;	node = -1;	while ((node = find_next_bit(node_map, O2NM_MAX_NODES,				     node + 1)) < O2NM_MAX_NODES) {		if (node == dlm->node_num)			continue;		tmpstat = dlm_send_one_join_cancel(dlm, node);		if (tmpstat) {			mlog(ML_ERROR, "Error return %d cancelling join on "			     "node %d\n", tmpstat, node);			if (!status)				status = tmpstat;		}	}	if (status)		mlog_errno(status);	return status;}static int dlm_request_join(struct dlm_ctxt *dlm,			    int node,			    enum dlm_query_join_response_code *response){	int status;	struct dlm_query_join_request join_msg;	struct dlm_query_join_packet packet;	u32 join_resp;	mlog(0, "querying node %d\n", node);	memset(&join_msg, 0, sizeof(join_msg));	join_msg.node_idx = dlm->node_num;	join_msg.name_len = strlen(dlm->name);	memcpy(join_msg.domain, dlm->name, join_msg.name_len);	join_msg.dlm_proto = dlm->dlm_locking_proto;	join_msg.fs_proto = dlm->fs_locking_proto;	/* copy live node map to join message */	byte_copymap(join_msg.node_map, dlm->live_nodes_map, O2NM_MAX_NODES);	status = o2net_send_message(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY, &join_msg,				    sizeof(join_msg), node,				    &join_resp);	if (status < 0 && status != -ENOPROTOOPT) {		mlog_errno(status);		goto bail;	}	dlm_query_join_wire_to_packet(join_resp, &packet);	/* -ENOPROTOOPT from the net code means the other side isn't	    listening for our message type -- that's fine, it means	    his dlm isn't up, so we can consider him a 'yes' but not	    joined into the domain.  */	if (status == -ENOPROTOOPT) {		status = 0;		*response = JOIN_OK_NO_MAP;	} else if (packet.code == JOIN_DISALLOW ||		   packet.code == JOIN_OK_NO_MAP) {		*response = packet.code;	} else if (packet.code == JOIN_PROTOCOL_MISMATCH) {		mlog(ML_NOTICE,		     "This node requested DLM locking protocol %u.%u and "		     "filesystem locking protocol %u.%u.  At least one of "		     "the protocol versions on node %d is not compatible, "		     "disconnecting\n",		     dlm->dlm_locking_proto.pv_major,		     dlm->dlm_locking_proto.pv_minor,		     dlm->fs_locking_proto.pv_major,		     dlm->fs_locking_proto.pv_minor,		     node);		status = -EPROTO;		*response = packet.code;	} else if (packet.code == JOIN_OK) {		*response = packet.code;		/* Use the same locking protocol as the remote node */		dlm->dlm_locking_proto.pv_minor = packet.dlm_minor;		dlm->fs_locking_proto.pv_minor = packet.fs_minor;		mlog(0,		     "Node %d responds JOIN_OK with DLM locking protocol "		     "%u.%u and fs locking protocol %u.%u\n",		     node,		     dlm->dlm_locking_proto.pv_major,		     dlm->dlm_locking_proto.pv_minor,		     dlm->fs_locking_proto.pv_major,		     dlm->fs_locking_proto.pv_minor);	} else {		status = -EINVAL;		mlog(ML_ERROR, "invalid response %d from node %u\n",		     packet.code, node);	}	mlog(0, "status %d, node %d response is %d\n", status, node,	     *response);bail:	return status;}static int dlm_send_one_join_assert(struct dlm_ctxt *dlm,				    unsigned int node){	int status;	struct dlm_assert_joined assert_msg;	mlog(0, "Sending join assert to node %u\n", node);	memset(&assert_msg, 0, sizeof(assert_msg));	assert_msg.node_idx = dlm->node_num;	assert_msg.name_len = strlen(dlm->name);	memcpy(assert_msg.domain, dlm->name, assert_msg.name_len);	status = o2net_send_message(DLM_ASSERT_JOINED_MSG, DLM_MOD_KEY,				    &assert_msg, sizeof(assert_msg), node,				    NULL);	if (status < 0)		mlog_errno(status);	return status;}static void dlm_send_join_asserts(struct dlm_ctxt *dlm,				  unsigned long *node_map){	int status, node, live;	status = 0;	node = -1;	while ((node = find_next_bit(node_map, O2NM_MAX_NODES,				     node + 1)) < O2NM_MAX_NODES) {		if (node == dlm->node_num)			continue;		do {			/* It is very important that this message be			 * received so we spin until either the node			 * has died or it gets the message. */			status = dlm_send_one_join_assert(dlm, node);			spin_lock(&dlm->spinlock);			live = test_bit(node, dlm->live_nodes_map);			spin_unlock(&dlm->spinlock);			if (status) {				mlog(ML_ERROR, "Error return %d asserting "				     "join on node %d\n", status, node);				/* give us some time between errors... */				if (live)					msleep(DLM_DOMAIN_BACKOFF_MS);			}		} while (status && live);	}}struct domain_join_ctxt {	unsigned long live_map[BITS_TO_LONGS(O2NM_MAX_NODES)];	unsigned long yes_resp_map[BITS_TO_LONGS(O2NM_MAX_NODES)];};static int dlm_should_restart_join(struct dlm_ctxt *dlm,				   struct domain_join_ctxt *ctxt,				   enum dlm_query_join_response_code response){	int ret;	if (response == JOIN_DISALLOW) {		mlog(0, "Latest response of disallow -- should restart\n");		return 1;	}	spin_lock(&dlm->spinlock);	/* For now, we restart the process if the node maps have	 * changed at all */	ret = memcmp(ctxt->live_map, dlm->live_nodes_map,		     sizeof(dlm->live_nodes_map));	spin_unlock(&dlm->spinlock);	if (ret)		mlog(0, "Node maps changed -- should restart\n");	return ret;}static int dlm_try_to_join_domain(struct dlm_ctxt *dlm){	int status = 0, tmpstat, node;	struct domain_join_ctxt *ctxt;	enum dlm_query_join_response_code response = JOIN_DISALLOW;	mlog_entry("%p", dlm);	ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);	if (!ctxt) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	/* group sem locking should work for us here -- we're already	 * registered for heartbeat events so filling this should be	 * atomic wrt getting those handlers called. */	o2hb_fill_node_map(dlm->live_nodes_map, sizeof(dlm->live_nodes_map));	spin_lock(&dlm->spinlock);	memcpy(ctxt->live_map, dlm->live_nodes_map, sizeof(ctxt->live_map));	__dlm_set_joining_node(dlm, dlm->node_num);	spin_unlock(&dlm->spinlock);	node = -1;	while ((node = find_next_bit(ctxt->live_map, O2NM_MAX_NODES,				     node + 1)) < O2NM_MAX_NODES) {		if (node == dlm->node_num)			continue;		status = dlm_request_join(dlm, node, &response);		if (status < 0) {			mlog_errno(status);			goto bail;		}		/* Ok, either we got a response or the node doesn't have a		 * dlm up. */		if (response == JOIN_OK)			set_bit(node, ctxt->yes_resp_map);		if (dlm_should_restart_join(dlm, ctxt, response)) {			status = -EAGAIN;			goto bail;		}	}	mlog(0, "Yay, done querying nodes!\n");	/* Yay, everyone agree's we can join the domain. My domain is	 * comprised of all nodes who were put in the	 * yes_resp_map. Copy that into our domain map and send a join	 * assert message to clean up everyone elses state. */	spin_lock(&dlm->spinlock);	memcpy(dlm->domain_map, ctxt->yes_resp_map,	       sizeof(ctxt->yes_resp_map));	set_bit(dlm->node_num, dlm->domain_map);	spin_unlock(&dlm->spinlock);	dlm_send_join_asserts(dlm, ctxt->yes_resp_map);	/* Joined state *must* be set before the joining node	 * information, otherwise the query_join handler may read no	 * current joiner but a state of NEW and tell joining nodes	 * we're not in the domain. */	spin_lock(&dlm_domain_lock);	dlm->dlm_state = DLM_CTXT_JOINED;	dlm->num_joins++;	spin_unlock(&dlm_domain_lock);bail:	spin_lock(&dlm->spinlock);	__dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);	if (!status)		__dlm_print_nodes(dlm);	spin_unlock(&dlm->spinlock);	if (ctxt) {		/* Do we need to send a cancel message to any nodes? */		if (status < 0) {			tmpstat = dlm_send_join_cancels(dlm,							ctxt->yes_resp_map,							sizeof(ctxt->yes_resp_map));			if (tmpstat < 0)				mlog_errno(tmpstat);		}		kfree(ctxt);	}	mlog(0, "returning %d\n", status);	return status;}static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm){	o2hb_unregister_callback(NULL, &dlm->dlm_hb_up);	o2hb_unregister_callback(NULL, &dlm->dlm_hb_down);	o2net_unregister_handler_list(&dlm->dlm_domain_handlers);}static int dlm_register_domain_handlers(struct dlm_ctxt *dlm){	int status;	mlog(0, "registering handlers.\n");	o2hb_setup_callback(&dlm->dlm_hb_down, O2HB_NODE_DOWN_CB,			    dlm_hb_node_down_cb, dlm, DLM_HB_NODE_DOWN_PRI);	status = o2hb_register_callback(NULL, &dlm->dlm_hb_down);	if (status)		goto bail;	o2hb_setup_callback(&dlm->dlm_hb_up, O2HB_NODE_UP_CB,			    dlm_hb_node_up_cb, dlm, DLM_HB_NODE_UP_PRI);	status = o2hb_register_callback(NULL, &dlm->dlm_hb_up);	if (status)		goto bail;	status = o2net_register_handler(DLM_MASTER_REQUEST_MSG, dlm->key,					sizeof(struct dlm_master_request),					dlm_master_request_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_ASSERT_MASTER_MSG, dlm->key,					sizeof(struct dlm_assert_master),					dlm_assert_master_handler,					dlm, dlm_assert_master_post_handler,					&dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_CREATE_LOCK_MSG, dlm->key,					sizeof(struct dlm_create_lock),					dlm_create_lock_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_CONVERT_LOCK_MSG, dlm->key,					DLM_CONVERT_LOCK_MAX_LEN,					dlm_convert_lock_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_UNLOCK_LOCK_MSG, dlm->key,					DLM_UNLOCK_LOCK_MAX_LEN,					dlm_unlock_lock_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_PROXY_AST_MSG, dlm->key,					DLM_PROXY_AST_MAX_LEN,					dlm_proxy_ast_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_EXIT_DOMAIN_MSG, dlm->key,					sizeof(struct dlm_exit_domain),					dlm_exit_domain_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_DEREF_LOCKRES_MSG, dlm->key,					sizeof(struct dlm_deref_lockres),					dlm_deref_lockres_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_MIGRATE_REQUEST_MSG, dlm->key,					sizeof(struct dlm_migrate_request),					dlm_migrate_request_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_MIG_LOCKRES_MSG, dlm->key,					DLM_MIG_LOCKRES_MAX_LEN,					dlm_mig_lockres_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_MASTER_REQUERY_MSG, dlm->key,					sizeof(struct dlm_master_requery),					dlm_master_requery_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_LOCK_REQUEST_MSG, dlm->key,					sizeof(struct dlm_lock_request),					dlm_request_all_locks_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_RECO_DATA_DONE_MSG, dlm->key,					sizeof(struct dlm_reco_data_done),					dlm_reco_data_done_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_BEGIN_RECO_MSG, dlm->key,					sizeof(struct dlm_begin_reco),					dlm_begin_reco_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;	status = o2net_register_handler(DLM_FINALIZE_RECO_MSG, dlm->key,					sizeof(struct dlm_finalize_reco),					dlm_finalize_reco_handler,					dlm, NULL, &dlm->dlm_domain_handlers);	if (status)		goto bail;bail:	if (status)		dlm_unregister_domain_handlers(dlm);	return status;}static int dlm_join_domain(struct dlm_ctxt *dlm){	int status;	unsigned int backoff;	unsigned int total_backoff = 0;	BUG_ON(!dlm);	mlog(0, "Join domain %s\n", dlm->name);	status = dlm_register_domain_handlers(dlm);	if (status) {		mlog_errno(status);		goto bail;	}	status = dlm_debug_init(dlm);	if (status < 0) {		mlog_errno(status);		goto bail;	}	status = dlm_launch_thread(dlm);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -