]> git.proxmox.com Git - pve-qemu-kvm.git/commitdiff
allow to backup into a directory
authorDietmar Maurer <dietmar@proxmox.com>
Fri, 6 Dec 2013 05:44:05 +0000 (06:44 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Fri, 6 Dec 2013 05:44:05 +0000 (06:44 +0100)
debian/patches/backup-add-dir-format.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/backup-add-dir-format.patch b/debian/patches/backup-add-dir-format.patch
new file mode 100644 (file)
index 0000000..18906ab
--- /dev/null
@@ -0,0 +1,215 @@
+Index: new/qapi-schema.json
+===================================================================
+--- new.orig/qapi-schema.json  2013-12-06 06:05:10.000000000 +0100
++++ new/qapi-schema.json       2013-12-06 06:17:13.000000000 +0100
+@@ -586,7 +586,7 @@
+ # @vma: Proxmox vma backup format
+ ##
+ { 'enum': 'BackupFormat',
+-  'data': [ 'vma' ] }
++  'data': [ 'vma', 'dir' ] }
+ ##
+ # @backup:
+Index: new/blockdev.c
+===================================================================
+--- new.orig/blockdev.c        2013-12-06 06:17:06.000000000 +0100
++++ new/blockdev.c     2013-12-06 06:17:13.000000000 +0100
+@@ -1463,6 +1463,8 @@
+     uint8_t dev_id;
+     //bool started;
+     bool completed;
++    char targetfile[PATH_MAX];
++    BlockDriverState *target;
+ } PVEBackupDevInfo;
+ static void pvebackup_run_next_job(void);
+@@ -1534,8 +1536,11 @@
+     di->completed = true;
+     di->bs = NULL;
++    di->target = NULL;
+-    vma_writer_close_stream(backup_state.vmaw, di->dev_id);
++    if (backup_state.vmaw) {
++        vma_writer_close_stream(backup_state.vmaw, di->dev_id);
++    }
+     if (!backup_state.cancel) {
+         pvebackup_run_next_job();
+@@ -1610,6 +1615,7 @@
+                     bool has_speed, int64_t speed, Error **errp)
+ {
+     BlockDriverState *bs;
++    const char *backup_dir = NULL;
+     Error *local_err = NULL;
+     uuid_t uuid;
+     VmaWriter *vmaw = NULL;
+@@ -1626,11 +1632,6 @@
+     /* Todo: try to auto-detect format based on file name */
+     format = has_format ? format : BACKUP_FORMAT_VMA;
+-    if (format != BACKUP_FORMAT_VMA) {
+-        error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
+-        return NULL;
+-    }
+-
+     if (has_devlist) {
+         devs = g_strsplit_set(devlist, ",;:", -1);
+@@ -1698,27 +1699,63 @@
+     uuid_generate(uuid);
+-    vmaw = vma_writer_create(backup_file, uuid, &local_err);
+-    if (!vmaw) {
+-        if (error_is_set(&local_err)) {
+-            error_propagate(errp, local_err);
++    if (format == BACKUP_FORMAT_VMA) {
++        vmaw = vma_writer_create(backup_file, uuid, &local_err);
++        if (!vmaw) {
++            if (error_is_set(&local_err)) {
++                error_propagate(errp, local_err);
++            }
++            goto err;
+         }
+-        goto err;
+-    }
+-    /* register all devices for vma writer */
+-    l = di_list;
+-    while (l) {
+-        PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
+-        l = g_list_next(l);
++        /* register all devices for vma writer */
++        l = di_list;
++        while (l) {
++            PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
++            l = g_list_next(l);
+-        const char *devname = bdrv_get_device_name(di->bs);
+-        di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
+-        if (di->dev_id <= 0) {
+-            error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+-                      "register_stream failed");
++            const char *devname = bdrv_get_device_name(di->bs);
++            di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
++            if (di->dev_id <= 0) {
++                error_set(errp, ERROR_CLASS_GENERIC_ERROR,
++                          "register_stream failed");
++                goto err;
++            }
++        }
++    } else if (format == BACKUP_FORMAT_DIR) {
++        if (mkdir(backup_file, 0640) != 0) {
++            error_setg_errno(errp, errno, "can't create directory '%s'\n",
++                             backup_file);
+             goto err;
+         }
++        backup_dir = backup_file;
++
++        l = di_list;
++        while (l) {
++            PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
++            l = g_list_next(l);
++
++            const char *devname = bdrv_get_device_name(di->bs);
++            snprintf(di->targetfile, PATH_MAX, "%s/%s.raw", backup_dir, devname);
++
++            int flags = BDRV_O_RDWR|BDRV_O_CACHE_WB;
++            bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
++                            di->size, flags, &local_err, false);
++            if (error_is_set(&local_err)) {
++                error_propagate(errp, local_err);
++                goto err;
++            }
++
++            di->target = bdrv_new("");
++            if (bdrv_open(di->target, di->targetfile, NULL, flags, NULL, &local_err) < 0) {
++                bdrv_unref(di->target);
++                error_propagate(errp, local_err);
++                goto err;
++            }
++        }
++    } else {
++       error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
++       goto err;
+     }
+     /* add configuration file to archive */
+@@ -1731,12 +1768,27 @@
+             goto err;
+         }
+-        const char *basename = g_path_get_basename(config_file);
+-        if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
+-            error_setg(errp, "unable to add config data to vma archive");
+-            g_free(cdata);
+-            goto err;
++        char *basename = g_path_get_basename(config_file);
++
++        if (format == BACKUP_FORMAT_VMA) {
++            if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
++                error_setg(errp, "unable to add config data to vma archive");
++                g_free(cdata);
++                g_free(basename);
++                goto err;
++            }
++        } else if (format == BACKUP_FORMAT_DIR) {
++            char config_path[PATH_MAX];
++            snprintf(config_path, PATH_MAX, "%s/%s.raw", backup_dir, basename);
++            if (!g_file_set_contents(config_path, cdata, clen, &err)) {
++                error_setg(errp, "unable to write config file '%s'", config_path);
++                g_free(cdata);
++                g_free(basename);
++                goto err;
++            }
+         }
++
++        g_free(basename);
+         g_free(cdata);
+     }
+@@ -1776,10 +1828,11 @@
+         PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
+         l = g_list_next(l);
+-        backup_start(di->bs, NULL, speed, MIRROR_SYNC_MODE_FULL,
++        backup_start(di->bs, di->target, speed, MIRROR_SYNC_MODE_FULL,
+                      BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
+                      pvebackup_dump_cb, pvebackup_complete_cb, di,
+                      true, &local_err);
++
+         if (local_err != NULL) {
+             error_setg(&backup_state.error, "backup_job_create failed");
+             pvebackup_cancel(NULL);
+@@ -1796,8 +1849,17 @@
+     l = di_list;
+     while (l) {
+-        g_free(l->data);
++        PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
+         l = g_list_next(l);
++
++        if (di->target) {
++            bdrv_unref(di->target);
++        }
++
++        if (di->targetfile[0]) {
++            unlink(di->targetfile);
++        }
++        g_free(di);
+     }
+     g_list_free(di_list);
+@@ -1811,6 +1873,10 @@
+         unlink(backup_file);
+     }
++    if (backup_dir) {
++        rmdir(backup_dir);
++    }
++
+     return NULL;
+ }
index c13ca90afae2a90f166d48f075b799f5a7faf778..65fd74065eaf2e485371319fee77e13203438201 100644 (file)
@@ -18,4 +18,5 @@ backup-vma-add-dump-config.patch
 backup-vma-restore-tolerate-a-size-difference-up-to-4M.patch
 backup-modify-job-api.patch
 backup-add-pve-monitor-commands.patch
+backup-add-dir-format.patch
 internal-snapshot-async.patch