|
@@ -1,7 +1,7 @@
|
|
/*
|
|
/*
|
|
* Block node graph modifications tests
|
|
* Block node graph modifications tests
|
|
*
|
|
*
|
|
- * Copyright (c) 2019 Virtuozzo International GmbH. All rights reserved.
|
|
|
|
|
|
+ * Copyright (c) 2019-2021 Virtuozzo International GmbH. All rights reserved.
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* it under the terms of the GNU General Public License as published by
|
|
@@ -44,6 +44,21 @@ static BlockDriver bdrv_no_perm = {
|
|
.bdrv_child_perm = no_perm_default_perms,
|
|
.bdrv_child_perm = no_perm_default_perms,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static void exclusive_write_perms(BlockDriverState *bs, BdrvChild *c,
|
|
|
|
+ BdrvChildRole role,
|
|
|
|
+ BlockReopenQueue *reopen_queue,
|
|
|
|
+ uint64_t perm, uint64_t shared,
|
|
|
|
+ uint64_t *nperm, uint64_t *nshared)
|
|
|
|
+{
|
|
|
|
+ *nperm = BLK_PERM_WRITE;
|
|
|
|
+ *nshared = BLK_PERM_ALL & ~BLK_PERM_WRITE;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static BlockDriver bdrv_exclusive_writer = {
|
|
|
|
+ .format_name = "exclusive-writer",
|
|
|
|
+ .bdrv_child_perm = exclusive_write_perms,
|
|
|
|
+};
|
|
|
|
+
|
|
static BlockDriverState *no_perm_node(const char *name)
|
|
static BlockDriverState *no_perm_node(const char *name)
|
|
{
|
|
{
|
|
return bdrv_new_open_driver(&bdrv_no_perm, name, BDRV_O_RDWR, &error_abort);
|
|
return bdrv_new_open_driver(&bdrv_no_perm, name, BDRV_O_RDWR, &error_abort);
|
|
@@ -55,6 +70,12 @@ static BlockDriverState *pass_through_node(const char *name)
|
|
BDRV_O_RDWR, &error_abort);
|
|
BDRV_O_RDWR, &error_abort);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static BlockDriverState *exclusive_writer_node(const char *name)
|
|
|
|
+{
|
|
|
|
+ return bdrv_new_open_driver(&bdrv_exclusive_writer, name,
|
|
|
|
+ BDRV_O_RDWR, &error_abort);
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* test_update_perm_tree
|
|
* test_update_perm_tree
|
|
*
|
|
*
|
|
@@ -185,8 +206,50 @@ static void test_should_update_child(void)
|
|
blk_unref(root);
|
|
blk_unref(root);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * test_parallel_exclusive_write
|
|
|
|
+ *
|
|
|
|
+ * Check that when we replace node, old permissions of the node being removed
|
|
|
|
+ * doesn't break the replacement.
|
|
|
|
+ */
|
|
|
|
+static void test_parallel_exclusive_write(void)
|
|
|
|
+{
|
|
|
|
+ BlockDriverState *top = exclusive_writer_node("top");
|
|
|
|
+ BlockDriverState *base = no_perm_node("base");
|
|
|
|
+ BlockDriverState *fl1 = pass_through_node("fl1");
|
|
|
|
+ BlockDriverState *fl2 = pass_through_node("fl2");
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * bdrv_attach_child() eats child bs reference, so we need two @base
|
|
|
|
+ * references for two filters:
|
|
|
|
+ */
|
|
|
|
+ bdrv_ref(base);
|
|
|
|
+
|
|
|
|
+ bdrv_attach_child(top, fl1, "backing", &child_of_bds, BDRV_CHILD_DATA,
|
|
|
|
+ &error_abort);
|
|
|
|
+ bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
|
|
|
|
+ &error_abort);
|
|
|
|
+ bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
|
|
|
|
+ &error_abort);
|
|
|
|
+
|
|
|
|
+ bdrv_replace_node(fl1, fl2, &error_abort);
|
|
|
|
+
|
|
|
|
+ bdrv_unref(fl2);
|
|
|
|
+ bdrv_unref(top);
|
|
|
|
+}
|
|
|
|
+
|
|
int main(int argc, char *argv[])
|
|
int main(int argc, char *argv[])
|
|
{
|
|
{
|
|
|
|
+ int i;
|
|
|
|
+ bool debug = false;
|
|
|
|
+
|
|
|
|
+ for (i = 1; i < argc; i++) {
|
|
|
|
+ if (!strcmp(argv[i], "-d")) {
|
|
|
|
+ debug = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
bdrv_init();
|
|
bdrv_init();
|
|
qemu_init_main_loop(&error_abort);
|
|
qemu_init_main_loop(&error_abort);
|
|
|
|
|
|
@@ -196,5 +259,10 @@ int main(int argc, char *argv[])
|
|
g_test_add_func("/bdrv-graph-mod/should-update-child",
|
|
g_test_add_func("/bdrv-graph-mod/should-update-child",
|
|
test_should_update_child);
|
|
test_should_update_child);
|
|
|
|
|
|
|
|
+ if (debug) {
|
|
|
|
+ g_test_add_func("/bdrv-graph-mod/parallel-exclusive-write",
|
|
|
|
+ test_parallel_exclusive_write);
|
|
|
|
+ }
|
|
|
|
+
|
|
return g_test_run();
|
|
return g_test_run();
|
|
}
|
|
}
|