diff --git a/block.c b/block.c index ff44e76c87..b90dbe036c 100644 --- a/block.c +++ b/block.c @@ -2140,13 +2140,13 @@ void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv, const char *action_str; switch (action) { - case BDRV_ACTION_REPORT: + case BLOCK_ERROR_ACTION_REPORT: action_str = "report"; break; - case BDRV_ACTION_IGNORE: + case BLOCK_ERROR_ACTION_IGNORE: action_str = "ignore"; break; - case BDRV_ACTION_STOP: + case BLOCK_ERROR_ACTION_STOP: action_str = "stop"; break; default: @@ -3606,13 +3606,14 @@ BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int e switch (on_err) { case BLOCKDEV_ON_ERROR_ENOSPC: - return (error == ENOSPC) ? BDRV_ACTION_STOP : BDRV_ACTION_REPORT; + return (error == ENOSPC) ? + BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT; case BLOCKDEV_ON_ERROR_STOP: - return BDRV_ACTION_STOP; + return BLOCK_ERROR_ACTION_STOP; case BLOCKDEV_ON_ERROR_REPORT: - return BDRV_ACTION_REPORT; + return BLOCK_ERROR_ACTION_REPORT; case BLOCKDEV_ON_ERROR_IGNORE: - return BDRV_ACTION_IGNORE; + return BLOCK_ERROR_ACTION_IGNORE; default: abort(); } @@ -3627,7 +3628,7 @@ void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action, { assert(error >= 0); - if (action == BDRV_ACTION_STOP) { + if (action == BLOCK_ERROR_ACTION_STOP) { /* First set the iostatus, so that "info block" returns an iostatus * that matches the events raised so far (an additional error iostatus * is fine, but not a lost one). diff --git a/block/backup.c b/block/backup.c index 15a2e55e8e..7978ae2e50 100644 --- a/block/backup.c +++ b/block/backup.c @@ -325,7 +325,7 @@ static void coroutine_fn backup_run(void *opaque) /* Depending on error action, fail now or retry cluster */ BlockErrorAction action = backup_error_action(job, error_is_read, -ret); - if (action == BDRV_ACTION_REPORT) { + if (action == BLOCK_ERROR_ACTION_REPORT) { break; } else { start--; diff --git a/block/mirror.c b/block/mirror.c index 94c8661777..df58aea730 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -118,7 +118,7 @@ static void mirror_write_complete(void *opaque, int ret) bdrv_set_dirty(source, op->sector_num, op->nb_sectors); action = mirror_error_action(s, false, -ret); - if (action == BDRV_ACTION_REPORT && s->ret >= 0) { + if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) { s->ret = ret; } } @@ -135,7 +135,7 @@ static void mirror_read_complete(void *opaque, int ret) bdrv_set_dirty(source, op->sector_num, op->nb_sectors); action = mirror_error_action(s, true, -ret); - if (action == BDRV_ACTION_REPORT && s->ret >= 0) { + if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) { s->ret = ret; } @@ -415,7 +415,8 @@ static void coroutine_fn mirror_run(void *opaque) trace_mirror_before_flush(s); ret = bdrv_flush(s->target); if (ret < 0) { - if (mirror_error_action(s, false, -ret) == BDRV_ACTION_REPORT) { + if (mirror_error_action(s, false, -ret) == + BLOCK_ERROR_ACTION_REPORT) { goto immediate_exit; } } else { diff --git a/block/stream.c b/block/stream.c index 91d18a2db7..043340994d 100644 --- a/block/stream.c +++ b/block/stream.c @@ -159,14 +159,14 @@ wait: BlockErrorAction action = block_job_error_action(&s->common, s->common.bs, s->on_error, true, -ret); - if (action == BDRV_ACTION_STOP) { + if (action == BLOCK_ERROR_ACTION_STOP) { n = 0; continue; } if (error == 0) { error = ret; } - if (action == BDRV_ACTION_REPORT) { + if (action == BLOCK_ERROR_ACTION_REPORT) { break; } } diff --git a/blockjob.c b/blockjob.c index 7d84ca1d6c..bc63d42dc8 100644 --- a/blockjob.c +++ b/blockjob.c @@ -262,22 +262,23 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs, switch (on_err) { case BLOCKDEV_ON_ERROR_ENOSPC: - action = (error == ENOSPC) ? BDRV_ACTION_STOP : BDRV_ACTION_REPORT; + action = (error == ENOSPC) ? + BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT; break; case BLOCKDEV_ON_ERROR_STOP: - action = BDRV_ACTION_STOP; + action = BLOCK_ERROR_ACTION_STOP; break; case BLOCKDEV_ON_ERROR_REPORT: - action = BDRV_ACTION_REPORT; + action = BLOCK_ERROR_ACTION_REPORT; break; case BLOCKDEV_ON_ERROR_IGNORE: - action = BDRV_ACTION_IGNORE; + action = BLOCK_ERROR_ACTION_IGNORE; break; default: abort(); } bdrv_emit_qmp_error_event(job->bs, QEVENT_BLOCK_JOB_ERROR, action, is_read); - if (action == BDRV_ACTION_STOP) { + if (action == BLOCK_ERROR_ACTION_STOP) { block_job_pause(job); block_job_iostatus_set_err(job, error); if (bs != job->bs) { diff --git a/hmp.c b/hmp.c index 41006f5eef..98b40be264 100644 --- a/hmp.c +++ b/hmp.c @@ -465,7 +465,8 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict) for (client = info->clients; client; client = client->next) { monitor_printf(mon, "Client:\n"); monitor_printf(mon, " address: %s:%s\n", - client->value->host, client->value->service); + client->value->base->host, + client->value->base->service); monitor_printf(mon, " x509_dname: %s\n", client->value->x509_dname ? client->value->x509_dname : "none"); @@ -513,7 +514,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict) for (chan = info->channels; chan; chan = chan->next) { monitor_printf(mon, "Channel:\n"); monitor_printf(mon, " address: %s:%s%s\n", - chan->value->host, chan->value->port, + chan->value->base->host, chan->value->base->port, chan->value->tls ? " [tls]" : ""); monitor_printf(mon, " session: %" PRId64 "\n", chan->value->connection_id); diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 85aa8715ba..08562ea390 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -56,17 +56,17 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, BlockErrorAction action = bdrv_get_error_action(req->dev->bs, is_read, error); VirtIOBlock *s = req->dev; - if (action == BDRV_ACTION_STOP) { + if (action == BLOCK_ERROR_ACTION_STOP) { req->next = s->rq; s->rq = req; - } else if (action == BDRV_ACTION_REPORT) { + } else if (action == BLOCK_ERROR_ACTION_REPORT) { virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); bdrv_acct_done(s->bs, &req->acct); g_free(req); } bdrv_error_action(s->bs, action, is_read, error); - return action != BDRV_ACTION_IGNORE; + return action != BLOCK_ERROR_ACTION_IGNORE; } static void virtio_blk_rw_complete(void *opaque, int ret) diff --git a/hw/ide/core.c b/hw/ide/core.c index 1cac5f53dc..3a38f1e599 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -596,10 +596,10 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) bool is_read = (op & BM_STATUS_RETRY_READ) != 0; BlockErrorAction action = bdrv_get_error_action(s->bs, is_read, error); - if (action == BDRV_ACTION_STOP) { + if (action == BLOCK_ERROR_ACTION_STOP) { s->bus->dma->ops->set_unit(s->bus->dma, s->unit); s->bus->error_status = op; - } else if (action == BDRV_ACTION_REPORT) { + } else if (action == BLOCK_ERROR_ACTION_REPORT) { if (op & BM_STATUS_DMA_RETRY) { dma_buf_commit(s); ide_dma_error(s); @@ -608,7 +608,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) } } bdrv_error_action(s->bs, action, is_read, error); - return action != BDRV_ACTION_IGNORE; + return action != BLOCK_ERROR_ACTION_IGNORE; } void ide_dma_cb(void *opaque, int ret) diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index a529ad24c7..d47ecd6ab4 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -419,7 +419,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error) SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); BlockErrorAction action = bdrv_get_error_action(s->qdev.conf.bs, is_read, error); - if (action == BDRV_ACTION_REPORT) { + if (action == BLOCK_ERROR_ACTION_REPORT) { switch (error) { case ENOMEDIUM: scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); @@ -439,10 +439,10 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error) } } bdrv_error_action(s->qdev.conf.bs, action, is_read, error); - if (action == BDRV_ACTION_STOP) { + if (action == BLOCK_ERROR_ACTION_STOP) { scsi_req_retry(&r->req); } - return action != BDRV_ACTION_IGNORE; + return action != BLOCK_ERROR_ACTION_IGNORE; } static void scsi_write_complete(void * opaque, int ret) diff --git a/include/block/block.h b/include/block/block.h index f15b99b00b..d0baf4fb83 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -150,10 +150,6 @@ typedef enum { #define BDRV_BLOCK_ALLOCATED 0x10 #define BDRV_BLOCK_OFFSET_MASK BDRV_SECTOR_MASK -typedef enum { - BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP -} BlockErrorAction; - typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue; typedef struct BDRVReopenState { diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 45588d7d58..af24669c7b 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -29,6 +29,7 @@ int inet_aton(const char *cp, struct in_addr *ia); #include "qemu/option.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" +#include "qapi-types.h" extern QemuOptsList socket_optslist; @@ -61,6 +62,7 @@ int inet_nonblocking_connect(const char *str, int inet_dgram_opts(QemuOpts *opts, Error **errp); const char *inet_strfamily(int family); +NetworkAddressFamily inet_netfamily(int family); int unix_listen_opts(QemuOpts *opts, Error **errp); int unix_listen(const char *path, char *ostr, int olen, Error **errp); diff --git a/qapi-schema.json b/qapi-schema.json index 98350048f6..4334e8ff33 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -629,23 +629,61 @@ ## { 'command': 'query-iothreads', 'returns': ['IOThreadInfo'] } +## +# @NetworkAddressFamily +# +# The network address family +# +# @ipv4: IPV4 family +# +# @ipv6: IPV6 family +# +# @unix: unix socket +# +# @unknown: otherwise +# +# Since: 2.1 +## +{ 'enum': 'NetworkAddressFamily', + 'data': [ 'ipv4', 'ipv6', 'unix', 'unknown' ] } + +## +# @VncBasicInfo +# +# The basic information for vnc network connection +# +# @host: IP address +# +# @service: The service name of vnc port. This may depend on the host system's +# service database so symbolic names should not be relied on. +# +# @family: address family +# +# Since: 2.1 +## +{ 'type': 'VncBasicInfo', + 'data': { 'host': 'str', + 'service': 'str', + 'family': 'NetworkAddressFamily' } } + +## +# @VncServerInfo +# +# The network connection information for server +# +# @auth: #optional, authentication method +# +# Since: 2.1 +## +{ 'type': 'VncServerInfo', + 'base': 'VncBasicInfo', + 'data': { '*auth': 'str' } } + ## # @VncClientInfo: # # Information about a connected VNC client. # -# @host: The host name of the client. QEMU tries to resolve this to a DNS name -# when possible. -# -# @family: 'ipv6' if the client is connected via IPv6 and TCP -# 'ipv4' if the client is connected via IPv4 and TCP -# 'unix' if the client is connected via a unix domain socket -# 'unknown' otherwise -# -# @service: The service name of the client's port. This may depends on the -# host system's service database so symbolic names should not be -# relied on. -# # @x509_dname: #optional If x509 authentication is in use, the Distinguished # Name of the client. # @@ -655,8 +693,8 @@ # Since: 0.14.0 ## { 'type': 'VncClientInfo', - 'data': {'host': 'str', 'family': 'str', 'service': 'str', - '*x509_dname': 'str', '*sasl_username': 'str'} } + 'base': 'VncBasicInfo', + 'data': { '*x509_dname' : 'str', '*sasl_username': 'str' } } ## # @VncInfo: @@ -695,7 +733,8 @@ # Since: 0.14.0 ## { 'type': 'VncInfo', - 'data': {'enabled': 'bool', '*host': 'str', '*family': 'str', + 'data': {'enabled': 'bool', '*host': 'str', + '*family': 'NetworkAddressFamily', '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} } ## @@ -709,21 +748,42 @@ ## { 'command': 'query-vnc', 'returns': 'VncInfo' } +## +# @SpiceBasicInfo +# +# The basic information for SPICE network connection +# +# @host: IP address +# +# @port: port number +# +# @family: address family +# +# Since: 2.1 +## +{ 'type': 'SpiceBasicInfo', + 'data': { 'host': 'str', + 'port': 'str', + 'family': 'NetworkAddressFamily' } } + +## +# @SpiceServerInfo +# +# Information about a SPICE server +# +# @auth: #optional, authentication method +# +# Since: 2.1 +## +{ 'type': 'SpiceServerInfo', + 'base': 'SpiceBasicInfo', + 'data': { '*auth': 'str' } } + ## # @SpiceChannel # # Information about a SPICE client channel. # -# @host: The host name of the client. QEMU tries to resolve this to a DNS name -# when possible. -# -# @family: 'ipv6' if the client is connected via IPv6 and TCP -# 'ipv4' if the client is connected via IPv4 and TCP -# 'unix' if the client is connected via a unix domain socket -# 'unknown' otherwise -# -# @port: The client's port number. -# # @connection-id: SPICE connection id number. All channels with the same id # belong to the same SPICE session. # @@ -740,8 +800,8 @@ # Since: 0.14.0 ## { 'type': 'SpiceChannel', - 'data': {'host': 'str', 'family': 'str', 'port': 'str', - 'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int', + 'base': 'SpiceBasicInfo', + 'data': {'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int', 'tls': 'bool'} } ## diff --git a/qapi/block-core.json b/qapi/block-core.json index 7215e48130..b7f36c638a 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1410,3 +1410,19 @@ ## { 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } } + +## +# @BlockErrorAction +# +# An enumeration of action that has been taken when a DISK I/O occurs +# +# @ignore: error has been ignored +# +# @report: error has been reported to the device +# +# @stop: error caused VM to be stopped +# +# Since: 2.1 +## +{ 'enum': 'BlockErrorAction', + 'data': [ 'ignore', 'report', 'stop' ] } diff --git a/ui/spice-core.c b/ui/spice-core.c index d10818a925..8d54fb320f 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -391,15 +391,16 @@ static SpiceChannelList *qmp_query_spice_channels(void) chan = g_malloc0(sizeof(*chan)); chan->value = g_malloc0(sizeof(*chan->value)); + chan->value->base = g_malloc0(sizeof(*chan->value->base)); paddr = (struct sockaddr *)&item->info->paddr_ext; plen = item->info->plen_ext; getnameinfo(paddr, plen, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); - chan->value->host = g_strdup(host); - chan->value->port = g_strdup(port); - chan->value->family = g_strdup(inet_strfamily(paddr->sa_family)); + chan->value->base->host = g_strdup(host); + chan->value->base->port = g_strdup(port); + chan->value->base->family = inet_netfamily(paddr->sa_family); chan->value->connection_id = item->info->connection_id; chan->value->channel_type = item->info->type; diff --git a/ui/vnc.c b/ui/vnc.c index aac93f0e17..20f8aa3f95 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -321,9 +321,10 @@ static VncClientInfo *qmp_query_vnc_client(const VncState *client) } info = g_malloc0(sizeof(*info)); - info->host = g_strdup(host); - info->service = g_strdup(serv); - info->family = g_strdup(inet_strfamily(sa.ss_family)); + info->base = g_malloc0(sizeof(*info->base)); + info->base->host = g_strdup(host); + info->base->service = g_strdup(serv); + info->base->family = inet_netfamily(sa.ss_family); #ifdef CONFIG_VNC_TLS if (client->tls.session && client->tls.dname) { @@ -398,7 +399,7 @@ VncInfo *qmp_query_vnc(Error **errp) info->service = g_strdup(serv); info->has_family = true; - info->family = g_strdup(inet_strfamily(sa.ss_family)); + info->family = inet_netfamily(sa.ss_family); info->has_auth = true; info->auth = g_strdup(vnc_auth_name(vnc_display)); diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index a4a1e9d300..447720f62a 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -102,6 +102,16 @@ const char *inet_strfamily(int family) return "unknown"; } +NetworkAddressFamily inet_netfamily(int family) +{ + switch (family) { + case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6; + case PF_INET: return NETWORK_ADDRESS_FAMILY_IPV4; + case PF_UNIX: return NETWORK_ADDRESS_FAMILY_UNIX; + } + return NETWORK_ADDRESS_FAMILY_UNKNOWN; +} + int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp) { struct addrinfo ai,*res,*e;