1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-09-26 01:44:56 +03:00

Compare commits

..

17 Commits

Author SHA1 Message Date
Ján Tomko
415cc5c064 api: disallow virConnect*HypervisorCPU on read-only connections
These APIs can be used to execute arbitrary emulators.
Forbid them on read-only connections.

Fixes: CVE-2019-10168
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit bf6c2830b6)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Ján Tomko
fd16bd525a api: disallow virConnectGetDomainCapabilities on read-only connections
This API can be used to execute arbitrary emulators.
Forbid it on read-only connections.

Fixes: CVE-2019-10167
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 8afa68bac0)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Ján Tomko
d025c10d54 api: disallow virDomainManagedSaveDefineXML on read-only connections
The virDomainManagedSaveDefineXML can be used to alter the domain's
config used for managedsave or even execute arbitrary emulator binaries.
Forbid it on read-only connections.

Fixes: CVE-2019-10166
Reported-by: Matthias Gerstner <mgerstner@suse.de>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit db0b78457f)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Ján Tomko
6a028b6e82 api: disallow virDomainSaveImageGetXMLDesc on read-only connections
The virDomainSaveImageGetXMLDesc API is taking a path parameter,
which can point to any path on the system. This file will then be
read and parsed by libvirtd running with root privileges.

Forbid it on read-only connections.

Fixes: CVE-2019-10161
Reported-by: Matthias Gerstner <mgerstner@suse.de>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit aed6a032ce)
Signed-off-by: Ján Tomko <jtomko@redhat.com>

Conflicts:
  src/libvirt-domain.c
  src/remote/remote_protocol.x

Upstream commit 12a51f372 which introduced the VIR_DOMAIN_SAVE_IMAGE_XML_SECURE
alias for VIR_DOMAIN_XML_SECURE is not backported.
Just skip the commit since we now disallow the whole API on read-only
connections, regardless of the flag.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Daniel P. Berrangé
ec58805400 logging: restrict sockets to mode 0600
The virtlogd daemon's only intended client is the libvirtd daemon. As
such it should never allow clients from other user accounts to connect.
The code already enforces this and drops clients from other UIDs, but
we can get earlier (and thus stronger) protection against DoS by setting
the socket permissions to 0600

Fixes CVE-2019-10132

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit e37bd65f99)
2019-05-21 13:30:02 +01:00
Daniel P. Berrangé
618358632b locking: restrict sockets to mode 0600
The virtlockd daemon's only intended client is the libvirtd daemon. As
such it should never allow clients from other user accounts to connect.
The code already enforces this and drops clients from other UIDs, but
we can get earlier (and thus stronger) protection against DoS by setting
the socket permissions to 0600

Fixes CVE-2019-10132

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit f111e09468)
2019-05-21 13:30:01 +01:00
Daniel P. Berrangé
d1017aeee9 admin: reject clients unless their UID matches the current UID
The admin protocol RPC messages are only intended for use by the user
running the daemon. As such they should not be allowed for any client
UID that does not match the server UID.

Fixes CVE-2019-10132

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 96f41cd765)
2019-05-21 13:30:01 +01:00
Luyao Huang
35176b5c78 virDomainConfNWFilterInstantiate: initialize @xml to avoid random crash
If the code jump to the cleanup before assigning value to @xml
libvirtd may crash when it tries to free an uninitialized pointer.

backtrace:

0  0x00007ffff428d59c in free () from /lib64/libc.so.6
1  0x00007ffff721314a in virFree (ptrptr=ptrptr@entry=0x7fffc67f1b00) at util/viralloc.c:582
2  0x00007ffff7345ac4 in virDomainConfNWFilterInstantiate (vmname=<optimized out>,
   vmuuid=vmuuid@entry=0x7fffc0181ca8 "߉\237\\۔H\262\206z\340\302f\265\233z", net=<optimized out>,
   ignoreExists=ignoreExists@entry=true) at conf/domain_nwfilter.c:122
3  0x00007fffca5a77f6 in qemuProcessFiltersInstantiate (ignoreExists=true, def=0x7fffc0181ca0) at qemu/qemu_process.c:3028
4  qemuProcessReconnect (opaque=<optimized out>) at qemu/qemu_process.c:7653
5  0x00007ffff72c4895 in virThreadHelper (data=<optimized out>) at util/virthread.c:206
6  0x00007ffff45dcdd5 in start_thread () from /lib64/libpthread.so.0
7  0x00007ffff4305ead in clone () from /lib64/libc.so.6

Signed-off-by: Luyao Huang <lhuang@redhat.com>
(cherry picked from commit d7557f5f6f)
2018-07-06 14:31:47 +01:00
Daniel P. Berrangé
6aedf9bfad qemu: fix UNIX socket chardevs operating in client mode
When support was adding for passing a pre-opened listener socket to UNIX
chardevs, it accidentally passed the listener socket for client mode
chardevs too with predictable amounts of fail resulting. This affects
libvirt when using QEMU >= 2.12

