2010-12-16 16:10:54 +00:00
|
|
|
/*
|
|
|
|
* qemu_hotplug.h: QEMU device hotplug management
|
|
|
|
*
|
2013-01-30 16:02:05 +00:00
|
|
|
* Copyright (C) 2006-2013 Red Hat, Inc.
|
2010-12-16 16:10:54 +00:00
|
|
|
* Copyright (C) 2006 Daniel P. Berrange
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2010-12-16 16:10:54 +00:00
|
|
|
*
|
|
|
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "qemu_hotplug.h"
|
|
|
|
#include "qemu_capabilities.h"
|
|
|
|
#include "qemu_domain.h"
|
|
|
|
#include "qemu_command.h"
|
|
|
|
#include "qemu_bridge_filter.h"
|
|
|
|
#include "qemu_hostdev.h"
|
Move qemu_audit.h helpers into shared code
The LXC and UML drivers can both make use of auditing. Move
the qemu_audit.{c,h} files to src/conf/domain_audit.{c,h}
* src/conf/domain_audit.c: Rename from src/qemu/qemu_audit.c
* src/conf/domain_audit.h: Rename from src/qemu/qemu_audit.h
* src/Makefile.am: Remove qemu_audit.{c,h}, add domain_audit.{c,h}
* src/qemu/qemu_audit.h, src/qemu/qemu_cgroup.c,
src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c,
src/qemu/qemu_process.c: Update for changed audit API names
2011-07-04 10:56:13 +00:00
|
|
|
#include "domain_audit.h"
|
2010-12-16 16:10:54 +00:00
|
|
|
#include "domain_nwfilter.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
#include "datatypes.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2012-12-13 14:52:25 +00:00
|
|
|
#include "virpci.h"
|
2011-07-19 18:32:58 +00:00
|
|
|
#include "virfile.h"
|
2013-04-25 16:45:55 +00:00
|
|
|
#include "virprocess.h"
|
2010-12-16 16:10:54 +00:00
|
|
|
#include "qemu_cgroup.h"
|
2010-10-26 14:04:46 +00:00
|
|
|
#include "locking/domain_lock.h"
|
2011-07-04 06:27:12 +00:00
|
|
|
#include "network/bridge_driver.h"
|
2012-03-28 19:11:09 +00:00
|
|
|
#include "virnetdev.h"
|
|
|
|
#include "virnetdevbridge.h"
|
2012-02-10 21:09:00 +00:00
|
|
|
#include "virnetdevtap.h"
|
2012-08-16 15:41:06 +00:00
|
|
|
#include "device_conf.h"
|
2012-12-13 15:25:48 +00:00
|
|
|
#include "virstoragefile.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
2013-01-24 14:14:14 +00:00
|
|
|
#define CHANGE_MEDIA_RETRIES 10
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainDiskDefPtr disk,
|
2013-02-19 12:27:45 +00:00
|
|
|
virDomainDiskDefPtr origdisk,
|
2010-12-16 16:10:54 +00:00
|
|
|
bool force)
|
|
|
|
{
|
2013-01-10 21:03:14 +00:00
|
|
|
int ret = -1;
|
2010-12-16 16:10:54 +00:00
|
|
|
char *driveAlias = NULL;
|
2011-05-04 12:09:09 +00:00
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
2013-01-24 14:14:14 +00:00
|
|
|
int retries = CHANGE_MEDIA_RETRIES;
|
2013-01-10 21:03:14 +00:00
|
|
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
if (!origdisk->info.alias) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("missing disk device alias name for %s"), origdisk->dst);
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (origdisk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY &&
|
|
|
|
origdisk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Removable media not supported for %s device"),
|
2013-01-24 14:14:14 +00:00
|
|
|
virDomainDiskDeviceTypeToString(disk->device));
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
|
2012-09-17 13:36:47 +00:00
|
|
|
vm, disk) < 0)
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-10-26 14:04:46 +00:00
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerSetImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, disk) < 0) {
|
2010-10-26 14:04:46 +00:00
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on %s", disk->src);
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-10-26 14:04:46 +00:00
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, priv->qemuCaps)))
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-01-24 14:14:14 +00:00
|
|
|
ret = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
|
2013-05-20 17:26:14 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2013-01-24 14:14:14 +00:00
|
|
|
|
2013-05-20 17:26:14 +00:00
|
|
|
virObjectRef(vm);
|
2013-01-24 14:14:14 +00:00
|
|
|
/* we don't want to report errors from media tray_open polling */
|
2013-05-28 14:23:00 +00:00
|
|
|
while (retries) {
|
2013-01-24 14:14:14 +00:00
|
|
|
if (origdisk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)
|
|
|
|
break;
|
|
|
|
|
2013-05-28 14:23:00 +00:00
|
|
|
retries--;
|
2013-05-20 17:26:14 +00:00
|
|
|
virObjectUnlock(vm);
|
2013-01-24 14:14:14 +00:00
|
|
|
VIR_DEBUG("Waiting 500ms for tray to open. Retries left %d", retries);
|
|
|
|
usleep(500 * 1000); /* sleep 500ms */
|
2013-05-20 17:26:14 +00:00
|
|
|
virObjectLock(vm);
|
2013-01-24 14:14:14 +00:00
|
|
|
}
|
2013-05-20 17:26:14 +00:00
|
|
|
virObjectUnref(vm);
|
2013-01-24 14:14:14 +00:00
|
|
|
|
2013-05-28 14:23:00 +00:00
|
|
|
if (retries <= 0) {
|
|
|
|
if (ret == 0) {
|
|
|
|
/* If ret == -1, EjectMedia already set an error message */
|
2013-01-24 14:14:14 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
2013-05-28 14:23:00 +00:00
|
|
|
_("Unable to eject media"));
|
2013-01-24 14:14:14 +00:00
|
|
|
}
|
2013-05-28 14:23:00 +00:00
|
|
|
goto audit;
|
|
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
if (disk->src) {
|
|
|
|
/* deliberately don't depend on 'ret' as 'eject' may have failed the
|
|
|
|
* first time and we are going to check the drive state anyway */
|
|
|
|
const char *format = NULL;
|
2013-01-24 14:14:14 +00:00
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
if (disk->type != VIR_DOMAIN_DISK_TYPE_DIR) {
|
2012-10-15 21:47:42 +00:00
|
|
|
if (disk->format > 0)
|
|
|
|
format = virStorageFileFormatTypeToString(disk->format);
|
|
|
|
else if (origdisk->format > 0)
|
|
|
|
format = virStorageFileFormatTypeToString(origdisk->format);
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
2013-05-20 17:26:14 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
ret = qemuMonitorChangeMedia(priv->mon,
|
|
|
|
driveAlias,
|
|
|
|
disk->src, format);
|
2013-05-20 17:26:14 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
2013-05-20 17:26:14 +00:00
|
|
|
audit:
|
2011-08-22 19:49:10 +00:00
|
|
|
virDomainAuditDisk(vm, origdisk->src, disk->src, "update", ret >= 0);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, origdisk) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_WARN("Unable to restore security label on ejected image %s", origdisk->src);
|
|
|
|
|
2010-10-26 14:04:46 +00:00
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, origdisk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on disk %s", origdisk->src);
|
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_FREE(origdisk->src);
|
|
|
|
origdisk->src = disk->src;
|
|
|
|
disk->src = NULL;
|
|
|
|
origdisk->type = disk->type;
|
|
|
|
|
|
|
|
|
|
|
|
virDomainDiskDefFree(disk);
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
cleanup:
|
|
|
|
VIR_FREE(driveAlias);
|
|
|
|
virObjectUnref(cfg);
|
2010-12-16 16:10:54 +00:00
|
|
|
return ret;
|
|
|
|
|
|
|
|
error:
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, disk) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_WARN("Unable to restore security label on new media %s", disk->src);
|
2010-10-26 14:04:46 +00:00
|
|
|
|
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on %s", disk->src);
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2011-09-13 13:49:50 +00:00
|
|
|
int
|
2012-11-28 16:43:10 +00:00
|
|
|
qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
|
2012-04-02 13:55:08 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
enum qemuDomainAsyncJob asyncJob)
|
2011-09-13 13:49:50 +00:00
|
|
|
{
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
2012-04-02 13:55:08 +00:00
|
|
|
virHashTablePtr table = NULL;
|
2011-09-13 13:49:50 +00:00
|
|
|
int ret = -1;
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2011-09-13 13:49:50 +00:00
|
|
|
|
2012-04-02 13:55:08 +00:00
|
|
|
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
|
|
|
|
table = qemuMonitorGetBlockInfo(priv->mon);
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2012-04-02 13:55:08 +00:00
|
|
|
}
|
2012-01-18 21:01:30 +00:00
|
|
|
|
|
|
|
if (!table)
|
|
|
|
goto cleanup;
|
|
|
|
|
2011-09-13 13:49:50 +00:00
|
|
|
for (i = 0; i < vm->def->ndisks; i++) {
|
|
|
|
virDomainDiskDefPtr disk = vm->def->disks[i];
|
2012-01-18 21:01:30 +00:00
|
|
|
struct qemuDomainDiskInfo *info;
|
2011-09-13 13:49:50 +00:00
|
|
|
|
qemu: add new disk device='lun' for bus='virtio' & type='block'
In the past, generic SCSI commands issued from a guest to a virtio
disk were always passed through to the underlying disk by qemu, and
the kernel would also pass them on.
As a result of CVE-2011-4127 (see:
http://seclists.org/oss-sec/2011/q4/536), qemu now honors its
scsi=on|off device option for virtio-blk-pci (which enables/disables
passthrough of generic SCSI commands), and the kernel will only allow
the commands for physical devices (not for partitions or logical
volumes). The default behavior of qemu is still to allow sending
generic SCSI commands to physical disks that are presented to a guest
as virtio-blk-pci devices, but libvirt prefers to disable those
commands in the standard virtio block devices, enabling it only when
specifically requested (hopefully indicating that the requester
understands what they're asking for). For this purpose, a new libvirt
disk device type (device='lun') has been created.
device='lun' is identical to the default device='disk', except that:
1) It is only allowed if bus='virtio', type='block', and the qemu
version is "new enough" to support it ("new enough" == qemu 0.11 or
better), otherwise the domain will fail to start and a
CONFIG_UNSUPPORTED error will be logged).
2) The option "scsi=on" will be added to the -device arg to allow
SG_IO commands (if device !='lun', "scsi=off" will be added to the
-device arg so that SG_IO commands are specifically forbidden).
Guests which continue to use disk device='disk' (the default) will no
longer be able to use SG_IO commands on the disk; those that have
their disk device changed to device='lun' will still be able to use SG_IO
commands.
*docs/formatdomain.html.in - document the new device attribute value.
*docs/schemas/domaincommon.rng - allow it in the RNG
*tests/* - update the args of several existing tests to add scsi=off, and
add one new test that will test scsi=on.
*src/conf/domain_conf.c - update domain XML parser and formatter
*src/qemu/qemu_(command|driver|hotplug).c - treat
VIR_DOMAIN_DISK_DEVICE_LUN *almost* identically to
VIR_DOMAIN_DISK_DEVICE_DISK, except as indicated above.
Note that no support for this new device value was added to any
hypervisor drivers other than qemu, because it's unclear what it might
mean (if anything) to those drivers.
2012-01-05 03:48:38 +00:00
|
|
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
|
|
|
|
disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
|
2011-09-13 13:49:50 +00:00
|
|
|
continue;
|
qemu: add new disk device='lun' for bus='virtio' & type='block'
In the past, generic SCSI commands issued from a guest to a virtio
disk were always passed through to the underlying disk by qemu, and
the kernel would also pass them on.
As a result of CVE-2011-4127 (see:
http://seclists.org/oss-sec/2011/q4/536), qemu now honors its
scsi=on|off device option for virtio-blk-pci (which enables/disables
passthrough of generic SCSI commands), and the kernel will only allow
the commands for physical devices (not for partitions or logical
volumes). The default behavior of qemu is still to allow sending
generic SCSI commands to physical disks that are presented to a guest
as virtio-blk-pci devices, but libvirt prefers to disable those
commands in the standard virtio block devices, enabling it only when
specifically requested (hopefully indicating that the requester
understands what they're asking for). For this purpose, a new libvirt
disk device type (device='lun') has been created.
device='lun' is identical to the default device='disk', except that:
1) It is only allowed if bus='virtio', type='block', and the qemu
version is "new enough" to support it ("new enough" == qemu 0.11 or
better), otherwise the domain will fail to start and a
CONFIG_UNSUPPORTED error will be logged).
2) The option "scsi=on" will be added to the -device arg to allow
SG_IO commands (if device !='lun', "scsi=off" will be added to the
-device arg so that SG_IO commands are specifically forbidden).
Guests which continue to use disk device='disk' (the default) will no
longer be able to use SG_IO commands on the disk; those that have
their disk device changed to device='lun' will still be able to use SG_IO
commands.
*docs/formatdomain.html.in - document the new device attribute value.
*docs/schemas/domaincommon.rng - allow it in the RNG
*tests/* - update the args of several existing tests to add scsi=off, and
add one new test that will test scsi=on.
*src/conf/domain_conf.c - update domain XML parser and formatter
*src/qemu/qemu_(command|driver|hotplug).c - treat
VIR_DOMAIN_DISK_DEVICE_LUN *almost* identically to
VIR_DOMAIN_DISK_DEVICE_DISK, except as indicated above.
Note that no support for this new device value was added to any
hypervisor drivers other than qemu, because it's unclear what it might
mean (if anything) to those drivers.
2012-01-05 03:48:38 +00:00
|
|
|
}
|
2011-09-13 13:49:50 +00:00
|
|
|
|
2012-01-18 21:01:30 +00:00
|
|
|
info = qemuMonitorBlockInfoLookup(table, disk->info.alias);
|
|
|
|
if (!info)
|
2011-09-13 13:49:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2012-01-18 21:01:30 +00:00
|
|
|
if (info->tray_open && disk->src)
|
2011-09-13 13:49:50 +00:00
|
|
|
VIR_FREE(disk->src);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2012-01-18 21:01:30 +00:00
|
|
|
virHashFree(table);
|
2011-09-13 13:49:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-03-05 15:44:22 +00:00
|
|
|
int qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
|
|
|
|
virQEMUDriverPtr driver,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainDiskDefPtr disk)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int ret = -1;
|
2010-12-16 16:10:54 +00:00
|
|
|
const char* type = virDomainDiskBusTypeToString(disk->bus);
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
char *devstr = NULL;
|
|
|
|
char *drivestr = NULL;
|
2011-04-26 03:40:01 +00:00
|
|
|
bool releaseaddr = false;
|
2013-01-10 21:03:14 +00:00
|
|
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-03-05 15:44:22 +00:00
|
|
|
if (!disk->info.type) {
|
|
|
|
if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW))
|
|
|
|
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
|
|
|
|
else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390))
|
|
|
|
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390;
|
|
|
|
}
|
|
|
|
|
2013-05-21 07:21:20 +00:00
|
|
|
for (i = 0; i < vm->def->ndisks; i++) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("target %s already exists"), disk->dst);
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
|
2012-09-17 13:36:47 +00:00
|
|
|
vm, disk) < 0)
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-10-26 14:04:46 +00:00
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerSetImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, disk) < 0) {
|
2010-10-26 14:04:46 +00:00
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on %s", disk->src);
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-10-26 14:04:46 +00:00
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2013-03-05 15:44:22 +00:00
|
|
|
if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
|
|
|
|
if (qemuDomainCCWAddressAssign(&disk->info, priv->ccwaddrs,
|
|
|
|
!disk->info.addr.ccw.assigned) < 0)
|
|
|
|
goto error;
|
2013-03-22 09:25:42 +00:00
|
|
|
} else if (!disk->info.type ||
|
|
|
|
disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
2013-03-05 15:44:22 +00:00
|
|
|
if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0)
|
|
|
|
goto error;
|
|
|
|
}
|
2011-04-26 03:40:01 +00:00
|
|
|
releaseaddr = true;
|
2013-02-01 13:48:58 +00:00
|
|
|
if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps)))
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!(devstr = qemuBuildDriveDevStr(NULL, disk, 0, priv->qemuCaps)))
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
ret = qemuMonitorAddDrive(priv->mon, drivestr);
|
|
|
|
if (ret == 0) {
|
|
|
|
ret = qemuMonitorAddDevice(priv->mon, devstr);
|
|
|
|
if (ret < 0) {
|
2012-09-20 20:28:35 +00:00
|
|
|
virErrorPtr orig_err = virSaveLastError();
|
|
|
|
if (qemuMonitorDriveDel(priv->mon, drivestr) < 0) {
|
|
|
|
VIR_WARN("Unable to remove drive %s (%s) after failed "
|
|
|
|
"qemuMonitorAddDevice",
|
|
|
|
drivestr, devstr);
|
|
|
|
}
|
|
|
|
if (orig_err) {
|
|
|
|
virSetError(orig_err);
|
|
|
|
virFreeError(orig_err);
|
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
}
|
2013-03-22 09:25:42 +00:00
|
|
|
} else if (!disk->info.type ||
|
|
|
|
disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
2012-08-16 15:41:06 +00:00
|
|
|
virDevicePCIAddress guestAddr = disk->info.addr.pci;
|
2010-12-16 16:10:54 +00:00
|
|
|
ret = qemuMonitorAddPCIDisk(priv->mon,
|
|
|
|
disk->src,
|
|
|
|
type,
|
|
|
|
&guestAddr);
|
2013-03-22 09:25:42 +00:00
|
|
|
if (ret == 0) {
|
|
|
|
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
2010-12-16 16:10:54 +00:00
|
|
|
memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
|
2013-03-22 09:25:42 +00:00
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2011-08-22 19:49:10 +00:00
|
|
|
virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
virDomainDiskInsertPreAlloced(vm->def, disk);
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
cleanup:
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_FREE(devstr);
|
|
|
|
VIR_FREE(drivestr);
|
2013-01-10 21:03:14 +00:00
|
|
|
virObjectUnref(cfg);
|
|
|
|
return ret;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
error:
|
2013-03-05 15:44:22 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && releaseaddr) {
|
|
|
|
if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
|
|
|
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
|
|
|
&disk->info.addr.pci) < 0)
|
|
|
|
VIR_WARN("Unable to release PCI address on %s", disk->src);
|
|
|
|
else if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
|
|
|
|
qemuDomainCCWAddressReleaseAddr(priv->ccwaddrs,
|
|
|
|
&disk->info) < 0)
|
|
|
|
VIR_WARN("Unable to release CCW address on %s", disk->src);
|
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, disk) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_WARN("Unable to restore security label on %s", disk->src);
|
|
|
|
|
2010-10-26 14:04:46 +00:00
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on %s", disk->src);
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainAttachPciControllerDevice(virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
virDomainControllerDefPtr controller)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
const char* type = virDomainControllerTypeToString(controller->type);
|
|
|
|
char *devstr = NULL;
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
2011-04-26 03:40:01 +00:00
|
|
|
bool releaseaddr = false;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2012-07-23 08:18:57 +00:00
|
|
|
if (virDomainControllerFind(vm->def, controller->type, controller->idx) > 0) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("target %s:%d already exists"),
|
|
|
|
type, controller->idx);
|
|
|
|
return -1;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0)
|
|
|
|
goto cleanup;
|
2011-04-26 03:40:01 +00:00
|
|
|
releaseaddr = true;
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuAssignDeviceControllerAlias(controller) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2011-09-02 13:21:23 +00:00
|
|
|
if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
|
|
|
|
controller->model == -1 &&
|
2013-02-01 13:48:58 +00:00
|
|
|
!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("USB controller hotplug unsupported in this QEMU binary"));
|
2011-09-02 13:21:23 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!(devstr = qemuBuildControllerDevStr(vm->def, controller, priv->qemuCaps, NULL))) {
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
ret = qemuMonitorAddDevice(priv->mon, devstr);
|
|
|
|
} else {
|
|
|
|
ret = qemuMonitorAttachPCIDiskController(priv->mon,
|
|
|
|
type,
|
|
|
|
&controller->info.addr.pci);
|
|
|
|
}
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
controller->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
|
|
|
virDomainControllerInsertPreAlloced(vm->def, controller);
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if ((ret != 0) &&
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
2010-12-16 16:10:54 +00:00
|
|
|
(controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
2011-04-26 03:40:01 +00:00
|
|
|
releaseaddr &&
|
2011-05-23 07:43:35 +00:00
|
|
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
2013-02-15 06:48:49 +00:00
|
|
|
&controller->info.addr.pci) < 0)
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_WARN("Unable to release PCI address on controller");
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
VIR_FREE(devstr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainControllerDefPtr
|
2012-11-28 16:43:10 +00:00
|
|
|
qemuDomainFindOrCreateSCSIDiskController(virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
int controller)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainControllerDefPtr cont;
|
2011-05-04 12:09:09 +00:00
|
|
|
|
2013-05-21 07:21:20 +00:00
|
|
|
for (i = 0; i < vm->def->ncontrollers; i++) {
|
2010-12-16 16:10:54 +00:00
|
|
|
cont = vm->def->controllers[i];
|
|
|
|
|
|
|
|
if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (cont->idx == controller)
|
|
|
|
return cont;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No SCSI controller present, for backward compatibility we
|
|
|
|
* now hotplug a controller */
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_ALLOC(cont) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
return NULL;
|
|
|
|
cont->type = VIR_DOMAIN_CONTROLLER_TYPE_SCSI;
|
2011-01-31 07:55:40 +00:00
|
|
|
cont->idx = controller;
|
2010-12-16 16:10:54 +00:00
|
|
|
cont->model = -1;
|
|
|
|
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_INFO("No SCSI controller present, hotplugging one");
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuDomainAttachPciControllerDevice(driver,
|
2011-05-04 12:09:09 +00:00
|
|
|
vm, cont) < 0) {
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_FREE(cont);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virDomainObjIsActive(vm)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("guest unexpectedly quit"));
|
2010-12-16 16:10:54 +00:00
|
|
|
/* cont doesn't need freeing here, since the reference
|
|
|
|
* now held in def->controllers */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cont;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-31 19:06:23 +00:00
|
|
|
int qemuDomainAttachSCSIDisk(virConnectPtr conn,
|
2012-11-28 16:43:10 +00:00
|
|
|
virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
virDomainDiskDefPtr disk)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-12-16 16:10:54 +00:00
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
virDomainControllerDefPtr cont = NULL;
|
|
|
|
char *drivestr = NULL;
|
|
|
|
char *devstr = NULL;
|
|
|
|
int ret = -1;
|
2013-01-10 21:03:14 +00:00
|
|
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-05-21 07:21:20 +00:00
|
|
|
for (i = 0; i < vm->def->ndisks; i++) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("target %s already exists"), disk->dst);
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
|
2012-09-17 13:36:47 +00:00
|
|
|
vm, disk) < 0)
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerSetImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, disk) < 0) {
|
2010-10-26 14:04:46 +00:00
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on %s", disk->src);
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-10-26 14:04:46 +00:00
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
/* We should have an address already, so make sure */
|
|
|
|
if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected disk address type %s"),
|
|
|
|
virDomainDeviceAddressTypeToString(disk->info.type));
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
|
|
|
if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps)))
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-05-21 07:21:20 +00:00
|
|
|
for (i = 0; i <= disk->info.addr.drive.controller; i++) {
|
2011-05-04 12:09:09 +00:00
|
|
|
cont = qemuDomainFindOrCreateSCSIDiskController(driver, vm, i);
|
2010-12-16 16:10:54 +00:00
|
|
|
if (!cont)
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Tell clang that "cont" is non-NULL.
|
|
|
|
This is because disk->info.addr.driver.controller is unsigned,
|
|
|
|
and hence the above loop must iterate at least once. */
|
2012-10-17 09:23:12 +00:00
|
|
|
sa_assert(cont);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
if (cont->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("SCSI controller %d was missing its PCI address"), cont->idx);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
ret = qemuMonitorAddDrive(priv->mon, drivestr);
|
|
|
|
if (ret == 0) {
|
|
|
|
ret = qemuMonitorAddDevice(priv->mon, devstr);
|
|
|
|
if (ret < 0) {
|
|
|
|
VIR_WARN("qemuMonitorAddDevice failed on %s (%s)",
|
|
|
|
drivestr, devstr);
|
|
|
|
/* XXX should call 'drive_del' on error but this does not
|
|
|
|
exist yet */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
virDomainDeviceDriveAddress driveAddr;
|
|
|
|
ret = qemuMonitorAttachDrive(priv->mon,
|
|
|
|
drivestr,
|
|
|
|
&cont->info.addr.pci,
|
|
|
|
&driveAddr);
|
|
|
|
if (ret == 0) {
|
|
|
|
/* XXX we should probably validate that the addr matches
|
|
|
|
* our existing defined addr instead of overwriting */
|
|
|
|
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
|
2011-10-21 23:09:17 +00:00
|
|
|
disk->info.addr.drive.bus = driveAddr.bus;
|
|
|
|
disk->info.addr.drive.unit = driveAddr.unit;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
}
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2011-08-22 19:49:10 +00:00
|
|
|
virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
virDomainDiskInsertPreAlloced(vm->def, disk);
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
cleanup:
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_FREE(devstr);
|
|
|
|
VIR_FREE(drivestr);
|
2013-01-10 21:03:14 +00:00
|
|
|
virObjectUnref(cfg);
|
|
|
|
return ret;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
error:
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, disk) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_WARN("Unable to restore security label on %s", disk->src);
|
|
|
|
|
2010-10-26 14:04:46 +00:00
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on %s", disk->src);
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-31 19:06:23 +00:00
|
|
|
int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn,
|
2012-11-28 16:43:10 +00:00
|
|
|
virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
virDomainDiskDefPtr disk)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int ret = -1;
|
2010-12-16 16:10:54 +00:00
|
|
|
char *drivestr = NULL;
|
|
|
|
char *devstr = NULL;
|
2013-01-10 21:03:14 +00:00
|
|
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-05-21 07:21:20 +00:00
|
|
|
for (i = 0; i < vm->def->ndisks; i++) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("target %s already exists"), disk->dst);
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
|
2012-09-17 13:36:47 +00:00
|
|
|
vm, disk) < 0)
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-10-26 14:04:46 +00:00
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerSetImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, disk) < 0) {
|
2010-10-26 14:04:46 +00:00
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on %s", disk->src);
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-10-26 14:04:46 +00:00
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2010-10-26 14:04:46 +00:00
|
|
|
/* XXX not correct once we allow attaching a USB CDROM */
|
2010-12-16 16:10:54 +00:00
|
|
|
if (!disk->src) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("disk source path is missing"));
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
|
|
|
if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps)))
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!(devstr = qemuBuildDriveDevStr(NULL, disk, 0, priv->qemuCaps)))
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
ret = qemuMonitorAddDrive(priv->mon, drivestr);
|
|
|
|
if (ret == 0) {
|
|
|
|
ret = qemuMonitorAddDevice(priv->mon, devstr);
|
|
|
|
if (ret < 0) {
|
|
|
|
VIR_WARN("qemuMonitorAddDevice failed on %s (%s)",
|
|
|
|
drivestr, devstr);
|
|
|
|
/* XXX should call 'drive_del' on error but this does not
|
|
|
|
exist yet */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret = qemuMonitorAddUSBDisk(priv->mon, disk->src);
|
|
|
|
}
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2011-08-22 19:49:10 +00:00
|
|
|
virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
virDomainDiskInsertPreAlloced(vm->def, disk);
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
cleanup:
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_FREE(devstr);
|
|
|
|
VIR_FREE(drivestr);
|
2013-01-10 21:03:14 +00:00
|
|
|
virObjectUnref(cfg);
|
|
|
|
return ret;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
error:
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, disk) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_WARN("Unable to restore security label on %s", disk->src);
|
|
|
|
|
2010-10-26 14:04:46 +00:00
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on %s", disk->src);
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* XXX conn required for network -> bridge resolution */
|
|
|
|
int qemuDomainAttachNetDevice(virConnectPtr conn,
|
2012-11-28 16:43:10 +00:00
|
|
|
virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
virDomainNetDefPtr net)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
2013-05-21 13:50:09 +00:00
|
|
|
char **tapfdName = NULL;
|
|
|
|
int *tapfd = NULL;
|
|
|
|
int tapfdSize = 0;
|
|
|
|
char **vhostfdName = NULL;
|
|
|
|
int *vhostfd = NULL;
|
|
|
|
int vhostfdSize = 0;
|
2010-12-16 16:10:54 +00:00
|
|
|
char *nicstr = NULL;
|
|
|
|
char *netstr = NULL;
|
2012-02-10 21:09:00 +00:00
|
|
|
virNetDevVPortProfilePtr vport = NULL;
|
2010-12-16 16:10:54 +00:00
|
|
|
int ret = -1;
|
2012-08-16 15:41:06 +00:00
|
|
|
virDevicePCIAddress guestAddr;
|
2010-12-16 16:10:54 +00:00
|
|
|
int vlan;
|
2011-04-26 03:40:01 +00:00
|
|
|
bool releaseaddr = false;
|
2011-07-04 06:27:12 +00:00
|
|
|
bool iface_connected = false;
|
|
|
|
int actualType;
|
2013-01-10 21:03:14 +00:00
|
|
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
qemu: support type=hostdev network device live hotplug attach/detach
qemuDomainAttachNetDevice
- re-ordered some things at start of function because
networkAllocateActualDevice should always be run and a slot
in def->nets always allocated, but host_net_add isn't needed
if the actual type is hostdev.
- if actual type is hostdev, defer to
qemuDomainAttachHostDevice (which will reach up to the NetDef
for things like MAC address when necessary). After return
from qemuDomainAttachHostDevice, slip directly to cleanup,
since the rest of the function is specific to emulated net
devices.
- put assignment of new NetDef into expanded def->nets down
below cleanup: (but only on success) since it is also needed
for emulated and hostdev net devices.
qemuDomainDetachHostDevice
- after locating the exact device to detach, check if it's a
network device and, if so, use toplevel
qemuDomainDetachNetDevice instead so that the def->nets list
is properly updated, and 'actual device' properly returned to
network pool if appropriate. Otherwise, for normal hostdevs,
call the lower level qemuDomainDetachThisDevice.
qemuDomainDetachNetDevice
- This is where it gets a bit tricky. After locating the device
on the def->nets list, if the network device type == hostdev,
call the *lower level* qemuDomainDetachThisDevice (which will
reach back up to the parent net device for MAC address /
virtualport when appropriate, then clear the device out of
def->hostdevs) before skipping past all the emulated
net-device-specific code to cleanup:, where the network
device is removed from def->nets, and the network device
object is freed.
In short, any time a hostdev-type network device is detached, we must
go through the toplevel virDomaineDetachNetDevice function first and
last, to make sure 1) the def->nnets list is properly managed, and 2)
any device allocated with networkAllocateActualDevice is properly
freed. At the same time, in the middle we need to go through the
lower-level vidDomainDetach*This*HostDevice to be sure that 1) the
def->hostdevs list is properly managed, 2) the PCI device is properly
detached from the guest and reattached to the host (if appropriate),
and 3) any higher level teardown is called at the appropriate time, by
reaching back up to the NetDef config (part (3) will be covered in a
separate patch).
2012-02-27 19:20:17 +00:00
|
|
|
/* preallocate new slot for device */
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0)
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2011-07-04 06:27:12 +00:00
|
|
|
/* If appropriate, grab a physical device from the configured
|
|
|
|
* network's pool of devices, or resolve bridge device name
|
|
|
|
* to the one defined in the network definition.
|
|
|
|
*/
|
|
|
|
if (networkAllocateActualDevice(net) < 0)
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2011-07-04 06:27:12 +00:00
|
|
|
|
|
|
|
actualType = virDomainNetGetActualType(net);
|
qemu: support type=hostdev network device live hotplug attach/detach
qemuDomainAttachNetDevice
- re-ordered some things at start of function because
networkAllocateActualDevice should always be run and a slot
in def->nets always allocated, but host_net_add isn't needed
if the actual type is hostdev.
- if actual type is hostdev, defer to
qemuDomainAttachHostDevice (which will reach up to the NetDef
for things like MAC address when necessary). After return
from qemuDomainAttachHostDevice, slip directly to cleanup,
since the rest of the function is specific to emulated net
devices.
- put assignment of new NetDef into expanded def->nets down
below cleanup: (but only on success) since it is also needed
for emulated and hostdev net devices.
qemuDomainDetachHostDevice
- after locating the exact device to detach, check if it's a
network device and, if so, use toplevel
qemuDomainDetachNetDevice instead so that the def->nets list
is properly updated, and 'actual device' properly returned to
network pool if appropriate. Otherwise, for normal hostdevs,
call the lower level qemuDomainDetachThisDevice.
qemuDomainDetachNetDevice
- This is where it gets a bit tricky. After locating the device
on the def->nets list, if the network device type == hostdev,
call the *lower level* qemuDomainDetachThisDevice (which will
reach back up to the parent net device for MAC address /
virtualport when appropriate, then clear the device out of
def->hostdevs) before skipping past all the emulated
net-device-specific code to cleanup:, where the network
device is removed from def->nets, and the network device
object is freed.
In short, any time a hostdev-type network device is detached, we must
go through the toplevel virDomaineDetachNetDevice function first and
last, to make sure 1) the def->nnets list is properly managed, and 2)
any device allocated with networkAllocateActualDevice is properly
freed. At the same time, in the middle we need to go through the
lower-level vidDomainDetach*This*HostDevice to be sure that 1) the
def->hostdevs list is properly managed, 2) the PCI device is properly
detached from the guest and reattached to the host (if appropriate),
and 3) any higher level teardown is called at the appropriate time, by
reaching back up to the NetDef config (part (3) will be covered in a
separate patch).
2012-02-27 19:20:17 +00:00
|
|
|
|
|
|
|
if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
|
|
|
|
/* This is really a "smart hostdev", so it should be attached
|
|
|
|
* as a hostdev (the hostdev code will reach over into the
|
|
|
|
* netdev-specific code as appropriate), then also added to
|
|
|
|
* the nets list (see cleanup:) if successful.
|
|
|
|
*/
|
|
|
|
ret = qemuDomainAttachHostDevice(driver, vm,
|
|
|
|
virDomainNetGetActualHostdev(net));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_HOST_NET_ADD)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("installed qemu version does not support host_net_add"));
|
qemu: support type=hostdev network device live hotplug attach/detach
qemuDomainAttachNetDevice
- re-ordered some things at start of function because
networkAllocateActualDevice should always be run and a slot
in def->nets always allocated, but host_net_add isn't needed
if the actual type is hostdev.
- if actual type is hostdev, defer to
qemuDomainAttachHostDevice (which will reach up to the NetDef
for things like MAC address when necessary). After return
from qemuDomainAttachHostDevice, slip directly to cleanup,
since the rest of the function is specific to emulated net
devices.
- put assignment of new NetDef into expanded def->nets down
below cleanup: (but only on success) since it is also needed
for emulated and hostdev net devices.
qemuDomainDetachHostDevice
- after locating the exact device to detach, check if it's a
network device and, if so, use toplevel
qemuDomainDetachNetDevice instead so that the def->nets list
is properly updated, and 'actual device' properly returned to
network pool if appropriate. Otherwise, for normal hostdevs,
call the lower level qemuDomainDetachThisDevice.
qemuDomainDetachNetDevice
- This is where it gets a bit tricky. After locating the device
on the def->nets list, if the network device type == hostdev,
call the *lower level* qemuDomainDetachThisDevice (which will
reach back up to the parent net device for MAC address /
virtualport when appropriate, then clear the device out of
def->hostdevs) before skipping past all the emulated
net-device-specific code to cleanup:, where the network
device is removed from def->nets, and the network device
object is freed.
In short, any time a hostdev-type network device is detached, we must
go through the toplevel virDomaineDetachNetDevice function first and
last, to make sure 1) the def->nnets list is properly managed, and 2)
any device allocated with networkAllocateActualDevice is properly
freed. At the same time, in the middle we need to go through the
lower-level vidDomainDetach*This*HostDevice to be sure that 1) the
def->hostdevs list is properly managed, 2) the PCI device is properly
detached from the guest and reattached to the host (if appropriate),
and 3) any higher level teardown is called at the appropriate time, by
reaching back up to the NetDef config (part (3) will be covered in a
separate patch).
2012-02-27 19:20:17 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-04-18 08:47:01 +00:00
|
|
|
/* Currently nothing besides TAP devices supports multiqueue. */
|
|
|
|
if (net->driver.virtio.queues > 0 &&
|
|
|
|
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
|
|
|
|
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("Multiqueue network is not supported for: %s"),
|
|
|
|
virDomainNetTypeToString(actualType));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-07-04 01:57:45 +00:00
|
|
|
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
|
|
|
|
actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
|
2013-04-18 08:47:01 +00:00
|
|
|
tapfdSize = vhostfdSize = net->driver.virtio.queues;
|
|
|
|
if (!tapfdSize)
|
|
|
|
tapfdSize = vhostfdSize = 1;
|
|
|
|
if (VIR_ALLOC_N(tapfd, tapfdSize) < 0 ||
|
2013-07-04 10:14:12 +00:00
|
|
|
VIR_ALLOC_N(vhostfd, vhostfdSize) < 0)
|
2013-05-21 13:50:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
if (qemuNetworkIfaceConnect(vm->def, conn, driver, net,
|
|
|
|
priv->qemuCaps, tapfd, &tapfdSize) < 0)
|
2013-04-20 09:11:25 +00:00
|
|
|
goto cleanup;
|
|
|
|
iface_connected = true;
|
2013-05-21 13:50:09 +00:00
|
|
|
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
|
2013-04-20 09:11:25 +00:00
|
|
|
goto cleanup;
|
2011-07-04 01:57:45 +00:00
|
|
|
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
|
2013-04-18 08:47:01 +00:00
|
|
|
tapfdSize = vhostfdSize = 1;
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_ALLOC(tapfd) < 0 || VIR_ALLOC(vhostfd) < 0)
|
2013-05-21 13:50:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
if ((tapfd[0] = qemuPhysIfaceConnect(vm->def, driver, net,
|
|
|
|
priv->qemuCaps,
|
|
|
|
VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0)
|
2011-07-04 06:27:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
iface_connected = true;
|
2013-05-21 13:50:09 +00:00
|
|
|
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
|
2011-03-09 04:43:33 +00:00
|
|
|
goto cleanup;
|
2013-02-08 17:19:09 +00:00
|
|
|
} else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
|
2013-04-18 08:47:01 +00:00
|
|
|
vhostfdSize = 1;
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_ALLOC(vhostfd) < 0)
|
2013-05-21 13:50:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
|
2013-02-08 17:19:09 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NET_NAME) ||
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-03-05 15:44:22 +00:00
|
|
|
if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
|
|
|
|
net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
|
|
|
|
if (qemuDomainCCWAddressAssign(&net->info, priv->ccwaddrs,
|
|
|
|
!net->info.addr.ccw.assigned) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
} else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390))
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("virtio-s390 net device cannot be hotplugged."));
|
|
|
|
else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
|
|
|
qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0)
|
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2011-04-26 03:40:01 +00:00
|
|
|
releaseaddr = true;
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
vlan = -1;
|
|
|
|
} else {
|
|
|
|
vlan = qemuDomainNetVLAN(net);
|
|
|
|
|
|
|
|
if (vlan < 0) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("Unable to attach network devices without vlan"));
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-21 13:50:09 +00:00
|
|
|
if (VIR_ALLOC_N(tapfdName, tapfdSize) < 0 ||
|
2013-07-04 10:14:12 +00:00
|
|
|
VIR_ALLOC_N(vhostfdName, vhostfdSize) < 0)
|
2013-05-21 13:50:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < tapfdSize; i++) {
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (virAsprintf(&tapfdName[i], "fd-%s%zu", net->info.alias, i) < 0)
|
2013-07-04 10:14:12 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2013-05-21 13:50:09 +00:00
|
|
|
for (i = 0; i < vhostfdSize; i++) {
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (virAsprintf(&vhostfdName[i], "vhostfd-%s%zu", net->info.alias, i) < 0)
|
2013-07-04 10:14:12 +00:00
|
|
|
goto cleanup;
|
2011-03-09 04:43:33 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2013-04-20 09:11:25 +00:00
|
|
|
if (!(netstr = qemuBuildHostNetStr(net, driver,
|
2013-05-21 13:50:09 +00:00
|
|
|
',', -1,
|
|
|
|
tapfdName, tapfdSize,
|
|
|
|
vhostfdName, vhostfdSize)))
|
2011-03-16 02:21:45 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
} else {
|
2013-04-20 09:11:25 +00:00
|
|
|
if (!(netstr = qemuBuildHostNetStr(net, driver,
|
2013-05-21 13:50:09 +00:00
|
|
|
' ', vlan,
|
|
|
|
tapfdName, tapfdSize,
|
|
|
|
vhostfdName, vhostfdSize)))
|
2011-03-16 02:21:45 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2013-05-21 13:50:09 +00:00
|
|
|
if (qemuMonitorAddNetdev(priv->mon, netstr,
|
|
|
|
tapfd, tapfdName, tapfdSize,
|
|
|
|
vhostfd, vhostfdName, vhostfdSize) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
Move qemu_audit.h helpers into shared code
The LXC and UML drivers can both make use of auditing. Move
the qemu_audit.{c,h} files to src/conf/domain_audit.{c,h}
* src/conf/domain_audit.c: Rename from src/qemu/qemu_audit.c
* src/conf/domain_audit.h: Rename from src/qemu/qemu_audit.h
* src/Makefile.am: Remove qemu_audit.{c,h}, add domain_audit.{c,h}
* src/qemu/qemu_audit.h, src/qemu/qemu_cgroup.c,
src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c,
src/qemu/qemu_process.c: Update for changed audit API names
2011-07-04 10:56:13 +00:00
|
|
|
virDomainAuditNet(vm, NULL, net, "attach", false);
|
2011-03-16 02:21:45 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
} else {
|
2013-05-21 13:50:09 +00:00
|
|
|
if (qemuMonitorAddHostNetwork(priv->mon, netstr,
|
|
|
|
tapfd, tapfdName, tapfdSize,
|
|
|
|
vhostfd, vhostfdName, vhostfdSize) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
Move qemu_audit.h helpers into shared code
The LXC and UML drivers can both make use of auditing. Move
the qemu_audit.{c,h} files to src/conf/domain_audit.{c,h}
* src/conf/domain_audit.c: Rename from src/qemu/qemu_audit.c
* src/conf/domain_audit.h: Rename from src/qemu/qemu_audit.h
* src/Makefile.am: Remove qemu_audit.{c,h}, add domain_audit.{c,h}
* src/qemu/qemu_audit.h, src/qemu/qemu_cgroup.c,
src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c,
src/qemu/qemu_process.c: Update for changed audit API names
2011-07-04 10:56:13 +00:00
|
|
|
virDomainAuditNet(vm, NULL, net, "attach", false);
|
2011-03-16 02:21:45 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
}
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-05-21 13:50:09 +00:00
|
|
|
for (i = 0; i < tapfdSize; i++)
|
|
|
|
VIR_FORCE_CLOSE(tapfd[i]);
|
|
|
|
for (i = 0; i < vhostfdSize; i++)
|
|
|
|
VIR_FORCE_CLOSE(vhostfd[i]);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
if (!virDomainObjIsActive(vm)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("guest unexpectedly quit"));
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
|
|
|
if (!(nicstr = qemuBuildNicDevStr(net, vlan, 0, priv->qemuCaps)))
|
2010-12-16 16:10:54 +00:00
|
|
|
goto try_remove;
|
|
|
|
} else {
|
|
|
|
if (!(nicstr = qemuBuildNicStr(net, NULL, vlan)))
|
|
|
|
goto try_remove;
|
|
|
|
}
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
Move qemu_audit.h helpers into shared code
The LXC and UML drivers can both make use of auditing. Move
the qemu_audit.{c,h} files to src/conf/domain_audit.{c,h}
* src/conf/domain_audit.c: Rename from src/qemu/qemu_audit.c
* src/conf/domain_audit.h: Rename from src/qemu/qemu_audit.h
* src/Makefile.am: Remove qemu_audit.{c,h}, add domain_audit.{c,h}
* src/qemu/qemu_audit.h, src/qemu/qemu_cgroup.c,
src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c,
src/qemu/qemu_process.c: Update for changed audit API names
2011-07-04 10:56:13 +00:00
|
|
|
virDomainAuditNet(vm, NULL, net, "attach", false);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto try_remove;
|
|
|
|
}
|
|
|
|
} else {
|
2011-10-26 23:40:12 +00:00
|
|
|
guestAddr = net->info.addr.pci;
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuMonitorAddPCINetwork(priv->mon, nicstr,
|
|
|
|
&guestAddr) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
Move qemu_audit.h helpers into shared code
The LXC and UML drivers can both make use of auditing. Move
the qemu_audit.{c,h} files to src/conf/domain_audit.{c,h}
* src/conf/domain_audit.c: Rename from src/qemu/qemu_audit.c
* src/conf/domain_audit.h: Rename from src/qemu/qemu_audit.h
* src/Makefile.am: Remove qemu_audit.{c,h}, add domain_audit.{c,h}
* src/qemu/qemu_audit.h, src/qemu/qemu_cgroup.c,
src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c,
src/qemu/qemu_process.c: Update for changed audit API names
2011-07-04 10:56:13 +00:00
|
|
|
virDomainAuditNet(vm, NULL, net, "attach", false);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto try_remove;
|
|
|
|
}
|
|
|
|
net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
|
|
|
memcpy(&net->info.addr.pci, &guestAddr, sizeof(guestAddr));
|
|
|
|
}
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2011-09-06 08:23:47 +00:00
|
|
|
/* set link state */
|
|
|
|
if (net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) {
|
|
|
|
if (!net->info.alias) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("device alias not found: cannot set link state to down"));
|
2011-09-06 08:23:47 +00:00
|
|
|
} else {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2011-09-06 08:23:47 +00:00
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) {
|
2011-09-06 08:23:47 +00:00
|
|
|
if (qemuMonitorSetLink(priv->mon, net->info.alias, VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2011-09-06 08:23:47 +00:00
|
|
|
virDomainAuditNet(vm, NULL, net, "attach", false);
|
|
|
|
goto try_remove;
|
|
|
|
}
|
|
|
|
} else {
|
maint: don't permit format strings without %
Any time we have a string with no % passed through gettext, a
translator can inject a % to cause a stack overread. When there
is nothing to format, it's easier to ask for a string that cannot
be used as a formatter, by using a trivial "%s" format instead.
In the past, we have used --disable-nls to catch some of the
offenders, but that doesn't get run very often, and many more
uses have crept in. Syntax check to the rescue!
The syntax check can catch uses such as
virReportError(code,
_("split "
"string"));
by using a sed script to fold context lines into one pattern
space before checking for a string without %.
This patch is just mechanical insertion of %s; there are probably
several messages touched by this patch where we would be better
off giving the user more information than a fixed string.
* cfg.mk (sc_prohibit_diagnostic_without_format): New rule.
* src/datatypes.c (virUnrefConnect, virGetDomain)
(virUnrefDomain, virGetNetwork, virUnrefNetwork, virGetInterface)
(virUnrefInterface, virGetStoragePool, virUnrefStoragePool)
(virGetStorageVol, virUnrefStorageVol, virGetNodeDevice)
(virGetSecret, virUnrefSecret, virGetNWFilter, virUnrefNWFilter)
(virGetDomainSnapshot, virUnrefDomainSnapshot): Add %s wrapper.
* src/lxc/lxc_driver.c (lxcDomainSetBlkioParameters)
(lxcDomainGetBlkioParameters): Likewise.
* src/conf/domain_conf.c (virSecurityDeviceLabelDefParseXML)
(virDomainDiskDefParseXML, virDomainGraphicsDefParseXML):
Likewise.
* src/conf/network_conf.c (virNetworkDNSHostsDefParseXML)
(virNetworkDefParseXML): Likewise.
* src/conf/nwfilter_conf.c (virNWFilterIsValidChainName):
Likewise.
* src/conf/nwfilter_params.c (virNWFilterVarValueCreateSimple)
(virNWFilterVarAccessParse): Likewise.
* src/libvirt.c (virDomainSave, virDomainSaveFlags)
(virDomainRestore, virDomainRestoreFlags)
(virDomainSaveImageGetXMLDesc, virDomainSaveImageDefineXML)
(virDomainCoreDump, virDomainGetXMLDesc)
(virDomainMigrateVersion1, virDomainMigrateVersion2)
(virDomainMigrateVersion3, virDomainMigrate, virDomainMigrate2)
(virStreamSendAll, virStreamRecvAll)
(virDomainSnapshotGetXMLDesc): Likewise.
* src/nwfilter/nwfilter_dhcpsnoop.c (virNWFilterSnoopReqLeaseDel)
(virNWFilterDHCPSnoopReq): Likewise.
* src/openvz/openvz_driver.c (openvzUpdateDevice): Likewise.
* src/openvz/openvz_util.c (openvzKBPerPages): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupCgroup): Likewise.
* src/qemu/qemu_command.c (qemuBuildHubDevStr, qemuBuildChrChardevStr)
(qemuBuildCommandLine): Likewise.
* src/qemu/qemu_driver.c (qemuDomainGetPercpuStats): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/rpc/virnetsaslcontext.c (virNetSASLSessionGetIdentity):
Likewise.
* src/rpc/virnetsocket.c (virNetSocketNewConnectUNIX)
(virNetSocketSendFD, virNetSocketRecvFD): Likewise.
* src/storage/storage_backend_disk.c
(virStorageBackendDiskBuildPool): Likewise.
* src/storage/storage_backend_fs.c
(virStorageBackendFileSystemProbe)
(virStorageBackendFileSystemBuild): Likewise.
* src/storage/storage_backend_rbd.c
(virStorageBackendRBDOpenRADOSConn): Likewise.
* src/storage/storage_driver.c (storageVolumeResize): Likewise.
* src/test/test_driver.c (testInterfaceChangeBegin)
(testInterfaceChangeCommit, testInterfaceChangeRollback):
Likewise.
* src/vbox/vbox_tmpl.c (vboxListAllDomains): Likewise.
* src/xenxs/xen_sxpr.c (xenFormatSxprDisk, xenFormatSxpr):
Likewise.
* src/xenxs/xen_xm.c (xenXMConfigGetUUID, xenFormatXMDisk)
(xenFormatXM): Likewise.
2012-07-23 20:33:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
2012-07-18 15:22:03 +00:00
|
|
|
_("setting of link state not supported: Link is up"));
|
2011-09-06 08:23:47 +00:00
|
|
|
}
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2011-09-06 08:23:47 +00:00
|
|
|
}
|
|
|
|
/* link set to down */
|
|
|
|
}
|
|
|
|
|
Move qemu_audit.h helpers into shared code
The LXC and UML drivers can both make use of auditing. Move
the qemu_audit.{c,h} files to src/conf/domain_audit.{c,h}
* src/conf/domain_audit.c: Rename from src/qemu/qemu_audit.c
* src/conf/domain_audit.h: Rename from src/qemu/qemu_audit.h
* src/Makefile.am: Remove qemu_audit.{c,h}, add domain_audit.{c,h}
* src/qemu/qemu_audit.h, src/qemu/qemu_cgroup.c,
src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c,
src/qemu/qemu_process.c: Update for changed audit API names
2011-07-04 10:56:13 +00:00
|
|
|
virDomainAuditNet(vm, NULL, net, "attach", true);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
qemu: support type=hostdev network device live hotplug attach/detach
qemuDomainAttachNetDevice
- re-ordered some things at start of function because
networkAllocateActualDevice should always be run and a slot
in def->nets always allocated, but host_net_add isn't needed
if the actual type is hostdev.
- if actual type is hostdev, defer to
qemuDomainAttachHostDevice (which will reach up to the NetDef
for things like MAC address when necessary). After return
from qemuDomainAttachHostDevice, slip directly to cleanup,
since the rest of the function is specific to emulated net
devices.
- put assignment of new NetDef into expanded def->nets down
below cleanup: (but only on success) since it is also needed
for emulated and hostdev net devices.
qemuDomainDetachHostDevice
- after locating the exact device to detach, check if it's a
network device and, if so, use toplevel
qemuDomainDetachNetDevice instead so that the def->nets list
is properly updated, and 'actual device' properly returned to
network pool if appropriate. Otherwise, for normal hostdevs,
call the lower level qemuDomainDetachThisDevice.
qemuDomainDetachNetDevice
- This is where it gets a bit tricky. After locating the device
on the def->nets list, if the network device type == hostdev,
call the *lower level* qemuDomainDetachThisDevice (which will
reach back up to the parent net device for MAC address /
virtualport when appropriate, then clear the device out of
def->hostdevs) before skipping past all the emulated
net-device-specific code to cleanup:, where the network
device is removed from def->nets, and the network device
object is freed.
In short, any time a hostdev-type network device is detached, we must
go through the toplevel virDomaineDetachNetDevice function first and
last, to make sure 1) the def->nnets list is properly managed, and 2)
any device allocated with networkAllocateActualDevice is properly
freed. At the same time, in the middle we need to go through the
lower-level vidDomainDetach*This*HostDevice to be sure that 1) the
def->hostdevs list is properly managed, 2) the PCI device is properly
detached from the guest and reattached to the host (if appropriate),
and 3) any higher level teardown is called at the appropriate time, by
reaching back up to the NetDef config (part (3) will be covered in a
separate patch).
2012-02-27 19:20:17 +00:00
|
|
|
if (!ret) {
|
|
|
|
vm->def->nets[vm->def->nnets++] = net;
|
|
|
|
} else {
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
2013-03-05 15:44:22 +00:00
|
|
|
net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
|
2011-07-04 06:27:12 +00:00
|
|
|
releaseaddr &&
|
|
|
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
2013-02-15 06:48:49 +00:00
|
|
|
&net->info.addr.pci) < 0)
|
2011-07-04 06:27:12 +00:00
|
|
|
VIR_WARN("Unable to release PCI address on NIC");
|
2013-03-05 15:44:22 +00:00
|
|
|
else if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW) &&
|
|
|
|
net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
|
|
|
|
releaseaddr &&
|
|
|
|
qemuDomainCCWAddressReleaseAddr(priv->ccwaddrs,
|
|
|
|
&net->info) < 0)
|
|
|
|
VIR_WARN("Unable to release CCW address on NIC");
|
2011-07-04 06:27:12 +00:00
|
|
|
|
2012-02-28 03:43:23 +00:00
|
|
|
if (iface_connected) {
|
2011-07-04 06:27:12 +00:00
|
|
|
virDomainConfNWFilterTeardown(net);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-07-01 15:04:57 +00:00
|
|
|
if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) {
|
|
|
|
ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
|
|
|
|
net->ifname, &net->mac,
|
|
|
|
virDomainNetGetActualDirectDev(net),
|
|
|
|
virDomainNetGetActualDirectMode(net),
|
|
|
|
virDomainNetGetActualVirtPortProfile(net),
|
|
|
|
cfg->stateDir));
|
|
|
|
VIR_FREE(net->ifname);
|
|
|
|
}
|
|
|
|
|
2012-02-28 03:43:23 +00:00
|
|
|
vport = virDomainNetGetActualVirtPortProfile(net);
|
|
|
|
if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH)
|
|
|
|
ignore_value(virNetDevOpenvswitchRemovePort(
|
|
|
|
virDomainNetGetActualBridgeName(net), net->ifname));
|
|
|
|
}
|
2012-02-10 21:09:00 +00:00
|
|
|
|
2011-07-04 06:27:12 +00:00
|
|
|
networkReleaseActualDevice(net);
|
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
VIR_FREE(nicstr);
|
|
|
|
VIR_FREE(netstr);
|
2013-04-18 08:47:01 +00:00
|
|
|
for (i = 0; tapfd && i < tapfdSize; i++) {
|
2013-05-21 13:50:09 +00:00
|
|
|
VIR_FORCE_CLOSE(tapfd[i]);
|
2013-04-18 08:47:01 +00:00
|
|
|
if (tapfdName)
|
|
|
|
VIR_FREE(tapfdName[i]);
|
2013-05-21 13:50:09 +00:00
|
|
|
}
|
|
|
|
VIR_FREE(tapfd);
|
|
|
|
VIR_FREE(tapfdName);
|
2013-04-18 08:47:01 +00:00
|
|
|
for (i = 0; vhostfd && i < vhostfdSize; i++) {
|
2013-05-21 13:50:09 +00:00
|
|
|
VIR_FORCE_CLOSE(vhostfd[i]);
|
2013-04-18 08:47:01 +00:00
|
|
|
if (vhostfdName)
|
|
|
|
VIR_FREE(vhostfdName[i]);
|
2013-05-21 13:50:09 +00:00
|
|
|
}
|
|
|
|
VIR_FREE(vhostfd);
|
|
|
|
VIR_FREE(vhostfdName);
|
2013-01-10 21:03:14 +00:00
|
|
|
virObjectUnref(cfg);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
try_remove:
|
|
|
|
if (!virDomainObjIsActive(vm))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (vlan < 0) {
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
char *netdev_name;
|
|
|
|
if (virAsprintf(&netdev_name, "host%s", net->info.alias) < 0)
|
2013-07-04 10:14:12 +00:00
|
|
|
goto cleanup;
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuMonitorRemoveNetdev(priv->mon, netdev_name) < 0)
|
|
|
|
VIR_WARN("Failed to remove network backend for netdev %s",
|
|
|
|
netdev_name);
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_FREE(netdev_name);
|
|
|
|
} else {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_WARN("Unable to remove network backend");
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
char *hostnet_name;
|
|
|
|
if (virAsprintf(&hostnet_name, "host%s", net->info.alias) < 0)
|
2013-07-04 10:14:12 +00:00
|
|
|
goto cleanup;
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0)
|
|
|
|
VIR_WARN("Failed to remove network backend for vlan %d, net %s",
|
|
|
|
vlan, hostnet_name);
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_FREE(hostnet_name);
|
|
|
|
}
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
virDomainHostdevDefPtr hostdev)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
int ret;
|
|
|
|
char *devstr = NULL;
|
|
|
|
int configfd = -1;
|
|
|
|
char *configfd_name = NULL;
|
2011-04-26 03:40:01 +00:00
|
|
|
bool releaseaddr = false;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
return -1;
|
|
|
|
|
2012-03-06 01:12:44 +00:00
|
|
|
if (qemuPrepareHostdevPCIDevices(driver, vm->def->name, vm->def->uuid,
|
|
|
|
&hostdev, 1) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
return -1;
|
|
|
|
|
2013-04-25 16:45:55 +00:00
|
|
|
if (hostdev->source.subsys.u.pci.backend
|
2013-04-26 20:44:05 +00:00
|
|
|
== VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
|
2013-04-25 16:45:55 +00:00
|
|
|
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("VFIO PCI device assignment is not "
|
|
|
|
"supported by this version of qemu"));
|
|
|
|
goto error;
|
|
|
|
}
|
2013-06-28 14:54:38 +00:00
|
|
|
|
|
|
|
/* VFIO requires all of the guest's memory to be locked resident.
|
|
|
|
* In this case, the guest's memory may already be locked, but it
|
|
|
|
* doesn't hurt to "change" the limit to the same value.
|
2013-04-25 16:45:55 +00:00
|
|
|
*/
|
2013-06-28 14:54:38 +00:00
|
|
|
vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
|
|
|
|
virProcessSetMaxMemLock(vm->pid,
|
|
|
|
qemuDomainMemoryLimit(vm->def) * 1024);
|
|
|
|
vm->def->hostdevs[vm->def->nhostdevs--] = NULL;
|
2013-04-25 11:58:37 +00:00
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
|
|
|
|
goto error;
|
2012-01-31 09:16:54 +00:00
|
|
|
if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
2011-04-26 03:40:01 +00:00
|
|
|
releaseaddr = true;
|
2013-04-25 11:58:37 +00:00
|
|
|
if ((hostdev->source.subsys.u.pci.backend
|
2013-04-26 20:44:05 +00:00
|
|
|
!= VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) &&
|
2013-04-25 11:58:37 +00:00
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
configfd = qemuOpenPCIConfig(hostdev);
|
|
|
|
if (configfd >= 0) {
|
|
|
|
if (virAsprintf(&configfd_name, "fd-%s",
|
2013-07-04 10:14:12 +00:00
|
|
|
hostdev->info->alias) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virDomainObjIsActive(vm)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("guest unexpectedly quit during hotplug"));
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2011-02-01 16:22:01 +00:00
|
|
|
if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev, configfd_name,
|
2013-02-01 13:48:58 +00:00
|
|
|
priv->qemuCaps)))
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2011-03-15 23:10:16 +00:00
|
|
|
ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr,
|
|
|
|
configfd, configfd_name);
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
} else {
|
2012-08-16 15:41:06 +00:00
|
|
|
virDevicePCIAddress guestAddr = hostdev->info->addr.pci;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
ret = qemuMonitorAddPCIHostDevice(priv->mon,
|
2013-03-18 19:56:12 +00:00
|
|
|
&hostdev->source.subsys.u.pci.addr,
|
2010-12-16 16:10:54 +00:00
|
|
|
&guestAddr);
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2012-01-31 09:16:54 +00:00
|
|
|
hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
|
|
|
memcpy(&hostdev->info->addr.pci, &guestAddr, sizeof(guestAddr));
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
Move qemu_audit.h helpers into shared code
The LXC and UML drivers can both make use of auditing. Move
the qemu_audit.{c,h} files to src/conf/domain_audit.{c,h}
* src/conf/domain_audit.c: Rename from src/qemu/qemu_audit.c
* src/conf/domain_audit.h: Rename from src/qemu/qemu_audit.h
* src/Makefile.am: Remove qemu_audit.{c,h}, add domain_audit.{c,h}
* src/qemu/qemu_audit.h, src/qemu/qemu_cgroup.c,
src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c,
src/qemu/qemu_process.c: Update for changed audit API names
2011-07-04 10:56:13 +00:00
|
|
|
virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
|
2010-12-16 16:10:54 +00:00
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
|
|
|
|
|
|
|
|
VIR_FREE(devstr);
|
|
|
|
VIR_FREE(configfd_name);
|
|
|
|
VIR_FORCE_CLOSE(configfd);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
2012-01-31 09:16:54 +00:00
|
|
|
(hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
2011-04-26 03:40:01 +00:00
|
|
|
releaseaddr &&
|
2011-05-23 07:43:35 +00:00
|
|
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
2013-02-15 06:48:49 +00:00
|
|
|
&hostdev->info->addr.pci) < 0)
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_WARN("Unable to release PCI address on host device");
|
2010-12-16 16:10:54 +00:00
|
|
|
|
qemu: Do not reattach PCI device used by other domain when shutdown
When failing on starting a domain, it tries to reattach all the PCI
devices defined in the domain conf, regardless of whether the devices
are still used by other domain. This will cause the devices to be deleted
from the list qemu_driver->activePciHostdevs, thus the devices will be
thought as usable even if it's not true. And following commands
nodedev-{reattach,reset} will be successful.
How to reproduce:
1) Define two domains with same PCI device defined in the confs.
2) # virsh start domain1
3) # virsh start domain2
4) # virsh nodedev-reattach $pci_device
You will see the device will be reattached to host successfully.
As pciDeviceReattach just check if the device is still used by
other domain via checking if the device is in list driver->activePciHostdevs,
however, the device is deleted from the list by step 2).
This patch is to prohibit the bug by:
1) Prohibit a domain starting or device attachment right at
preparation period (qemuPrepareHostdevPCIDevices) if the
device is in list driver->activePciHostdevs, which means
it's used by other domain.
2) Introduces a new field for struct _pciDevice, (const char *used_by),
it will be set as the domain name at preparation period,
(qemuPrepareHostdevPCIDevices). Thus we can prohibit deleting
the device from driver->activePciHostdevs if it's still used by
other domain when stopping the domain process.
* src/pci.h (define two internal functions, pciDeviceSetUsedBy and
pciDevceGetUsedBy)
* src/pci.c (new field "const char *used_by" for struct _pciDevice,
implementations for the two new functions)
* src/libvirt_private.syms (Add the two new internal functions)
* src/qemu_hostdev.h (Modify the definition of functions
qemuPrepareHostdevPCIDevices, and qemuDomainReAttachHostdevDevices)
* src/qemu_hostdev.c (Prohibit preparation and don't delete the
device from activePciHostdevs list if it's still used by other domain)
* src/qemu_hotplug.c (Update function usage, as the definitions are
changed)
Signed-off-by: Eric Blake <eblake@redhat.com>
2011-10-13 04:05:04 +00:00
|
|
|
qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
VIR_FREE(devstr);
|
|
|
|
VIR_FREE(configfd_name);
|
|
|
|
VIR_FORCE_CLOSE(configfd);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
|
2011-09-02 15:09:14 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainRedirdevDefPtr redirdev)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
2012-09-13 07:25:46 +00:00
|
|
|
virDomainDefPtr def = vm->def;
|
2011-09-02 15:09:14 +00:00
|
|
|
char *devstr = NULL;
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2011-09-02 15:09:14 +00:00
|
|
|
if (qemuAssignDeviceRedirdevAlias(vm->def, redirdev, -1) < 0)
|
|
|
|
goto error;
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, priv->qemuCaps)))
|
2011-09-02 15:09:14 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->redirdevs, vm->def->nredirdevs+1) < 0)
|
2011-09-02 15:09:14 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
|
2011-09-02 15:09:14 +00:00
|
|
|
ret = qemuMonitorAddDevice(priv->mon, devstr);
|
|
|
|
else
|
|
|
|
goto error;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2011-09-02 15:09:14 +00:00
|
|
|
virDomainAuditRedirdev(vm, redirdev, "attach", ret == 0);
|
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
vm->def->redirdevs[vm->def->nredirdevs++] = redirdev;
|
|
|
|
|
|
|
|
VIR_FREE(devstr);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
VIR_FREE(devstr);
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-03-12 14:59:25 +00:00
|
|
|
int
|
|
|
|
qemuDomainChrInsert(virDomainDefPtr vmdef,
|
|
|
|
virDomainChrDefPtr chr)
|
|
|
|
{
|
|
|
|
if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
|
|
|
|
chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|
|
|
_("attaching serial console is not supported"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virDomainChrFind(vmdef, chr)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("chardev already exists"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virDomainChrInsert(vmdef, chr) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* Due to some crazy backcompat stuff, the first serial device is an alias
|
|
|
|
* to the first console too. If this is the case, the definition must be
|
|
|
|
* duplicated as first console device. */
|
|
|
|
if (vmdef->nserials == 1 && vmdef->nconsoles == 0) {
|
|
|
|
if ((!vmdef->consoles && VIR_ALLOC(vmdef->consoles) < 0) ||
|
|
|
|
VIR_ALLOC(vmdef->consoles[0]) < 0) {
|
|
|
|
virDomainChrRemove(vmdef, chr);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
vmdef->nconsoles = 1;
|
|
|
|
|
|
|
|
/* Create an console alias for the serial port */
|
|
|
|
vmdef->consoles[0]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
|
|
|
|
vmdef->consoles[0]->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
virDomainChrDefPtr
|
|
|
|
qemuDomainChrRemove(virDomainDefPtr vmdef,
|
|
|
|
virDomainChrDefPtr chr)
|
|
|
|
{
|
|
|
|
virDomainChrDefPtr ret;
|
|
|
|
bool removeCompat;
|
|
|
|
|
|
|
|
if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
|
|
|
|
chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("detaching serial console is not supported"));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Due to some crazy backcompat stuff, the first serial device is an alias
|
|
|
|
* to the first console too. If this is the case, the definition must be
|
|
|
|
* duplicated as first console device. */
|
|
|
|
removeCompat = vmdef->nserials && vmdef->nconsoles &&
|
|
|
|
vmdef->consoles[0]->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
|
|
|
|
vmdef->consoles[0]->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL &&
|
|
|
|
virDomainChrEquals(vmdef->serials[0], chr);
|
|
|
|
|
|
|
|
if (!(ret = virDomainChrRemove(vmdef, chr))) {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
_("device not present in domain configuration"));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (removeCompat)
|
|
|
|
VIR_DELETE_ELEMENT(vmdef->consoles, 0, vmdef->nconsoles);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2013-03-13 10:08:55 +00:00
|
|
|
|
|
|
|
int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainChrDefPtr chr)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
virDomainDefPtr vmdef = vm->def;
|
|
|
|
char *devstr = NULL;
|
|
|
|
char *charAlias = NULL;
|
|
|
|
bool remove = false;
|
|
|
|
|
|
|
|
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("qemu does not support -device"));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemuAssignDeviceChrAlias(vmdef, chr, -1) < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (qemuBuildChrDeviceStr(&devstr, vm->def, chr, priv->qemuCaps) < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (virAsprintf(&charAlias, "char%s", chr->info.alias) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemuDomainChrInsert(vmdef, chr) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
remove = true;
|
|
|
|
|
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
|
|
|
if (qemuMonitorAttachCharDev(priv->mon, charAlias, &chr->source) < 0) {
|
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (devstr && qemuMonitorAddDevice(priv->mon, devstr) < 0) {
|
|
|
|
/* detach associated chardev on error */
|
|
|
|
qemuMonitorDetachCharDev(priv->mon, charAlias);
|
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
if (ret < 0 && remove)
|
|
|
|
qemuDomainChrRemove(vmdef, chr);
|
|
|
|
VIR_FREE(charAlias);
|
|
|
|
VIR_FREE(devstr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
virDomainHostdevDefPtr hostdev)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
2013-05-03 18:07:30 +00:00
|
|
|
virUSBDeviceList *list = NULL;
|
|
|
|
virUSBDevicePtr usb = NULL;
|
2010-12-16 16:10:54 +00:00
|
|
|
char *devstr = NULL;
|
2013-05-03 18:07:30 +00:00
|
|
|
bool added = false;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!(list = virUSBDeviceListNew()))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virUSBDeviceListAdd(list, usb) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (qemuPrepareHostdevUSBDevices(driver, vm->def->name, list) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
added = true;
|
|
|
|
virUSBDeviceListSteal(list, usb);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
|
2013-05-03 18:07:30 +00:00
|
|
|
goto cleanup;
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev, priv->qemuCaps)))
|
2013-05-03 18:07:30 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0)
|
2013-05-03 18:07:30 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
|
2010-12-16 16:10:54 +00:00
|
|
|
ret = qemuMonitorAddDevice(priv->mon, devstr);
|
|
|
|
else
|
|
|
|
ret = qemuMonitorAddUSBDeviceExact(priv->mon,
|
|
|
|
hostdev->source.subsys.u.usb.bus,
|
|
|
|
hostdev->source.subsys.u.usb.device);
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
Move qemu_audit.h helpers into shared code
The LXC and UML drivers can both make use of auditing. Move
the qemu_audit.{c,h} files to src/conf/domain_audit.{c,h}
* src/conf/domain_audit.c: Rename from src/qemu/qemu_audit.c
* src/conf/domain_audit.h: Rename from src/qemu/qemu_audit.h
* src/Makefile.am: Remove qemu_audit.{c,h}, add domain_audit.{c,h}
* src/qemu/qemu_audit.h, src/qemu/qemu_cgroup.c,
src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c,
src/qemu/qemu_process.c: Update for changed audit API names
2011-07-04 10:56:13 +00:00
|
|
|
virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
|
2010-12-16 16:10:54 +00:00
|
|
|
if (ret < 0)
|
2013-05-03 18:07:30 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
|
|
|
|
|
2013-05-03 18:07:30 +00:00
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
if (added)
|
|
|
|
virUSBDeviceListSteal(driver->activeUsbHostdevs, usb);
|
|
|
|
virUSBDeviceFree(usb);
|
|
|
|
virObjectUnref(list);
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_FREE(devstr);
|
2013-05-03 18:07:30 +00:00
|
|
|
return ret;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2013-05-03 18:07:31 +00:00
|
|
|
static int
|
|
|
|
qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainHostdevDefPtr hostdev)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
char *devstr = NULL;
|
|
|
|
char *drvstr = NULL;
|
|
|
|
|
|
|
|
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE) ||
|
|
|
|
!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) ||
|
|
|
|
!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC)) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("SCSI passthrough is not supported by this version of qemu"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemuPrepareHostdevSCSIDevices(driver, vm->def->name,
|
|
|
|
&hostdev, 1)) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Unable to prepare scsi hostdev: %s:%d:%d:%d"),
|
|
|
|
hostdev->source.subsys.u.scsi.adapter,
|
|
|
|
hostdev->source.subsys.u.scsi.bus,
|
|
|
|
hostdev->source.subsys.u.scsi.target,
|
|
|
|
hostdev->source.subsys.u.scsi.unit);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, 0) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2013-05-17 10:34:24 +00:00
|
|
|
if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, priv->qemuCaps,
|
|
|
|
&buildCommandLineCallbacks)))
|
2013-05-03 18:07:31 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, hostdev, priv->qemuCaps)))
|
|
|
|
goto cleanup;
|
|
|
|
|
2013-07-04 10:14:12 +00:00
|
|
|
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
|
2013-05-03 18:07:31 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
|
|
|
if ((ret = qemuMonitorAddDrive(priv->mon, drvstr)) == 0) {
|
|
|
|
if ((ret = qemuMonitorAddDevice(priv->mon, devstr)) < 0) {
|
|
|
|
virErrorPtr orig_err = virSaveLastError();
|
|
|
|
if (qemuMonitorDriveDel(priv->mon, drvstr) < 0)
|
|
|
|
VIR_WARN("Unable to remove drive %s (%s) after failed "
|
|
|
|
"qemuMonitorAddDevice",
|
|
|
|
drvstr, devstr);
|
|
|
|
if (orig_err) {
|
|
|
|
virSetError(orig_err);
|
|
|
|
virFreeError(orig_err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
|
|
|
|
|
|
|
virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
|
|
|
|
if (ret < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
if (ret < 0)
|
|
|
|
qemuDomainReAttachHostScsiDevices(driver, vm->def->name, &hostdev, 1);
|
|
|
|
VIR_FREE(drvstr);
|
|
|
|
VIR_FREE(devstr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
virDomainHostdevDefPtr hostdev)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
|
|
|
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("hostdev mode '%s' not supported"),
|
|
|
|
virDomainHostdevModeTypeToString(hostdev->mode));
|
2010-12-16 16:10:54 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-04-29 17:15:26 +00:00
|
|
|
if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
|
2013-05-03 18:07:30 +00:00
|
|
|
return -1;
|
2013-04-29 17:15:26 +00:00
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerSetHostdevLabel(driver->securityManager,
|
2012-11-27 16:17:47 +00:00
|
|
|
vm->def, hostdev, NULL) < 0)
|
2013-05-03 18:07:30 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
switch (hostdev->source.subsys.type) {
|
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
|
|
|
if (qemuDomainAttachHostPciDevice(driver, vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
hostdev) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
|
|
|
if (qemuDomainAttachHostUsbDevice(driver, vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
hostdev) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
break;
|
|
|
|
|
2013-05-03 18:07:31 +00:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
|
|
|
|
if (qemuDomainAttachHostScsiDevice(driver, vm,
|
|
|
|
hostdev) < 0)
|
|
|
|
goto error;
|
|
|
|
break;
|
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
default:
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("hostdev subsys type '%s' not supported"),
|
|
|
|
virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
|
2010-12-16 16:10:54 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
|
2012-11-27 16:17:47 +00:00
|
|
|
vm->def, hostdev, NULL) < 0)
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_WARN("Unable to restore host device labelling on hotplug fail");
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-05-03 18:07:30 +00:00
|
|
|
cleanup:
|
2013-04-29 17:15:26 +00:00
|
|
|
if (qemuTeardownHostdevCgroup(vm, hostdev) < 0)
|
|
|
|
VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
|
2010-12-16 16:10:54 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
static virDomainNetDefPtr *qemuDomainFindNet(virDomainObjPtr vm,
|
|
|
|
virDomainNetDefPtr dev)
|
2011-09-06 08:23:47 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2011-09-06 08:23:47 +00:00
|
|
|
|
|
|
|
for (i = 0; i < vm->def->nnets; i++) {
|
2012-07-17 12:07:59 +00:00
|
|
|
if (virMacAddrCmp(&vm->def->nets[i]->mac, &dev->mac) == 0)
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
return &vm->def->nets[i];
|
2011-09-06 08:23:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
static char *
|
|
|
|
qemuDomainNetGetBridgeName(virConnectPtr conn, virDomainNetDefPtr net)
|
|
|
|
{
|
|
|
|
char *brname = NULL;
|
|
|
|
int actualType = virDomainNetGetActualType(net);
|
|
|
|
|
|
|
|
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
|
|
|
|
const char *tmpbr = virDomainNetGetActualBridgeName(net);
|
|
|
|
if (!tmpbr) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("interface is missing bridge name"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* we need a copy, not just a pointer to the original */
|
2013-05-20 09:23:13 +00:00
|
|
|
if (VIR_STRDUP(brname, tmpbr) < 0)
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
|
|
|
|
int active;
|
|
|
|
virErrorPtr errobj;
|
|
|
|
virNetworkPtr network;
|
|
|
|
|
|
|
|
if (!(network = virNetworkLookupByName(conn, net->data.network.name))) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Couldn't find network '%s'"),
|
|
|
|
net->data.network.name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
active = virNetworkIsActive(network);
|
|
|
|
if (active == 1) {
|
|
|
|
brname = virNetworkGetBridgeName(network);
|
|
|
|
} else if (active == 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Network '%s' is not active."),
|
|
|
|
net->data.network.name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure any above failure is preserved */
|
|
|
|
errobj = virSaveLastError();
|
|
|
|
virNetworkFree(network);
|
|
|
|
virSetError(errobj);
|
|
|
|
virFreeError(errobj);
|
|
|
|
|
qemu: eliminate bogus error log when changing netdev's bridge
This fixes a problem that showed up during testing of:
https://bugzilla.redhat.com/show_bug.cgi?id=881480
Due to a logic error in the function that gets the name of the bridge
an interface connects to, any time a bridge was specified directly
(type='bridge') rather than indirectly (type='network'), An error
would be logged (although the operation would then complete
successfully):
Network type 6 is not supported
The final virReportError() in the function
qemuDomainNetGetBridgeName() was apparently avoided in the past with a
"goto cleanup" at the end of each case, but the case of bridge somehow
no longer has that final goto cleanup.
The proper solution is anyway to not rely on goto's, but put the error
log inside an else {} clause, so that it's executed only if the type
is neither bridge nor network (in reality, this function should only
ever be called for those two types, that's why this is an internal
error).
While making this change, the error message was also tuned to be more
correct (since it's not really the type of the network, but the type
of the interface, and it *is* otherwise supported, it's just that the
interface type in question doesn't *have* a bridge device associated
with it, or at least we don't know how to get it).
2012-12-10 16:21:39 +00:00
|
|
|
} else {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Interface type %d has no bridge name"),
|
|
|
|
virDomainNetGetActualType(net));
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return brname;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
qemuDomainChangeNetBridge(virConnectPtr conn,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainNetDefPtr olddev,
|
|
|
|
virDomainNetDefPtr newdev)
|
2012-03-28 19:11:09 +00:00
|
|
|
{
|
|
|
|
int ret = -1;
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
char *oldbridge = NULL, *newbridge = NULL;
|
|
|
|
|
|
|
|
if (!(oldbridge = qemuDomainNetGetBridgeName(conn, olddev)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(newbridge = qemuDomainNetGetBridgeName(conn, newdev)))
|
|
|
|
goto cleanup;
|
2012-03-28 19:11:09 +00:00
|
|
|
|
|
|
|
VIR_DEBUG("Change bridge for interface %s: %s -> %s",
|
|
|
|
olddev->ifname, oldbridge, newbridge);
|
|
|
|
|
|
|
|
if (virNetDevExists(newbridge) != 1) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("bridge %s doesn't exist"), newbridge);
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
goto cleanup;
|
2012-03-28 19:11:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (oldbridge) {
|
|
|
|
ret = virNetDevBridgeRemovePort(oldbridge, olddev->ifname);
|
|
|
|
virDomainAuditNet(vm, olddev, NULL, "detach", ret == 0);
|
2012-12-14 00:09:51 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
/* warn but continue - possibly the old network
|
|
|
|
* had been destroyed and reconstructed, leaving the
|
|
|
|
* tap device orphaned.
|
|
|
|
*/
|
|
|
|
VIR_WARN("Unable to detach device %s from bridge %s",
|
|
|
|
olddev->ifname, oldbridge);
|
|
|
|
}
|
2012-03-28 19:11:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = virNetDevBridgeAddPort(newbridge, olddev->ifname);
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
virDomainAuditNet(vm, NULL, newdev, "attach", ret == 0);
|
2012-03-28 19:11:09 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
ret = virNetDevBridgeAddPort(oldbridge, olddev->ifname);
|
|
|
|
virDomainAuditNet(vm, NULL, olddev, "attach", ret == 0);
|
|
|
|
if (ret < 0) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
2012-09-12 16:54:42 +00:00
|
|
|
_("unable to recover former state by adding port "
|
2012-07-18 15:22:03 +00:00
|
|
|
"to bridge %s"), oldbridge);
|
2012-03-28 19:11:09 +00:00
|
|
|
}
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
goto cleanup;
|
2012-03-28 19:11:09 +00:00
|
|
|
}
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
/* caller will replace entire olddev with newdev in domain nets list */
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
2012-03-28 19:11:09 +00:00
|
|
|
VIR_FREE(oldbridge);
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
VIR_FREE(newbridge);
|
|
|
|
return ret;
|
2012-03-28 19:11:09 +00:00
|
|
|
}
|
|
|
|
|
2012-11-12 16:21:10 +00:00
|
|
|
static int
|
|
|
|
qemuDomainChangeNetFilter(virConnectPtr conn,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainNetDefPtr olddev,
|
|
|
|
virDomainNetDefPtr newdev)
|
|
|
|
{
|
|
|
|
/* make sure this type of device supports filters. */
|
|
|
|
switch (virDomainNetGetActualType(newdev)) {
|
|
|
|
case VIR_DOMAIN_NET_TYPE_ETHERNET:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_BRIDGE:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("filters not supported on interfaces of type %s"),
|
|
|
|
virDomainNetTypeToString(virDomainNetGetActualType(newdev)));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
virDomainConfNWFilterTeardown(olddev);
|
|
|
|
|
|
|
|
if (virDomainConfNWFilterInstantiate(conn, vm->def->uuid, newdev) < 0) {
|
|
|
|
virErrorPtr errobj;
|
|
|
|
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("failed to add new filter rules to '%s' "
|
|
|
|
"- attempting to restore old rules"),
|
|
|
|
olddev->ifname);
|
|
|
|
errobj = virSaveLastError();
|
|
|
|
ignore_value(virDomainConfNWFilterInstantiate(conn, vm->def->uuid, olddev));
|
|
|
|
virSetError(errobj);
|
|
|
|
virFreeError(errobj);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
|
2011-09-06 08:23:47 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainNetDefPtr dev,
|
|
|
|
int linkstate)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
|
|
|
|
VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate);
|
|
|
|
|
|
|
|
if (!dev->info.alias) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("can't change link state: device alias not found"));
|
2011-09-06 08:23:47 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2011-09-06 08:23:47 +00:00
|
|
|
|
|
|
|
ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate);
|
|
|
|
if (ret < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* modify the device configuration */
|
|
|
|
dev->linkstate = linkstate;
|
|
|
|
|
|
|
|
cleanup:
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2011-09-06 08:23:47 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
int
|
2012-11-28 16:43:10 +00:00
|
|
|
qemuDomainChangeNet(virQEMUDriverPtr driver,
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainPtr dom,
|
|
|
|
virDomainDeviceDefPtr dev)
|
2011-09-06 08:23:47 +00:00
|
|
|
{
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
virDomainNetDefPtr newdev = dev->data.net;
|
|
|
|
virDomainNetDefPtr *devslot = qemuDomainFindNet(vm, newdev);
|
|
|
|
virDomainNetDefPtr olddev;
|
|
|
|
int oldType, newType;
|
|
|
|
bool needReconnect = false;
|
|
|
|
bool needBridgeChange = false;
|
2012-11-12 16:21:10 +00:00
|
|
|
bool needFilterChange = false;
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
bool needLinkStateChange = false;
|
|
|
|
bool needReplaceDevDef = false;
|
|
|
|
int ret = -1;
|
2011-09-06 08:23:47 +00:00
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
if (!devslot || !(olddev = *devslot)) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
2012-07-18 15:22:03 +00:00
|
|
|
_("cannot find existing network device to modify"));
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
oldType = virDomainNetGetActualType(olddev);
|
|
|
|
if (oldType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
|
|
|
|
/* no changes are possible to a type='hostdev' interface */
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot change config of '%s' network type"),
|
|
|
|
virDomainNetTypeToString(oldType));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check individual attributes for changes that can't be done to a
|
|
|
|
* live netdev. These checks *mostly* go in order of the
|
|
|
|
* declarations in virDomainNetDef in order to assure nothing is
|
|
|
|
* omitted. (exceptiong where noted in comments - in particular,
|
|
|
|
* some things require that a new "actual device" be allocated
|
|
|
|
* from the network driver first, but we delay doing that until
|
|
|
|
* after we've made as many other checks as possible)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* type: this can change (with some restrictions), but the actual
|
|
|
|
* type of the new device connection isn't known until after we
|
|
|
|
* allocate the "actual" device.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (virMacAddrCmp(&olddev->mac, &newdev->mac)) {
|
|
|
|
char oldmac[VIR_MAC_STRING_BUFLEN], newmac[VIR_MAC_STRING_BUFLEN];
|
|
|
|
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot change network interface mac address "
|
|
|
|
"from %s to %s"),
|
|
|
|
virMacAddrFormat(&olddev->mac, oldmac),
|
|
|
|
virMacAddrFormat(&newdev->mac, newmac));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (STRNEQ_NULLABLE(olddev->model, newdev->model)) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot modify network device model from %s to %s"),
|
|
|
|
olddev->model ? olddev->model : "(default)",
|
|
|
|
newdev->model ? newdev->model : "(default)");
|
|
|
|
goto cleanup;
|
2011-09-06 08:23:47 +00:00
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
if (olddev->model && STREQ(olddev->model, "virtio") &&
|
|
|
|
(olddev->driver.virtio.name != newdev->driver.virtio.name ||
|
|
|
|
olddev->driver.virtio.txmode != newdev->driver.virtio.txmode ||
|
|
|
|
olddev->driver.virtio.ioeventfd != newdev->driver.virtio.ioeventfd ||
|
|
|
|
olddev->driver.virtio.event_idx != newdev->driver.virtio.event_idx)) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot modify virtio network device driver attributes"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* data: this union will be examined later, after allocating new actualdev */
|
|
|
|
/* virtPortProfile: will be examined later, after allocating new actualdev */
|
|
|
|
|
|
|
|
if (olddev->tune.sndbuf_specified != newdev->tune.sndbuf_specified ||
|
|
|
|
olddev->tune.sndbuf != newdev->tune.sndbuf) {
|
|
|
|
needReconnect = true;
|
2011-09-06 08:23:47 +00:00
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
if (STRNEQ_NULLABLE(olddev->script, newdev->script)) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot modify network device script attribute"));
|
|
|
|
goto cleanup;
|
2012-07-30 06:03:25 +00:00
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
/* ifname: check if it's set in newdev. If not, retain the autogenerated one */
|
2013-05-20 09:23:13 +00:00
|
|
|
if (!newdev->ifname && VIR_STRDUP(newdev->ifname, olddev->ifname) < 0)
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
goto cleanup;
|
|
|
|
if (STRNEQ_NULLABLE(olddev->ifname, newdev->ifname)) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot modify network device tap name"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2011-09-06 08:23:47 +00:00
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
/* info: if newdev->info is empty, fill it in from olddev,
|
|
|
|
* otherwise verify that it matches - nothing is allowed to
|
|
|
|
* change. (There is no helper function to do this, so
|
|
|
|
* individually check the few feidls of virDomainDeviceInfo that
|
|
|
|
* are relevant in this case).
|
|
|
|
*/
|
|
|
|
if (!virDomainDeviceAddressIsValid(&newdev->info,
|
|
|
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
|
|
|
virDomainDeviceInfoCopy(&newdev->info, &olddev->info) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!virDevicePCIAddressEqual(&olddev->info.addr.pci,
|
|
|
|
&newdev->info.addr.pci)) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot modify network device guest PCI address"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* grab alias from olddev if not set in newdev */
|
2013-05-20 09:23:13 +00:00
|
|
|
if (!newdev->info.alias &&
|
|
|
|
VIR_STRDUP(newdev->info.alias, olddev->info.alias) < 0)
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
goto cleanup;
|
|
|
|
if (STRNEQ_NULLABLE(olddev->info.alias, newdev->info.alias)) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot modify network device alias"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (olddev->info.rombar != newdev->info.rombar) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot modify network device rom bar setting"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (STRNEQ_NULLABLE(olddev->info.romfile, newdev->info.romfile)) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot modify network rom file"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (olddev->info.bootIndex != newdev->info.bootIndex) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot modify network device boot index setting"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* (end of device info checks) */
|
2011-09-06 08:23:47 +00:00
|
|
|
|
2012-11-12 16:21:10 +00:00
|
|
|
if (STRNEQ_NULLABLE(olddev->filter, newdev->filter) ||
|
|
|
|
!virNWFilterHashTableEqual(olddev->filterparams, newdev->filterparams)) {
|
|
|
|
needFilterChange = true;
|
|
|
|
}
|
2011-09-06 08:23:47 +00:00
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
/* bandwidth can be modified, and will be checked later */
|
|
|
|
/* vlan can be modified, and will be checked later */
|
|
|
|
/* linkstate can be modified */
|
|
|
|
|
|
|
|
/* allocate new actual device to compare to old - we will need to
|
|
|
|
* free it if we fail for any reason
|
|
|
|
*/
|
|
|
|
if (newdev->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
|
|
|
|
networkAllocateActualDevice(newdev) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
newType = virDomainNetGetActualType(newdev);
|
|
|
|
|
|
|
|
if (newType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
|
|
|
|
/* can't turn it into a type='hostdev' interface */
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("cannot change network interface type to '%s'"),
|
|
|
|
virDomainNetTypeToString(newType));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (olddev->type == newdev->type && oldType == newType) {
|
2011-09-06 08:23:47 +00:00
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
/* if type hasn't changed, check the relevant fields for the type */
|
|
|
|
switch (newdev->type) {
|
|
|
|
case VIR_DOMAIN_NET_TYPE_USER:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_NET_TYPE_ETHERNET:
|
|
|
|
if (STRNEQ_NULLABLE(olddev->data.ethernet.dev,
|
|
|
|
newdev->data.ethernet.dev) ||
|
|
|
|
STRNEQ_NULLABLE(olddev->data.ethernet.ipaddr,
|
|
|
|
newdev->data.ethernet.ipaddr)) {
|
|
|
|
needReconnect = true;
|
|
|
|
}
|
2011-09-06 08:23:47 +00:00
|
|
|
break;
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
case VIR_DOMAIN_NET_TYPE_SERVER:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_CLIENT:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_MCAST:
|
|
|
|
if (STRNEQ_NULLABLE(olddev->data.socket.address,
|
|
|
|
newdev->data.socket.address) ||
|
|
|
|
olddev->data.socket.port != newdev->data.socket.port) {
|
|
|
|
needReconnect = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
|
|
|
if (STRNEQ(olddev->data.network.name, newdev->data.network.name)) {
|
|
|
|
if (virDomainNetGetActualVirtPortProfile(newdev))
|
|
|
|
needReconnect = true;
|
|
|
|
else
|
|
|
|
needBridgeChange = true;
|
|
|
|
}
|
|
|
|
/* other things handled in common code directly below this switch */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_NET_TYPE_BRIDGE:
|
|
|
|
/* all handled in bridge name checked in common code below */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_NET_TYPE_INTERNAL:
|
|
|
|
if (STRNEQ_NULLABLE(olddev->data.internal.name,
|
|
|
|
newdev->data.internal.name)) {
|
|
|
|
needReconnect = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_NET_TYPE_DIRECT:
|
|
|
|
/* all handled in common code directly below this switch */
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("unable to change config on '%s' network type"),
|
|
|
|
virDomainNetTypeToString(newdev->type));
|
|
|
|
break;
|
2012-03-28 19:11:09 +00:00
|
|
|
|
2011-09-06 08:23:47 +00:00
|
|
|
}
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
} else {
|
|
|
|
/* interface type has changed. There are a few special cases
|
|
|
|
* where this can only require a minor (or even no) change,
|
|
|
|
* but in most cases we need to do a full reconnection.
|
|
|
|
*
|
|
|
|
* If we switch (in either direction) between type='bridge'
|
|
|
|
* and type='network' (for a traditional managed virtual
|
|
|
|
* network that uses a host bridge, i.e. forward
|
|
|
|
* mode='route|nat'), we just need to change the bridge.
|
|
|
|
*/
|
|
|
|
if ((oldType == VIR_DOMAIN_NET_TYPE_NETWORK &&
|
|
|
|
newType == VIR_DOMAIN_NET_TYPE_BRIDGE) ||
|
|
|
|
(oldType == VIR_DOMAIN_NET_TYPE_BRIDGE &&
|
|
|
|
newType == VIR_DOMAIN_NET_TYPE_NETWORK)) {
|
|
|
|
|
|
|
|
needBridgeChange = true;
|
|
|
|
|
|
|
|
} else if (oldType == VIR_DOMAIN_NET_TYPE_DIRECT &&
|
|
|
|
newType == VIR_DOMAIN_NET_TYPE_DIRECT) {
|
|
|
|
|
|
|
|
/* this is the case of switching from type='direct' to
|
|
|
|
* type='network' for a network that itself uses direct
|
|
|
|
* (macvtap) devices. If the physical device and mode are
|
|
|
|
* the same, this doesn't require any actual setup
|
|
|
|
* change. If the physical device or mode *does* change,
|
|
|
|
* that will be caught in the common section below */
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/* for all other combinations, we'll need a full reconnect */
|
|
|
|
needReconnect = true;
|
2011-09-06 08:23:47 +00:00
|
|
|
|
|
|
|
}
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
}
|
2011-09-06 08:23:47 +00:00
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
/* now several things that are in multiple (but not all)
|
|
|
|
* different types, and can be safely compared even for those
|
|
|
|
* cases where they don't apply to a particular type.
|
|
|
|
*/
|
|
|
|
if (STRNEQ_NULLABLE(virDomainNetGetActualBridgeName(olddev),
|
|
|
|
virDomainNetGetActualBridgeName(newdev))) {
|
|
|
|
if (virDomainNetGetActualVirtPortProfile(newdev))
|
|
|
|
needReconnect = true;
|
|
|
|
else
|
|
|
|
needBridgeChange = true;
|
|
|
|
}
|
2011-09-06 08:23:47 +00:00
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
if (STRNEQ_NULLABLE(virDomainNetGetActualDirectDev(olddev),
|
|
|
|
virDomainNetGetActualDirectDev(newdev)) ||
|
|
|
|
virDomainNetGetActualDirectMode(olddev) != virDomainNetGetActualDirectMode(olddev) ||
|
|
|
|
!virNetDevVPortProfileEqual(virDomainNetGetActualVirtPortProfile(olddev),
|
|
|
|
virDomainNetGetActualVirtPortProfile(newdev)) ||
|
|
|
|
!virNetDevBandwidthEqual(virDomainNetGetActualBandwidth(olddev),
|
|
|
|
virDomainNetGetActualBandwidth(newdev)) ||
|
|
|
|
!virNetDevVlanEqual(virDomainNetGetActualVlan(olddev),
|
|
|
|
virDomainNetGetActualVlan(newdev))) {
|
|
|
|
needReconnect = true;
|
2011-09-06 08:23:47 +00:00
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
if (olddev->linkstate != newdev->linkstate)
|
|
|
|
needLinkStateChange = true;
|
|
|
|
|
|
|
|
/* FINALLY - actually perform the required actions */
|
|
|
|
|
|
|
|
if (needReconnect) {
|
2013-03-20 15:57:08 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
_("unable to change config on '%s' network type"),
|
|
|
|
virDomainNetTypeToString(newdev->type));
|
|
|
|
goto cleanup;
|
2011-09-06 08:23:47 +00:00
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
if (needBridgeChange) {
|
|
|
|
if (qemuDomainChangeNetBridge(dom->conn, vm, olddev, newdev) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
/* we successfully switched to the new bridge, and we've
|
|
|
|
* determined that the rest of newdev is equivalent to olddev,
|
2012-11-12 16:21:10 +00:00
|
|
|
* so move newdev into place */
|
|
|
|
needReplaceDevDef = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (needFilterChange) {
|
|
|
|
if (qemuDomainChangeNetFilter(dom->conn, vm, olddev, newdev) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
/* we successfully switched to the new filter, and we've
|
|
|
|
* determined that the rest of newdev is equivalent to olddev,
|
|
|
|
* so move newdev into place */
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
needReplaceDevDef = true;
|
2011-09-06 08:23:47 +00:00
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
if (needLinkStateChange &&
|
|
|
|
qemuDomainChangeNetLinkState(driver, vm, olddev, newdev->linkstate) < 0) {
|
|
|
|
goto cleanup;
|
2012-03-28 19:11:09 +00:00
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
if (needReplaceDevDef) {
|
|
|
|
/* the changes above warrant replacing olddev with newdev in
|
|
|
|
* the domain's nets list.
|
|
|
|
*/
|
|
|
|
networkReleaseActualDevice(olddev);
|
|
|
|
virDomainNetDefFree(olddev);
|
|
|
|
/* move newdev into the nets list, and NULL it out from the
|
|
|
|
* virDomainDeviceDef that we were given so that the caller
|
|
|
|
* won't delete it on return.
|
|
|
|
*/
|
|
|
|
*devslot = newdev;
|
|
|
|
newdev = dev->data.net = NULL;
|
|
|
|
dev->type = VIR_DOMAIN_DEVICE_NONE;
|
2011-09-06 08:23:47 +00:00
|
|
|
}
|
|
|
|
|
qemu: reorganize qemuDomainChangeNet and qemuDomainChangeNetBridge
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=805071
to the extent that it can be resolved with current qemu functionality.
It attempts to detect as many situations as possible when the simple
operation of disconnecting an existing tap device from one bridge and
attaching it to another will satisfy the change requested in
virDomainUpdateDeviceFlags() for a network device. Before this patch,
that situation could only be detected if the pre-change interface
*and* the post-change interface definition were both "type='bridge'".
After this patch, it can also be detected if the before or after
interfaces are any combination of type='bridge' and type='network'
(the networks can be <forward mode='nat|route|bridge'>, as long as
they use a Linux host bridge and not macvtap connections).
This extra effort is especially useful since the recent discovery that
a netdev_del+netdev_add combo (to reconnect the network device with
completely different hostside configuration) doesn't work properly
with current qemu (1.2) unless it is accompanied by the matching
device_del+device_add - see this mailing list message for details:
http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg02355.html
(A slight modification of the patch referenced there has been prepared
to apply on top of this patch, but won't be pushed until qemu can be
made to work with it.)
* qemuDomainChangeNet needs access to the virDomainDeviceDef that
holds the new netdef (so that it can clear out the virDomainDeviceDef
if it ends up using the NetDef to replace the original), so the
virDomainNetDefPtr arg is replaced with a virDomainDeviceDefPtr.
* qemuDomainChangeNet previously checked for *some* changes to the
interface config, but this check was by no means complete. It was also
a bit disorganized.
This refactoring of the code is (I believe) complete in its check of
all NetDef attributes that might be changed, and either returns a
failure (for changes that are simply impossible), or sets one of three
flags:
needLinkStateChange - if the device link state needs to go up/down
needBridgeChange - if everything else is the same, but it needs
to be connected to a difference linux host
bridge
needReconnect - if the entire host side of the device needs
to be torn down and reconstructed (currently
non-working, as mentioned above)
Note that this function will refuse to make any change that requires
the *guest* side of the device to be detached (e.g. changing the PCI
address or mac address). Those would be disruptive enough to the guest
that it's reasonable to require an explicit detach/attach sequence
from the management application.
* As mentioned above, qemuDomainChangeNet also does its best to
understand when a simple change in attached bridge for the existing
tap device will work vs. the need to completely tear down/reconstruct
the host side of the device (including tap device).
This patch *does not* implement the "reconnect" code anyway - there is
a placeholder that turns that into an error. Rather, the purpose of
this patch is to replicate existing behavior with code that is ready
to have that functionality plugged in in a later patch.
* The expanded uses for qemuDomainChangeNetBridge meant that it needed
to be enhanced as well - it no longer replaces the original brname
string in olddev with the new brname; instead, it relies on the
caller to replace the *entire* olddev with newdev (since we've gone
to great lengths to assure they are functionally identical other
than the name of the bridge, this is now not only safe, but more
correct). Additionally, qemuDomainNetChangeBridge can now set the
bridge for type='network' interfaces as well as plain type='bridge'
interfaces. (Note that I had to make this change simultaneous to the
reorganization of qemuDomainChangeNet because the two are too
closely intertwined to separate).
2012-10-10 19:38:00 +00:00
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
/* When we get here, we will be in one of these two states:
|
|
|
|
*
|
|
|
|
* 1) newdev has been moved into the domain's list of nets and
|
|
|
|
* newdev set to NULL, and dev->data.net will be NULL (and
|
|
|
|
* dev->type is NONE). olddev will have been completely
|
|
|
|
* released and freed. (aka success) In this case no extra
|
|
|
|
* cleanup is needed.
|
|
|
|
*
|
|
|
|
* 2) newdev has *not* been moved into the domain's list of nets,
|
|
|
|
* and dev->data.net == newdev (and dev->type == NET). In this *
|
|
|
|
* case, we need to at least release the "actual device" from *
|
|
|
|
* newdev (the caller will free dev->data.net a.k.a. newdev, and
|
|
|
|
* the original olddev is still in used)
|
|
|
|
*
|
|
|
|
* Note that case (2) isn't necessarily a failure. It may just be
|
|
|
|
* that the changes were minor enough that we didn't need to
|
|
|
|
* replace the entire device object.
|
|
|
|
*/
|
|
|
|
if (newdev)
|
|
|
|
networkReleaseActualDevice(newdev);
|
|
|
|
|
2011-09-06 08:23:47 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
static virDomainGraphicsDefPtr qemuDomainFindGraphics(virDomainObjPtr vm,
|
|
|
|
virDomainGraphicsDefPtr dev)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-05-21 07:21:20 +00:00
|
|
|
for (i = 0; i < vm->def->ngraphics; i++) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (vm->def->graphics[i]->type == dev->type)
|
|
|
|
return vm->def->graphics[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2012-11-28 16:43:10 +00:00
|
|
|
qemuDomainChangeGraphics(virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainGraphicsDefPtr dev)
|
|
|
|
{
|
|
|
|
virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev);
|
|
|
|
int ret = -1;
|
2013-01-10 21:03:14 +00:00
|
|
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
qemuDomainChangeGraphics: Check listen address change by listen type
Currently, we have a bug when updating a graphics device. A graphics device can
have a listen address set. This address is either defined by user (in which case
it's type is VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) or it can be inherited
from a network (in which case it's type is
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK). However, in both cases we have a
listen address to process (e.g. during migration, as I've tried to fix in
7f15ebc7).
Later, when a user tries to update the graphics device (e.g. set a password),
we check if listen addresses match the original as qemu doesn't know how to
change listen address yet. Hence, users are required to not change the listen
address. The implementation then just dumps listen addresses and compare them.
Previously, while dumping the listen addresses, NULL was returned for NETWORK.
After my patch, this is no longer true, and we get a listen address for olddev
even if it is a type of NETWORK. So we have a real string on one side, the NULL
from user's XML on the other side and hence we think user wants to change the
listen address and we refuse it.
Therefore, we must take the type of listen address into account as well.
2013-06-20 16:27:35 +00:00
|
|
|
size_t i;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
if (!olddev) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("cannot find existing graphics device to modify"));
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
qemuDomainChangeGraphics: Check listen address change by listen type
Currently, we have a bug when updating a graphics device. A graphics device can
have a listen address set. This address is either defined by user (in which case
it's type is VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) or it can be inherited
from a network (in which case it's type is
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK). However, in both cases we have a
listen address to process (e.g. during migration, as I've tried to fix in
7f15ebc7).
Later, when a user tries to update the graphics device (e.g. set a password),
we check if listen addresses match the original as qemu doesn't know how to
change listen address yet. Hence, users are required to not change the listen
address. The implementation then just dumps listen addresses and compare them.
Previously, while dumping the listen addresses, NULL was returned for NETWORK.
After my patch, this is no longer true, and we get a listen address for olddev
even if it is a type of NETWORK. So we have a real string on one side, the NULL
from user's XML on the other side and hence we think user wants to change the
listen address and we refuse it.
Therefore, we must take the type of listen address into account as well.
2013-06-20 16:27:35 +00:00
|
|
|
if (dev->nListens != olddev->nListens) {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
_("cannot change the number of listen addresses"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < dev->nListens; i++) {
|
2013-06-20 18:55:00 +00:00
|
|
|
virDomainGraphicsListenDefPtr newlisten = &dev->listens[i];
|
qemuDomainChangeGraphics: Check listen address change by listen type
Currently, we have a bug when updating a graphics device. A graphics device can
have a listen address set. This address is either defined by user (in which case
it's type is VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) or it can be inherited
from a network (in which case it's type is
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK). However, in both cases we have a
listen address to process (e.g. during migration, as I've tried to fix in
7f15ebc7).
Later, when a user tries to update the graphics device (e.g. set a password),
we check if listen addresses match the original as qemu doesn't know how to
change listen address yet. Hence, users are required to not change the listen
address. The implementation then just dumps listen addresses and compare them.
Previously, while dumping the listen addresses, NULL was returned for NETWORK.
After my patch, this is no longer true, and we get a listen address for olddev
even if it is a type of NETWORK. So we have a real string on one side, the NULL
from user's XML on the other side and hence we think user wants to change the
listen address and we refuse it.
Therefore, we must take the type of listen address into account as well.
2013-06-20 16:27:35 +00:00
|
|
|
virDomainGraphicsListenDefPtr oldlisten = &olddev->listens[i];
|
|
|
|
|
2013-06-20 18:55:00 +00:00
|
|
|
if (newlisten->type != oldlisten->type) {
|
qemuDomainChangeGraphics: Check listen address change by listen type
Currently, we have a bug when updating a graphics device. A graphics device can
have a listen address set. This address is either defined by user (in which case
it's type is VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) or it can be inherited
from a network (in which case it's type is
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK). However, in both cases we have a
listen address to process (e.g. during migration, as I've tried to fix in
7f15ebc7).
Later, when a user tries to update the graphics device (e.g. set a password),
we check if listen addresses match the original as qemu doesn't know how to
change listen address yet. Hence, users are required to not change the listen
address. The implementation then just dumps listen addresses and compare them.
Previously, while dumping the listen addresses, NULL was returned for NETWORK.
After my patch, this is no longer true, and we get a listen address for olddev
even if it is a type of NETWORK. So we have a real string on one side, the NULL
from user's XML on the other side and hence we think user wants to change the
listen address and we refuse it.
Therefore, we must take the type of listen address into account as well.
2013-06-20 16:27:35 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
_("cannot change the type of listen address"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-06-20 18:55:00 +00:00
|
|
|
switch ((enum virDomainGraphicsListenType) newlisten->type) {
|
qemuDomainChangeGraphics: Check listen address change by listen type
Currently, we have a bug when updating a graphics device. A graphics device can
have a listen address set. This address is either defined by user (in which case
it's type is VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) or it can be inherited
from a network (in which case it's type is
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK). However, in both cases we have a
listen address to process (e.g. during migration, as I've tried to fix in
7f15ebc7).
Later, when a user tries to update the graphics device (e.g. set a password),
we check if listen addresses match the original as qemu doesn't know how to
change listen address yet. Hence, users are required to not change the listen
address. The implementation then just dumps listen addresses and compare them.
Previously, while dumping the listen addresses, NULL was returned for NETWORK.
After my patch, this is no longer true, and we get a listen address for olddev
even if it is a type of NETWORK. So we have a real string on one side, the NULL
from user's XML on the other side and hence we think user wants to change the
listen address and we refuse it.
Therefore, we must take the type of listen address into account as well.
2013-06-20 16:27:35 +00:00
|
|
|
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
|
2013-06-20 18:55:00 +00:00
|
|
|
if (STRNEQ_NULLABLE(newlisten->address, oldlisten->address)) {
|
qemuDomainChangeGraphics: Check listen address change by listen type
Currently, we have a bug when updating a graphics device. A graphics device can
have a listen address set. This address is either defined by user (in which case
it's type is VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) or it can be inherited
from a network (in which case it's type is
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK). However, in both cases we have a
listen address to process (e.g. during migration, as I've tried to fix in
7f15ebc7).
Later, when a user tries to update the graphics device (e.g. set a password),
we check if listen addresses match the original as qemu doesn't know how to
change listen address yet. Hence, users are required to not change the listen
address. The implementation then just dumps listen addresses and compare them.
Previously, while dumping the listen addresses, NULL was returned for NETWORK.
After my patch, this is no longer true, and we get a listen address for olddev
even if it is a type of NETWORK. So we have a real string on one side, the NULL
from user's XML on the other side and hence we think user wants to change the
listen address and we refuse it.
Therefore, we must take the type of listen address into account as well.
2013-06-20 16:27:35 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
dev->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ?
|
|
|
|
_("cannot change listen address setting on vnc graphics") :
|
|
|
|
_("cannot change listen address setting on spice graphics"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
|
2013-06-20 18:55:00 +00:00
|
|
|
if (STRNEQ_NULLABLE(newlisten->network, oldlisten->network)) {
|
qemuDomainChangeGraphics: Check listen address change by listen type
Currently, we have a bug when updating a graphics device. A graphics device can
have a listen address set. This address is either defined by user (in which case
it's type is VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) or it can be inherited
from a network (in which case it's type is
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK). However, in both cases we have a
listen address to process (e.g. during migration, as I've tried to fix in
7f15ebc7).
Later, when a user tries to update the graphics device (e.g. set a password),
we check if listen addresses match the original as qemu doesn't know how to
change listen address yet. Hence, users are required to not change the listen
address. The implementation then just dumps listen addresses and compare them.
Previously, while dumping the listen addresses, NULL was returned for NETWORK.
After my patch, this is no longer true, and we get a listen address for olddev
even if it is a type of NETWORK. So we have a real string on one side, the NULL
from user's XML on the other side and hence we think user wants to change the
listen address and we refuse it.
Therefore, we must take the type of listen address into account as well.
2013-06-20 16:27:35 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
dev->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ?
|
|
|
|
_("cannot change listen network setting on vnc graphics") :
|
|
|
|
_("cannot change listen network setting on spice graphics"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
|
|
|
|
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
|
|
|
|
/* nada */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
conf: add <listen> subelement to domain <graphics> element
Once it's plugged in, the <listen> element will be an optional
replacement for the "listen" attribute that graphics elements already
have. If the <listen> element is type='address', it will have an
attribute called 'address' which will contain an IP address or dns
name that the guest's display server should listen on. If, however,
type='network', the <listen> element should have an attribute called
'network' that will be set to the name of a network configuration to
get the IP address from.
* docs/schemas/domain.rng: updated to allow the <listen> element
* docs/formatdomain.html.in: document the <listen> element and its
attributes.
* src/conf/domain_conf.[hc]:
1) The domain parser, formatter, and data structure are modified to
support 0 or more <listen> subelements to each <graphics>
element. The old style "legacy" listen attribute is also still
accepted, and will be stored internally just as if it were a
separate <listen> element. On output (i.e. format), the address
attribute of the first <listen> element of type 'address' will be
duplicated in the legacy "listen" attribute of the <graphic>
element.
2) The "listenAddr" attribute has been removed from the unions in
virDomainGRaphicsDef for graphics types vnc, rdp, and spice.
This attribute is now in the <listen> subelement (aka
virDomainGraphicsListenDef)
3) Helper functions were written to provide simple access
(both Get and Set) to the listen elements and their attributes.
* src/libvirt_private.syms: export the listen helper functions
* src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/vbox/vbox_tmpl.c,
src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c
Modify all these files to use the listen helper functions rather
than directly referencing the (now missing) listenAddr
attribute. There can be multiple <listen> elements to a single
<graphics>, but the drivers all currently only support one, so all
replacements of direct access with a helper function indicate index
"0".
* tests/* - only 3 of these are new files added explicitly to test the
new <listen> element. All the others have been modified to reflect
the fact that any legacy "listen" attributes passed in to the domain
parse will be saved in a <listen> element (i.e. one of the
virDomainGraphicsListenDefs), and during the domain format function,
both the <listen> element as well as the legacy attributes will be
output.
2011-07-07 04:20:28 +00:00
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
switch (dev->type) {
|
|
|
|
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
|
|
|
|
if ((olddev->data.vnc.autoport != dev->data.vnc.autoport) ||
|
2011-06-06 19:35:41 +00:00
|
|
|
(!dev->data.vnc.autoport &&
|
|
|
|
(olddev->data.vnc.port != dev->data.vnc.port))) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("cannot change port settings on vnc graphics"));
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
if (STRNEQ_NULLABLE(olddev->data.vnc.keymap, dev->data.vnc.keymap)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("cannot change keymap setting on vnc graphics"));
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 14:15:54 +00:00
|
|
|
/* If a password lifetime was, or is set, or action if connected has
|
|
|
|
* changed, then we must always run, even if new password matches
|
|
|
|
* old password */
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
if (olddev->data.vnc.auth.expires ||
|
|
|
|
dev->data.vnc.auth.expires ||
|
2011-05-26 14:15:54 +00:00
|
|
|
olddev->data.vnc.auth.connected != dev->data.vnc.auth.connected ||
|
2011-06-06 19:35:41 +00:00
|
|
|
STRNEQ_NULLABLE(olddev->data.vnc.auth.passwd,
|
|
|
|
dev->data.vnc.auth.passwd)) {
|
|
|
|
VIR_DEBUG("Updating password on VNC server %p %p",
|
2013-01-10 21:03:14 +00:00
|
|
|
dev->data.vnc.auth.passwd, cfg->vncPassword);
|
2011-06-06 19:35:41 +00:00
|
|
|
ret = qemuDomainChangeGraphicsPasswords(driver, vm,
|
|
|
|
VIR_DOMAIN_GRAPHICS_TYPE_VNC,
|
|
|
|
&dev->data.vnc.auth,
|
2013-01-10 21:03:14 +00:00
|
|
|
cfg->vncPassword);
|
2012-09-03 14:52:27 +00:00
|
|
|
if (ret < 0)
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
/* Steal the new dev's char * reference */
|
|
|
|
VIR_FREE(olddev->data.vnc.auth.passwd);
|
|
|
|
olddev->data.vnc.auth.passwd = dev->data.vnc.auth.passwd;
|
|
|
|
dev->data.vnc.auth.passwd = NULL;
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
olddev->data.vnc.auth.validTo = dev->data.vnc.auth.validTo;
|
|
|
|
olddev->data.vnc.auth.expires = dev->data.vnc.auth.expires;
|
2011-05-26 14:15:54 +00:00
|
|
|
olddev->data.vnc.auth.connected = dev->data.vnc.auth.connected;
|
2010-12-16 16:10:54 +00:00
|
|
|
} else {
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
|
|
|
|
if ((olddev->data.spice.autoport != dev->data.spice.autoport) ||
|
2011-06-06 19:35:41 +00:00
|
|
|
(!dev->data.spice.autoport &&
|
|
|
|
(olddev->data.spice.port != dev->data.spice.port)) ||
|
|
|
|
(!dev->data.spice.autoport &&
|
|
|
|
(olddev->data.spice.tlsPort != dev->data.spice.tlsPort))) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("cannot change port settings on spice graphics"));
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
}
|
2011-06-06 19:35:41 +00:00
|
|
|
if (STRNEQ_NULLABLE(olddev->data.spice.keymap,
|
|
|
|
dev->data.spice.keymap)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
_("cannot change keymap setting on spice graphics"));
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
}
|
|
|
|
|
2012-06-14 12:48:42 +00:00
|
|
|
/* We must reset the password if it has changed but also if:
|
|
|
|
* - password lifetime is or was set
|
|
|
|
* - the requested action has changed
|
|
|
|
* - the action is "disconnect"
|
|
|
|
*/
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
if (olddev->data.spice.auth.expires ||
|
|
|
|
dev->data.spice.auth.expires ||
|
2011-05-26 14:15:54 +00:00
|
|
|
olddev->data.spice.auth.connected != dev->data.spice.auth.connected ||
|
2012-06-14 12:48:42 +00:00
|
|
|
dev->data.spice.auth.connected ==
|
|
|
|
VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_DISCONNECT ||
|
2011-06-06 19:35:41 +00:00
|
|
|
STRNEQ_NULLABLE(olddev->data.spice.auth.passwd,
|
|
|
|
dev->data.spice.auth.passwd)) {
|
|
|
|
VIR_DEBUG("Updating password on SPICE server %p %p",
|
2013-01-10 21:03:14 +00:00
|
|
|
dev->data.spice.auth.passwd, cfg->spicePassword);
|
2011-06-06 19:35:41 +00:00
|
|
|
ret = qemuDomainChangeGraphicsPasswords(driver, vm,
|
|
|
|
VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
|
|
|
|
&dev->data.spice.auth,
|
2013-01-10 21:03:14 +00:00
|
|
|
cfg->spicePassword);
|
2011-06-06 19:35:41 +00:00
|
|
|
|
2012-09-03 14:52:27 +00:00
|
|
|
if (ret < 0)
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2012-09-03 14:52:27 +00:00
|
|
|
|
2011-06-06 19:35:41 +00:00
|
|
|
/* Steal the new dev's char * reference */
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
VIR_FREE(olddev->data.spice.auth.passwd);
|
|
|
|
olddev->data.spice.auth.passwd = dev->data.spice.auth.passwd;
|
|
|
|
dev->data.spice.auth.passwd = NULL;
|
|
|
|
olddev->data.spice.auth.validTo = dev->data.spice.auth.validTo;
|
|
|
|
olddev->data.spice.auth.expires = dev->data.spice.auth.expires;
|
2011-05-26 14:15:54 +00:00
|
|
|
olddev->data.spice.auth.connected = dev->data.spice.auth.connected;
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
} else {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Not updating since password didn't change");
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
ret = 0;
|
|
|
|
}
|
2011-06-06 19:30:52 +00:00
|
|
|
break;
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
default:
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unable to change config on '%s' graphics type"),
|
|
|
|
virDomainGraphicsTypeToString(dev->type));
|
2010-12-16 16:10:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
cleanup:
|
|
|
|
virObjectUnref(cfg);
|
2010-12-16 16:10:54 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline int qemuFindDisk(virDomainDefPtr def, const char *dst)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-05-21 07:21:20 +00:00
|
|
|
for (i = 0; i < def->ndisks; i++) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (STREQ(def->disks[i]->dst, dst)) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-05-09 06:59:16 +00:00
|
|
|
static int qemuComparePCIDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
2012-02-22 21:06:10 +00:00
|
|
|
virDomainDeviceDefPtr device ATTRIBUTE_UNUSED,
|
2012-02-23 17:59:21 +00:00
|
|
|
virDomainDeviceInfoPtr info1,
|
2011-05-09 06:59:16 +00:00
|
|
|
void *opaque)
|
|
|
|
{
|
2012-02-23 17:59:21 +00:00
|
|
|
virDomainDeviceInfoPtr info2 = opaque;
|
2011-05-09 06:59:16 +00:00
|
|
|
|
2012-02-23 17:59:21 +00:00
|
|
|
if (info1->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
|
|
|
|
info2->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
|
2011-05-09 06:59:16 +00:00
|
|
|
return 0;
|
|
|
|
|
2013-04-03 16:09:47 +00:00
|
|
|
if (info1->addr.pci.domain == info2->addr.pci.domain &&
|
|
|
|
info1->addr.pci.bus == info2->addr.pci.bus &&
|
|
|
|
info1->addr.pci.slot == info2->addr.pci.slot &&
|
2012-02-23 17:59:21 +00:00
|
|
|
info1->addr.pci.function != info2->addr.pci.function)
|
2011-05-09 06:59:16 +00:00
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool qemuIsMultiFunctionDevice(virDomainDefPtr def,
|
|
|
|
virDomainDeviceInfoPtr dev)
|
|
|
|
{
|
|
|
|
if (virDomainDeviceInfoIterate(def, qemuComparePCIDevice, dev) < 0)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-03-05 15:44:22 +00:00
|
|
|
int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainDeviceDefPtr dev)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
int idx;
|
|
|
|
int ret = -1;
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainDiskDefPtr detach = NULL;
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
char *drivestr = NULL;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
idx = qemuFindDisk(vm->def, dev->data.disk->dst);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (idx < 0) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("disk %s not found"), dev->data.disk->dst);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
detach = vm->def->disks[idx];
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2011-05-09 06:59:16 +00:00
|
|
|
if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("cannot hot unplug multifunction PCI device: %s"),
|
|
|
|
dev->data.disk->dst);
|
2011-05-09 06:59:16 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-03-05 15:44:22 +00:00
|
|
|
if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
|
|
|
|
if (!virDomainDeviceAddressIsValid(&detach->info,
|
|
|
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("device cannot be detached without a valid CCW address"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!virDomainDeviceAddressIsValid(&detach->info,
|
|
|
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("device cannot be detached without a valid PCI address"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* build the actual drive id string as the disk->info.alias doesn't
|
|
|
|
* contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
|
|
|
|
if (virAsprintf(&drivestr, "%s%s",
|
2013-07-04 10:14:12 +00:00
|
|
|
QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2011-08-22 19:49:10 +00:00
|
|
|
virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (qemuMonitorRemovePCIDevice(priv->mon,
|
|
|
|
&detach->info.addr.pci) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2011-08-22 19:49:10 +00:00
|
|
|
virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* disconnect guest from host device */
|
|
|
|
qemuMonitorDriveDel(priv->mon, drivestr);
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2011-08-22 19:49:10 +00:00
|
|
|
virDomainAuditDisk(vm, detach->src, NULL, "detach", true);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-03-05 15:44:22 +00:00
|
|
|
if (detach->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
|
|
|
|
STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW) &&
|
|
|
|
qemuDomainCCWAddressReleaseAddr(priv->ccwaddrs, &detach->info) < 0) {
|
|
|
|
VIR_WARN("Unable to release CCW address on %s", dev->data.disk->src);
|
|
|
|
} else if (detach->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
|
|
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
|
|
|
&detach->info.addr.pci) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_WARN("Unable to release PCI address on %s", dev->data.disk->src);
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
virDomainDiskRemove(vm->def, idx);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2012-11-27 13:55:00 +00:00
|
|
|
dev->data.disk->backingChain = detach->backingChain;
|
|
|
|
detach->backingChain = NULL;
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainDiskDefFree(detach);
|
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, dev->data.disk) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
|
|
|
|
|
2013-03-21 14:40:29 +00:00
|
|
|
if (qemuTeardownDiskCgroup(vm, dev->data.disk) < 0)
|
|
|
|
VIR_WARN("Failed to teardown cgroup for disk path %s",
|
|
|
|
NULLSTR(dev->data.disk->src));
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2010-10-26 14:04:46 +00:00
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, dev->data.disk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on %s", dev->data.disk->src);
|
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(drivestr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
|
2011-03-07 03:31:48 +00:00
|
|
|
virDomainObjPtr vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
virDomainDeviceDefPtr dev)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
int idx;
|
|
|
|
int ret = -1;
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainDiskDefPtr detach = NULL;
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
char *drivestr = NULL;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
idx = qemuFindDisk(vm->def, dev->data.disk->dst);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if (idx < 0) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("disk %s not found"), dev->data.disk->dst);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("Underlying qemu does not support %s disk removal"),
|
|
|
|
virDomainDiskBusTypeToString(dev->data.disk->bus));
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
detach = vm->def->disks[idx];
|
2010-12-16 16:10:54 +00:00
|
|
|
|
blockjob: react to active block copy
For now, disk migration via block copy job is not implemented in
libvirt. But when we do implement it, we have to deal with the
fact that qemu does not yet provide an easy way to re-start a qemu
process with mirroring still intact. Paolo has proposed an idea
for a persistent dirty bitmap that might make this possible, but
until that design is complete, it's hard to say what changes
libvirt would need. Even something like 'virDomainSave' becomes
hairy, if you realize the implications that 'virDomainRestore'
would be stuck with recreating the same mirror layout.
But if we step back and look at the bigger picture, we realize that
the initial client of live storage migration via disk mirroring is
oVirt, which always uses transient domains, and that if a transient
domain is destroyed while a mirror exists, oVirt can easily restart
the storage migration by creating a new domain that visits just the
source storage, with no loss in data.
We can make life a lot easier by being cowards for now, forbidding
certain operations on a domain. This patch guarantees that we
never get in a state where we would have to restart a domain with
a mirroring block copy, by preventing saves, snapshots, migration,
hot unplug of a disk in use, and conversion to a persistent domain
(thankfully, it is still relatively easy to 'virsh undefine' a
running domain to temporarily make it transient, run tests on
'virsh blockcopy', then 'virsh define' to restore the persistence).
Later, if the qemu design is enhanced, we can relax our code.
The change to qemudDomainDefine looks a bit odd for undoing an
assignment, rather than probing up front to avoid the assignment,
but this is because of how virDomainAssignDef combines both a
lookup and assignment into a single function call.
* src/conf/domain_conf.h (virDomainHasDiskMirror): New prototype.
* src/conf/domain_conf.c (virDomainHasDiskMirror): New function.
* src/libvirt_private.syms (domain_conf.h): Export it.
* src/qemu/qemu_driver.c (qemuDomainSaveInternal)
(qemuDomainSnapshotCreateXML, qemuDomainRevertToSnapshot)
(qemuDomainBlockJobImpl, qemudDomainDefine): Prevent dangerous
actions while block copy is already in action.
* src/qemu/qemu_hotplug.c (qemuDomainDetachDiskDevice): Likewise.
* src/qemu/qemu_migration.c (qemuMigrationIsAllowed): Likewise.
2012-04-10 02:39:47 +00:00
|
|
|
if (detach->mirror) {
|
|
|
|
virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
|
|
|
|
_("disk '%s' is in an active block copy job"),
|
|
|
|
detach->dst);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
/* build the actual drive id string as the disk->info.alias doesn't
|
|
|
|
* contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
|
|
|
|
if (virAsprintf(&drivestr, "%s%s",
|
2013-07-04 10:14:12 +00:00
|
|
|
QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2011-08-22 19:49:10 +00:00
|
|
|
virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* disconnect guest from host device */
|
|
|
|
qemuMonitorDriveDel(priv->mon, drivestr);
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2011-08-22 19:49:10 +00:00
|
|
|
virDomainAuditDisk(vm, detach->src, NULL, "detach", true);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
virDomainDiskRemove(vm->def, idx);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2012-11-27 13:55:00 +00:00
|
|
|
dev->data.disk->backingChain = detach->backingChain;
|
|
|
|
detach->backingChain = NULL;
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainDiskDefFree(detach);
|
|
|
|
|
Refactor the security drivers to simplify usage
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
2010-11-17 20:26:30 +00:00
|
|
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
Change security driver APIs to use virDomainDefPtr instead of virDomainObjPtr
When sVirt is integrated with the LXC driver, it will be neccessary
to invoke the security driver APIs using only a virDomainDefPtr
since the lxc_container.c code has no virDomainObjPtr available.
Aside from two functions which want obj->pid, every bit of the
security driver code only touches obj->def. So we don't need to
pass a virDomainObjPtr into the security drivers, a virDomainDefPtr
is sufficient. Two functions also gain a 'pid_t pid' argument.
* src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/security/security_apparmor.c,
src/security/security_dac.c,
src/security/security_driver.h,
src/security/security_manager.c,
src/security/security_manager.h,
src/security/security_nop.c,
src/security/security_selinux.c,
src/security/security_stack.c: Change all security APIs to use a
virDomainDefPtr instead of virDomainObjPtr
2011-07-14 13:32:06 +00:00
|
|
|
vm->def, dev->data.disk) < 0)
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
|
|
|
|
|
2013-03-21 14:40:29 +00:00
|
|
|
if (qemuTeardownDiskCgroup(vm, dev->data.disk) < 0)
|
|
|
|
VIR_WARN("Failed to teardown cgroup for disk path %s",
|
|
|
|
NULLSTR(dev->data.disk->src));
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2010-10-26 14:04:46 +00:00
|
|
|
if (virDomainLockDiskDetach(driver->lockManager, vm, dev->data.disk) < 0)
|
|
|
|
VIR_WARN("Unable to release lock on disk %s", dev->data.disk->src);
|
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(drivestr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-02-21 07:35:52 +00:00
|
|
|
static bool qemuDomainDiskControllerIsBusy(virDomainObjPtr vm,
|
|
|
|
virDomainControllerDefPtr detach)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2011-02-21 07:35:52 +00:00
|
|
|
virDomainDiskDefPtr disk;
|
|
|
|
|
|
|
|
for (i = 0; i < vm->def->ndisks; i++) {
|
|
|
|
disk = vm->def->disks[i];
|
|
|
|
if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE)
|
|
|
|
/* the disk does not use disk controller */
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* check whether the disk uses this type controller */
|
|
|
|
if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE &&
|
|
|
|
detach->type != VIR_DOMAIN_CONTROLLER_TYPE_IDE)
|
|
|
|
continue;
|
|
|
|
if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC &&
|
|
|
|
detach->type != VIR_DOMAIN_CONTROLLER_TYPE_FDC)
|
|
|
|
continue;
|
|
|
|
if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI &&
|
|
|
|
detach->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (disk->info.addr.drive.controller == detach->idx)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool qemuDomainControllerIsBusy(virDomainObjPtr vm,
|
|
|
|
virDomainControllerDefPtr detach)
|
|
|
|
{
|
|
|
|
switch (detach->type) {
|
|
|
|
case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
|
|
|
|
case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
|
|
|
|
case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
|
|
|
|
return qemuDomainDiskControllerIsBusy(vm, detach);
|
|
|
|
|
|
|
|
case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
|
|
|
|
case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
|
|
|
|
case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
|
|
|
|
default:
|
|
|
|
/* libvirt does not support sata controller, and does not support to
|
|
|
|
* detach virtio and smart card controller.
|
|
|
|
*/
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainDetachPciControllerDevice(virQEMUDriverPtr driver,
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainObjPtr vm,
|
2011-05-04 12:09:09 +00:00
|
|
|
virDomainDeviceDefPtr dev)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
2012-07-23 08:18:57 +00:00
|
|
|
int idx, ret = -1;
|
2010-12-16 16:10:54 +00:00
|
|
|
virDomainControllerDefPtr detach = NULL;
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
|
2012-07-23 08:18:57 +00:00
|
|
|
if ((idx = virDomainControllerFind(vm->def,
|
|
|
|
dev->data.controller->type,
|
|
|
|
dev->data.controller->idx)) < 0) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
2013-05-09 09:39:21 +00:00
|
|
|
_("controller %s:%d not found"),
|
2012-07-18 15:22:03 +00:00
|
|
|
virDomainControllerTypeToString(dev->data.controller->type),
|
|
|
|
dev->data.controller->idx);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2012-07-23 08:18:57 +00:00
|
|
|
detach = vm->def->controllers[idx];
|
|
|
|
|
2010-12-16 16:10:54 +00:00
|
|
|
if (!virDomainDeviceAddressIsValid(&detach->info,
|
|
|
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("device cannot be detached without a PCI address"));
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-05-09 06:59:16 +00:00
|
|
|
if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("cannot hot unplug multifunction PCI device: %s"),
|
|
|
|
dev->data.disk->dst);
|
2011-05-09 06:59:16 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-02-21 07:35:52 +00:00
|
|
|
if (qemuDomainControllerIsBusy(vm, detach)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("device cannot be detached: device is busy"));
|
2011-02-21 07:35:52 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuAssignDeviceControllerAlias(detach) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2010-12-16 16:10:54 +00:00
|
|
|
if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (qemuMonitorRemovePCIDevice(priv->mon,
|
|
|
|
&detach->info.addr.pci) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2012-07-23 08:18:57 +00:00
|
|
|
virDomainControllerRemove(vm->def, idx);
|
|
|
|
virDomainControllerDefFree(detach);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
2011-05-23 07:43:35 +00:00
|
|
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
2013-02-15 06:48:49 +00:00
|
|
|
&detach->info.addr.pci) < 0)
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_WARN("Unable to release PCI address on controller");
|
2010-12-16 16:10:54 +00:00
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-12-15 16:51:56 +00:00
|
|
|
static int
|
2012-11-28 16:43:10 +00:00
|
|
|
qemuDomainDetachHostPciDevice(virQEMUDriverPtr driver,
|
2011-12-15 16:51:56 +00:00
|
|
|
virDomainObjPtr vm,
|
2012-03-07 01:43:22 +00:00
|
|
|
virDomainHostdevDefPtr detach)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
2012-02-27 11:53:19 +00:00
|
|
|
virDomainHostdevSubsysPtr subsys = &detach->source.subsys;
|
2013-01-10 21:03:14 +00:00
|
|
|
int ret = -1, rv;
|
2013-01-14 22:11:44 +00:00
|
|
|
virPCIDevicePtr pci;
|
|
|
|
virPCIDevicePtr activePci;
|
2013-01-10 21:03:14 +00:00
|
|
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2012-01-31 09:16:54 +00:00
|
|
|
if (qemuIsMultiFunctionDevice(vm->def, detach->info)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("cannot hot unplug multifunction PCI device: %.4x:%.2x:%.2x.%.1x"),
|
2013-03-18 19:56:12 +00:00
|
|
|
subsys->u.pci.addr.domain, subsys->u.pci.addr.bus,
|
|
|
|
subsys->u.pci.addr.slot, subsys->u.pci.addr.function);
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2012-01-31 09:16:54 +00:00
|
|
|
if (!virDomainDeviceAddressIsValid(detach->info,
|
2010-12-16 16:10:54 +00:00
|
|
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("device cannot be detached without a PCI address"));
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2013-01-10 21:03:14 +00:00
|
|
|
rv = qemuMonitorDelDevice(priv->mon, detach->info->alias);
|
2010-12-16 16:10:54 +00:00
|
|
|
} else {
|
2013-01-10 21:03:14 +00:00
|
|
|
rv = qemuMonitorRemovePCIDevice(priv->mon, &detach->info->addr.pci);
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2013-01-10 21:03:14 +00:00
|
|
|
virDomainAuditHostdev(vm, detach, "detach", rv == 0);
|
|
|
|
if (rv < 0)
|
|
|
|
goto cleanup;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2012-03-06 01:12:44 +00:00
|
|
|
/*
|
|
|
|
* For SRIOV net host devices, unset mac and port profile before
|
|
|
|
* reset and reattach device
|
|
|
|
*/
|
|
|
|
if (detach->parent.data.net)
|
2013-01-10 21:03:14 +00:00
|
|
|
qemuDomainHostdevNetConfigRestore(detach, cfg->stateDir);
|
2012-03-06 01:12:44 +00:00
|
|
|
|
2013-01-16 12:09:58 +00:00
|
|
|
virObjectLock(driver->activePciHostdevs);
|
|
|
|
virObjectLock(driver->inactivePciHostdevs);
|
2013-03-18 19:56:12 +00:00
|
|
|
pci = virPCIDeviceNew(subsys->u.pci.addr.domain, subsys->u.pci.addr.bus,
|
|
|
|
subsys->u.pci.addr.slot, subsys->u.pci.addr.function);
|
2011-11-29 10:09:24 +00:00
|
|
|
if (pci) {
|
2013-01-14 22:11:44 +00:00
|
|
|
activePci = virPCIDeviceListSteal(driver->activePciHostdevs, pci);
|
2012-05-21 14:31:53 +00:00
|
|
|
if (activePci &&
|
2013-06-29 02:35:21 +00:00
|
|
|
virPCIDeviceReset(activePci, driver->activePciHostdevs,
|
|
|
|
driver->inactivePciHostdevs) == 0) {
|
2011-11-29 10:09:24 +00:00
|
|
|
qemuReattachPciDevice(activePci, driver);
|
2013-01-10 21:03:14 +00:00
|
|
|
ret = 0;
|
2012-05-21 14:31:53 +00:00
|
|
|
} else {
|
|
|
|
/* reset of the device failed, treat it as if it was returned */
|
2013-01-14 22:11:44 +00:00
|
|
|
virPCIDeviceFree(activePci);
|
2012-05-21 14:31:53 +00:00
|
|
|
}
|
2013-01-14 22:11:44 +00:00
|
|
|
virPCIDeviceFree(pci);
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
2013-01-16 12:09:58 +00:00
|
|
|
virObjectUnlock(driver->activePciHostdevs);
|
|
|
|
virObjectUnlock(driver->inactivePciHostdevs);
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
2011-05-23 07:43:35 +00:00
|
|
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
2013-02-15 06:48:49 +00:00
|
|
|
&detach->info->addr.pci) < 0)
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_WARN("Unable to release PCI address on host device");
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
cleanup:
|
|
|
|
virObjectUnref(cfg);
|
2010-12-16 16:10:54 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-12-15 16:51:56 +00:00
|
|
|
static int
|
2012-11-28 16:43:10 +00:00
|
|
|
qemuDomainDetachHostUsbDevice(virQEMUDriverPtr driver,
|
2011-12-15 16:51:56 +00:00
|
|
|
virDomainObjPtr vm,
|
2012-03-07 01:43:22 +00:00
|
|
|
virDomainHostdevDefPtr detach)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
2012-02-27 11:53:19 +00:00
|
|
|
virDomainHostdevSubsysPtr subsys = &detach->source.subsys;
|
2013-01-14 22:11:44 +00:00
|
|
|
virUSBDevicePtr usb;
|
2012-02-27 11:53:19 +00:00
|
|
|
int ret;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2012-01-31 09:16:54 +00:00
|
|
|
if (!detach->info->alias) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("device cannot be detached without a device alias"));
|
2010-12-16 16:10:54 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("device cannot be detached with this QEMU version"));
|
2010-12-16 16:10:54 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2012-01-31 09:16:54 +00:00
|
|
|
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
Move qemu_audit.h helpers into shared code
The LXC and UML drivers can both make use of auditing. Move
the qemu_audit.{c,h} files to src/conf/domain_audit.{c,h}
* src/conf/domain_audit.c: Rename from src/qemu/qemu_audit.c
* src/conf/domain_audit.h: Rename from src/qemu/qemu_audit.h
* src/Makefile.am: Remove qemu_audit.{c,h}, add domain_audit.{c,h}
* src/qemu/qemu_audit.h, src/qemu/qemu_cgroup.c,
src/qemu/qemu_command.c, src/qemu/qemu_driver.c,
src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c,
src/qemu/qemu_process.c: Update for changed audit API names
2011-07-04 10:56:13 +00:00
|
|
|
virDomainAuditHostdev(vm, detach, "detach", ret == 0);
|
2011-02-23 23:15:23 +00:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2013-01-14 22:11:44 +00:00
|
|
|
usb = virUSBDeviceNew(subsys->u.usb.bus, subsys->u.usb.device, NULL);
|
2011-12-21 17:58:29 +00:00
|
|
|
if (usb) {
|
2013-01-16 12:09:58 +00:00
|
|
|
virObjectLock(driver->activeUsbHostdevs);
|
2013-01-14 22:11:44 +00:00
|
|
|
virUSBDeviceListDel(driver->activeUsbHostdevs, usb);
|
2013-01-16 12:09:58 +00:00
|
|
|
virObjectUnlock(driver->activeUsbHostdevs);
|
2013-01-14 22:11:44 +00:00
|
|
|
virUSBDeviceFree(usb);
|
2011-12-21 17:58:29 +00:00
|
|
|
} else {
|
|
|
|
VIR_WARN("Unable to find device %03d.%03d in list of used USB devices",
|
2012-02-27 11:53:19 +00:00
|
|
|
subsys->u.usb.bus, subsys->u.usb.device);
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-05-03 18:07:31 +00:00
|
|
|
static int
|
|
|
|
qemuDomainDetachHostScsiDevice(virQEMUDriverPtr driver,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainHostdevDefPtr detach)
|
|
|
|
{
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
char *drvstr = NULL;
|
|
|
|
char *devstr = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (!detach->info->alias) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("device cannot be detached without a device alias"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("device cannot be detached with this QEMU version"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-05-17 10:34:24 +00:00
|
|
|
if (!(drvstr = qemuBuildSCSIHostdevDrvStr(detach, priv->qemuCaps,
|
|
|
|
&buildCommandLineCallbacks)))
|
2013-05-03 18:07:31 +00:00
|
|
|
goto cleanup;
|
|
|
|
if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, detach, priv->qemuCaps)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
|
|
|
if ((ret = qemuMonitorDelDevice(priv->mon, detach->info->alias)) == 0) {
|
|
|
|
if ((ret = qemuMonitorDriveDel(priv->mon, drvstr)) < 0) {
|
|
|
|
virErrorPtr orig_err = virSaveLastError();
|
|
|
|
if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
|
|
|
|
VIR_WARN("Unable to add device %s (%s) after failed "
|
|
|
|
"qemuMonitorDriveDel",
|
|
|
|
drvstr, devstr);
|
|
|
|
if (orig_err) {
|
|
|
|
virSetError(orig_err);
|
|
|
|
virFreeError(orig_err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
|
|
|
|
|
|
|
virDomainAuditHostdev(vm, detach, "detach", ret == 0);
|
|
|
|
|
|
|
|
if (ret == 0)
|
|
|
|
qemuDomainReAttachHostScsiDevices(driver, vm->def->name, &detach, 1);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(drvstr);
|
|
|
|
VIR_FREE(devstr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainHostdevDefPtr detach,
|
|
|
|
int idx)
|
2010-12-16 16:10:54 +00:00
|
|
|
{
|
2012-02-27 11:53:19 +00:00
|
|
|
int ret = -1;
|
2010-12-16 16:10:54 +00:00
|
|
|
|
2012-02-27 11:53:19 +00:00
|
|
|
if (idx < 0) {
|
|
|
|
/* caller didn't know index of hostdev in hostdevs list, so we
|
|
|
|
* need to find it.
|
|
|
|
*/
|
|
|
|
for (idx = 0; idx < vm->def->nhostdevs; idx++) {
|
|
|
|
if (vm->def->hostdevs[idx] == detach)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (idx >= vm->def->nhostdevs) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2012-09-26 15:12:28 +00:00
|
|
|
_("device not found in hostdevs list (%zu entries)"),
|
2012-07-18 15:22:03 +00:00
|
|
|
vm->def->nhostdevs);
|
2012-02-27 11:53:19 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
}
|
|
|
|
|
2012-02-27 11:53:19 +00:00
|
|
|
switch (detach->source.subsys.type) {
|
2010-12-16 16:10:54 +00:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
2012-03-07 01:43:22 +00:00
|
|
|
ret = qemuDomainDetachHostPciDevice(driver, vm, detach);
|
|
|
|
break;
|
2010-12-16 16:10:54 +00:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
2012-03-07 01:43:22 +00:00
|
|
|
ret = qemuDomainDetachHostUsbDevice(driver, vm, detach);
|
2010-12-16 16:10:54 +00:00
|
|
|
break;
|
2013-05-03 18:07:31 +00:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
|
|
|
|
ret = qemuDomainDetachHostScsiDevice(driver, vm, detach);
|
|
|
|
break;
|
2010-12-16 16:10:54 +00:00
|
|
|
default:
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("hostdev subsys type '%s' not supported"),
|
|
|
|
virDomainHostdevSubsysTypeToString(detach->source.subsys.type));
|
2010-12-16 16:10:54 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2012-03-07 01:43:22 +00:00
|
|
|
if (!ret) {
|
2013-04-29 17:15:26 +00:00
|
|
|
if (qemuTeardownHostdevCgroup(vm, detach) < 0)
|
|
|
|
VIR_WARN("Failed to remove host device cgroup ACL");
|
|
|
|
|
2012-03-07 01:43:22 +00:00
|
|
|
if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
|
2012-11-27 16:17:47 +00:00
|
|
|
vm->def, detach, NULL) < 0) {
|
2012-03-07 01:43:22 +00:00
|
|
|
VIR_WARN("Failed to restore host device labelling");
|
|
|
|
}
|
|
|
|
virDomainHostdevRemove(vm->def, idx);
|
|
|
|
virDomainHostdevDefFree(detach);
|
2012-02-27 11:53:19 +00:00
|
|
|
}
|
2010-12-16 16:10:54 +00:00
|
|
|
return ret;
|
|
|
|
}
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
|
2012-02-27 11:53:19 +00:00
|
|
|
/* search for a hostdev matching dev and detach it */
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
|
2012-02-27 11:53:19 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainDeviceDefPtr dev)
|
|
|
|
{
|
|
|
|
virDomainHostdevDefPtr hostdev = dev->data.hostdev;
|
|
|
|
virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
|
|
|
|
virDomainHostdevDefPtr detach = NULL;
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("hostdev mode '%s' not supported"),
|
|
|
|
virDomainHostdevModeTypeToString(hostdev->mode));
|
2012-02-27 11:53:19 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
idx = virDomainHostdevFind(vm->def, hostdev, &detach);
|
|
|
|
|
|
|
|
if (idx < 0) {
|
2012-10-17 09:23:12 +00:00
|
|
|
switch (subsys->type) {
|
2012-02-27 11:53:19 +00:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("host pci device %.4x:%.2x:%.2x.%.1x not found"),
|
2013-03-18 19:56:12 +00:00
|
|
|
subsys->u.pci.addr.domain, subsys->u.pci.addr.bus,
|
|
|
|
subsys->u.pci.addr.slot, subsys->u.pci.addr.function);
|
2012-02-27 11:53:19 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
|
|
|
if (subsys->u.usb.bus && subsys->u.usb.device) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("host usb device %03d.%03d not found"),
|
|
|
|
subsys->u.usb.bus, subsys->u.usb.device);
|
2012-02-27 11:53:19 +00:00
|
|
|
} else {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("host usb device vendor=0x%.4x product=0x%.4x not found"),
|
|
|
|
subsys->u.usb.vendor, subsys->u.usb.product);
|
2012-02-27 11:53:19 +00:00
|
|
|
}
|
|
|
|
break;
|
2013-05-03 18:07:31 +00:00
|
|
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("host scsi device %s:%d:%d.%d not found"),
|
|
|
|
subsys->u.scsi.adapter, subsys->u.scsi.bus,
|
|
|
|
subsys->u.scsi.target, subsys->u.scsi.unit);
|
|
|
|
break;
|
2012-02-27 11:53:19 +00:00
|
|
|
default:
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected hostdev type %d"), subsys->type);
|
2012-02-27 11:53:19 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
qemu: support type=hostdev network device live hotplug attach/detach
qemuDomainAttachNetDevice
- re-ordered some things at start of function because
networkAllocateActualDevice should always be run and a slot
in def->nets always allocated, but host_net_add isn't needed
if the actual type is hostdev.
- if actual type is hostdev, defer to
qemuDomainAttachHostDevice (which will reach up to the NetDef
for things like MAC address when necessary). After return
from qemuDomainAttachHostDevice, slip directly to cleanup,
since the rest of the function is specific to emulated net
devices.
- put assignment of new NetDef into expanded def->nets down
below cleanup: (but only on success) since it is also needed
for emulated and hostdev net devices.
qemuDomainDetachHostDevice
- after locating the exact device to detach, check if it's a
network device and, if so, use toplevel
qemuDomainDetachNetDevice instead so that the def->nets list
is properly updated, and 'actual device' properly returned to
network pool if appropriate. Otherwise, for normal hostdevs,
call the lower level qemuDomainDetachThisDevice.
qemuDomainDetachNetDevice
- This is where it gets a bit tricky. After locating the device
on the def->nets list, if the network device type == hostdev,
call the *lower level* qemuDomainDetachThisDevice (which will
reach back up to the parent net device for MAC address /
virtualport when appropriate, then clear the device out of
def->hostdevs) before skipping past all the emulated
net-device-specific code to cleanup:, where the network
device is removed from def->nets, and the network device
object is freed.
In short, any time a hostdev-type network device is detached, we must
go through the toplevel virDomaineDetachNetDevice function first and
last, to make sure 1) the def->nnets list is properly managed, and 2)
any device allocated with networkAllocateActualDevice is properly
freed. At the same time, in the middle we need to go through the
lower-level vidDomainDetach*This*HostDevice to be sure that 1) the
def->hostdevs list is properly managed, 2) the PCI device is properly
detached from the guest and reattached to the host (if appropriate),
and 3) any higher level teardown is called at the appropriate time, by
reaching back up to the NetDef config (part (3) will be covered in a
separate patch).
2012-02-27 19:20:17 +00:00
|
|
|
/* If this is a network hostdev, we need to use the higher-level detach
|
|
|
|
* function so that mac address / virtualport are reset
|
|
|
|
*/
|
|
|
|
if (detach->parent.type == VIR_DOMAIN_DEVICE_NET)
|
|
|
|
return qemuDomainDetachNetDevice(driver, vm, &detach->parent);
|
|
|
|
else
|
|
|
|
return qemuDomainDetachThisHostDevice(driver, vm, detach, idx);
|
2012-02-27 11:53:19 +00:00
|
|
|
}
|
|
|
|
|
2012-02-27 12:03:12 +00:00
|
|
|
int
|
2012-11-28 16:43:10 +00:00
|
|
|
qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
|
2012-02-27 12:03:12 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainDeviceDefPtr dev)
|
|
|
|
{
|
qemu: fix attach/detach of netdevs with matching mac addrs
This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=862515
which describes inconsistencies in dealing with duplicate mac
addresses on network devices in a domain.
(at any rate, it resolves *almost* everything, and prints out an
informative error message for the one problem that isn't solved, but
has a workaround.)
A synopsis of the problems:
1) you can't do a persistent attach-interface of a device with a mac
address that matches an existing device.
2) you *can* do a live attach-interface of such a device.
3) you *can* directly edit a domain and put in two devices with
matching mac addresses.
4) When running virsh detach-device (live or config), only MAC address
is checked when matching the device to remove, so the first device
with the desired mac address will be removed. This isn't always the
one that's wanted.
5) when running virsh detach-interface (live or config), the only two
items that can be specified to match against are mac address and model
type (virtio, etc) - if multiple netdevs match both of those
attributes, it again just finds the first one added and assumes that
is the only match.
Since it is completely valid to have multiple network devices with the
same MAC address (although it can cause problems in many cases, there
*are* valid use cases), what is needed is:
1) remove the restriction that prohibits doing a persistent add of a
netdev with a duplicate mac address.
2) enhance the backend of virDomainDetachDeviceFlags to check for
something that *is* guaranteed unique (but still work with just mac
address, as long as it yields only a single results.
This patch does three things:
1) removes the check for duplicate mac address during a persistent
netdev attach.
2) unifies the searching for both live and config detach of netdevices
in the subordinate functions of qemuDomainModifyDeviceFlags() to use the
new function virDomainNetFindIdx (which matches mac address and PCI
address if available, checking for duplicates if only mac address was
specified). This function returns -2 if multiple matches are found,
allowing the callers to print out an appropriate message.
Steps 1 & 2 are enough to fully fix the problem when using virsh
attach-device and detach-device (which require an XML description of
the device rather than a bunch of commandline args)
3) modifies the virsh detach-interface command to check for multiple
matches of mac address and show an error message suggesting use of the
detach-device command in cases where there are multiple matching mac
addresses.
Later we should decide how we want to input a PCI address on the virsh
commandline, and enhance detach-interface to take a --address option,
eliminating the need to use detach-device
* src/conf/domain_conf.c
* src/conf/domain_conf.h
* src/libvirt_private.syms
* added new virDomainNetFindIdx function
* removed now unused virDomainNetIndexByMac and
virDomainNetRemoveByMac
* src/qemu/qemu_driver.c
* remove check for duplicate max from qemuDomainAttachDeviceConfig
* use virDomainNetFindIdx/virDomainNetRemove instead
of virDomainNetRemoveByMac in qemuDomainDetachDeviceConfig
* use virDomainNetFindIdx instead of virDomainIndexByMac
in qemuDomainUpdateDeviceConfig
* src/qemu/qemu_hotplug.c
* use virDomainNetFindIdx instead of a homespun loop in
qemuDomainDetachNetDevice.
* tools/virsh-domain.c: modified detach-interface command as described
above
2012-10-25 20:03:35 +00:00
|
|
|
int detachidx, ret = -1;
|
2012-02-27 12:03:12 +00:00
|
|
|
virDomainNetDefPtr detach = NULL;
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
int vlan;
|
|
|
|
char *hostnet_name = NULL;
|
qemu: fix attach/detach of netdevs with matching mac addrs
This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=862515
which describes inconsistencies in dealing with duplicate mac
addresses on network devices in a domain.
(at any rate, it resolves *almost* everything, and prints out an
informative error message for the one problem that isn't solved, but
has a workaround.)
A synopsis of the problems:
1) you can't do a persistent attach-interface of a device with a mac
address that matches an existing device.
2) you *can* do a live attach-interface of such a device.
3) you *can* directly edit a domain and put in two devices with
matching mac addresses.
4) When running virsh detach-device (live or config), only MAC address
is checked when matching the device to remove, so the first device
with the desired mac address will be removed. This isn't always the
one that's wanted.
5) when running virsh detach-interface (live or config), the only two
items that can be specified to match against are mac address and model
type (virtio, etc) - if multiple netdevs match both of those
attributes, it again just finds the first one added and assumes that
is the only match.
Since it is completely valid to have multiple network devices with the
same MAC address (although it can cause problems in many cases, there
*are* valid use cases), what is needed is:
1) remove the restriction that prohibits doing a persistent add of a
netdev with a duplicate mac address.
2) enhance the backend of virDomainDetachDeviceFlags to check for
something that *is* guaranteed unique (but still work with just mac
address, as long as it yields only a single results.
This patch does three things:
1) removes the check for duplicate mac address during a persistent
netdev attach.
2) unifies the searching for both live and config detach of netdevices
in the subordinate functions of qemuDomainModifyDeviceFlags() to use the
new function virDomainNetFindIdx (which matches mac address and PCI
address if available, checking for duplicates if only mac address was
specified). This function returns -2 if multiple matches are found,
allowing the callers to print out an appropriate message.
Steps 1 & 2 are enough to fully fix the problem when using virsh
attach-device and detach-device (which require an XML description of
the device rather than a bunch of commandline args)
3) modifies the virsh detach-interface command to check for multiple
matches of mac address and show an error message suggesting use of the
detach-device command in cases where there are multiple matching mac
addresses.
Later we should decide how we want to input a PCI address on the virsh
commandline, and enhance detach-interface to take a --address option,
eliminating the need to use detach-device
* src/conf/domain_conf.c
* src/conf/domain_conf.h
* src/libvirt_private.syms
* added new virDomainNetFindIdx function
* removed now unused virDomainNetIndexByMac and
virDomainNetRemoveByMac
* src/qemu/qemu_driver.c
* remove check for duplicate max from qemuDomainAttachDeviceConfig
* use virDomainNetFindIdx/virDomainNetRemove instead
of virDomainNetRemoveByMac in qemuDomainDetachDeviceConfig
* use virDomainNetFindIdx instead of virDomainIndexByMac
in qemuDomainUpdateDeviceConfig
* src/qemu/qemu_hotplug.c
* use virDomainNetFindIdx instead of a homespun loop in
qemuDomainDetachNetDevice.
* tools/virsh-domain.c: modified detach-interface command as described
above
2012-10-25 20:03:35 +00:00
|
|
|
char mac[VIR_MAC_STRING_BUFLEN];
|
2012-02-27 12:03:12 +00:00
|
|
|
virNetDevVPortProfilePtr vport = NULL;
|
2013-01-10 21:03:14 +00:00
|
|
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
2012-02-27 12:03:12 +00:00
|
|
|
|
qemu: fix attach/detach of netdevs with matching mac addrs
This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=862515
which describes inconsistencies in dealing with duplicate mac
addresses on network devices in a domain.
(at any rate, it resolves *almost* everything, and prints out an
informative error message for the one problem that isn't solved, but
has a workaround.)
A synopsis of the problems:
1) you can't do a persistent attach-interface of a device with a mac
address that matches an existing device.
2) you *can* do a live attach-interface of such a device.
3) you *can* directly edit a domain and put in two devices with
matching mac addresses.
4) When running virsh detach-device (live or config), only MAC address
is checked when matching the device to remove, so the first device
with the desired mac address will be removed. This isn't always the
one that's wanted.
5) when running virsh detach-interface (live or config), the only two
items that can be specified to match against are mac address and model
type (virtio, etc) - if multiple netdevs match both of those
attributes, it again just finds the first one added and assumes that
is the only match.
Since it is completely valid to have multiple network devices with the
same MAC address (although it can cause problems in many cases, there
*are* valid use cases), what is needed is:
1) remove the restriction that prohibits doing a persistent add of a
netdev with a duplicate mac address.
2) enhance the backend of virDomainDetachDeviceFlags to check for
something that *is* guaranteed unique (but still work with just mac
address, as long as it yields only a single results.
This patch does three things:
1) removes the check for duplicate mac address during a persistent
netdev attach.
2) unifies the searching for both live and config detach of netdevices
in the subordinate functions of qemuDomainModifyDeviceFlags() to use the
new function virDomainNetFindIdx (which matches mac address and PCI
address if available, checking for duplicates if only mac address was
specified). This function returns -2 if multiple matches are found,
allowing the callers to print out an appropriate message.
Steps 1 & 2 are enough to fully fix the problem when using virsh
attach-device and detach-device (which require an XML description of
the device rather than a bunch of commandline args)
3) modifies the virsh detach-interface command to check for multiple
matches of mac address and show an error message suggesting use of the
detach-device command in cases where there are multiple matching mac
addresses.
Later we should decide how we want to input a PCI address on the virsh
commandline, and enhance detach-interface to take a --address option,
eliminating the need to use detach-device
* src/conf/domain_conf.c
* src/conf/domain_conf.h
* src/libvirt_private.syms
* added new virDomainNetFindIdx function
* removed now unused virDomainNetIndexByMac and
virDomainNetRemoveByMac
* src/qemu/qemu_driver.c
* remove check for duplicate max from qemuDomainAttachDeviceConfig
* use virDomainNetFindIdx/virDomainNetRemove instead
of virDomainNetRemoveByMac in qemuDomainDetachDeviceConfig
* use virDomainNetFindIdx instead of virDomainIndexByMac
in qemuDomainUpdateDeviceConfig
* src/qemu/qemu_hotplug.c
* use virDomainNetFindIdx instead of a homespun loop in
qemuDomainDetachNetDevice.
* tools/virsh-domain.c: modified detach-interface command as described
above
2012-10-25 20:03:35 +00:00
|
|
|
detachidx = virDomainNetFindIdx(vm->def, dev->data.net);
|
|
|
|
if (detachidx == -2) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("multiple devices matching mac address %s found"),
|
|
|
|
virMacAddrFormat(&dev->data.net->mac, mac));
|
|
|
|
goto cleanup;
|
2013-01-10 21:03:14 +00:00
|
|
|
}
|
qemu: fix attach/detach of netdevs with matching mac addrs
This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=862515
which describes inconsistencies in dealing with duplicate mac
addresses on network devices in a domain.
(at any rate, it resolves *almost* everything, and prints out an
informative error message for the one problem that isn't solved, but
has a workaround.)
A synopsis of the problems:
1) you can't do a persistent attach-interface of a device with a mac
address that matches an existing device.
2) you *can* do a live attach-interface of such a device.
3) you *can* directly edit a domain and put in two devices with
matching mac addresses.
4) When running virsh detach-device (live or config), only MAC address
is checked when matching the device to remove, so the first device
with the desired mac address will be removed. This isn't always the
one that's wanted.
5) when running virsh detach-interface (live or config), the only two
items that can be specified to match against are mac address and model
type (virtio, etc) - if multiple netdevs match both of those
attributes, it again just finds the first one added and assumes that
is the only match.
Since it is completely valid to have multiple network devices with the
same MAC address (although it can cause problems in many cases, there
*are* valid use cases), what is needed is:
1) remove the restriction that prohibits doing a persistent add of a
netdev with a duplicate mac address.
2) enhance the backend of virDomainDetachDeviceFlags to check for
something that *is* guaranteed unique (but still work with just mac
address, as long as it yields only a single results.
This patch does three things:
1) removes the check for duplicate mac address during a persistent
netdev attach.
2) unifies the searching for both live and config detach of netdevices
in the subordinate functions of qemuDomainModifyDeviceFlags() to use the
new function virDomainNetFindIdx (which matches mac address and PCI
address if available, checking for duplicates if only mac address was
specified). This function returns -2 if multiple matches are found,
allowing the callers to print out an appropriate message.
Steps 1 & 2 are enough to fully fix the problem when using virsh
attach-device and detach-device (which require an XML description of
the device rather than a bunch of commandline args)
3) modifies the virsh detach-interface command to check for multiple
matches of mac address and show an error message suggesting use of the
detach-device command in cases where there are multiple matching mac
addresses.
Later we should decide how we want to input a PCI address on the virsh
commandline, and enhance detach-interface to take a --address option,
eliminating the need to use detach-device
* src/conf/domain_conf.c
* src/conf/domain_conf.h
* src/libvirt_private.syms
* added new virDomainNetFindIdx function
* removed now unused virDomainNetIndexByMac and
virDomainNetRemoveByMac
* src/qemu/qemu_driver.c
* remove check for duplicate max from qemuDomainAttachDeviceConfig
* use virDomainNetFindIdx/virDomainNetRemove instead
of virDomainNetRemoveByMac in qemuDomainDetachDeviceConfig
* use virDomainNetFindIdx instead of virDomainIndexByMac
in qemuDomainUpdateDeviceConfig
* src/qemu/qemu_hotplug.c
* use virDomainNetFindIdx instead of a homespun loop in
qemuDomainDetachNetDevice.
* tools/virsh-domain.c: modified detach-interface command as described
above
2012-10-25 20:03:35 +00:00
|
|
|
else if (detachidx < 0) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
qemu: fix attach/detach of netdevs with matching mac addrs
This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=862515
which describes inconsistencies in dealing with duplicate mac
addresses on network devices in a domain.
(at any rate, it resolves *almost* everything, and prints out an
informative error message for the one problem that isn't solved, but
has a workaround.)
A synopsis of the problems:
1) you can't do a persistent attach-interface of a device with a mac
address that matches an existing device.
2) you *can* do a live attach-interface of such a device.
3) you *can* directly edit a domain and put in two devices with
matching mac addresses.
4) When running virsh detach-device (live or config), only MAC address
is checked when matching the device to remove, so the first device
with the desired mac address will be removed. This isn't always the
one that's wanted.
5) when running virsh detach-interface (live or config), the only two
items that can be specified to match against are mac address and model
type (virtio, etc) - if multiple netdevs match both of those
attributes, it again just finds the first one added and assumes that
is the only match.
Since it is completely valid to have multiple network devices with the
same MAC address (although it can cause problems in many cases, there
*are* valid use cases), what is needed is:
1) remove the restriction that prohibits doing a persistent add of a
netdev with a duplicate mac address.
2) enhance the backend of virDomainDetachDeviceFlags to check for
something that *is* guaranteed unique (but still work with just mac
address, as long as it yields only a single results.
This patch does three things:
1) removes the check for duplicate mac address during a persistent
netdev attach.
2) unifies the searching for both live and config detach of netdevices
in the subordinate functions of qemuDomainModifyDeviceFlags() to use the
new function virDomainNetFindIdx (which matches mac address and PCI
address if available, checking for duplicates if only mac address was
specified). This function returns -2 if multiple matches are found,
allowing the callers to print out an appropriate message.
Steps 1 & 2 are enough to fully fix the problem when using virsh
attach-device and detach-device (which require an XML description of
the device rather than a bunch of commandline args)
3) modifies the virsh detach-interface command to check for multiple
matches of mac address and show an error message suggesting use of the
detach-device command in cases where there are multiple matching mac
addresses.
Later we should decide how we want to input a PCI address on the virsh
commandline, and enhance detach-interface to take a --address option,
eliminating the need to use detach-device
* src/conf/domain_conf.c
* src/conf/domain_conf.h
* src/libvirt_private.syms
* added new virDomainNetFindIdx function
* removed now unused virDomainNetIndexByMac and
virDomainNetRemoveByMac
* src/qemu/qemu_driver.c
* remove check for duplicate max from qemuDomainAttachDeviceConfig
* use virDomainNetFindIdx/virDomainNetRemove instead
of virDomainNetRemoveByMac in qemuDomainDetachDeviceConfig
* use virDomainNetFindIdx instead of virDomainIndexByMac
in qemuDomainUpdateDeviceConfig
* src/qemu/qemu_hotplug.c
* use virDomainNetFindIdx instead of a homespun loop in
qemuDomainDetachNetDevice.
* tools/virsh-domain.c: modified detach-interface command as described
above
2012-10-25 20:03:35 +00:00
|
|
|
_("network device %s not found"),
|
|
|
|
virMacAddrFormat(&dev->data.net->mac, mac));
|
2012-02-27 12:03:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
qemu: fix attach/detach of netdevs with matching mac addrs
This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=862515
which describes inconsistencies in dealing with duplicate mac
addresses on network devices in a domain.
(at any rate, it resolves *almost* everything, and prints out an
informative error message for the one problem that isn't solved, but
has a workaround.)
A synopsis of the problems:
1) you can't do a persistent attach-interface of a device with a mac
address that matches an existing device.
2) you *can* do a live attach-interface of such a device.
3) you *can* directly edit a domain and put in two devices with
matching mac addresses.
4) When running virsh detach-device (live or config), only MAC address
is checked when matching the device to remove, so the first device
with the desired mac address will be removed. This isn't always the
one that's wanted.
5) when running virsh detach-interface (live or config), the only two
items that can be specified to match against are mac address and model
type (virtio, etc) - if multiple netdevs match both of those
attributes, it again just finds the first one added and assumes that
is the only match.
Since it is completely valid to have multiple network devices with the
same MAC address (although it can cause problems in many cases, there
*are* valid use cases), what is needed is:
1) remove the restriction that prohibits doing a persistent add of a
netdev with a duplicate mac address.
2) enhance the backend of virDomainDetachDeviceFlags to check for
something that *is* guaranteed unique (but still work with just mac
address, as long as it yields only a single results.
This patch does three things:
1) removes the check for duplicate mac address during a persistent
netdev attach.
2) unifies the searching for both live and config detach of netdevices
in the subordinate functions of qemuDomainModifyDeviceFlags() to use the
new function virDomainNetFindIdx (which matches mac address and PCI
address if available, checking for duplicates if only mac address was
specified). This function returns -2 if multiple matches are found,
allowing the callers to print out an appropriate message.
Steps 1 & 2 are enough to fully fix the problem when using virsh
attach-device and detach-device (which require an XML description of
the device rather than a bunch of commandline args)
3) modifies the virsh detach-interface command to check for multiple
matches of mac address and show an error message suggesting use of the
detach-device command in cases where there are multiple matching mac
addresses.
Later we should decide how we want to input a PCI address on the virsh
commandline, and enhance detach-interface to take a --address option,
eliminating the need to use detach-device
* src/conf/domain_conf.c
* src/conf/domain_conf.h
* src/libvirt_private.syms
* added new virDomainNetFindIdx function
* removed now unused virDomainNetIndexByMac and
virDomainNetRemoveByMac
* src/qemu/qemu_driver.c
* remove check for duplicate max from qemuDomainAttachDeviceConfig
* use virDomainNetFindIdx/virDomainNetRemove instead
of virDomainNetRemoveByMac in qemuDomainDetachDeviceConfig
* use virDomainNetFindIdx instead of virDomainIndexByMac
in qemuDomainUpdateDeviceConfig
* src/qemu/qemu_hotplug.c
* use virDomainNetFindIdx instead of a homespun loop in
qemuDomainDetachNetDevice.
* tools/virsh-domain.c: modified detach-interface command as described
above
2012-10-25 20:03:35 +00:00
|
|
|
detach = vm->def->nets[detachidx];
|
2012-02-27 12:03:12 +00:00
|
|
|
|
2012-03-12 15:50:02 +00:00
|
|
|
if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
|
2013-01-22 14:41:01 +00:00
|
|
|
/* coverity[negative_returns] */
|
2012-03-12 15:50:02 +00:00
|
|
|
ret = qemuDomainDetachThisHostDevice(driver, vm,
|
|
|
|
virDomainNetGetActualHostdev(detach),
|
|
|
|
-1);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2013-03-05 15:44:22 +00:00
|
|
|
if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
|
|
|
|
if (!virDomainDeviceAddressIsValid(&detach->info,
|
|
|
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("device cannot be detached without a CCW address"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!virDomainDeviceAddressIsValid(&detach->info,
|
|
|
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("device cannot be detached without a PCI address"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-03-12 15:50:02 +00:00
|
|
|
|
2013-03-05 15:44:22 +00:00
|
|
|
if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("cannot hot unplug multifunction PCI device :%s"),
|
|
|
|
dev->data.disk->dst);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-02-27 12:03:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((vlan = qemuDomainNetVLAN(detach)) < 0) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("unable to determine original VLAN"));
|
2012-02-27 12:03:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-07-04 10:14:12 +00:00
|
|
|
if (virAsprintf(&hostnet_name, "host%s", detach->info.alias) < 0)
|
2012-02-27 12:03:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2012-02-27 12:03:12 +00:00
|
|
|
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2012-02-27 12:03:12 +00:00
|
|
|
virDomainAuditNet(vm, detach, NULL, "detach", false);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (qemuMonitorRemovePCIDevice(priv->mon,
|
|
|
|
&detach->info.addr.pci) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2012-02-27 12:03:12 +00:00
|
|
|
virDomainAuditNet(vm, detach, NULL, "detach", false);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
2012-02-27 12:03:12 +00:00
|
|
|
if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2012-02-27 12:03:12 +00:00
|
|
|
virDomainAuditNet(vm, detach, NULL, "detach", false);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) {
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2012-02-27 12:03:12 +00:00
|
|
|
virDomainAuditNet(vm, detach, NULL, "detach", false);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2012-02-27 12:03:12 +00:00
|
|
|
|
|
|
|
virDomainAuditNet(vm, detach, NULL, "detach", true);
|
|
|
|
|
2013-03-05 15:44:22 +00:00
|
|
|
if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
|
|
|
|
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
|
|
|
|
if (qemuDomainCCWAddressReleaseAddr(priv->ccwaddrs, &detach->info) < 0)
|
|
|
|
VIR_WARN("Unable to release CCW address on NIC");
|
|
|
|
} else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
2012-02-27 12:03:12 +00:00
|
|
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
2013-02-15 06:48:49 +00:00
|
|
|
&detach->info.addr.pci) < 0)
|
2012-02-27 12:03:12 +00:00
|
|
|
VIR_WARN("Unable to release PCI address on NIC");
|
|
|
|
|
|
|
|
virDomainConfNWFilterTeardown(detach);
|
|
|
|
|
|
|
|
if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_DIRECT) {
|
|
|
|
ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
|
2012-07-17 12:07:59 +00:00
|
|
|
detach->ifname, &detach->mac,
|
2012-02-27 12:03:12 +00:00
|
|
|
virDomainNetGetActualDirectDev(detach),
|
|
|
|
virDomainNetGetActualDirectMode(detach),
|
|
|
|
virDomainNetGetActualVirtPortProfile(detach),
|
2013-01-10 21:03:14 +00:00
|
|
|
cfg->stateDir));
|
2012-02-27 12:03:12 +00:00
|
|
|
VIR_FREE(detach->ifname);
|
|
|
|
}
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
if (cfg->macFilter && (detach->ifname != NULL)) {
|
2012-02-27 12:03:12 +00:00
|
|
|
if ((errno = networkDisallowMacOnPort(driver,
|
|
|
|
detach->ifname,
|
2012-07-17 12:07:59 +00:00
|
|
|
&detach->mac))) {
|
2012-02-27 12:03:12 +00:00
|
|
|
virReportSystemError(errno,
|
2012-07-18 23:45:34 +00:00
|
|
|
_("failed to remove ebtables rule on '%s'"),
|
2012-02-27 12:03:12 +00:00
|
|
|
detach->ifname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vport = virDomainNetGetActualVirtPortProfile(detach);
|
|
|
|
if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH)
|
|
|
|
ignore_value(virNetDevOpenvswitchRemovePort(
|
|
|
|
virDomainNetGetActualBridgeName(detach),
|
|
|
|
detach->ifname));
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
qemu: support type=hostdev network device live hotplug attach/detach
qemuDomainAttachNetDevice
- re-ordered some things at start of function because
networkAllocateActualDevice should always be run and a slot
in def->nets always allocated, but host_net_add isn't needed
if the actual type is hostdev.
- if actual type is hostdev, defer to
qemuDomainAttachHostDevice (which will reach up to the NetDef
for things like MAC address when necessary). After return
from qemuDomainAttachHostDevice, slip directly to cleanup,
since the rest of the function is specific to emulated net
devices.
- put assignment of new NetDef into expanded def->nets down
below cleanup: (but only on success) since it is also needed
for emulated and hostdev net devices.
qemuDomainDetachHostDevice
- after locating the exact device to detach, check if it's a
network device and, if so, use toplevel
qemuDomainDetachNetDevice instead so that the def->nets list
is properly updated, and 'actual device' properly returned to
network pool if appropriate. Otherwise, for normal hostdevs,
call the lower level qemuDomainDetachThisDevice.
qemuDomainDetachNetDevice
- This is where it gets a bit tricky. After locating the device
on the def->nets list, if the network device type == hostdev,
call the *lower level* qemuDomainDetachThisDevice (which will
reach back up to the parent net device for MAC address /
virtualport when appropriate, then clear the device out of
def->hostdevs) before skipping past all the emulated
net-device-specific code to cleanup:, where the network
device is removed from def->nets, and the network device
object is freed.
In short, any time a hostdev-type network device is detached, we must
go through the toplevel virDomaineDetachNetDevice function first and
last, to make sure 1) the def->nnets list is properly managed, and 2)
any device allocated with networkAllocateActualDevice is properly
freed. At the same time, in the middle we need to go through the
lower-level vidDomainDetach*This*HostDevice to be sure that 1) the
def->hostdevs list is properly managed, 2) the PCI device is properly
detached from the guest and reattached to the host (if appropriate),
and 3) any higher level teardown is called at the appropriate time, by
reaching back up to the NetDef config (part (3) will be covered in a
separate patch).
2012-02-27 19:20:17 +00:00
|
|
|
if (!ret) {
|
|
|
|
networkReleaseActualDevice(detach);
|
qemu: fix attach/detach of netdevs with matching mac addrs
This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=862515
which describes inconsistencies in dealing with duplicate mac
addresses on network devices in a domain.
(at any rate, it resolves *almost* everything, and prints out an
informative error message for the one problem that isn't solved, but
has a workaround.)
A synopsis of the problems:
1) you can't do a persistent attach-interface of a device with a mac
address that matches an existing device.
2) you *can* do a live attach-interface of such a device.
3) you *can* directly edit a domain and put in two devices with
matching mac addresses.
4) When running virsh detach-device (live or config), only MAC address
is checked when matching the device to remove, so the first device
with the desired mac address will be removed. This isn't always the
one that's wanted.
5) when running virsh detach-interface (live or config), the only two
items that can be specified to match against are mac address and model
type (virtio, etc) - if multiple netdevs match both of those
attributes, it again just finds the first one added and assumes that
is the only match.
Since it is completely valid to have multiple network devices with the
same MAC address (although it can cause problems in many cases, there
*are* valid use cases), what is needed is:
1) remove the restriction that prohibits doing a persistent add of a
netdev with a duplicate mac address.
2) enhance the backend of virDomainDetachDeviceFlags to check for
something that *is* guaranteed unique (but still work with just mac
address, as long as it yields only a single results.
This patch does three things:
1) removes the check for duplicate mac address during a persistent
netdev attach.
2) unifies the searching for both live and config detach of netdevices
in the subordinate functions of qemuDomainModifyDeviceFlags() to use the
new function virDomainNetFindIdx (which matches mac address and PCI
address if available, checking for duplicates if only mac address was
specified). This function returns -2 if multiple matches are found,
allowing the callers to print out an appropriate message.
Steps 1 & 2 are enough to fully fix the problem when using virsh
attach-device and detach-device (which require an XML description of
the device rather than a bunch of commandline args)
3) modifies the virsh detach-interface command to check for multiple
matches of mac address and show an error message suggesting use of the
detach-device command in cases where there are multiple matching mac
addresses.
Later we should decide how we want to input a PCI address on the virsh
commandline, and enhance detach-interface to take a --address option,
eliminating the need to use detach-device
* src/conf/domain_conf.c
* src/conf/domain_conf.h
* src/libvirt_private.syms
* added new virDomainNetFindIdx function
* removed now unused virDomainNetIndexByMac and
virDomainNetRemoveByMac
* src/qemu/qemu_driver.c
* remove check for duplicate max from qemuDomainAttachDeviceConfig
* use virDomainNetFindIdx/virDomainNetRemove instead
of virDomainNetRemoveByMac in qemuDomainDetachDeviceConfig
* use virDomainNetFindIdx instead of virDomainIndexByMac
in qemuDomainUpdateDeviceConfig
* src/qemu/qemu_hotplug.c
* use virDomainNetFindIdx instead of a homespun loop in
qemuDomainDetachNetDevice.
* tools/virsh-domain.c: modified detach-interface command as described
above
2012-10-25 20:03:35 +00:00
|
|
|
virDomainNetRemove(vm->def, detachidx);
|
qemu: support type=hostdev network device live hotplug attach/detach
qemuDomainAttachNetDevice
- re-ordered some things at start of function because
networkAllocateActualDevice should always be run and a slot
in def->nets always allocated, but host_net_add isn't needed
if the actual type is hostdev.
- if actual type is hostdev, defer to
qemuDomainAttachHostDevice (which will reach up to the NetDef
for things like MAC address when necessary). After return
from qemuDomainAttachHostDevice, slip directly to cleanup,
since the rest of the function is specific to emulated net
devices.
- put assignment of new NetDef into expanded def->nets down
below cleanup: (but only on success) since it is also needed
for emulated and hostdev net devices.
qemuDomainDetachHostDevice
- after locating the exact device to detach, check if it's a
network device and, if so, use toplevel
qemuDomainDetachNetDevice instead so that the def->nets list
is properly updated, and 'actual device' properly returned to
network pool if appropriate. Otherwise, for normal hostdevs,
call the lower level qemuDomainDetachThisDevice.
qemuDomainDetachNetDevice
- This is where it gets a bit tricky. After locating the device
on the def->nets list, if the network device type == hostdev,
call the *lower level* qemuDomainDetachThisDevice (which will
reach back up to the parent net device for MAC address /
virtualport when appropriate, then clear the device out of
def->hostdevs) before skipping past all the emulated
net-device-specific code to cleanup:, where the network
device is removed from def->nets, and the network device
object is freed.
In short, any time a hostdev-type network device is detached, we must
go through the toplevel virDomaineDetachNetDevice function first and
last, to make sure 1) the def->nnets list is properly managed, and 2)
any device allocated with networkAllocateActualDevice is properly
freed. At the same time, in the middle we need to go through the
lower-level vidDomainDetach*This*HostDevice to be sure that 1) the
def->hostdevs list is properly managed, 2) the PCI device is properly
detached from the guest and reattached to the host (if appropriate),
and 3) any higher level teardown is called at the appropriate time, by
reaching back up to the NetDef config (part (3) will be covered in a
separate patch).
2012-02-27 19:20:17 +00:00
|
|
|
virDomainNetDefFree(detach);
|
|
|
|
}
|
2012-02-27 12:03:12 +00:00
|
|
|
VIR_FREE(hostnet_name);
|
2013-01-10 21:03:14 +00:00
|
|
|
virObjectUnref(cfg);
|
2012-02-27 12:03:12 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
int
|
2012-11-28 16:43:10 +00:00
|
|
|
qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
int type,
|
|
|
|
virDomainGraphicsAuthDefPtr auth,
|
|
|
|
const char *defaultPasswd)
|
|
|
|
{
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
time_t now = time(NULL);
|
|
|
|
char expire_time [64];
|
2011-05-26 14:15:54 +00:00
|
|
|
const char *connected = NULL;
|
2013-01-10 21:03:14 +00:00
|
|
|
int ret = -1;
|
|
|
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
|
2013-04-19 05:00:44 +00:00
|
|
|
if (!auth->passwd && !defaultPasswd) {
|
2013-01-10 21:03:14 +00:00
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
|
2011-05-26 14:15:54 +00:00
|
|
|
if (auth->connected)
|
|
|
|
connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected);
|
|
|
|
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
ret = qemuMonitorSetPassword(priv->mon,
|
|
|
|
type,
|
|
|
|
auth->passwd ? auth->passwd : defaultPasswd,
|
2011-05-26 14:15:54 +00:00
|
|
|
connected);
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
|
|
|
|
if (ret == -2) {
|
|
|
|
if (type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Graphics password only supported for VNC"));
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
ret = -1;
|
|
|
|
} else {
|
|
|
|
ret = qemuMonitorSetVNCPassword(priv->mon,
|
|
|
|
auth->passwd ? auth->passwd : defaultPasswd);
|
|
|
|
}
|
|
|
|
}
|
2011-01-18 18:37:45 +00:00
|
|
|
if (ret != 0)
|
2013-01-10 21:03:14 +00:00
|
|
|
goto end_job;
|
2011-01-18 18:37:45 +00:00
|
|
|
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
if (auth->expires) {
|
|
|
|
time_t lifetime = auth->validTo - now;
|
|
|
|
if (lifetime <= 0)
|
2012-03-29 09:52:04 +00:00
|
|
|
snprintf(expire_time, sizeof(expire_time), "now");
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
else
|
2012-03-29 09:52:04 +00:00
|
|
|
snprintf(expire_time, sizeof(expire_time), "%lu", (long unsigned)auth->validTo);
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
} else {
|
2012-03-29 09:52:04 +00:00
|
|
|
snprintf(expire_time, sizeof(expire_time), "never");
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = qemuMonitorExpirePassword(priv->mon, type, expire_time);
|
|
|
|
|
|
|
|
if (ret == -2) {
|
|
|
|
/* XXX we could fake this with a timer */
|
|
|
|
if (auth->expires) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Expiry of passwords is not supported"));
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
ret = -1;
|
2011-01-18 18:37:45 +00:00
|
|
|
} else {
|
|
|
|
ret = 0;
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
end_job:
|
2013-02-06 18:17:20 +00:00
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
2013-01-10 21:03:14 +00:00
|
|
|
cleanup:
|
|
|
|
virObjectUnref(cfg);
|
Use the new set_password monitor command to set password.
We try to use that command first when setting a VNC/SPICE password. If
that doesn't work we fallback to the legacy VNC only password
Allow an expiry time to be set, if that doesn't work, throw an error
if they try to use SPICE.
Change since v1:
- moved qemuInitGraphicsPasswords to qemu_hotplug, renamed
to qemuDomainChangeGraphicsPasswords.
- updated what looks like a typo (that appears to work anyway) in
initial patch from Daniel:
- ret = qemuInitGraphicsPasswords(driver, vm,
- VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
- &vm->def->graphics[0]->data.vnc.auth,
- driver->vncPassword);
+ ret = qemuInitGraphicsPasswords(driver, vm,
+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
+ &vm->def->graphics[0]->data.spice.auth,
+ driver->spicePassword);
Based on patch by Daniel P. Berrange <berrange@redhat.com>.
2011-01-10 11:12:33 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2011-05-18 16:20:53 +00:00
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainAttachLease(virQEMUDriverPtr driver,
|
2011-05-18 16:20:53 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainLeaseDefPtr lease)
|
|
|
|
{
|
2013-01-10 21:03:14 +00:00
|
|
|
int ret = -1;
|
|
|
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
|
|
|
|
2011-05-18 16:20:53 +00:00
|
|
|
if (virDomainLeaseInsertPreAlloc(vm->def) < 0)
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2011-05-18 16:20:53 +00:00
|
|
|
|
2013-01-10 21:03:14 +00:00
|
|
|
if (virDomainLockLeaseAttach(driver->lockManager, cfg->uri,
|
2012-09-17 13:36:47 +00:00
|
|
|
vm, lease) < 0) {
|
2011-05-18 16:20:53 +00:00
|
|
|
virDomainLeaseInsertPreAlloced(vm->def, NULL);
|
2013-01-10 21:03:14 +00:00
|
|
|
goto cleanup;
|
2011-05-18 16:20:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
virDomainLeaseInsertPreAlloced(vm->def, lease);
|
2013-01-10 21:03:14 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virObjectUnref(cfg);
|
|
|
|
return ret;
|
2011-05-18 16:20:53 +00:00
|
|
|
}
|
|
|
|
|
2012-11-28 16:43:10 +00:00
|
|
|
int qemuDomainDetachLease(virQEMUDriverPtr driver,
|
2011-05-18 16:20:53 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainLeaseDefPtr lease)
|
|
|
|
{
|
util: eliminate device object leaks related to virDomain*Remove*()
There are several functions in domain_conf.c that remove a device
object from the domain's list of that object type, but don't free the
object or return it to the caller to free. In many cases this isn't a
problem because the caller already had a pointer to the object and
frees it afterward, but in several cases the removed object was just
left floating around with no references to it.
In particular, the function qemuDomainDetachDeviceConfig() calls
functions to locate and remove net (virDomainNetRemoveByMac), disk
(virDomainDiskRemoveByName()), and lease (virDomainLeaseRemove())
devices, but neither it nor its caller qemuDomainModifyDeviceConfig()
ever obtain a pointer to the device being removed, much less free it.
This patch modifies the following "remove" functions to return a
pointer to the device object being removed from the domain device
arrays, to give the caller the option of freeing the device object
using that pointer if needed. In places where the object was
previously leaked, it is now freed:
virDomainDiskRemove
virDomainDiskRemoveByName
virDomainNetRemove
virDomainNetRemoveByMac
virDomainHostdevRemove
virDomainLeaseRemove
virDomainLeaseRemoveAt
The functions that had been leaking:
libxlDomainDetachConfig - leaked a virDomainDiskDef
qemuDomainDetachDeviceConfig - could leak a virDomainDiskDef,
a virDomainNetDef, or a
virDomainLeaseDef
qemuDomainDetachLease - leaked a virDomainLeaseDef
2012-03-06 23:06:14 +00:00
|
|
|
virDomainLeaseDefPtr det_lease;
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
int idx;
|
2011-05-18 16:20:53 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
if ((idx = virDomainLeaseIndex(vm->def, lease)) < 0) {
|
2012-07-18 15:22:03 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("Lease %s in lockspace %s does not exist"),
|
|
|
|
lease->key, NULLSTR(lease->lockspace));
|
2011-05-18 16:20:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virDomainLockLeaseDetach(driver->lockManager, vm, lease) < 0)
|
|
|
|
return -1;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/qemu files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
det_lease = virDomainLeaseRemoveAt(vm->def, idx);
|
util: eliminate device object leaks related to virDomain*Remove*()
There are several functions in domain_conf.c that remove a device
object from the domain's list of that object type, but don't free the
object or return it to the caller to free. In many cases this isn't a
problem because the caller already had a pointer to the object and
frees it afterward, but in several cases the removed object was just
left floating around with no references to it.
In particular, the function qemuDomainDetachDeviceConfig() calls
functions to locate and remove net (virDomainNetRemoveByMac), disk
(virDomainDiskRemoveByName()), and lease (virDomainLeaseRemove())
devices, but neither it nor its caller qemuDomainModifyDeviceConfig()
ever obtain a pointer to the device being removed, much less free it.
This patch modifies the following "remove" functions to return a
pointer to the device object being removed from the domain device
arrays, to give the caller the option of freeing the device object
using that pointer if needed. In places where the object was
previously leaked, it is now freed:
virDomainDiskRemove
virDomainDiskRemoveByName
virDomainNetRemove
virDomainNetRemoveByMac
virDomainHostdevRemove
virDomainLeaseRemove
virDomainLeaseRemoveAt
The functions that had been leaking:
libxlDomainDetachConfig - leaked a virDomainDiskDef
qemuDomainDetachDeviceConfig - could leak a virDomainDiskDef,
a virDomainNetDef, or a
virDomainLeaseDef
qemuDomainDetachLease - leaked a virDomainLeaseDef
2012-03-06 23:06:14 +00:00
|
|
|
virDomainLeaseDefFree(det_lease);
|
2011-05-18 16:20:53 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2013-03-13 10:08:55 +00:00
|
|
|
|
|
|
|
int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
|
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainChrDefPtr chr)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
|
virDomainDefPtr vmdef = vm->def;
|
|
|
|
virDomainChrDefPtr tmpChr;
|
|
|
|
char *charAlias = NULL;
|
|
|
|
char *devstr = NULL;
|
|
|
|
|
|
|
|
if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("device not present in domain configuration"));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemuBuildChrDeviceStr(&devstr, vm->def, chr, priv->qemuCaps) < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (virAsprintf(&charAlias, "char%s", tmpChr->info.alias) < 0) {
|
|
|
|
virReportOOMError();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
qemuDomainObjEnterMonitor(driver, vm);
|
|
|
|
if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
|
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemuMonitorDetachCharDev(priv->mon, charAlias) < 0) {
|
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
qemuDomainObjExitMonitor(driver, vm);
|
|
|
|
|
|
|
|
qemuDomainChrRemove(vmdef, tmpChr);
|
|
|
|
virDomainChrDefFree(tmpChr);
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(devstr);
|
|
|
|
VIR_FREE(charAlias);
|
|
|
|
return ret;
|
|
|
|
}
|