Rebased to version 1.2.13.1
Fix getVersion() after installing qemu (bz #1000116) Fix autosocket setup with qemu:///session (bz #1044561, bz #1105274) Ignore storage volumes with non-ascii in names (bz #1066564) Don't generate invalid system nodedev XML (bz #1184131) Fix crash via race when unrefing rpc identity object (bz #1203030) Fix domcapabilities failure with ppc64le (bz #1209948) Fix regression with 'virsh event ' (bz #1212620) Add {Haswell,Broadwell}-noTSX CPU models (bz #1182650) Don't lose VMs on libvirtd restart if qemu is uninstalled (bz #1099847) Ignore storage volumes that libvirt can't open (bz #1103308)remotes/origin/f22
parent
a99455b301
commit
e18130141c
|
@ -1,46 +0,0 @@
|
||||||
From: Laine Stump <laine@laine.org>
|
|
||||||
Date: Tue, 10 Mar 2015 02:09:24 -0400
|
|
||||||
Subject: [PATCH] qemu: don't fill in nicindexes for session mode libvirtd
|
|
||||||
|
|
||||||
Commit 4bbe1029f fixed a problem in commit f7afeddc by moving the call
|
|
||||||
to virNetDevGetIndex() to a location common to all interface types (so
|
|
||||||
that the nicindex array would be filled in for macvtap as well as tap
|
|
||||||
interfaces), but the location was *too* common, as the original call
|
|
||||||
to virNetDevGetIndex() had been in a section qualified by "if
|
|
||||||
(cfg->privileged)". The result was that the "fixed" libvirtd would try
|
|
||||||
to call virNetDevGetIndex() even for session mode libvirtd, and end up
|
|
||||||
failing with the log message:
|
|
||||||
|
|
||||||
Unable to open control socket: Operation not permitted
|
|
||||||
|
|
||||||
To remedy that, this patch qualifies the call to virNetDevGetIndex()
|
|
||||||
in its new location with cfg->privileged.
|
|
||||||
|
|
||||||
This resolves https://bugzilla.redhat.com/show_bug.cgi?id=1198244
|
|
||||||
|
|
||||||
(cherry picked from commit 705242f8809dc2222c35c64d5408dd6b0cc94cf8)
|
|
||||||
---
|
|
||||||
src/qemu/qemu_command.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|
||||||
index 24b2ad9..6526ba8 100644
|
|
||||||
--- a/src/qemu/qemu_command.c
|
|
||||||
+++ b/src/qemu/qemu_command.c
|
|
||||||
@@ -7766,6 +7766,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
|
|
||||||
char **tapfdName = NULL;
|
|
||||||
char **vhostfdName = NULL;
|
|
||||||
int actualType = virDomainNetGetActualType(net);
|
|
||||||
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
|
||||||
virNetDevBandwidthPtr actualBandwidth;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
@@ -7841,7 +7842,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
|
|
||||||
/* network and bridge use a tap device, and direct uses a
|
|
||||||
* macvtap device
|
|
||||||
*/
|
|
||||||
- if (nicindexes && nnicindexes && net->ifname) {
|
|
||||||
+ if (cfg->privileged && nicindexes && nnicindexes && net->ifname) {
|
|
||||||
if (virNetDevGetIndex(net->ifname, &nicindex) < 0 ||
|
|
||||||
VIR_APPEND_ELEMENT(*nicindexes, *nnicindexes, nicindex) < 0)
|
|
||||||
goto cleanup;
|
|
|
@ -1,35 +0,0 @@
|
||||||
From: Lubomir Rintel <lkundrak@v3.sk>
|
|
||||||
Date: Wed, 8 Apr 2015 19:16:52 +0200
|
|
||||||
Subject: [PATCH] lxc: create the required directories upon driver start
|
|
||||||
|
|
||||||
/var/run may reside on a tmpfs and we fail to create the PID file if
|
|
||||||
/var/run/lxc does not exist.
|
|
||||||
|
|
||||||
Since commit 0a8addc1, the lxc driver's state directory isn't
|
|
||||||
automatically created before starting a domain. Now, the lxc driver
|
|
||||||
makes sure the state directory exists when it initializes.
|
|
||||||
|
|
||||||
Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
|
|
||||||
(cherry picked from commit da33a1ac1f6c0ae2ebe72bc385bbc7c407026956)
|
|
||||||
---
|
|
||||||
src/lxc/lxc_driver.c | 7 +++++++
|
|
||||||
1 file changed, 7 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
|
|
||||||
index 3a28dd5..8a00721 100644
|
|
||||||
--- a/src/lxc/lxc_driver.c
|
|
||||||
+++ b/src/lxc/lxc_driver.c
|
|
||||||
@@ -1650,6 +1650,13 @@ static int lxcStateInitialize(bool privileged,
|
|
||||||
if (!(caps = virLXCDriverGetCapabilities(lxc_driver, false)))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
+ if (virFileMakePath(cfg->stateDir) < 0) {
|
|
||||||
+ virReportSystemError(errno,
|
|
||||||
+ _("Failed to mkdir %s"),
|
|
||||||
+ cfg->stateDir);
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Get all the running persistent or transient configs first */
|
|
||||||
if (virDomainObjListLoadAllConfigs(lxc_driver->domains,
|
|
||||||
cfg->stateDir,
|
|
|
@ -1,62 +0,0 @@
|
||||||
From: Peter Krempa <pkrempa@redhat.com>
|
|
||||||
Date: Wed, 25 Mar 2015 08:56:07 +0100
|
|
||||||
Subject: [PATCH] rpc: Don't unref identity object while callbacks still can be
|
|
||||||
executed
|
|
||||||
|
|
||||||
While this thread is cleaning up the client and connection objects:
|
|
||||||
#2 virFileReadAll (path=0x7f28780012b0 "/proc/1319/stat", maxlen=maxlen@entry=1024, buf=buf@entry=0x7f289c60fc40) at util/virfile.c:1287
|
|
||||||
#3 0x00007f28adbb1539 in virProcessGetStartTime (pid=<optimized out>, timestamp=timestamp@entry=0x7f289c60fc98) at util/virprocess.c:838
|
|
||||||
#4 0x00007f28adb91981 in virIdentityGetSystem () at util/viridentity.c:151
|
|
||||||
#5 0x00007f28ae73f17c in remoteClientFreeFunc (data=<optimized out>) at remote.c:1131
|
|
||||||
#6 0x00007f28adcb7f33 in virNetServerClientDispose (obj=0x7f28aecad180) at rpc/virnetserverclient.c:858
|
|
||||||
#7 0x00007f28adba8eeb in virObjectUnref (anyobj=<optimized out>) at util/virobject.c:265
|
|
||||||
#8 0x00007f28ae74ad05 in virNetServerHandleJob (jobOpaque=<optimized out>, opaque=0x7f28aec93ff0) at rpc/virnetserver.c:205
|
|
||||||
#9 0x00007f28adbbef4e in virThreadPoolWorker (opaque=opaque@entry=0x7f28aec88030) at util/virthreadpool.c:145
|
|
||||||
|
|
||||||
In stack frame #6 the client->identity object got unref'd, but the code
|
|
||||||
that removes the event callbacks in frame #5 did not run yet as we are
|
|
||||||
trying to obtain the system identity (frames #4, #3, #2).
|
|
||||||
|
|
||||||
In other thead:
|
|
||||||
#0 virObjectUnref (anyobj=anyobj@entry=0x7f288c162c60) at util/virobject.c:264
|
|
||||||
klass = 0xdeadbeef
|
|
||||||
obj = 0x7f288c162c60
|
|
||||||
#1 0x00007f28ae71c709 in remoteRelayDomainEventCheckACL (client=<optimized out>, conn=<optimized out>, dom=dom@entry=0x7f28aecaafc0) at remote.c:164
|
|
||||||
#2 0x00007f28ae71fc83 in remoteRelayDomainEventTrayChange (conn=<optimized out>, dom=0x7f28aecaafc0, ... ) at remote.c:717
|
|
||||||
#3 0x00007f28adc04e53 in virDomainEventDispatchDefaultFunc (conn=0x7f287c0009a0, event=0x7f28aecab1a0, ...) at conf/domain_event.c:1455
|
|
||||||
#4 0x00007f28adc03831 in virObjectEventStateDispatchCallbacks (callbacks=<optimized out>, ....) at conf/object_event.c:724
|
|
||||||
#5 virObjectEventStateQueueDispatch (callbacks=0x7f288c083730, queue=0x7fff51f90030, state=0x7f288c18da20) at conf/object_event.c:738
|
|
||||||
#6 virObjectEventStateFlush (state=0x7f288c18da20) at conf/object_event.c:816
|
|
||||||
#7 virObjectEventTimer (timer=<optimized out>, opaque=0x7f288c18da20) at conf/object_event.c:562
|
|
||||||
#8 0x00007f28adb859cd in virEventPollDispatchTimeouts () at util/vireventpoll.c:459
|
|
||||||
|
|
||||||
Frame #0 is unrefing an invalid identity object while frame #2 hints
|
|
||||||
that the client is still dispatching the event.
|
|
||||||
|
|
||||||
For untrimmed backtrace see the bugzilla attachment.
|
|
||||||
|
|
||||||
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1203030
|
|
||||||
(cherry picked from commit a98129c0ee52b6a8fdd39988a6d090057f149ae9)
|
|
||||||
---
|
|
||||||
src/rpc/virnetserverclient.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
|
|
||||||
index b2a4fdf..541055f 100644
|
|
||||||
--- a/src/rpc/virnetserverclient.c
|
|
||||||
+++ b/src/rpc/virnetserverclient.c
|
|
||||||
@@ -850,12 +850,12 @@ void virNetServerClientDispose(void *obj)
|
|
||||||
PROBE(RPC_SERVER_CLIENT_DISPOSE,
|
|
||||||
"client=%p", client);
|
|
||||||
|
|
||||||
- virObjectUnref(client->identity);
|
|
||||||
-
|
|
||||||
if (client->privateData &&
|
|
||||||
client->privateDataFreeFunc)
|
|
||||||
client->privateDataFreeFunc(client->privateData);
|
|
||||||
|
|
||||||
+ virObjectUnref(client->identity);
|
|
||||||
+
|
|
||||||
#if WITH_SASL
|
|
||||||
virObjectUnref(client->sasl);
|
|
||||||
#endif
|
|
|
@ -1,267 +0,0 @@
|
||||||
From: Michal Privoznik <mprivozn@redhat.com>
|
|
||||||
Date: Thu, 2 Apr 2015 14:41:17 +0200
|
|
||||||
Subject: [PATCH] virNetSocketNewConnectUNIX: Use flocks when spawning a daemon
|
|
||||||
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=1200149
|
|
||||||
|
|
||||||
Even though we have a mutex mechanism so that two clients don't spawn
|
|
||||||
two daemons, it's not strong enough. It can happen that while one
|
|
||||||
client is spawning the daemon, the other one fails to connect.
|
|
||||||
Basically two possible errors can happen:
|
|
||||||
|
|
||||||
error: Failed to connect socket to '/home/mprivozn/.cache/libvirt/libvirt-sock': Connection refused
|
|
||||||
|
|
||||||
or:
|
|
||||||
|
|
||||||
error: Failed to connect socket to '/home/mprivozn/.cache/libvirt/libvirt-sock': No such file or directory
|
|
||||||
|
|
||||||
The problem in both cases is, the daemon is only starting up, while we
|
|
||||||
are trying to connect (and fail). We should postpone the connecting
|
|
||||||
phase until the daemon is started (by the other thread that is
|
|
||||||
spawning it). In order to do that, create a file lock 'libvirt-lock'
|
|
||||||
in the directory where session daemon would create its socket. So even
|
|
||||||
when called from multiple processes, spawning a daemon will serialize
|
|
||||||
on the file lock. So only the first to come will spawn the daemon.
|
|
||||||
|
|
||||||
Tested-by: Richard W. M. Jones <rjones@redhat.com>
|
|
||||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
|
||||||
(cherry picked from commit be78814ae07f092d9c4e71fd82dd1947aba2f029)
|
|
||||||
---
|
|
||||||
src/rpc/virnetsocket.c | 164 +++++++++++++++++--------------------------------
|
|
||||||
1 file changed, 55 insertions(+), 109 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
|
|
||||||
index 6b019cc..b824285 100644
|
|
||||||
--- a/src/rpc/virnetsocket.c
|
|
||||||
+++ b/src/rpc/virnetsocket.c
|
|
||||||
@@ -123,7 +123,7 @@ VIR_ONCE_GLOBAL_INIT(virNetSocket)
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
-static int virNetSocketForkDaemon(const char *binary, int passfd)
|
|
||||||
+static int virNetSocketForkDaemon(const char *binary)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
virCommandPtr cmd = virCommandNewArgList(binary,
|
|
||||||
@@ -136,10 +136,6 @@ static int virNetSocketForkDaemon(const char *binary, int passfd)
|
|
||||||
virCommandAddEnvPassBlockSUID(cmd, "XDG_RUNTIME_DIR", NULL);
|
|
||||||
virCommandClearCaps(cmd);
|
|
||||||
virCommandDaemonize(cmd);
|
|
||||||
- if (passfd) {
|
|
||||||
- virCommandPassFD(cmd, passfd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
|
|
||||||
- virCommandPassListenFDs(cmd);
|
|
||||||
- }
|
|
||||||
ret = virCommandRun(cmd, NULL);
|
|
||||||
virCommandFree(cmd);
|
|
||||||
return ret;
|
|
||||||
@@ -543,45 +539,26 @@ int virNetSocketNewConnectUNIX(const char *path,
|
|
||||||
const char *binary,
|
|
||||||
virNetSocketPtr *retsock)
|
|
||||||
{
|
|
||||||
- char *binname = NULL;
|
|
||||||
- char *pidpath = NULL;
|
|
||||||
- int fd, passfd = -1;
|
|
||||||
- int pidfd = -1;
|
|
||||||
+ char *lockpath = NULL;
|
|
||||||
+ int lockfd = -1;
|
|
||||||
+ int fd = -1;
|
|
||||||
+ int retries = 100;
|
|
||||||
virSocketAddr localAddr;
|
|
||||||
virSocketAddr remoteAddr;
|
|
||||||
+ char *rundir = NULL;
|
|
||||||
|
|
||||||
memset(&localAddr, 0, sizeof(localAddr));
|
|
||||||
memset(&remoteAddr, 0, sizeof(remoteAddr));
|
|
||||||
|
|
||||||
remoteAddr.len = sizeof(remoteAddr.data.un);
|
|
||||||
|
|
||||||
- if (spawnDaemon && !binary) {
|
|
||||||
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
- _("Auto-spawn of daemon requested, but no binary specified"));
|
|
||||||
- return -1;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
|
||||||
- virReportSystemError(errno, "%s", _("Failed to create socket"));
|
|
||||||
- goto error;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- remoteAddr.data.un.sun_family = AF_UNIX;
|
|
||||||
- if (virStrcpyStatic(remoteAddr.data.un.sun_path, path) == NULL) {
|
|
||||||
- virReportSystemError(ENOMEM, _("Path %s too long for unix socket"), path);
|
|
||||||
- goto error;
|
|
||||||
- }
|
|
||||||
- if (remoteAddr.data.un.sun_path[0] == '@')
|
|
||||||
- remoteAddr.data.un.sun_path[0] = '\0';
|
|
||||||
-
|
|
||||||
- retry:
|
|
||||||
- if (connect(fd, &remoteAddr.data.sa, remoteAddr.len) < 0) {
|
|
||||||
- int status = 0;
|
|
||||||
- pid_t pid = 0;
|
|
||||||
+ if (spawnDaemon) {
|
|
||||||
+ const char *binname;
|
|
||||||
|
|
||||||
- if (!spawnDaemon) {
|
|
||||||
- virReportSystemError(errno, _("Failed to connect socket to '%s'"),
|
|
||||||
- path);
|
|
||||||
+ if (spawnDaemon && !binary) {
|
|
||||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
+ _("Auto-spawn of daemon requested, "
|
|
||||||
+ "but no binary specified"));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -592,90 +569,63 @@ int virNetSocketNewConnectUNIX(const char *path,
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (virPidFileConstructPath(false, NULL, binname, &pidpath) < 0)
|
|
||||||
+ if (!(rundir = virGetUserRuntimeDirectory()))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
- pidfd = virPidFileAcquirePath(pidpath, false, getpid());
|
|
||||||
- if (pidfd < 0) {
|
|
||||||
- /*
|
|
||||||
- * This can happen in a very rare case of two clients spawning two
|
|
||||||
- * daemons at the same time, and the error in the logs that gets
|
|
||||||
- * reset here can be a clue to some future debugging.
|
|
||||||
- */
|
|
||||||
- virResetLastError();
|
|
||||||
- spawnDaemon = false;
|
|
||||||
- goto retry;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if ((passfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
|
||||||
- virReportSystemError(errno, "%s", _("Failed to create socket"));
|
|
||||||
+ if (virFileMakePathWithMode(rundir, 0700) < 0) {
|
|
||||||
+ virReportSystemError(errno,
|
|
||||||
+ _("Cannot create user runtime directory '%s'"),
|
|
||||||
+ rundir);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * We already even acquired the pidfile, so no one else should be using
|
|
||||||
- * @path right now. So we're OK to unlink it and paying attention to
|
|
||||||
- * the return value makes no real sense here. Only if it's not an
|
|
||||||
- * abstract socket, of course.
|
|
||||||
- */
|
|
||||||
- if (path[0] != '@')
|
|
||||||
- unlink(path);
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * We have to fork() here, because umask() is set per-process, chmod()
|
|
||||||
- * is racy and fchmod() has undefined behaviour on sockets according to
|
|
||||||
- * POSIX, so it doesn't work outside Linux.
|
|
||||||
- */
|
|
||||||
- if ((pid = virFork()) < 0)
|
|
||||||
+ if (virAsprintf(&lockpath, "%s/%s.lock", rundir, binname) < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
- if (pid == 0) {
|
|
||||||
- umask(0077);
|
|
||||||
- if (bind(passfd, &remoteAddr.data.sa, remoteAddr.len) < 0)
|
|
||||||
- _exit(EXIT_FAILURE);
|
|
||||||
-
|
|
||||||
- _exit(EXIT_SUCCESS);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (virProcessWait(pid, &status, false) < 0)
|
|
||||||
+ if ((lockfd = open(lockpath, O_RDWR | O_CREAT, 0600)) < 0 ||
|
|
||||||
+ virSetCloseExec(lockfd) < 0) {
|
|
||||||
+ virReportSystemError(errno, _("Unable to create lock '%s'"), lockpath);
|
|
||||||
goto error;
|
|
||||||
-
|
|
||||||
- if (status != EXIT_SUCCESS) {
|
|
||||||
- /*
|
|
||||||
- * OK, so the child failed to bind() the socket. This may mean that
|
|
||||||
- * another daemon was starting at the same time and succeeded with
|
|
||||||
- * its bind() (even though it should not happen because we using a
|
|
||||||
- * pidfile for the race). So we'll try connecting again, but this
|
|
||||||
- * time without spawning the daemon.
|
|
||||||
- */
|
|
||||||
- spawnDaemon = false;
|
|
||||||
- virPidFileDeletePath(pidpath);
|
|
||||||
- VIR_FORCE_CLOSE(pidfd);
|
|
||||||
- VIR_FORCE_CLOSE(passfd);
|
|
||||||
- goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (listen(passfd, 0) < 0) {
|
|
||||||
- virReportSystemError(errno, "%s",
|
|
||||||
- _("Failed to listen on socket that's about "
|
|
||||||
- "to be passed to the daemon"));
|
|
||||||
+ if (virFileLock(lockfd, false, 0, 1, true) < 0) {
|
|
||||||
+ virReportSystemError(errno, _("Unable to lock '%s'"), lockpath);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
|
||||||
+ virReportSystemError(errno, "%s", _("Failed to create socket"));
|
|
||||||
+ goto error;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- if (connect(fd, &remoteAddr.data.sa, remoteAddr.len) < 0) {
|
|
||||||
+ remoteAddr.data.un.sun_family = AF_UNIX;
|
|
||||||
+ if (virStrcpyStatic(remoteAddr.data.un.sun_path, path) == NULL) {
|
|
||||||
+ virReportSystemError(ENOMEM, _("Path %s too long for unix socket"), path);
|
|
||||||
+ goto error;
|
|
||||||
+ }
|
|
||||||
+ if (remoteAddr.data.un.sun_path[0] == '@')
|
|
||||||
+ remoteAddr.data.un.sun_path[0] = '\0';
|
|
||||||
+
|
|
||||||
+ while (retries &&
|
|
||||||
+ connect(fd, &remoteAddr.data.sa, remoteAddr.len) < 0) {
|
|
||||||
+ if (!(spawnDaemon && errno == ENOENT)) {
|
|
||||||
virReportSystemError(errno, _("Failed to connect socket to '%s'"),
|
|
||||||
path);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Do we need to eliminate the super-rare race here any more? It would
|
|
||||||
- * need incorporating the following VIR_FORCE_CLOSE() into a
|
|
||||||
- * virCommandHook inside a virNetSocketForkDaemon().
|
|
||||||
- */
|
|
||||||
- VIR_FORCE_CLOSE(pidfd);
|
|
||||||
- if (virNetSocketForkDaemon(binary, passfd) < 0)
|
|
||||||
+ if (virNetSocketForkDaemon(binary) < 0)
|
|
||||||
goto error;
|
|
||||||
+
|
|
||||||
+ retries--;
|
|
||||||
+ usleep(5000);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (lockfd) {
|
|
||||||
+ unlink(lockpath);
|
|
||||||
+ VIR_FORCE_CLOSE(lockfd);
|
|
||||||
+ VIR_FREE(lockpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
localAddr.len = sizeof(localAddr.data);
|
|
||||||
@@ -687,19 +637,15 @@ int virNetSocketNewConnectUNIX(const char *path,
|
|
||||||
if (!(*retsock = virNetSocketNew(&localAddr, &remoteAddr, true, fd, -1, 0)))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
- VIR_FREE(pidpath);
|
|
||||||
-
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
- if (pidfd >= 0)
|
|
||||||
- virPidFileDeletePath(pidpath);
|
|
||||||
- VIR_FREE(pidpath);
|
|
||||||
+ if (lockfd)
|
|
||||||
+ unlink(lockpath);
|
|
||||||
+ VIR_FREE(lockpath);
|
|
||||||
+ VIR_FREE(rundir);
|
|
||||||
VIR_FORCE_CLOSE(fd);
|
|
||||||
- VIR_FORCE_CLOSE(passfd);
|
|
||||||
- VIR_FORCE_CLOSE(pidfd);
|
|
||||||
- if (spawnDaemon)
|
|
||||||
- unlink(path);
|
|
||||||
+ VIR_FORCE_CLOSE(lockfd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#else
|
|
|
@ -1,58 +0,0 @@
|
||||||
From: Cole Robinson <crobinso@redhat.com>
|
|
||||||
Date: Mon, 6 Apr 2015 13:59:46 -0400
|
|
||||||
Subject: [PATCH] virsh: Improve change-media success message
|
|
||||||
|
|
||||||
$ sudo virsh change-media f19 hdc /mnt/data/devel/media/Fedora-16-x86_64-Live-KDE.iso
|
|
||||||
succeeded to complete action update on media
|
|
||||||
|
|
||||||
Change the message to:
|
|
||||||
|
|
||||||
Successfully {inserted,ejected,changed} media.
|
|
||||||
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=967946
|
|
||||||
(cherry picked from commit e3aa4c91c8b54cdfb1c312a142fd9fb79daec65a)
|
|
||||||
---
|
|
||||||
tools/virsh-domain.c | 6 +++++-
|
|
||||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
|
|
||||||
index 80a96b2..c737ad4 100644
|
|
||||||
--- a/tools/virsh-domain.c
|
|
||||||
+++ b/tools/virsh-domain.c
|
|
||||||
@@ -12104,6 +12104,7 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd)
|
|
||||||
bool ret = false;
|
|
||||||
int prepare_type = 0;
|
|
||||||
const char *action = NULL;
|
|
||||||
+ const char *success_msg = NULL;
|
|
||||||
bool config = vshCommandOptBool(cmd, "config");
|
|
||||||
bool live = vshCommandOptBool(cmd, "live");
|
|
||||||
bool current = vshCommandOptBool(cmd, "current");
|
|
||||||
@@ -12120,16 +12121,19 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd)
|
|
||||||
if (eject) {
|
|
||||||
prepare_type = VSH_PREPARE_DISK_XML_EJECT;
|
|
||||||
action = "eject";
|
|
||||||
+ success_msg = _("Successfully ejected media.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insert) {
|
|
||||||
prepare_type = VSH_PREPARE_DISK_XML_INSERT;
|
|
||||||
action = "insert";
|
|
||||||
+ success_msg = _("Successfully inserted media.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update || (!eject && !insert)) {
|
|
||||||
prepare_type = VSH_PREPARE_DISK_XML_UPDATE;
|
|
||||||
action = "update";
|
|
||||||
+ success_msg = _("Successfully updated media.");
|
|
||||||
}
|
|
||||||
|
|
||||||
VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
|
|
||||||
@@ -12174,7 +12178,7 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd)
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
- vshPrint(ctl, _("succeeded to complete action %s on media\n"), action);
|
|
||||||
+ vshPrint(ctl, "%s", success_msg);
|
|
||||||
ret = true;
|
|
||||||
|
|
||||||
cleanup:
|
|
|
@ -1,41 +0,0 @@
|
||||||
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
|
|
||||||
Date: Tue, 14 Apr 2015 12:06:44 +0200
|
|
||||||
Subject: [PATCH] tests: rename testStripIPv6BracketsData to testStripData
|
|
||||||
|
|
||||||
For reuse with other Strip* functions.
|
|
||||||
|
|
||||||
(cherry picked from commit e892842dfd3c7bad8fbfbfcf0501d01804e9e7c3)
|
|
||||||
---
|
|
||||||
tests/virstringtest.c | 6 +++---
|
|
||||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/virstringtest.c b/tests/virstringtest.c
|
|
||||||
index a0bfd61..9d0b438 100644
|
|
||||||
--- a/tests/virstringtest.c
|
|
||||||
+++ b/tests/virstringtest.c
|
|
||||||
@@ -522,14 +522,14 @@ testVirStringFreeListCount(const void *opaque ATTRIBUTE_UNUSED)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-struct testStripIPv6BracketsData {
|
|
||||||
+struct testStripData {
|
|
||||||
const char *string;
|
|
||||||
const char *result;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int testStripIPv6Brackets(const void *args)
|
|
||||||
{
|
|
||||||
- const struct testStripIPv6BracketsData *data = args;
|
|
||||||
+ const struct testStripData *data = args;
|
|
||||||
int ret = -1;
|
|
||||||
char *res = NULL;
|
|
||||||
|
|
||||||
@@ -766,7 +766,7 @@ mymain(void)
|
|
||||||
|
|
||||||
#define TEST_STRIP_IPV6_BRACKETS(str, res) \
|
|
||||||
do { \
|
|
||||||
- struct testStripIPv6BracketsData stripData = { \
|
|
||||||
+ struct testStripData stripData = { \
|
|
||||||
.string = str, \
|
|
||||||
.result = res, \
|
|
||||||
}; \
|
|
|
@ -1,155 +0,0 @@
|
||||||
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
|
|
||||||
Date: Tue, 14 Apr 2015 12:30:16 +0200
|
|
||||||
Subject: [PATCH] Add functions dealing with control characters in strings
|
|
||||||
|
|
||||||
Add virStringHasControlChars that checks if the string has
|
|
||||||
any control characters other than \t\r\n,
|
|
||||||
and virStringStripControlChars that removes them in-place.
|
|
||||||
|
|
||||||
(cherry picked from commit 2a530a3e50d9314950cff0a5790c81910b0750a9)
|
|
||||||
---
|
|
||||||
src/libvirt_private.syms | 2 ++
|
|
||||||
src/util/virstring.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
src/util/virstring.h | 2 ++
|
|
||||||
tests/virstringtest.c | 39 +++++++++++++++++++++++++++++++++++++++
|
|
||||||
4 files changed, 85 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
||||||
index ba05cc6..5d54861 100644
|
|
||||||
--- a/src/libvirt_private.syms
|
|
||||||
+++ b/src/libvirt_private.syms
|
|
||||||
@@ -2091,6 +2091,7 @@ virStrdup;
|
|
||||||
virStringArrayHasString;
|
|
||||||
virStringFreeList;
|
|
||||||
virStringFreeListCount;
|
|
||||||
+virStringHasControlChars;
|
|
||||||
virStringIsEmpty;
|
|
||||||
virStringJoin;
|
|
||||||
virStringListLength;
|
|
||||||
@@ -2100,6 +2101,7 @@ virStringSortCompare;
|
|
||||||
virStringSortRevCompare;
|
|
||||||
virStringSplit;
|
|
||||||
virStringSplitCount;
|
|
||||||
+virStringStripControlChars;
|
|
||||||
virStringStripIPv6Brackets;
|
|
||||||
virStrncpy;
|
|
||||||
virStrndup;
|
|
||||||
diff --git a/src/util/virstring.c b/src/util/virstring.c
|
|
||||||
index 3dad9dd..1cd4987 100644
|
|
||||||
--- a/src/util/virstring.c
|
|
||||||
+++ b/src/util/virstring.c
|
|
||||||
@@ -968,3 +968,45 @@ virStringStripIPv6Brackets(char *str)
|
|
||||||
str[len - 2] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static const char control_chars[] =
|
|
||||||
+ "\x01\x02\x03\x04\x05\x06\x07"
|
|
||||||
+ "\x08" /* \t \n */ "\x0B\x0C" /* \r */ "\x0E\x0F"
|
|
||||||
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
|
|
||||||
+ "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
|
|
||||||
+
|
|
||||||
+bool
|
|
||||||
+virStringHasControlChars(const char *str)
|
|
||||||
+{
|
|
||||||
+ if (!str)
|
|
||||||
+ return false;
|
|
||||||
+
|
|
||||||
+ return str[strcspn(str, control_chars)] != '\0';
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * virStringStripControlChars:
|
|
||||||
+ * @str: the string to strip
|
|
||||||
+ *
|
|
||||||
+ * Modify the string in-place to remove the control characters
|
|
||||||
+ * in the interval: [0x01, 0x20)
|
|
||||||
+ */
|
|
||||||
+void
|
|
||||||
+virStringStripControlChars(char *str)
|
|
||||||
+{
|
|
||||||
+ size_t len, i, j;
|
|
||||||
+
|
|
||||||
+ if (!str)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ len = strlen(str);
|
|
||||||
+ for (i = 0, j = 0; i < len; i++) {
|
|
||||||
+ if (index(control_chars, str[i]))
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ str[j++] = str[i];
|
|
||||||
+ }
|
|
||||||
+ str[j] = '\0';
|
|
||||||
+}
|
|
||||||
diff --git a/src/util/virstring.h b/src/util/virstring.h
|
|
||||||
index 2ec60fa..e6dcb32 100644
|
|
||||||
--- a/src/util/virstring.h
|
|
||||||
+++ b/src/util/virstring.h
|
|
||||||
@@ -271,5 +271,7 @@ char *virStringReplace(const char *haystack,
|
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
|
|
||||||
|
|
||||||
void virStringStripIPv6Brackets(char *str);
|
|
||||||
+bool virStringHasControlChars(const char *str);
|
|
||||||
+void virStringStripControlChars(char *str);
|
|
||||||
|
|
||||||
#endif /* __VIR_STRING_H__ */
|
|
||||||
diff --git a/tests/virstringtest.c b/tests/virstringtest.c
|
|
||||||
index 9d0b438..38d0126 100644
|
|
||||||
--- a/tests/virstringtest.c
|
|
||||||
+++ b/tests/virstringtest.c
|
|
||||||
@@ -551,6 +551,29 @@ static int testStripIPv6Brackets(const void *args)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int testStripControlChars(const void *args)
|
|
||||||
+{
|
|
||||||
+ const struct testStripData *data = args;
|
|
||||||
+ int ret = -1;
|
|
||||||
+ char *res = NULL;
|
|
||||||
+
|
|
||||||
+ if (VIR_STRDUP(res, data->string) < 0)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+ virStringStripControlChars(res);
|
|
||||||
+
|
|
||||||
+ if (STRNEQ_NULLABLE(res, data->result)) {
|
|
||||||
+ fprintf(stderr, "Returned '%s', expected '%s'\n",
|
|
||||||
+ NULLSTR(res), NULLSTR(data->result));
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = 0;
|
|
||||||
+
|
|
||||||
+ cleanup:
|
|
||||||
+ VIR_FREE(res);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
|
|
||||||
static int
|
|
||||||
mymain(void)
|
|
||||||
@@ -783,6 +806,22 @@ mymain(void)
|
|
||||||
TEST_STRIP_IPV6_BRACKETS(":hello]", ":hello]");
|
|
||||||
TEST_STRIP_IPV6_BRACKETS(":[]:", ":[]:");
|
|
||||||
|
|
||||||
+#define TEST_STRIP_CONTROL_CHARS(str, res) \
|
|
||||||
+ do { \
|
|
||||||
+ struct testStripData stripData = { \
|
|
||||||
+ .string = str, \
|
|
||||||
+ .result = res, \
|
|
||||||
+ }; \
|
|
||||||
+ if (virtTestRun("Strip control chars from " #str, \
|
|
||||||
+ testStripControlChars, &stripData) < 0) \
|
|
||||||
+ ret = -1; \
|
|
||||||
+ } while (0)
|
|
||||||
+
|
|
||||||
+ TEST_STRIP_CONTROL_CHARS(NULL, NULL);
|
|
||||||
+ TEST_STRIP_CONTROL_CHARS("\nhello \r hello\t", "\nhello \r hello\t");
|
|
||||||
+ TEST_STRIP_CONTROL_CHARS("\x01H\x02" "E\x03L\x04L\x05O", "HELLO");
|
|
||||||
+ TEST_STRIP_CONTROL_CHARS("\x01\x02\x03\x04HELL\x05O", "HELLO");
|
|
||||||
+ TEST_STRIP_CONTROL_CHARS("\nhello \x01\x07hello\t", "\nhello hello\t");
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
|
|
||||||
Date: Tue, 14 Apr 2015 12:30:34 +0200
|
|
||||||
Subject: [PATCH] Strip control characters from sysfs attributes
|
|
||||||
|
|
||||||
Including them in the XML makes them unparsable.
|
|
||||||
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=1184131
|
|
||||||
(cherry picked from commit 557107500b22d4a5ba7d1b09f5f516512dfca67b)
|
|
||||||
---
|
|
||||||
src/node_device/node_device_udev.c | 6 +++++-
|
|
||||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
|
|
||||||
index 03c7a0b..eb6209b 100644
|
|
||||||
--- a/src/node_device/node_device_udev.c
|
|
||||||
+++ b/src/node_device/node_device_udev.c
|
|
||||||
@@ -194,7 +194,9 @@ static int udevGetUintProperty(struct udev_device *udev_device,
|
|
||||||
|
|
||||||
|
|
||||||
/* This function allocates memory from the heap for the property
|
|
||||||
- * value. That memory must be later freed by some other code. */
|
|
||||||
+ * value. That memory must be later freed by some other code.
|
|
||||||
+ * Any control characters that cannot be printed in the XML are stripped
|
|
||||||
+ * from the string */
|
|
||||||
static int udevGetDeviceSysfsAttr(struct udev_device *udev_device,
|
|
||||||
const char *attr_name,
|
|
||||||
char **attr_value)
|
|
||||||
@@ -239,6 +241,8 @@ static int udevGetStringSysfsAttr(struct udev_device *udev_device,
|
|
||||||
|
|
||||||
ret = udevGetDeviceSysfsAttr(udev_device, attr_name, &tmp);
|
|
||||||
|
|
||||||
+ virStringStripControlChars(tmp);
|
|
||||||
+
|
|
||||||
if (tmp != NULL && (STREQ(tmp, ""))) {
|
|
||||||
VIR_FREE(tmp);
|
|
||||||
tmp = NULL;
|
|
|
@ -1,29 +0,0 @@
|
||||||
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
|
|
||||||
Date: Tue, 14 Apr 2015 12:30:55 +0200
|
|
||||||
Subject: [PATCH] Ignore storage volumes with control codes in their names
|
|
||||||
|
|
||||||
To prevent generating invalid XML.
|
|
||||||
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=1066564
|
|
||||||
(cherry picked from commit 60db2bc80fb5048b227c77c5138fe0e2c97e9c14)
|
|
||||||
---
|
|
||||||
src/storage/storage_backend_fs.c | 6 ++++++
|
|
||||||
1 file changed, 6 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
|
|
||||||
index 2af5dd7..861d4f6 100644
|
|
||||||
--- a/src/storage/storage_backend_fs.c
|
|
||||||
+++ b/src/storage/storage_backend_fs.c
|
|
||||||
@@ -861,6 +861,12 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
||||||
while ((direrr = virDirRead(dir, &ent, pool->def->target.path)) > 0) {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
+ if (virStringHasControlChars(ent->d_name)) {
|
|
||||||
+ VIR_WARN("Ignoring file with control characters under '%s'",
|
|
||||||
+ pool->def->target.path);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (VIR_ALLOC(vol) < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
|
@ -1,144 +0,0 @@
|
||||||
From: Peter Krempa <pkrempa@redhat.com>
|
|
||||||
Date: Tue, 24 Mar 2015 10:53:29 +0100
|
|
||||||
Subject: [PATCH] util: buffer: Add support for adding text blocks with
|
|
||||||
indentation
|
|
||||||
|
|
||||||
The current auto-indentation buffer code applies indentation only on
|
|
||||||
complete strings. To allow adding a string containing newlines and
|
|
||||||
having it properly indented this patch adds virBufferAddStr.
|
|
||||||
|
|
||||||
(cherry picked from commit 6ff59cbc8367856f12f4eef5755eeccade36d8cf)
|
|
||||||
---
|
|
||||||
src/libvirt_private.syms | 1 +
|
|
||||||
src/util/virbuffer.c | 29 ++++++++++++++++++++++++++++
|
|
||||||
src/util/virbuffer.h | 1 +
|
|
||||||
tests/virbuftest.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
4 files changed, 80 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
||||||
index 5d54861..6674c67 100644
|
|
||||||
--- a/src/libvirt_private.syms
|
|
||||||
+++ b/src/libvirt_private.syms
|
|
||||||
@@ -1083,6 +1083,7 @@ virBitmapToData;
|
|
||||||
virBufferAdd;
|
|
||||||
virBufferAddBuffer;
|
|
||||||
virBufferAddChar;
|
|
||||||
+virBufferAddStr;
|
|
||||||
virBufferAdjustIndent;
|
|
||||||
virBufferAsprintf;
|
|
||||||
virBufferCheckErrorInternal;
|
|
||||||
diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
|
|
||||||
index 96a0f16..b5639a8 100644
|
|
||||||
--- a/src/util/virbuffer.c
|
|
||||||
+++ b/src/util/virbuffer.c
|
|
||||||
@@ -752,3 +752,32 @@ virBufferTrim(virBufferPtr buf, const char *str, int len)
|
|
||||||
buf->use -= len < 0 ? len2 : len;
|
|
||||||
buf->content[buf->use] = '\0';
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * virBufferAddStr:
|
|
||||||
+ * @buf: the buffer to append to
|
|
||||||
+ * @str: string to append
|
|
||||||
+ *
|
|
||||||
+ * Appends @str to @buffer. Applies autoindentation on the separate lines of
|
|
||||||
+ * @str.
|
|
||||||
+ */
|
|
||||||
+void
|
|
||||||
+virBufferAddStr(virBufferPtr buf,
|
|
||||||
+ const char *str)
|
|
||||||
+{
|
|
||||||
+ const char *end;
|
|
||||||
+
|
|
||||||
+ if (!buf || !str || buf->error)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ while (*str) {
|
|
||||||
+ if ((end = strchr(str, '\n'))) {
|
|
||||||
+ virBufferAdd(buf, str, (end - str) + 1);
|
|
||||||
+ str = end + 1;
|
|
||||||
+ } else {
|
|
||||||
+ virBufferAdd(buf, str, -1);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h
|
|
||||||
index 24e81c7..144a1ba 100644
|
|
||||||
--- a/src/util/virbuffer.h
|
|
||||||
+++ b/src/util/virbuffer.h
|
|
||||||
@@ -96,5 +96,6 @@ void virBufferAdjustIndent(virBufferPtr buf, int indent);
|
|
||||||
int virBufferGetIndent(const virBuffer *buf, bool dynamic);
|
|
||||||
|
|
||||||
void virBufferTrim(virBufferPtr buf, const char *trim, int len);
|
|
||||||
+void virBufferAddStr(virBufferPtr buf, const char *str);
|
|
||||||
|
|
||||||
#endif /* __VIR_BUFFER_H__ */
|
|
||||||
diff --git a/tests/virbuftest.c b/tests/virbuftest.c
|
|
||||||
index f964feb..21cb18b 100644
|
|
||||||
--- a/tests/virbuftest.c
|
|
||||||
+++ b/tests/virbuftest.c
|
|
||||||
@@ -310,6 +310,43 @@ static int testBufAddBuffer(const void *data ATTRIBUTE_UNUSED)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+struct testBufAddStrData {
|
|
||||||
+ const char *data;
|
|
||||||
+ const char *expect;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int
|
|
||||||
+testBufAddStr(const void *opaque ATTRIBUTE_UNUSED)
|
|
||||||
+{
|
|
||||||
+ const struct testBufAddStrData *data = opaque;
|
|
||||||
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
||||||
+ char *actual;
|
|
||||||
+ int ret = -1;
|
|
||||||
+
|
|
||||||
+ virBufferAddLit(&buf, "<c>\n");
|
|
||||||
+ virBufferAdjustIndent(&buf, 2);
|
|
||||||
+ virBufferAddStr(&buf, data->data);
|
|
||||||
+ virBufferAdjustIndent(&buf, -2);
|
|
||||||
+ virBufferAddLit(&buf, "</c>");
|
|
||||||
+
|
|
||||||
+ if (!(actual = virBufferContentAndReset(&buf))) {
|
|
||||||
+ TEST_ERROR("buf is empty");
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (STRNEQ_NULLABLE(actual, data->expect)) {
|
|
||||||
+ TEST_ERROR("testBufAddStr(): Strings don't match:\n");
|
|
||||||
+ virtTestDifference(stderr, data->expect, actual);
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = 0;
|
|
||||||
+
|
|
||||||
+ cleanup:
|
|
||||||
+ VIR_FREE(actual);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
|
|
||||||
static int
|
|
||||||
mymain(void)
|
|
||||||
@@ -330,6 +367,18 @@ mymain(void)
|
|
||||||
DO_TEST("Trim", testBufTrim, 0);
|
|
||||||
DO_TEST("AddBuffer", testBufAddBuffer, 0);
|
|
||||||
|
|
||||||
+#define DO_TEST_ADD_STR(DATA, EXPECT) \
|
|
||||||
+ do { \
|
|
||||||
+ struct testBufAddStrData info = { DATA, EXPECT }; \
|
|
||||||
+ if (virtTestRun("Buf: AddStr", testBufAddStr, &info) < 0) \
|
|
||||||
+ ret = -1; \
|
|
||||||
+ } while (0)
|
|
||||||
+
|
|
||||||
+ DO_TEST_ADD_STR("", "<c>\n</c>");
|
|
||||||
+ DO_TEST_ADD_STR("<a/>", "<c>\n <a/></c>");
|
|
||||||
+ DO_TEST_ADD_STR("<a/>\n", "<c>\n <a/>\n</c>");
|
|
||||||
+ DO_TEST_ADD_STR("<b>\n <a/>\n</b>\n", "<c>\n <b>\n <a/>\n </b>\n</c>");
|
|
||||||
+
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
|
|
||||||
Date: Mon, 30 Mar 2015 12:41:40 +0200
|
|
||||||
Subject: [PATCH] Strip control codes in virBufferEscapeString
|
|
||||||
|
|
||||||
These cannot be represented in XML.
|
|
||||||
|
|
||||||
We have been stripping them, but only if the string had
|
|
||||||
characters that needed escaping: <>"'&
|
|
||||||
|
|
||||||
Extend the strcspn check to include control codes, and strip
|
|
||||||
them even if we don't do any escaping.
|
|
||||||
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=1184131
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=1066564
|
|
||||||
(cherry picked from commit aeb5262e4397528d582682471cb8075141189465)
|
|
||||||
---
|
|
||||||
src/util/virbuffer.c | 14 +++++++++++---
|
|
||||||
tests/virbuftest.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 60 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
|
|
||||||
index b5639a8..431fd9f 100644
|
|
||||||
--- a/src/util/virbuffer.c
|
|
||||||
+++ b/src/util/virbuffer.c
|
|
||||||
@@ -434,6 +434,13 @@ virBufferEscapeString(virBufferPtr buf, const char *format, const char *str)
|
|
||||||
int len;
|
|
||||||
char *escaped, *out;
|
|
||||||
const char *cur;
|
|
||||||
+ const char forbidden_characters[] = {
|
|
||||||
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
|
||||||
+ /*\t*/ /*\n*/ 0x0B, 0x0C, /*\r*/ 0x0E, 0x0F, 0x10,
|
|
||||||
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
|
||||||
+ 0x19, '"', '&', '\'', '<', '>',
|
|
||||||
+ '\0'
|
|
||||||
+ };
|
|
||||||
|
|
||||||
if ((format == NULL) || (buf == NULL) || (str == NULL))
|
|
||||||
return;
|
|
||||||
@@ -442,7 +449,7 @@ virBufferEscapeString(virBufferPtr buf, const char *format, const char *str)
|
|
||||||
return;
|
|
||||||
|
|
||||||
len = strlen(str);
|
|
||||||
- if (strcspn(str, "<>&'\"") == len) {
|
|
||||||
+ if (strcspn(str, forbidden_characters) == len) {
|
|
||||||
virBufferAsprintf(buf, format, str);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
@@ -486,8 +493,7 @@ virBufferEscapeString(virBufferPtr buf, const char *format, const char *str)
|
|
||||||
*out++ = 'o';
|
|
||||||
*out++ = 's';
|
|
||||||
*out++ = ';';
|
|
||||||
- } else if (((unsigned char)*cur >= 0x20) || (*cur == '\n') || (*cur == '\t') ||
|
|
||||||
- (*cur == '\r')) {
|
|
||||||
+ } else if (!strchr(forbidden_characters, *cur)) {
|
|
||||||
/*
|
|
||||||
* default case, just copy !
|
|
||||||
* Note that character over 0x80 are likely to give problem
|
|
||||||
@@ -495,6 +501,8 @@ virBufferEscapeString(virBufferPtr buf, const char *format, const char *str)
|
|
||||||
* it's hard to handle properly we have to assume it's UTF-8 too
|
|
||||||
*/
|
|
||||||
*out++ = *cur;
|
|
||||||
+ } else {
|
|
||||||
+ /* silently ignore control characters */
|
|
||||||
}
|
|
||||||
cur++;
|
|
||||||
}
|
|
||||||
diff --git a/tests/virbuftest.c b/tests/virbuftest.c
|
|
||||||
index 21cb18b..10398d5 100644
|
|
||||||
--- a/tests/virbuftest.c
|
|
||||||
+++ b/tests/virbuftest.c
|
|
||||||
@@ -349,6 +349,39 @@ testBufAddStr(const void *opaque ATTRIBUTE_UNUSED)
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
+testBufEscapeStr(const void *opaque ATTRIBUTE_UNUSED)
|
|
||||||
+{
|
|
||||||
+ const struct testBufAddStrData *data = opaque;
|
|
||||||
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
||||||
+ char *actual;
|
|
||||||
+ int ret = -1;
|
|
||||||
+
|
|
||||||
+ virBufferAddLit(&buf, "<c>\n");
|
|
||||||
+ virBufferAdjustIndent(&buf, 2);
|
|
||||||
+ virBufferEscapeString(&buf, "<el>%s</el>\n", data->data);
|
|
||||||
+ virBufferAdjustIndent(&buf, -2);
|
|
||||||
+ virBufferAddLit(&buf, "</c>");
|
|
||||||
+
|
|
||||||
+ if (!(actual = virBufferContentAndReset(&buf))) {
|
|
||||||
+ TEST_ERROR("buf is empty");
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (STRNEQ_NULLABLE(actual, data->expect)) {
|
|
||||||
+ TEST_ERROR("testBufEscapeStr(): Strings don't match:\n");
|
|
||||||
+ virtTestDifference(stderr, data->expect, actual);
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = 0;
|
|
||||||
+
|
|
||||||
+ cleanup:
|
|
||||||
+ VIR_FREE(actual);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static int
|
|
||||||
mymain(void)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
@@ -379,6 +412,22 @@ mymain(void)
|
|
||||||
DO_TEST_ADD_STR("<a/>\n", "<c>\n <a/>\n</c>");
|
|
||||||
DO_TEST_ADD_STR("<b>\n <a/>\n</b>\n", "<c>\n <b>\n <a/>\n </b>\n</c>");
|
|
||||||
|
|
||||||
+#define DO_TEST_ESCAPE(data, expect) \
|
|
||||||
+ do { \
|
|
||||||
+ struct testBufAddStrData info = { data, expect }; \
|
|
||||||
+ if (virtTestRun("Buf: EscapeStr", testBufEscapeStr, &info) < 0) \
|
|
||||||
+ ret = -1; \
|
|
||||||
+ } while (0)
|
|
||||||
+
|
|
||||||
+ DO_TEST_ESCAPE("<td></td><td></td>",
|
|
||||||
+ "<c>\n <el><td></td><td></td></el>\n</c>");
|
|
||||||
+ DO_TEST_ESCAPE("\007\"&&\"\x15",
|
|
||||||
+ "<c>\n <el>"&&"</el>\n</c>");
|
|
||||||
+ DO_TEST_ESCAPE(",,'..',,",
|
|
||||||
+ "<c>\n <el>,,'..',,</el>\n</c>");
|
|
||||||
+ DO_TEST_ESCAPE("\x01\x01\x02\x03\x05\x08",
|
|
||||||
+ "<c>\n <el></el>\n</c>");
|
|
||||||
+
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
48
libvirt.spec
48
libvirt.spec
|
@ -337,6 +337,12 @@
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
|
||||||
|
# Advertise OVMF and AAVMF from nightly firmware repo
|
||||||
|
%if 0%{?fedora}
|
||||||
|
%define with_loader_nvram --with-loader-nvram="/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd:/usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd:/usr/share/edk2.git/aarch64/QEMU_EFI-pflash.raw:/usr/share/edk2.git/aarch64/vars-template-pflash.raw"
|
||||||
|
%endif
|
||||||
|
|
||||||
|
|
||||||
# The RHEL-5 Xen package has some feature backports. This
|
# The RHEL-5 Xen package has some feature backports. This
|
||||||
# flag is set to enable use of those special bits on RHEL-5
|
# flag is set to enable use of those special bits on RHEL-5
|
||||||
%if 0%{?rhel} == 5
|
%if 0%{?rhel} == 5
|
||||||
|
@ -364,8 +370,8 @@
|
||||||
|
|
||||||
Summary: Library providing a simple virtualization API
|
Summary: Library providing a simple virtualization API
|
||||||
Name: libvirt
|
Name: libvirt
|
||||||
Version: 1.2.13
|
Version: 1.2.13.1
|
||||||
Release: 3%{?dist}%{?extra_release}
|
Release: 1%{?dist}%{?extra_release}
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
Group: Development/Libraries
|
Group: Development/Libraries
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||||
|
@ -376,24 +382,6 @@ URL: http://libvirt.org/
|
||||||
%endif
|
%endif
|
||||||
Source: http://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.gz
|
Source: http://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.gz
|
||||||
|
|
||||||
# Fix connecting to qemu:///session (bz #1198244)
|
|
||||||
Patch0001: 0001-qemu-don-t-fill-in-nicindexes-for-session-mode-libvi.patch
|
|
||||||
# Fix LXC domain startup (bz #1210397)
|
|
||||||
Patch0002: 0002-lxc-create-the-required-directories-upon-driver-star.patch
|
|
||||||
# Fix crash via identify object cleanup race (bz #1203030)
|
|
||||||
Patch0003: 0003-rpc-Don-t-unref-identity-object-while-callbacks-stil.patch
|
|
||||||
# Fix race starting multiple session daemons (bz #1200149)
|
|
||||||
Patch0004: 0004-virNetSocketNewConnectUNIX-Use-flocks-when-spawning-.patch
|
|
||||||
# Fix change-media success messages
|
|
||||||
Patch0005: 0005-virsh-Improve-change-media-success-message.patch
|
|
||||||
# Strip invalid control codes from XML (bz #1066564, bz #1184131)
|
|
||||||
Patch0006: 0006-tests-rename-testStripIPv6BracketsData-to-testStripD.patch
|
|
||||||
Patch0007: 0007-Add-functions-dealing-with-control-characters-in-str.patch
|
|
||||||
Patch0008: 0008-Strip-control-characters-from-sysfs-attributes.patch
|
|
||||||
Patch0009: 0009-Ignore-storage-volumes-with-control-codes-in-their-n.patch
|
|
||||||
Patch0010: 0010-util-buffer-Add-support-for-adding-text-blocks-with-.patch
|
|
||||||
Patch0011: 0011-Strip-control-codes-in-virBufferEscapeString.patch
|
|
||||||
|
|
||||||
%if %{with_libvirtd}
|
%if %{with_libvirtd}
|
||||||
Requires: libvirt-daemon = %{version}-%{release}
|
Requires: libvirt-daemon = %{version}-%{release}
|
||||||
%if %{with_network}
|
%if %{with_network}
|
||||||
|
@ -1528,6 +1516,7 @@ rm -f po/stamp-po
|
||||||
%{with_packager_version} \
|
%{with_packager_version} \
|
||||||
--with-qemu-user=%{qemu_user} \
|
--with-qemu-user=%{qemu_user} \
|
||||||
--with-qemu-group=%{qemu_group} \
|
--with-qemu-group=%{qemu_group} \
|
||||||
|
%{?with_loader_nvram} \
|
||||||
%{?enable_werror} \
|
%{?enable_werror} \
|
||||||
--enable-expensive-tests \
|
--enable-expensive-tests \
|
||||||
%{init_scripts}
|
%{init_scripts}
|
||||||
|
@ -1979,9 +1968,6 @@ exit 0
|
||||||
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/
|
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/
|
||||||
%ghost %dir %attr(0700, root, root) %{_localstatedir}/run/libvirt/qemu/
|
%ghost %dir %attr(0700, root, root) %{_localstatedir}/run/libvirt/qemu/
|
||||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
||||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/
|
|
||||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/
|
|
||||||
%dir %attr(0711, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/
|
|
||||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
||||||
%{_datadir}/augeas/lenses/libvirtd_qemu.aug
|
%{_datadir}/augeas/lenses/libvirtd_qemu.aug
|
||||||
%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
|
%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
|
||||||
|
@ -2082,9 +2068,6 @@ exit 0
|
||||||
%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.qemu
|
%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.qemu
|
||||||
%ghost %dir %attr(0700, root, root) %{_localstatedir}/run/libvirt/qemu/
|
%ghost %dir %attr(0700, root, root) %{_localstatedir}/run/libvirt/qemu/
|
||||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
||||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/
|
|
||||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/
|
|
||||||
%dir %attr(0711, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/
|
|
||||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
||||||
%{_datadir}/augeas/lenses/libvirtd_qemu.aug
|
%{_datadir}/augeas/lenses/libvirtd_qemu.aug
|
||||||
%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
|
%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
|
||||||
|
@ -2297,6 +2280,19 @@ exit 0
|
||||||
%doc examples/systemtap
|
%doc examples/systemtap
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Apr 28 2015 Cole Robinson <crobinso@redhat.com> - 1.2.13.1-1
|
||||||
|
- Rebased to version 1.2.13.1
|
||||||
|
- Fix getVersion() after installing qemu (bz #1000116)
|
||||||
|
- Fix autosocket setup with qemu:///session (bz #1044561, bz #1105274)
|
||||||
|
- Ignore storage volumes with non-ascii in names (bz #1066564)
|
||||||
|
- Don't generate invalid system nodedev XML (bz #1184131)
|
||||||
|
- Fix crash via race when unrefing rpc identity object (bz #1203030)
|
||||||
|
- Fix domcapabilities failure with ppc64le (bz #1209948)
|
||||||
|
- Fix regression with 'virsh event ' (bz #1212620)
|
||||||
|
- Add {Haswell,Broadwell}-noTSX CPU models (bz #1182650)
|
||||||
|
- Don't lose VMs on libvirtd restart if qemu is uninstalled (bz #1099847)
|
||||||
|
- Ignore storage volumes that libvirt can't open (bz #1103308)
|
||||||
|
|
||||||
* Wed Apr 15 2015 Cole Robinson <crobinso@redhat.com> - 1.2.13-3
|
* Wed Apr 15 2015 Cole Robinson <crobinso@redhat.com> - 1.2.13-3
|
||||||
- Fix LXC domain startup (bz #1210397)
|
- Fix LXC domain startup (bz #1210397)
|
||||||
- Fix crash via identify object cleanup race (bz #1203030)
|
- Fix crash via identify object cleanup race (bz #1203030)
|
||||||
|
|
Loading…
Reference in New Issue