Expand the unit test coverage to validate that we are only doing FD
passing when operating in server mode.

  https://bugzilla.redhat.com/show_bug.cgi?id=1598440

Tested-by: Richard W.M. Jones <rjones@redhat.com>
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 1bc1a7e320)
2018-07-06 14:31:35 +01:00
Daniel P. Berrangé
78920738ca qemu: don't use chardev FD passing for vhostuser backend
QEMU chardevs have a bug which makes the vhostuser backend complain
about lack of support for FD passing when validating the chardev.
While this is ultimately QEMU's responsibility to fix, libvirt needs to
avoid tickling the bug.

Simply disabling chardev FD passing just for vhostuser's chardev is
the most prudent approach, avoiding need for a QEMU version number
check.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit ed5aa85f37)
2018-07-06 14:31:29 +01:00
Daniel P. Berrangé
88924317f3 qemu: consolidate parameters of qemuBuildChrChardevStr into flags
There are two boolean parameters passed to qemuBuildChrChardevStr,
and soon there will be a third. It will be clearer to understand
from callers' POV if we use named flags instead.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 0140d4c59b)
2018-07-06 14:31:23 +01:00
Daniel P. Berrangé
941ca31e90 qemu: remove chardevStdioLogd param from vhostuser code path
The vhostuser network backend is only supported with the UNIX domain
socket chardev backend, so passing around chardevStdioLogd is not
required.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 4c76266bac)
2018-07-06 14:31:15 +01:00
Daniel P. Berrangé
3818514602 qemu: don't use chardev FD passing with standalone args
When using domxml-to-native, we must generate CLI args that can be used
in a standalone scenario. This means no FD passing can be used. To
achieve this we must clear the QEMU_CAPS_CHARDEV_FD_PASS capability bit.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 7ac08cc929)
2018-07-06 14:30:43 +01:00
Daniel Veillard
6a32f5b89d Release of libvirt-4.5.0
- docs/news.xml: updated for the release

Signed-off-by: Daniel Veillard <veillard@redhat.com>
2018-07-02 22:11:33 +02:00
Andrea Bolognani
04e10e8714 news: Update for 4.5.0 release
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
2018-07-02 17:42:30 +02:00
Jiri Denemark
5f99821911 qemu_migration: Check for active domain after talking to remote daemon
Once we called qemuDomainObjEnterRemote to talk to the destination
daemon during a peer to peer migration, the vm lock is released and we
only hold an async job. If the source domain dies at this point the
monitor EOF callback is allowed to do its job and (among other things)
clear all private data irrelevant for stopped domain. Thus when we call
qemuDomainObjExitRemote, the domain may already be gone and we should
avoid touching runtime private data (such as current job info).

In other words after acquiring the lock in qemuDomainObjExitRemote, we
need to check the domain is still alive. Unless we're doing offline
migration.

https://bugzilla.redhat.com/show_bug.cgi?id=1589730

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
2018-07-02 11:53:21 +02:00
Jiri Denemark
e05ed21623 qemu_migration: Rename 'offline' variable in SrcPerformPeer2Peer
The variable is used to store the offline migration capability of the
destination daemon. Let's call it 'dstOffline' so that we can later use
'offline' to indicate whether we were asked to do offline migration.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
2018-07-02 11:52:30 +02:00
22 changed files with 293 additions and 98 deletions

View File

@@ -33,7 +33,7 @@
-->
<libvirt>
<release version="v4.5.0" date="unreleased">
<release version="v4.5.0" date="2018-07-02">
<section title="New features">
<change>
<summary>
@@ -61,6 +61,16 @@
Support specifying extended TSEG size for SMM in QEMU.
</description>
</change>
<change>
<summary>
qemu: Add support for SEV guests
</summary>
<description>
SEV (Secure Encrypted Virtualization) is a feature available on AMD
CPUs that encrypts the guest memory and makes it inaccessible even
to the host OS.
</description>
</change>
</section>
<section title="Removed features">
<change>
@@ -76,6 +86,24 @@
secret objects, but that support was never added to libvirt.
</description>
</change>
<change>
<summary>
Make GnuTLS mandatory
</summary>
<description>
Building without GnuTLS is no longer possible.
</description>
</change>
<change>
<summary>
qemu: Remove allow_disk_format_probing configuration option
</summary>
<description>
The option represented a security risk when used with malicious
disk images, so users were recommended against enabling it; with
this release, it's been removed altogether.
</description>
</change>
</section>
<section title="Improvements">
<change>
@@ -130,6 +158,39 @@
or virStorageVolCreateXMLFrom.
</description>
</change>
<change>
<summary>
qemu: Add support for vsock hot (un)plug and cold (un)plug
</summary>
</change>
<change>
<summary>
qemu: Add support for NBD over TLS
</summary>
<description>
NBD volumes can now be accessed securely.
</description>
</change>
<change>
<summary>
qemu: Implement FD passing for Unix sockets
</summary>
<description>
Instead of having QEMU open the socket and then connecting to it,
which is inherently racy, starting with QEMU 2.12 we can open the
socket ourselves and pass it to QEMU, avoiding race conditions.
</description>
</change>
<change>
<summary>
virsh: Introduce --nowait option for domstat command
</summary>
<description>
When this option is specified, virsh will try to fetch the guest
stats but abort instead of stalling if they can't be retrieved right
away.
</description>
</change>
</section>
<section title="Bug fixes">
<change>
@@ -143,6 +204,26 @@
us getting to the worker pool initialization.
</description>
</change>
<change>
<summary>
qemu: Fix domain resume after failed migration
</summary>
<description>
Recent versions of QEMU activate block devices before the guest CPU
has been started, which makes it impossible to roll back a failed
migration. Use the <code>late-block-activate</code> migration
capability if supported to avoid the issue.
</description>
</change>
<change>
<summary>
vmx: Permit guests to have an odd number of vCPUs
</summary>
<description>
An odd number of vCPUs greater than 1 was forbidden in the past,
but current versions of ESXi have lifted that restriction.
</description>
</change>
</section>
</release>
<release version="v4.4.0" date="2018-06-04">

