drbd: Implemented new commands to create/delete connections/minors
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
		
					parent
					
						
							
								80883197da
							
						
					
				
			
			
				commit
				
					
						774b305518
					
				
			
		
					 5 changed files with 119 additions and 72 deletions
				
			
		| 
						 | 
					@ -1258,7 +1258,6 @@ extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev);
 | 
				
			||||||
extern void drbd_go_diskless(struct drbd_conf *mdev);
 | 
					extern void drbd_go_diskless(struct drbd_conf *mdev);
 | 
				
			||||||
extern void drbd_ldev_destroy(struct drbd_conf *mdev);
 | 
					extern void drbd_ldev_destroy(struct drbd_conf *mdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Meta data layout
 | 
					/* Meta data layout
 | 
				
			||||||
   We reserve a 128MB Block (4k aligned)
 | 
					   We reserve a 128MB Block (4k aligned)
 | 
				
			||||||
   * either at the end of the backing device
 | 
					   * either at the end of the backing device
 | 
				
			||||||
| 
						 | 
					@ -1476,8 +1475,9 @@ extern wait_queue_head_t drbd_pp_wait;
 | 
				
			||||||
extern rwlock_t global_state_lock;
 | 
					extern rwlock_t global_state_lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int conn_lowest_minor(struct drbd_tconn *tconn);
 | 
					extern int conn_lowest_minor(struct drbd_tconn *tconn);
 | 
				
			||||||
extern struct drbd_conf *drbd_new_device(unsigned int minor);
 | 
					enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, int vnr);
 | 
				
			||||||
extern void drbd_free_mdev(struct drbd_conf *mdev);
 | 
					extern void drbd_free_mdev(struct drbd_conf *mdev);
 | 
				
			||||||
 | 
					extern void drbd_delete_device(unsigned int minor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct drbd_tconn *drbd_new_tconn(char *name);
 | 
					struct drbd_tconn *drbd_new_tconn(char *name);
 | 
				
			||||||
extern void drbd_free_tconn(struct drbd_tconn *tconn);
 | 
					extern void drbd_free_tconn(struct drbd_tconn *tconn);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -614,13 +614,16 @@ char *drbd_task_to_thread_name(struct drbd_tconn *tconn, struct task_struct *tas
 | 
				
			||||||
	return thi ? thi->name : task->comm;
 | 
						return thi ? thi->name : task->comm;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_SMP
 | 
					 | 
				
			||||||
int conn_lowest_minor(struct drbd_tconn *tconn)
 | 
					int conn_lowest_minor(struct drbd_tconn *tconn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int minor = 0;
 | 
						int minor = 0;
 | 
				
			||||||
	idr_get_next(&tconn->volumes, &minor);
 | 
					
 | 
				
			||||||
 | 
						if (!idr_get_next(&tconn->volumes, &minor))
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
	return minor;
 | 
						return minor;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SMP
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs
 | 
					 * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs
 | 
				
			||||||
 * @mdev:	DRBD device.
 | 
					 * @mdev:	DRBD device.
 | 
				
			||||||
| 
						 | 
					@ -2078,15 +2081,16 @@ static void drbd_release_ee_lists(struct drbd_conf *mdev)
 | 
				
			||||||
		dev_err(DEV, "%d EEs in net list found!\n", rr);
 | 
							dev_err(DEV, "%d EEs in net list found!\n", rr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* caution. no locking.
 | 
					/* caution. no locking. */
 | 
				
			||||||
 * currently only used from module cleanup code. */
 | 
					void drbd_delete_device(unsigned int minor)
 | 
				
			||||||
static void drbd_delete_device(unsigned int minor)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct drbd_conf *mdev = minor_to_mdev(minor);
 | 
						struct drbd_conf *mdev = minor_to_mdev(minor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!mdev)
 | 
						if (!mdev)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						idr_remove(&mdev->tconn->volumes, minor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* paranoia asserts */
 | 
						/* paranoia asserts */
 | 
				
			||||||
	D_ASSERT(mdev->open_cnt == 0);
 | 
						D_ASSERT(mdev->open_cnt == 0);
 | 
				
			||||||
	D_ASSERT(list_empty(&mdev->tconn->data.work.q));
 | 
						D_ASSERT(list_empty(&mdev->tconn->data.work.q));
 | 
				
			||||||
| 
						 | 
					@ -2101,7 +2105,6 @@ static void drbd_delete_device(unsigned int minor)
 | 
				
			||||||
		bdput(mdev->this_bdev);
 | 
							bdput(mdev->this_bdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drbd_free_resources(mdev);
 | 
						drbd_free_resources(mdev);
 | 
				
			||||||
	drbd_free_tconn(mdev->tconn);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drbd_release_ee_lists(mdev);
 | 
						drbd_release_ee_lists(mdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2223,6 +2226,9 @@ struct drbd_tconn *drbd_new_tconn(char *name)
 | 
				
			||||||
	if (!tconn->name)
 | 
						if (!tconn->name)
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!zalloc_cpumask_var(&tconn->cpu_mask, GFP_KERNEL))
 | 
				
			||||||
 | 
							goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!tl_init(tconn))
 | 
						if (!tl_init(tconn))
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2252,6 +2258,7 @@ struct drbd_tconn *drbd_new_tconn(char *name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fail:
 | 
					fail:
 | 
				
			||||||
	tl_cleanup(tconn);
 | 
						tl_cleanup(tconn);
 | 
				
			||||||
 | 
						free_cpumask_var(tconn->cpu_mask);
 | 
				
			||||||
	kfree(tconn->name);
 | 
						kfree(tconn->name);
 | 
				
			||||||
	kfree(tconn);
 | 
						kfree(tconn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2265,6 +2272,7 @@ void drbd_free_tconn(struct drbd_tconn *tconn)
 | 
				
			||||||
	write_unlock_irq(&global_state_lock);
 | 
						write_unlock_irq(&global_state_lock);
 | 
				
			||||||
	idr_destroy(&tconn->volumes);
 | 
						idr_destroy(&tconn->volumes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free_cpumask_var(tconn->cpu_mask);
 | 
				
			||||||
	kfree(tconn->name);
 | 
						kfree(tconn->name);
 | 
				
			||||||
	kfree(tconn->int_dig_out);
 | 
						kfree(tconn->int_dig_out);
 | 
				
			||||||
	kfree(tconn->int_dig_in);
 | 
						kfree(tconn->int_dig_in);
 | 
				
			||||||
| 
						 | 
					@ -2272,32 +2280,31 @@ void drbd_free_tconn(struct drbd_tconn *tconn)
 | 
				
			||||||
	kfree(tconn);
 | 
						kfree(tconn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct drbd_conf *drbd_new_device(unsigned int minor)
 | 
					enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, int vnr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct drbd_conf *mdev;
 | 
						struct drbd_conf *mdev;
 | 
				
			||||||
	struct gendisk *disk;
 | 
						struct gendisk *disk;
 | 
				
			||||||
	struct request_queue *q;
 | 
						struct request_queue *q;
 | 
				
			||||||
	char conn_name[9]; /* drbd1234N */
 | 
						int vnr_got = vnr;
 | 
				
			||||||
	int vnr;
 | 
					
 | 
				
			||||||
 | 
						mdev = minor_to_mdev(minor);
 | 
				
			||||||
 | 
						if (mdev)
 | 
				
			||||||
 | 
							return ERR_MINOR_EXISTS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* GFP_KERNEL, we are outside of all write-out paths */
 | 
						/* GFP_KERNEL, we are outside of all write-out paths */
 | 
				
			||||||
	mdev = kzalloc(sizeof(struct drbd_conf), GFP_KERNEL);
 | 
						mdev = kzalloc(sizeof(struct drbd_conf), GFP_KERNEL);
 | 
				
			||||||
	if (!mdev)
 | 
						if (!mdev)
 | 
				
			||||||
		return NULL;
 | 
							return ERR_NOMEM;
 | 
				
			||||||
	sprintf(conn_name, "drbd%d", minor);
 | 
					
 | 
				
			||||||
	mdev->tconn = drbd_new_tconn(conn_name);
 | 
						mdev->tconn = tconn;
 | 
				
			||||||
	if (!mdev->tconn)
 | 
						if (!idr_pre_get(&tconn->volumes, GFP_KERNEL))
 | 
				
			||||||
		goto out_no_tconn;
 | 
							goto out_no_idr;
 | 
				
			||||||
	if (!idr_pre_get(&mdev->tconn->volumes, GFP_KERNEL))
 | 
						if (idr_get_new(&tconn->volumes, mdev, &vnr_got))
 | 
				
			||||||
		goto out_no_cpumask;
 | 
							goto out_no_idr;
 | 
				
			||||||
	if (idr_get_new(&mdev->tconn->volumes, mdev, &vnr))
 | 
						if (vnr_got != vnr) {
 | 
				
			||||||
		goto out_no_cpumask;
 | 
							dev_err(DEV, "vnr_got (%d) != vnr (%d)\n", vnr_got, vnr);
 | 
				
			||||||
	if (vnr != 0) {
 | 
							goto out_no_q;
 | 
				
			||||||
		dev_err(DEV, "vnr = %d\n", vnr);
 | 
					 | 
				
			||||||
		goto out_no_cpumask;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!zalloc_cpumask_var(&mdev->tconn->cpu_mask, GFP_KERNEL))
 | 
					 | 
				
			||||||
		goto out_no_cpumask;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mdev->minor = minor;
 | 
						mdev->minor = minor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2354,7 +2361,10 @@ struct drbd_conf *drbd_new_device(unsigned int minor)
 | 
				
			||||||
	INIT_LIST_HEAD(&mdev->current_epoch->list);
 | 
						INIT_LIST_HEAD(&mdev->current_epoch->list);
 | 
				
			||||||
	mdev->epochs = 1;
 | 
						mdev->epochs = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mdev;
 | 
						minor_table[minor] = mdev;
 | 
				
			||||||
 | 
						add_disk(disk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NO_ERROR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* out_whatever_else:
 | 
					/* out_whatever_else:
 | 
				
			||||||
	kfree(mdev->current_epoch); */
 | 
						kfree(mdev->current_epoch); */
 | 
				
			||||||
| 
						 | 
					@ -2367,12 +2377,10 @@ out_no_io_page:
 | 
				
			||||||
out_no_disk:
 | 
					out_no_disk:
 | 
				
			||||||
	blk_cleanup_queue(q);
 | 
						blk_cleanup_queue(q);
 | 
				
			||||||
out_no_q:
 | 
					out_no_q:
 | 
				
			||||||
	free_cpumask_var(mdev->tconn->cpu_mask);
 | 
						idr_remove(&tconn->volumes, vnr_got);
 | 
				
			||||||
out_no_cpumask:
 | 
					out_no_idr:
 | 
				
			||||||
	drbd_free_tconn(mdev->tconn);
 | 
					 | 
				
			||||||
out_no_tconn:
 | 
					 | 
				
			||||||
	kfree(mdev);
 | 
						kfree(mdev);
 | 
				
			||||||
	return NULL;
 | 
						return ERR_NOMEM;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* counterpart of drbd_new_device.
 | 
					/* counterpart of drbd_new_device.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -443,40 +443,6 @@ drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
 | 
				
			||||||
	return rv;
 | 
						return rv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct drbd_conf *ensure_mdev(int minor, int create)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct drbd_conf *mdev;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (minor >= minor_count)
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mdev = minor_to_mdev(minor);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!mdev && create) {
 | 
					 | 
				
			||||||
		struct gendisk *disk = NULL;
 | 
					 | 
				
			||||||
		mdev = drbd_new_device(minor);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		spin_lock_irq(&drbd_pp_lock);
 | 
					 | 
				
			||||||
		if (minor_table[minor] == NULL) {
 | 
					 | 
				
			||||||
			minor_table[minor] = mdev;
 | 
					 | 
				
			||||||
			disk = mdev->vdisk;
 | 
					 | 
				
			||||||
			mdev = NULL;
 | 
					 | 
				
			||||||
		} /* else: we lost the race */
 | 
					 | 
				
			||||||
		spin_unlock_irq(&drbd_pp_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (disk) /* we won the race above */
 | 
					 | 
				
			||||||
			/* in case we ever add a drbd_delete_device(),
 | 
					 | 
				
			||||||
			 * don't forget the del_gendisk! */
 | 
					 | 
				
			||||||
			add_disk(disk);
 | 
					 | 
				
			||||||
		else /* we lost the race above */
 | 
					 | 
				
			||||||
			drbd_free_mdev(mdev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		mdev = minor_to_mdev(minor);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return mdev;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 | 
					static int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 | 
				
			||||||
			   struct drbd_nl_cfg_reply *reply)
 | 
								   struct drbd_nl_cfg_reply *reply)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1789,12 +1755,6 @@ static int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *n
 | 
				
			||||||
	if (!expect(sc.al_extents <= DRBD_AL_EXTENTS_MAX))
 | 
						if (!expect(sc.al_extents <= DRBD_AL_EXTENTS_MAX))
 | 
				
			||||||
		sc.al_extents = DRBD_AL_EXTENTS_MAX;
 | 
							sc.al_extents = DRBD_AL_EXTENTS_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* to avoid spurious errors when configuring minors before configuring
 | 
					 | 
				
			||||||
	 * the minors they depend on: if necessary, first create the minor we
 | 
					 | 
				
			||||||
	 * depend on */
 | 
					 | 
				
			||||||
	if (sc.after >= 0)
 | 
					 | 
				
			||||||
		ensure_mdev(sc.after, 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* most sanity checks done, try to assign the new sync-after
 | 
						/* most sanity checks done, try to assign the new sync-after
 | 
				
			||||||
	 * dependency.  need to hold the global lock in there,
 | 
						 * dependency.  need to hold the global lock in there,
 | 
				
			||||||
	 * to avoid a race in the dependency loop check. */
 | 
						 * to avoid a race in the dependency loop check. */
 | 
				
			||||||
| 
						 | 
					@ -2184,13 +2144,73 @@ out:
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int drbd_nl_new_conn(struct drbd_nl_cfg_req *nlp, struct drbd_nl_cfg_reply *reply)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct new_connection args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!new_connection_from_tags(nlp->tag_list, &args)) {
 | 
				
			||||||
 | 
							reply->ret_code = ERR_MANDATORY_TAG;
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reply->ret_code = NO_ERROR;
 | 
				
			||||||
 | 
						if (!drbd_new_tconn(args.name))
 | 
				
			||||||
 | 
							reply->ret_code = ERR_NOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int drbd_nl_new_minor(struct drbd_tconn *tconn,
 | 
				
			||||||
 | 
							      struct drbd_nl_cfg_req *nlp, struct drbd_nl_cfg_reply *reply)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct new_minor args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args.vol_nr = 0;
 | 
				
			||||||
 | 
						args.minor = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!new_minor_from_tags(nlp->tag_list, &args)) {
 | 
				
			||||||
 | 
							reply->ret_code = ERR_MANDATORY_TAG;
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reply->ret_code = conn_new_minor(tconn, args.minor, args.vol_nr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int drbd_nl_del_minor(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 | 
				
			||||||
 | 
								     struct drbd_nl_cfg_reply *reply)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (mdev->state.disk == D_DISKLESS &&
 | 
				
			||||||
 | 
						    mdev->state.conn == C_STANDALONE &&
 | 
				
			||||||
 | 
						    mdev->state.role == R_SECONDARY) {
 | 
				
			||||||
 | 
							drbd_delete_device(mdev_to_minor(mdev));
 | 
				
			||||||
 | 
							reply->ret_code = NO_ERROR;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							reply->ret_code = ERR_MINOR_CONFIGURED;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int drbd_nl_del_conn(struct drbd_tconn *tconn,
 | 
				
			||||||
 | 
								    struct drbd_nl_cfg_req *nlp, struct drbd_nl_cfg_reply *reply)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (conn_lowest_minor(tconn) < 0) {
 | 
				
			||||||
 | 
							drbd_free_tconn(tconn);
 | 
				
			||||||
 | 
							reply->ret_code = NO_ERROR;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							reply->ret_code = ERR_CONN_IN_USE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum cn_handler_type {
 | 
					enum cn_handler_type {
 | 
				
			||||||
	CHT_MINOR,
 | 
						CHT_MINOR,
 | 
				
			||||||
	CHT_CONN,
 | 
						CHT_CONN,
 | 
				
			||||||
	CHT_CTOR,
 | 
						CHT_CTOR,
 | 
				
			||||||
	/* CHT_RES, later */
 | 
						/* CHT_RES, later */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
struct cn_handler_struct {
 | 
					struct cn_handler_struct {
 | 
				
			||||||
	enum cn_handler_type type;
 | 
						enum cn_handler_type type;
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
| 
						 | 
					@ -2235,6 +2255,10 @@ static struct cn_handler_struct cnd_table[] = {
 | 
				
			||||||
				    sizeof(struct get_timeout_flag_tag_len_struct)},
 | 
									    sizeof(struct get_timeout_flag_tag_len_struct)},
 | 
				
			||||||
	[ P_start_ov ]		= { CHT_MINOR, { &drbd_nl_start_ov },	0 },
 | 
						[ P_start_ov ]		= { CHT_MINOR, { &drbd_nl_start_ov },	0 },
 | 
				
			||||||
	[ P_new_c_uuid ]	= { CHT_MINOR, { &drbd_nl_new_c_uuid },	0 },
 | 
						[ P_new_c_uuid ]	= { CHT_MINOR, { &drbd_nl_new_c_uuid },	0 },
 | 
				
			||||||
 | 
						[ P_new_connection ]	= { CHT_CTOR,  { .constructor = &drbd_nl_new_conn }, 0 },
 | 
				
			||||||
 | 
						[ P_new_minor ]		= { CHT_CONN,  { .conn_based = &drbd_nl_new_minor }, 0 },
 | 
				
			||||||
 | 
						[ P_del_minor ]		= { CHT_MINOR, { &drbd_nl_del_minor },	0 },
 | 
				
			||||||
 | 
						[ P_del_connection ]    = { CHT_CONN,  { .conn_based = &drbd_nl_del_conn }, 0 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms *nsp)
 | 
					static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms *nsp)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,6 +156,9 @@ enum drbd_ret_code {
 | 
				
			||||||
	ERR_PIC_AFTER_DEP	= 156,
 | 
						ERR_PIC_AFTER_DEP	= 156,
 | 
				
			||||||
	ERR_PIC_PEER_DEP	= 157,
 | 
						ERR_PIC_PEER_DEP	= 157,
 | 
				
			||||||
	ERR_CONN_NOT_KNOWN      = 158,
 | 
						ERR_CONN_NOT_KNOWN      = 158,
 | 
				
			||||||
 | 
						ERR_CONN_IN_USE         = 159,
 | 
				
			||||||
 | 
						ERR_MINOR_CONFIGURED    = 160,
 | 
				
			||||||
 | 
						ERR_MINOR_EXISTS	= 161,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* insert new ones above this line */
 | 
						/* insert new ones above this line */
 | 
				
			||||||
	AFTER_LAST_ERR_CODE
 | 
						AFTER_LAST_ERR_CODE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -152,6 +152,18 @@ NL_PACKET(new_c_uuid, 26,
 | 
				
			||||||
NL_RESPONSE(return_code_only, 27)
 | 
					NL_RESPONSE(return_code_only, 27)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NL_PACKET(new_connection, 28, /* CHT_CTOR */
 | 
				
			||||||
 | 
						NL_STRING(	85,	T_MANDATORY,	name, DRBD_NL_OBJ_NAME_LEN)
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NL_PACKET(new_minor, 29, /* CHT_CONN */
 | 
				
			||||||
 | 
						NL_INTEGER(	86,	T_MANDATORY,	minor)
 | 
				
			||||||
 | 
						NL_INTEGER(	87,	T_MANDATORY,	vol_nr)
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NL_PACKET(del_minor, 30, ) /* CHT_MINOR */
 | 
				
			||||||
 | 
					NL_PACKET(del_connection, 31, ) /* CHT_CONN */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef NL_PACKET
 | 
					#undef NL_PACKET
 | 
				
			||||||
#undef NL_INTEGER
 | 
					#undef NL_INTEGER
 | 
				
			||||||
#undef NL_INT64
 | 
					#undef NL_INT64
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue