1*9ef8112aSAlberto Garcia /* 2*9ef8112aSAlberto Garcia * Blockjob tests 3*9ef8112aSAlberto Garcia * 4*9ef8112aSAlberto Garcia * Copyright Igalia, S.L. 2016 5*9ef8112aSAlberto Garcia * 6*9ef8112aSAlberto Garcia * Authors: 7*9ef8112aSAlberto Garcia * Alberto Garcia <berto@igalia.com> 8*9ef8112aSAlberto Garcia * 9*9ef8112aSAlberto Garcia * This work is licensed under the terms of the GNU LGPL, version 2 or later. 10*9ef8112aSAlberto Garcia * See the COPYING.LIB file in the top-level directory. 11*9ef8112aSAlberto Garcia */ 12*9ef8112aSAlberto Garcia 13*9ef8112aSAlberto Garcia #include "qemu/osdep.h" 14*9ef8112aSAlberto Garcia #include "qapi/error.h" 15*9ef8112aSAlberto Garcia #include "qemu/main-loop.h" 16*9ef8112aSAlberto Garcia #include "block/blockjob.h" 17*9ef8112aSAlberto Garcia #include "sysemu/block-backend.h" 18*9ef8112aSAlberto Garcia 19*9ef8112aSAlberto Garcia static const BlockJobDriver test_block_job_driver = { 20*9ef8112aSAlberto Garcia .instance_size = sizeof(BlockJob), 21*9ef8112aSAlberto Garcia }; 22*9ef8112aSAlberto Garcia 23*9ef8112aSAlberto Garcia static void block_job_cb(void *opaque, int ret) 24*9ef8112aSAlberto Garcia { 25*9ef8112aSAlberto Garcia } 26*9ef8112aSAlberto Garcia 27*9ef8112aSAlberto Garcia static BlockJob *do_test_id(BlockBackend *blk, const char *id, 28*9ef8112aSAlberto Garcia bool should_succeed) 29*9ef8112aSAlberto Garcia { 30*9ef8112aSAlberto Garcia BlockJob *job; 31*9ef8112aSAlberto Garcia Error *errp = NULL; 32*9ef8112aSAlberto Garcia 33*9ef8112aSAlberto Garcia job = block_job_create(id, &test_block_job_driver, blk_bs(blk), 0, 34*9ef8112aSAlberto Garcia block_job_cb, NULL, &errp); 35*9ef8112aSAlberto Garcia if (should_succeed) { 36*9ef8112aSAlberto Garcia g_assert_null(errp); 37*9ef8112aSAlberto Garcia g_assert_nonnull(job); 38*9ef8112aSAlberto Garcia if (id) { 39*9ef8112aSAlberto Garcia g_assert_cmpstr(job->id, ==, id); 40*9ef8112aSAlberto Garcia } else { 41*9ef8112aSAlberto Garcia g_assert_cmpstr(job->id, ==, blk_name(blk)); 42*9ef8112aSAlberto Garcia } 43*9ef8112aSAlberto Garcia } else { 44*9ef8112aSAlberto Garcia g_assert_nonnull(errp); 45*9ef8112aSAlberto Garcia g_assert_null(job); 46*9ef8112aSAlberto Garcia error_free(errp); 47*9ef8112aSAlberto Garcia } 48*9ef8112aSAlberto Garcia 49*9ef8112aSAlberto Garcia return job; 50*9ef8112aSAlberto Garcia } 51*9ef8112aSAlberto Garcia 52*9ef8112aSAlberto Garcia /* This creates a BlockBackend (optionally with a name) with a 53*9ef8112aSAlberto Garcia * BlockDriverState inserted. */ 54*9ef8112aSAlberto Garcia static BlockBackend *create_blk(const char *name) 55*9ef8112aSAlberto Garcia { 56*9ef8112aSAlberto Garcia BlockBackend *blk = blk_new(); 57*9ef8112aSAlberto Garcia BlockDriverState *bs = bdrv_new(); 58*9ef8112aSAlberto Garcia 59*9ef8112aSAlberto Garcia blk_insert_bs(blk, bs); 60*9ef8112aSAlberto Garcia bdrv_unref(bs); 61*9ef8112aSAlberto Garcia 62*9ef8112aSAlberto Garcia if (name) { 63*9ef8112aSAlberto Garcia Error *errp = NULL; 64*9ef8112aSAlberto Garcia monitor_add_blk(blk, name, &errp); 65*9ef8112aSAlberto Garcia g_assert_null(errp); 66*9ef8112aSAlberto Garcia } 67*9ef8112aSAlberto Garcia 68*9ef8112aSAlberto Garcia return blk; 69*9ef8112aSAlberto Garcia } 70*9ef8112aSAlberto Garcia 71*9ef8112aSAlberto Garcia /* This destroys the backend */ 72*9ef8112aSAlberto Garcia static void destroy_blk(BlockBackend *blk) 73*9ef8112aSAlberto Garcia { 74*9ef8112aSAlberto Garcia if (blk_name(blk)[0] != '\0') { 75*9ef8112aSAlberto Garcia monitor_remove_blk(blk); 76*9ef8112aSAlberto Garcia } 77*9ef8112aSAlberto Garcia 78*9ef8112aSAlberto Garcia blk_remove_bs(blk); 79*9ef8112aSAlberto Garcia blk_unref(blk); 80*9ef8112aSAlberto Garcia } 81*9ef8112aSAlberto Garcia 82*9ef8112aSAlberto Garcia static void test_job_ids(void) 83*9ef8112aSAlberto Garcia { 84*9ef8112aSAlberto Garcia BlockBackend *blk[3]; 85*9ef8112aSAlberto Garcia BlockJob *job[3]; 86*9ef8112aSAlberto Garcia 87*9ef8112aSAlberto Garcia blk[0] = create_blk(NULL); 88*9ef8112aSAlberto Garcia blk[1] = create_blk("drive1"); 89*9ef8112aSAlberto Garcia blk[2] = create_blk("drive2"); 90*9ef8112aSAlberto Garcia 91*9ef8112aSAlberto Garcia /* No job ID provided and the block backend has no name */ 92*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], NULL, false); 93*9ef8112aSAlberto Garcia 94*9ef8112aSAlberto Garcia /* These are all invalid job IDs */ 95*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], "0id", false); 96*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], "", false); 97*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], " ", false); 98*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], "123", false); 99*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], "_id", false); 100*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], "-id", false); 101*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], ".id", false); 102*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], "#id", false); 103*9ef8112aSAlberto Garcia 104*9ef8112aSAlberto Garcia /* This one is valid */ 105*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], "id0", true); 106*9ef8112aSAlberto Garcia 107*9ef8112aSAlberto Garcia /* We cannot have two jobs in the same BDS */ 108*9ef8112aSAlberto Garcia do_test_id(blk[0], "id1", false); 109*9ef8112aSAlberto Garcia 110*9ef8112aSAlberto Garcia /* Duplicate job IDs are not allowed */ 111*9ef8112aSAlberto Garcia job[1] = do_test_id(blk[1], "id0", false); 112*9ef8112aSAlberto Garcia 113*9ef8112aSAlberto Garcia /* But once job[0] finishes we can reuse its ID */ 114*9ef8112aSAlberto Garcia block_job_unref(job[0]); 115*9ef8112aSAlberto Garcia job[1] = do_test_id(blk[1], "id0", true); 116*9ef8112aSAlberto Garcia 117*9ef8112aSAlberto Garcia /* No job ID specified, defaults to the backend name ('drive1') */ 118*9ef8112aSAlberto Garcia block_job_unref(job[1]); 119*9ef8112aSAlberto Garcia job[1] = do_test_id(blk[1], NULL, true); 120*9ef8112aSAlberto Garcia 121*9ef8112aSAlberto Garcia /* Duplicate job ID */ 122*9ef8112aSAlberto Garcia job[2] = do_test_id(blk[2], "drive1", false); 123*9ef8112aSAlberto Garcia 124*9ef8112aSAlberto Garcia /* The ID of job[2] would default to 'drive2' but it is already in use */ 125*9ef8112aSAlberto Garcia job[0] = do_test_id(blk[0], "drive2", true); 126*9ef8112aSAlberto Garcia job[2] = do_test_id(blk[2], NULL, false); 127*9ef8112aSAlberto Garcia 128*9ef8112aSAlberto Garcia /* This one is valid */ 129*9ef8112aSAlberto Garcia job[2] = do_test_id(blk[2], "id_2", true); 130*9ef8112aSAlberto Garcia 131*9ef8112aSAlberto Garcia block_job_unref(job[0]); 132*9ef8112aSAlberto Garcia block_job_unref(job[1]); 133*9ef8112aSAlberto Garcia block_job_unref(job[2]); 134*9ef8112aSAlberto Garcia 135*9ef8112aSAlberto Garcia destroy_blk(blk[0]); 136*9ef8112aSAlberto Garcia destroy_blk(blk[1]); 137*9ef8112aSAlberto Garcia destroy_blk(blk[2]); 138*9ef8112aSAlberto Garcia } 139*9ef8112aSAlberto Garcia 140*9ef8112aSAlberto Garcia int main(int argc, char **argv) 141*9ef8112aSAlberto Garcia { 142*9ef8112aSAlberto Garcia qemu_init_main_loop(&error_abort); 143*9ef8112aSAlberto Garcia 144*9ef8112aSAlberto Garcia g_test_init(&argc, &argv, NULL); 145*9ef8112aSAlberto Garcia g_test_add_func("/blockjob/ids", test_job_ids); 146*9ef8112aSAlberto Garcia return g_test_run(); 147*9ef8112aSAlberto Garcia } 148