net: do not exit on "netdev_add help" monitor command

"netdev_add help" is causing QEMU to exit because the code that
invokes show_netdevs is shared between CLI and HMP processing.
Move the check to the callers so that exit(0) remains only
in the CLI flow.

"netdev_add help" is not fixed by this patch; that is left for
later work.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
This commit is contained in:
Paolo Bonzini 2020-11-11 05:52:22 -05:00 committed by Jason Wang
parent c2cb511634
commit ad6f932fe8
3 changed files with 43 additions and 36 deletions

View File

@ -199,6 +199,7 @@ extern const char *host_net_devices[];
/* from net.c */ /* from net.c */
int net_client_parse(QemuOptsList *opts_list, const char *str); int net_client_parse(QemuOptsList *opts_list, const char *str);
void show_netdevs(void);
int net_init_clients(Error **errp); int net_init_clients(Error **errp);
void net_check_clients(void); void net_check_clients(void);
void net_cleanup(void); void net_cleanup(void);

View File

@ -24,6 +24,7 @@
#include "qemu/option.h" #include "qemu/option.h"
#include "qemu/timer.h" #include "qemu/timer.h"
#include "qemu/sockets.h" #include "qemu/sockets.h"
#include "qemu/help_option.h"
#include "monitor/monitor-internal.h" #include "monitor/monitor-internal.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/clone-visitor.h" #include "qapi/clone-visitor.h"
@ -1631,7 +1632,12 @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict)
{ {
Error *err = NULL; Error *err = NULL;
QemuOpts *opts; QemuOpts *opts;
const char *type = qdict_get_try_str(qdict, "type");
if (type && is_help_option(type)) {
show_netdevs();
return;
}
opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err); opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
if (err) { if (err) {
goto out; goto out;

View File

@ -44,6 +44,7 @@
#include "qemu/config-file.h" #include "qemu/config-file.h"
#include "qemu/ctype.h" #include "qemu/ctype.h"
#include "qemu/iov.h" #include "qemu/iov.h"
#include "qemu/qemu-print.h"
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
#include "qemu/option.h" #include "qemu/option.h"
#include "qapi/error.h" #include "qapi/error.h"
@ -1025,7 +1026,7 @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
return 0; return 0;
} }
static void show_netdevs(void) void show_netdevs(void)
{ {
int idx; int idx;
const char *available_netdevs[] = { const char *available_netdevs[] = {
@ -1055,9 +1056,9 @@ static void show_netdevs(void)
#endif #endif
}; };
printf("Available netdev backend types:\n"); qemu_printf("Available netdev backend types:\n");
for (idx = 0; idx < ARRAY_SIZE(available_netdevs); idx++) { for (idx = 0; idx < ARRAY_SIZE(available_netdevs); idx++) {
puts(available_netdevs[idx]); qemu_printf("%s\n", available_netdevs[idx]);
} }
} }
@ -1068,42 +1069,35 @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
int ret = -1; int ret = -1;
Visitor *v = opts_visitor_new(opts); Visitor *v = opts_visitor_new(opts);
const char *type = qemu_opt_get(opts, "type"); /* Parse convenience option format ip6-net=fec0::0[/64] */
const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
if (is_netdev && type && is_help_option(type)) { if (ip6_net) {
show_netdevs(); char *prefix_addr;
exit(0); unsigned long prefix_len = 64; /* Default 64bit prefix length. */
} else {
/* Parse convenience option format ip6-net=fec0::0[/64] */
const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
if (ip6_net) { substrings = g_strsplit(ip6_net, "/", 2);
char *prefix_addr; if (!substrings || !substrings[0]) {
unsigned long prefix_len = 64; /* Default 64bit prefix length. */ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
"a valid IPv6 prefix");
substrings = g_strsplit(ip6_net, "/", 2); goto out;
if (!substrings || !substrings[0]) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
"a valid IPv6 prefix");
goto out;
}
prefix_addr = substrings[0];
/* Handle user-specified prefix length. */
if (substrings[1] &&
qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
{
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
"ipv6-prefixlen", "a number");
goto out;
}
qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
&error_abort);
qemu_opt_unset(opts, "ipv6-net");
} }
prefix_addr = substrings[0];
/* Handle user-specified prefix length. */
if (substrings[1] &&
qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
{
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
"ipv6-prefixlen", "a number");
goto out;
}
qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
&error_abort);
qemu_opt_unset(opts, "ipv6-net");
} }
/* Create an ID for -net if the user did not specify one */ /* Create an ID for -net if the user did not specify one */
@ -1421,6 +1415,12 @@ static int net_init_client(void *dummy, QemuOpts *opts, Error **errp)
static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp) static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp)
{ {
const char *type = qemu_opt_get(opts, "type");
if (type && is_help_option(type)) {
show_netdevs();
exit(0);
}
return net_client_init(opts, true, errp); return net_client_init(opts, true, errp);
} }