[libvirt] [PATCH] ARMHF: CPU Support for armhf.
by Chuck Short
Adding CPU encoder/decoder for armhf to avoid runtime error messages.
Signed-off-by: Chuck Short <chuck.short(a)canonical.com>
---
src/Makefile.am | 1 +
src/cpu/cpu.c | 2 ++
src/cpu/cpu_arm.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/cpu/cpu_arm.h | 31 ++++++++++++++++++++++
4 files changed, 109 insertions(+)
create mode 100644 src/cpu/cpu_arm.c
create mode 100644 src/cpu/cpu_arm.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 6c3eaa7..bfe74d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -567,6 +567,7 @@ CPU_SOURCES = \
cpu/cpu_generic.h cpu/cpu_generic.c \
cpu/cpu_x86.h cpu/cpu_x86.c cpu/cpu_x86_data.h \
cpu/cpu_s390.h cpu/cpu_s390.c \
+ cpu/cpu_arm.h cpu/cpu_arm.c \
cpu/cpu_map.h cpu/cpu_map.c cpu/cpu_powerpc.h \
cpu/cpu_powerpc.c
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 70a1da5..0ccbd4c 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -30,6 +30,7 @@
#include "cpu_x86.h"
#include "cpu_powerpc.h"
#include "cpu_s390.h"
+#include "cpu_arm.h"
#include "cpu_generic.h"
@@ -40,6 +41,7 @@ static struct cpuArchDriver *drivers[] = {
&cpuDriverX86,
&cpuDriverPowerPC,
&cpuDriverS390,
+ &cpuDriverArm,
/* generic driver must always be the last one */
&cpuDriverGeneric
};
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
new file mode 100644
index 0000000..d6c991f
--- /dev/null
+++ b/src/cpu/cpu_arm.c
@@ -0,0 +1,75 @@
+/*
+ * cpu_arm.c: CPU driver for arm CPUs
+ *
+ * Copyright (C) Canonical Ltd. 2012
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Chuck Short <chuck.short(a)canonical.com>
+ */
+
+#include <config.h>
+
+#include "memory.h"
+#include "cpu.h"
+
+#define VIR_FROM_THIS VIR_FROM_CPU
+
+static const char *archs[] = { "armv7l" };
+
+static union cpuData *
+ArmNodeData(void)
+{
+ union cpuData *data;
+
+ if (VIR_ALLOC(data) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ return data;
+}
+
+static int
+ArmDecode(virCPUDefPtr cpu ATTRIBUTE_UNUSED,
+ const union cpuData *data ATTRIBUTE_UNUSED,
+ const char **models ATTRIBUTE_UNUSED,
+ unsigned int nmodels ATTRIBUTE_UNUSED,
+ const char *preferred ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static void
+ArmDataFree(union cpuData *data)
+{
+ VIR_FREE(data);
+}
+
+struct cpuArchDriver cpuDriverArm = {
+ .name = "arm",
+ .arch = archs,
+ .narch = ARRAY_CARDINALITY(archs),
+ .compare = NULL,
+ .decode = ArmDecode,
+ .encode = NULL,
+ .free = ArmDataFree,
+ .nodeData = ArmNodeData,
+ .guestData = NULL,
+ .baseline = NULL,
+ .update = NULL,
+ .hasFeature = NULL,
+};
diff --git a/src/cpu/cpu_arm.h b/src/cpu/cpu_arm.h
new file mode 100644
index 0000000..30e7ae5
--- /dev/null
+++ b/src/cpu/cpu_arm.h
@@ -0,0 +1,31 @@
+/*
+ * cpu_arm.h: CPU driver for arm CPUs
+ *
+ * Copyright (C) Canonical Ltd. 2012
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Chuck Short <chuck.short(a)canonical.com>
+ */
+
+#ifndef __VIR_CPU_ARM_H__
+#define __VIR_CPU_ARM_H__
+
+#include "cpu.h"
+
+extern struct cpuArchDriver cpuDriverArm;
+
+#endif /* __VIR_CPU_ARM_H__ */
--
1.7.10.4
12 years, 5 months
[libvirt] [PATCH] qemu: Do not fail virConnectCompareCPU if host CPU is not known
by Jiri Denemark
When host CPU could not be properly detected, virConnectCompareCPU will
just report that any CPU is incompatible with host CPU instead of
failing.
---
src/qemu/qemu_driver.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index dc04d13..6d3b8d5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9419,8 +9419,8 @@ qemuCPUCompare(virConnectPtr conn,
qemuDriverLock(driver);
if (!driver->caps || !driver->caps->host.cpu) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("cannot get host CPU capabilities"));
+ VIR_WARN("cannot get host CPU capabilities");
+ ret = VIR_CPU_COMPARE_INCOMPATIBLE;
} else {
ret = cpuCompareXML(driver->caps->host.cpu, xmlDesc);
}
--
1.7.11.1
12 years, 5 months
[libvirt] [PATCH] qemu: Fix probing for guest capabilities
by Jiri Denemark
Even though qemu-kvm binaries can be used in TCG mode, libvirt would
only detect them if /dev/kvm was available. Thus, one would need to make
a /usr/bin/qemu symlink to be able to use TCG mode with qemu-kvm in an
environment without KVM support.
And even though QEMU is able to make use of KVM, libvirt would not
advertise KVM support unless there was a qemu-kvm symlink available.
This patch fixes both issues.
---
src/qemu/qemu_capabilities.c | 95 ++++++++++++++++++++++++--------------------
1 file changed, 53 insertions(+), 42 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 9e4d927..cbea365 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -645,6 +645,7 @@ qemuCapsInitGuest(virCapsPtr caps,
struct stat st;
unsigned int ncpus;
virBitmapPtr qemuCaps = NULL;
+ virBitmapPtr kvmCaps = NULL;
int ret = -1;
/* Check for existance of base emulator, or alternate base
@@ -657,7 +658,12 @@ qemuCapsInitGuest(virCapsPtr caps,
binary = virFindFileInPath(info->altbinary);
}
- /* Can use acceleration for KVM/KQEMU if
+ /* Ignore binary if extracting version info fails */
+ if (binary &&
+ qemuCapsExtractVersionInfo(binary, info->arch, NULL, &qemuCaps) < 0)
+ VIR_FREE(binary);
+
+ /* qemu-kvm/kvm binaries can only be used if
* - host & guest arches match
* Or
* - hostarch is x86_64 and guest arch is i686
@@ -665,37 +671,44 @@ qemuCapsInitGuest(virCapsPtr caps,
*/
if (STREQ(info->arch, hostmachine) ||
(STREQ(hostmachine, "x86_64") && STREQ(info->arch, "i686"))) {
- if (access("/dev/kvm", F_OK) == 0) {
- const char *const kvmbins[] = { "/usr/libexec/qemu-kvm", /* RHEL */
- "qemu-kvm", /* Fedora */
- "kvm" }; /* Upstream .spec */
+ const char *const kvmbins[] = { "/usr/libexec/qemu-kvm", /* RHEL */
+ "qemu-kvm", /* Fedora */
+ "kvm" }; /* Upstream .spec */
- for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) {
- kvmbin = virFindFileInPath(kvmbins[i]);
+ for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) {
+ kvmbin = virFindFileInPath(kvmbins[i]);
- if (!kvmbin)
- continue;
+ if (!kvmbin)
+ continue;
- haskvm = 1;
- if (!binary)
- binary = kvmbin;
+ if (qemuCapsExtractVersionInfo(kvmbin, info->arch,
+ NULL, &kvmCaps) < 0) {
+ VIR_FREE(kvmbin);
+ continue;
+ }
- break;
+ if (!binary) {
+ binary = kvmbin;
+ qemuCaps = kvmCaps;
+ kvmbin = NULL;
+ kvmCaps = NULL;
}
+ break;
}
-
- if (access("/dev/kqemu", F_OK) == 0)
- haskqemu = 1;
}
if (!binary)
return 0;
- /* Ignore binary if extracting version info fails */
- if (qemuCapsExtractVersionInfo(binary, info->arch, NULL, &qemuCaps) < 0) {
- ret = 0;
- goto cleanup;
- }
+ if (access("/dev/kvm", F_OK) == 0 &&
+ (qemuCapsGet(qemuCaps, QEMU_CAPS_KVM) ||
+ qemuCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM) ||
+ kvmbin))
+ haskvm = 1;
+
+ if (access("/dev/kqemu", F_OK) == 0 &&
+ qemuCapsGet(qemuCaps, QEMU_CAPS_KQEMU))
+ haskqemu = 1;
if (stat(binary, &st) == 0) {
binary_mtime = st.st_mtime;
@@ -787,21 +800,23 @@ qemuCapsInitGuest(virCapsPtr caps,
if (haskvm) {
virCapsGuestDomainPtr dom;
- if (stat(kvmbin, &st) == 0) {
- binary_mtime = st.st_mtime;
- } else {
- char ebuf[1024];
- VIR_WARN("Failed to stat %s, most peculiar : %s",
- binary, virStrerror(errno, ebuf, sizeof(ebuf)));
- binary_mtime = 0;
- }
-
- if (!STREQ(binary, kvmbin)) {
+ if (kvmbin) {
int probe = 1;
+
+ if (stat(kvmbin, &st) == 0) {
+ binary_mtime = st.st_mtime;
+ } else {
+ char ebuf[1024];
+ VIR_WARN("Failed to stat %s, most peculiar : %s",
+ binary, virStrerror(errno, ebuf, sizeof(ebuf)));
+ binary_mtime = 0;
+ }
+
if (old_caps && binary_mtime)
- probe = !qemuCapsGetOldMachines("hvm", info->arch, info->wordsize,
- kvmbin, binary_mtime,
- old_caps, &machines, &nmachines);
+ probe = !qemuCapsGetOldMachines("hvm", info->arch,
+ info->wordsize, kvmbin,
+ binary_mtime, old_caps,
+ &machines, &nmachines);
if (probe &&
qemuCapsProbeMachineTypes(kvmbin, qemuCaps,
&machines, &nmachines) < 0)
@@ -810,7 +825,7 @@ qemuCapsInitGuest(virCapsPtr caps,
if ((dom = virCapabilitiesAddGuestDomain(guest,
"kvm",
- kvmbin,
+ kvmbin ? kvmbin : binary,
NULL,
nmachines,
machines)) == NULL) {
@@ -845,14 +860,10 @@ qemuCapsInitGuest(virCapsPtr caps,
ret = 0;
cleanup:
- if (binary == kvmbin) {
- /* don't double free */
- VIR_FREE(binary);
- } else {
- VIR_FREE(binary);
- VIR_FREE(kvmbin);
- }
+ VIR_FREE(binary);
+ VIR_FREE(kvmbin);
qemuCapsFree(qemuCaps);
+ qemuCapsFree(kvmCaps);
return ret;
--
1.7.11.1
12 years, 5 months
[libvirt] [glib PATCH V6] Add bindings for virDomainSave*()
by Jovanka Gulicoska
---
libvirt-gobject/libvirt-gobject-domain.c | 147 ++++++++++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-domain.h | 18 ++++
libvirt-gobject/libvirt-gobject.sym | 3 +
3 files changed, 168 insertions(+)
diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
index 088cd33..308a817 100644
--- a/libvirt-gobject/libvirt-gobject-domain.c
+++ b/libvirt-gobject/libvirt-gobject-domain.c
@@ -557,6 +557,153 @@ gboolean gvir_domain_reboot(GVirDomain *dom,
}
/**
+ * gvir_domain_save_to_file:
+ * @dom: the domain
+ * @filename: path to the output file
+ * @custom_conf: (allow-none): configuration for domain or NULL
+ * @flags: the flags
+ *
+ * Returns: TRUE on success, FALSE otherwise
+ */
+gboolean gvir_domain_save_to_file(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GError **err)
+{
+ GVirDomainPrivate *priv;
+ int ret;
+
+ g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ priv = dom->priv;
+
+ if (flags || custom_conf != NULL) {
+ gchar *custom_xml = NULL;
+
+ if (custom_conf != NULL)
+ custom_xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(custom_conf));
+
+ ret = virDomainSaveFlags(priv->handle, filename, custom_xml, flags);
+ g_free(custom_xml);
+ }
+ else {
+ ret = virDomainSave(priv->handle, filename);
+ }
+
+ if (ret < 0) {
+ gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
+ 0,
+ "Unable to save domain to file");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+typedef struct {
+ gchar *filename;
+ GVirConfigDomain *custom_conf;
+ guint flags;
+} DomainSaveToFileData;
+
+static void domain_save_to_file_data_free(DomainSaveToFileData *data)
+{
+ g_free(data->filename);
+ g_object_unref(data->custom_conf);
+ g_slice_free(DomainSaveToFileData, data);
+}
+
+static void
+gvir_domain_save_to_file_helper(GSimpleAsyncResult *res,
+ GObject *object,
+ GCancellable *cancellable G_GNUC_UNUSED)
+{
+ GVirDomain *dom = GVIR_DOMAIN(object);
+ DomainSaveToFileData *data;
+ GError *err = NULL;
+
+ data = g_simple_async_result_get_op_res_gpointer(res);
+
+ if (!gvir_domain_save_to_file(dom, data->filename, data->custom_conf, data->flags, &err))
+ g_simple_async_result_take_error(res, err);
+}
+
+/**
+ * gvir_domain_save_to_file_async:
+ * @dom: the domain
+ * @filename: path to output file
+ * @custom_conf: (allow-none): configuration for domain or NULL
+ * @flags: the flags
+ * @cancellable: (allow-none) (transfer none): cancallation object
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
+ *
+ * Asynchronous variant of #gvir_domain_save_to_file
+ */
+void gvir_domain_save_to_file_async(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ DomainSaveToFileData *data;
+
+ g_return_if_fail(GVIR_IS_DOMAIN(dom));
+ g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
+
+ data = g_slice_new0(DomainSaveToFileData);
+ data->filename = g_strdup(filename);
+ data->custom_conf = g_object_ref(custom_conf);
+ data->flags = flags;
+
+ res = g_simple_async_result_new(G_OBJECT(dom),
+ callback,
+ user_data,
+ gvir_domain_save_to_file_async);
+ g_simple_async_result_set_op_res_gpointer(res, data, (GDestroyNotify)
+ domain_save_to_file_data_free);
+
+ g_simple_async_result_run_in_thread(res,
+ gvir_domain_save_to_file_helper,
+ G_PRIORITY_DEFAULT,
+ cancellable);
+
+ g_object_unref(res);
+}
+
+/**
+ * gvir_domain_save_to_file_finish:
+ * @dom: the domain to save
+ * @result: (transfer none): async method result
+ * @err: Place-holder for possible errors
+ *
+ * Finishes the operation started by #gvir_domain_save_to_file_async.
+ *
+ * Returns: TRUE if domain was saved successfully, FALSE otherwise.
+ */
+gboolean gvir_domain_save_to_file_finish(GVirDomain *dom,
+ GAsyncResult *result,
+ GError **err)
+{
+ g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
+ g_return_val_if_fail(g_simple_async_result_is_valid
+ (result,
+ G_OBJECT(dom),
+ gvir_domain_save_to_file_async), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ if (g_simple_async_result_propagate_error(G_SIMPLE_ASYNC_RESULT(result), err))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
* gvir_domain_get_config:
* @dom: the domain
* @flags: the flags
diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h
index 87b94f4..8f17799 100644
--- a/libvirt-gobject/libvirt-gobject-domain.h
+++ b/libvirt-gobject/libvirt-gobject-domain.h
@@ -148,6 +148,24 @@ gboolean gvir_domain_reboot(GVirDomain *dom,
guint flags,
GError **err);
+gboolean gvir_domain_save_to_file(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GError **err);
+
+void gvir_domain_save_to_file_async(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean gvir_domain_save_to_file_finish(GVirDomain *dom,
+ GAsyncResult *result,
+ GError **err);
+
GVirDomainInfo *gvir_domain_get_info(GVirDomain *dom,
GError **err);
void gvir_domain_get_info_async(GVirDomain *dom,
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index 94e441a..54a093a 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -75,6 +75,9 @@ LIBVIRT_GOBJECT_0.0.8 {
gvir_domain_get_persistent;
gvir_domain_get_saved;
gvir_domain_screenshot;
+ gvir_domain_save_to_file;
+ gvir_domain_save_to_file_async;
+ gvir_domain_save_to_file_finish;
gvir_domain_snapshot_get_type;
gvir_domain_snapshot_handle_get_type;
--
1.7.10.4
12 years, 5 months
[libvirt] Question about contribution
by Benjamin Wang (gendwang)
Hi,
I am from Cisco. Now we want to use and contribute to Libvirt. One simple question is as following:
If our product needs a new feature for Libvirt, what is the process to submit our contribution to Libvirt? Must we
be approved by some committee?
B.R.
Benjamin
12 years, 5 months
[libvirt] [PATCHv3] docs: Improve patch submission guidelines
by Michal Privoznik
We should really advise (new) developers to send rebased patches
that apply cleanly and use git-send-email rather than all other
obscure ways.
---
diff to v2:
-Eric's suggestions worked in
HACKING | 37 ++++++++++++++++++++++++++++++++++++-
docs/hacking.html.in | 49 ++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 80 insertions(+), 6 deletions(-)
diff --git a/HACKING b/HACKING
index 69ea96b..d960992 100644
--- a/HACKING
+++ b/HACKING
@@ -21,9 +21,44 @@ or:
git diff > libvirt-myfeature.patch
+However, the usual workflow of libvirt developer is:
+
+ git checkout master
+ git pull
+ git checkout -t origin -b workbranch
+ Hack, committing any changes along the way
+
+Then, when you want to post your patches:
+
+ git pull --rebase
+ (fix any conflicts)
+ git send-email --cover-letter --no-chain-reply-to --annotate --to=libvir-list(a)redhat.com master
+
+For a single patch you can omit "--cover-letter", but series of a two or more
+patches needs a cover letter. If you get tired of typing
+"--to=libvir-list(a)redhat.com" designation you can set it in git config:
+
+ git config sendemail.to libvir-list(a)redhat.com
+
+Please follow this as close as you can, especially the rebase and git
+send-email part, as it makes life easier for other developers to review your
+patch set. One should avoid sending patches as attachments, but rather send
+them in email body among with commit message. If a developer is sending
+another version of the patch (e.g. to address review comments), he is advised
+to note differences to previous versions after the "---" line in the patch so
+that it helps reviewers but doesn't become part of git history. Moreover, such
+patch needs to be prefixed correctly with "--subject-prefix=PATCHv2" appended
+to "git send-email" (substitute "v2" with the correct version if needed
+though).
+
(3) Split large changes into a series of smaller patches, self-contained if
possible, with an explanation of each patch and an explanation of how the
-sequence of patches fits together.
+sequence of patches fits together. Moreover, please keep in mind that it's
+required to be able to compile cleanly after each patch. A feature does not
+have to work until the end of a series, as long as intermediate patches don't
+cause test-suite failures.
+
+
(4) Make sure your patches apply against libvirt GIT. Developers only follow GIT
and don't care much about released versions.
diff --git a/docs/hacking.html.in b/docs/hacking.html.in
index 89f9980..96cc062 100644
--- a/docs/hacking.html.in
+++ b/docs/hacking.html.in
@@ -11,19 +11,58 @@
<li><p>Post patches in unified diff format. A command similar to this
should work:</p>
-<pre>
+<del><pre>
diff -urp libvirt.orig/ libvirt.modified/ > libvirt-myfeature.patch
-</pre>
+</pre></del>
<p>
or:
</p>
<pre>
git diff > libvirt-myfeature.patch
</pre>
+ <p>However, the usual workflow of libvirt developer is:</p>
+<pre>
+ git checkout master
+ git pull
+ git checkout -t origin -b workbranch
+ Hack, committing any changes along the way
+</pre>
+ <p>Then, when you want to post your patches:</p>
+<pre>
+ git pull --rebase
+ (fix any conflicts)
+ git send-email --cover-letter --no-chain-reply-to --annotate --to=libvir-list(a)redhat.com master
+</pre>
+ <p>For a single patch you can omit <code>--cover-letter</code>, but
+ series of a two or more patches needs a cover letter. If you get tired
+ of typing <code>--to=libvir-list(a)redhat.com</code> designation you can
+ set it in git config:</p>
+<pre>
+ git config sendemail.to libvir-list(a)redhat.com
+</pre>
+ <p>Please follow this as close as you can, especially the rebase and
+ git send-email part, as it makes life easier for other developers to
+ review your patch set. One should avoid sending patches as attachments,
+ but rather send them in email body among with commit message. If a
+ developer is sending another version of the patch (e.g. to address
+ review comments), he is advised to note differences to previous
+ versions after the <code>---</code> line in the patch so that it helps
+ reviewers but doesn't become part of git history. Moreover, such patch
+ needs to be prefixed correctly with
+ <code>--subject-prefix=PATCHv2</code> appended to <code>git
+ send-email</code> (substitute <code>v2</code> with the correct
+ version if needed though).</p>
</li>
- <li>Split large changes into a series of smaller patches, self-contained
- if possible, with an explanation of each patch and an explanation of how
- the sequence of patches fits together.</li>
+
+ <li><p>Split large changes into a series of smaller patches,
+ self-contained if possible, with an explanation of each patch and an
+ explanation of how the sequence of patches fits together. Moreover,
+ please keep in mind that it's required to be able to compile cleanly
+ after each patch. A feature does not have to work until the end of a
+ series, as long as intermediate patches don't cause test-suite
+ failures.</p>
+ </li>
+
<li>Make sure your patches apply against libvirt GIT. Developers
only follow GIT and don't care much about released versions.</li>
<li><p>Run the automated tests on your code before submitting any changes.
--
1.7.8.6
12 years, 5 months
[libvirt] [PATCH 0/5] Allow to query a guest's hostname
by Guido Günther
The following patches allow to query a guest's hostname. The last patch might
be debatable since it adds yet another option to virsh list but I hope the rest
of the serious looks sane.
Cheers,
-- Guido
Guido Günther (5):
Add virGetHostname
virsh: Add domhostname
openvz: Add openvzVEGetStringParam
openvz: Implement domainGetHostname
virsh: allow to print hostname in domain listings
include/libvirt/libvirt.h.in | 2 ++
src/driver.h | 6 ++++
src/libvirt.c | 42 ++++++++++++++++++++++++++++
src/libvirt_openvz.syms | 2 +-
src/libvirt_public.syms | 5 ++++
src/openvz/openvz_driver.c | 28 +++++++++++++++++++
src/openvz/openvz_util.c | 31 +++++++++++++++++++++
src/openvz/openvz_util.h | 1 +
tools/virsh.c | 62 +++++++++++++++++++++++++++++++++++++++++-
tools/virsh.pod | 4 +++
10 files changed, 181 insertions(+), 2 deletions(-)
--
1.7.10.4
12 years, 5 months
[libvirt] [ESX Patch V2]: Add routines to interface driver
by Ata Bohra
From: Ata E Husain Bohra <ata.husain(a)hotmail.com>
Add following routines to esx_interface_driver:
esxNumOfInterfaces,
esxNumOfDefinedInterfaces,
esxListInterfaces,
esxListDefinedInterfaces,
esxInterfaceLookupByMACString,
esxInterfaceGetXMLDesc,
esxInterfaceUndefine,
esxInterfaceCreate,
esxInterfaceDestroy
Signed-off-by: Ata E Husain Bohra <ata.husain(a)hotmail.com>
---
src/esx/esx_interface_driver.c | 506 +++++++++++++++++++++++++++++++++++++++-
src/esx/esx_vi.c | 126 ++++++++++
src/esx/esx_vi.h | 10 +
src/esx/esx_vi_generator.input | 227 ++++++++++++++++++
src/esx/esx_vi_generator.py | 31 ++-
src/esx/esx_vi_types.c | 18 +-
6 files changed, 913 insertions(+), 5 deletions(-)
diff --git a/src/esx/esx_interface_driver.c b/src/esx/esx_interface_driver.c
index 5713137..b1ba5e2 100644
--- a/src/esx/esx_interface_driver.c
+++ b/src/esx/esx_interface_driver.c
@@ -23,6 +23,9 @@
*/
#include <config.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include "internal.h"
#include "util.h"
@@ -34,6 +37,7 @@
#include "esx_vi.h"
#include "esx_vi_methods.h"
#include "esx_util.h"
+#include "interface_conf.h"
#define VIR_FROM_THIS VIR_FROM_ESX
@@ -67,10 +71,508 @@ esxInterfaceClose(virConnectPtr conn)
+static int
+esxNumOfInterfaces(virConnectPtr conn)
+{
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_HostVirtualNic *virtualNicList = NULL;
+ const esxVI_HostVirtualNic *virtualNic = NULL;
+ int count = 0;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupVirtualNicList(priv->primary, &virtualNicList) < 0) {
+ goto cleanup;
+ }
+
+ if (virtualNicList == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve vNic List"));
+
+ goto cleanup;
+ }
+
+ for (virtualNic = virtualNicList;
+ virtualNic != NULL;
+ virtualNic = virtualNic->_next) {
+ count++;
+ }
+
+cleanup:
+
+ esxVI_HostVirtualNic_Free(&virtualNicList);
+
+ return count;
+}
+
+
+
+static int
+esxNumOfDefinedInterfaces(virConnectPtr conn)
+{
+ conn->interfacePrivateData = NULL;
+
+ // ESX interfaces are always active
+ return 0;
+}
+
+
+
+static int
+esxListInterfaces(virConnectPtr conn, char **names, int maxnames)
+{
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_HostVirtualNic *virtualNicList = NULL;
+ const esxVI_HostVirtualNic *virtualNic = NULL;
+ int result = -1;
+ int i = 0;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupVirtualNicList(priv->primary,
+ &virtualNicList) < 0) {
+ goto cleanup;
+ }
+
+ if (virtualNicList == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve vNIC List"));
+ goto cleanup;
+ }
+
+ for (i= 0, virtualNic = virtualNicList;
+ virtualNic != NULL && i < maxnames;
+ ++i, virtualNic = virtualNic->_next) {
+ names[i] = strdup(virtualNic->device);
+
+ if (names[i] == NULL) {
+ for(;i >=0;--i) {
+ VIR_FREE(names[i]);
+ }
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ result = i;
+ cleanup:
+ esxVI_HostVirtualNic_Free(&virtualNicList);
+
+ return result;
+}
+
+
+
+static int
+esxListDefinedInterfaces(virConnectPtr conn, char **names, int maxnames)
+{
+ conn->interfacePrivateData = conn->privateData;
+ *names = NULL;
+
+ /* keeps compiler happy */
+ VIR_DEBUG("max interfaces: %d", maxnames);
+
+ // ESX interfaces are always active
+ return 0;
+}
+
+
+
+static virInterfacePtr
+esxInterfaceLookupByName(virConnectPtr conn, const char *name)
+{
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_HostVirtualNic *virtualNicList = NULL;
+ const esxVI_HostVirtualNic *virtualNic = NULL;
+ virInterfacePtr ret = NULL;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupVirtualNicList(priv->primary,
+ &virtualNicList) < 0) {
+ goto cleanup;
+ }
+
+ if (virtualNicList == 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve vNIC List"));
+ goto cleanup;
+ }
+
+
+ for(virtualNic = virtualNicList;
+ virtualNic != NULL;
+ virtualNic = virtualNic->_next) {
+ if (STREQ(virtualNic->device, name)) {
+ if (virtualNic->spec == NULL ||
+ virtualNic->spec->mac == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Malformed HostVirtualNicSpec"));
+ goto cleanup;
+ }
+
+ ret = virGetInterface(conn, virtualNic->device, virtualNic->spec->mac);
+ break;
+ }
+ }
+
+ cleanup:
+ esxVI_HostVirtualNic_Free(&virtualNicList);
+
+ return ret;
+}
+
+
+
+static virInterfacePtr
+esxInterfaceLookupByMACString(virConnectPtr conn, const char *mac)
+{
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_HostVirtualNic *virtualNicList = NULL;
+ const esxVI_HostVirtualNic *virtualNic = NULL;
+ virInterfacePtr ret = NULL;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupVirtualNicList(priv->primary,
+ &virtualNicList) < 0) {
+ goto cleanup;
+ }
+
+ if (virtualNicList == 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve vNIC List"));
+ goto cleanup;
+ }
+
+
+ for(virtualNic = virtualNicList;
+ virtualNic != NULL;
+ virtualNic = virtualNic->_next) {
+ if (virtualNic->spec == NULL ||
+ virtualNic->spec->mac == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Malformed HostVirtualNicSpec"));
+ goto cleanup;
+ }
+
+ if (STREQ(virtualNic->spec->mac, mac)) {
+ ret = virGetInterface(conn, virtualNic->device, virtualNic->spec->mac);
+ break;
+ }
+ }
+
+ cleanup:
+ esxVI_HostVirtualNic_Free(&virtualNicList);
+
+ return ret;
+}
+
+
+
+static char*
+esxInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags)
+{
+ esxPrivate *priv = iface->conn->interfacePrivateData;
+ esxVI_HostVirtualNic *virtualNicList = NULL;
+ const esxVI_HostVirtualNic *virtualNic = NULL;
+ esxVI_PhysicalNic *physicalNicList = NULL;
+ const esxVI_PhysicalNic *physicalNic = NULL;
+ esxVI_PhysicalNic *matchingPhysicalNicList = NULL;
+ esxVI_HostIpRouteConfig *ipRouteConfig = NULL;
+ esxVI_HostPortGroup *portGroupList = NULL;
+ esxVI_HostVirtualSwitch *virtualSwitchList = NULL;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *hostSystem = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+ virInterfaceDefPtr def = NULL;
+ int use_static = 0;
+ struct in_addr addr;
+ uint32_t host_addr = 0;
+ int zero_count = 0;
+ int masklen = 0;
+ int i = 0;
+ char *ret = NULL;
+
+ if (VIR_INTERFACE_XML_INACTIVE & flags) {
+ use_static = 1;
+ }
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_String_AppendValueListToList(&propertyNameList,
+ "config.network.vnic\0"
+ "config.network.ipRouteConfig\0"
+ "config.network.vswitch\0"
+ "config.network.pnic\0"
+ "config.network.portgroup\0") < 0 ||
+ esxVI_LookupHostSystemProperties(priv->primary, propertyNameList,
+ &hostSystem) < 0) {
+ goto cleanup;
+ }
+
+ for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "config.network.vnic")) {
+ if (esxVI_HostVirtualNic_CastListFromAnyType(
+ dynamicProperty->val, &virtualNicList) < 0) {
+ goto cleanup;
+ }
+ } else if (STREQ(dynamicProperty->name,
+ "config.network.ipRouteConfig")) {
+ if (esxVI_HostIpRouteConfig_CastFromAnyType(
+ dynamicProperty->val, &ipRouteConfig)) {
+ goto cleanup;
+ }
+ } else if (STREQ(dynamicProperty->name, "config.network.vswitch")) {
+ if (esxVI_HostVirtualSwitch_CastListFromAnyType
+ (dynamicProperty->val, &virtualSwitchList) < 0) {
+ goto cleanup;
+ }
+ } else if (STREQ(dynamicProperty->name, "config.network.pnic")) {
+ if (esxVI_PhysicalNic_CastListFromAnyType(
+ dynamicProperty->val, &physicalNicList) < 0) {
+ goto cleanup;
+ }
+ } else if (STREQ(dynamicProperty->name, "config.network.portgroup")) {
+ if (esxVI_HostPortGroup_CastListFromAnyType(
+ dynamicProperty->val, &portGroupList) < 0) {
+ goto cleanup;
+ }
+ } else {
+ VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+ }
+ }
+
+ if (!virtualNicList ||
+ !ipRouteConfig ||
+ !virtualSwitchList ||
+ !portGroupList) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to retrieve network parameters"));
+
+ goto cleanup;
+ }
+
+ for (virtualNic = virtualNicList;
+ virtualNic != NULL;
+ virtualNic = virtualNic->_next) {
+ if (STREQ(virtualNic->device, iface->name)) {
+ break;
+ }
+ }
+
+ if (virtualNic == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find Interface"));
+ goto cleanup;
+ }
+
+ if (esxVI_LookupPhysicalNicFromPortGroup(virtualNic->portgroup,
+ portGroupList,
+ virtualSwitchList,
+ physicalNicList,
+ &matchingPhysicalNicList) < 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No Physical NIC found matching Virtual NIC's portgroup"));
+ goto cleanup;
+ }
+
+ /*
+ * populate virInterfaceDef object to obtain
+ * libvirt interface domain xml.
+ */
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ def->type = VIR_INTERFACE_TYPE_BRIDGE;
+ def->name = strdup(virtualNic->device);
+ if (virtualNic->spec->mtu && virtualNic->spec->mtu->value) {
+ def->mtu = virtualNic->spec->mtu->value;
+ } else {
+ def->mtu = 1500;
+ }
+
+ def->startmode = VIR_INTERFACE_START_ONBOOT;
+
+ if (!use_static && virtualNic->spec->mac) {
+ def->mac = strdup(virtualNic->spec->mac);
+ }
+
+ /* TODO - Handle VLAN (via portgroup?) */
+ if (virtualNic->spec->ip->subnetMask &&
+ *virtualNic->spec->ip->subnetMask &&
+ inet_aton(virtualNic->spec->ip->subnetMask, &addr) == 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Error parsing netmask"));
+ goto cleanup;
+ }
+
+ host_addr = ntohl(addr.s_addr);
+ /* Calculate masklen */
+ for (i = 0; i < 32; ++i) {
+ if (host_addr & 0x01) {
+ break;
+ }
+ zero_count++;
+ host_addr >>= 1;
+ }
+ masklen = 32 - zero_count;
+
+ /* append protocol field */
+ def->nprotos = 1;
+ if (VIR_ALLOC_N(def->protos, def->nprotos) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* TODO - Add IPv6 Support */
+ for (i = 0; i < def->nprotos; ++i) {
+ if (VIR_ALLOC(def->protos[i]) < 0) {
+ goto cleanup;
+ }
+
+ def->protos[i]->family = strdup("ipv4");
+ if (virtualNic->spec->ip->dhcp == 1) {
+ def->protos[i]->dhcp = 1;
+ }
+ def->protos[i]->nips = 1;
+ if (virtualNic->spec->ip->dhcp != 1 || !use_static) {
+ if (virtualNic->spec->ip->ipAddress &&
+ *virtualNic->spec->ip->ipAddress) {
+ int j =0;
+ if (VIR_ALLOC_N(def->protos[i]->ips, def->protos[i]->nips)
+ < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ for (j=0; j < def->protos[i]->nips; ++j) {
+ if (VIR_ALLOC(def->protos[i]->ips[j]) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ def->protos[i]->ips[0]->address =
+ strdup(virtualNic->spec->ip->ipAddress);
+ def->protos[i]->ips[0]->prefix = masklen;
+ def->protos[i]->gateway =
+ strdup(ipRouteConfig->defaultGateway);
+ }
+ }
+ }
+ }
+
+ /* Add bridge information */
+ def->data.bridge.stp = 0; /* off */
+
+ /**
+ * traversing physical nic list twice, first to get total
+ * interfaces and second to populate interface items.
+ * Total Complexity ~= O(N); also total physical nics
+ * cannot be that large number
+ */
+ for (physicalNic = matchingPhysicalNicList, i = 0; physicalNic != NULL;
+ physicalNic = physicalNic->_next, ++i) {
+ }
+
+ if ( i > 0) {
+ if (VIR_ALLOC_N(def->data.bridge.itf, i) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ def->data.bridge.nbItf = i;
+ for (physicalNic = matchingPhysicalNicList, i = 0; physicalNic != NULL;
+ physicalNic = physicalNic->_next, ++i) {
+ virInterfaceDefPtr itf = NULL;
+ if (VIR_ALLOC(itf) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ itf->type = VIR_INTERFACE_TYPE_ETHERNET;
+ itf->name = strdup(physicalNic->device);
+ itf->mac = strdup(physicalNic->mac);
+
+ def->data.bridge.itf[i] = itf;
+ }
+ }
+
+ ret = virInterfaceDefFormat(def);
+ if (!ret) {
+ goto cleanup;
+ }
+
+ cleanup:
+ esxVI_HostVirtualNic_Free(&virtualNicList);
+ esxVI_PhysicalNic_Free(&physicalNicList);
+ esxVI_PhysicalNic_Free(&matchingPhysicalNicList);
+ esxVI_HostPortGroup_Free(&portGroupList);
+ esxVI_HostVirtualSwitch_Free(&virtualSwitchList);
+ esxVI_HostIpRouteConfig_Free(&ipRouteConfig);
+ esxVI_ObjectContent_Free(&hostSystem);
+ esxVI_String_Free(&propertyNameList);
+ virInterfaceDefFree(def);
+
+ return ret;
+}
+
+
+
+static int
+esxInterfaceUndefine(virInterfacePtr iface)
+{
+ esxPrivate *priv = iface->conn->interfacePrivateData;
+
+ if (esxVI_RemoveVirtualNic(
+ priv->primary,
+ priv->primary->hostSystem->configManager->networkSystem,
+ iface->name) < 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Error deleting interface"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+static int
+esxInterfaceCreate(virInterfacePtr iface, unsigned int flags)
+{
+ iface->conn->interfacePrivateData = NULL;
+
+ virCheckFlags(0, -1);
+
+ /* ESX interfaces are always active */
+ return 0;
+}
+
+
+
+static int
+esxInterfaceDestroy(virInterfacePtr iface, unsigned int flags)
+{
+ iface->conn->interfacePrivateData = NULL;
+
+ virCheckFlags(0, -1);
+
+ /* ESX interfaces can not be deactivated */
+ return 1;
+}
+
+
+
static virInterfaceDriver esxInterfaceDriver = {
.name = "ESX",
- .open = esxInterfaceOpen, /* 0.7.6 */
- .close = esxInterfaceClose, /* 0.7.6 */
+ .open = esxInterfaceOpen, /* 0.7.6 */
+ .close = esxInterfaceClose, /* 0.7.6 */
+ .numOfInterfaces = esxNumOfInterfaces, /* 0.9.x */
+ .numOfDefinedInterfaces = esxNumOfDefinedInterfaces, /* 0.9.x */
+ .listInterfaces = esxListInterfaces, /* 0.9.x */
+ .listDefinedInterfaces = esxListDefinedInterfaces, /* 0.9.x */
+ .interfaceLookupByName = esxInterfaceLookupByName, /* 0.9.x */
+ .interfaceLookupByMACString = esxInterfaceLookupByMACString, /* 0.9.x */
+ .interfaceGetXMLDesc = esxInterfaceGetXMLDesc, /* 0.9.x */
+ .interfaceUndefine = esxInterfaceUndefine, /* 0.9.x */
+ .interfaceCreate = esxInterfaceCreate, /* 0.9.x */
+ .interfaceDestroy = esxInterfaceDestroy, /* 0.9.x */
};
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 48718b6..80ddb76 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -4523,6 +4523,132 @@ esxVI_LookupManagedObjectHelper(esxVI_Context *ctx,
return result;
}
+int
+esxVI_LookupVirtualNicList(esxVI_Context* ctx,
+ esxVI_HostVirtualNic** virtualNicList)
+{
+ int result = -1;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+ esxVI_ObjectContent* hostSystem = NULL;
+
+ if (esxVI_String_AppendValueListToList(
+ &propertyNameList, "config.network.vnic\0") < 0 ||
+ esxVI_LookupHostSystemProperties(ctx, propertyNameList, &hostSystem) < 0) {
+ goto cleanup;
+ }
+ if (hostSystem == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve the HostSystem object"));
+
+ goto cleanup;
+ }
+
+ for (dynamicProperty = hostSystem->propSet;
+ dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "config.network.vnic")) {
+ if (esxVI_HostVirtualNic_CastListFromAnyType(dynamicProperty->val,
+ virtualNicList) < 0) {
+ goto cleanup;
+ }
+ break;
+ } else {
+ VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+ }
+ }
+
+ result = 0;
+
+cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&hostSystem);
+
+ return result;
+}
+
+int
+esxVI_LookupPhysicalNicFromPortGroup(
+ const char *portgroup,
+ const esxVI_HostPortGroup *portGroupList,
+ const esxVI_HostVirtualSwitch *virtualSwitchList,
+ const esxVI_PhysicalNic *physicalNicList,
+ esxVI_PhysicalNic **ret_physicalNicList)
+{
+ int result = -1;
+ const esxVI_HostPortGroup *portGroup = NULL;
+ const esxVI_HostVirtualSwitch *virtualSwitch = NULL;
+ esxVI_PhysicalNic *matchingPhysicalNicList = NULL;
+ const esxVI_PhysicalNic *physicalNic = NULL;
+ esxVI_PhysicalNic *tempPhysicalNic = NULL;
+ const esxVI_String *pnicKey = NULL;
+
+ if (portgroup == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No Portgroup found!"));
+ goto cleanup;
+ }
+
+ /* Go through all the port groups to find the one that matches. */
+ for (portGroup = portGroupList;
+ portGroup != NULL;
+ portGroup = portGroup->_next) {
+ if (STREQ(portGroup->spec->name, portgroup)) {
+ break;
+ }
+ }
+
+ if (portGroup == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find Host port group"));
+ goto cleanup;
+ }
+
+ /* Go through all the virtual switches to find the one that matches */
+ for (virtualSwitch = virtualSwitchList;
+ virtualSwitch != NULL;
+ virtualSwitch = virtualSwitch->_next) {
+ if (STREQ(portGroup->spec->vswitchName, virtualSwitch->name)) {
+ break;
+ }
+ }
+
+ if (virtualSwitch == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find Virtual Switch"));
+ goto cleanup;
+ }
+
+ /* Go through all physical nics */
+ for (pnicKey = virtualSwitch->pnic;
+ pnicKey != NULL;
+ pnicKey = pnicKey->_next) {
+ /* O(n^2), but probably faster than a hash due to small N */
+ for (physicalNic = physicalNicList;
+ physicalNic != NULL;
+ physicalNic = physicalNic->_next) {
+
+ if (STREQ(pnicKey->value, physicalNic->key)) {
+ if (esxVI_PhysicalNic_DeepCopy(&tempPhysicalNic,
+ (esxVI_PhysicalNic *)physicalNic) < 0 ||
+ esxVI_PhysicalNic_AppendToList(&matchingPhysicalNicList,
+ tempPhysicalNic) < 0) {
+ goto cleanup;
+ }
+ tempPhysicalNic = NULL;
+ }
+ }
+ }
+
+ *ret_physicalNicList = matchingPhysicalNicList;
+ matchingPhysicalNicList = NULL; /* no cleanup needed */
+ tempPhysicalNic = NULL; /* no cleanup needed */
+ result = 0;
+ cleanup:
+ esxVI_PhysicalNic_Free(&matchingPhysicalNicList);
+ esxVI_PhysicalNic_Free(&tempPhysicalNic);
+ return result;
+}
#include "esx_vi.generated.c"
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 9560bd2..9b694b5 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -505,6 +505,16 @@ int esxVI_ParseHostCpuIdInfo(esxVI_ParsedHostCpuIdInfo *parsedHostCpuIdInfo,
int esxVI_ProductVersionToDefaultVirtualHWVersion(esxVI_ProductVersion productVersion);
+int esxVI_LookupVirtualNicList(esxVI_Context* ctx,
+ esxVI_HostVirtualNic** virtualNicList);
+
+int esxVI_LookupPhysicalNicFromPortGroup(
+ const char *portgroup,
+ const esxVI_HostPortGroup *portGroupList,
+ const esxVI_HostVirtualSwitch *virtualSwitchList,
+ const esxVI_PhysicalNic *physicalNicList,
+ esxVI_PhysicalNic **ret_physicalNicList);
+
# include "esx_vi.generated.h"
#endif /* __ESX_VI_H__ */
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index 1a67a8c..64f8389 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -57,6 +57,29 @@ enum AutoStartWaitHeartbeatSetting
systemDefault
end
+enum HostConfigChangeOperation
+ add
+ edit
+ remove
+end
+
+enum HostIpConfigIpV6AdressStatus
+ deprecated
+ duplicate
+ inaccessible
+ invalid
+ preferred
+ tentative
+ unknown
+end
+
+enum HostIpConfigV6AdressConfigType
+ dhcp
+ linklayer
+ manual
+ other
+ random
+end
enum ManagedEntityStatus
gray
@@ -197,6 +220,12 @@ object DeviceBackedVirtualDiskSpec extends VirtualDiskSpec
String device r
end
+object DistributedVirtualSwitchPortConnection
+ Int connectionCookie o
+ String portgroupKey o
+ String portKey o
+ String switchUuid r
+end
object DynamicProperty
String name r
@@ -316,6 +345,34 @@ object HostFileSystemVolume
Long capacity r
end
+object HostIpConfig
+ Boolean dhcp r
+ String ipAddress o
+ HostIpConfigIpV6AddressConfiguration ipV6Config o
+ String subnetMask o
+end
+
+object HostIpConfigIpV6Address
+ String dadState o
+ String ipAddress r
+ DateTime lifetime o
+ String operation o
+ String origin o
+ Int prefixLength r
+end
+
+object HostIpConfigIpV6AddressConfiguration
+ Boolean autoConfigurationEnabled o
+ Boolean dhcpV6Enabled o
+ HostIpConfigIpV6Address ipV6Address ol
+end
+
+object HostIpRouteConfig
+ String defaultGateway o
+ String gatewayDevice o
+ String ipV6DefaultGateway o
+ String ipV6GatewayDevice o
+end
object HostMountInfo
String path o
@@ -331,11 +388,131 @@ object HostNasVolume extends HostFileSystemVolume
end
+object HostNicTeamingPolicy
+ String policy o
+ Boolean reversePolicy o
+ Boolean notifySwitches o
+ Boolean rollingOrder o
+ HostNicFailureCriteria failureCriteria o
+ HostNicOrderPolicy nicOrder o
+end
+
+object HostNetOffloadCapabilities
+ Boolean csumOffload o
+ Boolean tcpSegmentation o
+ Boolean zeroCopyXmit o
+end
+
+object HostNetworkSecurityPolicy
+ Boolean allowPromiscuous o
+ Boolean macChanges o
+ Boolean forgedTransmits o
+end
+
+object HostNetworkPolicy
+ HostNetworkSecurityPolicy security o
+ HostNicTeamingPolicy nicTeaming o
+ HostNetOffloadCapabilities offloadPolicy o
+ HostNetworkTrafficShapingPolicy shapingPolicy o
+end
+
+object HostNetworkTrafficShapingPolicy
+ Boolean enabled o
+end
+
+object HostNicFailureCriteria
+ String checkSpeed o
+ Int speed o
+ Boolean checkDuplex o
+ Boolean fullDuplex o
+ Boolean checkErrorPercent o
+ Int percentage o
+ Boolean checkBeacon o
+end
+
+object HostNicOrderPolicy
+ String activeNic ol
+ String standbyNic ol
+end
+
+object HostPortGroup
+ String key r
+ HostPortGroupPort port ol
+ String vswitch r
+ HostNetworkPolicy computedPolicy r
+ HostPortGroupSpec spec r
+end
+
+object HostPortGroupPort
+ String key o
+ String mac ol
+ String type r
+end
+
+object HostPortGroupSpec
+ String name r
+ Int vlanId r
+ String vswitchName r
+ HostNetworkPolicy policy r
+end
+
object HostScsiDiskPartition
String diskName r
Int partition r
end
+object HostVirtualNic
+ String device r
+ String key r
+ String port o
+ String portgroup r
+ HostVirtualNicSpec spec r
+end
+
+object HostVirtualNicSpec
+ DistributedVirtualSwitchPortConnection distributedVirtualPort o
+ HostIpConfig ip o
+ String mac o
+ Int mtu o
+ String portgroup o
+ Boolean tsoEnabled o
+end
+
+
+object HostVirtualSwitch
+ String key r
+ Int mtu o
+ String name r
+ Int numPorts r
+ Int numPortsAvailable r
+ String pnic ol
+ String portgroup ol
+ HostVirtualSwitchSpec spec r
+end
+
+object HostVirtualSwitchBridge
+end
+
+object HostVirtualSwitchAutoBridge extends HostVirtualSwitchBridge
+ String excludedNicDevice ol
+end
+
+object HostVirtualSwitchBeaconBridge extends HostVirtualSwitchBridge
+ Int interval r
+end
+
+object HostVirtualSwitchBondBridge extends HostVirtualSwitchBridge
+ HostVirtualSwitchBeaconBridge beacon o
+ LinkDiscoveryProtocolConfig linkDiscoveryProtocolConfig o
+ String nicDevice rl
+end
+
+object HostVirtualSwitchSpec
+ HostVirtualSwitchBridge bridge o
+ Int mtu o
+ Int numPorts r
+ HostNetworkPolicy policy o
+end
object HostVmfsVolume extends HostFileSystemVolume
Int blockSizeMb r
@@ -355,6 +532,10 @@ end
object IsoImageFileQuery extends FileQuery
end
+object LinkDiscoveryProtocolConfig
+ String operation r
+ String protocol r
+end
object LocalDatastoreInfo extends DatastoreInfo
String path o
@@ -398,6 +579,10 @@ object OptionType
Boolean valueIsReadonly o
end
+object OptionValue
+ String key r
+ AnyType value r
+end
object PerfCounterInfo
Int key r
@@ -454,6 +639,27 @@ object PerfSampleInfo
Int interval r
end
+object PhysicalNic
+ String device r
+ String driver o
+ String key o
+ PhysicalNicInfo linkSpeed o
+ String mac r
+ String pci r
+ PhysicalNicSpec spec r
+ PhysicalNicInfo validLinkSpecification ol
+ Boolean wakeOnLanSupported r
+end
+
+object PhysicalNicInfo
+ Boolean duplex r
+ Int speedMb r
+end
+
+object PhysicalNicSpec
+ HostIpConfig ip o
+ PhysicalNicInfo linkSpeed o
+end
object PropertyChange
String name r
@@ -773,6 +979,13 @@ end
# Methods
#
+method AddVirtualNic returns String r
+ ManagedObjectReference _this r
+ String portgroup r
+ HostVirtualNicSpec nic r
+end
+
+
method AnswerVM
ManagedObjectReference _this r
String questionId r
@@ -954,6 +1167,10 @@ method RemoveSnapshot_Task returns ManagedObjectReference r
Boolean removeChildren r
end
+method RemoveVirtualNic
+ ManagedObjectReference _this r
+ String device r
+end
method RetrieveProperties returns ObjectContent ol
ManagedObjectReference _this:propertyCollector r
@@ -1002,6 +1219,16 @@ method UnregisterVM
ManagedObjectReference _this r
end
+method UpdateIpRouteConfig
+ ManagedObjectReference _this r
+ HostIpRouteConfig config r
+end
+
+method UpdateVirtualNic
+ ManagedObjectReference _this r
+ String device r
+ HostVirtualNicSpec nic r
+end
method WaitForUpdates returns UpdateSet r
ManagedObjectReference _this:propertyCollector r
diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index 8a128df..f4e4a11 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -371,8 +371,12 @@ class Property(Member):
% self.name
elif self.occurrence in [OCCURRENCE__REQUIRED_LIST,
OCCURRENCE__OPTIONAL_LIST]:
- return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_LIST(%s, %s)\n" \
- % (self.type, self.name)
+ if self.type == "String":
+ return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_STRING_LIST(%s, %s)\n" \
+ % (self.type, self.name)
+ else:
+ return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_LIST(%s, %s)\n" \
+ % (self.type, self.name)
elif self.type == "String":
return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, %s)\n" \
% self.name
@@ -1519,8 +1523,31 @@ additional_object_features = { "AutoStartDefaults" : Object.FEATURE__AN
Object.FEATURE__ANY_TYPE,
"HostDatastoreBrowserSearchResults" : Object.FEATURE__LIST |
Object.FEATURE__ANY_TYPE,
+ "HostIpConfig" : Object.FEATURE__DEEP_COPY,
+ "HostIpRouteConfig" : Object.FEATURE__ANY_TYPE,
+ "HostIpConfigIpV6Address" : Object.FEATURE__LIST |
+ Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__DEEP_COPY,
+ "HostIpConfigIpV6AddressConfiguration" : Object.FEATURE__DEEP_COPY,
+ "HostPortGroup" : Object.FEATURE__LIST |
+ Object.FEATURE__ANY_TYPE,
+ "HostVirtualNic" : Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__LIST,
+ "HostVirtualSwitch" : Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__LIST,
+ "KeyValue" : Object.FEATURE__ANY_TYPE,
"ManagedObjectReference" : Object.FEATURE__ANY_TYPE,
+ "PhysicalNic" : Object.FEATURE__LIST |
+ Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__DEEP_COPY,
"ObjectContent" : Object.FEATURE__DEEP_COPY,
+ "OptionValue" : Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__LIST,
+ "PhysicalNic" : Object.FEATURE__LIST |
+ Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__DEEP_COPY,
+ "PhysicalNicSpec" : Object.FEATURE__DEEP_COPY,
+ "PhysicalNicLinkInfo" : Object.FEATURE__LIST,
"ResourcePoolResourceUsage" : Object.FEATURE__ANY_TYPE,
"ServiceContent" : Object.FEATURE__DESERIALIZE,
"SharesInfo" : Object.FEATURE__ANY_TYPE,
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index bcc310f..f23af8d 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -475,7 +475,23 @@
continue; \
}
-
+#define ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_STRING_LIST(_type, _name) \
+ if (xmlStrEqual(childNode->name, BAD_CAST #_name)) { \
+ char *value = NULL; \
+ \
+ if (esxVI_String_DeserializeValue(childNode, &value) < 0 || \
+ value == NULL) { \
+ goto failure; \
+ } \
+ \
+ if (esxVI_##_type##_AppendValueToList(&(*ptrptr)->_name, \
+ value) < 0) { \
+ VIR_FREE(value); \
+ goto failure; \
+ } \
+ \
+ continue; \
+ }
/*
* A required property must be != 0 (NULL for pointers, "undefined" == 0 for
--
1.7.9.5
12 years, 5 months