diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/mirror.c | 2 | ||||
-rw-r--r-- | block/qcow2-cluster.c | 3 | ||||
-rw-r--r-- | block/rbd.c | 71 | ||||
-rw-r--r-- | block/sheepdog.c | 149 | ||||
-rw-r--r-- | block/ssh.c | 151 | ||||
-rw-r--r-- | block/stream.c | 4 | ||||
-rw-r--r-- | block/vvfat.c | 36 |
7 files changed, 246 insertions, 170 deletions
diff --git a/block/mirror.c b/block/mirror.c index 1c38aa8f77..94c8661777 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -498,7 +498,7 @@ immediate_exit: /* drop the bs loop chain formed by the swap: break the loop then * trigger the unref from the top one */ BlockDriverState *p = s->base->backing_hd; - s->base->backing_hd = NULL; + bdrv_set_backing_hd(s->base, NULL); bdrv_unref(p); } } diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 76d2bcf63a..4208dc08b5 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -379,7 +379,8 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs, BLKDBG_EVENT(bs->file, BLKDBG_COW_READ); if (!bs->drv) { - return -ENOMEDIUM; + ret = -ENOMEDIUM; + goto out; } /* Call .bdrv_co_readv() directly instead of using the public block-layer diff --git a/block/rbd.c b/block/rbd.c index dbc79f4525..09af48426e 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -105,7 +105,7 @@ typedef struct BDRVRBDState { static int qemu_rbd_next_tok(char *dst, int dst_len, char *src, char delim, const char *name, - char **p) + char **p, Error **errp) { int l; char *end; @@ -128,10 +128,10 @@ static int qemu_rbd_next_tok(char *dst, int dst_len, } l = strlen(src); if (l >= dst_len) { - error_report("%s too long", name); + error_setg(errp, "%s too long", name); return -EINVAL; } else if (l == 0) { - error_report("%s too short", name); + error_setg(errp, "%s too short", name); return -EINVAL; } @@ -157,13 +157,15 @@ static int qemu_rbd_parsename(const char *filename, char *pool, int pool_len, char *snap, int snap_len, char *name, int name_len, - char *conf, int conf_len) + char *conf, int conf_len, + Error **errp) { const char *start; char *p, *buf; int ret; if (!strstart(filename, "rbd:", &start)) { + error_setg(errp, "File name must start with 'rbd:'"); return -EINVAL; } @@ -172,7 +174,8 @@ static int qemu_rbd_parsename(const char *filename, *snap = '\0'; *conf = '\0'; - ret = qemu_rbd_next_tok(pool, pool_len, p, '/', "pool name", &p); + ret = qemu_rbd_next_tok(pool, pool_len, p, + '/', "pool name", &p, errp); if (ret < 0 || !p) { ret = -EINVAL; goto done; @@ -180,21 +183,25 @@ static int qemu_rbd_parsename(const char *filename, qemu_rbd_unescape(pool); if (strchr(p, '@')) { - ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p); + ret = qemu_rbd_next_tok(name, name_len, p, + '@', "object name", &p, errp); if (ret < 0) { goto done; } - ret = qemu_rbd_next_tok(snap, snap_len, p, ':', "snap name", &p); + ret = qemu_rbd_next_tok(snap, snap_len, p, + ':', "snap name", &p, errp); qemu_rbd_unescape(snap); } else { - ret = qemu_rbd_next_tok(name, name_len, p, ':', "object name", &p); + ret = qemu_rbd_next_tok(name, name_len, p, + ':', "object name", &p, errp); } qemu_rbd_unescape(name); if (ret < 0 || !p) { goto done; } - ret = qemu_rbd_next_tok(conf, conf_len, p, '\0', "configuration", &p); + ret = qemu_rbd_next_tok(conf, conf_len, p, + '\0', "configuration", &p, errp); done: g_free(buf); @@ -229,7 +236,7 @@ static char *qemu_rbd_parse_clientname(const char *conf, char *clientname) return NULL; } -static int qemu_rbd_set_conf(rados_t cluster, const char *conf) +static int qemu_rbd_set_conf(rados_t cluster, const char *conf, Error **errp) { char *p, *buf; char name[RBD_MAX_CONF_NAME_SIZE]; @@ -241,20 +248,20 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf) while (p) { ret = qemu_rbd_next_tok(name, sizeof(name), p, - '=', "conf option name", &p); + '=', "conf option name", &p, errp); if (ret < 0) { break; } qemu_rbd_unescape(name); if (!p) { - error_report("conf option %s has no value", name); + error_setg(errp, "conf option %s has no value", name); ret = -EINVAL; break; } ret = qemu_rbd_next_tok(value, sizeof(value), p, - ':', "conf option value", &p); + ':', "conf option value", &p, errp); if (ret < 0) { break; } @@ -263,7 +270,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf) if (strcmp(name, "conf") == 0) { ret = rados_conf_read_file(cluster, value); if (ret < 0) { - error_report("error reading conf file %s", value); + error_setg(errp, "error reading conf file %s", value); break; } } else if (strcmp(name, "id") == 0) { @@ -271,7 +278,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf) } else { ret = rados_conf_set(cluster, name, value); if (ret < 0) { - error_report("invalid conf option %s", name); + error_setg(errp, "invalid conf option %s", name); ret = -EINVAL; break; } @@ -285,6 +292,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf) static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options, Error **errp) { + Error *local_err = NULL; int64_t bytes = 0; int64_t objsize; int obj_order = 0; @@ -301,7 +309,8 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options, if (qemu_rbd_parsename(filename, pool, sizeof(pool), snap_buf, sizeof(snap_buf), name, sizeof(name), - conf, sizeof(conf)) < 0) { + conf, sizeof(conf), &local_err) < 0) { + error_propagate(errp, local_err); return -EINVAL; } @@ -313,11 +322,11 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options, if (options->value.n) { objsize = options->value.n; if ((objsize - 1) & objsize) { /* not a power of 2? */ - error_report("obj size needs to be power of 2"); + error_setg(errp, "obj size needs to be power of 2"); return -EINVAL; } if (objsize < 4096) { - error_report("obj size too small"); + error_setg(errp, "obj size too small"); return -EINVAL; } obj_order = ffs(objsize) - 1; @@ -328,7 +337,7 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options, clientname = qemu_rbd_parse_clientname(conf, clientname_buf); if (rados_create(&cluster, clientname) < 0) { - error_report("error initializing"); + error_setg(errp, "error initializing"); return -EIO; } @@ -338,20 +347,20 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options, } if (conf[0] != '\0' && - qemu_rbd_set_conf(cluster, conf) < 0) { - error_report("error setting config options"); + qemu_rbd_set_conf(cluster, conf, &local_err) < 0) { rados_shutdown(cluster); + error_propagate(errp, local_err); return -EIO; } if (rados_connect(cluster) < 0) { - error_report("error connecting"); + error_setg(errp, "error connecting"); rados_shutdown(cluster); return -EIO; } if (rados_ioctx_create(cluster, pool, &io_ctx) < 0) { - error_report("error opening pool %s", pool); + error_setg(errp, "error opening pool %s", pool); rados_shutdown(cluster); return -EIO; } @@ -441,8 +450,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); if (local_err) { - qerror_report_err(local_err); - error_free(local_err); + error_propagate(errp, local_err); qemu_opts_del(opts); return -EINVAL; } @@ -452,7 +460,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, if (qemu_rbd_parsename(filename, pool, sizeof(pool), snap_buf, sizeof(snap_buf), s->name, sizeof(s->name), - conf, sizeof(conf)) < 0) { + conf, sizeof(conf), errp) < 0) { r = -EINVAL; goto failed_opts; } @@ -460,7 +468,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, clientname = qemu_rbd_parse_clientname(conf, clientname_buf); r = rados_create(&s->cluster, clientname); if (r < 0) { - error_report("error initializing"); + error_setg(&local_err, "error initializing"); goto failed_opts; } @@ -488,28 +496,27 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, } if (conf[0] != '\0') { - r = qemu_rbd_set_conf(s->cluster, conf); + r = qemu_rbd_set_conf(s->cluster, conf, errp); if (r < 0) { - error_report("error setting config options"); goto failed_shutdown; } } r = rados_connect(s->cluster); if (r < 0) { - error_report("error connecting"); + error_setg(&local_err, "error connecting"); goto failed_shutdown; } r = rados_ioctx_create(s->cluster, pool, &s->io_ctx); if (r < 0) { - error_report("error opening pool %s", pool); + error_setg(&local_err, "error opening pool %s", pool); goto failed_shutdown; } r = rbd_open(s->io_ctx, s->name, &s->image, s->snap); if (r < 0) { - error_report("error reading header from %s", s->name); + error_setg(&local_err, "error reading header from %s", s->name); goto failed_open; } diff --git a/block/sheepdog.c b/block/sheepdog.c index 2c3fb016a8..39f746157a 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -526,17 +526,16 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov, return acb; } -static int connect_to_sdog(BDRVSheepdogState *s) +static int connect_to_sdog(BDRVSheepdogState *s, Error **errp) { int fd; - Error *err = NULL; if (s->is_unix) { - fd = unix_connect(s->host_spec, &err); + fd = unix_connect(s->host_spec, errp); } else { - fd = inet_connect(s->host_spec, &err); + fd = inet_connect(s->host_spec, errp); - if (err == NULL) { + if (fd >= 0) { int ret = socket_set_nodelay(fd); if (ret < 0) { error_report("%s", strerror(errno)); @@ -544,10 +543,7 @@ static int connect_to_sdog(BDRVSheepdogState *s) } } - if (err != NULL) { - qerror_report_err(err); - error_free(err); - } else { + if (fd >= 0) { qemu_set_nonblock(fd); } @@ -672,7 +668,7 @@ static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, enum AIOCBState aiocb_type); static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req); static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag); -static int get_sheep_fd(BDRVSheepdogState *s); +static int get_sheep_fd(BDRVSheepdogState *s, Error **errp); static void co_write_request(void *opaque); static AIOReq *find_pending_req(BDRVSheepdogState *s, uint64_t oid) @@ -709,6 +705,7 @@ static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid) static coroutine_fn void reconnect_to_sdog(void *opaque) { + Error *local_err = NULL; BDRVSheepdogState *s = opaque; AIOReq *aio_req, *next; @@ -723,9 +720,11 @@ static coroutine_fn void reconnect_to_sdog(void *opaque) /* Try to reconnect the sheepdog server every one second. */ while (s->fd < 0) { - s->fd = get_sheep_fd(s); + s->fd = get_sheep_fd(s, &local_err); if (s->fd < 0) { DPRINTF("Wait for connection to be established\n"); + error_report("%s", error_get_pretty(local_err)); + error_free(local_err); co_aio_sleep_ns(bdrv_get_aio_context(s->bs), QEMU_CLOCK_REALTIME, 1000000000ULL); } @@ -914,11 +913,11 @@ static void co_write_request(void *opaque) * We cannot use this descriptor for other operations because * the block driver may be on waiting response from the server. */ -static int get_sheep_fd(BDRVSheepdogState *s) +static int get_sheep_fd(BDRVSheepdogState *s, Error **errp) { int fd; - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, errp); if (fd < 0) { return fd; } @@ -1061,7 +1060,7 @@ static int parse_vdiname(BDRVSheepdogState *s, const char *filename, static int find_vdi_name(BDRVSheepdogState *s, const char *filename, uint32_t snapid, const char *tag, uint32_t *vid, - bool lock) + bool lock, Error **errp) { int ret, fd; SheepdogVdiReq hdr; @@ -1069,7 +1068,7 @@ static int find_vdi_name(BDRVSheepdogState *s, const char *filename, unsigned int wlen, rlen = 0; char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN]; - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, errp); if (fd < 0) { return fd; } @@ -1095,12 +1094,13 @@ static int find_vdi_name(BDRVSheepdogState *s, const char *filename, ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen); if (ret) { + error_setg_errno(errp, -ret, "cannot get vdi info"); goto out; } if (rsp->result != SD_RES_SUCCESS) { - error_report("cannot get vdi info, %s, %s %" PRIu32 " %s", - sd_strerror(rsp->result), filename, snapid, tag); + error_setg(errp, "cannot get vdi info, %s, %s %" PRIu32 " %s", + sd_strerror(rsp->result), filename, snapid, tag); if (rsp->result == SD_RES_NO_VDI) { ret = -ENOENT; } else { @@ -1263,19 +1263,24 @@ static int write_object(int fd, char *buf, uint64_t oid, uint8_t copies, /* update inode with the latest state */ static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag) { + Error *local_err = NULL; SheepdogInode *inode; int ret = 0, fd; uint32_t vid = 0; - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, &local_err); if (fd < 0) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); return -EIO; } inode = g_malloc(sizeof(s->inode)); - ret = find_vdi_name(s, s->name, snapid, tag, &vid, false); + ret = find_vdi_name(s, s->name, snapid, tag, &vid, false, &local_err); if (ret) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); goto out; } @@ -1386,8 +1391,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags, opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); if (local_err) { - qerror_report_err(local_err); - error_free(local_err); + error_propagate(errp, local_err); ret = -EINVAL; goto out; } @@ -1408,15 +1412,16 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags, ret = parse_vdiname(s, filename, vdi, &snapid, tag); } if (ret < 0) { + error_setg(errp, "Can't parse filename"); goto out; } - s->fd = get_sheep_fd(s); + s->fd = get_sheep_fd(s, errp); if (s->fd < 0) { ret = s->fd; goto out; } - ret = find_vdi_name(s, vdi, snapid, tag, &vid, true); + ret = find_vdi_name(s, vdi, snapid, tag, &vid, true, errp); if (ret) { goto out; } @@ -1436,7 +1441,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags, s->is_snapshot = true; } - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, errp); if (fd < 0) { ret = fd; goto out; @@ -1449,6 +1454,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags, closesocket(fd); if (ret) { + error_setg(errp, "Can't read snapshot inode"); goto out; } @@ -1472,7 +1478,8 @@ out: return ret; } -static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot) +static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot, + Error **errp) { SheepdogVdiReq hdr; SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr; @@ -1480,7 +1487,7 @@ static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot) unsigned int wlen, rlen = 0; char buf[SD_MAX_VDI_LEN]; - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, errp); if (fd < 0) { return fd; } @@ -1510,11 +1517,12 @@ static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot) closesocket(fd); if (ret) { + error_setg_errno(errp, -ret, "create failed"); return ret; } if (rsp->result != SD_RES_SUCCESS) { - error_report("%s, %s", sd_strerror(rsp->result), s->inode.name); + error_setg(errp, "%s, %s", sd_strerror(rsp->result), s->inode.name); return -EIO; } @@ -1525,21 +1533,18 @@ static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot) return 0; } -static int sd_prealloc(const char *filename) +static int sd_prealloc(const char *filename, Error **errp) { BlockDriverState *bs = NULL; uint32_t idx, max_idx; int64_t vdi_size; void *buf = g_malloc0(SD_DATA_OBJ_SIZE); - Error *local_err = NULL; int ret; ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, - NULL, &local_err); + NULL, errp); if (ret < 0) { - qerror_report_err(local_err); - error_free(local_err); - goto out; + goto out_with_err_set; } vdi_size = bdrv_getlength(bs); @@ -1563,7 +1568,12 @@ static int sd_prealloc(const char *filename) goto out; } } + out: + if (ret < 0) { + error_setg_errno(errp, -ret, "Can't pre-allocate"); + } +out_with_err_set: if (bs) { bdrv_unref(bs); } @@ -1636,7 +1646,6 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, char tag[SD_MAX_VDI_TAG_LEN]; uint32_t snapid; bool prealloc = false; - Error *local_err = NULL; s = g_malloc0(sizeof(BDRVSheepdogState)); @@ -1647,6 +1656,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, ret = parse_vdiname(s, filename, s->name, &snapid, tag); } if (ret < 0) { + error_setg(errp, "Can't parse filename"); goto out; } @@ -1661,8 +1671,8 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, } else if (!strcmp(options->value.s, "full")) { prealloc = true; } else { - error_report("Invalid preallocation mode: '%s'", - options->value.s); + error_setg(errp, "Invalid preallocation mode: '%s'", + options->value.s); ret = -EINVAL; goto out; } @@ -1670,6 +1680,8 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, if (options->value.s) { ret = parse_redundancy(s, options->value.s); if (ret < 0) { + error_setg(errp, "Invalid redundancy mode: '%s'", + options->value.s); goto out; } } @@ -1678,7 +1690,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, } if (s->inode.vdi_size > SD_MAX_VDI_SIZE) { - error_report("too big image size"); + error_setg(errp, "too big image size"); ret = -EINVAL; goto out; } @@ -1691,24 +1703,22 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, /* Currently, only Sheepdog backing image is supported. */ drv = bdrv_find_protocol(backing_file, true); if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) { - error_report("backing_file must be a sheepdog image"); + error_setg(errp, "backing_file must be a sheepdog image"); ret = -EINVAL; goto out; } bs = NULL; ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_PROTOCOL, NULL, - &local_err); + errp); if (ret < 0) { - qerror_report_err(local_err); - error_free(local_err); goto out; } base = bs->opaque; if (!is_snapshot(&base->inode)) { - error_report("cannot clone from a non snapshot vdi"); + error_setg(errp, "cannot clone from a non snapshot vdi"); bdrv_unref(bs); ret = -EINVAL; goto out; @@ -1717,12 +1727,14 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, bdrv_unref(bs); } - ret = do_sd_create(s, &vid, 0); - if (!prealloc || ret) { + ret = do_sd_create(s, &vid, 0, errp); + if (ret) { goto out; } - ret = sd_prealloc(filename); + if (prealloc) { + ret = sd_prealloc(filename, errp); + } out: g_free(s); return ret; @@ -1730,6 +1742,7 @@ out: static void sd_close(BlockDriverState *bs) { + Error *local_err = NULL; BDRVSheepdogState *s = bs->opaque; SheepdogVdiReq hdr; SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr; @@ -1738,8 +1751,10 @@ static void sd_close(BlockDriverState *bs) DPRINTF("%s\n", s->name); - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, &local_err); if (fd < 0) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); return; } @@ -1774,6 +1789,7 @@ static int64_t sd_getlength(BlockDriverState *bs) static int sd_truncate(BlockDriverState *bs, int64_t offset) { + Error *local_err = NULL; BDRVSheepdogState *s = bs->opaque; int ret, fd; unsigned int datalen; @@ -1786,8 +1802,10 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset) return -EINVAL; } - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, &local_err); if (fd < 0) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); return fd; } @@ -1846,6 +1864,7 @@ static void coroutine_fn sd_write_done(SheepdogAIOCB *acb) /* Delete current working VDI on the snapshot chain */ static bool sd_delete(BDRVSheepdogState *s) { + Error *local_err = NULL; unsigned int wlen = SD_MAX_VDI_LEN, rlen = 0; SheepdogVdiReq hdr = { .opcode = SD_OP_DEL_VDI, @@ -1856,8 +1875,10 @@ static bool sd_delete(BDRVSheepdogState *s) SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr; int fd, ret; - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, &local_err); if (fd < 0) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); return false; } @@ -1885,6 +1906,7 @@ static bool sd_delete(BDRVSheepdogState *s) */ static int sd_create_branch(BDRVSheepdogState *s) { + Error *local_err = NULL; int ret, fd; uint32_t vid; char *buf; @@ -1900,15 +1922,19 @@ static int sd_create_branch(BDRVSheepdogState *s) * false bail out. */ deleted = sd_delete(s); - ret = do_sd_create(s, &vid, !deleted); + ret = do_sd_create(s, &vid, !deleted, &local_err); if (ret) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); goto out; } DPRINTF("%" PRIx32 " is created.\n", vid); - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, &local_err); if (fd < 0) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); ret = fd; goto out; } @@ -2122,6 +2148,7 @@ static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs) static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) { + Error *local_err = NULL; BDRVSheepdogState *s = bs->opaque; int ret, fd; uint32_t new_vid; @@ -2151,8 +2178,10 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id); /* refresh inode. */ - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, &local_err); if (fd < 0) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); ret = fd; goto cleanup; } @@ -2164,8 +2193,10 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) goto cleanup; } - ret = do_sd_create(s, &new_vid, 1); + ret = do_sd_create(s, &new_vid, 1, &local_err); if (ret < 0) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); error_report("failed to create inode for snapshot. %s", strerror(errno)); goto cleanup; @@ -2249,6 +2280,7 @@ static int sd_snapshot_delete(BlockDriverState *bs, static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) { + Error *local_err = NULL; BDRVSheepdogState *s = bs->opaque; SheepdogReq req; int fd, nr = 1024, ret, max = BITS_TO_LONGS(SD_NR_VDIS) * sizeof(long); @@ -2263,8 +2295,10 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) vdi_inuse = g_malloc(max); - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, &local_err); if (fd < 0) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); ret = fd; goto out; } @@ -2290,8 +2324,10 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT); start_nr = hval & (SD_NR_VDIS - 1); - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, &local_err); if (fd < 0) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); ret = fd; goto out; } @@ -2341,6 +2377,7 @@ out: static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data, int64_t pos, int size, int load) { + Error *local_err = NULL; bool create; int fd, ret = 0, remaining = size; unsigned int data_len; @@ -2349,8 +2386,10 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data, uint32_t vdi_index; uint32_t vdi_id = load ? s->inode.parent_vdi_id : s->inode.vdi_id; - fd = connect_to_sdog(s); + fd = connect_to_sdog(s, &local_err); if (fd < 0) { + error_report("%s", error_get_pretty(local_err));; + error_free(local_err); return fd; } diff --git a/block/ssh.c b/block/ssh.c index aa63c9d20e..b2129714bc 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -106,30 +106,59 @@ static void ssh_state_free(BDRVSSHState *s) } } -/* Wrappers around error_report which make sure to dump as much - * information from libssh2 as possible. - */ -static void GCC_FMT_ATTR(2, 3) -session_error_report(BDRVSSHState *s, const char *fs, ...) +static void GCC_FMT_ATTR(3, 4) +session_error_setg(Error **errp, BDRVSSHState *s, const char *fs, ...) { va_list args; + char *msg; va_start(args, fs); - error_vprintf(fs, args); + msg = g_strdup_vprintf(fs, args); + va_end(args); - if ((s)->session) { + if (s->session) { char *ssh_err; int ssh_err_code; - libssh2_session_last_error((s)->session, &ssh_err, NULL, 0); /* This is not an errno. See <libssh2.h>. */ - ssh_err_code = libssh2_session_last_errno((s)->session); - - error_printf(": %s (libssh2 error code: %d)", ssh_err, ssh_err_code); + ssh_err_code = libssh2_session_last_error(s->session, + &ssh_err, NULL, 0); + error_setg(errp, "%s: %s (libssh2 error code: %d)", + msg, ssh_err, ssh_err_code); + } else { + error_setg(errp, "%s", msg); } + g_free(msg); +} + +static void GCC_FMT_ATTR(3, 4) +sftp_error_setg(Error **errp, BDRVSSHState *s, const char *fs, ...) +{ + va_list args; + char *msg; + va_start(args, fs); + msg = g_strdup_vprintf(fs, args); va_end(args); - error_printf("\n"); + + if (s->sftp) { + char *ssh_err; + int ssh_err_code; + unsigned long sftp_err_code; + + /* This is not an errno. See <libssh2.h>. */ + ssh_err_code = libssh2_session_last_error(s->session, + &ssh_err, NULL, 0); + /* See <libssh2_sftp.h>. */ + sftp_err_code = libssh2_sftp_last_error((s)->sftp); + + error_setg(errp, + "%s: %s (libssh2 error code: %d, sftp error code: %lu)", + msg, ssh_err, ssh_err_code, sftp_err_code); + } else { + error_setg(errp, "%s", msg); + } + g_free(msg); } static void GCC_FMT_ATTR(2, 3) @@ -145,9 +174,9 @@ sftp_error_report(BDRVSSHState *s, const char *fs, ...) int ssh_err_code; unsigned long sftp_err_code; - libssh2_session_last_error((s)->session, &ssh_err, NULL, 0); /* This is not an errno. See <libssh2.h>. */ - ssh_err_code = libssh2_session_last_errno((s)->session); + ssh_err_code = libssh2_session_last_error(s->session, + &ssh_err, NULL, 0); /* See <libssh2_sftp.h>. */ sftp_err_code = libssh2_sftp_last_error((s)->sftp); @@ -243,7 +272,7 @@ static void ssh_parse_filename(const char *filename, QDict *options, } static int check_host_key_knownhosts(BDRVSSHState *s, - const char *host, int port) + const char *host, int port, Error **errp) { const char *home; char *knh_file = NULL; @@ -257,14 +286,15 @@ static int check_host_key_knownhosts(BDRVSSHState *s, hostkey = libssh2_session_hostkey(s->session, &len, &type); if (!hostkey) { ret = -EINVAL; - session_error_report(s, "failed to read remote host key"); + session_error_setg(errp, s, "failed to read remote host key"); goto out; } knh = libssh2_knownhost_init(s->session); if (!knh) { ret = -EINVAL; - session_error_report(s, "failed to initialize known hosts support"); + session_error_setg(errp, s, + "failed to initialize known hosts support"); goto out; } @@ -289,21 +319,23 @@ static int check_host_key_knownhosts(BDRVSSHState *s, break; case LIBSSH2_KNOWNHOST_CHECK_MISMATCH: ret = -EINVAL; - session_error_report(s, "host key does not match the one in known_hosts (found key %s)", - found->key); + session_error_setg(errp, s, + "host key does not match the one in known_hosts" + " (found key %s)", found->key); goto out; case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND: ret = -EINVAL; - session_error_report(s, "no host key was found in known_hosts"); + session_error_setg(errp, s, "no host key was found in known_hosts"); goto out; case LIBSSH2_KNOWNHOST_CHECK_FAILURE: ret = -EINVAL; - session_error_report(s, "failure matching the host key with known_hosts"); + session_error_setg(errp, s, + "failure matching the host key with known_hosts"); goto out; default: ret = -EINVAL; - session_error_report(s, "unknown error matching the host key with known_hosts (%d)", - r); + session_error_setg(errp, s, "unknown error matching the host key" + " with known_hosts (%d)", r); goto out; } @@ -358,20 +390,20 @@ static int compare_fingerprint(const unsigned char *fingerprint, size_t len, static int check_host_key_hash(BDRVSSHState *s, const char *hash, - int hash_type, size_t fingerprint_len) + int hash_type, size_t fingerprint_len, Error **errp) { const char *fingerprint; fingerprint = libssh2_hostkey_hash(s->session, hash_type); if (!fingerprint) { - session_error_report(s, "failed to read remote host key"); + session_error_setg(errp, s, "failed to read remote host key"); return -EINVAL; } if(compare_fingerprint((unsigned char *) fingerprint, fingerprint_len, hash) != 0) { - error_report("remote host key does not match host_key_check '%s'", - hash); + error_setg(errp, "remote host key does not match host_key_check '%s'", + hash); return -EPERM; } @@ -379,7 +411,7 @@ check_host_key_hash(BDRVSSHState *s, const char *hash, } static int check_host_key(BDRVSSHState *s, const char *host, int port, - const char *host_key_check) + const char *host_key_check, Error **errp) { /* host_key_check=no */ if (strcmp(host_key_check, "no") == 0) { @@ -389,25 +421,25 @@ static int check_host_key(BDRVSSHState *s, const char *host, int port, /* host_key_check=md5:xx:yy:zz:... */ if (strncmp(host_key_check, "md5:", 4) == 0) { return check_host_key_hash(s, &host_key_check[4], - LIBSSH2_HOSTKEY_HASH_MD5, 16); + LIBSSH2_HOSTKEY_HASH_MD5, 16, errp); } /* host_key_check=sha1:xx:yy:zz:... */ if (strncmp(host_key_check, "sha1:", 5) == 0) { return check_host_key_hash(s, &host_key_check[5], - LIBSSH2_HOSTKEY_HASH_SHA1, 20); + LIBSSH2_HOSTKEY_HASH_SHA1, 20, errp); } /* host_key_check=yes */ if (strcmp(host_key_check, "yes") == 0) { - return check_host_key_knownhosts(s, host, port); + return check_host_key_knownhosts(s, host, port, errp); } - error_report("unknown host_key_check setting (%s)", host_key_check); + error_setg(errp, "unknown host_key_check setting (%s)", host_key_check); return -EINVAL; } -static int authenticate(BDRVSSHState *s, const char *user) +static int authenticate(BDRVSSHState *s, const char *user, Error **errp) { int r, ret; const char *userauthlist; @@ -418,7 +450,8 @@ static int authenticate(BDRVSSHState *s, const char *user) userauthlist = libssh2_userauth_list(s->session, user, strlen(user)); if (strstr(userauthlist, "publickey") == NULL) { ret = -EPERM; - error_report("remote server does not support \"publickey\" authentication"); + error_setg(errp, + "remote server does not support \"publickey\" authentication"); goto out; } @@ -426,17 +459,18 @@ static int authenticate(BDRVSSHState *s, const char *user) agent = libssh2_agent_init(s->session); if (!agent) { ret = -EINVAL; - session_error_report(s, "failed to initialize ssh-agent support"); + session_error_setg(errp, s, "failed to initialize ssh-agent support"); goto out; } if (libssh2_agent_connect(agent)) { ret = -ECONNREFUSED; - session_error_report(s, "failed to connect to ssh-agent"); + session_error_setg(errp, s, "failed to connect to ssh-agent"); goto out; } if (libssh2_agent_list_identities(agent)) { ret = -EINVAL; - session_error_report(s, "failed requesting identities from ssh-agent"); + session_error_setg(errp, s, + "failed requesting identities from ssh-agent"); goto out; } @@ -447,7 +481,8 @@ static int authenticate(BDRVSSHState *s, const char *user) } if (r < 0) { ret = -EINVAL; - session_error_report(s, "failed to obtain identity from ssh-agent"); + session_error_setg(errp, s, + "failed to obtain identity from ssh-agent"); goto out; } r = libssh2_agent_userauth(agent, user, identity); @@ -461,8 +496,8 @@ static int authenticate(BDRVSSHState *s, const char *user) } ret = -EPERM; - error_report("failed to authenticate using publickey authentication " - "and the identities held by your ssh-agent"); + error_setg(errp, "failed to authenticate using publickey authentication " + "and the identities held by your ssh-agent"); out: if (agent != NULL) { @@ -476,10 +511,9 @@ static int authenticate(BDRVSSHState *s, const char *user) } static int connect_to_ssh(BDRVSSHState *s, QDict *options, - int ssh_flags, int creat_mode) + int ssh_flags, int creat_mode, Error **errp) { int r, ret; - Error *err = NULL; const char *host, *user, *path, *host_key_check; int port; @@ -498,6 +532,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options, } else { user = g_get_user_name(); if (!user) { + error_setg_errno(errp, errno, "Can't get user name"); ret = -errno; goto err; } @@ -514,11 +549,9 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options, s->hostport = g_strdup_printf("%s:%d", host, port); /* Open the socket and connect. */ - s->sock = inet_connect(s->hostport, &err); - if (err != NULL) { + s->sock = inet_connect(s->hostport, errp); + if (s->sock < 0) { ret = -errno; - qerror_report_err(err); - error_free(err); goto err; } @@ -526,7 +559,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options, s->session = libssh2_session_init(); if (!s->session) { ret = -EINVAL; - session_error_report(s, "failed to initialize libssh2 session"); + session_error_setg(errp, s, "failed to initialize libssh2 session"); goto err; } @@ -537,18 +570,18 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options, r = libssh2_session_handshake(s->session, s->sock); if (r != 0) { ret = -EINVAL; - session_error_report(s, "failed to establish SSH session"); + session_error_setg(errp, s, "failed to establish SSH session"); goto err; } /* Check the remote host's key against known_hosts. */ - ret = check_host_key(s, host, port, host_key_check); + ret = check_host_key(s, host, port, host_key_check, errp); if (ret < 0) { goto err; } /* Authenticate. */ - ret = authenticate(s, user); + ret = authenticate(s, user, errp); if (ret < 0) { goto err; } @@ -556,7 +589,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options, /* Start SFTP. */ s->sftp = libssh2_sftp_init(s->session); if (!s->sftp) { - session_error_report(s, "failed to initialize sftp handle"); + session_error_setg(errp, s, "failed to initialize sftp handle"); ret = -EINVAL; goto err; } @@ -566,14 +599,14 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options, path, ssh_flags, creat_mode); s->sftp_handle = libssh2_sftp_open(s->sftp, path, ssh_flags, creat_mode); if (!s->sftp_handle) { - session_error_report(s, "failed to open remote file '%s'", path); + session_error_setg(errp, s, "failed to open remote file '%s'", path); ret = -EINVAL; goto err; } r = libssh2_sftp_fstat(s->sftp_handle, &s->attrs); if (r < 0) { - sftp_error_report(s, "failed to read file attributes"); + sftp_error_setg(errp, s, "failed to read file attributes"); return -EINVAL; } @@ -623,7 +656,7 @@ static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags, } /* Start up SSH. */ - ret = connect_to_ssh(s, options, ssh_flags, 0); + ret = connect_to_ssh(s, options, ssh_flags, 0, errp); if (ret < 0) { goto err; } @@ -655,7 +688,6 @@ static int ssh_create(const char *filename, QEMUOptionParameter *options, Error **errp) { int r, ret; - Error *local_err = NULL; int64_t total_size = 0; QDict *uri_options = NULL; BDRVSSHState s; @@ -674,17 +706,16 @@ static int ssh_create(const char *filename, QEMUOptionParameter *options, DPRINTF("total_size=%" PRIi64, total_size); uri_options = qdict_new(); - r = parse_uri(filename, uri_options, &local_err); + r = parse_uri(filename, uri_options, errp); if (r < 0) { - qerror_report_err(local_err); - error_free(local_err); ret = r; goto out; } r = connect_to_ssh(&s, uri_options, LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE| - LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, 0644); + LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, + 0644, errp); if (r < 0) { ret = r; goto out; @@ -694,7 +725,7 @@ static int ssh_create(const char *filename, QEMUOptionParameter *options, libssh2_sftp_seek64(s.sftp_handle, total_size-1); r2 = libssh2_sftp_write(s.sftp_handle, c, 1); if (r2 < 0) { - sftp_error_report(&s, "truncate failed"); + sftp_error_setg(errp, &s, "truncate failed"); ret = -EINVAL; goto out; } diff --git a/block/stream.c b/block/stream.c index dd0b4ac3d2..91d18a2db7 100644 --- a/block/stream.c +++ b/block/stream.c @@ -60,7 +60,7 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base, /* Must assign before bdrv_delete() to prevent traversing dangling pointer * while we delete backing image instances. */ - top->backing_hd = base; + bdrv_set_backing_hd(top, base); while (intermediate) { BlockDriverState *unused; @@ -72,7 +72,7 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base, unused = intermediate; intermediate = intermediate->backing_hd; - unused->backing_hd = NULL; + bdrv_set_backing_hd(unused, NULL); bdrv_unref(unused); } diff --git a/block/vvfat.c b/block/vvfat.c index c3af7ff4c5..8f5114bd16 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -831,7 +831,8 @@ static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num) } static int init_directories(BDRVVVFATState* s, - const char *dirname, int heads, int secs) + const char *dirname, int heads, int secs, + Error **errp) { bootsector_t* bootsector; mapping_t* mapping; @@ -892,8 +893,8 @@ static int init_directories(BDRVVVFATState* s, if (mapping->mode & MODE_DIRECTORY) { mapping->begin = cluster; if(read_directory(s, i)) { - fprintf(stderr, "Could not read directory %s\n", - mapping->path); + error_setg(errp, "Could not read directory %s", + mapping->path); return -1; } mapping = array_get(&(s->mapping), i); @@ -919,9 +920,10 @@ static int init_directories(BDRVVVFATState* s, cluster = mapping->end; if(cluster > s->cluster_count) { - fprintf(stderr,"Directory does not fit in FAT%d (capacity %.2f MB)\n", - s->fat_type, s->sector_count / 2000.0); - return -EINVAL; + error_setg(errp, + "Directory does not fit in FAT%d (capacity %.2f MB)", + s->fat_type, s->sector_count / 2000.0); + return -1; } /* fix fat for entry */ @@ -979,7 +981,7 @@ static int init_directories(BDRVVVFATState* s, static BDRVVVFATState *vvv = NULL; #endif -static int enable_write_target(BDRVVVFATState *s); +static int enable_write_target(BDRVVVFATState *s, Error **errp); static int is_consistent(BDRVVVFATState *s); static void vvfat_rebind(BlockDriverState *bs) @@ -1160,7 +1162,7 @@ DLOG(if (stderr == NULL) { s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1); if (qemu_opt_get_bool(opts, "rw", false)) { - ret = enable_write_target(s); + ret = enable_write_target(s, errp); if (ret < 0) { goto fail; } @@ -1169,7 +1171,7 @@ DLOG(if (stderr == NULL) { bs->total_sectors = cyls * heads * secs; - if (init_directories(s, dirname, heads, secs)) { + if (init_directories(s, dirname, heads, secs, errp)) { ret = -EIO; goto fail; } @@ -2904,11 +2906,10 @@ static BlockDriver vvfat_write_target = { .bdrv_close = write_target_close, }; -static int enable_write_target(BDRVVVFATState *s) +static int enable_write_target(BDRVVVFATState *s, Error **errp) { BlockDriver *bdrv_qcow; QEMUOptionParameter *options; - Error *local_err = NULL; int ret; int size = sector2cluster(s, s->sector_count); s->used_clusters = calloc(size, 1); @@ -2918,6 +2919,7 @@ static int enable_write_target(BDRVVVFATState *s) s->qcow_filename = g_malloc(1024); ret = get_tmp_filename(s->qcow_filename, 1024); if (ret < 0) { + error_setg_errno(errp, -ret, "can't create temporary file"); goto err; } @@ -2926,20 +2928,16 @@ static int enable_write_target(BDRVVVFATState *s) set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512); set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:"); - ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, &local_err); + ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, errp); if (ret < 0) { - qerror_report_err(local_err); - error_free(local_err); goto err; } s->qcow = NULL; ret = bdrv_open(&s->qcow, s->qcow_filename, NULL, NULL, - BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow, - &local_err); + BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, + bdrv_qcow, errp); if (ret < 0) { - qerror_report_err(local_err); - error_free(local_err); goto err; } @@ -2947,7 +2945,7 @@ static int enable_write_target(BDRVVVFATState *s) unlink(s->qcow_filename); #endif - s->bs->backing_hd = bdrv_new("", &error_abort); + bdrv_set_backing_hd(s->bs, bdrv_new("", &error_abort)); s->bs->backing_hd->drv = &vvfat_write_target; s->bs->backing_hd->opaque = g_malloc(sizeof(void*)); *(void**)s->bs->backing_hd->opaque = s; |