mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging
# gpg: Signature made Fri Jun 12 13:57:20 2015 BST using RSA key ID 81AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" * remotes/stefanha/tags/net-pull-request: qmp/hmp: add rocker device support rocker: bring link up/down on PHY enable/disable rocker: update tests using hw-derived interface names rocker: Add support for phys name iohandler: Change return type of qemu_set_fd_handler to "void" event-notifier: Always return 0 for posix implementation xen_backend: Remove unused error handling of qemu_set_fd_handler oss: Remove unused error handling of qemu_set_fd_handler alsaaudio: Remove unused error handling of qemu_set_fd_handler main-loop: Drop qemu_set_fd_handler2 Change qemu_set_fd_handler2(..., NULL, ...) to qemu_set_fd_handler tap: Drop tap_can_send net/socket: Drop net_socket_can_send netmap: Drop netmap_can_send l2tpv3: Drop l2tpv3_can_send stubs: Add qemu_set_fd_handler Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+2
-14
@@ -266,31 +266,19 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (pfds[i].events & POLLIN) {
|
||||
err = qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler,
|
||||
NULL, hlp);
|
||||
qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler, NULL, hlp);
|
||||
}
|
||||
if (pfds[i].events & POLLOUT) {
|
||||
if (conf.verbose) {
|
||||
dolog ("POLLOUT %d %d\n", i, pfds[i].fd);
|
||||
}
|
||||
err = qemu_set_fd_handler (pfds[i].fd, NULL,
|
||||
alsa_poll_handler, hlp);
|
||||
qemu_set_fd_handler (pfds[i].fd, NULL, alsa_poll_handler, hlp);
|
||||
}
|
||||
if (conf.verbose) {
|
||||
dolog ("Set handler events=%#x index=%d fd=%d err=%d\n",
|
||||
pfds[i].events, i, pfds[i].fd, err);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
dolog ("Failed to set handler events=%#x index=%d fd=%d err=%d\n",
|
||||
pfds[i].events, i, pfds[i].fd, err);
|
||||
|
||||
while (i--) {
|
||||
qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
|
||||
}
|
||||
g_free (pfds);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
hlp->pfds = pfds;
|
||||
hlp->count = count;
|
||||
|
||||
+8
-6
@@ -138,18 +138,18 @@ static void oss_helper_poll_in (void *opaque)
|
||||
audio_run ("oss_poll_in");
|
||||
}
|
||||
|
||||
static int oss_poll_out (HWVoiceOut *hw)
|
||||
static void oss_poll_out (HWVoiceOut *hw)
|
||||
{
|
||||
OSSVoiceOut *oss = (OSSVoiceOut *) hw;
|
||||
|
||||
return qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL);
|
||||
qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL);
|
||||
}
|
||||
|
||||
static int oss_poll_in (HWVoiceIn *hw)
|
||||
static void oss_poll_in (HWVoiceIn *hw)
|
||||
{
|
||||
OSSVoiceIn *oss = (OSSVoiceIn *) hw;
|
||||
|
||||
return qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL);
|
||||
qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL);
|
||||
}
|
||||
|
||||
static int oss_write (SWVoiceOut *sw, void *buf, int len)
|
||||
@@ -634,7 +634,8 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
|
||||
va_end (ap);
|
||||
|
||||
ldebug ("enabling voice\n");
|
||||
if (poll_mode && oss_poll_out (hw)) {
|
||||
if (poll_mode) {
|
||||
oss_poll_out (hw);
|
||||
poll_mode = 0;
|
||||
}
|
||||
hw->poll_mode = poll_mode;
|
||||
@@ -828,7 +829,8 @@ static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...)
|
||||
poll_mode = va_arg (ap, int);
|
||||
va_end (ap);
|
||||
|
||||
if (poll_mode && oss_poll_in (hw)) {
|
||||
if (poll_mode) {
|
||||
oss_poll_in (hw);
|
||||
poll_mode = 0;
|
||||
}
|
||||
hw->poll_mode = poll_mode;
|
||||
|
||||
+2
-2
@@ -43,7 +43,7 @@ void qmp_nbd_server_start(SocketAddress *addr, Error **errp)
|
||||
|
||||
server_fd = socket_listen(addr, errp);
|
||||
if (server_fd != -1) {
|
||||
qemu_set_fd_handler2(server_fd, NULL, nbd_accept, NULL, NULL);
|
||||
qemu_set_fd_handler(server_fd, nbd_accept, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ void qmp_nbd_server_stop(Error **errp)
|
||||
}
|
||||
|
||||
if (server_fd != -1) {
|
||||
qemu_set_fd_handler2(server_fd, NULL, NULL, NULL, NULL);
|
||||
qemu_set_fd_handler(server_fd, NULL, NULL, NULL);
|
||||
close(server_fd);
|
||||
server_fd = -1;
|
||||
}
|
||||
|
||||
@@ -420,6 +420,7 @@ Other properties for front-panel ports are available via DMA CMD descriptors:
|
||||
LEARNING 1 MAC address learning on port
|
||||
1 = enabled
|
||||
0 = disabled
|
||||
PHYS_NAME <var> Physical port name (string)
|
||||
|
||||
Set PORT_SETTINGS descriptor:
|
||||
|
||||
|
||||
@@ -1798,6 +1798,30 @@ STEXI
|
||||
show available trace events and their state
|
||||
ETEXI
|
||||
|
||||
STEXI
|
||||
@item rocker @var{name}
|
||||
@findex rocker
|
||||
Show Rocker(s)
|
||||
ETEXI
|
||||
|
||||
STEXI
|
||||
@item rocker_ports @var{name}
|
||||
@findex rocker_ports
|
||||
Show Rocker ports
|
||||
ETEXI
|
||||
|
||||
STEXI
|
||||
@item rocker_of_dpa_flows @var{name} [@var{tbl_id}]
|
||||
@findex rocker_of_dpa_flows
|
||||
Show Rocker OF-DPA flow tables
|
||||
ETEXI
|
||||
|
||||
STEXI
|
||||
@item rocker_of_dpa_groups @var{name} [@var{type}]
|
||||
@findex rocker_of_dpa_groups
|
||||
Show Rocker OF-DPA groups
|
||||
ETEXI
|
||||
|
||||
STEXI
|
||||
@end table
|
||||
ETEXI
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "hmp.h"
|
||||
#include "net/net.h"
|
||||
#include "net/eth.h"
|
||||
#include "sysemu/char.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "qemu/option.h"
|
||||
@@ -1999,3 +2000,305 @@ void hmp_qom_set(Monitor *mon, const QDict *qdict)
|
||||
}
|
||||
hmp_handle_error(mon, &err);
|
||||
}
|
||||
|
||||
void hmp_rocker(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *name = qdict_get_str(qdict, "name");
|
||||
RockerSwitch *rocker;
|
||||
Error *errp = NULL;
|
||||
|
||||
rocker = qmp_query_rocker(name, &errp);
|
||||
if (errp != NULL) {
|
||||
hmp_handle_error(mon, &errp);
|
||||
return;
|
||||
}
|
||||
|
||||
monitor_printf(mon, "name: %s\n", rocker->name);
|
||||
monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id);
|
||||
monitor_printf(mon, "ports: %d\n", rocker->ports);
|
||||
|
||||
qapi_free_RockerSwitch(rocker);
|
||||
}
|
||||
|
||||
void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
RockerPortList *list, *port;
|
||||
const char *name = qdict_get_str(qdict, "name");
|
||||
Error *errp = NULL;
|
||||
|
||||
list = qmp_query_rocker_ports(name, &errp);
|
||||
if (errp != NULL) {
|
||||
hmp_handle_error(mon, &errp);
|
||||
return;
|
||||
}
|
||||
|
||||
monitor_printf(mon, " ena/ speed/ auto\n");
|
||||
monitor_printf(mon, " port link duplex neg?\n");
|
||||
|
||||
for (port = list; port; port = port->next) {
|
||||
monitor_printf(mon, "%10s %-4s %-3s %2s %-3s\n",
|
||||
port->value->name,
|
||||
port->value->enabled ? port->value->link_up ?
|
||||
"up" : "down" : "!ena",
|
||||
port->value->speed == 10000 ? "10G" : "??",
|
||||
port->value->duplex ? "FD" : "HD",
|
||||
port->value->autoneg ? "Yes" : "No");
|
||||
}
|
||||
|
||||
qapi_free_RockerPortList(list);
|
||||
}
|
||||
|
||||
void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
RockerOfDpaFlowList *list, *info;
|
||||
const char *name = qdict_get_str(qdict, "name");
|
||||
uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1);
|
||||
Error *errp = NULL;
|
||||
|
||||
list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &errp);
|
||||
if (errp != NULL) {
|
||||
hmp_handle_error(mon, &errp);
|
||||
return;
|
||||
}
|
||||
|
||||
monitor_printf(mon, "prio tbl hits key(mask) --> actions\n");
|
||||
|
||||
for (info = list; info; info = info->next) {
|
||||
RockerOfDpaFlow *flow = info->value;
|
||||
RockerOfDpaFlowKey *key = flow->key;
|
||||
RockerOfDpaFlowMask *mask = flow->mask;
|
||||
RockerOfDpaFlowAction *action = flow->action;
|
||||
|
||||
if (flow->hits) {
|
||||
monitor_printf(mon, "%-4d %-3d %-4" PRIu64,
|
||||
key->priority, key->tbl_id, flow->hits);
|
||||
} else {
|
||||
monitor_printf(mon, "%-4d %-3d ",
|
||||
key->priority, key->tbl_id);
|
||||
}
|
||||
|
||||
if (key->has_in_pport) {
|
||||
monitor_printf(mon, " pport %d", key->in_pport);
|
||||
if (mask->has_in_pport) {
|
||||
monitor_printf(mon, "(0x%x)", mask->in_pport);
|
||||
}
|
||||
}
|
||||
|
||||
if (key->has_vlan_id) {
|
||||
monitor_printf(mon, " vlan %d",
|
||||
key->vlan_id & VLAN_VID_MASK);
|
||||
if (mask->has_vlan_id) {
|
||||
monitor_printf(mon, "(0x%x)", mask->vlan_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (key->has_tunnel_id) {
|
||||
monitor_printf(mon, " tunnel %d", key->tunnel_id);
|
||||
if (mask->has_tunnel_id) {
|
||||
monitor_printf(mon, "(0x%x)", mask->tunnel_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (key->has_eth_type) {
|
||||
switch (key->eth_type) {
|
||||
case 0x0806:
|
||||
monitor_printf(mon, " ARP");
|
||||
break;
|
||||
case 0x0800:
|
||||
monitor_printf(mon, " IP");
|
||||
break;
|
||||
case 0x86dd:
|
||||
monitor_printf(mon, " IPv6");
|
||||
break;
|
||||
case 0x8809:
|
||||
monitor_printf(mon, " LACP");
|
||||
break;
|
||||
case 0x88cc:
|
||||
monitor_printf(mon, " LLDP");
|
||||
break;
|
||||
default:
|
||||
monitor_printf(mon, " eth type 0x%04x", key->eth_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (key->has_eth_src) {
|
||||
if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) &&
|
||||
(mask->has_eth_src) &&
|
||||
(strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
|
||||
monitor_printf(mon, " src <any mcast/bcast>");
|
||||
} else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) &&
|
||||
(mask->has_eth_src) &&
|
||||
(strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
|
||||
monitor_printf(mon, " src <any ucast>");
|
||||
} else {
|
||||
monitor_printf(mon, " src %s", key->eth_src);
|
||||
if (mask->has_eth_src) {
|
||||
monitor_printf(mon, "(%s)", mask->eth_src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key->has_eth_dst) {
|
||||
if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) &&
|
||||
(mask->has_eth_dst) &&
|
||||
(strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
|
||||
monitor_printf(mon, " dst <any mcast/bcast>");
|
||||
} else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) &&
|
||||
(mask->has_eth_dst) &&
|
||||
(strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
|
||||
monitor_printf(mon, " dst <any ucast>");
|
||||
} else {
|
||||
monitor_printf(mon, " dst %s", key->eth_dst);
|
||||
if (mask->has_eth_dst) {
|
||||
monitor_printf(mon, "(%s)", mask->eth_dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key->has_ip_proto) {
|
||||
monitor_printf(mon, " proto %d", key->ip_proto);
|
||||
if (mask->has_ip_proto) {
|
||||
monitor_printf(mon, "(0x%x)", mask->ip_proto);
|
||||
}
|
||||
}
|
||||
|
||||
if (key->has_ip_tos) {
|
||||
monitor_printf(mon, " TOS %d", key->ip_tos);
|
||||
if (mask->has_ip_tos) {
|
||||
monitor_printf(mon, "(0x%x)", mask->ip_tos);
|
||||
}
|
||||
}
|
||||
|
||||
if (key->has_ip_dst) {
|
||||
monitor_printf(mon, " dst %s", key->ip_dst);
|
||||
}
|
||||
|
||||
if (action->has_goto_tbl || action->has_group_id ||
|
||||
action->has_new_vlan_id) {
|
||||
monitor_printf(mon, " -->");
|
||||
}
|
||||
|
||||
if (action->has_new_vlan_id) {
|
||||
monitor_printf(mon, " apply new vlan %d",
|
||||
ntohs(action->new_vlan_id));
|
||||
}
|
||||
|
||||
if (action->has_group_id) {
|
||||
monitor_printf(mon, " write group 0x%08x", action->group_id);
|
||||
}
|
||||
|
||||
if (action->has_goto_tbl) {
|
||||
monitor_printf(mon, " goto tbl %d", action->goto_tbl);
|
||||
}
|
||||
|
||||
monitor_printf(mon, "\n");
|
||||
}
|
||||
|
||||
qapi_free_RockerOfDpaFlowList(list);
|
||||
}
|
||||
|
||||
void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
RockerOfDpaGroupList *list, *g;
|
||||
const char *name = qdict_get_str(qdict, "name");
|
||||
uint8_t type = qdict_get_try_int(qdict, "type", 9);
|
||||
Error *errp = NULL;
|
||||
bool set = false;
|
||||
|
||||
list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &errp);
|
||||
if (errp != NULL) {
|
||||
hmp_handle_error(mon, &errp);
|
||||
return;
|
||||
}
|
||||
|
||||
monitor_printf(mon, "id (decode) --> buckets\n");
|
||||
|
||||
for (g = list; g; g = g->next) {
|
||||
RockerOfDpaGroup *group = g->value;
|
||||
|
||||
monitor_printf(mon, "0x%08x", group->id);
|
||||
|
||||
monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" :
|
||||
group->type == 1 ? "L2 rewrite" :
|
||||
group->type == 2 ? "L3 unicast" :
|
||||
group->type == 3 ? "L2 multicast" :
|
||||
group->type == 4 ? "L2 flood" :
|
||||
group->type == 5 ? "L3 interface" :
|
||||
group->type == 6 ? "L3 multicast" :
|
||||
group->type == 7 ? "L3 ECMP" :
|
||||
group->type == 8 ? "L2 overlay" :
|
||||
"unknown");
|
||||
|
||||
if (group->has_vlan_id) {
|
||||
monitor_printf(mon, " vlan %d", group->vlan_id);
|
||||
}
|
||||
|
||||
if (group->has_pport) {
|
||||
monitor_printf(mon, " pport %d", group->pport);
|
||||
}
|
||||
|
||||
if (group->has_index) {
|
||||
monitor_printf(mon, " index %d", group->index);
|
||||
}
|
||||
|
||||
monitor_printf(mon, ") -->");
|
||||
|
||||
if (group->has_set_vlan_id && group->set_vlan_id) {
|
||||
set = true;
|
||||
monitor_printf(mon, " set vlan %d",
|
||||
group->set_vlan_id & VLAN_VID_MASK);
|
||||
}
|
||||
|
||||
if (group->has_set_eth_src) {
|
||||
if (!set) {
|
||||
set = true;
|
||||
monitor_printf(mon, " set");
|
||||
}
|
||||
monitor_printf(mon, " src %s", group->set_eth_src);
|
||||
}
|
||||
|
||||
if (group->has_set_eth_dst) {
|
||||
if (!set) {
|
||||
set = true;
|
||||
monitor_printf(mon, " set");
|
||||
}
|
||||
monitor_printf(mon, " dst %s", group->set_eth_dst);
|
||||
}
|
||||
|
||||
set = false;
|
||||
|
||||
if (group->has_ttl_check && group->ttl_check) {
|
||||
monitor_printf(mon, " check TTL");
|
||||
}
|
||||
|
||||
if (group->has_group_id && group->group_id) {
|
||||
monitor_printf(mon, " group id 0x%08x", group->group_id);
|
||||
}
|
||||
|
||||
if (group->has_pop_vlan && group->pop_vlan) {
|
||||
monitor_printf(mon, " pop vlan");
|
||||
}
|
||||
|
||||
if (group->has_out_pport) {
|
||||
monitor_printf(mon, " out pport %d", group->out_pport);
|
||||
}
|
||||
|
||||
if (group->has_group_ids) {
|
||||
struct uint32List *id;
|
||||
|
||||
monitor_printf(mon, " groups [");
|
||||
for (id = group->group_ids; id; id = id->next) {
|
||||
monitor_printf(mon, "0x%08x", id->value);
|
||||
if (id->next) {
|
||||
monitor_printf(mon, ",");
|
||||
}
|
||||
}
|
||||
monitor_printf(mon, "]");
|
||||
}
|
||||
|
||||
monitor_printf(mon, "\n");
|
||||
}
|
||||
|
||||
qapi_free_RockerOfDpaGroupList(list);
|
||||
}
|
||||
|
||||
@@ -124,5 +124,9 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args,
|
||||
const char *str);
|
||||
void delvm_completion(ReadLineState *rs, int nb_args, const char *str);
|
||||
void loadvm_completion(ReadLineState *rs, int nb_args, const char *str);
|
||||
void hmp_rocker(Monitor *mon, const QDict *qdict);
|
||||
void hmp_rocker_ports(Monitor *mon, const QDict *qdict);
|
||||
void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict);
|
||||
void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,3 +39,4 @@ obj-$(CONFIG_ETSEC) += fsl_etsec/etsec.o fsl_etsec/registers.o \
|
||||
common-obj-$(CONFIG_ROCKER) += rocker/rocker.o rocker/rocker_fp.o \
|
||||
rocker/rocker_desc.o rocker/rocker_world.o \
|
||||
rocker/rocker_of_dpa.o
|
||||
obj-$(call lnot,$(CONFIG_ROCKER)) += rocker/qmp-norocker.o
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* QMP Target options - Commands handled based on a target config
|
||||
* versus a host config
|
||||
*
|
||||
* Copyright (c) 2015 David Ahern <dsahern@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qmp-commands.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
|
||||
RockerSwitch *qmp_query_rocker(const char *name, Error **errp)
|
||||
{
|
||||
error_set(errp, QERR_FEATURE_DISABLED, "rocker");
|
||||
return NULL;
|
||||
};
|
||||
|
||||
RockerPortList *qmp_query_rocker_ports(const char *name, Error **errp)
|
||||
{
|
||||
error_set(errp, QERR_FEATURE_DISABLED, "rocker");
|
||||
return NULL;
|
||||
};
|
||||
|
||||
RockerOfDpaFlowList *qmp_query_rocker_of_dpa_flows(const char *name,
|
||||
bool has_tbl_id,
|
||||
uint32_t tbl_id,
|
||||
Error **errp)
|
||||
{
|
||||
error_set(errp, QERR_FEATURE_DISABLED, "rocker");
|
||||
return NULL;
|
||||
};
|
||||
|
||||
RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name,
|
||||
bool has_type,
|
||||
uint8_t type,
|
||||
Error **errp)
|
||||
{
|
||||
error_set(errp, QERR_FEATURE_DISABLED, "rocker");
|
||||
return NULL;
|
||||
};
|
||||
+67
-1
@@ -94,6 +94,51 @@ World *rocker_get_world(Rocker *r, enum rocker_world_type type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RockerSwitch *qmp_query_rocker(const char *name, Error **errp)
|
||||
{
|
||||
RockerSwitch *rocker = g_malloc0(sizeof(*rocker));
|
||||
Rocker *r;
|
||||
|
||||
r = rocker_find(name);
|
||||
if (!r) {
|
||||
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
|
||||
"rocker %s not found", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rocker->name = g_strdup(r->name);
|
||||
rocker->id = r->switch_id;
|
||||
rocker->ports = r->fp_ports;
|
||||
|
||||
return rocker;
|
||||
}
|
||||
|
||||
RockerPortList *qmp_query_rocker_ports(const char *name, Error **errp)
|
||||
{
|
||||
RockerPortList *list = NULL;
|
||||
Rocker *r;
|
||||
int i;
|
||||
|
||||
r = rocker_find(name);
|
||||
if (!r) {
|
||||
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
|
||||
"rocker %s not found", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = r->fp_ports - 1; i >= 0; i--) {
|
||||
RockerPortList *info = g_malloc0(sizeof(*info));
|
||||
info->value = g_malloc0(sizeof(*info->value));
|
||||
struct fp_port *port = r->fp_port[i];
|
||||
|
||||
fp_port_get_info(port, info);
|
||||
info->next = list;
|
||||
list = info;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
uint32_t rocker_fp_ports(Rocker *r)
|
||||
{
|
||||
return r->fp_ports;
|
||||
@@ -238,6 +283,7 @@ static int cmd_get_port_settings(Rocker *r,
|
||||
uint8_t duplex;
|
||||
uint8_t autoneg;
|
||||
uint8_t learning;
|
||||
char *phys_name;
|
||||
MACAddr macaddr;
|
||||
enum rocker_world_type mode;
|
||||
size_t tlv_size;
|
||||
@@ -265,6 +311,7 @@ static int cmd_get_port_settings(Rocker *r,
|
||||
fp_port_get_macaddr(fp_port, &macaddr);
|
||||
mode = world_type(fp_port_get_world(fp_port));
|
||||
learning = fp_port_get_learning(fp_port);
|
||||
phys_name = fp_port_get_name(fp_port);
|
||||
|
||||
tlv_size = rocker_tlv_total_size(0) + /* nest */
|
||||
rocker_tlv_total_size(sizeof(uint32_t)) + /* pport */
|
||||
@@ -273,7 +320,8 @@ static int cmd_get_port_settings(Rocker *r,
|
||||
rocker_tlv_total_size(sizeof(uint8_t)) + /* autoneg */
|
||||
rocker_tlv_total_size(sizeof(macaddr.a)) + /* macaddr */
|
||||
rocker_tlv_total_size(sizeof(uint8_t)) + /* mode */
|
||||
rocker_tlv_total_size(sizeof(uint8_t)); /* learning */
|
||||
rocker_tlv_total_size(sizeof(uint8_t)) + /* learning */
|
||||
rocker_tlv_total_size(strlen(phys_name));
|
||||
|
||||
if (tlv_size > desc_buf_size(info)) {
|
||||
return -ROCKER_EMSGSIZE;
|
||||
@@ -290,6 +338,8 @@ static int cmd_get_port_settings(Rocker *r,
|
||||
rocker_tlv_put_u8(buf, &pos, ROCKER_TLV_CMD_PORT_SETTINGS_MODE, mode);
|
||||
rocker_tlv_put_u8(buf, &pos, ROCKER_TLV_CMD_PORT_SETTINGS_LEARNING,
|
||||
learning);
|
||||
rocker_tlv_put(buf, &pos, ROCKER_TLV_CMD_PORT_SETTINGS_PHYS_NAME,
|
||||
strlen(phys_name), phys_name);
|
||||
rocker_tlv_nest_end(buf, &pos, nest);
|
||||
|
||||
return desc_set_buf(info, tlv_size);
|
||||
@@ -1277,6 +1327,22 @@ static int pci_rocker_init(PCIDevice *dev)
|
||||
goto err_duplicate;
|
||||
}
|
||||
|
||||
/* Rocker name is passed in port name requests to OS with the intention
|
||||
* that the name is used in interface names. Limit the length of the
|
||||
* rocker name to avoid naming problems in the OS. Also, adding the
|
||||
* port number as p# and unganged breakout b#, where # is at most 2
|
||||
* digits, so leave room for it too (-1 for string terminator, -3 for
|
||||
* p# and -3 for b#)
|
||||
*/
|
||||
#define ROCKER_IFNAMSIZ 16
|
||||
#define MAX_ROCKER_NAME_LEN (ROCKER_IFNAMSIZ - 1 - 3 - 3)
|
||||
if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {
|
||||
fprintf(stderr,
|
||||
"rocker: name too long; please shorten to at most %d chars\n",
|
||||
MAX_ROCKER_NAME_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) {
|
||||
memcpy(&r->fp_start_macaddr, &dflt, sizeof(dflt));
|
||||
r->fp_start_macaddr.a[4] += (sw_index++);
|
||||
|
||||
@@ -41,11 +41,26 @@ struct fp_port {
|
||||
NICConf conf;
|
||||
};
|
||||
|
||||
char *fp_port_get_name(FpPort *port)
|
||||
{
|
||||
return port->name;
|
||||
}
|
||||
|
||||
bool fp_port_get_link_up(FpPort *port)
|
||||
{
|
||||
return !qemu_get_queue(port->nic)->link_down;
|
||||
}
|
||||
|
||||
void fp_port_get_info(FpPort *port, RockerPortList *info)
|
||||
{
|
||||
info->value->name = g_strdup(port->name);
|
||||
info->value->enabled = port->enabled;
|
||||
info->value->link_up = fp_port_get_link_up(port);
|
||||
info->value->speed = port->speed;
|
||||
info->value->duplex = port->duplex;
|
||||
info->value->autoneg = port->autoneg;
|
||||
}
|
||||
|
||||
void fp_port_get_macaddr(FpPort *port, MACAddr *macaddr)
|
||||
{
|
||||
memcpy(macaddr->a, port->conf.macaddr.a, sizeof(macaddr->a));
|
||||
@@ -173,8 +188,19 @@ bool fp_port_enabled(FpPort *port)
|
||||
return port->enabled;
|
||||
}
|
||||
|
||||
static void fp_port_set_link(FpPort *port, bool up)
|
||||
{
|
||||
NetClientState *nc = qemu_get_queue(port->nic);
|
||||
|
||||
if (up == nc->link_down) {
|
||||
nc->link_down = !up;
|
||||
nc->info->link_status_changed(nc);
|
||||
}
|
||||
}
|
||||
|
||||
void fp_port_enable(FpPort *port)
|
||||
{
|
||||
fp_port_set_link(port, true);
|
||||
port->enabled = true;
|
||||
DPRINTF("port %d enabled\n", port->index);
|
||||
}
|
||||
@@ -182,6 +208,7 @@ void fp_port_enable(FpPort *port)
|
||||
void fp_port_disable(FpPort *port)
|
||||
{
|
||||
port->enabled = false;
|
||||
fp_port_set_link(port, false);
|
||||
DPRINTF("port %d disabled\n", port->index);
|
||||
}
|
||||
|
||||
@@ -201,7 +228,7 @@ FpPort *fp_port_alloc(Rocker *r, char *sw_name,
|
||||
|
||||
/* front-panel switch port names are 1-based */
|
||||
|
||||
port->name = g_strdup_printf("%s.%d", sw_name, port->pport);
|
||||
port->name = g_strdup_printf("%sp%d", sw_name, port->pport);
|
||||
|
||||
memcpy(port->conf.macaddr.a, start_mac, sizeof(port->conf.macaddr.a));
|
||||
port->conf.macaddr.a[5] += index;
|
||||
|
||||
@@ -26,7 +26,9 @@ typedef struct fp_port FpPort;
|
||||
|
||||
int fp_port_eg(FpPort *port, const struct iovec *iov, int iovcnt);
|
||||
|
||||
char *fp_port_get_name(FpPort *port);
|
||||
bool fp_port_get_link_up(FpPort *port);
|
||||
void fp_port_get_info(FpPort *port, RockerPortList *info);
|
||||
void fp_port_get_macaddr(FpPort *port, MACAddr *macaddr);
|
||||
void fp_port_set_macaddr(FpPort *port, MACAddr *macaddr);
|
||||
uint8_t fp_port_get_learning(FpPort *port);
|
||||
|
||||
@@ -179,6 +179,7 @@ enum {
|
||||
ROCKER_TLV_CMD_PORT_SETTINGS_MACADDR, /* binary */
|
||||
ROCKER_TLV_CMD_PORT_SETTINGS_MODE, /* u8 */
|
||||
ROCKER_TLV_CMD_PORT_SETTINGS_LEARNING, /* u8 */
|
||||
ROCKER_TLV_CMD_PORT_SETTINGS_PHYS_NAME, /* binary */
|
||||
|
||||
__ROCKER_TLV_CMD_PORT_SETTINGS_MAX,
|
||||
ROCKER_TLV_CMD_PORT_SETTINGS_MAX = __ROCKER_TLV_CMD_PORT_SETTINGS_MAX - 1,
|
||||
|
||||
@@ -2302,6 +2302,318 @@ static void of_dpa_uninit(World *world)
|
||||
g_hash_table_destroy(of_dpa->flow_tbl);
|
||||
}
|
||||
|
||||
struct of_dpa_flow_fill_context {
|
||||
RockerOfDpaFlowList *list;
|
||||
uint32_t tbl_id;
|
||||
};
|
||||
|
||||
static void of_dpa_flow_fill(void *cookie, void *value, void *user_data)
|
||||
{
|
||||
struct of_dpa_flow *flow = value;
|
||||
struct of_dpa_flow_key *key = &flow->key;
|
||||
struct of_dpa_flow_key *mask = &flow->mask;
|
||||
struct of_dpa_flow_fill_context *flow_context = user_data;
|
||||
RockerOfDpaFlowList *new;
|
||||
RockerOfDpaFlow *nflow;
|
||||
RockerOfDpaFlowKey *nkey;
|
||||
RockerOfDpaFlowMask *nmask;
|
||||
RockerOfDpaFlowAction *naction;
|
||||
|
||||
if (flow_context->tbl_id != -1 &&
|
||||
flow_context->tbl_id != key->tbl_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
new = g_malloc0(sizeof(*new));
|
||||
nflow = new->value = g_malloc0(sizeof(*nflow));
|
||||
nkey = nflow->key = g_malloc0(sizeof(*nkey));
|
||||
nmask = nflow->mask = g_malloc0(sizeof(*nmask));
|
||||
naction = nflow->action = g_malloc0(sizeof(*naction));
|
||||
|
||||
nflow->cookie = flow->cookie;
|
||||
nflow->hits = flow->stats.hits;
|
||||
nkey->priority = flow->priority;
|
||||
nkey->tbl_id = key->tbl_id;
|
||||
|
||||
if (key->in_pport || mask->in_pport) {
|
||||
nkey->has_in_pport = true;
|
||||
nkey->in_pport = key->in_pport;
|
||||
}
|
||||
|
||||
if (nkey->has_in_pport && mask->in_pport != 0xffffffff) {
|
||||
nmask->has_in_pport = true;
|
||||
nmask->in_pport = mask->in_pport;
|
||||
}
|
||||
|
||||
if (key->eth.vlan_id || mask->eth.vlan_id) {
|
||||
nkey->has_vlan_id = true;
|
||||
nkey->vlan_id = ntohs(key->eth.vlan_id);
|
||||
}
|
||||
|
||||
if (nkey->has_vlan_id && mask->eth.vlan_id != 0xffff) {
|
||||
nmask->has_vlan_id = true;
|
||||
nmask->vlan_id = ntohs(mask->eth.vlan_id);
|
||||
}
|
||||
|
||||
if (key->tunnel_id || mask->tunnel_id) {
|
||||
nkey->has_tunnel_id = true;
|
||||
nkey->tunnel_id = key->tunnel_id;
|
||||
}
|
||||
|
||||
if (nkey->has_tunnel_id && mask->tunnel_id != 0xffffffff) {
|
||||
nmask->has_tunnel_id = true;
|
||||
nmask->tunnel_id = mask->tunnel_id;
|
||||
}
|
||||
|
||||
if (memcmp(key->eth.src.a, zero_mac.a, ETH_ALEN) ||
|
||||
memcmp(mask->eth.src.a, zero_mac.a, ETH_ALEN)) {
|
||||
nkey->has_eth_src = true;
|
||||
nkey->eth_src = qemu_mac_strdup_printf(key->eth.src.a);
|
||||
}
|
||||
|
||||
if (nkey->has_eth_src && memcmp(mask->eth.src.a, ff_mac.a, ETH_ALEN)) {
|
||||
nmask->has_eth_src = true;
|
||||
nmask->eth_src = qemu_mac_strdup_printf(mask->eth.src.a);
|
||||
}
|
||||
|
||||
if (memcmp(key->eth.dst.a, zero_mac.a, ETH_ALEN) ||
|
||||
memcmp(mask->eth.dst.a, zero_mac.a, ETH_ALEN)) {
|
||||
nkey->has_eth_dst = true;
|
||||
nkey->eth_dst = qemu_mac_strdup_printf(key->eth.dst.a);
|
||||
}
|
||||
|
||||
if (nkey->has_eth_dst && memcmp(mask->eth.dst.a, ff_mac.a, ETH_ALEN)) {
|
||||
nmask->has_eth_dst = true;
|
||||
nmask->eth_dst = qemu_mac_strdup_printf(mask->eth.dst.a);
|
||||
}
|
||||
|
||||
if (key->eth.type) {
|
||||
|
||||
nkey->has_eth_type = true;
|
||||
nkey->eth_type = ntohs(key->eth.type);
|
||||
|
||||
switch (ntohs(key->eth.type)) {
|
||||
case 0x0800:
|
||||
case 0x86dd:
|
||||
if (key->ip.proto || mask->ip.proto) {
|
||||
nkey->has_ip_proto = true;
|
||||
nkey->ip_proto = key->ip.proto;
|
||||
}
|
||||
if (nkey->has_ip_proto && mask->ip.proto != 0xff) {
|
||||
nmask->has_ip_proto = true;
|
||||
nmask->ip_proto = mask->ip.proto;
|
||||
}
|
||||
if (key->ip.tos || mask->ip.tos) {
|
||||
nkey->has_ip_tos = true;
|
||||
nkey->ip_tos = key->ip.tos;
|
||||
}
|
||||
if (nkey->has_ip_tos && mask->ip.tos != 0xff) {
|
||||
nmask->has_ip_tos = true;
|
||||
nmask->ip_tos = mask->ip.tos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ntohs(key->eth.type)) {
|
||||
case 0x0800:
|
||||
if (key->ipv4.addr.dst || mask->ipv4.addr.dst) {
|
||||
char *dst = inet_ntoa(*(struct in_addr *)&key->ipv4.addr.dst);
|
||||
int dst_len = of_dpa_mask2prefix(mask->ipv4.addr.dst);
|
||||
nkey->has_ip_dst = true;
|
||||
nkey->ip_dst = g_strdup_printf("%s/%d", dst, dst_len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flow->action.goto_tbl) {
|
||||
naction->has_goto_tbl = true;
|
||||
naction->goto_tbl = flow->action.goto_tbl;
|
||||
}
|
||||
|
||||
if (flow->action.write.group_id) {
|
||||
naction->has_group_id = true;
|
||||
naction->group_id = flow->action.write.group_id;
|
||||
}
|
||||
|
||||
if (flow->action.apply.new_vlan_id) {
|
||||
naction->has_new_vlan_id = true;
|
||||
naction->new_vlan_id = flow->action.apply.new_vlan_id;
|
||||
}
|
||||
|
||||
new->next = flow_context->list;
|
||||
flow_context->list = new;
|
||||
}
|
||||
|
||||
RockerOfDpaFlowList *qmp_query_rocker_of_dpa_flows(const char *name,
|
||||
bool has_tbl_id,
|
||||
uint32_t tbl_id,
|
||||
Error **errp)
|
||||
{
|
||||
struct rocker *r;
|
||||
struct world *w;
|
||||
struct of_dpa *of_dpa;
|
||||
struct of_dpa_flow_fill_context fill_context = {
|
||||
.list = NULL,
|
||||
.tbl_id = tbl_id,
|
||||
};
|
||||
|
||||
r = rocker_find(name);
|
||||
if (!r) {
|
||||
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
|
||||
"rocker %s not found", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
w = rocker_get_world(r, ROCKER_WORLD_TYPE_OF_DPA);
|
||||
if (!w) {
|
||||
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
|
||||
"rocker %s doesn't have OF-DPA world", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
of_dpa = world_private(w);
|
||||
|
||||
g_hash_table_foreach(of_dpa->flow_tbl, of_dpa_flow_fill, &fill_context);
|
||||
|
||||
return fill_context.list;
|
||||
}
|
||||
|
||||
struct of_dpa_group_fill_context {
|
||||
RockerOfDpaGroupList *list;
|
||||
uint8_t type;
|
||||
};
|
||||
|
||||
static void of_dpa_group_fill(void *key, void *value, void *user_data)
|
||||
{
|
||||
struct of_dpa_group *group = value;
|
||||
struct of_dpa_group_fill_context *flow_context = user_data;
|
||||
RockerOfDpaGroupList *new;
|
||||
RockerOfDpaGroup *ngroup;
|
||||
struct uint32List *id;
|
||||
int i;
|
||||
|
||||
if (flow_context->type != 9 &&
|
||||
flow_context->type != ROCKER_GROUP_TYPE_GET(group->id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
new = g_malloc0(sizeof(*new));
|
||||
ngroup = new->value = g_malloc0(sizeof(*ngroup));
|
||||
|
||||
ngroup->id = group->id;
|
||||
|
||||
ngroup->type = ROCKER_GROUP_TYPE_GET(group->id);
|
||||
|
||||
switch (ngroup->type) {
|
||||
case ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE:
|
||||
ngroup->has_vlan_id = true;
|
||||
ngroup->vlan_id = ROCKER_GROUP_VLAN_GET(group->id);
|
||||
ngroup->has_pport = true;
|
||||
ngroup->pport = ROCKER_GROUP_PORT_GET(group->id);
|
||||
ngroup->has_out_pport = true;
|
||||
ngroup->out_pport = group->l2_interface.out_pport;
|
||||
ngroup->has_pop_vlan = true;
|
||||
ngroup->pop_vlan = group->l2_interface.pop_vlan;
|
||||
break;
|
||||
case ROCKER_OF_DPA_GROUP_TYPE_L2_REWRITE:
|
||||
ngroup->has_index = true;
|
||||
ngroup->index = ROCKER_GROUP_INDEX_LONG_GET(group->id);
|
||||
ngroup->has_group_id = true;
|
||||
ngroup->group_id = group->l2_rewrite.group_id;
|
||||
if (group->l2_rewrite.vlan_id) {
|
||||
ngroup->has_set_vlan_id = true;
|
||||
ngroup->set_vlan_id = ntohs(group->l2_rewrite.vlan_id);
|
||||
}
|
||||
break;
|
||||
if (memcmp(group->l2_rewrite.src_mac.a, zero_mac.a, ETH_ALEN)) {
|
||||
ngroup->has_set_eth_src = true;
|
||||
ngroup->set_eth_src =
|
||||
qemu_mac_strdup_printf(group->l2_rewrite.src_mac.a);
|
||||
}
|
||||
if (memcmp(group->l2_rewrite.dst_mac.a, zero_mac.a, ETH_ALEN)) {
|
||||
ngroup->has_set_eth_dst = true;
|
||||
ngroup->set_eth_dst =
|
||||
qemu_mac_strdup_printf(group->l2_rewrite.dst_mac.a);
|
||||
}
|
||||
case ROCKER_OF_DPA_GROUP_TYPE_L2_FLOOD:
|
||||
case ROCKER_OF_DPA_GROUP_TYPE_L2_MCAST:
|
||||
ngroup->has_vlan_id = true;
|
||||
ngroup->vlan_id = ROCKER_GROUP_VLAN_GET(group->id);
|
||||
ngroup->has_index = true;
|
||||
ngroup->index = ROCKER_GROUP_INDEX_GET(group->id);
|
||||
for (i = 0; i < group->l2_flood.group_count; i++) {
|
||||
ngroup->has_group_ids = true;
|
||||
id = g_malloc0(sizeof(*id));
|
||||
id->value = group->l2_flood.group_ids[i];
|
||||
id->next = ngroup->group_ids;
|
||||
ngroup->group_ids = id;
|
||||
}
|
||||
break;
|
||||
case ROCKER_OF_DPA_GROUP_TYPE_L3_UCAST:
|
||||
ngroup->has_index = true;
|
||||
ngroup->index = ROCKER_GROUP_INDEX_LONG_GET(group->id);
|
||||
ngroup->has_group_id = true;
|
||||
ngroup->group_id = group->l3_unicast.group_id;
|
||||
if (group->l3_unicast.vlan_id) {
|
||||
ngroup->has_set_vlan_id = true;
|
||||
ngroup->set_vlan_id = ntohs(group->l3_unicast.vlan_id);
|
||||
}
|
||||
if (memcmp(group->l3_unicast.src_mac.a, zero_mac.a, ETH_ALEN)) {
|
||||
ngroup->has_set_eth_src = true;
|
||||
ngroup->set_eth_src =
|
||||
qemu_mac_strdup_printf(group->l3_unicast.src_mac.a);
|
||||
}
|
||||
if (memcmp(group->l3_unicast.dst_mac.a, zero_mac.a, ETH_ALEN)) {
|
||||
ngroup->has_set_eth_dst = true;
|
||||
ngroup->set_eth_dst =
|
||||
qemu_mac_strdup_printf(group->l3_unicast.dst_mac.a);
|
||||
}
|
||||
if (group->l3_unicast.ttl_check) {
|
||||
ngroup->has_ttl_check = true;
|
||||
ngroup->ttl_check = group->l3_unicast.ttl_check;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
new->next = flow_context->list;
|
||||
flow_context->list = new;
|
||||
}
|
||||
|
||||
RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name,
|
||||
bool has_type,
|
||||
uint8_t type,
|
||||
Error **errp)
|
||||
{
|
||||
struct rocker *r;
|
||||
struct world *w;
|
||||
struct of_dpa *of_dpa;
|
||||
struct of_dpa_group_fill_context fill_context = {
|
||||
.list = NULL,
|
||||
.type = type,
|
||||
};
|
||||
|
||||
r = rocker_find(name);
|
||||
if (!r) {
|
||||
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
|
||||
"rocker %s not found", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
w = rocker_get_world(r, ROCKER_WORLD_TYPE_OF_DPA);
|
||||
if (!w) {
|
||||
error_set(errp, ERROR_CLASS_GENERIC_ERROR,
|
||||
"rocker %s doesn't have OF-DPA world", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
of_dpa = world_private(w);
|
||||
|
||||
g_hash_table_foreach(of_dpa->group_tbl, of_dpa_group_fill, &fill_context);
|
||||
|
||||
return fill_context.list;
|
||||
}
|
||||
|
||||
static WorldOps of_dpa_ops = {
|
||||
.init = of_dpa_init,
|
||||
.uninit = of_dpa_uninit,
|
||||
|
||||
@@ -714,9 +714,7 @@ int xen_be_init(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL) < 0) {
|
||||
goto err;
|
||||
}
|
||||
qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL);
|
||||
|
||||
if (xen_xc == XC_HANDLER_INITIAL_VALUE) {
|
||||
/* Check if xen_init() have been called */
|
||||
|
||||
+1
-1
@@ -241,7 +241,7 @@ bool aio_dispatch(AioContext *ctx);
|
||||
bool aio_poll(AioContext *ctx, bool blocking);
|
||||
|
||||
/* Register a file descriptor and associated callbacks. Behaves very similarly
|
||||
* to qemu_set_fd_handler2. Unlike qemu_set_fd_handler2, these callbacks will
|
||||
* to qemu_set_fd_handler. Unlike qemu_set_fd_handler, these callbacks will
|
||||
* be invoked when using aio_poll().
|
||||
*
|
||||
* Code that invokes AIO completion functions should rely on this function
|
||||
|
||||
@@ -96,8 +96,7 @@ AioContext *qemu_get_aio_context(void);
|
||||
* that the main loop waits for.
|
||||
*
|
||||
* Calling qemu_notify_event is rarely necessary, because main loop
|
||||
* services (bottom halves and timers) call it themselves. One notable
|
||||
* exception occurs when using qemu_set_fd_handler2 (see below).
|
||||
* services (bottom halves and timers) call it themselves.
|
||||
*/
|
||||
void qemu_notify_event(void);
|
||||
|
||||
@@ -171,52 +170,6 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
|
||||
typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
|
||||
typedef int IOCanReadHandler(void *opaque);
|
||||
|
||||
/**
|
||||
* qemu_set_fd_handler2: Register a file descriptor with the main loop
|
||||
*
|
||||
* This function tells the main loop to wake up whenever one of the
|
||||
* following conditions is true:
|
||||
*
|
||||
* 1) if @fd_write is not %NULL, when the file descriptor is writable;
|
||||
*
|
||||
* 2) if @fd_read is not %NULL, when the file descriptor is readable.
|
||||
*
|
||||
* @fd_read_poll can be used to disable the @fd_read callback temporarily.
|
||||
* This is useful to avoid calling qemu_set_fd_handler2 every time the
|
||||
* client becomes interested in reading (or dually, stops being interested).
|
||||
* A typical example is when @fd is a listening socket and you want to bound
|
||||
* the number of active clients. Remember to call qemu_notify_event whenever
|
||||
* the condition may change from %false to %true.
|
||||
*
|
||||
* The callbacks that are set up by qemu_set_fd_handler2 are level-triggered.
|
||||
* If @fd_read does not read from @fd, or @fd_write does not write to @fd
|
||||
* until its buffers are full, they will be called again on the next
|
||||
* iteration.
|
||||
*
|
||||
* @fd: The file descriptor to be observed. Under Windows it must be
|
||||
* a #SOCKET.
|
||||
*
|
||||
* @fd_read_poll: A function that returns 1 if the @fd_read callback
|
||||
* should be fired. If the function returns 0, the main loop will not
|
||||
* end its iteration even if @fd becomes readable.
|
||||
*
|
||||
* @fd_read: A level-triggered callback that is fired if @fd is readable
|
||||
* at the beginning of a main loop iteration, or if it becomes readable
|
||||
* during one.
|
||||
*
|
||||
* @fd_write: A level-triggered callback that is fired when @fd is writable
|
||||
* at the beginning of a main loop iteration, or if it becomes writable
|
||||
* during one.
|
||||
*
|
||||
* @opaque: A pointer-sized value that is passed to @fd_read_poll,
|
||||
* @fd_read and @fd_write.
|
||||
*/
|
||||
int qemu_set_fd_handler2(int fd,
|
||||
IOCanReadHandler *fd_read_poll,
|
||||
IOHandler *fd_read,
|
||||
IOHandler *fd_write,
|
||||
void *opaque);
|
||||
|
||||
/**
|
||||
* qemu_set_fd_handler: Register a file descriptor with the main loop
|
||||
*
|
||||
@@ -245,10 +198,10 @@ int qemu_set_fd_handler2(int fd,
|
||||
*
|
||||
* @opaque: A pointer-sized value that is passed to @fd_read and @fd_write.
|
||||
*/
|
||||
int qemu_set_fd_handler(int fd,
|
||||
IOHandler *fd_read,
|
||||
IOHandler *fd_write,
|
||||
void *opaque);
|
||||
void qemu_set_fd_handler(int fd,
|
||||
IOHandler *fd_read,
|
||||
IOHandler *fd_write,
|
||||
void *opaque);
|
||||
|
||||
#ifdef CONFIG_POSIX
|
||||
/**
|
||||
|
||||
+2
-19
@@ -33,7 +33,6 @@
|
||||
#endif
|
||||
|
||||
typedef struct IOHandlerRecord {
|
||||
IOCanReadHandler *fd_read_poll;
|
||||
IOHandler *fd_read;
|
||||
IOHandler *fd_write;
|
||||
void *opaque;
|
||||
@@ -46,11 +45,7 @@ typedef struct IOHandlerRecord {
|
||||
static QLIST_HEAD(, IOHandlerRecord) io_handlers =
|
||||
QLIST_HEAD_INITIALIZER(io_handlers);
|
||||
|
||||
|
||||
/* XXX: fd_read_poll should be suppressed, but an API change is
|
||||
necessary in the character devices to suppress fd_can_read(). */
|
||||
int qemu_set_fd_handler2(int fd,
|
||||
IOCanReadHandler *fd_read_poll,
|
||||
void qemu_set_fd_handler(int fd,
|
||||
IOHandler *fd_read,
|
||||
IOHandler *fd_write,
|
||||
void *opaque)
|
||||
@@ -75,7 +70,6 @@ int qemu_set_fd_handler2(int fd,
|
||||
QLIST_INSERT_HEAD(&io_handlers, ioh, next);
|
||||
found:
|
||||
ioh->fd = fd;
|
||||
ioh->fd_read_poll = fd_read_poll;
|
||||
ioh->fd_read = fd_read;
|
||||
ioh->fd_write = fd_write;
|
||||
ioh->opaque = opaque;
|
||||
@@ -83,15 +77,6 @@ int qemu_set_fd_handler2(int fd,
|
||||
ioh->deleted = 0;
|
||||
qemu_notify_event();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qemu_set_fd_handler(int fd,
|
||||
IOHandler *fd_read,
|
||||
IOHandler *fd_write,
|
||||
void *opaque)
|
||||
{
|
||||
return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
|
||||
}
|
||||
|
||||
void qemu_iohandler_fill(GArray *pollfds)
|
||||
@@ -103,9 +88,7 @@ void qemu_iohandler_fill(GArray *pollfds)
|
||||
|
||||
if (ioh->deleted)
|
||||
continue;
|
||||
if (ioh->fd_read &&
|
||||
(!ioh->fd_read_poll ||
|
||||
ioh->fd_read_poll(ioh->opaque) != 0)) {
|
||||
if (ioh->fd_read) {
|
||||
events |= G_IO_IN | G_IO_HUP | G_IO_ERR;
|
||||
}
|
||||
if (ioh->fd_write) {
|
||||
|
||||
+1
-2
@@ -100,8 +100,7 @@ static int qemu_signal_init(void)
|
||||
|
||||
fcntl_setfl(sigfd, O_NONBLOCK);
|
||||
|
||||
qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
|
||||
(void *)(intptr_t)sigfd);
|
||||
qemu_set_fd_handler(sigfd, sigfd_handler, NULL, (void *)(intptr_t)sigfd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+3
-3
@@ -49,7 +49,7 @@ static void exec_accept_incoming_migration(void *opaque)
|
||||
{
|
||||
QEMUFile *f = opaque;
|
||||
|
||||
qemu_set_fd_handler2(qemu_get_fd(f), NULL, NULL, NULL, NULL);
|
||||
qemu_set_fd_handler(qemu_get_fd(f), NULL, NULL, NULL);
|
||||
process_incoming_migration(f);
|
||||
}
|
||||
|
||||
@@ -64,6 +64,6 @@ void exec_start_incoming_migration(const char *command, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_set_fd_handler2(qemu_get_fd(f), NULL,
|
||||
exec_accept_incoming_migration, NULL, f);
|
||||
qemu_set_fd_handler(qemu_get_fd(f), exec_accept_incoming_migration, NULL,
|
||||
f);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user