X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=block%2Fsheepdog.c;h=6f402e5d4d1bdc2841857d5dffcf4abc088d6a9c;hb=6b7ac49d570c66754fad1b80cc200c7596d1facd;hp=387f59c8aa53befecfba43ac8f7c74edb9ddd111;hpb=4bdc24fa018901892bb8a5bd1808ebd605f4c64d;p=mirror_qemu.git diff --git a/block/sheepdog.c b/block/sheepdog.c index 387f59c8aa..6f402e5d4d 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" #include "qapi/error.h" #include "qapi/qapi-visit-sockets.h" #include "qapi/qapi-visit-block-core.h" @@ -21,12 +22,15 @@ #include "qapi/qobject-output-visitor.h" #include "qemu/uri.h" #include "qemu/error-report.h" +#include "qemu/module.h" #include "qemu/option.h" #include "qemu/sockets.h" #include "block/block_int.h" +#include "block/qdict.h" #include "sysemu/block-backend.h" #include "qemu/bitops.h" #include "qemu/cutils.h" +#include "trace.h" #define SD_PROTO_VER 0x01 @@ -298,19 +302,6 @@ static inline size_t count_data_objs(const struct SheepdogInode *inode) (1UL << inode->block_size_shift)); } -#undef DPRINTF -#ifdef DEBUG_SDOG -#define DEBUG_SDOG_PRINT 1 -#else -#define DEBUG_SDOG_PRINT 0 -#endif -#define DPRINTF(fmt, args...) \ - do { \ - if (DEBUG_SDOG_PRINT) { \ - fprintf(stderr, "%s %d: " fmt, __func__, __LINE__, ##args); \ - } \ - } while (0) - typedef struct SheepdogAIOCB SheepdogAIOCB; typedef struct BDRVSheepdogState BDRVSheepdogState; @@ -390,12 +381,12 @@ struct BDRVSheepdogState { uint32_t aioreq_seq_num; /* Every aio request must be linked to either of these queues. */ - QLIST_HEAD(inflight_aio_head, AIOReq) inflight_aio_head; - QLIST_HEAD(failed_aio_head, AIOReq) failed_aio_head; + QLIST_HEAD(, AIOReq) inflight_aio_head; + QLIST_HEAD(, AIOReq) failed_aio_head; CoMutex queue_lock; CoQueue overlapping_queue; - QLIST_HEAD(inflight_aiocb_head, SheepdogAIOCB) inflight_aiocb_head; + QLIST_HEAD(, SheepdogAIOCB) inflight_aiocb_head; }; typedef struct BDRVSheepdogReopenState { @@ -538,27 +529,17 @@ static void sd_aio_setup(SheepdogAIOCB *acb, BDRVSheepdogState *s, static SocketAddress *sd_server_config(QDict *options, Error **errp) { QDict *server = NULL; - QObject *crumpled_server = NULL; Visitor *iv = NULL; SocketAddress *saddr = NULL; Error *local_err = NULL; qdict_extract_subqdict(options, &server, "server."); - crumpled_server = qdict_crumple(server, errp); - if (!crumpled_server) { + iv = qobject_input_visitor_new_flat_confused(server, errp); + if (!iv) { goto done; } - /* - * FIXME .numeric, .to, .ipv4 or .ipv6 don't work with -drive - * server.type=inet. .to doesn't matter, it's ignored anyway. - * That's because when @options come from -blockdev or - * blockdev_add, members are typed according to the QAPI schema, - * but when they come from -drive, they're all QString. The - * visitor expects the former. - */ - iv = qobject_input_visitor_new(crumpled_server); visit_type_SocketAddress(iv, NULL, &saddr, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -567,8 +548,7 @@ static SocketAddress *sd_server_config(QDict *options, Error **errp) done: visit_free(iv); - qobject_decref(crumpled_server); - QDECREF(server); + qobject_unref(server); return saddr; } @@ -582,7 +562,7 @@ static int connect_to_sdog(BDRVSheepdogState *s, Error **errp) if (s->addr->type == SOCKET_ADDRESS_TYPE_INET && fd >= 0) { int ret = socket_set_nodelay(fd); if (ret < 0) { - error_report("%s", strerror(errno)); + warn_report("can't set TCP_NODELAY: %s", strerror(errno)); } } @@ -760,7 +740,7 @@ static coroutine_fn void reconnect_to_sdog(void *opaque) Error *local_err = NULL; s->fd = get_sheep_fd(s, &local_err); if (s->fd < 0) { - DPRINTF("Wait for connection to be established\n"); + trace_sheepdog_reconnect_to_sdog(); error_report_err(local_err); qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000000ULL); } @@ -857,7 +837,7 @@ static void coroutine_fn aio_read_response(void *opaque) break; case AIOCB_FLUSH_CACHE: if (rsp.result == SD_RES_INVALID_PARMS) { - DPRINTF("disable cache since the server doesn't support it\n"); + trace_sheepdog_aio_read_response(); s->cache_flags = SD_FLAG_CMD_DIRECT; rsp.result = SD_RES_SUCCESS; } @@ -1234,7 +1214,7 @@ static int find_vdi_name(BDRVSheepdogState *s, const char *filename, SheepdogVdiReq hdr; SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr; unsigned int wlen, rlen = 0; - char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN]; + char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN] QEMU_NONSTRING; fd = connect_to_sdog(s, errp); if (fd < 0) { @@ -1649,7 +1629,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags, s->discard_supported = true; if (snap_id || tag[0]) { - DPRINTF("%" PRIx32 " snapshot inode was open.\n", vid); + trace_sheepdog_open(vid); s->is_snapshot = true; } @@ -1822,7 +1802,8 @@ static int sd_prealloc(BlockDriverState *bs, int64_t old_size, int64_t new_size, void *buf = NULL; int ret; - blk = blk_new(BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE | BLK_PERM_RESIZE, + blk = blk_new(bdrv_get_aio_context(bs), + BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL); ret = blk_insert_bs(blk, bs, errp); @@ -1859,9 +1840,7 @@ out: error_setg_errno(errp, -ret, "Can't pre-allocate"); } out_with_err_set: - if (blk) { - blk_unref(blk); - } + blk_unref(blk); g_free(buf); return ret; @@ -1883,7 +1862,7 @@ static int sd_create_prealloc(BlockdevOptionsSheepdog *location, int64_t size, if (local_err) { error_propagate(errp, local_err); - qobject_decref(obj); + qobject_unref(obj); return -EINVAL; } @@ -1901,7 +1880,7 @@ static int sd_create_prealloc(BlockdevOptionsSheepdog *location, int64_t size, ret = sd_prealloc(bs, 0, size, errp); fail: bdrv_unref(bs); - QDECREF(qdict); + qobject_unref(qdict); return ret; } @@ -1987,6 +1966,7 @@ static SheepdogRedundancy *parse_redundancy_str(const char *opt) } else { ret = qemu_strtol(n2, NULL, 10, &parity); if (ret < 0) { + g_free(redundancy); return NULL; } @@ -2181,9 +2161,8 @@ static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, { BlockdevCreateOptions *create_options = NULL; QDict *qdict, *location_qdict; - QObject *crumpled; Visitor *v; - const char *redundancy; + char *redundancy; Error *local_err = NULL; int ret; @@ -2217,16 +2196,14 @@ static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, } /* Get the QAPI object */ - crumpled = qdict_crumple(qdict, errp); - if (crumpled == NULL) { + v = qobject_input_visitor_new_flat_confused(qdict, errp); + if (!v) { ret = -EINVAL; goto fail; } - v = qobject_input_visitor_new_keyval(crumpled); visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err); visit_free(v); - qobject_decref(crumpled); if (local_err) { error_propagate(errp, local_err); @@ -2252,7 +2229,8 @@ static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts, ret = sd_co_create(create_options, errp); fail: qapi_free_BlockdevCreateOptions(create_options); - QDECREF(qdict); + qobject_unref(qdict); + g_free(redundancy); return ret; } @@ -2265,7 +2243,7 @@ static void sd_close(BlockDriverState *bs) unsigned int wlen, rlen = 0; int fd, ret; - DPRINTF("%s\n", s->name); + trace_sheepdog_close(s->name); fd = connect_to_sdog(s, &local_err); if (fd < 0) { @@ -2305,8 +2283,8 @@ static int64_t sd_getlength(BlockDriverState *bs) return s->inode.vdi_size; } -static int sd_truncate(BlockDriverState *bs, int64_t offset, - PreallocMode prealloc, Error **errp) +static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset, + PreallocMode prealloc, Error **errp) { BDRVSheepdogState *s = bs->opaque; int ret, fd; @@ -2335,7 +2313,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset, } /* we don't need to update entire object */ - datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id); + datalen = SD_INODE_HEADER_SIZE; s->inode.vdi_size = offset; ret = write_object(fd, s->bs, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id), s->inode.nr_copies, @@ -2442,7 +2420,7 @@ static int sd_create_branch(BDRVSheepdogState *s) char *buf; bool deleted; - DPRINTF("%" PRIx32 " is snapshot.\n", s->inode.vdi_id); + trace_sheepdog_create_branch_snapshot(s->inode.vdi_id); buf = g_malloc(SD_INODE_SIZE); @@ -2458,7 +2436,7 @@ static int sd_create_branch(BDRVSheepdogState *s) goto out; } - DPRINTF("%" PRIx32 " is created.\n", vid); + trace_sheepdog_create_branch_created(vid); fd = connect_to_sdog(s, &local_err); if (fd < 0) { @@ -2480,7 +2458,7 @@ static int sd_create_branch(BDRVSheepdogState *s) s->is_snapshot = false; ret = 0; - DPRINTF("%" PRIx32 " was newly created.\n", s->inode.vdi_id); + trace_sheepdog_create_branch_new(s->inode.vdi_id); out: g_free(buf); @@ -2574,11 +2552,11 @@ static void coroutine_fn sd_co_rw_vector(SheepdogAIOCB *acb) } if (create) { - DPRINTF("update ino (%" PRIu32 ") %" PRIu64 " %" PRIu64 " %ld\n", - inode->vdi_id, oid, - vid_to_data_oid(inode->data_vdi_id[idx], idx), idx); + trace_sheepdog_co_rw_vector_update(inode->vdi_id, oid, + vid_to_data_oid(inode->data_vdi_id[idx], idx), + idx); oid = vid_to_data_oid(inode->vdi_id, idx); - DPRINTF("new oid %" PRIx64 "\n", oid); + trace_sheepdog_co_rw_vector_new(oid); } aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, create, @@ -2612,15 +2590,17 @@ static void sd_aio_complete(SheepdogAIOCB *acb) } static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov) + int nb_sectors, QEMUIOVector *qiov, + int flags) { SheepdogAIOCB acb; int ret; int64_t offset = (sector_num + nb_sectors) * BDRV_SECTOR_SIZE; BDRVSheepdogState *s = bs->opaque; + assert(!flags); if (offset > s->inode.vdi_size) { - ret = sd_truncate(bs, offset, PREALLOC_MODE_OFF, NULL); + ret = sd_co_truncate(bs, offset, PREALLOC_MODE_OFF, NULL); if (ret < 0) { return ret; } @@ -2681,9 +2661,8 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) SheepdogInode *inode; unsigned int datalen; - DPRINTF("sn_info: name %s id_str %s s: name %s vm_state_size %" PRId64 " " - "is_snapshot %d\n", sn_info->name, sn_info->id_str, - s->name, sn_info->vm_state_size, s->is_snapshot); + trace_sheepdog_snapshot_create_info(sn_info->name, sn_info->id_str, s->name, + sn_info->vm_state_size, s->is_snapshot); if (s->is_snapshot) { error_report("You can't create a snapshot of a snapshot VDI, " @@ -2692,7 +2671,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) return -EINVAL; } - DPRINTF("%s %s\n", sn_info->name, sn_info->id_str); + trace_sheepdog_snapshot_create(sn_info->name, sn_info->id_str); s->inode.vm_state_size = sn_info->vm_state_size; s->inode.vm_clock_nsec = sn_info->vm_clock_nsec; @@ -2701,7 +2680,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) */ strncpy(s->inode.tag, sn_info->name, sizeof(s->inode.tag)); /* we don't need to update entire object */ - datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id); + datalen = SD_INODE_HEADER_SIZE; inode = g_malloc(datalen); /* refresh inode. */ @@ -2737,8 +2716,8 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) } memcpy(&s->inode, inode, datalen); - DPRINTF("s->inode: name %s snap_id %x oid %x\n", - s->inode.name, s->inode.snap_id, s->inode.vdi_id); + trace_sheepdog_snapshot_create_inode(s->inode.name, s->inode.snap_id, + s->inode.vdi_id); cleanup: g_free(inode); @@ -2936,13 +2915,14 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) QEMUSnapshotInfo *sn_tab = NULL; unsigned wlen, rlen; int found = 0; - static SheepdogInode inode; + SheepdogInode *inode; unsigned long *vdi_inuse; unsigned int start_nr; uint64_t hval; uint32_t vid; vdi_inuse = g_malloc(max); + inode = g_malloc(SD_INODE_HEADER_SIZE); fd = connect_to_sdog(s, &local_err); if (fd < 0) { @@ -2985,26 +2965,26 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) } /* we don't need to read entire object */ - ret = read_object(fd, s->bs, (char *)&inode, + ret = read_object(fd, s->bs, (char *)inode, vid_to_vdi_oid(vid), - 0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0, + 0, SD_INODE_HEADER_SIZE, 0, s->cache_flags); if (ret) { continue; } - if (!strcmp(inode.name, s->name) && is_snapshot(&inode)) { - sn_tab[found].date_sec = inode.snap_ctime >> 32; - sn_tab[found].date_nsec = inode.snap_ctime & 0xffffffff; - sn_tab[found].vm_state_size = inode.vm_state_size; - sn_tab[found].vm_clock_nsec = inode.vm_clock_nsec; + if (!strcmp(inode->name, s->name) && is_snapshot(inode)) { + sn_tab[found].date_sec = inode->snap_ctime >> 32; + sn_tab[found].date_nsec = inode->snap_ctime & 0xffffffff; + sn_tab[found].vm_state_size = inode->vm_state_size; + sn_tab[found].vm_clock_nsec = inode->vm_clock_nsec; snprintf(sn_tab[found].id_str, sizeof(sn_tab[found].id_str), - "%" PRIu32, inode.snap_id); + "%" PRIu32, inode->snap_id); pstrcpy(sn_tab[found].name, - MIN(sizeof(sn_tab[found].name), sizeof(inode.tag)), - inode.tag); + MIN(sizeof(sn_tab[found].name), sizeof(inode->tag)), + inode->tag); found++; } } @@ -3014,6 +2994,7 @@ out: *psn_tab = sn_tab; g_free(vdi_inuse); + g_free(inode); if (ret < 0) { return ret; @@ -3225,6 +3206,15 @@ static QemuOptsList sd_create_opts = { } }; +static const char *const sd_strong_runtime_opts[] = { + "vdi", + "snap-id", + "tag", + "server.", + + NULL +}; + static BlockDriver bdrv_sheepdog = { .format_name = "sheepdog", .protocol_name = "sheepdog", @@ -3240,7 +3230,7 @@ static BlockDriver bdrv_sheepdog = { .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, .bdrv_get_allocated_file_size = sd_get_allocated_file_size, - .bdrv_truncate = sd_truncate, + .bdrv_co_truncate = sd_co_truncate, .bdrv_co_readv = sd_co_readv, .bdrv_co_writev = sd_co_writev, @@ -3260,6 +3250,7 @@ static BlockDriver bdrv_sheepdog = { .bdrv_attach_aio_context = sd_attach_aio_context, .create_opts = &sd_create_opts, + .strong_runtime_opts = sd_strong_runtime_opts, }; static BlockDriver bdrv_sheepdog_tcp = { @@ -3277,7 +3268,7 @@ static BlockDriver bdrv_sheepdog_tcp = { .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, .bdrv_get_allocated_file_size = sd_get_allocated_file_size, - .bdrv_truncate = sd_truncate, + .bdrv_co_truncate = sd_co_truncate, .bdrv_co_readv = sd_co_readv, .bdrv_co_writev = sd_co_writev, @@ -3297,6 +3288,7 @@ static BlockDriver bdrv_sheepdog_tcp = { .bdrv_attach_aio_context = sd_attach_aio_context, .create_opts = &sd_create_opts, + .strong_runtime_opts = sd_strong_runtime_opts, }; static BlockDriver bdrv_sheepdog_unix = { @@ -3314,7 +3306,7 @@ static BlockDriver bdrv_sheepdog_unix = { .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, .bdrv_get_allocated_file_size = sd_get_allocated_file_size, - .bdrv_truncate = sd_truncate, + .bdrv_co_truncate = sd_co_truncate, .bdrv_co_readv = sd_co_readv, .bdrv_co_writev = sd_co_writev, @@ -3334,6 +3326,7 @@ static BlockDriver bdrv_sheepdog_unix = { .bdrv_attach_aio_context = sd_attach_aio_context, .create_opts = &sd_create_opts, + .strong_runtime_opts = sd_strong_runtime_opts, }; static void bdrv_sheepdog_init(void)