[libvirt] [PATCH] Allow use of block devices for guest filesystem
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Currently the LXC driver can only populate filesystems from
host filesystems, using bind mounts. This patch allows host
block devices to be mounted. It autodetects the filesystem
format at mount time, and adds the block device to the cgroups
ACL. Example usage is
<filesystem type='block' accessmode='passthrough'>
<source dev='/dev/sda1'/>
<target dir='/home'/>
</filesystem>
* src/lxc/lxc_container.c: Mount block device filesystems
* src/lxc/lxc_controller.c: Add block device filesystems
to cgroups ACL
---
src/lxc/lxc_container.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
src/lxc/lxc_controller.c | 17 +++++
2 files changed, 195 insertions(+), 1 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 026d621..f6ab407 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -35,6 +35,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <mntent.h>
+#include <dirent.h>
/* Yes, we want linux private one, for _syscall2() macro */
#include <linux/unistd.h>
@@ -597,12 +598,184 @@ static int lxcContainerMountFSBind(virDomainFSDefPtr fs,
virReportSystemError(errno,
_("Failed to make directory %s readonly"),
fs->dst);
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(src);
+ return ret;
+}
+
+
+
+/*
+ * This functions attempts todo automatic detection of filesystem
+ * type following the same rules as the util-linux 'mount' binary.
+ *
+ * The main difference is that we don't (currently) try to use
+ * libblkid to detect the format first. We go straight to using
+ * /etc/filesystems, and then /proc/filesystems
+ */
+static int lxcContainerMountFSBlockAuto(virDomainFSDefPtr fs,
+ int flags,
+ const char *src,
+ const char *srcprefix)
+{
+ FILE *fp = NULL;
+ int ret = -1;
+ bool tryProc = false;
+ bool gotStar = false;
+ char *fslist = NULL;
+ char *line = NULL;
+ const char *type;
+
+ VIR_DEBUG("src=%s srcprefix=%s dst=%s", src, srcprefix, fs->dst);
+
+ /* First time around we use /etc/filesystems */
+retry:
+ if (virAsprintf(&fslist, "%s%s",
+ srcprefix, tryProc ? "/proc/filesystems" : "/etc/filesystems") < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Open fslist %s", fslist);
+ if (!(fp = fopen(fslist, "r"))) {
+ /* If /etc/filesystems does not exist, then we need to retry
+ * with /proc/filesystems next
+ */
+ if (errno == ENOENT &&
+ !tryProc) {
+ tryProc = true;
+ VIR_FREE(fslist);
+ goto retry;
+ }
+
+ virReportSystemError(errno,
+ _("Unable to read %s"),
+ fslist);
+ goto cleanup;
+ }
+
+ while (!feof(fp)) {
+ size_t n;
+ VIR_FREE(line);
+ if (getline(&line, &n, fp) <= 0) {
+ if (feof(fp))
+ break;
+
goto cleanup;
}
+ if (strstr(line, "nodev"))
+ continue;
+
+ type = strchr(line, '\n');
+ if (type)
+ line[type-line] = '\0';
+
+ type = line;
+ virSkipSpaces(&type);
+
+ /*
+ * /etc/filesystems is only allowed to contain '*' on the last line
+ */
+ if (gotStar) {
+ lxcError(VIR_ERR_INTERNAL_ERROR,
+ _("%s has unexpected '*' before last line"),
+ fslist);
+ goto cleanup;
+ }
+
+ /* An '*' on the last line in /etc/filesystems
+ * means try /proc/filesystems next. We don't
+ * jump immediately though, since we need to see
+ * if any more lines follow
+ */
+ if (!tryProc &&
+ STREQ(type, "*"))
+ gotStar = true;
+
+ VIR_DEBUG("Trying mount %s with %s", src, type);
+ if (mount(src, fs->dst, type, flags, NULL) < 0) {
+ /* These errnos indicate a bogus filesystem type for
+ * the image we have, so skip to the next type
+ */
+ if (errno == EINVAL || errno == ENODEV)
+ continue;
+
+ virReportSystemError(errno,
+ _("Failed to bind mount directory %s to %s"),
+ src, fs->dst);
+ goto cleanup;
+ }
+
+ ret = 0;
+ break;
}
- ret = 0;
+ /* We've got to the end of /etc/filesystems and saw
+ * a '*', so we mhust try /proc/filesystems next
+ */
+ if (ret != 0 &&
+ !tryProc &&
+ gotStar) {
+ tryProc = true;
+ VIR_FREE(fslist);
+ VIR_FORCE_FCLOSE(fp);
+ goto retry;
+ }
+
+ VIR_DEBUG("Done mounting filesystem ret=%d tryProc=%d", ret, tryProc);
+
+cleanup:
+ VIR_FREE(line);
+ VIR_FORCE_FCLOSE(fp);
+ return ret;
+}
+
+
+/*
+ * Mount a block device 'src' on fs->dst, automatically
+ * probing for filesystem type
+ */
+static int lxcContainerMountFSBlockHelper(virDomainFSDefPtr fs,
+ const char *src,
+ const char *srcprefix)
+{
+ int flags = 0;
+ int ret = -1;
+ if (fs->readonly)
+ flags |= MS_RDONLY;
+
+ if (virFileMakePath(fs->dst) < 0) {
+ virReportSystemError(errno,
+ _("Failed to create %s"),
+ fs->dst);
+ goto cleanup;
+ }
+
+ ret = lxcContainerMountFSBlockAuto(fs, flags, src, srcprefix);
+
+cleanup:
+ return ret;
+}
+
+
+static int lxcContainerMountFSBlock(virDomainFSDefPtr fs,
+ const char *srcprefix)
+{
+ char *src = NULL;
+ int ret = -1;
+
+ if (virAsprintf(&src, "%s%s", srcprefix, fs->src) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ ret = lxcContainerMountFSBlockHelper(fs, src, srcprefix);
VIR_DEBUG("Done mounting filesystem ret=%d", ret);
@@ -620,6 +793,10 @@ static int lxcContainerMountFS(virDomainFSDefPtr fs,
if (lxcContainerMountFSBind(fs, srcprefix) < 0)
return -1;
break;
+ case VIR_DOMAIN_FS_TYPE_BLOCK:
+ if (lxcContainerMountFSBlock(fs, srcprefix) < 0)
+ return -1;
+ break;
default:
lxcError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Cannot mount filesystem type %s"),
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index ff42aa5..bc5ee25 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -188,6 +188,23 @@ static int lxcSetContainerResources(virDomainDefPtr def)
}
}
+ for (i = 0 ; i < def->nfss ; i++) {
+ if (def->fss[i]->type != VIR_DOMAIN_FS_TYPE_BLOCK)
+ continue;
+
+ rc = virCgroupAllowDevicePath(cgroup,
+ def->fss[i]->src,
+ def->fss[i]->readonly ?
+ VIR_CGROUP_DEVICE_READ :
+ VIR_CGROUP_DEVICE_RW);
+ if (rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to allow device %s for domain %s"),
+ def->fss[i]->src, def->name);
+ goto cleanup;
+ }
+ }
+
rc = virCgroupAllowDeviceMajor(cgroup, 'c', LXC_DEV_MAJ_PTY,
VIR_CGROUP_DEVICE_RWM);
if (rc != 0) {
--
1.7.6
13 years, 3 months
[libvirt] [PATCH] network: eliminate lag in updating dnsmasq hosts files
by Laine Stump
This addresses https://bugzilla.redhat.com/show_bug.cgi?id=713728
When "defining" a new network (or one that exists but isn't currently
active) the new definition is stored in network->def, but for a
network that already exists and is active, the new definition is
stored in network->newDef, and then moved over to network->def as soon
as the network is destroyed.
However, the code that writes the dhcp and dns hosts files used by
dnsmasq was always using network->def for its information, even when
the new data was actually in network->newDef, so the hosts files
always lagged one edit behind the definition.
This patch changes the code to keep the pointer to the new definition
after it's been assigned into the network, and use it directly
(regardless of whether it's stored in network->newDef or network->def)
to construct the hosts files.
---
src/network/bridge_driver.c | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index c7d2dfd..c90db63 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2338,6 +2338,7 @@ static virNetworkPtr networkDefine(virConnectPtr conn, const char *xml) {
struct network_driver *driver = conn->networkPrivateData;
virNetworkIpDefPtr ipdef, ipv4def = NULL;
virNetworkDefPtr def;
+ bool freeDef = true;
virNetworkObjPtr network = NULL;
virNetworkPtr ret = NULL;
int ii;
@@ -2367,21 +2368,19 @@ static virNetworkPtr networkDefine(virConnectPtr conn, const char *xml) {
if (!(network = virNetworkAssignDef(&driver->networks,
def)))
goto cleanup;
- def = NULL;
+ freeDef = false;
network->persistent = 1;
- if (virNetworkSaveConfig(driver->networkConfigDir,
- network->newDef ? network->newDef : network->def) < 0) {
- virNetworkRemoveInactive(&driver->networks,
- network);
+ if (virNetworkSaveConfig(driver->networkConfigDir, def) < 0) {
+ virNetworkRemoveInactive(&driver->networks, network);
network = NULL;
goto cleanup;
}
/* We only support dhcp on one IPv4 address per defined network */
for (ii = 0;
- (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
+ (ipdef = virNetworkDefGetIpByIndex(def, AF_UNSPEC, ii));
ii++) {
if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) {
if (ipdef->nranges || ipdef->nhosts) {
@@ -2396,18 +2395,19 @@ static virNetworkPtr networkDefine(virConnectPtr conn, const char *xml) {
}
}
if (ipv4def) {
- dctx = dnsmasqContextNew(network->def->name, DNSMASQ_STATE_DIR);
+ dctx = dnsmasqContextNew(def->name, DNSMASQ_STATE_DIR);
if (dctx == NULL ||
- networkBuildDnsmasqHostsfile(dctx, ipv4def, network->def->dns) < 0 ||
+ networkBuildDnsmasqHostsfile(dctx, ipv4def, def->dns) < 0 ||
dnsmasqSave(dctx) < 0)
goto cleanup;
}
- VIR_INFO("Defining network '%s'", network->def->name);
- ret = virGetNetwork(conn, network->def->name, network->def->uuid);
+ VIR_INFO("Defining network '%s'", def->name);
+ ret = virGetNetwork(conn, def->name, def->uuid);
cleanup:
- virNetworkDefFree(def);
+ if (freeDef)
+ virNetworkDefFree(def);
dnsmasqContextFree(dctx);
if (network)
virNetworkObjUnlock(network);
--
1.7.3.4
13 years, 3 months
[libvirt] [PATCH] Don't mount /dev for application containers
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
An application container shouldn't get a private /dev. Fix
the regression from 6d37888e6a35a37e6faf7c0a1b1b4d9a5dee1285
* src/lxc/lxc_container.c: Don't mount /dev for app containers
---
src/lxc/lxc_container.c | 34 ++++++++++++++++++++++------------
1 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index e73128d..cc72586 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -403,9 +403,10 @@ err:
}
-static int lxcContainerMountBasicFS(const char *srcprefix)
+static int lxcContainerMountBasicFS(const char *srcprefix, bool pivotRoot)
{
const struct {
+ bool onlyPivotRoot;
bool needPrefix;
const char *src;
const char *dst;
@@ -419,20 +420,28 @@ static int lxcContainerMountBasicFS(const char *srcprefix)
* mount point in the main OS becomes readonly too which si not what
* we want. Hence some things have two entries here.
*/
- { false, "devfs", "/dev", "tmpfs", "mode=755", MS_NOSUID },
- { false, "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
- { false, "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND },
- { false, "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
- { true, "/sys", "/sys", NULL, NULL, MS_BIND },
- { true, "/sys", "/sys", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
- { true, "/selinux", "/selinux", NULL, NULL, MS_BIND },
- { true, "/selinux", "/selinux", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
+ { true, false, "devfs", "/dev", "tmpfs", "mode=755", MS_NOSUID },
+ { false, false, "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
+ { false, false, "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND },
+ { false, false, "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
+ { false, true, "/sys", "/sys", NULL, NULL, MS_BIND },
+ { false, true, "/sys", "/sys", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
+ { false, true, "/selinux", "/selinux", NULL, NULL, MS_BIND },
+ { false, true, "/selinux", "/selinux", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
};
int i, rc = -1;
+ VIR_DEBUG("Mounting basic filesystems %s pivotRoot=%d", NULLSTR(srcprefix), pivotRoot);
+
for (i = 0 ; i < ARRAY_CARDINALITY(mnts) ; i++) {
char *src = NULL;
const char *srcpath = NULL;
+
+ VIR_DEBUG("Consider %s onlyPivotRoot=%d",
+ mnts[i].src, mnts[i].onlyPivotRoot);
+ if (mnts[i].onlyPivotRoot && !pivotRoot)
+ continue;
+
if (virFileMakePath(mnts[i].dst) < 0) {
virReportSystemError(errno,
_("Failed to mkdir %s"),
@@ -455,6 +464,8 @@ static int lxcContainerMountBasicFS(const char *srcprefix)
(access(srcpath, R_OK) < 0))
continue;
+ VIR_DEBUG("Mount %s on %s type=%s flags=%d, opts=%s",
+ srcpath, mnts[i].dst, mnts[i].type, mnts[i].mflags, mnts[i].opts);
if (mount(srcpath, mnts[i].dst, mnts[i].type, mnts[i].mflags, mnts[i].opts) < 0) {
VIR_FREE(src);
virReportSystemError(errno,
@@ -915,7 +926,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
return -1;
/* Mounts the core /proc, /sys, etc filesystems */
- if (lxcContainerMountBasicFS("/.oldroot") < 0)
+ if (lxcContainerMountBasicFS("/.oldroot", true) < 0)
return -1;
/* Mounts /dev and /dev/pts */
@@ -959,8 +970,7 @@ static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef)
return -1;
/* Mounts the core /proc, /sys, etc filesystems */
- VIR_DEBUG("Mounting basic FS");
- if (lxcContainerMountBasicFS(NULL) < 0)
+ if (lxcContainerMountBasicFS(NULL, false) < 0)
return -1;
VIR_DEBUG("Mounting completed");
--
1.7.6
13 years, 3 months
[libvirt] virNetClientPtr leak in remote driver
by Matthias Bolte
doRemoteClose doesn't free the virNetClientPtr and this creates a
260kb leak per remote connection. This happens because
virNetClientFree doesn't remove the last ref, because virNetClientNew
creates the virNetClientPtr with a refcount of 2.
static virNetClientPtr virNetClientNew(virNetSocketPtr sock,
const char *hostname)
{
[...]
client->refs = 1;
[...]
/* Set up a callback to listen on the socket data */
client->refs++;
if (virNetSocketAddIOCallback(client->sock,
VIR_EVENT_HANDLE_READABLE,
virNetClientIncomingEvent,
client,
virNetClientEventFree) < 0) {
client->refs--;
VIR_DEBUG("Failed to add event watch, disabling events");
}
[...]
}
virNetClientNew adds a ref before calling virNetSocketAddIOCallback
but only removes it when virNetSocketAddIOCallback fails. This seems
wrong too me and the ref should be removed in the success case too.
The same pattern was added in 0302391ee643ad91fdc6d2ecf7e4cf0fc9724516
(Fix race in ref counting when handling RPC jobs)
--- a/src/rpc/virnetserverclient.c
+++ b/src/rpc/virnetserverclient.c
@@ -763,10 +763,12 @@ readmore:
/* Send off to for normal dispatch to workers */
if (msg) {
+ client->refs++;
if (!client->dispatchFunc ||
client->dispatchFunc(client, msg,
client->dispatchOpaque) < 0) {
virNetMessageFree(msg);
client->wantClose = true;
+ client->refs--;
return;
}
}
Again, this seems wrong and the ref should be removed in the success
case here too. Before I spent time to figure out how the refcounting
is supposed to work here I just report it and hope that Dan can easily
fix this.
--
Matthias Bolte
http://photron.blogspot.com
13 years, 3 months
[libvirt] [PATCH] Fix typo in LXC cgroups setup error message
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
* src/lxc/lxc_controller.c: s/PYT/PTY/
---
src/lxc/lxc_controller.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index bc5ee25..8848ae2 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -209,7 +209,7 @@ static int lxcSetContainerResources(virDomainDefPtr def)
VIR_CGROUP_DEVICE_RWM);
if (rc != 0) {
virReportSystemError(-rc,
- _("Unable to allow PYT devices for domain %s"),
+ _("Unable to allow PTY devices for domain %s"),
def->name);
goto cleanup;
}
--
1.7.6
13 years, 3 months
[libvirt] [PATCH] rpc:fix sasl session relocking intead of unlocking it
by Guannan Ren
When to make use of any SASL authentication for TCP sockets by
setting auth_tls = "sasl" in libvirtd.conf on server side,The
client will hange because of the sasl session relocking other than
dropping it in virNetSASLSessionExtKeySize()
---
src/rpc/virnetsaslcontext.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/rpc/virnetsaslcontext.c b/src/rpc/virnetsaslcontext.c
index ef36e2c..d4e7bf2 100644
--- a/src/rpc/virnetsaslcontext.c
+++ b/src/rpc/virnetsaslcontext.c
@@ -298,7 +298,7 @@ int virNetSASLSessionExtKeySize(virNetSASLSessionPtr sasl,
ret = 0;
cleanup:
- virMutexLock(&sasl->lock);
+ virMutexUnlock(&sasl->lock);
return ret;
}
--
1.7.1
13 years, 3 months
[libvirt] REG: JAVA API for physical host addition
by srivatsan jagannathan
Hi Team,
I working on performance measurement of various cloud management
software. I am working on code such that it will calculate (cpu usage,
memory usage, disk io, time of operation & network bandwidth usage) for
various cloud management operation. once such operation is adding 2 or 3
physical host and obtain the above measurement. Is there is any java api
that support this function.
what I need is for creating instance there is method Create() in class
Domain, I need same operation for physical host.
Regards,
Srivatsan J.
13 years, 3 months
[libvirt] [PATCH v3] daemon: Unlink unix socket paths on shutdown
by Osier Yang
This patch introduces a internal RPC API "virNetServerClose", which
is standalone with "virNetServerFree". it closes all the socket fds,
and unlinks the unix socket paths, regardless of whether the socket
is still referenced or not.
This is to address regression bug:
https://bugzilla.redhat.com/show_bug.cgi?id=725702
---
daemon/libvirtd.c | 1 +
src/rpc/virnetserver.c | 16 ++++++++++++++++
src/rpc/virnetserver.h | 1 +
src/rpc/virnetserverservice.c | 12 ++++++++++++
src/rpc/virnetserverservice.h | 2 ++
src/rpc/virnetsocket.c | 22 ++++++++++++++++++++++
src/rpc/virnetsocket.h | 1 +
7 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 9e044e2..53f1002 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -1558,6 +1558,7 @@ int main(int argc, char **argv) {
cleanup:
virNetServerProgramFree(remoteProgram);
virNetServerProgramFree(qemuProgram);
+ virNetServerClose(srv);
virNetServerFree(srv);
if (statuswrite != -1) {
if (ret != 0) {
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 5e4826b..1a49dbb 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -798,3 +798,19 @@ void virNetServerFree(virNetServerPtr srv)
virMutexDestroy(&srv->lock);
VIR_FREE(srv);
}
+
+void virNetServerClose(virNetServerPtr srv)
+{
+ int i;
+
+ if (!srv)
+ return;
+
+ virNetServerLock(srv);
+
+ for (i = 0; i < srv->nservices; i++) {
+ virNetServerServiceClose(srv->services[i]);
+ }
+
+ virNetServerUnlock(srv);
+}
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index 810d8a3..324cfb7 100644
--- a/src/rpc/virnetserver.h
+++ b/src/rpc/virnetserver.h
@@ -85,5 +85,6 @@ void virNetServerQuit(virNetServerPtr srv);
void virNetServerFree(virNetServerPtr srv);
+void virNetServerClose(virNetServerPtr srv);
#endif
diff --git a/src/rpc/virnetserverservice.c b/src/rpc/virnetserverservice.c
index d5648dc..8c9ed1e 100644
--- a/src/rpc/virnetserverservice.c
+++ b/src/rpc/virnetserverservice.c
@@ -280,3 +280,15 @@ void virNetServerServiceToggle(virNetServerServicePtr svc,
VIR_EVENT_HANDLE_READABLE :
0);
}
+
+void virNetServerServiceClose(virNetServerServicePtr svc)
+{
+ int i;
+
+ if (!svc)
+ return;
+
+ for (i = 0; i < svc->nsocks; i++) {
+ virNetSocketClose(svc->socks[i]);
+ }
+}
diff --git a/src/rpc/virnetserverservice.h b/src/rpc/virnetserverservice.h
index 9357598..8540bd9 100644
--- a/src/rpc/virnetserverservice.h
+++ b/src/rpc/virnetserverservice.h
@@ -66,4 +66,6 @@ void virNetServerServiceFree(virNetServerServicePtr svc);
void virNetServerServiceToggle(virNetServerServicePtr svc,
bool enabled);
+void virNetServerServiceClose(virNetServerServicePtr svc);
+
#endif
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 41b691a..992e33a 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -1222,3 +1222,25 @@ void virNetSocketRemoveIOCallback(virNetSocketPtr sock)
virMutexUnlock(&sock->lock);
}
+
+void virNetSocketClose(virNetSocketPtr sock)
+{
+ if (!sock)
+ return;
+
+ virMutexLock(&sock->lock);
+
+ VIR_FORCE_CLOSE(sock->fd);
+
+#ifdef HAVE_SYS_UN_H
+ /* If a server socket, then unlink UNIX path */
+ if (!sock->client &&
+ sock->localAddr.data.sa.sa_family == AF_UNIX &&
+ sock->localAddr.data.un.sun_path[0] != '\0') {
+ if (unlink(sock->localAddr.data.un.sun_path) == 0)
+ sock->localAddr.data.un.sun_path[0] = '\0';
+ }
+#endif
+
+ virMutexUnlock(&sock->lock);
+}
diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h
index dfb3c5d..1e1c63c 100644
--- a/src/rpc/virnetsocket.h
+++ b/src/rpc/virnetsocket.h
@@ -118,6 +118,7 @@ void virNetSocketUpdateIOCallback(virNetSocketPtr sock,
void virNetSocketRemoveIOCallback(virNetSocketPtr sock);
+void virNetSocketClose(virNetSocketPtr sock);
#endif /* __VIR_NET_SOCKET_H__ */
--
1.7.6
13 years, 3 months
[libvirt] speeding up qemu core dumps
by Jim Fehlig
Hi All,
I've had user reports of "libvirt limiting KVM core dumps". This isn't
quite true since libvirt just uses the default migration speed defined
in qemu's migration.c
/* Migration speed throttling */
static int64_t max_throttle = (32 << 20);
AFAIK, there's not much interest in changing the qemu default
http://lists.nongnu.org/archive/html/qemu-devel/2011-02/msg01156.html
I thought there were more discussions on the topic but can only find the
above thread ATM.
Do folks here have objections to increasing the migration speed prior to
core dump? If not, any suggestions for a value? I set the migration
speed to 1G in doCoreDump() prior to calling qemuMigrationToFile() with
following improvement dumping a 4G guest
32MiB/s migration speed (qemu default):
# time virsh dump --live test /tmp/dump
Domain test dumped to /tmp/dump
real 0m10.121s
user 0m0.004s
sys 0m0.004s
1GiB/s migration speed:
# time virsh dump --live test /tmp/dump
Domain test dumped to /tmp/dump
real 0m3.745s
user 0m0.004s
sys 0m0.004s
I suppose the same applies for save.
Regards,
Jim
13 years, 3 months