[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