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

📄 heartbeat.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		    .ca_name = "blocks",		    .ca_mode = S_IRUGO | S_IWUSR },	.show	= o2hb_region_blocks_read,	.store	= o2hb_region_blocks_write,};static struct o2hb_region_attribute o2hb_region_attr_dev = {	.attr	= { .ca_owner = THIS_MODULE,		    .ca_name = "dev",		    .ca_mode = S_IRUGO | S_IWUSR },	.show	= o2hb_region_dev_read,	.store	= o2hb_region_dev_write,};static struct o2hb_region_attribute o2hb_region_attr_pid = {       .attr   = { .ca_owner = THIS_MODULE,                   .ca_name = "pid",                   .ca_mode = S_IRUGO | S_IRUSR },       .show   = o2hb_region_pid_read,};static struct configfs_attribute *o2hb_region_attrs[] = {	&o2hb_region_attr_block_bytes.attr,	&o2hb_region_attr_start_block.attr,	&o2hb_region_attr_blocks.attr,	&o2hb_region_attr_dev.attr,	&o2hb_region_attr_pid.attr,	NULL,};static ssize_t o2hb_region_show(struct config_item *item,				struct configfs_attribute *attr,				char *page){	struct o2hb_region *reg = to_o2hb_region(item);	struct o2hb_region_attribute *o2hb_region_attr =		container_of(attr, struct o2hb_region_attribute, attr);	ssize_t ret = 0;	if (o2hb_region_attr->show)		ret = o2hb_region_attr->show(reg, page);	return ret;}static ssize_t o2hb_region_store(struct config_item *item,				 struct configfs_attribute *attr,				 const char *page, size_t count){	struct o2hb_region *reg = to_o2hb_region(item);	struct o2hb_region_attribute *o2hb_region_attr =		container_of(attr, struct o2hb_region_attribute, attr);	ssize_t ret = -EINVAL;	if (o2hb_region_attr->store)		ret = o2hb_region_attr->store(reg, page, count);	return ret;}static struct configfs_item_operations o2hb_region_item_ops = {	.release		= o2hb_region_release,	.show_attribute		= o2hb_region_show,	.store_attribute	= o2hb_region_store,};static struct config_item_type o2hb_region_type = {	.ct_item_ops	= &o2hb_region_item_ops,	.ct_attrs	= o2hb_region_attrs,	.ct_owner	= THIS_MODULE,};/* heartbeat set */struct o2hb_heartbeat_group {	struct config_group hs_group;	/* some stuff? */};static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group *group){	return group ?		container_of(group, struct o2hb_heartbeat_group, hs_group)		: NULL;}static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *group,							  const char *name){	struct o2hb_region *reg = NULL;	struct config_item *ret = NULL;	reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL);	if (reg == NULL)		goto out; /* ENOMEM */	config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type);	ret = &reg->hr_item;	spin_lock(&o2hb_live_lock);	list_add_tail(&reg->hr_all_item, &o2hb_all_regions);	spin_unlock(&o2hb_live_lock);out:	if (ret == NULL)		kfree(reg);	return ret;}static void o2hb_heartbeat_group_drop_item(struct config_group *group,					   struct config_item *item){	struct task_struct *hb_task;	struct o2hb_region *reg = to_o2hb_region(item);	/* stop the thread when the user removes the region dir */	spin_lock(&o2hb_live_lock);	hb_task = reg->hr_task;	reg->hr_task = NULL;	spin_unlock(&o2hb_live_lock);	if (hb_task)		kthread_stop(hb_task);	/*	 * If we're racing a dev_write(), we need to wake them.  They will	 * check reg->hr_task	 */	if (atomic_read(&reg->hr_steady_iterations) != 0) {		atomic_set(&reg->hr_steady_iterations, 0);		wake_up(&o2hb_steady_queue);	}	config_item_put(item);}struct o2hb_heartbeat_group_attribute {	struct configfs_attribute attr;	ssize_t (*show)(struct o2hb_heartbeat_group *, char *);	ssize_t (*store)(struct o2hb_heartbeat_group *, const char *, size_t);};static ssize_t o2hb_heartbeat_group_show(struct config_item *item,					 struct configfs_attribute *attr,					 char *page){	struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item));	struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr =		container_of(attr, struct o2hb_heartbeat_group_attribute, attr);	ssize_t ret = 0;	if (o2hb_heartbeat_group_attr->show)		ret = o2hb_heartbeat_group_attr->show(reg, page);	return ret;}static ssize_t o2hb_heartbeat_group_store(struct config_item *item,					  struct configfs_attribute *attr,					  const char *page, size_t count){	struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item));	struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr =		container_of(attr, struct o2hb_heartbeat_group_attribute, attr);	ssize_t ret = -EINVAL;	if (o2hb_heartbeat_group_attr->store)		ret = o2hb_heartbeat_group_attr->store(reg, page, count);	return ret;}static ssize_t o2hb_heartbeat_group_threshold_show(struct o2hb_heartbeat_group *group,						     char *page){	return sprintf(page, "%u\n", o2hb_dead_threshold);}static ssize_t o2hb_heartbeat_group_threshold_store(struct o2hb_heartbeat_group *group,						    const char *page,						    size_t count){	unsigned long tmp;	char *p = (char *)page;	tmp = simple_strtoul(p, &p, 10);	if (!p || (*p && (*p != '\n')))                return -EINVAL;	/* this will validate ranges for us. */	o2hb_dead_threshold_set((unsigned int) tmp);	return count;}static struct o2hb_heartbeat_group_attribute o2hb_heartbeat_group_attr_threshold = {	.attr	= { .ca_owner = THIS_MODULE,		    .ca_name = "dead_threshold",		    .ca_mode = S_IRUGO | S_IWUSR },	.show	= o2hb_heartbeat_group_threshold_show,	.store	= o2hb_heartbeat_group_threshold_store,};static struct configfs_attribute *o2hb_heartbeat_group_attrs[] = {	&o2hb_heartbeat_group_attr_threshold.attr,	NULL,};static struct configfs_item_operations o2hb_hearbeat_group_item_ops = {	.show_attribute		= o2hb_heartbeat_group_show,	.store_attribute	= o2hb_heartbeat_group_store,};static struct configfs_group_operations o2hb_heartbeat_group_group_ops = {	.make_item	= o2hb_heartbeat_group_make_item,	.drop_item	= o2hb_heartbeat_group_drop_item,};static struct config_item_type o2hb_heartbeat_group_type = {	.ct_group_ops	= &o2hb_heartbeat_group_group_ops,	.ct_item_ops	= &o2hb_hearbeat_group_item_ops,	.ct_attrs	= o2hb_heartbeat_group_attrs,	.ct_owner	= THIS_MODULE,};/* this is just here to avoid touching group in heartbeat.h which the * entire damn world #includes */struct config_group *o2hb_alloc_hb_set(void){	struct o2hb_heartbeat_group *hs = NULL;	struct config_group *ret = NULL;	hs = kzalloc(sizeof(struct o2hb_heartbeat_group), GFP_KERNEL);	if (hs == NULL)		goto out;	config_group_init_type_name(&hs->hs_group, "heartbeat",				    &o2hb_heartbeat_group_type);	ret = &hs->hs_group;out:	if (ret == NULL)		kfree(hs);	return ret;}void o2hb_free_hb_set(struct config_group *group){	struct o2hb_heartbeat_group *hs = to_o2hb_heartbeat_group(group);	kfree(hs);}/* hb callback registration and issueing */static struct o2hb_callback *hbcall_from_type(enum o2hb_callback_type type){	if (type == O2HB_NUM_CB)		return ERR_PTR(-EINVAL);	return &o2hb_callbacks[type];}void o2hb_setup_callback(struct o2hb_callback_func *hc,			 enum o2hb_callback_type type,			 o2hb_cb_func *func,			 void *data,			 int priority){	INIT_LIST_HEAD(&hc->hc_item);	hc->hc_func = func;	hc->hc_data = data;	hc->hc_priority = priority;	hc->hc_type = type;	hc->hc_magic = O2HB_CB_MAGIC;}EXPORT_SYMBOL_GPL(o2hb_setup_callback);static struct o2hb_region *o2hb_find_region(const char *region_uuid){	struct o2hb_region *p, *reg = NULL;	assert_spin_locked(&o2hb_live_lock);	list_for_each_entry(p, &o2hb_all_regions, hr_all_item) {		if (!strcmp(region_uuid, config_item_name(&p->hr_item))) {			reg = p;			break;		}	}	return reg;}static int o2hb_region_get(const char *region_uuid){	int ret = 0;	struct o2hb_region *reg;	spin_lock(&o2hb_live_lock);	reg = o2hb_find_region(region_uuid);	if (!reg)		ret = -ENOENT;	spin_unlock(&o2hb_live_lock);	if (ret)		goto out;	ret = o2nm_depend_this_node();	if (ret)		goto out;	ret = o2nm_depend_item(&reg->hr_item);	if (ret)		o2nm_undepend_this_node();out:	return ret;}static void o2hb_region_put(const char *region_uuid){	struct o2hb_region *reg;	spin_lock(&o2hb_live_lock);	reg = o2hb_find_region(region_uuid);	spin_unlock(&o2hb_live_lock);	if (reg) {		o2nm_undepend_item(&reg->hr_item);		o2nm_undepend_this_node();	}}int o2hb_register_callback(const char *region_uuid,			   struct o2hb_callback_func *hc){	struct o2hb_callback_func *tmp;	struct list_head *iter;	struct o2hb_callback *hbcall;	int ret;	BUG_ON(hc->hc_magic != O2HB_CB_MAGIC);	BUG_ON(!list_empty(&hc->hc_item));	hbcall = hbcall_from_type(hc->hc_type);	if (IS_ERR(hbcall)) {		ret = PTR_ERR(hbcall);		goto out;	}	if (region_uuid) {		ret = o2hb_region_get(region_uuid);		if (ret)			goto out;	}	down_write(&o2hb_callback_sem);	list_for_each(iter, &hbcall->list) {		tmp = list_entry(iter, struct o2hb_callback_func, hc_item);		if (hc->hc_priority < tmp->hc_priority) {			list_add_tail(&hc->hc_item, iter);			break;		}	}	if (list_empty(&hc->hc_item))		list_add_tail(&hc->hc_item, &hbcall->list);	up_write(&o2hb_callback_sem);	ret = 0;out:	mlog(ML_HEARTBEAT, "returning %d on behalf of %p for funcs %p\n",	     ret, __builtin_return_address(0), hc);	return ret;}EXPORT_SYMBOL_GPL(o2hb_register_callback);void o2hb_unregister_callback(const char *region_uuid,			      struct o2hb_callback_func *hc){	BUG_ON(hc->hc_magic != O2HB_CB_MAGIC);	mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n",	     __builtin_return_address(0), hc);	/* XXX Can this happen _with_ a region reference? */	if (list_empty(&hc->hc_item))		return;	if (region_uuid)		o2hb_region_put(region_uuid);	down_write(&o2hb_callback_sem);	list_del_init(&hc->hc_item);	up_write(&o2hb_callback_sem);}EXPORT_SYMBOL_GPL(o2hb_unregister_callback);int o2hb_check_node_heartbeating(u8 node_num){	unsigned long testing_map[BITS_TO_LONGS(O2NM_MAX_NODES)];	o2hb_fill_node_map(testing_map, sizeof(testing_map));	if (!test_bit(node_num, testing_map)) {		mlog(ML_HEARTBEAT,		     "node (%u) does not have heartbeating enabled.\n",		     node_num);		return 0;	}	return 1;}EXPORT_SYMBOL_GPL(o2hb_check_node_heartbeating);int o2hb_check_node_heartbeating_from_callback(u8 node_num){	unsigned long testing_map[BITS_TO_LONGS(O2NM_MAX_NODES)];	o2hb_fill_node_map_from_callback(testing_map, sizeof(testing_map));	if (!test_bit(node_num, testing_map)) {		mlog(ML_HEARTBEAT,		     "node (%u) does not have heartbeating enabled.\n",		     node_num);		return 0;	}	return 1;}EXPORT_SYMBOL_GPL(o2hb_check_node_heartbeating_from_callback);/* Makes sure our local node is configured with a node number, and is * heartbeating. */int o2hb_check_local_node_heartbeating(void){	u8 node_num;	/* if this node was set then we have networking */	node_num = o2nm_this_node();	if (node_num == O2NM_MAX_NODES) {		mlog(ML_HEARTBEAT, "this node has not been configured.\n");		return 0;	}	return o2hb_check_node_heartbeating(node_num);}EXPORT_SYMBOL_GPL(o2hb_check_local_node_heartbeating);/* * this is just a hack until we get the plumbing which flips file systems * read only and drops the hb ref instead of killing the node dead. */void o2hb_stop_all_regions(void){	struct o2hb_region *reg;	mlog(ML_ERROR, "stopping heartbeat on all active regions.\n");	spin_lock(&o2hb_live_lock);	list_for_each_entry(reg, &o2hb_all_regions, hr_all_item)		reg->hr_unclean_stop = 1;	spin_unlock(&o2hb_live_lock);}EXPORT_SYMBOL_GPL(o2hb_stop_all_regions);

⌨️ 快捷键说明

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