Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

vzctl: use newer API for pci_add (v2)

New kernels (since 2.6.32-042test005.1) contains virtualization for
generic linux devices. Now you can move any device and kernel will
create sysfs tree, send uevent and give permission for char/block
devices.

Old scheme was not good enough, so we removed it from kernel while
(hoping that) nobody's using it.

Additions by kir@openvz.org:
- remove nvidia module loading;
- remove structs and defines used by set_pci();
- fixes for sysfs filenames with spaces;
- 80-col fixes;
- other minor cleanups and dead code removal;
- copyright year fixes.

Signed-off-by: Andrew Vagin <avagin@openvz.org>
Signed-off-by: Kir Kolyshkin <kir@openvz.org>
  • Loading branch information...
commit 3dd594bffbaaff5476d8bb10af68d37ca417f81b 1 parent 0432676
Andrew Vagin avagin authored kolyshkin committed
Showing with 23 additions and 107 deletions.
  1. +1 −3 include/linux/vzcalluser.h
  2. +16 −63 scripts/vps-pci.in
  3. +6 −41 src/lib/dev.c
4 include/linux/vzcalluser.h
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2010, Parallels, Inc. All rights reserved.
+ * Copyright (C) 2000-2011, Parallels, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -87,8 +87,6 @@ struct vzctl_ve_configure {
unsigned int veid;
unsigned int key;
#define VE_CONFIGURE_OS_RELEASE 2
-#define VE_CONFIGURE_ADD_PCI_DEVICE 3
-#define VE_CONFIGURE_DEL_PCI_DEVICE 4
#define VE_CONFIGURE_CREATE_PROC_LINK 5
unsigned int val;
unsigned int size;
79 scripts/vps-pci.in
View
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 2010, Parallels, Inc. All rights reserved.
+# Copyright (C) 2010-2011, Parallels, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -23,73 +23,26 @@
#
# Parameters are passed in environment variables:
# VEID - container ID
+# VE_ROOT - container root directory
# PCI - list of PCI devices
# ADD - boolean flag (1 - add, 0 - del)
-#
-# Currently this only supports adding/removing of NVidia video cards.
-
-VZCTL=vzctl
-SELF=$(basename $0)
-
-# Prepare nVidia video card for using in CT
-handle_nvidia_device()
-{
- local pci major minor dev card dev_num PCI
- local nv_proc=/proc/driver/nvidia
- PCI=$1
-
- lspci -s $PCI | grep -qi VGA.*nvidia || return
-
- modprobe nvidia > /dev/null
- if [ $? -ne 0 ]; then
- echo "$SELF: can't load module nvidia" 1>&2
- return
- fi
- major=$(cat /proc/devices | awk '/nvidia/ {print $1}')
- for card in $(ls $nv_proc/cards/); do
- pci=$(cat $nv_proc/cards/$card | awk '/Bus Location/ {print $3}')
- unify_dev()
- {
- echo $1 | sed 's/:/./g' # I love debian!
- }
- if [ "$(unify_dev $pci)" = "$(unify_dev $PCI)" ]; then
- dev_num=$card
- break
- fi
- done
-
- if [ -z "$dev_num" ]; then
- echo "$SELF: Unknown device $PCI" 1>&2
- return
+for dev in $PCI; do
+ if [ "$ADD" = 1 ]; then
+ cmd='+'
+ sort=''
+ prefix=''
+ else
+ cmd='-'
+ sort='-r'
+ prefix=$VE_ROOT
fi
+ devdir=${prefix}/sys/bus/pci/devices/$dev/
+ cd $devdir >/dev/null|| exit 1
- for dev in nvidiactl nvidia$dev_num; do
- if [ ! -e /dev/$dev ]; then
- if [ "nvidiactl" = "$dev" ]; then
- minor=255
- else
- minor=$dev_num
- fi
- mknod /dev/$dev c $major $minor
- if [ $? -ne 0 ]; then
- echo "$SELF: Can't create device $dev" 1>&2
- return
- fi
- fi
- if [ "$ADD" = 1 ]; then
- $VZCTL --quiet --skiplock set $VEID --devnodes $dev:rw
- else
- $VZCTL --quiet --skiplock set $VEID --devnodes $dev:none
- fi
- if [ $? -ne 0 ]; then
- echo "$SELF: Can't give access to device $dev" 1>&2
- return
- fi
+ find $devdir -name ve_device_add -printf '%d %p\n' | \
+ sort -n $sort | while read n f; do
+ echo ${cmd}${VEID} > "$f" || exit 1
done
-}
-
-for dev in $PCI; do
- handle_nvidia_device $dev
done
exit 0
47 src/lib/dev.c
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2009, Parallels, Inc. All rights reserved.
+ * Copyright (C) 2000-2011, Parallels, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -108,37 +108,6 @@ int set_devperm(vps_handler *h, envid_t veid, dev_res *dev)
return 0;
}
-struct vzctl_ve_configure_pci {
- struct vzctl_ve_configure conf;
- struct vzctl_ve_pci_dev dev;
-};
-
-static int set_pci(vps_handler *h, envid_t veid, int op, char *dev_id)
-{
- int ret;
- struct vzctl_ve_configure_pci conf_pci;
- struct vzctl_ve_configure *conf = &conf_pci.conf;
- struct vzctl_ve_pci_dev *dev = &conf_pci.dev;
-
- sscanf(dev_id, "%x:%x:%x.%d", &dev->domain, &dev->bus,
- &dev->slot, &dev->func);
- conf->veid = veid;
- if (op == ADD)
- conf->key = VE_CONFIGURE_ADD_PCI_DEVICE;
- else
- conf->key = VE_CONFIGURE_DEL_PCI_DEVICE;
- conf->val = 0;
- conf->size = sizeof(struct vzctl_ve_pci_dev);
-
- if ((ret = ioctl(h->vzfd, VZCTL_VE_CONFIGURE, &conf_pci))) {
- if (errno == EEXIST)
- return 0;
- logger(-1, errno, "Unable to move pci device %s", dev_id);
- }
-
- return ret;
-}
-
/** Allow/disallow access to devices on host system from CT.
*
* @param h CT handler.
@@ -206,7 +175,8 @@ void free_dev_param(dev_param *dev)
free_dev(&dev->dev);
}
-int run_pci_script(envid_t veid, int op, list_head_t *pci_h)
+int run_pci_script(envid_t veid, int op, list_head_t *pci_h,
+ const char *ve_root)
{
char *argv[3];
char *envp[10];
@@ -219,6 +189,8 @@ int run_pci_script(envid_t veid, int op, list_head_t *pci_h)
return 0;
snprintf(buf, sizeof(buf), "VEID=%d", veid);
envp[i++] = strdup(buf);
+ snprintf(buf, sizeof(buf), "VE_ROOT=%s", ve_root);
+ envp[i++] = strdup(buf);
snprintf(buf, sizeof(buf), "ADD=%d", op == ADD);
envp[i++] = strdup(buf);
envp[i++] = list2str("PCI", pci_h);
@@ -236,9 +208,7 @@ int run_pci_script(envid_t veid, int op, list_head_t *pci_h)
int vps_set_pci(vps_handler *h, envid_t veid, int op, const char *root,
pci_param *pci)
{
- int ret = 0;
list_head_t *pci_h = &pci->list;
- str_param *res;
if (list_empty(pci_h))
return 0;
@@ -250,10 +220,5 @@ int vps_set_pci(vps_handler *h, envid_t veid, int op, const char *root,
}
logger(0, 0, "Setting PCI devices");
- list_for_each(res, pci_h, list)
- if ((ret = set_pci(h, veid, op, res->val)))
- break;
- if (!ret)
- ret = run_pci_script(veid, op, pci_h);
- return ret;
+ return run_pci_script(veid, op, pci_h, root);
}
Please sign in to comment.
Something went wrong with that request. Please try again.