View File

@@ -66,6 +66,28 @@ remoteAdmClientNew(virNetServerClientPtr client ATTRIBUTE_UNUSED,
void *opaque)
{
struct daemonAdmClientPrivate *priv;
uid_t clientuid;
gid_t clientgid;
pid_t clientpid;
unsigned long long timestamp;
if (virNetServerClientGetUNIXIdentity(client,
&clientuid,
&clientgid,
&clientpid,
&timestamp) < 0)
return NULL;
VIR_DEBUG("New client pid %lld uid %lld",
(long long)clientpid,
(long long)clientuid);
if (geteuid() != clientuid) {
virReportRestrictedError(_("Disallowing client %lld with uid %lld"),
(long long)clientpid,
(long long)clientuid);
return NULL;
}
if (VIR_ALLOC(priv) < 0)
return NULL;

View File

@@ -90,7 +90,7 @@ virDomainConfNWFilterInstantiate(const char *vmname,
virConnectPtr conn = virGetConnectNWFilter();
virNWFilterBindingDefPtr def = NULL;
virNWFilterBindingPtr binding = NULL;
char *xml;
char *xml = NULL;
int ret = -1;
VIR_DEBUG("vmname=%s portdev=%s filter=%s ignoreExists=%d",

View File

@@ -1073,9 +1073,7 @@ virDomainRestoreFlags(virConnectPtr conn, const char *from, const char *dxml,
* previously by virDomainSave() or virDomainSaveFlags().
*
* No security-sensitive data will be included unless @flags contains
* VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
* connections. For this API, @flags should not contain either
* VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU.
* VIR_DOMAIN_XML_SECURE.
*
* Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of
* error. The caller must free() the returned value.
@@ -1091,12 +1089,7 @@ virDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *file,
virCheckConnectReturn(conn, NULL);
virCheckNonNullArgGoto(file, error);
if ((conn->flags & VIR_CONNECT_RO) && (flags & VIR_DOMAIN_XML_SECURE)) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("virDomainSaveImageGetXMLDesc with secure flag"));
goto error;
}
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->domainSaveImageGetXMLDesc) {
char *ret;
@@ -9484,6 +9477,7 @@ virDomainManagedSaveDefineXML(virDomainPtr domain, const char *dxml,
virCheckDomainReturn(domain, -1);
conn = domain->conn;
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->domainManagedSaveDefineXML) {
int ret;
@@ -11275,6 +11269,7 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
virResetLastError();
virCheckConnectReturn(conn, NULL);
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->connectGetDomainCapabilities) {
char *ret;

View File

@@ -1041,6 +1041,7 @@ virConnectCompareHypervisorCPU(virConnectPtr conn,
virCheckConnectReturn(conn, VIR_CPU_COMPARE_ERROR);
virCheckNonNullArgGoto(xmlCPU, error);
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->connectCompareHypervisorCPU) {
int ret;
@@ -1234,6 +1235,7 @@ virConnectBaselineHypervisorCPU(virConnectPtr conn,
virCheckConnectReturn(conn, NULL);
virCheckNonNullArgGoto(xmlCPUs, error);
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->connectBaselineHypervisorCPU) {
char *cpu;

View File

@@ -5,6 +5,7 @@ Before=libvirtd.service
[Socket]
ListenStream=@localstatedir@/run/libvirt/virtlockd-admin-sock
Service=virtlockd.service
SocketMode=0600
[Install]
WantedBy=sockets.target

View File

@@ -4,6 +4,7 @@ Before=libvirtd.service
[Socket]
ListenStream=@localstatedir@/run/libvirt/virtlockd-sock
SocketMode=0600
[Install]
WantedBy=sockets.target

View File

@@ -5,6 +5,7 @@ Before=libvirtd.service
[Socket]
ListenStream=@localstatedir@/run/libvirt/virtlogd-admin-sock
Service=virtlogd.service
SocketMode=0600
[Install]
WantedBy=sockets.target

View File

@@ -4,6 +4,7 @@ Before=libvirtd.service
[Socket]
ListenStream=@localstatedir@/run/libvirt/virtlogd-sock
SocketMode=0600
[Install]
WantedBy=sockets.target

View File

@@ -4934,6 +4934,13 @@ qemuOpenChrChardevUNIXSocket(const virDomainChrSourceDef *dev)
return -1;
}
enum {
QEMU_BUILD_CHARDEV_TCP_NOWAIT = (1 << 0),
QEMU_BUILD_CHARDEV_FILE_LOGD = (1 << 1),
QEMU_BUILD_CHARDEV_UNIX_FD_PASS = (1 << 2),
};
/* This function outputs a -chardev command line option which describes only the
* host side of the character device */
static char *
@@ -4945,8 +4952,7 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
const virDomainChrSourceDef *dev,
const char *alias,
virQEMUCapsPtr qemuCaps,
bool nowait,
bool chardevStdioLogd)
unsigned int flags)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
bool telnet;
@@ -4985,7 +4991,8 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
_("append not supported in this QEMU binary"));
goto cleanup;
}
if (qemuBuildChrChardevFileStr(chardevStdioLogd ? logManager : NULL,
if (qemuBuildChrChardevFileStr(flags & QEMU_BUILD_CHARDEV_FILE_LOGD ?
logManager : NULL,
cmd, def, &buf,
"path", dev->data.file.path,
"append", dev->data.file.append) < 0)
@@ -5031,8 +5038,11 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
dev->data.tcp.service,
telnet ? ",telnet" : "");
if (dev->data.tcp.listen)
virBufferAdd(&buf, nowait ? ",server,nowait" : ",server", -1);
if (dev->data.tcp.listen) {
virBufferAddLit(&buf, ",server");
if (flags & QEMU_BUILD_CHARDEV_TCP_NOWAIT)
virBufferAddLit(&buf, ",nowait");
}
qemuBuildChrChardevReconnectStr(&buf, &dev->data.tcp.reconnect);
@@ -5072,7 +5082,9 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
break;
case VIR_DOMAIN_CHR_TYPE_UNIX:
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FD_PASS)) {
if (dev->data.nix.listen &&
(flags & QEMU_BUILD_CHARDEV_UNIX_FD_PASS) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FD_PASS)) {
if (qemuSecuritySetSocketLabel(secManager, (virDomainDefPtr)def) < 0)
goto cleanup;
int fd = qemuOpenChrChardevUNIXSocket(dev);
@@ -5090,8 +5102,11 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager,
virBufferAsprintf(&buf, "socket,id=%s,path=", charAlias);
virQEMUBuildBufferEscapeComma(&buf, dev->data.nix.path);
}
if (dev->data.nix.listen)
virBufferAdd(&buf, nowait ? ",server,nowait" : ",server", -1);
if (dev->data.nix.listen) {
virBufferAddLit(&buf, ",server");
if (flags & QEMU_BUILD_CHARDEV_TCP_NOWAIT)
virBufferAddLit(&buf, ",nowait");
}
qemuBuildChrChardevReconnectStr(&buf, &dev->data.nix.reconnect);
break;
@@ -5425,6 +5440,10 @@ qemuBuildMonitorCommandLine(virLogManagerPtr logManager,
qemuDomainObjPrivatePtr priv)
{
char *chrdev;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (priv->chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
if (!priv->monConfig)
return 0;
@@ -5432,8 +5451,7 @@ qemuBuildMonitorCommandLine(virLogManagerPtr logManager,
if (!(chrdev = qemuBuildChrChardevStr(logManager, secManager,
cmd, cfg, def,
priv->monConfig, "monitor",
priv->qemuCaps, true,
priv->chardevStdioLogd)))
priv->qemuCaps, cdevflags)))
return -1;
virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, chrdev);
@@ -5558,6 +5576,10 @@ qemuBuildRNGBackendChrdevStr(virLogManagerPtr logManager,
char **chr,
bool chardevStdioLogd)
{
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
*chr = NULL;
switch ((virDomainRNGBackend) rng->backend) {
@@ -5570,8 +5592,8 @@ qemuBuildRNGBackendChrdevStr(virLogManagerPtr logManager,
if (!(*chr = qemuBuildChrChardevStr(logManager, secManager,
cmd, cfg, def,
rng->source.chardev,
rng->info.alias, qemuCaps, true,
chardevStdioLogd)))
rng->info.alias, qemuCaps,
cdevflags)))
return -1;
}
@@ -8174,8 +8196,7 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver,
virDomainDefPtr def,
virDomainNetDefPtr net,
virQEMUCapsPtr qemuCaps,
unsigned int bootindex,
bool chardevStdioLogd)
unsigned int bootindex)
{
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
char *chardev = NULL;
@@ -8195,8 +8216,7 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver,
if (!(chardev = qemuBuildChrChardevStr(logManager, secManager,
cmd, cfg, def,
net->data.vhostuser,
net->info.alias, qemuCaps, false,
chardevStdioLogd)))
net->info.alias, qemuCaps, 0)))
goto cleanup;
break;
@@ -8270,8 +8290,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
virNetDevVPortProfileOp vmop,
bool standalone,
size_t *nnicindexes,
int **nicindexes,
bool chardevStdioLogd)
int **nicindexes)
{
int ret = -1;
char *nic = NULL, *host = NULL;
@@ -8394,8 +8413,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
ret = qemuBuildVhostuserCommandLine(driver, logManager, secManager, cmd, def,
net, qemuCaps, bootindex,
chardevStdioLogd);
net, qemuCaps, bootindex);
goto cleanup;
break;
@@ -8579,8 +8597,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver,
bool standalone,
size_t *nnicindexes,
int **nicindexes,
unsigned int *bootHostdevNet,
bool chardevStdioLogd)
unsigned int *bootHostdevNet)
{
size_t i;
int last_good_net = -1;
@@ -8607,8 +8624,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver,
if (qemuBuildInterfaceCommandLine(driver, logManager, secManager, cmd, def, net,
qemuCaps, bootNet, vmop,
standalone, nnicindexes,
nicindexes,
chardevStdioLogd) < 0)
nicindexes) < 0)
goto error;
last_good_net = i;
@@ -8680,6 +8696,10 @@ qemuBuildSmartcardCommandLine(virLogManagerPtr logManager,
virBuffer opt = VIR_BUFFER_INITIALIZER;
const char *database;
const char *contAlias = NULL;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
if (!def->nsmartcards)
return 0;
@@ -8745,8 +8765,7 @@ qemuBuildSmartcardCommandLine(virLogManagerPtr logManager,
cmd, cfg, def,
smartcard->data.passthru,
smartcard->info.alias,
qemuCaps, true,
chardevStdioLogd))) {
qemuCaps, cdevflags))) {
virBufferFreeAndReset(&opt);
return -1;
}
@@ -8914,6 +8933,10 @@ qemuBuildShmemCommandLine(virLogManagerPtr logManager,
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *devstr = NULL;
int rc;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
if (shmem->size) {
/*
@@ -8977,8 +9000,8 @@ qemuBuildShmemCommandLine(virLogManagerPtr logManager,
devstr = qemuBuildChrChardevStr(logManager, secManager,
cmd, cfg, def,
&shmem->server.chr,
shmem->info.alias, qemuCaps, true,
chardevStdioLogd);
shmem->info.alias, qemuCaps,
cdevflags);
if (!devstr)
return -1;
@@ -9071,6 +9094,10 @@ qemuBuildSerialCommandLine(virLogManagerPtr logManager,
{
size_t i;
bool havespice = false;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
if (def->nserials) {
for (i = 0; i < def->ngraphics && !havespice; i++) {
@@ -9090,8 +9117,7 @@ qemuBuildSerialCommandLine(virLogManagerPtr logManager,
cmd, cfg, def,
serial->source,
serial->info.alias,
qemuCaps, true,
chardevStdioLogd)))
qemuCaps, cdevflags)))
return -1;
virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr);
@@ -9132,6 +9158,10 @@ qemuBuildParallelsCommandLine(virLogManagerPtr logManager,
bool chardevStdioLogd)
{
size_t i;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
for (i = 0; i < def->nparallels; i++) {
virDomainChrDefPtr parallel = def->parallels[i];
@@ -9141,8 +9171,7 @@ qemuBuildParallelsCommandLine(virLogManagerPtr logManager,
cmd, cfg, def,
parallel->source,
parallel->info.alias,
qemuCaps, true,
chardevStdioLogd)))
qemuCaps, cdevflags)))
return -1;
virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr);
@@ -9167,6 +9196,10 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
bool chardevStdioLogd)
{
size_t i;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
for (i = 0; i < def->nchannels; i++) {
virDomainChrDefPtr channel = def->channels[i];
@@ -9178,8 +9211,7 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
cmd, cfg, def,
channel->source,
channel->info.alias,
qemuCaps, true,
chardevStdioLogd)))
qemuCaps, cdevflags)))
return -1;
virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr);
@@ -9196,8 +9228,7 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
cmd, cfg, def,
channel->source,
channel->info.alias,
qemuCaps, true,
chardevStdioLogd)))
qemuCaps, cdevflags)))
return -1;
virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr);
@@ -9223,6 +9254,10 @@ qemuBuildConsoleCommandLine(virLogManagerPtr logManager,
bool chardevStdioLogd)
{
size_t i;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
/* Explicit console devices */
for (i = 0; i < def->nconsoles; i++) {
@@ -9241,8 +9276,7 @@ qemuBuildConsoleCommandLine(virLogManagerPtr logManager,
cmd, cfg, def,
console->source,
console->info.alias,
qemuCaps, true,
chardevStdioLogd)))
qemuCaps, cdevflags)))
return -1;
virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr);
@@ -9263,8 +9297,7 @@ qemuBuildConsoleCommandLine(virLogManagerPtr logManager,
cmd, cfg, def,
console->source,
console->info.alias,
qemuCaps, true,
chardevStdioLogd)))
qemuCaps, cdevflags)))
return -1;
virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr);
@@ -9279,8 +9312,7 @@ qemuBuildConsoleCommandLine(virLogManagerPtr logManager,
cmd, cfg, def,
console->source,
console->info.alias,
qemuCaps, true,
chardevStdioLogd)))
qemuCaps, cdevflags)))
return -1;
virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr);
@@ -9403,6 +9435,10 @@ qemuBuildRedirdevCommandLine(virLogManagerPtr logManager,
bool chardevStdioLogd)
{
size_t i;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
if (chardevStdioLogd)
cdevflags |= QEMU_BUILD_CHARDEV_FILE_LOGD;
for (i = 0; i < def->nredirdevs; i++) {
virDomainRedirdevDefPtr redirdev = def->redirdevs[i];
@@ -9412,8 +9448,7 @@ qemuBuildRedirdevCommandLine(virLogManagerPtr logManager,
cmd, cfg, def,
redirdev->source,
redirdev->info.alias,
qemuCaps, true,
chardevStdioLogd))) {
qemuCaps, cdevflags))) {
return -1;
}
@@ -10269,8 +10304,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
if (qemuBuildNetCommandLine(driver, logManager, secManager, cmd, def,
qemuCaps, vmop, standalone,
nnicindexes, nicindexes, &bootHostdevNet,
chardevStdioLogd) < 0)
nnicindexes, nicindexes, &bootHostdevNet) < 0)
goto error;
if (qemuBuildSmartcardCommandLine(logManager, secManager, cmd, cfg, def, qemuCaps,

View File

@@ -7023,11 +7023,23 @@ void qemuDomainObjEnterRemote(virDomainObjPtr obj)
virObjectUnlock(obj);
}
void qemuDomainObjExitRemote(virDomainObjPtr obj)
int
qemuDomainObjExitRemote(virDomainObjPtr obj,
bool checkActive)
{
virObjectLock(obj);
VIR_DEBUG("Exited remote (vm=%p name=%s)",
obj, obj->def->name);
if (checkActive && !virDomainObjIsActive(obj)) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("domain '%s' is not running"),
obj->def->name);
return -1;
}
return 0;
}

