[libvirt] Intend to add fuse filesystem support for libvirt lxc
by Gao feng
Hi Everyone,
Now I'm working on making the container's system info(such as /proc/meminfo,cpuinfo..) isolate from
the host.
I made a patch which implement showing the /proc/meminfo base on container's memcg,
and sent it to the community.(http://marc.info/?l=linux-mm&m=133826035821338&w=2)
but I found it's difficult to be accepted, because this way is ugly,
and somebody gave me some suggestions.
the first way is making another kernel file(just like memory.limit_in_bytes),and mount it to the container.
I don't like this way,because there will be many redundance information between this new kernel file and
the existing kernel file,some files such as memory.stat already contains memcg information.
the other way is adding fuse filesystem support for libvirt lxc.
with this way,
we can simply collect information from cgroup in fuse_operations.read function,
and mount this file to the container.
we can impletment isolate meminfo in userspace without changing kernel codes.
I have impletment fuse support for libvrit now, and ready to impletement the meminfo isolated.
I want to know if you have any comment or another ideas?
please let me know.
thanks.
12 years, 5 months
[libvirt] [PATCH] build: define WITH_INTERFACE for the driver
by Eric Blake
Our code was mistakenly relying on an undefined macro, WITH_INTERFACE,
for determining whether to load the interface driver which wraps the
netcf library. Clean this situation up by having only one automake
conditional for the driver, and having both WITH_NETCF (library
detected) and WITH_INTERFACE (driver enabled) in C code, in case a
future patch ever adds a network management via means other than
the netcf library.
While at it, output more information at the conclusion of configure
about the various drivers we enabled.
* configure.ac: Enhance with_netcf, and add with_interface.
Improve output to list final decisions. Replace WITH_NETCF with
WITH_INTERFACE.
* src/interface/netcf_driver.c: Rename...
* src/interface/interface_driver.c: ...to this.
* src/interface/interface_driver.h: Likewise.
* daemon/Makefile.am (libvirtd_LDADD): Reflect better naming.
* src/Makefile.am (libvirt_driver_interface_la_*): Likewise.
(INTERFACE_DRIVER_SOURCES): Reflect file moves.
* daemon/libvirtd.c (daemonInitialize): Likewise.
* tools/virsh.c (vshShowVersion): Show both driver and library
decisions.
* libvirt.spec.in (with_interface): Tweak to deal with new usage
as a real switch.
---
I think this addresses the point that Osier raised here:
https://www.redhat.com/archives/libvir-list/2012-June/msg01266.html
but it is complex enough that I'd appreciate a careful review.
configure.ac | 44 ++++++++++++++++----
daemon/Makefile.am | 2 +-
daemon/libvirtd.c | 6 +--
libvirt.spec.in | 10 +++--
src/Makefile.am | 4 +-
.../{netcf_driver.c => interface_driver.c} | 4 +-
.../{netcf_driver.h => interface_driver.h} | 0
tools/virsh.c | 11 +++--
8 files changed, 59 insertions(+), 22 deletions(-)
rename src/interface/{netcf_driver.c => interface_driver.c} (99%)
rename src/interface/{netcf_driver.h => interface_driver.h} (100%)
diff --git a/configure.ac b/configure.ac
index 6436885..a29b3b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1755,6 +1755,7 @@ if test "$with_network" = "yes" ; then
fi
AM_CONDITIONAL([WITH_NETWORK], [test "$with_network" = "yes"])
+dnl check whether helper code is needed for above selections
with_bridge=no
if test "$with_qemu:$with_lxc:$with_network" != "no:no:no"; then
with_bridge=yes
@@ -1762,16 +1763,31 @@ if test "$with_qemu:$with_lxc:$with_network" != "no:no:no"; then
fi
AM_CONDITIONAL([WITH_BRIDGE], [test "$with_bridge" = "yes"])
-dnl netcf library
+dnl check if the interface driver should be compiled
+
+AC_ARG_WITH([interface],
+ AC_HELP_STRING([--with-interface],
+ [with host interface driver @<:@default=check@:>@]),[],
+ [with_interface=check])
+
+dnl there's no use compiling the interface driver without the libvirt daemon
+if test "$with_libvirtd" = "no"; then
+ with_interface=no
+fi
+
+dnl The interface driver depends on the netcf library
AC_ARG_WITH([netcf],
AC_HELP_STRING([--with-netcf], [libnetcf support to configure physical host network interfaces @<:@default=check@:>@]),
[], [with_netcf=check])
NETCF_CFLAGS=
NETCF_LIBS=
-if test "$with_libvirtd" = "no" ; then
+if test "$with_libvirtd" = "no" || test "$with_interface" = "no"; then
with_netcf=no
fi
+if test "$with_interface:$with_netcf" = "yes:check"; then
+ with_netcf=yes
+fi
if test "$with_netcf" = "yes" || test "$with_netcf" = "check"; then
PKG_CHECK_MODULES(NETCF, netcf >= $NETCF_REQUIRED,
[with_netcf=yes], [
@@ -1792,11 +1808,21 @@ if test "$with_netcf" = "yes" || test "$with_netcf" = "check"; then
fi
fi
fi
-AM_CONDITIONAL([WITH_NETCF], [test "$with_netcf" = "yes"])
AC_SUBST([NETCF_CFLAGS])
AC_SUBST([NETCF_LIBS])
+dnl Final decision on the interface driver
+if test "$with_interface" = "check"; then
+ with_interface=$with_netcf
+fi
+
+if test "$with_interface" = "yes" ; then
+ AC_DEFINE_UNQUOTED([WITH_INTERFACE], [1],
+ [whether interface driver is enabled])
+fi
+AM_CONDITIONAL([WITH_INTERFACE], [test "$with_interface" = "yes"])
+dnl Check whether the Secrets driver is needed
AC_ARG_WITH([secrets],
AC_HELP_STRING([--with-secrets], [with local secrets management driver @<:@default=yes@:>@]),[],[with_secrets=yes])
@@ -2807,11 +2833,12 @@ AC_MSG_NOTICE([ ESX: $with_esx])
AC_MSG_NOTICE([ Hyper-V: $with_hyperv])
AC_MSG_NOTICE([ Test: $with_test])
AC_MSG_NOTICE([ Remote: $with_remote])
-AC_MSG_NOTICE([ Network: $with_network])
AC_MSG_NOTICE([Libvirtd: $with_libvirtd])
-AC_MSG_NOTICE([ netcf: $with_netcf])
-AC_MSG_NOTICE([ macvtap: $with_macvtap])
-AC_MSG_NOTICE([virtport: $with_virtualport])
+AC_MSG_NOTICE([ Network: $with_network])
+AC_MSG_NOTICE([ Iface: $with_interface])
+AC_MSG_NOTICE([ Secrets: $with_secrets])
+AC_MSG_NOTICE([ NodeDev: $with_nodedev])
+AC_MSG_NOTICE([NWfilter: $with_nwfilter])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Storage Drivers])
AC_MSG_NOTICE([])
@@ -2977,6 +3004,9 @@ AC_MSG_NOTICE([ Readline: $lv_use_readline])
AC_MSG_NOTICE([ Python: $with_python])
AC_MSG_NOTICE([ DTrace: $with_dtrace])
AC_MSG_NOTICE([ numad: $with_numad])
+AC_MSG_NOTICE([ bridge: $with_bridge])
+AC_MSG_NOTICE([ macvtap: $with_macvtap])
+AC_MSG_NOTICE([ virtport: $with_virtualport])
AC_MSG_NOTICE([ XML Catalog: $XML_CATALOG_FILE])
AC_MSG_NOTICE([ Init script: $with_init_script])
AC_MSG_NOTICE([Console locks: $with_console_lock_files])
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 71e91cd..f0e422e 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -148,7 +148,7 @@ if WITH_NETWORK
libvirtd_LDADD += ../src/libvirt_driver_network.la
endif
-if WITH_NETCF
+if WITH_INTERFACE
libvirtd_LDADD += ../src/libvirt_driver_interface.la
endif
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 9c06344..a4f98cf 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -74,8 +74,8 @@
# ifdef WITH_NETWORK
# include "network/bridge_driver.h"
# endif
-# ifdef WITH_NETCF
-# include "interface/netcf_driver.h"
+# ifdef WITH_INTERFACE
+# include "interface/interface_driver.h"
# endif
# ifdef WITH_STORAGE
# include "storage/storage_driver.h"
@@ -400,7 +400,7 @@ static void daemonInitialize(void)
# ifdef WITH_NETWORK
networkRegister();
# endif
-# ifdef WITH_NETCF
+# ifdef WITH_INTERFACE
interfaceRegister();
# endif
# ifdef WITH_STORAGE
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 896ef51..26ea2d9 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -70,6 +70,7 @@
# Then the secondary host drivers, which run inside libvirtd
%define with_network 0%{!?_without_network:%{server_drivers}}
+%define with_interface 0%{!?_without_interface:%{server_drivers}}
%define with_storage_fs 0%{!?_without_storage_fs:%{server_drivers}}
%define with_storage_lvm 0%{!?_without_storage_lvm:%{server_drivers}}
%define with_storage_iscsi 0%{!?_without_storage_iscsi:%{server_drivers}}
@@ -214,6 +215,7 @@
# The logic is the same as in configure.ac
%if ! %{with_libvirtd}
%define with_network 0
+%define with_interface 0
%define with_qemu 0
%define with_lxc 0
%define with_uml 0
@@ -267,9 +269,7 @@
%define with_nodedev 0
%endif
-%if %{with_netcf}
-%define with_interface 1
-%else
+%if !%{with_netcf}
%define with_interface 0
%endif
@@ -1056,6 +1056,9 @@ of recent versions of Linux (and other OSes).
%define _without_network --without-network
%endif
+%if ! %{with_interface}
+%define _without_interface --without-interface
+%endif
%if ! %{with_storage_fs}
%define _without_storage_fs --without-storage-fs
%endif
@@ -1171,6 +1174,7 @@ autoreconf -if
%{?_without_hyperv} \
%{?_without_vmware} \
%{?_without_network} \
+ %{?_without_interface} \
%{?_with_rhel5_api} \
%{?_without_storage_fs} \
%{?_without_storage_lvm} \
diff --git a/src/Makefile.am b/src/Makefile.am
index 2309984..3cfaf01 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -483,7 +483,7 @@ NETWORK_DRIVER_SOURCES = \
network/bridge_driver.h network/bridge_driver.c
INTERFACE_DRIVER_SOURCES = \
- interface/netcf_driver.h interface/netcf_driver.c
+ interface/interface_driver.h interface/interface_driver.c
SECRET_DRIVER_SOURCES = \
secret/secret_driver.h secret/secret_driver.c
@@ -924,7 +924,7 @@ EXTRA_DIST += network/default.xml
-if WITH_NETCF
+if WITH_INTERFACE
if WITH_DRIVER_MODULES
mod_LTLIBRARIES += libvirt_driver_interface.la
else
diff --git a/src/interface/netcf_driver.c b/src/interface/interface_driver.c
similarity index 99%
rename from src/interface/netcf_driver.c
rename to src/interface/interface_driver.c
index 45e6442..4959c72 100644
--- a/src/interface/netcf_driver.c
+++ b/src/interface/interface_driver.c
@@ -2,7 +2,7 @@
* interface_driver.c: backend driver methods to handle physical
* interface configuration using the netcf library.
*
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@
#include "virterror_internal.h"
#include "datatypes.h"
-#include "netcf_driver.h"
+#include "interface_driver.h"
#include "interface_conf.h"
#include "memory.h"
diff --git a/src/interface/netcf_driver.h b/src/interface/interface_driver.h
similarity index 100%
rename from src/interface/netcf_driver.h
rename to src/interface/interface_driver.h
diff --git a/tools/virsh.c b/tools/virsh.c
index 53d1825..c1e7010 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -20832,15 +20832,18 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
#ifdef WITH_NETWORK
vshPrint(ctl, " Network");
#endif
-#ifdef WITH_BRIDGE
- vshPrint(ctl, " Bridging");
-#endif
-#ifdef WITH_NETCF
+#ifdef WITH_INTERFACE
vshPrint(ctl, " Interface");
#endif
#ifdef WITH_NWFILTER
vshPrint(ctl, " Nwfilter");
#endif
+#ifdef WITH_BRIDGE
+ vshPrint(ctl, " Bridging");
+#endif
+#ifdef WITH_NETCF
+ vshPrint(ctl, " Netcf");
+#endif
#ifdef WITH_VIRTUALPORT
vshPrint(ctl, " VirtualPort");
#endif
--
1.7.10.4
12 years, 5 months
[libvirt] [PATCH] esx_storage_driver: Add API to upload volumes (virStorageVolUpload for ESX storage driver)
by Ata Bohra
Patch to add API to upload Volume contents using ESX driver. As stream driver is not supported for ESX, I have used libcurl to transfer the volume, second, using flags here to pass
file descriptor of the source file.
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index 9b64891..0519efc 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -1643,6 +1643,94 @@ esxStoragePoolIsPersistent(virStoragePoolPtr pool ATTRIBUTE_UNUSED)
return 1;
}
+/**
+ * esxStorageVolumeUpload
+ *
+ * Upload file contents to a given volume.
+ * Method uses libcurl to POST the contents to ESX server.
+ * flags is used to pass file descriptor of the
+ * source file to be read.
+ */
+static int
+esxStorageVolumeUpload(virStorageVolPtr volume,
+ virStreamPtr stream,
+ unsigned long long offset,
+ unsigned long long length,
+ unsigned int flags)
+{
+ esxPrivate *priv = volume->conn->privateData;
+ int err = -1;
+ char *escapedDatastoreName = NULL;
+ char *url = NULL;
+ virBuffer buffer = VIR_BUFFER_INITIALIZER;
+ int fd = (int)flags;
+
+ /**
+ * Use CURL module to transfer the file to ESX.
+ * Use flags to pass the file handle.
+ */
+ const char *unescapedDatastoreName = virStorageVolGetPoolName(volume);
+ const char *volumeName = virStorageVolGetName(volume);
+
+ if (!unescapedDatastoreName) {
+ goto cleanup;
+ }
+
+ if (volume->conn != stream->conn) {
+ virReportInvalidArg(conn,
+ _("conn in %s must match stream connection."),
+ __FUNCTION__);
+ goto cleanup;
+ }
+
+ virBufferAsprintf(&buffer, "%s://%s:%d/folder/",
+ priv->parsedUri->transport,
+ volume->conn->uri->server, volume->conn->uri->port);
+
+ escapedDatastoreName = esxUtil_EscapeDatastoreItem(unescapedDatastoreName);
+
+ if (escapedDatastoreName == NULL) {
+ goto cleanup;
+ }
+
+ /* Prepare URL to upload file */
+ virBufferAdd(&buffer, volumeName, strlen(volumeName));
+ virBufferAddLit(&buffer, "?dcPath=");
+ virBufferURIEncodeString(&buffer, priv->primary->datacenterPath);
+ virBufferAddLit(&buffer, "&dsName=");
+ virBufferURIEncodeString(&buffer, escapedDatastoreName);
+
+ if (virBufferError(&buffer)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ url = virBufferContentAndReset(&buffer);
+
+ if (esxVI_EnsureSession(priv->primary) < 0) {
+ return -1;
+ }
+
+ /* Upload file */
+ if (esxVI_CURL_UploadFile(priv->primary->curl, url,
+ fd, offset, length) < 0) {
+ goto cleanup;
+ }
+
+ err = 0;
+
+ cleanup:
+
+ if (url == NULL) {
+ virBufferFreeAndReset(&buffer);
+ }
+
+ VIR_FREE(escapedDatastoreName);
+ VIR_FREE(url);
+
+ return err;
+
+}
static virStorageDriver esxStorageDriver = {
@@ -1673,6 +1761,7 @@ static virStorageDriver esxStorageDriver = {
.volGetInfo = esxStorageVolumeGetInfo, /* 0.8.4 */
.volGetXMLDesc = esxStorageVolumeGetXMLDesc, /* 0.8.4 */
.volGetPath = esxStorageVolumeGetPath, /* 0.8.4 */
+ .volUpload = esxStorageVolumeUpload, /* 0.9.x */
.poolIsActive = esxStoragePoolIsActive, /* 0.8.2 */
.poolIsPersistent = esxStoragePoolIsPersistent, /* 0.8.2 */
};
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 5b5ab69..831ae36 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -425,7 +425,67 @@ esxVI_CURL_Upload(esxVI_CURL *curl, const char *url, const char *content)
return 0;
}
+static size_t
+esxVI_CURL_read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ size_t retcode = read((int) stream, ptr, size*nmemb);
+
+ VIR_DEBUG("Read bytes: %d", retcode);
+
+ return retcode;
+}
+
+int
+esxVI_CURL_UploadFile(esxVI_CURL *curl,
+ const char *url,
+ int fd,
+ unsigned long long offset,
+ unsigned long long length)
+{
+ int error = -1;
+ int responseCode = 0;
+
+ if (fd < 0) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid file descriptor: %d",
+ fd);
+ goto cleanup;
+ }
+
+ if (lseek(fd, (off_t) offset, SEEK_SET) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Cannot seek file descriptor "));
+ goto cleanup;
+ }
+
+ virMutexLock(&curl->lock);
+
+ /* set CURL headers */
+ curl_easy_setopt(curl->handle, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(curl->handle, CURLOPT_URL, url);
+ curl_easy_setopt(curl->handle, CURLOPT_READDATA, fd);
+ curl_easy_setopt(curl->handle, CURLOPT_INFILESIZE_LARGE,
+ (curl_off_t) length);
+ curl_easy_setopt(curl->handle, CURLOPT_READFUNCTION,
+ esxVI_CURL_read_callback);
+ responseCode = esxVI_CURL_Perform(curl, url);
+
+ virMutexUnlock(&curl->lock);
+
+ if (responseCode < 0) {
+ goto cleanup;
+ } else if (responseCode != 200) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("HTTP response code %d for upload to '%s'"),
+ responseCode, url);
+ goto cleanup;
+ }
+ error = 0;
+
+ cleanup:
+
+ return error;
+}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* SharedCURL
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 78d3986..f95ad1d 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -92,7 +92,6 @@ typedef struct _esxVI_EnumerationValue esxVI_EnumerationValue;
typedef struct _esxVI_List esxVI_List;
-
enum _esxVI_APIVersion {
esxVI_APIVersion_Undefined = 0,
esxVI_APIVersion_Unknown,
@@ -167,6 +166,9 @@ void esxVI_CURL_Free(esxVI_CURL **curl);
int esxVI_CURL_Connect(esxVI_CURL *curl, esxUtil_ParsedUri *parsedUri);
int esxVI_CURL_Download(esxVI_CURL *curl, const char *url, char **content);
int esxVI_CURL_Upload(esxVI_CURL *curl, const char *url, const char *content);
+int esxVI_CURL_UploadFile(esxVI_CURL *curl, const char *url, int fd,
+ unsigned long long offset,
+ unsigned long long length);
diff --git a/src/libvirt.c b/src/libvirt.c
index 0aa50cb..508593b 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -12537,6 +12537,28 @@ error:
return NULL;
}
+/**
+ * virStorageVolGetPoolName:
+ * @vol: pointer to storage volume
+ *
+ * Fetch the storage volume pool name.
+ *
+ * Returns the pool name, or NULL on error
+ */
+const char*
+virStorageVolGetPoolName(virStorageVolPtr vol)
+{
+ VIR_DEBUG("vol=%p", vol);
+
+ virResetLastError();
+
+ if (!VIR_IS_STORAGE_VOL(vol)) {
+ virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ virDispatchError(NULL);
+ return NULL;
+ }
+ return vol->pool;
+}
/**
* virStorageVolGetName:
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 2913a81..cdfbf15 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -542,6 +542,7 @@ LIBVIRT_0.9.13 {
virDomainSnapshotIsCurrent;
virDomainSnapshotListAllChildren;
virDomainSnapshotRef;
+ virStorageVolGetPoolName;
} LIBVIRT_0.9.11;
# .... define new API here using predicted next version number ....
Thanks!
Ata
Attachment:
1. StorageVolUpload.diff
12 years, 5 months
[libvirt] Fwd: Re: Intend to add OVA installation API
by Bob Cochran
Ooops, I should have sent this to the list. I want to support Doug's
suggestion, thanks.
Bob Cochran
-------- Original Message --------
Subject: Re: [libvirt] Intend to add OVA installation API
Date: Sun, 24 Jun 2012 22:45:15 -0400
From: Bob Cochran <bcochran13(a)verizon.net>
To: Doug Goldstein <cardoe(a)cardoe.com>
On 6/24/12 6:27 PM, Doug Goldstein wrote:
> On Sun, Jun 24, 2012 at 5:05 PM, Ata Bohra<ata.husain(a)hotmail.com> wrote:
>> Thanks Doug for your suggestions.
>>
>> I believe you are correct about the relation between OVA and OVF. But I am
>> not 100 % possitive about your suggestion: "defining an appropriate domain
>> in libvirt". To understand better I am sharing more details about my plans:
>>
>> 1. Enhance libvirt interface code (libvirt.c) to provide a
>> domain-independent routine: virDomainCreateOVA, an alternate API to create
>> domain.
>> To make client code real simple, this routine can take ova path as input
>> and internally strip the OVA to extract required details. (planning to
>> define a struct to hold all essential
>> information).
>> 2. Second, to enhance ESX driver to perform ESX specfic calls.
>>
>> Given OVA is a tar file, the parsing is just another file open/read
>> operation; it would be simple to perform it inside domain_conf.c (infact I
>> have written a parser to strip information off OVA already).
>>
>> Hope to get some comments/suggestions on above steps.
>>
>> Thanks!
>> Ata
> Right. I'm suggesting you don't go that route and approach the problem
> from another angle. I did a little Googling since my last e-mail to at
> least make sure I understood the basics. So an OVF looks like the
> following:
>
> virtualappliance/package.ovf
> virtualappliance/disk1.vmdk
> virtualappliance/disk2.vmdk
> virtualappliance/cdrom.iso
> virtualappliance/en-US-resources.xml
>
> An OVA would simply be a tar of the above and named
> virtualappliance.ova package.ovf is an XML file containing the
> description of the hardware of the virtual machine, much like the XML
> that libvirt stores about domains. While en-US-resources.xml would be
> the US English descriptions of the machine and its hardware.
>
> I'm suggesting you write an application that transforms package.ovf
> into libvirt's own domain XML format and simply call
> virDomainDefineXML() rather than adding API to libvirt itself. You
> could then further extend the application to allow you to take a
> libvirt domain and export it as a OVA.
>
> Looking at VMWare and Xen, they both treat OVA/OVF as a foreign format
> and require a converter application to import them to their native
> internals so it wouldn't be much different than their approach.
>
> Just my 2 cents.
I really like what Doug suggests here.
Bob Cochran
12 years, 5 months
[libvirt] nwfilter: Fix memory leak
by Stefan Berger
Below patch fixes this coverity report:
/libvirt/src/conf/nwfilter_conf.c:382:
leaked_storage: Variable "varAccess" going out of scope leaks the
storage it points to.
---
src/conf/nwfilter_conf.c | 1 +
1 file changed, 1 insertion(+)
Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -379,6 +379,7 @@ virNWFilterRuleDefAddVar(virNWFilterRule
if (VIR_EXPAND_N(nwf->varAccess, nwf->nVarAccess, 1) < 0) {
virReportOOMError();
+ virNWFilterVarAccessFree(varAccess);
return -1;
}
12 years, 5 months
[libvirt] [PATCH] Remove sub-mounts under /dev when starting an LXC container
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Since we are mounting a new /dev in the container, we must
remove any sub-mounts like /dev/shm, /dev/mqueue, etc,
otherwise they'll be recorded in /proc/mounts, but not be
accessible to applications.
---
src/lxc/lxc_container.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 071d8d1..910e82b 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1416,10 +1416,11 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
if (lxcContainerPivotRoot(root) < 0)
goto cleanup;
- /* Gets rid of any existing stuff under /proc, since we need new
- * namespace aware versions of those. We must do /proc second
- * otherwise we won't find /proc/mounts :-) */
+ /* Gets rid of any existing stuff under /proc, /sys & /tmp
+ * We need new namespace aware versions of those. We must
+ * do /proc last otherwise we won't find /proc/mounts :-) */
if (lxcContainerUnmountSubtree("/sys", false) < 0 ||
+ lxcContainerUnmountSubtree("/dev", false) < 0 ||
lxcContainerUnmountSubtree("/proc", false) < 0)
goto cleanup;
--
1.7.10.4
12 years, 5 months
[libvirt] [PATCH] Fix vm's outbound traffic control problem
by Eiichi Tsukata
Hello,
This is a patch to fix vm's outbound traffic control problem.
Currently, vm's outbound traffic control by libvirt doesn't go well.
This problem was previously discussed at libvir-list ML, however
it seems that there isn't still any answer to the problem.
http://www.redhat.com/archives/libvir-list/2011-August/msg00333.html
I measured Guest(with virtio-net) to Host TCP throughput with the
command "netperf -H".
Here are the outbound QoS parameters and the results.
outbound average rate[kilobytes/s] : Guest to Host throughput[Mbit/s]
======================================================================
1024 (8Mbit/s) : 4.56
2048 (16Mbit/s) : 3.29
4096 (32Mbit/s) : 3.35
8192 (64Mbit/s) : 3.95
16384 (128Mbit/s) : 4.08
32768 (256Mbit/s) : 3.94
65536 (512Mbit/s) : 3.23
The outbound traffic goes down unreasonably and is even not controled.
The cause of this problem is too large mtu value in "tc filter" command run by
libvirt. The command uses burst value to set mtu and the burst is equal to
average rate value if it's not set. This value is too large. For example
if the average rate is set to 1024 kilobytes/s, the mtu value is set to 1024
kilobytes. That's too large compared to the size of network packets.
Here libvirt applies tc ingress filter to Host's vnet(tun) device.
Tc ingress filter is implemented with TBF(Token Buckets Filter) algorithm. TBF
uses mtu value to calculate the amount of token consumed by each packet. With too
large mtu value, the token consumption rate is set too large. This leads to
token starvation and deterioration of TCP throughput.
Then, should we use the default mtu value 2 kilobytes?
The anser is No, because Guest with virtio-net device uses 65536 bytes
as mtu to transmit packets to Host, and the tc filter with the default mtu
value 2k drops packets whose size is larger than 2k. So, the most packets
is droped and again leads to deterioration of TCP throughput.
The appropriate mtu value is 65536 bytes which is equal to the maximum value
of network interface device defined in <linux/netdevice.h>. The value is
not so large that it causes token starvation and not so small that it
drops most packets.
Therefore this patch set the mtu value to 64kb(== 65535 bytes).
Again, here are the outbound QoS parameters and the TCP throughput with
the libvirt patched.
outbound average rate[kilobytes/s] : Guest to Host throughput[Mbit/s]
======================================================================
1024 (8Mbit/s) : 8.22
2048 (16Mbit/s) : 16.42
4096 (32Mbit/s) : 32.93
8192 (64Mbit/s) : 66.85
16384 (128Mbit/s) : 133.88
32768 (256Mbit/s) : 271.01
65536 (512Mbit/s) : 547.32
The outbound traffic conforms to the given limit.
Thank you,
Signed-off-by: Eiichi Tsukata <eiichi.tsukata.xh(a)hitachi.com>
---
AUTHORS | 1 +
src/util/virnetdevbandwidth.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index b876ee6..375db24 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -246,6 +246,7 @@ Patches have also been contributed by:
Gerd Hoffmann <kraxel(a)redhat.com>
Viktor Mihajlovski <mihajlov(a)linux.vnet.ibm.com>
Thang Pham <thang.pham(a)us.ibm.com>
+ Eiichi Tsukata <eiichi.tsukata.xh(a)hitachi.com>
[....send patches to get your name here....]
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
index b9bd2e3..93df5c1 100644
--- a/src/util/virnetdevbandwidth.c
+++ b/src/util/virnetdevbandwidth.c
@@ -136,7 +136,7 @@ virNetDevBandwidthSet(const char *ifname,
virCommandAddArgList(cmd, "filter", "add", "dev", ifname, "parent",
"ffff:", "protocol", "ip", "u32", "match", "ip",
"src", "0.0.0.0/0", "police", "rate", average,
- "burst", burst, "mtu", burst, "drop", "flowid",
+ "burst", burst, "mtu", "64kb", "drop", "flowid",
":1", NULL);
if (virCommandRun(cmd, NULL) < 0)
--
1.7.4.4
--
Eiichi Tsukata
Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: eiichi.tsukata.xh(a)hitachi.com
12 years, 5 months
[libvirt] [PATCH] network_conf: Don't free uninitialized pointers while parsing DNS SRV
by Peter Krempa
If the user specified invalid protocol type in a network's SRV record
the error path ended up in freeing uninitialized pointers causing a
daemon crash.
*network_conf.c: virNetworkDNSSrvDefParseXML(): initialize local
variables
---
src/conf/network_conf.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 60cd888..515bc36 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -574,10 +574,10 @@ virNetworkDNSSrvDefParseXML(virNetworkDNSDefPtr def,
xmlNodePtr cur,
xmlXPathContextPtr ctxt)
{
- char *domain;
- char *service;
- char *protocol;
- char *target;
+ char *domain = NULL;
+ char *service = NULL;
+ char *protocol = NULL;
+ char *target = NULL;
int port;
int priority;
int weight;
--
1.7.8.6
12 years, 5 months
[libvirt] [PATCH] virsh: Cleanup virsh -V output
by Doug Goldstein
Fixed up virsh -V output by removing invalid WITH_PROXY & WITH_ONE
checks, adding Hyper-V check and fixing the DTrace check.
Signed-off-by: Doug Goldstein <cardoe(a)cardoe.com>
---
tools/virsh.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 2b4cb2c..9fccd2d 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -20636,8 +20636,8 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
#ifdef WITH_PHYP
vshPrint(ctl, " PHYP");
#endif
-#ifdef WITH_ONE
- vshPrint(ctl, " ONE");
+#ifdef WITH_HYPERV
+ vshPrint(ctl, " Hyper-V");
#endif
#ifdef WITH_TEST
vshPrint(ctl, " Test");
@@ -20648,9 +20648,6 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
#ifdef WITH_REMOTE
vshPrint(ctl, " Remote");
#endif
-#ifdef WITH_PROXY
- vshPrint(ctl, " Proxy");
-#endif
#ifdef WITH_LIBVIRTD
vshPrint(ctl, " Daemon");
#endif
@@ -20711,7 +20708,7 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
#ifdef ENABLE_DEBUG
vshPrint(ctl, " Debug");
#endif
-#ifdef WITH_DTRACE
+#ifdef WITH_DTRACE_PROBES
vshPrint(ctl, " DTrace");
#endif
#ifdef USE_READLINE
--
1.7.3.4
12 years, 5 months
[libvirt] [PATCH] conf: Don't shadow error from virGetDomain()
by Peter Krempa
virGetDomain() does a good job of reporting errors itself. This patch
removes shadowing of that error in virDomainListPopulate().
---
src/conf/virdomainlist.c | 11 ++++-------
1 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/conf/virdomainlist.c b/src/conf/virdomainlist.c
index f9fbde8..2b0b878 100644
--- a/src/conf/virdomainlist.c
+++ b/src/conf/virdomainlist.c
@@ -117,8 +117,10 @@ virDomainListPopulate(void *payload,
return;
}
- if (!(dom = virGetDomain(data->conn, vm->def->name, vm->def->uuid)))
- goto no_memory;
+ if (!(dom = virGetDomain(data->conn, vm->def->name, vm->def->uuid))) {
+ data->error = true;
+ goto cleanup;
+ }
dom->id = vm->def->id;
@@ -127,11 +129,6 @@ virDomainListPopulate(void *payload,
cleanup:
virDomainObjUnlock(vm);
return;
-
-no_memory:
- virReportOOMError();
- data->error = true;
- goto cleanup;
}
#undef MATCH
--
1.7.8.6
12 years, 5 months