[Sheepdog] [PATCH 4/5] collie: add vdi clone support
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Mon Aug 8 18:44:18 CEST 2011
$ collie vdi clone -h
vdi clone - create a clone image
Usage:
collie vdi clone <src vdi> <dst vdi> [-s snapshot] [-P] [-a address] [-p port] [-h]
Command parameters:
-s, --snapshot specify a snapshot id or tag name
-P, --prealloc preallocate all the data objects
-a, --address specify the daemon address (default: localhost)
-p, --port specify the daemon port
-h, --help display this help and exit
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
collie/collie.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/collie/collie.c b/collie/collie.c
index 0929a45..64f0748 100644
--- a/collie/collie.c
+++ b/collie/collie.c
@@ -1055,6 +1055,98 @@ static int vdi_snapshot(int argc, char **argv)
return do_vdi_create(vdiname, inode->vdi_size, vid, NULL, 1);
}
+static int vdi_clone(int argc, char **argv)
+{
+ char *src_vdi = argv[optind++], *dst_vdi;
+ uint32_t base_vid, new_vid;
+ uint64_t oid;
+ int idx, max_idx, ret;
+ struct sheepdog_inode *inode = NULL;
+ char *buf = NULL;
+
+ dst_vdi = argv[optind];
+ if (!dst_vdi) {
+ fprintf(stderr, "a dst vdi must be specified\n");
+ ret = EXIT_USAGE;
+ goto out;
+ }
+
+ if (!vdi_cmd_data.snapshot_id && !vdi_cmd_data.snapshot_tag[0]) {
+ fprintf(stderr, "it is not supported to create a clone image of "
+ "the non-snapshot vdi\n");
+ fprintf(stderr, "please specify a '-s' option\n");
+ ret = EXIT_USAGE;
+ goto out;
+ }
+
+ ret = find_vdi_name(src_vdi, vdi_cmd_data.snapshot_id,
+ vdi_cmd_data.snapshot_tag, &base_vid, 0);
+ if (ret < 0) {
+ fprintf(stderr, "failed to open vdi %s\n", src_vdi);
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+
+ inode = malloc(sizeof(*inode));
+ if (!inode) {
+ fprintf(stderr, "oom\n");
+ ret = EXIT_SYSFAIL;
+ goto out;
+ }
+ ret = sd_read_object(vid_to_vdi_oid(base_vid), inode, SD_INODE_SIZE, 0);
+ if (ret != SD_RES_SUCCESS) {
+ fprintf(stderr, "failed to read a base inode\n");
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+
+ ret = do_vdi_create(dst_vdi, inode->vdi_size, base_vid, &new_vid, 0);
+ if (ret != EXIT_SUCCESS || !vdi_cmd_data.prealloc)
+ goto out;
+
+ buf = zalloc(SD_DATA_OBJ_SIZE);
+ if (!buf) {
+ fprintf(stderr, "oom\n");
+ ret = EXIT_SYSFAIL;
+ goto out;
+ }
+
+ max_idx = DIV_ROUND_UP(inode->vdi_size, SD_DATA_OBJ_SIZE);
+
+ for (idx = 0; idx < max_idx; idx++) {
+ if (inode->data_vdi_id[idx]) {
+ oid = vid_to_data_oid(inode->data_vdi_id[idx], idx);
+ ret = sd_read_object(oid, buf, SD_DATA_OBJ_SIZE, 0);
+ if (ret) {
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+ } else
+ memset(buf, 0, SD_DATA_OBJ_SIZE);
+
+ oid = vid_to_data_oid(new_vid, idx);
+ ret = sd_write_object(oid, buf, SD_DATA_OBJ_SIZE, 0, 0,
+ inode->nr_copies, 1);
+ if (ret != SD_RES_SUCCESS) {
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+
+ ret = sd_write_object(vid_to_vdi_oid(new_vid), &new_vid, sizeof(new_vid),
+ SD_INODE_HEADER_SIZE + sizeof(new_vid) * idx, 0,
+ inode->nr_copies, 0);
+ if (ret) {
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+ }
+ ret = EXIT_SUCCESS;
+out:
+ free(inode);
+ free(buf);
+ return ret;
+}
+
static int vdi_delete(int argc, char **argv)
{
char *data = argv[optind];
@@ -1346,6 +1438,8 @@ static struct subcommand vdi_cmd[] = {
SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_create},
{"snapshot", "<vdiname>", "saph", "create a snapshot",
SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_snapshot},
+ {"clone", "<src vdi> <dst vdi>", "sPaph", "create a clone image",
+ SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_clone},
{"delete", "<vdiname>", "saph", "delete a image",
SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_delete},
{"list", "[vdiname]", "aprh", "list images",
--
1.7.2.5
More information about the sheepdog
mailing list