[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