mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
Merge
This commit is contained in:
commit
cfc96e7b31
11 files changed
+473
-50
No files matched your search
@@ -81,20 +81,26 @@ fi
|
||||
|
||||
case "$command" in
|
||||
online)
|
||||
setup_bridge_port "$vif"
|
||||
add_to_bridge "$bridge" "$vif"
|
||||
setup_bridge_port "$dev"
|
||||
add_to_bridge "$bridge" "$dev"
|
||||
;;
|
||||
|
||||
offline)
|
||||
do_without_error brctl delif "$bridge" "$vif"
|
||||
do_without_error ifconfig "$vif" down
|
||||
do_without_error brctl delif "$bridge" "$dev"
|
||||
do_without_error ifconfig "$dev" down
|
||||
;;
|
||||
|
||||
add)
|
||||
add_to_bridge "$bridge" "$dev"
|
||||
;;
|
||||
esac
|
||||
|
||||
handle_iptable
|
||||
if [ "$type_if" = vif ]; then
|
||||
handle_iptable
|
||||
fi
|
||||
|
||||
log debug "Successful vif-bridge $command for $vif, bridge $bridge."
|
||||
if [ "$command" == "online" ]
|
||||
log debug "Successful vif-bridge $command for $dev, bridge $bridge."
|
||||
if [ "$type_if" = vif -a "$command" = "online" ]
|
||||
then
|
||||
success
|
||||
fi
|
||||
@@ -31,12 +31,6 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$command" in
|
||||
add | remove)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Parameters may be read from the environment, the command line arguments, and
|
||||
# the store, with overriding in that order. The environment is given by the
|
||||
@@ -45,24 +39,62 @@ esac
|
||||
|
||||
evalVariables "$@"
|
||||
|
||||
ip=${ip:-}
|
||||
ip=$(xenstore_read_default "$XENBUS_PATH/ip" "$ip")
|
||||
# Older versions of Xen do not pass in the type as an argument,
|
||||
# so the default value is vif.
|
||||
: ${type_if:=vif}
|
||||
|
||||
# Check presence of compulsory args.
|
||||
XENBUS_PATH="${XENBUS_PATH:?}"
|
||||
vif="${vif:?}"
|
||||
case "$type_if" in
|
||||
vif)
|
||||
dev=$vif
|
||||
;;
|
||||
tap)
|
||||
dev=$INTERFACE
|
||||
;;
|
||||
*)
|
||||
log err "unknown interface type $type_if"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$command" in
|
||||
online | offline)
|
||||
test "$type_if" != vif && exit 0
|
||||
;;
|
||||
add | remove)
|
||||
test "$type_if" != tap && exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
vifname=$(xenstore_read_default "$XENBUS_PATH/vifname" "")
|
||||
if [ "$vifname" ]
|
||||
then
|
||||
if [ "$command" == "online" ] && ! ip link show "$vifname" >&/dev/null
|
||||
then
|
||||
do_or_die ip link set "$vif" name "$vifname"
|
||||
fi
|
||||
vif="$vifname"
|
||||
if [ "$type_if" = vif ]; then
|
||||
# Check presence of compulsory args.
|
||||
XENBUS_PATH="${XENBUS_PATH:?}"
|
||||
vif="${vif:?}"
|
||||
|
||||
vifname=$(xenstore_read_default "$XENBUS_PATH/vifname" "")
|
||||
if [ "$vifname" ]
|
||||
then
|
||||
if [ "$command" == "online" ] && ! ip link show "$vifname" >&/dev/null
|
||||
then
|
||||
do_or_die ip link set "$vif" name "$vifname"
|
||||
fi
|
||||
vif="$vifname"
|
||||
fi
|
||||
elif [ "$type_if" = tap ]; then
|
||||
# Check presence of compulsory args.
|
||||
: ${INTERFACE:?}
|
||||
|
||||
# Get xenbus_path from device name.
|
||||
# The name is built like that: "tap${domid}.${devid}".
|
||||
dev_=${dev#tap}
|
||||
domid=${dev_%.*}
|
||||
devid=${dev_#*.}
|
||||
|
||||
XENBUS_PATH="/local/domain/0/backend/vif/$domid/$devid"
|
||||
fi
|
||||
|
||||
ip=${ip:-}
|
||||
ip=$(xenstore_read_default "$XENBUS_PATH/ip" "$ip")
|
||||
|
||||
frob_iptable()
|
||||
{
|
||||
|
||||
@@ -2,10 +2,11 @@ SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap $env{ACT
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm $env{ACTION}"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vif2-*", RUN+="/etc/xen/scripts/vif2 $env{ACTION}"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="online", RUN+="/etc/xen/scripts/vif-setup online"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="offline", RUN+="/etc/xen/scripts/vif-setup offline"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="online", RUN+="/etc/xen/scripts/vif-setup online type_if=vif"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="offline", RUN+="/etc/xen/scripts/vif-setup offline type_if=vif"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vscsi*", RUN+="/etc/xen/scripts/vscsi $env{ACTION}"
|
||||
SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
|
||||
KERNEL=="evtchn", NAME="xen/%k"
|
||||
KERNEL=="blktap[0-9]*", NAME="xen/%k"
|
||||
KERNEL=="pci_iomul", NAME="xen/%k"
|
||||
SUBSYSTEM=="net", KERNEL=="tap*", ACTION=="add", RUN+="/etc/xen/scripts/vif-setup $env{ACTION} type_if=tap"
|
||||
@@ -142,6 +142,7 @@ static int setup_guest(xc_interface *xch,
|
||||
if ( memsize > target )
|
||||
pod_mode = 1;
|
||||
|
||||
memset(&elf, 0, sizeof(elf));
|
||||
if ( elf_init(&elf, image, image_size) != 0 )
|
||||
goto error_out;
|
||||
elf_parse_binary(&elf);
|
||||
|
||||
+162
-4
@@ -964,7 +964,7 @@ skip_autopass:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char ** libxl_build_device_model_args(libxl_ctx *ctx,
|
||||
static char ** libxl_build_device_model_args_old(libxl_ctx *ctx,
|
||||
libxl_device_model_info *info,
|
||||
libxl_device_nic *vifs,
|
||||
int num_vifs)
|
||||
@@ -1070,12 +1070,12 @@ static char ** libxl_build_device_model_args(libxl_ctx *ctx,
|
||||
vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
|
||||
vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
|
||||
if (!vifs[i].ifname)
|
||||
vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid - 1);
|
||||
vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid);
|
||||
flexarray_set(dm_args, num++, "-net");
|
||||
flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s",
|
||||
vifs[i].devid, smac, vifs[i].model));
|
||||
flexarray_set(dm_args, num++, "-net");
|
||||
flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s",
|
||||
flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s,script=no",
|
||||
vifs[i].devid, vifs[i].ifname, vifs[i].bridge));
|
||||
ioemu_vifs++;
|
||||
}
|
||||
@@ -1098,10 +1098,168 @@ static char ** libxl_build_device_model_args(libxl_ctx *ctx,
|
||||
else
|
||||
flexarray_set(dm_args, num++, "xenfv");
|
||||
flexarray_set(dm_args, num++, NULL);
|
||||
|
||||
return (char **) flexarray_contents(dm_args);
|
||||
}
|
||||
|
||||
static char ** libxl_build_device_model_args_new(libxl_ctx *ctx,
|
||||
libxl_device_model_info *info,
|
||||
libxl_device_nic *vifs,
|
||||
int num_vifs)
|
||||
{
|
||||
int num = 0, i;
|
||||
flexarray_t *dm_args;
|
||||
int nb;
|
||||
libxl_device_disk *disks;
|
||||
|
||||
dm_args = flexarray_make(16, 1);
|
||||
if (!dm_args)
|
||||
return NULL;
|
||||
|
||||
flexarray_set(dm_args, num++, "qemu-system-xen");
|
||||
flexarray_set(dm_args, num++, "-xen-domid");
|
||||
|
||||
flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid));
|
||||
|
||||
if (info->dom_name) {
|
||||
flexarray_set(dm_args, num++, "-name");
|
||||
flexarray_set(dm_args, num++, info->dom_name);
|
||||
}
|
||||
if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
|
||||
int display = 0;
|
||||
const char *listen = "127.0.0.1";
|
||||
|
||||
flexarray_set(dm_args, num++, "-vnc");
|
||||
|
||||
if (info->vncdisplay) {
|
||||
display = info->vncdisplay;
|
||||
if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
|
||||
listen = info->vnclisten;
|
||||
}
|
||||
} else if (info->vnclisten) {
|
||||
listen = info->vnclisten;
|
||||
}
|
||||
|
||||
if (strchr(listen, ':') != NULL)
|
||||
flexarray_set(dm_args, num++,
|
||||
libxl_sprintf(ctx, "%s%s", listen,
|
||||
info->vncunused ? ",to=99" : ""));
|
||||
else
|
||||
flexarray_set(dm_args, num++,
|
||||
libxl_sprintf(ctx, "%s:%d%s", listen, display,
|
||||
info->vncunused ? ",to=99" : ""));
|
||||
}
|
||||
if (info->sdl) {
|
||||
flexarray_set(dm_args, num++, "-sdl");
|
||||
}
|
||||
if (info->keymap) {
|
||||
flexarray_set(dm_args, num++, "-k");
|
||||
flexarray_set(dm_args, num++, info->keymap);
|
||||
}
|
||||
if (info->nographic && (!info->sdl && !info->vnc)) {
|
||||
flexarray_set(dm_args, num++, "-nographic");
|
||||
}
|
||||
if (info->serial) {
|
||||
flexarray_set(dm_args, num++, "-serial");
|
||||
flexarray_set(dm_args, num++, info->serial);
|
||||
}
|
||||
if (info->type == XENFV) {
|
||||
int ioemu_vifs = 0;
|
||||
|
||||
if (info->stdvga) {
|
||||
flexarray_set(dm_args, num++, "-vga");
|
||||
flexarray_set(dm_args, num++, "std");
|
||||
}
|
||||
|
||||
if (info->boot) {
|
||||
flexarray_set(dm_args, num++, "-boot");
|
||||
flexarray_set(dm_args, num++, libxl_sprintf(ctx, "order=%s", info->boot));
|
||||
}
|
||||
if (info->usb || info->usbdevice) {
|
||||
flexarray_set(dm_args, num++, "-usb");
|
||||
if (info->usbdevice) {
|
||||
flexarray_set(dm_args, num++, "-usbdevice");
|
||||
flexarray_set(dm_args, num++, info->usbdevice);
|
||||
}
|
||||
}
|
||||
if (info->soundhw) {
|
||||
flexarray_set(dm_args, num++, "-soundhw");
|
||||
flexarray_set(dm_args, num++, info->soundhw);
|
||||
}
|
||||
if (!info->apic) {
|
||||
flexarray_set(dm_args, num++, "-no-acpi");
|
||||
}
|
||||
if (info->vcpus > 1) {
|
||||
flexarray_set(dm_args, num++, "-smp");
|
||||
if (info->vcpu_avail)
|
||||
flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail));
|
||||
else
|
||||
flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->vcpus));
|
||||
}
|
||||
for (i = 0; i < num_vifs; i++) {
|
||||
if (vifs[i].nictype == NICTYPE_IOEMU) {
|
||||
char *smac = libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
|
||||
vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
|
||||
if (!vifs[i].ifname)
|
||||
vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid);
|
||||
flexarray_set(dm_args, num++, "-net");
|
||||
flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s",
|
||||
vifs[i].devid, smac, vifs[i].model));
|
||||
flexarray_set(dm_args, num++, "-net");
|
||||
flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,script=no",
|
||||
vifs[i].devid, vifs[i].ifname));
|
||||
ioemu_vifs++;
|
||||
}
|
||||
}
|
||||
/* If we have no emulated nics, tell qemu not to create any */
|
||||
if ( ioemu_vifs == 0 ) {
|
||||
flexarray_set(dm_args, num++, "-net");
|
||||
flexarray_set(dm_args, num++, "none");
|
||||
}
|
||||
}
|
||||
if (info->saved_state) {
|
||||
flexarray_set(dm_args, num++, "-loadvm");
|
||||
flexarray_set(dm_args, num++, info->saved_state);
|
||||
}
|
||||
for (i = 0; info->extra && info->extra[i] != NULL; i++)
|
||||
flexarray_set(dm_args, num++, info->extra[i]);
|
||||
flexarray_set(dm_args, num++, "-M");
|
||||
if (info->type == XENPV)
|
||||
flexarray_set(dm_args, num++, "xenpv");
|
||||
else
|
||||
flexarray_set(dm_args, num++, "xenfv");
|
||||
|
||||
disks = libxl_device_disk_list(ctx, info->domid, &nb);
|
||||
for (; nb > 0; --nb, ++disks) {
|
||||
if ( disks->is_cdrom ) {
|
||||
flexarray_set(dm_args, num++, "-cdrom");
|
||||
flexarray_set(dm_args, num++, disks->physpath);
|
||||
}else{
|
||||
flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-%s", disks->virtpath));
|
||||
flexarray_set(dm_args, num++, disks->physpath);
|
||||
}
|
||||
}
|
||||
|
||||
flexarray_set(dm_args, num++, NULL);
|
||||
return (char **) flexarray_contents(dm_args);
|
||||
}
|
||||
|
||||
static char ** libxl_build_device_model_args(libxl_ctx *ctx,
|
||||
libxl_device_model_info *info,
|
||||
libxl_device_nic *vifs,
|
||||
int num_vifs)
|
||||
{
|
||||
int new_qemu;
|
||||
|
||||
new_qemu = libxl_check_device_model_version(ctx, info->device_model);
|
||||
|
||||
if (new_qemu == 1) {
|
||||
return libxl_build_device_model_args_new(ctx, info, vifs, num_vifs);
|
||||
} else {
|
||||
return libxl_build_device_model_args_old(ctx, info, vifs, num_vifs);
|
||||
}
|
||||
}
|
||||
|
||||
void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
|
||||
{
|
||||
libxl_device_model_starting *starting = for_spawn;
|
||||
|
||||
@@ -310,6 +310,8 @@ typedef struct {
|
||||
};
|
||||
unsigned int domain;
|
||||
unsigned int vdevfn;
|
||||
#define LIBXL_PCI_FUNC_ALL (~0U)
|
||||
unsigned int vfunc_mask;
|
||||
bool msitranslate;
|
||||
bool power_mgmt;
|
||||
} libxl_device_pci;
|
||||
|
||||
+138
-11
@@ -136,8 +136,13 @@ int libxl_device_pci_parse_bdf(libxl_ctx *ctx, libxl_device_pci *pcidev, const c
|
||||
break;
|
||||
}
|
||||
*ptr = '\0';
|
||||
if ( hex_convert(tok, &func, 0x7) )
|
||||
goto parse_error;
|
||||
if ( !strcmp(tok, "*") ) {
|
||||
pcidev->vfunc_mask = LIBXL_PCI_FUNC_ALL;
|
||||
}else{
|
||||
if ( hex_convert(tok, &func, 0x7) )
|
||||
goto parse_error;
|
||||
pcidev->vfunc_mask = (1 << 0);
|
||||
}
|
||||
tok = ptr + 1;
|
||||
}
|
||||
break;
|
||||
@@ -187,7 +192,6 @@ int libxl_device_pci_parse_bdf(libxl_ctx *ctx, libxl_device_pci *pcidev, const c
|
||||
return 0;
|
||||
|
||||
parse_error:
|
||||
printf("parse error: %s\n", str);
|
||||
return ERROR_INVAL;
|
||||
}
|
||||
|
||||
@@ -531,6 +535,55 @@ int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, in
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function checks that all functions of a device are bound to pciback
|
||||
* driver. It also initialises a bit-mask of which function numbers are present
|
||||
* on that device.
|
||||
*/
|
||||
static int pci_multifunction_check(libxl_ctx *ctx, libxl_device_pci *pcidev, unsigned int *func_mask)
|
||||
{
|
||||
struct dirent *de;
|
||||
DIR *dir;
|
||||
|
||||
*func_mask = 0;
|
||||
|
||||
dir = opendir(SYSFS_PCI_DEV);
|
||||
if ( NULL == dir ) {
|
||||
XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", SYSFS_PCI_DEV);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while( (de = readdir(dir)) ) {
|
||||
unsigned dom, bus, dev, func;
|
||||
struct stat st;
|
||||
char *path;
|
||||
|
||||
if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
|
||||
continue;
|
||||
if ( pcidev->domain != dom )
|
||||
continue;
|
||||
if ( pcidev->bus != bus )
|
||||
continue;
|
||||
if ( pcidev->dev != dev )
|
||||
continue;
|
||||
|
||||
path = libxl_sprintf(ctx, "%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func);
|
||||
if ( lstat(path, &st) ) {
|
||||
if ( errno == ENOENT )
|
||||
XL_LOG(ctx, XL_LOG_ERROR, PCI_BDF " is not assigned to pciback driver",
|
||||
dom, bus, dev, func);
|
||||
else
|
||||
XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't lstat %s", path);
|
||||
closedir(dir);
|
||||
return -1;
|
||||
}
|
||||
(*func_mask) |= (1 << func);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci_ins_check(libxl_ctx *ctx, uint32_t domid, const char *state, void *priv)
|
||||
{
|
||||
char *orig_state = priv;
|
||||
@@ -652,8 +705,9 @@ out:
|
||||
|
||||
int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
|
||||
{
|
||||
unsigned int orig_vdev, pfunc_mask;
|
||||
libxl_device_pci *assigned;
|
||||
int num_assigned, rc;
|
||||
int num_assigned, rc, i;
|
||||
int stubdomid = 0;
|
||||
|
||||
rc = get_all_assigned_devices(ctx, &assigned, &num_assigned);
|
||||
@@ -679,10 +733,43 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcide
|
||||
return rc;
|
||||
}
|
||||
|
||||
return do_pci_add(ctx, domid, pcidev);
|
||||
orig_vdev = pcidev->vdevfn & ~7U;
|
||||
|
||||
if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
|
||||
if ( !(pcidev->vdevfn >> 3) ) {
|
||||
XL_LOG(ctx, XL_LOG_ERROR, "Must specify a v-slot for multi-function devices");
|
||||
return ERROR_INVAL;
|
||||
}
|
||||
if ( pci_multifunction_check(ctx, pcidev, &pfunc_mask) ) {
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
pcidev->vfunc_mask &= pfunc_mask;
|
||||
/* so now vfunc_mask == pfunc_mask */
|
||||
}else{
|
||||
pfunc_mask = (1 << pcidev->func);
|
||||
}
|
||||
|
||||
for(i = 7; i >= 0; --i) {
|
||||
if ( (1 << i) & pfunc_mask ) {
|
||||
if ( pcidev->vfunc_mask == pfunc_mask ) {
|
||||
pcidev->func = i;
|
||||
pcidev->vdevfn = orig_vdev | i;
|
||||
}else{
|
||||
/* if not passing through multiple devices in a block make
|
||||
* sure that virtual function number 0 is always used otherwise
|
||||
* guest won't see the device
|
||||
*/
|
||||
pcidev->vdevfn = orig_vdev;
|
||||
}
|
||||
if ( do_pci_add(ctx, domid, pcidev) )
|
||||
rc = ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
|
||||
static int do_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
|
||||
{
|
||||
libxl_device_pci *assigned;
|
||||
char *path;
|
||||
@@ -711,10 +798,15 @@ int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pc
|
||||
libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF, pcidev->domain,
|
||||
pcidev->bus, pcidev->dev, pcidev->func);
|
||||
path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid);
|
||||
xs_write(ctx->xsh, XBT_NULL, path, "pci-rem", strlen("pci-rem"));
|
||||
if (libxl_wait_for_device_model(ctx, domid, "pci-removed", NULL, NULL) < 0) {
|
||||
XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time");
|
||||
return ERROR_FAIL;
|
||||
|
||||
/* Remove all functions at once atomically by only signalling
|
||||
* device-model for function 0 */
|
||||
if ( (pcidev->vdevfn & 0x7) == 0 ) {
|
||||
xs_write(ctx->xsh, XBT_NULL, path, "pci-rem", strlen("pci-rem"));
|
||||
if (libxl_wait_for_device_model(ctx, domid, "pci-removed", NULL, NULL) < 0) {
|
||||
XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid);
|
||||
xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state));
|
||||
@@ -769,7 +861,10 @@ skip1:
|
||||
fclose(f);
|
||||
}
|
||||
out:
|
||||
libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
|
||||
/* don't do multiple resets while some functions are still passed through */
|
||||
if ( (pcidev->vdevfn & 0x7) == 0 ) {
|
||||
libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
|
||||
}
|
||||
|
||||
if (!libxl_is_stubdom(ctx, domid, NULL)) {
|
||||
rc = xc_deassign_device(ctx->xch, domid, pcidev->value);
|
||||
@@ -786,6 +881,38 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
|
||||
{
|
||||
unsigned int orig_vdev, pfunc_mask;
|
||||
int i, rc;
|
||||
|
||||
orig_vdev = pcidev->vdevfn & ~7U;
|
||||
|
||||
if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
|
||||
if ( pci_multifunction_check(ctx, pcidev, &pfunc_mask) ) {
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
pcidev->vfunc_mask &= pfunc_mask;
|
||||
}else{
|
||||
pfunc_mask = (1 << pcidev->func);
|
||||
}
|
||||
|
||||
for(i = 7; i >= 0; --i) {
|
||||
if ( (1 << i) & pfunc_mask ) {
|
||||
if ( pcidev->vfunc_mask == pfunc_mask ) {
|
||||
pcidev->func = i;
|
||||
pcidev->vdevfn = orig_vdev | i;
|
||||
}else{
|
||||
pcidev->vdevfn = orig_vdev;
|
||||
}
|
||||
if ( do_pci_remove(ctx, domid, pcidev) )
|
||||
rc = ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint32_t domid, int *num)
|
||||
{
|
||||
char *be_path, *num_devs, *xsdev, *xsvdevfn, *xsopts;
|
||||
|
||||
@@ -538,3 +538,81 @@ int libxl_strtomac(const char *mac_s, uint8_t *mac)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define QEMU_VERSION_STR "QEMU emulator version "
|
||||
|
||||
|
||||
int libxl_check_device_model_version(libxl_ctx *ctx, char *path)
|
||||
{
|
||||
pid_t pid = -1;
|
||||
int pipefd[2];
|
||||
char buf[100];
|
||||
ssize_t i, count = 0;
|
||||
int status;
|
||||
char *abs_path = NULL;
|
||||
|
||||
abs_path = libxl_abs_path(ctx, path, libxl_private_bindir_path());
|
||||
|
||||
if (pipe(pipefd))
|
||||
return -1;
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!pid) {
|
||||
close(pipefd[0]);
|
||||
if (dup2(pipefd[1], STDOUT_FILENO) == -1)
|
||||
exit(1);
|
||||
execlp(abs_path, abs_path, "-h", NULL);
|
||||
|
||||
close(pipefd[1]);
|
||||
exit(127);
|
||||
}
|
||||
|
||||
close(pipefd[1]);
|
||||
if (abs_path != path)
|
||||
libxl_free(ctx, abs_path);
|
||||
|
||||
/* attempt to get the first line of `qemu -h` */
|
||||
while ((i = read(pipefd[0], buf + count, 99 - count)) > 0) {
|
||||
if (i + count > 90)
|
||||
break;
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (buf[j + count] == '\n')
|
||||
break;
|
||||
}
|
||||
count += i;
|
||||
}
|
||||
count += i;
|
||||
close(pipefd[0]);
|
||||
waitpid(pid, &status, 0);
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if we have the forked qemu-xen. */
|
||||
/* QEMU-DM emulator version 0.10.2, ... */
|
||||
if (strncmp("QEMU-DM ", buf, 7) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if the version is above 12.0 */
|
||||
/* The first line is : QEMU emulator version 0.12.50, ... */
|
||||
if (strncmp(QEMU_VERSION_STR, buf, strlen(QEMU_VERSION_STR)) == 0) {
|
||||
int major, minor;
|
||||
char *endptr = NULL;
|
||||
char *v = buf + strlen(QEMU_VERSION_STR);
|
||||
|
||||
major = strtol(v, &endptr, 10);
|
||||
if (major == 0 && endptr && *endptr == '.') {
|
||||
v = endptr + 1;
|
||||
minor = strtol(v, &endptr, 10);
|
||||
if (minor >= 12)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -68,5 +68,11 @@ int libxl_strtomac(const char *mac_s, uint8_t *mac);
|
||||
int libxl_devid_to_device_net2(libxl_ctx *ctx, uint32_t domid,
|
||||
const char *devid, libxl_device_net2 *net2);
|
||||
|
||||
/* check the version of qemu
|
||||
* return 1 if is the new one
|
||||
* return 0 if is the old one
|
||||
* return -1 if there are an error */
|
||||
int libxl_check_device_model_version(libxl_ctx *ctx, char *path);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -833,6 +833,11 @@ static void parse_config_data(const char *configfile_filename_report,
|
||||
nic->script = strdup(p2 + 1);
|
||||
} else if (!strcmp(p, "vifname")) {
|
||||
nic->ifname = strdup(p2 + 1);
|
||||
} else if (!strcmp(p, "backend")) {
|
||||
if(libxl_name_to_domid(&ctx, (p2 + 1), &(nic->backend_domid))) {
|
||||
fprintf(stderr, "Specified backend domain does not exist, defaulting to Dom0\n");
|
||||
nic->backend_domid = 0;
|
||||
}
|
||||
} else if (!strcmp(p, "rate")) {
|
||||
fprintf(stderr, "the rate parameter for vifs is currently not supported\n");
|
||||
} else if (!strcmp(p, "accel")) {
|
||||
@@ -1926,7 +1931,7 @@ void pcilist_assignable(void)
|
||||
if ( libxl_device_pci_list_assignable(&ctx, &pcidevs, &num) )
|
||||
return;
|
||||
for (i = 0; i < num; i++) {
|
||||
printf("%04x:%02x:%02x:%01x\n",
|
||||
printf("%04x:%02x:%02x.%01x\n",
|
||||
pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, pcidevs[i].func);
|
||||
}
|
||||
free(pcidevs);
|
||||
@@ -2127,6 +2132,9 @@ void list_domains_details(const libxl_dominfo *info, int nb_domain)
|
||||
libxl_device_model_info dm_info;
|
||||
|
||||
for (i = 0; i < nb_domain; i++) {
|
||||
/* no detailed info available on dom0 */
|
||||
if (info[i].domid == 0)
|
||||
continue;
|
||||
rc = libxl_userdata_retrieve(&ctx, info[i].domid, "xl", &data, &len);
|
||||
if (rc)
|
||||
continue;
|
||||
@@ -3003,6 +3011,11 @@ int main_list(int argc, char **argv)
|
||||
} else if (optind == argc-1) {
|
||||
find_domain(argv[optind]);
|
||||
rc = libxl_domain_info(&ctx, &info_buf, domid);
|
||||
if (rc == ERROR_INVAL) {
|
||||
fprintf(stderr, "Error: Domain \'%s\' does not exist.\n",
|
||||
argv[optind]);
|
||||
return -rc;
|
||||
}
|
||||
if (rc) {
|
||||
fprintf(stderr, "libxl_domain_info failed (code %d).\n", rc);
|
||||
return -rc;
|
||||
@@ -4004,10 +4017,9 @@ int main_networkattach(int argc, char **argv)
|
||||
} else if (!strncmp("script=", *argv, 6)) {
|
||||
nic.script = (*argv) + 6;
|
||||
} else if (!strncmp("backend=", *argv, 8)) {
|
||||
val = strtoul((*argv) + 8, &endptr, 10);
|
||||
if (((*argv) + 8) == endptr) {
|
||||
fprintf(stderr, "Invalid parameter `backend'.\n");
|
||||
return 1;
|
||||
if(libxl_name_to_domid(&ctx, ((*argv) + 8), &val)) {
|
||||
fprintf(stderr, "Specified backend domain does not exist, defaulting to Dom0\n");
|
||||
val = 0;
|
||||
}
|
||||
nic.backend_domid = val;
|
||||
} else if (!strncmp("vifname=", *argv, 8)) {
|
||||
|
||||
@@ -35,8 +35,8 @@ struct cmd_spec cmd_table[] = {
|
||||
&main_list,
|
||||
"List information about all/some domains",
|
||||
"[options] [Domain]\n",
|
||||
"-l, --long Output all VM details"
|
||||
"-v, --verbose Prints out UUIDs",
|
||||
"-l, --long Output all VM details\n"
|
||||
"-v, --verbose Prints out UUIDs",
|
||||
},
|
||||
{ "destroy",
|
||||
&main_destroy,
|
||||
|
||||