aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-10-28 12:06:41 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-10-28 12:06:41 +0100
commit9879b75873cacc88cdee490f6ab481e8ce766c69 (patch)
treec5a575eed03a36c2824d8c061132e2adb6690497 /block
parent86398328467d78c84d8e3341f098f4697148a665 (diff)
parentb74fc7f78e0dd54fbae67d46552cebf81b59ae9f (diff)
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches # gpg: Signature made Thu 27 Oct 2016 18:15:47 BST # gpg: using RSA key 0x7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: (23 commits) iotests: Add test for NBD's blockdev-add interface iotests: Add assert_json_filename_equal() method socket_scm_helper: Accept fd directly iotests.py: Allow concurrent qemu instances iotests.py: Add qemu_nbd function qapi: Allow blockdev-add for NBD block/nbd: Use SocketAddress options block/nbd: Accept SocketAddress block/nbd: Add nbd_has_filename_options_conflict() block/nbd: Use qdict_put() block/nbd: Default port in nbd_refresh_filename() block/nbd: Reject port parameter without host block/nbd: Drop trailing "." in error messages qemu-iotests: Fix typo for NFS with IMGOPTSSYNTAX block: Remove bdrv_aio_ioctl() raw: Implement .bdrv_co_ioctl instead of .bdrv_aio_ioctl block: Introduce .bdrv_co_ioctl() driver callback block: Remove bdrv_ioctl() raw-posix: Don't use bdrv_ioctl() block: Use blk_co_ioctl() for all BB level ioctls ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block')
-rw-r--r--block/block-backend.c94
-rw-r--r--block/io.c111
-rw-r--r--block/nbd.c234
-rw-r--r--block/raw-posix.c16
-rw-r--r--block/raw_bsd.c9
-rw-r--r--block/trace-events1
6 files changed, 244 insertions, 221 deletions
diff --git a/block/block-backend.c b/block/block-backend.c
index 1a724a8d89..c53ca30000 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1099,26 +1099,36 @@ BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
blk_aio_write_entry, flags, cb, opaque);
}
+static void blk_aio_flush_entry(void *opaque)
+{
+ BlkAioEmAIOCB *acb = opaque;
+ BlkRwCo *rwco = &acb->rwco;
+
+ rwco->ret = blk_co_flush(rwco->blk);
+ blk_aio_complete(acb);
+}
+
BlockAIOCB *blk_aio_flush(BlockBackend *blk,
BlockCompletionFunc *cb, void *opaque)
{
- if (!blk_is_available(blk)) {
- return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM);
- }
+ return blk_aio_prwv(blk, 0, 0, NULL, blk_aio_flush_entry, 0, cb, opaque);
+}
+
+static void blk_aio_pdiscard_entry(void *opaque)
+{
+ BlkAioEmAIOCB *acb = opaque;
+ BlkRwCo *rwco = &acb->rwco;
- return bdrv_aio_flush(blk_bs(blk), cb, opaque);
+ rwco->ret = blk_co_pdiscard(rwco->blk, rwco->offset, acb->bytes);
+ blk_aio_complete(acb);
}
BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk,
int64_t offset, int count,
BlockCompletionFunc *cb, void *opaque)
{
- int ret = blk_check_byte_request(blk, offset, count);
- if (ret < 0) {
- return blk_abort_aio_request(blk, cb, opaque, ret);
- }
-
- return bdrv_aio_pdiscard(blk_bs(blk), offset, count, cb, opaque);
+ return blk_aio_prwv(blk, offset, count, NULL, blk_aio_pdiscard_entry, 0,
+ cb, opaque);
}
void blk_aio_cancel(BlockAIOCB *acb)
@@ -1131,23 +1141,50 @@ void blk_aio_cancel_async(BlockAIOCB *acb)
bdrv_aio_cancel_async(acb);
}
-int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
+int blk_co_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
{
if (!blk_is_available(blk)) {
return -ENOMEDIUM;
}
- return bdrv_ioctl(blk_bs(blk), req, buf);
+ return bdrv_co_ioctl(blk_bs(blk), req, buf);
+}
+
+static void blk_ioctl_entry(void *opaque)
+{
+ BlkRwCo *rwco = opaque;
+ rwco->ret = blk_co_ioctl(rwco->blk, rwco->offset,
+ rwco->qiov->iov[0].iov_base);
+}
+
+int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
+{
+ return blk_prw(blk, req, buf, 0, blk_ioctl_entry, 0);
+}
+
+static void blk_aio_ioctl_entry(void *opaque)
+{
+ BlkAioEmAIOCB *acb = opaque;
+ BlkRwCo *rwco = &acb->rwco;
+
+ rwco->ret = blk_co_ioctl(rwco->blk, rwco->offset,
+ rwco->qiov->iov[0].iov_base);
+ blk_aio_complete(acb);
}
BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
BlockCompletionFunc *cb, void *opaque)
{
- if (!blk_is_available(blk)) {
- return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM);
- }
+ QEMUIOVector qiov;
+ struct iovec iov;
- return bdrv_aio_ioctl(blk_bs(blk), req, buf, cb, opaque);
+ iov = (struct iovec) {
+ .iov_base = buf,
+ .iov_len = 0,
+ };
+ qemu_iovec_init_external(&qiov, &iov, 1);
+
+ return blk_aio_prwv(blk, req, 0, &qiov, blk_aio_ioctl_entry, 0, cb, opaque);
}
int blk_co_pdiscard(BlockBackend *blk, int64_t offset, int count)
@@ -1169,13 +1206,15 @@ int blk_co_flush(BlockBackend *blk)
return bdrv_co_flush(blk_bs(blk));
}
-int blk_flush(BlockBackend *blk)
+static void blk_flush_entry(void *opaque)
{
- if (!blk_is_available(blk)) {
- return -ENOMEDIUM;
- }
+ BlkRwCo *rwco = opaque;
+ rwco->ret = blk_co_flush(rwco->blk);
+}
- return bdrv_flush(blk_bs(blk));
+int blk_flush(BlockBackend *blk)
+{
+ return blk_prw(blk, 0, NULL, 0, blk_flush_entry, 0);
}
void blk_drain(BlockBackend *blk)
@@ -1555,14 +1594,15 @@ int blk_truncate(BlockBackend *blk, int64_t offset)
return bdrv_truncate(blk_bs(blk), offset);
}
-int blk_pdiscard(BlockBackend *blk, int64_t offset, int count)
+static void blk_pdiscard_entry(void *opaque)
{
- int ret = blk_check_byte_request(blk, offset, count);
- if (ret < 0) {
- return ret;
- }
+ BlkRwCo *rwco = opaque;
+ rwco->ret = blk_co_pdiscard(rwco->blk, rwco->offset, rwco->qiov->size);
+}
- return bdrv_pdiscard(blk_bs(blk), offset, count);
+int blk_pdiscard(BlockBackend *blk, int64_t offset, int count)
+{
+ return blk_prw(blk, offset, NULL, count, blk_pdiscard_entry, 0);
}
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
diff --git a/block/io.c b/block/io.c
index b136c89ae0..79cbbdf769 100644
--- a/block/io.c
+++ b/block/io.c
@@ -2196,35 +2196,6 @@ BlockAIOCB *bdrv_aio_flush(BlockDriverState *bs,
return &acb->common;
}
-static void coroutine_fn bdrv_aio_pdiscard_co_entry(void *opaque)
-{
- BlockAIOCBCoroutine *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
-
- acb->req.error = bdrv_co_pdiscard(bs, acb->req.offset, acb->req.bytes);
- bdrv_co_complete(acb);
-}
-
-BlockAIOCB *bdrv_aio_pdiscard(BlockDriverState *bs, int64_t offset, int count,
- BlockCompletionFunc *cb, void *opaque)
-{
- Coroutine *co;
- BlockAIOCBCoroutine *acb;
-
- trace_bdrv_aio_pdiscard(bs, offset, count, opaque);
-
- acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque);
- acb->need_bh = true;
- acb->req.error = -EINPROGRESS;
- acb->req.offset = offset;
- acb->req.bytes = count;
- co = qemu_coroutine_create(bdrv_aio_pdiscard_co_entry, acb);
- qemu_coroutine_enter(co);
-
- bdrv_co_maybe_schedule_bh(acb);
- return &acb->common;
-}
-
void *qemu_aio_get(const AIOCBInfo *aiocb_info, BlockDriverState *bs,
BlockCompletionFunc *cb, void *opaque)
{
@@ -2521,7 +2492,7 @@ int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int count)
return rwco.ret;
}
-static int bdrv_co_do_ioctl(BlockDriverState *bs, int req, void *buf)
+int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf)
{
BlockDriver *drv = bs->drv;
BdrvTrackedRequest tracked_req;
@@ -2531,86 +2502,26 @@ static int bdrv_co_do_ioctl(BlockDriverState *bs, int req, void *buf)
BlockAIOCB *acb;
tracked_request_begin(&tracked_req, bs, 0, 0, BDRV_TRACKED_IOCTL);
- if (!drv || !drv->bdrv_aio_ioctl) {
+ if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
co.ret = -ENOTSUP;
goto out;
}
- acb = drv->bdrv_aio_ioctl(bs, req, buf, bdrv_co_io_em_complete, &co);
- if (!acb) {
- co.ret = -ENOTSUP;
- goto out;
+ if (drv->bdrv_co_ioctl) {
+ co.ret = drv->bdrv_co_ioctl(bs, req, buf);
+ } else {
+ acb = drv->bdrv_aio_ioctl(bs, req, buf, bdrv_co_io_em_complete, &co);
+ if (!acb) {
+ co.ret = -ENOTSUP;
+ goto out;
+ }
+ qemu_coroutine_yield();
}
- qemu_coroutine_yield();
out:
tracked_request_end(&tracked_req);
return co.ret;
}
-typedef struct {
- BlockDriverState *bs;
- int req;
- void *buf;
- int ret;
-} BdrvIoctlCoData;
-
-static void coroutine_fn bdrv_co_ioctl_entry(void *opaque)
-{
- BdrvIoctlCoData *data = opaque;
- data->ret = bdrv_co_do_ioctl(data->bs, data->req, data->buf);
-}
-
-/* needed for generic scsi interface */
-int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
-{
- BdrvIoctlCoData data = {
- .bs = bs,
- .req = req,
- .buf = buf,
- .ret = -EINPROGRESS,
- };
-
- if (qemu_in_coroutine()) {
- /* Fast-path if already in coroutine context */
- bdrv_co_ioctl_entry(&data);
- } else {
- Coroutine *co = qemu_coroutine_create(bdrv_co_ioctl_entry, &data);
-
- qemu_coroutine_enter(co);
- while (data.ret == -EINPROGRESS) {
- aio_poll(bdrv_get_aio_context(bs), true);
- }
- }
- return data.ret;
-}
-
-static void coroutine_fn bdrv_co_aio_ioctl_entry(void *opaque)
-{
- BlockAIOCBCoroutine *acb = opaque;
- acb->req.error = bdrv_co_do_ioctl(acb->common.bs,
- acb->req.req, acb->req.buf);
- bdrv_co_complete(acb);
-}
-
-BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
- unsigned long int req, void *buf,
- BlockCompletionFunc *cb, void *opaque)
-{
- BlockAIOCBCoroutine *acb = qemu_aio_get(&bdrv_em_co_aiocb_info,
- bs, cb, opaque);
- Coroutine *co;
-
- acb->need_bh = true;
- acb->req.error = -EINPROGRESS;
- acb->req.req = req;
- acb->req.buf = buf;
- co = qemu_coroutine_create(bdrv_co_aio_ioctl_entry, acb);
- qemu_coroutine_enter(co);
-
- bdrv_co_maybe_schedule_bh(acb);
- return &acb->common;
-}
-
void *qemu_blockalign(BlockDriverState *bs, size_t size)
{
return qemu_memalign(bdrv_opt_mem_align(bs), size);
diff --git a/block/nbd.c b/block/nbd.c
index 6bc06d6198..8ef143870f 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -32,6 +32,9 @@
#include "qemu/uri.h"
#include "block/block_int.h"
#include "qemu/module.h"
+#include "qapi-visit.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qapi/qobject-output-visitor.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qint.h"
@@ -44,7 +47,8 @@ typedef struct BDRVNBDState {
NbdClientSession client;
/* For nbd_refresh_filename() */
- char *path, *host, *port, *export, *tlscredsid;
+ SocketAddress *saddr;
+ char *export, *tlscredsid;
} BDRVNBDState;
static int nbd_parse_uri(const char *filename, QDict *options)
@@ -90,9 +94,13 @@ static int nbd_parse_uri(const char *filename, QDict *options)
ret = -EINVAL;
goto out;
}
- qdict_put(options, "path", qstring_from_str(qp->p[0].value));
+ qdict_put(options, "server.type", qstring_from_str("unix"));
+ qdict_put(options, "server.data.path",
+ qstring_from_str(qp->p[0].value));
} else {
QString *host;
+ char *port_str;
+
/* nbd[+tcp]://host[:port]/export */
if (!uri->server) {
ret = -EINVAL;
@@ -107,12 +115,12 @@ static int nbd_parse_uri(const char *filename, QDict *options)
host = qstring_from_str(uri->server);
}
- qdict_put(options, "host", host);
- if (uri->port) {
- char* port_str = g_strdup_printf("%d", uri->port);
- qdict_put(options, "port", qstring_from_str(port_str));
- g_free(port_str);
- }
+ qdict_put(options, "server.type", qstring_from_str("inet"));
+ qdict_put(options, "server.data.host", host);
+
+ port_str = g_strdup_printf("%d", uri->port ?: NBD_DEFAULT_PORT);
+ qdict_put(options, "server.data.port", qstring_from_str(port_str));
+ g_free(port_str);
}
out:
@@ -123,6 +131,26 @@ out:
return ret;
}
+static bool nbd_has_filename_options_conflict(QDict *options, Error **errp)
+{
+ const QDictEntry *e;
+
+ for (e = qdict_first(options); e; e = qdict_next(options, e)) {
+ if (!strcmp(e->key, "host") ||
+ !strcmp(e->key, "port") ||
+ !strcmp(e->key, "path") ||
+ !strcmp(e->key, "export") ||
+ strstart(e->key, "server.", NULL))
+ {
+ error_setg(errp, "Option '%s' cannot be used with a file name",
+ e->key);
+ return true;
+ }
+ }
+
+ return false;
+}
+
static void nbd_parse_filename(const char *filename, QDict *options,
Error **errp)
{
@@ -131,12 +159,7 @@ static void nbd_parse_filename(const char *filename, QDict *options,
const char *host_spec;
const char *unixpath;
- if (qdict_haskey(options, "host")
- || qdict_haskey(options, "port")
- || qdict_haskey(options, "path"))
- {
- error_setg(errp, "host/port/path and a file name may not be specified "
- "at the same time");
+ if (nbd_has_filename_options_conflict(options, errp)) {
return;
}
@@ -173,7 +196,8 @@ static void nbd_parse_filename(const char *filename, QDict *options,
/* are we a UNIX or TCP socket? */
if (strstart(host_spec, "unix:", &unixpath)) {
- qdict_put(options, "path", qstring_from_str(unixpath));
+ qdict_put(options, "server.type", qstring_from_str("unix"));
+ qdict_put(options, "server.data.path", qstring_from_str(unixpath));
} else {
InetSocketAddress *addr = NULL;
@@ -182,8 +206,9 @@ static void nbd_parse_filename(const char *filename, QDict *options,
goto out;
}
- qdict_put(options, "host", qstring_from_str(addr->host));
- qdict_put(options, "port", qstring_from_str(addr->port));
+ qdict_put(options, "server.type", qstring_from_str("inet"));
+ qdict_put(options, "server.data.host", qstring_from_str(addr->host));
+ qdict_put(options, "server.data.port", qstring_from_str(addr->port));
qapi_free_InetSocketAddress(addr);
}
@@ -191,47 +216,81 @@ out:
g_free(file);
}
-static SocketAddress *nbd_config(BDRVNBDState *s, QemuOpts *opts, Error **errp)
+static bool nbd_process_legacy_socket_options(QDict *output_options,
+ QemuOpts *legacy_opts,
+ Error **errp)
{
- SocketAddress *saddr;
+ const char *path = qemu_opt_get(legacy_opts, "path");
+ const char *host = qemu_opt_get(legacy_opts, "host");
+ const char *port = qemu_opt_get(legacy_opts, "port");
+ const QDictEntry *e;
- s->path = g_strdup(qemu_opt_get(opts, "path"));
- s->host = g_strdup(qemu_opt_get(opts, "host"));
+ if (!path && !host && !port) {
+ return true;
+ }
- if (!s->path == !s->host) {
- if (s->path) {
- error_setg(errp, "path and host may not be used at the same time.");
- } else {
- error_setg(errp, "one of path and host must be specified.");
+ for (e = qdict_first(output_options); e; e = qdict_next(output_options, e))
+ {
+ if (strstart(e->key, "server.", NULL)) {
+ error_setg(errp, "Cannot use 'server' and path/host/port at the "
+ "same time");
+ return false;
}
- return NULL;
}
- saddr = g_new0(SocketAddress, 1);
+ if (path && host) {
+ error_setg(errp, "path and host may not be used at the same time");
+ return false;
+ } else if (path) {
+ if (port) {
+ error_setg(errp, "port may not be used without host");
+ return false;
+ }
- if (s->path) {
- UnixSocketAddress *q_unix;
- saddr->type = SOCKET_ADDRESS_KIND_UNIX;
- q_unix = saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
- q_unix->path = g_strdup(s->path);
- } else {
- InetSocketAddress *inet;
+ qdict_put(output_options, "server.type", qstring_from_str("unix"));
+ qdict_put(output_options, "server.data.path", qstring_from_str(path));
+ } else if (host) {
+ qdict_put(output_options, "server.type", qstring_from_str("inet"));
+ qdict_put(output_options, "server.data.host", qstring_from_str(host));
+ qdict_put(output_options, "server.data.port",
+ qstring_from_str(port ?: stringify(NBD_DEFAULT_PORT)));
+ }
- s->port = g_strdup(qemu_opt_get(opts, "port"));
+ return true;
+}
- saddr->type = SOCKET_ADDRESS_KIND_INET;
- inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
- inet->host = g_strdup(s->host);
- inet->port = g_strdup(s->port);
- if (!inet->port) {
- inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
- }
+static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, Error **errp)
+{
+ SocketAddress *saddr = NULL;
+ QDict *addr = NULL;
+ QObject *crumpled_addr = NULL;
+ Visitor *iv = NULL;
+ Error *local_err = NULL;
+
+ qdict_extract_subqdict(options, &addr, "server.");
+ if (!qdict_size(addr)) {
+ error_setg(errp, "NBD server address missing");
+ goto done;
}
- s->client.is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
+ crumpled_addr = qdict_crumple(addr, errp);
+ if (!crumpled_addr) {
+ goto done;
+ }
- s->export = g_strdup(qemu_opt_get(opts, "export"));
+ iv = qobject_input_visitor_new(crumpled_addr, true);
+ visit_type_SocketAddress(iv, NULL, &saddr, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ goto done;
+ }
+
+ s->client.is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
+done:
+ QDECREF(addr);
+ qobject_decref(crumpled_addr);
+ visit_free(iv);
return saddr;
}
@@ -332,7 +391,6 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
QemuOpts *opts = NULL;
Error *local_err = NULL;
QIOChannelSocket *sioc = NULL;
- SocketAddress *saddr = NULL;
QCryptoTLSCreds *tlscreds = NULL;
const char *hostname = NULL;
int ret = -EINVAL;
@@ -344,12 +402,19 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
goto error;
}
+ /* Translate @host, @port, and @path to a SocketAddress */
+ if (!nbd_process_legacy_socket_options(options, opts, errp)) {
+ goto error;
+ }
+
/* Pop the config into our state object. Exit if invalid. */
- saddr = nbd_config(s, opts, errp);
- if (!saddr) {
+ s->saddr = nbd_config(s, options, errp);
+ if (!s->saddr) {
goto error;
}
+ s->export = g_strdup(qemu_opt_get(opts, "export"));
+
s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
if (s->tlscredsid) {
tlscreds = nbd_get_tls_creds(s->tlscredsid, errp);
@@ -357,17 +422,17 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
goto error;
}
- if (saddr->type != SOCKET_ADDRESS_KIND_INET) {
+ if (s->saddr->type != SOCKET_ADDRESS_KIND_INET) {
error_setg(errp, "TLS only supported over IP sockets");
goto error;
}
- hostname = saddr->u.inet.data->host;
+ hostname = s->saddr->u.inet.data->host;
}
/* establish TCP connection, return error if it fails
* TODO: Configurable retry-until-timeout behaviour.
*/
- sioc = nbd_establish_connection(saddr, errp);
+ sioc = nbd_establish_connection(s->saddr, errp);
if (!sioc) {
ret = -ECONNREFUSED;
goto error;
@@ -384,13 +449,10 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
object_unref(OBJECT(tlscreds));
}
if (ret < 0) {
- g_free(s->path);
- g_free(s->host);
- g_free(s->port);
+ qapi_free_SocketAddress(s->saddr);
g_free(s->export);
g_free(s->tlscredsid);
}
- qapi_free_SocketAddress(saddr);
qemu_opts_del(opts);
return ret;
}
@@ -412,9 +474,7 @@ static void nbd_close(BlockDriverState *bs)
nbd_client_close(bs);
- g_free(s->path);
- g_free(s->host);
- g_free(s->port);
+ qapi_free_SocketAddress(s->saddr);
g_free(s->export);
g_free(s->tlscredsid);
}
@@ -441,45 +501,51 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
{
BDRVNBDState *s = bs->opaque;
QDict *opts = qdict_new();
+ QObject *saddr_qdict;
+ Visitor *ov;
+ const char *host = NULL, *port = NULL, *path = NULL;
+
+ if (s->saddr->type == SOCKET_ADDRESS_KIND_INET) {
+ const InetSocketAddress *inet = s->saddr->u.inet.data;
+ if (!inet->has_ipv4 && !inet->has_ipv6 && !inet->has_to) {
+ host = inet->host;
+ port = inet->port;
+ }
+ } else if (s->saddr->type == SOCKET_ADDRESS_KIND_UNIX) {
+ path = s->saddr->u.q_unix.data->path;
+ }
- qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("nbd")));
+ qdict_put(opts, "driver", qstring_from_str("nbd"));
- if (s->path && s->export) {
+ if (path && s->export) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "nbd+unix:///%s?socket=%s", s->export, s->path);
- } else if (s->path && !s->export) {
+ "nbd+unix:///%s?socket=%s", s->export, path);
+ } else if (path && !s->export) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "nbd+unix://?socket=%s", s->path);
- } else if (!s->path && s->export && s->port) {
+ "nbd+unix://?socket=%s", path);
+ } else if (host && s->export) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "nbd://%s:%s/%s", s->host, s->port, s->export);
- } else if (!s->path && s->export && !s->port) {
+ "nbd://%s:%s/%s", host, port, s->export);
+ } else if (host && !s->export) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "nbd://%s/%s", s->host, s->export);
- } else if (!s->path && !s->export && s->port) {
- snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "nbd://%s:%s", s->host, s->port);
- } else if (!s->path && !s->export && !s->port) {
- snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "nbd://%s", s->host);
+ "nbd://%s:%s", host, port);
}
- if (s->path) {
- qdict_put_obj(opts, "path", QOBJECT(qstring_from_str(s->path)));
- } else if (s->port) {
- qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(s->host)));
- qdict_put_obj(opts, "port", QOBJECT(qstring_from_str(s->port)));
- } else {
- qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(s->host)));
- }
+ ov = qobject_output_visitor_new(&saddr_qdict);
+ visit_type_SocketAddress(ov, NULL, &s->saddr, &error_abort);
+ visit_complete(ov, &saddr_qdict);
+ assert(qobject_type(saddr_qdict) == QTYPE_QDICT);
+
+ qdict_put_obj(opts, "server", saddr_qdict);
+
if (s->export) {
- qdict_put_obj(opts, "export", QOBJECT(qstring_from_str(s->export)));
+ qdict_put(opts, "export", qstring_from_str(s->export));
}
if (s->tlscredsid) {
- qdict_put_obj(opts, "tls-creds",
- QOBJECT(qstring_from_str(s->tlscredsid)));
+ qdict_put(opts, "tls-creds", qstring_from_str(s->tlscredsid));
}
+ qdict_flatten(opts);
bs->full_open_options = opts;
}
diff --git a/block/raw-posix.c b/block/raw-posix.c
index f481e57f78..247e47b88f 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -2069,13 +2069,23 @@ static bool hdev_is_sg(BlockDriverState *bs)
#if defined(__linux__)
+ BDRVRawState *s = bs->opaque;
struct stat st;
struct sg_scsi_id scsiid;
int sg_version;
+ int ret;
+
+ if (stat(bs->filename, &st) < 0 || !S_ISCHR(st.st_mode)) {
+ return false;
+ }
- if (stat(bs->filename, &st) >= 0 && S_ISCHR(st.st_mode) &&
- !bdrv_ioctl(bs, SG_GET_VERSION_NUM, &sg_version) &&
- !bdrv_ioctl(bs, SG_GET_SCSI_ID, &scsiid)) {
+ ret = ioctl(s->fd, SG_GET_VERSION_NUM, &sg_version);
+ if (ret < 0) {
+ return false;
+ }
+
+ ret = ioctl(s->fd, SG_GET_SCSI_ID, &scsiid);
+ if (ret >= 0) {
DPRINTF("SG device found: type=%d, version=%d\n",
scsiid.scsi_type, sg_version);
return true;
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 588d4080f9..fc16ec1f74 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -176,12 +176,9 @@ static void raw_lock_medium(BlockDriverState *bs, bool locked)
bdrv_lock_medium(bs->file->bs, locked);
}
-static BlockAIOCB *raw_aio_ioctl(BlockDriverState *bs,
- unsigned long int req, void *buf,
- BlockCompletionFunc *cb,
- void *opaque)
+static int raw_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
{
- return bdrv_aio_ioctl(bs->file->bs, req, buf, cb, opaque);
+ return bdrv_co_ioctl(bs->file->bs, req, buf);
}
static int raw_has_zero_init(BlockDriverState *bs)
@@ -261,7 +258,7 @@ BlockDriver bdrv_raw = {
.bdrv_media_changed = &raw_media_changed,
.bdrv_eject = &raw_eject,
.bdrv_lock_medium = &raw_lock_medium,
- .bdrv_aio_ioctl = &raw_aio_ioctl,
+ .bdrv_co_ioctl = &raw_co_ioctl,
.create_opts = &raw_create_opts,
.bdrv_has_zero_init = &raw_has_zero_init
};
diff --git a/block/trace-events b/block/trace-events
index 05fa13c891..aff8a9674d 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -9,7 +9,6 @@ blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags
blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags %x"
# block/io.c
-bdrv_aio_pdiscard(void *bs, int64_t offset, int count, void *opaque) "bs %p offset %"PRId64" count %d opaque %p"
bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"