[Sheepdog] [PATCH] sheepdog: add live snapshot feature

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Tue Apr 20 04:47:25 CEST 2010


Hi,

On 2010/04/19 17:39, OZAWA Tsuyoshi wrote:
> This patch provide sheepdog with live snapshot.
> 
> NOTE: To work this patch correctly, it's needed to apply the patch
> which adds vm_clock_nsec and vm_state_size to sd_inode to collie.
> 
> Signed-off-by: OZAWA Tsuyoshi <ozawa.tsuyoshi at lab.ntt.co.jp>
> ---
>  block/sheepdog.c |  284 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 280 insertions(+), 4 deletions(-)
> 

This looks great, thanks!

Some commenets are below:

- save_vm with no parameter causes segmentation fault.
- load_vm fails to load snapshot occasionally and qemu hungs up
- please add "\n" to the end of the format of printf

>  
> +static void set_vdi_index_and_offset(int *vdi_index, int *offset,
> +				int64_t pos, int size)
> +{
> +	int next_offset, overflow;
> +
> +	*vdi_index = pos / SD_DATA_OBJ_SIZE;
> +	*offset = pos % SD_DATA_OBJ_SIZE;
> +	next_offset = *offset + size;
> +	overflow = next_offset / SD_DATA_OBJ_SIZE;
> +	if (overflow && (next_offset % SD_DATA_OBJ_SIZE != 0)) {
> +		/* change to write data to next vdi */
> +		(*vdi_index)++;
> +		*offset = 0;
> +	}
> +	return;
> +}
> +

- *vdi_index should be unsigned 32 bit number.
- If overflow has happened, write only overflowed data to the next object.

> @@ -1587,12 +1615,156 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
>  
>  	dprintf("%s %s\n", sn_info->name, sn_info->id_str);
>  
> -	ret = do_sd_create(s->name, sn_info->name, s->inode.vdi_size >> 9,
> -			   s->inode.oid, NULL, 1);
> +	s->inode.vm_state_size = sn_info->vm_state_size;
> +	s->inode.vm_clock_nsec = sn_info->vm_clock_nsec;
> +
> +	/* refresh inode. */
> +	fd = connect_to_vost();
> +	if (fd < 0) {
> +		ret = -EIO;
> +		goto cleanup;
> +	}
> +
> +	memset(&hdr, 0, sizeof(hdr));
> +	hdr.opcode = SD_OP_WRITE_OBJ;
> +
> +	hdr.oid = s->inode.oid;
> +	hdr.copies = s->inode.nr_copies;
> +
> +	hdr.flags |= SD_FLAG_CMD_WRITE;
> +	hdr.data_length = SD_INODE_SIZE;
> +	hdr.offset = 0;
> +	wlen = SD_INODE_SIZE;
> +	rlen = 0;
> +
> +	ret = do_req(fd, (struct sd_req *)&hdr, &s->inode, &wlen, &rlen);
> +	if (ret < 0) {
> +		eprintf("do_req write\n");
> +		ret = -EIO;
> +		goto cleanup;
> +	}
> +
> +	if (fd < 0) {
> +		ret = -EIO;
> +		goto cleanup;
> +	}
> +
> +	ret = do_sd_create(s->name, NULL, s->inode.vdi_size >> 9,
> +			   s->inode.oid, &new_oid, 1);
> +	if (ret < 0) {
> +		eprintf("do_sd_create %m");
> +		ret = -EIO;
> +		goto cleanup;
> +	}
> +
> +	inode = (struct sd_inode *)malloc(sizeof(struct sd_inode));
> +	if (!inode) {
> +		eprintf("malloc %m");
> +		goto cleanup;
> +	}
> +
> +	memset(&hdr, 0, sizeof(hdr));
> +
> +	hdr.opcode = SD_OP_READ_OBJ;
> +	hdr.oid = new_oid;
> +	hdr.data_length = SD_INODE_SIZE;
> +	hdr.offset = 0;
> +
> +	wlen = 0;
> +	rlen = SD_INODE_SIZE;
> +
> +	ret = do_req(fd, (struct sd_req *)&hdr, inode, &wlen, &rlen);
> +	if (ret < 0) {
> +		eprintf("do_req read\n");
> +		ret = -EIO;
> +		goto cleanup;
> +	}

- use read_vdi_obj here.

> +
> +	memcpy(&s->inode, inode, sizeof(struct sd_inode));
> +	eprintf("s->inode: name %s snap_id %x oid %lxn",
> +		s->inode.name, s->inode.snap_id, s->inode.oid);
> +
> +cleanup:
> +	close(fd);
> +	return ret;
> +}
> +
> +static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
> +{
> +	struct bdrv_sd_state *s = bs->opaque;
> +	struct bdrv_sd_state *old_s;
> +	char vdi[256];
> +	char *buf = NULL;
> +	uint64_t oid;
> +	uint32_t snapid = 0;
> +	int ret = -ENOENT, dummy;
> +
> +
> +	old_s = malloc(sizeof(struct bdrv_sd_state));
> +	if (!old_s) {
> +		eprintf("malloc");
> +		goto out;
> +	}
> +
> +	memcpy(old_s, s, sizeof(struct bdrv_sd_state));
> +	sd_release(bs);
> +
> +	snapid = strtol(snapshot_id, NULL, 16);

- This should be "strtol(snapshot_id, NULL, 10);".
  It is because qemu shows a snapshot index in decimal.

Thanks,

Kazutaka Morita




More information about the sheepdog mailing list