In this example, user first create two qcow2 images, and then get the backing file relationship information of them. Then does write and read sync IO on them.
Signed-off-by: Wenchao Xia <xiaw...@linux.vnet.ibm.com> --- tests/libqblock/libqblock-test.c | 219 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 219 insertions(+), 0 deletions(-) create mode 100644 tests/libqblock/libqblock-test.c diff --git a/tests/libqblock/libqblock-test.c b/tests/libqblock/libqblock-test.c new file mode 100644 index 0000000..9a1eac5 --- /dev/null +++ b/tests/libqblock/libqblock-test.c @@ -0,0 +1,219 @@ +#include <stdarg.h> +#include <stdio.h> +#include <unistd.h> +#include <inttypes.h> +#include <string.h> + +#include "libqblock.h" + +static unsigned char buf_r[1024]; +static unsigned char buf_w[1024] = {4, 0, 0, 2}; + +struct verify_data { + unsigned char *buf_r; + unsigned char *buf_w; + int len; +}; + +static void print_loc(struct QBlockOptionLoc *loc) +{ + switch (loc->prot_type) { + case QB_PROTO_NONE: + printf("protocol type [none]."); + break; + case QB_PROTO_FILE: + printf("protocol type [file], filename [%s].", + loc->prot_op.o_file.filename); + break; + default: + printf("protocol type not supported."); + break; + } +} + +static void print_info_image_static(struct QBlockInfoImageStatic *info) +{ + printf("=======image location:\n"); + print_loc(&info->loc); + printf("\nvirtual_size %" PRId64 ", format type %d,", + info->virt_size, info->fmt_type); + printf("allocated size %" PRId64 ", encrypt %d,", + info->allocated_size, info->encrypt); + printf("\nbacking image location:\n"); + print_loc(&info->backing_loc); + printf("\n"); +} + +static void test_check(struct verify_data *vdata) +{ + int cmp; + cmp = memcmp(vdata->buf_r, vdata->buf_w, vdata->len); + if (cmp == 0) { + printf("compare succeed, %d.\n", vdata->buf_r[24]); + } else { + printf("!!! compare fail, %d.\n", vdata->buf_r[24]); + exit(1); + } +} + +int main(int argc, char **argv) +{ + char *filename1, *filename2; + struct QBroker *broker = NULL; + struct QBlockState *qbs = NULL; + struct QBlockOptionLoc *ol = NULL; + struct QBlockOptionFormat *of = NULL; + struct QBlockInfoImageStatic *info_st = NULL; + int ret, flag; + int test_offset = 0; + int test_len = 512; + struct verify_data vdata; + char err_str[1024]; + + vdata.buf_r = buf_r; + vdata.buf_w = buf_w; + vdata.len = test_len; + + filename1 = (char *)"./qemu_image1"; + filename2 = (char *)"./qemu_image2"; + printf("qemu test, filename1 is %s, filename2 is %s.\n", + filename1, filename2); + + libqblock_init(); + + ret = qb_broker_new(&broker); + if (ret < 0) { + goto free; + } + + ret = qb_state_new(broker, &qbs); + if (ret < 0) { + goto free; + } + + ret = qb_ol_new(broker, &ol); + if (ret < 0) { + goto free; + } + + ret = qb_of_new(broker, &of); + if (ret < 0) { + goto free; + } + + /* create a new image */ + + ol->prot_type = QB_PROTO_FILE; + ol->prot_op.o_file.filename = filename2; + of->fmt_type = QB_FMT_QCOW2; + of->fmt_op.o_qcow2.virt_size = 100 * 1024; + flag = 0; + + ret = qb_create(broker, qbs, ol, of, flag); + if (ret < 0) { + qb_error_get_human_str(broker, err_str, sizeof(err_str)); + printf("create fail 1. %s.\n", err_str); + goto unlink; + } + + ol->prot_type = QB_PROTO_FILE; + ol->prot_op.o_file.filename = filename1; + of->fmt_type = QB_FMT_QCOW2; + of->fmt_op.o_qcow2.backing_loc.prot_type = QB_PROTO_FILE; + of->fmt_op.o_qcow2.backing_loc.prot_op.o_file.filename = filename2; + flag = 0; + ret = qb_create(broker, qbs, ol, of, flag); + if (ret < 0) { + qb_error_get_human_str(broker, err_str, sizeof(err_str)); + printf("create fail 2. %s.\n", err_str); + goto unlink; + } + + /* get informations */ + ol->prot_type = QB_PROTO_FILE; + ol->prot_op.o_file.filename = filename1; + of->fmt_type = QB_FMT_NONE; + flag = LIBQBLOCK_O_NO_BACKING; + ret = qb_open(broker, qbs, ol, of, flag); + if (ret < 0) { + qb_error_get_human_str(broker, err_str, sizeof(err_str)); + printf("info getting, open failed. %s.\n", err_str); + goto free; + } + + while (1) { + ret = qb_info_image_static_get(broker, qbs, &info_st); + if (ret < 0) { + qb_error_get_human_str(broker, err_str, sizeof(err_str)); + printf("info get error. %s.\n", err_str); + goto close; + } + print_info_image_static(info_st); + qb_close(broker, qbs); + if (info_st->backing_loc.prot_type == QB_FMT_NONE) { + break; + } + *ol = info_st->backing_loc; + ret = qb_open(broker, qbs, ol, of, flag); + if (ret < 0) { + qb_error_get_human_str(broker, err_str, sizeof(err_str)); + printf("info getting, open failed in backing file. %s.\n", + err_str); + goto free; + } + qb_info_image_static_delete(broker, &info_st); + } + /* read and write the image */ + ol->prot_type = QB_PROTO_FILE; + ol->prot_op.o_file.filename = filename1; + of->fmt_type = QB_FMT_NONE; + flag = LIBQBLOCK_O_RDWR; + ret = qb_open(broker, qbs, ol, of, flag); + if (ret < 0) { + qb_error_get_human_str(broker, err_str, sizeof(err_str)); + printf("open failed. %s.\n", err_str); + goto free; + } + + buf_w[24] = 3; + memset(buf_r, 0, sizeof(buf_r)); + + ret = qb_write(broker, qbs, buf_w, test_len, test_offset); + if (ret < 0) { + qb_error_get_human_str(broker, err_str, sizeof(err_str)); + printf("%s.\n", err_str); + goto close; + } + + ret = qb_read(broker, qbs, buf_r, test_len, test_offset); + if (ret < 0) { + qb_error_get_human_str(broker, err_str, sizeof(err_str)); + printf("%s.\n", err_str); + goto close; + } + + test_check(&vdata); + + close: + qb_close(broker, qbs); + unlink: + unlink(filename1); + unlink(filename2); + free: + if (info_st != NULL) { + qb_info_image_static_delete(broker, &info_st); + } + if (qbs != NULL) { + qb_state_delete(broker, &qbs); + } + if (ol != NULL) { + qb_ol_delete(broker, &ol); + } + if (of != NULL) { + qb_of_delete(broker, &of); + } + if (broker != NULL) { + qb_broker_delete(&broker); + } + return 0; +} -- 1.7.1