[Libvir] RFC: Supporting serial & parallel ports for QEMU (and improving Xen)
by Daniel P. Berrange
One user's feature request for our QEMU driver is to support serial ports.
Easy you might think... you'd be wrong :-)
On Xen we have very simple approach. When creating a guest simply add
<console/>
And it'll cause a serial port to be setup with an autoallocated pty, so
you get back
<console pty='/dev/pts/5'/>
In retrospect calling it 'console' was dumb, but hey we're stuck with that
now and its only a tiny naming issue so I don't mind really.
We can do the same thing with QEMU quite easily. QEMU, however, supports
many many many more ways to hooking up the serial port to Dom0. Indeed
so does Xen fullyvirt, but we don't expose this ability. Parallel ports
have identical config syntax to serial ports so we might as well deal
with both at once.
So, here's a stripped down version of the QEMU docs:
[quote http://fabrice.bellard.free.fr/qemu/qemu-doc.html#SEC10]
`-serial dev'
Redirect the virtual serial port to host character device dev. The
default device is vc in graphical mode and stdio in non graphical
mode. This option can be used several times to simulate up to 4
serials ports. Use -serial none to disable all serial ports.
Available character devices are:
vc
Virtual console
pty
[Linux only] Pseudo TTY (a new PTY is automatically allocated)
none
No device is allocated.
null
void device
/dev/XXX
[Linux only] Use host tty, e.g. `/dev/ttyS0'. The host serial port
parameters are set according to the emulated ones.
/dev/parportN
[Linux only, parallel port only] Use host parallel port N. Currently
only SPP parallel port features can be used.
file:filename
Write output to filename. No character can be read.
stdio
[Unix only] standard input/output
pipe:filename
name pipe filename
COMn
[Windows only] Use host serial port n
udp:[remote_host]:remote_port[@[src_ip]:src_port]
This implements UDP Net Console.
tcp:[host]:port[,server][,nowait][,nodelay]
The TCP Net Console has two modes of operation.
telnet:host:port[,server][,nowait][,nodelay]
The telnet protocol is used instead of raw tcp sockets.
unix:path[,server][,nowait]
A unix domain socket is used instead of a tcp socket.
[/quote]
I don't see any reason to not support all/most of these options. The things
I don't like here is that /dev/XXX, vs /dev/parportN, vs COMn differences
for connecting guest <-> host passthrough of the devices. I figure it could
be simpler if it was just represented as 'n' and we'd translate that to
be /dev/ttyS[n] or /dev/parport[n] or COM[n] as needed.
The question as ever is how to represent this in XML. For serial ports we'll
stick with '<console>', while parallel ports we might as well use a better
named '<parallel>'. Next up, I think should use a 'type' attribute on this
element to determine the main way ot connecting the device, and then more
type specific attributes or sub-elements as needed. If 'type' was not
specified then use a default of 'pty', since that gives compatability with
existing practice.
As an illustrative example
/*
* Parse the XML definition for a character device
*
* Top level node will be <console> or <parallel>, but all attributes
* and sub-elements are identical.
*
* type=vc|pty|null|host|file|pipe|udp|tcp|telnet, default is pty
*
* <console type='vc'/>
*
* <console type='pty' pty='/dev/pts/3'/>
*
* <console type='null'/>
*
* <console type='host' port='3'/>
*
* <console type='file' path='/some/file'/>
*
* <console type='pipe' path='/some/file'/>
*
* <console type='udp'>
* <sendto port='12356'/>
* </console>
*
* <console type='udp'>
* <sendto addr='127.0.0.1' port='12356'/>
* </console>
*
* <console type='udp'>
* <sendto addr='127.0.0.1' port='12356'/>
* <bind port='12356'/>
* </console>
*
* <console type='udp'>
* <sendto addr='127.0.0.1' port='12356'/>
* <bind addr='127.0.0.1' port='12356'/>
* </console>
*
* <console type='tcp'>
* <listen port='12356'/>
* </console>
*
* <console type='tcp'>
* <listen addr='127.0.0.1' port='12356'>
* <nowait/>
* <nodelay/>
* </listen>
* </console>
*
* <console type='tcp'>
* <connect addr='127.0.0.1' port='12356'>
* <nodelay/>
* </connect>
* </console>
*
* <console type='telnet'>
* <listen addr='127.0.0.1' port='12356'/>
* </console>
*
* <console type='telnet'>
* <connect addr='127.0.0.1' port='12356'/>
* </console>
*
*/
BTW, the udp, tcp, telnet options are only available on QEMU >= 0.9.0. We
already have ability to detect / validate that for both Xen & QEMU drivers.
NB, whereever there are IP addresses, hostnames can be used too, hence I
call the attriute 'addr' instead of 'ip'
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
16 years, 8 months
[Libvir] [PATCH] Xen: Support cpu_weight and cpu_cap for Xen.
by Tatsuro Enokura
Hi,
I set the information of cpu_weight/cpu_cap to configuration file or
sxp format, and execute "virsh start".
But the information of weight/cap is lost.
libvirt doesn't support cpu_weight and cpu_cap for XML format.
see also Bz#337591
https://bugzilla.redhat.com/show_bug.cgi?id=337591
I make a patch to add weight/cap attributes as vcpus element
(eg. <vcpus weight='512' cap='280'>4</vcpus>)
c.f. the thread at:
https://www.redhat.com/archives/libvir-list/2007-October/msg00044.html
Signed-off-by: Tatsuro Enokura <fj7716hz(a)aa.jp.fujitsu.com>
Thanks,
Tatsuro Enokura
Index: libvirt/src/xend_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xend_internal.c,v
retrieving revision 1.151
diff -u -p -r1.151 xend_internal.c
--- libvirt/src/xend_internal.c 22 Oct 2007 20:28:55 -0000 1.151
+++ libvirt/src/xend_internal.c 24 Oct 2007 06:02:27 -0000
@@ -1438,8 +1438,19 @@ xend_parse_sexp_desc(virConnectPtr conn,
if ((cur_mem >= MIN_XEN_GUEST_SIZE) && (cur_mem != max_mem))
virBufferVSprintf(&buf, " <currentMemory>%d</currentMemory>\n",
cur_mem);
- virBufferVSprintf(&buf, " <vcpu>%d</vcpu>\n",
+ virBufferVSprintf(&buf, " <vcpu");
+ if (sexpr_node(root, "domain/cpu_weight") != NULL) {
+ virBufferVSprintf(&buf, " weight='%d'",
+ sexpr_int(root, "domain/cpu_weight"));
+ }
+ if (sexpr_node(root, "domain/cpu_cap") != NULL) {
+ virBufferVSprintf(&buf, " cap='%d'",
+ sexpr_int(root, "domain/cpu_cap"));
+ }
+ virBufferVSprintf(&buf, ">%d</vcpu>\n",
sexpr_int(root, "domain/vcpus"));
+
+
tmp = sexpr_node(root, "domain/on_poweroff");
if (tmp != NULL)
virBufferVSprintf(&buf, " <on_poweroff>%s</on_poweroff>\n", tmp);
Index: libvirt/src/xm_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xm_internal.c,v
retrieving revision 1.41
diff -u -p -r1.41 xm_internal.c
--- libvirt/src/xm_internal.c 10 Oct 2007 17:55:38 -0000 1.41
+++ libvirt/src/xm_internal.c 24 Oct 2007 06:02:28 -0000
@@ -661,9 +661,14 @@ char *xenXMDomainFormatXML(virConnectPtr
virBufferVSprintf(buf, " <memory>%ld</memory>\n", val * 1024);
+ virBufferVSprintf(buf, " <vcpu");
+ if (xenXMConfigGetInt(conf, "cpu_weight", &val) == 0)
+ virBufferVSprintf(buf, " weight='%ld'", val);
+ if (xenXMConfigGetInt(conf, "cpu_cap", &val) == 0)
+ virBufferVSprintf(buf, " cap='%ld'", val);
if (xenXMConfigGetInt(conf, "vcpus", &val) < 0)
val = 1;
- virBufferVSprintf(buf, " <vcpu>%ld</vcpu>\n", val);
+ virBufferVSprintf(buf, ">%ld</vcpu>\n", val);
if (xenXMConfigGetString(conf, "on_poweroff", &str) < 0)
@@ -1820,6 +1825,12 @@ virConfPtr xenXMParseXMLToConfig(virConn
if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "vcpus", "string(/domain/vcpu)", 0, 1,
"cannot set vcpus config parameter") < 0)
goto error;
+ if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "cpu_weight", "string(/domain/vcpu/@weight)", 0, 1,
+ "cannot set cpu_weight config paramerter") < 0)
+ goto error;
+ if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "cpu_cap", "string(/domain/vcpu/@cap)", 0, 1,
+ "cannot set cpu_cap config paramerter") < 0)
+ goto error;
obj = xmlXPathEval(BAD_CAST "string(/domain/os/type)", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
Index: libvirt/src/xml.c
===================================================================
RCS file: /data/cvs/libvirt/src/xml.c,v
retrieving revision 1.94
diff -u -p -r1.94 xml.c
--- libvirt/src/xml.c 23 Oct 2007 15:31:33 -0000 1.94
+++ libvirt/src/xml.c 24 Oct 2007 06:02:28 -0000
@@ -1529,6 +1529,12 @@ virDomainParseXMLDesc(virConnectPtr conn
vcpus = (unsigned int) f;
}
virBufferVSprintf(&buf, "(vcpus %u)", vcpus);
+ if (virXPathNumber("number(/domain/vcpu[1]/@weight)", ctxt, &f) == 0) {
+ virBufferVSprintf(&buf, "(cpu_weight %ld)", (long) f);
+ }
+ if (virXPathNumber("number(/domain/vcpu[1]/@cap)", ctxt, &f) == 0) {
+ virBufferVSprintf(&buf, "(cpu_cap %ld)", (long) f);
+ }
str = virXPathString("string(/domain/vcpu/@cpuset)", ctxt);
if (str != NULL) {
16 years, 10 months
[Libvir] [PATCH] Enhanced stats for fullvirt domains
by Richard W.M. Jones
This patch does a couple of primary things:
Firstly it allows you to use "hda", etc. as a path for getting block
device stats from fullvirt domains.
Secondly it separates out the stats code into a new file called
'stats_linux.c'. The reasoning behind the name is that this code can be
shared between Xen & QEMU, and that the code is Linux-specific (it never
worked on Solaris, but now this is explicit). I anticipate a
'stats_solaris.c' file once I can get Solaris + Xen going on a test machine.
Also we try to detect the case where the block dev stats of a fullvirt
domain are stuck at 0 -- caused by there being no frontend driver
connected. We detect the condition by a query to xenstore.
XENVBD_MAJOR is no longer hard-coded if we can get it instead from Linux
header files.
This patch adds bytes written/read to block devices for Xen PV domains
if available.
This also corrects a bug where stats from xvdb, xvdc, .. could not be
read out because the device number was being miscalculated.
Rich.
--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903
17 years
[Libvir] [PATCH] Fix xen://hostname URIs with no trailing slash
by Richard W.M. Jones
It turns out that xmlParseURI gives an error if asked to parse the
string "xen://".
This string arises because after a URI such as "xen://hostname" has been
stripped of its server field, it becomes "xen://" on the remote end of
the connection, and the failure of xmlParseURI causes the whole
connection to fail.
I'm not sure of the best way to fix it. The attached patch is a
semi-hack which at least allows xen://hostname to work. It's not a
problem for qemu because these URIs should always contain a path. Nor
for test for the same reason. Not sure about OpenVZ.
Rich.
--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903
17 years
[Libvir] [PATCH] parse URI once in src/libvirt.c, pass parsed URI to all drivers
by Richard W.M. Jones
The basic change here is that the virDrvOpen call (the internal "open"
call for drivers) now takes the parsed xmlURIPtr instead of the raw name
string.
typedef virDrvOpenStatus
(*virDrvOpen) (virConnectPtr conn,
- const char *name,
+ xmlURIPtr uri,
int flags);
So we avoid the redundant URI parsing which was going on inside all the
drivers, and also the ad-hoc "does-it-look-like-a-URI" string comparisons.
That's straightforward enough except that all of the drivers were saving
the name string in their private data so that they could implement the
virConnectGetURI call. I've changed this so that the name is copied and
saved in the main virConnect structure, and virConnectGetURI will return
that unless the driver wants to override it.
You need another patch (coming shortly) to allow URIs like
xen://localhost (without the trailing slash) to work, which was IIRC the
original point of this discussion.
Rich.
--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903
17 years
[Libvir] [RFC] Linux-VServer support
by Daniel Hokka Zakrisson
Hi,
This is an initial stab at adding Linux-VServer support to libvirt.
There are still a couple of things missing, like scheduler support in
the XML parsing, and proper network support.
I've got a few questions though. virsh's schedinfo hardcodes the
available options, should I be adding new ones there? Would better
introspection from getSchedulerType make this a non-issue? How do the
network domains interact and associate with the regular domains?
--
Daniel Hokka Zakrisson
17 years
[Libvir] [PATCH] finish NUMA code reorg, plug cpuset at creat time support
by Daniel Veillard
The following patch finishes the cleanup for NUMA parsing code:
- the cpuset parsing is moved to xml.c
- some comments and cleanups of the include
then add the output of a (cpus '...') line based on the /domain/vcpu/@cpuset
attributes, this is parsed and reserialized as ranges to avoid any possibility
of misinterpretation of say ^ or any special syntax we may want to add in
the future.
A few things to note:
- dependant on the tiny patch I sent earlier today
- if we notice that the set covers all CPU maybe we should
avoid outputing (cpus '...'), trivial to add
- mostly untested yet
Daniel
--
Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard | virtualization library http://libvirt.org/
veillard(a)redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
17 years
[Libvir] PATCH: 0/7 Implementation of storage APIs
by Daniel P. Berrange
Since the previous discussions didn't really end up anywhere conclusive I decided
it would be better to have a crack at getting some working code to illustrate my
ideas. Thus, the following series of 7 patches provide an implementation of storage
APIs which follow the scheme outlined in the previous mail on storage concepts
http://www.redhat.com/archives/libvir-list/2007-October/msg00195.html
I have only addressed storage pools & volumes. I am not tackling the host device
enumeration APIs at this time, since it is not a blocker for the rest of the work.
The mails which follow, in particular the last one, will explain the patches in
more details. The focus is primarily on providing the public API, and wiring up
the remote driver, daemon and protocol, and the generic storage driver. The generic
storage driver then calls out to specific backends for different types of storage.
implementation provides a fully functional backend for managing local directories
containing raw files (aka equivalent of /var/lib/xen/images). There are empty stubs
for LVM, iSCSI, Disks/Partitions, etc to be filled in as we decide...
Some open questions
- Is it worth bothering with a UUID for individual storage volumes. It is possible
to construct a globally unique identifier for most volumes, by combing various
bits of metadata we have such as device unique ID, inode, iSCSI target & LUN, etc
There isn't really any UUID that fits into the classic libvirt 16 byte UUID.
I've implemented (randomly generated) UUIDs for the virStorageVolPtr object, but
I'm inclined to remove them, since its not much use if they change each time the
libvirtd daemon is restarted.
The 'name' field provides a unique identifier scoped to the storage pool. I think
we could add a 'char *key' field, as an arbitrary opaque string, forming a
globally unique identifier for the volume. This would serve same purpose as UUID,
but without the 16 bytes constraint which we can't usefully provide.
- For the local directory backend, I've got the ability to choose between file
formats on a per-volume basis. eg, /var/lib/xen/images can contain a mix of
raw, qcow, vmdk, etc files. This is nice & flexible for the user, but a more
complex thing to implement, since it means we have to probe each volume and
try & figure out its format each time we list volumes. If we constrained the
choice between formats to be at the pool level instead of the volume level
we could avoid probing & thus simplify the code. This is what XenAPI does.
- If creating non-sparse files, it can take a very long time to do the I/O to
fill in the image. In virt-intsall/virt-manager we have nice incremental
progress display. The API I've got currently though is blocking. This blocks
the calling application. It also blocks the entire libvirtd daemon since we
are single process. There are a couple of ways we can address this:
- Allow the libvirtd daemon to serve each client connection in a separate
thread. We'd need to adding some mutex locking to the QEMU driver and
the storage driver to handle this. It would have been nice to avoid
threads, but I don't think we can much longer.
- For long running operations, spawn off a worker thread (or process) to
perform the operation. Don't send a reply to the RPC message, instead
just put the client on a 'wait queue', and get on with serving other
clients. When the worker thread completes, send the RPC reply to the
original client.
- Having the virStorageVolCreate() method return immediately, giving back
the client app some kind of 'job id'. The client app can poll on another
API virStorageVolJob() method to determine how far through the task has
got. The implementation in the driver would have to spawn a worker thread
to do the actual long operation.
Possibly we can allow creation to be async or blocking by making use of
the 'flags' field to virStorageVolCreate() method, eg VIR_STORAGE_ASYNC.
If we make async behaviour optional, we still need some work in the
daemon to avoid blocking all clients.
This problem will also impact us when we add cloning of existing volumes.
It already sort of hits us when saving & restoring VMs if they have large
amounts of memory. So perhaps we need togo for the general solution of
making the daemon threaded per client connection. The ASYNC flag may still
be useful anyway to get the incremental progress feedback in the UI.
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years
[Libvir] PATCH: Support NIC model selection for QEMU/KVM
by Jim Paris
Hi,
Sometime between kvm-36 and kvm-46 I ran into problems with the
default QEMU network card (ne2k-pci). Switching it fixed the
problems, but libvirt doesn't support changing the NIC model.
These patches add support for:
<interface>
<nic model="rtl8139"/>
</interface>
which becomes
qemu -net nic,model=rtl8139,mac=...
By default, no model is appended to the qemu command line, as before.
Documentation update & some fixes are included too.
-jim
17 years