[libvirt] [RFC,PATCH] network: add 'netboot' option to dhcp config
by Jeremy Kerr
Currently, libvirtd will start a dnsmasq process for the virtual
network, but (aside from killing the dnsmasq process and replacing it),
there's no way to define tftp boot options.
This change introduces a 'netboot' tag to the dhcp configuration:
<network>
<name>default</name>
<bridge name="virbr%d" />
<forward/>
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.2" end="192.168.122.254" />
<netboot root="/srv/tftp" file="pxeboot.img"/>
</dhcp>
</ip>
</network>
When root= and file= attributes are present, these are passed to the
arguments to dnsmasq:
dnsmasq [...] --enable-tftp --tftp-root /srv/tftp --dhcp-boot pxeboot.img
At present, only local tftp servers are supported (ie, dnsmasq runs as
the tftp server), but we could improve this in future by adding a
server= attribute.
Signed-off-by: Jeremy Kerr <jk(a)ozlabs.org>
---
docs/formatnetwork.html.in | 6 ++++++
docs/schemas/network.rng | 6 ++++++
src/network_conf.c | 28 ++++++++++++++++++++++++++++
src/network_conf.h | 9 +++++++++
src/network_driver.c | 10 ++++++++++
5 files changed, 59 insertions(+)
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index fd68430..3186498 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -138,6 +138,12 @@
name to be given that host by the DHCP server (via the
<code>name</code> attribute). <span class="since">Since 0.4.5</span>
</dd>
+ <dt><code>netboot</code></dt>
+ <dd>The optional <code>netboot</code> element specified network boot
+ options to be provided by the DHCP server. Two attributes are
+ required: <code>root</code> (the root path of the TFTP server), and
+ <code>file</code> (the file to be used for the boot image).
+ </dd>
</dl>
<h2><a name="examples">Example configuration</a></h2>
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index a4281a5..571e916 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -76,6 +76,12 @@
<attribute name="ip"><text/></attribute>
</element>
</zeroOrMore>
+ <optional>
+ <element name="netboot">
+ <attribute name="root"><text/></attribute>
+ <attribute name="file"><text/></attribute>
+ </element>
+ </optional>
</element>
</element>
</optional>
diff --git a/src/network_conf.c b/src/network_conf.c
index 3764bb4..87bb5e4 100644
--- a/src/network_conf.c
+++ b/src/network_conf.c
@@ -115,6 +115,9 @@ void virNetworkDefFree(virNetworkDefPtr def)
}
VIR_FREE(def->hosts);
+ VIR_FREE(def->tftproot);
+ VIR_FREE(def->bootfile);
+
VIR_FREE(def);
}
@@ -299,6 +302,24 @@ virNetworkDHCPRangeDefParseXML(virConnectPtr conn,
def->hosts[def->nhosts].name = (char *)name;
def->hosts[def->nhosts].ip = (char *)ip;
def->nhosts++;
+
+ } else if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "netboot")) {
+ xmlChar *root, *file;
+
+ if (!(root = xmlGetProp(cur, BAD_CAST "root"))) {
+ cur = cur->next;
+ continue;
+ }
+
+ if (!(file = xmlGetProp(cur, BAD_CAST "file"))) {
+ cur = cur->next;
+ xmlFree(root);
+ continue;
+ }
+
+ def->tftproot = (char *)root;
+ def->bootfile = (char *)file;
}
cur = cur->next;
@@ -621,6 +642,13 @@ char *virNetworkDefFormat(virConnectPtr conn,
virBufferVSprintf(&buf, "ip='%s' ", def->hosts[i].ip);
virBufferAddLit(&buf, "/>\n");
}
+ if (virNetworkDefProvidesNetboot(def)) {
+ virBufferAddLit(&buf, " <netboot");
+ virBufferEscapeString(&buf, " root='%s'", def->tftproot);
+ virBufferEscapeString(&buf, " file='%s'", def->bootfile);
+ virBufferAddLit(&buf, " />\n");
+ }
+
virBufferAddLit(&buf, " </dhcp>\n");
}
diff --git a/src/network_conf.h b/src/network_conf.h
index 4076f9a..f6f7c1e 100644
--- a/src/network_conf.h
+++ b/src/network_conf.h
@@ -78,8 +78,17 @@ struct _virNetworkDef {
unsigned int nhosts; /* Zero or more dhcp hosts */
virNetworkDHCPHostDefPtr hosts;
+
+ char *tftproot;
+ char *bootfile;
};
+static inline int
+virNetworkDefProvidesNetboot(const virNetworkDefPtr def)
+{
+ return def->tftproot && def->bootfile;
+}
+
typedef struct _virNetworkObj virNetworkObj;
typedef virNetworkObj *virNetworkObjPtr;
struct _virNetworkObj {
diff --git a/src/network_driver.c b/src/network_driver.c
index 49855bf..cf462f2 100644
--- a/src/network_driver.c
+++ b/src/network_driver.c
@@ -400,6 +400,8 @@ networkBuildDnsmasqArgv(virConnectPtr conn,
(2 * network->def->nranges) + /* --dhcp-range 10.0.0.2,10.0.0.254 */
/* --dhcp-host 01:23:45:67:89:0a,hostname,10.0.0.3 */
(2 * network->def->nhosts) +
+ /* --enable-tftp --tftp-root /srv/tftp --dhcp-boot pxeboot.img */
+ (virNetworkDefProvidesNetboot(network->def) ? 5 : 0) +
1; /* NULL */
if (VIR_ALLOC_N(*argv, len) < 0)
@@ -478,6 +480,14 @@ networkBuildDnsmasqArgv(virConnectPtr conn,
APPEND_ARG(*argv, i++, buf);
}
+ if (virNetworkDefProvidesNetboot(network->def)) {
+ APPEND_ARG(*argv, i++, "--enable-tftp");
+ APPEND_ARG(*argv, i++, "--tftp-root");
+ APPEND_ARG(*argv, i++, network->def->tftproot);
+ APPEND_ARG(*argv, i++, "--dhcp-boot");
+ APPEND_ARG(*argv, i++, network->def->bootfile);
+ }
+
#undef APPEND_ARG
return 0;
15 years, 2 months
[libvirt] [PATCH] virStrncpy
by Chris Lalancette
Next revision of the virStrncpy patch. This one has the feedback from
Mattias Bolte incorporated in, and passes all of the "make check"
tests. I've also done basic testing on the hypervisors I have access to,
(xen and kvm) and it seems to work there. That doesn't guarantee that it
is bug-free, but most of the problems have been ironed out.
15 years, 2 months
[libvirt] [RFC] Support for CPUID masking v2
by Jiri Denemark
Hi,
This is an attempt to provide similar flexibility to CPU ID masking without
being x86-specific and unfriendly to users. As suggested by Dan, we need a way
to specify both CPU flags and topology to achieve this goal.
Firstly, CPU topology and all (actually all that libvirt knows about) CPU
features have to be advertised in host capabilities:
<host>
<cpu>
...
<features>
<feature>NAME</feature>
</features>
<topology>
<sockets>NUMBER_OF_SOCKETS</sockets>
<cores>CORES_PER_SOCKET</cores>
<threads>THREADS_PER_CORE</threads>
</topology>
</cpu>
...
</host>
I'm not 100% sure we should represent CPU features as <feature>NAME</feature>
especially because some features are currently advertised as <NAME/>. However,
extending XML schema every time a new feature is introduced doesn't look like
a good idea at all. The problem is we can't get rid of <NAME/>-style features,
which would result in redundancy:
<features>
<vmx/>
<feature>vmx</feature>
</features>
But I think it's better than changing the schema to add new features.
Secondly, drivers which support detailed CPU specification have to advertise
it in guest capabilities. In case <features> are meant to be hypervisor
features, than it could look like:
<guest>
...
<features>
<cpu/>
</features>
</guest>
But if they are meant to be CPU features, we need to come up with something
else:
<guest>
...
<cpu_selection/>
</guest>
I'm not sure how to deal with named CPUs suggested by Dan. Either we need to
come up with global set of named CPUs and document what they mean or let
drivers specify their own named CPUs and advertise them through guest
capabilities:
<guest>
...
<cpu model="NAME">
<feature>NAME</feature>
...
</cpu>
</guest>
The former approach would make matching named CPUs with those defined by a
hypervisor (such as qemu) quite hard. The latter could bring the need for
hardcoding features provided by specific CPU models or, in case we decide not
to provide a list of features for each CPU model, it can complicate
transferring a domain from one hypervisor to another.
And finally, CPU may be configured in domain XML configuration:
<domain>
...
<cpu model="NAME">
<topology>
<sockets>NUMBER_OF_SOCKETS</sockets>
<cores>CORES_PER_SOCKET</cores>
<threads>THREADS_PER_CORE</threads>
</topology>
<feature name="NAME" mode="set|check" value="on|off"/>
</cpu>
</domain>
Mode 'check' checks physical CPU for the feature and refuses the domain to
start if it doesn't match. VCPU feature is set to the same value. Mode 'set'
just sets the VCPU feature.
Final note: <topology> could also be called <cpu_topology> to avoid confusion
with NUMA <topology>, which is used in host capabilities. However, I prefer
<cpu><topology>...</topology></cpu> over
<cpu><cpu_topology>...</cpu_topology></cpu>.
Thanks for your comments.
Jirka
15 years, 2 months
[libvirt] Fix Xen virConnectPtr leak
by Matthias Bolte
The commit cb51aa48a777ddae6997faa9f28350cb62655ffd "Fix up connection
reference counting." changed the driver closing and virConnectPtr
unref-logic in virConnectClose().
Before this commit virConnectClose() closed all drivers of the given
virConnectPtr and virUnrefConnect()'ed it afterwards. After this
commit the driver-closing is done in virUnrefConnect() if and only if
the ref-count of the virConnectPtr dropped to zero.
This change in execution order leads to a virConnectPtr leak, at least
for connections to Xen.
The relevant call sequences:
virConnectOpen() -> xenUnifiedOpen() ...
... xenInotifyOpen() -> virConnectRef(conn)
... xenStoreOpen() -> xenStoreAddWatch() -> conn->refs++
virConnectClose() -> xenUnifiedClose() ...
... xenInotifyClose() -> virUnrefConnect(conn)
... xenStoreClose() -> xenStoreRemoveWatch() -> virUnrefConnect(conn)
Before the commit this additional virConnectRef/virUnrefConnect calls
where no problem, because virConnectClose() closed the drivers
explicitly and the additional refs added by the Xen subdrivers were
removed properly. After the commit this additional refs result in a
virConnectPtr leak (including a leak of the hypercall file handle;
that's how I noticed this problem), because now the drivers are only
close if and only if the ref-count drops to zero, but this cannot
happen anymore, because the additional refs from the Xen subdrivers
would only be removed if the drivers get closed, but that doesn't
happen because the ref-count cannot drop to zero.
The fix for this problem is simple: remove the
virConnectRef/virUnrefConnect calls from the Xen subdrivers (see
attached patch). Maybe someone could explain why the Xen Inotify and
Xen Store driver do this extra ref-counting, but none of the other Xen
subdrivers. It seems unnecessary to me and can be removed without
problems.
Matthias
15 years, 2 months
[libvirt] kvm networking () on debian unstable
by Thomas Koch
Hi,
I'm trying to get NAT networking running as described in
http://libvirt.org/formatnetwork.html#examplesNAT
But in the guest, ifconfig shows only the lo interface. I created the kvm
image (debian lenny 5.0.3) directly with qemu-img and kvm, because virt-
install also didn't work. Afterwards I created the XML file for libvirt:
<domain type='kvm'>
<name>hadoop1</name>
<uuid>c40b6644-362a-e5ab-8825-cd1a7fbe24eb</uuid>
<memory>524288</memory>
<currentMemory>524288</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='x86_64' machine='pc'>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='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/images/hadoop1.qcow2'/>
<target dev='hda' bus='ide'/>
</disk>
<interface type='network'>
<mac address='52:54:00:05:74:bb'/>
<source network='default'/>
<model type='virtio'/>
</interface>
<!--serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target port='0'/>
</console-->
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' keymap='de-ch'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</devices>
</domain>
The network config is:
<network>
<name>default</name>
<bridge name="virbr0" />
<forward/>
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.2" end="192.168.122.254" />
</dhcp>
</ip>
</network>
ifconfig of the host (needs cleanup, I know):
eth1 Link encap:Ethernet Hardware Adresse 00:1c:25:18:4d:e6
UP BROADCAST RUNNING MULTICAST MTU:1500 Metrik:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
Kollisionen:0 Sendewarteschlangenlänge:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Speicher:fe200000-fe220000
eth1:avahi Link encap:Ethernet Hardware Adresse 00:1c:25:18:4d:e6
inet Adresse:169.254.6.97 Bcast:169.254.255.255 Maske:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metrik:1
Speicher:fe200000-fe220000
lo Link encap:Lokale Schleife
inet Adresse:127.0.0.1 Maske:255.0.0.0
inet6-Adresse: ::1/128 Gültigkeitsbereich:Maschine
UP LOOPBACK RUNNING MTU:16436 Metrik:1
RX packets:160751 errors:0 dropped:0 overruns:0 frame:0
TX packets:160751 errors:0 dropped:0 overruns:0 carrier:0
Kollisionen:0 Sendewarteschlangenlänge:0
RX bytes:27262569 (25.9 MiB) TX bytes:27262569 (25.9 MiB)
virbr0 Link encap:Ethernet Hardware Adresse 4a:30:15:4d:b5:0d
inet Adresse:192.168.122.1 Bcast:192.168.122.255
Maske:255.255.255.0
inet6-Adresse: fe80::8804:ecff:febc:fa54/64
Gültigkeitsbereich:Verbindung
UP BROADCAST RUNNING MULTICAST MTU:1500 Metrik:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:299 errors:0 dropped:0 overruns:0 carrier:0
Kollisionen:0 Sendewarteschlangenlänge:0
RX bytes:0 (0.0 B) TX bytes:47842 (46.7 KiB)
vnet0 Link encap:Ethernet Hardware Adresse 4a:30:15:4d:b5:0d
inet6-Adresse: fe80::4830:15ff:fe4d:b50d/64
Gültigkeitsbereich:Verbindung
UP BROADCAST RUNNING MULTICAST MTU:1500 Metrik:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:128 errors:0 dropped:0 overruns:0 carrier:0
Kollisionen:0 Sendewarteschlangenlänge:500
RX bytes:0 (0.0 B) TX bytes:16426 (16.0 KiB)
wlan0 Link encap:Ethernet Hardware Adresse 00:1d:e0:08:89:21
inet Adresse:192.168.178.23 Bcast:192.168.178.255
Maske:255.255.255.0
inet6-Adresse: fe80::21d:e0ff:fe08:8921/64
Gültigkeitsbereich:Verbindung
UP BROADCAST RUNNING MULTICAST MTU:1500 Metrik:1
RX packets:10608 errors:0 dropped:0 overruns:0 frame:0
TX packets:10358 errors:0 dropped:0 overruns:0 carrier:0
Kollisionen:0 Sendewarteschlangenlänge:1000
RX bytes:7515487 (7.1 MiB) TX bytes:1367200 (1.3 MiB)
wmaster0 Link encap:UNSPEC Hardware Adresse 00-1D-
E0-08-89-21-00-00-00-00-00-00-00-00-00-00
UP BROADCAST RUNNING MULTICAST MTU:1500 Metrik:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
Kollisionen:0 Sendewarteschlangenlänge:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Thanks for any help,
Thomas Koch, http://www.koch.ro
15 years, 2 months
[libvirt] [PATCH] tiny tiny typos
by Dan Kenigsberg
---
docs/auth.html.in | 2 +-
docs/downloads.html.in | 2 +-
docs/errors.html | 2 +-
docs/errors.html.in | 2 +-
docs/formatdomain.html.in | 2 +-
docs/java.html.in | 2 +-
docs/news.html.in | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/docs/auth.html.in b/docs/auth.html.in
index 04b1210..5e5497e 100644
--- a/docs/auth.html.in
+++ b/docs/auth.html.in
@@ -151,7 +151,7 @@ Plugin "gssapiv2" [loaded], API version: 4
features: WANT_CLIENT_FIRST|PROXY_AUTHENTICATION|NEED_SERVER_FQDN
</pre>
<p>
-Next is is necessary for the administrator of the Kerberos realm to issue a principle
+Next is necessary for the administrator of the Kerberos realm to issue a principle
for the libvirt server. There needs to be one principle per host running the libvirt
daemon. The principle should be named <code>libvirt/full.hostname(a)KERBEROS.REALM</code>.
This is typically done by running the <code>kadmin.local</code> command on the Kerberos
diff --git a/docs/downloads.html.in b/docs/downloads.html.in
index a34ddd1..493923c 100644
--- a/docs/downloads.html.in
+++ b/docs/downloads.html.in
@@ -60,7 +60,7 @@
<p> The libvirt build process uses GNU autotools, so after obtaining a
checkout it is necessary to generate the configure script and Makefile.in
templates using the <code>autogen.sh</code> command, passing the extra
- arguments as as for configure. As an example, to do a complete build and
+ arguments as for configure. As an example, to do a complete build and
install it into your home directory run:</p>
<pre>
diff --git a/docs/errors.html b/docs/errors.html
index dad8c69..c34bcd8 100644
--- a/docs/errors.html
+++ b/docs/errors.html
@@ -107,7 +107,7 @@ to 0 or NULL if unused</p>
<ul><li>str1, str2, str3: string information, usually str1 is the error
message format</li><li>int1, int2: integer information</li></ul>
<p>So usually, setting up specific error handling with libvirt consist of
-registering an handler with with <a href="html/libvirt-virterror.html#virSetErrorFunc">virSetErrorFunc</a> or
+registering a handler with <a href="html/libvirt-virterror.html#virSetErrorFunc">virSetErrorFunc</a> or
with <a href="html/libvirt-virterror.html#virConnSetErrorFunc">virConnSetErrorFunc</a>,
check the value of the code value, take appropriate action, if needed let
libvirt print the error on stderr by calling <a href="html/libvirt-virterror.html#virDefaultErrorFunc">virDefaultErrorFunc</a>.
diff --git a/docs/errors.html.in b/docs/errors.html.in
index 57cbe6f..cbd6e4b 100644
--- a/docs/errors.html.in
+++ b/docs/errors.html.in
@@ -58,7 +58,7 @@ to 0 or NULL if unused</p>
<li>int1, int2: integer information</li>
</ul>
<p>So usually, setting up specific error handling with libvirt consist of
-registering an handler with with <a href="html/libvirt-virterror.html#virSetErrorFunc">virSetErrorFunc</a> or
+registering a handler with <a href="html/libvirt-virterror.html#virSetErrorFunc">virSetErrorFunc</a> or
with <a href="html/libvirt-virterror.html#virConnSetErrorFunc">virConnSetErrorFunc</a>,
check the value of the code value, take appropriate action, if needed let
libvirt print the error on stderr by calling <a href="html/libvirt-virterror.html#virDefaultErrorFunc">virDefaultErrorFunc</a>.
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 915814d..49b212e 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -500,7 +500,7 @@
</interface>
...</pre>
- <h5><a name="elementsNICSBridge">Bridge to to LAN</a></h5>
+ <h5><a name="elementsNICSBridge">Bridge to LAN</a></h5>
<p>
<strong><em>
diff --git a/docs/java.html.in b/docs/java.html.in
index 5c659bb..d3e3ebc 100644
--- a/docs/java.html.in
+++ b/docs/java.html.in
@@ -5,7 +5,7 @@
<h2>Presentation</h2>
<p>The Java bindings make use of <a href="https://jna.dev.java.net/">JNA</a>
- to expose the C API in a Java friendly way. The bindings are are based on
+ to expose the C API in a Java friendly way. The bindings are based on
work initiated by Toth Istvan.</p>
<h2>Getting it</h2>
diff --git a/docs/news.html.in b/docs/news.html.in
index faba773..31f4aea 100644
--- a/docs/news.html.in
+++ b/docs/news.html.in
@@ -1375,7 +1375,7 @@ and check the <a href="ChangeLog.html">ChangeLog</a> to gauge progress.</p>
</ul>
<h3>0.0.3: Feb 9 2006</h3>
<ul>
- <li>Switch name from from 'libvir' to libvirt</li>
+ <li>Switch name from 'libvir' to libvirt</li>
<li>Starting infrastructure to add code examples</li>
<li>Update of python bindings for completeness</li>
</ul>
--
1.6.2.5
15 years, 2 months
[libvirt] [PATCH: 0/MANY] Re-arrange files in the source tree
by Daniel P. Berrange
This is a followup to
http://www.redhat.com/archives/libvir-list/2009-September/msg00477.html
I am not actually going to spam the list with all the patches, since
it'd generate a HUGE series of mails.
Instead I have published a branch containing all the patches which you
can directly pull into your GIT checkout. I recommend you do the
following set of steps.
- make maintainer-clean
- git checkout master
- git pull
- git remote add -f danb git://gitorious.org/~berrange/libvirt/staging.git
- git checkout -b rearrange danb/rearrange
You will now have a checkout on a branch called 'rearrange' containing
all my patches applied.
If you want to go straight into building it, the normal build process
still applies eg ./autogen && make
I've committed the changes in a large series of steps to make it easier
to see what's going on at each point. To see the list of changes run
the following
git log -b berrange/rearrange master..
The changes basically follow everything we discussed in the previous
thread
I've added a src/README file which describes the split of sub-directories.
I'll reproduce the content here for convenience
libvirt library code README
===========================
The directory provides the bulk of the libvirt codebase. Everything
except for the libvirtd daemon and client tools. The build uses a
large number of libtool convenience libraries - one for each child
directory, and then links them together for the final libvirt.so,
although some bits get linked directly to libvirtd daemon instead.
The files directly in this directory are supporting the public API
entry points & data structures.
There are two core shared modules to be aware of:
* util/ - a collection of shared APIs that can be used by any
code. This directory is always in the include path
for all things built
* conf/ - APIs for parsing / manipulating all the official XML
files used by the public API. This directory is only
in the include path for driver implementation modules
Then there are the hypervisor implementations:
* esx/ - VMWare ESX and GSX support using XMLRPC
* lxc/ - Linux Native Containers
* opennebula/ - Open Nebula using XMLRPC
* openvz/ - OpenVZ containers using cli tools
* phyp/ - IBM Power Hypervisor using CLI tools over SSH
* qemu/ - QEMU / KVM using qemu CLI/monitor
* remote/ - Generic libvirt native RPC client
* test/ - A "mock" driver for testing
* uml/ - User Mode Linux
* vbox/ - Virtual Box using native API
* xen/ - Xen using hypercalls, XenD SEXPR & XenStore
Finally some secondary drivers that are shared for several HVs.
Currently these are used by LXC, OpenVZ, QEMU, UML and Xen drivers.
The ESX, OpenNebula, Power Hypervisor, Remote, Test & VirtualBox
drivers all implement the secondary drivers directly
* interface/ - Host network interface management
* network/ - Virtual NAT networking
* node_device/ - Host device enumeration
* secret/ - Secret management
* security/ - Mandatory access control drivers
* storage/ - Storage management drivers
Since both the hypervisor and secondary drivers can be built as
dlopen()able modules, it is *FORBIDDEN* to have build dependancies
between these directories. Drivers are only allowed to depend on
the public API, and the internal APIs in the util/ and conf/
directories
For the docs directory, I left the docs/libvirt-{api,refs}.xml files
in GIT as Daniel requested. I have removed the *.html, devhelp/*.html
and html/*.html files though. These are all re-generated when doing
make in the docs directory, and the generated HTML is included in
the tar.gz when doing make dist. So end users won't have to rebuild
them, only libvirt developers
The example programs & XML is now all under examples/ with various
sub-directories.
The qemud/ directory is renamed to daemon/
The python/ directory has its file nameing changed and the genrator
tweaked so that its more obvious which are generated files and which
are manually written.
virsh has moved to the tools/ directory, and the docs/pki_check.sh
file has been turned into a real installed tool, tools/virt-pki-validate
along with man page.
A few minor bugs were fixed along the way (eg bogus include files
discovered when files were moved) & unused png/gif images in docs/
There should be no FUNCTIONAL change in any of this work though. It
is a pure re-arrangement of files.
Please try out a build using this 'rearrange' branch from gitorious.
Since this is a huge change I'd like to apply this to the master repo
as soon as people can verify its doing the right thing for them.
FWIW, I checked an RPM build and 'make distcheck' too with no issues.
Regards,
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 2 months
[libvirt] [PATCH] lxc: suspend/resume support
by Ryota Ozaki
Hi,
This patch implements suspend/resume functions for LXC
using cgroups freezer subsystem.
The use of freezer is quite simple and well documented
in Documentation/cgroups/freezer-subsystem.txt. The patch
just uses it as it is. That is like:
# freeze the container
echo FROZEN > /target/container/freezer.state
# unfreeze the container
echo THAWED > /target/container/freezer.state
However, freezer sometimes looks behaving different from the
document. The document is saying "It's important to note that
freezing can be incomplete. In that case we return EBUSY.",
but in the case returning 0, freezing can be incomplete under
load. So the code doesn't believe the return value and always
check the content of freezer.state to identify whether the
freezing is finished.
Please refer to the comments in the code for more details.
And the patch modifies domain_conf.c that assumes
obj->monitor_chr != NULL but that is true only when qemu.
Thanks,
ozaki-r
>From 50d273941eaf764f3ac3458ff10e618c771b77ef Mon Sep 17 00:00:00 2001
From: Ryota Ozaki <ozaki.ryota(a)gmail.com>
Date: Wed, 16 Sep 2009 17:59:54 +0900
Subject: [PATCH] lxc: suspend/resume support
---
src/cgroup.c | 23 ++++++-
src/cgroup.h | 4 +
src/domain_conf.c | 27 ++++----
src/lxc_driver.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 225 insertions(+), 15 deletions(-)
diff --git a/src/cgroup.c b/src/cgroup.c
index 111601d..2e646fd 100644
--- a/src/cgroup.c
+++ b/src/cgroup.c
@@ -32,7 +32,8 @@
#define CGROUP_MAX_VAL 512
VIR_ENUM_IMPL(virCgroupController, VIR_CGROUP_CONTROLLER_LAST,
- "cpu", "cpuacct", "cpuset", "memory", "devices");
+ "cpu", "cpuacct", "cpuset", "memory", "devices",
+ "freezer");
struct virCgroupController {
int type;
@@ -896,3 +897,23 @@ int virCgroupGetCpuacctUsage(virCgroupPtr group,
unsigned long long *usage)
VIR_CGROUP_CONTROLLER_CPUACCT,
"cpuacct.usage", (uint64_t *)usage);
}
+
+int virCgroupSetFreezerState(virCgroupPtr group, const char *state)
+{
+ return virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_CPU,
+ "freezer.state", state);
+}
+
+int virCgroupGetFreezerState(virCgroupPtr group, char **state)
+{
+ int ret;
+ ret = virCgroupGetValueStr(group,
+ VIR_CGROUP_CONTROLLER_CPU,
+ "freezer.state", state);
+ if (ret == 0) {
+ char *p = strchr(*state, '¥n');
+ if (p) *p = '¥0';
+ }
+ return ret;
+}
diff --git a/src/cgroup.h b/src/cgroup.h
index 6d43b14..aba56c6 100644
--- a/src/cgroup.h
+++ b/src/cgroup.h
@@ -21,6 +21,7 @@ enum {
VIR_CGROUP_CONTROLLER_CPUSET,
VIR_CGROUP_CONTROLLER_MEMORY,
VIR_CGROUP_CONTROLLER_DEVICES,
+ VIR_CGROUP_CONTROLLER_FREEZER,
VIR_CGROUP_CONTROLLER_LAST
};
@@ -68,6 +69,9 @@ int virCgroupGetCpuShares(virCgroupPtr group,
unsigned long long *shares);
int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage);
+int virCgroupSetFreezerState(virCgroupPtr group, const char *state);
+int virCgroupGetFreezerState(virCgroupPtr group, char **state);
+
int virCgroupRemove(virCgroupPtr group);
void virCgroupFree(virCgroupPtr *group);
diff --git a/src/domain_conf.c b/src/domain_conf.c
index 5ae0775..5e37d96 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -4433,19 +4433,22 @@ char *virDomainObjFormat(virConnectPtr conn,
virDomainStateTypeToString(obj->state),
obj->pid);
- switch (obj->monitor_chr->type) {
- case VIR_DOMAIN_CHR_TYPE_UNIX:
- monitorpath = obj->monitor_chr->data.nix.path;
- break;
- default:
- case VIR_DOMAIN_CHR_TYPE_PTY:
- monitorpath = obj->monitor_chr->data.file.path;
- break;
- }
+ /* obj->monitor_chr is set only for qemu */
+ if (obj->monitor_chr) {
+ switch (obj->monitor_chr->type) {
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ monitorpath = obj->monitor_chr->data.nix.path;
+ break;
+ default:
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ monitorpath = obj->monitor_chr->data.file.path;
+ break;
+ }
- virBufferEscapeString(&buf, " <monitor path='%s'", monitorpath);
- virBufferVSprintf(&buf, " type='%s'/>¥n",
- virDomainChrTypeToString(obj->monitor_chr->type));
+ virBufferEscapeString(&buf, " <monitor path='%s'", monitorpath);
+ virBufferVSprintf(&buf, " type='%s'/>¥n",
+ virDomainChrTypeToString(obj->monitor_chr->type));
+ }
if (obj->nvcpupids) {
diff --git a/src/lxc_driver.c b/src/lxc_driver.c
index 0ec1e92..2399d98 100644
--- a/src/lxc_driver.c
+++ b/src/lxc_driver.c
@@ -1862,6 +1862,188 @@ static char *lxcGetHostname (virConnectPtr conn)
return result;
}
+static int lxcFreezeContainer(lxc_driver_t *driver, virDomainObjPtr vm)
+{
+ int timeout = 3; /* In seconds */
+ int check_interval = 500; /* In milliseconds */
+ int n_try = (timeout * (1000 / check_interval));
+ int i = 0;
+ int ret = -1;
+ char *state = NULL;
+ virCgroupPtr cgroup = NULL;
+
+ if (!(driver->cgroup &&
+ virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0))
+ return -1;
+
+ while (++i <= n_try) {
+ int r;
+ /*
+ * Writing "FROZEN" to the "freezer.state" freezes the group,
+ * i.e., the container, temporarily transiting "FREEZING" state.
+ * Once the freezing is completed, the state of the group transits
+ * to "FROZEN".
+ * (see linux-2.6/Documentation/cgroups/freezer-subsystem.txt)
+ */
+ r = virCgroupSetFreezerState(cgroup, "FROZEN");
+
+ /*
+ * Returning EBUSY explicitly indicates that the group is
+ * being freezed but incomplete and other errors are true
+ * errors.
+ */
+ if (r < 0 && r != -EBUSY) {
+ VIR_DEBUG("Writing freezer.state failed with errno: %d", r);
+ goto error;
+ }
+
+ /*
+ * Unfortunately, returning 0 (success) is likely to happen
+ * even when the freezing has not been completed. Sometimes
+ * the state of the group remains "FREEZING" like when
+ * returning -EBUSY and even worse may never transit to
+ * "FROZEN" even if writing "FROZEN" again.
+ *
+ * So we don't trust the return value anyway and always
+ * decide that the freezing has been complete only with
+ * the state actually transit to "FROZEN".
+ */
+ usleep(check_interval * 1000);
+
+ r = virCgroupGetFreezerState(cgroup, &state);
+
+ if (r < 0) {
+ VIR_DEBUG("Reading freezer.state failed with errno: %d", r);
+ goto error;
+ }
+ VIR_DEBUG("Read freezer.state: %s", state);
+
+ if (STREQ(state, "FROZEN")) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ VIR_FREE(state);
+ }
+ VIR_DEBUG0("lxcFreezeContainer timeout");
+error:
+ /*
+ * If timeout or an error on reading the state occurs,
+ * activate the group again and return an error.
+ * This is likely to fall the group back again gracefully.
+ */
+ virCgroupSetFreezerState(cgroup, "THAWED");
+ ret = -1;
+
+cleanup:
+ if (cgroup)
+ virCgroupFree(&cgroup);
+ VIR_FREE(state);
+ return ret;
+}
+
+static int lxcDomainSuspend(virDomainPtr dom)
+{
+ lxc_driver_t *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ lxcDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ lxcError(dom->conn, dom, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ if (!virDomainIsActive(vm)) {
+ lxcError(dom->conn, dom, VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ if (vm->state != VIR_DOMAIN_PAUSED) {
+ if (lxcFreezeContainer(driver, vm) < 0) {
+ lxcError(dom->conn, dom, VIR_ERR_OPERATION_FAILED,
+ "%s", _("suspend operation failed"));
+ goto cleanup;
+ }
+ vm->state = VIR_DOMAIN_PAUSED;
+ }
+
+ if (virDomainSaveStatus(dom->conn, driver->stateDir, vm) < 0)
+ goto cleanup;
+ ret = 0;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ lxcDriverUnlock(driver);
+ return ret;
+}
+
+static int lxcUnfreezeContainer(lxc_driver_t *driver, virDomainObjPtr vm)
+{
+ int ret;
+ virCgroupPtr cgroup = NULL;
+
+ if (!(driver->cgroup &&
+ virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0))
+ return -1;
+
+ ret = virCgroupSetFreezerState(cgroup, "THAWED");
+
+ virCgroupFree(&cgroup);
+ return ret;
+}
+
+static int lxcDomainResume(virDomainPtr dom)
+{
+ lxc_driver_t *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ lxcDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ lxcError(dom->conn, dom, VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ if (!virDomainIsActive(vm)) {
+ lxcError(dom->conn, dom, VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ if (vm->state == VIR_DOMAIN_PAUSED) {
+ if (lxcUnfreezeContainer(driver, vm) < 0) {
+ lxcError(dom->conn, dom, VIR_ERR_OPERATION_FAILED,
+ "%s", _("resume operation failed"));
+ goto cleanup;
+ }
+ vm->state = VIR_DOMAIN_RUNNING;
+ }
+
+ if (virDomainSaveStatus(dom->conn, driver->stateDir, vm) < 0)
+ goto cleanup;
+ ret = 0;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ lxcDriverUnlock(driver);
+ return ret;
+}
+
+
/* Function Tables */
static virDriver lxcDriver = {
VIR_DRV_LXC, /* the number virDrvNo */
@@ -1881,8 +2063,8 @@ static virDriver lxcDriver = {
lxcDomainLookupByID, /* domainLookupByID */
lxcDomainLookupByUUID, /* domainLookupByUUID */
lxcDomainLookupByName, /* domainLookupByName */
- NULL, /* domainSuspend */
- NULL, /* domainResume */
+ lxcDomainSuspend, /* domainSuspend */
+ lxcDomainResume, /* domainResume */
lxcDomainShutdown, /* domainShutdown */
NULL, /* domainReboot */
lxcDomainDestroy, /* domainDestroy */
--
1.6.0.6
15 years, 2 months
[libvirt] [PATCH] Power Hypervisor now with libssh2
by Eduardo Otubo
Hello friends,
This is the new version of phyp driver now using libssh2. I also did
some other changes:
* Added some debug information. Sometimes its worth to know which
command is being executed and where. So I added the PHYP_CMD_DEBUG
macro.
* All the connection startup is now "hard coded" in libssh2. For
example, I need to open the socket and start the connection all by
myself. Not a big deal, but in a near future I am planning to send a
patch to libssh2 to encapsulate all these procedures into functions,
hence, less code, probably less bugs :)
* There is a lot of "out of scope" functions in the bottom of the file.
In the next patch I may put all those together in a phyp_config.[ch] in
order to get things clearer.
What's up next:
* The problem of handling the UUID in a centralized way still remains.
I started to handle this by opening a sftp connection to the HMC system
and transfer my UUID database. But there is an odd behavior that makes
the driver connect OR NOT to some HMC systems.
* CPU management: this feature planned to be released in this version
is not ready yet due to the issue above.
* Storage management.
Vacations:
I'll be on vacations from 26th/august to 14th/september. I'll check my
emails in the meanwhile, but no so often. Anyway, any comments on this
patch are always welcome :)
[]'s
--
Eduardo Otubo
Software Engineer
Linux Technology Center
IBM Systems & Technology Group
Mobile: +55 19 8135 0885
otubo(a)linux.vnet.ibm.com
15 years, 2 months