[sheepdog] [PATCH 3/9] collie: use stdout and stdin for vdi backup and restore

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Mon Sep 17 00:59:56 CEST 2012


This helps us to use backup/restore via ssh or pipe.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 collie/vdi.c  |  128 +++++++++++++++++++++++++++++---------------------------
 man/collie.8  |    4 +-
 tests/041     |   14 +++---
 tests/041.out |    4 --
 4 files changed, 75 insertions(+), 75 deletions(-)

diff --git a/collie/vdi.c b/collie/vdi.c
index 13c758a..a80ce79 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -1536,8 +1536,6 @@ out:
 struct backup_hdr {
 	uint32_t version;
 	uint32_t magic;
-	uint32_t nr_obj_backups;
-	uint32_t reserved;
 };
 
 struct obj_backup {
@@ -1613,8 +1611,8 @@ static int get_obj_backup(int idx, uint32_t from_vid, uint32_t to_vid,
 
 static int vdi_backup(int argc, char **argv)
 {
-	char *vdiname = argv[optind++], *backup_file;
-	int ret = EXIT_SUCCESS, fd = -1, idx, nr_objs;
+	char *vdiname = argv[optind++];
+	int ret = EXIT_SUCCESS, idx, nr_objs;
 	struct sheepdog_inode *from_inode = xzalloc(sizeof(*from_inode));
 	struct sheepdog_inode *to_inode = xzalloc(sizeof(*to_inode));
 	struct backup_hdr hdr = {
@@ -1623,20 +1621,6 @@ static int vdi_backup(int argc, char **argv)
 	};
 	struct obj_backup *backup = xzalloc(sizeof(*backup));
 
-	backup_file = argv[optind++];
-	if (!backup_file) {
-		fprintf(stderr, "Please specify a backup file\n");
-		ret = EXIT_USAGE;
-		goto out;
-	}
-
-	fd = open(backup_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
-	if (fd < 0) {
-		fprintf(stderr, "Cannot open %s, %m\n", backup_file);
-		ret = EXIT_FAILURE;
-		goto out;
-	}
-
 	if ((!vdi_cmd_data.snapshot_id && !vdi_cmd_data.snapshot_tag[0]) ||
 	    (!vdi_cmd_data.from_snapshot_id &&
 	     !vdi_cmd_data.from_snapshot_tag[0])) {
@@ -1660,10 +1644,10 @@ static int vdi_backup(int argc, char **argv)
 
 	nr_objs = DIV_ROUND_UP(to_inode->vdi_size, SD_DATA_OBJ_SIZE);
 
-	ret = lseek(fd, sizeof(hdr), SEEK_SET);
-	if (ret != sizeof(hdr)) {
-		fprintf(stderr, "failed to seek, %m\n");
-		ret = EXIT_FAILURE;
+	ret = xwrite(STDOUT_FILENO, &hdr, sizeof(hdr));
+	if (ret < 0) {
+		fprintf(stderr, "failed to write backup header, %m\n");
+		ret = EXIT_SYSFAIL;
 		goto out;
 	}
 
@@ -1678,18 +1662,38 @@ static int vdi_backup(int argc, char **argv)
 		if (ret != EXIT_SUCCESS)
 			goto out;
 
-		if (backup->length) {
-			hdr.nr_obj_backups++;
-			xwrite(fd, backup, sizeof(*backup) - sizeof(backup->data));
-			xwrite(fd, backup->data + backup->offset, backup->length);
+		if (backup->length == 0)
+			continue;
+
+		ret = xwrite(STDOUT_FILENO, backup,
+			     sizeof(*backup) - sizeof(backup->data));
+		if (ret < 0) {
+			fprintf(stderr, "failed to write backup data, %m\n");
+			ret = EXIT_SYSFAIL;
+			goto out;
+		}
+		ret = xwrite(STDOUT_FILENO, backup->data + backup->offset,
+			     backup->length);
+		if (ret < 0) {
+			fprintf(stderr, "failed to write backup data, %m\n");
+			ret = EXIT_SYSFAIL;
+			goto out;
 		}
 	}
 
-	xpwrite(fd, &hdr, sizeof(hdr), 0);
-out:
-	if (fd >= 0)
-		close(fd);
+	/* write end marker */
+	memset(backup, 0, sizeof(*backup) - sizeof(backup->data));
+	backup->idx = UINT32_MAX;
+	ret = xwrite(STDOUT_FILENO, backup,
+		     sizeof(*backup) - sizeof(backup->data));
+	if (ret < 0) {
+		fprintf(stderr, "failed to write end marker, %m\n");
+		ret = EXIT_SYSFAIL;
+		goto out;
+	}
 
+	fsync(STDOUT_FILENO);
+out:
 	free(from_inode);
 	free(to_inode);
 	free(backup);
@@ -1719,30 +1723,23 @@ static int restore_obj(struct obj_backup *backup, uint32_t vid,
 			       0, parent_inode->nr_copies, 0);
 }
 
-static uint32_t do_restore(char *vdiname, int snapid, const char *tag,
-			   const char *backup_file)
+static uint32_t do_restore(char *vdiname, int snapid, const char *tag)
 {
-	int fd, i, ret;
+	int ret;
 	uint32_t vid;
 	struct backup_hdr hdr;
 	struct obj_backup *backup = xzalloc(sizeof(*backup));
 	struct sheepdog_inode *inode = xzalloc(sizeof(*inode));
 
-	printf("restoring %s... ", backup_file);
-
-	fd = open(backup_file, O_RDONLY);
-	if (fd < 0) {
-		printf("Cannot open the backup file\n");
-		ret = EXIT_FAILURE;
-		goto out;
+	ret = xread(STDIN_FILENO, &hdr, sizeof(hdr));
+	if (ret != sizeof(hdr)) {
+		fprintf(stderr, "failed to read backup header, %m\n");
 	}
 
-	xread(fd, &hdr, sizeof(hdr));
-
 	if (hdr.version != VDI_BACKUP_FORMAT_VERSION ||
 	    hdr.magic != VDI_BACKUP_MAGIC) {
-		printf("The backup file is corrupted\n");
-		ret = EXIT_FAILURE;
+		fprintf(stderr, "The backup file is corrupted\n");
+		ret = EXIT_SYSFAIL;
 		goto out;
 	}
 
@@ -1753,25 +1750,39 @@ static uint32_t do_restore(char *vdiname, int snapid, const char *tag,
 	ret = do_vdi_create(vdiname, inode->vdi_size, inode->vdi_id, &vid, 1,
 			    inode->nr_copies);
 	if (ret != EXIT_SUCCESS) {
-		printf("Failed to read VDI\n");
+		fprintf(stderr, "Failed to read VDI\n");
 		goto out;
 	}
 
-	for (i = 0; i < hdr.nr_obj_backups; i++) {
-		xread(fd, backup, sizeof(*backup) - sizeof(backup->data));
-		xread(fd, backup->data, backup->length);
+	while (true) {
+		ret = xread(STDIN_FILENO, backup,
+			    sizeof(*backup) - sizeof(backup->data));
+		if (ret != sizeof(*backup) - sizeof(backup->data)) {
+			fprintf(stderr, "failed to read backup data\n");
+			ret = EXIT_SYSFAIL;
+			break;
+		}
+
+		if (backup->idx == UINT32_MAX) {
+			ret = EXIT_SUCCESS;
+			break;
+		}
+
+		ret = xread(STDIN_FILENO, backup->data, backup->length);
+		if (ret != backup->length) {
+			fprintf(stderr, "failed to read backup data\n");
+			ret = EXIT_SYSFAIL;
+			break;
+		}
 
 		ret = restore_obj(backup, vid, inode);
 		if (ret != SD_RES_SUCCESS) {
-			printf("error\n");
+			fprintf(stderr, "failed to restore backup\n");
 			do_vdi_delete(vdiname, 0, NULL);
 			ret = EXIT_FAILURE;
-			goto out;
+			break;
 		}
 	}
-
-	ret = EXIT_SUCCESS;
-	printf("done\n");
 out:
 	free(backup);
 	free(inode);
@@ -1781,20 +1792,13 @@ out:
 
 static int vdi_restore(int argc, char **argv)
 {
-	char *vdiname = argv[optind++], *backup_file;
+	char *vdiname = argv[optind++];
 	int ret;
 	char buf[SD_INODE_HEADER_SIZE] = {0};
 	struct sheepdog_inode *current_inode = xzalloc(sizeof(*current_inode));
 	struct sheepdog_inode *parent_inode = (struct sheepdog_inode *)buf;
 	bool need_current_recovery = false;
 
-	backup_file = argv[optind++];
-	if (!backup_file) {
-		fprintf(stderr, "Please specify a backup to be restored\n");
-		ret = EXIT_USAGE;
-		goto out;
-	}
-
 	if (!vdi_cmd_data.snapshot_id && !vdi_cmd_data.snapshot_tag[0]) {
 		fprintf(stderr, "We can restore a backup file only to"
 			"snapshots\n");
@@ -1827,7 +1831,7 @@ static int vdi_restore(int argc, char **argv)
 
 	/* restore backup data */
 	ret = do_restore(vdiname, vdi_cmd_data.snapshot_id,
-			 vdi_cmd_data.snapshot_tag, backup_file);
+			 vdi_cmd_data.snapshot_tag);
 out:
 	if (need_current_recovery) {
 		int recovery_ret;
diff --git a/man/collie.8 b/man/collie.8
index 61d56e6..3ca2372 100644
--- a/man/collie.8
+++ b/man/collie.8
@@ -109,10 +109,10 @@ This command reads data from an image.
 .BI "vdi write [-a address] [-p port] [-h] <vdiname> [<offset> [<len>]]"
 This command writes data to an image.
 .TP
-.BI "vdi backup [-s snapshot] [-F from] [-a address] [-p port] [-h] <vdiname> <backup>"
+.BI "vdi backup [-s snapshot] [-F from] [-a address] [-p port] [-h] <vdiname>"
 This command creates an incremental backup between two snapshots.
 .TP
-.BI "vdi restore [-s snapshot] [-a address] [-p port] [-h] <vdiname> <backup>"
+.BI "vdi restore [-s snapshot] [-a address] [-p port] [-h] <vdiname>"
 This command restores snapshot images from a backup.
 .TP
 .BI "node kill [-a address] [-p port] [-r] [-h] <node id>"
diff --git a/tests/041 b/tests/041
index aa904a5..a266fa9 100755
--- a/tests/041
+++ b/tests/041
@@ -44,24 +44,24 @@ for i in `seq 1 3`; do
 done
 
 # create backup files between snapshots
-$COLLIE vdi backup test -F snap1 -s snap2 /tmp/backup.1.2
-$COLLIE vdi backup test -F snap1 -s snap3 /tmp/backup.1.3
-$COLLIE vdi backup test -F snap2 -s snap3 /tmp/backup.2.3
+$COLLIE vdi backup test -F snap1 -s snap2 > /tmp/backup.1.2
+$COLLIE vdi backup test -F snap1 -s snap3 > /tmp/backup.1.3
+$COLLIE vdi backup test -F snap2 -s snap3 > /tmp/backup.2.3
 
 # restore backups
-$COLLIE vdi restore test -s snap1 /tmp/backup.1.2
+$COLLIE vdi restore test -s snap1 < /tmp/backup.1.2
 $COLLIE vdi list | _filter_short_date
 $COLLIE vdi tree | _filter_short_date
 
-$COLLIE vdi restore test -s 4 /tmp/backup.2.3
+$COLLIE vdi restore test -s 4 < /tmp/backup.2.3
 $COLLIE vdi list | _filter_short_date
 $COLLIE vdi tree | _filter_short_date
 
-$COLLIE vdi restore test -s snap1 /tmp/backup.1.3
+$COLLIE vdi restore test -s snap1 < /tmp/backup.1.3
 $COLLIE vdi list | _filter_short_date
 $COLLIE vdi tree | _filter_short_date
 
-$COLLIE vdi restore test -s snap2 /tmp/backup.2.3
+$COLLIE vdi restore test -s snap2 < /tmp/backup.2.3
 $COLLIE vdi list | _filter_short_date
 $COLLIE vdi tree | _filter_short_date
 
diff --git a/tests/041.out b/tests/041.out
index 220a6b3..d7c3643 100644
--- a/tests/041.out
+++ b/tests/041.out
@@ -9,7 +9,6 @@ test---[DATE]---[DATE]---[DATE]---(you are here)
 b6338c1861851820f8d289c3b4e6443c  -
 1885611ba75e996f619e8eaf136366e6  -
 d210baf5c55b42b5e0edf04a8535ad6d  -
-restoring /tmp/backup.1.2... done
   Name        Id    Size    Used  Shared    Creation time   VDI id  Copies  Tag
 s test         1   12 MB  4.0 MB  0.0 MB DATE   7c2b25     3         snap1
 s test         2   12 MB  4.0 MB  4.0 MB DATE   7c2b26     3         snap2
@@ -18,7 +17,6 @@ s test         4   12 MB  4.0 MB  4.0 MB DATE   7c2b29     3
   test         5   12 MB  0.0 MB  8.0 MB DATE   7c2b2a     3              
 test---[DATE]-+-[DATE]---[DATE]---(you are here)
                           `-[DATE]
-restoring /tmp/backup.2.3... done
   Name        Id    Size    Used  Shared    Creation time   VDI id  Copies  Tag
 s test         1   12 MB  4.0 MB  0.0 MB DATE   7c2b25     3         snap1
 s test         2   12 MB  4.0 MB  4.0 MB DATE   7c2b26     3         snap2
@@ -28,7 +26,6 @@ s test         5   12 MB  4.0 MB  4.0 MB DATE   7c2b2b     3
   test         6   12 MB  0.0 MB  8.0 MB DATE   7c2b2c     3              
 test---[DATE]-+-[DATE]---[DATE]---(you are here)
                           `-[DATE]---[DATE]
-restoring /tmp/backup.1.3... done
   Name        Id    Size    Used  Shared    Creation time   VDI id  Copies  Tag
 s test         1   12 MB  4.0 MB  0.0 MB DATE   7c2b25     3         snap1
 s test         2   12 MB  4.0 MB  4.0 MB DATE   7c2b26     3         snap2
@@ -40,7 +37,6 @@ s test         6   12 MB  8.0 MB  0.0 MB DATE   7c2b2d     3
 test---[DATE]-+-[DATE]---[DATE]---(you are here)
                           |-[DATE]---[DATE]
                           `-[DATE]
-restoring /tmp/backup.2.3... done
   Name        Id    Size    Used  Shared    Creation time   VDI id  Copies  Tag
 s test         1   12 MB  4.0 MB  0.0 MB DATE   7c2b25     3         snap1
 s test         2   12 MB  4.0 MB  4.0 MB DATE   7c2b26     3         snap2
-- 
1.7.2.5




More information about the sheepdog mailing list