[Sheepdog] [PATCH 1/2] collie: add support for reading data from the vdi
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Wed Aug 10 18:00:23 CEST 2011
This command reads data from a vdi directly, and prints the data to
the standard output.
$ collie vdi read -h
vdi read - read data from a image
Usage:
collie vdi read <vdiname> <offset> <len> [-s snapshot] [-a address] [-p port] [-h]
Command parameters:
-s, --snapshot specify a snapshot id or tag name
-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/vdi.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 85 insertions(+), 0 deletions(-)
diff --git a/collie/vdi.c b/collie/vdi.c
index 5ab6c25..1547e15 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -966,6 +966,89 @@ static int vdi_getattr(int argc, char **argv)
return EXIT_FAILURE;
}
+static int vdi_read(int argc, char **argv)
+{
+ char *vdiname = argv[optind++];
+ uint32_t vid;
+ int ret, idx;
+ struct sheepdog_inode *inode = NULL;
+ uint64_t offset, oid, done = 0, total;
+ unsigned int len;
+ char *buf = NULL;
+
+ if (!argv[optind]) {
+ fprintf(stderr, "please specify a start offset\n");
+ return EXIT_USAGE;
+ }
+ ret = parse_option_size(argv[optind++], &offset);
+ if (ret < 0)
+ return EXIT_USAGE;
+
+ if (!argv[optind]) {
+ fprintf(stderr, "please specify a length to read\n");
+ return EXIT_USAGE;
+ }
+ ret = parse_option_size(argv[optind], &total);
+ if (ret < 0)
+ return EXIT_USAGE;
+
+ inode = malloc(sizeof(*inode));
+ buf = malloc(SD_DATA_OBJ_SIZE);
+ if (!inode || !buf) {
+ fprintf(stderr, "oom\n");
+ ret = EXIT_SYSFAIL;
+ goto out;
+ }
+
+ ret = find_vdi_name(vdiname, vdi_cmd_data.snapshot_id,
+ vdi_cmd_data.snapshot_tag, &vid, 0);
+ if (ret < 0) {
+ fprintf(stderr, "failed to open vdi %s\n", vdiname);
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+ ret = sd_read_object(vid_to_vdi_oid(vid), inode, SD_INODE_SIZE, 0);
+ if (ret != SD_RES_SUCCESS) {
+ fprintf(stderr, "failed to read an inode\n");
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+
+ idx = offset / SD_DATA_OBJ_SIZE;
+ while (done != total) {
+ len = min(total - done, SD_DATA_OBJ_SIZE - offset);
+
+ if (inode->data_vdi_id[idx]) {
+ oid = vid_to_data_oid(inode->data_vdi_id[idx], idx);
+ ret = sd_read_object(oid, buf, len, offset);
+ if (ret != SD_RES_SUCCESS) {
+ fprintf(stderr, "failed to read vdi\n");
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+ } else
+ memset(buf, 0, len);
+
+ ret = write(STDOUT_FILENO, buf, len);
+ if (ret < 0) {
+ fprintf(stderr, "failed to output, %m\n");
+ ret = EXIT_SYSFAIL;
+ goto out;
+ }
+
+ offset = 0;
+ idx++;
+ done += len;
+ }
+ fsync(STDOUT_FILENO);
+ ret = EXIT_SUCCESS;
+out:
+ free(inode);
+ free(buf);
+
+ return ret;
+}
+
static struct subcommand vdi_cmd[] = {
{"create", "<vdiname> <size>", "Paph", "create a image",
SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_create},
@@ -989,6 +1072,8 @@ static struct subcommand vdi_cmd[] = {
SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_getattr},
{"resize", "<vdiname> <new size>", "aph", "resize a image",
SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_resize},
+ {"read", "<vdiname> <offset> <len>", "saph", "read data from a image",
+ SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_read},
{NULL,},
};
--
1.7.2.5
More information about the sheepdog
mailing list