[libvirt] problems with remote authentication with policykit
by Jim Paris
Hi,
I have libvirt 0.6.4 running kvm instances on a headless server.
I'm using virt-manager 0.7.0 to manage them. In the past, I would SSH
in and run virt-manager as root. Since running GTK apps as root is no
good, I've switched to policykit authentication. By default, the
libvirt policy only allows management if the user is in the active
host session, which isn't the case with my SSH logins. Therefore
I've added an override in /etc/PolicyKit/PolicyKit.conf:
<match action="org.libvirt.unix.manage">
<return result="auth_admin_keep_session"/>
</match>
Now things generally work fine when SSHed in:
- as root, virsh gives ro and rw access with no password
- as jim, virsh gives ro access with no password, but requests a password for rw
- as jim, virsh asks for a password for rw access
But when accessing remotely, I get no useful error, and a hang:
$ virsh -c qemu+ssh://jim@server/system
libvir: Remote error : authentication failed
<process hangs here>
$ virsh --readonly -c qemu+ssh://jim@server/system
libvir: Remote error : authentication failed
<process hangs here>
Furthermore, on the server, this leaves "nc" processes running,
and eventually there are enough that libvirtd stops accepting new
connections.
I was also getting strange errors including:
polkit-grant-helper: given auth type (8 -> yes) is bogus
but now I can't reproduce that for the life of me, I have no idea what
changed.
Is policykit authentication supposed to work over qemu+ssh?
I was hoping it would at least not break the --readonly case.
-jim
15 years, 5 months
[libvirt] netbsd5.0
by Fabien Georget
Hi
I want to run netbsd 5.0 with kvm in virt-manager. It works with
default
option but any network devices is recognized by the netbsd kernel.
To enable network with qemu-kvm, we had to disable the acpi and
add other
options like -tdf, -localtime ... This is an an example who works :
http://ghantoos.org/2009/05/12/my-first-shot-of-netbsd/ (An
explanation I found
is that the new scheduler in netbsd 5.0 cause some problems with
virtualization based on VT)
Currently, I have not found the way to do it with libvirt (and I don't
think
it is possible with virt-manager).
It be very helpeful if these features can be add to libvirt.
Thanks
Fabien Georget
15 years, 5 months
[libvirt] [PATCH] Activate virtual networks initialized in custom test driver.
by Cole Robinson
If specifying a custom test driver, virtual networks were not 'activated'
on driver init. This differs from the behavior of domains and storage pools,
so fix it. Also improve a couple error messages in that area.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
src/test.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/test.c b/src/test.c
index 1661144..6f07462 100644
--- a/src/test.c
+++ b/src/test.c
@@ -462,7 +462,8 @@ static int testOpenFromFile(virConnectPtr conn,
if (!(xml = xmlReadFd(fd, file, NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
- testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("host"));
+ testError(NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Invalid XML in file '%s'"), file);
goto error;
}
close(fd);
@@ -470,7 +471,8 @@ static int testOpenFromFile(virConnectPtr conn,
root = xmlDocGetRootElement(xml);
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "node"))) {
- testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node"));
+ testError(NULL, VIR_ERR_XML_ERROR, "%s",
+ _("Root element is not 'node'"));
goto error;
}
@@ -622,6 +624,7 @@ static int testOpenFromFile(virConnectPtr conn,
goto error;
}
net->persistent = 1;
+ net->active = 1;
virNetworkObjUnlock(net);
}
VIR_FREE(networks);
--
1.6.3.2
15 years, 5 months
[libvirt] [PATCH] Fix storage handling for custom test driver.
by Cole Robinson
If using a custom test driver, storage pool file parsing was broken, and
storage volume parsing was never implemented. Fix these issues, and add
some examples in docs/
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
docs/testnode.xml | 3 ++
docs/testpool.xml | 15 +++++++++
docs/testvol.xml | 6 +++
src/test.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 112 insertions(+), 0 deletions(-)
create mode 100644 docs/testpool.xml
create mode 100644 docs/testvol.xml
diff --git a/docs/testnode.xml b/docs/testnode.xml
index be7121d..1ad7a10 100644
--- a/docs/testnode.xml
+++ b/docs/testnode.xml
@@ -11,6 +11,9 @@
<domain file="testdomfc4.xml"/>
<network file="testnetpriv.xml"/>
<network file="testnetdef.xml"/>
+ <pool file="testpool.xml">
+ <volume file="testvol.xml"/>
+ </pool>
<cpu>
<mhz>6000</mhz>
diff --git a/docs/testpool.xml b/docs/testpool.xml
new file mode 100644
index 0000000..c1a8dff
--- /dev/null
+++ b/docs/testpool.xml
@@ -0,0 +1,15 @@
+<pool type='dir'>
+ <name>default-pool</name>
+ <uuid>35bb2ad9-388a-cdfe-461a-b8907f6e53fe</uuid>
+ <capacity>107374182400</capacity>
+ <allocation>0</allocation>
+ <available>107374182400</available>
+ <target>
+ <path>/default-pool</path>
+ <permissions>
+ <mode>0700</mode>
+ <owner>10736</owner>
+ <group>10736</group>
+ </permissions>
+ </target>
+</pool>
diff --git a/docs/testvol.xml b/docs/testvol.xml
new file mode 100644
index 0000000..00198f8
--- /dev/null
+++ b/docs/testvol.xml
@@ -0,0 +1,6 @@
+<volume>
+ <name>default-vol</name>
+ <capacity>1000000</capacity>
+ <allocation>50000</allocation>
+ <target/>
+</volume>
diff --git a/src/test.c b/src/test.c
index 6874d63..1661144 100644
--- a/src/test.c
+++ b/src/test.c
@@ -341,6 +341,87 @@ static char *testBuildFilename(const char *relativeTo,
}
}
+static int testOpenVolumesForPool(virConnectPtr conn,
+ xmlDocPtr xml,
+ xmlXPathContextPtr ctxt,
+ const char *file,
+ virStoragePoolObjPtr pool,
+ int poolidx) {
+ char *vol_xpath;
+ int i, ret, func_ret = -1;
+ xmlNodePtr *vols = NULL;
+ virStorageVolDefPtr def;
+
+ /* Find storage volumes */
+ if (virAsprintf(&vol_xpath, "/node/pool[%d]/volume", poolidx) < 0) {
+ virReportOOMError(NULL);
+ goto error;
+ }
+
+ ret = virXPathNodeSet(conn, vol_xpath, ctxt, &vols);
+ VIR_FREE(vol_xpath);
+ if (ret < 0) {
+ testError(NULL, VIR_ERR_XML_ERROR,
+ _("node vol list for pool '%s'"), pool->def->name);
+ goto error;
+ }
+
+ for (i = 0 ; i < ret ; i++) {
+ char *relFile = virXMLPropString(vols[i], "file");
+ if (relFile != NULL) {
+ char *absFile = testBuildFilename(file, relFile);
+ VIR_FREE(relFile);
+ if (!absFile) {
+ testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("resolving volume filename"));
+ goto error;
+ }
+
+ def = virStorageVolDefParseFile(conn, pool->def, absFile);
+ VIR_FREE(absFile);
+ if (!def)
+ goto error;
+ } else {
+ if ((def = virStorageVolDefParseNode(conn, pool->def, xml,
+ vols[i])) == NULL) {
+ goto error;
+ }
+ }
+
+ if (VIR_REALLOC_N(pool->volumes.objs,
+ pool->volumes.count+1) < 0) {
+ virReportOOMError(conn);
+ goto error;
+ }
+
+ if (virAsprintf(&def->target.path, "%s/%s",
+ pool->def->target.path,
+ def->name) == -1) {
+ virReportOOMError(conn);
+ goto error;
+ }
+
+ def->key = strdup(def->target.path);
+ if (def->key == NULL) {
+ virReportOOMError(conn);
+ goto error;
+ }
+
+ pool->def->allocation += def->allocation;
+ pool->def->available = (pool->def->capacity -
+ pool->def->allocation);
+
+ pool->volumes.objs[pool->volumes.count++] = def;
+ def = NULL;
+ }
+
+ func_ret = 0;
+error:
+ virStorageVolDefFree(def);
+ VIR_FREE(vols);
+ return func_ret;
+}
+
static int testOpenFromFile(virConnectPtr conn,
const char *file) {
int fd = -1, i, ret;
@@ -586,6 +667,13 @@ static int testOpenFromFile(virConnectPtr conn,
goto error;
}
pool->active = 1;
+
+ /* Find storage volumes */
+ if (testOpenVolumesForPool(conn, xml, ctxt, file, pool, i+1) < 0) {
+ virStoragePoolObjUnlock(pool);
+ goto error;
+ }
+
virStoragePoolObjUnlock(pool);
}
VIR_FREE(pools);
--
1.6.3.2
15 years, 5 months
[libvirt] [PATCH] Fix segfault if storage pool has no type attribute (possibly others)
by Cole Robinson
virEnumFromString doesn't check for a NULL string, and will segfault if
passed one. Lots of calling code protects against this, but at least
/pool/@type parsing does not.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
src/util.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/src/util.c b/src/util.c
index d8ab37f..8b746f5 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1622,6 +1622,9 @@ int virEnumFromString(const char *const*types,
const char *type)
{
unsigned int i;
+ if (!type)
+ return -1;
+
for (i = 0 ; i < ntypes ; i++)
if (STREQ(types[i], type))
return i;
--
1.6.3.2
15 years, 5 months
[libvirt] [PATCH 0/1] Fix NPIV on older kernels
by David Allan
Ok, I redid the patch into a minimal change that fixes NPIV on older
kernels. I'll resubmit the rest of it when I decide how I want to
deal with the problem of things moving around in /sys.
Dave
15 years, 5 months
[libvirt] [PATCH] Add virsh commands for virInterface* functions - Take 2
by Laine Stump
This is a resubmission of the virsh commands to expose virInterface*
functionality. I've made the following changes from the original:
1) command names changed from if-* to iface-*
2) "if-create" is now "iface-start"
3) iface-edit implementation is manually included directly in virsh.c
rather than being generated with a makefile rule.
4) iface-list now has options --inactive and --all, similar to net-list.
(4) depends on new functions contained in the patch I submitted yesterday.
All of this builds and appears to be correct, but is non-functional
until either the netcf backend or test driver backend is
committed. The netcf backend is waiting on something in netcf to
provide the functionality required for
virConnectListDefinedInterfaces(), and the test driver is waiting on
XML parsing/formatting functions (and needs a small amount of rework
to support inactive interfaces).
---
src/virsh.c | 536 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 536 insertions(+), 0 deletions(-)
diff --git a/src/virsh.c b/src/virsh.c
index f5248d9..6ab6182 100644
--- a/src/virsh.c
+++ b/src/virsh.c
@@ -228,6 +228,7 @@ static int vshCommandOptBool(const vshCmd *cmd, const char *name);
#define VSH_BYID (1 << 1)
#define VSH_BYUUID (1 << 2)
#define VSH_BYNAME (1 << 3)
+#define VSH_BYMAC (1 << 4)
static virDomainPtr vshCommandOptDomainBy(vshControl *ctl, const vshCmd *cmd,
char **name, int flag);
@@ -244,6 +245,14 @@ static virNetworkPtr vshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd,
vshCommandOptNetworkBy(_ctl, _cmd, _name, \
VSH_BYUUID|VSH_BYNAME)
+static virInterfacePtr vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd,
+ char **name, int flag);
+
+/* default is lookup by Name and MAC */
+#define vshCommandOptInterface(_ctl, _cmd, _name) \
+ vshCommandOptInterfaceBy(_ctl, _cmd, _name, \
+ VSH_BYMAC|VSH_BYNAME)
+
static virStoragePoolPtr vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd,
const char *optname, char **name, int flag);
@@ -275,6 +284,10 @@ static const char *vshDomainVcpuStateToString(int state);
static int vshConnectionUsability(vshControl *ctl, virConnectPtr conn,
int showerror);
+static char *editWriteToTempFile (vshControl *ctl, const char *doc);
+static int editFile (vshControl *ctl, const char *filename);
+static char *editReadBackFile (vshControl *ctl, const char *filename);
+
static void *_vshMalloc(vshControl *ctl, size_t sz, const char *filename, int line);
#define vshMalloc(_ctl, _sz) _vshMalloc(_ctl, _sz, __FILE__, __LINE__)
@@ -2690,6 +2703,106 @@ cmdNetworkDumpXML(vshControl *ctl, const vshCmd *cmd)
/*
+ * "iface-edit" command
+ */
+static const vshCmdInfo info_interface_edit[] = {
+ {"help", gettext_noop("edit XML configuration for a physical host interface")},
+ {"desc", gettext_noop("Edit the XML configuration for a physical host interface.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_edit[] = {
+ {"interface", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("interface name or MAC address")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdInterfaceEdit (vshControl *ctl, const vshCmd *cmd)
+{
+ int ret = FALSE;
+ virInterfacePtr iface = NULL;
+ char *tmp = NULL;
+ char *doc = NULL;
+ char *doc_edited = NULL;
+ char *doc_reread = NULL;
+ int flags = 0;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ goto cleanup;
+
+ iface = vshCommandOptInterface (ctl, cmd, NULL);
+ if (iface == NULL)
+ goto cleanup;
+
+ /* Get the XML configuration of the interface. */
+ doc = virInterfaceGetXMLDesc (iface, flags);
+ if (!doc)
+ goto cleanup;
+
+ /* Create and open the temporary file. */
+ tmp = editWriteToTempFile (ctl, doc);
+ if (!tmp) goto cleanup;
+
+ /* Start the editor. */
+ if (editFile (ctl, tmp) == -1) goto cleanup;
+
+ /* Read back the edited file. */
+ doc_edited = editReadBackFile (ctl, tmp);
+ if (!doc_edited) goto cleanup;
+
+ unlink (tmp);
+ tmp = NULL;
+
+ /* Compare original XML with edited. Has it changed at all? */
+ if (STREQ (doc, doc_edited)) {
+ vshPrint (ctl, _("Interface %s XML configuration not changed.\n"),
+ virInterfaceGetName (iface));
+ ret = TRUE;
+ goto cleanup;
+ }
+
+ /* Now re-read the interface XML. Did someone else change it while
+ * it was being edited? This also catches problems such as us
+ * losing a connection or the interface going away.
+ */
+ doc_reread = virInterfaceGetXMLDesc (iface, flags);
+ if (!doc_reread)
+ goto cleanup;
+
+ if (STRNEQ (doc, doc_reread)) {
+ vshError (ctl, FALSE,
+ "%s", _("ERROR: the XML configuration was changed by another user"));
+ goto cleanup;
+ }
+
+ /* Everything checks out, so redefine the interface. */
+ virInterfaceFree (iface);
+ iface = virInterfaceDefineXML (ctl->conn, doc_edited, 0);
+ if (!iface)
+ goto cleanup;
+
+ vshPrint (ctl, _("Interface %s XML configuration edited.\n"),
+ virInterfaceGetName(iface));
+
+ ret = TRUE;
+
+cleanup:
+ if (iface)
+ virInterfaceFree (iface);
+
+ free (doc);
+ free (doc_edited);
+ free (doc_reread);
+
+ if (tmp) {
+ unlink (tmp);
+ free (tmp);
+ }
+
+ return ret;
+}
+
+/*
* "net-list" command
*/
static const vshCmdInfo info_network_list[] = {
@@ -2955,6 +3068,378 @@ cmdNetworkUuid(vshControl *ctl, const vshCmd *cmd)
}
+/**************************************************************************/
+/*
+ * "iface-list" command
+ */
+static const vshCmdInfo info_interface_list[] = {
+ {"help", gettext_noop("list physical host interfaces")},
+ {"desc", gettext_noop("Returns list of physical host interfaces.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_list[] = {
+ {"inactive", VSH_OT_BOOL, 0, gettext_noop("list inactive interfaces")},
+ {"all", VSH_OT_BOOL, 0, gettext_noop("list inactive & active interfaces")},
+ {NULL, 0, 0, NULL}
+};
+static int
+cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
+{
+ int inactive = vshCommandOptBool(cmd, "inactive");
+ int all = vshCommandOptBool(cmd, "all");
+ int active = !inactive || all ? 1 : 0;
+ int maxactive = 0, maxinactive = 0, i;
+ char **activeNames = NULL, **inactiveNames = NULL;
+ inactive |= all;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (active) {
+ maxactive = virConnectNumOfInterfaces(ctl->conn);
+ if (maxactive < 0) {
+ vshError(ctl, FALSE, "%s", _("Failed to list active interfaces"));
+ return FALSE;
+ }
+ if (maxactive) {
+ activeNames = vshMalloc(ctl, sizeof(char *) * maxactive);
+
+ if ((maxactive = virConnectListInterfaces(ctl->conn, activeNames,
+ maxactive)) < 0) {
+ vshError(ctl, FALSE, "%s", _("Failed to list active interfaces"));
+ free(activeNames);
+ return FALSE;
+ }
+
+ qsort(&activeNames[0], maxactive, sizeof(char *), namesorter);
+ }
+ }
+ if (inactive) {
+ maxinactive = virConnectNumOfDefinedInterfaces(ctl->conn);
+ if (maxinactive < 0) {
+ vshError(ctl, FALSE, "%s", _("Failed to list inactive interfaces"));
+ free(activeNames);
+ return FALSE;
+ }
+ if (maxinactive) {
+ inactiveNames = vshMalloc(ctl, sizeof(char *) * maxinactive);
+
+ if ((maxinactive = virConnectListDefinedInterfaces(ctl->conn, inactiveNames, maxinactive)) < 0) {
+ vshError(ctl, FALSE, "%s", _("Failed to list inactive interfaces"));
+ free(activeNames);
+ free(inactiveNames);
+ return FALSE;
+ }
+
+ qsort(&inactiveNames[0], maxinactive, sizeof(char*), namesorter);
+ }
+ }
+ vshPrintExtra(ctl, "%-20s %-10s %s\n", _("Name"), _("State"), _("MAC Address"));
+ vshPrintExtra(ctl, "--------------------------------------------\n");
+
+ for (i = 0; i < maxactive; i++) {
+ virInterfacePtr iface = virInterfaceLookupByName(ctl->conn, activeNames[i]);
+ const char *autostartStr;
+ int autostart = 0;
+
+ /* this kind of work with interfaces is not atomic */
+ if (!iface) {
+ free(activeNames[i]);
+ continue;
+ }
+
+ vshPrint(ctl, "%-20s %-10s %s\n",
+ virInterfaceGetName(iface),
+ _("active"),
+ virInterfaceGetMACString(iface));
+ virInterfaceFree(iface);
+ free(activeNames[i]);
+ }
+ for (i = 0; i < maxinactive; i++) {
+ virInterfacePtr iface = virInterfaceLookupByName(ctl->conn, inactiveNames[i]);
+ const char *autostartStr;
+ int autostart = 0;
+
+ /* this kind of work with interfaces is not atomic */
+ if (!iface) {
+ free(inactiveNames[i]);
+ continue;
+ }
+
+ vshPrint(ctl, "%-20s %-10s %s\n",
+ virInterfaceGetName(iface),
+ _("inactive"),
+ virInterfaceGetMACString(iface));
+ virInterfaceFree(iface);
+ free(inactiveNames[i]);
+ }
+ free(activeNames);
+ free(inactiveNames);
+ return TRUE;
+
+}
+
+/*
+ * "iface-name" command
+ */
+static const vshCmdInfo info_interface_name[] = {
+ {"help", gettext_noop("convert an interface MAC address to interface name")},
+ {"desc", ""},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_name[] = {
+ {"interface", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("interface mac")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdInterfaceName(vshControl *ctl, const vshCmd *cmd)
+{
+ virInterfacePtr iface;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+ if (!(iface = vshCommandOptInterfaceBy(ctl, cmd, NULL,
+ VSH_BYMAC)))
+ return FALSE;
+
+ vshPrint(ctl, "%s\n", virInterfaceGetName(iface));
+ virInterfaceFree(iface);
+ return TRUE;
+}
+
+/*
+ * "iface-mac" command
+ */
+static const vshCmdInfo info_interface_mac[] = {
+ {"help", gettext_noop("convert an interface name to interface MAC address")},
+ {"desc", ""},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_mac[] = {
+ {"interface", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("interface name")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdInterfaceMAC(vshControl *ctl, const vshCmd *cmd)
+{
+ virInterfacePtr iface;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+ if (!(iface = vshCommandOptInterfaceBy(ctl, cmd, NULL,
+ VSH_BYNAME)))
+ return FALSE;
+
+ vshPrint(ctl, "%s\n", virInterfaceGetMACString(iface));
+ virInterfaceFree(iface);
+ return TRUE;
+}
+
+/*
+ * "iface-dumpxml" command
+ */
+static const vshCmdInfo info_interface_dumpxml[] = {
+ {"help", gettext_noop("interface information in XML")},
+ {"desc", gettext_noop("Output the physical host interface information as an XML dump to stdout.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_dumpxml[] = {
+ {"interface", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("interface name or MAC address")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdInterfaceDumpXML(vshControl *ctl, const vshCmd *cmd)
+{
+ virInterfacePtr iface;
+ int ret = TRUE;
+ char *dump;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(iface = vshCommandOptInterface(ctl, cmd, NULL)))
+ return FALSE;
+
+ dump = virInterfaceGetXMLDesc(iface, 0);
+ if (dump != NULL) {
+ printf("%s", dump);
+ free(dump);
+ } else {
+ ret = FALSE;
+ }
+
+ virInterfaceFree(iface);
+ return ret;
+}
+
+/*
+ * "iface-define" command
+ */
+static const vshCmdInfo info_interface_define[] = {
+ {"help", gettext_noop("define (but don't start) a physical host interface from an XML file")},
+ {"desc", gettext_noop("Define a physical host interface.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_define[] = {
+ {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("file containing an XML interface description")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdInterfaceDefine(vshControl *ctl, const vshCmd *cmd)
+{
+ virInterfacePtr interface;
+ char *from;
+ int found;
+ int ret = TRUE;
+ char *buffer;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ from = vshCommandOptString(cmd, "file", &found);
+ if (!found)
+ return FALSE;
+
+ if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0)
+ return FALSE;
+
+ interface = virInterfaceDefineXML(ctl->conn, buffer, 0);
+ free (buffer);
+
+ if (interface != NULL) {
+ vshPrint(ctl, _("Interface %s defined from %s\n"),
+ virInterfaceGetName(interface), from);
+ } else {
+ vshError(ctl, FALSE, _("Failed to define interface from %s"), from);
+ ret = FALSE;
+ }
+ return ret;
+}
+
+/*
+ * "iface-undefine" command
+ */
+static const vshCmdInfo info_interface_undefine[] = {
+ {"help", gettext_noop("undefine a physical host interface (remove it from configuration)")},
+ {"desc", gettext_noop("undefine an interface.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_undefine[] = {
+ {"interface", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("interface name or MAC address")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdInterfaceUndefine(vshControl *ctl, const vshCmd *cmd)
+{
+ virInterfacePtr iface;
+ int ret = TRUE;
+ char *name;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(iface = vshCommandOptInterface(ctl, cmd, &name)))
+ return FALSE;
+
+ if (virInterfaceUndefine(iface) == 0) {
+ vshPrint(ctl, _("Interface %s undefined\n"), name);
+ } else {
+ vshError(ctl, FALSE, _("Failed to undefine interface %s"), name);
+ ret = FALSE;
+ }
+
+ virInterfaceFree(iface);
+ return ret;
+}
+
+/*
+ * "iface-start" command
+ */
+static const vshCmdInfo info_interface_start[] = {
+ {"help", gettext_noop("start a physical host interface (enable it / \"if-up\")")},
+ {"desc", gettext_noop("start a physical host interface.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_start[] = {
+ {"interface", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("interface name or MAC address")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdInterfaceStart(vshControl *ctl, const vshCmd *cmd)
+{
+ virInterfacePtr iface;
+ int ret = TRUE;
+ char *name;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(iface = vshCommandOptInterface(ctl, cmd, &name)))
+ return FALSE;
+
+ if (virInterfaceCreate(iface, 0) == 0) {
+ vshPrint(ctl, _("Interface %s started\n"), name);
+ } else {
+ vshError(ctl, FALSE, _("Failed to start interface %s"), name);
+ ret = FALSE;
+ }
+
+ virInterfaceFree(iface);
+ return ret;
+}
+
+/*
+ * "iface-destroy" command
+ */
+static const vshCmdInfo info_interface_destroy[] = {
+ {"help", gettext_noop("destroy a physical host interface (disable it / \"if-down\")")},
+ {"desc", gettext_noop("destroy a physical host interface.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_destroy[] = {
+ {"interface", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("interface name or MAC address")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdInterfaceDestroy(vshControl *ctl, const vshCmd *cmd)
+{
+ virInterfacePtr iface;
+ int ret = TRUE;
+ char *name;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(iface = vshCommandOptInterface(ctl, cmd, &name)))
+ return FALSE;
+
+ if (virInterfaceDestroy(iface, 0) == 0) {
+ vshPrint(ctl, _("Interface %s destroyed\n"), name);
+ } else {
+ vshError(ctl, FALSE, _("Failed to destroy interface %s"), name);
+ ret = FALSE;
+ }
+
+ virInterfaceFree(iface);
+ return ret;
+}
+
+/**************************************************************************/
/*
* "pool-autostart" command
*/
@@ -6247,6 +6732,17 @@ static const vshCmdDef commands[] = {
{"net-start", cmdNetworkStart, opts_network_start, info_network_start},
{"net-undefine", cmdNetworkUndefine, opts_network_undefine, info_network_undefine},
{"net-uuid", cmdNetworkUuid, opts_network_uuid, info_network_uuid},
+
+ {"iface-list", cmdInterfaceList, opts_interface_list, info_interface_list},
+ {"iface-name", cmdInterfaceName, opts_interface_name, info_interface_name},
+ {"iface-mac", cmdInterfaceMAC, opts_interface_mac, info_interface_mac},
+ {"iface-dumpxml", cmdInterfaceDumpXML, opts_interface_dumpxml, info_interface_dumpxml},
+ {"iface-define", cmdInterfaceDefine, opts_interface_define, info_interface_define},
+ {"iface-undefine", cmdInterfaceUndefine, opts_interface_undefine, info_interface_undefine},
+ {"iface-edit", cmdInterfaceEdit, opts_interface_edit, info_interface_edit},
+ {"iface-start", cmdInterfaceStart, opts_interface_start, info_interface_start},
+ {"iface-destroy", cmdInterfaceDestroy, opts_interface_destroy, info_interface_destroy},
+
{"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo},
{"nodedev-list", cmdNodeListDevices, opts_node_list_devices, info_node_list_devices},
@@ -6698,6 +7194,46 @@ vshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd,
return network;
}
+static virInterfacePtr
+vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd,
+ char **name, int flag)
+{
+ virInterfacePtr iface = NULL;
+ char *n;
+ const char *optname = "interface";
+ if (!cmd_has_option (ctl, cmd, optname))
+ return NULL;
+
+ if (!(n = vshCommandOptString(cmd, optname, NULL))) {
+ vshError(ctl, FALSE, "%s", _("undefined interface identifier"));
+ return NULL;
+ }
+
+ vshDebug(ctl, 5, "%s: found option <%s>: %s\n",
+ cmd->def->name, optname, n);
+
+ if (name)
+ *name = n;
+
+ /* try it by MAC */
+ if ((iface == NULL) && (flag & VSH_BYMAC)) {
+ vshDebug(ctl, 5, "%s: <%s> trying as interface MAC\n",
+ cmd->def->name, optname);
+ iface = virInterfaceLookupByMACString(ctl->conn, n);
+ }
+ /* try it by NAME */
+ if ((iface == NULL) && (flag & VSH_BYNAME)) {
+ vshDebug(ctl, 5, "%s: <%s> trying as interface NAME\n",
+ cmd->def->name, optname);
+ iface = virInterfaceLookupByName(ctl->conn, n);
+ }
+
+ if (!iface)
+ vshError(ctl, FALSE, _("failed to get interface '%s'"), n);
+
+ return iface;
+}
+
static virStoragePoolPtr
vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname,
char **name, int flag)
--
1.6.0.6
15 years, 5 months
[libvirt] [PATCH] Fix logging in libvirt_lxc controller
by Amy Griffis
The lxc controller can't see libvirtd's log level setting so it
needs to re-query it from the environment. The parsing code has
a few users now, so I added a new function to the internal API,
virLogParseDefaultPriority() along the lines of the other parse
functions.
Signed-off-by: Amy Griffis <amy.griffis(a)hp.com>
diff --git a/qemud/qemud.c b/qemud/qemud.c
index a58a767..bd17ccb 100644
--- a/qemud/qemud.c
+++ b/qemud/qemud.c
@@ -2465,16 +2465,8 @@ qemudSetLogging(virConfPtr conf, const char *filename) {
*/
GET_CONF_INT (conf, filename, log_level);
debugEnv = getenv("LIBVIRT_DEBUG");
- if (debugEnv && *debugEnv && *debugEnv != '0') {
- if (STREQ(debugEnv, "2") || STREQ(debugEnv, "info"))
- log_level = VIR_LOG_INFO;
- else if (STREQ(debugEnv, "3") || STREQ(debugEnv, "warning"))
- log_level = VIR_LOG_WARN;
- else if (STREQ(debugEnv, "4") || STREQ(debugEnv, "error"))
- log_level = VIR_LOG_ERROR;
- else
- log_level = VIR_LOG_DEBUG;
- }
+ if (debugEnv && *debugEnv && *debugEnv != '0')
+ log_level = virLogParseDefaultPriority(debugEnv);
if ((verbose) && (log_level >= VIR_LOG_WARN))
log_level = VIR_LOG_INFO;
virLogSetDefaultPriority(log_level);
diff --git a/src/libvirt.c b/src/libvirt.c
index bf49018..a3f36da 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -258,6 +258,7 @@ virInitialize(void)
{
#ifdef ENABLE_DEBUG
char *debugEnv;
+ int logPrio;
#endif
if (initialized)
return(0);
@@ -272,14 +273,8 @@ virInitialize(void)
#ifdef ENABLE_DEBUG
debugEnv = getenv("LIBVIRT_DEBUG");
if (debugEnv && *debugEnv && *debugEnv != '0') {
- if (STREQ(debugEnv, "2") || STREQ(debugEnv, "info"))
- virLogSetDefaultPriority(VIR_LOG_INFO);
- else if (STREQ(debugEnv, "3") || STREQ(debugEnv, "warning"))
- virLogSetDefaultPriority(VIR_LOG_WARN);
- else if (STREQ(debugEnv, "4") || STREQ(debugEnv, "error"))
- virLogSetDefaultPriority(VIR_LOG_ERROR);
- else
- virLogSetDefaultPriority(VIR_LOG_DEBUG);
+ logPrio = virLogParseDefaultPriority(debugEnv);
+ virLogSetDefaultPriority(logPrio);
}
debugEnv = getenv("LIBVIRT_LOG_FILTERS");
if (debugEnv)
diff --git a/src/libvirt_debug.syms b/src/libvirt_debug.syms
index 1742a0b..539d879 100644
--- a/src/libvirt_debug.syms
+++ b/src/libvirt_debug.syms
@@ -12,6 +12,7 @@ virLogMessage;
virLogSetDefaultPriority;
virLogDefineFilter;
virLogDefineOutput;
+virLogParseDefaultPriority;
virLogParseFilters;
virLogParseOutputs;
virLogStartup;
diff --git a/src/logging.c b/src/logging.c
index 83e07cc..c72d52e 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -793,5 +793,30 @@ int virLogParseFilters(const char *filters) {
}
return(ret);
}
+
+/**
+ * virLogParseDefaultPriority:
+ * @priority: string defining the desired logging behavior
+ *
+ * It can take a string or number corresponding to the following log
+ * levels:
+ * 1: DEBUG
+ * 2: INFO
+ * 3: WARNING
+ * 4: ERROR
+ *
+ * DEBUG is returned if @priority doesn't match any of the other values.
+ */
+int virLogParseDefaultPriority(const char *priority) {
+
+ if (STREQ(priority, "2") || STREQ(priority, "info"))
+ return VIR_LOG_INFO;
+ else if (STREQ(priority, "3") || STREQ(priority, "warning"))
+ return VIR_LOG_WARN;
+ else if (STREQ(priority, "4") || STREQ(priority, "error"))
+ return VIR_LOG_ERROR;
+ else
+ return VIR_LOG_DEBUG;
+}
#endif /* ENABLE_DEBUG */
diff --git a/src/logging.h b/src/logging.h
index 7ea8935..72b3119 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -110,6 +110,7 @@ typedef void (*virLogCloseFunc) (void *data);
#ifdef ENABLE_DEBUG
+extern int virLogParseDefaultPriority(const char *priority);
extern int virLogSetDefaultPriority(int priority);
extern int virLogDefineFilter(const char *match, int priority, int flags);
extern int virLogDefineOutput(virLogOutputFunc f, virLogCloseFunc c,
@@ -130,6 +131,7 @@ extern void virLogMessage(const char *category, int priority,
#else /* ENABLE_DEBUG */
+#define virLogParseDefaultPriority(p)
#define virLogSetDefaultPriority(p)
#define virLogDefineFilter(m, p, f)
#define virLogDefineOutput(func, c, d, p, f)
diff --git a/src/lxc_controller.c b/src/lxc_controller.c
index 356ecb8..9355d39 100644
--- a/src/lxc_controller.c
+++ b/src/lxc_controller.c
@@ -594,6 +594,8 @@ int main(int argc, char *argv[])
int monitor = -1;
int appPty = -1;
int bg = 0;
+ char *debugEnv;
+ int logPrio;
virCapsPtr caps = NULL;
virDomainDefPtr def = NULL;
char *configFile = NULL;
@@ -735,6 +737,13 @@ int main(int argc, char *argv[])
}
}
+ /* New programs need to re-query and set the libvirt log level. */
+ debugEnv = getenv("LIBVIRT_DEBUG");
+ if (debugEnv && *debugEnv && *debugEnv != '0') {
+ logPrio = virLogParseDefaultPriority(debugEnv);
+ virLogSetDefaultPriority(logPrio);
+ }
+
/* Accept initial client which is the libvirtd daemon */
if ((client = accept(monitor, NULL, 0)) < 0) {
virReportSystemError(NULL, errno, "%s",
15 years, 5 months
[libvirt] [PATCH 0/1] Make NPIV support work with older kernels
by David Allan
Here is a patch that makes NPIV support work with older kernels that
have vport_create and delete in /sys/class/scsi_host/hostN instead of
/sys/class/fc_host/hostN It doesn't look to me like there is a single
place to find those files that works with both old and new kernels, so
the new code checks both places at runtime.
Dave
15 years, 5 months
[libvirt] KVM root mac address
by Paul Reeves
A quick question -
What is the correct root for dynamically generated KVM mac addresses? The
docs (man virt-install) say 54:52:00 and I've seen Ubuntu docs on-line that
say 52:54:00.
Has someone got these mixed up?
Thanks
Paul
--
Paul Reeves
15 years, 5 months