2010-12-16 15:07:07 +00:00
|
|
|
/*
|
|
|
|
* qemu_command.h: QEMU command generation
|
|
|
|
*
|
qemu: allocate network connections sooner during domain startup
VFIO device assignment requires a cgroup ACL to be setup for access to
the /dev/vfio/nn "group" device for any devices that will be assigned
to a guest. In the case of a host device that is allocated from a
pool, it was being allocated during qemuBuildCommandLine(), which is
called by qemuProcessStart() *after* the all-encompassing
qemuSetupCgroup() was called, meaning that the standard Cgroup ACL
setup wasn't creating ACLs for these devices allocated from pools.
One possible solution was to manually add a single ACL down inside
qemuBuildCommandLine() when networkAllocateActualDevice() is called,
but that has two problems: 1) the function that adds the cgroup ACL
requires a virDomainObjPtr, which isn't available in
qemuBuildCommandLine(), and 2) we really shouldn't be doing network
device setup inside qemuBuildCommandLine() anyway.
Instead, I've created a new function called
qemuNetworkPrepareDevices() which is called just before
qemuPrepareHostDevices() during qemuProcessStart() (explanation of
ordering in the comments), i.e. well before the call to
qemuSetupCgroup(). To minimize code churn in a patch that will be
backported to 1.0.5-maint, qemuNetworkPrepareDevices only does
networkAllocateActualDevice() and the bare amount of setup required
for type='hostdev network devices, but it eventually should do *all*
device setup for guest network devices.
Note that some of the code that was previously needed in
qemuBuildCommandLine() is no longer required when
networkAllocateActualDevice() is called earlier:
* qemuAssignDeviceHostdevAlias() is already done further down in
qemuProcessStart().
* qemuPrepareHostdevPCIDevices() is called by
qemuPrepareHostDevices() which is called after
qemuNetworkPrepareDevices() in qemuProcessStart().
As hinted above, this new function should be moved into a separate
qemu_network.c (or similarly named) file along with
qemuPhysIfaceConnect(), qemuNetworkIfaceConnect(), and
qemuOpenVhostNet(), and expanded to call those functions as well, then
the nnets loop in qemuBuildCommandLine() should be reduced to only
build the commandline string (which itself can be in a separate
qemuInterfaceBuilldCommandLine() function as suggested by
Michal). However, this will require storing away an array of tapfd and
vhostfd that are needed for the commandline, so I would rather do that
in a separate patch and leave this patch at the minimum to fix the
bug.
2013-05-06 19:43:56 +00:00
|
|
|
* Copyright (C) 2006-2013 Red Hat, Inc.
|
2010-12-16 15:07:07 +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 15:07:07 +00:00
|
|
|
*
|
|
|
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __QEMU_COMMAND_H__
|
|
|
|
# define __QEMU_COMMAND_H__
|
|
|
|
|
|
|
|
# include "domain_conf.h"
|
2012-12-12 16:27:01 +00:00
|
|
|
# include "vircommand.h"
|
2010-12-16 15:07:07 +00:00
|
|
|
# include "capabilities.h"
|
|
|
|
# include "qemu_conf.h"
|
2010-12-16 15:23:41 +00:00
|
|
|
# include "qemu_domain.h"
|
2012-08-20 16:44:14 +00:00
|
|
|
# include "qemu_capabilities.h"
|
2010-12-16 15:07:07 +00:00
|
|
|
|
|
|
|
/* Config type for XML import/export conversions */
|
|
|
|
# define QEMU_CONFIG_FORMAT_ARGV "qemu-argv"
|
|
|
|
|
|
|
|
# define QEMU_DRIVE_HOST_PREFIX "drive-"
|
|
|
|
# define QEMU_VIRTIO_SERIAL_PREFIX "virtio-serial"
|
|
|
|
# define QEMU_FSDEV_HOST_PREFIX "fsdev-"
|
|
|
|
|
2012-06-18 08:22:07 +00:00
|
|
|
/* These are only defaults, they can be changed now in qemu.conf and
|
|
|
|
* explicitely specified port is checked against these two (makes
|
|
|
|
* sense to limit the values).
|
|
|
|
*
|
|
|
|
* This limitation is mentioned in qemu.conf, so bear in mind that the
|
|
|
|
* configuration file should reflect any changes made to these values.
|
|
|
|
*/
|
2012-06-18 07:58:31 +00:00
|
|
|
# define QEMU_REMOTE_PORT_MIN 5900
|
|
|
|
# define QEMU_REMOTE_PORT_MAX 65535
|
2011-02-14 16:09:39 +00:00
|
|
|
|
2013-04-30 14:26:43 +00:00
|
|
|
# define QEMU_WEBSOCKET_PORT_MIN 5700
|
|
|
|
# define QEMU_WEBSOCKET_PORT_MAX 65535
|
|
|
|
|
2013-10-11 03:27:13 +00:00
|
|
|
# define QEMU_MIGRATION_PORT_MIN 49152
|
|
|
|
# define QEMU_MIGRATION_PORT_MAX 49215
|
|
|
|
|
2013-05-17 10:34:24 +00:00
|
|
|
typedef struct _qemuBuildCommandLineCallbacks qemuBuildCommandLineCallbacks;
|
|
|
|
typedef qemuBuildCommandLineCallbacks *qemuBuildCommandLineCallbacksPtr;
|
|
|
|
struct _qemuBuildCommandLineCallbacks {
|
|
|
|
char * (*qemuGetSCSIDeviceSgName) (const char *adapter,
|
|
|
|
unsigned int bus,
|
|
|
|
unsigned int target,
|
|
|
|
unsigned int unit);
|
|
|
|
};
|
|
|
|
|
|
|
|
extern qemuBuildCommandLineCallbacks buildCommandLineCallbacks;
|
2011-02-14 16:09:39 +00:00
|
|
|
|
2010-12-16 15:07:07 +00:00
|
|
|
virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
|
2012-11-28 16:43:10 +00:00
|
|
|
virQEMUDriverPtr driver,
|
2010-12-16 15:07:07 +00:00
|
|
|
virDomainDefPtr def,
|
2011-01-07 23:36:25 +00:00
|
|
|
virDomainChrSourceDefPtr monitor_chr,
|
2010-12-16 15:07:07 +00:00
|
|
|
bool monitor_json,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps,
|
2010-12-16 15:07:07 +00:00
|
|
|
const char *migrateFrom,
|
2010-12-22 22:13:29 +00:00
|
|
|
int migrateFd,
|
2010-12-16 15:07:07 +00:00
|
|
|
virDomainSnapshotObjPtr current_snapshot,
|
2013-05-17 10:34:24 +00:00
|
|
|
enum virNetDevVPortProfileOp vmop,
|
|
|
|
qemuBuildCommandLineCallbacksPtr callbacks)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(11);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
2013-03-13 15:20:34 +00:00
|
|
|
/* Generate '-device' string for chardev device */
|
|
|
|
int
|
|
|
|
qemuBuildChrDeviceStr(char **deviceStr,
|
|
|
|
virDomainDefPtr vmdef,
|
|
|
|
virDomainChrDefPtr chr,
|
|
|
|
virQEMUCapsPtr qemuCaps);
|
2011-11-21 12:50:42 +00:00
|
|
|
|
2010-12-16 15:07:07 +00:00
|
|
|
/* With vlan == -1, use netdev syntax, else old hostnet */
|
|
|
|
char * qemuBuildHostNetStr(virDomainNetDefPtr net,
|
2012-11-28 16:43:10 +00:00
|
|
|
virQEMUDriverPtr driver,
|
2010-12-16 15:07:07 +00:00
|
|
|
char type_sep,
|
|
|
|
int vlan,
|
2013-05-21 13:50:09 +00:00
|
|
|
char **tapfd,
|
|
|
|
int tapfdSize,
|
|
|
|
char **vhostfd,
|
|
|
|
int vhostfdSize);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
|
|
|
/* Legacy, pre device support */
|
|
|
|
char * qemuBuildNicStr(virDomainNetDefPtr net,
|
|
|
|
const char *prefix,
|
|
|
|
int vlan);
|
|
|
|
|
|
|
|
/* Current, best practice */
|
2013-08-02 17:48:50 +00:00
|
|
|
char * qemuBuildNicDevStr(virDomainDefPtr def,
|
|
|
|
virDomainNetDefPtr net,
|
2011-01-12 10:33:34 +00:00
|
|
|
int vlan,
|
2011-05-26 14:15:01 +00:00
|
|
|
int bootindex,
|
2013-08-22 08:19:08 +00:00
|
|
|
bool multiqueue,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
|
|
|
char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
|
|
|
/* Both legacy & current support */
|
2011-10-31 19:06:23 +00:00
|
|
|
char *qemuBuildDriveStr(virConnectPtr conn,
|
|
|
|
virDomainDiskDefPtr disk,
|
2011-05-26 14:15:01 +00:00
|
|
|
bool bootable,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
char *qemuBuildFSStr(virDomainFSDefPtr fs,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
|
|
|
/* Current, best practice */
|
qemu: Build command line for the new address format
For any disk controller model which is not "lsilogic", the command
line will be like:
-drive file=/dev/sda,if=none,id=drive-scsi0-0-3-0,format=raw \
-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=3,lun=0,i\
drive=drive-scsi0-0-3-0,id=scsi0-0-3-0
The relationship between the libvirt address attrs and the qdev
properties are (controller model is not "lsilogic"; strings
inside <> represent libvirt adress attrs):
bus=scsi<controller>.0
channel=<bus>
scsi-id=<target>
lun=<unit>
* src/qemu/qemu_command.h: (New param "virDomainDefPtr def"
for function qemuBuildDriveDevStr; new param "virDomainDefPtr
vmdef" for function qemuAssignDeviceDiskAlias. Both for
virDomainDiskFindControllerModel's use).
* src/qemu/qemu_command.c:
- New param "virDomainDefPtr def" for qemuAssignDeviceDiskAliasCustom.
For virDomainDiskFindControllerModel's use, if the disk bus is "scsi"
and the controller model is not "lsilogic", "target" is one part of
the alias name.
- According change on qemuAssignDeviceDiskAlias and qemuBuildDriveDevStr
* src/qemu/qemu_hotplug.c:
- Changes to be consistent with declarations of qemuAssignDeviceDiskAlias
qemuBuildDriveDevStr, and qemuBuildControllerDevStr.
* tests/qemuxml2argvdata/qemuxml2argv-pseries-vio-user-assigned.args,
tests/qemuxml2argvdata/qemuxml2argv-pseries-vio.args: Update the
generated command line.
2012-02-28 03:39:43 +00:00
|
|
|
char * qemuBuildDriveDevStr(virDomainDefPtr def,
|
|
|
|
virDomainDiskDefPtr disk,
|
2011-05-26 14:15:01 +00:00
|
|
|
int bootindex,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2013-08-02 17:48:50 +00:00
|
|
|
char * qemuBuildFSDevStr(virDomainDefPtr domainDef,
|
|
|
|
virDomainFSDefPtr fs,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
/* Current, best practice */
|
2011-12-08 06:41:24 +00:00
|
|
|
char * qemuBuildControllerDevStr(virDomainDefPtr domainDef,
|
|
|
|
virDomainControllerDefPtr def,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps,
|
2011-09-02 13:21:23 +00:00
|
|
|
int *nusbcontroller);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
2013-08-02 17:48:50 +00:00
|
|
|
char * qemuBuildWatchdogDevStr(virDomainDefPtr domainDef,
|
|
|
|
virDomainWatchdogDefPtr dev,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
2013-08-02 17:48:50 +00:00
|
|
|
char * qemuBuildMemballoonDevStr(virDomainDefPtr domainDef,
|
|
|
|
virDomainMemballoonDefPtr dev,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
2013-08-02 17:48:50 +00:00
|
|
|
char * qemuBuildUSBInputDevStr(virDomainDefPtr domainDef,
|
|
|
|
virDomainInputDefPtr dev,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
2013-08-02 17:48:50 +00:00
|
|
|
char * qemuBuildSoundDevStr(virDomainDefPtr domainDef,
|
|
|
|
virDomainSoundDefPtr sound,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
|
|
|
/* Legacy, pre device support */
|
|
|
|
char * qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev);
|
|
|
|
/* Current, best practice */
|
2013-08-02 17:48:50 +00:00
|
|
|
char * qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
|
|
|
|
virDomainHostdevDefPtr dev,
|
2011-02-01 16:22:01 +00:00
|
|
|
const char *configfd,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
|
|
|
int qemuOpenPCIConfig(virDomainHostdevDefPtr dev);
|
|
|
|
|
|
|
|
/* Legacy, pre device support */
|
|
|
|
char * qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev);
|
|
|
|
/* Current, best practice */
|
2013-08-02 17:48:50 +00:00
|
|
|
char * qemuBuildUSBHostdevDevStr(virDomainDefPtr def,
|
|
|
|
virDomainHostdevDefPtr dev,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
qemu: Build qemu command line for scsi host device
Except the scsi host device's controller is "lsilogic", mapping
between the libvirt attributes and scsi-generic properties is:
libvirt qemu
-----------------------------------------
controller bus ($libvirt_controller.0)
bus channel
target scsi-id
unit lun
For scsi host device with "lsilogic" controller, the mapping is:
('target (libvirt)' must be 0, as it's not used; 'unit (libvirt)
must <= 7).
libvirt qemu
----------------------------------------------------------
controller && bus bus ($libvirt_controller.$libvirt_bus)
unit scsi-id
It's not good to hardcode/hard-check limits of these attributes,
and even worse, these limits are not documented, one has to find
out by either testing or reading the qemu code, I'm looking forward
to qemu expose limits like these one day). For example, exposing
"max_target", "max_lun" for megasas:
static const struct SCSIBusInfo megasas_scsi_info = {
.tcq = true,
.max_target = MFI_MAX_LD,
.max_lun = 255,
.transfer_data = megasas_xfer_complete,
.get_sg_list = megasas_get_sg_list,
.complete = megasas_command_complete,
.cancel = megasas_command_cancel,
};
Example of the qemu command line (lsilogic controller):
-drive file=/dev/sg2,if=none,id=drive-hostdev-scsi_host7-0-0-0 \
-device scsi-generic,bus=scsi0.0,scsi-id=8,\
drive=drive-hostdev-scsi_host7-0-0-0,id=hostdev-scsi_host7-0-0-0
Example of the qemu command line (virtio-scsi controller):
-drive file=/dev/sg2,if=none,id=drive-hostdev-scsi_host7-0-0-0 \
-device scsi-generic,bus=scsi0.0,channel=0,scsi-id=128,lun=128,\
drive=drive-hostdev-scsi_host7-0-0-0,id=hostdev-scsi_host7-0-0-0
Signed-off-by: Han Cheng <hanc.fnst@cn.fujitsu.com>
Signed-off-by: Osier Yang <jyang@redhat.com>
2013-05-03 18:07:23 +00:00
|
|
|
char * qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
|
2013-05-17 10:34:24 +00:00
|
|
|
virQEMUCapsPtr qemuCaps,
|
|
|
|
qemuBuildCommandLineCallbacksPtr callbacks)
|
|
|
|
ATTRIBUTE_NONNULL(3);
|
qemu: Build qemu command line for scsi host device
Except the scsi host device's controller is "lsilogic", mapping
between the libvirt attributes and scsi-generic properties is:
libvirt qemu
-----------------------------------------
controller bus ($libvirt_controller.0)
bus channel
target scsi-id
unit lun
For scsi host device with "lsilogic" controller, the mapping is:
('target (libvirt)' must be 0, as it's not used; 'unit (libvirt)
must <= 7).
libvirt qemu
----------------------------------------------------------
controller && bus bus ($libvirt_controller.$libvirt_bus)
unit scsi-id
It's not good to hardcode/hard-check limits of these attributes,
and even worse, these limits are not documented, one has to find
out by either testing or reading the qemu code, I'm looking forward
to qemu expose limits like these one day). For example, exposing
"max_target", "max_lun" for megasas:
static const struct SCSIBusInfo megasas_scsi_info = {
.tcq = true,
.max_target = MFI_MAX_LD,
.max_lun = 255,
.transfer_data = megasas_xfer_complete,
.get_sg_list = megasas_get_sg_list,
.complete = megasas_command_complete,
.cancel = megasas_command_cancel,
};
Example of the qemu command line (lsilogic controller):
-drive file=/dev/sg2,if=none,id=drive-hostdev-scsi_host7-0-0-0 \
-device scsi-generic,bus=scsi0.0,scsi-id=8,\
drive=drive-hostdev-scsi_host7-0-0-0,id=hostdev-scsi_host7-0-0-0
Example of the qemu command line (virtio-scsi controller):
-drive file=/dev/sg2,if=none,id=drive-hostdev-scsi_host7-0-0-0 \
-device scsi-generic,bus=scsi0.0,channel=0,scsi-id=128,lun=128,\
drive=drive-hostdev-scsi_host7-0-0-0,id=hostdev-scsi_host7-0-0-0
Signed-off-by: Han Cheng <hanc.fnst@cn.fujitsu.com>
Signed-off-by: Osier Yang <jyang@redhat.com>
2013-05-03 18:07:23 +00:00
|
|
|
char * qemuBuildSCSIHostdevDevStr(virDomainDefPtr def,
|
|
|
|
virDomainHostdevDefPtr dev,
|
|
|
|
virQEMUCapsPtr qemuCaps);
|
|
|
|
|
2013-08-02 17:48:50 +00:00
|
|
|
char * qemuBuildHubDevStr(virDomainDefPtr def,
|
|
|
|
virDomainHubDefPtr dev,
|
|
|
|
virQEMUCapsPtr qemuCaps);
|
2012-09-13 07:25:46 +00:00
|
|
|
char * qemuBuildRedirdevDevStr(virDomainDefPtr def,
|
|
|
|
virDomainRedirdevDefPtr dev,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2013-11-15 15:29:35 +00:00
|
|
|
char *qemuBuildNetworkDriveURI(int proto,
|
|
|
|
const char *src,
|
|
|
|
size_t nhosts,
|
|
|
|
virDomainDiskHostDefPtr hosts,
|
|
|
|
const char *username,
|
|
|
|
const char *secret);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
audit: audit use of /dev/net/tun, /dev/tapN, /dev/vhost-net
Opening raw network devices with the intent of passing those fds to
qemu is worth an audit point. This makes a multi-part audit: first,
we audit the device(s) that libvirt opens on behalf of the MAC address
of a to-be-created interface (which can independently succeed or
fail), then we audit whether qemu actually started the network device
with the same MAC (so searching backwards for successful audits with
the same MAC will show which fd(s) qemu is actually using). Note that
it is possible for the fd to be successfully opened but no attempt
made to pass the fd to qemu (for example, because intermediate
nwfilter operations failed) - no interface start audit will occur in
that case; so the audit for a successful opened fd does not imply
rights given to qemu unless there is a followup audit about the
attempt to start a new interface.
Likewise, when a network device is hot-unplugged, there is only one
audit message about the MAC being discontinued; again, searching back
to the earlier device open audits will show which fds that qemu quits
using (and yes, I checked via /proc/<qemu-pid>/fd that qemu _does_
close out the fds associated with an interface on hot-unplug). The
code would require much more refactoring to be able to definitively
state which device(s) were discontinued at that point, since we
currently don't record anywhere in the XML whether /dev/vhost-net was
opened for a given interface.
* src/qemu/qemu_audit.h (qemuAuditNetDevice): New prototype.
* src/qemu/qemu_audit.c (qemuAuditNetDevice): New function.
* src/qemu/qemu_command.h (qemuNetworkIfaceConnect)
(qemuPhysIfaceConnect, qemuOpenVhostNet): Adjust prototype.
* src/qemu/qemu_command.c (qemuNetworkIfaceConnect)
(qemuPhysIfaceConnect, qemuOpenVhostNet): Add audit points and
adjust parameters.
(qemuBuildCommandLine): Adjust caller.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
2011-03-08 18:00:59 +00:00
|
|
|
int qemuNetworkIfaceConnect(virDomainDefPtr def,
|
|
|
|
virConnectPtr conn,
|
2012-11-28 16:43:10 +00:00
|
|
|
virQEMUDriverPtr driver,
|
2010-12-16 15:07:07 +00:00
|
|
|
virDomainNetDefPtr net,
|
2013-05-21 13:50:09 +00:00
|
|
|
virQEMUCapsPtr qemuCaps,
|
|
|
|
int *tapfd,
|
|
|
|
int *tapfdSize)
|
audit: audit use of /dev/net/tun, /dev/tapN, /dev/vhost-net
Opening raw network devices with the intent of passing those fds to
qemu is worth an audit point. This makes a multi-part audit: first,
we audit the device(s) that libvirt opens on behalf of the MAC address
of a to-be-created interface (which can independently succeed or
fail), then we audit whether qemu actually started the network device
with the same MAC (so searching backwards for successful audits with
the same MAC will show which fd(s) qemu is actually using). Note that
it is possible for the fd to be successfully opened but no attempt
made to pass the fd to qemu (for example, because intermediate
nwfilter operations failed) - no interface start audit will occur in
that case; so the audit for a successful opened fd does not imply
rights given to qemu unless there is a followup audit about the
attempt to start a new interface.
Likewise, when a network device is hot-unplugged, there is only one
audit message about the MAC being discontinued; again, searching back
to the earlier device open audits will show which fds that qemu quits
using (and yes, I checked via /proc/<qemu-pid>/fd that qemu _does_
close out the fds associated with an interface on hot-unplug). The
code would require much more refactoring to be able to definitively
state which device(s) were discontinued at that point, since we
currently don't record anywhere in the XML whether /dev/vhost-net was
opened for a given interface.
* src/qemu/qemu_audit.h (qemuAuditNetDevice): New prototype.
* src/qemu/qemu_audit.c (qemuAuditNetDevice): New function.
* src/qemu/qemu_command.h (qemuNetworkIfaceConnect)
(qemuPhysIfaceConnect, qemuOpenVhostNet): Adjust prototype.
* src/qemu/qemu_command.c (qemuNetworkIfaceConnect)
(qemuPhysIfaceConnect, qemuOpenVhostNet): Add audit points and
adjust parameters.
(qemuBuildCommandLine): Adjust caller.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
2011-03-08 18:00:59 +00:00
|
|
|
ATTRIBUTE_NONNULL(2);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
audit: audit use of /dev/net/tun, /dev/tapN, /dev/vhost-net
Opening raw network devices with the intent of passing those fds to
qemu is worth an audit point. This makes a multi-part audit: first,
we audit the device(s) that libvirt opens on behalf of the MAC address
of a to-be-created interface (which can independently succeed or
fail), then we audit whether qemu actually started the network device
with the same MAC (so searching backwards for successful audits with
the same MAC will show which fd(s) qemu is actually using). Note that
it is possible for the fd to be successfully opened but no attempt
made to pass the fd to qemu (for example, because intermediate
nwfilter operations failed) - no interface start audit will occur in
that case; so the audit for a successful opened fd does not imply
rights given to qemu unless there is a followup audit about the
attempt to start a new interface.
Likewise, when a network device is hot-unplugged, there is only one
audit message about the MAC being discontinued; again, searching back
to the earlier device open audits will show which fds that qemu quits
using (and yes, I checked via /proc/<qemu-pid>/fd that qemu _does_
close out the fds associated with an interface on hot-unplug). The
code would require much more refactoring to be able to definitively
state which device(s) were discontinued at that point, since we
currently don't record anywhere in the XML whether /dev/vhost-net was
opened for a given interface.
* src/qemu/qemu_audit.h (qemuAuditNetDevice): New prototype.
* src/qemu/qemu_audit.c (qemuAuditNetDevice): New function.
* src/qemu/qemu_command.h (qemuNetworkIfaceConnect)
(qemuPhysIfaceConnect, qemuOpenVhostNet): Adjust prototype.
* src/qemu/qemu_command.c (qemuNetworkIfaceConnect)
(qemuPhysIfaceConnect, qemuOpenVhostNet): Add audit points and
adjust parameters.
(qemuBuildCommandLine): Adjust caller.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
2011-03-08 18:00:59 +00:00
|
|
|
int qemuPhysIfaceConnect(virDomainDefPtr def,
|
2012-11-28 16:43:10 +00:00
|
|
|
virQEMUDriverPtr driver,
|
2010-12-16 15:07:07 +00:00
|
|
|
virDomainNetDefPtr net,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps,
|
Rename Macvtap management APIs
In preparation for code re-organization, rename the Macvtap
management APIs to have the following patterns
virNetDevMacVLanXXXXX - macvlan/macvtap interface management
virNetDevVPortProfileXXXX - virtual port profile management
* src/util/macvtap.c, src/util/macvtap.h: Rename APIs
* src/conf/domain_conf.c, src/network/bridge_driver.c,
src/qemu/qemu_command.c, src/qemu/qemu_command.h,
src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c,
src/qemu/qemu_process.h: Update for renamed APIs
2011-11-02 16:51:01 +00:00
|
|
|
enum virNetDevVPortProfileOp vmop);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
audit: audit use of /dev/net/tun, /dev/tapN, /dev/vhost-net
Opening raw network devices with the intent of passing those fds to
qemu is worth an audit point. This makes a multi-part audit: first,
we audit the device(s) that libvirt opens on behalf of the MAC address
of a to-be-created interface (which can independently succeed or
fail), then we audit whether qemu actually started the network device
with the same MAC (so searching backwards for successful audits with
the same MAC will show which fd(s) qemu is actually using). Note that
it is possible for the fd to be successfully opened but no attempt
made to pass the fd to qemu (for example, because intermediate
nwfilter operations failed) - no interface start audit will occur in
that case; so the audit for a successful opened fd does not imply
rights given to qemu unless there is a followup audit about the
attempt to start a new interface.
Likewise, when a network device is hot-unplugged, there is only one
audit message about the MAC being discontinued; again, searching back
to the earlier device open audits will show which fds that qemu quits
using (and yes, I checked via /proc/<qemu-pid>/fd that qemu _does_
close out the fds associated with an interface on hot-unplug). The
code would require much more refactoring to be able to definitively
state which device(s) were discontinued at that point, since we
currently don't record anywhere in the XML whether /dev/vhost-net was
opened for a given interface.
* src/qemu/qemu_audit.h (qemuAuditNetDevice): New prototype.
* src/qemu/qemu_audit.c (qemuAuditNetDevice): New function.
* src/qemu/qemu_command.h (qemuNetworkIfaceConnect)
(qemuPhysIfaceConnect, qemuOpenVhostNet): Adjust prototype.
* src/qemu/qemu_command.c (qemuNetworkIfaceConnect)
(qemuPhysIfaceConnect, qemuOpenVhostNet): Add audit points and
adjust parameters.
(qemuBuildCommandLine): Adjust caller.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
2011-03-08 18:00:59 +00:00
|
|
|
int qemuOpenVhostNet(virDomainDefPtr def,
|
|
|
|
virDomainNetDefPtr net,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps,
|
2013-05-21 13:50:09 +00:00
|
|
|
int *vhostfd,
|
|
|
|
int *vhostfdSize);
|
2011-03-09 04:43:33 +00:00
|
|
|
|
qemu: allocate network connections sooner during domain startup
VFIO device assignment requires a cgroup ACL to be setup for access to
the /dev/vfio/nn "group" device for any devices that will be assigned
to a guest. In the case of a host device that is allocated from a
pool, it was being allocated during qemuBuildCommandLine(), which is
called by qemuProcessStart() *after* the all-encompassing
qemuSetupCgroup() was called, meaning that the standard Cgroup ACL
setup wasn't creating ACLs for these devices allocated from pools.
One possible solution was to manually add a single ACL down inside
qemuBuildCommandLine() when networkAllocateActualDevice() is called,
but that has two problems: 1) the function that adds the cgroup ACL
requires a virDomainObjPtr, which isn't available in
qemuBuildCommandLine(), and 2) we really shouldn't be doing network
device setup inside qemuBuildCommandLine() anyway.
Instead, I've created a new function called
qemuNetworkPrepareDevices() which is called just before
qemuPrepareHostDevices() during qemuProcessStart() (explanation of
ordering in the comments), i.e. well before the call to
qemuSetupCgroup(). To minimize code churn in a patch that will be
backported to 1.0.5-maint, qemuNetworkPrepareDevices only does
networkAllocateActualDevice() and the bare amount of setup required
for type='hostdev network devices, but it eventually should do *all*
device setup for guest network devices.
Note that some of the code that was previously needed in
qemuBuildCommandLine() is no longer required when
networkAllocateActualDevice() is called earlier:
* qemuAssignDeviceHostdevAlias() is already done further down in
qemuProcessStart().
* qemuPrepareHostdevPCIDevices() is called by
qemuPrepareHostDevices() which is called after
qemuNetworkPrepareDevices() in qemuProcessStart().
As hinted above, this new function should be moved into a separate
qemu_network.c (or similarly named) file along with
qemuPhysIfaceConnect(), qemuNetworkIfaceConnect(), and
qemuOpenVhostNet(), and expanded to call those functions as well, then
the nnets loop in qemuBuildCommandLine() should be reduced to only
build the commandline string (which itself can be in a separate
qemuInterfaceBuilldCommandLine() function as suggested by
Michal). However, this will require storing away an array of tapfd and
vhostfd that are needed for the commandline, so I would rather do that
in a separate patch and leave this patch at the minimum to fix the
bug.
2013-05-06 19:43:56 +00:00
|
|
|
int qemuNetworkPrepareDevices(virDomainDefPtr def);
|
|
|
|
|
2011-06-17 14:31:02 +00:00
|
|
|
/*
|
|
|
|
* NB: def->name can be NULL upon return and the caller
|
|
|
|
* *must* decide how to fill in a name in this case
|
|
|
|
*/
|
2013-02-01 13:48:58 +00:00
|
|
|
virDomainDefPtr qemuParseCommandLineString(virCapsPtr qemuCaps,
|
2013-03-31 18:03:42 +00:00
|
|
|
virDomainXMLOptionPtr xmlopt,
|
2011-06-17 14:31:02 +00:00
|
|
|
const char *args,
|
|
|
|
char **pidfile,
|
|
|
|
virDomainChrSourceDefPtr *monConfig,
|
|
|
|
bool *monJSON);
|
2013-02-01 13:48:58 +00:00
|
|
|
virDomainDefPtr qemuParseCommandLinePid(virCapsPtr qemuCaps,
|
2013-03-31 18:03:42 +00:00
|
|
|
virDomainXMLOptionPtr xmlopt,
|
build: use correct type for pid and similar types
No thanks to 64-bit windows, with 64-bit pid_t, we have to avoid
constructs like 'int pid'. Our API in libvirt-qemu cannot be
changed without breaking ABI; but then again, libvirt-qemu can
only be used on systems that support UNIX sockets, which rules
out Windows (even if qemu could be compiled there) - so for all
points on the call chain that interact with this API decision,
we require a different variable name to make it clear that we
audited the use for safety.
Adding a syntax-check rule only solves half the battle; anywhere
that uses printf on a pid_t still needs to be converted, but that
will be a separate patch.
* cfg.mk (sc_correct_id_types): New syntax check.
* src/libvirt-qemu.c (virDomainQemuAttach): Document why we didn't
use pid_t for pid, and validate for overflow.
* include/libvirt/libvirt-qemu.h (virDomainQemuAttach): Tweak name
for syntax check.
* src/vmware/vmware_conf.c (vmwareExtractPid): Likewise.
* src/driver.h (virDrvDomainQemuAttach): Likewise.
* tools/virsh.c (cmdQemuAttach): Likewise.
* src/remote/qemu_protocol.x (qemu_domain_attach_args): Likewise.
* src/qemu_protocol-structs (qemu_domain_attach_args): Likewise.
* src/util/cgroup.c (virCgroupPidCode, virCgroupKillInternal):
Likewise.
* src/qemu/qemu_command.c(qemuParseProcFileStrings): Likewise.
(qemuParseCommandLinePid): Use pid_t for pid.
* daemon/libvirtd.c (daemonForkIntoBackground): Likewise.
* src/conf/domain_conf.h (_virDomainObj): Likewise.
* src/probes.d (rpc_socket_new): Likewise.
* src/qemu/qemu_command.h (qemuParseCommandLinePid): Likewise.
* src/qemu/qemu_driver.c (qemudGetProcessInfo, qemuDomainAttach):
Likewise.
* src/qemu/qemu_process.c (qemuProcessAttach): Likewise.
* src/qemu/qemu_process.h (qemuProcessAttach): Likewise.
* src/uml/uml_driver.c (umlGetProcessInfo): Likewise.
* src/util/virnetdev.h (virNetDevSetNamespace): Likewise.
* src/util/virnetdev.c (virNetDevSetNamespace): Likewise.
* tests/testutils.c (virtTestCaptureProgramOutput): Likewise.
* src/conf/storage_conf.h (_virStoragePerms): Use mode_t, uid_t,
and gid_t rather than int.
* src/security/security_dac.c (virSecurityDACSetOwnership): Likewise.
* src/conf/storage_conf.c (virStorageDefParsePerms): Avoid
compiler warning.
2012-02-10 23:08:11 +00:00
|
|
|
pid_t pid,
|
2011-06-17 14:34:00 +00:00
|
|
|
char **pidfile,
|
|
|
|
virDomainChrSourceDefPtr *monConfig,
|
|
|
|
bool *monJSON);
|
2011-12-08 06:41:26 +00:00
|
|
|
|
2012-06-29 15:02:03 +00:00
|
|
|
int qemuDomainAssignAddresses(virDomainDefPtr def,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps,
|
2012-08-22 14:39:54 +00:00
|
|
|
virDomainObjPtr obj)
|
|
|
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
2012-08-08 07:06:33 +00:00
|
|
|
int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
2013-07-09 20:30:57 +00:00
|
|
|
void qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
|
|
|
|
virDomainDeviceInfoPtr info,
|
|
|
|
const char *devstr);
|
|
|
|
|
qemu: set/validate slot/connection type when assigning slots for PCI devices
Since PCI bridges, PCIe bridges, PCIe switches, and PCIe root ports
all share the same namespace, they are all defined as controllers of
type='pci' in libvirt (but with a differing model attribute). Each of
these controllers has a certain connection type upstream, allows
certain connection types downstream, and each can either allow a
single downstream connection at slot 0, or connections from slot 1 -
31.
Right now, we only support the pci-root and pci-bridge devices, both
of which only allow PCI devices to connect, and both which have usable
slots 1 - 31. In preparation for adding other types of controllers
that have different capabilities, this patch 1) adds info to the
qemuDomainPCIAddressBus object to indicate the capabilities, 2) sets
those capabilities appropriately for pci-root and pci-bridge devices,
and 3) validates that the controller being connected to is the proper
type when allocating slots or validating that a user-selected slot is
appropriate for a device..
Having this infrastructure in place will make it much easier to add
support for the other PCI controller types.
While it would be possible to do all the necessary checking by just
storing the controller model in the qemyuDomainPCIAddressBus, it
greatly simplifies all the validation code to also keep a "flags",
"minSlot" and "maxSlot" for each - that way we can just check those
attributes rather than requiring a nearly identical switch statement
everywhere we need to validate compatibility.
You may notice many places where the flags are seemingly hard-coded to
QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI
This is currently the correct value for all PCI devices, and in the
future will be the default, with small bits of code added to change to
the flags for the few devices which are the exceptions to this rule.
Finally, there are a few places with "FIXME" comments. Note that these
aren't indicating places that are broken according to the currently
supported devices, they are places that will need fixing when support
for new PCI controller models is added.
To assure that there was no regression in the auto-allocation of PCI
addresses or auto-creation of integrated pci-root, ide, and usb
controllers, a new test case (pci-bridge-many-disks) has been added to
both the qemuxml2argv and qemuxml2xml tests. This new test defines a
domain with several dozen virtio disks but no pci-root or
pci-bridges. The .args file of the new test case was created using
libvirt sources from before this patch, and the test still passes
after this patch has been applied.
2013-07-15 00:09:44 +00:00
|
|
|
typedef enum {
|
|
|
|
QEMU_PCI_CONNECT_HOTPLUGGABLE = 1 << 0,
|
|
|
|
/* This bus supports hot-plug */
|
|
|
|
QEMU_PCI_CONNECT_SINGLESLOT = 1 << 1,
|
|
|
|
/* This "bus" has only a single downstream slot/port */
|
|
|
|
|
|
|
|
QEMU_PCI_CONNECT_TYPE_PCI = 1 << 2,
|
|
|
|
/* PCI devices can connect to this bus */
|
2013-07-10 19:19:32 +00:00
|
|
|
QEMU_PCI_CONNECT_TYPE_PCIE = 1 << 3,
|
|
|
|
/* PCI Express devices can connect to this bus */
|
2013-09-24 13:16:25 +00:00
|
|
|
QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG = 1 << 4,
|
|
|
|
/* PCI *and* PCIe devices allowed, if the address
|
|
|
|
* was specified in the config by the user
|
|
|
|
*/
|
qemu: set/validate slot/connection type when assigning slots for PCI devices
Since PCI bridges, PCIe bridges, PCIe switches, and PCIe root ports
all share the same namespace, they are all defined as controllers of
type='pci' in libvirt (but with a differing model attribute). Each of
these controllers has a certain connection type upstream, allows
certain connection types downstream, and each can either allow a
single downstream connection at slot 0, or connections from slot 1 -
31.
Right now, we only support the pci-root and pci-bridge devices, both
of which only allow PCI devices to connect, and both which have usable
slots 1 - 31. In preparation for adding other types of controllers
that have different capabilities, this patch 1) adds info to the
qemuDomainPCIAddressBus object to indicate the capabilities, 2) sets
those capabilities appropriately for pci-root and pci-bridge devices,
and 3) validates that the controller being connected to is the proper
type when allocating slots or validating that a user-selected slot is
appropriate for a device..
Having this infrastructure in place will make it much easier to add
support for the other PCI controller types.
While it would be possible to do all the necessary checking by just
storing the controller model in the qemyuDomainPCIAddressBus, it
greatly simplifies all the validation code to also keep a "flags",
"minSlot" and "maxSlot" for each - that way we can just check those
attributes rather than requiring a nearly identical switch statement
everywhere we need to validate compatibility.
You may notice many places where the flags are seemingly hard-coded to
QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI
This is currently the correct value for all PCI devices, and in the
future will be the default, with small bits of code added to change to
the flags for the few devices which are the exceptions to this rule.
Finally, there are a few places with "FIXME" comments. Note that these
aren't indicating places that are broken according to the currently
supported devices, they are places that will need fixing when support
for new PCI controller models is added.
To assure that there was no regression in the auto-allocation of PCI
addresses or auto-creation of integrated pci-root, ide, and usb
controllers, a new test case (pci-bridge-many-disks) has been added to
both the qemuxml2argv and qemuxml2xml tests. This new test defines a
domain with several dozen virtio disks but no pci-root or
pci-bridges. The .args file of the new test case was created using
libvirt sources from before this patch, and the test still passes
after this patch has been applied.
2013-07-15 00:09:44 +00:00
|
|
|
} qemuDomainPCIConnectFlags;
|
|
|
|
|
|
|
|
/* a combination of all bit that describe the type of connections
|
|
|
|
* allowed, e.g. PCI, PCIe, switch
|
|
|
|
*/
|
|
|
|
# define QEMU_PCI_CONNECT_TYPES_MASK \
|
2013-07-10 19:19:32 +00:00
|
|
|
(QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE)
|
qemu: set/validate slot/connection type when assigning slots for PCI devices
Since PCI bridges, PCIe bridges, PCIe switches, and PCIe root ports
all share the same namespace, they are all defined as controllers of
type='pci' in libvirt (but with a differing model attribute). Each of
these controllers has a certain connection type upstream, allows
certain connection types downstream, and each can either allow a
single downstream connection at slot 0, or connections from slot 1 -
31.
Right now, we only support the pci-root and pci-bridge devices, both
of which only allow PCI devices to connect, and both which have usable
slots 1 - 31. In preparation for adding other types of controllers
that have different capabilities, this patch 1) adds info to the
qemuDomainPCIAddressBus object to indicate the capabilities, 2) sets
those capabilities appropriately for pci-root and pci-bridge devices,
and 3) validates that the controller being connected to is the proper
type when allocating slots or validating that a user-selected slot is
appropriate for a device..
Having this infrastructure in place will make it much easier to add
support for the other PCI controller types.
While it would be possible to do all the necessary checking by just
storing the controller model in the qemyuDomainPCIAddressBus, it
greatly simplifies all the validation code to also keep a "flags",
"minSlot" and "maxSlot" for each - that way we can just check those
attributes rather than requiring a nearly identical switch statement
everywhere we need to validate compatibility.
You may notice many places where the flags are seemingly hard-coded to
QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI
This is currently the correct value for all PCI devices, and in the
future will be the default, with small bits of code added to change to
the flags for the few devices which are the exceptions to this rule.
Finally, there are a few places with "FIXME" comments. Note that these
aren't indicating places that are broken according to the currently
supported devices, they are places that will need fixing when support
for new PCI controller models is added.
To assure that there was no regression in the auto-allocation of PCI
addresses or auto-creation of integrated pci-root, ide, and usb
controllers, a new test case (pci-bridge-many-disks) has been added to
both the qemuxml2argv and qemuxml2xml tests. This new test defines a
domain with several dozen virtio disks but no pci-root or
pci-bridges. The .args file of the new test case was created using
libvirt sources from before this patch, and the test still passes
after this patch has been applied.
2013-07-15 00:09:44 +00:00
|
|
|
|
|
|
|
|
2012-06-29 15:02:03 +00:00
|
|
|
int qemuDomainAssignPCIAddresses(virDomainDefPtr def,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps,
|
2012-06-29 15:02:03 +00:00
|
|
|
virDomainObjPtr obj);
|
2013-04-22 12:16:13 +00:00
|
|
|
qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
|
2013-04-19 10:38:53 +00:00
|
|
|
unsigned int nbuses,
|
|
|
|
bool dryRun);
|
2010-12-16 15:07:07 +00:00
|
|
|
int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
|
qemu: set/validate slot/connection type when assigning slots for PCI devices
Since PCI bridges, PCIe bridges, PCIe switches, and PCIe root ports
all share the same namespace, they are all defined as controllers of
type='pci' in libvirt (but with a differing model attribute). Each of
these controllers has a certain connection type upstream, allows
certain connection types downstream, and each can either allow a
single downstream connection at slot 0, or connections from slot 1 -
31.
Right now, we only support the pci-root and pci-bridge devices, both
of which only allow PCI devices to connect, and both which have usable
slots 1 - 31. In preparation for adding other types of controllers
that have different capabilities, this patch 1) adds info to the
qemuDomainPCIAddressBus object to indicate the capabilities, 2) sets
those capabilities appropriately for pci-root and pci-bridge devices,
and 3) validates that the controller being connected to is the proper
type when allocating slots or validating that a user-selected slot is
appropriate for a device..
Having this infrastructure in place will make it much easier to add
support for the other PCI controller types.
While it would be possible to do all the necessary checking by just
storing the controller model in the qemyuDomainPCIAddressBus, it
greatly simplifies all the validation code to also keep a "flags",
"minSlot" and "maxSlot" for each - that way we can just check those
attributes rather than requiring a nearly identical switch statement
everywhere we need to validate compatibility.
You may notice many places where the flags are seemingly hard-coded to
QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI
This is currently the correct value for all PCI devices, and in the
future will be the default, with small bits of code added to change to
the flags for the few devices which are the exceptions to this rule.
Finally, there are a few places with "FIXME" comments. Note that these
aren't indicating places that are broken according to the currently
supported devices, they are places that will need fixing when support
for new PCI controller models is added.
To assure that there was no regression in the auto-allocation of PCI
addresses or auto-creation of integrated pci-root, ide, and usb
controllers, a new test case (pci-bridge-many-disks) has been added to
both the qemuxml2argv and qemuxml2xml tests. This new test defines a
domain with several dozen virtio disks but no pci-root or
pci-bridges. The .args file of the new test case was created using
libvirt sources from before this patch, and the test still passes
after this patch has been applied.
2013-07-15 00:09:44 +00:00
|
|
|
virDevicePCIAddressPtr addr,
|
|
|
|
qemuDomainPCIConnectFlags flags);
|
2010-12-16 15:07:07 +00:00
|
|
|
int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
|
qemu: set/validate slot/connection type when assigning slots for PCI devices
Since PCI bridges, PCIe bridges, PCIe switches, and PCIe root ports
all share the same namespace, they are all defined as controllers of
type='pci' in libvirt (but with a differing model attribute). Each of
these controllers has a certain connection type upstream, allows
certain connection types downstream, and each can either allow a
single downstream connection at slot 0, or connections from slot 1 -
31.
Right now, we only support the pci-root and pci-bridge devices, both
of which only allow PCI devices to connect, and both which have usable
slots 1 - 31. In preparation for adding other types of controllers
that have different capabilities, this patch 1) adds info to the
qemuDomainPCIAddressBus object to indicate the capabilities, 2) sets
those capabilities appropriately for pci-root and pci-bridge devices,
and 3) validates that the controller being connected to is the proper
type when allocating slots or validating that a user-selected slot is
appropriate for a device..
Having this infrastructure in place will make it much easier to add
support for the other PCI controller types.
While it would be possible to do all the necessary checking by just
storing the controller model in the qemyuDomainPCIAddressBus, it
greatly simplifies all the validation code to also keep a "flags",
"minSlot" and "maxSlot" for each - that way we can just check those
attributes rather than requiring a nearly identical switch statement
everywhere we need to validate compatibility.
You may notice many places where the flags are seemingly hard-coded to
QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI
This is currently the correct value for all PCI devices, and in the
future will be the default, with small bits of code added to change to
the flags for the few devices which are the exceptions to this rule.
Finally, there are a few places with "FIXME" comments. Note that these
aren't indicating places that are broken according to the currently
supported devices, they are places that will need fixing when support
for new PCI controller models is added.
To assure that there was no regression in the auto-allocation of PCI
addresses or auto-creation of integrated pci-root, ide, and usb
controllers, a new test case (pci-bridge-many-disks) has been added to
both the qemuxml2argv and qemuxml2xml tests. This new test defines a
domain with several dozen virtio disks but no pci-root or
pci-bridges. The .args file of the new test case was created using
libvirt sources from before this patch, and the test still passes
after this patch has been applied.
2013-07-15 00:09:44 +00:00
|
|
|
virDevicePCIAddressPtr addr,
|
qemu: eliminate almost-duplicate code in qemu_command.c
* The functions qemuDomainPCIAddressReserveAddr and
qemuDomainPCIAddressReserveSlot were very similar (and should have
been more similar) and were about to get more code added to them which
would create even more duplicated code, so this patch gives
qemuDomainPCIAddressReserveAddr a "reserveEntireSlot" arg, then
replaces the body of qemuDomainPCIAddressReserveSlot with a call to
qemuDomainPCIAddressReserveAddr.
You will notice that addrs->lastaddr was previously set in
qemuDomainPCIAddressReserveAddr (but *not* set in
qemuDomainPCIAddressReserveSlot). For consistency and cleanliness of
code, that bit was removed and put into the one caller of
qemuDomainPCIAddressReserveAddr (there is a similar place where the
caller of qemuDomainPCIAddressReserveSlot sets lastaddr). This does
guarantee identical functionality to pre-patch code, but in practice
isn't really critical, because lastaddr is just keeping track of where
to start when looking for a free slot - if it isn't updated, we will
just start looking on a slot that's already occupied, then skip up to
one that isn't.
* qemuCollectPCIAddress was essentially doing the same thing as
qemuDomainPCIAddressReserveAddr, but with some extra special case
checking at the beginning. The duplicate code has been replaced with
a call to qemuDomainPCIAddressReserveAddr. This required adding a
"fromConfig" boolean, which is only used to change the log error
code from VIR_ERR_INTERNAL_ERROR (when the address was
auto-generated by libvirt) to VIR_ERR_XML_ERROR (when the address is
coming from the config); without this differentiation, it would be
difficult to tell if an error was caused by something wrong in
libvirt's auto-allocate code or just bad config.
* the bit of code in qemuDomainPCIAddressValidate that checks the
connect type flags is going to be used in a couple more places where
we don't need to also check the slot limits (because we're generating
the slot number ourselves), so that has been pulled out into a
separate qemuDomainPCIAddressFlagsCompatible function.
2013-07-27 00:42:14 +00:00
|
|
|
qemuDomainPCIConnectFlags flags,
|
|
|
|
bool reserveEntireSlot,
|
|
|
|
bool fromConfig);
|
qemu: rename some functions in qemu_command.c
* qemuDomainPCIAddressSetNextAddr
The name of this function was confusing because 1) other functions in
the file that end in "Addr" are only operating on a single function of
one PCI slot, not the entire slot, while functions that do something
with the entire slot end in "Slot", and 2) it didn't contain a verb
describing what it is doing (the "Set" refers to the set that contains
all PCI buses in the system, used to keep track of which slots in
which buses are already reserved for use).
It is now renamed to qemuDomainPCIAddressReserveNextSlot, which more
clearly describes what it is doing. Arguably, it could have been
changed to qemuDomainPCIAddressSetReserveNextSlot, but 1) the word
"set" is confusing in this context because it could be intended as a
verb or as a noun, and 2) most other functions that operate on a
single slot or address within this set are also named
qemuDomainPCIAddress... rather than qemuDomainPCIAddressSet... Only
the Create, Free, and Grow functions for an address set (which modify the
entire set, not just one element) use "Set" in their name.
* qemuPCIAddressAsString, qemuPCIAddressValidate
All the other functions in this set are named
qemuDomainPCIAddressxxxxx, so I renamed these to be consistent.
2013-07-27 01:04:18 +00:00
|
|
|
int qemuDomainPCIAddressReserveNextSlot(qemuDomainPCIAddressSetPtr addrs,
|
|
|
|
virDomainDeviceInfoPtr dev,
|
|
|
|
qemuDomainPCIConnectFlags flags);
|
2010-12-16 15:07:07 +00:00
|
|
|
int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
|
|
|
|
virDomainDeviceInfoPtr dev);
|
|
|
|
int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
|
2013-02-15 06:48:49 +00:00
|
|
|
virDevicePCIAddressPtr addr);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
|
|
|
void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs);
|
2012-12-14 07:08:01 +00:00
|
|
|
int qemuAssignDevicePCISlots(virDomainDefPtr def,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps,
|
2012-12-14 07:08:01 +00:00
|
|
|
qemuDomainPCIAddressSetPtr addrs);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
2013-03-05 15:44:21 +00:00
|
|
|
int qemuDomainCCWAddressAssign(virDomainDeviceInfoPtr dev, qemuDomainCCWAddressSetPtr addrs,
|
|
|
|
bool autoassign);
|
|
|
|
void qemuDomainCCWAddressSetFree(qemuDomainCCWAddressSetPtr addrs);
|
|
|
|
|
2013-02-01 13:48:58 +00:00
|
|
|
int qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps);
|
2010-12-16 15:07:07 +00:00
|
|
|
int qemuDomainNetVLAN(virDomainNetDefPtr def);
|
|
|
|
int qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx);
|
qemu: Build command line for the new address format
For any disk controller model which is not "lsilogic", the command
line will be like:
-drive file=/dev/sda,if=none,id=drive-scsi0-0-3-0,format=raw \
-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=3,lun=0,i\
drive=drive-scsi0-0-3-0,id=scsi0-0-3-0
The relationship between the libvirt address attrs and the qdev
properties are (controller model is not "lsilogic"; strings
inside <> represent libvirt adress attrs):
bus=scsi<controller>.0
channel=<bus>
scsi-id=<target>
lun=<unit>
* src/qemu/qemu_command.h: (New param "virDomainDefPtr def"
for function qemuBuildDriveDevStr; new param "virDomainDefPtr
vmdef" for function qemuAssignDeviceDiskAlias. Both for
virDomainDiskFindControllerModel's use).
* src/qemu/qemu_command.c:
- New param "virDomainDefPtr def" for qemuAssignDeviceDiskAliasCustom.
For virDomainDiskFindControllerModel's use, if the disk bus is "scsi"
and the controller model is not "lsilogic", "target" is one part of
the alias name.
- According change on qemuAssignDeviceDiskAlias and qemuBuildDriveDevStr
* src/qemu/qemu_hotplug.c:
- Changes to be consistent with declarations of qemuAssignDeviceDiskAlias
qemuBuildDriveDevStr, and qemuBuildControllerDevStr.
* tests/qemuxml2argvdata/qemuxml2argv-pseries-vio-user-assigned.args,
tests/qemuxml2argvdata/qemuxml2argv-pseries-vio.args: Update the
generated command line.
2012-02-28 03:39:43 +00:00
|
|
|
int qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef,
|
|
|
|
virDomainDiskDefPtr def,
|
2013-02-01 13:48:58 +00:00
|
|
|
virQEMUCapsPtr qemuCaps);
|
2011-09-02 15:09:14 +00:00
|
|
|
int qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev, int idx);
|
2010-12-16 15:07:07 +00:00
|
|
|
int qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller);
|
2011-09-02 15:09:14 +00:00
|
|
|
int qemuAssignDeviceRedirdevAlias(virDomainDefPtr def, virDomainRedirdevDefPtr redirdev, int idx);
|
2013-03-13 08:41:33 +00:00
|
|
|
int qemuAssignDeviceChrAlias(virDomainDefPtr def,
|
|
|
|
virDomainChrDefPtr chr,
|
|
|
|
ssize_t idx);
|
2010-12-16 15:07:07 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
qemuParseKeywords(const char *str,
|
|
|
|
char ***retkeywords,
|
|
|
|
char ***retvalues,
|
2013-09-23 13:16:09 +00:00
|
|
|
int *retnkeywords,
|
2010-12-16 15:07:07 +00:00
|
|
|
int allowEmptyValue);
|
|
|
|
|
|
|
|
#endif /* __QEMU_COMMAND_H__*/
|