On 7/7/25 22:58, Denis V. Lunev wrote:
 From time to time it is needed to remove all bitmaps from the image.
Before this patch the process is not very convinient. One should
perform
     qemu-img info
and parse the output to obtain all names. After that one should
sequentially call
     qemu-img bitmap --remove
for each present bitmap.

The patch adds --remove-all sub-command to 'qemu-img bitmap'.

Signed-off-by: Denis V. Lunev <d...@openvz.org>
CC: Kevin Wolf <kw...@redhat.com>
CC: Hanna Reitz <hre...@redhat.com>
---
  docs/tools/qemu-img.rst |  4 +++-
  qemu-img.c              | 43 ++++++++++++++++++++++++++++++++++-------
  2 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
index 3653adb963..a08fd6019f 100644
--- a/docs/tools/qemu-img.rst
+++ b/docs/tools/qemu-img.rst
@@ -301,7 +301,7 @@ Command description:
    For write tests, by default a buffer filled with zeros is written. This can 
be
    overridden with a pattern byte specified by *PATTERN*.
-.. option:: bitmap (--merge SOURCE | --add | --remove | --clear | --enable | --disable)... [-b SOURCE_FILE [-F SOURCE_FMT]] [-g GRANULARITY] [--object OBJECTDEF] [--image-opts | -f FMT] FILENAME BITMAP
+.. option:: bitmap (--merge SOURCE | --add | --remove | --remove-all | --clear 
| --enable | --disable)... [-b SOURCE_FILE [-F SOURCE_FMT]] [-g GRANULARITY] 
[--object OBJECTDEF] [--image-opts | -f FMT] FILENAME BITMAP
Perform one or more modifications of the persistent bitmap *BITMAP*
    in the disk image *FILENAME*.  The various modifications are:
@@ -310,6 +310,8 @@ Command description:
``--remove`` to remove *BITMAP*. + ``--remove-all`` to remove all bitmaps.
+
    ``--clear`` to clear *BITMAP*.
``--enable`` to change *BITMAP* to start recording future edits.
diff --git a/qemu-img.c b/qemu-img.c
index e75707180d..920ede2a6a 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -86,6 +86,7 @@ enum {
      OPTION_BITMAPS = 275,
      OPTION_FORCE = 276,
      OPTION_SKIP_BROKEN = 277,
+    OPTION_REMOVE_ALL = 278,
  };
