From 8277c15151e7407e07e2286cadb1d1a0c9b16984 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 6 Sep 2011 16:18:57 +0800 Subject: [PATCH] link-state: qemu: Add monitor handling for link state modification This patch adds handlers for modification of guest's interface link state. Both HMP and QMP commands are supported, but as the link state functionality is from the beginning supported in QMP the HMP code will probably never be used. --- src/qemu/qemu_monitor.c | 19 +++++++++++++++ src/qemu/qemu_monitor.h | 4 ++++ src/qemu/qemu_monitor_json.c | 23 ++++++++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++++ src/qemu/qemu_monitor_text.c | 46 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_text.h | 4 ++++ 6 files changed, 100 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 16bdc594d3..fca8fa41ab 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1135,6 +1135,25 @@ int qemuMonitorGetCPUInfo(qemuMonitorPtr mon, return ret; } +int qemuMonitorSetLink(qemuMonitorPtr mon, + const char *name, + enum virDomainNetInterfaceLinkState state) +{ + int ret; + VIR_DEBUG("mon=%p, name=%p:%s, state=%u", mon, name, name, state); + + if (!mon || !name) { + qemuReportError(VIR_ERR_INVALID_ARG, + _("monitor || name must not be NULL")); + return -1; + } + + if (mon->json) + ret = qemuMonitorJSONSetLink(mon, name, state); + else + ret = qemuMonitorTextSetLink(mon, name, state); + return ret; +} int qemuMonitorGetVirtType(qemuMonitorPtr mon, int *virtType) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 95956041ae..390eeff784 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -145,6 +145,10 @@ void qemuMonitorUnlock(qemuMonitorPtr mon); int qemuMonitorRef(qemuMonitorPtr mon); int qemuMonitorUnref(qemuMonitorPtr mon) ATTRIBUTE_RETURN_CHECK; +int qemuMonitorSetLink(qemuMonitorPtr mon, + const char *name, + enum virDomainNetInterfaceLinkState state) ; + /* These APIs are for use by the internal Text/JSON monitor impl code only */ char *qemuMonitorNextCommandID(qemuMonitorPtr mon); int qemuMonitorSend(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index b6368a239c..3a81ec8b06 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -955,6 +955,29 @@ int qemuMonitorJSONSystemPowerdown(qemuMonitorPtr mon) return ret; } +int qemuMonitorJSONSetLink(qemuMonitorPtr mon, + const char *name, + enum virDomainNetInterfaceLinkState state) +{ + + int ret; + virJSONValuePtr reply = NULL; + virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("set_link", + "s:name", name, + "b:up", state != VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN, + NULL); + + if (!cmd) + return -1; + + if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + virJSONValueFree(cmd); + virJSONValueFree(reply); + + return ret; +} int qemuMonitorJSONSystemReset(qemuMonitorPtr mon) { diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 28c4a093a3..dfeba7ec8b 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -241,4 +241,8 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon, virDomainBlockJobInfoPtr info, int mode); +int qemuMonitorJSONSetLink(qemuMonitorPtr mon, + const char *name, + enum virDomainNetInterfaceLinkState state); + #endif /* QEMU_MONITOR_JSON_H */ diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index b2a29e030b..0b50ba2d42 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -433,6 +433,52 @@ int qemuMonitorTextSystemPowerdown(qemuMonitorPtr mon) { return 0; } +int qemuMonitorTextSetLink(qemuMonitorPtr mon, const char *name, enum virDomainNetInterfaceLinkState state) { + char *info = NULL; + char *cmd = NULL; + const char *st_str = NULL; + + /* determine state */ + if (state == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) + st_str = "off"; + else + st_str = "on"; + + if (virAsprintf(&cmd, "set_link %s %s", name, st_str) < 0) { + virReportOOMError(); + goto error; + } + if (qemuMonitorHMPCommand(mon, cmd, &info) < 0) { + qemuReportError(VIR_ERR_OPERATION_FAILED, + "%s", _("set_link operation failed")); + goto error; + } + + /* check if set_link command is supported */ + if (strstr(info, "\nunknown ")) { + qemuReportError(VIR_ERR_NO_SUPPORT, + "%s", + _("\'set_link\' not supported by this qemu")); + goto error; + } + + /* check if qemu didn't reject device name */ + if (strstr(info, "\nDevice ")) { + qemuReportError(VIR_ERR_OPERATION_FAILED, + "%s", _("device name rejected")); + goto error; + } + + VIR_FREE(info); + VIR_FREE(cmd); + return 0; + +error: + VIR_FREE(info); + VIR_FREE(cmd); + + return -1; +} int qemuMonitorTextSystemReset(qemuMonitorPtr mon) { char *info; diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index 96d5d78c4c..7cc317223f 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -234,4 +234,8 @@ int qemuMonitorTextBlockJob(qemuMonitorPtr mon, virDomainBlockJobInfoPtr info, int mode); +int qemuMonitorTextSetLink(qemuMonitorPtr mon, + const char *name, + enum virDomainNetInterfaceLinkState state); + #endif /* QEMU_MONITOR_TEXT_H */