1 Index: new/qapi-schema.json
2 ===================================================================
3 --- new.orig/qapi-schema.json 2013-12-06 06:05:10.000000000 +0100
4 +++ new/qapi-schema.json 2013-12-06 06:17:13.000000000 +0100
6 # @vma: Proxmox vma backup format
8 { 'enum': 'BackupFormat',
10 + 'data': [ 'vma', 'dir' ] }
15 ===================================================================
16 --- new.orig/blockdev.c 2013-12-06 06:17:06.000000000 +0100
17 +++ new/blockdev.c 2013-12-06 06:17:13.000000000 +0100
22 + char targetfile[PATH_MAX];
23 + BlockDriverState *target;
26 static void pvebackup_run_next_job(void);
27 @@ -1534,8 +1536,11 @@
33 - vma_writer_close_stream(backup_state.vmaw, di->dev_id);
34 + if (backup_state.vmaw) {
35 + vma_writer_close_stream(backup_state.vmaw, di->dev_id);
38 if (!backup_state.cancel) {
39 pvebackup_run_next_job();
41 bool has_speed, int64_t speed, Error **errp)
44 + const char *backup_dir = NULL;
45 Error *local_err = NULL;
47 VmaWriter *vmaw = NULL;
48 @@ -1626,11 +1632,6 @@
49 /* Todo: try to auto-detect format based on file name */
50 format = has_format ? format : BACKUP_FORMAT_VMA;
52 - if (format != BACKUP_FORMAT_VMA) {
53 - error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
58 devs = g_strsplit_set(devlist, ",;:", -1);
60 @@ -1698,27 +1699,63 @@
64 - vmaw = vma_writer_create(backup_file, uuid, &local_err);
66 - if (error_is_set(&local_err)) {
67 - error_propagate(errp, local_err);
68 + if (format == BACKUP_FORMAT_VMA) {
69 + vmaw = vma_writer_create(backup_file, uuid, &local_err);
71 + if (error_is_set(&local_err)) {
72 + error_propagate(errp, local_err);
79 - /* register all devices for vma writer */
82 - PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
84 + /* register all devices for vma writer */
87 + PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
90 - const char *devname = bdrv_get_device_name(di->bs);
91 - di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
92 - if (di->dev_id <= 0) {
93 - error_set(errp, ERROR_CLASS_GENERIC_ERROR,
94 - "register_stream failed");
95 + const char *devname = bdrv_get_device_name(di->bs);
96 + di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
97 + if (di->dev_id <= 0) {
98 + error_set(errp, ERROR_CLASS_GENERIC_ERROR,
99 + "register_stream failed");
103 + } else if (format == BACKUP_FORMAT_DIR) {
104 + if (mkdir(backup_file, 0640) != 0) {
105 + error_setg_errno(errp, errno, "can't create directory '%s'\n",
109 + backup_dir = backup_file;
113 + PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
114 + l = g_list_next(l);
116 + const char *devname = bdrv_get_device_name(di->bs);
117 + snprintf(di->targetfile, PATH_MAX, "%s/%s.raw", backup_dir, devname);
119 + int flags = BDRV_O_RDWR|BDRV_O_CACHE_WB;
120 + bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
121 + di->size, flags, &local_err, false);
122 + if (error_is_set(&local_err)) {
123 + error_propagate(errp, local_err);
127 + di->target = bdrv_new("");
128 + if (bdrv_open(di->target, di->targetfile, NULL, flags, NULL, &local_err) < 0) {
129 + bdrv_unref(di->target);
130 + error_propagate(errp, local_err);
135 + error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
139 /* add configuration file to archive */
140 @@ -1731,12 +1768,27 @@
144 - const char *basename = g_path_get_basename(config_file);
145 - if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
146 - error_setg(errp, "unable to add config data to vma archive");
149 + char *basename = g_path_get_basename(config_file);
151 + if (format == BACKUP_FORMAT_VMA) {
152 + if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
153 + error_setg(errp, "unable to add config data to vma archive");
158 + } else if (format == BACKUP_FORMAT_DIR) {
159 + char config_path[PATH_MAX];
160 + snprintf(config_path, PATH_MAX, "%s/%s.raw", backup_dir, basename);
161 + if (!g_file_set_contents(config_path, cdata, clen, &err)) {
162 + error_setg(errp, "unable to write config file '%s'", config_path);
173 @@ -1776,10 +1828,11 @@
174 PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
177 - backup_start(di->bs, NULL, speed, MIRROR_SYNC_MODE_FULL,
178 + backup_start(di->bs, di->target, speed, MIRROR_SYNC_MODE_FULL,
179 BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
180 pvebackup_dump_cb, pvebackup_complete_cb, di,
183 if (local_err != NULL) {
184 error_setg(&backup_state.error, "backup_job_create failed");
185 pvebackup_cancel(NULL);
186 @@ -1796,8 +1849,17 @@
191 + PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
195 + bdrv_unref(di->target);
198 + if (di->targetfile[0]) {
199 + unlink(di->targetfile);
203 g_list_free(di_list);
205 @@ -1811,6 +1873,10 @@