@@ -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).
@@ -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--;
@@ -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 {
@@ -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;
}
}
@@ -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) {
@@ -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);
@@ -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)
@@ -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)
@@ -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)
@@ -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 {
@@ -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);
@@ -630,21 +630,59 @@
{ 'command': 'query-iothreads', 'returns': ['IOThreadInfo'] }
##
-# @VncClientInfo:
+# @NetworkAddressFamily
#
-# Information about a connected VNC client.
+# 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
#
-# @host: The host name of the client. QEMU tries to resolve this to a DNS name
-# when possible.
+# The basic information for vnc network connection
#
-# @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
+# @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:
#
-# @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.
+# Information about a connected VNC client.
#
# @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']} }
##
@@ -710,19 +749,40 @@
{ 'command': 'query-vnc', 'returns': 'VncInfo' }
##
-# @SpiceChannel
+# @SpiceBasicInfo
#
-# Information about a SPICE client channel.
+# 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
#
-# @host: The host name of the client. QEMU tries to resolve this to a DNS name
-# when possible.
+# Information about a SPICE server
#
-# @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
+# @auth: #optional, authentication method
#
-# @port: The client's port number.
+# Since: 2.1
+##
+{ 'type': 'SpiceServerInfo',
+ 'base': 'SpiceBasicInfo',
+ 'data': { '*auth': 'str' } }
+
+##
+# @SpiceChannel
+#
+# Information about a SPICE client channel.
#
# @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'} }
##
@@ -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' ] }
@@ -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;
@@ -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));
@@ -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;