typedef enum OutputFormat {
@@ -191,7 +192,7 @@ void help(void)
             "Parameters to bitmap subcommand:\n"
             "  'bitmap' is the name of the bitmap to manipulate, through one or 
more\n"
             "       actions from '--add', '--remove', '--clear', '--enable', 
'--disable',\n"
-           "       or '--merge source'\n"
+           "       '--remove-all' or '--merge source'\n"
             "  '-g granularity' sets the granularity for '--add' actions\n"
             "  '-b source' and '-F src_fmt' tell '--merge' actions to find the 
source\n"
             "       bitmaps from an alternative file\n"
@@ -4770,6 +4771,7 @@ enum ImgBitmapAct {
      BITMAP_ENABLE,
      BITMAP_DISABLE,
      BITMAP_MERGE,
+    BITMAP_REMOVE_ALL,
  };
  typedef struct ImgBitmapAction {
      enum ImgBitmapAct act;
@@ -4788,7 +4790,7 @@ static int img_bitmap(int argc, char **argv)
      BlockDriverState *bs = NULL, *src_bs = NULL;
      bool image_opts = false;
      int64_t granularity = 0;
-    bool add = false, merge = false;
+    bool add = false, merge = false, remove_all = false, any = false;
      QSIMPLEQ_HEAD(, ImgBitmapAction) actions;
      ImgBitmapAction *act, *act_next;
      const char *op;
@@ -4803,6 +4805,7 @@ static int img_bitmap(int argc, char **argv)
              {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
              {"add", no_argument, 0, OPTION_ADD},
              {"remove", no_argument, 0, OPTION_REMOVE},
+            {"remove-all", no_argument, 0, OPTION_REMOVE_ALL},
              {"clear", no_argument, 0, OPTION_CLEAR},
              {"enable", no_argument, 0, OPTION_ENABLE},
              {"disable", no_argument, 0, OPTION_DISABLE},
@@ -4846,34 +4849,44 @@ static int img_bitmap(int argc, char **argv)
              act = g_new0(ImgBitmapAction, 1);
              act->act = BITMAP_ADD;
              QSIMPLEQ_INSERT_TAIL(&actions, act, next);
-            add = true;
+            add = any = true;
              break;
          case OPTION_REMOVE:
              act = g_new0(ImgBitmapAction, 1);
              act->act = BITMAP_REMOVE;
              QSIMPLEQ_INSERT_TAIL(&actions, act, next);
+            any = true;
+            break;
+        case OPTION_REMOVE_ALL:
+            act = g_new0(ImgBitmapAction, 1);
+            act->act = BITMAP_REMOVE_ALL;
+            QSIMPLEQ_INSERT_TAIL(&actions, act, next);
+            remove_all = true;
              break;
          case OPTION_CLEAR:
              act = g_new0(ImgBitmapAction, 1);
              act->act = BITMAP_CLEAR;
              QSIMPLEQ_INSERT_TAIL(&actions, act, next);
+            any = true;
              break;
          case OPTION_ENABLE:
              act = g_new0(ImgBitmapAction, 1);
              act->act = BITMAP_ENABLE;
              QSIMPLEQ_INSERT_TAIL(&actions, act, next);
+            any = true;
              break;
          case OPTION_DISABLE:
              act = g_new0(ImgBitmapAction, 1);
              act->act = BITMAP_DISABLE;
              QSIMPLEQ_INSERT_TAIL(&actions, act, next);
+            any = true;
              break;
          case OPTION_MERGE:
              act = g_new0(ImgBitmapAction, 1);
              act->act = BITMAP_MERGE;
              act->src = optarg;
              QSIMPLEQ_INSERT_TAIL(&actions, act, next);
-            merge = true;
+            any = merge = true;
              break;
          case OPTION_OBJECT:
              user_creatable_process_cmdline(optarg);
@@ -4885,8 +4898,8 @@ static int img_bitmap(int argc, char **argv)
      }
if (QSIMPLEQ_EMPTY(&actions)) {
-        error_report("Need at least one of --add, --remove, --clear, "
-                     "--enable, --disable, or --merge");
+        error_report("Need at least one of --add, --remove, --remove-all, "
+                     "--clear, --enable, --disable, or --merge");
          goto out;
      }
@@ -4904,10 +4917,14 @@ static int img_bitmap(int argc, char **argv)
          goto out;
      }
- if (optind != argc - 2) {
+    if (any && optind != argc - 2) {
          error_report("Expecting filename and bitmap name");
          goto out;
      }
+    if (!any && remove_all && optind != argc - 1) {
+        error_report("Expecting filename");
+        goto out;
+    }
filename = argv[optind];
      bitmap = argv[optind + 1];
@@ -4945,6 +4962,18 @@ static int img_bitmap(int argc, char **argv)
              qmp_block_dirty_bitmap_remove(bs->node_name, bitmap, &err);
              op = "remove";
              break;
+        case BITMAP_REMOVE_ALL: {
+            while (1) {
+                BdrvDirtyBitmap *bm = bdrv_dirty_bitmap_first(bs);
+                if (bm == NULL) {
+                    break;
+                }
+                qmp_block_dirty_bitmap_remove(bs->node_name,
+                                              bdrv_dirty_bitmap_name(bm), 
&err);
+            }
+            op = "remove-all";
+            break;
+        }
          case BITMAP_CLEAR:
              qmp_block_dirty_bitmap_clear(bs->node_name, bitmap, &err);
              op = "clear";
ping

Reply via email to