[libvirt] [PATCH] Fix USB passthrough based on product/vendor
by Daniel P. Berrange
Changeset
commit 5073aa994af460e775cb3e548528e28d7660fcc8
Author: Cole Robinson <crobinso(a)redhat.com>
Date: Mon Jan 11 11:40:46 2010 -0500
Added support for product/vendor based passthrough, but it only
worked at the security driver layer. The main guest XML config
was not updated with the resolved bus/device ID. When the QEMU
argv refactoring removed use of product/vendor, this then broke
launching guests.
THe solution is to move the product/vendor resolution up a layer
into the QEMU driver. So the first thing QEMU does is resolve
the product/vendor to a bus/device and updates the XML config
with this info. The rest of the code, including security drivers
and QEMU argv generated can now rely on bus/device always being
set.
* src/util/hostusb.c, src/util/hostusb.h: Split vendor/product
resolution code out of usbGetDevice and into usbFindDevice.
Add accessors for bus/device ID
* src/security/virt-aa-helper.c, src/security/security_selinux.c,
src/qemu/qemu_security_dac.c: Remove vendor/product from the
usbGetDevice() calls
* src/qemu/qemu_driver.c: Use usbFindDevice to resolve vendor/product
into a bus/device ID
---
src/libvirt_private.syms | 3 +
src/qemu/qemu_driver.c | 102 +++++++++++++++++++++++++++++++++++----
src/qemu/qemu_security_dac.c | 8 +--
src/security/security_selinux.c | 8 +--
src/security/virt-aa-helper.c | 4 +-
src/util/hostusb.c | 39 +++++++++++----
src/util/hostusb.h | 13 +++--
7 files changed, 136 insertions(+), 41 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ce9f013..c5ee23d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -599,7 +599,10 @@ virArgvToString;
# usb.h
usbGetDevice;
+usbFindDevice;
usbFreeDevice;
+usbDeviceGetBus;
+usbDeviceGetDevno;
usbDeviceFileIterate;
# uuid.h
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ef3cd6c..50bd55b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2283,17 +2283,15 @@ cleanup:
return ret;
}
+
static int
-qemuPrepareHostDevices(struct qemud_driver *driver,
- virDomainDefPtr def)
+qemuPrepareHostPCIDevices(struct qemud_driver *driver,
+ virDomainDefPtr def)
{
pciDeviceList *pcidevs;
int i;
int ret = -1;
- if (!def->nhostdevs)
- return 0;
-
if (!(pcidevs = qemuGetPciHostDeviceList(def)))
return -1;
@@ -2344,6 +2342,62 @@ cleanup:
return ret;
}
+
+static int
+qemuPrepareHostUSBDevices(struct qemud_driver *driver ATTRIBUTE_UNUSED,
+ virDomainDefPtr def)
+{
+ int i;
+ for (i = 0 ; i < def->nhostdevs ; i++) {
+ virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ continue;
+
+ /* Resolve a vendor/product to bus/device */
+ if (hostdev->source.subsys.u.usb.vendor) {
+ usbDevice *usb
+ = usbFindDevice(hostdev->source.subsys.u.usb.vendor,
+ hostdev->source.subsys.u.usb.product);
+
+ if (!usb)
+ return -1;
+
+ hostdev->source.subsys.u.usb.bus = usbDeviceGetBus(usb);
+ hostdev->source.subsys.u.usb.device = usbDeviceGetDevno(usb);
+
+ fprintf(stderr, "Resolve %u %u -> %u %u\n",
+ hostdev->source.subsys.u.usb.vendor,
+ hostdev->source.subsys.u.usb.product,
+ hostdev->source.subsys.u.usb.bus,
+ hostdev->source.subsys.u.usb.device );
+
+ usbFreeDevice(usb);
+ }
+ }
+
+ return 0;
+}
+
+static int
+qemuPrepareHostDevices(struct qemud_driver *driver,
+ virDomainDefPtr def)
+{
+ if (!def->nhostdevs)
+ return 0;
+
+ if (qemuPrepareHostPCIDevices(driver, def) < 0)
+ return -1;
+
+ if (qemuPrepareHostUSBDevices(driver, def) < 0)
+ return -1;
+
+ return 0;
+}
+
+
static void
qemudReattachManagedDevice(pciDevice *dev)
{
@@ -6114,6 +6168,23 @@ static int qemudDomainAttachHostDevice(struct qemud_driver *driver,
return -1;
}
+ /* Resolve USB product/vendor to bus/device */
+ if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
+ hostdev->source.subsys.u.usb.vendor) {
+ usbDevice *usb
+ = usbFindDevice(hostdev->source.subsys.u.usb.vendor,
+ hostdev->source.subsys.u.usb.product);
+
+ if (!usb)
+ return -1;
+
+ hostdev->source.subsys.u.usb.bus = usbDeviceGetBus(usb);
+ hostdev->source.subsys.u.usb.device = usbDeviceGetDevno(usb);
+
+ usbFreeDevice(usb);
+ }
+
+
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(vm, hostdev) < 0)
@@ -6677,11 +6748,22 @@ static int qemudDomainDetachHostUsbDevice(struct qemud_driver *driver,
unsigned bus = vm->def->hostdevs[i]->source.subsys.u.usb.bus;
unsigned device = vm->def->hostdevs[i]->source.subsys.u.usb.device;
-
- if (dev->data.hostdev->source.subsys.u.usb.bus == bus &&
- dev->data.hostdev->source.subsys.u.usb.device == device) {
- detach = vm->def->hostdevs[i];
- break;
+ unsigned product = vm->def->hostdevs[i]->source.subsys.u.usb.product;
+ unsigned vendor = vm->def->hostdevs[i]->source.subsys.u.usb.vendor;
+
+ if (dev->data.hostdev->source.subsys.u.usb.bus &&
+ dev->data.hostdev->source.subsys.u.usb.device) {
+ if (dev->data.hostdev->source.subsys.u.usb.bus == bus &&
+ dev->data.hostdev->source.subsys.u.usb.device == device) {
+ detach = vm->def->hostdevs[i];
+ break;
+ }
+ } else {
+ if (dev->data.hostdev->source.subsys.u.usb.product == product &&
+ dev->data.hostdev->source.subsys.u.usb.vendor == vendor) {
+ detach = vm->def->hostdevs[i];
+ break;
+ }
}
}
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
index f281b96..6911f48 100644
--- a/src/qemu/qemu_security_dac.c
+++ b/src/qemu/qemu_security_dac.c
@@ -206,9 +206,7 @@ qemuSecurityDACSetSecurityHostdevLabel(virDomainObjPtr vm,
switch (dev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device,
- dev->source.subsys.u.usb.vendor,
- dev->source.subsys.u.usb.product);
+ dev->source.subsys.u.usb.device);
if (!usb)
goto done;
@@ -277,9 +275,7 @@ qemuSecurityDACRestoreSecurityHostdevLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
switch (dev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device,
- dev->source.subsys.u.usb.vendor,
- dev->source.subsys.u.usb.product);
+ dev->source.subsys.u.usb.device);
if (!usb)
goto done;
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 06a2479..b2c8581 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -491,9 +491,7 @@ SELinuxSetSecurityHostdevLabel(virDomainObjPtr vm,
switch (dev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device,
- dev->source.subsys.u.usb.vendor,
- dev->source.subsys.u.usb.product);
+ dev->source.subsys.u.usb.device);
if (!usb)
goto done;
@@ -561,9 +559,7 @@ SELinuxRestoreSecurityHostdevLabel(virDomainObjPtr vm,
switch (dev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device,
- dev->source.subsys.u.usb.vendor,
- dev->source.subsys.u.usb.product);
+ dev->source.subsys.u.usb.device);
if (!usb)
goto done;
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 066e18b..78bef41 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -836,9 +836,7 @@ get_files(vahControl * ctl)
switch (dev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device,
- dev->source.subsys.u.usb.vendor,
- dev->source.subsys.u.usb.product);
+ dev->source.subsys.u.usb.device);
if (usb == NULL)
continue;
diff --git a/src/util/hostusb.c b/src/util/hostusb.c
index bf96539..afba325 100644
--- a/src/util/hostusb.c
+++ b/src/util/hostusb.c
@@ -159,9 +159,7 @@ cleanup:
usbDevice *
usbGetDevice(unsigned bus,
- unsigned devno,
- unsigned vendor,
- unsigned product)
+ unsigned devno)
{
usbDevice *dev;
@@ -170,14 +168,6 @@ usbGetDevice(unsigned bus,
return NULL;
}
- if (vendor) {
- /* Look up bus.dev by vendor:product */
- if (usbFindBusByVendor(vendor, product, &bus, &devno) < 0) {
- VIR_FREE(dev);
- return NULL;
- }
- }
-
dev->bus = bus;
dev->dev = devno;
@@ -194,6 +184,21 @@ usbGetDevice(unsigned bus,
return dev;
}
+
+usbDevice *
+usbFindDevice(unsigned vendor,
+ unsigned product)
+{
+ unsigned bus = 0, devno = 0;
+
+ if (usbFindBusByVendor(vendor, product, &bus, &devno) < 0) {
+ return NULL;
+ }
+
+ return usbGetDevice(bus, devno);
+}
+
+
void
usbFreeDevice(usbDevice *dev)
{
@@ -202,6 +207,18 @@ usbFreeDevice(usbDevice *dev)
}
+unsigned usbDeviceGetBus(usbDevice *dev)
+{
+ return dev->bus;
+}
+
+
+unsigned usbDeviceGetDevno(usbDevice *dev)
+{
+ return dev->dev;
+}
+
+
int usbDeviceFileIterate(usbDevice *dev,
usbDeviceFileActor actor,
void *opaque)
diff --git a/src/util/hostusb.h b/src/util/hostusb.h
index bc22671..9a1b1b7 100644
--- a/src/util/hostusb.h
+++ b/src/util/hostusb.h
@@ -26,11 +26,14 @@
typedef struct _usbDevice usbDevice;
-usbDevice *usbGetDevice (unsigned bus,
- unsigned devno,
- unsigned vendor,
- unsigned product);
-void usbFreeDevice (usbDevice *dev);
+usbDevice *usbGetDevice(unsigned bus,
+ unsigned devno);
+usbDevice *usbFindDevice(unsigned vendor,
+ unsigned product);
+void usbFreeDevice (usbDevice *dev);
+
+unsigned usbDeviceGetBus(usbDevice *dev);
+unsigned usbDeviceGetDevno(usbDevice *dev);
/*
* Callback that will be invoked once for each file
--
1.6.5.2
14 years, 8 months
[libvirt] RFC: Modelling timers/ clocks / tick policies in libvirt
by Daniel P. Berrange
One of the things we've not dealt with in libvirt yet is how to model the
various evil hacks most virt products have for dealing with timers in
guests. This email tries to outlines the problems & way each virt system
has dealt with them. Finally it suggests how to manage this in libvirt
domain XML. Comments please :-)
Virtual machine timer management in libvirt
===========================================
On PC hardware there are a number of terrible timers / clock sources available
to operating systems
* PIT
Timer with periodic interrupts
* RTC
Time of Day clock, continuous running
Timer with periodic interrupts
* Local APIC Timer
Timer with periodic interrupts
* ACPI Timer
Timer with periodic interrupts
* TSC
Read via rdtsc instruction. No interrupts
Unreliable on some hardware. eg changes frequency.
Not synced between cores
Different HZ across hosts
* HPET
Multiple timers with periodic interrupts
Can replace PIT/RTC timers
They all generally suck in real hardware, and this gets worse in virtual machines.
Many different approaches to making them suck less in VMWare, Xen & KVM, but there
are some reasonably common concepts....
Virtual timekeeping problems
----------------------------
Three primary problems / areas to deal with:
* Time of day clock (RTC)
- Initialized to UTC/Localtime/Timezone/UTC+offset
- Two modes of operation:
1. Guest wallclock: only runs when guest is executing. ie stopped across save/restore, etc
2. Host wallclock: runs continuously with host wall time.
* Interrupt timers
- Ticks can not always be delivered on time
Policies to deal with "missed" ticks:
1. Deliver at normal rate without catchup
2. Deliver at higher rate to catch up
3. Merge into 1 tick & deliver asap
4. Discard all missed ticks
* TSC
- rdtsc instruction can be exposed to guests in two ways
1. Trap + emulate (slow, but more reliable)
2. Native (fast, but possibly unreliable)
Optionally also expose a 'rdtscp' instruction
Possiblly set a fixed HZ independant of host.
VMWare timekeeping
------------------
* All timers run in "apparant time" ie track guest wallclock
* Missed tick policy is to deliver at higher rate to catchup
* TSC can be switched between native/emulate (virtual_rdtsc=TRUE|FALSE)
* TSC can have hardcoded HZ in emulate mode (apparantHZ=VALUE)
* RTC time of day is synced to host at startup (rtc.diffFromUTC or rtc.startTime)
* VMWare tools reset guest TOD if it gets out of sync
Xen timekeeping
---------------
* Virtual platform timer (VPT) used as source for other timers
* VPT has 4 modes
0: delay_for_missed_ticks
Missed ticks are delivered when next scheduled, at the normal
rate. RTC runs in guest wallclock, so is delayed. No catchup is
attempted
1: no_delay_for_missed_ticks
Missed ticks are delivered when next scheduled, at the normal
rate. RTC runs in host wallclock, so is not delayed.
2: no_missed_ticks_pending
Missed ticks are discarded & next tick is delivered normally. RTC
runs in host wallclock.
3: one_missed_tick_pending
Missed interrupts are collapsed into a single late tick. RTC
run in host wallclock.
* HPET
Optionally enabled
* TSC. Can run in 4 modes
- auto: emulate if host TSC is unstable. native with invariant TSC
- native: always native regardless of host TSC stability
- emulate: trap + emulate regardless of host TSC invariant
- pvrdtsc: native, requiring invariant TSC. Also exposes rdtscp instruction
KVM timekeeping
---------------
* PIT: can be in kernel, or userspace (userspace deprecated for KVM)
Default tick policies differ for both impls
- Userspace: Default: missed ticks are delivered when next scheduled at normal rate
-tdf flag enable tick reinjection to catchup
- Kernel: Default: Missed ticks are delivered at higher rate to catch up
-no-kvm-pit-reinjection to disable tick reinjection catchup
* RTC
TOD clock can run in host or guest wallclock (clock=host|guest)
Default: missed ticks are delivered when next scheduled at normal rate
-rtc-td-hack or -clock driftfix=slew: missed ticks are delivered at a
higher rate to catchup
* TSC
- Always runs native.
* HPET
- Optionally enabled/disabled
Mapping in libvirt XML
----------------------
Currently supports setting Time of Day clock via
<clock offset="utc"/>
Always sync to UTC
<clock offset="localtime"/>
Always sync to host timezone
<clock offset="timezone" timezone='Europe/Paris'/>
Sync to arbitrary timezone
<clock offset="variable" adjustment='123456'/>
Sync to UTC + arbitrary offset
Proposal to model all timers policies as sub-elements of this <clock/>
In general we wil allow zero or more <timer/> elements following the
syntax:
<timer name='platform|pit|rtc|hpet|tsc'
wallclock='host|guest'
tickpolicy='none|catchup|merge|discard'
frequency='123'
mode='auto|native|emulate|paravirt'
present='yes|no' />
Meaning of 'name':
Names map to regular PC timers / clocks. 'Platform' refers to the
(optional) master virtual clock source that may be used to drive
policy of "other" clocks (eg used in Xen, which clocks are controlled
by the platform clock is to be undefined because it has varied in
Xen over time).
Meaning of 'tickpolicy':
none: continue to deliver at normal rate (ie ticks are delayed)
catchup: deliver at higher rate to catchup
merge: ticks merged into 1 single tick
discard: all missed ticks are discarded
Meaning of 'wallclock':
Only valid for name='rtc' or 'platform'
host: RTC wallclock always tracks host time
guest: RTC wallclock always tracks host time
Meaning of 'frequency':
Set a fixed frequency in HZ.
NB: Only relevant for TSC. All other timers are fixed (PIT, RTC), or
fully guest controlled frequency (HPET)
Meaning of 'mode':
Control how the clock is exposed to guest.
auto: native if safe, otherwise emulate
native: always native
emulate: always emulate
paravirt: native + paravirtualize
NB: Only relevant for TSC. All other timers are always emulated.
Meaing of 'present':
Used to override default set of timers visible to the guest. eg to
enable or disable the HPET
Mapping to VMWare
-----------------
eg with guest config showing
diffFromUTC='123456'
apparentHZ='123456'
virtual_rdtsc=False
libvirt XML gets:
<clock mode='variable' adjustment='123456'>
<timer name='tsc' frequency='123456' mode='native'/>
</clock>
Mapping to Xen
--------------
eg with guest config showing
timer_mode=3
hpet=1
tsc_mode=2
localtime=1
<clock mode='localtime'>
<timer name='platform' tickpolicy='merge' wallclock='host'/>
<timer name='hpet'/>
<timer name='tsc' mode='native'/>
</clock>
Mapping to KVM
--------------
eg with guest ARGV showing
-no-kvm-pit-reinjection
-clock base=localtime,clock=guest,driftfix=slew
-no-hpet
<clock mode='localtime'>
<timer name='rtc' tickpolicy='catchup' wallclock='guest'/>
<timer name='pit' tickpolicy='none'/>
<timer name='hpet' present='no'/>
</clock>
Further reading
---------------
VMWare has the best doc:
http://www.vmware.com/pdf/vmware_timekeeping.pdf
Xen:
Docs on 'tsc_mode' at
$SOURCETREE/docs/misc/tscmode.txt
Docs for 'timer_mode' in the source code only:
xen/include/public/hvm/params.h
KVM:
No docs at all. Guess from -help descriptions, reading source code & asking
clever people about it :-)
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
14 years, 8 months
[libvirt] Get IP of ghost from remote with libvirt
by angelo alfano
Hello everyone, sorry for my English,
I need to create a script (preferably in Python) that runs on a host
machine, I return the IP address of a Ghost running, providing its hostname.
In this VM is assigned the IP in DHCP with a network with this
configuration:
$ virsh net-dumpxml network1
Connecting to uri: qemu:///system
<network>
<name>network1</name>
<uuid>6050d8d4-4030-fdd5-ddfa-041c89bbdfa7</uuid>
<forward mode='nat'/>
<bridge name='virbr0' stp='on' forwardDelay='0' />
<ip address='192.168.100.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.100.2' end='192.168.100.254' />
</dhcp>
</ip>
</network>
While the configuration of one of the VM is:
$ virsh dumpxml test1
Connecting to uri: qemu:///system
<domain type='kvm' id='1'>
<name>test1</name>
<uuid>cf71c7d3-0d05-d51c-492e-f5ad2be3ec0e</uuid>
<memory>524288</memory>
<currentMemory>524288</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='x86_64' machine='pc-0.11'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/bin/kvm</emulator>
<disk type='file' device='cdrom'>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
<disk type='file' device='disk'>
<source file='/var/lib/libvirt/images/test1.img'/>
<target dev='vda' bus='virtio'/>
</disk>
<interface type='network'>
<mac address='54:52:00:4e:59:0d'/>
<source network='network1'/>
<target dev='vnet0'/>
<model type='virtio'/>
</interface>
<serial type='pty'>
<source path='/dev/pts/1'/>
<target port='0'/>
</serial>
<console type='pty' tty='/dev/pts/1'>
<source path='/dev/pts/1'/>
<target port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='5900' autoport='yes' keymap='it'/>
<sound model='es1370'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</devices>
<seclabel type='dynamic' model='apparmor'>
<label>libvirt-cf71c7d3-0d05-d51c-492e-f5ad2be3ec0e</label>
<imagelabel>libvirt-cf71c7d3-0d05-d51c-492e-f5ad2be3ec0e</imagelabel>
</seclabel>
</domain>
Give me a hand?
Thanks
--
Angelo
14 years, 8 months
[libvirt] Assigning a static IP to the Linux Container through libvirt.
by Kumar L Srikanth-B22348
Hi,
I want to assign a static IP 172.16.1.20 to one of the containers
created using libvirt.
For that, I defined a network 'mynetwork' using net-define. The XML
format for that network is shown below:
<network>
<name>mynetwork</name>
<uuid>f76c44dd-bcef-6b45-4a50-00d575a369ad</uuid>
<bridge name='virbr1' stp='on' delay='0' />
<ip address='172.16.1.20' netmask='255.255.255.0'>
</ip>
</network>
I started the network 'mynetwork' using net-start.
virsh # net-list --all
Name State Autostart
-----------------------------------------
default active yes
mynetwork active no
I created a domain 'vm1_fedora' with libvirt XML:
<domain type='lxc' id='1'>
<name>vm1_fedora</name>
<memory>500000</memory>
<os>
<type>exe</type>
<init>/bin/bash</init>
</os>
<vcpu>1</vcpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/libexec/libvirt_lxc</emulator>
<filesystem type='mount'>
<source dir='/root/lxc/fedora12'/>
<target dir='/'/>
</filesystem>
<filesystem type='mount'>
<source dir='/root/lxc/fedora12/dev'/>
<target dir='/dev'/>
</filesystem>
<interface type='network'>
<source network='mynetwork'/>
</interface>
<console type='pty' />
</devices>
</domain>
But, when I start that domain and see for 'ifconfig', I am not able to
see the IP address 172.16.1.20 there.
[root@localhost /]# ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:53:4D:BF
inet6 addr: fe80::5054:ff:fe53:4dbf/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:18 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:840 (840.0 b) TX bytes:384 (384.0 b)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
can you please let me know, how can I assign a static IP to the Linux
Container?
Regards,
Srikanth.
14 years, 8 months
[libvirt] Assigning a Static IP to the Domain.
by Kumar L Srikanth-B22348
Hi,
I am using libvirt version 0.7.6, to create a Linux Container. With the
domain XML format, I am able to create a Domain and able to access.
But, I am struck at assigning an IP address to the Domain. I want to
assign a static IP to eth0 of the Domain and ale to ping that from the
host machine.
For that, I created a bridge br0 [which can be linked to the interface
eth0 of the Domain created by libvirt] with the IP 172.16.1.10. I want
to assign an IP 172.16.1.16 to the Domain.
Can any one please guide me?
Regards,
Srikanth.
14 years, 8 months
[libvirt] [PATCH] Change default for storage uid/gid from getuid()/getgid() to -1/-1
by Laine Stump
This allows the config to have a setting that means "leave it alone",
eg when building a pool where the directory already exists the user
may want the current uid/gid of the directory left intact. This
actually gets us back to older behavior - before recent changes to the
pool building code, we weren't as insistent about honoring the uid/gid
settings in the XML, and virt-manager was taking advantage of this
behavior.
As a side benefit, removing calls to getuid/getgid from the XML
parsing functions also seems like a good idea. And having a default
that is different from a common/useful value (0 == root) is a good
thing in general, as it removes ambiguity from decisions (at least one
place in the code was checking for (perms.uid == 0) to see if a
special uid was requested).
Note that this will only affect newly created pools and volumes. Due
to the way that the XML is parsed, then formatted for newly created
volumes, all existing pools/volumes already have an explicit uid and
gid set.
src/conf/storage_conf.c: Remove calls to setuid/setgid for default values
of uid/gid, and set them to -1 instead
src/storage/storage_backend.c:
src/storage/storage_backend_fs.c:
Make account for the new default values of perms.uid
and perms.gid.
---
src/conf/storage_conf.c | 8 +++---
src/storage/storage_backend.c | 25 +++++++++++++----------
src/storage/storage_backend_fs.c | 39 +++++++++++++++++++++++++++----------
3 files changed, 46 insertions(+), 26 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 19a1db9..f59f109 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -539,8 +539,8 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt,
if (node == NULL) {
/* Set default values if there is not <permissions> element */
perms->mode = defaultmode;
- perms->uid = getuid();
- perms->gid = getgid();
+ perms->uid = -1;
+ perms->gid = -1;
perms->label = NULL;
return 0;
}
@@ -564,7 +564,7 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt,
}
if (virXPathNode("./owner", ctxt) == NULL) {
- perms->uid = getuid();
+ perms->uid = -1;
} else {
if (virXPathLong("number(./owner)", ctxt, &v) < 0) {
virStorageReportError(VIR_ERR_XML_ERROR,
@@ -575,7 +575,7 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt,
}
if (virXPathNode("./group", ctxt) == NULL) {
- perms->gid = getgid();
+ perms->gid = -1;
} else {
if (virXPathLong("number(./group)", ctxt, &v) < 0) {
virStorageReportError(VIR_ERR_XML_ERROR,
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 3742493..ee6a32e 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -241,11 +241,10 @@ virStorageBackendCreateBlockFrom(virConnectPtr conn ATTRIBUTE_UNUSED,
uid = (vol->target.perms.uid != st.st_uid) ? vol->target.perms.uid : -1;
gid = (vol->target.perms.gid != st.st_gid) ? vol->target.perms.gid : -1;
if (((uid != -1) || (gid != -1))
- && (fchown(fd, vol->target.perms.uid, vol->target.perms.gid) < 0)) {
+ && (fchown(fd, uid, gid) < 0)) {
virReportSystemError(errno,
_("cannot chown '%s' to (%u, %u)"),
- vol->target.path, vol->target.perms.uid,
- vol->target.perms.gid);
+ vol->target.path, uid, gid);
goto cleanup;
}
if (fchmod(fd, vol->target.perms.mode) < 0) {
@@ -356,10 +355,12 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED,
goto cleanup;
}
+ uid_t uid = (vol->target.perms.uid == -1) ? getuid() : vol->target.perms.uid;
+ gid_t gid = (vol->target.perms.gid == -1) ? getgid() : vol->target.perms.gid;
+
if ((createstat = virFileOperation(vol->target.path,
O_RDWR | O_CREAT | O_EXCL | O_DSYNC,
- vol->target.perms.mode,
- vol->target.perms.uid, vol->target.perms.gid,
+ vol->target.perms.mode, uid, gid,
createRawFileOpHook, &hdata,
VIR_FILE_OP_FORCE_PERMS |
(pool->def->type == VIR_STORAGE_POOL_NETFS
@@ -491,14 +492,14 @@ cleanup:
static int virStorageBuildSetUIDHook(void *data) {
virStorageVolDefPtr vol = data;
- if ((vol->target.perms.gid != 0)
+ if ((vol->target.perms.gid != -1)
&& (setgid(vol->target.perms.gid) != 0)) {
virReportSystemError(errno,
_("Cannot set gid to %u before creating %s"),
vol->target.perms.gid, vol->target.path);
return -1;
}
- if ((vol->target.perms.uid != 0)
+ if ((vol->target.perms.uid != -1)
&& (setuid(vol->target.perms.uid) != 0)) {
virReportSystemError(errno,
_("Cannot set uid to %u before creating %s"),
@@ -517,8 +518,11 @@ static int virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool,
int filecreated = 0;
if ((pool->def->type == VIR_STORAGE_POOL_NETFS)
- && (getuid() == 0)
- && ((vol->target.perms.uid != 0) || (vol->target.perms.gid != 0))) {
+ && (((getuid() == 0)
+ && (vol->target.perms.uid != -1)
+ && (vol->target.perms.uid != 0))
+ || ((vol->target.perms.gid != -1)
+ && (vol->target.perms.gid != getgid())))) {
if (virRunWithHook(cmdargv,
virStorageBuildSetUIDHook, vol, NULL) == 0) {
/* command was successfully run, check if the file was created */
@@ -547,8 +551,7 @@ static int virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool,
&& (chown(vol->target.path, uid, gid) < 0)) {
virReportSystemError(errno,
_("cannot chown %s to (%u, %u)"),
- vol->target.path, vol->target.perms.uid,
- vol->target.perms.gid);
+ vol->target.path, uid, gid);
return -1;
}
if (chmod(vol->target.path, vol->target.perms.mode) < 0) {
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 8279d78..dfd417f 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -529,16 +529,28 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED,
/* Now create the final dir in the path with the uid/gid/mode
* requested in the config. If the dir already exists, just set
* the perms. */
- if ((err = virDirCreate(pool->def->target.path,
- pool->def->target.perms.mode,
- pool->def->target.perms.uid,
- pool->def->target.perms.gid,
- VIR_DIR_CREATE_FORCE_PERMS | VIR_DIR_CREATE_ALLOW_EXIST |
- (pool->def->type == VIR_STORAGE_POOL_NETFS
- ? VIR_DIR_CREATE_AS_UID : 0)) != 0)) {
- virReportSystemError(err, _("cannot create path '%s'"),
- pool->def->target.path);
- goto error;
+
+ struct stat st;
+
+ if ((stat(pool->def->target.path, &st) < 0)
+ || (pool->def->target.perms.uid != -1)) {
+
+ uid_t uid = (pool->def->target.perms.uid == -1)
+ ? getuid() : pool->def->target.perms.uid;
+ gid_t gid = (pool->def->target.perms.gid == -1)
+ ? getgid() : pool->def->target.perms.gid;
+
+ if ((err = virDirCreate(pool->def->target.path,
+ pool->def->target.perms.mode,
+ uid, gid,
+ VIR_DIR_CREATE_FORCE_PERMS |
+ VIR_DIR_CREATE_ALLOW_EXIST |
+ (pool->def->type == VIR_STORAGE_POOL_NETFS
+ ? VIR_DIR_CREATE_AS_UID : 0)) != 0)) {
+ virReportSystemError(err, _("cannot create path '%s'"),
+ pool->def->target.path);
+ goto error;
+ }
}
ret = 0;
error:
@@ -777,8 +789,13 @@ static int createFileDir(virConnectPtr conn ATTRIBUTE_UNUSED,
return -1;
}
+ uid_t uid = (vol->target.perms.uid == -1)
+ ? getuid() : vol->target.perms.uid;
+ gid_t gid = (vol->target.perms.gid == -1)
+ ? getgid() : vol->target.perms.gid;
+
if ((err = virDirCreate(vol->target.path, vol->target.perms.mode,
- vol->target.perms.uid, vol->target.perms.gid,
+ uid, gid,
VIR_DIR_CREATE_FORCE_PERMS |
(pool->def->type == VIR_STORAGE_POOL_NETFS
? VIR_DIR_CREATE_AS_UID : 0))) != 0) {
--
1.6.6.1
14 years, 8 months
[libvirt] [PATCH 0/9] Storage volume wiping API
by David Allan
Here's the revised volume wiping API patchset (thanks to Dan for the improved name). I'm sending a replacement patchset since the name change made for a very large and messy incremental. This set contains everybody's feedback, which was all very helpful. Many thanks.
Dave
David Allan (9):
Add public API for volume wiping
Define the internal driver API for vol wiping
Add vol wiping to ESX storage driver struct
Implement the public API for vol wiping
Define wire protocol format for vol wiping
Implement RPC client for vol wiping
Implement the remote dispatch bits of vol wiping
Simplified version of volume wiping based on feedback from the list.
Virsh support for vol wiping
daemon/remote.c | 32 +++++
daemon/remote_dispatch_args.h | 1 +
daemon/remote_dispatch_prototypes.h | 8 ++
daemon/remote_dispatch_table.h | 5 +
include/libvirt/libvirt.h.in | 2 +
src/driver.h | 5 +
src/esx/esx_storage_driver.c | 1 +
src/libvirt.c | 47 ++++++++
src/libvirt_public.syms | 1 +
src/remote/remote_driver.c | 27 ++++
src/remote/remote_protocol.c | 11 ++
src/remote/remote_protocol.h | 9 ++
src/remote/remote_protocol.x | 8 +-
src/storage/storage_driver.c | 224 +++++++++++++++++++++++++++++++++++
tools/virsh.c | 42 +++++++
15 files changed, 422 insertions(+), 1 deletions(-)
14 years, 8 months
[libvirt] Libvirt Auth
by Marco Mornati
Hello guys,
I've created a plugin for Hudson (CI) to manage virtmachines using
libvirt java (start vm for a build and stop just after).
I've just a problem in authentication, in fact I cannot send uname and
password using code, libvirt ask me for the credentials on CLI.
someone could explain me How I can use authentican or where I can find
an usage guide or example?
Thanks a lot
Bye
Marco
14 years, 8 months
[libvirt] FW: Libvirt and openvz?
by Thomas Graves
I just recently started using openvz and I'm trying to use libvirt/virsh
with it.
I followed the directions on page: http://libvirt.org/drvopenvz.html
But I get an error trying to run define with the example config file:
virsh define virt.conf
error: Failed to define domain from virt.conf
error: unknown OS type exe
sudo virsh -c openvz:/// list
error: could not connect to openvz:///
error: failed to connect to the hypervisor
I'm using libvirt 0.7.2 with latest rhel5.4 openvz.
Does anyone have more example configuration files or other setup
instructions?
Does Libvirt allow you to specify other resource limits and controls that
openvz has - like vzctl set --devnodes device:rw or vzctl set kmemsize?
Thanks,
Tom
14 years, 9 months