[sheepdog] [PATCH] dog: let sheeps prevent inode update requests during snapshot creation

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Mon Aug 25 03:21:06 CEST 2014


At Fri, 22 Aug 2014 13:32:42 +0900,
Hitoshi Mitake wrote:
> 
> The recent new GC algorithm requires mutual exclusion between inode
> update and and snapshot creation. This patch let sheeps prevent inode
> update requests during snapshot creation with VDI locking information.
> 
> Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
> ---
>  dog/vdi.c | 131 +++++++++++++++++++++++++++++++++++++++++++-------------------
>  1 file changed, 91 insertions(+), 40 deletions(-)

Applied.

Thanks,
Hitoshi

> 
> diff --git a/dog/vdi.c b/dog/vdi.c
> index cd85b65..19da73e 100644
> --- a/dog/vdi.c
> +++ b/dog/vdi.c
> @@ -517,6 +517,47 @@ out:
>  	return ret;
>  }
>  
> +static struct vdi_state *get_vdi_state(int *count)
> +{
> +	int ret;
> +	struct sd_req hdr;
> +	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
> +	struct vdi_state *vs = NULL;
> +	unsigned int rlen;
> +
> +#define DEFAULT_VDI_STATE_COUNT 512
> +	rlen = DEFAULT_VDI_STATE_COUNT * sizeof(struct vdi_state);
> +	vs = xzalloc(rlen);
> +retry:
> +	sd_init_req(&hdr, SD_OP_GET_VDI_COPIES);
> +	hdr.data_length = rlen;
> +
> +	ret = dog_exec_req(&sd_nid, &hdr, (char *)vs);
> +	if (ret < 0)
> +		goto fail;
> +
> +	switch (ret) {
> +	case SD_RES_SUCCESS:
> +		break;
> +	case SD_RES_BUFFER_SMALL:
> +		rlen *= 2;
> +		vs = xrealloc(vs, rlen);
> +		goto retry;
> +	default:
> +		sd_err("failed to execute SD_OP_GET_VDI_COPIES: %s",
> +		       sd_strerror(ret));
> +		goto fail;
> +	}
> +
> +	*count = rsp->data_length / sizeof(*vs);
> +	return vs;
> +
> +fail:
> +	free(vs);
> +	vs = NULL;
> +	return NULL;
> +}
> +
>  static int vdi_snapshot(int argc, char **argv)
>  {
>  	const char *vdiname = argv[optind++];
> @@ -525,6 +566,10 @@ static int vdi_snapshot(int argc, char **argv)
>  	char buf[SD_INODE_HEADER_SIZE];
>  	struct sd_inode *inode = (struct sd_inode *)buf;
>  	struct sd_req hdr;
> +	struct vdi_state *vs = NULL;
> +	int vs_count = 0;
> +	struct node_id owners[SD_MAX_COPIES];
> +	int nr_owners = 0, nr_issued_prevent_inode_update = 0;
>  
>  	if (vdi_cmd_data.snapshot_id != 0) {
>  		sd_err("Please specify a non-integer value for "
> @@ -541,11 +586,43 @@ static int vdi_snapshot(int argc, char **argv)
>  		return EXIT_FAILURE;
>  	}
>  
> -	sd_init_req(&hdr, SD_OP_PREVENT_INODE_UPDATE);
> -	ret = dog_exec_req(&sd_nid, &hdr, NULL);
> -	if (ret < 0) {
> -		sd_err("preventing inode update failed");
> +	vs = get_vdi_state(&vs_count);
> +	if (!vs)
>  		return EXIT_FAILURE;
> +
> +	for (int i = 0; i < vs_count; i++) {
> +		struct vdi_state *s = &vs[i];
> +
> +		if (s->vid != vid)
> +			continue;
> +
> +		if (s->lock_state == LOCK_STATE_LOCKED) {
> +			/* QEMU is using it */
> +			memset(&owners[0], 0, sizeof(owners[0]));
> +			memcpy(&owners[0], &s->lock_owner, sizeof(owners[0]));
> +			nr_owners = 1;
> +		} else {
> +			/* tgt is using it */
> +			for (int j = 0; j < s->nr_participants; i++) {
> +				memset(&owners[nr_owners], 0,
> +				       sizeof(owners[nr_owners]));
> +				memcpy(&owners[nr_owners],
> +				       &s->participants[nr_owners],
> +				       sizeof(owners[nr_owners]));
> +				nr_owners++;
> +			}
> +		}
> +	}
> +
> +	for (int i = 0; i < nr_owners; i++) {
> +		sd_init_req(&hdr, SD_OP_PREVENT_INODE_UPDATE);
> +		ret = dog_exec_req(&owners[i], &hdr, NULL);
> +		if (ret < 0) {
> +			sd_err("preventing inode update failed");
> +			goto out;
> +		}
> +
> +		nr_issued_prevent_inode_update++;
>  	}
>  
>  	ret = dog_write_object(vid_to_vdi_oid(vid), 0,
> @@ -555,7 +632,7 @@ static int vdi_snapshot(int argc, char **argv)
>  			       0, inode->nr_copies, inode->copy_policy,
>  			       false, false);
>  	if (ret != SD_RES_SUCCESS)
> -		return EXIT_FAILURE;
> +		goto out;
>  
>  	ret = do_vdi_create(vdiname, inode->vdi_size, vid, &new_vid, true,
>  			    inode->nr_copies, inode->copy_policy,
> @@ -569,11 +646,12 @@ static int vdi_snapshot(int argc, char **argv)
>  			       " VDI ID of newly created snapshot: %x\n", new_vid, vid);
>  	}
>  
> -	sd_init_req(&hdr, SD_OP_ALLOW_INODE_UPDATE);
> -	ret = dog_exec_req(&sd_nid, &hdr, NULL);
> -	if (ret < 0) {
> -		sd_err("allowing inode update failed");
> -		return EXIT_FAILURE;
> +out:
> +	for (int i = 0; i < nr_issued_prevent_inode_update; i++) {
> +		sd_init_req(&hdr, SD_OP_ALLOW_INODE_UPDATE);
> +		ret = dog_exec_req(&owners[i], &hdr, NULL);
> +		if (ret < 0)
> +			sd_err("allowing inode update failed");
>  	}
>  
>  	return ret;
> @@ -2716,41 +2794,14 @@ static int vdi_alter_copy(int argc, char **argv)
>  
>  static int lock_list(int argc, char **argv)
>  {
> -	struct sd_req hdr;
> -	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
>  	struct vdi_state *vs = NULL;
> -	unsigned int rlen;
> -	int ret, count;
> +	int ret = 0, count = 0;
>  
> -#define DEFAULT_VDI_STATE_COUNT 512
> -	rlen = DEFAULT_VDI_STATE_COUNT * sizeof(struct vdi_state);
> -	vs = xzalloc(rlen);
> -retry:
> -	sd_init_req(&hdr, SD_OP_GET_VDI_COPIES);
> -	hdr.data_length = rlen;
> -
> -	ret = dog_exec_req(&sd_nid, &hdr, (char *)vs);
> -	if (ret < 0)
> -		return EXIT_SYSFAIL;
> -
> -	switch (ret) {
> -	case SD_RES_SUCCESS:
> -		break;
> -	case SD_RES_BUFFER_SMALL:
> -		rlen *= 2;
> -		vs = xrealloc(vs, rlen);
> -		goto retry;
> -	default:
> -		sd_err("failed to execute SD_OP_GET_VDI_COPIES: %s",
> -		       sd_strerror(ret));
> -		goto out;
> -	}
> +	vs = get_vdi_state(&count);
>  
>  	init_tree();
>  	if (parse_vdi(construct_vdi_tree, SD_INODE_HEADER_SIZE, NULL) < 0)
> -		return EXIT_SYSFAIL;
> -
> -	count = rsp->data_length / sizeof(*vs);
> +		goto out;
>  
>  	printf("VDI | owner node\n");
>  	for (int i = 0; i < count; i++) {
> -- 
> 1.8.3.2
> 



More information about the sheepdog mailing list