View File

@@ -584,8 +584,9 @@ void qemuDomainObjExitAgent(virDomainObjPtr obj, qemuAgentPtr agent)
void qemuDomainObjEnterRemote(virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1);
void qemuDomainObjExitRemote(virDomainObjPtr obj)
ATTRIBUTE_NONNULL(1);
int qemuDomainObjExitRemote(virDomainObjPtr obj,
bool checkActive)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
virDomainDefPtr qemuDomainDefCopy(virQEMUDriverPtr driver,
virDomainDefPtr src,

View File

@@ -6792,7 +6792,7 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path,
if (fd < 0)
goto cleanup;
if (virDomainSaveImageGetXMLDescEnsureACL(conn, def, flags) < 0)
if (virDomainSaveImageGetXMLDescEnsureACL(conn, def) < 0)
goto cleanup;
ret = qemuDomainDefFormatXML(driver, def, flags);

View File

@@ -3920,27 +3920,20 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver,
qemuDomainObjEnterRemote(vm);
ret = dconn->driver->domainMigratePrepareTunnel
(dconn, st, destflags, dname, resource, dom_xml);
qemuDomainObjExitRemote(vm);
if (qemuDomainObjExitRemote(vm, true) < 0)
goto cleanup;
} else {
qemuDomainObjEnterRemote(vm);
ret = dconn->driver->domainMigratePrepare2
(dconn, &cookie, &cookielen, NULL, &uri_out,
destflags, dname, resource, dom_xml);
qemuDomainObjExitRemote(vm);
if (qemuDomainObjExitRemote(vm, true) < 0)
goto cleanup;
}
VIR_FREE(dom_xml);
if (ret == -1)
goto cleanup;
/* the domain may have shutdown or crashed while we had the locks dropped
* in qemuDomainObjEnterRemote, so check again
*/
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("guest unexpectedly quit"));
goto cleanup;
}
if (!(flags & VIR_MIGRATE_TUNNELLED) &&
(uri_out == NULL)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -3987,7 +3980,8 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver,
ddomain = dconn->driver->domainMigrateFinish2
(dconn, dname, cookie, cookielen,
uri_out ? uri_out : dconnuri, destflags, cancelled);
qemuDomainObjExitRemote(vm);
/* The domain is already gone at this point */
ignore_value(qemuDomainObjExitRemote(vm, false));
if (cancelled && ddomain)
VIR_ERROR(_("finish step ignored that migration was cancelled"));
@@ -4052,6 +4046,7 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
int nparams = 0;
int maxparams = 0;
size_t i;
bool offline = !!(flags & VIR_MIGRATE_OFFLINE);
VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, dconnuri=%s, vm=%p, xmlin=%s, "
"dname=%s, uri=%s, graphicsuri=%s, listenAddress=%s, "
@@ -4145,7 +4140,8 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
(dconn, st, cookiein, cookieinlen, &cookieout, &cookieoutlen,
destflags, dname, bandwidth, dom_xml);
}
qemuDomainObjExitRemote(vm);
if (qemuDomainObjExitRemote(vm, !offline) < 0)
goto cleanup;
} else {
qemuDomainObjEnterRemote(vm);
if (useParams) {
@@ -4157,13 +4153,14 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
(dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen,
uri, &uri_out, destflags, dname, bandwidth, dom_xml);
}
qemuDomainObjExitRemote(vm);
if (qemuDomainObjExitRemote(vm, !offline) < 0)
goto cleanup;
}
VIR_FREE(dom_xml);
if (ret == -1)
goto cleanup;
if (flags & VIR_MIGRATE_OFFLINE) {
if (offline) {
VIR_DEBUG("Offline migration, skipping Perform phase");
VIR_FREE(cookieout);
cookieoutlen = 0;
@@ -4253,7 +4250,8 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
ddomain = dconn->driver->domainMigrateFinish3Params
(dconn, params, nparams, cookiein, cookieinlen,
&cookieout, &cookieoutlen, destflags, cancelled);
qemuDomainObjExitRemote(vm);
if (qemuDomainObjExitRemote(vm, !offline) < 0)
goto cleanup;
}
} else {
dname = dname ? dname : vm->def->name;
@@ -4261,7 +4259,8 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver,
ddomain = dconn->driver->domainMigrateFinish3
(dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
dconnuri, uri, destflags, cancelled);
qemuDomainObjExitRemote(vm);
if (qemuDomainObjExitRemote(vm, !offline) < 0)
goto cleanup;
}
if (cancelled) {
@@ -4399,7 +4398,8 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver,
virConnectPtr dconn = NULL;
bool p2p;
virErrorPtr orig_err = NULL;
bool offline = false;
bool offline = !!(flags & VIR_MIGRATE_OFFLINE);
bool dstOffline = false;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
bool useParams;
@@ -4439,7 +4439,9 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver,
qemuDomainObjEnterRemote(vm);
dconn = virConnectOpenAuth(dconnuri, &virConnectAuthConfig, 0);
qemuDomainObjExitRemote(vm);
if (qemuDomainObjExitRemote(vm, !offline) < 0)
goto cleanup;
if (dconn == NULL) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("Failed to connect to remote libvirt URI %s: %s"),
@@ -4468,10 +4470,11 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver,
VIR_DRV_FEATURE_MIGRATION_V3);
useParams = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
VIR_DRV_FEATURE_MIGRATION_PARAMS);
if (flags & VIR_MIGRATE_OFFLINE)
offline = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
VIR_DRV_FEATURE_MIGRATION_OFFLINE);
qemuDomainObjExitRemote(vm);
if (offline)
dstOffline = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
VIR_DRV_FEATURE_MIGRATION_OFFLINE);
if (qemuDomainObjExitRemote(vm, !offline) < 0)
goto cleanup;
if (!p2p) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
@@ -4488,20 +4491,13 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver,
goto cleanup;
}
if (flags & VIR_MIGRATE_OFFLINE && !offline) {
if (offline && !dstOffline) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
_("offline migration is not supported by "
"the destination host"));
goto cleanup;
}
/* domain may have been stopped while we were talking to remote daemon */
if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("guest unexpectedly quit"));
goto cleanup;
}
/* Change protection is only required on the source side (us), and
* only for v3 migration when begin and perform are separate jobs.
* But peer-2-peer is already a single job, and we still want to
@@ -4526,7 +4522,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver,
qemuDomainObjEnterRemote(vm);
virConnectUnregisterCloseCallback(dconn, qemuMigrationSrcConnectionClosed);
virObjectUnref(dconn);
qemuDomainObjExitRemote(vm);
ignore_value(qemuDomainObjExitRemote(vm, false));
if (orig_err) {
virSetError(orig_err);
virFreeError(orig_err);

View File

@@ -5124,6 +5124,9 @@ qemuProcessInit(virQEMUDriverPtr driver,
vm->def->os.machine)))
goto cleanup;
if (flags & VIR_QEMU_PROCESS_START_STANDALONE)
virQEMUCapsClear(priv->qemuCaps, QEMU_CAPS_CHARDEV_FD_PASS);
if (qemuDomainUpdateCPU(vm, updatedCPU, &origCPU) < 0)
goto cleanup;
@@ -6632,6 +6635,8 @@ qemuProcessCreatePretendCmd(virQEMUDriverPtr driver,
flags |= VIR_QEMU_PROCESS_START_PRETEND;
flags |= VIR_QEMU_PROCESS_START_NEW;
if (standalone)
flags |= VIR_QEMU_PROCESS_START_STANDALONE;
if (qemuProcessInit(driver, vm, NULL, QEMU_ASYNC_JOB_NONE,
!!migrateURI, flags) < 0)

View File

@@ -81,6 +81,8 @@ typedef enum {
VIR_QEMU_PROCESS_START_PRETEND = 1 << 3,
VIR_QEMU_PROCESS_START_NEW = 1 << 4, /* internal, new VM is starting */
VIR_QEMU_PROCESS_START_GEN_VMID = 1 << 5, /* Generate a new VMID */
VIR_QEMU_PROCESS_START_STANDALONE = 1 << 6, /* Require CLI args to be usable standalone,
ie no FD passing and the like */
} qemuProcessStartFlags;
int qemuProcessStart(virConnectPtr conn,

View File

@@ -5226,8 +5226,7 @@ enum remote_procedure {
/**
* @generate: both
* @priority: high
* @acl: domain:read
* @acl: domain:read_secure:VIR_DOMAIN_XML_SECURE
* @acl: domain:write
*/
REMOTE_PROC_DOMAIN_SAVE_IMAGE_GET_XML_DESC = 235,

View File

@@ -14,8 +14,7 @@ QEMU_AUDIO_DRV=none \
-display none \
-no-user-config \
-nodefaults \
-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
server,nowait \
-chardev socket,id=charmonitor,fd=1729,server,nowait \
-mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=utc \
-no-shutdown \

View File

@@ -26,4 +26,6 @@ server,nowait \
-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
-chardev socket,id=charserial0,path=/tmp/serial.sock \
-device isa-serial,chardev=charserial0,id=serial0 \
-chardev socket,id=charserial1,path=/tmp/serial-server.sock,server,nowait \
-device isa-serial,chardev=charserial1,id=serial1 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@@ -0,0 +1,36 @@
LC_ALL=C \
PATH=/bin \
HOME=/home/test \
USER=test \
LOGNAME=test \
QEMU_AUDIO_DRV=none \
/usr/bin/qemu-system-i686 \
-name guest=QEMUGuest1,debug-threads=on \
-S \
-object secret,id=masterKey0,format=raw,\
file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
-machine pc,accel=tcg,usb=off,dump-guest-core=off \
-m 214 \
-realtime mlock=off \
-smp 1,sockets=1,cores=1,threads=1 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
-display none \
-no-user-config \
-nodefaults \
-chardev socket,id=charmonitor,fd=1729,server,nowait \
-mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=utc \
-no-shutdown \
-no-acpi \
-boot strict=on \
-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \
-chardev socket,id=charserial0,path=/tmp/serial.sock \
-device isa-serial,chardev=charserial0,id=serial0 \
-chardev socket,id=charserial1,fd=1729,server,nowait \
-device isa-serial,chardev=charserial1,id=serial1 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
resourcecontrol=deny \
-msg timestamp=on

View File

@@ -25,6 +25,10 @@
<source mode='connect' path='/tmp/serial.sock'/>
<target port='0'/>
</serial>
<serial type='unix'>
<source mode='bind' path='/tmp/serial-server.sock'/>
<target port='1'/>
</serial>
<console type='unix'>
<source mode='connect' path='/tmp/serial.sock'/>
<target port='0'/>

View File

@@ -1266,7 +1266,7 @@ mymain(void)
DO_TEST("misc-no-reboot", NONE);
DO_TEST("misc-uuid", NONE);
DO_TEST_PARSE_ERROR("vhost_queues-invalid", NONE);
DO_TEST("net-vhostuser", NONE);
DO_TEST("net-vhostuser", QEMU_CAPS_CHARDEV_FD_PASS);
DO_TEST("net-vhostuser-multiq",
QEMU_CAPS_VHOSTUSER_MULTIQUEUE);
DO_TEST_FAILURE("net-vhostuser-multiq", NONE);
@@ -1335,6 +1335,7 @@ mymain(void)
QEMU_CAPS_CHARDEV_FILE_APPEND);
DO_TEST("serial-unix-chardev",
QEMU_CAPS_DEVICE_ISA_SERIAL);
DO_TEST_CAPS_LATEST("serial-unix-chardev");
DO_TEST("serial-tcp-chardev",
QEMU_CAPS_DEVICE_ISA_SERIAL);
DO_TEST("serial-udp-chardev",