]> git.proxmox.com Git - pve-qemu.git/blobdiff - debian/patches/pve/0052-vma-allow-partial-restore.patch
add QAPI naming exceptions in patches introducing them
[pve-qemu.git] / debian / patches / pve / 0052-vma-allow-partial-restore.patch
diff --git a/debian/patches/pve/0052-vma-allow-partial-restore.patch b/debian/patches/pve/0052-vma-allow-partial-restore.patch
deleted file mode 100644 (file)
index f1fd7cb..0000000
+++ /dev/null
@@ -1,407 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Fabian Ebner <f.ebner@proxmox.com>
-Date: Thu, 21 Apr 2022 13:26:48 +0200
-Subject: [PATCH] vma: allow partial restore
-
-Introduce a new map line for skipping a certain drive, of the form
-skip=drive-scsi0
-
-Since in PVE, most archives are compressed and piped to vma for
-restore, it's not easily possible to skip reads.
-
-For the reader, a new skip flag for VmaRestoreState is added and the
-target is allowed to be NULL if skip is specified when registering. If
-the skip flag is set, no writes will be made as well as no check for
-duplicate clusters. Therefore, the flag is not set for verify.
-
-Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
-Acked-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
----
- vma-reader.c |  64 ++++++++++++---------
- vma.c        | 157 +++++++++++++++++++++++++++++----------------------
- vma.h        |   2 +-
- 3 files changed, 126 insertions(+), 97 deletions(-)
-
-diff --git a/vma-reader.c b/vma-reader.c
-index e65f1e8415..81a891c6b1 100644
---- a/vma-reader.c
-+++ b/vma-reader.c
-@@ -28,6 +28,7 @@ typedef struct VmaRestoreState {
-     bool write_zeroes;
-     unsigned long *bitmap;
-     int bitmap_size;
-+    bool skip;
- }  VmaRestoreState;
- struct VmaReader {
-@@ -425,13 +426,14 @@ VmaDeviceInfo *vma_reader_get_device_info(VmaReader *vmar, guint8 dev_id)
- }
- static void allocate_rstate(VmaReader *vmar,  guint8 dev_id,
--                            BlockBackend *target, bool write_zeroes)
-+                            BlockBackend *target, bool write_zeroes, bool skip)
- {
-     assert(vmar);
-     assert(dev_id);
-     vmar->rstate[dev_id].target = target;
-     vmar->rstate[dev_id].write_zeroes = write_zeroes;
-+    vmar->rstate[dev_id].skip = skip;
-     int64_t size = vmar->devinfo[dev_id].size;
-@@ -446,28 +448,30 @@ static void allocate_rstate(VmaReader *vmar,  guint8 dev_id,
- }
- int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id, BlockBackend *target,
--                           bool write_zeroes, Error **errp)
-+                           bool write_zeroes, bool skip, Error **errp)
- {
-     assert(vmar);
--    assert(target != NULL);
-+    assert(target != NULL || skip);
-     assert(dev_id);
--    assert(vmar->rstate[dev_id].target == NULL);
--
--    int64_t size = blk_getlength(target);
--    int64_t size_diff = size - vmar->devinfo[dev_id].size;
--
--    /* storage types can have different size restrictions, so it
--     * is not always possible to create an image with exact size.
--     * So we tolerate a size difference up to 4MB.
--     */
--    if ((size_diff < 0) || (size_diff > 4*1024*1024)) {
--        error_setg(errp, "vma_reader_register_bs for stream %s failed - "
--                   "unexpected size %zd != %zd", vmar->devinfo[dev_id].devname,
--                   size, vmar->devinfo[dev_id].size);
--        return -1;
-+    assert(vmar->rstate[dev_id].target == NULL && !vmar->rstate[dev_id].skip);
-+
-+    if (target != NULL) {
-+        int64_t size = blk_getlength(target);
-+        int64_t size_diff = size - vmar->devinfo[dev_id].size;
-+
-+        /* storage types can have different size restrictions, so it
-+         * is not always possible to create an image with exact size.
-+         * So we tolerate a size difference up to 4MB.
-+         */
-+        if ((size_diff < 0) || (size_diff > 4*1024*1024)) {
-+            error_setg(errp, "vma_reader_register_bs for stream %s failed - "
-+                       "unexpected size %zd != %zd", vmar->devinfo[dev_id].devname,
-+                       size, vmar->devinfo[dev_id].size);
-+            return -1;
-+        }
-     }
--    allocate_rstate(vmar, dev_id, target, write_zeroes);
-+    allocate_rstate(vmar, dev_id, target, write_zeroes, skip);
-     return 0;
- }
-@@ -560,19 +564,23 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
-         VmaRestoreState *rstate = &vmar->rstate[dev_id];
-         BlockBackend *target = NULL;
-+        bool skip = rstate->skip;
-+
-         if (dev_id != vmar->vmstate_stream) {
-             target = rstate->target;
--            if (!verify && !target) {
-+            if (!verify && !target && !skip) {
-                 error_setg(errp, "got wrong dev id %d", dev_id);
-                 return -1;
-             }
--            if (vma_reader_get_bitmap(rstate, cluster_num)) {
--                error_setg(errp, "found duplicated cluster %zd for stream %s",
--                          cluster_num, vmar->devinfo[dev_id].devname);
--                return -1;
-+            if (!skip) {
-+                if (vma_reader_get_bitmap(rstate, cluster_num)) {
-+                    error_setg(errp, "found duplicated cluster %zd for stream %s",
-+                              cluster_num, vmar->devinfo[dev_id].devname);
-+                    return -1;
-+                }
-+                vma_reader_set_bitmap(rstate, cluster_num, 1);
-             }
--            vma_reader_set_bitmap(rstate, cluster_num, 1);
-             max_sector = vmar->devinfo[dev_id].size/BDRV_SECTOR_SIZE;
-         } else {
-@@ -618,7 +626,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
-                 return -1;
-             }
--            if (!verify) {
-+            if (!verify && !skip) {
-                 int nb_sectors = end_sector - sector_num;
-                 if (restore_write_data(vmar, dev_id, target, vmstate_fd,
-                                        buf + start, sector_num, nb_sectors,
-@@ -654,7 +662,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
-                         return -1;
-                     }
--                    if (!verify) {
-+                    if (!verify && !skip) {
-                         int nb_sectors = end_sector - sector_num;
-                         if (restore_write_data(vmar, dev_id, target, vmstate_fd,
-                                                buf + start, sector_num,
-@@ -679,7 +687,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
-                             vmar->partial_zero_cluster_data += zero_size;
-                         }
--                        if (rstate->write_zeroes && !verify) {
-+                        if (rstate->write_zeroes && !verify && !skip) {
-                             if (restore_write_data(vmar, dev_id, target, vmstate_fd,
-                                                    zero_vma_block, sector_num,
-                                                    nb_sectors, errp) < 0) {
-@@ -850,7 +858,7 @@ int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp)
-     for (dev_id = 1; dev_id < 255; dev_id++) {
-         if (vma_reader_get_device_info(vmar, dev_id)) {
--            allocate_rstate(vmar, dev_id, NULL, false);
-+            allocate_rstate(vmar, dev_id, NULL, false, false);
-         }
-     }
-diff --git a/vma.c b/vma.c
-index e8dffb43e0..e6e9ffc7fe 100644
---- a/vma.c
-+++ b/vma.c
-@@ -138,6 +138,7 @@ typedef struct RestoreMap {
-     char *throttling_group;
-     char *cache;
-     bool write_zero;
-+    bool skip;
- } RestoreMap;
- static bool try_parse_option(char **line, const char *optname, char **out, const char *inbuf) {
-@@ -245,47 +246,61 @@ static int extract_content(int argc, char **argv)
-             char *bps = NULL;
-             char *group = NULL;
-             char *cache = NULL;
-+            char *devname = NULL;
-+            bool skip = false;
-+            uint64_t bps_value = 0;
-+            const char *path = NULL;
-+            bool write_zero = true;
-+
-             if (!line || line[0] == '\0' || !strcmp(line, "done\n")) {
-                 break;
-             }
-             int len = strlen(line);
-             if (line[len - 1] == '\n') {
-                 line[len - 1] = '\0';
--                if (len == 1) {
-+                len = len - 1;
-+                if (len == 0) {
-                     break;
-                 }
-             }
--            while (1) {
--                if (!try_parse_option(&line, "format", &format, inbuf) &&
--                    !try_parse_option(&line, "throttling.bps", &bps, inbuf) &&
--                    !try_parse_option(&line, "throttling.group", &group, inbuf) &&
--                    !try_parse_option(&line, "cache", &cache, inbuf))
--                {
--                    break;
-+            if (strncmp(line, "skip", 4) == 0) {
-+                if (len < 6 || line[4] != '=') {
-+                    g_error("read map failed - option 'skip' has no value ('%s')",
-+                            inbuf);
-+                } else {
-+                    devname = line + 5;
-+                    skip = true;
-+                }
-+            } else {
-+                while (1) {
-+                    if (!try_parse_option(&line, "format", &format, inbuf) &&
-+                        !try_parse_option(&line, "throttling.bps", &bps, inbuf) &&
-+                        !try_parse_option(&line, "throttling.group", &group, inbuf) &&
-+                        !try_parse_option(&line, "cache", &cache, inbuf))
-+                    {
-+                        break;
-+                    }
-                 }
--            }
--            uint64_t bps_value = 0;
--            if (bps) {
--                bps_value = verify_u64(bps);
--                g_free(bps);
--            }
-+                if (bps) {
-+                    bps_value = verify_u64(bps);
-+                    g_free(bps);
-+                }
--            const char *path;
--            bool write_zero;
--            if (line[0] == '0' && line[1] == ':') {
--                path = line + 2;
--                write_zero = false;
--            } else if (line[0] == '1' && line[1] == ':') {
--                path = line + 2;
--                write_zero = true;
--            } else {
--                g_error("read map failed - parse error ('%s')", inbuf);
-+                if (line[0] == '0' && line[1] == ':') {
-+                    path = line + 2;
-+                    write_zero = false;
-+                } else if (line[0] == '1' && line[1] == ':') {
-+                    path = line + 2;
-+                    write_zero = true;
-+                } else {
-+                    g_error("read map failed - parse error ('%s')", inbuf);
-+                }
-+
-+                path = extract_devname(path, &devname, -1);
-             }
--            char *devname = NULL;
--            path = extract_devname(path, &devname, -1);
-             if (!devname) {
-                 g_error("read map failed - no dev name specified ('%s')",
-                         inbuf);
-@@ -299,6 +314,7 @@ static int extract_content(int argc, char **argv)
-             map->throttling_group = group;
-             map->cache = cache;
-             map->write_zero = write_zero;
-+            map->skip = skip;
-             g_hash_table_insert(devmap, map->devname, map);
-@@ -328,6 +344,7 @@ static int extract_content(int argc, char **argv)
-             const char *cache = NULL;
-             int flags = BDRV_O_RDWR;
-             bool write_zero = true;
-+            bool skip = false;
-             BlockBackend *blk = NULL;
-@@ -343,6 +360,7 @@ static int extract_content(int argc, char **argv)
-                 throttling_group = map->throttling_group;
-                 cache = map->cache;
-                 write_zero = map->write_zero;
-+                skip = map->skip;
-             } else {
-                 devfn = g_strdup_printf("%s/tmp-disk-%s.raw",
-                                         dirname, di->devname);
-@@ -361,57 +379,60 @@ static int extract_content(int argc, char **argv)
-                 write_zero = false;
-             }
--          size_t devlen = strlen(devfn);
--          QDict *options = NULL;
--            bool writethrough;
--            if (format) {
--                /* explicit format from commandline */
--                options = qdict_new();
--                qdict_put_str(options, "driver", format);
--            } else if ((devlen > 4 && strcmp(devfn+devlen-4, ".raw") == 0) ||
--                     strncmp(devfn, "/dev/", 5) == 0)
--          {
--                /* This part is now deprecated for PVE as well (just as qemu
--                 * deprecated not specifying an explicit raw format, too.
--                 */
--              /* explicit raw format */
--              options = qdict_new();
--              qdict_put_str(options, "driver", "raw");
--          }
--            if (cache && bdrv_parse_cache_mode(cache, &flags, &writethrough)) {
--                g_error("invalid cache option: %s\n", cache);
--            }
-+            if (!skip) {
-+                size_t devlen = strlen(devfn);
-+                QDict *options = NULL;
-+                bool writethrough;
-+                if (format) {
-+                    /* explicit format from commandline */
-+                    options = qdict_new();
-+                    qdict_put_str(options, "driver", format);
-+                } else if ((devlen > 4 && strcmp(devfn+devlen-4, ".raw") == 0) ||
-+                    strncmp(devfn, "/dev/", 5) == 0)
-+                {
-+                    /* This part is now deprecated for PVE as well (just as qemu
-+                     * deprecated not specifying an explicit raw format, too.
-+                     */
-+                    /* explicit raw format */
-+                    options = qdict_new();
-+                    qdict_put_str(options, "driver", "raw");
-+                }
--          if (errp || !(blk = blk_new_open(devfn, NULL, options, flags, &errp))) {
--                g_error("can't open file %s - %s", devfn,
--                        error_get_pretty(errp));
--            }
-+                if (cache && bdrv_parse_cache_mode(cache, &flags, &writethrough)) {
-+                    g_error("invalid cache option: %s\n", cache);
-+                }
--            if (cache) {
--                blk_set_enable_write_cache(blk, !writethrough);
--            }
-+                if (errp || !(blk = blk_new_open(devfn, NULL, options, flags, &errp))) {
-+                    g_error("can't open file %s - %s", devfn,
-+                            error_get_pretty(errp));
-+                }
--            if (throttling_group) {
--                blk_io_limits_enable(blk, throttling_group);
--            }
-+                if (cache) {
-+                    blk_set_enable_write_cache(blk, !writethrough);
-+                }
--            if (throttling_bps) {
--                if (!throttling_group) {
--                    blk_io_limits_enable(blk, devfn);
-+                if (throttling_group) {
-+                    blk_io_limits_enable(blk, throttling_group);
-                 }
--                ThrottleConfig cfg;
--                throttle_config_init(&cfg);
--                cfg.buckets[THROTTLE_BPS_WRITE].avg = throttling_bps;
--                Error *err = NULL;
--                if (!throttle_is_valid(&cfg, &err)) {
--                    error_report_err(err);
--                    g_error("failed to apply throttling");
-+                if (throttling_bps) {
-+                    if (!throttling_group) {
-+                        blk_io_limits_enable(blk, devfn);
-+                    }
-+
-+                    ThrottleConfig cfg;
-+                    throttle_config_init(&cfg);
-+                    cfg.buckets[THROTTLE_BPS_WRITE].avg = throttling_bps;
-+                    Error *err = NULL;
-+                    if (!throttle_is_valid(&cfg, &err)) {
-+                        error_report_err(err);
-+                        g_error("failed to apply throttling");
-+                    }
-+                    blk_set_io_limits(blk, &cfg);
-                 }
--                blk_set_io_limits(blk, &cfg);
-             }
--            if (vma_reader_register_bs(vmar, i, blk, write_zero, &errp) < 0) {
-+            if (vma_reader_register_bs(vmar, i, blk, write_zero, skip, &errp) < 0) {
-                 g_error("%s", error_get_pretty(errp));
-             }
-diff --git a/vma.h b/vma.h
-index c895c97f6d..1b62859165 100644
---- a/vma.h
-+++ b/vma.h
-@@ -142,7 +142,7 @@ GList *vma_reader_get_config_data(VmaReader *vmar);
- VmaDeviceInfo *vma_reader_get_device_info(VmaReader *vmar, guint8 dev_id);
- int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id,
-                            BlockBackend *target, bool write_zeroes,
--                           Error **errp);
-+                           bool skip, Error **errp);
- int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
-                        Error **errp);
- int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp);