mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
maint: this branch is now dead
Upstream is no longer willing to backport patches to a branch this old. If you disagree with the policy, please volunteer to become the branch maintainer on libvir-list@redhat.com Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
bffb94488b
commit
cd0d348ed0
@ -1,17 +0,0 @@
|
||||
(
|
||||
(c-mode . (
|
||||
(c-file-style . "K&R")
|
||||
(indent-tabs-mode . nil)
|
||||
(c-indent-level . 4)
|
||||
(c-basic-offset . 4)
|
||||
))
|
||||
(html-mode . (
|
||||
(indent-tabs-mode . nil)
|
||||
))
|
||||
(sh-mode . (
|
||||
(indent-tabs-mode . nil)
|
||||
))
|
||||
(nxml-mode . (
|
||||
(indent-tabs-mode . nil)
|
||||
))
|
||||
)
|
1
.gnulib
1
.gnulib
@ -1 +0,0 @@
|
||||
Subproject commit dbd914496c99c52220e5f5ba4121d6cb55fb3beb
|
37
.mailmap
37
.mailmap
@ -1,37 +0,0 @@
|
||||
# 'git shortlog --help' and look for mailmap for the format of each line
|
||||
|
||||
# Email consolidation:
|
||||
# <Preferred address in AUTHORS> <other alias used by same author>
|
||||
|
||||
<amy.griffis@hp.com> <aron.griffis@hp.com>
|
||||
<bozzolan@gmail.com> <redshift@gmx.com>
|
||||
<charles_duffy@messageone.com> <charles@dyfis.net>
|
||||
<dfj@redhat.com> <dfj@dfj.bne.redhat.com>
|
||||
<eblake@redhat.com> <ebb9@byu.net>
|
||||
<gdolley@arpnetworks.com> <gdolley@ucla.edu>
|
||||
<gerhard.stenzel@de.ibm.com> <gstenzel@linux.vnet.ibm.com>
|
||||
<jamie@canonical.com> <jamie@ubuntu.com>
|
||||
<laine@redhat.com> <laine@laine.org>
|
||||
<meyering@redhat.com> <jim@meyering.net>
|
||||
<socketpair@gmail.com> <socketpair gmail com>
|
||||
<soren@linux2go.dk> <soren@ubuntu.com>
|
||||
<jfehlig@suse.com> <jfehlig@novell.com>
|
||||
<jfehlig@suse.com> <jfehlig@linux-ypgk.site>
|
||||
<jclift@redhat.com> <justin@salasaga.org>
|
||||
<berrange@redhat.com> <dan@berrange.com>
|
||||
<soren@linux2go.dk> <soren@canonical.com>
|
||||
<cfergeau@redhat.com> <teuf@gnome.org>
|
||||
<wency@cn.fujitsu.com> <wency cn fujitsu com>
|
||||
<cardoe@cardoe.com> <cardoe@gentoo.org>
|
||||
<fsimonce@redhat.com> <federico.simoncelli@gmail.com>
|
||||
<marcandre.lureau@redhat.com> <marcandre.lureau@gmail.com>
|
||||
<supriyak@linux.vnet.ibm.com> <supriyak@in.ibm.com>
|
||||
<neil@aldur.co.uk> <neil@brightbox.co.uk>
|
||||
<stefanb@us.ibm.com> <stefanb@linux.vnet.ibm.com>
|
||||
<josh.durgin@inktank.com> <joshd@hq.newdream.net>
|
||||
<josh.durgin@inktank.com> <josh.durgin@dreamhost.com>
|
||||
|
||||
# Name consolidation:
|
||||
# Preferred author spelling <preferred email>
|
||||
Alex Jia <ajia@redhat.com>
|
||||
Wen Ruo Lv <lvroyce@linux.vnet.ibm.com>
|
255
AUTHORS
255
AUTHORS
@ -1,255 +0,0 @@
|
||||
libvirt Authors
|
||||
===============
|
||||
|
||||
The libvirt project was initiated by:
|
||||
|
||||
Daniel Veillard <veillard@redhat.com> or <daniel@veillard.com>
|
||||
|
||||
The primary maintainers and people with commit access rights:
|
||||
|
||||
Daniel Veillard <veillard@redhat.com>
|
||||
Daniel Berrange <berrange@redhat.com>
|
||||
Richard W.M. Jones <rjones@redhat.com>
|
||||
Mark McLoughlin <markmc@redhat.com>
|
||||
Anthony Liguori <aliguori@us.ibm.com>
|
||||
Jim Meyering <meyering@redhat.com>
|
||||
Jim Fehlig <jfehlig@suse.com>
|
||||
Chris Lalancette <clalance@redhat.com>
|
||||
Cole Robinson <crobinso@redhat.com>
|
||||
Guido Günther <agx@sigxcpu.org>
|
||||
John Levon <john.levon@sun.com>
|
||||
Matthias Bolte <matthias.bolte@googlemail.com>
|
||||
Jiří Denemark <jdenemar@redhat.com>
|
||||
Dave Allan <dallan@redhat.com>
|
||||
Laine Stump <laine@redhat.com>
|
||||
Stefan Berger <stefanb@us.ibm.com>
|
||||
Eric Blake <eblake@redhat.com>
|
||||
Justin Clift <jclift@redhat.com>
|
||||
Osier Yang <jyang@redhat.com>
|
||||
Wen Congyang <wency@cn.fujitsu.com>
|
||||
Michal Prívozník <mprivozn@redhat.com>
|
||||
Peter Krempa <pkrempa@redhat.com>
|
||||
Christophe Fergeau <cfergeau@redhat.com>
|
||||
Alex Jia <ajia@redhat.com>
|
||||
|
||||
Previous maintainers:
|
||||
Karel Zak <kzak@redhat.com>
|
||||
Atsushi SAKAI <sakaia@jp.fujitsu.com>
|
||||
Dave Leskovec <dlesko@linux.vnet.ibm.com>
|
||||
Dan Smith <danms@us.ibm.com>
|
||||
|
||||
Patches have also been contributed by:
|
||||
|
||||
David Lutterkort <dlutter@redhat.com>
|
||||
Andrew Puch <apuch@redhat.com>
|
||||
Philippe Berthault <philippe.berthault@Bull.net>
|
||||
Hugh Brock <hbrock@redhat.com>
|
||||
Michel Ponceau <michel.ponceau@bull.net>
|
||||
Jeremy Katz <katzj@redhat.com>
|
||||
Pete Vetere <pvetere@redhat.com>
|
||||
Kazuki Mizushima <mizushima.kazuk@jp.fujitsu.com>
|
||||
Saori Fukuta <fukuta.saori@jp.fujitsu.com>
|
||||
Tatsuro Enokura <fj7716hz@aa.jp.fujitsu.com>
|
||||
Takahashi Tomohiro <takatom@jp.fujitsu.com>
|
||||
Nobuhiro Itou <fj0873gn@aa.jp.fujitsu.com>
|
||||
Masayuki Sunou <fj1826dm@aa.jp.fujitsu.com>
|
||||
Mark Johnson <johnson.nh@gmail.com>
|
||||
Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
|
||||
Shuveb Hussain <shuveb@binarykarma.com>
|
||||
Jim Paris <jim@jtan.com>
|
||||
Daniel Hokka Zakrisson <daniel@hozac.com>
|
||||
Mads Chr. Olesen <shiyee@shiyee.dk>
|
||||
Anton Protopopov <aspsk2@gmail.com>
|
||||
Stefan de Konink <dekonink@kinkrsoftware.nl>
|
||||
Kaitlin Rupert <kaitlin@linux.vnet.ibm.com>
|
||||
Evgeniy Sokolov <evg@openvz.org>
|
||||
David Lively <dlively@virtualiron.com>
|
||||
Charles Duffy <Charles_Duffy@messageone.com>
|
||||
Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
James Morris <jmorris@namei.org>
|
||||
Chris Wright <chrisw@redhat.com>
|
||||
Ben Guthro <ben.guthro@gmail.com>
|
||||
Shigeki Sakamoto <fj0588di@aa.jp.fujitsu.com>
|
||||
Gerd von Egidy <lists@egidy.de>
|
||||
Itamar Heim <iheim@redhat.com>
|
||||
Markus Armbruster <armbru@redhat.com>
|
||||
Ryota Ozaki <ozaki.ryota@gmail.com>
|
||||
Daniel J Walsh <dwalsh@redhat.com>
|
||||
Maximilian Wilhelm <max@rfc2324.org>
|
||||
Pritesh Kothari <Pritesh.Kothari@Sun.COM>
|
||||
Amit Shah <amit.shah@redhat.com>
|
||||
Florian Vichot <florian.vichot@diateam.net>
|
||||
Serge E. Hallyn <serue@us.ibm.com>
|
||||
Soren Hansen <soren@linux2go.dk>
|
||||
Abel Míguez Rodríguez<amiguezr@pdi.ucm.es>
|
||||
Doug Goldstein <cardoe@cardoe.com>
|
||||
Javier Fontan <jfontan@gmail.com>
|
||||
Federico Simoncelli <fsimonce@redhat.com>
|
||||
Amy Griffis <amy.griffis@hp.com>
|
||||
Henrik Persson E <henrik.e.persson@ericsson.com>
|
||||
Satoru SATOH <satoru.satoh@gmail.com>
|
||||
Paolo Bonzini <pbonzini@redhat.com>
|
||||
Miloslav Trmač <mitr@redhat.com>
|
||||
Jamie Strandboge <jamie@canonical.com>
|
||||
Gerhard Stenzel <gerhard.stenzel@de.ibm.com>
|
||||
Matthew Booth <mbooth@redhat.com>
|
||||
Diego Elio Pettenò <flameeyes@gmail.com>
|
||||
Adam Litke <agl@us.ibm.com>
|
||||
Steve Yarmie <steve.yarmie@gmail.com>
|
||||
Dan Kenigsberg <danken@redhat.com>
|
||||
Yuji NISHIDA <nishidy@nict.go.jp>
|
||||
Dustin Xiong <x_k_123@hotmail.com>
|
||||
Rolf Eike Beer <eike@sf-mail.de>
|
||||
Wolfgang Mauerer <wolfgang.mauerer@siemens.com>
|
||||
Philipp Hahn <hahn@univention.de>
|
||||
Ed Swierk <eswierk@aristanetworks.com>
|
||||
Paolo Smiraglia <paolo.smiraglia@gmail.com>
|
||||
Sharadha Prabhakar <sharadha.prabhakar@citrix.com>
|
||||
Chris Wong <wongc-redhat@hoku.net>
|
||||
Daniel Berteaud <daniel@firewall-services.com>
|
||||
Dustin Kirkland <kirkland@canonical.com>
|
||||
Luiz Capitulino <lcapitulino@redhat.com>
|
||||
Ryan Harper <ryanh@us.ibm.com>
|
||||
Spencer Shimko <sshimko@tresys.com>
|
||||
Marco Bozzolan <bozzolan@gmail.com>
|
||||
Alex Williamson <alex.williamson@redhat.com>
|
||||
Ersek Laszlo <lacos@caesar.elte.hu>
|
||||
Kenneth Nagin <NAGIN@il.ibm.com>
|
||||
Klaus Ethgen <Klaus@Ethgen.de>
|
||||
Bryan Kearney <bkearney@redhat.com>
|
||||
Darry L. Pierce <dpierce@redhat.com>
|
||||
David Jorm <dfj@redhat.com>
|
||||
Eduardo Otubo <otubo@linux.vnet.ibm.com>
|
||||
Garry Dolley <gdolley@arpnetworks.com>
|
||||
Harshavardhana <harsha@gluster.com>
|
||||
Jonas Eriksson <jonas.j.eriksson@ericsson.com>
|
||||
Jun Koi <junkoi2004@gmail.com>
|
||||
Olivier Fourdan <ofourdan@redhat.com>
|
||||
Ron Yorston <rmy@tigress.co.uk>
|
||||
Shahar Klein <shaharklein@yahoo.com>
|
||||
Taizo ITO <taizo.ito@hde.co.jp>
|
||||
Thomas Treutner <thomas@scripty.at>
|
||||
Jean-Baptiste Rouault <jean-baptiste.rouault@diateam.net>
|
||||
Марк Коренберг <socketpair@gmail.com>
|
||||
Alan Pevec <apevec@redhat.com>
|
||||
Aurelien Rougemont <beorn@binaries.fr>
|
||||
Patrick Dignan <pat_dignan@dell.com>
|
||||
Serge Hallyn <serge.hallyn@canonical.com>
|
||||
Nikunj A. Dadhania <nikunj@linux.vnet.ibm.com>
|
||||
Lai Jiangshan <laijs@cn.fujitsu.com>
|
||||
Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
|
||||
John Morrissey <jwm@horde.net>
|
||||
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
|
||||
Hu Tao <hutao@cn.fujitsu.com>
|
||||
Laurent Léonard <laurent@open-minds.org>
|
||||
MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
|
||||
Josh Durgin <josh.durgin@inktank.com>
|
||||
Roopa Prabhu <roprabhu@cisco.com>
|
||||
Paweł Krześniak <pawel.krzesniak@gmail.com>
|
||||
Kay Schubert <kayegypt@web.de>
|
||||
Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Juerg Haefliger <juerg.haefliger@hp.com>
|
||||
Matthias Dahl <mdvirt@designassembly.de>
|
||||
Niels de Vos <ndevos@redhat.com>
|
||||
Davidlohr Bueso <dave@gnu.org>
|
||||
Alon Levy <alevy@redhat.com>
|
||||
Hero Phương <herophuong93@gmail.com>
|
||||
Zdenek Styblik <stybla@turnovfree.net>
|
||||
Gui Jianfeng <guijianfeng@cn.fujitsu.com>
|
||||
Michal Novotny <minovotn@redhat.com>
|
||||
Markus Groß <gross@univention.de>
|
||||
Phil Petty <phpetty@cisco.com>
|
||||
Taku Izumi <izumi.taku@jp.fujitsu.com>
|
||||
Minoru Usui <usui@mxm.nes.nec.co.jp>
|
||||
Tiziano Mueller <dev-zero@gentoo.org>
|
||||
Thibault VINCENT <thibault.vincent@smartjog.com>
|
||||
Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
|
||||
Jesse Cook <code.crashenx@gmail.com>
|
||||
Alexander Todorov <atodorov@otb.bg>
|
||||
Richard Laager <rlaager@wiktel.com>
|
||||
Mark Wu <dwu@redhat.com>
|
||||
Yufang Zhang <yuzhang@redhat.com>
|
||||
Supriya Kannery <supriyak@linux.vnet.ibm.com>
|
||||
Dirk Herrendoerfer <d.herrendoerfer@herrendoerfer.name>
|
||||
Taisuke Yamada <tai@rakugaki.org>
|
||||
Heath Petersen <HeathPetersen@Kandre.com>
|
||||
Neil Wilson <neil@aldur.co.uk>
|
||||
Ohad Levy <ohadlevy@gmail.com>
|
||||
Michael Chapman <mike@very.puzzling.org>
|
||||
Daniel Gollub <gollub@b1-systems.de>
|
||||
David S. Wang <dwang2@cisco.com>
|
||||
Ruben Kerkhof <ruben@rubenkerkhof.com>
|
||||
Scott Moser <smoser@ubuntu.com>
|
||||
Guannan Ren <gren@redhat.com>
|
||||
John Williams <john.williams@petalogix.com>
|
||||
Michael Santos <michael.santos@gmail.com>
|
||||
Oskari Saarenmaa <os@ohmu.fi>
|
||||
Nan Zhang <nzhang@redhat.com>
|
||||
Wieland Hoffmann <themineo@googlemail.com>
|
||||
Douglas Schilling Landgraf <dougsland@redhat.com>
|
||||
Tom Vijlbrief <tom.vijlbrief@xs4all.nl>
|
||||
Shradha Shah <sshah@solarflare.com>
|
||||
Steve Hodgson <shodgson@solarflare.com>
|
||||
Xu He Jie <xuhj@linux.vnet.ibm.com>
|
||||
Lei Li <lilei@linux.vnet.ibm.com>
|
||||
Matthias Witte <witte@netzquadrat.de>
|
||||
Tang Chen <tangchen@cn.fujitsu.com>
|
||||
Dan Horák <dan@danny.cz>
|
||||
Sage Weil <sage@newdream.net>
|
||||
David L Stevens <dlstevens@us.ibm.com>
|
||||
Tyler Coumbes <coumbes@gmail.com>
|
||||
Wen Ruo Lv <lvroyce@linux.vnet.ibm.com>
|
||||
Patrice LACHANCE <patlachance@gmail.com>
|
||||
Eli Qiao <taget@linux.vnet.ibm.com>
|
||||
Michael Wood <esiotrot@gmail.com>
|
||||
Bharata B Rao <bharata@linux.vnet.ibm.com>
|
||||
Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
|
||||
Chang Liu <lingjiao.lc@taobao.com>
|
||||
Lorin Hochstein <lorin@isi.edu>
|
||||
Christian Franke <nobody@nowhere.ws>
|
||||
Prerna Saxena <prerna@linux.vnet.ibm.com>
|
||||
Michael Ellerman <michael@ellerman.id.au>
|
||||
Rommer <rommer@active.by>
|
||||
Yuri Chornoivan <yurchor@ukr.net>
|
||||
Deepak C Shetty <deepakcs@linux.vnet.ibm.com>
|
||||
Martin Kletzander <mkletzan@redhat.com>
|
||||
Laszlo Ersek <lersek@redhat.com>
|
||||
Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
|
||||
Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
|
||||
Hendrik Schwartke <hendrik@os-t.de>
|
||||
Ansis Atteka <aatteka@nicira.com>
|
||||
Dan Wendlandt <dan@nicira.com>
|
||||
Kyle Mestery <kmestery@cisco.com>
|
||||
Lincoln Myers <lincoln_myers@yahoo.com>
|
||||
Peter Robinson <pbrobinson@gmail.com>
|
||||
Benjamin Cama <benoar@dolka.fr>
|
||||
Duncan Rance <libvirt@dunquino.com>
|
||||
Peng Zhou <ailvpeng25@gmail.com>
|
||||
Li Zhang <zhlcindy@linux.vnet.ibm.com>
|
||||
Stef Walter <stefw@gnome.org>
|
||||
Christian Benvenuti <benve@cisco.com>
|
||||
Ilja Livenson <ilja.livenson@gmail.com>
|
||||
Stefan Bader <stefan.bader@canonical.com>
|
||||
MATSUDA Daiki <matsudadik@intellilink.co.jp>
|
||||
Jan Kiszka <jan.kiszka@siemens.com>
|
||||
Ryan Woodsmall <rwoodsmall@gmail.com>
|
||||
Radu Caragea <dmns_serp@yahoo.com>
|
||||
Beat Jörg <Beat.Joerg@ssatr.ch>
|
||||
Gao feng <gaofeng@cn.fujitsu.com>
|
||||
Dipankar Sarma <dipankar@in.ibm.com>
|
||||
Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
|
||||
Thang Pham <thang.pham@us.ibm.com>
|
||||
Eiichi Tsukata <eiichi.tsukata.xh@hitachi.com>
|
||||
Wido den Hollander <wido@widodh.nl>
|
||||
Gene Czarcinski <gene@czarc.net>
|
||||
Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Vladislav Bogdanov <bubble@hoster-ok.com>
|
||||
|
||||
[....send patches to get your name here....]
|
||||
|
||||
The libvirt Logo was designed by Diana Fong
|
||||
|
||||
-- End
|
||||
;; Local Variables:
|
||||
;; coding: utf-8
|
||||
;; End:
|
508
COPYING.LIB
508
COPYING.LIB
@ -1,508 +0,0 @@
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations
|
||||
below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
^L
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it
|
||||
becomes a de-facto standard. To achieve this, non-free programs must
|
||||
be allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
^L
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control
|
||||
compilation and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
^L
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
^L
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at least
|
||||
three years, to give the same user the materials specified in
|
||||
Subsection 6a, above, for a charge no more than the cost of
|
||||
performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
^L
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
^L
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply, and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License
|
||||
may add an explicit geographical distribution limitation excluding those
|
||||
countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
^L
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
^L
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms
|
||||
of the ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library.
|
||||
It is safest to attach them to the start of each source file to most
|
||||
effectively convey the exclusion of warranty; and each file should
|
||||
have at least the "copyright" line and a pointer to where the full
|
||||
notice is found.
|
||||
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or
|
||||
your school, if any, to sign a "copyright disclaimer" for the library,
|
||||
if necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James
|
||||
Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
16699
ChangeLog-old
16699
ChangeLog-old
File diff suppressed because it is too large
Load Diff
714
HACKING
714
HACKING
@ -1,714 +0,0 @@
|
||||
-*- buffer-read-only: t -*- vi: set ro:
|
||||
DO NOT EDIT THIS FILE! IT IS GENERATED AUTOMATICALLY!
|
||||
|
||||
|
||||
|
||||
Contributor guidelines
|
||||
======================
|
||||
|
||||
|
||||
|
||||
General tips for contributing patches
|
||||
=====================================
|
||||
(1) Discuss any large changes on the mailing list first. Post patches early and
|
||||
listen to feedback.
|
||||
|
||||
(2) Post patches in unified diff format. A command similar to this should work:
|
||||
|
||||
diff -urp libvirt.orig/ libvirt.modified/ > libvirt-myfeature.patch
|
||||
|
||||
or:
|
||||
|
||||
git diff > libvirt-myfeature.patch
|
||||
|
||||
(3) Split large changes into a series of smaller patches, self-contained if
|
||||
possible, with an explanation of each patch and an explanation of how the
|
||||
sequence of patches fits together.
|
||||
|
||||
(4) Make sure your patches apply against libvirt GIT. Developers only follow GIT
|
||||
and don't care much about released versions.
|
||||
|
||||
(5) Run the automated tests on your code before submitting any changes. In
|
||||
particular, configure with compile warnings set to -Werror:
|
||||
|
||||
./configure --enable-compile-warnings=error
|
||||
|
||||
and run the tests:
|
||||
|
||||
make check
|
||||
make syntax-check
|
||||
make -C tests valgrind
|
||||
|
||||
The latter test checks for memory leaks.
|
||||
|
||||
If you encounter any failing tests, the VIR_TEST_DEBUG environment variable
|
||||
may provide extra information to debug the failures. Larger values of
|
||||
VIR_TEST_DEBUG may provide larger amounts of information:
|
||||
|
||||
VIR_TEST_DEBUG=1 make check (or)
|
||||
VIR_TEST_DEBUG=2 make check
|
||||
|
||||
Also, individual tests can be run from inside the "tests/" directory, like:
|
||||
|
||||
./qemuxml2xmltest
|
||||
|
||||
(6) Update tests and/or documentation, particularly if you are adding a new
|
||||
feature or changing the output of a program.
|
||||
|
||||
|
||||
|
||||
There is more on this subject, including lots of links to background reading
|
||||
on the subject, on
|
||||
|
||||
Richard Jones' guide to working with open source projects
|
||||
http://et.redhat.com/~rjones/how-to-supply-code-to-open-source-projects/
|
||||
|
||||
|
||||
Code indentation
|
||||
================
|
||||
Libvirt's C source code generally adheres to some basic code-formatting
|
||||
conventions. The existing code base is not totally consistent on this front,
|
||||
but we do prefer that contributed code be formatted similarly. In short, use
|
||||
spaces-not-TABs for indentation, use 4 spaces for each indentation level, and
|
||||
other than that, follow the K&R style.
|
||||
|
||||
If you use Emacs, add the following to one of one of your start-up files
|
||||
(e.g., ~/.emacs), to help ensure that you get indentation right:
|
||||
|
||||
;;; When editing C sources in libvirt, use this style.
|
||||
(defun libvirt-c-mode ()
|
||||
"C mode with adjusted defaults for use with libvirt."
|
||||
(interactive)
|
||||
(c-set-style "K&R")
|
||||
(setq indent-tabs-mode nil) ; indent using spaces, not TABs
|
||||
(setq c-indent-level 4)
|
||||
(setq c-basic-offset 4))
|
||||
(add-hook 'c-mode-hook
|
||||
'(lambda () (if (string-match "/libvirt" (buffer-file-name))
|
||||
(libvirt-c-mode))))
|
||||
|
||||
If you use vim, append the following to your ~/.vimrc file:
|
||||
|
||||
set nocompatible
|
||||
filetype on
|
||||
set autoindent
|
||||
set smartindent
|
||||
set cindent
|
||||
set tabstop=8
|
||||
set shiftwidth=4
|
||||
set expandtab
|
||||
set cinoptions=(0,:0,l1,t0
|
||||
filetype plugin indent on
|
||||
au FileType make setlocal noexpandtab
|
||||
au BufRead,BufNewFile *.am setlocal noexpandtab
|
||||
match ErrorMsg /\s\+$\| \+\ze\t/
|
||||
|
||||
Or if you don't want to mess your ~/.vimrc up, you can save the above into a
|
||||
file called .lvimrc (not .vimrc) located at the root of libvirt source, then
|
||||
install a vim script from
|
||||
http://www.vim.org/scripts/script.php?script_id=1408, which will load the
|
||||
.lvimrc only when you edit libvirt code.
|
||||
|
||||
|
||||
Code formatting (especially for new code)
|
||||
=========================================
|
||||
With new code, we can be even more strict. Please apply the following function
|
||||
(using GNU indent) to any new code. Note that this also gives you an idea of
|
||||
the type of spacing we prefer around operators and keywords:
|
||||
|
||||
indent-libvirt()
|
||||
{
|
||||
indent -bad -bap -bbb -bli4 -br -ce -brs -cs -i4 -l75 -lc75 \
|
||||
-sbi4 -psl -saf -sai -saw -sbi4 -ss -sc -cdw -cli4 -npcs -nbc \
|
||||
--no-tabs "$@"
|
||||
}
|
||||
|
||||
Note that sometimes you'll have to post-process that output further, by piping
|
||||
it through "expand -i", since some leading TABs can get through. Usually
|
||||
they're in macro definitions or strings, and should be converted anyhow.
|
||||
|
||||
Libvirt requires a C99 compiler for various reasons. However, most of the code
|
||||
base prefers to stick to C89 syntax unless there is a compelling reason
|
||||
otherwise. For example, it is preferable to use "/* */" comments rather than
|
||||
"//". Also, when declaring local variables, the prevailing style has been to
|
||||
declare them at the beginning of a scope, rather than immediately before use.
|
||||
|
||||
|
||||
Curly braces
|
||||
============
|
||||
Omit the curly braces around an "if", "while", "for" etc. body only when that
|
||||
body occupies a single line. In every other case we require the braces. This
|
||||
ensures that it is trivially easy to identify a single-'statement' loop: each
|
||||
has only one 'line' in its body.
|
||||
|
||||
Omitting braces with a single-line body is fine:
|
||||
|
||||
while (expr) // one-line body -> omitting curly braces is ok
|
||||
single_line_stmt();
|
||||
|
||||
However, the moment your loop/if/else body extends onto a second line, for
|
||||
whatever reason (even if it's just an added comment), then you should add
|
||||
braces. Otherwise, it would be too easy to insert a statement just before that
|
||||
comment (without adding braces), thinking it is already a multi-statement loop:
|
||||
|
||||
while (true) // BAD! multi-line body with no braces
|
||||
/* comment... */
|
||||
single_line_stmt();
|
||||
|
||||
Do this instead:
|
||||
|
||||
while (true) { // Always put braces around a multi-line body.
|
||||
/* comment... */
|
||||
single_line_stmt();
|
||||
}
|
||||
|
||||
There is one exception: when the second body line is not at the same
|
||||
indentation level as the first body line:
|
||||
|
||||
if (expr)
|
||||
die("a diagnostic that would make this line"
|
||||
" extend past the 80-column limit"));
|
||||
|
||||
It is safe to omit the braces in the code above, since the further-indented
|
||||
second body line makes it obvious that this is still a single-statement body.
|
||||
|
||||
To reiterate, don't do this:
|
||||
|
||||
if (expr) // BAD: no braces around...
|
||||
while (expr_2) { // ... a multi-line body
|
||||
...
|
||||
}
|
||||
|
||||
Do this, instead:
|
||||
|
||||
if (expr) {
|
||||
while (expr_2) {
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
However, there is one exception in the other direction, when even a one-line
|
||||
block should have braces. That occurs when that one-line, brace-less block is
|
||||
an "if" or "else" block, and the counterpart block *does* use braces. In that
|
||||
case, put braces around both blocks. Also, if the "else" block is much shorter
|
||||
than the "if" block, consider negating the "if"-condition and swapping the
|
||||
bodies, putting the short block first and making the longer, multi-line block
|
||||
be the "else" block.
|
||||
|
||||
if (expr) {
|
||||
...
|
||||
...
|
||||
}
|
||||
else
|
||||
x = y; // BAD: braceless "else" with braced "then",
|
||||
// and short block last
|
||||
|
||||
if (expr)
|
||||
x = y; // BAD: braceless "if" with braced "else"
|
||||
else {
|
||||
...
|
||||
...
|
||||
}
|
||||
|
||||
Keeping braces consistent and putting the short block first is preferred,
|
||||
especially when the multi-line body is more than a few lines long, because it
|
||||
is easier to read and grasp the semantics of an if-then-else block when the
|
||||
simpler block occurs first, rather than after the more involved block:
|
||||
|
||||
if (!expr) {
|
||||
x = y; // putting the smaller block first is more readable
|
||||
} else {
|
||||
...
|
||||
...
|
||||
}
|
||||
|
||||
But if negating a complex condition is too ugly, then at least add braces:
|
||||
|
||||
if (complex expr not worth negating) {
|
||||
...
|
||||
...
|
||||
} else {
|
||||
x = y;
|
||||
}
|
||||
|
||||
|
||||
Preprocessor
|
||||
============
|
||||
For variadic macros, stick with C99 syntax:
|
||||
|
||||
#define vshPrint(_ctl, ...) fprintf(stdout, __VA_ARGS__)
|
||||
|
||||
Use parenthesis when checking if a macro is defined, and use indentation to
|
||||
track nesting:
|
||||
|
||||
#if defined(HAVE_POSIX_FALLOCATE) && !defined(HAVE_FALLOCATE)
|
||||
# define fallocate(a,ignored,b,c) posix_fallocate(a,b,c)
|
||||
#endif
|
||||
|
||||
|
||||
C types
|
||||
=======
|
||||
Use the right type.
|
||||
|
||||
Scalars
|
||||
-------
|
||||
- If you're using "int" or "long", odds are good that there's a better type.
|
||||
|
||||
- If a variable is counting something, be sure to declare it with an unsigned
|
||||
type.
|
||||
|
||||
- If it's memory-size-related, use "size_t" (use "ssize_t" only if required).
|
||||
|
||||
- If it's file-size related, use uintmax_t, or maybe "off_t".
|
||||
|
||||
- If it's file-offset related (i.e., signed), use "off_t".
|
||||
|
||||
- If it's just counting small numbers use "unsigned int"; (on all but oddball
|
||||
embedded systems, you can assume that that type is at least four bytes wide).
|
||||
|
||||
- If a variable has boolean semantics, give it the "bool" type and use the
|
||||
corresponding "true" and "false" macros. It's ok to include <stdbool.h>, since
|
||||
libvirt's use of gnulib ensures that it exists and is usable.
|
||||
|
||||
- In the unusual event that you require a specific width, use a standard type
|
||||
like "int32_t", "uint32_t", "uint64_t", etc.
|
||||
|
||||
- While using "bool" is good for readability, it comes with minor caveats:
|
||||
|
||||
-- Don't use "bool" in places where the type size must be constant across all
|
||||
systems, like public interfaces and on-the-wire protocols. Note that it would
|
||||
be possible (albeit wasteful) to use "bool" in libvirt's logical wire
|
||||
protocol, since XDR maps that to its lower-level "bool_t" type, which *is*
|
||||
fixed-size.
|
||||
|
||||
-- Don't compare a bool variable against the literal, "true", since a value with
|
||||
a logical non-false value need not be "1". I.e., don't write "if (seen ==
|
||||
true) ...". Rather, write "if (seen)...".
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Of course, take all of the above with a grain of salt. If you're about to use
|
||||
some system interface that requires a type like "size_t", "pid_t" or "off_t",
|
||||
use matching types for any corresponding variables.
|
||||
|
||||
Also, if you try to use e.g., "unsigned int" as a type, and that conflicts
|
||||
with the signedness of a related variable, sometimes it's best just to use the
|
||||
*wrong* type, if 'pulling the thread' and fixing all related variables would
|
||||
be too invasive.
|
||||
|
||||
Finally, while using descriptive types is important, be careful not to go
|
||||
overboard. If whatever you're doing causes warnings, or requires casts, then
|
||||
reconsider or ask for help.
|
||||
|
||||
Pointers
|
||||
--------
|
||||
Ensure that all of your pointers are 'const-correct'. Unless a pointer is used
|
||||
to modify the pointed-to storage, give it the "const" attribute. That way, the
|
||||
reader knows up-front that this is a read-only pointer. Perhaps more
|
||||
importantly, if we're diligent about this, when you see a non-const pointer,
|
||||
you're guaranteed that it is used to modify the storage it points to, or it is
|
||||
aliased to another pointer that is.
|
||||
|
||||
|
||||
Low level memory management
|
||||
===========================
|
||||
Use of the malloc/free/realloc/calloc APIs is deprecated in the libvirt
|
||||
codebase, because they encourage a number of serious coding bugs and do not
|
||||
enable compile time verification of checks for NULL. Instead of these
|
||||
routines, use the macros from memory.h.
|
||||
|
||||
- To allocate a single object:
|
||||
|
||||
virDomainPtr domain;
|
||||
|
||||
if (VIR_ALLOC(domain) < 0) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
- To allocate an array of objects:
|
||||
|
||||
virDomainPtr domains;
|
||||
size_t ndomains = 10;
|
||||
|
||||
if (VIR_ALLOC_N(domains, ndomains) < 0) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
- To allocate an array of object pointers:
|
||||
|
||||
virDomainPtr *domains;
|
||||
size_t ndomains = 10;
|
||||
|
||||
if (VIR_ALLOC_N(domains, ndomains) < 0) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
- To re-allocate the array of domains to be 1 element longer (however, note that
|
||||
repeatedly expanding an array by 1 scales quadratically, so this is
|
||||
recommended only for smaller arrays):
|
||||
|
||||
virDomainPtr domains;
|
||||
size_t ndomains = 0;
|
||||
|
||||
if (VIR_EXPAND_N(domains, ndomains, 1) < 0) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
domains[ndomains - 1] = domain;
|
||||
|
||||
|
||||
|
||||
- To ensure an array has room to hold at least one more element (this approach
|
||||
scales better, but requires tracking allocation separately from usage)
|
||||
|
||||
virDomainPtr domains;
|
||||
size_t ndomains = 0;
|
||||
size_t ndomains_max = 0;
|
||||
|
||||
if (VIR_RESIZE_N(domains, ndomains_max, ndomains, 1) < 0) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
domains[ndomains++] = domain;
|
||||
|
||||
|
||||
|
||||
- To trim an array of domains from its allocated size down to the actual used
|
||||
size:
|
||||
|
||||
virDomainPtr domains;
|
||||
size_t ndomains = x;
|
||||
size_t ndomains_max = y;
|
||||
|
||||
VIR_SHRINK_N(domains, ndomains_max, ndomains_max - ndomains);
|
||||
|
||||
|
||||
|
||||
- To free an array of domains:
|
||||
|
||||
virDomainPtr domains;
|
||||
size_t ndomains = x;
|
||||
size_t ndomains_max = y;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ndomains; i++)
|
||||
VIR_FREE(domains[i]);
|
||||
VIR_FREE(domains);
|
||||
ndomains_max = ndomains = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File handling
|
||||
=============
|
||||
Usage of the "fdopen()", "close()", "fclose()" APIs is deprecated in libvirt
|
||||
code base to help avoiding double-closing of files or file descriptors, which
|
||||
is particulary dangerous in a multi-threaded applications. Instead of these
|
||||
APIs, use the macros from virfile.h
|
||||
|
||||
- Open a file from a file descriptor:
|
||||
|
||||
if ((file = VIR_FDOPEN(fd, "r")) == NULL) {
|
||||
virReportSystemError(errno, "%s",
|
||||
_("failed to open file from file descriptor"));
|
||||
return -1;
|
||||
}
|
||||
/* fd is now invalid; only access the file using file variable */
|
||||
|
||||
|
||||
|
||||
- Close a file descriptor:
|
||||
|
||||
if (VIR_CLOSE(fd) < 0) {
|
||||
virReportSystemError(errno, "%s", _("failed to close file"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
- Close a file:
|
||||
|
||||
if (VIR_FCLOSE(file) < 0) {
|
||||
virReportSystemError(errno, "%s", _("failed to close file"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
- Close a file or file descriptor in an error path, without losing the previous
|
||||
"errno" value:
|
||||
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
VIR_FORCE_FCLOSE(file);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
String comparisons
|
||||
==================
|
||||
Do not use the strcmp, strncmp, etc functions directly. Instead use one of the
|
||||
following semantically named macros
|
||||
|
||||
- For strict equality:
|
||||
|
||||
STREQ(a,b)
|
||||
STRNEQ(a,b)
|
||||
|
||||
|
||||
|
||||
- For case insensitive equality:
|
||||
|
||||
STRCASEEQ(a,b)
|
||||
STRCASENEQ(a,b)
|
||||
|
||||
|
||||
|
||||
- For strict equality of a substring:
|
||||
|
||||
STREQLEN(a,b,n)
|
||||
STRNEQLEN(a,b,n)
|
||||
|
||||
|
||||
|
||||
- For case insensitive equality of a substring:
|
||||
|
||||
STRCASEEQLEN(a,b,n)
|
||||
STRCASENEQLEN(a,b,n)
|
||||
|
||||
|
||||
|
||||
- For strict equality of a prefix:
|
||||
|
||||
STRPREFIX(a,b)
|
||||
|
||||
|
||||
|
||||
- To avoid having to check if a or b are NULL:
|
||||
|
||||
STREQ_NULLABLE(a, b)
|
||||
STRNEQ_NULLABLE(a, b)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
String copying
|
||||
==============
|
||||
Do not use the strncpy function. According to the man page, it does *not*
|
||||
guarantee a NULL-terminated buffer, which makes it extremely dangerous to use.
|
||||
Instead, use one of the functionally equivalent functions:
|
||||
|
||||
virStrncpy(char *dest, const char *src, size_t n, size_t destbytes)
|
||||
|
||||
The first three arguments have the same meaning as for strncpy; namely the
|
||||
destination, source, and number of bytes to copy, respectively. The last
|
||||
argument is the number of bytes available in the destination string; if a copy
|
||||
of the source string (including a \0) will not fit into the destination, no
|
||||
bytes are copied and the routine returns NULL. Otherwise, n bytes from the
|
||||
source are copied into the destination and a trailing \0 is appended.
|
||||
|
||||
virStrcpy(char *dest, const char *src, size_t destbytes)
|
||||
|
||||
Use this variant if you know you want to copy the entire src string into dest.
|
||||
Note that this is a macro, so arguments could be evaluated more than once.
|
||||
This is equivalent to virStrncpy(dest, src, strlen(src), destbytes)
|
||||
|
||||
virStrcpyStatic(char *dest, const char *src)
|
||||
|
||||
Use this variant if you know you want to copy the entire src string into dest
|
||||
*and* you know that your destination string is a static string (i.e. that
|
||||
sizeof(dest) returns something meaningful). Note that this is a macro, so
|
||||
arguments could be evaluated more than once. This is equivalent to
|
||||
virStrncpy(dest, src, strlen(src), sizeof(dest)).
|
||||
|
||||
|
||||
Variable length string buffer
|
||||
=============================
|
||||
If there is a need for complex string concatenations, avoid using the usual
|
||||
sequence of malloc/strcpy/strcat/snprintf functions and make use of the
|
||||
virBuffer API described in buf.h
|
||||
|
||||
Typical usage is as follows:
|
||||
|
||||
char *
|
||||
somefunction(...)
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
...
|
||||
|
||||
virBufferAddLit(&buf, "<domain>\n");
|
||||
virBufferAsprintf(&buf, " <memory>%d</memory>\n", memory);
|
||||
...
|
||||
virBufferAddLit(&buf, "</domain>\n");
|
||||
|
||||
...
|
||||
|
||||
if (virBufferError(&buf)) {
|
||||
virBufferFreeAndReset(&buf);
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return virBufferContentAndReset(&buf);
|
||||
}
|
||||
|
||||
|
||||
Include files
|
||||
=============
|
||||
There are now quite a large number of include files, both libvirt internal and
|
||||
external, and system includes. To manage all this complexity it's best to
|
||||
stick to the following general plan for all *.c source files:
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
* ....
|
||||
* ....
|
||||
* ....
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h> Must come first in every file.
|
||||
|
||||
#include <stdio.h> Any system includes you need.
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if HAVE_NUMACTL Some system includes aren't supported
|
||||
# include <numa.h> everywhere so need these #if guards.
|
||||
#endif
|
||||
|
||||
#include "internal.h" Include this first, after system includes.
|
||||
|
||||
#include "util.h" Any libvirt internal header files.
|
||||
#include "buf.h"
|
||||
|
||||
static int
|
||||
myInternalFunc() The actual code.
|
||||
{
|
||||
...
|
||||
|
||||
Of particular note: *Do not* include libvirt/libvirt.h or libvirt/virterror.h.
|
||||
It is included by "internal.h" already and there are some special reasons why
|
||||
you cannot include these files explicitly.
|
||||
|
||||
|
||||
Printf-style functions
|
||||
======================
|
||||
Whenever you add a new printf-style function, i.e., one with a format string
|
||||
argument and following "..." in its prototype, be sure to use gcc's printf
|
||||
attribute directive in the prototype. For example, here's the one for
|
||||
virAsprintf, in util.h:
|
||||
|
||||
int virAsprintf(char **strp, const char *fmt, ...)
|
||||
ATTRIBUTE_FORMAT(printf, 2, 3);
|
||||
|
||||
This makes it so gcc's -Wformat and -Wformat-security options can do their
|
||||
jobs and cross-check format strings with the number and types of arguments.
|
||||
|
||||
When printing to a string, consider using virBuffer for incremental
|
||||
allocations, virAsprintf for a one-shot allocation, and snprintf for
|
||||
fixed-width buffers. Do not use sprintf, even if you can prove the buffer
|
||||
won't overflow, since gnulib does not provide the same portability guarantees
|
||||
for sprintf as it does for snprintf.
|
||||
|
||||
|
||||
Use of goto
|
||||
===========
|
||||
The use of goto is not forbidden, and goto is widely used throughout libvirt.
|
||||
While the uncontrolled use of goto will quickly lead to unmaintainable code,
|
||||
there is a place for it in well structured code where its use increases
|
||||
readability and maintainability. In general, if goto is used for error
|
||||
recovery, it's likely to be ok, otherwise, be cautious or avoid it all
|
||||
together.
|
||||
|
||||
The typical use of goto is to jump to cleanup code in the case of a long list
|
||||
of actions, any of which may fail and cause the entire operation to fail. In
|
||||
this case, a function will have a single label at the end of the function.
|
||||
It's almost always ok to use this style. In particular, if the cleanup code
|
||||
only involves free'ing memory, then having multiple labels is overkill.
|
||||
VIR_FREE() and every function named XXXFree() in libvirt is required to handle
|
||||
NULL as its arg. Thus you can safely call free on all the variables even if
|
||||
they were not yet allocated (yes they have to have been initialized to NULL).
|
||||
This is much simpler and clearer than having multiple labels.
|
||||
|
||||
There are a couple of signs that a particular use of goto is not ok:
|
||||
|
||||
- You're using multiple labels. If you find yourself using multiple labels,
|
||||
you're strongly encouraged to rework your code to eliminate all but one of
|
||||
them.
|
||||
|
||||
- The goto jumps back up to a point above the current line of code being
|
||||
executed. Please use some combination of looping constructs to re-execute code
|
||||
instead; it's almost certainly going to be more understandable by others. One
|
||||
well-known exception to this rule is restarting an i/o operation following
|
||||
EINTR.
|
||||
|
||||
- The goto jumps down to an arbitrary place in the middle of a function followed
|
||||
by further potentially failing calls. You should almost certainly be using a
|
||||
conditional and a block instead of a goto. Perhaps some of your function's
|
||||
logic would be better pulled out into a helper function.
|
||||
|
||||
|
||||
|
||||
Although libvirt does not encourage the Linux kernel wind/unwind style of
|
||||
multiple labels, there's a good general discussion of the issue archived at
|
||||
|
||||
KernelTrap
|
||||
http://kerneltrap.org/node/553/2131
|
||||
|
||||
When using goto, please use one of these standard labels if it makes sense:
|
||||
|
||||
error: A path only taken upon return with an error code
|
||||
cleanup: A path taken upon return with success code + optional error
|
||||
no_memory: A path only taken upon return with an OOM error code
|
||||
retry: If needing to jump upwards (e.g., retry on EINTR)
|
||||
|
||||
|
||||
Libvirt committer guidelines
|
||||
============================
|
||||
The AUTHORS files indicates the list of people with commit access right who
|
||||
can actually merge the patches.
|
||||
|
||||
The general rule for committing a patch is to make sure it has been reviewed
|
||||
properly in the mailing-list first, usually if a couple of people gave an ACK
|
||||
or +1 to a patch and nobody raised an objection on the list it should be good
|
||||
to go. If the patch touches a part of the code where you're not the main
|
||||
maintainer, or where you do not have a very clear idea of how things work,
|
||||
it's better to wait for a more authoritative feedback though. Before
|
||||
committing, please also rebuild locally, run 'make check syntax-check', and
|
||||
make sure you don't raise errors. Try to look for warnings too; for example,
|
||||
configure with
|
||||
|
||||
--enable-compile-warnings=error
|
||||
|
||||
which adds -Werror to compile flags, so no warnings get missed
|
||||
|
||||
An exception to 'review and approval on the list first' is fixing failures to
|
||||
build:
|
||||
|
||||
- if a recently committed patch breaks compilation on a platform or for a given
|
||||
driver, then it's fine to commit a minimal fix directly without getting the
|
||||
review feedback first
|
||||
|
||||
- if make check or make syntax-check breaks, if there is an obvious fix, it's
|
||||
fine to commit immediately. The patch should still be sent to the list (or
|
||||
tell what the fix was if trivial), and 'make check syntax-check' should pass
|
||||
too, before committing anything
|
||||
|
||||
- fixes for documentation and code comments can be managed in the same way, but
|
||||
still make sure they get reviewed if non-trivial.
|
92
Makefile.am
92
Makefile.am
@ -1,92 +0,0 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
## Copyright (C) 2005-2011 Red Hat, Inc.
|
||||
## See COPYING.LIB for the License of this software
|
||||
|
||||
LCOV = lcov
|
||||
GENHTML = genhtml
|
||||
|
||||
SUBDIRS = gnulib/lib include src daemon tools docs gnulib/tests \
|
||||
python tests po examples/domain-events/events-c examples/hellolibvirt \
|
||||
examples/dominfo examples/domsuspend examples/python examples/apparmor \
|
||||
examples/xml/nwfilter examples/openauth examples/systemtap
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 -I gnulib/m4
|
||||
|
||||
XML_EXAMPLES = \
|
||||
$(patsubst $(srcdir)/%,%,$(wildcard $(addprefix $(srcdir)/examples/xml/, \
|
||||
test/*.xml storage/*.xml)))
|
||||
|
||||
EXTRA_DIST = \
|
||||
ChangeLog-old \
|
||||
libvirt.spec libvirt.spec.in \
|
||||
mingw32-libvirt.spec.in \
|
||||
libvirt.pc.in \
|
||||
autobuild.sh \
|
||||
Makefile.nonreentrant \
|
||||
autogen.sh \
|
||||
cfg.mk \
|
||||
examples/domain-events/events-python \
|
||||
$(XML_EXAMPLES)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libvirt.pc
|
||||
|
||||
NEWS: $(top_srcdir)/docs/news.xsl $(top_srcdir)/docs/news.html.in
|
||||
-@(if [ -x $(XSLTPROC) ] ; then \
|
||||
$(XSLTPROC) --nonet $(top_srcdir)/docs/news.xsl \
|
||||
$(top_srcdir)/docs/news.html.in \
|
||||
| perl -0777 -pe 's/\n\n+$$/\n/' \
|
||||
| perl -pe 's/[ \t]+$$//' \
|
||||
> $@-t && mv $@-t $@ ; fi );
|
||||
|
||||
$(top_srcdir)/HACKING: $(top_srcdir)/docs/hacking1.xsl $(top_srcdir)/docs/hacking2.xsl \
|
||||
$(top_srcdir)/docs/wrapstring.xsl $(top_srcdir)/docs/hacking.html.in
|
||||
-@(if [ -x $(XSLTPROC) ] ; then \
|
||||
$(XSLTPROC) --nonet $(top_srcdir)/docs/hacking1.xsl $(top_srcdir)/docs/hacking.html.in | \
|
||||
$(XSLTPROC) --nonet $(top_srcdir)/docs/hacking2.xsl - \
|
||||
| perl -0777 -pe 's/\n\n+$$/\n/' \
|
||||
> $@-t && mv $@-t $@ ; fi );
|
||||
|
||||
rpm: clean
|
||||
@(unset CDPATH ; $(MAKE) dist && rpmbuild -ta $(distdir).tar.gz)
|
||||
|
||||
check-local: all tests
|
||||
|
||||
tests:
|
||||
@(cd docs/examples ; $(MAKE) MAKEFLAGS+=--silent tests)
|
||||
@(if [ "$(pythondir)" != "" ] ; then cd python ; \
|
||||
$(MAKE) MAKEFLAGS+=--silent tests ; fi)
|
||||
|
||||
cov: clean-cov
|
||||
mkdir $(top_builddir)/coverage
|
||||
$(LCOV) -c -o $(top_builddir)/coverage/libvirt.info.tmp \
|
||||
-d $(top_builddir)/src -d $(top_builddir)/daemon \
|
||||
-d $(top_builddir)/tests
|
||||
$(LCOV) -r $(top_builddir)/coverage/libvirt.info.tmp \
|
||||
-o $(top_builddir)/coverage/libvirt.info
|
||||
rm $(top_builddir)/coverage/libvirt.info.tmp
|
||||
$(GENHTML) --show-details -t "libvirt" -o $(top_builddir)/coverage \
|
||||
--legend $(top_builddir)/coverage/libvirt.info
|
||||
|
||||
clean-cov:
|
||||
rm -rf $(top_builddir)/coverage
|
||||
|
||||
MAINTAINERCLEANFILES = .git-module-status
|
||||
|
||||
# disable this check
|
||||
distuninstallcheck:
|
||||
|
||||
dist-hook: gen-ChangeLog
|
||||
|
||||
# Generate the ChangeLog file (with all entries since the switch to git)
|
||||
# and insert it into the directory we're about to use to create a tarball.
|
||||
gen_start_date = 2009-07-04
|
||||
.PHONY: gen-ChangeLog
|
||||
gen-ChangeLog:
|
||||
if test -d .git; then \
|
||||
$(top_srcdir)/build-aux/gitlog-to-changelog \
|
||||
--since=$(gen_start_date) > $(distdir)/cl-t; \
|
||||
rm -f $(distdir)/ChangeLog; \
|
||||
mv $(distdir)/cl-t $(distdir)/ChangeLog; \
|
||||
fi
|
@ -1,100 +0,0 @@
|
||||
|
||||
#
|
||||
# Generated by running the following on Fedora 9:
|
||||
#
|
||||
# nm -D --defined-only /lib/libc.so.6 \
|
||||
# | grep '_r$' \
|
||||
# | awk '{print $3}' \
|
||||
# | grep -v __ \
|
||||
# | grep -v qsort \ # Red herring since we don't need to pass extra args to qsort comparator
|
||||
# | grep -v readdir \ # This is safe as long as each DIR * instance is only used by one thread
|
||||
# | sort \
|
||||
# | uniq \
|
||||
# | sed -e 's/_r//'
|
||||
#
|
||||
# Also manually add in all inet_* functions some of which
|
||||
# are not threadsafe and do not have _r variants. They are
|
||||
# all deprecated in favour of getnameinfo/getaddrinfo
|
||||
#
|
||||
|
||||
NON_REENTRANT =
|
||||
NON_REENTRANT += asctime
|
||||
NON_REENTRANT += ctime
|
||||
NON_REENTRANT += drand48
|
||||
NON_REENTRANT += ecvt
|
||||
NON_REENTRANT += erand48
|
||||
NON_REENTRANT += ether_aton
|
||||
NON_REENTRANT += ether_ntoa
|
||||
NON_REENTRANT += fcvt
|
||||
NON_REENTRANT += fgetgrent
|
||||
NON_REENTRANT += fgetpwent
|
||||
NON_REENTRANT += fgetspent
|
||||
NON_REENTRANT += getaliasbyname
|
||||
NON_REENTRANT += getaliasent
|
||||
NON_REENTRANT += getdate
|
||||
NON_REENTRANT += getgrent
|
||||
NON_REENTRANT += getgrgid
|
||||
NON_REENTRANT += getgrnam
|
||||
NON_REENTRANT += gethostbyaddr
|
||||
NON_REENTRANT += gethostbyname2
|
||||
NON_REENTRANT += gethostbyname
|
||||
NON_REENTRANT += gethostent
|
||||
NON_REENTRANT += getlogin
|
||||
NON_REENTRANT += getmntent
|
||||
NON_REENTRANT += getnetbyaddr
|
||||
NON_REENTRANT += getnetbyname
|
||||
NON_REENTRANT += getnetent
|
||||
NON_REENTRANT += getnetgrent
|
||||
NON_REENTRANT += getprotobyname
|
||||
NON_REENTRANT += getprotobynumber
|
||||
NON_REENTRANT += getprotoent
|
||||
NON_REENTRANT += getpwent
|
||||
NON_REENTRANT += getpwnam
|
||||
NON_REENTRANT += getpwuid
|
||||
NON_REENTRANT += getrpcbyname
|
||||
NON_REENTRANT += getrpcbynumber
|
||||
NON_REENTRANT += getrpcent
|
||||
NON_REENTRANT += getservbyname
|
||||
NON_REENTRANT += getservbyport
|
||||
NON_REENTRANT += getservent
|
||||
NON_REENTRANT += getspent
|
||||
NON_REENTRANT += getspnam
|
||||
NON_REENTRANT += getutent
|
||||
NON_REENTRANT += getutid
|
||||
NON_REENTRANT += getutline
|
||||
NON_REENTRANT += gmtime
|
||||
NON_REENTRANT += hcreate
|
||||
NON_REENTRANT += hdestroy
|
||||
NON_REENTRANT += hsearch
|
||||
NON_REENTRANT += initstate
|
||||
NON_REENTRANT += jrand48
|
||||
NON_REENTRANT += lcong48
|
||||
NON_REENTRANT += localtime
|
||||
NON_REENTRANT += lrand48
|
||||
NON_REENTRANT += mrand48
|
||||
NON_REENTRANT += nrand48
|
||||
NON_REENTRANT += ptsname
|
||||
NON_REENTRANT += qecvt
|
||||
NON_REENTRANT += qfcvt
|
||||
NON_REENTRANT += random
|
||||
NON_REENTRANT += rand
|
||||
NON_REENTRANT += seed48
|
||||
NON_REENTRANT += setstate
|
||||
NON_REENTRANT += sgetspent
|
||||
NON_REENTRANT += srand48
|
||||
NON_REENTRANT += srandom
|
||||
NON_REENTRANT += strerror
|
||||
NON_REENTRANT += strtok
|
||||
NON_REENTRANT += tmpnam
|
||||
NON_REENTRANT += ttyname
|
||||
NON_REENTRANT += inet_addr
|
||||
NON_REENTRANT += inet_aton
|
||||
NON_REENTRANT += inet_lnaof
|
||||
NON_REENTRANT += inet_makeaddr
|
||||
NON_REENTRANT += inet_netof
|
||||
NON_REENTRANT += inet_network
|
||||
NON_REENTRANT += inet_nsap_addr
|
||||
NON_REENTRANT += inet_nsap_ntoa
|
||||
NON_REENTRANT += inet_ntoa
|
||||
NON_REENTRANT += inet_ntop
|
||||
NON_REENTRANT += inet_pton
|
14
README
14
README
@ -1,13 +1 @@
|
||||
|
||||
LibVirt : simple API for virtualization
|
||||
|
||||
Libvirt is a C toolkit to interact with the virtualization capabilities
|
||||
of recent versions of Linux (and other OSes). It is free software
|
||||
available under the GNU Lesser General Public License. Virtualization of
|
||||
the Linux Operating System means the ability to run multiple instances of
|
||||
Operating Systems concurrently on a single hardware system where the basic
|
||||
resources are driven by a Linux instance. The library aim at providing
|
||||
long term stable C API initially for the Xen paravirtualization but
|
||||
should be able to integrate other virtualization mechanisms if needed.
|
||||
|
||||
Daniel Veillard <veillard@redhat.com>
|
||||
This branch is no longer maintained upstream.
|
||||
|
@ -1,57 +0,0 @@
|
||||
-*- outline -*-
|
||||
|
||||
These notes intend to help people working on the checked-out sources.
|
||||
These requirements do not apply when building from a distribution tarball.
|
||||
See also HACKING for more detailed libvirt contribution guidelines.
|
||||
|
||||
* Requirements
|
||||
|
||||
We've opted to keep only the highest-level sources in the GIT repository.
|
||||
This eases our maintenance burden, (fewer merges etc.), but imposes more
|
||||
requirements on anyone wishing to build from the just-checked-out sources.
|
||||
Note the requirements to build the released archive are much less and
|
||||
are just the requirements of the standard ./configure && make procedure.
|
||||
Specific development tools and versions will be checked for and listed by
|
||||
the bootstrap script.
|
||||
|
||||
Valgrind <http://valgrind.org/> is also highly recommended, if
|
||||
Valgrind supports your architecture. See also README-valgrind.
|
||||
|
||||
While building from a just-cloned source tree may require installing a
|
||||
few prerequisites, later, a plain `git pull && make' should be sufficient.
|
||||
|
||||
* First GIT checkout
|
||||
|
||||
You can get a copy of the source repository like this:
|
||||
|
||||
$ git clone git://libvirt.org/libvirt
|
||||
$ cd libvirt
|
||||
|
||||
As an optional step, if you already have a copy of the gnulib git
|
||||
repository on your hard drive, then you can use it as a reference to
|
||||
reduce download time and disk space requirements:
|
||||
|
||||
$ export GNULIB_SRCDIR=/path/to/gnulib
|
||||
|
||||
The next step is to get all required pieces from gnulib,
|
||||
to run autoreconf, and to invoke ./configure:
|
||||
|
||||
$ ./autogen.sh
|
||||
|
||||
And there you are! Just
|
||||
|
||||
$ make
|
||||
$ make check
|
||||
|
||||
At this point, there should be no difference between your local copy,
|
||||
and the GIT master copy:
|
||||
|
||||
$ git diff
|
||||
|
||||
should output no difference.
|
||||
|
||||
Enjoy!
|
||||
|
||||
Local Variables:
|
||||
indent-tabs-mode: nil
|
||||
End:
|
22
TODO
22
TODO
@ -1,22 +0,0 @@
|
||||
libvirt TODO list
|
||||
=================
|
||||
|
||||
The TODO list changes frequently, so is maintained online
|
||||
in the libvirt bugzilla
|
||||
|
||||
http://bugzilla.redhat.com/
|
||||
|
||||
Search against
|
||||
|
||||
Product: Virtualization Tools
|
||||
Component: libvirt
|
||||
Subject: RFE
|
||||
|
||||
Or browse dependent bugs under
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=libvirtTodo
|
||||
|
||||
Summarized reports automatically generated from bugzilla
|
||||
and provided online at
|
||||
|
||||
http://libvirt.org/todo.html
|
93
autobuild.sh
93
autobuild.sh
@ -1,93 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
set -v
|
||||
|
||||
# Make things clean.
|
||||
|
||||
test -n "$1" && RESULTS=$1 || RESULTS=results.log
|
||||
: ${AUTOBUILD_INSTALL_ROOT=$HOME/builder}
|
||||
|
||||
test -f Makefile && make -k distclean || :
|
||||
rm -rf coverage
|
||||
|
||||
rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
# Run with options not normally exercised by the rpm build, for
|
||||
# more complete code coverage.
|
||||
../autogen.sh --prefix="$AUTOBUILD_INSTALL_ROOT" \
|
||||
--enable-test-coverage \
|
||||
--disable-nls \
|
||||
--enable-werror
|
||||
|
||||
# If the MAKEFLAGS envvar does not yet include a -j option,
|
||||
# add -jN where N depends on the number of processors.
|
||||
case $MAKEFLAGS in
|
||||
*-j*) ;;
|
||||
*) n=$(getconf _NPROCESSORS_ONLN 2> /dev/null)
|
||||
test "$n" -gt 0 || n=1
|
||||
n=$(expr $n + 1)
|
||||
MAKEFLAGS="$MAKEFLAGS -j$n"
|
||||
export MAKEFLAGS
|
||||
;;
|
||||
esac
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
# set -o pipefail is a bashism; this use of exec is the POSIX alternative
|
||||
exec 3>&1
|
||||
st=$(
|
||||
exec 4>&1 >&3
|
||||
{ make check syntax-check 2>&1 3>&- 4>&-; echo $? >&4; } | tee "$RESULTS"
|
||||
)
|
||||
exec 3>&-
|
||||
test "$st" = 0
|
||||
test -x /usr/bin/lcov && make cov
|
||||
|
||||
rm -f *.tar.gz
|
||||
make dist
|
||||
|
||||
if [ -n "$AUTOBUILD_COUNTER" ]; then
|
||||
EXTRA_RELEASE=".auto$AUTOBUILD_COUNTER"
|
||||
else
|
||||
NOW=`date +"%s"`
|
||||
EXTRA_RELEASE=".$USER$NOW"
|
||||
fi
|
||||
|
||||
if [ -f /usr/bin/rpmbuild ]; then
|
||||
rpmbuild --nodeps \
|
||||
--define "extra_release $EXTRA_RELEASE" \
|
||||
--define "_sourcedir `pwd`" \
|
||||
-ba --clean libvirt.spec
|
||||
fi
|
||||
|
||||
# Test mingw cross-compile
|
||||
if [ -x /usr/bin/i686-pc-mingw32-gcc ]; then
|
||||
make distclean
|
||||
|
||||
PKG_CONFIG_PATH="$AUTOBUILD_INSTALL_ROOT/i686-pc-mingw32/sys-root/mingw/lib/pkgconfig" \
|
||||
CC="i686-pc-mingw32-gcc" \
|
||||
../configure \
|
||||
--build=$(uname -m)-pc-linux \
|
||||
--host=i686-pc-mingw32 \
|
||||
--prefix="$AUTOBUILD_INSTALL_ROOT/i686-pc-mingw32/sys-root/mingw" \
|
||||
--enable-werror \
|
||||
--without-libvirtd \
|
||||
--without-python
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
#set -o pipefail
|
||||
#make check 2>&1 | tee "$RESULTS"
|
||||
|
||||
if [ -f /usr/bin/rpmbuild ]; then
|
||||
rpmbuild --nodeps \
|
||||
--define "extra_release $EXTRA_RELEASE" \
|
||||
--define "_sourcedir `pwd`" \
|
||||
-ba --clean mingw32-libvirt.spec
|
||||
fi
|
||||
fi
|
98
autogen.sh
98
autogen.sh
@ -1,98 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname "$0"`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
THEDIR=`pwd`
|
||||
cd "$srcdir"
|
||||
|
||||
test -f src/libvirt.c || {
|
||||
echo "You must run this script in the top-level libvirt directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
EXTRA_ARGS=
|
||||
no_git=
|
||||
if test "x$1" = "x--no-git"; then
|
||||
no_git=" $1"
|
||||
shift
|
||||
fi
|
||||
if test "x$1" = "x--system"; then
|
||||
shift
|
||||
prefix=/usr
|
||||
libdir=$prefix/lib
|
||||
sysconfdir=/etc
|
||||
localstatedir=/var
|
||||
if [ -d /usr/lib64 ]; then
|
||||
libdir=$prefix/lib64
|
||||
fi
|
||||
EXTRA_ARGS="--prefix=$prefix --sysconfdir=$sysconfdir --localstatedir=$localstatedir --libdir=$libdir"
|
||||
echo "Running ./configure with $EXTRA_ARGS $@"
|
||||
else
|
||||
if test -z "$*" && test ! -f "$THEDIR/config.status"; then
|
||||
echo "I am going to run ./configure with no arguments - if you wish "
|
||||
echo "to pass any to it, please specify them on the $0 command line."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Compute the hash we'll use to determine whether rerunning bootstrap
|
||||
# is required. The first is just the SHA1 that selects a gnulib snapshot.
|
||||
# The second ensures that whenever we change the set of gnulib modules used
|
||||
# by this package, we rerun bootstrap to pull in the matching set of files.
|
||||
# The third ensures that whenever we change the set of local gnulib diffs,
|
||||
# we rerun bootstrap to pull in those diffs.
|
||||
bootstrap_hash()
|
||||
{
|
||||
git submodule status | sed 's/^[ +-]//;s/ .*//'
|
||||
git hash-object bootstrap.conf
|
||||
git ls-tree -d HEAD gnulib/local | awk '{print $3}'
|
||||
}
|
||||
|
||||
# Ensure that whenever we pull in a gnulib update or otherwise change to a
|
||||
# different version (i.e., when switching branches), we also rerun ./bootstrap.
|
||||
# Also, running 'make rpm' tends to litter the po/ directory, and some people
|
||||
# like to run 'git clean -x -f po' to fix it; but only ./bootstrap regenerates
|
||||
# the required file po/Makevars.
|
||||
# Only run bootstrap from a git checkout, never from a tarball.
|
||||
if test -d .git; then
|
||||
curr_status=.git-module-status
|
||||
t=$(bootstrap_hash; git diff .gnulib)
|
||||
case $t:${CLEAN_SUBMODULE+set} in
|
||||
*:set) ;;
|
||||
*-dirty*)
|
||||
echo "error: gnulib submodule is dirty, please investigate" 2>&1
|
||||
echo "set env-var CLEAN_SUBMODULE to discard gnulib changes" 2>&1
|
||||
exit 1 ;;
|
||||
esac
|
||||
if test "$t" = "$(cat $curr_status 2>/dev/null)" \
|
||||
&& test -f "po/Makevars"; then
|
||||
# good, it's up to date, all we need is autoreconf
|
||||
autoreconf -if
|
||||
else
|
||||
if test ${CLEAN_SUBMODULE+set}; then
|
||||
echo cleaning up submodules...
|
||||
git submodule foreach 'git clean -dfqx && git reset --hard'
|
||||
fi
|
||||
echo running bootstrap$no_git...
|
||||
./bootstrap$no_git --bootstrap-sync && bootstrap_hash > $curr_status \
|
||||
|| { echo "Failed to bootstrap, please investigate."; exit 1; }
|
||||
fi
|
||||
fi
|
||||
|
||||
cd "$THEDIR"
|
||||
|
||||
if test "x$OBJ_DIR" != x; then
|
||||
mkdir -p "$OBJ_DIR"
|
||||
cd "$OBJ_DIR"
|
||||
fi
|
||||
|
||||
if test -z "$*" && test -z "$EXTRA_ARGS" && test -f config.status; then
|
||||
./config.status --recheck
|
||||
else
|
||||
$srcdir/configure $EXTRA_ARGS "$@"
|
||||
fi && {
|
||||
echo
|
||||
echo "Now type 'make' to compile libvirt."
|
||||
}
|
976
bootstrap
976
bootstrap
@ -1,976 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2012-07-19.14; # UTC
|
||||
|
||||
# Bootstrap this package from checked-out sources.
|
||||
|
||||
# Copyright (C) 2003-2012 Free Software Foundation, Inc.
|
||||
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Originally written by Paul Eggert. The canonical version of this
|
||||
# script is maintained as build-aux/bootstrap in gnulib, however, to
|
||||
# be useful to your project, you should place a copy of it under
|
||||
# version control in the top-level directory of your project. The
|
||||
# intent is that all customization can be done with a bootstrap.conf
|
||||
# file also maintained in your version control; gnulib comes with a
|
||||
# template build-aux/bootstrap.conf to get you started.
|
||||
|
||||
# Please report bugs or propose patches to bug-gnulib@gnu.org.
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# Ensure file names are sorted consistently across platforms.
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
# Ensure that CDPATH is not set. Otherwise, the output from cd
|
||||
# would cause trouble in at least one use below.
|
||||
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
|
||||
|
||||
local_gl_dir=gl
|
||||
|
||||
me=$0
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $me [OPTION]...
|
||||
Bootstrap this package from the checked-out sources.
|
||||
|
||||
Options:
|
||||
--gnulib-srcdir=DIRNAME specify the local directory where gnulib
|
||||
sources reside. Use this if you already
|
||||
have gnulib sources on your machine, and
|
||||
do not want to waste your bandwidth downloading
|
||||
them again. Defaults to \$GNULIB_SRCDIR
|
||||
--bootstrap-sync if this bootstrap script is not identical to
|
||||
the version in the local gnulib sources,
|
||||
update this script, and then restart it with
|
||||
/bin/sh or the shell \$CONFIG_SHELL
|
||||
--no-bootstrap-sync do not check whether bootstrap is out of sync
|
||||
--copy copy files instead of creating symbolic links
|
||||
--force attempt to bootstrap even if the sources seem
|
||||
not to have been checked out
|
||||
--no-git do not use git to update gnulib. Requires that
|
||||
--gnulib-srcdir point to a correct gnulib snapshot
|
||||
--skip-po do not download po files
|
||||
|
||||
If the file $me.conf exists in the same directory as this script, its
|
||||
contents are read as shell variables to configure the bootstrap.
|
||||
|
||||
For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
|
||||
are honored.
|
||||
|
||||
Running without arguments will suffice in most cases.
|
||||
EOF
|
||||
}
|
||||
|
||||
# warnf_ FORMAT-STRING ARG1...
|
||||
warnf_ ()
|
||||
{
|
||||
warnf_format_=$1
|
||||
shift
|
||||
nl='
|
||||
'
|
||||
case $* in
|
||||
*$nl*) me_=$(printf "$me"|tr "$nl|" '??')
|
||||
printf "$warnf_format_" "$@" | sed "s|^|$me_: |" ;;
|
||||
*) printf "$me: $warnf_format_" "$@" ;;
|
||||
esac >&2
|
||||
}
|
||||
|
||||
# warn_ WORD1...
|
||||
warn_ ()
|
||||
{
|
||||
# If IFS does not start with ' ', set it and emit the warning in a subshell.
|
||||
case $IFS in
|
||||
' '*) warnf_ '%s\n' "$*";;
|
||||
*) (IFS=' '; warn_ "$@");;
|
||||
esac
|
||||
}
|
||||
|
||||
# die WORD1...
|
||||
die() { warn_ "$@"; exit 1; }
|
||||
|
||||
# Configuration.
|
||||
|
||||
# Name of the Makefile.am
|
||||
gnulib_mk=gnulib.mk
|
||||
|
||||
# List of gnulib modules needed.
|
||||
gnulib_modules=
|
||||
|
||||
# Any gnulib files needed that are not in modules.
|
||||
gnulib_files=
|
||||
|
||||
: ${AUTOPOINT=autopoint}
|
||||
: ${AUTORECONF=autoreconf}
|
||||
|
||||
# A function to be called right after gnulib-tool is run.
|
||||
# Override it via your own definition in bootstrap.conf.
|
||||
bootstrap_post_import_hook() { :; }
|
||||
|
||||
# A function to be called after everything else in this script.
|
||||
# Override it via your own definition in bootstrap.conf.
|
||||
bootstrap_epilogue() { :; }
|
||||
|
||||
# The command to download all .po files for a specified domain into
|
||||
# a specified directory. Fill in the first %s is the domain name, and
|
||||
# the second with the destination directory. Use rsync's -L and -r
|
||||
# options because the latest/%s directory and the .po files within are
|
||||
# all symlinks.
|
||||
po_download_command_format=\
|
||||
"rsync --delete --exclude '*.s1' -Lrtvz \
|
||||
'translationproject.org::tp/latest/%s/' '%s'"
|
||||
|
||||
# Fallback for downloading .po files (if rsync fails).
|
||||
po_download_command_format2=\
|
||||
"wget --mirror -nd -q -np -A.po -P '%s' \
|
||||
http://translationproject.org/latest/%s/"
|
||||
|
||||
extract_package_name='
|
||||
/^AC_INIT(/{
|
||||
/.*,.*,.*, */{
|
||||
s///
|
||||
s/[][]//g
|
||||
s/)$//
|
||||
p
|
||||
q
|
||||
}
|
||||
s/AC_INIT(\[*//
|
||||
s/]*,.*//
|
||||
s/^GNU //
|
||||
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
|
||||
s/[^A-Za-z0-9_]/-/g
|
||||
p
|
||||
}
|
||||
'
|
||||
package=$(sed -n "$extract_package_name" configure.ac) \
|
||||
|| die 'cannot find package name in configure.ac'
|
||||
gnulib_name=lib$package
|
||||
|
||||
build_aux=build-aux
|
||||
source_base=lib
|
||||
m4_base=m4
|
||||
doc_base=doc
|
||||
tests_base=tests
|
||||
gnulib_extra_files=''
|
||||
|
||||
# Additional gnulib-tool options to use. Use "\newline" to break lines.
|
||||
gnulib_tool_option_extras=
|
||||
|
||||
# Other locale categories that need message catalogs.
|
||||
EXTRA_LOCALE_CATEGORIES=
|
||||
|
||||
# Additional xgettext options to use. Use "\\\newline" to break lines.
|
||||
XGETTEXT_OPTIONS='\\\
|
||||
--flag=_:1:pass-c-format\\\
|
||||
--flag=N_:1:pass-c-format\\\
|
||||
--flag=error:3:c-format --flag=error_at_line:5:c-format\\\
|
||||
'
|
||||
|
||||
# Package bug report address and copyright holder for gettext files
|
||||
COPYRIGHT_HOLDER='Free Software Foundation, Inc.'
|
||||
MSGID_BUGS_ADDRESS=bug-$package@gnu.org
|
||||
|
||||
# Files we don't want to import.
|
||||
excluded_files=
|
||||
|
||||
# File that should exist in the top directory of a checked out hierarchy,
|
||||
# but not in a distribution tarball.
|
||||
checkout_only_file=README-hacking
|
||||
|
||||
# Whether to use copies instead of symlinks.
|
||||
copy=false
|
||||
|
||||
# Set this to '.cvsignore .gitignore' in bootstrap.conf if you want
|
||||
# those files to be generated in directories like lib/, m4/, and po/.
|
||||
# Or set it to 'auto' to make this script select which to use based
|
||||
# on which version control system (if any) is used in the source directory.
|
||||
vc_ignore=auto
|
||||
|
||||
# Set this to true in bootstrap.conf to enable --bootstrap-sync by
|
||||
# default.
|
||||
bootstrap_sync=false
|
||||
|
||||
# Use git to update gnulib sources
|
||||
use_git=true
|
||||
|
||||
# find_tool ENVVAR NAMES...
|
||||
# -------------------------
|
||||
# Search for a required program. Use the value of ENVVAR, if set,
|
||||
# otherwise find the first of the NAMES that can be run (i.e.,
|
||||
# supports --version). If found, set ENVVAR to the program name,
|
||||
# die otherwise.
|
||||
#
|
||||
# FIXME: code duplication, see also gnu-web-doc-update.
|
||||
find_tool ()
|
||||
{
|
||||
find_tool_envvar=$1
|
||||
shift
|
||||
find_tool_names=$@
|
||||
eval "find_tool_res=\$$find_tool_envvar"
|
||||
if test x"$find_tool_res" = x; then
|
||||
for i
|
||||
do
|
||||
if ($i --version </dev/null) >/dev/null 2>&1; then
|
||||
find_tool_res=$i
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
find_tool_error_prefix="\$$find_tool_envvar: "
|
||||
fi
|
||||
test x"$find_tool_res" != x \
|
||||
|| die "one of these is required: $find_tool_names"
|
||||
($find_tool_res --version </dev/null) >/dev/null 2>&1 \
|
||||
|| die "${find_tool_error_prefix}cannot run $find_tool_res --version"
|
||||
eval "$find_tool_envvar=\$find_tool_res"
|
||||
eval "export $find_tool_envvar"
|
||||
}
|
||||
|
||||
# Find sha1sum, named gsha1sum on MacPorts, and shasum on Mac OS X 10.6.
|
||||
find_tool SHA1SUM sha1sum gsha1sum shasum
|
||||
|
||||
# Override the default configuration, if necessary.
|
||||
# Make sure that bootstrap.conf is sourced from the current directory
|
||||
# if we were invoked as "sh bootstrap".
|
||||
case "$0" in
|
||||
*/*) test -r "$0.conf" && . "$0.conf" ;;
|
||||
*) test -r "$0.conf" && . ./"$0.conf" ;;
|
||||
esac
|
||||
|
||||
# Extra files from gnulib, which override files from other sources.
|
||||
test -z "${gnulib_extra_files}" && \
|
||||
gnulib_extra_files="
|
||||
$build_aux/install-sh
|
||||
$build_aux/mdate-sh
|
||||
$build_aux/texinfo.tex
|
||||
$build_aux/depcomp
|
||||
$build_aux/config.guess
|
||||
$build_aux/config.sub
|
||||
doc/INSTALL
|
||||
"
|
||||
|
||||
if test "$vc_ignore" = auto; then
|
||||
vc_ignore=
|
||||
test -d .git && vc_ignore=.gitignore
|
||||
test -d CVS && vc_ignore="$vc_ignore .cvsignore"
|
||||
fi
|
||||
|
||||
# Translate configuration into internal form.
|
||||
|
||||
# Parse options.
|
||||
|
||||
for option
|
||||
do
|
||||
case $option in
|
||||
--help)
|
||||
usage
|
||||
exit;;
|
||||
--gnulib-srcdir=*)
|
||||
GNULIB_SRCDIR=${option#--gnulib-srcdir=};;
|
||||
--skip-po)
|
||||
SKIP_PO=t;;
|
||||
--force)
|
||||
checkout_only_file=;;
|
||||
--copy)
|
||||
copy=true;;
|
||||
--bootstrap-sync)
|
||||
bootstrap_sync=true;;
|
||||
--no-bootstrap-sync)
|
||||
bootstrap_sync=false;;
|
||||
--no-git)
|
||||
use_git=false;;
|
||||
*)
|
||||
die "$option: unknown option";;
|
||||
esac
|
||||
done
|
||||
|
||||
$use_git || test -d "$GNULIB_SRCDIR" \
|
||||
|| die "Error: --no-git requires --gnulib-srcdir"
|
||||
|
||||
if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
|
||||
die "Bootstrapping from a non-checked-out distribution is risky."
|
||||
fi
|
||||
|
||||
# Ensure that lines starting with ! sort last, per gitignore conventions
|
||||
# for whitelisting exceptions after a more generic blacklist pattern.
|
||||
sort_patterns() {
|
||||
sort -u "$@" | sed '/^!/ {
|
||||
H
|
||||
d
|
||||
}
|
||||
$ {
|
||||
P
|
||||
x
|
||||
s/^\n//
|
||||
}' | sed '/^$/d'
|
||||
}
|
||||
|
||||
# If $STR is not already on a line by itself in $FILE, insert it,
|
||||
# sorting the new contents of the file and replacing $FILE with the result.
|
||||
insert_sorted_if_absent() {
|
||||
file=$1
|
||||
str=$2
|
||||
test -f $file || touch $file
|
||||
echo "$str" | sort_patterns - $file | cmp -s - $file > /dev/null \
|
||||
|| { echo "$str" | sort_patterns - $file > $file.bak \
|
||||
&& mv $file.bak $file; } \
|
||||
|| die "insert_sorted_if_absent $file $str: failed"
|
||||
}
|
||||
|
||||
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
|
||||
# insert_sorted_if_absent.
|
||||
insert_vc_ignore() {
|
||||
vc_ignore_file="$1"
|
||||
pattern="$2"
|
||||
case $vc_ignore_file in
|
||||
*.gitignore)
|
||||
# A .gitignore entry that does not start with '/' applies
|
||||
# recursively to subdirectories, so prepend '/' to every
|
||||
# .gitignore entry.
|
||||
pattern=$(echo "$pattern" | sed s,^,/,);;
|
||||
esac
|
||||
insert_sorted_if_absent "$vc_ignore_file" "$pattern"
|
||||
}
|
||||
|
||||
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
|
||||
found_aux_dir=no
|
||||
grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \
|
||||
>/dev/null && found_aux_dir=yes
|
||||
grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
|
||||
>/dev/null && found_aux_dir=yes
|
||||
test $found_aux_dir = yes \
|
||||
|| die "configure.ac lacks 'AC_CONFIG_AUX_DIR([$build_aux])'; add it"
|
||||
|
||||
# If $build_aux doesn't exist, create it now, otherwise some bits
|
||||
# below will malfunction. If creating it, also mark it as ignored.
|
||||
if test ! -d $build_aux; then
|
||||
mkdir $build_aux
|
||||
for dot_ig in x $vc_ignore; do
|
||||
test $dot_ig = x && continue
|
||||
insert_vc_ignore $dot_ig $build_aux
|
||||
done
|
||||
fi
|
||||
|
||||
# Note this deviates from the version comparison in automake
|
||||
# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
|
||||
# but this should suffice as we won't be specifying old
|
||||
# version formats or redundant trailing .0 in bootstrap.conf.
|
||||
# If we did want full compatibility then we should probably
|
||||
# use m4_version_compare from autoconf.
|
||||
sort_ver() { # sort -V is not generally available
|
||||
ver1="$1"
|
||||
ver2="$2"
|
||||
|
||||
# split on '.' and compare each component
|
||||
i=1
|
||||
while : ; do
|
||||
p1=$(echo "$ver1" | cut -d. -f$i)
|
||||
p2=$(echo "$ver2" | cut -d. -f$i)
|
||||
if [ ! "$p1" ]; then
|
||||
echo "$1 $2"
|
||||
break
|
||||
elif [ ! "$p2" ]; then
|
||||
echo "$2 $1"
|
||||
break
|
||||
elif [ ! "$p1" = "$p2" ]; then
|
||||
if [ "$p1" -gt "$p2" ] 2>/dev/null; then # numeric comparison
|
||||
echo "$2 $1"
|
||||
elif [ "$p2" -gt "$p1" ] 2>/dev/null; then # numeric comparison
|
||||
echo "$1 $2"
|
||||
else # numeric, then lexicographic comparison
|
||||
lp=$(printf "$p1\n$p2\n" | LANG=C sort -n | tail -n1)
|
||||
if [ "$lp" = "$p2" ]; then
|
||||
echo "$1 $2"
|
||||
else
|
||||
echo "$2 $1"
|
||||
fi
|
||||
fi
|
||||
break
|
||||
fi
|
||||
i=$(($i+1))
|
||||
done
|
||||
}
|
||||
|
||||
get_version() {
|
||||
app=$1
|
||||
|
||||
$app --version >/dev/null 2>&1 || return 1
|
||||
|
||||
$app --version 2>&1 |
|
||||
sed -n '# Move version to start of line.
|
||||
s/.*[v ]\([0-9]\)/\1/
|
||||
|
||||
# Skip lines that do not start with version.
|
||||
/^[0-9]/!d
|
||||
|
||||
# Remove characters after the version.
|
||||
s/[^.a-z0-9-].*//
|
||||
|
||||
# The first component must be digits only.
|
||||
s/^\([0-9]*\)[a-z-].*/\1/
|
||||
|
||||
#the following essentially does s/5.005/5.5/
|
||||
s/\.0*\([1-9]\)/.\1/g
|
||||
p
|
||||
q'
|
||||
}
|
||||
|
||||
check_versions() {
|
||||
ret=0
|
||||
|
||||
while read app req_ver; do
|
||||
# We only need libtoolize from the libtool package.
|
||||
if test "$app" = libtool; then
|
||||
app=libtoolize
|
||||
fi
|
||||
# Exempt git if --no-git is in effect.
|
||||
if test "$app" = git; then
|
||||
$use_git || continue
|
||||
fi
|
||||
# Honor $APP variables ($TAR, $AUTOCONF, etc.)
|
||||
appvar=$(echo $app | LC_ALL=C tr '[a-z]-' '[A-Z]_')
|
||||
test "$appvar" = TAR && appvar=AMTAR
|
||||
case $appvar in
|
||||
GZIP) ;; # Do not use $GZIP: it contains gzip options.
|
||||
*) eval "app=\${$appvar-$app}" ;;
|
||||
esac
|
||||
|
||||
# Handle the still-experimental Automake-NG programs specially.
|
||||
# They remain named as the mainstream Automake programs ("automake",
|
||||
# and "aclocal") to avoid gratuitous incompatibilities with
|
||||
# pre-existing usages (by, say, autoreconf, or custom autogen.sh
|
||||
# scripts), but correctly identify themselves (as being part of
|
||||
# "GNU automake-ng") when asked their version.
|
||||
case $app in
|
||||
automake-ng|aclocal-ng)
|
||||
app=${app%-ng}
|
||||
($app --version | grep '(GNU automake-ng)') >/dev/null 2>&1 || {
|
||||
warn_ "Error: '$app' not found or not from Automake-NG"
|
||||
ret=1
|
||||
continue
|
||||
} ;;
|
||||
esac
|
||||
if [ "$req_ver" = "-" ]; then
|
||||
# Merely require app to exist; not all prereq apps are well-behaved
|
||||
# so we have to rely on $? rather than get_version.
|
||||
$app --version >/dev/null 2>&1
|
||||
if [ 126 -le $? ]; then
|
||||
warn_ "Error: '$app' not found"
|
||||
ret=1
|
||||
fi
|
||||
else
|
||||
# Require app to produce a new enough version string.
|
||||
inst_ver=$(get_version $app)
|
||||
if [ ! "$inst_ver" ]; then
|
||||
warn_ "Error: '$app' not found"
|
||||
ret=1
|
||||
else
|
||||
latest_ver=$(sort_ver $req_ver $inst_ver | cut -d' ' -f2)
|
||||
if [ ! "$latest_ver" = "$inst_ver" ]; then
|
||||
warnf_ '%s\n' \
|
||||
"Error: '$app' version == $inst_ver is too old" \
|
||||
" '$app' version >= $req_ver is required"
|
||||
ret=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
return $ret
|
||||
}
|
||||
|
||||
print_versions() {
|
||||
echo "Program Min_version"
|
||||
echo "----------------------"
|
||||
printf %s "$buildreq"
|
||||
echo "----------------------"
|
||||
# can't depend on column -t
|
||||
}
|
||||
|
||||
use_libtool=0
|
||||
# We'd like to use grep -E, to see if any of LT_INIT,
|
||||
# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
|
||||
# but that's not portable enough (e.g., for Solaris).
|
||||
grep '^[ ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \
|
||||
&& use_libtool=1
|
||||
grep '^[ ]*LT_INIT' configure.ac >/dev/null \
|
||||
&& use_libtool=1
|
||||
if test $use_libtool = 1; then
|
||||
find_tool LIBTOOLIZE glibtoolize libtoolize
|
||||
fi
|
||||
|
||||
# gnulib-tool requires at least automake and autoconf.
|
||||
# If either is not listed, add it (with minimum version) as a prerequisite.
|
||||
case $buildreq in
|
||||
*automake*) ;;
|
||||
*) buildreq="automake 1.9
|
||||
$buildreq" ;;
|
||||
esac
|
||||
case $buildreq in
|
||||
*autoconf*) ;;
|
||||
*) buildreq="autoconf 2.59
|
||||
$buildreq" ;;
|
||||
esac
|
||||
|
||||
# When we can deduce that gnulib-tool will require patch,
|
||||
# and when patch is not already listed as a prerequisite, add it, too.
|
||||
if test -d "$local_gl_dir" \
|
||||
&& ! find "$local_gl_dir" -name '*.diff' -exec false {} +; then
|
||||
case $buildreq in
|
||||
*patch*) ;;
|
||||
*) buildreq="patch -
|
||||
$buildreq" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if ! printf "$buildreq" | check_versions; then
|
||||
echo >&2
|
||||
if test -f README-prereq; then
|
||||
die "See README-prereq for how to get the prerequisite programs"
|
||||
else
|
||||
die "Please install the prerequisite programs"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$0: Bootstrapping from checked-out $package sources..."
|
||||
|
||||
# See if we can use gnulib's git-merge-changelog merge driver.
|
||||
if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
|
||||
if git config merge.merge-changelog.driver >/dev/null ; then
|
||||
:
|
||||
elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
|
||||
echo "$0: initializing git-merge-changelog driver"
|
||||
git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
|
||||
git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
|
||||
else
|
||||
echo "$0: consider installing git-merge-changelog from gnulib"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
cleanup_gnulib() {
|
||||
status=$?
|
||||
rm -fr "$gnulib_path"
|
||||
exit $status
|
||||
}
|
||||
|
||||
git_modules_config () {
|
||||
test -f .gitmodules && git config --file .gitmodules "$@"
|
||||
}
|
||||
|
||||
gnulib_path=$(git_modules_config submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
|
||||
# Get gnulib files.
|
||||
|
||||
case ${GNULIB_SRCDIR--} in
|
||||
-)
|
||||
if git_modules_config submodule.gnulib.url >/dev/null; then
|
||||
echo "$0: getting gnulib files..."
|
||||
git submodule init || exit $?
|
||||
git submodule update || exit $?
|
||||
|
||||
elif [ ! -d "$gnulib_path" ]; then
|
||||
echo "$0: getting gnulib files..."
|
||||
|
||||
trap cleanup_gnulib 1 2 13 15
|
||||
|
||||
shallow=
|
||||
git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2'
|
||||
git clone $shallow git://git.sv.gnu.org/gnulib "$gnulib_path" ||
|
||||
cleanup_gnulib
|
||||
|
||||
trap - 1 2 13 15
|
||||
fi
|
||||
GNULIB_SRCDIR=$gnulib_path
|
||||
;;
|
||||
*)
|
||||
# Use GNULIB_SRCDIR as a reference.
|
||||
if test -d "$GNULIB_SRCDIR"/.git && \
|
||||
git_modules_config submodule.gnulib.url >/dev/null; then
|
||||
echo "$0: getting gnulib files..."
|
||||
if git submodule -h|grep -- --reference > /dev/null; then
|
||||
# Prefer the one-liner available in git 1.6.4 or newer.
|
||||
git submodule update --init --reference "$GNULIB_SRCDIR" \
|
||||
"$gnulib_path" || exit $?
|
||||
else
|
||||
# This fallback allows at least git 1.5.5.
|
||||
if test -f "$gnulib_path"/gnulib-tool; then
|
||||
# Since file already exists, assume submodule init already complete.
|
||||
git submodule update || exit $?
|
||||
else
|
||||
# Older git can't clone into an empty directory.
|
||||
rmdir "$gnulib_path" 2>/dev/null
|
||||
git clone --reference "$GNULIB_SRCDIR" \
|
||||
"$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \
|
||||
&& git submodule init && git submodule update \
|
||||
|| exit $?
|
||||
fi
|
||||
fi
|
||||
GNULIB_SRCDIR=$gnulib_path
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if $bootstrap_sync; then
|
||||
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
|
||||
echo "$0: updating bootstrap and restarting..."
|
||||
exec sh -c \
|
||||
'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
|
||||
-- "$GNULIB_SRCDIR/build-aux/bootstrap" \
|
||||
"$0" "$@" --no-bootstrap-sync
|
||||
}
|
||||
fi
|
||||
|
||||
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
|
||||
<$gnulib_tool || exit $?
|
||||
|
||||
# Get translations.
|
||||
|
||||
download_po_files() {
|
||||
subdir=$1
|
||||
domain=$2
|
||||
echo "$me: getting translations into $subdir for $domain..."
|
||||
cmd=$(printf "$po_download_command_format" "$domain" "$subdir")
|
||||
eval "$cmd" && return
|
||||
# Fallback to HTTP.
|
||||
cmd=$(printf "$po_download_command_format2" "$subdir" "$domain")
|
||||
eval "$cmd"
|
||||
}
|
||||
|
||||
# Mirror .po files to $po_dir/.reference and copy only the new
|
||||
# or modified ones into $po_dir. Also update $po_dir/LINGUAS.
|
||||
# Note po files that exist locally only are left in $po_dir but will
|
||||
# not be included in LINGUAS and hence will not be distributed.
|
||||
update_po_files() {
|
||||
# Directory containing primary .po files.
|
||||
# Overwrite them only when we're sure a .po file is new.
|
||||
po_dir=$1
|
||||
domain=$2
|
||||
|
||||
# Mirror *.po files into this dir.
|
||||
# Usually contains *.s1 checksum files.
|
||||
ref_po_dir="$po_dir/.reference"
|
||||
|
||||
test -d $ref_po_dir || mkdir $ref_po_dir || return
|
||||
download_po_files $ref_po_dir $domain \
|
||||
&& ls "$ref_po_dir"/*.po 2>/dev/null |
|
||||
sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
|
||||
|
||||
langs=$(cd $ref_po_dir && echo *.po | sed 's/\.po//g')
|
||||
test "$langs" = '*' && langs=x
|
||||
for po in $langs; do
|
||||
case $po in x) continue;; esac
|
||||
new_po="$ref_po_dir/$po.po"
|
||||
cksum_file="$ref_po_dir/$po.s1"
|
||||
if ! test -f "$cksum_file" ||
|
||||
! test -f "$po_dir/$po.po" ||
|
||||
! $SHA1SUM -c --status "$cksum_file" \
|
||||
< "$new_po" > /dev/null; then
|
||||
echo "$me: updated $po_dir/$po.po..."
|
||||
cp "$new_po" "$po_dir/$po.po" \
|
||||
&& $SHA1SUM < "$new_po" > "$cksum_file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
case $SKIP_PO in
|
||||
'')
|
||||
if test -d po; then
|
||||
update_po_files po $package || exit
|
||||
fi
|
||||
|
||||
if test -d runtime-po; then
|
||||
update_po_files runtime-po $package-runtime || exit
|
||||
fi;;
|
||||
esac
|
||||
|
||||
symlink_to_dir()
|
||||
{
|
||||
src=$1/$2
|
||||
dst=${3-$2}
|
||||
|
||||
test -f "$src" && {
|
||||
|
||||
# If the destination directory doesn't exist, create it.
|
||||
# This is required at least for "lib/uniwidth/cjk.h".
|
||||
dst_dir=$(dirname "$dst")
|
||||
if ! test -d "$dst_dir"; then
|
||||
mkdir -p "$dst_dir"
|
||||
|
||||
# If we've just created a directory like lib/uniwidth,
|
||||
# tell version control system(s) it's ignorable.
|
||||
# FIXME: for now, this does only one level
|
||||
parent=$(dirname "$dst_dir")
|
||||
for dot_ig in x $vc_ignore; do
|
||||
test $dot_ig = x && continue
|
||||
ig=$parent/$dot_ig
|
||||
insert_vc_ignore $ig "${dst_dir##*/}"
|
||||
done
|
||||
fi
|
||||
|
||||
if $copy; then
|
||||
{
|
||||
test ! -h "$dst" || {
|
||||
echo "$me: rm -f $dst" &&
|
||||
rm -f "$dst"
|
||||
}
|
||||
} &&
|
||||
test -f "$dst" &&
|
||||
cmp -s "$src" "$dst" || {
|
||||
echo "$me: cp -fp $src $dst" &&
|
||||
cp -fp "$src" "$dst"
|
||||
}
|
||||
else
|
||||
# Leave any existing symlink alone, if it already points to the source,
|
||||
# so that broken build tools that care about symlink times
|
||||
# aren't confused into doing unnecessary builds. Conversely, if the
|
||||
# existing symlink's time stamp is older than the source, make it afresh,
|
||||
# so that broken tools aren't confused into skipping needed builds. See
|
||||
# <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00326.html>.
|
||||
test -h "$dst" &&
|
||||
src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 &&
|
||||
dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 &&
|
||||
test "$src_i" = "$dst_i" &&
|
||||
both_ls=$(ls -dt "$src" "$dst") &&
|
||||
test "X$both_ls" = "X$dst$nl$src" || {
|
||||
dot_dots=
|
||||
case $src in
|
||||
/*) ;;
|
||||
*)
|
||||
case /$dst/ in
|
||||
*//* | */../* | */./* | /*/*/*/*/*/)
|
||||
die "invalid symlink calculation: $src -> $dst";;
|
||||
/*/*/*/*/) dot_dots=../../../;;
|
||||
/*/*/*/) dot_dots=../../;;
|
||||
/*/*/) dot_dots=../;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
echo "$me: ln -fs $dot_dots$src $dst" &&
|
||||
ln -fs "$dot_dots$src" "$dst"
|
||||
}
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
version_controlled_file() {
|
||||
parent=$1
|
||||
file=$2
|
||||
if test -d .git; then
|
||||
git rm -n "$file" > /dev/null 2>&1
|
||||
elif test -d .svn; then
|
||||
svn log -r HEAD "$file" > /dev/null 2>&1
|
||||
elif test -d CVS; then
|
||||
grep -F "/${file##*/}/" "$parent/CVS/Entries" 2>/dev/null |
|
||||
grep '^/[^/]*/[0-9]' > /dev/null
|
||||
else
|
||||
warn_ "no version control for $file?"
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
# NOTE: we have to be careful to run both autopoint and libtoolize
|
||||
# before gnulib-tool, since gnulib-tool is likely to provide newer
|
||||
# versions of files "installed" by these two programs.
|
||||
# Then, *after* gnulib-tool (see below), we have to be careful to
|
||||
# run autoreconf in such a way that it does not run either of these
|
||||
# two just-pre-run programs.
|
||||
|
||||
# Import from gettext.
|
||||
with_gettext=yes
|
||||
grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
|
||||
with_gettext=no
|
||||
|
||||
if test $with_gettext = yes || test $use_libtool = 1; then
|
||||
|
||||
tempbase=.bootstrap$$
|
||||
trap "rm -f $tempbase.0 $tempbase.1" 1 2 13 15
|
||||
|
||||
> $tempbase.0 > $tempbase.1 &&
|
||||
find . ! -type d -print | sort > $tempbase.0 || exit
|
||||
|
||||
if test $with_gettext = yes; then
|
||||
# Released autopoint has the tendency to install macros that have been
|
||||
# obsoleted in current gnulib, so run this before gnulib-tool.
|
||||
echo "$0: $AUTOPOINT --force"
|
||||
$AUTOPOINT --force || exit
|
||||
fi
|
||||
|
||||
# Autoreconf runs aclocal before libtoolize, which causes spurious
|
||||
# warnings if the initial aclocal is confused by the libtoolized
|
||||
# (or worse out-of-date) macro directory.
|
||||
# libtoolize 1.9b added the --install option; but we support back
|
||||
# to libtoolize 1.5.22, where the install action was default.
|
||||
if test $use_libtool = 1; then
|
||||
install=
|
||||
case $($LIBTOOLIZE --help) in
|
||||
*--install*) install=--install ;;
|
||||
esac
|
||||
echo "running: $LIBTOOLIZE $install --copy"
|
||||
$LIBTOOLIZE $install --copy
|
||||
fi
|
||||
|
||||
find . ! -type d -print | sort >$tempbase.1
|
||||
old_IFS=$IFS
|
||||
IFS=$nl
|
||||
for file in $(comm -13 $tempbase.0 $tempbase.1); do
|
||||
IFS=$old_IFS
|
||||
parent=${file%/*}
|
||||
version_controlled_file "$parent" "$file" || {
|
||||
for dot_ig in x $vc_ignore; do
|
||||
test $dot_ig = x && continue
|
||||
ig=$parent/$dot_ig
|
||||
insert_vc_ignore "$ig" "${file##*/}"
|
||||
done
|
||||
}
|
||||
done
|
||||
IFS=$old_IFS
|
||||
|
||||
rm -f $tempbase.0 $tempbase.1
|
||||
trap - 1 2 13 15
|
||||
fi
|
||||
|
||||
# Import from gnulib.
|
||||
|
||||
gnulib_tool_options="\
|
||||
--import\
|
||||
--no-changelog\
|
||||
--aux-dir $build_aux\
|
||||
--doc-base $doc_base\
|
||||
--lib $gnulib_name\
|
||||
--m4-base $m4_base/\
|
||||
--source-base $source_base/\
|
||||
--tests-base $tests_base\
|
||||
--local-dir $local_gl_dir\
|
||||
$gnulib_tool_option_extras\
|
||||
"
|
||||
if test $use_libtool = 1; then
|
||||
case "$gnulib_tool_options " in
|
||||
*' --libtool '*) ;;
|
||||
*) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
|
||||
esac
|
||||
fi
|
||||
echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
|
||||
$gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
|
||||
|
||||
for file in $gnulib_files; do
|
||||
symlink_to_dir "$GNULIB_SRCDIR" $file \
|
||||
|| die "failed to symlink $file"
|
||||
done
|
||||
|
||||
bootstrap_post_import_hook \
|
||||
|| die "bootstrap_post_import_hook failed"
|
||||
|
||||
# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
|
||||
# gnulib-populated directories. Such .m4 files would cause aclocal to fail.
|
||||
# The following requires GNU find 4.2.3 or newer. Considering the usual
|
||||
# portability constraints of this script, that may seem a very demanding
|
||||
# requirement, but it should be ok. Ignore any failure, which is fine,
|
||||
# since this is only a convenience to help developers avoid the relatively
|
||||
# unusual case in which a symlinked-to .m4 file is git-removed from gnulib
|
||||
# between successive runs of this script.
|
||||
find "$m4_base" "$source_base" \
|
||||
-depth \( -name '*.m4' -o -name '*.[ch]' \) \
|
||||
-type l -xtype l -delete > /dev/null 2>&1
|
||||
|
||||
# Some systems (RHEL 5) are using ancient autotools, for which the
|
||||
# --no-recursive option had not been invented. Detect that lack and
|
||||
# omit the option when it's not supported. FIXME in 2017: remove this
|
||||
# hack when RHEL 5 autotools are updated, or when they become irrelevant.
|
||||
no_recursive=
|
||||
case $($AUTORECONF --help) in
|
||||
*--no-recursive*) no_recursive=--no-recursive;;
|
||||
esac
|
||||
|
||||
# Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
|
||||
echo "running: AUTOPOINT=true LIBTOOLIZE=true " \
|
||||
"$AUTORECONF --verbose --install $no_recursive -I $m4_base $ACLOCAL_FLAGS"
|
||||
AUTOPOINT=true LIBTOOLIZE=true \
|
||||
$AUTORECONF --verbose --install $no_recursive -I $m4_base $ACLOCAL_FLAGS \
|
||||
|| die "autoreconf failed"
|
||||
|
||||
# Get some extra files from gnulib, overriding existing files.
|
||||
for file in $gnulib_extra_files; do
|
||||
case $file in
|
||||
*/INSTALL) dst=INSTALL;;
|
||||
build-aux/*) dst=$build_aux/${file#build-aux/};;
|
||||
*) dst=$file;;
|
||||
esac
|
||||
symlink_to_dir "$GNULIB_SRCDIR" $file $dst \
|
||||
|| die "failed to symlink $file"
|
||||
done
|
||||
|
||||
if test $with_gettext = yes; then
|
||||
# Create gettext configuration.
|
||||
echo "$0: Creating po/Makevars from po/Makevars.template ..."
|
||||
rm -f po/Makevars
|
||||
sed '
|
||||
/^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
|
||||
/^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/
|
||||
/^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'|
|
||||
/^XGETTEXT_OPTIONS *=/{
|
||||
s/$/ \\/
|
||||
a\
|
||||
'"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
|
||||
}
|
||||
' po/Makevars.template >po/Makevars \
|
||||
|| die 'cannot generate po/Makevars'
|
||||
|
||||
# If the 'gettext' module is in use, grab the latest Makefile.in.in.
|
||||
# If only the 'gettext-h' module is in use, assume autopoint already
|
||||
# put the correct version of this file into place.
|
||||
case $gnulib_modules in
|
||||
*gettext-h*) ;;
|
||||
*gettext*)
|
||||
cp $GNULIB_SRCDIR/build-aux/po/Makefile.in.in po/Makefile.in.in \
|
||||
|| die "cannot create po/Makefile.in.in"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -d runtime-po; then
|
||||
# Similarly for runtime-po/Makevars, but not quite the same.
|
||||
rm -f runtime-po/Makevars
|
||||
sed '
|
||||
/^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
|
||||
/^subdir *=.*/s/=.*/= runtime-po/
|
||||
/^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
|
||||
/^XGETTEXT_OPTIONS *=/{
|
||||
s/$/ \\/
|
||||
a\
|
||||
'"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
|
||||
}
|
||||
' po/Makevars.template >runtime-po/Makevars \
|
||||
|| die 'cannot generate runtime-po/Makevars'
|
||||
|
||||
# Copy identical files from po to runtime-po.
|
||||
(cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
|
||||
fi
|
||||
fi
|
||||
|
||||
bootstrap_epilogue
|
||||
|
||||
echo "$0: done. Now you can run './configure'."
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
241
bootstrap.conf
241
bootstrap.conf
@ -1,241 +0,0 @@
|
||||
# Bootstrap configuration.
|
||||
|
||||
# Copyright (C) 2010-2012 Red Hat, Inc.
|
||||
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
# gnulib modules used by this package.
|
||||
gnulib_modules='
|
||||
accept
|
||||
areadlink
|
||||
base64
|
||||
bind
|
||||
bitrotate
|
||||
byteswap
|
||||
c-ctype
|
||||
c-strcase
|
||||
c-strcasestr
|
||||
calloc-posix
|
||||
canonicalize-lgpl
|
||||
chown
|
||||
close
|
||||
connect
|
||||
configmake
|
||||
count-one-bits
|
||||
crypto/md5
|
||||
dirname-lgpl
|
||||
environ
|
||||
fclose
|
||||
fcntl
|
||||
fcntl-h
|
||||
fdatasync
|
||||
ffs
|
||||
fnmatch
|
||||
fsync
|
||||
func
|
||||
getaddrinfo
|
||||
getcwd-lgpl
|
||||
gethostname
|
||||
getpass
|
||||
getpeername
|
||||
getsockname
|
||||
gettext-h
|
||||
gettimeofday
|
||||
gitlog-to-changelog
|
||||
gnumakefile
|
||||
ignore-value
|
||||
inet_pton
|
||||
intprops
|
||||
ioctl
|
||||
isatty
|
||||
largefile
|
||||
listen
|
||||
maintainer-makefile
|
||||
manywarnings
|
||||
mkstemp
|
||||
mkstemps
|
||||
mktempd
|
||||
netdb
|
||||
nonblocking
|
||||
openpty
|
||||
passfd
|
||||
perror
|
||||
physmem
|
||||
pipe-posix
|
||||
pipe2
|
||||
poll
|
||||
posix-shell
|
||||
pthread
|
||||
pthread_sigmask
|
||||
recv
|
||||
regex
|
||||
random_r
|
||||
sched
|
||||
send
|
||||
setsockopt
|
||||
sigaction
|
||||
sigpipe
|
||||
snprintf
|
||||
socket
|
||||
stdarg
|
||||
stpcpy
|
||||
strchrnul
|
||||
strdup-posix
|
||||
strndup
|
||||
strerror
|
||||
strerror_r-posix
|
||||
strptime
|
||||
strsep
|
||||
strtok_r
|
||||
sys_stat
|
||||
sys_wait
|
||||
termios
|
||||
time_r
|
||||
timegm
|
||||
ttyname_r
|
||||
uname
|
||||
useless-if-before-free
|
||||
usleep
|
||||
vasprintf
|
||||
verify
|
||||
vc-list-files
|
||||
vsnprintf
|
||||
waitpid
|
||||
warnings
|
||||
'
|
||||
|
||||
# Additional xgettext options to use. Use "\\\newline" to break lines.
|
||||
XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
|
||||
--flag=virAsprintf:2:c-format\\\
|
||||
--from-code=UTF-8\\\
|
||||
'
|
||||
|
||||
# This is not a GNU package, so the default bug address is invalid,
|
||||
# and the translation project is not in use.
|
||||
MSGID_BUGS_ADDRESS=libvir-list@redhat.com
|
||||
COPYRIGHT_HOLDER='Red Hat, Inc.'
|
||||
SKIP_PO=true
|
||||
|
||||
# Enable copy-mode for MSYS/MinGW. MSYS' ln doesn't work well in the way
|
||||
# bootstrap uses it with relative paths.
|
||||
if test -n "$MSYSTEM"; then
|
||||
copy=true
|
||||
fi
|
||||
|
||||
# If "AM_GNU_GETTEXT(external" or "AM_GNU_GETTEXT([external]"
|
||||
# appears in configure.ac, exclude some unnecessary files.
|
||||
# Without grep's -E option (not portable enough, pre-configure),
|
||||
# the following test is ugly. Also, this depends on the existence
|
||||
# of configure.ac, not the obsolescent-named configure.in. But if
|
||||
# you're using this infrastructure, you should care about such things.
|
||||
|
||||
gettext_external=0
|
||||
grep '^[ ]*AM_GNU_GETTEXT(external\>' configure.ac > /dev/null &&
|
||||
gettext_external=1
|
||||
grep '^[ ]*AM_GNU_GETTEXT(\[external\]' configure.ac > /dev/null &&
|
||||
gettext_external=1
|
||||
|
||||
if test $gettext_external = 1; then
|
||||
# Gettext supplies these files, but we don't need them since
|
||||
# we don't have an intl subdirectory.
|
||||
excluded_files='
|
||||
m4/glibc2.m4
|
||||
m4/intdiv0.m4
|
||||
m4/lcmessage.m4
|
||||
m4/uintmax_t.m4
|
||||
m4/ulonglong.m4
|
||||
m4/visibility.m4
|
||||
'
|
||||
fi
|
||||
|
||||
# Tell gnulib to:
|
||||
# require LGPLv2+
|
||||
# apply any local diffs in gnulib/local/ dir
|
||||
# put *.m4 files in new gnulib/m4/ dir
|
||||
# put *.[ch] files in new gnulib/lib/ dir
|
||||
# import gnulib tests in new gnulib/tests/ dir
|
||||
gnulib_name=libgnu
|
||||
m4_base=gnulib/m4
|
||||
source_base=gnulib/lib
|
||||
tests_base=gnulib/tests
|
||||
gnulib_tool_option_extras="\
|
||||
--lgpl=2\
|
||||
--with-tests\
|
||||
--makefile-name=gnulib.mk\
|
||||
--avoid=pt_chown\
|
||||
--avoid=lock-tests\
|
||||
"
|
||||
local_gl_dir=gnulib/local
|
||||
|
||||
# Convince bootstrap to use multiple m4 directories.
|
||||
: ${ACLOCAL=aclocal}
|
||||
ACLOCAL="$ACLOCAL -I m4"
|
||||
export ACLOCAL
|
||||
|
||||
# Build prerequisites
|
||||
# Note that some of these programs are only required for 'make dist' to
|
||||
# succeed from a fresh git checkout; not all of these programs are
|
||||
# required to run 'make dist' on a tarball. As a special case, we want
|
||||
# to require the equivalent of the Fedora python-devel package, but
|
||||
# RHEL 5 lacks the witness python-config package; we hack around that
|
||||
# old environment below.
|
||||
buildreq="\
|
||||
autoconf 2.59
|
||||
automake 1.9.6
|
||||
autopoint -
|
||||
gettext 0.17
|
||||
git 1.5.5
|
||||
gzip -
|
||||
libtool -
|
||||
patch -
|
||||
perl 5.5
|
||||
pkg-config -
|
||||
python-config -
|
||||
rpcgen -
|
||||
tar -
|
||||
xmllint -
|
||||
xsltproc -
|
||||
"
|
||||
# Use rpm as a fallback to bypass the bootstrap probe for python-config,
|
||||
# for the sake of RHEL 5; without requiring it on newer systems that
|
||||
# have python-config to begin with.
|
||||
if `(${PYTHON_CONFIG-python-config} --version;
|
||||
test $? -lt 126 || rpm -q python-devel) >/dev/null 2>&1`; then
|
||||
PYTHON_CONFIG=true
|
||||
fi
|
||||
|
||||
# Automake requires that ChangeLog exist.
|
||||
touch ChangeLog || exit 1
|
||||
|
||||
# Override bootstrap's list - we don't use mdate-sh or texinfo.tex.
|
||||
gnulib_extra_files="
|
||||
$build_aux/install-sh
|
||||
$build_aux/depcomp
|
||||
$build_aux/config.guess
|
||||
$build_aux/config.sub
|
||||
doc/INSTALL
|
||||
"
|
||||
|
||||
|
||||
bootstrap_epilogue()
|
||||
{
|
||||
# Change paths in gnulib/tests/gnulib.mk from "../../.." to "../..",
|
||||
# then ensure that gnulib/tests/Makefile.in is up-to-date.
|
||||
m=gnulib/tests/gnulib.mk
|
||||
sed 's,\.\./\.\./\.\.,../..,g' $m > $m-t
|
||||
mv -f $m-t $m
|
||||
${AUTOMAKE-automake} gnulib/tests/Makefile
|
||||
}
|
828
cfg.mk
828
cfg.mk
@ -1,828 +0,0 @@
|
||||
# Customize Makefile.maint. -*- makefile -*-
|
||||
# Copyright (C) 2008-2012 Red Hat, Inc.
|
||||
# Copyright (C) 2003-2008 Free Software Foundation, Inc.
|
||||
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Use alpha.gnu.org for alpha and beta releases.
|
||||
# Use ftp.gnu.org for major releases.
|
||||
gnu_ftp_host-alpha = alpha.gnu.org
|
||||
gnu_ftp_host-beta = alpha.gnu.org
|
||||
gnu_ftp_host-major = ftp.gnu.org
|
||||
gnu_rel_host = $(gnu_ftp_host-$(RELEASE_TYPE))
|
||||
|
||||
url_dir_list = \
|
||||
ftp://$(gnu_rel_host)/gnu/coreutils
|
||||
|
||||
# We use .gnulib, not gnulib.
|
||||
gnulib_dir = $(srcdir)/.gnulib
|
||||
|
||||
# List of additional files that we want to pick up in our POTFILES.in
|
||||
# This is all gnulib files, as well as generated files for RPC code.
|
||||
generated_files = \
|
||||
$(srcdir)/daemon/*_dispatch.h \
|
||||
$(srcdir)/src/remote/*_client_bodies.h \
|
||||
$(srcdir)/src/remote/*_protocol.[ch] \
|
||||
$(srcdir)/gnulib/lib/*.[ch]
|
||||
|
||||
# We haven't converted all scripts to using gnulib's init.sh yet.
|
||||
_test_script_regex = \<\(init\|test-lib\)\.sh\>
|
||||
|
||||
# Tests not to run as part of "make distcheck".
|
||||
local-checks-to-skip = \
|
||||
changelog-check \
|
||||
check-AUTHORS \
|
||||
makefile-check \
|
||||
makefile_path_separator_check \
|
||||
patch-check \
|
||||
sc_GPL_version \
|
||||
sc_always_defined_macros \
|
||||
sc_cast_of_alloca_return_value \
|
||||
sc_cross_check_PATH_usage_in_tests \
|
||||
sc_dd_max_sym_length \
|
||||
sc_error_exit_success \
|
||||
sc_file_system \
|
||||
sc_immutable_NEWS \
|
||||
sc_makefile_path_separator_check \
|
||||
sc_obsolete_symbols \
|
||||
sc_prohibit_S_IS_definition \
|
||||
sc_prohibit_atoi_atof \
|
||||
sc_prohibit_hash_without_use \
|
||||
sc_prohibit_jm_in_m4 \
|
||||
sc_prohibit_quote_without_use \
|
||||
sc_prohibit_quotearg_without_use \
|
||||
sc_prohibit_stat_st_blocks \
|
||||
sc_root_tests \
|
||||
sc_space_tab \
|
||||
sc_sun_os_names \
|
||||
sc_system_h_headers \
|
||||
sc_texinfo_acronym \
|
||||
sc_tight_scope \
|
||||
sc_two_space_separator_in_usage \
|
||||
sc_error_message_uppercase \
|
||||
sc_program_name \
|
||||
sc_require_test_exit_idiom \
|
||||
sc_makefile_check \
|
||||
sc_useless_cpp_parens
|
||||
|
||||
# Most developers don't run 'make distcheck'. We want the official
|
||||
# dist to be secure, but don't want to penalize other developers
|
||||
# using a distro that has not yet picked up the automake fix.
|
||||
# FIXME remove this ifeq (making the syntax check unconditional)
|
||||
# once fixed automake (1.11.6 or 1.12.2+) is more common.
|
||||
ifeq ($(filter dist%, $(MAKECMDGOALS)), )
|
||||
local-checks-to-skip += sc_vulnerable_makefile_CVE-2012-3386
|
||||
else
|
||||
distdir: sc_vulnerable_makefile_CVE-2012-3386
|
||||
endif
|
||||
|
||||
# Files that should never cause syntax check failures.
|
||||
VC_LIST_ALWAYS_EXCLUDE_REGEX = \
|
||||
(^(HACKING|docs/(news\.html\.in|.*\.patch))|\.po)$$
|
||||
|
||||
# Functions like free() that are no-ops on NULL arguments.
|
||||
useless_free_options = \
|
||||
--name=VIR_FREE \
|
||||
--name=qemuCapsFree \
|
||||
--name=qemuMigrationCookieFree \
|
||||
--name=qemuMigrationCookieGraphicsFree \
|
||||
--name=sexpr_free \
|
||||
--name=virBandwidthDefFree \
|
||||
--name=virBitmapFree \
|
||||
--name=virCPUDefFree \
|
||||
--name=virCapabilitiesFree \
|
||||
--name=virCapabilitiesFreeGuest \
|
||||
--name=virCapabilitiesFreeGuestDomain \
|
||||
--name=virCapabilitiesFreeGuestFeature \
|
||||
--name=virCapabilitiesFreeGuestMachine \
|
||||
--name=virCapabilitiesFreeHostNUMACell \
|
||||
--name=virCapabilitiesFreeMachines \
|
||||
--name=virCgroupFree \
|
||||
--name=virCommandFree \
|
||||
--name=virConfFreeList \
|
||||
--name=virConfFreeValue \
|
||||
--name=virDomainActualNetDefFree \
|
||||
--name=virDomainChrDefFree \
|
||||
--name=virDomainChrSourceDefFree \
|
||||
--name=virDomainControllerDefFree \
|
||||
--name=virDomainDefFree \
|
||||
--name=virDomainDeviceDefFree \
|
||||
--name=virDomainDiskDefFree \
|
||||
--name=virDomainEventCallbackListFree \
|
||||
--name=virDomainEventFree \
|
||||
--name=virDomainEventQueueFree \
|
||||
--name=virDomainEventStateFree \
|
||||
--name=virDomainFSDefFree \
|
||||
--name=virDomainGraphicsDefFree \
|
||||
--name=virDomainHostdevDefFree \
|
||||
--name=virDomainInputDefFree \
|
||||
--name=virDomainNetDefFree \
|
||||
--name=virDomainObjFree \
|
||||
--name=virDomainSmartcardDefFree \
|
||||
--name=virDomainSnapshotDefFree \
|
||||
--name=virDomainSnapshotObjFree \
|
||||
--name=virDomainSoundDefFree \
|
||||
--name=virDomainVideoDefFree \
|
||||
--name=virDomainWatchdogDefFree \
|
||||
--name=virFileDirectFdFree \
|
||||
--name=virHashFree \
|
||||
--name=virInterfaceDefFree \
|
||||
--name=virInterfaceIpDefFree \
|
||||
--name=virInterfaceObjFree \
|
||||
--name=virInterfaceProtocolDefFree \
|
||||
--name=virJSONValueFree \
|
||||
--name=virLastErrFreeData \
|
||||
--name=virNetMessageFree \
|
||||
--name=virNetClientFree \
|
||||
--name=virNetClientProgramFree \
|
||||
--name=virNetClientStreamFree \
|
||||
--name=virNetServerFree \
|
||||
--name=virNetServerClientFree \
|
||||
--name=virNetServerMDNSFree \
|
||||
--name=virNetServerMDNSEntryFree \
|
||||
--name=virNetServerMDNSGroupFree \
|
||||
--name=virNetServerProgramFree \
|
||||
--name=virNetServerServiceFree \
|
||||
--name=virNetSocketFree \
|
||||
--name=virNetSASLContextFree \
|
||||
--name=virNetSASLSessionFree \
|
||||
--name=virNetTLSSessionFree \
|
||||
--name=virNWFilterDefFree \
|
||||
--name=virNWFilterEntryFree \
|
||||
--name=virNWFilterHashTableFree \
|
||||
--name=virNWFilterIPAddrLearnReqFree \
|
||||
--name=virNWFilterIncludeDefFree \
|
||||
--name=virNWFilterObjFree \
|
||||
--name=virNWFilterRuleDefFree \
|
||||
--name=virNWFilterRuleInstFree \
|
||||
--name=virNetworkDefFree \
|
||||
--name=virNetworkObjFree \
|
||||
--name=virNodeDeviceDefFree \
|
||||
--name=virNodeDeviceObjFree \
|
||||
--name=virSecretDefFree \
|
||||
--name=virStorageEncryptionFree \
|
||||
--name=virStorageEncryptionSecretFree \
|
||||
--name=virStorageFileFreeMetadata \
|
||||
--name=virStoragePoolDefFree \
|
||||
--name=virStoragePoolObjFree \
|
||||
--name=virStoragePoolSourceFree \
|
||||
--name=virStorageVolDefFree \
|
||||
--name=virThreadPoolFree \
|
||||
--name=xmlBufferFree \
|
||||
--name=xmlFree \
|
||||
--name=xmlFreeDoc \
|
||||
--name=xmlFreeNode \
|
||||
--name=xmlXPathFreeContext \
|
||||
--name=xmlXPathFreeObject
|
||||
|
||||
# The following template was generated by this command:
|
||||
# make ID && aid free|grep '^vi'|sed 's/ .*//;s/^/# /'
|
||||
# N virBufferFreeAndReset
|
||||
# y virCPUDefFree
|
||||
# y virCapabilitiesFree
|
||||
# y virCapabilitiesFreeGuest
|
||||
# y virCapabilitiesFreeGuestDomain
|
||||
# y virCapabilitiesFreeGuestFeature
|
||||
# y virCapabilitiesFreeGuestMachine
|
||||
# y virCapabilitiesFreeHostNUMACell
|
||||
# y virCapabilitiesFreeMachines
|
||||
# N virCapabilitiesFreeNUMAInfo FIXME
|
||||
# y virCgroupFree
|
||||
# N virConfFree (diagnoses the "error")
|
||||
# y virConfFreeList
|
||||
# y virConfFreeValue
|
||||
# y virDomainChrDefFree
|
||||
# y virDomainControllerDefFree
|
||||
# y virDomainDefFree
|
||||
# y virDomainDeviceDefFree
|
||||
# y virDomainDiskDefFree
|
||||
# y virDomainEventCallbackListFree
|
||||
# y virDomainEventFree
|
||||
# y virDomainEventQueueFree
|
||||
# y virDomainFSDefFree
|
||||
# n virDomainFree
|
||||
# n virDomainFreeName (can't fix -- returns int)
|
||||
# y virDomainGraphicsDefFree
|
||||
# y virDomainHostdevDefFree
|
||||
# y virDomainInputDefFree
|
||||
# y virDomainNetDefFree
|
||||
# y virDomainObjFree
|
||||
# y virDomainSnapshotDefFree
|
||||
# n virDomainSnapshotFree (returns int)
|
||||
# n virDomainSnapshotFreeName (returns int)
|
||||
# y virDomainSnapshotObjFree
|
||||
# y virDomainSoundDefFree
|
||||
# y virDomainVideoDefFree
|
||||
# y virDomainWatchdogDefFree
|
||||
# n virDrvNodeGetCellsFreeMemory (returns int)
|
||||
# n virDrvNodeGetFreeMemory (returns long long)
|
||||
# n virFree - dereferences param
|
||||
# n virFreeError
|
||||
# n virHashFree (takes 2 args)
|
||||
# y virInterfaceDefFree
|
||||
# n virInterfaceFree (returns int)
|
||||
# n virInterfaceFreeName
|
||||
# y virInterfaceIpDefFree
|
||||
# y virInterfaceObjFree
|
||||
# n virInterfaceObjListFree
|
||||
# y virInterfaceProtocolDefFree
|
||||
# y virJSONValueFree
|
||||
# y virLastErrFreeData
|
||||
# y virNWFilterDefFree
|
||||
# y virNWFilterEntryFree
|
||||
# n virNWFilterFree (returns int)
|
||||
# y virNWFilterHashTableFree
|
||||
# y virNWFilterIPAddrLearnReqFree
|
||||
# y virNWFilterIncludeDefFree
|
||||
# n virNWFilterFreeName (returns int)
|
||||
# y virNWFilterObjFree
|
||||
# n virNWFilterObjListFree FIXME
|
||||
# y virNWFilterRuleDefFree
|
||||
# n virNWFilterRuleFreeInstanceData (typedef)
|
||||
# y virNWFilterRuleInstFree
|
||||
# y virNetworkDefFree
|
||||
# n virNetworkFree (returns int)
|
||||
# n virNetworkFreeName (returns int)
|
||||
# y virNetworkObjFree
|
||||
# n virNetworkObjListFree FIXME
|
||||
# n virNodeDevCapsDefFree FIXME
|
||||
# y virNodeDeviceDefFree
|
||||
# n virNodeDeviceFree (returns int)
|
||||
# y virNodeDeviceObjFree
|
||||
# n virNodeDeviceObjListFree FIXME
|
||||
# n virNodeGetCellsFreeMemory (returns int)
|
||||
# n virNodeGetFreeMemory (returns non-void)
|
||||
# y virSecretDefFree
|
||||
# n virSecretFree (returns non-void)
|
||||
# n virSecretFreeName (2 args)
|
||||
# n virSecurityLabelDefFree FIXME
|
||||
# n virStorageBackendDiskMakeFreeExtent (returns non-void)
|
||||
# y virStorageEncryptionFree
|
||||
# y virStorageEncryptionSecretFree
|
||||
# n virStorageFreeType (enum)
|
||||
# y virStoragePoolDefFree
|
||||
# n virStoragePoolFree (returns non-void)
|
||||
# n virStoragePoolFreeName (returns non-void)
|
||||
# y virStoragePoolObjFree
|
||||
# n virStoragePoolObjListFree FIXME
|
||||
# y virStoragePoolSourceFree
|
||||
# y virStorageVolDefFree
|
||||
# n virStorageVolFree (returns non-void)
|
||||
# n virStorageVolFreeName (returns non-void)
|
||||
# n virStreamFree
|
||||
|
||||
# Avoid uses of write(2). Either switch to streams (fwrite), or use
|
||||
# the safewrite wrapper.
|
||||
sc_avoid_write:
|
||||
@prohibit='\<write *\(' \
|
||||
in_vc_files='\.c$$' \
|
||||
halt='consider using safewrite instead of write' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# In debug statements, print flags as bitmask and mode_t as octal.
|
||||
sc_flags_debug:
|
||||
@prohibit='\<mode=%[0-9.]*[diux]' \
|
||||
halt='use %o to debug mode_t values' \
|
||||
$(_sc_search_regexp)
|
||||
@prohibit='[Ff]lags=%[0-9.]*l*[diou]' \
|
||||
halt='use %x to debug flag values' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Prefer 'unsigned int flags', along with checks for unknown flags.
|
||||
# For historical reasons, we are stuck with 'unsigned long flags' in
|
||||
# migration, so check for those known 4 instances and no more in public
|
||||
# API. Also check that no flags are marked unused, and 'unsigned' should
|
||||
# appear before any declaration of a flags variable (achieved by
|
||||
# prohibiting the word prior to the type from ending in anything other
|
||||
# than d). The existence of long long, and of documentation about
|
||||
# flags, makes the regex in the third test slightly harder.
|
||||
sc_flags_usage:
|
||||
@test "$$(cat $(srcdir)/include/libvirt/libvirt.h.in \
|
||||
$(srcdir)/include/libvirt/virterror.h \
|
||||
$(srcdir)/include/libvirt/libvirt-qemu.h \
|
||||
| grep -c '\(long\|unsigned\) flags')" != 4 && \
|
||||
{ echo '$(ME): new API should use "unsigned int flags"' 1>&2; \
|
||||
exit 1; } || :
|
||||
@prohibit=' flags ''ATTRIBUTE_UNUSED' \
|
||||
halt='flags should be checked with virCheckFlags' \
|
||||
$(_sc_search_regexp)
|
||||
@prohibit='^[^@]*([^d] (int|long long)|[^dg] long) flags[;,)]' \
|
||||
halt='flags should be unsigned' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Avoid functions that should only be called via macro counterparts.
|
||||
sc_prohibit_internal_functions:
|
||||
@prohibit='vir(Free|AllocN?|ReallocN|File(Close|Fclose|Fdopen)) *\(' \
|
||||
halt='use VIR_ macros instead of internal functions' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Avoid raw malloc and free, except in documentation comments.
|
||||
sc_prohibit_raw_allocation:
|
||||
@prohibit='^.[^*].*\<((m|c|re)alloc|free) *\([^)]' \
|
||||
halt='use VIR_ macros from memory.h instead of malloc/free' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Avoid functions that can lead to double-close bugs.
|
||||
sc_prohibit_close:
|
||||
@prohibit='([^>.]|^)\<[fp]?close *\(' \
|
||||
halt='use VIR_{FORCE_}[F]CLOSE instead of [f]close' \
|
||||
$(_sc_search_regexp)
|
||||
@prohibit='\<fdopen *\(' \
|
||||
halt='use VIR_FDOPEN instead of fdopen' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Prefer virCommand for all child processes.
|
||||
sc_prohibit_fork_wrappers:
|
||||
@prohibit='= *\<(fork|popen|system) *\(' \
|
||||
halt='use virCommand for child processes' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# access with X_OK accepts directories, but we can't exec() those.
|
||||
# access with F_OK or R_OK is okay, though.
|
||||
sc_prohibit_access_xok:
|
||||
@prohibit='access''(at)? *\(.*X_OK' \
|
||||
halt='use virFileIsExecutable instead of access''(,X_OK)' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Similar to the gnulib maint.mk rule for sc_prohibit_strcmp
|
||||
# Use STREQLEN or STRPREFIX rather than comparing strncmp == 0, or != 0.
|
||||
snp_ = strncmp *\(.+\)
|
||||
sc_prohibit_strncmp:
|
||||
@prohibit='! *strncmp *\(|\<$(snp_) *[!=]=|[!=]= *$(snp_)' \
|
||||
exclude=':# *define STR(N?EQLEN|PREFIX)\(' \
|
||||
halt='$(ME): use STREQLEN or STRPREFIX instead of str''ncmp' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Use virAsprintf rather than as'printf since *strp is undefined on error.
|
||||
sc_prohibit_asprintf:
|
||||
@prohibit='\<v?a[s]printf\>' \
|
||||
halt='use virAsprintf, not as'printf \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Prefer virSetUIDGID.
|
||||
sc_prohibit_setuid:
|
||||
@prohibit='\<set(re)?[ug]id\> *\(' \
|
||||
halt='use virSetUIDGID, not raw set*id' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Use snprintf rather than s'printf, even if buffer is provably large enough,
|
||||
# since gnulib has more guarantees for snprintf portability
|
||||
sc_prohibit_sprintf:
|
||||
@prohibit='\<[s]printf\>' \
|
||||
halt='use snprintf, not s'printf \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
sc_prohibit_readlink:
|
||||
@prohibit='readlink *\(' \
|
||||
halt='use virFileResolveLink, not readlink' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
sc_prohibit_gethostname:
|
||||
@prohibit='gethostname *\(' \
|
||||
halt='use virGetHostname, not gethostname' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
sc_prohibit_gettext_noop:
|
||||
@prohibit='gettext_noop *\(' \
|
||||
halt='use N_, not gettext_noop' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
sc_prohibit_VIR_ERR_NO_MEMORY:
|
||||
@prohibit='\<V''IR_ERR_NO_MEMORY\>' \
|
||||
halt='use virReportOOMError, not V'IR_ERR_NO_MEMORY \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
sc_prohibit_PATH_MAX:
|
||||
@prohibit='\<P''ATH_MAX\>' \
|
||||
halt='dynamically allocate paths, do not use P'ATH_MAX \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Use a subshell for each function, to give the optimal warning message.
|
||||
include $(srcdir)/Makefile.nonreentrant
|
||||
sc_prohibit_nonreentrant:
|
||||
@fail=0 ; \
|
||||
for i in $(NON_REENTRANT) ; \
|
||||
do \
|
||||
(prohibit="\\<$$i *\\(" \
|
||||
halt="use $${i}_r, not $$i" \
|
||||
$(_sc_search_regexp) \
|
||||
) || fail=1; \
|
||||
done ; \
|
||||
exit $$fail
|
||||
|
||||
# Prohibit the inclusion of <ctype.h>.
|
||||
sc_prohibit_ctype_h:
|
||||
@prohibit='^# *include *<ctype\.h>' \
|
||||
halt="don't use ctype.h; instead, use c-ctype.h" \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Insist on correct types for [pug]id.
|
||||
sc_correct_id_types:
|
||||
@prohibit='\<(int|long) *[pug]id\>' \
|
||||
halt="use pid_t for pid, uid_t for uid, gid_t for gid" \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Forbid sizeof foo or sizeof (foo), require sizeof(foo)
|
||||
sc_size_of_brackets:
|
||||
@prohibit='sizeof\s' \
|
||||
halt='use sizeof(foo), not sizeof (foo) or sizeof foo' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Ensure that no C source file, docs, or rng schema uses TABs for
|
||||
# indentation. Also match *.h.in files, to get libvirt.h.in. Exclude
|
||||
# files in gnulib, since they're imported.
|
||||
space_indent_files=(\.(rng|s?[ch](\.in)?|html.in|py|syms)|(daemon|tools)/.*\.in)
|
||||
sc_TAB_in_indentation:
|
||||
@prohibit='^ * ' \
|
||||
in_vc_files='$(space_indent_files)$$' \
|
||||
halt='indent with space, not TAB, in C, sh, html, py, syms and RNG schemas' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
ctype_re = isalnum|isalpha|isascii|isblank|iscntrl|isdigit|isgraph|islower\
|
||||
|isprint|ispunct|isspace|isupper|isxdigit|tolower|toupper
|
||||
|
||||
sc_avoid_ctype_macros:
|
||||
@prohibit='\b($(ctype_re)) *\(' \
|
||||
halt="don't use ctype macros (use c-ctype.h)" \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
sc_avoid_strcase:
|
||||
@prohibit='\bstrn?case(cmp|str) *\(' \
|
||||
halt="don't use raw strcase functions (use c-strcase instead)" \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
sc_prohibit_virBufferAdd_with_string_literal:
|
||||
@prohibit='\<virBufferAdd *\([^,]+, *"[^"]' \
|
||||
halt='use virBufferAddLit, not virBufferAdd, with a string literal' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Not only do they fail to deal well with ipv6, but the gethostby*
|
||||
# functions are also not thread-safe.
|
||||
sc_prohibit_gethostby:
|
||||
@prohibit='\<gethostby(addr|name2?) *\(' \
|
||||
halt='use getaddrinfo, not gethostby*' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# raw xmlGetProp requires some nasty casts
|
||||
sc_prohibit_xmlGetProp:
|
||||
@prohibit='\<xmlGetProp *\(' \
|
||||
halt='use virXMLPropString, not xmlGetProp' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# xml(ParseURI|SaveUri) doesn't handle IPv6 URIs well
|
||||
sc_prohibit_xmlURI:
|
||||
@prohibit='\<xml(ParseURI|SaveUri) *\(' \
|
||||
halt='use virURI(Parse|Format), not xml(ParseURI|SaveUri)' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# we don't want old old-style return with parentheses around argument
|
||||
sc_prohibit_return_as_function:
|
||||
@prohibit='\<return *\(([^()]*(\([^()]*\)[^()]*)*)\) *;' \
|
||||
halt='avoid extra () with return statements' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# ATTRIBUTE_UNUSED should only be applied in implementations, not
|
||||
# header declarations
|
||||
sc_avoid_attribute_unused_in_header:
|
||||
@prohibit='^[^#]*ATTRIBUTE_UNUSED([^:]|$$)' \
|
||||
in_vc_files='\.h$$' \
|
||||
halt='use ATTRIBUTE_UNUSED in .c rather than .h files' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Many of the function names below came from this filter:
|
||||
# git grep -B2 '\<_('|grep -E '\.c- *[[:alpha:]_][[:alnum:]_]* ?\(.*[,;]$' \
|
||||
# |sed 's/.*\.c- *//'|perl -pe 's/ ?\(.*//'|sort -u \
|
||||
# |grep -vE '^(qsort|if|close|assert|fputc|free|N_|vir.*GetName|.*Unlock|virNodeListDevices|virHashRemoveEntry|freeaddrinfo|.*[fF]ree|xdrmem_create|xmlXPathFreeObject|virUUIDFormat|openvzSetProgramSentinal|polkit_action_unref)$'
|
||||
|
||||
msg_gen_function =
|
||||
msg_gen_function += ESX_ERROR
|
||||
msg_gen_function += ESX_VI_ERROR
|
||||
msg_gen_function += HYPERV_ERROR
|
||||
msg_gen_function += PHYP_ERROR
|
||||
msg_gen_function += VIR_ERROR
|
||||
msg_gen_function += VMX_ERROR
|
||||
msg_gen_function += XENXS_ERROR
|
||||
msg_gen_function += eventReportError
|
||||
msg_gen_function += ifaceError
|
||||
msg_gen_function += interfaceReportError
|
||||
msg_gen_function += iptablesError
|
||||
msg_gen_function += lxcError
|
||||
msg_gen_function += libxlError
|
||||
msg_gen_function += macvtapError
|
||||
msg_gen_function += networkReportError
|
||||
msg_gen_function += nodeReportError
|
||||
msg_gen_function += openvzError
|
||||
msg_gen_function += pciReportError
|
||||
msg_gen_function += qemuReportError
|
||||
msg_gen_function += qemudDispatchClientFailure
|
||||
msg_gen_function += regerror
|
||||
msg_gen_function += remoteError
|
||||
msg_gen_function += remoteDispatchFormatError
|
||||
msg_gen_function += statsError
|
||||
msg_gen_function += streamsReportError
|
||||
msg_gen_function += usbReportError
|
||||
msg_gen_function += umlReportError
|
||||
msg_gen_function += vah_error
|
||||
msg_gen_function += vah_warning
|
||||
msg_gen_function += vboxError
|
||||
msg_gen_function += virCommandError
|
||||
msg_gen_function += virConfError
|
||||
msg_gen_function += virCPUReportError
|
||||
msg_gen_function += virEventError
|
||||
msg_gen_function += virDomainReportError
|
||||
msg_gen_function += virGenericReportError
|
||||
msg_gen_function += virHashError
|
||||
msg_gen_function += virHookReportError
|
||||
msg_gen_function += virInterfaceReportError
|
||||
msg_gen_function += virJSONError
|
||||
msg_gen_function += virLibConnError
|
||||
msg_gen_function += virLibDomainError
|
||||
msg_gen_function += virLibDomainSnapshotError
|
||||
msg_gen_function += virLibInterfaceError
|
||||
msg_gen_function += virLibNetworkError
|
||||
msg_gen_function += virLibNodeDeviceError
|
||||
msg_gen_function += virLibNWFilterError
|
||||
msg_gen_function += virLibSecretError
|
||||
msg_gen_function += virLibStoragePoolError
|
||||
msg_gen_function += virLibStorageVolError
|
||||
msg_gen_function += virNetworkReportError
|
||||
msg_gen_function += virNodeDeviceReportError
|
||||
msg_gen_function += virNWFilterReportError
|
||||
msg_gen_function += virRaiseError
|
||||
msg_gen_function += virReportErrorHelper
|
||||
msg_gen_function += virReportSystemError
|
||||
msg_gen_function += virSecretReportError
|
||||
msg_gen_function += virSecurityReportError
|
||||
msg_gen_function += virSexprError
|
||||
msg_gen_function += virSmbiosReportError
|
||||
msg_gen_function += virSocketError
|
||||
msg_gen_function += virStatsError
|
||||
msg_gen_function += virStorageReportError
|
||||
msg_gen_function += virUtilError
|
||||
msg_gen_function += virXMLError
|
||||
msg_gen_function += virXenInotifyError
|
||||
msg_gen_function += virXenStoreError
|
||||
msg_gen_function += virXendError
|
||||
msg_gen_function += vmwareError
|
||||
msg_gen_function += xenapiSessionErrorHandler
|
||||
msg_gen_function += xenUnifiedError
|
||||
msg_gen_function += xenXMError
|
||||
|
||||
# Uncomment the following and run "make syntax-check" to see diagnostics
|
||||
# that are not yet marked for translation, but that need to be rewritten
|
||||
# so that they are translatable.
|
||||
# msg_gen_function += fprintf
|
||||
# msg_gen_function += testError
|
||||
# msg_gen_function += virXenError
|
||||
# msg_gen_function += vshPrint
|
||||
# msg_gen_function += vshError
|
||||
|
||||
func_or := $(shell printf '$(msg_gen_function)'|tr -s '[[:space:]]' '|')
|
||||
func_re := ($(func_or))
|
||||
|
||||
# Look for diagnostics that aren't marked for translation.
|
||||
# This won't find any for which error's format string is on a separate line.
|
||||
# The sed filters eliminate false-positives like these:
|
||||
# _("...: "
|
||||
# "%s", _("no storage vol w..."
|
||||
sc_libvirt_unmarked_diagnostics:
|
||||
@prohibit='\<$(func_re) *\([^"]*"[^"]*[a-z]{3}' \
|
||||
exclude='_\(' \
|
||||
halt='$(ME): found unmarked diagnostic(s)' \
|
||||
$(_sc_search_regexp)
|
||||
@{ grep -nE '\<$(func_re) *\(.*;$$' $$($(VC_LIST_EXCEPT)); \
|
||||
grep -A1 -nE '\<$(func_re) *\(.*,$$' $$($(VC_LIST_EXCEPT)); } \
|
||||
| sed 's/_("\([^\"]\|\\.\)\+"//;s/[ ]"%s"//' \
|
||||
| grep '[ ]"' && \
|
||||
{ echo '$(ME): found unmarked diagnostic(s)' 1>&2; \
|
||||
exit 1; } || :
|
||||
|
||||
# Like the above, but prohibit a newline at the end of a diagnostic.
|
||||
# This is subject to false positives partly because it naively looks for
|
||||
# `\n"', which may not be the end of the string, and also because it takes
|
||||
# two lines of context (the -A2) after the line with the function name.
|
||||
# FIXME: this rule might benefit from a separate function list, in case
|
||||
# there are functions to which this one applies but that do not get marked
|
||||
# diagnostics.
|
||||
sc_prohibit_newline_at_end_of_diagnostic:
|
||||
@grep -A2 -nE \
|
||||
'\<$(func_re) *\(' $$($(VC_LIST_EXCEPT)) \
|
||||
| grep '\\n"' \
|
||||
&& { echo '$(ME): newline at end of message(s)' 1>&2; \
|
||||
exit 1; } || :
|
||||
|
||||
# Enforce recommended preprocessor indentation style.
|
||||
sc_preprocessor_indentation:
|
||||
@if cppi --version >/dev/null 2>&1; then \
|
||||
$(VC_LIST_EXCEPT) | grep '\.[ch]$$' | xargs cppi -a -c \
|
||||
|| { echo '$(ME): incorrect preprocessor indentation' 1>&2; \
|
||||
exit 1; }; \
|
||||
else \
|
||||
echo '$(ME): skipping test $@: cppi not installed' 1>&2; \
|
||||
fi
|
||||
|
||||
sc_copyright_format:
|
||||
@require='Copyright .*Red 'Hat', Inc\.' \
|
||||
containing='Copyright .*Red 'Hat \
|
||||
halt='Red Hat copyright is missing Inc.' \
|
||||
$(_sc_search_regexp)
|
||||
@prohibit='Copyright [^(].*Red 'Hat \
|
||||
halt='consistently use (C) in Red Hat copyright' \
|
||||
$(_sc_search_regexp)
|
||||
@prohibit='\<Red''Hat\>' \
|
||||
halt='spell Red Hat as two words' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Some functions/macros produce messages intended solely for developers
|
||||
# and maintainers. Do not mark them for translation.
|
||||
sc_prohibit_gettext_markup:
|
||||
@prohibit='\<VIR_(WARN|INFO|DEBUG) *\(_\(' \
|
||||
halt='do not mark these strings for translation' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Our code is divided into modular subdirectories for a reason, and
|
||||
# lower-level code must not include higher-level headers.
|
||||
cross_dirs=$(patsubst $(srcdir)/src/%.,%,$(wildcard $(srcdir)/src/*/.))
|
||||
cross_dirs_re=($(subst / ,/|,$(cross_dirs)))
|
||||
sc_prohibit_cross_inclusion:
|
||||
@for dir in $(cross_dirs); do \
|
||||
case $$dir in \
|
||||
util/) safe="util";; \
|
||||
cpu/ | locking/ | network/ | rpc/ | security/) \
|
||||
safe="($$dir|util|conf)";; \
|
||||
xenapi/ | xenxs/ ) safe="($$dir|util|conf|xen)";; \
|
||||
*) safe="($$dir|util|conf|cpu|network|locking|rpc|security)";; \
|
||||
esac; \
|
||||
in_vc_files="^src/$$dir" \
|
||||
prohibit='^# *include .$(cross_dirs_re)' \
|
||||
exclude="# *include .$$safe" \
|
||||
halt='unsafe cross-directory include' \
|
||||
$(_sc_search_regexp) \
|
||||
done
|
||||
|
||||
# When converting an enum to a string, make sure that we track any new
|
||||
# elements added to the enum by using a _LAST marker.
|
||||
sc_require_enum_last_marker:
|
||||
@grep -A1 -nE '^[^#]*VIR_ENUM_IMPL *\(' $$($(VC_LIST_EXCEPT)) \
|
||||
| sed -ne '/VIR_ENUM_IMPL[^,]*,$$/N' \
|
||||
-e '/VIR_ENUM_IMPL[^,]*,[^,]*[^_,][^L,][^A,][^S,][^T,],/p' \
|
||||
-e '/VIR_ENUM_IMPL[^,]*,[^,]\{0,4\},/p' \
|
||||
| grep . && \
|
||||
{ echo '$(ME): enum impl needs to use _LAST marker' 1>&2; \
|
||||
exit 1; } || :
|
||||
|
||||
# We don't use this feature of maint.mk.
|
||||
prev_version_file = /dev/null
|
||||
|
||||
ifeq (0,$(MAKELEVEL))
|
||||
_curr_status = .git-module-status
|
||||
# The sed filter accommodates those who check out on a commit from which
|
||||
# no tag is reachable. In that case, git submodule status prints a "-"
|
||||
# in column 1 and does not print a "git describe"-style string after the
|
||||
# submodule name. Contrast these:
|
||||
# -b653eda3ac4864de205419d9f41eec267cb89eeb .gnulib
|
||||
# b653eda3ac4864de205419d9f41eec267cb89eeb .gnulib (v0.0-2286-gb653eda)
|
||||
# $ cat .git-module-status
|
||||
# b653eda3ac4864de205419d9f41eec267cb89eeb
|
||||
_submodule_hash = sed 's/^[ +-]//;s/ .*//'
|
||||
_update_required := $(shell \
|
||||
cd '$(srcdir)'; \
|
||||
test -d .git || { echo 0; exit; }; \
|
||||
test -f po/Makevars || { echo 1; exit; }; \
|
||||
actual=$$(git submodule status | $(_submodule_hash); \
|
||||
git hash-object bootstrap.conf; \
|
||||
git ls-tree -d HEAD gnulib/local | awk '{print $$3}'; \
|
||||
git diff .gnulib); \
|
||||
stamp="$$($(_submodule_hash) $(_curr_status) 2>/dev/null)"; \
|
||||
test "$$stamp" = "$$actual"; echo $$?)
|
||||
_clean_requested = $(filter %clean,$(MAKECMDGOALS))
|
||||
ifeq (1,$(_update_required)$(_clean_requested))
|
||||
$(info INFO: gnulib update required; running ./autogen.sh first)
|
||||
maint.mk Makefile: _autogen
|
||||
endif
|
||||
endif
|
||||
|
||||
# It is necessary to call autogen any time gnulib changes. Autogen
|
||||
# reruns configure, then we regenerate all Makefiles at once.
|
||||
.PHONY: _autogen
|
||||
_autogen:
|
||||
$(srcdir)/autogen.sh
|
||||
./config.status
|
||||
|
||||
# Give credit where due:
|
||||
# Ensure that each commit author email address (possibly mapped via
|
||||
# git log's .mailmap) appears in our AUTHORS file.
|
||||
sc_check_author_list:
|
||||
@fail=0; \
|
||||
for i in $$(git log --pretty=format:%aE%n|sort -u|grep -v '^$$'); do \
|
||||
sanitized=$$(echo "$$i"|LC_ALL=C sed 's/\([^a-zA-Z0-9_@-]\)/\\\1/g'); \
|
||||
grep -iq "<$$sanitized>" $(srcdir)/AUTHORS \
|
||||
|| { printf '%s\n' "$$i" >&2; fail=1; }; \
|
||||
done; \
|
||||
test $$fail = 1 \
|
||||
&& echo '$(ME): committer(s) not listed in AUTHORS' >&2; \
|
||||
test $$fail = 0
|
||||
|
||||
# regenerate HACKING as part of the syntax-check
|
||||
syntax-check: $(top_srcdir)/HACKING
|
||||
|
||||
# sc_po_check can fail if generated files are not built first
|
||||
sc_po_check: \
|
||||
$(srcdir)/daemon/remote_dispatch.h \
|
||||
$(srcdir)/daemon/qemu_dispatch.h \
|
||||
$(srcdir)/src/remote/remote_client_bodies.h
|
||||
$(srcdir)/daemon/remote_dispatch.h: $(srcdir)/src/remote/remote_protocol.x
|
||||
$(MAKE) -C daemon remote_dispatch.h
|
||||
$(srcdir)/daemon/qemu_dispatch.h: $(srcdir)/src/remote/qemu_protocol.x
|
||||
$(MAKE) -C daemon qemu_dispatch.h
|
||||
$(srcdir)/src/remote/remote_client_bodies.h: $(srcdir)/src/remote/remote_protocol.x
|
||||
$(MAKE) -C src remote/remote_client_bodies.h
|
||||
|
||||
# List all syntax-check exemptions:
|
||||
exclude_file_name_regexp--sc_avoid_strcase = ^tools/virsh\.c$$
|
||||
|
||||
_src1=libvirt|fdstream|qemu/qemu_monitor|util/(command|util)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller
|
||||
exclude_file_name_regexp--sc_avoid_write = \
|
||||
^(src/($(_src1))|daemon/libvirtd|tools/console|tests/(shunload|virnettlscontext)test)\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_bindtextdomain = ^(tests|examples)/
|
||||
|
||||
exclude_file_name_regexp--sc_flags_usage = ^(docs/|src/util/virnetdevtap\.c$$)
|
||||
|
||||
exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics = \
|
||||
^src/rpc/gendispatch\.pl$$
|
||||
|
||||
exclude_file_name_regexp--sc_po_check = ^(docs/|src/rpc/gendispatch\.pl$$)
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_VIR_ERR_NO_MEMORY = \
|
||||
^(include/libvirt/virterror\.h|daemon/dispatch\.c|src/util/virterror\.c)$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_access_xok = ^src/util/util\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_always_true_header_tests = \
|
||||
^python/(libvirt-(qemu-)?override|typewrappers)\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_asprintf = \
|
||||
^(bootstrap.conf$$|src/util/util\.c$$|examples/domain-events/events-c/event-test\.c$$)
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_close = \
|
||||
(\.p[yl]$$|^docs/|^(src/util/virfile\.c|src/libvirt\.c)$$)
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
|
||||
(^tests/qemuhelpdata/|\.(gif|ico|png|diff)$$)
|
||||
|
||||
_src2=src/(util/command|libvirt|lxc/lxc_controller)
|
||||
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
|
||||
(^($(_src2)|tests/testutils|daemon/libvirtd)\.c$$)
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/util\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_internal_functions = \
|
||||
^src/(util/(memory|util|virfile)\.[hc]|esx/esx_vi\.c)$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
|
||||
^src/rpc/gendispatch\.pl$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_nonreentrant = \
|
||||
^((po|tests)/|docs/.*py$$|tools/(virsh|console)\.c$$)
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_raw_allocation = \
|
||||
^(src/util/memory\.[ch]|examples/.*)$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_readlink = ^src/util/util\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_setuid = ^src/util/util\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_sprintf = \
|
||||
^(docs/hacking\.html\.in)|(examples/systemtap/.*stp)|(src/dtrace2systemtap\.pl)|(src/rpc/gensystemtap\.pl)$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_strncpy = \
|
||||
^(src/util/util|tools/virsh)\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/xml\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_xmlURI = ^src/util/viruri\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_return_as_function = \.py$$
|
||||
|
||||
exclude_file_name_regexp--sc_require_config_h = ^examples/
|
||||
|
||||
exclude_file_name_regexp--sc_require_config_h_first = ^examples/
|
||||
|
||||
exclude_file_name_regexp--sc_trailing_blank = \.(fig|gif|ico|png)$$
|
||||
|
||||
exclude_file_name_regexp--sc_unmarked_diagnostics = \
|
||||
^(docs/apibuild.py|tests/virt-aa-helper-test)$$
|
||||
|
||||
exclude_file_name_regexp--sc_size_of_brackets = cfg.mk
|
2935
configure.ac
2935
configure.ac
File diff suppressed because it is too large
Load Diff
@ -1,384 +0,0 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
## Copyright (C) 2005-2012 Red Hat, Inc.
|
||||
## See COPYING.LIB for the License of this software
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib \
|
||||
-I$(top_builddir)/include -I$(top_srcdir)/include \
|
||||
-I$(top_builddir)/src -I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/src/util \
|
||||
-I$(top_srcdir)/src/conf \
|
||||
-I$(top_srcdir)/src/rpc \
|
||||
-I$(top_srcdir)/src/remote \
|
||||
$(GETTEXT_CPPFLAGS)
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
DAEMON_GENERATED = \
|
||||
$(srcdir)/remote_dispatch.h \
|
||||
$(srcdir)/qemu_dispatch.h
|
||||
|
||||
DAEMON_SOURCES = \
|
||||
libvirtd.c libvirtd.h \
|
||||
remote.c remote.h \
|
||||
stream.c stream.h \
|
||||
../src/remote/remote_protocol.c \
|
||||
../src/remote/qemu_protocol.c \
|
||||
$(DAEMON_GENERATED)
|
||||
|
||||
DISTCLEANFILES =
|
||||
EXTRA_DIST = \
|
||||
remote_dispatch.h \
|
||||
qemu_dispatch.h \
|
||||
libvirtd.conf \
|
||||
libvirtd.init.in \
|
||||
libvirtd.upstart \
|
||||
libvirtd.policy-0 \
|
||||
libvirtd.policy-1 \
|
||||
libvirtd.sasl \
|
||||
libvirtd.sysconf \
|
||||
libvirtd.sysctl \
|
||||
libvirtd.aug \
|
||||
libvirtd.logrotate.in \
|
||||
libvirtd.qemu.logrotate.in \
|
||||
libvirtd.lxc.logrotate.in \
|
||||
libvirtd.uml.logrotate.in \
|
||||
test_libvirtd.aug \
|
||||
THREADS.txt \
|
||||
libvirtd.pod.in \
|
||||
libvirtd.8.in \
|
||||
$(DAEMON_SOURCES)
|
||||
|
||||
BUILT_SOURCES =
|
||||
|
||||
REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x
|
||||
QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x
|
||||
|
||||
$(srcdir)/remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
|
||||
$(REMOTE_PROTOCOL)
|
||||
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -b remote \
|
||||
$(REMOTE_PROTOCOL) > $@
|
||||
|
||||
$(srcdir)/qemu_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
|
||||
$(QEMU_PROTOCOL)
|
||||
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -b qemu \
|
||||
$(QEMU_PROTOCOL) > $@
|
||||
|
||||
if WITH_LIBVIRTD
|
||||
|
||||
man8_MANS = libvirtd.8
|
||||
|
||||
sbin_PROGRAMS = libvirtd
|
||||
|
||||
confdir = $(sysconfdir)/libvirt/
|
||||
conf_DATA = libvirtd.conf
|
||||
|
||||
augeasdir = $(datadir)/augeas/lenses
|
||||
augeas_DATA = libvirtd.aug
|
||||
|
||||
augeastestsdir = $(datadir)/augeas/lenses/tests
|
||||
augeastests_DATA = test_libvirtd.aug
|
||||
|
||||
libvirtd.8: $(srcdir)/libvirtd.8.in
|
||||
sed \
|
||||
-e 's![@]sysconfdir[@]!$(sysconfdir)!g' \
|
||||
-e 's![@]localstatedir[@]!$(localstatedir)!g' \
|
||||
-e 's![@]remote_pid_file[@]!$(REMOTE_PID_FILE)!g' \
|
||||
< $< > $@-t
|
||||
mv $@-t $@
|
||||
|
||||
libvirtd_SOURCES = $(DAEMON_SOURCES)
|
||||
|
||||
#-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L
|
||||
libvirtd_CFLAGS = \
|
||||
$(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \
|
||||
$(XDR_CFLAGS) $(POLKIT_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
$(COVERAGE_CFLAGS) \
|
||||
-DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\"" \
|
||||
-DREMOTE_PID_FILE="\"$(REMOTE_PID_FILE)\""
|
||||
|
||||
libvirtd_LDFLAGS = \
|
||||
$(WARN_CFLAGS) \
|
||||
$(COVERAGE_LDFLAGS)
|
||||
|
||||
libvirtd_LDADD = \
|
||||
$(LIBXML_LIBS) \
|
||||
$(GNUTLS_LIBS) \
|
||||
$(SASL_LIBS) \
|
||||
$(POLKIT_LIBS)
|
||||
|
||||
if WITH_DTRACE_PROBES
|
||||
libvirtd_LDADD += ../src/probes.o
|
||||
endif
|
||||
|
||||
libvirtd_LDADD += \
|
||||
../src/libvirt-qemu.la
|
||||
|
||||
if ! WITH_DRIVER_MODULES
|
||||
if WITH_QEMU
|
||||
libvirtd_LDADD += ../src/libvirt_driver_qemu.la
|
||||
endif
|
||||
|
||||
if WITH_LXC
|
||||
libvirtd_LDADD += ../src/libvirt_driver_lxc.la
|
||||
endif
|
||||
|
||||
if WITH_LIBXL
|
||||
libvirtd_LDADD += ../src/libvirt_driver_libxl.la
|
||||
endif
|
||||
|
||||
if WITH_UML
|
||||
libvirtd_LDADD += ../src/libvirt_driver_uml.la
|
||||
endif
|
||||
|
||||
if WITH_STORAGE_DIR
|
||||
libvirtd_LDADD += ../src/libvirt_driver_storage.la
|
||||
endif
|
||||
|
||||
if WITH_NETWORK
|
||||
libvirtd_LDADD += ../src/libvirt_driver_network.la
|
||||
endif
|
||||
|
||||
if WITH_NETCF
|
||||
libvirtd_LDADD += ../src/libvirt_driver_interface.la
|
||||
endif
|
||||
|
||||
if WITH_NODE_DEVICES
|
||||
libvirtd_LDADD += ../src/libvirt_driver_nodedev.la
|
||||
endif
|
||||
|
||||
if WITH_SECRETS
|
||||
libvirtd_LDADD += ../src/libvirt_driver_secret.la
|
||||
endif
|
||||
|
||||
if WITH_NWFILTER
|
||||
libvirtd_LDADD += ../src/libvirt_driver_nwfilter.la
|
||||
endif
|
||||
endif
|
||||
|
||||
libvirtd_LDADD += ../src/libvirt.la
|
||||
|
||||
if HAVE_POLKIT
|
||||
if HAVE_POLKIT0
|
||||
policydir = $(datadir)/PolicyKit/policy
|
||||
policyfile = libvirtd.policy-0
|
||||
else
|
||||
policydir = $(datadir)/polkit-1/actions
|
||||
policyfile = libvirtd.policy-1
|
||||
endif
|
||||
endif
|
||||
|
||||
install-data-local: install-init-redhat install-init-systemd install-init-upstart \
|
||||
install-data-sasl install-data-polkit \
|
||||
install-logrotate install-sysctl
|
||||
$(MKDIR_P) $(DESTDIR)$(localstatedir)/log/libvirt \
|
||||
$(DESTDIR)$(localstatedir)/run/libvirt \
|
||||
$(DESTDIR)$(localstatedir)/lib/libvirt
|
||||
|
||||
uninstall-local:: uninstall-init-redhat uninstall-init-systemd uninstall-init-upstart \
|
||||
uninstall-data-sasl uninstall-data-polkit \
|
||||
uninstall-logrotate uninstall-sysctl
|
||||
rmdir $(DESTDIR)$(localstatedir)/log/libvirt || :
|
||||
rmdir $(DESTDIR)$(localstatedir)/run/libvirt || :
|
||||
rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || :
|
||||
|
||||
if HAVE_POLKIT
|
||||
install-data-polkit::
|
||||
$(MKDIR_P) $(DESTDIR)$(policydir)
|
||||
$(INSTALL_DATA) $(srcdir)/$(policyfile) $(DESTDIR)$(policydir)/org.libvirt.unix.policy
|
||||
uninstall-data-polkit::
|
||||
rm -f $(DESTDIR)$(policydir)/org.libvirt.unix.policy
|
||||
rmdir $(DESTDIR)$(policydir) || :
|
||||
else
|
||||
install-data-polkit::
|
||||
uninstall-data-polkit::
|
||||
endif
|
||||
|
||||
remote.c: $(DAEMON_GENERATED)
|
||||
remote.h: $(DAEMON_GENERATED)
|
||||
|
||||
LOGROTATE_CONFS = libvirtd.qemu.logrotate libvirtd.lxc.logrotate \
|
||||
libvirtd.uml.logrotate libvirtd.logrotate
|
||||
|
||||
BUILT_SOURCES += $(LOGROTATE_CONFS)
|
||||
|
||||
libvirtd.logrotate: libvirtd.logrotate.in
|
||||
sed \
|
||||
-e 's![@]localstatedir[@]!$(localstatedir)!g' \
|
||||
< $< > $@-t
|
||||
mv $@-t $@
|
||||
|
||||
libvirtd.qemu.logrotate: libvirtd.qemu.logrotate.in
|
||||
sed \
|
||||
-e 's![@]localstatedir[@]!$(localstatedir)!g' \
|
||||
< $< > $@-t
|
||||
mv $@-t $@
|
||||
|
||||
libvirtd.lxc.logrotate: libvirtd.lxc.logrotate.in
|
||||
$(AM_V_GEN)sed \
|
||||
-e 's![@]localstatedir[@]!$(localstatedir)!g' \
|
||||
< $< > $@-t && \
|
||||
mv $@-t $@
|
||||
|
||||
libvirtd.uml.logrotate: libvirtd.uml.logrotate.in
|
||||
$(AM_V_GEN)sed \
|
||||
-e 's![@]localstatedir[@]!$(localstatedir)!g' \
|
||||
< $< > $@-t && \
|
||||
mv $@-t $@
|
||||
|
||||
install-logrotate: $(LOGROTATE_CONFS)
|
||||
$(MKDIR_P) $(DESTDIR)$(localstatedir)/log/libvirt/qemu/ \
|
||||
$(DESTDIR)$(localstatedir)/log/libvirt/lxc/ \
|
||||
$(DESTDIR)$(localstatedir)/log/libvirt/uml/ \
|
||||
$(DESTDIR)$(sysconfdir)/logrotate.d/
|
||||
$(INSTALL_DATA) libvirtd.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd
|
||||
$(INSTALL_DATA) libvirtd.qemu.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.qemu
|
||||
$(INSTALL_DATA) libvirtd.lxc.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc
|
||||
$(INSTALL_DATA) libvirtd.uml.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
|
||||
|
||||
uninstall-logrotate:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd \
|
||||
$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.qemu \
|
||||
$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc \
|
||||
$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
|
||||
rmdir $(DESTDIR)$(localstatedir)/log/libvirt/qemu || :
|
||||
rmdir $(DESTDIR)$(localstatedir)/log/libvirt/lxc || :
|
||||
rmdir $(DESTDIR)$(localstatedir)/log/libvirt/uml || :
|
||||
rmdir $(DESTDIR)$(sysconfdir)/logrotate.d || :
|
||||
|
||||
install-sysconfig:
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/sysconfig
|
||||
$(INSTALL_DATA) $(srcdir)/libvirtd.sysconf \
|
||||
$(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
|
||||
uninstall-sysconfig:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
|
||||
rmdir $(DESTDIR)$(sysconfdir)/sysconfig || :
|
||||
|
||||
if WITH_SYSCTL
|
||||
install-sysctl:
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/sysctl.d
|
||||
$(INSTALL_DATA) $(srcdir)/libvirtd.sysctl \
|
||||
$(DESTDIR)$(sysconfdir)/sysctl.d/libvirtd
|
||||
|
||||
uninstall-sysctl:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/sysctl.d/libvirtd
|
||||
rmdir $(DESTDIR)$(sysconfdir)/sysctl.d || :
|
||||
else
|
||||
install-sysctl:
|
||||
uninstall-sysctl:
|
||||
endif
|
||||
|
||||
if LIBVIRT_INIT_SCRIPT_RED_HAT
|
||||
|
||||
BUILT_SOURCES += libvirtd.init
|
||||
|
||||
install-init-redhat: install-sysconfig libvirtd.init
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/rc.d/init.d
|
||||
$(INSTALL_SCRIPT) libvirtd.init \
|
||||
$(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
|
||||
|
||||
uninstall-init-redhat: uninstall-sysconfig
|
||||
rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
|
||||
rmdir $(DESTDIR)$(sysconfdir)/rc.d/init.d || :
|
||||
else
|
||||
install-init-redhat:
|
||||
uninstall-init-redhat:
|
||||
endif # LIBVIRT_INIT_SCRIPT_RED_HAT
|
||||
|
||||
|
||||
if LIBVIRT_INIT_SCRIPT_UPSTART
|
||||
|
||||
install-init-upstart: install-sysconfig
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/event.d
|
||||
$(INSTALL_SCRIPT) libvirtd.upstart \
|
||||
$(DESTDIR)$(sysconfdir)/event.d/libvirtd
|
||||
|
||||
uninstall-init-upstart: uninstall-sysconfig
|
||||
rm -f $(DESTDIR)$(sysconfdir)/event.d/libvirtd
|
||||
rmdir $(DESTDIR)$(sysconfdir)/event.d || :
|
||||
else
|
||||
install-init-upstart:
|
||||
uninstall-init-upstart:
|
||||
endif # LIBVIRT_INIT_SCRIPT_UPSTART
|
||||
|
||||
|
||||
EXTRA_DIST += libvirtd.service.in
|
||||
if LIBVIRT_INIT_SCRIPT_SYSTEMD
|
||||
|
||||
SYSTEMD_UNIT_DIR = /lib/systemd/system
|
||||
BUILT_SOURCES += libvirtd.service
|
||||
|
||||
install-init-systemd: install-sysconfig libvirtd.service
|
||||
$(MKDIR_P) $(DESTDIR)$(SYSTEMD_UNIT_DIR)
|
||||
$(INSTALL_DATA) libvirtd.service \
|
||||
$(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
|
||||
|
||||
uninstall-init-systemd: uninstall-sysconfig
|
||||
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
|
||||
rmdir $(DESTDIR)$(SYSTEMD_UNIT_DIR) || :
|
||||
else
|
||||
install-init-systemd:
|
||||
uninstall-init-systemd:
|
||||
endif # LIBVIRT_INIT_SCRIPT_SYSTEMD
|
||||
|
||||
libvirtd.init: libvirtd.init.in $(top_builddir)/config.status
|
||||
$(AM_V_GEN)sed \
|
||||
-e s!\@localstatedir\@!$(localstatedir)!g \
|
||||
-e s!\@sbindir\@!$(sbindir)!g \
|
||||
-e s!\@sysconfdir\@!$(sysconfdir)!g \
|
||||
< $< > $@-t && \
|
||||
chmod a+x $@-t && \
|
||||
mv $@-t $@
|
||||
|
||||
libvirtd.service: libvirtd.service.in $(top_builddir)/config.status
|
||||
$(AM_V_GEN)sed \
|
||||
-e s!\@localstatedir\@!$(localstatedir)!g \
|
||||
-e s!\@sbindir\@!$(sbindir)!g \
|
||||
-e s!\@sysconfdir\@!$(sysconfdir)!g \
|
||||
< $< > $@-t && \
|
||||
chmod a+x $@-t && \
|
||||
mv $@-t $@
|
||||
|
||||
|
||||
check-local:
|
||||
$(AM_V_GEN)if test -x '$(AUGPARSE)'; then \
|
||||
'$(AUGPARSE)' -I $(srcdir) $(srcdir)/test_libvirtd.aug; \
|
||||
fi
|
||||
|
||||
|
||||
# This must be added last, since functions it provides/replaces
|
||||
# are used by nearly every other library.
|
||||
libvirtd_LDADD += ../gnulib/lib/libgnu.la $(LIBSOCKET)
|
||||
|
||||
else # WITH_LIBVIRTD
|
||||
install-data-local: install-data-sasl
|
||||
uninstall-local:: uninstall-data-sasl
|
||||
endif # WITH_LIBVIRTD
|
||||
|
||||
POD2MAN = pod2man -c "Virtualization Support" \
|
||||
-r "$(PACKAGE)-$(VERSION)" -s 8
|
||||
|
||||
$(srcdir)/libvirtd.8.in: libvirtd.pod.in
|
||||
$(AM_V_GEN)$(POD2MAN) $< $@
|
||||
|
||||
# This is needed for clients too, so can't wrap in
|
||||
# the WITH_LIBVIRTD conditional
|
||||
if HAVE_SASL
|
||||
install-data-sasl:
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/sasl2/
|
||||
$(INSTALL_DATA) $(srcdir)/libvirtd.sasl $(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
|
||||
|
||||
uninstall-data-sasl:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
|
||||
rmdir $(DESTDIR)$(sysconfdir)/sasl2/ || :
|
||||
else
|
||||
install-data-sasl:
|
||||
uninstall-data-sasl:
|
||||
endif
|
||||
|
||||
|
||||
CLEANFILES += $(BUILT_SOURCES) $(man8_MANS)
|
||||
CLEANFILES += *.cov *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda
|
||||
MAINTAINERCLEANFILES = $(srcdir)/libvirtd.8.in $(DAEMON_GENERATED)
|
@ -1,52 +0,0 @@
|
||||
|
||||
Threading in the libvirtd daemon
|
||||
================================
|
||||
|
||||
To allow efficient processing of RPC requests, the libvirtd daemon
|
||||
makes use of threads.
|
||||
|
||||
- The process leader. This is the initial thread of control
|
||||
when the daemon starts running. It is responsible for
|
||||
initializing all the state, and starting the event loop.
|
||||
Once that's all done, this thread does nothing except
|
||||
wait for the event loop to quit, thus indicating an orderly
|
||||
shutdown is required.
|
||||
|
||||
- The event loop. This thread runs the event loop, sitting
|
||||
in poll() on all monitored file handles, and calculating
|
||||
and dispatching any timers that may be registered. When
|
||||
this thread quits, the entire daemon will shutdown.
|
||||
|
||||
- The workers. These 'n' threads all sit around waiting to
|
||||
process incoming RPC requests. Since RPC requests may take
|
||||
a long time to complete, with long idle periods, there will
|
||||
be quite a few workers running.
|
||||
|
||||
The use of threads obviously requires locking to ensure safety when
|
||||
accessing/changing data structures.
|
||||
|
||||
- the top level lock is on 'struct qemud_server'. This must be
|
||||
held before acquiring any other lock
|
||||
|
||||
- Each 'struct qemud_client' object has a lock. The server lock
|
||||
must be held before acquiring it. Once the client lock is acquired
|
||||
the server lock can (optionally) be dropped.
|
||||
|
||||
- The event loop has its own self-contained lock. You can ignore
|
||||
this as a caller of virEvent APIs.
|
||||
|
||||
|
||||
The server lock is used in conjunction with a condition variable
|
||||
to pass jobs from the event loop thread to the workers. The main
|
||||
event loop thread handles I/O from the client socket, and once a
|
||||
complete RPC message has been read off the wire (and optionally
|
||||
decrypted), it will be placed onto the 'dx' job queue for the
|
||||
associated client object. The job condition will be signalled and
|
||||
a worker will wakup and process it.
|
||||
|
||||
The worker thread must quickly drop its locks on the server and
|
||||
client to allow the main event loop thread to continue running
|
||||
with its other work. Critically important, is that now libvirt
|
||||
API call will ever be made with the server or client locks held.
|
||||
|
||||
-- End
|
@ -1,97 +0,0 @@
|
||||
(* /etc/libvirt/libvirtd.conf *)
|
||||
|
||||
module Libvirtd =
|
||||
autoload xfm
|
||||
|
||||
let eol = del /[ \t]*\n/ "\n"
|
||||
let value_sep = del /[ \t]*=[ \t]*/ " = "
|
||||
let indent = del /[ \t]*/ ""
|
||||
|
||||
let array_sep = del /,[ \t\n]*/ ", "
|
||||
let array_start = del /\[[ \t\n]*/ "[ "
|
||||
let array_end = del /\]/ "]"
|
||||
|
||||
let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\""
|
||||
let bool_val = store /0|1/
|
||||
let int_val = store /[0-9]+/
|
||||
let str_array_element = [ seq "el" . str_val ] . del /[ \t\n]*/ ""
|
||||
let str_array_val = counter "el" . array_start . ( str_array_element . ( array_sep . str_array_element ) * ) ? . array_end
|
||||
|
||||
let str_entry (kw:string) = [ key kw . value_sep . str_val ]
|
||||
let bool_entry (kw:string) = [ key kw . value_sep . bool_val ]
|
||||
let int_entry (kw:string) = [ key kw . value_sep . int_val ]
|
||||
let str_array_entry (kw:string) = [ key kw . value_sep . str_array_val ]
|
||||
|
||||
|
||||
(* Config entry grouped by function - same order as example config *)
|
||||
let network_entry = bool_entry "listen_tls"
|
||||
| bool_entry "listen_tcp"
|
||||
| str_entry "tls_port"
|
||||
| str_entry "tcp_port"
|
||||
| str_entry "listen_addr"
|
||||
| bool_entry "mdns_adv"
|
||||
| str_entry "mdns_name"
|
||||
|
||||
let sock_acl_entry = str_entry "unix_sock_group"
|
||||
| str_entry "unix_sock_ro_perms"
|
||||
| str_entry "unix_sock_rw_perms"
|
||||
| str_entry "unix_sock_dir"
|
||||
|
||||
let authentication_entry = str_entry "auth_unix_ro"
|
||||
| str_entry "auth_unix_rw"
|
||||
| str_entry "auth_tcp"
|
||||
| str_entry "auth_tls"
|
||||
|
||||
let certificate_entry = str_entry "key_file"
|
||||
| str_entry "cert_file"
|
||||
| str_entry "ca_file"
|
||||
| str_entry "crl_file"
|
||||
|
||||
let authorization_entry = bool_entry "tls_no_verify_certificate"
|
||||
| bool_entry "tls_no_sanity_certificate"
|
||||
| str_array_entry "tls_allowed_dn_list"
|
||||
| str_array_entry "sasl_allowed_username_list"
|
||||
|
||||
let processing_entry = int_entry "min_workers"
|
||||
| int_entry "max_workers"
|
||||
| int_entry "max_clients"
|
||||
| int_entry "max_requests"
|
||||
| int_entry "max_client_requests"
|
||||
| int_entry "prio_workers"
|
||||
|
||||
let logging_entry = int_entry "log_level"
|
||||
| str_entry "log_filters"
|
||||
| str_entry "log_outputs"
|
||||
| int_entry "log_buffer_size"
|
||||
|
||||
let auditing_entry = int_entry "audit_level"
|
||||
| bool_entry "audit_logging"
|
||||
|
||||
let keepalive_entry = int_entry "keepalive_interval"
|
||||
| int_entry "keepalive_count"
|
||||
| bool_entry "keepalive_required"
|
||||
|
||||
let misc_entry = str_entry "host_uuid"
|
||||
|
||||
(* Each enty in the config is one of the following three ... *)
|
||||
let entry = network_entry
|
||||
| sock_acl_entry
|
||||
| authentication_entry
|
||||
| certificate_entry
|
||||
| authorization_entry
|
||||
| processing_entry
|
||||
| logging_entry
|
||||
| auditing_entry
|
||||
| keepalive_entry
|
||||
| misc_entry
|
||||
let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
|
||||
let empty = [ label "#empty" . eol ]
|
||||
|
||||
let record = indent . entry . eol
|
||||
|
||||
let lns = ( record | comment | empty ) *
|
||||
|
||||
let filter = incl "/etc/libvirt/libvirtd.conf"
|
||||
. Util.stdexcl
|
||||
|
||||
let xfm = transform lns filter
|
1659
daemon/libvirtd.c
1659
daemon/libvirtd.c
File diff suppressed because it is too large
Load Diff
@ -1,392 +0,0 @@
|
||||
# Master libvirt daemon configuration file
|
||||
#
|
||||
# For further information consult http://libvirt.org/format.html
|
||||
#
|
||||
# NOTE: the tests/daemon-conf regression test script requires
|
||||
# that each "PARAMETER = VALUE" line in this file have the parameter
|
||||
# name just after a leading "#".
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Network connectivity controls
|
||||
#
|
||||
|
||||
# Flag listening for secure TLS connections on the public TCP/IP port.
|
||||
# NB, must pass the --listen flag to the libvirtd process for this to
|
||||
# have any effect.
|
||||
#
|
||||
# It is necessary to setup a CA and issue server certificates before
|
||||
# using this capability.
|
||||
#
|
||||
# This is enabled by default, uncomment this to disable it
|
||||
#listen_tls = 0
|
||||
|
||||
# Listen for unencrypted TCP connections on the public TCP/IP port.
|
||||
# NB, must pass the --listen flag to the libvirtd process for this to
|
||||
# have any effect.
|
||||
#
|
||||
# Using the TCP socket requires SASL authentication by default. Only
|
||||
# SASL mechanisms which support data encryption are allowed. This is
|
||||
# DIGEST_MD5 and GSSAPI (Kerberos5)
|
||||
#
|
||||
# This is disabled by default, uncomment this to enable it.
|
||||
#listen_tcp = 1
|
||||
|
||||
|
||||
|
||||
# Override the port for accepting secure TLS connections
|
||||
# This can be a port number, or service name
|
||||
#
|
||||
#tls_port = "16514"
|
||||
|
||||
# Override the port for accepting insecure TCP connections
|
||||
# This can be a port number, or service name
|
||||
#
|
||||
#tcp_port = "16509"
|
||||
|
||||
|
||||
# Override the default configuration which binds to all network
|
||||
# interfaces. This can be a numeric IPv4/6 address, or hostname
|
||||
#
|
||||
#listen_addr = "192.168.0.1"
|
||||
|
||||
|
||||
# Flag toggling mDNS advertizement of the libvirt service.
|
||||
#
|
||||
# Alternatively can disable for all services on a host by
|
||||
# stopping the Avahi daemon
|
||||
#
|
||||
# This is disabled by default, uncomment this to enable it
|
||||
#mdns_adv = 1
|
||||
|
||||
# Override the default mDNS advertizement name. This must be
|
||||
# unique on the immediate broadcast network.
|
||||
#
|
||||
# The default is "Virtualization Host HOSTNAME", where HOSTNAME
|
||||
# is subsituted for the short hostname of the machine (without domain)
|
||||
#
|
||||
#mdns_name = "Virtualization Host Joe Demo"
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# UNIX socket access controls
|
||||
#
|
||||
|
||||
# Set the UNIX domain socket group ownership. This can be used to
|
||||
# allow a 'trusted' set of users access to management capabilities
|
||||
# without becoming root.
|
||||
#
|
||||
# This is restricted to 'root' by default.
|
||||
#unix_sock_group = "libvirt"
|
||||
|
||||
# Set the UNIX socket permissions for the R/O socket. This is used
|
||||
# for monitoring VM status only
|
||||
#
|
||||
# Default allows any user. If setting group ownership may want to
|
||||
# restrict this to:
|
||||
#unix_sock_ro_perms = "0777"
|
||||
|
||||
# Set the UNIX socket permissions for the R/W socket. This is used
|
||||
# for full management of VMs
|
||||
#
|
||||
# Default allows only root. If PolicyKit is enabled on the socket,
|
||||
# the default will change to allow everyone (eg, 0777)
|
||||
#
|
||||
# If not using PolicyKit and setting group ownership for access
|
||||
# control then you may want to relax this to:
|
||||
#unix_sock_rw_perms = "0770"
|
||||
|
||||
# Set the name of the directory in which sockets will be found/created.
|
||||
#unix_sock_dir = "/var/run/libvirt"
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Authentication.
|
||||
#
|
||||
# - none: do not perform auth checks. If you can connect to the
|
||||
# socket you are allowed. This is suitable if there are
|
||||
# restrictions on connecting to the socket (eg, UNIX
|
||||
# socket permissions), or if there is a lower layer in
|
||||
# the network providing auth (eg, TLS/x509 certificates)
|
||||
#
|
||||
# - sasl: use SASL infrastructure. The actual auth scheme is then
|
||||
# controlled from /etc/sasl2/libvirt.conf. For the TCP
|
||||
# socket only GSSAPI & DIGEST-MD5 mechanisms will be used.
|
||||
# For non-TCP or TLS sockets, any scheme is allowed.
|
||||
#
|
||||
# - polkit: use PolicyKit to authenticate. This is only suitable
|
||||
# for use on the UNIX sockets. The default policy will
|
||||
# require a user to supply their own password to gain
|
||||
# full read/write access (aka sudo like), while anyone
|
||||
# is allowed read/only access.
|
||||
#
|
||||
# Set an authentication scheme for UNIX read-only sockets
|
||||
# By default socket permissions allow anyone to connect
|
||||
#
|
||||
# To restrict monitoring of domains you may wish to enable
|
||||
# an authentication mechanism here
|
||||
#auth_unix_ro = "none"
|
||||
|
||||
# Set an authentication scheme for UNIX read-write sockets
|
||||
# By default socket permissions only allow root. If PolicyKit
|
||||
# support was compiled into libvirt, the default will be to
|
||||
# use 'polkit' auth.
|
||||
#
|
||||
# If the unix_sock_rw_perms are changed you may wish to enable
|
||||
# an authentication mechanism here
|
||||
#auth_unix_rw = "none"
|
||||
|
||||
# Change the authentication scheme for TCP sockets.
|
||||
#
|
||||
# If you don't enable SASL, then all TCP traffic is cleartext.
|
||||
# Don't do this outside of a dev/test scenario. For real world
|
||||
# use, always enable SASL and use the GSSAPI or DIGEST-MD5
|
||||
# mechanism in /etc/sasl2/libvirt.conf
|
||||
#auth_tcp = "sasl"
|
||||
|
||||
# Change the authentication scheme for TLS sockets.
|
||||
#
|
||||
# TLS sockets already have encryption provided by the TLS
|
||||
# layer, and limited authentication is done by certificates
|
||||
#
|
||||
# It is possible to make use of any SASL authentication
|
||||
# mechanism as well, by using 'sasl' for this option
|
||||
#auth_tls = "none"
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# TLS x509 certificate configuration
|
||||
#
|
||||
|
||||
|
||||
# Override the default server key file path
|
||||
#
|
||||
#key_file = "/etc/pki/libvirt/private/serverkey.pem"
|
||||
|
||||
# Override the default server certificate file path
|
||||
#
|
||||
#cert_file = "/etc/pki/libvirt/servercert.pem"
|
||||
|
||||
# Override the default CA certificate path
|
||||
#
|
||||
#ca_file = "/etc/pki/CA/cacert.pem"
|
||||
|
||||
# Specify a certificate revocation list.
|
||||
#
|
||||
# Defaults to not using a CRL, uncomment to enable it
|
||||
#crl_file = "/etc/pki/CA/crl.pem"
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Authorization controls
|
||||
#
|
||||
|
||||
|
||||
# Flag to disable verification of our own server certificates
|
||||
#
|
||||
# When libvirtd starts it performs some sanity checks against
|
||||
# its own certificates.
|
||||
#
|
||||
# Default is to always run sanity checks. Uncommenting this
|
||||
# will disable sanity checks which is not a good idea
|
||||
#tls_no_sanity_certificate = 1
|
||||
|
||||
# Flag to disable verification of client certificates
|
||||
#
|
||||
# Client certificate verification is the primary authentication mechanism.
|
||||
# Any client which does not present a certificate signed by the CA
|
||||
# will be rejected.
|
||||
#
|
||||
# Default is to always verify. Uncommenting this will disable
|
||||
# verification - make sure an IP whitelist is set
|
||||
#tls_no_verify_certificate = 1
|
||||
|
||||
|
||||
# A whitelist of allowed x509 Distinguished Names
|
||||
# This list may contain wildcards such as
|
||||
#
|
||||
# "C=GB,ST=London,L=London,O=Red Hat,CN=*"
|
||||
#
|
||||
# See the POSIX fnmatch function for the format of the wildcards.
|
||||
#
|
||||
# NB If this is an empty list, no client can connect, so comment out
|
||||
# entirely rather than using empty list to disable these checks
|
||||
#
|
||||
# By default, no DN's are checked
|
||||
#tls_allowed_dn_list = ["DN1", "DN2"]
|
||||
|
||||
|
||||
# A whitelist of allowed SASL usernames. The format for usernames
|
||||
# depends on the SASL authentication mechanism. Kerberos usernames
|
||||
# look like username@REALM
|
||||
#
|
||||
# This list may contain wildcards such as
|
||||
#
|
||||
# "*@EXAMPLE.COM"
|
||||
#
|
||||
# See the POSIX fnmatch function for the format of the wildcards.
|
||||
#
|
||||
# NB If this is an empty list, no client can connect, so comment out
|
||||
# entirely rather than using empty list to disable these checks
|
||||
#
|
||||
# By default, no Username's are checked
|
||||
#sasl_allowed_username_list = ["joe@EXAMPLE.COM", "fred@EXAMPLE.COM" ]
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Processing controls
|
||||
#
|
||||
|
||||
# The maximum number of concurrent client connections to allow
|
||||
# over all sockets combined.
|
||||
#max_clients = 20
|
||||
|
||||
|
||||
# The minimum limit sets the number of workers to start up
|
||||
# initially. If the number of active clients exceeds this,
|
||||
# then more threads are spawned, upto max_workers limit.
|
||||
# Typically you'd want max_workers to equal maximum number
|
||||
# of clients allowed
|
||||
#min_workers = 5
|
||||
#max_workers = 20
|
||||
|
||||
|
||||
# The number of priority workers. If all workers from above
|
||||
# pool will stuck, some calls marked as high priority
|
||||
# (notably domainDestroy) can be executed in this pool.
|
||||
#prio_workers = 5
|
||||
|
||||
# Total global limit on concurrent RPC calls. Should be
|
||||
# at least as large as max_workers. Beyond this, RPC requests
|
||||
# will be read into memory and queued. This directly impact
|
||||
# memory usage, currently each request requires 256 KB of
|
||||
# memory. So by default upto 5 MB of memory is used
|
||||
#
|
||||
# XXX this isn't actually enforced yet, only the per-client
|
||||
# limit is used so far
|
||||
#max_requests = 20
|
||||
|
||||
# Limit on concurrent requests from a single client
|
||||
# connection. To avoid one client monopolizing the server
|
||||
# this should be a small fraction of the global max_requests
|
||||
# and max_workers parameter
|
||||
#max_client_requests = 5
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Logging controls
|
||||
#
|
||||
|
||||
# Logging level: 4 errors, 3 warnings, 2 information, 1 debug
|
||||
# basically 1 will log everything possible
|
||||
#log_level = 3
|
||||
|
||||
# Logging filters:
|
||||
# A filter allows to select a different logging level for a given category
|
||||
# of logs
|
||||
# The format for a filter is:
|
||||
# x:name
|
||||
# where name is a match string e.g. remote or qemu
|
||||
# the x prefix is the minimal level where matching messages should be logged
|
||||
# 1: DEBUG
|
||||
# 2: INFO
|
||||
# 3: WARNING
|
||||
# 4: ERROR
|
||||
#
|
||||
# Multiple filter can be defined in a single @filters, they just need to be
|
||||
# separated by spaces.
|
||||
#
|
||||
# e.g. to only get warning or errors from the remote layer and only errors
|
||||
# from the event layer:
|
||||
#log_filters = "3:remote 4:event"
|
||||
|
||||
# Logging outputs:
|
||||
# An output is one of the places to save logging information
|
||||
# The format for an output can be:
|
||||
# x:stderr
|
||||
# output goes to stderr
|
||||
# x:syslog:name
|
||||
# use syslog for the output and use the given name as the ident
|
||||
# x:file:file_path
|
||||
# output to a file, with the given filepath
|
||||
# In all case the x prefix is the minimal level, acting as a filter
|
||||
# 1: DEBUG
|
||||
# 2: INFO
|
||||
# 3: WARNING
|
||||
# 4: ERROR
|
||||
#
|
||||
# Multiple output can be defined, they just need to be separated by spaces.
|
||||
# e.g. to log all warnings and errors to syslog under the libvirtd ident:
|
||||
#log_outputs = "3:syslog:libvirtd"
|
||||
#
|
||||
|
||||
# Log debug buffer size: default 64
|
||||
# The daemon keeps an internal debug log buffer which will be dumped in case
|
||||
# of crash or upon receiving a SIGUSR2 signal. This setting allows to override
|
||||
# the default buffer size in kilobytes.
|
||||
# If value is 0 or less the debug log buffer is deactivated
|
||||
#log_buffer_size = 64
|
||||
|
||||
|
||||
##################################################################
|
||||
#
|
||||
# Auditing
|
||||
#
|
||||
# This setting allows usage of the auditing subsystem to be altered:
|
||||
#
|
||||
# audit_level == 0 -> disable all auditing
|
||||
# audit_level == 1 -> enable auditing, only if enabled on host (default)
|
||||
# audit_level == 2 -> enable auditing, and exit if disabled on host
|
||||
#
|
||||
#audit_level = 2
|
||||
#
|
||||
# If set to 1, then audit messages will also be sent
|
||||
# via libvirt logging infrastructure. Defaults to 0
|
||||
#
|
||||
#audit_logging = 1
|
||||
|
||||
###################################################################
|
||||
# UUID of the host:
|
||||
# Provide the UUID of the host here in case the command
|
||||
# 'dmidecode -s system-uuid' does not provide a valid uuid. In case
|
||||
# 'dmidecode' does not provide a valid UUID and none is provided here, a
|
||||
# temporary UUID will be generated.
|
||||
# Keep the format of the example UUID below. UUID must not have all digits
|
||||
# be the same.
|
||||
|
||||
# NB This default all-zeros UUID will not work. Replace
|
||||
# it with the output of the 'uuidgen' command and then
|
||||
# uncomment this entry
|
||||
#host_uuid = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
###################################################################
|
||||
# Keepalive protocol:
|
||||
# This allows libvirtd to detect broken client connections or even
|
||||
# dead client. A keepalive message is sent to a client after
|
||||
# keepalive_interval seconds of inactivity to check if the client is
|
||||
# still responding; keepalive_count is a maximum number of keepalive
|
||||
# messages that are allowed to be sent to the client without getting
|
||||
# any response before the connection is considered broken. In other
|
||||
# words, the connection is automatically closed approximately after
|
||||
# keepalive_interval * (keepalive_count + 1) seconds since the last
|
||||
# message received from the client. If keepalive_interval is set to
|
||||
# -1, libvirtd will never send keepalive requests; however clients
|
||||
# can still send them and the deamon will send responses. When
|
||||
# keepalive_count is set to 0, connections will be automatically
|
||||
# closed after keepalive_interval seconds of inactivity without
|
||||
# sending any keepalive messages.
|
||||
#
|
||||
#keepalive_interval = 5
|
||||
#keepalive_count = 5
|
||||
#
|
||||
# If set to 1, libvirtd will refuse to talk to clients that do not
|
||||
# support keepalive protocol. Defaults to 0.
|
||||
#
|
||||
#keepalive_required = 1
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* libvirtd.h: daemon data structure definitions
|
||||
*
|
||||
* Copyright (C) 2006-2012 Red Hat, Inc.
|
||||
* Copyright (C) 2006 Daniel P. Berrange
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIBVIRTD_H__
|
||||
# define LIBVIRTD_H__
|
||||
|
||||
# define VIR_ENUM_SENTINELS
|
||||
|
||||
# include <config.h>
|
||||
|
||||
# include <rpc/types.h>
|
||||
# include <rpc/xdr.h>
|
||||
# include "remote_protocol.h"
|
||||
# include "qemu_protocol.h"
|
||||
# include "logging.h"
|
||||
# include "threads.h"
|
||||
# if HAVE_SASL
|
||||
# include "virnetsaslcontext.h"
|
||||
# endif
|
||||
# include "virnetserverprogram.h"
|
||||
|
||||
typedef struct daemonClientStream daemonClientStream;
|
||||
typedef daemonClientStream *daemonClientStreamPtr;
|
||||
typedef struct daemonClientPrivate daemonClientPrivate;
|
||||
typedef daemonClientPrivate *daemonClientPrivatePtr;
|
||||
|
||||
/* Stores the per-client connection state */
|
||||
struct daemonClientPrivate {
|
||||
/* Hold while accessing any data except conn */
|
||||
virMutex lock;
|
||||
|
||||
int domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LAST];
|
||||
|
||||
# if HAVE_SASL
|
||||
virNetSASLSessionPtr sasl;
|
||||
# endif
|
||||
|
||||
/* This is only valid if a remote open call has been made on this
|
||||
* connection, otherwise it will be NULL. Also if remote close is
|
||||
* called, it will be set back to NULL if that succeeds.
|
||||
*/
|
||||
virConnectPtr conn;
|
||||
|
||||
daemonClientStreamPtr streams;
|
||||
bool keepalive_supported;
|
||||
};
|
||||
|
||||
# if HAVE_SASL
|
||||
extern virNetSASLContextPtr saslCtxt;
|
||||
# endif
|
||||
extern virNetServerProgramPtr remoteProgram;
|
||||
extern virNetServerProgramPtr qemuProgram;
|
||||
|
||||
#endif
|
@ -1,123 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# the following is the LSB init header see
|
||||
# http://www.linux-foundation.org/spec//booksets/LSB-Core-generic/LSB-Core-generic.html#INITSCRCOMCONV
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: libvirtd
|
||||
# Required-Start: $network messagebus
|
||||
# Should-Start: $named
|
||||
# Should-Start: xend
|
||||
# Should-Start: avahi-daemon
|
||||
# Required-Stop: $network messagebus
|
||||
# Should-Stop: $named
|
||||
# Default-Start: 3 4 5
|
||||
# Short-Description: daemon for libvirt virtualization API
|
||||
# Description: This is a daemon for managing guest instances
|
||||
# and libvirt virtual networks
|
||||
# See http://libvirt.org
|
||||
### END INIT INFO
|
||||
|
||||
# the following is chkconfig init header
|
||||
#
|
||||
# libvirtd: guest and virtual network management daemon
|
||||
#
|
||||
# chkconfig: 345 97 03
|
||||
# description: This is a daemon for managing guest instances \
|
||||
# and libvirt virtual networks \
|
||||
# See http://libvirt.org
|
||||
#
|
||||
# processname: libvirtd
|
||||
# pidfile: @localstatedir@/run/libvirtd.pid
|
||||
#
|
||||
|
||||
# Source function library.
|
||||
. @sysconfdir@/rc.d/init.d/functions
|
||||
|
||||
SERVICE=libvirtd
|
||||
PROCESS=libvirtd
|
||||
PIDFILE=@localstatedir@/run/$SERVICE.pid
|
||||
|
||||
LIBVIRTD_CONFIG=
|
||||
LIBVIRTD_ARGS=
|
||||
KRB5_KTNAME=/etc/libvirt/krb5.tab
|
||||
|
||||
test -f @sysconfdir@/sysconfig/libvirtd && . @sysconfdir@/sysconfig/libvirtd
|
||||
|
||||
export QEMU_AUDIO_DRV
|
||||
export SDL_AUDIODRIVER
|
||||
|
||||
LIBVIRTD_CONFIG_ARGS=
|
||||
if [ -n "$LIBVIRTD_CONFIG" ]
|
||||
then
|
||||
LIBVIRTD_CONFIG_ARGS="--config $LIBVIRTD_CONFIG"
|
||||
fi
|
||||
|
||||
RETVAL=0
|
||||
|
||||
start() {
|
||||
echo -n $"Starting $SERVICE daemon: "
|
||||
mkdir -p @localstatedir@/cache/libvirt
|
||||
rm -rf @localstatedir@/cache/libvirt/*
|
||||
|
||||
# LIBVIRTD_NOFILES_LIMIT from /etc/sysconfig/libvirtd is not handled
|
||||
# automatically
|
||||
if [ -n "$LIBVIRTD_NOFILES_LIMIT" ]; then
|
||||
ulimit -n "$LIBVIRTD_NOFILES_LIMIT"
|
||||
fi
|
||||
|
||||
KRB5_KTNAME=$KRB5_KTNAME daemon --pidfile $PIDFILE --check $SERVICE $PROCESS --daemon $LIBVIRTD_CONFIG_ARGS $LIBVIRTD_ARGS
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && touch @localstatedir@/lock/subsys/$SERVICE
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo -n $"Stopping $SERVICE daemon: "
|
||||
|
||||
killproc -p $PIDFILE $PROCESS
|
||||
RETVAL=$?
|
||||
echo
|
||||
if [ $RETVAL -eq 0 ]; then
|
||||
rm -f @localstatedir@/lock/subsys/$SERVICE
|
||||
rm -rf @localstatedir@/cache/libvirt/*
|
||||
else
|
||||
exit $RETVAL
|
||||
fi
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
reload() {
|
||||
echo -n $"Reloading $SERVICE configuration: "
|
||||
|
||||
killproc -p $PIDFILE $PROCESS -HUP
|
||||
RETVAL=$?
|
||||
echo
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start|stop|restart|reload)
|
||||
$1
|
||||
;;
|
||||
status)
|
||||
status -p $PIDFILE $PROCESS
|
||||
RETVAL=$?
|
||||
;;
|
||||
force-reload)
|
||||
reload
|
||||
;;
|
||||
condrestart|try-restart)
|
||||
[ -f @localstatedir@/lock/subsys/$SERVICE ] && restart || :
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|force-reload|try-restart}"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
exit $RETVAL
|
@ -1,9 +0,0 @@
|
||||
@localstatedir@/log/libvirt/libvirtd.log {
|
||||
weekly
|
||||
missingok
|
||||
rotate 4
|
||||
compress
|
||||
delaycompress
|
||||
copytruncate
|
||||
minsize 100k
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
@localstatedir@/log/libvirt/lxc/*.log {
|
||||
weekly
|
||||
missingok
|
||||
rotate 4
|
||||
compress
|
||||
delaycompress
|
||||
copytruncate
|
||||
minsize 100k
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
libvirtd - libvirtd management daemon
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<libvirtd> [ -dlv ] [ -f config_file ] [ -p pid_file ] [ -t timeout_seconds ]
|
||||
|
||||
B<libvirtd> --version
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<libvirtd> program is the server side daemon component of the libvirt
|
||||
virtualization management system.
|
||||
|
||||
This daemon runs on host servers and performs required management tasks for
|
||||
virtualized guests. This includes activities such as starting, stopping
|
||||
and migrating guests between host servers, configuring and manipulating
|
||||
networking, and managing storage for use by guests.
|
||||
|
||||
The libvirt client libraries and utilities connect to this daemon to issue
|
||||
tasks and collect information about the configuration and resources of the host
|
||||
system and guests.
|
||||
|
||||
By default, the libvirtd daemon listens for requests on a local Unix domain
|
||||
socket. Using the B<-l>|B<--listen> command line option, the libvirtd daemon
|
||||
can be instructed to additionally listen on a TCP/IP socket. The TCP/IP socket
|
||||
to use is defined in the libvirtd configuration file.
|
||||
|
||||
Restarting libvirtd does not impact running guests. Guests continue to operate
|
||||
and will be picked up automatically if their XML configuration has been
|
||||
defined. Any guests whose XML configuration has not been defined will be lost
|
||||
from the configuration.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over
|
||||
|
||||
=item B<-d, --daemon>
|
||||
|
||||
Run as a daemon & write PID file.
|
||||
|
||||
=item B<-f, --config> I<FILE>
|
||||
|
||||
Use this configuration file, overriding the default value.
|
||||
|
||||
=item B<-l, --listen>
|
||||
|
||||
Listen for TCP/IP connections.
|
||||
|
||||
=item B<-p, --pid-file> I<FILE>
|
||||
|
||||
Use this name for the PID file, overriding the default value.
|
||||
|
||||
=item B<-t, --timeout> I<SECONDS>
|
||||
|
||||
Exit after timeout period (in seconds) expires.
|
||||
|
||||
=item B<-v, --verbose>
|
||||
|
||||
Enable output of verbose messages.
|
||||
|
||||
=item B< --version>
|
||||
|
||||
Display version information then exit.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SIGNALS
|
||||
|
||||
On receipt of B<SIGHUP> libvirtd will reload its configuration.
|
||||
|
||||
=head1 FILES
|
||||
|
||||
=over
|
||||
|
||||
=item F<@sysconfdir@/libvirtd.conf>
|
||||
|
||||
The default configuration file used by libvirtd, unless overridden on the
|
||||
command line using the B<-f>|B<--config> option.
|
||||
|
||||
=item F<@localstatedir@/run/libvirt/libvirt-sock>
|
||||
|
||||
=item F<@localstatedir@/run/libvirt/libvirt-sock-ro>
|
||||
|
||||
The sockets libvirtd will use when B<run as root>.
|
||||
|
||||
=item F<$HOME/.libvirt/libvirt-sock>
|
||||
|
||||
The socket libvirtd will use when run as a B<non-root> user.
|
||||
|
||||
=item F<@sysconfdir@/pki/CA/cacert.pem>
|
||||
|
||||
The TLS B<Certificate Authority> certificate libvirtd will use.
|
||||
|
||||
=item F<@sysconfdir@/pki/libvirt/servercert.pem>
|
||||
|
||||
The TLS B<Server> certificate libvirtd will use.
|
||||
|
||||
=item F<@sysconfdir@/pki/libvirt/private/serverkey.pem>
|
||||
|
||||
The TLS B<Server> private key libvirtd will use.
|
||||
|
||||
=item F<@remote_pid_file@>
|
||||
|
||||
The PID file to use, unless overridden by the B<-p>|B<--pid-file> option.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
To retrieve the version of libvirtd:
|
||||
|
||||
# libvirtd --version
|
||||
libvirtd (libvirt) 0.8.2
|
||||
#
|
||||
|
||||
To start libvirtd, instructing it to daemonize and create a PID file:
|
||||
|
||||
# libvirtd -d
|
||||
# ls -la @remote_pid_file@
|
||||
-rw-r--r-- 1 root root 6 Jul 9 02:40 @remote_pid_file@
|
||||
#
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please report all bugs you discover. This should be done via either:
|
||||
|
||||
=over
|
||||
|
||||
=item a) the mailing list
|
||||
|
||||
L<http://libvirt.org/contact.html>
|
||||
|
||||
=item or,
|
||||
|
||||
B<>
|
||||
|
||||
=item b) the bug tracker
|
||||
|
||||
L<http://libvirt.org/bugs.html>
|
||||
|
||||
=item Alternatively, you may report bugs to your software distributor / vendor.
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Please refer to the AUTHORS file distributed with libvirt.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2006-2010 Red Hat, Inc., and the authors listed in the
|
||||
libvirt AUTHORS file.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
libvirtd is distributed under the terms of the GNU LGPL v2.1+.
|
||||
This is free software; see the source for copying conditions. There
|
||||
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<virsh(1)>, L<virt-install(1)>, L<virt-xml-validate(1)>, L<virt-top(1)>,
|
||||
L<virt-df(1)>, L<http://www.libvirt.org/>
|
||||
|
||||
=cut
|
@ -1,42 +0,0 @@
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
|
||||
<!--
|
||||
Policy definitions for libvirt daemon
|
||||
|
||||
Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
|
||||
|
||||
libvirt is licensed to you under the GNU Lesser General Public License
|
||||
version 2. See COPYING for details.
|
||||
|
||||
NOTE: If you make changes to this file, make sure to validate the file
|
||||
using the polkit-policy-file-validate(1) tool. Changes made to this
|
||||
file are instantly applied.
|
||||
-->
|
||||
|
||||
<policyconfig>
|
||||
<action id="org.libvirt.unix.monitor">
|
||||
<description>Monitor local virtualized systems</description>
|
||||
<message>System policy prevents monitoring of local virtualized systems</message>
|
||||
<defaults>
|
||||
<!-- Any program can use libvirt in read-only mode for monitoring,
|
||||
even if not part of a session -->
|
||||
<allow_any>yes</allow_any>
|
||||
<allow_inactive>yes</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.libvirt.unix.manage">
|
||||
<description>Manage local virtualized systems</description>
|
||||
<message>System policy prevents management of local virtualized systems</message>
|
||||
<defaults>
|
||||
<!-- Only a program in the active host session can use libvirt in
|
||||
read-write mode for management, and we require user password -->
|
||||
<allow_any>auth_admin</allow_any>
|
||||
<allow_inactive>auth_admin</allow_inactive>
|
||||
<allow_active>auth_admin_keep_session</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
</policyconfig>
|
@ -1,42 +0,0 @@
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
|
||||
<!--
|
||||
Policy definitions for libvirt daemon
|
||||
|
||||
Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
|
||||
|
||||
libvirt is licensed to you under the GNU Lesser General Public License
|
||||
version 2. See COPYING for details.
|
||||
|
||||
NOTE: If you make changes to this file, make sure to validate the file
|
||||
using the polkit-policy-file-validate(1) tool. Changes made to this
|
||||
file are instantly applied.
|
||||
-->
|
||||
|
||||
<policyconfig>
|
||||
<action id="org.libvirt.unix.monitor">
|
||||
<description>Monitor local virtualized systems</description>
|
||||
<message>System policy prevents monitoring of local virtualized systems</message>
|
||||
<defaults>
|
||||
<!-- Any program can use libvirt in read-only mode for monitoring,
|
||||
even if not part of a session -->
|
||||
<allow_any>yes</allow_any>
|
||||
<allow_inactive>yes</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.libvirt.unix.manage">
|
||||
<description>Manage local virtualized systems</description>
|
||||
<message>System policy prevents management of local virtualized systems</message>
|
||||
<defaults>
|
||||
<!-- Only a program in the active host session can use libvirt in
|
||||
read-write mode for management, and we require user password -->
|
||||
<allow_any>auth_admin</allow_any>
|
||||
<allow_inactive>auth_admin</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
</policyconfig>
|
@ -1,9 +0,0 @@
|
||||
@localstatedir@/log/libvirt/qemu/*.log {
|
||||
weekly
|
||||
missingok
|
||||
rotate 4
|
||||
compress
|
||||
delaycompress
|
||||
copytruncate
|
||||
minsize 100k
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
# If you want to use the non-TLS socket, then you *must* include
|
||||
# the GSSAPI or DIGEST-MD5 mechanisms, because they are the only
|
||||
# ones that can offer session encryption as well as authentication.
|
||||
#
|
||||
# If you're only using TLS, then you can turn on any mechanisms
|
||||
# you like for authentication, because TLS provides the encryption
|
||||
#
|
||||
# Default to a simple username+password mechanism
|
||||
mech_list: digest-md5
|
||||
|
||||
# Before you can use GSSAPI, you need a service principle on the
|
||||
# KDC server for libvirt, and that to be exported to the keytab
|
||||
# file listed below
|
||||
#mech_list: gssapi
|
||||
#
|
||||
# You can also list many mechanisms at once, then the user can choose
|
||||
# by adding '?auth=sasl.gssapi' to their libvirt URI, eg
|
||||
# qemu+tcp://hostname/system?auth=sasl.gssapi
|
||||
#mech_list: digest-md5 gssapi
|
||||
|
||||
# Some older builds of MIT kerberos on Linux ignore this option &
|
||||
# instead need KRB5_KTNAME env var.
|
||||
# For modern Linux, and other OS, this should be sufficient
|
||||
#
|
||||
# There is no default value here, uncomment if you need this
|
||||
#keytab: /etc/libvirt/krb5.tab
|
||||
|
||||
# If using digest-md5 for username/passwds, then this is the file
|
||||
# containing the passwds. Use 'saslpasswd2 -a libvirt [username]'
|
||||
# to add entries, and 'sasldblistusers2 -a libvirt' to browse it
|
||||
sasldb_path: /etc/libvirt/passwd.db
|
@ -1,20 +0,0 @@
|
||||
# NB we don't use socket activation. When libvirtd starts it will
|
||||
# spawn any virtual machines registered for autostart. We want this
|
||||
# to occur on every boot, regardless of whether any client connects
|
||||
# to a socket. Thus socket activation doesn't have any benefit
|
||||
|
||||
[Unit]
|
||||
Description=Virtualization daemon
|
||||
Before=libvirt-guests.service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=-/etc/sysconfig/libvirtd
|
||||
ExecStart=@sbindir@/libvirtd $LIBVIRTD_ARGS
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
# Override the maximum number of opened files
|
||||
#LimitNOFILE=2048
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -1,24 +0,0 @@
|
||||
# Override the default config file
|
||||
# NOTE: This setting is no longer honoured if using
|
||||
# systemd. Set '--config /etc/libvirt/libvirtd.conf'
|
||||
# in LIBVIRTD_ARGS instead.
|
||||
#LIBVIRTD_CONFIG=/etc/libvirt/libvirtd.conf
|
||||
|
||||
# Listen for TCP/IP connections
|
||||
# NB. must setup TLS/SSL keys prior to using this
|
||||
#LIBVIRTD_ARGS="--listen"
|
||||
|
||||
# Override Kerberos service keytab for SASL/GSSAPI
|
||||
#KRB5_KTNAME=/etc/libvirt/krb5.tab
|
||||
|
||||
# Override the QEMU/SDL default audio driver probing when
|
||||
# starting virtual machines using SDL graphics
|
||||
#
|
||||
# NB these have no effect for VMs using VNC, unless vnc_allow_host_audio
|
||||
# is enabled in /etc/libvirt/qemu.conf
|
||||
#QEMU_AUDIO_DRV=sdl
|
||||
#
|
||||
#SDL_AUDIODRIVER=pulse
|
||||
|
||||
# Override the maximum number of opened files
|
||||
#LIBVIRTD_NOFILES_LIMIT=2048
|
@ -1,8 +0,0 @@
|
||||
# The kernel allocates aio memory on demand, and this number limits the
|
||||
# number of parallel aio requests; the only drawback of a larger limit is
|
||||
# that a malicious guest could issue parallel requests to cause the kernel
|
||||
# to set aside memory. Set this number at least as large as
|
||||
# 128 * (number of virtual disks on the host)
|
||||
# Libvirt uses a default of 1M requests to allow 8k disks, with at most
|
||||
# 64M of kernel memory if all disks hit an aio request at the same time.
|
||||
fs.aio-max-nr = 1048576
|
@ -1,9 +0,0 @@
|
||||
@localstatedir@/log/libvirt/uml/*.log {
|
||||
weekly
|
||||
missingok
|
||||
rotate 4
|
||||
compress
|
||||
delaycompress
|
||||
copytruncate
|
||||
minsize 100k
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
# libvirtd upstart job
|
||||
#
|
||||
# XXX wait for rc to get all dependent initscripts started
|
||||
# from sysv libvirtd initscript: Required-Start: $network messagebus
|
||||
start on stopped rc RUNLEVEL=[345]
|
||||
stop on runlevel [!345]
|
||||
|
||||
respawn
|
||||
|
||||
script
|
||||
LIBVIRTD_CONFIG=
|
||||
LIBVIRTD_ARGS=
|
||||
KRB5_KTNAME=/etc/libvirt/krb5.tab
|
||||
|
||||
if [ -f /etc/sysconfig/libvirtd ]; then
|
||||
. /etc/sysconfig/libvirtd
|
||||
fi
|
||||
|
||||
export QEMU_AUDIO_DRV
|
||||
export SDL_AUDIODRIVER
|
||||
export KRB5_KTNAME
|
||||
|
||||
LIBVIRTD_CONFIG_ARGS=
|
||||
if [ -n "$LIBVIRTD_CONFIG" ]; then
|
||||
LIBVIRTD_CONFIG_ARGS="--config $LIBVIRTD_CONFIG"
|
||||
fi
|
||||
|
||||
# DAEMON_COREFILE_LIMIT from /etc/sysconfig/libvirtd is not handled
|
||||
# automatically
|
||||
if [ -n "$DAEMON_COREFILE_LIMIT" ]; then
|
||||
ulimit -c "$DAEMON_COREFILE_LIMIT"
|
||||
fi
|
||||
|
||||
# LIBVIRTD_NOFILES_LIMIT from /etc/sysconfig/libvirtd is not handled
|
||||
# automatically
|
||||
if [ -n "$LIBVIRTD_NOFILES_LIMIT" ]; then
|
||||
ulimit -n "$LIBVIRTD_NOFILES_LIMIT"
|
||||
fi
|
||||
mkdir -p /var/cache/libvirt
|
||||
rm -rf /var/cache/libvirt/*
|
||||
|
||||
exec /usr/sbin/libvirtd $LIBVIRTD_CONFIG_ARGS $LIBVIRTD_ARGS
|
||||
end script
|
||||
|
||||
post-stop script
|
||||
rm -rf /var/cache/libvirt/*
|
||||
end script
|
3905
daemon/remote.c
3905
daemon/remote.c
File diff suppressed because it is too large
Load Diff
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* remote.h: handlers for RPC method calls
|
||||
*
|
||||
* Copyright (C) 2007, 2008, 2009 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Richard W.M. Jones <rjones@redhat.com>
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __LIBVIRTD_REMOTE_H__
|
||||
# define __LIBVIRTD_REMOTE_H__
|
||||
|
||||
# include "remote_protocol.h"
|
||||
# include "rpc/virnetserverprogram.h"
|
||||
# include "rpc/virnetserverclient.h"
|
||||
|
||||
|
||||
extern virNetServerProgramProc remoteProcs[];
|
||||
extern size_t remoteNProcs;
|
||||
|
||||
extern virNetServerProgramProc qemuProcs[];
|
||||
extern size_t qemuNProcs;
|
||||
|
||||
int remoteClientInitHook(virNetServerPtr srv,
|
||||
virNetServerClientPtr client);
|
||||
|
||||
#endif /* __LIBVIRTD_REMOTE_H__ */
|
782
daemon/stream.c
782
daemon/stream.c
@ -1,782 +0,0 @@
|
||||
/*
|
||||
* stream.c: APIs for managing client streams
|
||||
*
|
||||
* Copyright (C) 2009, 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "stream.h"
|
||||
#include "remote.h"
|
||||
#include "memory.h"
|
||||
#include "logging.h"
|
||||
#include "virnetserverclient.h"
|
||||
#include "virterror_internal.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_STREAMS
|
||||
|
||||
#define virNetError(code, ...) \
|
||||
virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
|
||||
__FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
|
||||
struct daemonClientStream {
|
||||
daemonClientPrivatePtr priv;
|
||||
int refs;
|
||||
|
||||
virNetServerProgramPtr prog;
|
||||
|
||||
virStreamPtr st;
|
||||
int procedure;
|
||||
int serial;
|
||||
|
||||
unsigned int recvEOF : 1;
|
||||
unsigned int closed : 1;
|
||||
|
||||
int filterID;
|
||||
|
||||
virNetMessagePtr rx;
|
||||
int tx;
|
||||
|
||||
daemonClientStreamPtr next;
|
||||
};
|
||||
|
||||
static int
|
||||
daemonStreamHandleWrite(virNetServerClientPtr client,
|
||||
daemonClientStream *stream);
|
||||
static int
|
||||
daemonStreamHandleRead(virNetServerClientPtr client,
|
||||
daemonClientStream *stream);
|
||||
static int
|
||||
daemonStreamHandleFinish(virNetServerClientPtr client,
|
||||
daemonClientStream *stream,
|
||||
virNetMessagePtr msg);
|
||||
static int
|
||||
daemonStreamHandleAbort(virNetServerClientPtr client,
|
||||
daemonClientStream *stream,
|
||||
virNetMessagePtr msg);
|
||||
|
||||
|
||||
|
||||
static void
|
||||
daemonStreamUpdateEvents(daemonClientStream *stream)
|
||||
{
|
||||
int newEvents = 0;
|
||||
if (stream->rx)
|
||||
newEvents |= VIR_STREAM_EVENT_WRITABLE;
|
||||
if (stream->tx && !stream->recvEOF)
|
||||
newEvents |= VIR_STREAM_EVENT_READABLE;
|
||||
|
||||
virStreamEventUpdateCallback(stream->st, newEvents);
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoked when an outgoing data packet message has been fully sent.
|
||||
* This simply re-enables TX of further data.
|
||||
*
|
||||
* The idea is to stop the daemon growing without bound due to
|
||||
* fast stream, but slow client
|
||||
*/
|
||||
static void
|
||||
daemonStreamMessageFinished(virNetMessagePtr msg ATTRIBUTE_UNUSED,
|
||||
void *opaque)
|
||||
{
|
||||
daemonClientStream *stream = opaque;
|
||||
VIR_DEBUG("stream=%p proc=%d serial=%d",
|
||||
stream, msg->header.proc, msg->header.serial);
|
||||
|
||||
stream->tx = 1;
|
||||
daemonStreamUpdateEvents(stream);
|
||||
|
||||
daemonFreeClientStream(NULL, stream);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
daemonStreamEventFreeFunc(void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
|
||||
virNetServerClientFree(client);
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback that gets invoked when a stream becomes writable/readable
|
||||
*/
|
||||
static void
|
||||
daemonStreamEvent(virStreamPtr st, int events, void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
daemonClientStream *stream;
|
||||
daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
|
||||
|
||||
virMutexLock(&priv->lock);
|
||||
|
||||
stream = priv->streams;
|
||||
while (stream) {
|
||||
if (stream->st == st)
|
||||
break;
|
||||
stream = stream->next;
|
||||
}
|
||||
|
||||
if (!stream) {
|
||||
VIR_WARN("event for client=%p stream st=%p, but missing stream state", client, st);
|
||||
virStreamEventRemoveCallback(st);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
VIR_DEBUG("st=%p events=%d EOF=%d closed=%d", st, events, stream->recvEOF, stream->closed);
|
||||
|
||||
if (!stream->closed &&
|
||||
(events & VIR_STREAM_EVENT_WRITABLE)) {
|
||||
if (daemonStreamHandleWrite(client, stream) < 0) {
|
||||
daemonRemoveClientStream(client, stream);
|
||||
virNetServerClientClose(client);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream->closed && !stream->recvEOF &&
|
||||
(events & (VIR_STREAM_EVENT_READABLE))) {
|
||||
events = events & ~(VIR_STREAM_EVENT_READABLE);
|
||||
if (daemonStreamHandleRead(client, stream) < 0) {
|
||||
daemonRemoveClientStream(client, stream);
|
||||
virNetServerClientClose(client);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have a completion/abort message, always process it */
|
||||
if (stream->rx) {
|
||||
virNetMessagePtr msg = stream->rx;
|
||||
switch (msg->header.status) {
|
||||
case VIR_NET_CONTINUE:
|
||||
/* nada */
|
||||
break;
|
||||
case VIR_NET_OK:
|
||||
virNetMessageQueueServe(&stream->rx);
|
||||
if (daemonStreamHandleFinish(client, stream, msg) < 0) {
|
||||
virNetMessageFree(msg);
|
||||
daemonRemoveClientStream(client, stream);
|
||||
virNetServerClientClose(client);
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
case VIR_NET_ERROR:
|
||||
default:
|
||||
virNetMessageQueueServe(&stream->rx);
|
||||
if (daemonStreamHandleAbort(client, stream, msg) < 0) {
|
||||
virNetMessageFree(msg);
|
||||
daemonRemoveClientStream(client, stream);
|
||||
virNetServerClientClose(client);
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If we got HANGUP, we need to only send an empty
|
||||
* packet so the client sees an EOF and cleans up
|
||||
*/
|
||||
if (!stream->closed && !stream->recvEOF &&
|
||||
(events & VIR_STREAM_EVENT_HANGUP)) {
|
||||
virNetMessagePtr msg;
|
||||
events &= ~(VIR_STREAM_EVENT_HANGUP);
|
||||
stream->tx = 0;
|
||||
stream->recvEOF = 1;
|
||||
if (!(msg = virNetMessageNew(false))) {
|
||||
daemonRemoveClientStream(client, stream);
|
||||
virNetServerClientClose(client);
|
||||
goto cleanup;
|
||||
}
|
||||
msg->cb = daemonStreamMessageFinished;
|
||||
msg->opaque = stream;
|
||||
stream->refs++;
|
||||
if (virNetServerProgramSendStreamData(remoteProgram,
|
||||
client,
|
||||
msg,
|
||||
stream->procedure,
|
||||
stream->serial,
|
||||
"", 0) < 0) {
|
||||
virNetMessageFree(msg);
|
||||
daemonRemoveClientStream(client, stream);
|
||||
virNetServerClientClose(client);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream->closed &&
|
||||
(events & (VIR_STREAM_EVENT_ERROR | VIR_STREAM_EVENT_HANGUP))) {
|
||||
int ret;
|
||||
virNetMessagePtr msg;
|
||||
virNetMessageError rerr;
|
||||
|
||||
memset(&rerr, 0, sizeof(rerr));
|
||||
stream->closed = 1;
|
||||
virStreamEventRemoveCallback(stream->st);
|
||||
virStreamAbort(stream->st);
|
||||
if (events & VIR_STREAM_EVENT_HANGUP)
|
||||
virNetError(VIR_ERR_RPC,
|
||||
"%s", _("stream had unexpected termination"));
|
||||
else
|
||||
virNetError(VIR_ERR_RPC,
|
||||
"%s", _("stream had I/O failure"));
|
||||
|
||||
msg = virNetMessageNew(false);
|
||||
if (!msg) {
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = virNetServerProgramSendStreamError(remoteProgram,
|
||||
client,
|
||||
msg,
|
||||
&rerr,
|
||||
stream->procedure,
|
||||
stream->serial);
|
||||
}
|
||||
daemonRemoveClientStream(client, stream);
|
||||
if (ret < 0)
|
||||
virNetServerClientClose(client);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (stream->closed) {
|
||||
daemonRemoveClientStream(client, stream);
|
||||
} else {
|
||||
daemonStreamUpdateEvents(stream);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
virMutexUnlock(&priv->lock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @client: a locked client object
|
||||
*
|
||||
* Invoked by the main loop when filtering incoming messages.
|
||||
*
|
||||
* Returns 1 if the message was processed, 0 if skipped,
|
||||
* -1 on fatal client error
|
||||
*/
|
||||
static int
|
||||
daemonStreamFilter(virNetServerClientPtr client ATTRIBUTE_UNUSED,
|
||||
virNetMessagePtr msg,
|
||||
void *opaque)
|
||||
{
|
||||
daemonClientStream *stream = opaque;
|
||||
int ret = 0;
|
||||
|
||||
virMutexLock(&stream->priv->lock);
|
||||
|
||||
if (msg->header.type != VIR_NET_STREAM)
|
||||
goto cleanup;
|
||||
|
||||
if (!virNetServerProgramMatches(stream->prog, msg))
|
||||
goto cleanup;
|
||||
|
||||
if (msg->header.proc != stream->procedure ||
|
||||
msg->header.serial != stream->serial)
|
||||
goto cleanup;
|
||||
|
||||
VIR_DEBUG("Incoming client=%p, rx=%p, serial=%d, proc=%d, status=%d",
|
||||
client, stream->rx, msg->header.proc,
|
||||
msg->header.serial, msg->header.status);
|
||||
|
||||
virNetMessageQueuePush(&stream->rx, msg);
|
||||
daemonStreamUpdateEvents(stream);
|
||||
ret = 1;
|
||||
|
||||
cleanup:
|
||||
virMutexUnlock(&stream->priv->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @conn: a connection object to associate the stream with
|
||||
* @header: the method call to associate with the stream
|
||||
*
|
||||
* Creates a new stream for this conn
|
||||
*
|
||||
* Returns a new stream object, or NULL upon OOM
|
||||
*/
|
||||
daemonClientStream *
|
||||
daemonCreateClientStream(virNetServerClientPtr client,
|
||||
virStreamPtr st,
|
||||
virNetServerProgramPtr prog,
|
||||
virNetMessageHeaderPtr header)
|
||||
{
|
||||
daemonClientStream *stream;
|
||||
daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
|
||||
|
||||
VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p",
|
||||
client, header->proc, header->serial, st);
|
||||
|
||||
if (VIR_ALLOC(stream) < 0) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stream->refs = 1;
|
||||
stream->priv = priv;
|
||||
stream->prog = prog;
|
||||
stream->procedure = header->proc;
|
||||
stream->serial = header->serial;
|
||||
stream->filterID = -1;
|
||||
stream->st = st;
|
||||
|
||||
virNetServerProgramRef(prog);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
/*
|
||||
* @stream: an unused client stream
|
||||
*
|
||||
* Frees the memory associated with this inactive client
|
||||
* stream
|
||||
*/
|
||||
int daemonFreeClientStream(virNetServerClientPtr client,
|
||||
daemonClientStream *stream)
|
||||
{
|
||||
virNetMessagePtr msg;
|
||||
int ret = 0;
|
||||
|
||||
if (!stream)
|
||||
return 0;
|
||||
|
||||
stream->refs--;
|
||||
if (stream->refs)
|
||||
return 0;
|
||||
|
||||
VIR_DEBUG("client=%p, proc=%d, serial=%d",
|
||||
client, stream->procedure, stream->serial);
|
||||
|
||||
virNetServerProgramFree(stream->prog);
|
||||
|
||||
msg = stream->rx;
|
||||
while (msg) {
|
||||
virNetMessagePtr tmp = msg->next;
|
||||
if (client) {
|
||||
/* Send a dummy reply to free up 'msg' & unblock client rx */
|
||||
virNetMessageClear(msg);
|
||||
msg->header.type = VIR_NET_REPLY;
|
||||
if (virNetServerClientSendMessage(client, msg) < 0) {
|
||||
virNetServerClientImmediateClose(client);
|
||||
virNetMessageFree(msg);
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
virNetMessageFree(msg);
|
||||
}
|
||||
msg = tmp;
|
||||
}
|
||||
|
||||
virStreamFree(stream->st);
|
||||
VIR_FREE(stream);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @client: a locked client to add the stream to
|
||||
* @stream: a stream to add
|
||||
*/
|
||||
int daemonAddClientStream(virNetServerClientPtr client,
|
||||
daemonClientStream *stream,
|
||||
bool transmit)
|
||||
{
|
||||
VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p, transmit=%d",
|
||||
client, stream->procedure, stream->serial, stream->st, transmit);
|
||||
daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
|
||||
|
||||
if (stream->filterID != -1) {
|
||||
VIR_WARN("Filter already added to client %p", client);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virStreamEventAddCallback(stream->st, 0,
|
||||
daemonStreamEvent, client,
|
||||
daemonStreamEventFreeFunc) < 0)
|
||||
return -1;
|
||||
|
||||
virNetServerClientRef(client);
|
||||
if ((stream->filterID = virNetServerClientAddFilter(client,
|
||||
daemonStreamFilter,
|
||||
stream)) < 0) {
|
||||
virStreamEventRemoveCallback(stream->st);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (transmit)
|
||||
stream->tx = 1;
|
||||
|
||||
virMutexLock(&priv->lock);
|
||||
stream->next = priv->streams;
|
||||
priv->streams = stream;
|
||||
|
||||
daemonStreamUpdateEvents(stream);
|
||||
|
||||
virMutexUnlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @client: a locked client object
|
||||
* @stream: an inactive, closed stream object
|
||||
*
|
||||
* Removes a stream from the list of active streams for the client
|
||||
*
|
||||
* Returns 0 if the stream was removd, -1 if it doesn't exist
|
||||
*/
|
||||
int
|
||||
daemonRemoveClientStream(virNetServerClientPtr client,
|
||||
daemonClientStream *stream)
|
||||
{
|
||||
VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p",
|
||||
client, stream->procedure, stream->serial, stream->st);
|
||||
daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
|
||||
daemonClientStream *curr = priv->streams;
|
||||
daemonClientStream *prev = NULL;
|
||||
|
||||
if (stream->filterID != -1) {
|
||||
virNetServerClientRemoveFilter(client,
|
||||
stream->filterID);
|
||||
stream->filterID = -1;
|
||||
}
|
||||
|
||||
if (!stream->closed) {
|
||||
virStreamEventRemoveCallback(stream->st);
|
||||
virStreamAbort(stream->st);
|
||||
}
|
||||
|
||||
while (curr) {
|
||||
if (curr == stream) {
|
||||
if (prev)
|
||||
prev->next = curr->next;
|
||||
else
|
||||
priv->streams = curr->next;
|
||||
return daemonFreeClientStream(client, stream);
|
||||
}
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
daemonRemoveAllClientStreams(daemonClientStream *stream)
|
||||
{
|
||||
daemonClientStream *tmp;
|
||||
|
||||
VIR_DEBUG("stream=%p", stream);
|
||||
|
||||
while (stream) {
|
||||
tmp = stream->next;
|
||||
|
||||
if (!stream->closed) {
|
||||
virStreamEventRemoveCallback(stream->st);
|
||||
virStreamAbort(stream->st);
|
||||
}
|
||||
|
||||
daemonFreeClientStream(NULL, stream);
|
||||
|
||||
VIR_DEBUG("next stream=%p", tmp);
|
||||
stream = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns:
|
||||
* -1 if fatal error occurred
|
||||
* 0 if message was fully processed
|
||||
* 1 if message is still being processed
|
||||
*/
|
||||
static int
|
||||
daemonStreamHandleWriteData(virNetServerClientPtr client,
|
||||
daemonClientStream *stream,
|
||||
virNetMessagePtr msg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%d, len=%zu, offset=%zu",
|
||||
client, stream, msg->header.proc, msg->header.serial,
|
||||
msg->bufferLength, msg->bufferOffset);
|
||||
|
||||
ret = virStreamSend(stream->st,
|
||||
msg->buffer + msg->bufferOffset,
|
||||
msg->bufferLength - msg->bufferOffset);
|
||||
|
||||
if (ret > 0) {
|
||||
msg->bufferOffset += ret;
|
||||
|
||||
/* Partial write, so indicate we have more todo later */
|
||||
if (msg->bufferOffset < msg->bufferLength)
|
||||
return 1;
|
||||
} else if (ret == -2) {
|
||||
/* Blocking, so indicate we have more todo later */
|
||||
return 1;
|
||||
} else {
|
||||
virNetMessageError rerr;
|
||||
|
||||
memset(&rerr, 0, sizeof(rerr));
|
||||
|
||||
VIR_INFO("Stream send failed");
|
||||
stream->closed = 1;
|
||||
return virNetServerProgramSendReplyError(stream->prog,
|
||||
client,
|
||||
msg,
|
||||
&rerr,
|
||||
&msg->header);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process a finish handshake from the client.
|
||||
*
|
||||
* Returns a VIR_NET_OK confirmation if successful, or a VIR_NET_ERROR
|
||||
* if there was a stream error
|
||||
*
|
||||
* Returns 0 if successfully sent RPC reply, -1 upon fatal error
|
||||
*/
|
||||
static int
|
||||
daemonStreamHandleFinish(virNetServerClientPtr client,
|
||||
daemonClientStream *stream,
|
||||
virNetMessagePtr msg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%d",
|
||||
client, stream, msg->header.proc, msg->header.serial);
|
||||
|
||||
stream->closed = 1;
|
||||
virStreamEventRemoveCallback(stream->st);
|
||||
ret = virStreamFinish(stream->st);
|
||||
|
||||
if (ret < 0) {
|
||||
virNetMessageError rerr;
|
||||
memset(&rerr, 0, sizeof(rerr));
|
||||
return virNetServerProgramSendReplyError(stream->prog,
|
||||
client,
|
||||
msg,
|
||||
&rerr,
|
||||
&msg->header);
|
||||
} else {
|
||||
/* Send zero-length confirm */
|
||||
return virNetServerProgramSendStreamData(stream->prog,
|
||||
client,
|
||||
msg,
|
||||
stream->procedure,
|
||||
stream->serial,
|
||||
NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process an abort request from the client.
|
||||
*
|
||||
* Returns 0 if successfully aborted, -1 upon error
|
||||
*/
|
||||
static int
|
||||
daemonStreamHandleAbort(virNetServerClientPtr client,
|
||||
daemonClientStream *stream,
|
||||
virNetMessagePtr msg)
|
||||
{
|
||||
VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%d",
|
||||
client, stream, msg->header.proc, msg->header.serial);
|
||||
virNetMessageError rerr;
|
||||
|
||||
memset(&rerr, 0, sizeof(rerr));
|
||||
|
||||
stream->closed = 1;
|
||||
virStreamEventRemoveCallback(stream->st);
|
||||
virStreamAbort(stream->st);
|
||||
|
||||
if (msg->header.status == VIR_NET_ERROR)
|
||||
virNetError(VIR_ERR_RPC,
|
||||
"%s", _("stream aborted at client request"));
|
||||
else {
|
||||
VIR_WARN("unexpected stream status %d", msg->header.status);
|
||||
virNetError(VIR_ERR_RPC,
|
||||
_("stream aborted with unexpected status %d"),
|
||||
msg->header.status);
|
||||
}
|
||||
|
||||
return virNetServerProgramSendReplyError(remoteProgram,
|
||||
client,
|
||||
msg,
|
||||
&rerr,
|
||||
&msg->header);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Called when the stream is signalled has being able to accept
|
||||
* data writes. Will process all pending incoming messages
|
||||
* until they're all gone, or I/O blocks
|
||||
*
|
||||
* Returns 0 on success, or -1 upon fatal error
|
||||
*/
|
||||
static int
|
||||
daemonStreamHandleWrite(virNetServerClientPtr client,
|
||||
daemonClientStream *stream)
|
||||
{
|
||||
VIR_DEBUG("client=%p, stream=%p", client, stream);
|
||||
|
||||
while (stream->rx && !stream->closed) {
|
||||
virNetMessagePtr msg = stream->rx;
|
||||
int ret;
|
||||
|
||||
switch (msg->header.status) {
|
||||
case VIR_NET_OK:
|
||||
ret = daemonStreamHandleFinish(client, stream, msg);
|
||||
break;
|
||||
|
||||
case VIR_NET_CONTINUE:
|
||||
ret = daemonStreamHandleWriteData(client, stream, msg);
|
||||
break;
|
||||
|
||||
case VIR_NET_ERROR:
|
||||
default:
|
||||
ret = daemonStreamHandleAbort(client, stream, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
break; /* still processing data from msg */
|
||||
|
||||
virNetMessageQueueServe(&stream->rx);
|
||||
if (ret < 0) {
|
||||
virNetMessageFree(msg);
|
||||
virNetServerClientImmediateClose(client);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 'CONTINUE' messages don't send a reply (unless error
|
||||
* occurred), so to release the 'msg' object we need to
|
||||
* send a fake zero-length reply. Nothing actually gets
|
||||
* onto the wire, but this causes the client to reset
|
||||
* its active request count / throttling
|
||||
*/
|
||||
if (msg->header.status == VIR_NET_CONTINUE) {
|
||||
virNetMessageClear(msg);
|
||||
msg->header.type = VIR_NET_REPLY;
|
||||
if (virNetServerClientSendMessage(client, msg) < 0) {
|
||||
virNetMessageFree(msg);
|
||||
virNetServerClientImmediateClose(client);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Invoked when a stream is signalled as having data
|
||||
* available to read. This reads upto one message
|
||||
* worth of data, and then queues that for transmission
|
||||
* to the client.
|
||||
*
|
||||
* Returns 0 if data was queued for TX, or a error RPC
|
||||
* was sent, or -1 on fatal error, indicating client should
|
||||
* be killed
|
||||
*/
|
||||
static int
|
||||
daemonStreamHandleRead(virNetServerClientPtr client,
|
||||
daemonClientStream *stream)
|
||||
{
|
||||
char *buffer;
|
||||
size_t bufferLen = VIR_NET_MESSAGE_PAYLOAD_MAX;
|
||||
int ret;
|
||||
|
||||
VIR_DEBUG("client=%p, stream=%p tx=%d closed=%d",
|
||||
client, stream, stream->tx, stream->closed);
|
||||
|
||||
/* We might have had an event pending before we shut
|
||||
* down the stream, so if we're marked as closed,
|
||||
* then do nothing
|
||||
*/
|
||||
if (stream->closed)
|
||||
return 0;
|
||||
|
||||
/* Shouldn't ever be called unless we're marked able to
|
||||
* transmit, but doesn't hurt to check */
|
||||
if (!stream->tx)
|
||||
return 0;
|
||||
|
||||
if (VIR_ALLOC_N(buffer, bufferLen) < 0)
|
||||
return -1;
|
||||
|
||||
ret = virStreamRecv(stream->st, buffer, bufferLen);
|
||||
if (ret == -2) {
|
||||
/* Should never get this, since we're only called when we know
|
||||
* we're readable, but hey things change... */
|
||||
ret = 0;
|
||||
} else if (ret < 0) {
|
||||
virNetMessagePtr msg;
|
||||
virNetMessageError rerr;
|
||||
|
||||
memset(&rerr, 0, sizeof(rerr));
|
||||
|
||||
if (!(msg = virNetMessageNew(false)))
|
||||
ret = -1;
|
||||
else
|
||||
ret = virNetServerProgramSendStreamError(remoteProgram,
|
||||
client,
|
||||
msg,
|
||||
&rerr,
|
||||
stream->procedure,
|
||||
stream->serial);
|
||||
} else {
|
||||
virNetMessagePtr msg;
|
||||
stream->tx = 0;
|
||||
if (ret == 0)
|
||||
stream->recvEOF = 1;
|
||||
if (!(msg = virNetMessageNew(false)))
|
||||
ret = -1;
|
||||
|
||||
if (msg) {
|
||||
msg->cb = daemonStreamMessageFinished;
|
||||
msg->opaque = stream;
|
||||
stream->refs++;
|
||||
ret = virNetServerProgramSendStreamData(remoteProgram,
|
||||
client,
|
||||
msg,
|
||||
stream->procedure,
|
||||
stream->serial,
|
||||
buffer, ret);
|
||||
}
|
||||
}
|
||||
|
||||
VIR_FREE(buffer);
|
||||
return ret;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* stream.h: APIs for managing client streams
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __LIBVIRTD_STREAM_H__
|
||||
# define __LIBVIRTD_STREAM_H__
|
||||
|
||||
# include "libvirtd.h"
|
||||
|
||||
|
||||
|
||||
daemonClientStream *
|
||||
daemonCreateClientStream(virNetServerClientPtr client,
|
||||
virStreamPtr st,
|
||||
virNetServerProgramPtr prog,
|
||||
virNetMessageHeaderPtr hdr);
|
||||
|
||||
int daemonFreeClientStream(virNetServerClientPtr client,
|
||||
daemonClientStream *stream);
|
||||
|
||||
int daemonAddClientStream(virNetServerClientPtr client,
|
||||
daemonClientStream *stream,
|
||||
bool transmit);
|
||||
|
||||
int
|
||||
daemonRemoveClientStream(virNetServerClientPtr client,
|
||||
daemonClientStream *stream);
|
||||
|
||||
void
|
||||
daemonRemoveAllClientStreams(daemonClientStream *stream);
|
||||
|
||||
#endif /* __LIBVIRTD_STREAM_H__ */
|
@ -1,553 +0,0 @@
|
||||
module Test_libvirtd =
|
||||
let conf = "# Master libvirt daemon configuration file
|
||||
#
|
||||
# For further information consult http://libvirt.org/format.html
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Network connectivity controls
|
||||
#
|
||||
|
||||
# Flag listening for secure TLS connections on the public TCP/IP port.
|
||||
# NB, must pass the --listen flag to the libvirtd process for this to
|
||||
# have any effect.
|
||||
#
|
||||
# It is necessary to setup a CA and issue server certificates before
|
||||
# using this capability.
|
||||
#
|
||||
# This is enabled by default, uncomment this to disable it
|
||||
listen_tls = 0
|
||||
|
||||
# Listen for unencrypted TCP connections on the public TCP/IP port.
|
||||
# NB, must pass the --listen flag to the libvirtd process for this to
|
||||
# have any effect.
|
||||
#
|
||||
# Using the TCP socket requires SASL authentication by default. Only
|
||||
# SASL mechanisms which support data encryption are allowed. This is
|
||||
# DIGEST_MD5 and GSSAPI (Kerberos5)
|
||||
#
|
||||
# This is disabled by default, uncomment this to enable it.
|
||||
listen_tcp = 1
|
||||
|
||||
|
||||
|
||||
# Override the port for accepting secure TLS connections
|
||||
# This can be a port number, or service name
|
||||
#
|
||||
tls_port = \"16514\"
|
||||
|
||||
# Override the port for accepting insecure TCP connections
|
||||
# This can be a port number, or service name
|
||||
#
|
||||
tcp_port = \"16509\"
|
||||
|
||||
|
||||
# Override the default configuration which binds to all network
|
||||
# interfaces. This can be a numeric IPv4/6 address, or hostname
|
||||
#
|
||||
listen_addr = \"192.168.0.1\"
|
||||
|
||||
|
||||
# Flag toggling mDNS advertizement of the libvirt service.
|
||||
#
|
||||
# Alternatively can disable for all services on a host by
|
||||
# stopping the Avahi daemon
|
||||
#
|
||||
# This is disabled by default, uncomment this to enable it
|
||||
mdns_adv = 1
|
||||
|
||||
# Override the default mDNS advertizement name. This must be
|
||||
# unique on the immediate broadcast network.
|
||||
#
|
||||
# The default is \"Virtualization Host HOSTNAME\", where HOSTNAME
|
||||
# is subsituted for the short hostname of the machine (without domain)
|
||||
#
|
||||
mdns_name = \"Virtualization Host Joe Demo\"
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# UNIX socket access controls
|
||||
#
|
||||
|
||||
# Set the UNIX domain socket group ownership. This can be used to
|
||||
# allow a 'trusted' set of users access to management capabilities
|
||||
# without becoming root.
|
||||
#
|
||||
# This is restricted to 'root' by default.
|
||||
unix_sock_group = \"libvirt\"
|
||||
|
||||
# Set the UNIX socket permissions for the R/O socket. This is used
|
||||
# for monitoring VM status only
|
||||
#
|
||||
# Default allows any user. If setting group ownership may want to
|
||||
# restrict this to:
|
||||
unix_sock_ro_perms = \"0777\"
|
||||
|
||||
# Set the UNIX socket permissions for the R/W socket. This is used
|
||||
# for full management of VMs
|
||||
#
|
||||
# Default allows only root. If PolicyKit is enabled on the socket,
|
||||
# the default will change to allow everyone (eg, 0777)
|
||||
#
|
||||
# If not using PolicyKit and setting group ownership for access
|
||||
# control then you may want to relax this to:
|
||||
unix_sock_rw_perms = \"0770\"
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Authentication.
|
||||
#
|
||||
# - none: do not perform auth checks. If you can connect to the
|
||||
# socket you are allowed. This is suitable if there are
|
||||
# restrictions on connecting to the socket (eg, UNIX
|
||||
# socket permissions), or if there is a lower layer in
|
||||
# the network providing auth (eg, TLS/x509 certificates)
|
||||
#
|
||||
# - sasl: use SASL infrastructure. The actual auth scheme is then
|
||||
# controlled from /etc/sasl2/libvirt.conf. For the TCP
|
||||
# socket only GSSAPI & DIGEST-MD5 mechanisms will be used.
|
||||
# For non-TCP or TLS sockets, any scheme is allowed.
|
||||
#
|
||||
# - polkit: use PolicyKit to authenticate. This is only suitable
|
||||
# for use on the UNIX sockets. The default policy will
|
||||
# require a user to supply their own password to gain
|
||||
# full read/write access (aka sudo like), while anyone
|
||||
# is allowed read/only access.
|
||||
#
|
||||
# Set an authentication scheme for UNIX read-only sockets
|
||||
# By default socket permissions allow anyone to connect
|
||||
#
|
||||
# To restrict monitoring of domains you may wish to enable
|
||||
# an authentication mechanism here
|
||||
auth_unix_ro = \"none\"
|
||||
|
||||
# Set an authentication scheme for UNIX read-write sockets
|
||||
# By default socket permissions only allow root. If PolicyKit
|
||||
# support was compiled into libvirt, the default will be to
|
||||
# use 'polkit' auth.
|
||||
#
|
||||
# If the unix_sock_rw_perms are changed you may wish to enable
|
||||
# an authentication mechanism here
|
||||
auth_unix_rw = \"none\"
|
||||
|
||||
# Change the authentication scheme for TCP sockets.
|
||||
#
|
||||
# If you don't enable SASL, then all TCP traffic is cleartext.
|
||||
# Don't do this outside of a dev/test scenario. For real world
|
||||
# use, always enable SASL and use the GSSAPI or DIGEST-MD5
|
||||
# mechanism in /etc/sasl2/libvirt.conf
|
||||
auth_tcp = \"sasl\"
|
||||
|
||||
# Change the authentication scheme for TLS sockets.
|
||||
#
|
||||
# TLS sockets already have encryption provided by the TLS
|
||||
# layer, and limited authentication is done by certificates
|
||||
#
|
||||
# It is possible to make use of any SASL authentication
|
||||
# mechanism as well, by using 'sasl' for this option
|
||||
auth_tls = \"none\"
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# TLS x509 certificate configuration
|
||||
#
|
||||
|
||||
|
||||
# Override the default server key file path
|
||||
#
|
||||
key_file = \"/etc/pki/libvirt/private/serverkey.pem\"
|
||||
|
||||
# Override the default server certificate file path
|
||||
#
|
||||
cert_file = \"/etc/pki/libvirt/servercert.pem\"
|
||||
|
||||
# Override the default CA certificate path
|
||||
#
|
||||
ca_file = \"/etc/pki/CA/cacert.pem\"
|
||||
|
||||
# Specify a certificate revocation list.
|
||||
#
|
||||
# Defaults to not using a CRL, uncomment to enable it
|
||||
crl_file = \"/etc/pki/CA/crl.pem\"
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Authorization controls
|
||||
#
|
||||
|
||||
|
||||
# Flag to disable verification of client certificates
|
||||
#
|
||||
# Client certificate verification is the primary authentication mechanism.
|
||||
# Any client which does not present a certificate signed by the CA
|
||||
# will be rejected.
|
||||
#
|
||||
# Default is to always verify. Uncommenting this will disable
|
||||
# verification - make sure an IP whitelist is set
|
||||
tls_no_verify_certificate = 1
|
||||
tls_no_sanity_certificate = 1
|
||||
|
||||
|
||||
# A whitelist of allowed x509 Distinguished Names
|
||||
# This list may contain wildcards such as
|
||||
#
|
||||
# \"C=GB,ST=London,L=London,O=Red Hat,CN=*\"
|
||||
#
|
||||
# See the POSIX fnmatch function for the format of the wildcards.
|
||||
#
|
||||
# NB If this is an empty list, no client can connect, so comment out
|
||||
# entirely rather than using empty list to disable these checks
|
||||
#
|
||||
# By default, no DN's are checked
|
||||
tls_allowed_dn_list = [\"DN1\", \"DN2\"]
|
||||
|
||||
|
||||
# A whitelist of allowed SASL usernames. The format for usernames
|
||||
# depends on the SASL authentication mechanism. Kerberos usernames
|
||||
# look like username@REALM
|
||||
#
|
||||
# This list may contain wildcards such as
|
||||
#
|
||||
# \"*@EXAMPLE.COM\"
|
||||
#
|
||||
# See the POSIX fnmatch function for the format of the wildcards.
|
||||
#
|
||||
# NB If this is an empty list, no client can connect, so comment out
|
||||
# entirely rather than using empty list to disable these checks
|
||||
#
|
||||
# By default, no Username's are checked
|
||||
sasl_allowed_username_list = [
|
||||
\"joe@EXAMPLE.COM\",
|
||||
\"fred@EXAMPLE.COM\"
|
||||
]
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Processing controls
|
||||
#
|
||||
|
||||
# The maximum number of concurrent client connections to allow
|
||||
# over all sockets combined.
|
||||
max_clients = 20
|
||||
|
||||
|
||||
# The minimum limit sets the number of workers to start up
|
||||
# initially. If the number of active clients exceeds this,
|
||||
# then more threads are spawned, upto max_workers limit.
|
||||
# Typically you'd want max_workers to equal maximum number
|
||||
# of clients allowed
|
||||
min_workers = 5
|
||||
max_workers = 20
|
||||
|
||||
# Total global limit on concurrent RPC calls. Should be
|
||||
# at least as large as max_workers. Beyond this, RPC requests
|
||||
# will be read into memory and queued. This directly impact
|
||||
# memory usage, currently each request requires 256 KB of
|
||||
# memory. So by default upto 5 MB of memory is used
|
||||
max_requests = 20
|
||||
|
||||
# Limit on concurrent requests from a single client
|
||||
# connection. To avoid one client monopolizing the server
|
||||
# this should be a small fraction of the global max_requests
|
||||
# and max_workers parameter
|
||||
max_client_requests = 5
|
||||
|
||||
# Logging level:
|
||||
log_level = 4
|
||||
|
||||
# Logging outputs:
|
||||
log_outputs=\"4:stderr\"
|
||||
|
||||
# Logging filters:
|
||||
log_filters=\"a\"
|
||||
|
||||
# Auditing:
|
||||
audit_level = 2
|
||||
"
|
||||
|
||||
test Libvirtd.lns get conf =
|
||||
{ "#comment" = "Master libvirt daemon configuration file" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "For further information consult http://libvirt.org/format.html" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Network connectivity controls" }
|
||||
{ "#comment" = "" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Flag listening for secure TLS connections on the public TCP/IP port." }
|
||||
{ "#comment" = "NB, must pass the --listen flag to the libvirtd process for this to" }
|
||||
{ "#comment" = "have any effect." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "It is necessary to setup a CA and issue server certificates before" }
|
||||
{ "#comment" = "using this capability." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "This is enabled by default, uncomment this to disable it" }
|
||||
{ "listen_tls" = "0" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Listen for unencrypted TCP connections on the public TCP/IP port." }
|
||||
{ "#comment" = "NB, must pass the --listen flag to the libvirtd process for this to" }
|
||||
{ "#comment" = "have any effect." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Using the TCP socket requires SASL authentication by default. Only" }
|
||||
{ "#comment" = "SASL mechanisms which support data encryption are allowed. This is" }
|
||||
{ "#comment" = "DIGEST_MD5 and GSSAPI (Kerberos5)" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "This is disabled by default, uncomment this to enable it." }
|
||||
{ "listen_tcp" = "1" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the port for accepting secure TLS connections" }
|
||||
{ "#comment" = "This can be a port number, or service name" }
|
||||
{ "#comment" = "" }
|
||||
{ "tls_port" = "16514" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the port for accepting insecure TCP connections" }
|
||||
{ "#comment" = "This can be a port number, or service name" }
|
||||
{ "#comment" = "" }
|
||||
{ "tcp_port" = "16509" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the default configuration which binds to all network" }
|
||||
{ "#comment" = "interfaces. This can be a numeric IPv4/6 address, or hostname" }
|
||||
{ "#comment" = "" }
|
||||
{ "listen_addr" = "192.168.0.1" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Flag toggling mDNS advertizement of the libvirt service." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Alternatively can disable for all services on a host by" }
|
||||
{ "#comment" = "stopping the Avahi daemon" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "This is disabled by default, uncomment this to enable it" }
|
||||
{ "mdns_adv" = "1" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the default mDNS advertizement name. This must be" }
|
||||
{ "#comment" = "unique on the immediate broadcast network." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "The default is \"Virtualization Host HOSTNAME\", where HOSTNAME" }
|
||||
{ "#comment" = "is subsituted for the short hostname of the machine (without domain)" }
|
||||
{ "#comment" = "" }
|
||||
{ "mdns_name" = "Virtualization Host Joe Demo" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "UNIX socket access controls" }
|
||||
{ "#comment" = "" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Set the UNIX domain socket group ownership. This can be used to" }
|
||||
{ "#comment" = "allow a 'trusted' set of users access to management capabilities" }
|
||||
{ "#comment" = "without becoming root." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "This is restricted to 'root' by default." }
|
||||
{ "unix_sock_group" = "libvirt" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Set the UNIX socket permissions for the R/O socket. This is used" }
|
||||
{ "#comment" = "for monitoring VM status only" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Default allows any user. If setting group ownership may want to" }
|
||||
{ "#comment" = "restrict this to:" }
|
||||
{ "unix_sock_ro_perms" = "0777" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Set the UNIX socket permissions for the R/W socket. This is used" }
|
||||
{ "#comment" = "for full management of VMs" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Default allows only root. If PolicyKit is enabled on the socket," }
|
||||
{ "#comment" = "the default will change to allow everyone (eg, 0777)" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "If not using PolicyKit and setting group ownership for access" }
|
||||
{ "#comment" = "control then you may want to relax this to:" }
|
||||
{ "unix_sock_rw_perms" = "0770" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Authentication." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "- none: do not perform auth checks. If you can connect to the" }
|
||||
{ "#comment" = "socket you are allowed. This is suitable if there are" }
|
||||
{ "#comment" = "restrictions on connecting to the socket (eg, UNIX" }
|
||||
{ "#comment" = "socket permissions), or if there is a lower layer in" }
|
||||
{ "#comment" = "the network providing auth (eg, TLS/x509 certificates)" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "- sasl: use SASL infrastructure. The actual auth scheme is then" }
|
||||
{ "#comment" = "controlled from /etc/sasl2/libvirt.conf. For the TCP" }
|
||||
{ "#comment" = "socket only GSSAPI & DIGEST-MD5 mechanisms will be used." }
|
||||
{ "#comment" = "For non-TCP or TLS sockets, any scheme is allowed." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "- polkit: use PolicyKit to authenticate. This is only suitable" }
|
||||
{ "#comment" = "for use on the UNIX sockets. The default policy will" }
|
||||
{ "#comment" = "require a user to supply their own password to gain" }
|
||||
{ "#comment" = "full read/write access (aka sudo like), while anyone" }
|
||||
{ "#comment" = "is allowed read/only access." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Set an authentication scheme for UNIX read-only sockets" }
|
||||
{ "#comment" = "By default socket permissions allow anyone to connect" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "To restrict monitoring of domains you may wish to enable" }
|
||||
{ "#comment" = "an authentication mechanism here" }
|
||||
{ "auth_unix_ro" = "none" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Set an authentication scheme for UNIX read-write sockets" }
|
||||
{ "#comment" = "By default socket permissions only allow root. If PolicyKit" }
|
||||
{ "#comment" = "support was compiled into libvirt, the default will be to" }
|
||||
{ "#comment" = "use 'polkit' auth." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "If the unix_sock_rw_perms are changed you may wish to enable" }
|
||||
{ "#comment" = "an authentication mechanism here" }
|
||||
{ "auth_unix_rw" = "none" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Change the authentication scheme for TCP sockets." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "If you don't enable SASL, then all TCP traffic is cleartext." }
|
||||
{ "#comment" = "Don't do this outside of a dev/test scenario. For real world" }
|
||||
{ "#comment" = "use, always enable SASL and use the GSSAPI or DIGEST-MD5" }
|
||||
{ "#comment" = "mechanism in /etc/sasl2/libvirt.conf" }
|
||||
{ "auth_tcp" = "sasl" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Change the authentication scheme for TLS sockets." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "TLS sockets already have encryption provided by the TLS" }
|
||||
{ "#comment" = "layer, and limited authentication is done by certificates" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "It is possible to make use of any SASL authentication" }
|
||||
{ "#comment" = "mechanism as well, by using 'sasl' for this option" }
|
||||
{ "auth_tls" = "none" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "TLS x509 certificate configuration" }
|
||||
{ "#comment" = "" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the default server key file path" }
|
||||
{ "#comment" = "" }
|
||||
{ "key_file" = "/etc/pki/libvirt/private/serverkey.pem" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the default server certificate file path" }
|
||||
{ "#comment" = "" }
|
||||
{ "cert_file" = "/etc/pki/libvirt/servercert.pem" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the default CA certificate path" }
|
||||
{ "#comment" = "" }
|
||||
{ "ca_file" = "/etc/pki/CA/cacert.pem" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Specify a certificate revocation list." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Defaults to not using a CRL, uncomment to enable it" }
|
||||
{ "crl_file" = "/etc/pki/CA/crl.pem" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Authorization controls" }
|
||||
{ "#comment" = "" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Flag to disable verification of client certificates" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Client certificate verification is the primary authentication mechanism." }
|
||||
{ "#comment" = "Any client which does not present a certificate signed by the CA" }
|
||||
{ "#comment" = "will be rejected." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Default is to always verify. Uncommenting this will disable" }
|
||||
{ "#comment" = "verification - make sure an IP whitelist is set" }
|
||||
{ "tls_no_verify_certificate" = "1" }
|
||||
{ "tls_no_sanity_certificate" = "1" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "A whitelist of allowed x509 Distinguished Names" }
|
||||
{ "#comment" = "This list may contain wildcards such as" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "\"C=GB,ST=London,L=London,O=Red Hat,CN=*\"" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "See the POSIX fnmatch function for the format of the wildcards." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "NB If this is an empty list, no client can connect, so comment out" }
|
||||
{ "#comment" = "entirely rather than using empty list to disable these checks" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "By default, no DN's are checked" }
|
||||
{ "tls_allowed_dn_list"
|
||||
{ "1" = "DN1"}
|
||||
{ "2" = "DN2"}
|
||||
}
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "A whitelist of allowed SASL usernames. The format for usernames" }
|
||||
{ "#comment" = "depends on the SASL authentication mechanism. Kerberos usernames" }
|
||||
{ "#comment" = "look like username@REALM" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "This list may contain wildcards such as" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "\"*@EXAMPLE.COM\"" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "See the POSIX fnmatch function for the format of the wildcards." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "NB If this is an empty list, no client can connect, so comment out" }
|
||||
{ "#comment" = "entirely rather than using empty list to disable these checks" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "By default, no Username's are checked" }
|
||||
{ "sasl_allowed_username_list"
|
||||
{ "1" = "joe@EXAMPLE.COM" }
|
||||
{ "2" = "fred@EXAMPLE.COM" }
|
||||
}
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################"}
|
||||
{ "#comment" = ""}
|
||||
{ "#comment" = "Processing controls"}
|
||||
{ "#comment" = ""}
|
||||
{ "#empty" }
|
||||
{ "#comment" = "The maximum number of concurrent client connections to allow"}
|
||||
{ "#comment" = "over all sockets combined."}
|
||||
{ "max_clients" = "20" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "The minimum limit sets the number of workers to start up"}
|
||||
{ "#comment" = "initially. If the number of active clients exceeds this,"}
|
||||
{ "#comment" = "then more threads are spawned, upto max_workers limit."}
|
||||
{ "#comment" = "Typically you'd want max_workers to equal maximum number"}
|
||||
{ "#comment" = "of clients allowed"}
|
||||
{ "min_workers" = "5" }
|
||||
{ "max_workers" = "20" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Total global limit on concurrent RPC calls. Should be" }
|
||||
{ "#comment" = "at least as large as max_workers. Beyond this, RPC requests" }
|
||||
{ "#comment" = "will be read into memory and queued. This directly impact" }
|
||||
{ "#comment" = "memory usage, currently each request requires 256 KB of" }
|
||||
{ "#comment" = "memory. So by default upto 5 MB of memory is used" }
|
||||
{ "max_requests" = "20" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Limit on concurrent requests from a single client" }
|
||||
{ "#comment" = "connection. To avoid one client monopolizing the server" }
|
||||
{ "#comment" = "this should be a small fraction of the global max_requests" }
|
||||
{ "#comment" = "and max_workers parameter" }
|
||||
{ "max_client_requests" = "5" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Logging level:" }
|
||||
{ "log_level" = "4" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Logging outputs:" }
|
||||
{ "log_outputs" = "4:stderr" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Logging filters:" }
|
||||
{ "log_filters" = "a" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Auditing:" }
|
||||
{ "audit_level" = "2" }
|
Binary file not shown.
Before Width: | Height: | Size: 783 B |
261
docs/Makefile.am
261
docs/Makefile.am
@ -1,261 +0,0 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
## Copyright (C) 2005-2012 Red Hat, Inc.
|
||||
## See COPYING.LIB for the License of this software
|
||||
|
||||
SUBDIRS= schemas
|
||||
|
||||
PERL = perl
|
||||
|
||||
# The directory containing the source code (if it contains documentation).
|
||||
DOC_SOURCE_DIR=../src
|
||||
|
||||
DEVHELP_DIR=$(datadir)/gtk-doc/html/libvirt
|
||||
|
||||
BUILT_SOURCES=hvsupport.html.in
|
||||
|
||||
apihtml = \
|
||||
html/index.html \
|
||||
html/libvirt-libvirt.html \
|
||||
html/libvirt-virterror.html
|
||||
|
||||
apipng = \
|
||||
html/left.png \
|
||||
html/up.png \
|
||||
html/home.png \
|
||||
html/right.png
|
||||
|
||||
devhelphtml = \
|
||||
devhelp/libvirt.devhelp \
|
||||
devhelp/index.html \
|
||||
devhelp/general.html \
|
||||
devhelp/libvirt-libvirt.html \
|
||||
devhelp/libvirt-virterror.html
|
||||
|
||||
css = \
|
||||
generic.css \
|
||||
libvirt.css \
|
||||
main.css
|
||||
|
||||
devhelppng = \
|
||||
devhelp/home.png \
|
||||
devhelp/left.png \
|
||||
devhelp/right.png \
|
||||
devhelp/up.png
|
||||
|
||||
devhelpcss = devhelp/style.css
|
||||
|
||||
devhelpxsl = devhelp/devhelp.xsl devhelp/html.xsl
|
||||
|
||||
png = \
|
||||
32favicon.png \
|
||||
footer_corner.png \
|
||||
footer_pattern.png \
|
||||
libvirt-header-bg.png \
|
||||
libvirt-header-logo.png \
|
||||
libvirtLogo.png \
|
||||
libvirt-net-logical.png \
|
||||
libvirt-net-physical.png \
|
||||
libvirt-daemon-arch.png \
|
||||
libvirt-driver-arch.png \
|
||||
libvirt-object-model.png \
|
||||
madeWith.png \
|
||||
et.png \
|
||||
migration-managed-direct.png \
|
||||
migration-managed-p2p.png \
|
||||
migration-native.png \
|
||||
migration-tunnel.png \
|
||||
migration-unmanaged-direct.png
|
||||
|
||||
gif = \
|
||||
architecture.gif \
|
||||
node.gif
|
||||
|
||||
|
||||
internals_html_in = \
|
||||
$(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/internals/*.html.in))
|
||||
internals_html = $(internals_html_in:%.html.in=%.html)
|
||||
|
||||
dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) \
|
||||
todo.html.in \
|
||||
hvsupport.html.in
|
||||
dot_html = $(dot_html_in:%.html.in=%.html)
|
||||
|
||||
patches = $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/api_extension/*.patch))
|
||||
|
||||
xml = \
|
||||
libvirt-api.xml \
|
||||
libvirt-refs.xml
|
||||
|
||||
qemu_xml = \
|
||||
libvirt-qemu-api.xml \
|
||||
libvirt-qemu-refs.xml
|
||||
|
||||
apidir = $(pkgdatadir)/api
|
||||
api_DATA = libvirt-api.xml libvirt-qemu-api.xml
|
||||
|
||||
fig = \
|
||||
libvirt-net-logical.fig \
|
||||
libvirt-net-physical.fig \
|
||||
libvirt-daemon-arch.fig \
|
||||
libvirt-driver-arch.fig \
|
||||
libvirt-object-model.fig \
|
||||
migration-managed-direct.fig \
|
||||
migration-managed-p2p.fig \
|
||||
migration-native.fig \
|
||||
migration-tunnel.fig \
|
||||
migration-unmanaged-direct.fig
|
||||
|
||||
EXTRA_DIST= \
|
||||
apibuild.py \
|
||||
site.xsl newapi.xsl news.xsl page.xsl \
|
||||
hacking1.xsl hacking2.xsl wrapstring.xsl \
|
||||
$(dot_html) $(dot_html_in) $(gif) $(apihtml) $(apipng) \
|
||||
$(devhelphtml) $(devhelppng) $(devhelpcss) $(devhelpxsl) \
|
||||
$(xml) $(qemu_xml) $(fig) $(png) $(css) \
|
||||
$(patches) $(internals_html_in) $(internals_html) \
|
||||
sitemap.html.in \
|
||||
todo.pl hvsupport.pl todo.cfg-example
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
$(addprefix $(srcdir)/,$(dot_html)) \
|
||||
$(addprefix $(srcdir)/,$(apihtml)) \
|
||||
$(addprefix $(srcdir)/,$(devhelphtml)) \
|
||||
$(addprefix $(srcdir)/,$(internals_html))
|
||||
|
||||
all-am: web
|
||||
|
||||
api: $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml
|
||||
qemu_api: $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-refs.xml
|
||||
|
||||
web: $(dot_html) $(internals_html) html/index.html devhelp/index.html
|
||||
|
||||
todo.html.in: todo.pl
|
||||
if [ -f todo.cfg ]; then \
|
||||
echo "Generating $@"; \
|
||||
$(PERL) $< > $@ \
|
||||
|| { rm $@ && exit 1; }; \
|
||||
else \
|
||||
echo "Stubbing $@"; \
|
||||
echo "<html><body><h1>Todo list</h1></body></html>" > $@ ; \
|
||||
fi
|
||||
|
||||
todo:
|
||||
rm -f todo.html.in
|
||||
$(MAKE) todo.html
|
||||
|
||||
hvsupport.html.in: $(srcdir)/hvsupport.pl $(srcdir)/../src/libvirt_public.syms \
|
||||
$(srcdir)/../src/libvirt_qemu.syms $(srcdir)/../src/driver.h
|
||||
$(AM_V_GEN)$(PERL) $(srcdir)/hvsupport.pl $(srcdir)/../src > $@ || { rm $@ && exit 1; }
|
||||
|
||||
.PHONY: todo
|
||||
|
||||
%.png: %.fig
|
||||
convert -rotate 90 $< $@
|
||||
|
||||
internals/%.html.tmp: internals/%.html.in subsite.xsl page.xsl sitemap.html.in
|
||||
@if [ -x $(XSLTPROC) ] ; then \
|
||||
echo "Generating $@"; \
|
||||
$(MKDIR_P) internals; \
|
||||
name=`echo $@ | sed -e 's/.tmp//'`; \
|
||||
$(XSLTPROC) --stringparam pagename $$name --nonet --html \
|
||||
$(top_srcdir)/docs/subsite.xsl $< > $@ \
|
||||
|| { rm $@ && exit 1; }; fi
|
||||
|
||||
%.html.tmp: %.html.in site.xsl page.xsl sitemap.html.in
|
||||
@if [ -x $(XSLTPROC) ] ; then \
|
||||
echo "Generating $@"; \
|
||||
name=`echo $@ | sed -e 's/.tmp//'`; \
|
||||
$(XSLTPROC) --stringparam pagename $$name --nonet --html \
|
||||
$(top_srcdir)/docs/site.xsl $< > $@ \
|
||||
|| { rm $@ && exit 1; }; fi
|
||||
|
||||
%.html: %.html.tmp
|
||||
@if test -x $(XMLLINT) && test -x $(XMLCATALOG) ; then \
|
||||
if $(XMLCATALOG) '$(XML_CATALOG_FILE)' \
|
||||
"-//W3C//DTD XHTML 1.0 Strict//EN" > /dev/null ; then \
|
||||
echo "Validating $@" ; \
|
||||
SGML_CATALOG_FILES='$(XML_CATALOG_FILE)' \
|
||||
$(XMLLINT) --catalogs --nonet --format --valid $< > $(srcdir)/$@ \
|
||||
|| { rm $(srcdir)/$@ && exit 1; }; \
|
||||
else echo "missing XHTML1 DTD" ; fi ; fi
|
||||
|
||||
|
||||
html/index.html: libvirt-api.xml newapi.xsl page.xsl sitemap.html.in
|
||||
$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
|
||||
$(XSLTPROC) --nonet -o $(srcdir)/ \
|
||||
$(srcdir)/newapi.xsl $(srcdir)/libvirt-api.xml ; fi && \
|
||||
if test -x $(XMLLINT) && test -x $(XMLCATALOG) ; then \
|
||||
if $(XMLCATALOG) '$(XML_CATALOG_FILE)' "-//W3C//DTD XHTML 1.0 Strict//EN" \
|
||||
> /dev/null ; then \
|
||||
SGML_CATALOG_FILES='$(XML_CATALOG_FILE)' \
|
||||
$(XMLLINT) --catalogs --nonet --valid --noout $(srcdir)/html/*.html ; \
|
||||
else echo "missing XHTML1 DTD" ; fi ; fi
|
||||
|
||||
$(addprefix $(srcdir)/,$(devhelphtml)): $(srcdir)/libvirt-api.xml $(devhelpxsl)
|
||||
$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
|
||||
$(XSLTPROC) --nonet -o $(srcdir)/devhelp/ \
|
||||
$(top_srcdir)/docs/devhelp/devhelp.xsl $(srcdir)/libvirt-api.xml ; fi
|
||||
|
||||
|
||||
python_generated_files = \
|
||||
$(srcdir)/html/libvirt-libvirt.html \
|
||||
$(srcdir)/html/libvirt-libvirt-qemu.html \
|
||||
$(srcdir)/html/libvirt-virterror.html \
|
||||
$(srcdir)/libvirt-api.xml \
|
||||
$(srcdir)/libvirt-refs.xml \
|
||||
$(srcdir)/libvirt-qemu-api.xml \
|
||||
$(srcdir)/libvirt-qemu-refs.xml
|
||||
|
||||
APIBUILD=$(srcdir)/apibuild.py
|
||||
APIBUILD_STAMP=$(APIBUILD).stamp
|
||||
EXTRA_DIST += $(APIBUILD_STAMP)
|
||||
|
||||
$(python_generated_files): $(APIBUILD_STAMP)
|
||||
|
||||
$(APIBUILD_STAMP): $(srcdir)/apibuild.py \
|
||||
$(srcdir)/../include/libvirt/libvirt.h.in \
|
||||
$(srcdir)/../include/libvirt/libvirt-qemu.h \
|
||||
$(srcdir)/../include/libvirt/virterror.h \
|
||||
$(srcdir)/../src/libvirt.c \
|
||||
$(srcdir)/../src/libvirt-qemu.c \
|
||||
$(srcdir)/../src/util/virterror.c
|
||||
$(AM_V_GEN)srcdir=$(srcdir) $(PYTHON) $(APIBUILD)
|
||||
touch $@
|
||||
|
||||
|
||||
check-local: all
|
||||
|
||||
clean-local:
|
||||
rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html
|
||||
|
||||
maintainer-clean-local: clean-local
|
||||
rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml todo.html.in hvsupport.html.in
|
||||
rm -rf $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-refs.xml
|
||||
rm -rf $(APIBUILD_STAMP)
|
||||
|
||||
rebuild: api qemu_api all
|
||||
|
||||
install-data-local:
|
||||
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)
|
||||
for f in $(css) $(dot_html) $(gif) $(png); do \
|
||||
$(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR); done
|
||||
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/html
|
||||
for h in $(apihtml); do \
|
||||
$(INSTALL) -m 0644 $(srcdir)/$$h $(DESTDIR)$(HTML_DIR)/html; done
|
||||
for p in $(apipng); do \
|
||||
$(INSTALL) -m 0644 $(srcdir)/$$p $(DESTDIR)$(HTML_DIR)/html; done
|
||||
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/internals
|
||||
for f in $(internals_html); do \
|
||||
$(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR)/internals; done
|
||||
$(mkinstalldirs) $(DESTDIR)$(DEVHELP_DIR)
|
||||
for file in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
|
||||
$(INSTALL) -m 0644 $(srcdir)/$${file} $(DESTDIR)$(DEVHELP_DIR) ; \
|
||||
done
|
||||
|
||||
uninstall-local:
|
||||
for h in $(apihtml); do rm $(DESTDIR)$(HTML_DIR)/$$h; done
|
||||
for p in $(apipng); do rm $(DESTDIR)$(HTML_DIR)/$$p; done
|
||||
for f in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
|
||||
rm $(DESTDIR)$(DEVHELP_DIR)/$$(basename $$f); \
|
||||
done
|
126
docs/api.html.in
126
docs/api.html.in
@ -1,126 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1>The libvirt API concepts</h1>
|
||||
|
||||
<p> This page describes the main principles and architecture choices
|
||||
behind the definition of the libvirt API:</p>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="Objects">Objects exposed</a></h2>
|
||||
<p> As defined in the <a href="goals.html">goals section</a>, libvirt
|
||||
API need to expose all the resources needed to manage the virtualization
|
||||
support of recent operating systems. The first object manipulated though
|
||||
the API is <code>virConnectPtr</code> which represent a connection to
|
||||
an hypervisor. Any application using libvirt is likely to start using the
|
||||
API by calling one of <a href="html/libvirt-libvirt.html#virConnectOpen"
|
||||
>the virConnectOpen functions</a>. You will note that those functions take
|
||||
a name argument which is actually an URI to select the right hypervisor to
|
||||
open, this is needed to allow remote connections and also select between
|
||||
different possible hypervisors (for example on a Linux system it may be
|
||||
possible to use both KVM and LinuxContainers on the same node). A NULL
|
||||
name will default to a preselected hypervisor but it's probably not a
|
||||
wise thing to do in most cases. See the <a href="uri.html">connection
|
||||
URI</a> page for a full descriptions of the values allowed.</p>
|
||||
<p> Once the application obtained a <code class='docref'>virConnectPtr</code>
|
||||
connection to the
|
||||
hypervisor it can then use it to manage domains and related resources
|
||||
available for virtualization like storage and networking. All those are
|
||||
exposed as first class objects, and connected to the hypervisor connection
|
||||
(and the node or cluster where it is available).</p>
|
||||
<p class="image">
|
||||
<img alt="first class objects exposed by the API"
|
||||
src="libvirt-object-model.png"/>
|
||||
</p>
|
||||
<p> The figure above shows the five main objects exported by the API:</p>
|
||||
<ul>
|
||||
<li>virConnectPtr: represent a connection to an hypervisor.</li>
|
||||
<li>virDomainPtr: represent one domain either active or defined (i.e.
|
||||
existing as permanent config file and storage but not currently running
|
||||
on that node). The function <code class='docref'>virConnectListDomains</code>
|
||||
allows to list all the IDs for the domains active on this hypervisor.</li>
|
||||
<li>virNetworkPtr: represent one network either active or defined (i.e.
|
||||
existing as permanent config file and storage but not currently activated.
|
||||
The function <code class='docref'>virConnectListNetworks</code>
|
||||
allows to list all the virtualization networks actived on this node.</li>
|
||||
<li>virStorageVolPtr: represent one storage volume, usually this is used
|
||||
as a block device available to one of the domains. The function
|
||||
<code class="docref">virStorageVolLookupByPath</code> allows to find
|
||||
the object based on its path on the node.</li>
|
||||
<li>virStoragePoolPtr: represent a storage pool, i.e. a logical area
|
||||
which can be used to allocate and store storage volumes. The function
|
||||
<code class="docref">virStoragePoolLookupByVolume</code> allows to find
|
||||
the storage pool containing a given storage volume.</li>
|
||||
</ul>
|
||||
<p> Most object manipulated by the library can also be represented using
|
||||
XML descriptions. This is used primarily to create those object, but is
|
||||
also helpful to modify or save their description back.</p>
|
||||
<p> Domains, network and storage pools can be either <code>active</code>
|
||||
i.e. either running or available for immediate use, or
|
||||
<code>defined</code> in which case they are inactive but there is
|
||||
a permanent definition available in the system for them. Based on this
|
||||
thay can be activated dynamically in order to be used.</p>
|
||||
<p> Most kind of object can also be named in various ways:</p>
|
||||
<ul>
|
||||
<li>by their <code>name</code>, an user friendly identifier but
|
||||
whose unicity cannot be garanteed between two nodes.</li>
|
||||
<li>by their <code>ID</code>, which is a runtime unique identifier
|
||||
provided by the hypervisor for one given activation of the object,
|
||||
but it becomes invalid once the resource is deactivated.</li >
|
||||
<li>by their <code>UUID</code>, a 16 bytes unique identifier
|
||||
as defined in <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>,
|
||||
which is garanteed to be unique for long term usage and across a
|
||||
set of nodes.</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="Functions">Functions and naming
|
||||
conventions</a></h2>
|
||||
<p> The naming of the functions present in the library is usually
|
||||
made of a prefix describing the object associated to the function
|
||||
and a verb describing the action on that object.</p>
|
||||
<p> For each first class object you will find apis
|
||||
for the following actions:</p>
|
||||
<ul>
|
||||
<li><b>Lookup</b>:...LookupByName,</li>
|
||||
<li><b>Enumeration</b>:virConnectList... and virConnectNumOf...:
|
||||
those are used to enumerate a set of object available to an given
|
||||
hypervisor connection like:
|
||||
<code class='docref'>virConnectListDomains</code>,
|
||||
<code class='docref'>virConnectNumOfDomains</code>,
|
||||
<code class='docref'>virConnectListNetworks</code>,
|
||||
<code class='docref'>virConnectListStoragePools</code>, etc.</li>
|
||||
<li><b>Description</b>: ...GetInfo: those are generic accessor providing
|
||||
a set of informations about an object, they are
|
||||
<code class='docref'>virNodeGetInfo</code>,
|
||||
<code class='docref'>virDomainGetInfo</code>,
|
||||
<code class='docref'>virStoragePoolGetInfo</code>,
|
||||
<code class='docref'>virStorageVolGetInfo</code>.</li>
|
||||
<li><b>Accessors</b>: ...Get... and ...Set...: those are more specific
|
||||
accessors to query or modify the given object, like
|
||||
<code class='docref'>virConnectGetType</code>,
|
||||
<code class='docref'>virDomainGetMaxMemory</code>,
|
||||
<code class='docref'>virDomainSetMemory</code>,
|
||||
<code class='docref'>virDomainGetVcpus</code>,
|
||||
<code class='docref'>virStoragePoolSetAutostart</code>,
|
||||
<code class='docref'>virNetworkGetBridgeName</code>, etc.</li>
|
||||
<li><b>Creation</b>: </li>
|
||||
<li><b>Destruction</b>: ... </li>
|
||||
</ul>
|
||||
<p> For more in-depth details of the storage related APIs see
|
||||
<a href="storage.html">the storage management page</a>.
|
||||
</p>
|
||||
<h2><a name="Driver">The libvirt drivers</a></h2>
|
||||
<p></p>
|
||||
<p class="image">
|
||||
<img alt="The libvirt driver architecture"
|
||||
src="libvirt-driver-arch.png"/>
|
||||
</p>
|
||||
<h2><a name="Remote">Daemon and remote access</a></h2>
|
||||
<p></p>
|
||||
<p class="image">
|
||||
<img alt="The libvirt daemon and remote architecture"
|
||||
src="libvirt-daemon-arch.png"/>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -1,433 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Implementing a new API in Libvirt</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Implementing a new API in Libvirt</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<p>
|
||||
This document walks you through the process of implementing a new
|
||||
API in libvirt. It uses as an example the addition of an API for
|
||||
separating maximum from current vcpu usage of a domain, over
|
||||
the course of a fifteen-patch series.
|
||||
Remember that new API consists of any new public functions, as
|
||||
well as the addition of flags or extensions of XML used by
|
||||
existing functions. The example in this document adds both new
|
||||
functions and an XML extension. Not all libvirt API additions
|
||||
require quite as many patches.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Before you begin coding, it is critical that you propose your
|
||||
changes on the libvirt mailing list and get feedback on your ideas to
|
||||
make sure what you're proposing fits with the general direction of the
|
||||
project. Even before doing a proof of concept implementation, send an
|
||||
email giving an overview of the functionality you think should be
|
||||
added to libvirt. Someone may already be working on the feature you
|
||||
want. Also, recognize that everything you write is likely to undergo
|
||||
significant rework as you discuss it with the other developers, so
|
||||
don't wait too long before getting feedback. In the vcpu example
|
||||
below, list feedback was first requested
|
||||
<a href="https://www.redhat.com/archives/libvir-list/2010-September/msg00423.html">here</a>
|
||||
and resulted in several rounds of improvements before coding
|
||||
began. In turn, this example is slightly rearranged from the actual
|
||||
order of the commits.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Adding a new API to libvirt is not difficult, but there are quite a
|
||||
few steps. This document assumes that you are familiar with C
|
||||
programming and have checked out the libvirt code from the source code
|
||||
repository and successfully built the existing tree. Instructions on
|
||||
how to check out and build the code can be found at:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="http://libvirt.org/downloads.html">http://libvirt.org/downloads.html</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once you have a working development environment, the steps to create a
|
||||
new API are:
|
||||
</p>
|
||||
<ol>
|
||||
<li>define the public API</li>
|
||||
<li>define the internal driver API</li>
|
||||
<li>implement the public API</li>
|
||||
<li>implement the remote protocol:
|
||||
<ol>
|
||||
<li>define the wire protocol format</li>
|
||||
<li>implement the RPC client</li>
|
||||
<li>implement the server side dispatcher</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>use new API where appropriate in drivers</li>
|
||||
<li>add virsh support</li>
|
||||
<li>add common handling for new API</li>
|
||||
<li>for each driver that can support the new API:
|
||||
<ol>
|
||||
<li>add prerequisite support</li>
|
||||
<li>fully implement new API</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
It is, of course, possible to implement the pieces in any order, but
|
||||
if the development tasks are completed in the order listed, the code
|
||||
will compile after each step. Given the number of changes required,
|
||||
verification after each step is highly recommended.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Submit new code in the form shown in the example code: one patch
|
||||
per step. That's not to say submit patches before you have working
|
||||
functionality--get the whole thing working and make sure you're happy
|
||||
with it. Then use git or some other version control system that lets
|
||||
you rewrite your commit history and break patches into pieces so you
|
||||
don't drop a big blob of code on the mailing list in one go.
|
||||
Also, you should follow the upstream tree, and rebase your
|
||||
series to adapt your patches to work with any other changes
|
||||
that were accepted upstream during your development.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Don't mix anything else into the patches you submit. The patches
|
||||
should be the minimal changes required to implement the functionality
|
||||
you're adding. If you notice a bug in unrelated code (i.e., code you
|
||||
don't have to touch to implement your API change) during development,
|
||||
create a patch that just addresses that bug and submit it
|
||||
separately.
|
||||
</p>
|
||||
|
||||
<p>With that said, let's begin.</p>
|
||||
|
||||
<h2><a name='publicapi'>Defining the public API</a></h2>
|
||||
|
||||
<p>The first task is to define the public API. If the new API
|
||||
involves an XML extension, you have to enhance the RelaxNG
|
||||
schema and document the new elements or attributes:</p>
|
||||
|
||||
<p><code>
|
||||
docs/schemas/domain.rng<br/>
|
||||
docs/formatdomain.html.in
|
||||
</code></p>
|
||||
|
||||
<p>If the API extension involves a new function, you have to add a
|
||||
declaration in the public header, and arrange to export the
|
||||
function name (symbol) so other programs can link against the
|
||||
libvirt library and call the new function:</p>
|
||||
|
||||
<p><code>
|
||||
include/libvirt/libvirt.h.in
|
||||
src/libvirt_public.syms
|
||||
</code></p>
|
||||
|
||||
<p>
|
||||
This task is in many ways the most important to get right, since once
|
||||
the API has been committed to the repository, it's libvirt's policy
|
||||
never to change it. Mistakes in the implementation are bugs that you
|
||||
can fix. Make a mistake in the API definition and you're stuck with
|
||||
it, so think carefully about the interface and don't be afraid to
|
||||
rework it as you go through the process of implementing it.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0001-add-to-xml.patch">0001-add-to-xml.patch</a>
|
||||
and <a href="api_extension/0002-add-new-public-API.patch">0002-add-new-public-API.patch</a>
|
||||
for example code.</p>
|
||||
|
||||
<h2><a name='internalapi'>Defining the internal API</a></h2>
|
||||
|
||||
<p>
|
||||
Each public API call is associated with a driver, such as a host
|
||||
virtualization driver, a network virtualization driver, a storage
|
||||
virtualization driver, a state driver, or a device monitor. Adding
|
||||
the internal API is ordinarily a matter of adding a new member to the
|
||||
struct representing one of these drivers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Of course, it's possible that the new API will involve the creation of
|
||||
an entirely new driver type, in which case the changes will include the
|
||||
creation of a new struct type to represent the new driver type.
|
||||
</p>
|
||||
|
||||
<p>The driver structs are defined in:</p>
|
||||
|
||||
<p><code>src/driver.h</code></p>
|
||||
|
||||
<p>
|
||||
To define the internal API, first typedef the driver function
|
||||
prototype and then add a new field for it to the relevant driver
|
||||
struct. Then, update all existing instances of the driver to
|
||||
provide a <code>NULL</code> stub for the new function.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0003-define-internal-driver-API.patch">0003-define-internal-driver-API.patch</a></p>
|
||||
|
||||
<h2><a name='implpublic'>Implementing the public API</a></h2>
|
||||
|
||||
<p>
|
||||
Implementing the public API is largely a formality in which we wire up
|
||||
public API to the internal driver API. The public API implementation
|
||||
takes care of some basic validity checks before passing control to the
|
||||
driver implementation. In RFC 2119 vocabulary, this function:
|
||||
</p>
|
||||
|
||||
<ol class="ordinarylist">
|
||||
<li>SHOULD log a message with VIR_DEBUG() indicating that it is
|
||||
being called and its parameters;</li>
|
||||
<li>MUST call virResetLastError();</li>
|
||||
<li>SHOULD confirm that the connection is valid with
|
||||
VIR_IS_CONNECT(conn);</li>
|
||||
<li><strong>SECURITY: If the API requires a connection with write
|
||||
privileges, MUST confirm that the connection flags do not
|
||||
indicate that the connection is read-only;</strong></li>
|
||||
<li>SHOULD do basic validation of the parameters that are being
|
||||
passed in;</li>
|
||||
<li>MUST confirm that the driver for this connection exists and that
|
||||
it implements this function;</li>
|
||||
<li>MUST call the internal API;</li>
|
||||
<li>SHOULD log a message with VIR_DEBUG() indicating that it is
|
||||
returning, its return value, and status.</li>
|
||||
<li>MUST return status to the caller.</li>
|
||||
</ol>
|
||||
|
||||
<p>The public API calls are implemented in:</p>
|
||||
|
||||
<p><code>src/libvirt.c</code></p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0004-implement-the-public-APIs.patch">0004-implement-the-public-APIs.patch</a></p>
|
||||
|
||||
<h2><a name='remoteproto'>Implementing the remote protocol</a></h2>
|
||||
|
||||
<p>
|
||||
Implementing the remote protocol is essentially a
|
||||
straightforward exercise which is probably most easily
|
||||
understood by referring to the existing code and the example
|
||||
patch. It involves several related changes, including the
|
||||
regeneration of derived files, with further details below.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0005-implement-the-remote-protocol.patch">0005-implement-the-remote-protocol.patch</a></p>
|
||||
|
||||
<h3><a name='wireproto'>Defining the wire protocol format</a></h3>
|
||||
|
||||
<p>
|
||||
Defining the wire protocol involves making additions to:
|
||||
</p>
|
||||
|
||||
<p><code>src/remote/remote_protocol.x</code></p>
|
||||
|
||||
<p>
|
||||
First, create two new structs for each new function that you're adding
|
||||
to the API. One struct describes the parameters to be passed to the
|
||||
remote function, and a second struct describes the value returned by
|
||||
the remote function. The one exception to this rule is that functions
|
||||
that return only 0 or -1 for status do not require a struct for returned
|
||||
data.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Second, add values to the remote_procedure enum for each new function
|
||||
added to the API.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once these changes are in place, it's necessary to run 'make rpcgen'
|
||||
in the src directory to create the .c and .h files required by the
|
||||
remote protocol code. This must be done on a Linux host using the
|
||||
GLibC rpcgen program. Other rpcgen versions may generate code which
|
||||
results in bogus compile time warnings. This regenerates the
|
||||
following files:
|
||||
</p>
|
||||
|
||||
<p><code>
|
||||
daemon/remote_dispatch_args.h
|
||||
daemon/remote_dispatch_prototypes.h
|
||||
daemon/remote_dispatch_table.h
|
||||
src/remote/remote_protocol.c
|
||||
src/remote/remote_protocol.h
|
||||
</code></p>
|
||||
|
||||
<h3><a name='rpcclient'>Implement the RPC client</a></h3>
|
||||
|
||||
<p>
|
||||
Implementing the uses the rpcgen generated .h files. The remote
|
||||
method calls go in:
|
||||
</p>
|
||||
|
||||
<p><code>src/remote/remote_internal.c</code></p>
|
||||
|
||||
<p>Each remote method invocation does the following:</p>
|
||||
|
||||
<ol class="ordinarylist">
|
||||
<li>locks the remote driver;</li>
|
||||
<li>sets up the method arguments;</li>
|
||||
<li>invokes the remote function;</li>
|
||||
<li>checks the return value, if necessary;</li>
|
||||
<li>extracts any returned data;</li>
|
||||
<li>frees any returned data;</li>
|
||||
<li>unlocks the remote driver.</li>
|
||||
</ol>
|
||||
|
||||
<h3><a name="serverdispatch">Implement the server side dispatcher</a></h3>
|
||||
|
||||
<p>
|
||||
Implementing the server side of the remote function call is simply a
|
||||
matter of deserializing the parameters passed in from the remote
|
||||
caller and passing them to the corresponding internal API function.
|
||||
The server side dispatchers are implemented in:
|
||||
</p>
|
||||
|
||||
<p><code>daemon/remote.c</code></p>
|
||||
|
||||
<p>Again, this step uses the .h files generated by make rpcgen.</p>
|
||||
|
||||
<p>
|
||||
After all three pieces of the remote protocol are complete, and
|
||||
the generated files have been updated, it will be necessary to
|
||||
update the file:</p>
|
||||
|
||||
<p><code>src/remote_protocol-structs</code></p>
|
||||
|
||||
<p>
|
||||
This file should only have new lines added; modifications to
|
||||
existing lines probably imply a backwards-incompatible API change.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0005-implement-the-remote-protocol.patch">0005-implement-the-remote-protocol.patch</a></p>
|
||||
|
||||
<h2><a name="internaluseapi">Use the new API internally</a></h2>
|
||||
|
||||
<p>
|
||||
Sometimes, a new API serves as a superset of existing API, by
|
||||
adding more granularity in what can be managed. When this is
|
||||
the case, it makes sense to share a common implementation by
|
||||
making the older API become a trivial wrapper around the new
|
||||
API, rather than duplicating the common code. This step should
|
||||
not introduce any semantic differences for the old API, and is
|
||||
not necessary if the new API has no relation to existing API.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0006-make-old-API-trivially-wrap-to-new-API.patch">0006-make-old-API-trivially-wrap-to-new-API.patch</a></p>
|
||||
|
||||
<h2><a name="virshuseapi">Expose the new API in virsh</a></h2>
|
||||
|
||||
<p>
|
||||
All new API should be manageable from the virsh command line
|
||||
shell. This proves that the API is sufficient for the intended
|
||||
purpose, and helps to identify whether the proposed API needs
|
||||
slight changes for easier usage. However, remember that virsh
|
||||
is used to connect to hosts running older versions of libvirtd,
|
||||
so new commands should have fallbacks to an older API if
|
||||
possible; implementing the virsh hooks at this point makes it
|
||||
very easy to test these fallbacks. Also remember to document
|
||||
virsh additions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A virsh command is composed of a few pieces of code. You need to
|
||||
define an array of vshCmdInfo structs for each new command that
|
||||
contain the help text and the command description text. You also need
|
||||
an array of vshCmdOptDef structs to describe the command options.
|
||||
Once you have those pieces in place you can write the function
|
||||
implementing the virsh command. Finally, you need to add the new
|
||||
command to the commands[] array. The following files need changes:
|
||||
</p>
|
||||
|
||||
<p><code>
|
||||
tools/virsh.c<br/>
|
||||
tools/virsh.pod
|
||||
</code></p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0007-add-virsh-support.patch">0007-add-virsh-support.patch</a></p>
|
||||
|
||||
<h2><a name="driverimpl">Implement the driver methods</a></h2>
|
||||
|
||||
<p>
|
||||
So, after all that, we get to the fun part. All functionality in
|
||||
libvirt is implemented inside a driver. Thus, here is where you
|
||||
implement whatever functionality you're adding to libvirt. You'll
|
||||
either need to add additional files to the src directory or extend
|
||||
files that are already there, depending on what functionality you're
|
||||
adding.
|
||||
</p>
|
||||
|
||||
<h3><a name="commonimpl">Implement common handling</a></h3>
|
||||
|
||||
<p>
|
||||
If the new API is applicable to more than one driver, it may
|
||||
make sense to provide some utility routines, or to factor some
|
||||
of the work into the dispatcher, to avoid reimplementing the
|
||||
same code in every driver. In the example code, this involved
|
||||
adding a member to the virDomainDefPtr struct for mapping
|
||||
between the XML API addition and the in-memory representation of
|
||||
a domain, along with updating all clients to use the new member.
|
||||
Up to this point, there have been no changes to existing
|
||||
semantics, and the new APIs will fail unless they are used in
|
||||
the same way as the older API wrappers.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0008-support-new-xml.patch">0008-support-new-xml.patch</a></p>
|
||||
|
||||
<h3><a name="drivercode">Implement driver handling</a></h3>
|
||||
|
||||
<p>
|
||||
The remaining patches should only touch one driver at a time.
|
||||
It is possible to implement all changes for a driver in one
|
||||
patch, but for review purposes it may still make sense to break
|
||||
things into simpler steps. Here is where the new APIs finally
|
||||
start working.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the example patches, three separate drivers are supported:
|
||||
test, qemu, and xen. It is always a good idea to patch the test
|
||||
driver in addition to the target driver, to prove that the API
|
||||
can be used for more than one driver. The example updates the
|
||||
test driver in one patch:
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0009-support-all-flags-in-test-driver.patch">0009-support-all-flags-in-test-driver.patch</a></p>
|
||||
|
||||
<p>
|
||||
The qemu changes were easier to split into two phases, one for
|
||||
updating the mapping between the new XML and the hypervisor
|
||||
command line arguments, and one for supporting all possible
|
||||
flags of the new API:
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0010-improve-vcpu-support-in-qemu-command-line.patch">0010-improve-vcpu-support-in-qemu-command-line.patch</a>
|
||||
and <a href="api_extension/0011-complete-vcpu-support-in-qemu-driver.patch">0011-complete-vcpu-support-in-qemu-driver.patch</a></p>
|
||||
|
||||
<p>
|
||||
Finally, the example breaks the xen driver changes across four
|
||||
patches. One maps the XML changes to the hypervisor command,
|
||||
the next two are independently implementing the getter and
|
||||
setter APIs, and the last one provides cleanup of code that was
|
||||
rendered dead by the new API.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0012-improve-vcpu-support-in-xen-command-line.patch">0012-improve-vcpu-support-in-xen-command-line.patch</a>,
|
||||
<a href="api_extension/0013-improve-getting-xen-vcpu-counts.patch">0013-improve-getting-xen-vcpu-counts.patch</a>,
|
||||
<a href="api_extension/0014-improve-setting-xen-vcpu-counts.patch">0014-improve-setting-xen-vcpu-counts.patch</a>,
|
||||
and <a href="api_extension/0015-remove-dead-xen-code.patch">0015-remove-dead-xen-code.patch</a></p>
|
||||
|
||||
<p>
|
||||
The exact details of the example code are probably uninteresting
|
||||
unless you're concerned with virtual cpu management.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once you have working functionality, run make check and make
|
||||
syntax-check on each patch of the series before submitting
|
||||
patches. It may also be worth writing tests for the libvirt-TCK
|
||||
testsuite to exercise your new API, although those patches are
|
||||
not kept in the libvirt repository.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -1,145 +0,0 @@
|
||||
From a74f4e44649906dcd82151f7ef837f66d7fa2ab1 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Mon, 27 Sep 2010 17:36:06 -0600
|
||||
Subject: [PATCH 01/15] vcpu: add current attribute to <vcpu> element
|
||||
|
||||
Syntax agreed on in
|
||||
https://www.redhat.com/archives/libvir-list/2010-September/msg00476.html
|
||||
|
||||
<domain ...>
|
||||
<vcpu current='x'>y</vcpu>
|
||||
...
|
||||
|
||||
can now be used to specify 1 <= x <= y current vcpus, in relation
|
||||
to the boot-time max of y vcpus. If current is omitted, then
|
||||
current and max are assumed to be the same value.
|
||||
|
||||
* docs/schemas/domain.rng: Add new attribute.
|
||||
* docs/formatdomain.html.in: Document it.
|
||||
* tests/qemuxml2argvdata/qemuxml2argv-smp.xml: Add to
|
||||
domainschematest.
|
||||
* tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml: Likewise.
|
||||
---
|
||||
docs/formatdomain.html.in | 9 +++++--
|
||||
docs/schemas/domain.rng | 5 ++++
|
||||
tests/qemuxml2argvdata/qemuxml2argv-smp.xml | 28 +++++++++++++++++++++++++++
|
||||
tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml | 22 +++++++++++++++++++++
|
||||
4 files changed, 61 insertions(+), 3 deletions(-)
|
||||
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smp.xml
|
||||
create mode 100644 tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
|
||||
|
||||
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
|
||||
index a8a1fac..96de121 100644
|
||||
--- a/docs/formatdomain.html.in
|
||||
+++ b/docs/formatdomain.html.in
|
||||
@@ -200,7 +200,7 @@
|
||||
<swap_hard_limit>2097152</swap_hard_limit>
|
||||
<min_guarantee>65536</min_guarantee>
|
||||
</memtune>
|
||||
- <vcpu cpuset="1-4,^3,6">2</vcpu>
|
||||
+ <vcpu cpuset="1-4,^3,6" current="1">2</vcpu>
|
||||
...</pre>
|
||||
|
||||
<dl>
|
||||
@@ -238,7 +238,7 @@
|
||||
minimum memory allocation for the guest. The units for this value are
|
||||
kilobytes (i.e. blocks of 1024 bytes)</dd>
|
||||
<dt><code>vcpu</code></dt>
|
||||
- <dd>The content of this element defines the number of virtual
|
||||
+ <dd>The content of this element defines the maximum number of virtual
|
||||
CPUs allocated for the guest OS, which must be between 1 and
|
||||
the maximum supported by the hypervisor. <span class="since">Since
|
||||
0.4.4</span>, this element can contain an optional
|
||||
@@ -246,7 +246,10 @@
|
||||
list of physical CPU numbers that virtual CPUs can be pinned
|
||||
to. Each element in that list is either a single CPU number,
|
||||
a range of CPU numbers, or a caret followed by a CPU number to
|
||||
- be excluded from a previous range.
|
||||
+ be excluded from a previous range. <span class="since">Since
|
||||
+ 0.8.5</span>, the optional attribute <code>current</code> can
|
||||
+ be used to specify whether fewer than the maximum number of
|
||||
+ virtual CPUs should be enabled.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
|
||||
index f230263..a934a77 100644
|
||||
--- a/docs/schemas/domain.rng
|
||||
+++ b/docs/schemas/domain.rng
|
||||
@@ -337,6 +337,11 @@
|
||||
<ref name="cpuset"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
+ <optional>
|
||||
+ <attribute name="current">
|
||||
+ <ref name="countCPU"/>
|
||||
+ </attribute>
|
||||
+ </optional>
|
||||
<ref name="countCPU"/>
|
||||
</element>
|
||||
</optional>
|
||||
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smp.xml b/tests/qemuxml2argvdata/qemuxml2argv-smp.xml
|
||||
new file mode 100644
|
||||
index 0000000..975f873
|
||||
--- /dev/null
|
||||
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smp.xml
|
||||
@@ -0,0 +1,28 @@
|
||||
+<domain type='qemu'>
|
||||
+ <name>QEMUGuest1</name>
|
||||
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||
+ <memory>219200</memory>
|
||||
+ <currentMemory>219200</currentMemory>
|
||||
+ <vcpu current='1'>2</vcpu>
|
||||
+ <os>
|
||||
+ <type arch='i686' machine='pc'>hvm</type>
|
||||
+ <boot dev='hd'/>
|
||||
+ </os>
|
||||
+ <cpu>
|
||||
+ <topology sockets='2' cores='1' threads='1'/>
|
||||
+ </cpu>
|
||||
+ <clock offset='utc'/>
|
||||
+ <on_poweroff>destroy</on_poweroff>
|
||||
+ <on_reboot>restart</on_reboot>
|
||||
+ <on_crash>destroy</on_crash>
|
||||
+ <devices>
|
||||
+ <emulator>/usr/bin/qemu</emulator>
|
||||
+ <disk type='block' device='disk'>
|
||||
+ <source dev='/dev/HostVG/QEMUGuest1'/>
|
||||
+ <target dev='hda' bus='ide'/>
|
||||
+ <address type='drive' controller='0' bus='0' unit='0'/>
|
||||
+ </disk>
|
||||
+ <controller type='ide' index='0'/>
|
||||
+ <memballoon model='virtio'/>
|
||||
+ </devices>
|
||||
+</domain>
|
||||
diff --git a/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
|
||||
new file mode 100644
|
||||
index 0000000..d061e11
|
||||
--- /dev/null
|
||||
+++ b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
|
||||
@@ -0,0 +1,22 @@
|
||||
+<domain type='xen' id='15'>
|
||||
+ <name>pvtest</name>
|
||||
+ <uuid>596a5d2171f48fb2e068e2386a5c413e</uuid>
|
||||
+ <os>
|
||||
+ <type>linux</type>
|
||||
+ <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel>
|
||||
+ <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd>
|
||||
+ <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os </cmdline>
|
||||
+ </os>
|
||||
+ <memory>430080</memory>
|
||||
+ <vcpu current='2'>4</vcpu>
|
||||
+ <on_poweroff>destroy</on_poweroff>
|
||||
+ <on_reboot>destroy</on_reboot>
|
||||
+ <on_crash>destroy</on_crash>
|
||||
+ <devices>
|
||||
+ <disk type='file' device='disk'>
|
||||
+ <source file='/root/some.img'/>
|
||||
+ <target dev='xvda'/>
|
||||
+ </disk>
|
||||
+ <console tty='/dev/pts/4'/>
|
||||
+ </devices>
|
||||
+</domain>
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,62 +0,0 @@
|
||||
From ea3f5c68093429c6ad507b45689cdf209c2c257b Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Fri, 24 Sep 2010 16:48:45 -0600
|
||||
Subject: [PATCH 02/15] vcpu: add new public API
|
||||
|
||||
API agreed on in
|
||||
https://www.redhat.com/archives/libvir-list/2010-September/msg00456.html,
|
||||
but modified for enum names to be consistent with virDomainDeviceModifyFlags.
|
||||
|
||||
* include/libvirt/libvirt.h.in (virDomainVcpuFlags)
|
||||
(virDomainSetVcpusFlags, virDomainGetVcpusFlags): New
|
||||
declarations.
|
||||
* src/libvirt_public.syms: Export new symbols.
|
||||
---
|
||||
include/libvirt/libvirt.h.in | 15 +++++++++++++++
|
||||
src/libvirt_public.syms | 2 ++
|
||||
2 files changed, 17 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
|
||||
index 2eba61e..d0cc4c0 100644
|
||||
--- a/include/libvirt/libvirt.h.in
|
||||
+++ b/include/libvirt/libvirt.h.in
|
||||
@@ -915,8 +915,23 @@ struct _virVcpuInfo {
|
||||
};
|
||||
typedef virVcpuInfo *virVcpuInfoPtr;
|
||||
|
||||
+/* Flags for controlling virtual CPU hot-plugging. */
|
||||
+typedef enum {
|
||||
+ /* Must choose at least one of these two bits; SetVcpus can choose both */
|
||||
+ VIR_DOMAIN_VCPU_LIVE = (1 << 0), /* Affect active domain */
|
||||
+ VIR_DOMAIN_VCPU_CONFIG = (1 << 1), /* Affect next boot */
|
||||
+
|
||||
+ /* Additional flags to be bit-wise OR'd in */
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM = (1 << 2), /* Max rather than current count */
|
||||
+} virDomainVcpuFlags;
|
||||
+
|
||||
int virDomainSetVcpus (virDomainPtr domain,
|
||||
unsigned int nvcpus);
|
||||
+int virDomainSetVcpusFlags (virDomainPtr domain,
|
||||
+ unsigned int nvcpus,
|
||||
+ unsigned int flags);
|
||||
+int virDomainGetVcpusFlags (virDomainPtr domain,
|
||||
+ unsigned int flags);
|
||||
|
||||
int virDomainPinVcpu (virDomainPtr domain,
|
||||
unsigned int vcpu,
|
||||
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
|
||||
index fceb516..a8091b1 100644
|
||||
--- a/src/libvirt_public.syms
|
||||
+++ b/src/libvirt_public.syms
|
||||
@@ -409,6 +409,8 @@ LIBVIRT_0.8.5 {
|
||||
global:
|
||||
virDomainSetMemoryParameters;
|
||||
virDomainGetMemoryParameters;
|
||||
+ virDomainGetVcpusFlags;
|
||||
+ virDomainSetVcpusFlags;
|
||||
} LIBVIRT_0.8.2;
|
||||
|
||||
# .... define new API here using predicted next version number ....
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,222 +0,0 @@
|
||||
From dd255d64053e9960cd375994ce8f056522e12acc Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Mon, 27 Sep 2010 09:18:22 -0600
|
||||
Subject: [PATCH 03/15] vcpu: define internal driver API
|
||||
|
||||
* src/driver.h (virDrvDomainSetVcpusFlags)
|
||||
(virDrvDomainGetVcpusFlags): New typedefs.
|
||||
(_virDriver): New callback members.
|
||||
* src/esx/esx_driver.c (esxDriver): Add stub for driver.
|
||||
* src/lxc/lxc_driver.c (lxcDriver): Likewise.
|
||||
* src/opennebula/one_driver.c (oneDriver): Likewise.
|
||||
* src/openvz/openvz_driver.c (openvzDriver): Likewise.
|
||||
* src/phyp/phyp_driver.c (phypDriver): Likewise.
|
||||
* src/qemu/qemu_driver.c (qemuDriver): Likewise.
|
||||
* src/remote/remote_driver.c (remote_driver): Likewise.
|
||||
* src/test/test_driver.c (testDriver): Likewise.
|
||||
* src/uml/uml_driver.c (umlDriver): Likewise.
|
||||
* src/vbox/vbox_tmpl.c (Driver): Likewise.
|
||||
* src/xen/xen_driver.c (xenUnifiedDriver): Likewise.
|
||||
* src/xenapi/xenapi_driver.c (xenapiDriver): Likewise.
|
||||
---
|
||||
src/driver.h | 9 +++++++++
|
||||
src/esx/esx_driver.c | 2 ++
|
||||
src/lxc/lxc_driver.c | 2 ++
|
||||
src/opennebula/one_driver.c | 2 ++
|
||||
src/openvz/openvz_driver.c | 2 ++
|
||||
src/phyp/phyp_driver.c | 2 ++
|
||||
src/qemu/qemu_driver.c | 2 ++
|
||||
src/remote/remote_driver.c | 2 ++
|
||||
src/test/test_driver.c | 2 ++
|
||||
src/uml/uml_driver.c | 2 ++
|
||||
src/vbox/vbox_tmpl.c | 2 ++
|
||||
src/xen/xen_driver.c | 2 ++
|
||||
src/xenapi/xenapi_driver.c | 2 ++
|
||||
13 files changed, 33 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/src/driver.h b/src/driver.h
|
||||
index 32aeb04..79a96c1 100644
|
||||
--- a/src/driver.h
|
||||
+++ b/src/driver.h
|
||||
@@ -185,6 +185,13 @@ typedef int
|
||||
(*virDrvDomainSetVcpus) (virDomainPtr domain,
|
||||
unsigned int nvcpus);
|
||||
typedef int
|
||||
+ (*virDrvDomainSetVcpusFlags) (virDomainPtr domain,
|
||||
+ unsigned int nvcpus,
|
||||
+ unsigned int flags);
|
||||
+typedef int
|
||||
+ (*virDrvDomainGetVcpusFlags) (virDomainPtr domain,
|
||||
+ unsigned int flags);
|
||||
+typedef int
|
||||
(*virDrvDomainPinVcpu) (virDomainPtr domain,
|
||||
unsigned int vcpu,
|
||||
unsigned char *cpumap,
|
||||
@@ -520,6 +527,8 @@ struct _virDriver {
|
||||
virDrvDomainRestore domainRestore;
|
||||
virDrvDomainCoreDump domainCoreDump;
|
||||
virDrvDomainSetVcpus domainSetVcpus;
|
||||
+ virDrvDomainSetVcpusFlags domainSetVcpusFlags;
|
||||
+ virDrvDomainGetVcpusFlags domainGetVcpusFlags;
|
||||
virDrvDomainPinVcpu domainPinVcpu;
|
||||
virDrvDomainGetVcpus domainGetVcpus;
|
||||
virDrvDomainGetMaxVcpus domainGetMaxVcpus;
|
||||
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
|
||||
index 1b4ee29..2a32374 100644
|
||||
--- a/src/esx/esx_driver.c
|
||||
+++ b/src/esx/esx_driver.c
|
||||
@@ -4160,6 +4160,8 @@ static virDriver esxDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
esxDomainSetVcpus, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
esxDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
|
||||
index df814da..7563a8c 100644
|
||||
--- a/src/lxc/lxc_driver.c
|
||||
+++ b/src/lxc/lxc_driver.c
|
||||
@@ -2768,6 +2768,8 @@ static virDriver lxcDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
NULL, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
NULL, /* domainGetMaxVcpus */
|
||||
diff --git a/src/opennebula/one_driver.c b/src/opennebula/one_driver.c
|
||||
index ced9a38..199fca3 100644
|
||||
--- a/src/opennebula/one_driver.c
|
||||
+++ b/src/opennebula/one_driver.c
|
||||
@@ -751,6 +751,8 @@ static virDriver oneDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
NULL, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
NULL, /* domainGetMaxVcpus */
|
||||
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
|
||||
index 92cf4a1..9d19aeb 100644
|
||||
--- a/src/openvz/openvz_driver.c
|
||||
+++ b/src/openvz/openvz_driver.c
|
||||
@@ -1590,6 +1590,8 @@ static virDriver openvzDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
openvzDomainSetVcpus, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
|
||||
index e63d8d9..6e0a5e9 100644
|
||||
--- a/src/phyp/phyp_driver.c
|
||||
+++ b/src/phyp/phyp_driver.c
|
||||
@@ -3941,6 +3941,8 @@ static virDriver phypDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
phypDomainSetCPU, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
phypGetLparCPUMAX, /* domainGetMaxVcpus */
|
||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||
index abd8e9d..3d17e04 100644
|
||||
--- a/src/qemu/qemu_driver.c
|
||||
+++ b/src/qemu/qemu_driver.c
|
||||
@@ -12938,6 +12938,8 @@ static virDriver qemuDriver = {
|
||||
qemudDomainRestore, /* domainRestore */
|
||||
qemudDomainCoreDump, /* domainCoreDump */
|
||||
qemudDomainSetVcpus, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
qemudDomainPinVcpu, /* domainPinVcpu */
|
||||
qemudDomainGetVcpus, /* domainGetVcpus */
|
||||
qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
|
||||
index 0b10406..1a687ad 100644
|
||||
--- a/src/remote/remote_driver.c
|
||||
+++ b/src/remote/remote_driver.c
|
||||
@@ -10468,6 +10468,8 @@ static virDriver remote_driver = {
|
||||
remoteDomainRestore, /* domainRestore */
|
||||
remoteDomainCoreDump, /* domainCoreDump */
|
||||
remoteDomainSetVcpus, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
remoteDomainPinVcpu, /* domainPinVcpu */
|
||||
remoteDomainGetVcpus, /* domainGetVcpus */
|
||||
remoteDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
|
||||
index 7d4d119..6a00558 100644
|
||||
--- a/src/test/test_driver.c
|
||||
+++ b/src/test/test_driver.c
|
||||
@@ -5260,6 +5260,8 @@ static virDriver testDriver = {
|
||||
testDomainRestore, /* domainRestore */
|
||||
testDomainCoreDump, /* domainCoreDump */
|
||||
testSetVcpus, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
testDomainPinVcpu, /* domainPinVcpu */
|
||||
testDomainGetVcpus, /* domainGetVcpus */
|
||||
testDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
|
||||
index 3dcd321..5161012 100644
|
||||
--- a/src/uml/uml_driver.c
|
||||
+++ b/src/uml/uml_driver.c
|
||||
@@ -2129,6 +2129,8 @@ static virDriver umlDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
NULL, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
NULL, /* domainGetMaxVcpus */
|
||||
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
|
||||
index 7e7d8e4..cb9193a 100644
|
||||
--- a/src/vbox/vbox_tmpl.c
|
||||
+++ b/src/vbox/vbox_tmpl.c
|
||||
@@ -8267,6 +8267,8 @@ virDriver NAME(Driver) = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
vboxDomainSetVcpus, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
vboxDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
|
||||
index c2a4de3..7d67ced 100644
|
||||
--- a/src/xen/xen_driver.c
|
||||
+++ b/src/xen/xen_driver.c
|
||||
@@ -1951,6 +1951,8 @@ static virDriver xenUnifiedDriver = {
|
||||
xenUnifiedDomainRestore, /* domainRestore */
|
||||
xenUnifiedDomainCoreDump, /* domainCoreDump */
|
||||
xenUnifiedDomainSetVcpus, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
xenUnifiedDomainPinVcpu, /* domainPinVcpu */
|
||||
xenUnifiedDomainGetVcpus, /* domainGetVcpus */
|
||||
xenUnifiedDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
|
||||
index e62a139..753169c 100644
|
||||
--- a/src/xenapi/xenapi_driver.c
|
||||
+++ b/src/xenapi/xenapi_driver.c
|
||||
@@ -1754,6 +1754,8 @@ static virDriver xenapiDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
xenapiDomainSetVcpus, /* domainSetVcpus */
|
||||
+ NULL, /* domainSetVcpusFlags */
|
||||
+ NULL, /* domainGetVcpusFlags */
|
||||
xenapiDomainPinVcpu, /* domainPinVcpu */
|
||||
xenapiDomainGetVcpus, /* domainGetVcpus */
|
||||
xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,188 +0,0 @@
|
||||
From 9d2c60799271d605f82dfd4bfa6ed7d14ad87e26 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Mon, 27 Sep 2010 09:37:22 -0600
|
||||
Subject: [PATCH 04/15] vcpu: implement the public APIs
|
||||
|
||||
Factors common checks (such as nonzero vcpu count) up front, but
|
||||
drivers will still need to do additional flag checks.
|
||||
|
||||
* src/libvirt.c (virDomainSetVcpusFlags, virDomainGetVcpusFlags):
|
||||
New functions.
|
||||
(virDomainSetVcpus, virDomainGetMaxVcpus): Refer to new API.
|
||||
---
|
||||
src/libvirt.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 files changed, 134 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/libvirt.c b/src/libvirt.c
|
||||
index 629d97b..1b39210 100644
|
||||
--- a/src/libvirt.c
|
||||
+++ b/src/libvirt.c
|
||||
@@ -5192,7 +5192,9 @@ error:
|
||||
* This function requires privileged access to the hypervisor.
|
||||
*
|
||||
* This command only changes the runtime configuration of the domain,
|
||||
- * so can only be called on an active domain.
|
||||
+ * so can only be called on an active domain. It is hypervisor-dependent
|
||||
+ * whether it also affects persistent configuration; for more control,
|
||||
+ * use virDomainSetVcpusFlags().
|
||||
*
|
||||
* Returns 0 in case of success, -1 in case of failure.
|
||||
*/
|
||||
@@ -5237,13 +5239,139 @@ error:
|
||||
}
|
||||
|
||||
/**
|
||||
+ * virDomainSetVcpusFlags:
|
||||
+ * @domain: pointer to domain object, or NULL for Domain0
|
||||
+ * @nvcpus: the new number of virtual CPUs for this domain, must be at least 1
|
||||
+ * @flags: an OR'ed set of virDomainVcpuFlags
|
||||
+ *
|
||||
+ * Dynamically change the number of virtual CPUs used by the domain.
|
||||
+ * Note that this call may fail if the underlying virtualization hypervisor
|
||||
+ * does not support it or if growing the number is arbitrary limited.
|
||||
+ * This function requires privileged access to the hypervisor.
|
||||
+ *
|
||||
+ * @flags must include VIR_DOMAIN_VCPU_LIVE to affect a running
|
||||
+ * domain (which may fail if domain is not active), or
|
||||
+ * VIR_DOMAIN_VCPU_CONFIG to affect the next boot via the XML
|
||||
+ * description of the domain. Both flags may be set.
|
||||
+ *
|
||||
+ * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then
|
||||
+ * VIR_DOMAIN_VCPU_LIVE must be clear, and only the maximum virtual
|
||||
+ * CPU limit is altered; generally, this value must be less than or
|
||||
+ * equal to virConnectGetMaxVcpus(). Otherwise, this call affects the
|
||||
+ * current virtual CPU limit, which must be less than or equal to the
|
||||
+ * maximum limit.
|
||||
+ *
|
||||
+ * Returns 0 in case of success, -1 in case of failure.
|
||||
+ */
|
||||
+
|
||||
+int
|
||||
+virDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
+ virConnectPtr conn;
|
||||
+ VIR_DEBUG("domain=%p, nvcpus=%u, flags=%u", domain, nvcpus, flags);
|
||||
+
|
||||
+ virResetLastError();
|
||||
+
|
||||
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
|
||||
+ virDispatchError(NULL);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ if (domain->conn->flags & VIR_CONNECT_RO) {
|
||||
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /* Perform some argument validation common to all implementations. */
|
||||
+ if (nvcpus < 1 || (unsigned short) nvcpus != nvcpus ||
|
||||
+ (flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) {
|
||||
+ virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
+ goto error;
|
||||
+ }
|
||||
+ conn = domain->conn;
|
||||
+
|
||||
+ if (conn->driver->domainSetVcpusFlags) {
|
||||
+ int ret;
|
||||
+ ret = conn->driver->domainSetVcpusFlags (domain, nvcpus, flags);
|
||||
+ if (ret < 0)
|
||||
+ goto error;
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
+
|
||||
+error:
|
||||
+ virDispatchError(domain->conn);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * virDomainGetVcpusFlags:
|
||||
+ * @domain: pointer to domain object, or NULL for Domain0
|
||||
+ * @flags: an OR'ed set of virDomainVcpuFlags
|
||||
+ *
|
||||
+ * Query the number of virtual CPUs used by the domain. Note that
|
||||
+ * this call may fail if the underlying virtualization hypervisor does
|
||||
+ * not support it. This function requires privileged access to the
|
||||
+ * hypervisor.
|
||||
+ *
|
||||
+ * @flags must include either VIR_DOMAIN_VCPU_ACTIVE to query a
|
||||
+ * running domain (which will fail if domain is not active), or
|
||||
+ * VIR_DOMAIN_VCPU_PERSISTENT to query the XML description of the
|
||||
+ * domain. It is an error to set both flags.
|
||||
+ *
|
||||
+ * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then the maximum
|
||||
+ * virtual CPU limit is queried. Otherwise, this call queries the
|
||||
+ * current virtual CPU limit.
|
||||
+ *
|
||||
+ * Returns 0 in case of success, -1 in case of failure.
|
||||
+ */
|
||||
+
|
||||
+int
|
||||
+virDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
|
||||
+{
|
||||
+ virConnectPtr conn;
|
||||
+ VIR_DEBUG("domain=%p, flags=%u", domain, flags);
|
||||
+
|
||||
+ virResetLastError();
|
||||
+
|
||||
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
|
||||
+ virDispatchError(NULL);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ /* Exactly one of these two flags should be set. */
|
||||
+ if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
|
||||
+ virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
+ goto error;
|
||||
+ }
|
||||
+ conn = domain->conn;
|
||||
+
|
||||
+ if (conn->driver->domainGetVcpusFlags) {
|
||||
+ int ret;
|
||||
+ ret = conn->driver->domainGetVcpusFlags (domain, flags);
|
||||
+ if (ret < 0)
|
||||
+ goto error;
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
+
|
||||
+error:
|
||||
+ virDispatchError(domain->conn);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* virDomainPinVcpu:
|
||||
* @domain: pointer to domain object, or NULL for Domain0
|
||||
* @vcpu: virtual CPU number
|
||||
* @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
|
||||
- * Each bit set to 1 means that corresponding CPU is usable.
|
||||
- * Bytes are stored in little-endian order: CPU0-7, 8-15...
|
||||
- * In each byte, lowest CPU number is least significant bit.
|
||||
+ * Each bit set to 1 means that corresponding CPU is usable.
|
||||
+ * Bytes are stored in little-endian order: CPU0-7, 8-15...
|
||||
+ * In each byte, lowest CPU number is least significant bit.
|
||||
* @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
|
||||
* underlying virtualization system (Xen...).
|
||||
* If maplen < size, missing bytes are set to zero.
|
||||
@@ -5371,9 +5499,9 @@ error:
|
||||
*
|
||||
* Provides the maximum number of virtual CPUs supported for
|
||||
* the guest VM. If the guest is inactive, this is basically
|
||||
- * the same as virConnectGetMaxVcpus. If the guest is running
|
||||
+ * the same as virConnectGetMaxVcpus(). If the guest is running
|
||||
* this will reflect the maximum number of virtual CPUs the
|
||||
- * guest was booted with.
|
||||
+ * guest was booted with. For more details, see virDomainGetVcpusFlags().
|
||||
*
|
||||
* Returns the maximum of virtual CPU or -1 in case of error.
|
||||
*/
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,421 +0,0 @@
|
||||
From eb826444f90c2563dadf148630b0cd6a9b41ba1e Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Mon, 27 Sep 2010 10:10:06 -0600
|
||||
Subject: [PATCH 05/15] vcpu: implement the remote protocol
|
||||
|
||||
Done by editing the first three files, then running
|
||||
'make -C src rpcgen', then editing src/remote_protocol-structs
|
||||
to match.
|
||||
|
||||
* daemon/remote.c (remoteDispatchDomainSetVcpusFlags)
|
||||
(remoteDispatchDomainGetVcpusFlags): New functions.
|
||||
* src/remote/remote_driver.c (remoteDomainSetVcpusFlags)
|
||||
(remoteDomainGetVcpusFlags, remote_driver): Client side
|
||||
serialization.
|
||||
* src/remote/remote_protocol.x
|
||||
(remote_domain_set_vcpus_flags_args)
|
||||
(remote_domain_get_vcpus_flags_args)
|
||||
(remote_domain_get_vcpus_flags_ret)
|
||||
(REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS)
|
||||
(REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS): Define wire format.
|
||||
* daemon/remote_dispatch_args.h: Regenerate.
|
||||
* daemon/remote_dispatch_prototypes.h: Likewise.
|
||||
* daemon/remote_dispatch_table.h: Likewise.
|
||||
* src/remote/remote_protocol.c: Likewise.
|
||||
* src/remote/remote_protocol.h: Likewise.
|
||||
* src/remote_protocol-structs: Likewise.
|
||||
---
|
||||
daemon/remote.c | 53 ++++++++++++++++++++++++++++++++
|
||||
daemon/remote_dispatch_args.h | 2 +
|
||||
daemon/remote_dispatch_prototypes.h | 16 ++++++++++
|
||||
daemon/remote_dispatch_ret.h | 1 +
|
||||
daemon/remote_dispatch_table.h | 10 ++++++
|
||||
src/remote/remote_driver.c | 57 +++++++++++++++++++++++++++++++++-
|
||||
src/remote/remote_protocol.c | 33 ++++++++++++++++++++
|
||||
src/remote/remote_protocol.h | 26 ++++++++++++++++
|
||||
src/remote/remote_protocol.x | 19 +++++++++++-
|
||||
src/remote_protocol-structs | 12 +++++++
|
||||
10 files changed, 226 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/daemon/remote.c b/daemon/remote.c
|
||||
index 7a96e29..323f00c 100644
|
||||
--- a/daemon/remote.c
|
||||
+++ b/daemon/remote.c
|
||||
@@ -1751,6 +1751,33 @@ oom:
|
||||
}
|
||||
|
||||
static int
|
||||
+remoteDispatchDomainGetVcpusFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
+ struct qemud_client *client ATTRIBUTE_UNUSED,
|
||||
+ virConnectPtr conn,
|
||||
+ remote_message_header *hdr ATTRIBUTE_UNUSED,
|
||||
+ remote_error *rerr,
|
||||
+ remote_domain_get_vcpus_flags_args *args,
|
||||
+ remote_domain_get_vcpus_flags_ret *ret)
|
||||
+{
|
||||
+ virDomainPtr dom;
|
||||
+
|
||||
+ dom = get_nonnull_domain (conn, args->dom);
|
||||
+ if (dom == NULL) {
|
||||
+ remoteDispatchConnError(rerr, conn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ ret->num = virDomainGetVcpusFlags (dom, args->flags);
|
||||
+ if (ret->num == -1) {
|
||||
+ virDomainFree(dom);
|
||||
+ remoteDispatchConnError(rerr, conn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ virDomainFree(dom);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
remoteDispatchDomainMigratePrepare (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
struct qemud_client *client ATTRIBUTE_UNUSED,
|
||||
virConnectPtr conn,
|
||||
@@ -2568,6 +2595,32 @@ remoteDispatchDomainSetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
static int
|
||||
+remoteDispatchDomainSetVcpusFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
+ struct qemud_client *client ATTRIBUTE_UNUSED,
|
||||
+ virConnectPtr conn,
|
||||
+ remote_message_header *hdr ATTRIBUTE_UNUSED,
|
||||
+ remote_error *rerr,
|
||||
+ remote_domain_set_vcpus_flags_args *args,
|
||||
+ void *ret ATTRIBUTE_UNUSED)
|
||||
+{
|
||||
+ virDomainPtr dom;
|
||||
+
|
||||
+ dom = get_nonnull_domain (conn, args->dom);
|
||||
+ if (dom == NULL) {
|
||||
+ remoteDispatchConnError(rerr, conn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (virDomainSetVcpusFlags (dom, args->nvcpus, args->flags) == -1) {
|
||||
+ virDomainFree(dom);
|
||||
+ remoteDispatchConnError(rerr, conn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ virDomainFree(dom);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
remoteDispatchDomainShutdown (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
struct qemud_client *client ATTRIBUTE_UNUSED,
|
||||
virConnectPtr conn,
|
||||
diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h
|
||||
index d8528b6..9583e9c 100644
|
||||
--- a/daemon/remote_dispatch_args.h
|
||||
+++ b/daemon/remote_dispatch_args.h
|
||||
@@ -167,3 +167,5 @@
|
||||
remote_domain_create_with_flags_args val_remote_domain_create_with_flags_args;
|
||||
remote_domain_set_memory_parameters_args val_remote_domain_set_memory_parameters_args;
|
||||
remote_domain_get_memory_parameters_args val_remote_domain_get_memory_parameters_args;
|
||||
+ remote_domain_set_vcpus_flags_args val_remote_domain_set_vcpus_flags_args;
|
||||
+ remote_domain_get_vcpus_flags_args val_remote_domain_get_vcpus_flags_args;
|
||||
diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h
|
||||
index b674bb4..6b35851 100644
|
||||
--- a/daemon/remote_dispatch_prototypes.h
|
||||
+++ b/daemon/remote_dispatch_prototypes.h
|
||||
@@ -306,6 +306,14 @@ static int remoteDispatchDomainGetVcpus(
|
||||
remote_error *err,
|
||||
remote_domain_get_vcpus_args *args,
|
||||
remote_domain_get_vcpus_ret *ret);
|
||||
+static int remoteDispatchDomainGetVcpusFlags(
|
||||
+ struct qemud_server *server,
|
||||
+ struct qemud_client *client,
|
||||
+ virConnectPtr conn,
|
||||
+ remote_message_header *hdr,
|
||||
+ remote_error *err,
|
||||
+ remote_domain_get_vcpus_flags_args *args,
|
||||
+ remote_domain_get_vcpus_flags_ret *ret);
|
||||
static int remoteDispatchDomainHasCurrentSnapshot(
|
||||
struct qemud_server *server,
|
||||
struct qemud_client *client,
|
||||
@@ -554,6 +562,14 @@ static int remoteDispatchDomainSetVcpus(
|
||||
remote_error *err,
|
||||
remote_domain_set_vcpus_args *args,
|
||||
void *ret);
|
||||
+static int remoteDispatchDomainSetVcpusFlags(
|
||||
+ struct qemud_server *server,
|
||||
+ struct qemud_client *client,
|
||||
+ virConnectPtr conn,
|
||||
+ remote_message_header *hdr,
|
||||
+ remote_error *err,
|
||||
+ remote_domain_set_vcpus_flags_args *args,
|
||||
+ void *ret);
|
||||
static int remoteDispatchDomainShutdown(
|
||||
struct qemud_server *server,
|
||||
struct qemud_client *client,
|
||||
diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h
|
||||
index 17c9bca..3723b00 100644
|
||||
--- a/daemon/remote_dispatch_ret.h
|
||||
+++ b/daemon/remote_dispatch_ret.h
|
||||
@@ -136,3 +136,4 @@
|
||||
remote_domain_get_block_info_ret val_remote_domain_get_block_info_ret;
|
||||
remote_domain_create_with_flags_ret val_remote_domain_create_with_flags_ret;
|
||||
remote_domain_get_memory_parameters_ret val_remote_domain_get_memory_parameters_ret;
|
||||
+ remote_domain_get_vcpus_flags_ret val_remote_domain_get_vcpus_flags_ret;
|
||||
diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h
|
||||
index 47d95eb..dd2adc7 100644
|
||||
--- a/daemon/remote_dispatch_table.h
|
||||
+++ b/daemon/remote_dispatch_table.h
|
||||
@@ -997,3 +997,13 @@
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_get_memory_parameters_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_get_memory_parameters_ret,
|
||||
},
|
||||
+{ /* DomainSetVcpusFlags => 199 */
|
||||
+ .fn = (dispatch_fn) remoteDispatchDomainSetVcpusFlags,
|
||||
+ .args_filter = (xdrproc_t) xdr_remote_domain_set_vcpus_flags_args,
|
||||
+ .ret_filter = (xdrproc_t) xdr_void,
|
||||
+},
|
||||
+{ /* DomainGetVcpusFlags => 200 */
|
||||
+ .fn = (dispatch_fn) remoteDispatchDomainGetVcpusFlags,
|
||||
+ .args_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_flags_args,
|
||||
+ .ret_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_flags_ret,
|
||||
+},
|
||||
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
|
||||
index 1a687ad..37c37ef 100644
|
||||
--- a/src/remote/remote_driver.c
|
||||
+++ b/src/remote/remote_driver.c
|
||||
@@ -2580,6 +2580,59 @@ done:
|
||||
}
|
||||
|
||||
static int
|
||||
+remoteDomainSetVcpusFlags (virDomainPtr domain, unsigned int nvcpus,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
+ int rv = -1;
|
||||
+ remote_domain_set_vcpus_flags_args args;
|
||||
+ struct private_data *priv = domain->conn->privateData;
|
||||
+
|
||||
+ remoteDriverLock(priv);
|
||||
+
|
||||
+ make_nonnull_domain (&args.dom, domain);
|
||||
+ args.nvcpus = nvcpus;
|
||||
+ args.flags = flags;
|
||||
+
|
||||
+ if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS,
|
||||
+ (xdrproc_t) xdr_remote_domain_set_vcpus_flags_args,
|
||||
+ (char *) &args,
|
||||
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
|
||||
+ goto done;
|
||||
+
|
||||
+ rv = 0;
|
||||
+
|
||||
+done:
|
||||
+ remoteDriverUnlock(priv);
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+remoteDomainGetVcpusFlags (virDomainPtr domain, unsigned int flags)
|
||||
+{
|
||||
+ int rv = -1;
|
||||
+ remote_domain_get_vcpus_flags_args args;
|
||||
+ remote_domain_get_vcpus_flags_ret ret;
|
||||
+ struct private_data *priv = domain->conn->privateData;
|
||||
+
|
||||
+ remoteDriverLock(priv);
|
||||
+
|
||||
+ make_nonnull_domain (&args.dom, domain);
|
||||
+ args.flags = flags;
|
||||
+
|
||||
+ memset (&ret, 0, sizeof ret);
|
||||
+ if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS,
|
||||
+ (xdrproc_t) xdr_remote_domain_get_vcpus_flags_args, (char *) &args,
|
||||
+ (xdrproc_t) xdr_remote_domain_get_vcpus_flags_ret, (char *) &ret) == -1)
|
||||
+ goto done;
|
||||
+
|
||||
+ rv = ret.num;
|
||||
+
|
||||
+done:
|
||||
+ remoteDriverUnlock(priv);
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
remoteDomainPinVcpu (virDomainPtr domain,
|
||||
unsigned int vcpu,
|
||||
unsigned char *cpumap,
|
||||
@@ -10468,8 +10521,8 @@ static virDriver remote_driver = {
|
||||
remoteDomainRestore, /* domainRestore */
|
||||
remoteDomainCoreDump, /* domainCoreDump */
|
||||
remoteDomainSetVcpus, /* domainSetVcpus */
|
||||
- NULL, /* domainSetVcpusFlags */
|
||||
- NULL, /* domainGetVcpusFlags */
|
||||
+ remoteDomainSetVcpusFlags, /* domainSetVcpusFlags */
|
||||
+ remoteDomainGetVcpusFlags, /* domainGetVcpusFlags */
|
||||
remoteDomainPinVcpu, /* domainPinVcpu */
|
||||
remoteDomainGetVcpus, /* domainGetVcpus */
|
||||
remoteDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c
|
||||
index 5c55713..38ea050 100644
|
||||
--- a/src/remote/remote_protocol.c
|
||||
+++ b/src/remote/remote_protocol.c
|
||||
@@ -1355,6 +1355,39 @@ xdr_remote_domain_set_vcpus_args (XDR *xdrs, remote_domain_set_vcpus_args *objp)
|
||||
}
|
||||
|
||||
bool_t
|
||||
+xdr_remote_domain_set_vcpus_flags_args (XDR *xdrs, remote_domain_set_vcpus_flags_args *objp)
|
||||
+{
|
||||
+
|
||||
+ if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
|
||||
+ return FALSE;
|
||||
+ if (!xdr_u_int (xdrs, &objp->nvcpus))
|
||||
+ return FALSE;
|
||||
+ if (!xdr_u_int (xdrs, &objp->flags))
|
||||
+ return FALSE;
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+bool_t
|
||||
+xdr_remote_domain_get_vcpus_flags_args (XDR *xdrs, remote_domain_get_vcpus_flags_args *objp)
|
||||
+{
|
||||
+
|
||||
+ if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
|
||||
+ return FALSE;
|
||||
+ if (!xdr_u_int (xdrs, &objp->flags))
|
||||
+ return FALSE;
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+bool_t
|
||||
+xdr_remote_domain_get_vcpus_flags_ret (XDR *xdrs, remote_domain_get_vcpus_flags_ret *objp)
|
||||
+{
|
||||
+
|
||||
+ if (!xdr_int (xdrs, &objp->num))
|
||||
+ return FALSE;
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+bool_t
|
||||
xdr_remote_domain_pin_vcpu_args (XDR *xdrs, remote_domain_pin_vcpu_args *objp)
|
||||
{
|
||||
char **objp_cpp0 = (char **) (void *) &objp->cpumap.cpumap_val;
|
||||
diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h
|
||||
index 756da11..d75e76c 100644
|
||||
--- a/src/remote/remote_protocol.h
|
||||
+++ b/src/remote/remote_protocol.h
|
||||
@@ -750,6 +750,24 @@ struct remote_domain_set_vcpus_args {
|
||||
};
|
||||
typedef struct remote_domain_set_vcpus_args remote_domain_set_vcpus_args;
|
||||
|
||||
+struct remote_domain_set_vcpus_flags_args {
|
||||
+ remote_nonnull_domain dom;
|
||||
+ u_int nvcpus;
|
||||
+ u_int flags;
|
||||
+};
|
||||
+typedef struct remote_domain_set_vcpus_flags_args remote_domain_set_vcpus_flags_args;
|
||||
+
|
||||
+struct remote_domain_get_vcpus_flags_args {
|
||||
+ remote_nonnull_domain dom;
|
||||
+ u_int flags;
|
||||
+};
|
||||
+typedef struct remote_domain_get_vcpus_flags_args remote_domain_get_vcpus_flags_args;
|
||||
+
|
||||
+struct remote_domain_get_vcpus_flags_ret {
|
||||
+ int num;
|
||||
+};
|
||||
+typedef struct remote_domain_get_vcpus_flags_ret remote_domain_get_vcpus_flags_ret;
|
||||
+
|
||||
struct remote_domain_pin_vcpu_args {
|
||||
remote_nonnull_domain dom;
|
||||
int vcpu;
|
||||
@@ -2281,6 +2299,8 @@ enum remote_procedure {
|
||||
REMOTE_PROC_DOMAIN_CREATE_WITH_FLAGS = 196,
|
||||
REMOTE_PROC_DOMAIN_SET_MEMORY_PARAMETERS = 197,
|
||||
REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198,
|
||||
+ REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS = 199,
|
||||
+ REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS = 200,
|
||||
};
|
||||
typedef enum remote_procedure remote_procedure;
|
||||
|
||||
@@ -2422,6 +2442,9 @@ extern bool_t xdr_remote_domain_define_xml_args (XDR *, remote_domain_define_xm
|
||||
extern bool_t xdr_remote_domain_define_xml_ret (XDR *, remote_domain_define_xml_ret*);
|
||||
extern bool_t xdr_remote_domain_undefine_args (XDR *, remote_domain_undefine_args*);
|
||||
extern bool_t xdr_remote_domain_set_vcpus_args (XDR *, remote_domain_set_vcpus_args*);
|
||||
+extern bool_t xdr_remote_domain_set_vcpus_flags_args (XDR *, remote_domain_set_vcpus_flags_args*);
|
||||
+extern bool_t xdr_remote_domain_get_vcpus_flags_args (XDR *, remote_domain_get_vcpus_flags_args*);
|
||||
+extern bool_t xdr_remote_domain_get_vcpus_flags_ret (XDR *, remote_domain_get_vcpus_flags_ret*);
|
||||
extern bool_t xdr_remote_domain_pin_vcpu_args (XDR *, remote_domain_pin_vcpu_args*);
|
||||
extern bool_t xdr_remote_domain_get_vcpus_args (XDR *, remote_domain_get_vcpus_args*);
|
||||
extern bool_t xdr_remote_domain_get_vcpus_ret (XDR *, remote_domain_get_vcpus_ret*);
|
||||
@@ -2762,6 +2785,9 @@ extern bool_t xdr_remote_domain_define_xml_args ();
|
||||
extern bool_t xdr_remote_domain_define_xml_ret ();
|
||||
extern bool_t xdr_remote_domain_undefine_args ();
|
||||
extern bool_t xdr_remote_domain_set_vcpus_args ();
|
||||
+extern bool_t xdr_remote_domain_set_vcpus_flags_args ();
|
||||
+extern bool_t xdr_remote_domain_get_vcpus_flags_args ();
|
||||
+extern bool_t xdr_remote_domain_get_vcpus_flags_ret ();
|
||||
extern bool_t xdr_remote_domain_pin_vcpu_args ();
|
||||
extern bool_t xdr_remote_domain_get_vcpus_args ();
|
||||
extern bool_t xdr_remote_domain_get_vcpus_ret ();
|
||||
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
|
||||
index e80fb5f..d57e6d0 100644
|
||||
--- a/src/remote/remote_protocol.x
|
||||
+++ b/src/remote/remote_protocol.x
|
||||
@@ -768,6 +768,21 @@ struct remote_domain_set_vcpus_args {
|
||||
int nvcpus;
|
||||
};
|
||||
|
||||
+struct remote_domain_set_vcpus_flags_args {
|
||||
+ remote_nonnull_domain dom;
|
||||
+ unsigned int nvcpus;
|
||||
+ unsigned int flags;
|
||||
+};
|
||||
+
|
||||
+struct remote_domain_get_vcpus_flags_args {
|
||||
+ remote_nonnull_domain dom;
|
||||
+ unsigned int flags;
|
||||
+};
|
||||
+
|
||||
+struct remote_domain_get_vcpus_flags_ret {
|
||||
+ int num;
|
||||
+};
|
||||
+
|
||||
struct remote_domain_pin_vcpu_args {
|
||||
remote_nonnull_domain dom;
|
||||
int vcpu;
|
||||
@@ -2062,7 +2077,9 @@ enum remote_procedure {
|
||||
REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON = 195,
|
||||
REMOTE_PROC_DOMAIN_CREATE_WITH_FLAGS = 196,
|
||||
REMOTE_PROC_DOMAIN_SET_MEMORY_PARAMETERS = 197,
|
||||
- REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198
|
||||
+ REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198,
|
||||
+ REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS = 199,
|
||||
+ REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS = 200
|
||||
|
||||
/*
|
||||
* Notice how the entries are grouped in sets of 10 ?
|
||||
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
|
||||
index 838423e..d505886 100644
|
||||
--- a/src/remote_protocol-structs
|
||||
+++ b/src/remote_protocol-structs
|
||||
@@ -461,6 +461,18 @@ struct remote_domain_set_vcpus_args {
|
||||
remote_nonnull_domain dom;
|
||||
int nvcpus;
|
||||
};
|
||||
+struct remote_domain_set_vcpus_flags_args {
|
||||
+ remote_nonnull_domain dom;
|
||||
+ u_int nvcpus;
|
||||
+ u_int flags;
|
||||
+};
|
||||
+struct remote_domain_get_vcpus_flags_args {
|
||||
+ remote_nonnull_domain dom;
|
||||
+ u_int flags;
|
||||
+};
|
||||
+struct remote_domain_get_vcpus_flags_ret {
|
||||
+ int num;
|
||||
+};
|
||||
struct remote_domain_pin_vcpu_args {
|
||||
remote_nonnull_domain dom;
|
||||
int vcpu;
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,735 +0,0 @@
|
||||
From 50c51f13e2af04afac46e181c4ed62581545a488 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Mon, 27 Sep 2010 16:37:53 -0600
|
||||
Subject: [PATCH 06/15] vcpu: make old API trivially wrap to new API
|
||||
|
||||
Note - this wrapping is completely mechanical; the old API will
|
||||
function identically, since the new API validates that the exact
|
||||
same flags are provided by the old API. On a per-driver basis,
|
||||
it may make sense to have the old API pass a different set of flags,
|
||||
but that should be done in the per-driver patch that implements
|
||||
the full range of flag support in the new API.
|
||||
|
||||
* src/esx/esx_driver.c (esxDomainSetVcpus, escDomainGetMaxVpcus):
|
||||
Move guts...
|
||||
(esxDomainSetVcpusFlags, esxDomainGetVcpusFlags): ...to new
|
||||
functions.
|
||||
(esxDriver): Trivially support the new API.
|
||||
* src/openvz/openvz_driver.c (openvzDomainSetVcpus)
|
||||
(openvzDomainSetVcpusFlags, openvzDomainGetMaxVcpus)
|
||||
(openvzDomainGetVcpusFlags, openvzDriver): Likewise.
|
||||
* src/phyp/phyp_driver.c (phypDomainSetCPU)
|
||||
(phypDomainSetVcpusFlags, phypGetLparCPUMAX)
|
||||
(phypDomainGetVcpusFlags, phypDriver): Likewise.
|
||||
* src/qemu/qemu_driver.c (qemudDomainSetVcpus)
|
||||
(qemudDomainSetVcpusFlags, qemudDomainGetMaxVcpus)
|
||||
(qemudDomainGetVcpusFlags, qemuDriver): Likewise.
|
||||
* src/test/test_driver.c (testSetVcpus, testDomainSetVcpusFlags)
|
||||
(testDomainGetMaxVcpus, testDomainGetVcpusFlags, testDriver):
|
||||
Likewise.
|
||||
* src/vbox/vbox_tmpl.c (vboxDomainSetVcpus)
|
||||
(vboxDomainSetVcpusFlags, virDomainGetMaxVcpus)
|
||||
(virDomainGetVcpusFlags, virDriver): Likewise.
|
||||
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpus)
|
||||
(xenUnifiedDomainSetVcpusFlags, xenUnifiedDomainGetMaxVcpus)
|
||||
(xenUnifiedDomainGetVcpusFlags, xenUnifiedDriver): Likewise.
|
||||
* src/xenapi/xenapi_driver.c (xenapiDomainSetVcpus)
|
||||
(xenapiDomainSetVcpusFlags, xenapiDomainGetMaxVcpus)
|
||||
(xenapiDomainGetVcpusFlags, xenapiDriver): Likewise.
|
||||
(xenapiError): New helper macro.
|
||||
---
|
||||
src/esx/esx_driver.c | 32 +++++++++++++++++++---
|
||||
src/openvz/openvz_driver.c | 34 +++++++++++++++++++++---
|
||||
src/phyp/phyp_driver.c | 32 ++++++++++++++++++++---
|
||||
src/qemu/qemu_driver.c | 38 +++++++++++++++++++++++++---
|
||||
src/test/test_driver.c | 36 ++++++++++++++++++++++---
|
||||
src/vbox/vbox_tmpl.c | 36 +++++++++++++++++++++++---
|
||||
src/xen/xen_driver.c | 34 ++++++++++++++++++++++---
|
||||
src/xenapi/xenapi_driver.c | 60 ++++++++++++++++++++++++++++++++++++++------
|
||||
8 files changed, 263 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
|
||||
index 2a32374..b3e1284 100644
|
||||
--- a/src/esx/esx_driver.c
|
||||
+++ b/src/esx/esx_driver.c
|
||||
@@ -2384,7 +2384,8 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
|
||||
|
||||
|
||||
static int
|
||||
-esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
|
||||
+esxDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
|
||||
+ unsigned int flags)
|
||||
{
|
||||
int result = -1;
|
||||
esxPrivate *priv = domain->conn->privateData;
|
||||
@@ -2394,6 +2395,11 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
|
||||
esxVI_ManagedObjectReference *task = NULL;
|
||||
esxVI_TaskInfoState taskInfoState;
|
||||
|
||||
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ ESX_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if (nvcpus < 1) {
|
||||
ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
|
||||
_("Requested number of virtual CPUs must at least be 1"));
|
||||
@@ -2453,15 +2459,26 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
|
||||
}
|
||||
|
||||
|
||||
+static int
|
||||
+esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
|
||||
+{
|
||||
+ return esxDomainSetVcpusFlags(domain, nvcpus, VIR_DOMAIN_VCPU_LIVE);
|
||||
+}
|
||||
+
|
||||
|
||||
static int
|
||||
-esxDomainGetMaxVcpus(virDomainPtr domain)
|
||||
+esxDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
|
||||
{
|
||||
esxPrivate *priv = domain->conn->privateData;
|
||||
esxVI_String *propertyNameList = NULL;
|
||||
esxVI_ObjectContent *hostSystem = NULL;
|
||||
esxVI_DynamicProperty *dynamicProperty = NULL;
|
||||
|
||||
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
+ ESX_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if (priv->maxVcpus > 0) {
|
||||
return priv->maxVcpus;
|
||||
}
|
||||
@@ -2507,7 +2524,12 @@ esxDomainGetMaxVcpus(virDomainPtr domain)
|
||||
return priv->maxVcpus;
|
||||
}
|
||||
|
||||
-
|
||||
+static int
|
||||
+esxDomainGetMaxVcpus(virDomainPtr domain)
|
||||
+{
|
||||
+ return esxDomainGetVcpusFlags(domain, (VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM));
|
||||
+}
|
||||
|
||||
static char *
|
||||
esxDomainDumpXML(virDomainPtr domain, int flags)
|
||||
@@ -4160,8 +4182,8 @@ static virDriver esxDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
esxDomainSetVcpus, /* domainSetVcpus */
|
||||
- NULL, /* domainSetVcpusFlags */
|
||||
- NULL, /* domainGetVcpusFlags */
|
||||
+ esxDomainSetVcpusFlags, /* domainSetVcpusFlags */
|
||||
+ esxDomainGetVcpusFlags, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
esxDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
|
||||
index 9d19aeb..0f3cfdf 100644
|
||||
--- a/src/openvz/openvz_driver.c
|
||||
+++ b/src/openvz/openvz_driver.c
|
||||
@@ -67,7 +67,6 @@
|
||||
static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid);
|
||||
static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type);
|
||||
static int openvzDomainGetMaxVcpus(virDomainPtr dom);
|
||||
-static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus);
|
||||
static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
|
||||
unsigned int nvcpus);
|
||||
static int openvzDomainSetMemoryInternal(virDomainObjPtr vm,
|
||||
@@ -1211,11 +1210,24 @@ static int openvzGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
return -1;
|
||||
}
|
||||
|
||||
+static int
|
||||
+openvzDomainGetVcpusFlags(virDomainPtr dom ATTRIBUTE_UNUSED,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
+ openvzError(VIR_ERR_INVALID_ARG, _("unsupported flags (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
-static int openvzDomainGetMaxVcpus(virDomainPtr dom ATTRIBUTE_UNUSED) {
|
||||
return openvzGetMaxVCPUs(NULL, "openvz");
|
||||
}
|
||||
|
||||
+static int openvzDomainGetMaxVcpus(virDomainPtr dom)
|
||||
+{
|
||||
+ return openvzDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM));
|
||||
+}
|
||||
+
|
||||
static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
|
||||
unsigned int nvcpus)
|
||||
{
|
||||
@@ -1241,12 +1253,18 @@ static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
|
||||
+static int openvzDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
||||
+ unsigned int flags)
|
||||
{
|
||||
virDomainObjPtr vm;
|
||||
struct openvz_driver *driver = dom->conn->privateData;
|
||||
int ret = -1;
|
||||
|
||||
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ openvzError(VIR_ERR_INVALID_ARG, _("unsupported flags (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
openvzDriverLock(driver);
|
||||
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||
openvzDriverUnlock(driver);
|
||||
@@ -1272,6 +1290,12 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int
|
||||
+openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
|
||||
+{
|
||||
+ return openvzDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
|
||||
+}
|
||||
+
|
||||
static virDrvOpenStatus openvzOpen(virConnectPtr conn,
|
||||
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
||||
int flags ATTRIBUTE_UNUSED)
|
||||
@@ -1590,8 +1614,8 @@ static virDriver openvzDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
openvzDomainSetVcpus, /* domainSetVcpus */
|
||||
- NULL, /* domainSetVcpusFlags */
|
||||
- NULL, /* domainGetVcpusFlags */
|
||||
+ openvzDomainSetVcpusFlags, /* domainSetVcpusFlags */
|
||||
+ openvzDomainGetVcpusFlags, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
|
||||
index 6e0a5e9..e284ae0 100644
|
||||
--- a/src/phyp/phyp_driver.c
|
||||
+++ b/src/phyp/phyp_driver.c
|
||||
@@ -1497,15 +1497,27 @@ phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id)
|
||||
}
|
||||
|
||||
static int
|
||||
-phypGetLparCPUMAX(virDomainPtr dom)
|
||||
+phypDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
|
||||
{
|
||||
phyp_driverPtr phyp_driver = dom->conn->privateData;
|
||||
char *managed_system = phyp_driver->managed_system;
|
||||
|
||||
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
+ PHYP_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
return phypGetLparCPUGeneric(dom->conn, managed_system, dom->id, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
+phypGetLparCPUMAX(virDomainPtr dom)
|
||||
+{
|
||||
+ return phypDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM));
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
|
||||
const char *lpar_name)
|
||||
{
|
||||
@@ -3831,7 +3843,8 @@ phypConnectGetCapabilities(virConnectPtr conn)
|
||||
}
|
||||
|
||||
static int
|
||||
-phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
|
||||
+phypDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
||||
+ unsigned int flags)
|
||||
{
|
||||
ConnectionData *connection_data = dom->conn->networkPrivateData;
|
||||
phyp_driverPtr phyp_driver = dom->conn->privateData;
|
||||
@@ -3846,6 +3859,11 @@ phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
|
||||
unsigned int amount = 0;
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ PHYP_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if ((ncpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
|
||||
return 0;
|
||||
|
||||
@@ -3891,6 +3909,12 @@ phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
|
||||
|
||||
}
|
||||
|
||||
+static int
|
||||
+phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
|
||||
+{
|
||||
+ return phypDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
|
||||
+}
|
||||
+
|
||||
static virDrvOpenStatus
|
||||
phypVIOSDriverOpen(virConnectPtr conn,
|
||||
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
||||
@@ -3941,8 +3965,8 @@ static virDriver phypDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
phypDomainSetCPU, /* domainSetVcpus */
|
||||
- NULL, /* domainSetVcpusFlags */
|
||||
- NULL, /* domainGetVcpusFlags */
|
||||
+ phypDomainSetVcpusFlags, /* domainSetVcpusFlags */
|
||||
+ phypDomainGetVcpusFlags, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
phypGetLparCPUMAX, /* domainGetMaxVcpus */
|
||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||
index 3d17e04..7a2ea8f 100644
|
||||
--- a/src/qemu/qemu_driver.c
|
||||
+++ b/src/qemu/qemu_driver.c
|
||||
@@ -5934,13 +5934,22 @@ unsupported:
|
||||
}
|
||||
|
||||
|
||||
-static int qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
|
||||
+static int
|
||||
+qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
struct qemud_driver *driver = dom->conn->privateData;
|
||||
virDomainObjPtr vm;
|
||||
const char * type;
|
||||
int max;
|
||||
int ret = -1;
|
||||
|
||||
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
|
||||
+ flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
qemuDriverLock(driver);
|
||||
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||
qemuDriverUnlock(driver);
|
||||
@@ -5994,6 +6003,12 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int
|
||||
+qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
|
||||
+{
|
||||
+ return qemudDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
|
||||
+}
|
||||
+
|
||||
|
||||
static int
|
||||
qemudDomainPinVcpu(virDomainPtr dom,
|
||||
@@ -6150,12 +6165,20 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
-static int qemudDomainGetMaxVcpus(virDomainPtr dom) {
|
||||
+static int
|
||||
+qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
|
||||
+{
|
||||
struct qemud_driver *driver = dom->conn->privateData;
|
||||
virDomainObjPtr vm;
|
||||
const char *type;
|
||||
int ret = -1;
|
||||
|
||||
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
+ qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
|
||||
+ flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
qemuDriverLock(driver);
|
||||
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||
qemuDriverUnlock(driver);
|
||||
@@ -6183,6 +6206,13 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int
|
||||
+qemudDomainGetMaxVcpus(virDomainPtr dom)
|
||||
+{
|
||||
+ return qemudDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM));
|
||||
+}
|
||||
+
|
||||
static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr seclabel)
|
||||
{
|
||||
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
|
||||
@@ -12938,8 +12968,8 @@ static virDriver qemuDriver = {
|
||||
qemudDomainRestore, /* domainRestore */
|
||||
qemudDomainCoreDump, /* domainCoreDump */
|
||||
qemudDomainSetVcpus, /* domainSetVcpus */
|
||||
- NULL, /* domainSetVcpusFlags */
|
||||
- NULL, /* domainGetVcpusFlags */
|
||||
+ qemudDomainSetVcpusFlags, /* domainSetVcpusFlags */
|
||||
+ qemudDomainGetVcpusFlags, /* domainGetVcpusFlags */
|
||||
qemudDomainPinVcpu, /* domainPinVcpu */
|
||||
qemudDomainGetVcpus, /* domainGetVcpus */
|
||||
qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
|
||||
index 6a00558..b70c80d 100644
|
||||
--- a/src/test/test_driver.c
|
||||
+++ b/src/test/test_driver.c
|
||||
@@ -2029,17 +2029,37 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int testDomainGetMaxVcpus(virDomainPtr domain)
|
||||
+static int
|
||||
+testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
|
||||
{
|
||||
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
+ testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
return testGetMaxVCPUs(domain->conn, "test");
|
||||
}
|
||||
|
||||
-static int testSetVcpus(virDomainPtr domain,
|
||||
- unsigned int nrCpus) {
|
||||
+static int
|
||||
+testDomainGetMaxVcpus(virDomainPtr domain)
|
||||
+{
|
||||
+ return testDomainGetVcpusFlags(domain, (VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM));
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
testConnPtr privconn = domain->conn->privateData;
|
||||
virDomainObjPtr privdom = NULL;
|
||||
int ret = -1, maxvcpus;
|
||||
|
||||
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
/* Do this first before locking */
|
||||
maxvcpus = testDomainGetMaxVcpus(domain);
|
||||
if (maxvcpus < 0)
|
||||
@@ -2082,6 +2102,12 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int
|
||||
+testSetVcpus(virDomainPtr domain, unsigned int nrCpus)
|
||||
+{
|
||||
+ return testDomainSetVcpusFlags(domain, nrCpus, VIR_DOMAIN_VCPU_LIVE);
|
||||
+}
|
||||
+
|
||||
static int testDomainGetVcpus(virDomainPtr domain,
|
||||
virVcpuInfoPtr info,
|
||||
int maxinfo,
|
||||
@@ -5260,8 +5286,8 @@ static virDriver testDriver = {
|
||||
testDomainRestore, /* domainRestore */
|
||||
testDomainCoreDump, /* domainCoreDump */
|
||||
testSetVcpus, /* domainSetVcpus */
|
||||
- NULL, /* domainSetVcpusFlags */
|
||||
- NULL, /* domainGetVcpusFlags */
|
||||
+ testDomainSetVcpusFlags, /* domainSetVcpusFlags */
|
||||
+ testDomainGetVcpusFlags, /* domainGetVcpusFlags */
|
||||
testDomainPinVcpu, /* domainPinVcpu */
|
||||
testDomainGetVcpus, /* domainGetVcpus */
|
||||
testDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
|
||||
index cb9193a..0cbe8b3 100644
|
||||
--- a/src/vbox/vbox_tmpl.c
|
||||
+++ b/src/vbox/vbox_tmpl.c
|
||||
@@ -1839,13 +1839,21 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int vboxDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
|
||||
+static int
|
||||
+vboxDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
||||
IMachine *machine = NULL;
|
||||
vboxIID *iid = NULL;
|
||||
PRUint32 CPUCount = nvcpus;
|
||||
nsresult rc;
|
||||
|
||||
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ vboxError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
#if VBOX_API_VERSION == 2002
|
||||
if (VIR_ALLOC(iid) < 0) {
|
||||
virReportOOMError();
|
||||
@@ -1887,11 +1895,24 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int vboxDomainGetMaxVcpus(virDomainPtr dom) {
|
||||
+static int
|
||||
+vboxDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
|
||||
+{
|
||||
+ return vboxDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+vboxDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
|
||||
+{
|
||||
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
||||
ISystemProperties *systemProperties = NULL;
|
||||
PRUint32 maxCPUCount = 0;
|
||||
|
||||
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
+ vboxError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
/* Currently every domain supports the same number of max cpus
|
||||
* as that supported by vbox and thus take it directly from
|
||||
* the systemproperties.
|
||||
@@ -1909,6 +1930,13 @@ static int vboxDomainGetMaxVcpus(virDomainPtr dom) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int
|
||||
+vboxDomainGetMaxVcpus(virDomainPtr dom)
|
||||
+{
|
||||
+ return vboxDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM));
|
||||
+}
|
||||
+
|
||||
static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
|
||||
VBOX_OBJECT_CHECK(dom->conn, char *, NULL);
|
||||
virDomainDefPtr def = NULL;
|
||||
@@ -8267,8 +8295,8 @@ virDriver NAME(Driver) = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
vboxDomainSetVcpus, /* domainSetVcpus */
|
||||
- NULL, /* domainSetVcpusFlags */
|
||||
- NULL, /* domainGetVcpusFlags */
|
||||
+ vboxDomainSetVcpusFlags, /* domainSetVcpusFlags */
|
||||
+ vboxDomainGetVcpusFlags, /* domainGetVcpusFlags */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
vboxDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
|
||||
index 7d67ced..d6c9c57 100644
|
||||
--- a/src/xen/xen_driver.c
|
||||
+++ b/src/xen/xen_driver.c
|
||||
@@ -1069,11 +1069,18 @@ xenUnifiedDomainCoreDump (virDomainPtr dom, const char *to, int flags)
|
||||
}
|
||||
|
||||
static int
|
||||
-xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
|
||||
+xenUnifiedDomainSetVcpusFlags (virDomainPtr dom, unsigned int nvcpus,
|
||||
+ unsigned int flags)
|
||||
{
|
||||
GET_PRIVATE(dom->conn);
|
||||
int i;
|
||||
|
||||
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
|
||||
+ flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
/* Try non-hypervisor methods first, then hypervisor direct method
|
||||
* as a last resort.
|
||||
*/
|
||||
@@ -1093,6 +1100,12 @@ xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
|
||||
}
|
||||
|
||||
static int
|
||||
+xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
|
||||
+{
|
||||
+ return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
xenUnifiedDomainPinVcpu (virDomainPtr dom, unsigned int vcpu,
|
||||
unsigned char *cpumap, int maplen)
|
||||
{
|
||||
@@ -1126,11 +1139,17 @@ xenUnifiedDomainGetVcpus (virDomainPtr dom,
|
||||
}
|
||||
|
||||
static int
|
||||
-xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
|
||||
+xenUnifiedDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
|
||||
{
|
||||
GET_PRIVATE(dom->conn);
|
||||
int i, ret;
|
||||
|
||||
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
+ xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
|
||||
+ flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
|
||||
if (priv->opened[i] && drivers[i]->domainGetMaxVcpus) {
|
||||
ret = drivers[i]->domainGetMaxVcpus (dom);
|
||||
@@ -1140,6 +1159,13 @@ xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+static int
|
||||
+xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
|
||||
+{
|
||||
+ return xenUnifiedDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM));
|
||||
+}
|
||||
+
|
||||
static char *
|
||||
xenUnifiedDomainDumpXML (virDomainPtr dom, int flags)
|
||||
{
|
||||
@@ -1951,8 +1977,8 @@ static virDriver xenUnifiedDriver = {
|
||||
xenUnifiedDomainRestore, /* domainRestore */
|
||||
xenUnifiedDomainCoreDump, /* domainCoreDump */
|
||||
xenUnifiedDomainSetVcpus, /* domainSetVcpus */
|
||||
- NULL, /* domainSetVcpusFlags */
|
||||
- NULL, /* domainGetVcpusFlags */
|
||||
+ xenUnifiedDomainSetVcpusFlags, /* domainSetVcpusFlags */
|
||||
+ xenUnifiedDomainGetVcpusFlags, /* domainGetVcpusFlags */
|
||||
xenUnifiedDomainPinVcpu, /* domainPinVcpu */
|
||||
xenUnifiedDomainGetVcpus, /* domainGetVcpus */
|
||||
xenUnifiedDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
|
||||
index 753169c..7d4ab8d 100644
|
||||
--- a/src/xenapi/xenapi_driver.c
|
||||
+++ b/src/xenapi/xenapi_driver.c
|
||||
@@ -40,6 +40,11 @@
|
||||
#include "xenapi_driver_private.h"
|
||||
#include "xenapi_utils.h"
|
||||
|
||||
+#define VIR_FROM_THIS VIR_FROM_XENAPI
|
||||
+
|
||||
+#define xenapiError(code, ...) \
|
||||
+ virReportErrorHelper(NULL, VIR_FROM_THIS, code, __FILE__, \
|
||||
+ __FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
|
||||
/*
|
||||
* getCapsObject
|
||||
@@ -987,19 +992,26 @@ xenapiDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)
|
||||
|
||||
|
||||
/*
|
||||
- * xenapiDomainSetVcpus
|
||||
+ * xenapiDomainSetVcpusFlags
|
||||
*
|
||||
* Sets the VCPUs on the domain
|
||||
* Return 0 on success or -1 in case of error
|
||||
*/
|
||||
static int
|
||||
-xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
|
||||
+xenapiDomainSetVcpusFlags (virDomainPtr dom, unsigned int nvcpus,
|
||||
+ unsigned int flags)
|
||||
{
|
||||
-
|
||||
/* vm.set_vcpus_max */
|
||||
xen_vm vm;
|
||||
xen_vm_set *vms;
|
||||
xen_session *session = ((struct _xenapiPrivate *)(dom->conn->privateData))->session;
|
||||
+
|
||||
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ xenapiError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
|
||||
+ flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if (xen_vm_get_by_name_label(session, &vms, dom->name) && vms->size > 0) {
|
||||
if (vms->size != 1) {
|
||||
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR,
|
||||
@@ -1019,6 +1031,18 @@ xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * xenapiDomainSetVcpus
|
||||
+ *
|
||||
+ * Sets the VCPUs on the domain
|
||||
+ * Return 0 on success or -1 in case of error
|
||||
+ */
|
||||
+static int
|
||||
+xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
|
||||
+{
|
||||
+ return xenapiDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* xenapiDomainPinVcpu
|
||||
*
|
||||
* Dynamically change the real CPUs which can be allocated to a virtual CPU
|
||||
@@ -1140,19 +1164,26 @@ xenapiDomainGetVcpus (virDomainPtr dom,
|
||||
}
|
||||
|
||||
/*
|
||||
- * xenapiDomainGetMaxVcpus
|
||||
+ * xenapiDomainGetVcpusFlags
|
||||
*
|
||||
*
|
||||
- * Returns maximum number of Vcpus on success or -1 in case of error
|
||||
+ * Returns Vcpus count on success or -1 in case of error
|
||||
*/
|
||||
static int
|
||||
-xenapiDomainGetMaxVcpus (virDomainPtr dom)
|
||||
+xenapiDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
|
||||
{
|
||||
xen_vm vm;
|
||||
xen_vm_set *vms;
|
||||
int64_t maxvcpu = 0;
|
||||
enum xen_vm_power_state state;
|
||||
xen_session *session = ((struct _xenapiPrivate *)(dom->conn->privateData))->session;
|
||||
+
|
||||
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
+ xenapiError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
|
||||
+ flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if (xen_vm_get_by_name_label(session, &vms, dom->name) && vms->size > 0) {
|
||||
if (vms->size != 1) {
|
||||
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR,
|
||||
@@ -1176,6 +1207,19 @@ xenapiDomainGetMaxVcpus (virDomainPtr dom)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * xenapiDomainGetMaxVcpus
|
||||
+ *
|
||||
+ *
|
||||
+ * Returns maximum number of Vcpus on success or -1 in case of error
|
||||
+ */
|
||||
+static int
|
||||
+xenapiDomainGetMaxVcpus (virDomainPtr dom)
|
||||
+{
|
||||
+ return xenapiDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM));
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* xenapiDomainDumpXML
|
||||
*
|
||||
*
|
||||
@@ -1754,8 +1798,8 @@ static virDriver xenapiDriver = {
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
xenapiDomainSetVcpus, /* domainSetVcpus */
|
||||
- NULL, /* domainSetVcpusFlags */
|
||||
- NULL, /* domainGetVcpusFlags */
|
||||
+ xenapiDomainSetVcpusFlags, /* domainSetVcpusFlags */
|
||||
+ xenapiDomainGetVcpusFlags, /* domainGetVcpusFlags */
|
||||
xenapiDomainPinVcpu, /* domainPinVcpu */
|
||||
xenapiDomainGetVcpus, /* domainGetVcpus */
|
||||
xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,388 +0,0 @@
|
||||
From bf945ee97b72d3b0c4fc2da04530f5294f529d66 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Wed, 29 Sep 2010 15:20:23 -0600
|
||||
Subject: [PATCH 08/15] vcpu: add virsh support
|
||||
|
||||
* tools/virsh.c (cmdSetvcpus): Add new flags. Let invalid
|
||||
commands through to driver, to ease testing of hypervisor argument
|
||||
validation.
|
||||
(cmdMaxvcpus, cmdVcpucount): New commands.
|
||||
(commands): Add new commands.
|
||||
* tools/virsh.pod (setvcpus, vcpucount, maxvcpus): Document new
|
||||
behavior.
|
||||
---
|
||||
tools/virsh.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
tools/virsh.pod | 38 ++++++++-
|
||||
2 files changed, 262 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/tools/virsh.c b/tools/virsh.c
|
||||
index 4f8c495..7fb7fbd 100644
|
||||
--- a/tools/virsh.c
|
||||
+++ b/tools/virsh.c
|
||||
@@ -2281,10 +2281,216 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * "maxvcpus" command
|
||||
+ */
|
||||
+static const vshCmdInfo info_maxvcpus[] = {
|
||||
+ {"help", N_("connection vcpu maximum")},
|
||||
+ {"desc", N_("Show maximum number of virtual CPUs for guests on this connection.")},
|
||||
+ {NULL, NULL}
|
||||
+};
|
||||
+
|
||||
+static const vshCmdOptDef opts_maxvcpus[] = {
|
||||
+ {"type", VSH_OT_STRING, 0, N_("domain type")},
|
||||
+ {NULL, 0, 0, NULL}
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd)
|
||||
+{
|
||||
+ char *type;
|
||||
+ int vcpus;
|
||||
+
|
||||
+ type = vshCommandOptString(cmd, "type", NULL);
|
||||
+
|
||||
+ if (!vshConnectionUsability(ctl, ctl->conn))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ vcpus = virConnectGetMaxVcpus(ctl->conn, type);
|
||||
+ if (vcpus < 0)
|
||||
+ return FALSE;
|
||||
+ vshPrint(ctl, "%d\n", vcpus);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * "vcpucount" command
|
||||
+ */
|
||||
+static const vshCmdInfo info_vcpucount[] = {
|
||||
+ {"help", N_("domain vcpu counts")},
|
||||
+ {"desc", N_("Returns the number of virtual CPUs used by the domain.")},
|
||||
+ {NULL, NULL}
|
||||
+};
|
||||
+
|
||||
+static const vshCmdOptDef opts_vcpucount[] = {
|
||||
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
|
||||
+ {"maximum", VSH_OT_BOOL, 0, N_("get maximum cap on vcpus")},
|
||||
+ {"current", VSH_OT_BOOL, 0, N_("get current vcpu usage")},
|
||||
+ {"config", VSH_OT_BOOL, 0, N_("get value to be used on next boot")},
|
||||
+ {"live", VSH_OT_BOOL, 0, N_("get value from running domain")},
|
||||
+ {NULL, 0, 0, NULL}
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+cmdVcpucount(vshControl *ctl, const vshCmd *cmd)
|
||||
+{
|
||||
+ virDomainPtr dom;
|
||||
+ int ret = TRUE;
|
||||
+ int maximum = vshCommandOptBool(cmd, "maximum");
|
||||
+ int current = vshCommandOptBool(cmd, "current");
|
||||
+ int config = vshCommandOptBool(cmd, "config");
|
||||
+ int live = vshCommandOptBool(cmd, "live");
|
||||
+ bool all = maximum + current + config + live == 0;
|
||||
+ int count;
|
||||
+
|
||||
+ if (maximum && current) {
|
||||
+ vshError(ctl, "%s",
|
||||
+ _("--maximum and --current cannot both be specified"));
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ if (config && live) {
|
||||
+ vshError(ctl, "%s",
|
||||
+ _("--config and --live cannot both be specified"));
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ /* We want one of each pair of mutually exclusive options; that
|
||||
+ * is, use of flags requires exactly two options. */
|
||||
+ if (maximum + current + config + live == 1) {
|
||||
+ vshError(ctl,
|
||||
+ _("when using --%s, either --%s or --%s must be specified"),
|
||||
+ (maximum ? "maximum" : current ? "current"
|
||||
+ : config ? "config" : "live"),
|
||||
+ maximum + current ? "config" : "maximum",
|
||||
+ maximum + current ? "live" : "current");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (!vshConnectionUsability(ctl, ctl->conn))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* In all cases, try the new API first; if it fails because we are
|
||||
+ * talking to an older client, try a fallback API before giving
|
||||
+ * up. */
|
||||
+ if (all || (maximum && config)) {
|
||||
+ count = virDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_MAXIMUM |
|
||||
+ VIR_DOMAIN_VCPU_CONFIG));
|
||||
+ if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
|
||||
+ || last_error->code == VIR_ERR_INVALID_ARG)) {
|
||||
+ char *tmp;
|
||||
+ char *xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE);
|
||||
+ if (xml && (tmp = strstr(xml, "<vcpu"))) {
|
||||
+ tmp = strchr(tmp, '>');
|
||||
+ if (!tmp || virStrToLong_i(tmp + 1, &tmp, 10, &count) < 0)
|
||||
+ count = -1;
|
||||
+ }
|
||||
+ VIR_FREE(xml);
|
||||
+ }
|
||||
+
|
||||
+ if (count < 0) {
|
||||
+ virshReportError(ctl);
|
||||
+ ret = FALSE;
|
||||
+ } else if (all) {
|
||||
+ vshPrint(ctl, "%-12s %-12s %3d\n", _("maximum"), _("config"),
|
||||
+ count);
|
||||
+ } else {
|
||||
+ vshPrint(ctl, "%d\n", count);
|
||||
+ }
|
||||
+ virFreeError(last_error);
|
||||
+ last_error = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (all || (maximum && live)) {
|
||||
+ count = virDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_MAXIMUM |
|
||||
+ VIR_DOMAIN_VCPU_LIVE));
|
||||
+ if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
|
||||
+ || last_error->code == VIR_ERR_INVALID_ARG)) {
|
||||
+ count = virDomainGetMaxVcpus(dom);
|
||||
+ }
|
||||
+
|
||||
+ if (count < 0) {
|
||||
+ virshReportError(ctl);
|
||||
+ ret = FALSE;
|
||||
+ } else if (all) {
|
||||
+ vshPrint(ctl, "%-12s %-12s %3d\n", _("maximum"), _("live"),
|
||||
+ count);
|
||||
+ } else {
|
||||
+ vshPrint(ctl, "%d\n", count);
|
||||
+ }
|
||||
+ virFreeError(last_error);
|
||||
+ last_error = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (all || (current && config)) {
|
||||
+ count = virDomainGetVcpusFlags(dom, VIR_DOMAIN_VCPU_CONFIG);
|
||||
+ if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
|
||||
+ || last_error->code == VIR_ERR_INVALID_ARG)) {
|
||||
+ char *tmp, *end;
|
||||
+ char *xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE);
|
||||
+ if (xml && (tmp = strstr(xml, "<vcpu"))) {
|
||||
+ end = strchr(tmp, '>');
|
||||
+ if (end) {
|
||||
+ *end = '\0';
|
||||
+ tmp = strstr(tmp, "current=");
|
||||
+ if (!tmp)
|
||||
+ tmp = end + 1;
|
||||
+ else {
|
||||
+ tmp += strlen("current=");
|
||||
+ tmp += *tmp == '\'' || *tmp == '"';
|
||||
+ }
|
||||
+ }
|
||||
+ if (!tmp || virStrToLong_i(tmp, &tmp, 10, &count) < 0)
|
||||
+ count = -1;
|
||||
+ }
|
||||
+ VIR_FREE(xml);
|
||||
+ }
|
||||
+
|
||||
+ if (count < 0) {
|
||||
+ virshReportError(ctl);
|
||||
+ ret = FALSE;
|
||||
+ } else if (all) {
|
||||
+ vshPrint(ctl, "%-12s %-12s %3d\n", _("current"), _("config"),
|
||||
+ count);
|
||||
+ } else {
|
||||
+ vshPrint(ctl, "%d\n", count);
|
||||
+ }
|
||||
+ virFreeError(last_error);
|
||||
+ last_error = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (all || (current && live)) {
|
||||
+ count = virDomainGetVcpusFlags(dom, VIR_DOMAIN_VCPU_LIVE);
|
||||
+ if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
|
||||
+ || last_error->code == VIR_ERR_INVALID_ARG)) {
|
||||
+ virDomainInfo info;
|
||||
+ if (virDomainGetInfo(dom, &info) == 0)
|
||||
+ count = info.nrVirtCpu;
|
||||
+ }
|
||||
+
|
||||
+ if (count < 0) {
|
||||
+ virshReportError(ctl);
|
||||
+ ret = FALSE;
|
||||
+ } else if (all) {
|
||||
+ vshPrint(ctl, "%-12s %-12s %3d\n", _("current"), _("live"),
|
||||
+ count);
|
||||
+ } else {
|
||||
+ vshPrint(ctl, "%d\n", count);
|
||||
+ }
|
||||
+ virFreeError(last_error);
|
||||
+ last_error = NULL;
|
||||
+ }
|
||||
+
|
||||
+ virDomainFree(dom);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* "vcpuinfo" command
|
||||
*/
|
||||
static const vshCmdInfo info_vcpuinfo[] = {
|
||||
- {"help", N_("domain vcpu information")},
|
||||
+ {"help", N_("detailed domain vcpu information")},
|
||||
{"desc", N_("Returns basic information about the domain virtual CPUs.")},
|
||||
{NULL, NULL}
|
||||
};
|
||||
@@ -2514,6 +2720,9 @@ static const vshCmdInfo info_setvcpus[] = {
|
||||
static const vshCmdOptDef opts_setvcpus[] = {
|
||||
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
|
||||
{"count", VSH_OT_DATA, VSH_OFLAG_REQ, N_("number of virtual CPUs")},
|
||||
+ {"maximum", VSH_OT_BOOL, 0, N_("set maximum limit on next boot")},
|
||||
+ {"config", VSH_OT_BOOL, 0, N_("affect next boot")},
|
||||
+ {"live", VSH_OT_BOOL, 0, N_("affect running domain")},
|
||||
{NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -2522,8 +2731,13 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
|
||||
{
|
||||
virDomainPtr dom;
|
||||
int count;
|
||||
- int maxcpu;
|
||||
int ret = TRUE;
|
||||
+ int maximum = vshCommandOptBool(cmd, "maximum");
|
||||
+ int config = vshCommandOptBool(cmd, "config");
|
||||
+ int live = vshCommandOptBool(cmd, "live");
|
||||
+ int flags = ((maximum ? VIR_DOMAIN_VCPU_MAXIMUM : 0) |
|
||||
+ (config ? VIR_DOMAIN_VCPU_CONFIG : 0) |
|
||||
+ (live ? VIR_DOMAIN_VCPU_LIVE : 0));
|
||||
|
||||
if (!vshConnectionUsability(ctl, ctl->conn))
|
||||
return FALSE;
|
||||
@@ -2532,26 +2746,15 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
|
||||
return FALSE;
|
||||
|
||||
count = vshCommandOptInt(cmd, "count", &count);
|
||||
- if (count <= 0) {
|
||||
- vshError(ctl, "%s", _("Invalid number of virtual CPUs."));
|
||||
- virDomainFree(dom);
|
||||
- return FALSE;
|
||||
- }
|
||||
-
|
||||
- maxcpu = virDomainGetMaxVcpus(dom);
|
||||
- if (maxcpu <= 0) {
|
||||
- virDomainFree(dom);
|
||||
- return FALSE;
|
||||
- }
|
||||
-
|
||||
- if (count > maxcpu) {
|
||||
- vshError(ctl, "%s", _("Too many virtual CPUs."));
|
||||
- virDomainFree(dom);
|
||||
- return FALSE;
|
||||
- }
|
||||
|
||||
- if (virDomainSetVcpus(dom, count) != 0) {
|
||||
- ret = FALSE;
|
||||
+ if (!flags) {
|
||||
+ if (virDomainSetVcpus(dom, count) != 0) {
|
||||
+ ret = FALSE;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (virDomainSetVcpusFlags(dom, count, flags) < 0) {
|
||||
+ ret = FALSE;
|
||||
+ }
|
||||
}
|
||||
|
||||
virDomainFree(dom);
|
||||
@@ -9642,6 +9845,7 @@ static const vshCmdDef commands[] = {
|
||||
{"freecell", cmdFreecell, opts_freecell, info_freecell},
|
||||
{"hostname", cmdHostname, NULL, info_hostname},
|
||||
{"list", cmdList, opts_list, info_list},
|
||||
+ {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus},
|
||||
{"migrate", cmdMigrate, opts_migrate, info_migrate},
|
||||
{"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime},
|
||||
|
||||
@@ -9748,6 +9952,7 @@ static const vshCmdDef commands[] = {
|
||||
{"vol-name", cmdVolName, opts_vol_name, info_vol_name},
|
||||
{"vol-key", cmdVolKey, opts_vol_key, info_vol_key},
|
||||
|
||||
+ {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount},
|
||||
{"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
|
||||
{"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
|
||||
{"version", cmdVersion, NULL, info_version},
|
||||
diff --git a/tools/virsh.pod b/tools/virsh.pod
|
||||
index 943a563..dbcc680 100644
|
||||
--- a/tools/virsh.pod
|
||||
+++ b/tools/virsh.pod
|
||||
@@ -443,7 +443,14 @@ Remove the managed save file for a domain if it exists. The next time the
|
||||
domain is started it will not restore to its previous state but instead will
|
||||
do a full boot.
|
||||
|
||||
-=item B<migrate> optional I<--live> I<--suspend> I<domain-id> I<desturi> I<migrateuri>
|
||||
+=item B<maxvcpus> optional I<type>
|
||||
+
|
||||
+Provide the maximum number of virtual CPUs supported for a guest VM on
|
||||
+this connection. If provided, the I<type> parameter must be a valid
|
||||
+type attribute for the <domain> element of XML.
|
||||
+
|
||||
+=item B<migrate> optional I<--live> I<--suspend> I<domain-id> I<desturi>
|
||||
+I<migrateuri>
|
||||
|
||||
Migrate domain to another host. Add --live for live migration; --suspend
|
||||
leaves the domain paused on the destination host. The I<desturi> is the
|
||||
@@ -521,7 +528,8 @@ Displays the domain memory parameters.
|
||||
|
||||
Allows you to set the domain memory parameters. LXC and QEMU/KVM supports these parameters.
|
||||
|
||||
-=item B<setvcpus> I<domain-id> I<count>
|
||||
+=item B<setvcpus> I<domain-id> I<count> optional I<--maximum> I<--config>
|
||||
+I<--live>
|
||||
|
||||
Change the number of virtual CPUs active in the guest domain. Note that
|
||||
I<count> may be limited by host, hypervisor or limit coming from the
|
||||
@@ -530,6 +538,17 @@ original description of domain.
|
||||
For Xen, you can only adjust the virtual CPUs of a running domain if
|
||||
the domain is paravirtualized.
|
||||
|
||||
+If I<--config> is specified, the change will only affect the next
|
||||
+boot of a domain. If I<--live> is specified, the domain must be
|
||||
+running, and the change takes place immediately. Both flags may be
|
||||
+specified, if supported by the hypervisor. If neither flag is given,
|
||||
+then I<--live> is implied and it is up to the hypervisor whether
|
||||
+I<--config> is also implied.
|
||||
+
|
||||
+If I<--maximum> is specified, then you must use I<--config> and
|
||||
+avoid I<--live>; this flag controls the maximum limit of vcpus that
|
||||
+can be hot-plugged the next time the domain is booted.
|
||||
+
|
||||
=item B<shutdown> I<domain-id>
|
||||
|
||||
Gracefully shuts down a domain. This coordinates with the domain OS
|
||||
@@ -568,6 +587,21 @@ is not available the processes will provide an exit code of 1.
|
||||
Undefine the configuration for an inactive domain. Since it's not running
|
||||
the domain name or UUID must be used as the I<domain-id>.
|
||||
|
||||
+=item B<vcpucount> I<domain-id> optional I<--maximum> I<--current>
|
||||
+I<--config> I<--live>
|
||||
+
|
||||
+Print information about the virtual cpu counts of the given
|
||||
+I<domain-id>. If no flags are specified, all possible counts are
|
||||
+listed in a table; otherwise, the output is limited to just the
|
||||
+numeric value requested.
|
||||
+
|
||||
+I<--maximum> requests information on the maximum cap of vcpus that a
|
||||
+domain can add via B<setvcpus>, while I<--current> shows the current
|
||||
+usage; these two flags cannot both be specified. I<--config>
|
||||
+requests information regarding the next time the domain will be
|
||||
+booted, while I<--live> requires a running domain and lists current
|
||||
+values; these two flags cannot both be specified.
|
||||
+
|
||||
=item B<vcpuinfo> I<domain-id>
|
||||
|
||||
Returns basic information about the domain virtual CPUs, like the number of
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,519 +0,0 @@
|
||||
From 4617eedfaeee2b187a1f14691d25746ba3ff31b6 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Wed, 29 Sep 2010 10:20:07 -0600
|
||||
Subject: [PATCH 07/15] vcpu: support maxvcpu in domain_conf
|
||||
|
||||
Although this patch adds a distinction between maximum vcpus and
|
||||
current vcpus in the XML, the values should be identical for all
|
||||
drivers at this point. Only in subsequent per-driver patches will
|
||||
a distinction be made.
|
||||
|
||||
In general, virDomainGetInfo should prefer the current vcpus.
|
||||
|
||||
* src/conf/domain_conf.h (_virDomainDef): Adjust vcpus to unsigned
|
||||
short, to match virDomainGetInfo limit. Add maxvcpus member.
|
||||
* src/conf/domain_conf.c (virDomainDefParseXML)
|
||||
(virDomainDefFormat): parse and print out vcpu details.
|
||||
* src/xen/xend_internal.c (xenDaemonParseSxpr)
|
||||
(xenDaemonFormatSxpr): Manage both vcpu numbers, and require them
|
||||
to be equal for now.
|
||||
* src/xen/xm_internal.c (xenXMDomainConfigParse)
|
||||
(xenXMDomainConfigFormat): Likewise.
|
||||
* src/phyp/phyp_driver.c (phypDomainDumpXML): Likewise.
|
||||
* src/openvz/openvz_conf.c (openvzLoadDomains): Likewise.
|
||||
* src/openvz/openvz_driver.c (openvzDomainDefineXML)
|
||||
(openvzDomainCreateXML, openvzDomainSetVcpusInternal): Likewise.
|
||||
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxDomainDefineXML):
|
||||
Likewise.
|
||||
* src/xenapi/xenapi_driver.c (xenapiDomainDumpXML): Likewise.
|
||||
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
|
||||
* src/esx/esx_vmx.c (esxVMX_ParseConfig, esxVMX_FormatConfig):
|
||||
Likewise.
|
||||
* src/qemu/qemu_conf.c (qemuBuildSmpArgStr)
|
||||
(qemuParseCommandLineSmp, qemuParseCommandLine): Likewise.
|
||||
* src/qemu/qemu_driver.c (qemudDomainHotplugVcpus): Likewise.
|
||||
* src/opennebula/one_conf.c (xmlOneTemplate): Likewise.
|
||||
---
|
||||
src/conf/domain_conf.c | 45 +++++++++++++++++++++++++++++++++++++------
|
||||
src/conf/domain_conf.h | 3 +-
|
||||
src/esx/esx_vmx.c | 24 ++++++++++++++--------
|
||||
src/opennebula/one_conf.c | 9 +++++--
|
||||
src/openvz/openvz_conf.c | 7 +++--
|
||||
src/openvz/openvz_driver.c | 15 +++++++++----
|
||||
src/phyp/phyp_driver.c | 2 +-
|
||||
src/qemu/qemu_conf.c | 14 +++++++++++-
|
||||
src/qemu/qemu_driver.c | 5 ++-
|
||||
src/vbox/vbox_tmpl.c | 12 +++++++---
|
||||
src/xen/xend_internal.c | 9 ++++---
|
||||
src/xen/xm_internal.c | 11 ++++++---
|
||||
src/xenapi/xenapi_driver.c | 2 +-
|
||||
src/xenapi/xenapi_utils.c | 4 +-
|
||||
14 files changed, 114 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
||||
index 78d7a6a..a997e06 100644
|
||||
--- a/src/conf/domain_conf.c
|
||||
+++ b/src/conf/domain_conf.c
|
||||
@@ -4203,6 +4203,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
|
||||
int i, n;
|
||||
long id = -1;
|
||||
virDomainDefPtr def;
|
||||
+ unsigned long count;
|
||||
|
||||
if (VIR_ALLOC(def) < 0) {
|
||||
virReportOOMError();
|
||||
@@ -4287,8 +4288,37 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
|
||||
&def->mem.swap_hard_limit) < 0)
|
||||
def->mem.swap_hard_limit = 0;
|
||||
|
||||
- if (virXPathULong("string(./vcpu[1])", ctxt, &def->vcpus) < 0)
|
||||
- def->vcpus = 1;
|
||||
+ n = virXPathULong("string(./vcpu[1])", ctxt, &count);
|
||||
+ if (n == -2) {
|
||||
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
+ _("maximum vcpus must be an integer"));
|
||||
+ goto error;
|
||||
+ } else if (n < 0) {
|
||||
+ def->maxvcpus = 1;
|
||||
+ } else {
|
||||
+ def->maxvcpus = count;
|
||||
+ if (def->maxvcpus != count || count == 0) {
|
||||
+ virDomainReportError(VIR_ERR_XML_ERROR,
|
||||
+ _("invalid maxvcpus %lu"), count);
|
||||
+ goto error;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ n = virXPathULong("string(./vcpu[1]/@current)", ctxt, &count);
|
||||
+ if (n == -2) {
|
||||
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
+ _("current vcpus must be an integer"));
|
||||
+ goto error;
|
||||
+ } else if (n < 0) {
|
||||
+ def->vcpus = def->maxvcpus;
|
||||
+ } else {
|
||||
+ def->vcpus = count;
|
||||
+ if (def->vcpus != count || count == 0 || def->maxvcpus < count) {
|
||||
+ virDomainReportError(VIR_ERR_XML_ERROR,
|
||||
+ _("invalid current vcpus %lu"), count);
|
||||
+ goto error;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
tmp = virXPathString("string(./vcpu[1]/@cpuset)", ctxt);
|
||||
if (tmp) {
|
||||
@@ -6462,17 +6492,18 @@ char *virDomainDefFormat(virDomainDefPtr def,
|
||||
if (def->cpumask[n] != 1)
|
||||
allones = 0;
|
||||
|
||||
- if (allones) {
|
||||
- virBufferAsprintf(&buf, " <vcpu>%lu</vcpu>\n", def->vcpus);
|
||||
- } else {
|
||||
+ virBufferAddLit(&buf, " <vcpu");
|
||||
+ if (!allones) {
|
||||
char *cpumask = NULL;
|
||||
if ((cpumask =
|
||||
virDomainCpuSetFormat(def->cpumask, def->cpumasklen)) == NULL)
|
||||
goto cleanup;
|
||||
- virBufferAsprintf(&buf, " <vcpu cpuset='%s'>%lu</vcpu>\n",
|
||||
- cpumask, def->vcpus);
|
||||
+ virBufferAsprintf(&buf, " cpuset='%s'", cpumask);
|
||||
VIR_FREE(cpumask);
|
||||
}
|
||||
+ if (def->vcpus != def->maxvcpus)
|
||||
+ virBufferAsprintf(&buf, " current='%u'", def->vcpus);
|
||||
+ virBufferAsprintf(&buf, ">%u</vcpu>\n", def->maxvcpus);
|
||||
|
||||
if (def->os.bootloader) {
|
||||
virBufferEscapeString(&buf, " <bootloader>%s</bootloader>\n",
|
||||
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
||||
index db09c23..5499f28 100644
|
||||
--- a/src/conf/domain_conf.h
|
||||
+++ b/src/conf/domain_conf.h
|
||||
@@ -885,7 +885,8 @@ struct _virDomainDef {
|
||||
unsigned long min_guarantee;
|
||||
unsigned long swap_hard_limit;
|
||||
} mem;
|
||||
- unsigned long vcpus;
|
||||
+ unsigned short vcpus;
|
||||
+ unsigned short maxvcpus;
|
||||
int cpumasklen;
|
||||
char *cpumask;
|
||||
|
||||
diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c
|
||||
index 7ec8c0e..0a26614 100644
|
||||
--- a/src/esx/esx_vmx.c
|
||||
+++ b/src/esx/esx_vmx.c
|
||||
@@ -50,7 +50,7 @@ def->uuid = <value> <=> uuid.bios = "<value>"
|
||||
def->name = <value> <=> displayName = "<value>"
|
||||
def->mem.max_balloon = <value kilobyte> <=> memsize = "<value megabyte>" # must be a multiple of 4, defaults to 32
|
||||
def->mem.cur_balloon = <value kilobyte> <=> sched.mem.max = "<value megabyte>" # defaults to "unlimited" -> def->mem.cur_balloon = def->mem.max_balloon
|
||||
-def->vcpus = <value> <=> numvcpus = "<value>" # must be 1 or a multiple of 2, defaults to 1
|
||||
+def->maxvcpus = <value> <=> numvcpus = "<value>" # must be 1 or a multiple of 2, defaults to 1
|
||||
def->cpumask = <uint list> <=> sched.cpu.affinity = "<uint list>"
|
||||
|
||||
|
||||
@@ -1075,7 +1075,7 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- def->vcpus = numvcpus;
|
||||
+ def->maxvcpus = def->vcpus = numvcpus;
|
||||
|
||||
/* vmx:sched.cpu.affinity -> def:cpumask */
|
||||
// VirtualMachine:config.cpuAffinity.affinitySet
|
||||
@@ -2609,16 +2609,22 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
|
||||
(int)(def->mem.cur_balloon / 1024));
|
||||
}
|
||||
|
||||
- /* def:vcpus -> vmx:numvcpus */
|
||||
- if (def->vcpus <= 0 || (def->vcpus % 2 != 0 && def->vcpus != 1)) {
|
||||
+ /* def:maxvcpus -> vmx:numvcpus */
|
||||
+ if (def->vcpus != def->maxvcpus) {
|
||||
+ ESX_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
+ _("No support for domain XML entry 'vcpu' attribute "
|
||||
+ "'current'"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (def->maxvcpus <= 0 || (def->maxvcpus % 2 != 0 && def->maxvcpus != 1)) {
|
||||
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Expecting domain XML entry 'vcpu' to be an unsigned "
|
||||
"integer (1 or a multiple of 2) but found %d"),
|
||||
- (int)def->vcpus);
|
||||
+ def->maxvcpus);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- virBufferAsprintf(&buffer, "numvcpus = \"%d\"\n", (int)def->vcpus);
|
||||
+ virBufferAsprintf(&buffer, "numvcpus = \"%d\"\n", def->maxvcpus);
|
||||
|
||||
/* def:cpumask -> vmx:sched.cpu.affinity */
|
||||
if (def->cpumasklen > 0) {
|
||||
@@ -2632,11 +2638,11 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
|
||||
}
|
||||
}
|
||||
|
||||
- if (sched_cpu_affinity_length < def->vcpus) {
|
||||
+ if (sched_cpu_affinity_length < def->maxvcpus) {
|
||||
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Expecting domain XML attribute 'cpuset' of entry "
|
||||
- "'vcpu' to contains at least %d CPU(s)"),
|
||||
- (int)def->vcpus);
|
||||
+ "'vcpu' to contain at least %d CPU(s)"),
|
||||
+ def->maxvcpus);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
diff --git a/src/opennebula/one_conf.c b/src/opennebula/one_conf.c
|
||||
index 44e28dc..2079c51 100644
|
||||
--- a/src/opennebula/one_conf.c
|
||||
+++ b/src/opennebula/one_conf.c
|
||||
@@ -1,5 +1,7 @@
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
-/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
|
||||
+/*
|
||||
+ * Copyright (C) 2010 Red Hat, Inc.
|
||||
+ * Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
|
||||
* Complutense de Madrid (dsa-research.org)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -169,9 +171,10 @@ char* xmlOneTemplate(virDomainDefPtr def)
|
||||
{
|
||||
int i;
|
||||
virBuffer buf= VIR_BUFFER_INITIALIZER;
|
||||
- virBufferAsprintf(&buf,"#OpenNebula Template automatically generated by libvirt\nNAME = %s\nCPU = %ld\nMEMORY = %ld\n",
|
||||
+ virBufferAsprintf(&buf,"#OpenNebula Template automatically generated "
|
||||
+ "by libvirt\nNAME = %s\nCPU = %d\nMEMORY = %ld\n",
|
||||
def->name,
|
||||
- def->vcpus,
|
||||
+ def->maxvcpus,
|
||||
(def->mem.max_balloon)/1024);
|
||||
|
||||
/*Optional Booting OpenNebula Information:*/
|
||||
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
|
||||
index ec11bbc..c84a6f3 100644
|
||||
--- a/src/openvz/openvz_conf.c
|
||||
+++ b/src/openvz/openvz_conf.c
|
||||
@@ -507,11 +507,12 @@ int openvzLoadDomains(struct openvz_driver *driver) {
|
||||
veid);
|
||||
goto cleanup;
|
||||
} else if (ret > 0) {
|
||||
- dom->def->vcpus = strtoI(temp);
|
||||
+ dom->def->maxvcpus = strtoI(temp);
|
||||
}
|
||||
|
||||
- if (ret == 0 || dom->def->vcpus == 0)
|
||||
- dom->def->vcpus = openvzGetNodeCPUs();
|
||||
+ if (ret == 0 || dom->def->maxvcpus == 0)
|
||||
+ dom->def->maxvcpus = openvzGetNodeCPUs();
|
||||
+ dom->def->vcpus = dom->def->maxvcpus;
|
||||
|
||||
/* XXX load rest of VM config data .... */
|
||||
|
||||
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
|
||||
index 0f3cfdf..b7c2754 100644
|
||||
--- a/src/openvz/openvz_driver.c
|
||||
+++ b/src/openvz/openvz_driver.c
|
||||
@@ -925,8 +925,13 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
|
||||
if (openvzDomainSetNetworkConfig(conn, vm->def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
- if (vm->def->vcpus > 0) {
|
||||
- if (openvzDomainSetVcpusInternal(vm, vm->def->vcpus) < 0) {
|
||||
+ if (vm->def->vcpus != vm->def->maxvcpus) {
|
||||
+ openvzError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
+ _("current vcpu count must equal maximum"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (vm->def->maxvcpus > 0) {
|
||||
+ if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
|
||||
openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Could not set number of virtual cpu"));
|
||||
goto cleanup;
|
||||
@@ -1019,8 +1024,8 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
|
||||
vm->def->id = vm->pid;
|
||||
vm->state = VIR_DOMAIN_RUNNING;
|
||||
|
||||
- if (vm->def->vcpus > 0) {
|
||||
- if (openvzDomainSetVcpusInternal(vm, vm->def->vcpus) < 0) {
|
||||
+ if (vm->def->maxvcpus > 0) {
|
||||
+ if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
|
||||
openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Could not set number of virtual cpu"));
|
||||
goto cleanup;
|
||||
@@ -1249,7 +1254,7 @@ static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
|
||||
return -1;
|
||||
}
|
||||
|
||||
- vm->def->vcpus = nvcpus;
|
||||
+ vm->def->maxvcpus = vm->def->vcpus = nvcpus;
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
|
||||
index e284ae0..3d0ed11 100644
|
||||
--- a/src/phyp/phyp_driver.c
|
||||
+++ b/src/phyp/phyp_driver.c
|
||||
@@ -3540,7 +3540,7 @@ phypDomainDumpXML(virDomainPtr dom, int flags)
|
||||
goto err;
|
||||
}
|
||||
|
||||
- if ((def.vcpus =
|
||||
+ if ((def.maxvcpus = def.vcpus =
|
||||
phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) {
|
||||
VIR_ERROR0(_("Unable to determine domain's CPU."));
|
||||
goto err;
|
||||
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
|
||||
index 83c0f83..38c8351 100644
|
||||
--- a/src/qemu/qemu_conf.c
|
||||
+++ b/src/qemu/qemu_conf.c
|
||||
@@ -3711,7 +3711,7 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
- virBufferAsprintf(&buf, "%lu", def->vcpus);
|
||||
+ virBufferAsprintf(&buf, "%u", def->vcpus);
|
||||
|
||||
if ((qemuCmdFlags & QEMUD_CMD_FLAG_SMP_TOPOLOGY)) {
|
||||
/* sockets, cores, and threads are either all zero
|
||||
@@ -3722,11 +3722,18 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
|
||||
virBufferAsprintf(&buf, ",threads=%u", def->cpu->threads);
|
||||
}
|
||||
else {
|
||||
- virBufferAsprintf(&buf, ",sockets=%lu", def->vcpus);
|
||||
+ virBufferAsprintf(&buf, ",sockets=%u", def->maxvcpus);
|
||||
virBufferAsprintf(&buf, ",cores=%u", 1);
|
||||
virBufferAsprintf(&buf, ",threads=%u", 1);
|
||||
}
|
||||
}
|
||||
+ if (def->vcpus != def->maxvcpus) {
|
||||
+ virBufferFreeAndReset(&buf);
|
||||
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
+ _("setting current vcpu count less than maximum is "
|
||||
+ "not supported yet"));
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
if (virBufferError(&buf)) {
|
||||
virBufferFreeAndReset(&buf);
|
||||
@@ -6178,6 +6185,8 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
|
||||
}
|
||||
}
|
||||
|
||||
+ dom->maxvcpus = dom->vcpus;
|
||||
+
|
||||
if (sockets && cores && threads) {
|
||||
virCPUDefPtr cpu;
|
||||
|
||||
@@ -6247,6 +6256,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
|
||||
|
||||
def->id = -1;
|
||||
def->mem.cur_balloon = def->mem.max_balloon = 64 * 1024;
|
||||
+ def->maxvcpus = 1;
|
||||
def->vcpus = 1;
|
||||
def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
|
||||
def->features = (1 << VIR_DOMAIN_FEATURE_ACPI)
|
||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||
index 7a2ea8f..c66dc04 100644
|
||||
--- a/src/qemu/qemu_driver.c
|
||||
+++ b/src/qemu/qemu_driver.c
|
||||
@@ -2425,8 +2425,9 @@ qemuDetectVcpuPIDs(struct qemud_driver *driver,
|
||||
|
||||
if (ncpupids != vm->def->vcpus) {
|
||||
qemuReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
- _("got wrong number of vCPU pids from QEMU monitor. got %d, wanted %d"),
|
||||
- ncpupids, (int)vm->def->vcpus);
|
||||
+ _("got wrong number of vCPU pids from QEMU monitor. "
|
||||
+ "got %d, wanted %d"),
|
||||
+ ncpupids, vm->def->vcpus);
|
||||
VIR_FREE(cpupids);
|
||||
return -1;
|
||||
}
|
||||
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
|
||||
index 0cbe8b3..5a859a4 100644
|
||||
--- a/src/vbox/vbox_tmpl.c
|
||||
+++ b/src/vbox/vbox_tmpl.c
|
||||
@@ -2028,7 +2028,7 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
|
||||
def->mem.max_balloon = memorySize * 1024;
|
||||
|
||||
machine->vtbl->GetCPUCount(machine, &CPUCount);
|
||||
- def->vcpus = CPUCount;
|
||||
+ def->maxvcpus = def->vcpus = CPUCount;
|
||||
|
||||
/* Skip cpumasklen, cpumask, onReboot, onPoweroff, onCrash */
|
||||
|
||||
@@ -4598,11 +4598,15 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
|
||||
def->mem.cur_balloon, (unsigned)rc);
|
||||
}
|
||||
|
||||
- rc = machine->vtbl->SetCPUCount(machine, def->vcpus);
|
||||
+ if (def->vcpus != def->maxvcpus) {
|
||||
+ vboxError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
+ _("current vcpu count must equal maximum"));
|
||||
+ }
|
||||
+ rc = machine->vtbl->SetCPUCount(machine, def->maxvcpus);
|
||||
if (NS_FAILED(rc)) {
|
||||
vboxError(VIR_ERR_INTERNAL_ERROR,
|
||||
- _("could not set the number of virtual CPUs to: %lu, rc=%08x"),
|
||||
- def->vcpus, (unsigned)rc);
|
||||
+ _("could not set the number of virtual CPUs to: %u, rc=%08x"),
|
||||
+ def->maxvcpus, (unsigned)rc);
|
||||
}
|
||||
|
||||
#if VBOX_API_VERSION < 3001
|
||||
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
|
||||
index 5ffc3c8..456b477 100644
|
||||
--- a/src/xen/xend_internal.c
|
||||
+++ b/src/xen/xend_internal.c
|
||||
@@ -2190,7 +2190,8 @@ xenDaemonParseSxpr(virConnectPtr conn,
|
||||
}
|
||||
}
|
||||
|
||||
- def->vcpus = sexpr_int(root, "domain/vcpus");
|
||||
+ def->maxvcpus = sexpr_int(root, "domain/vcpus");
|
||||
+ def->vcpus = def->maxvcpus;
|
||||
|
||||
tmp = sexpr_node(root, "domain/on_poweroff");
|
||||
if (tmp != NULL) {
|
||||
@@ -5649,7 +5650,7 @@ xenDaemonFormatSxprInput(virDomainInputDefPtr input,
|
||||
*
|
||||
* Generate an SEXPR representing the domain configuration.
|
||||
*
|
||||
- * Returns the 0 terminatedi S-Expr string or NULL in case of error.
|
||||
+ * Returns the 0 terminated S-Expr string or NULL in case of error.
|
||||
* the caller must free() the returned value.
|
||||
*/
|
||||
char *
|
||||
@@ -5666,7 +5667,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
|
||||
virBufferAsprintf(&buf, "(name '%s')", def->name);
|
||||
virBufferAsprintf(&buf, "(memory %lu)(maxmem %lu)",
|
||||
def->mem.cur_balloon/1024, def->mem.max_balloon/1024);
|
||||
- virBufferAsprintf(&buf, "(vcpus %lu)", def->vcpus);
|
||||
+ virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
|
||||
|
||||
if (def->cpumask) {
|
||||
char *ranges = virDomainCpuSetFormat(def->cpumask, def->cpumasklen);
|
||||
@@ -5761,7 +5762,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
|
||||
else
|
||||
virBufferAsprintf(&buf, "(kernel '%s')", def->os.loader);
|
||||
|
||||
- virBufferAsprintf(&buf, "(vcpus %lu)", def->vcpus);
|
||||
+ virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
|
||||
|
||||
for (i = 0 ; i < def->os.nBootDevs ; i++) {
|
||||
switch (def->os.bootDevs[i]) {
|
||||
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
|
||||
index 8e42a1c..bf20a64 100644
|
||||
--- a/src/xen/xm_internal.c
|
||||
+++ b/src/xen/xm_internal.c
|
||||
@@ -678,6 +678,7 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
|
||||
int i;
|
||||
const char *defaultArch, *defaultMachine;
|
||||
int vmlocaltime = 0;
|
||||
+ unsigned long count;
|
||||
|
||||
if (VIR_ALLOC(def) < 0) {
|
||||
virReportOOMError();
|
||||
@@ -770,9 +771,11 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
|
||||
def->mem.cur_balloon *= 1024;
|
||||
def->mem.max_balloon *= 1024;
|
||||
|
||||
-
|
||||
- if (xenXMConfigGetULong(conf, "vcpus", &def->vcpus, 1) < 0)
|
||||
+ if (xenXMConfigGetULong(conf, "vcpus", &count, 1) < 0 ||
|
||||
+ (unsigned short) count != count)
|
||||
goto cleanup;
|
||||
+ def->maxvcpus = count;
|
||||
+ def->vcpus = def->maxvcpus;
|
||||
|
||||
if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
|
||||
goto cleanup;
|
||||
@@ -1650,7 +1653,7 @@ int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus) {
|
||||
if (!(entry = virHashLookup(priv->configCache, filename)))
|
||||
goto cleanup;
|
||||
|
||||
- entry->def->vcpus = vcpus;
|
||||
+ entry->def->maxvcpus = entry->def->vcpus = vcpus;
|
||||
|
||||
/* If this fails, should we try to undo our changes to the
|
||||
* in-memory representation of the config file. I say not!
|
||||
@@ -2241,7 +2244,7 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
|
||||
if (xenXMConfigSetInt(conf, "memory", def->mem.cur_balloon / 1024) < 0)
|
||||
goto no_memory;
|
||||
|
||||
- if (xenXMConfigSetInt(conf, "vcpus", def->vcpus) < 0)
|
||||
+ if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
|
||||
goto no_memory;
|
||||
|
||||
if ((def->cpumask != NULL) &&
|
||||
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
|
||||
index 7d4ab8d..5ccdede 100644
|
||||
--- a/src/xenapi/xenapi_driver.c
|
||||
+++ b/src/xenapi/xenapi_driver.c
|
||||
@@ -1335,7 +1335,7 @@ xenapiDomainDumpXML (virDomainPtr dom, int flags ATTRIBUTE_UNUSED)
|
||||
} else {
|
||||
defPtr->mem.cur_balloon = memory;
|
||||
}
|
||||
- defPtr->vcpus = xenapiDomainGetMaxVcpus(dom);
|
||||
+ defPtr->maxvcpus = defPtr->vcpus = xenapiDomainGetMaxVcpus(dom);
|
||||
enum xen_on_normal_exit action;
|
||||
if (xen_vm_get_actions_after_shutdown(session, &action, vm)) {
|
||||
defPtr->onPoweroff = xenapiNormalExitEnum2virDomainLifecycle(action);
|
||||
diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c
|
||||
index be55491..a7e2a4b 100644
|
||||
--- a/src/xenapi/xenapi_utils.c
|
||||
+++ b/src/xenapi/xenapi_utils.c
|
||||
@@ -510,8 +510,8 @@ createVMRecordFromXml (virConnectPtr conn, virDomainDefPtr def,
|
||||
else
|
||||
(*record)->memory_dynamic_max = (*record)->memory_static_max;
|
||||
|
||||
- if (def->vcpus) {
|
||||
- (*record)->vcpus_max = (int64_t) def->vcpus;
|
||||
+ if (def->maxvcpus) {
|
||||
+ (*record)->vcpus_max = (int64_t) def->maxvcpus;
|
||||
(*record)->vcpus_at_startup = (int64_t) def->vcpus;
|
||||
}
|
||||
if (def->onPoweroff)
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,197 +0,0 @@
|
||||
From 6c9e6b956453d0f0c4ff542ef8a184d663a39266 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Mon, 4 Oct 2010 17:01:12 -0600
|
||||
Subject: [PATCH 09/15] vcpu: support all flags in test driver
|
||||
|
||||
* src/test/test_driver.c (testDomainGetVcpusFlags)
|
||||
(testDomainSetVcpusFlags): Support all flags.
|
||||
(testDomainUpdateVCPUs): Update cpu count here.
|
||||
---
|
||||
src/test/test_driver.c | 128 ++++++++++++++++++++++++++++++++++++++++-------
|
||||
1 files changed, 109 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
|
||||
index b70c80d..a9d3d89 100644
|
||||
--- a/src/test/test_driver.c
|
||||
+++ b/src/test/test_driver.c
|
||||
@@ -450,6 +450,7 @@ testDomainUpdateVCPUs(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
+ dom->def->vcpus = nvcpus;
|
||||
ret = 0;
|
||||
cleanup:
|
||||
return ret;
|
||||
@@ -2032,12 +2033,51 @@ cleanup:
|
||||
static int
|
||||
testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
|
||||
{
|
||||
- if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
- testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
||||
+ testConnPtr privconn = domain->conn->privateData;
|
||||
+ virDomainObjPtr vm;
|
||||
+ virDomainDefPtr def;
|
||||
+ int ret = -1;
|
||||
+
|
||||
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_CONFIG |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
|
||||
+
|
||||
+ /* Exactly one of LIVE or CONFIG must be set. */
|
||||
+ if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
|
||||
+ testError(VIR_ERR_INVALID_ARG,
|
||||
+ _("invalid flag combination: (0x%x)"), flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
- return testGetMaxVCPUs(domain->conn, "test");
|
||||
+ testDriverLock(privconn);
|
||||
+ vm = virDomainFindByUUID(&privconn->domains, domain->uuid);
|
||||
+ testDriverUnlock(privconn);
|
||||
+
|
||||
+ if (!vm) {
|
||||
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
+ virUUIDFormat(domain->uuid, uuidstr);
|
||||
+ testError(VIR_ERR_NO_DOMAIN,
|
||||
+ _("no domain with matching uuid '%s'"), uuidstr);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ if (!virDomainObjIsActive(vm)) {
|
||||
+ testError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("domain not active"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ def = vm->def;
|
||||
+ } else {
|
||||
+ def = vm->newDef ? vm->newDef : vm->def;
|
||||
+ }
|
||||
+
|
||||
+ ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;
|
||||
+
|
||||
+cleanup:
|
||||
+ if (vm)
|
||||
+ virDomainObjUnlock(vm);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2053,21 +2093,30 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
|
||||
{
|
||||
testConnPtr privconn = domain->conn->privateData;
|
||||
virDomainObjPtr privdom = NULL;
|
||||
+ virDomainDefPtr def;
|
||||
int ret = -1, maxvcpus;
|
||||
|
||||
- if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
- testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
||||
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_CONFIG |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
|
||||
+
|
||||
+ /* At least one of LIVE or CONFIG must be set. MAXIMUM cannot be
|
||||
+ * mixed with LIVE. */
|
||||
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
|
||||
+ (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
|
||||
+ (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
|
||||
+ testError(VIR_ERR_INVALID_ARG,
|
||||
+ _("invalid flag combination: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (!nrCpus || (maxvcpus = testGetMaxVCPUs(domain->conn, NULL)) < nrCpus) {
|
||||
+ testError(VIR_ERR_INVALID_ARG,
|
||||
+ _("argument out of range: %d"), nrCpus);
|
||||
return -1;
|
||||
}
|
||||
-
|
||||
- /* Do this first before locking */
|
||||
- maxvcpus = testDomainGetMaxVcpus(domain);
|
||||
- if (maxvcpus < 0)
|
||||
- goto cleanup;
|
||||
|
||||
testDriverLock(privconn);
|
||||
- privdom = virDomainFindByName(&privconn->domains,
|
||||
- domain->name);
|
||||
+ privdom = virDomainFindByUUID(&privconn->domains, domain->uuid);
|
||||
testDriverUnlock(privconn);
|
||||
|
||||
if (privdom == NULL) {
|
||||
@@ -2075,13 +2124,17 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- if (!virDomainObjIsActive(privdom)) {
|
||||
+ if (!virDomainObjIsActive(privdom) && (flags & VIR_DOMAIN_VCPU_LIVE)) {
|
||||
testError(VIR_ERR_OPERATION_INVALID,
|
||||
"%s", _("cannot hotplug vcpus for an inactive domain"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- /* We allow more cpus in guest than host */
|
||||
+ /* We allow more cpus in guest than host, but not more than the
|
||||
+ * domain's starting limit. */
|
||||
+ if ((flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
|
||||
+ VIR_DOMAIN_VCPU_LIVE && privdom->def->maxvcpus < maxvcpus)
|
||||
+ maxvcpus = privdom->def->maxvcpus;
|
||||
if (nrCpus > maxvcpus) {
|
||||
testError(VIR_ERR_INVALID_ARG,
|
||||
"requested cpu amount exceeds maximum (%d > %d)",
|
||||
@@ -2089,12 +2142,49 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- /* Update VCPU state for the running domain */
|
||||
- if (testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0) < 0)
|
||||
- goto cleanup;
|
||||
+ switch (flags) {
|
||||
+ case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_CONFIG:
|
||||
+ def = privdom->def;
|
||||
+ if (virDomainObjIsActive(privdom)) {
|
||||
+ if (privdom->newDef)
|
||||
+ def = privdom->newDef;
|
||||
+ else {
|
||||
+ testError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("no persistent state"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+ def->maxvcpus = nrCpus;
|
||||
+ if (nrCpus < def->vcpus)
|
||||
+ def->vcpus = nrCpus;
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
|
||||
- privdom->def->vcpus = nrCpus;
|
||||
- ret = 0;
|
||||
+ case VIR_DOMAIN_VCPU_CONFIG:
|
||||
+ def = privdom->def;
|
||||
+ if (virDomainObjIsActive(privdom)) {
|
||||
+ if (privdom->newDef)
|
||||
+ def = privdom->newDef;
|
||||
+ else {
|
||||
+ testError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("no persistent state"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+ def->vcpus = nrCpus;
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+
|
||||
+ case VIR_DOMAIN_VCPU_LIVE:
|
||||
+ ret = testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0);
|
||||
+ break;
|
||||
+
|
||||
+ case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG:
|
||||
+ ret = testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0);
|
||||
+ if (ret == 0 && privdom->newDef)
|
||||
+ privdom->newDef->vcpus = nrCpus;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
cleanup:
|
||||
if (privdom)
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,122 +0,0 @@
|
||||
From d67c189e80e6aef7adf13e5763365555cfc1a02a Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Wed, 29 Sep 2010 15:58:47 -0600
|
||||
Subject: [PATCH 10/15] vcpu: improve vcpu support in qemu command line
|
||||
|
||||
* src/qemu/qemu_conf.c (qemuParseCommandLineSmp): Distinguish
|
||||
between vcpus and maxvcpus, for new enough qemu.
|
||||
* tests/qemuargv2xmltest.c (mymain): Add new test.
|
||||
* tests/qemuxml2argvtest.c (mymain): Likewise.
|
||||
* tests/qemuxml2xmltest.c (mymain): Likewise.
|
||||
* tests/qemuxml2argvdata/qemuxml2argv-smp.args: New file.
|
||||
---
|
||||
src/qemu/qemu_conf.c | 13 +++++++++----
|
||||
tests/qemuargv2xmltest.c | 2 ++
|
||||
tests/qemuxml2argvdata/qemuxml2argv-smp.args | 1 +
|
||||
tests/qemuxml2argvtest.c | 2 ++
|
||||
tests/qemuxml2xmltest.c | 2 ++
|
||||
5 files changed, 16 insertions(+), 4 deletions(-)
|
||||
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smp.args
|
||||
|
||||
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
|
||||
index 38c8351..ffe184b 100644
|
||||
--- a/src/qemu/qemu_conf.c
|
||||
+++ b/src/qemu/qemu_conf.c
|
||||
@@ -3714,6 +3714,8 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
|
||||
virBufferAsprintf(&buf, "%u", def->vcpus);
|
||||
|
||||
if ((qemuCmdFlags & QEMUD_CMD_FLAG_SMP_TOPOLOGY)) {
|
||||
+ if (def->vcpus != def->maxvcpus)
|
||||
+ virBufferAsprintf(&buf, ",maxcpus=%u", def->maxvcpus);
|
||||
/* sockets, cores, and threads are either all zero
|
||||
* or all non-zero, thus checking one of them is enough */
|
||||
if (def->cpu && def->cpu->sockets) {
|
||||
@@ -3726,12 +3728,12 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
|
||||
virBufferAsprintf(&buf, ",cores=%u", 1);
|
||||
virBufferAsprintf(&buf, ",threads=%u", 1);
|
||||
}
|
||||
- }
|
||||
- if (def->vcpus != def->maxvcpus) {
|
||||
+ } else if (def->vcpus != def->maxvcpus) {
|
||||
virBufferFreeAndReset(&buf);
|
||||
+ /* FIXME - consider hot-unplugging cpus after boot for older qemu */
|
||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("setting current vcpu count less than maximum is "
|
||||
- "not supported yet"));
|
||||
+ "not supported with this QEMU binary"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -6153,6 +6155,7 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
|
||||
unsigned int sockets = 0;
|
||||
unsigned int cores = 0;
|
||||
unsigned int threads = 0;
|
||||
+ unsigned int maxcpus = 0;
|
||||
int i;
|
||||
int nkws;
|
||||
char **kws;
|
||||
@@ -6180,12 +6183,14 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
|
||||
cores = n;
|
||||
else if (STREQ(kws[i], "threads"))
|
||||
threads = n;
|
||||
+ else if (STREQ(kws[i], "maxcpus"))
|
||||
+ maxcpus = n;
|
||||
else
|
||||
goto syntax;
|
||||
}
|
||||
}
|
||||
|
||||
- dom->maxvcpus = dom->vcpus;
|
||||
+ dom->maxvcpus = maxcpus ? maxcpus : dom->vcpus;
|
||||
|
||||
if (sockets && cores && threads) {
|
||||
virCPUDefPtr cpu;
|
||||
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
|
||||
index 4f9ec84..d941b0b 100644
|
||||
--- a/tests/qemuargv2xmltest.c
|
||||
+++ b/tests/qemuargv2xmltest.c
|
||||
@@ -221,6 +221,8 @@ mymain(int argc, char **argv)
|
||||
|
||||
DO_TEST("hostdev-pci-address");
|
||||
|
||||
+ DO_TEST("smp");
|
||||
+
|
||||
DO_TEST_FULL("restore-v1", 0, "stdio");
|
||||
DO_TEST_FULL("restore-v2", 0, "stdio");
|
||||
DO_TEST_FULL("restore-v2", 0, "exec:cat");
|
||||
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smp.args b/tests/qemuxml2argvdata/qemuxml2argv-smp.args
|
||||
new file mode 100644
|
||||
index 0000000..3ec8f15
|
||||
--- /dev/null
|
||||
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smp.args
|
||||
@@ -0,0 +1 @@
|
||||
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1,maxcpus=2,sockets=2,cores=1,threads=1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb
|
||||
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
|
||||
index 92d5b18..551d6c4 100644
|
||||
--- a/tests/qemuxml2argvtest.c
|
||||
+++ b/tests/qemuxml2argvtest.c
|
||||
@@ -385,6 +385,8 @@ mymain(int argc, char **argv)
|
||||
|
||||
DO_TEST("qemu-ns", 0);
|
||||
|
||||
+ DO_TEST("smp", QEMUD_CMD_FLAG_SMP_TOPOLOGY);
|
||||
+
|
||||
free(driver.stateDir);
|
||||
virCapabilitiesFree(driver.caps);
|
||||
|
||||
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
|
||||
index a33d435..cdc4390 100644
|
||||
--- a/tests/qemuxml2xmltest.c
|
||||
+++ b/tests/qemuxml2xmltest.c
|
||||
@@ -180,6 +180,8 @@ mymain(int argc, char **argv)
|
||||
DO_TEST("encrypted-disk");
|
||||
DO_TEST("memtune");
|
||||
|
||||
+ DO_TEST("smp");
|
||||
+
|
||||
/* These tests generate different XML */
|
||||
DO_TEST_DIFFERENT("balloon-device-auto");
|
||||
DO_TEST_DIFFERENT("channel-virtio-auto");
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,169 +0,0 @@
|
||||
From 28a3605906385cba43df77051dc26e865f237b09 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Wed, 29 Sep 2010 17:40:45 -0600
|
||||
Subject: [PATCH 11/15] vcpu: complete vcpu support in qemu driver
|
||||
|
||||
* src/qemu/qemu_driver.c (qemudDomainSetVcpusFlags)
|
||||
(qemudDomainGetVcpusFlags): Support all feasible flag
|
||||
combinations.
|
||||
---
|
||||
src/qemu/qemu_driver.c | 100 ++++++++++++++++++++++++++++++++++++++++-------
|
||||
1 files changed, 85 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||
index c66dc04..a9e057f 100644
|
||||
--- a/src/qemu/qemu_driver.c
|
||||
+++ b/src/qemu/qemu_driver.c
|
||||
@@ -5941,13 +5941,27 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
||||
{
|
||||
struct qemud_driver *driver = dom->conn->privateData;
|
||||
virDomainObjPtr vm;
|
||||
+ virDomainDefPtr def;
|
||||
const char * type;
|
||||
int max;
|
||||
int ret = -1;
|
||||
|
||||
- if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
- qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
|
||||
- flags);
|
||||
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_CONFIG |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
|
||||
+
|
||||
+ /* At least one of LIVE or CONFIG must be set. MAXIMUM cannot be
|
||||
+ * mixed with LIVE. */
|
||||
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
|
||||
+ (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
|
||||
+ (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
|
||||
+ qemuReportError(VIR_ERR_INVALID_ARG,
|
||||
+ _("invalid flag combination: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (!nvcpus || (unsigned short) nvcpus != nvcpus) {
|
||||
+ qemuReportError(VIR_ERR_INVALID_ARG,
|
||||
+ _("argument out of range: %d"), nvcpus);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -5966,7 +5980,7 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
||||
if (qemuDomainObjBeginJob(vm) < 0)
|
||||
goto cleanup;
|
||||
|
||||
- if (!virDomainObjIsActive(vm)) {
|
||||
+ if (!virDomainObjIsActive(vm) && (flags & VIR_DOMAIN_VCPU_LIVE)) {
|
||||
qemuReportError(VIR_ERR_OPERATION_INVALID,
|
||||
"%s", _("domain is not running"));
|
||||
goto endjob;
|
||||
@@ -5985,6 +5999,11 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
||||
goto endjob;
|
||||
}
|
||||
|
||||
+ if ((flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
|
||||
+ VIR_DOMAIN_VCPU_LIVE && vm->def->maxvcpus < max) {
|
||||
+ max = vm->def->maxvcpus;
|
||||
+ }
|
||||
+
|
||||
if (nvcpus > max) {
|
||||
qemuReportError(VIR_ERR_INVALID_ARG,
|
||||
_("requested vcpus is greater than max allowable"
|
||||
@@ -5992,7 +6011,49 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
||||
goto endjob;
|
||||
}
|
||||
|
||||
- ret = qemudDomainHotplugVcpus(vm, nvcpus);
|
||||
+ switch (flags) {
|
||||
+ case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_CONFIG:
|
||||
+ def = vm->def;
|
||||
+ if (virDomainObjIsActive(vm)) {
|
||||
+ if (vm->newDef)
|
||||
+ def = vm->newDef;
|
||||
+ else{
|
||||
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("no persistent state"));
|
||||
+ goto endjob;
|
||||
+ }
|
||||
+ }
|
||||
+ def->maxvcpus = nvcpus;
|
||||
+ if (nvcpus < vm->newDef->vcpus)
|
||||
+ def->vcpus = nvcpus;
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+
|
||||
+ case VIR_DOMAIN_VCPU_CONFIG:
|
||||
+ def = vm->def;
|
||||
+ if (virDomainObjIsActive(vm)) {
|
||||
+ if (vm->newDef)
|
||||
+ def = vm->newDef;
|
||||
+ else {
|
||||
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("no persistent state"));
|
||||
+ goto endjob;
|
||||
+ }
|
||||
+ }
|
||||
+ def->vcpus = nvcpus;
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+
|
||||
+ case VIR_DOMAIN_VCPU_LIVE:
|
||||
+ ret = qemudDomainHotplugVcpus(vm, nvcpus);
|
||||
+ break;
|
||||
+
|
||||
+ case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG:
|
||||
+ ret = qemudDomainHotplugVcpus(vm, nvcpus);
|
||||
+ if (ret == 0 && vm->newDef)
|
||||
+ vm->newDef->vcpus = nvcpus;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
endjob:
|
||||
if (qemuDomainObjEndJob(vm) == 0)
|
||||
@@ -6171,12 +6232,17 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
|
||||
{
|
||||
struct qemud_driver *driver = dom->conn->privateData;
|
||||
virDomainObjPtr vm;
|
||||
- const char *type;
|
||||
+ virDomainDefPtr def;
|
||||
int ret = -1;
|
||||
|
||||
- if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
- qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
|
||||
- flags);
|
||||
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_CONFIG |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
|
||||
+
|
||||
+ /* Exactly one of LIVE or CONFIG must be set. */
|
||||
+ if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
|
||||
+ qemuReportError(VIR_ERR_INVALID_ARG,
|
||||
+ _("invalid flag combination: (0x%x)"), flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -6192,14 +6258,18 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- if (!(type = virDomainVirtTypeToString(vm->def->virtType))) {
|
||||
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
- _("unknown virt type in domain definition '%d'"),
|
||||
- vm->def->virtType);
|
||||
- goto cleanup;
|
||||
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ if (!virDomainObjIsActive(vm)) {
|
||||
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("domain not active"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ def = vm->def;
|
||||
+ } else {
|
||||
+ def = vm->newDef ? vm->newDef : vm->def;
|
||||
}
|
||||
|
||||
- ret = qemudGetMaxVCPUs(NULL, type);
|
||||
+ ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;
|
||||
|
||||
cleanup:
|
||||
if (vm)
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,294 +0,0 @@
|
||||
From 0fab10e5ed971ab4f960a53e9640b0672f4b8ac3 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Tue, 5 Oct 2010 08:18:52 -0600
|
||||
Subject: [PATCH 12/15] vcpu: improve vcpu support in xen command line
|
||||
|
||||
This patch series focuses on xendConfigVersion 2 (xm_internal) and 3
|
||||
(xend_internal), but leaves out changes for xenapi drivers.
|
||||
|
||||
See this link for more details about vcpu_avail for xm usage.
|
||||
http://lists.xensource.com/archives/html/xen-devel/2009-11/msg01061.html
|
||||
|
||||
This relies on the fact that def->maxvcpus can be at most 32 with xen.
|
||||
|
||||
* src/xen/xend_internal.c (xenDaemonParseSxpr)
|
||||
(sexpr_to_xend_domain_info, xenDaemonFormatSxpr): Use vcpu_avail
|
||||
when current vcpus is less than maximum.
|
||||
* src/xen/xm_internal.c (xenXMDomainConfigParse)
|
||||
(xenXMDomainConfigFormat): Likewise.
|
||||
* tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr: New file.
|
||||
* tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr: Likewise.
|
||||
* tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml: Likewise.
|
||||
* tests/xmconfigdata/test-paravirt-vcpu.cfg: Likewise.
|
||||
* tests/xmconfigdata/test-paravirt-vcpu.xml: Likewise.
|
||||
* tests/xml2sexprtest.c (mymain): New test.
|
||||
* tests/sexpr2xmltest.c (mymain): Likewise.
|
||||
* tests/xmconfigtest.c (mymain): Likewise.
|
||||
---
|
||||
src/xen/xend_internal.c | 19 +++++++++++++--
|
||||
src/xen/xm_internal.c | 10 ++++++-
|
||||
tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr | 1 +
|
||||
tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml | 27 +++++++++++++++++++++
|
||||
tests/sexpr2xmltest.c | 1 +
|
||||
tests/xmconfigdata/test-paravirt-vcpu.cfg | 17 +++++++++++++
|
||||
tests/xmconfigdata/test-paravirt-vcpu.xml | 32 ++++++++++++++++++++++++++
|
||||
tests/xmconfigtest.c | 1 +
|
||||
tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr | 1 +
|
||||
tests/xml2sexprtest.c | 1 +
|
||||
10 files changed, 105 insertions(+), 5 deletions(-)
|
||||
create mode 100644 tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr
|
||||
create mode 100644 tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml
|
||||
create mode 100644 tests/xmconfigdata/test-paravirt-vcpu.cfg
|
||||
create mode 100644 tests/xmconfigdata/test-paravirt-vcpu.xml
|
||||
create mode 100644 tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr
|
||||
|
||||
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
|
||||
index 456b477..dfc6415 100644
|
||||
--- a/src/xen/xend_internal.c
|
||||
+++ b/src/xen/xend_internal.c
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "xen_hypervisor.h"
|
||||
#include "xs_internal.h" /* To extract VNC port & Serial console TTY */
|
||||
#include "memory.h"
|
||||
+#include "count-one-bits.h"
|
||||
|
||||
/* required for cpumap_t */
|
||||
#include <xen/dom0_ops.h>
|
||||
@@ -2191,7 +2192,9 @@ xenDaemonParseSxpr(virConnectPtr conn,
|
||||
}
|
||||
|
||||
def->maxvcpus = sexpr_int(root, "domain/vcpus");
|
||||
- def->vcpus = def->maxvcpus;
|
||||
+ def->vcpus = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
|
||||
+ if (!def->vcpus || def->maxvcpus < def->vcpus)
|
||||
+ def->vcpus = def->maxvcpus;
|
||||
|
||||
tmp = sexpr_node(root, "domain/on_poweroff");
|
||||
if (tmp != NULL) {
|
||||
@@ -2433,7 +2436,7 @@ sexpr_to_xend_domain_info(virDomainPtr domain, const struct sexpr *root,
|
||||
virDomainInfoPtr info)
|
||||
{
|
||||
const char *flags;
|
||||
-
|
||||
+ int vcpus;
|
||||
|
||||
if ((root == NULL) || (info == NULL))
|
||||
return (-1);
|
||||
@@ -2464,7 +2467,11 @@ sexpr_to_xend_domain_info(virDomainPtr domain, const struct sexpr *root,
|
||||
info->state = VIR_DOMAIN_NOSTATE;
|
||||
}
|
||||
info->cpuTime = sexpr_float(root, "domain/cpu_time") * 1000000000;
|
||||
- info->nrVirtCpu = sexpr_int(root, "domain/vcpus");
|
||||
+ vcpus = sexpr_int(root, "domain/vcpus");
|
||||
+ info->nrVirtCpu = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
|
||||
+ if (!info->nrVirtCpu || vcpus < info->nrVirtCpu)
|
||||
+ info->nrVirtCpu = vcpus;
|
||||
+
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -5668,6 +5675,9 @@ xenDaemonFormatSxpr(virConnectPtr conn,
|
||||
virBufferAsprintf(&buf, "(memory %lu)(maxmem %lu)",
|
||||
def->mem.cur_balloon/1024, def->mem.max_balloon/1024);
|
||||
virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
|
||||
+ /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is 32. */
|
||||
+ if (def->vcpus < def->maxvcpus)
|
||||
+ virBufferAsprintf(&buf, "(vcpu_avail %u)", (1U << def->vcpus) - 1);
|
||||
|
||||
if (def->cpumask) {
|
||||
char *ranges = virDomainCpuSetFormat(def->cpumask, def->cpumasklen);
|
||||
@@ -5763,6 +5773,9 @@ xenDaemonFormatSxpr(virConnectPtr conn,
|
||||
virBufferAsprintf(&buf, "(kernel '%s')", def->os.loader);
|
||||
|
||||
virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
|
||||
+ if (def->vcpus < def->maxvcpus)
|
||||
+ virBufferAsprintf(&buf, "(vcpu_avail %u)",
|
||||
+ (1U << def->vcpus) - 1);
|
||||
|
||||
for (i = 0 ; i < def->os.nBootDevs ; i++) {
|
||||
switch (def->os.bootDevs[i]) {
|
||||
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
|
||||
index bf20a64..f7121ab 100644
|
||||
--- a/src/xen/xm_internal.c
|
||||
+++ b/src/xen/xm_internal.c
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "logging.h"
|
||||
+#include "count-one-bits.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_XENXM
|
||||
|
||||
@@ -772,10 +773,12 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
|
||||
def->mem.max_balloon *= 1024;
|
||||
|
||||
if (xenXMConfigGetULong(conf, "vcpus", &count, 1) < 0 ||
|
||||
- (unsigned short) count != count)
|
||||
+ MAX_VIRT_CPUS < count)
|
||||
goto cleanup;
|
||||
def->maxvcpus = count;
|
||||
- def->vcpus = def->maxvcpus;
|
||||
+ if (xenXMConfigGetULong(conf, "vcpu_avail", &count, -1) < 0)
|
||||
+ goto cleanup;
|
||||
+ def->vcpus = MIN(count_one_bits(count), def->maxvcpus);
|
||||
|
||||
if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
|
||||
goto cleanup;
|
||||
@@ -2246,6 +2249,9 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
|
||||
|
||||
if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
|
||||
goto no_memory;
|
||||
+ if (def->vcpus < def->maxvcpus &&
|
||||
+ xenXMConfigSetInt(conf, "vcpu_avail", (1U << def->vcpus) - 1) < 0)
|
||||
+ goto no_memory;
|
||||
|
||||
if ((def->cpumask != NULL) &&
|
||||
((cpus = virDomainCpuSetFormat(def->cpumask,
|
||||
diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr
|
||||
new file mode 100644
|
||||
index 0000000..2be6822
|
||||
--- /dev/null
|
||||
+++ b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr
|
||||
@@ -0,0 +1 @@
|
||||
+(domain (domid 6)(name 'pvtest')(memory 420)(maxmem 420)(vcpus 4)(vcpu_avail 3)(uuid '596a5d2171f48fb2e068e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os ')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w'))))
|
||||
diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml
|
||||
new file mode 100644
|
||||
index 0000000..0d6bf11
|
||||
--- /dev/null
|
||||
+++ b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml
|
||||
@@ -0,0 +1,27 @@
|
||||
+<domain type='xen' id='6'>
|
||||
+ <name>pvtest</name>
|
||||
+ <uuid>596a5d21-71f4-8fb2-e068-e2386a5c413e</uuid>
|
||||
+ <memory>430080</memory>
|
||||
+ <currentMemory>430080</currentMemory>
|
||||
+ <vcpu current='2'>4</vcpu>
|
||||
+ <os>
|
||||
+ <type>linux</type>
|
||||
+ <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel>
|
||||
+ <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd>
|
||||
+ <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os </cmdline>
|
||||
+ </os>
|
||||
+ <clock offset='utc'/>
|
||||
+ <on_poweroff>destroy</on_poweroff>
|
||||
+ <on_reboot>destroy</on_reboot>
|
||||
+ <on_crash>destroy</on_crash>
|
||||
+ <devices>
|
||||
+ <disk type='file' device='disk'>
|
||||
+ <driver name='file'/>
|
||||
+ <source file='/root/some.img'/>
|
||||
+ <target dev='xvda' bus='xen'/>
|
||||
+ </disk>
|
||||
+ <console type='pty'>
|
||||
+ <target type='xen' port='0'/>
|
||||
+ </console>
|
||||
+ </devices>
|
||||
+</domain>
|
||||
diff --git a/tests/sexpr2xmltest.c b/tests/sexpr2xmltest.c
|
||||
index d62b44f..f100dd8 100644
|
||||
--- a/tests/sexpr2xmltest.c
|
||||
+++ b/tests/sexpr2xmltest.c
|
||||
@@ -132,6 +132,7 @@ mymain(int argc, char **argv)
|
||||
DO_TEST("pv-vfb-type-crash", "pv-vfb-type-crash", 3);
|
||||
DO_TEST("fv-autoport", "fv-autoport", 3);
|
||||
DO_TEST("pv-bootloader", "pv-bootloader", 1);
|
||||
+ DO_TEST("pv-vcpus", "pv-vcpus", 1);
|
||||
|
||||
DO_TEST("disk-file", "disk-file", 2);
|
||||
DO_TEST("disk-block", "disk-block", 2);
|
||||
diff --git a/tests/xmconfigdata/test-paravirt-vcpu.cfg b/tests/xmconfigdata/test-paravirt-vcpu.cfg
|
||||
new file mode 100644
|
||||
index 0000000..24c78f4
|
||||
--- /dev/null
|
||||
+++ b/tests/xmconfigdata/test-paravirt-vcpu.cfg
|
||||
@@ -0,0 +1,17 @@
|
||||
+name = "XenGuest1"
|
||||
+uuid = "c7a5fdb0-cdaf-9455-926a-d65c16db1809"
|
||||
+maxmem = 579
|
||||
+memory = 394
|
||||
+vcpus = 4
|
||||
+vcpu_avail = 3
|
||||
+bootloader = "/usr/bin/pygrub"
|
||||
+on_poweroff = "destroy"
|
||||
+on_reboot = "restart"
|
||||
+on_crash = "restart"
|
||||
+sdl = 0
|
||||
+vnc = 1
|
||||
+vncunused = 1
|
||||
+vnclisten = "127.0.0.1"
|
||||
+vncpasswd = "123poi"
|
||||
+disk = [ "phy:/dev/HostVG/XenGuest1,xvda,w" ]
|
||||
+vif = [ "mac=00:16:3e:66:94:9c,bridge=br0,script=vif-bridge" ]
|
||||
diff --git a/tests/xmconfigdata/test-paravirt-vcpu.xml b/tests/xmconfigdata/test-paravirt-vcpu.xml
|
||||
new file mode 100644
|
||||
index 0000000..0be9456
|
||||
--- /dev/null
|
||||
+++ b/tests/xmconfigdata/test-paravirt-vcpu.xml
|
||||
@@ -0,0 +1,32 @@
|
||||
+<domain type='xen'>
|
||||
+ <name>XenGuest1</name>
|
||||
+ <uuid>c7a5fdb0-cdaf-9455-926a-d65c16db1809</uuid>
|
||||
+ <memory>592896</memory>
|
||||
+ <currentMemory>403456</currentMemory>
|
||||
+ <vcpu current='2'>4</vcpu>
|
||||
+ <bootloader>/usr/bin/pygrub</bootloader>
|
||||
+ <os>
|
||||
+ <type arch='i686' machine='xenpv'>linux</type>
|
||||
+ </os>
|
||||
+ <clock offset='utc'/>
|
||||
+ <on_poweroff>destroy</on_poweroff>
|
||||
+ <on_reboot>restart</on_reboot>
|
||||
+ <on_crash>restart</on_crash>
|
||||
+ <devices>
|
||||
+ <disk type='block' device='disk'>
|
||||
+ <driver name='phy'/>
|
||||
+ <source dev='/dev/HostVG/XenGuest1'/>
|
||||
+ <target dev='xvda' bus='xen'/>
|
||||
+ </disk>
|
||||
+ <interface type='bridge'>
|
||||
+ <mac address='00:16:3e:66:94:9c'/>
|
||||
+ <source bridge='br0'/>
|
||||
+ <script path='vif-bridge'/>
|
||||
+ </interface>
|
||||
+ <console type='pty'>
|
||||
+ <target type='xen' port='0'/>
|
||||
+ </console>
|
||||
+ <input type='mouse' bus='xen'/>
|
||||
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
|
||||
+ </devices>
|
||||
+</domain>
|
||||
diff --git a/tests/xmconfigtest.c b/tests/xmconfigtest.c
|
||||
index 221b322..ea00747 100644
|
||||
--- a/tests/xmconfigtest.c
|
||||
+++ b/tests/xmconfigtest.c
|
||||
@@ -210,6 +210,7 @@ mymain(int argc, char **argv)
|
||||
DO_TEST("paravirt-new-pvfb-vncdisplay", 3);
|
||||
DO_TEST("paravirt-net-e1000", 3);
|
||||
DO_TEST("paravirt-net-vifname", 3);
|
||||
+ DO_TEST("paravirt-vcpu", 2);
|
||||
DO_TEST("fullvirt-old-cdrom", 1);
|
||||
DO_TEST("fullvirt-new-cdrom", 2);
|
||||
DO_TEST("fullvirt-utc", 2);
|
||||
diff --git a/tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr
|
||||
new file mode 100644
|
||||
index 0000000..e886545
|
||||
--- /dev/null
|
||||
+++ b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr
|
||||
@@ -0,0 +1 @@
|
||||
+(vm (name 'pvtest')(memory 420)(maxmem 420)(vcpus 4)(vcpu_avail 3)(uuid '596a5d21-71f4-8fb2-e068-e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os ')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w'))))
|
||||
\ No newline at end of file
|
||||
diff --git a/tests/xml2sexprtest.c b/tests/xml2sexprtest.c
|
||||
index 77cf760..9cf8d39 100644
|
||||
--- a/tests/xml2sexprtest.c
|
||||
+++ b/tests/xml2sexprtest.c
|
||||
@@ -118,6 +118,7 @@ mymain(int argc, char **argv)
|
||||
DO_TEST("pv-vfb-new", "pv-vfb-new", "pvtest", 3);
|
||||
DO_TEST("pv-vfb-new-auto", "pv-vfb-new-auto", "pvtest", 3);
|
||||
DO_TEST("pv-bootloader", "pv-bootloader", "pvtest", 1);
|
||||
+ DO_TEST("pv-vcpus", "pv-vcpus", "pvtest", 1);
|
||||
|
||||
DO_TEST("disk-file", "disk-file", "pvtest", 2);
|
||||
DO_TEST("disk-block", "disk-block", "pvtest", 2);
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,216 +0,0 @@
|
||||
From 290ea33111be7bdf1f1381b90de33eb0e67c1a15 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Wed, 6 Oct 2010 17:54:41 -0600
|
||||
Subject: [PATCH 13/15] vcpu: improve support for getting xen vcpu counts
|
||||
|
||||
* src/xen/xen_driver.c (xenUnifiedDomainGetVcpusFlags): Support
|
||||
more flags.
|
||||
* src/xen/xend_internal.h (xenDaemonDomainGetVcpusFlags): New
|
||||
prototype.
|
||||
* src/xen/xm_internal.h (xenXMDomainGetVcpusFlags): Likewise.
|
||||
* src/xen/xend_internal.c (virDomainGetVcpusFlags): New function.
|
||||
* src/xen/xm_internal.c (xenXMDomainGetVcpusFlags): Likewise.
|
||||
---
|
||||
src/xen/xen_driver.c | 31 +++++++++++++++++++--------
|
||||
src/xen/xend_internal.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
src/xen/xend_internal.h | 2 +
|
||||
src/xen/xm_internal.c | 47 ++++++++++++++++++++++++++++++++++++++++++
|
||||
src/xen/xm_internal.h | 1 +
|
||||
5 files changed, 124 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
|
||||
index d6c9c57..fe2ff86 100644
|
||||
--- a/src/xen/xen_driver.c
|
||||
+++ b/src/xen/xen_driver.c
|
||||
@@ -1142,20 +1142,33 @@ static int
|
||||
xenUnifiedDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
|
||||
{
|
||||
GET_PRIVATE(dom->conn);
|
||||
- int i, ret;
|
||||
+ int ret;
|
||||
|
||||
- if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
- xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
|
||||
- flags);
|
||||
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_CONFIG |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
|
||||
+
|
||||
+ /* Exactly one of LIVE or CONFIG must be set. */
|
||||
+ if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
|
||||
+ xenUnifiedError(VIR_ERR_INVALID_ARG,
|
||||
+ _("invalid flag combination: (0x%x)"), flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
- for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
|
||||
- if (priv->opened[i] && drivers[i]->domainGetMaxVcpus) {
|
||||
- ret = drivers[i]->domainGetMaxVcpus (dom);
|
||||
- if (ret != 0) return ret;
|
||||
- }
|
||||
+ if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
|
||||
+ ret = xenDaemonDomainGetVcpusFlags(dom, flags);
|
||||
+ if (ret != -2)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
|
||||
+ ret = xenXMDomainGetVcpusFlags(dom, flags);
|
||||
+ if (ret != -2)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (flags == (VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM))
|
||||
+ return xenHypervisorGetVcpuMax(dom);
|
||||
|
||||
+ xenUnifiedError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
|
||||
index dfc6415..3642296 100644
|
||||
--- a/src/xen/xend_internal.c
|
||||
+++ b/src/xen/xend_internal.c
|
||||
@@ -3620,6 +3620,58 @@ xenDaemonDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
|
||||
}
|
||||
|
||||
/**
|
||||
+ * xenDaemonDomainGetVcpusFlags:
|
||||
+ * @domain: pointer to domain object
|
||||
+ * @flags: bitwise-ORd from virDomainVcpuFlags
|
||||
+ *
|
||||
+ * Extract information about virtual CPUs of domain according to flags.
|
||||
+ *
|
||||
+ * Returns the number of vcpus on success, -1 if an error message was
|
||||
+ * issued, and -2 if the unified driver should keep trying.
|
||||
+
|
||||
+ */
|
||||
+int
|
||||
+xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
|
||||
+{
|
||||
+ struct sexpr *root;
|
||||
+ int ret;
|
||||
+ xenUnifiedPrivatePtr priv;
|
||||
+
|
||||
+ if (domain == NULL || domain->conn == NULL || domain->name == NULL) {
|
||||
+ virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
|
||||
+
|
||||
+ /* If xendConfigVersion is 2, then we can only report _LIVE (and
|
||||
+ * xm_internal reports _CONFIG). If it is 3, then _LIVE and
|
||||
+ * _CONFIG are always in sync for a running system. */
|
||||
+ if (domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4)
|
||||
+ return -2;
|
||||
+ if (domain->id < 0 && (flags & VIR_DOMAIN_VCPU_LIVE)) {
|
||||
+ virXendError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("domain not active"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
|
||||
+ if (root == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ ret = sexpr_int(root, "domain/vcpus");
|
||||
+ if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM)) {
|
||||
+ int vcpus = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
|
||||
+ if (vcpus)
|
||||
+ ret = MIN(vcpus, ret);
|
||||
+ }
|
||||
+ if (!ret)
|
||||
+ ret = -2;
|
||||
+ sexpr_free(root);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* virDomainGetVcpus:
|
||||
* @domain: pointer to domain object, or NULL for Domain0
|
||||
* @info: pointer to an array of virVcpuInfo structures (OUT)
|
||||
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
|
||||
index c757716..923cebd 100644
|
||||
--- a/src/xen/xend_internal.h
|
||||
+++ b/src/xen/xend_internal.h
|
||||
@@ -155,6 +155,8 @@ int xenDaemonDomainPinVcpu (virDomainPtr domain,
|
||||
unsigned int vcpu,
|
||||
unsigned char *cpumap,
|
||||
int maplen);
|
||||
+int xenDaemonDomainGetVcpusFlags (virDomainPtr domain,
|
||||
+ unsigned int flags);
|
||||
int xenDaemonDomainGetVcpus (virDomainPtr domain,
|
||||
virVcpuInfoPtr info,
|
||||
int maxinfo,
|
||||
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
|
||||
index f7121ab..4ea4245 100644
|
||||
--- a/src/xen/xm_internal.c
|
||||
+++ b/src/xen/xm_internal.c
|
||||
@@ -1671,6 +1671,53 @@ cleanup:
|
||||
}
|
||||
|
||||
/**
|
||||
+ * xenXMDomainGetVcpusFlags:
|
||||
+ * @domain: pointer to domain object
|
||||
+ * @flags: bitwise-ORd from virDomainVcpuFlags
|
||||
+ *
|
||||
+ * Extract information about virtual CPUs of domain according to flags.
|
||||
+ *
|
||||
+ * Returns the number of vcpus on success, -1 if an error message was
|
||||
+ * issued, and -2 if the unified driver should keep trying.
|
||||
+ */
|
||||
+int
|
||||
+xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
|
||||
+{
|
||||
+ xenUnifiedPrivatePtr priv;
|
||||
+ const char *filename;
|
||||
+ xenXMConfCachePtr entry;
|
||||
+ int ret = -2;
|
||||
+
|
||||
+ if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
|
||||
+ xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (domain->id != -1)
|
||||
+ return -2;
|
||||
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ xenXMError(VIR_ERR_OPERATION_FAILED, "%s", _("domain not active"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ priv = domain->conn->privateData;
|
||||
+ xenUnifiedLock(priv);
|
||||
+
|
||||
+ if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ if (!(entry = virHashLookup(priv->configCache, filename)))
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ ret = ((flags & VIR_DOMAIN_VCPU_MAXIMUM) ? entry->def->maxvcpus
|
||||
+ : entry->def->vcpus);
|
||||
+
|
||||
+cleanup:
|
||||
+ xenUnifiedUnlock(priv);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* xenXMDomainPinVcpu:
|
||||
* @domain: pointer to domain object
|
||||
* @vcpu: virtual CPU number (reserved)
|
||||
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
|
||||
index 3ad3456..3295fbd 100644
|
||||
--- a/src/xen/xm_internal.h
|
||||
+++ b/src/xen/xm_internal.h
|
||||
@@ -45,6 +45,7 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory);
|
||||
int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
|
||||
unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain);
|
||||
int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus);
|
||||
+int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags);
|
||||
int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
|
||||
unsigned char *cpumap, int maplen);
|
||||
virDomainPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname);
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,342 +0,0 @@
|
||||
From e443a003129a172a7332f3cb6e40b3c39363ed5e Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Thu, 14 Oct 2010 16:17:18 -0600
|
||||
Subject: [PATCH 14/15] vcpu: improve support for setting xen vcpu counts
|
||||
|
||||
Tested with RHEL 5.6 (xendConfigVersion 2, where xend_internal
|
||||
controls live domains and xm_internal controls inactive domains).
|
||||
Hopefully this works with xendConfigVersion 3 (where xend_internal
|
||||
controls everything).
|
||||
|
||||
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpusFlags): Support
|
||||
more flags.
|
||||
(xenUnifiedGetMaxVcpus): Export.
|
||||
* src/xen/xm_internal.h (xenXMDomainSetVcpusFlags): New prototype.
|
||||
* src/xen/xend_internal.h (xenDaemonDomainSetVcpusFlags): Likewise.
|
||||
* src/xen/xen_driver.h (xenUnifiedGetMaxVcpus): Likewise.
|
||||
* src/xen/xm_internal.c (xenXMDomainSetVcpusFlags): New function.
|
||||
* src/xen/xend_internal.c (xenDaemonDomainSetVcpusFlags): Likewise.
|
||||
---
|
||||
src/xen/xen_driver.c | 60 ++++++++++++++++++++++++---------
|
||||
src/xen/xen_driver.h | 1 +
|
||||
src/xen/xend_internal.c | 76 +++++++++++++++++++++++++++++++++++++++++++
|
||||
src/xen/xend_internal.h | 3 ++
|
||||
src/xen/xm_internal.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
src/xen/xm_internal.h | 2 +
|
||||
6 files changed, 208 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
|
||||
index fe2ff86..66e8518 100644
|
||||
--- a/src/xen/xen_driver.c
|
||||
+++ b/src/xen/xen_driver.c
|
||||
@@ -508,7 +508,7 @@ xenUnifiedIsSecure(virConnectPtr conn)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int
|
||||
+int
|
||||
xenUnifiedGetMaxVcpus (virConnectPtr conn, const char *type)
|
||||
{
|
||||
GET_PRIVATE(conn);
|
||||
@@ -1073,36 +1073,62 @@ xenUnifiedDomainSetVcpusFlags (virDomainPtr dom, unsigned int nvcpus,
|
||||
unsigned int flags)
|
||||
{
|
||||
GET_PRIVATE(dom->conn);
|
||||
- int i;
|
||||
+ int ret;
|
||||
+
|
||||
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
|
||||
+ VIR_DOMAIN_VCPU_CONFIG |
|
||||
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
|
||||
|
||||
- if (flags != VIR_DOMAIN_VCPU_LIVE) {
|
||||
- xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
|
||||
- flags);
|
||||
+ /* At least one of LIVE or CONFIG must be set. MAXIMUM cannot be
|
||||
+ * mixed with LIVE. */
|
||||
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
|
||||
+ (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
|
||||
+ (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
|
||||
+ xenUnifiedError(VIR_ERR_INVALID_ARG,
|
||||
+ _("invalid flag combination: (0x%x)"), flags);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (!nvcpus || (unsigned short) nvcpus != nvcpus) {
|
||||
+ xenUnifiedError(VIR_ERR_INVALID_ARG,
|
||||
+ _("argument out of range: %d"), nvcpus);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try non-hypervisor methods first, then hypervisor direct method
|
||||
* as a last resort.
|
||||
*/
|
||||
- for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
|
||||
- if (i != XEN_UNIFIED_HYPERVISOR_OFFSET &&
|
||||
- priv->opened[i] &&
|
||||
- drivers[i]->domainSetVcpus &&
|
||||
- drivers[i]->domainSetVcpus (dom, nvcpus) == 0)
|
||||
- return 0;
|
||||
-
|
||||
- if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET] &&
|
||||
- drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainSetVcpus &&
|
||||
- drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainSetVcpus (dom, nvcpus) == 0)
|
||||
- return 0;
|
||||
+ if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
|
||||
+ ret = xenDaemonDomainSetVcpusFlags(dom, nvcpus, flags);
|
||||
+ if (ret != -2)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
|
||||
+ ret = xenXMDomainSetVcpusFlags(dom, nvcpus, flags);
|
||||
+ if (ret != -2)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (flags == VIR_DOMAIN_VCPU_LIVE)
|
||||
+ return xenHypervisorSetVcpus(dom, nvcpus);
|
||||
|
||||
+ xenUnifiedError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
|
||||
{
|
||||
- return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
|
||||
+ unsigned int flags = VIR_DOMAIN_VCPU_LIVE;
|
||||
+ xenUnifiedPrivatePtr priv;
|
||||
+
|
||||
+ /* Per the documented API, it is hypervisor-dependent whether this
|
||||
+ * affects just _LIVE or _LIVE|_CONFIG; in xen's case, that
|
||||
+ * depends on xendConfigVersion. */
|
||||
+ if (dom) {
|
||||
+ priv = dom->conn->privateData;
|
||||
+ if (priv->xendConfigVersion >= XEND_CONFIG_VERSION_3_0_4)
|
||||
+ flags |= VIR_DOMAIN_VCPU_CONFIG;
|
||||
+ }
|
||||
+ return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
|
||||
index 3e7c1d0..115a26a 100644
|
||||
--- a/src/xen/xen_driver.h
|
||||
+++ b/src/xen/xen_driver.h
|
||||
@@ -220,6 +220,7 @@ int xenUnifiedRemoveDomainInfo(xenUnifiedDomainInfoListPtr info,
|
||||
void xenUnifiedDomainEventDispatch (xenUnifiedPrivatePtr priv,
|
||||
virDomainEventPtr event);
|
||||
unsigned long xenUnifiedVersion(void);
|
||||
+int xenUnifiedGetMaxVcpus(virConnectPtr conn, const char *type);
|
||||
|
||||
# ifndef PROXY
|
||||
void xenUnifiedLock(xenUnifiedPrivatePtr priv);
|
||||
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
|
||||
index 3642296..55c2cc4 100644
|
||||
--- a/src/xen/xend_internal.c
|
||||
+++ b/src/xen/xend_internal.c
|
||||
@@ -3535,6 +3535,82 @@ xenDaemonLookupByID(virConnectPtr conn, int id) {
|
||||
}
|
||||
|
||||
/**
|
||||
+ * xenDaemonDomainSetVcpusFlags:
|
||||
+ * @domain: pointer to domain object
|
||||
+ * @nvcpus: the new number of virtual CPUs for this domain
|
||||
+ * @flags: bitwise-ORd from virDomainVcpuFlags
|
||||
+ *
|
||||
+ * Change virtual CPUs allocation of domain according to flags.
|
||||
+ *
|
||||
+ * Returns 0 on success, -1 if an error message was issued, and -2 if
|
||||
+ * the unified driver should keep trying.
|
||||
+ */
|
||||
+int
|
||||
+xenDaemonDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
+ char buf[VIR_UUID_BUFLEN];
|
||||
+ xenUnifiedPrivatePtr priv;
|
||||
+ int max;
|
||||
+
|
||||
+ if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
|
||||
+ || (vcpus < 1)) {
|
||||
+ virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
|
||||
+
|
||||
+ if ((domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) ||
|
||||
+ (flags & VIR_DOMAIN_VCPU_MAXIMUM))
|
||||
+ return -2;
|
||||
+
|
||||
+ /* With xendConfigVersion 2, only _LIVE is supported. With
|
||||
+ * xendConfigVersion 3, only _LIVE|_CONFIG is supported for
|
||||
+ * running domains, or _CONFIG for inactive domains. */
|
||||
+ if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) {
|
||||
+ if (flags & VIR_DOMAIN_VCPU_CONFIG) {
|
||||
+ virXendError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("Xend version does not support modifying "
|
||||
+ "persistent config"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+ } else if (domain->id < 0) {
|
||||
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ virXendError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("domain not running"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) !=
|
||||
+ (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) {
|
||||
+ virXendError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("Xend only supports modifying both live and "
|
||||
+ "persistent config"));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Unfortunately, xend_op does not validate whether this exceeds
|
||||
+ * the maximum. */
|
||||
+ flags |= VIR_DOMAIN_VCPU_MAXIMUM;
|
||||
+ if ((max = xenDaemonDomainGetVcpusFlags(domain, flags)) < 0) {
|
||||
+ virXendError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("could not determin max vcpus for the domain"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (vcpus > max) {
|
||||
+ virXendError(VIR_ERR_INVALID_ARG,
|
||||
+ _("requested vcpus is greater than max allowable"
|
||||
+ " vcpus for the domain: %d > %d"), vcpus, max);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "%d", vcpus);
|
||||
+ return xend_op(domain->conn, domain->name, "op", "set_vcpus", "vcpus",
|
||||
+ buf, NULL);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* xenDaemonDomainSetVcpus:
|
||||
* @domain: pointer to domain object
|
||||
* @nvcpus: the new number of virtual CPUs for this domain
|
||||
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
|
||||
index 923cebd..53f5d2c 100644
|
||||
--- a/src/xen/xend_internal.h
|
||||
+++ b/src/xen/xend_internal.h
|
||||
@@ -151,6 +151,9 @@ int xenDaemonDomainUndefine(virDomainPtr domain);
|
||||
|
||||
int xenDaemonDomainSetVcpus (virDomainPtr domain,
|
||||
unsigned int vcpus);
|
||||
+int xenDaemonDomainSetVcpusFlags (virDomainPtr domain,
|
||||
+ unsigned int vcpus,
|
||||
+ unsigned int flags);
|
||||
int xenDaemonDomainPinVcpu (virDomainPtr domain,
|
||||
unsigned int vcpu,
|
||||
unsigned char *cpumap,
|
||||
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
|
||||
index 4ea4245..2b8e51e 100644
|
||||
--- a/src/xen/xm_internal.c
|
||||
+++ b/src/xen/xm_internal.c
|
||||
@@ -1670,6 +1670,89 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * xenXMDomainSetVcpusFlags:
|
||||
+ * @domain: pointer to domain object
|
||||
+ * @nvcpus: number of vcpus
|
||||
+ * @flags: bitwise-ORd from virDomainVcpuFlags
|
||||
+ *
|
||||
+ * Change virtual CPUs allocation of domain according to flags.
|
||||
+ *
|
||||
+ * Returns 0 on success, -1 if an error message was issued, and -2 if
|
||||
+ * the unified driver should keep trying.
|
||||
+ */
|
||||
+int
|
||||
+xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
+ xenUnifiedPrivatePtr priv;
|
||||
+ const char *filename;
|
||||
+ xenXMConfCachePtr entry;
|
||||
+ int ret = -1;
|
||||
+ int max;
|
||||
+
|
||||
+ if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
|
||||
+ xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (domain->conn->flags & VIR_CONNECT_RO) {
|
||||
+ xenXMError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (domain->id != -1)
|
||||
+ return -2;
|
||||
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
|
||||
+ xenXMError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("domain is not running"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ priv = domain->conn->privateData;
|
||||
+ xenUnifiedLock(priv);
|
||||
+
|
||||
+ if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ if (!(entry = virHashLookup(priv->configCache, filename)))
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* Hypervisor maximum. */
|
||||
+ if ((max = xenUnifiedGetMaxVcpus(domain->conn, NULL)) < 0) {
|
||||
+ xenXMError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
+ _("could not determin max vcpus for the domain"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ /* Can't specify a current larger than stored maximum; but
|
||||
+ * reducing maximum can silently reduce current. */
|
||||
+ if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM))
|
||||
+ max = entry->def->maxvcpus;
|
||||
+ if (vcpus > max) {
|
||||
+ xenXMError(VIR_ERR_INVALID_ARG,
|
||||
+ _("requested vcpus is greater than max allowable"
|
||||
+ " vcpus for the domain: %d > %d"), vcpus, max);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if (flags & VIR_DOMAIN_VCPU_MAXIMUM) {
|
||||
+ entry->def->maxvcpus = vcpus;
|
||||
+ if (entry->def->vcpus > vcpus)
|
||||
+ entry->def->vcpus = vcpus;
|
||||
+ } else {
|
||||
+ entry->def->vcpus = vcpus;
|
||||
+ }
|
||||
+
|
||||
+ /* If this fails, should we try to undo our changes to the
|
||||
+ * in-memory representation of the config file. I say not!
|
||||
+ */
|
||||
+ if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
|
||||
+ goto cleanup;
|
||||
+ ret = 0;
|
||||
+
|
||||
+cleanup:
|
||||
+ xenUnifiedUnlock(priv);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* xenXMDomainGetVcpusFlags:
|
||||
* @domain: pointer to domain object
|
||||
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
|
||||
index 3295fbd..a46e1a2 100644
|
||||
--- a/src/xen/xm_internal.h
|
||||
+++ b/src/xen/xm_internal.h
|
||||
@@ -45,6 +45,8 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory);
|
||||
int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
|
||||
unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain);
|
||||
int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus);
|
||||
+int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
|
||||
+ unsigned int flags);
|
||||
int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags);
|
||||
int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
|
||||
unsigned char *cpumap, int maplen);
|
||||
--
|
||||
1.7.2.3
|
||||
|
@ -1,228 +0,0 @@
|
||||
From b013788742183afec9aa5068d3cfd185a3b5c62e Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Thu, 7 Oct 2010 08:59:27 -0600
|
||||
Subject: [PATCH 15/15] vcpu: remove dead xen code
|
||||
|
||||
* src/xen/xen_driver.h (xenUnifiedDriver): Remove now-unused
|
||||
domainGetMaxVcpus, domainSetVcpus.
|
||||
* src/xen/proxy_internal.c (xenProxyDriver): Likewise.
|
||||
* src/xen/xen_hypervisor.c (xenHypervisorDriver): Likewise.
|
||||
* src/xen/xen_inotify.c (xenInotifyDriver): Likewise.
|
||||
* src/xen/xend_internal.c (xenDaemonDriver)
|
||||
(xenDaemonDomainSetVcpus): Likewise.
|
||||
* src/xen/xm_internal.c (xenXMDriver, xenXMDomainSetVcpus):
|
||||
Likewise.
|
||||
* src/xen/xs_internal.c (xenStoreDriver): Likewise.
|
||||
---
|
||||
src/xen/proxy_internal.c | 2 --
|
||||
src/xen/xen_driver.h | 4 +---
|
||||
src/xen/xen_hypervisor.c | 2 --
|
||||
src/xen/xen_inotify.c | 2 --
|
||||
src/xen/xend_internal.c | 33 ---------------------------------
|
||||
src/xen/xm_internal.c | 43 -------------------------------------------
|
||||
src/xen/xs_internal.c | 2 --
|
||||
7 files changed, 1 insertions(+), 87 deletions(-)
|
||||
|
||||
diff --git a/src/xen/proxy_internal.c b/src/xen/proxy_internal.c
|
||||
index 335dfc4..4033727 100644
|
||||
--- a/src/xen/proxy_internal.c
|
||||
+++ b/src/xen/proxy_internal.c
|
||||
@@ -67,10 +67,8 @@ struct xenUnifiedDriver xenProxyDriver = {
|
||||
NULL, /* domainSave */
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
- NULL, /* domainSetVcpus */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
- NULL, /* domainGetMaxVcpus */
|
||||
NULL, /* listDefinedDomains */
|
||||
NULL, /* numOfDefinedDomains */
|
||||
NULL, /* domainCreate */
|
||||
diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
|
||||
index 115a26a..53f97d4 100644
|
||||
--- a/src/xen/xen_driver.h
|
||||
+++ b/src/xen/xen_driver.h
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* xen_unified.c: Unified Xen driver.
|
||||
*
|
||||
- * Copyright (C) 2007 Red Hat, Inc.
|
||||
+ * Copyright (C) 2007, 2010 Red Hat, Inc.
|
||||
*
|
||||
* See COPYING.LIB for the License of this software
|
||||
*
|
||||
@@ -84,10 +84,8 @@ struct xenUnifiedDriver {
|
||||
virDrvDomainSave domainSave;
|
||||
virDrvDomainRestore domainRestore;
|
||||
virDrvDomainCoreDump domainCoreDump;
|
||||
- virDrvDomainSetVcpus domainSetVcpus;
|
||||
virDrvDomainPinVcpu domainPinVcpu;
|
||||
virDrvDomainGetVcpus domainGetVcpus;
|
||||
- virDrvDomainGetMaxVcpus domainGetMaxVcpus;
|
||||
virDrvListDefinedDomains listDefinedDomains;
|
||||
virDrvNumOfDefinedDomains numOfDefinedDomains;
|
||||
virDrvDomainCreate domainCreate;
|
||||
diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c
|
||||
index 6246513..3797865 100644
|
||||
--- a/src/xen/xen_hypervisor.c
|
||||
+++ b/src/xen/xen_hypervisor.c
|
||||
@@ -784,10 +784,8 @@ struct xenUnifiedDriver xenHypervisorDriver = {
|
||||
NULL, /* domainSave */
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
- xenHypervisorSetVcpus, /* domainSetVcpus */
|
||||
xenHypervisorPinVcpu, /* domainPinVcpu */
|
||||
xenHypervisorGetVcpus, /* domainGetVcpus */
|
||||
- xenHypervisorGetVcpuMax, /* domainGetMaxVcpus */
|
||||
NULL, /* listDefinedDomains */
|
||||
NULL, /* numOfDefinedDomains */
|
||||
NULL, /* domainCreate */
|
||||
diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c
|
||||
index d24b20f..9507061 100644
|
||||
--- a/src/xen/xen_inotify.c
|
||||
+++ b/src/xen/xen_inotify.c
|
||||
@@ -71,10 +71,8 @@ struct xenUnifiedDriver xenInotifyDriver = {
|
||||
NULL, /* domainSave */
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
- NULL, /* domainSetVcpus */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
- NULL, /* domainGetMaxVcpus */
|
||||
NULL, /* listDefinedDomains */
|
||||
NULL, /* numOfDefinedDomains */
|
||||
NULL, /* domainCreate */
|
||||
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
|
||||
index 55c2cc4..b90c331 100644
|
||||
--- a/src/xen/xend_internal.c
|
||||
+++ b/src/xen/xend_internal.c
|
||||
@@ -3611,37 +3611,6 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
|
||||
}
|
||||
|
||||
/**
|
||||
- * xenDaemonDomainSetVcpus:
|
||||
- * @domain: pointer to domain object
|
||||
- * @nvcpus: the new number of virtual CPUs for this domain
|
||||
- *
|
||||
- * Dynamically change the number of virtual CPUs used by the domain.
|
||||
- *
|
||||
- * Returns 0 for success; -1 (with errno) on error
|
||||
- */
|
||||
-int
|
||||
-xenDaemonDomainSetVcpus(virDomainPtr domain, unsigned int vcpus)
|
||||
-{
|
||||
- char buf[VIR_UUID_BUFLEN];
|
||||
- xenUnifiedPrivatePtr priv;
|
||||
-
|
||||
- if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
|
||||
- || (vcpus < 1)) {
|
||||
- virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
- return (-1);
|
||||
- }
|
||||
-
|
||||
- priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
|
||||
-
|
||||
- if (domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4)
|
||||
- return(-1);
|
||||
-
|
||||
- snprintf(buf, sizeof(buf), "%d", vcpus);
|
||||
- return(xend_op(domain->conn, domain->name, "op", "set_vcpus", "vcpus",
|
||||
- buf, NULL));
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
* xenDaemonDomainPinCpu:
|
||||
* @domain: pointer to domain object
|
||||
* @vcpu: virtual CPU number
|
||||
@@ -5213,10 +5182,8 @@ struct xenUnifiedDriver xenDaemonDriver = {
|
||||
xenDaemonDomainSave, /* domainSave */
|
||||
xenDaemonDomainRestore, /* domainRestore */
|
||||
xenDaemonDomainCoreDump, /* domainCoreDump */
|
||||
- xenDaemonDomainSetVcpus, /* domainSetVcpus */
|
||||
xenDaemonDomainPinVcpu, /* domainPinVcpu */
|
||||
xenDaemonDomainGetVcpus, /* domainGetVcpus */
|
||||
- NULL, /* domainGetMaxVcpus */
|
||||
xenDaemonListDefinedDomains, /* listDefinedDomains */
|
||||
xenDaemonNumOfDefinedDomains,/* numOfDefinedDomains */
|
||||
xenDaemonDomainCreate, /* domainCreate */
|
||||
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
|
||||
index 2b8e51e..430d40b 100644
|
||||
--- a/src/xen/xm_internal.c
|
||||
+++ b/src/xen/xm_internal.c
|
||||
@@ -103,10 +103,8 @@ struct xenUnifiedDriver xenXMDriver = {
|
||||
NULL, /* domainSave */
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
- xenXMDomainSetVcpus, /* domainSetVcpus */
|
||||
xenXMDomainPinVcpu, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
- NULL, /* domainGetMaxVcpus */
|
||||
xenXMListDefinedDomains, /* listDefinedDomains */
|
||||
xenXMNumOfDefinedDomains, /* numOfDefinedDomains */
|
||||
xenXMDomainCreate, /* domainCreate */
|
||||
@@ -1630,47 +1628,6 @@ cleanup:
|
||||
}
|
||||
|
||||
/*
|
||||
- * Set the VCPU count in config
|
||||
- */
|
||||
-int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus) {
|
||||
- xenUnifiedPrivatePtr priv;
|
||||
- const char *filename;
|
||||
- xenXMConfCachePtr entry;
|
||||
- int ret = -1;
|
||||
-
|
||||
- if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
|
||||
- xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
- return (-1);
|
||||
- }
|
||||
- if (domain->conn->flags & VIR_CONNECT_RO)
|
||||
- return (-1);
|
||||
- if (domain->id != -1)
|
||||
- return (-1);
|
||||
-
|
||||
- priv = domain->conn->privateData;
|
||||
- xenUnifiedLock(priv);
|
||||
-
|
||||
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
||||
- goto cleanup;
|
||||
-
|
||||
- if (!(entry = virHashLookup(priv->configCache, filename)))
|
||||
- goto cleanup;
|
||||
-
|
||||
- entry->def->maxvcpus = entry->def->vcpus = vcpus;
|
||||
-
|
||||
- /* If this fails, should we try to undo our changes to the
|
||||
- * in-memory representation of the config file. I say not!
|
||||
- */
|
||||
- if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
|
||||
- goto cleanup;
|
||||
- ret = 0;
|
||||
-
|
||||
-cleanup:
|
||||
- xenUnifiedUnlock(priv);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
* xenXMDomainSetVcpusFlags:
|
||||
* @domain: pointer to domain object
|
||||
* @nvcpus: number of vcpus
|
||||
diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c
|
||||
index 9296f25..a9817b1 100644
|
||||
--- a/src/xen/xs_internal.c
|
||||
+++ b/src/xen/xs_internal.c
|
||||
@@ -67,10 +67,8 @@ struct xenUnifiedDriver xenStoreDriver = {
|
||||
NULL, /* domainSave */
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainCoreDump */
|
||||
- NULL, /* domainSetVcpus */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
- NULL, /* domainGetMaxVcpus */
|
||||
NULL, /* listDefinedDomains */
|
||||
NULL, /* numOfDefinedDomains */
|
||||
NULL, /* domainCreate */
|
||||
--
|
||||
1.7.2.3
|
||||
|
2516
docs/apibuild.py
2516
docs/apibuild.py
File diff suppressed because it is too large
Load Diff
@ -1,363 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Applications using <strong>libvirt</strong></h1>
|
||||
|
||||
<p>
|
||||
This page provides an illustration of the wide variety of
|
||||
applications using the libvirt management API.
|
||||
</p>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="add">Add an application</a></h2>
|
||||
|
||||
<p>
|
||||
To add an application not listed on this page, send a message
|
||||
to the <a href="contact.html">mailing list</a>, requesting it
|
||||
be added here, or simply send a patch against the documentation
|
||||
in the libvirt.git docs subdirectory.
|
||||
If your application uses libvirt as its API,
|
||||
the following graphic is available for your website to advertise
|
||||
support for libvirt:
|
||||
</p>
|
||||
|
||||
<p class="image">
|
||||
<img src="madeWith.png" alt="Made with libvirt"/>
|
||||
</p>
|
||||
|
||||
<h2><a name="clientserver">Client/Server applications</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://archipelproject.org">Archipel</a></dt>
|
||||
<dd>
|
||||
Archipel is a libvirt-based solution to manage and supervise virtual
|
||||
machines. It uses XMPP for all communication. There is no web
|
||||
service or custom protocol. You just need at least one XMPP server,
|
||||
like eJabberd, to start playing with it. This allows Archipel to
|
||||
work completely real time. You never have to refresh the user
|
||||
interface, you'll be notified as soon as something happens. You can
|
||||
even use your favorite chat clients to command your infrastructure.
|
||||
</dd>
|
||||
<dd>
|
||||
Isn't it great to be able to open a chat conversation with your
|
||||
virtual machine and say things like "How are you today?" or "Hey,
|
||||
please reboot"?
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="command">Command line tools</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://libguestfs.org">guestfish</a></dt>
|
||||
<dd>
|
||||
Guestfish is an interactive shell and command-line tool for examining
|
||||
and modifying virtual machine filesystems. It uses libvirt to find
|
||||
guests and their associated disks.
|
||||
</dd>
|
||||
<dt>virsh</dt>
|
||||
<dd>
|
||||
An interactive shell, and batch scriptable tool for performing
|
||||
management tasks on all libvirt managed domains, networks and
|
||||
storage. This is part of the libvirt core distribution.
|
||||
</dd>
|
||||
<dt><a href="http://virt-manager.org/">virt-clone</a></dt>
|
||||
<dd>
|
||||
Allows the disk image(s) and configuration for an existing
|
||||
virtual machine to be cloned to form a new virtual machine.
|
||||
It automates copying of data across to new disk images, and
|
||||
updates the UUID, MAC address, and name in the configuration.
|
||||
</dd>
|
||||
<dt><a href="http://et.redhat.com/~rjones/virt-df/">virt-df</a></dt>
|
||||
<dd>
|
||||
Examine the utilization of each filesystem in a virtual machine
|
||||
from the comfort of the host machine. This tool peeks into the
|
||||
guest disks and determines how much space is used. It can cope
|
||||
with common Linux filesystems and LVM volumes.
|
||||
</dd>
|
||||
<dt><a href="http://virt-manager.org/">virt-image</a></dt>
|
||||
<dd>
|
||||
Provides a way to deploy virtual appliances. It defines a
|
||||
simplified portable XML format describing the pre-requisites
|
||||
of a virtual machine. At time of deployment this is translated
|
||||
into the domain XML format for execution under any libvirt
|
||||
hypervisor meeting the pre-requisites.
|
||||
</dd>
|
||||
<dt><a href="http://virt-manager.org/">virt-install</a></dt>
|
||||
<dd>
|
||||
Provides a way to provision new virtual machines from a
|
||||
OS distribution install tree. It supports provisioning from
|
||||
local CD images, and the network over NFS, HTTP and FTP.
|
||||
</dd>
|
||||
<dt><a href="http://et.redhat.com/~rjones/virt-top/">virt-top</a></dt>
|
||||
<dd>
|
||||
Watch the CPU, memory, network and disk utilization of all
|
||||
virtual machines running on a host.
|
||||
</dd>
|
||||
<dt>
|
||||
<a href="http://people.redhat.com/~rjones/virt-what/">virt-what</a>
|
||||
</dt>
|
||||
<dd>
|
||||
virt-what is a shell script for detecting if the program is running
|
||||
in a virtual machine. It prints out a list of facts about the
|
||||
virtual machine, derived from heuristics.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="configmgmt">Configuration Management</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="https://wiki.lcfg.org/bin/view/LCFG/LcfgLibvirt">LCFG</a></dt>
|
||||
<dd>
|
||||
LCFG is a system for automatically installing and managing the
|
||||
configuration of large numbers of Unix systems. It is particularly
|
||||
suitable for sites with very diverse and rapidly changing
|
||||
configurations.
|
||||
</dd>
|
||||
<dd>
|
||||
The lcfg-libvirt package adds support for virtualized systems to
|
||||
LCFG, with both Xen and KVM known to work. Cloning guests is
|
||||
supported, as are the bridged, routed, and isolated modes for
|
||||
Virtual Networking.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="continuousintegration">Continuous Integration</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://buildbot.net/buildbot/docs/current/Libvirt.html">BuildBot</a></dt>
|
||||
<dd>
|
||||
BuildBot is a system to automate the compile/test cycle required
|
||||
by most software projects. CVS commits trigger new builds, run on
|
||||
a variety of client machines. Build status (pass/fail/etc) are
|
||||
displayed on a web page or through other protocols.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://wiki.jenkins-ci.org/display/JENKINS/Libvirt+Slaves+Plugin">Jenkins</a></dt>
|
||||
<dd>
|
||||
This plugin for Jenkins adds a way to control guest domains hosted
|
||||
on Xen or QEMU/KVM. You configure a Jenkins Slave,
|
||||
selecting the guest domain and hypervisor. When you need to build a
|
||||
job on a specific Slave, its guest domain is started, then the job is
|
||||
run. When the build process is finished, the guest domain is shut
|
||||
down, ready to be used again as required.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="conversion">Conversion</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="https://rwmj.wordpress.com/2009/10/13/poor-mans-p2v/">Poor mans p2v</a></dt>
|
||||
<dd>
|
||||
A simple approach for converting a physical machine to a virtual
|
||||
machine, using a rescue CD.
|
||||
</dd>
|
||||
<dt><a href="http://et.redhat.com/~rjones/virt-p2v/">virt-p2v</a></dt>
|
||||
<dd>
|
||||
An older tool for converting a physical machine into a virtual
|
||||
machine. It is a LiveCD which is booted on the machine to be
|
||||
converted. It collects a little information from the user, then
|
||||
copies the disks over to a remote machine and defines the XML for a
|
||||
domain to run the guest.
|
||||
</dd>
|
||||
<dt><a href="http://git.fedorahosted.org/git/?p=virt-v2v.git;a=summary">virt-v2v</a></dt>
|
||||
<dd>
|
||||
virt-v2v converts guests from a foreign hypervisor to run on KVM,
|
||||
managed by libvirt. It can currently convert Red Hat Enterprise
|
||||
Linux (RHEL) and Fedora guests running on Xen and VMware ESX. It
|
||||
will enable VirtIO drivers in the converted guest if possible.
|
||||
</dd>
|
||||
<dd>
|
||||
For RHEL customers of Red Hat, conversion of Windows guests is also
|
||||
possible. This conversion requires some Microsoft signed pieces,
|
||||
that Red Hat can provide.
|
||||
</dd>
|
||||
<dt><a href="https://launchpad.net/virt-goodies">vmware2libvirt</a></dt>
|
||||
<dd>
|
||||
Part of the <i>virt-goodies</i> package, vmware2libvirt is a python
|
||||
script for migrating a vmware image to libvirt.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="desktop">Desktop applications</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://virt-manager.org/">virt-manager</a></dt>
|
||||
<dd>
|
||||
A general purpose desktop management tool, able to manage
|
||||
virtual machines across both local and remotely accessed
|
||||
hypervisors. It is targeted at home and small office usage
|
||||
upto managing 10-20 hosts and their VMs.
|
||||
</dd>
|
||||
<dt><a href="http://virt-manager.org/">virt-viewer</a></dt>
|
||||
<dd>
|
||||
A lightweight tool for accessing the graphical console
|
||||
associated with a virtual machine. It can securely connect
|
||||
to remote consoles supporting the VNC protocol. Also provides
|
||||
an optional mozilla browser plugin.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="iaas">Infrastructure as a Service (IaaS)</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://www.emotivecloud.net">EMOTIVE Cloud</a></dt>
|
||||
<dd>The EMOTIVE (Elastic Management Of Tasks In Virtualized
|
||||
Environments) middleware allows executing tasks and providing
|
||||
virtualized environments to the users with Xen, KVM or
|
||||
VirtualBox hypervisor. EMOTIVE's main feature is VM management
|
||||
with different scheduling policies. It can be also used as a
|
||||
cloud provider and is very easy to extend thanks to its
|
||||
modular Web Services architecture.
|
||||
</dd>
|
||||
|
||||
<dt><a href="http://www.nimbusproject.org">Nimbus</a></dt>
|
||||
<dd>
|
||||
Nimbus is an open-source toolkit focused on providing
|
||||
Infrastructure-as-a-Service (IaaS) capabilities to the scientific
|
||||
community. It uses libvirt for communication with all KVM and Xen
|
||||
virtual machines.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="libraries">Libraries</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://libguestfs.org">libguestfs</a></dt>
|
||||
<dd>
|
||||
A library and set of tools for accessing and modifying virtual
|
||||
machine disk images. It can be linked with C and C++ management
|
||||
programs, and has bindings for Perl, Python, Ruby, Java, OCaml,
|
||||
PHP, Haskell, and C#.
|
||||
</dd>
|
||||
<dd>
|
||||
Using its FUSE module, you can also mount guest filesystems on the
|
||||
host, and there is a subproject to allow merging changes into the
|
||||
Windows Registry in Windows guests.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt><a href="https://github.com/ohadlevy/virt#readme">Ruby
|
||||
Libvirt Object bindings</a></dt>
|
||||
<dd>
|
||||
Allows using simple ruby objects to manipulate
|
||||
hypervisors, guests, storage, network etc. It is
|
||||
based on top of
|
||||
the <a href="http://libvirt.org/ruby">native ruby
|
||||
bindings</a>.
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a name="livecd">LiveCD / Appliances</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://et.redhat.com/~rjones/virt-p2v/">virt-p2v</a></dt>
|
||||
<dd>
|
||||
An older tool for converting a physical machine into a virtual
|
||||
machine. It is a LiveCD which is booted on the machine to be
|
||||
converted. It collects a little information from the user, then
|
||||
copies the disks over to a remote machine and defines the XML for a
|
||||
domain to run the guest.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="monitoring">Monitoring</a></h2>
|
||||
<dl>
|
||||
<dt><a href="http://collectd.org/plugins/libvirt.shtml">collectd</a></dt>
|
||||
<dd>
|
||||
The libvirt-plugin is part of <a href="http://collectd.org/">collectd</a>
|
||||
and gathers statistics about virtualized guests on a system. This
|
||||
way, you can collect CPU, network interface and block device usage
|
||||
for each guest without installing collectd on the guest systems.
|
||||
For a full description, please refer to the libvirt section in the
|
||||
collectd.conf(5) manual page.
|
||||
</dd>
|
||||
<dt><a href="http://honk.sigxcpu.org/projects/libvirt/#munin">Munin</a></dt>
|
||||
<dd>
|
||||
The plugins provided by Guido Günther allow to monitor various things
|
||||
like network and block I/O with
|
||||
<a href="http://munin.projects.linpro.no/">Munin</a>.
|
||||
</dd>
|
||||
<dt><a href="http://et.redhat.com/~rjones/nagios-virt/">Nagios-virt</a></dt>
|
||||
<dd>
|
||||
Nagios-virt is a configuration tool to add monitoring of your
|
||||
virtualised domains to <a href="http://www.nagios.org/">Nagios</a>.
|
||||
You can use this tool to either set up a new Nagios installation for
|
||||
your Xen or QEMU/KVM guests, or to integrate with your existing Nagios
|
||||
installation.
|
||||
</dd>
|
||||
<dt><a href="http://community.zenoss.org/docs/DOC-4687">Zenoss</a></dt>
|
||||
<dd>
|
||||
The Zenoss libvirt Zenpack adds support for monitoring virtualization
|
||||
servers. It has been tested with KVM, QEMU, VMware ESX, and VMware
|
||||
GSX.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="provisioning">Provisioning</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://www.ibm.com/software/tivoli/products/prov-mgr/">Tivoli Provisioning Manager</a></dt>
|
||||
<dd>
|
||||
Part of the IBM Tivoli family, Tivoli Provisioning Manager (TPM) is
|
||||
an IT lifecycle automation product. It
|
||||
<a href="http://publib.boulder.ibm.com/infocenter/tivihelp/v38r1/index.jsp?topic=/com.ibm.tivoli.tpm.apk.doc/libvirt_package.html">uses libvirt</a>
|
||||
for communication with virtualization hosts and guest domains.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://theforeman.org">Foreman</a></dt>
|
||||
<dd>
|
||||
Foreman is an open source web based application aimed to be a
|
||||
Single Address For All Machines Life Cycle Management. Foreman:
|
||||
|
||||
<ul>
|
||||
<li>Creates everything you need when adding a new machine to
|
||||
your network, its goal being automatically managing
|
||||
everything you would normally manage manually (DNS, DHCP,
|
||||
TFTP, Virtual Machines,CA, CMDB...)</li>
|
||||
<li>Integrates with Puppet (and acts as web front end to it).</li>
|
||||
<li>Takes care of provisioning until the point puppet is
|
||||
running, allowing Puppet to do what it does best.</li>
|
||||
<li>Shows you Systems Inventory (based on Facter) and
|
||||
provides real time information about hosts status based on
|
||||
Puppet reports.</li>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<h2><a name="web">Web applications</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://community.abiquo.com/display/AbiCloud">AbiCloud</a></dt>
|
||||
<dd>
|
||||
AbiCloud is an open source cloud platform manager which allows to
|
||||
easily deploy a private cloud in your datacenter. One of the key
|
||||
differences of AbiCloud is the web rich interface for managing the
|
||||
infrastructure. You can deploy a new service just dragging and
|
||||
dropping a VM.
|
||||
</dd>
|
||||
<dt><a href="http://ovirt.org/">oVirt</a></dt>
|
||||
<dd>
|
||||
oVirt provides the ability to manage large numbers of virtual
|
||||
machines across an entire data center of hosts. It integrates
|
||||
with FreeIPA for Kerberos authentication, and in the future,
|
||||
certificate management.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="mobile">Mobile applications</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="https://market.android.com/details?id=vm.manager">VM Manager</a></dt>
|
||||
<dd>
|
||||
VM Manager is VM (libvirt) manager (over SSH) application. VM Manager
|
||||
is an application for libvirt VM / Domain management over SSH.
|
||||
Please keep in mind that this software is under heavy development.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Domain management architecture</h1>
|
||||
</body>
|
||||
</html>
|
@ -1,87 +0,0 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1050 7500 9375 7500 9375 8700 1050 8700 1050 7500
|
||||
2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
3525 7275 3525 4125 1050 4125 1050 7275 3525 7275
|
||||
2 1 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 2
|
||||
1050 6540 3540 6525
|
||||
2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5
|
||||
1590 6900 1590 6645 1140 6645 1140 6900 1590 6900
|
||||
2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5
|
||||
1590 7185 1590 6930 1140 6930 1140 7185 1590 7185
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 2.00 120.00 240.00
|
||||
1 1 2.00 120.00 240.00
|
||||
1875 7725 8625 7725
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1650 5625 3000 5625 3000 6375 1650 6375 1650 5625
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
2850 7725 2850 6375
|
||||
2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
6450 7275 6450 4125 3975 4125 3975 7275 6450 7275
|
||||
2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
9300 7275 9300 4125 6825 4125 6825 7275 9300 7275
|
||||
2 1 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 2
|
||||
3975 6540 6465 6525
|
||||
2 1 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 2
|
||||
6825 6540 9315 6525
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
5400 7725 5400 7050
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
8025 7725 8025 7050
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1050 8925 9375 8925 9375 9900 1050 9900 1050 8925
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2100 4575 3450 4575 3450 5325 2100 5325 2100 4575
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
3225 5325 3225 8325
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
6225 6900 6225 8250
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
8925 6900 8925 8250
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
1725 7125 1725 8325
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 2.00 120.00 240.00
|
||||
1 1 2.00 120.00 240.00
|
||||
2850 5850 2850 5025
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
5175 8475 5175 9375
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
1350 7125 1350 9450
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
2325 7725 2325 7200
|
||||
2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 1
|
||||
900 3975
|
||||
2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 1
|
||||
9525 9975
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 870 4350 7980 XenBus\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 780 1680 6870 drivers\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 1050 1800 6075 XenStore\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 900 1875 7125 Kernel0\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 960 4875 6975 KernelU\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 960 7650 6975 KernelU\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 255 1740 4050 8400 Xen Hypervisor\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 585 2325 4950 Xend\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 690 1200 4725 Dom0\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 750 4875 5325 DomU\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 750 7650 5325 DomU\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 1080 3750 9450 Hardware\001
|
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB |
@ -1,97 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1 >libvirt architecture</h1>
|
||||
|
||||
<p>
|
||||
Currently libvirt supports 2 kind of virtualization, and its
|
||||
internal structure is based on a driver model which simplifies
|
||||
adding new
|
||||
engines:
|
||||
</p>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="Xen">Xen support</a></h2>
|
||||
|
||||
<p>When running in a Xen environment, programs using libvirt have to execute
|
||||
in "Domain 0", which is the primary Linux OS loaded on the machine. That OS
|
||||
kernel provides most if not all of the actual drivers used by the set of
|
||||
domains. It also runs the Xen Store, a database of information shared by the
|
||||
hypervisor, the kernels, the drivers and the xen daemon. Xend. The xen daemon
|
||||
supervise the control and execution of the sets of domains. The hypervisor,
|
||||
drivers, kernels and daemons communicate though a shared system bus
|
||||
implemented in the hypervisor. The figure below tries to provide a view of
|
||||
this environment:</p>
|
||||
<img src="architecture.gif" alt="The Xen architecture" />
|
||||
<p>The library can be initialized in 2 ways depending on the level of
|
||||
privilege of the embedding program. If it runs with root access,
|
||||
virConnectOpen() can be used, it will use three different ways to connect to
|
||||
the Xen infrastructure:</p>
|
||||
<ul>
|
||||
<li>a connection to the Xen Daemon though an HTTP RPC layer</li>
|
||||
<li>a read/write connection to the Xen Store</li>
|
||||
<li>use Xen Hypervisor calls</li>
|
||||
<li>when used as non-root libvirt connect to a proxy daemon running
|
||||
as root and providing read-only support</li>
|
||||
</ul>
|
||||
<p>The library will usually interact with the Xen daemon for any operation
|
||||
changing the state of the system, but for performance and accuracy reasons
|
||||
may talk directly to the hypervisor when gathering state information at
|
||||
least when possible (i.e. when the running program using libvirt has root
|
||||
privilege access).</p>
|
||||
<p>If it runs without root access virConnectOpenReadOnly() should be used to
|
||||
connect to initialize the library. It will then fork a libvirt_proxy
|
||||
program running as root and providing read_only access to the API, this is
|
||||
then only useful for reporting and monitoring.</p>
|
||||
|
||||
<h2><a name="QEmu">QEmu and KVM support</a></h2>
|
||||
|
||||
<p>The model for QEmu and KVM is completely similar, basically KVM is based
|
||||
on QEmu for the process controlling a new domain, only small details differs
|
||||
between the two. In both case the libvirt API is provided by a controlling
|
||||
process forked by libvirt in the background and which launch and control the
|
||||
QEmu or KVM process. That program called libvirt_qemud talks though a specific
|
||||
protocol to the library, and connects to the console of the QEmu process in
|
||||
order to control and report on its status. Libvirt tries to expose all the
|
||||
emulations models of QEmu, the selection is done when creating the new
|
||||
domain, by specifying the architecture and machine type targeted.</p>
|
||||
<p>The code controlling the QEmu process is available in the
|
||||
<code>qemud/</code> directory.</p>
|
||||
|
||||
<h2><a name="drivers">Driver based architecture</a></h2>
|
||||
|
||||
<p>As the previous section explains, libvirt can communicate using different
|
||||
channels with the current hypervisor, and should also be able to use
|
||||
different kind of hypervisor. To simplify the internal design, code, ease
|
||||
maintenance and simplify the support of other virtualization engine the
|
||||
internals have been structured as one core component, the libvirt.c module
|
||||
acting as a front-end for the library API and a set of hypervisor drivers
|
||||
defining a common set of routines. That way the Xen Daemon access, the Xen
|
||||
Store one, the Hypervisor hypercall are all isolated in separate C modules
|
||||
implementing at least a subset of the common operations defined by the
|
||||
drivers present in driver.h:</p>
|
||||
<ul>
|
||||
<li>xend_internal: implements the driver functions though the Xen
|
||||
Daemon</li>
|
||||
<li>xs_internal: implements the subset of the driver available though the
|
||||
Xen Store</li>
|
||||
<li>xen_internal: provide the implementation of the functions possible via
|
||||
direct hypervisor access</li>
|
||||
<li>proxy_internal: provide read-only Xen access via a proxy, the proxy code
|
||||
is in the <code>proxy/</code> directory.</li>
|
||||
<li>xm_internal: provide support for Xen defined but not running
|
||||
domains.</li>
|
||||
<li>qemu_internal: implement the driver functions for QEmu and
|
||||
KVM virtualization engines. It also uses a qemud/ specific daemon
|
||||
which interacts with the QEmu process to implement libvirt API.</li>
|
||||
<li>test: this is a test driver useful for regression tests of the
|
||||
front-end part of libvirt.</li>
|
||||
</ul>
|
||||
<p>Note that a given driver may only implement a subset of those functions,
|
||||
(for example saving a Xen domain state to disk and restoring it is only
|
||||
possible though the Xen Daemon), in that case the driver entry points for
|
||||
unsupported functions are initialized to NULL.</p>
|
||||
<p></p>
|
||||
</body>
|
||||
</html>
|
@ -1,53 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1>Network management architecture</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="architecture">Architecture illustration</a></h2>
|
||||
|
||||
<p>
|
||||
The diagrams below illustrate some of the network configurations
|
||||
enabled by the libvirt networking APIs
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>VLAN 1</strong>. This virtual network has connectivity
|
||||
to <code>LAN 2</code> with traffic forwarded and NATed.
|
||||
</li>
|
||||
<li><strong>VLAN 2</strong>. This virtual network is completely
|
||||
isolated from any physical LAN.
|
||||
</li>
|
||||
<li><strong>Guest A</strong>. The first network interface is bridged
|
||||
to the physical <code>LAN 1</code>. The second interface is connected
|
||||
to a virtual network <code>VLAN 1</code>.
|
||||
</li>
|
||||
<li><strong>Guest B</strong>. The first network interface is connected
|
||||
to a virtual network <code>VLAN 1</code>, giving it limited NAT
|
||||
based connectivity to LAN2. It has a second network interface
|
||||
connected to <code>VLAN 2</code>. It acts a router allowing limited
|
||||
traffic between the two VLANs, thus giving <code>Guest C</code>
|
||||
connectivity to the physical <code>LAN 2</code>.
|
||||
</li>
|
||||
<li><strong>Guest C</strong>. The only network interface is connected
|
||||
to a virtual network <code>VLAN 2</code>. It has no direct connectivity
|
||||
to a physical LAN, relying on <code>Guest B</code> to route traffic
|
||||
on its behalf.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3><a name="logical">Logical diagram</a></h3>
|
||||
|
||||
<p class="image">
|
||||
<img src="libvirt-net-logical.png" alt="Logical network architecture"/>
|
||||
</p>
|
||||
|
||||
<h3><a name="physical">Physical diagram</a></h3>
|
||||
|
||||
<p class="image">
|
||||
<img src="libvirt-net-physical.png" alt="Physical network architecture"/>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Node device management architecture</h1>
|
||||
</body>
|
||||
</html>
|
@ -1,30 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Storage management architecture</h1>
|
||||
|
||||
<p>
|
||||
The storage management APIs are based around 2 core concepts
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
<strong>Volume</strong> - a single storage volume which can
|
||||
be assigned to a guest, or used for creating further pools. A
|
||||
volume is either a block device, a raw file, or a special format
|
||||
file.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Pool</strong> - provides a means for taking a chunk
|
||||
of storage and carving it up into volumes. A pool can be used to
|
||||
manage things such as a physical disk, a NFS server, a iSCSI target,
|
||||
a host adapter, an LVM group.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
These two concepts are mapped through to two libvirt objects, a
|
||||
<code>virStorageVolPtr</code> and a <code>virStoragePoolPtr</code>,
|
||||
each with a collection of APIs for their management.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,289 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1 >Authentication & access control</h1>
|
||||
<p>
|
||||
When connecting to libvirt, some connections may require client
|
||||
authentication before allowing use of the APIs. The set of possible
|
||||
authentication mechanisms is administrator controlled, independent
|
||||
of applications using libvirt.
|
||||
</p>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="Auth_client_config">Client configuration</a></h2>
|
||||
|
||||
<p>
|
||||
When connecting to a remote hypervisor which requires authentication,
|
||||
most libvirt applications will prompt the user for the credentials. It is
|
||||
also possible to provide a client configuration file containing all the
|
||||
authentication credentials, avoiding any interaction. Libvirt will look
|
||||
for the authentication file using the following sequence:
|
||||
</p>
|
||||
<ol>
|
||||
<li>The file path specified by the $LIBVIRT_AUTH_FILE environment
|
||||
variable.</li>
|
||||
<li>The file path specified by the "authfile=/some/file" URI
|
||||
query parameter</li>
|
||||
<li>The file $HOME/.libvirt/auth.conf</li>
|
||||
<li>The file /etc/libvirt/auth.conf</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
The auth configuration file uses the traditional <code>".ini"</code>
|
||||
style syntax. There are two types of groups that can be present in
|
||||
the config. First there are one or more <strong>credential</strong>
|
||||
sets, which provide the actual authentication credentials. The keys
|
||||
within the group may be:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><code>username</code>: the user login name to act as. This
|
||||
is relevant for ESX, Xen, HyperV and SSH, but probably not
|
||||
the one you want to libvirtd with SASL.</li>
|
||||
<li><code>authname</code>: the name to authorize as. This is
|
||||
what is commonly required for libvirtd with SASL.</li>
|
||||
<li><code>password</code>: the secret password</li>
|
||||
<li><code>realm</code>: the domain realm for SASL, mostly
|
||||
unused</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Each set of credentials has a name, which is part of the group
|
||||
entry name. Overall the syntax is
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
[credentials-$NAME]
|
||||
credname1=value1
|
||||
credname2=value2</pre>
|
||||
|
||||
<p>
|
||||
For example, to define two sets of credentials used for production
|
||||
and test machines, using libvirtd, and a further ESX server for dev:
|
||||
</p>
|
||||
<pre>
|
||||
[credentials-test]
|
||||
authname=fred
|
||||
password=123456
|
||||
|
||||
[credentials-prod]
|
||||
authname=bar
|
||||
password=letmein
|
||||
|
||||
[credentials-dev]
|
||||
username=joe
|
||||
password=hello</pre>
|
||||
|
||||
<p>
|
||||
The second set of groups provide mappings of credentials to
|
||||
specific machine services. The config file group names compromise
|
||||
the service type and host:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
[auth-$SERVICE-$HOSTNAME]
|
||||
credentials=$CREDENTIALS</pre>
|
||||
|
||||
<p>
|
||||
For example, following the previous example, here is how to
|
||||
list some machines
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
[auth-libvirt-test1.example.com]
|
||||
credentials=test
|
||||
|
||||
[auth-libvirt-test2.example.com]
|
||||
credentials=test
|
||||
|
||||
[auth-libvirt-demo3.example.com]
|
||||
credentials=test
|
||||
|
||||
[auth-libvirt-prod1.example.com]
|
||||
credentials=prod
|
||||
|
||||
[auth-esx-dev1.example.com]
|
||||
credentials=dev</pre>
|
||||
|
||||
<p>
|
||||
The following service types are known to libvirt
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li><code>libvirt</code> - used for connections to a libvirtd
|
||||
server, which is configured with SASL auth</li>
|
||||
<li><code>ssh</code> - used for connections to a Phyp server
|
||||
over SSH</li>
|
||||
<li><code>esx</code> - used for connections to an ESX or
|
||||
VirtualCenter server</li>
|
||||
<li><code>xen</code> - used for connections to a Xen Enterprise
|
||||
sever using XenAPI</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
Applications using libvirt are free to use this same configuration
|
||||
file for storing other credentials. For example, it can be used
|
||||
to storage VNC or SPICE login credentials
|
||||
</p>
|
||||
|
||||
<h2><a name="ACL_server_config">Server configuration</a></h2>
|
||||
<p>
|
||||
The libvirt daemon allows the administrator to choose the authentication
|
||||
mechanisms used for client connections on each network socket independently.
|
||||
This is primarily controlled via the libvirt daemon master config file in
|
||||
<code>/etc/libvirt/libvirtd.conf</code>. Each of the libvirt sockets can
|
||||
have its authentication mechanism configured independently. There is
|
||||
currently a choice of <code>none</code>, <code>polkit</code>, and <code>sasl</code>.
|
||||
The SASL scheme can be further configured to choose between a large
|
||||
number of different mechanisms.
|
||||
</p>
|
||||
<h2><a name="ACL_server_unix_perms">UNIX socket permissions/group</a></h2>
|
||||
<p>
|
||||
If libvirt does not contain support for PolicyKit, then access control for
|
||||
the UNIX domain socket is done using traditional file user/group ownership
|
||||
and permissions. There are 2 sockets, one for full read-write access, the
|
||||
other for read-only access. The RW socket will be restricted (mode 0700) to
|
||||
only allow the <code>root</code> user to connect. The read-only socket will
|
||||
be open access (mode 0777) to allow any user to connect.
|
||||
</p>
|
||||
<p>
|
||||
To allow non-root users greater access, the <code>libvirtd.conf</code> file
|
||||
can be edited to change the permissions via the <code>unix_sock_rw_perms</code>,
|
||||
config parameter and to set a user group via the <code>unix_sock_group</code>
|
||||
parameter. For example, setting the former to mode <code>0770</code> and the
|
||||
latter <code>wheel</code> would let any user in the wheel group connect to
|
||||
the libvirt daemon.
|
||||
</p>
|
||||
<h2><a name="ACL_server_polkit">UNIX socket PolicyKit auth</a></h2>
|
||||
<p>
|
||||
If libvirt contains support for PolicyKit, then access control options are
|
||||
more advanced. The <code>unix_sock_auth</code> parameter will default to
|
||||
<code>polkit</code>, and the file permissions will default to <code>0777</code>
|
||||
even on the RW socket. Upon connecting to the socket, the client application
|
||||
will be required to identify itself with PolicyKit. The default policy for the
|
||||
RW daemon socket will require any application running in the current desktop
|
||||
session to authenticate using the user's password. This is akin to <code>sudo</code>
|
||||
auth, but does not require that the client application ultimately run as root.
|
||||
Default policy will still allow any application to connect to the RO socket.
|
||||
</p>
|
||||
<p>
|
||||
The default policy can be overridden by creating a new policy file in the
|
||||
local override directory <code>/etc/polkit-1/localauthority/50-local.d/</code>.
|
||||
Policy files should have a unique name ending with .pkla. Using reverse DNS
|
||||
naming works well. Information on the options available can be found by
|
||||
reading the pklocalauthority man page. The two libvirt daemon actions
|
||||
available are named <code>org.libvirt.unix.manage</code> for full management
|
||||
access, and <code>org.libvirt.unix.monitor</code> for read-only access.
|
||||
</p>
|
||||
<p>
|
||||
As an example, this gives the user <code>fred</code> full management access:
|
||||
</p>
|
||||
<pre>[Allow fred libvirt management permissions]
|
||||
Identity=unix-user:fred
|
||||
Action=org.libvirt.unix.manage
|
||||
ResultAny=yes
|
||||
ResultInactive=yes
|
||||
ResultActive=yes</pre>
|
||||
<p>
|
||||
Further examples of PolicyKit setup can be found on the
|
||||
<a href="http://wiki.libvirt.org/page/SSHPolicyKitSetup">wiki page</a>.
|
||||
</p>
|
||||
<h2><a name="ACL_server_username">Username/password auth</a></h2>
|
||||
<p>
|
||||
The plain TCP socket of the libvirt daemon defaults to using SASL for authentication.
|
||||
The SASL mechanism configured by default is DIGEST-MD5, which provides a basic
|
||||
username+password style authentication. It also provides for encryption of the data
|
||||
stream, so the security of the plain TCP socket is on a par with that of the TLS
|
||||
socket. If desired the UNIX socket and TLS socket can also have SASL enabled by
|
||||
setting the <code>auth_unix_ro</code>, <code>auth_unix_rw</code>, <code>auth_tls</code>
|
||||
config params in <code>libvirt.conf</code>.
|
||||
</p>
|
||||
<p>
|
||||
Out of the box, no user accounts are defined, so no clients will be able to authenticate
|
||||
on the TCP socket. Adding users and setting their passwords is done with the <code>saslpasswd2</code>
|
||||
command. When running this command it is important to tell it that the appname is <code>libvirt</code>.
|
||||
As an example, to add a user <code>fred</code>, run
|
||||
</p>
|
||||
<pre>
|
||||
# saslpasswd2 -a libvirt fred
|
||||
Password: xxxxxx
|
||||
Again (for verification): xxxxxx
|
||||
</pre>
|
||||
<p>
|
||||
To see a list of all accounts the <code>sasldblistusers2</code> command can be used.
|
||||
This command expects to be given the path to the libvirt user database, which is kept
|
||||
in <code>/etc/libvirt/passwd.db</code>
|
||||
</p>
|
||||
<pre>
|
||||
# sasldblistusers2 -f /etc/libvirt/passwd.db
|
||||
fred@t60wlan.home.berrange.com: userPassword
|
||||
</pre>
|
||||
<p>
|
||||
Finally, to disable a user's access, the <code>saslpasswd2</code> command can be used
|
||||
again:
|
||||
</p>
|
||||
<pre>
|
||||
# saslpasswd2 -a libvirt -d fred
|
||||
</pre>
|
||||
<h2><a name="ACL_server_kerberos">Kerberos auth</a></h2>
|
||||
<p>
|
||||
The plain TCP socket of the libvirt daemon defaults to using SASL for authentication.
|
||||
The SASL mechanism configured by default is DIGEST-MD5, which provides a basic
|
||||
username+password style authentication. To enable Kerberos single-sign-on instead,
|
||||
the libvirt SASL configuration file must be changed. This is <code>/etc/sasl2/libvirt.conf</code>.
|
||||
The <code>mech_list</code> parameter must first be changed to <code>gssapi</code>
|
||||
instead of the default <code>digest-md5</code>, and keytab should be set to
|
||||
<code>/etc/libvirt/krb5.tab</code> . If SASL is enabled on the UNIX
|
||||
and/or TLS sockets, Kerberos will also be used for them. Like DIGEST-MD5, the Kerberos
|
||||
mechanism provides data encryption of the session.
|
||||
</p>
|
||||
<p>
|
||||
Some operating systems do not install the SASL kerberos plugin by default. It
|
||||
may be necessary to install a sub-package such as <code>cyrus-sasl-gssapi</code>.
|
||||
To check whether the Kerberos plugin is installed run the <code>pluginviewer</code>
|
||||
program and verify that <code>gssapi</code> is listed,eg:
|
||||
</p>
|
||||
<pre>
|
||||
# pluginviewer
|
||||
...snip...
|
||||
Plugin "gssapiv2" [loaded], API version: 4
|
||||
SASL mechanism: GSSAPI, best SSF: 56
|
||||
security flags: NO_ANONYMOUS|NO_PLAINTEXT|NO_ACTIVE|PASS_CREDENTIALS|MUTUAL_AUTH
|
||||
features: WANT_CLIENT_FIRST|PROXY_AUTHENTICATION|NEED_SERVER_FQDN
|
||||
</pre>
|
||||
<p>
|
||||
Next it 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@KERBEROS.REALM</code>.
|
||||
This is typically done by running the <code>kadmin.local</code> command on the Kerberos
|
||||
server, though some Kerberos servers have alternate ways of setting up service principles.
|
||||
Once created, the principle should be exported to a keytab, copied to the host running
|
||||
the libvirt daemon and placed in <code>/etc/libvirt/krb5.tab</code>
|
||||
</p>
|
||||
<pre>
|
||||
# kadmin.local
|
||||
kadmin.local: add_principal libvirt/foo.example.com
|
||||
Enter password for principal "libvirt/foo.example.com@EXAMPLE.COM":
|
||||
Re-enter password for principal "libvirt/foo.example.com@EXAMPLE.COM":
|
||||
Principal "libvirt/foo.example.com@EXAMPLE.COM" created.
|
||||
|
||||
kadmin.local: ktadd -k /root/libvirt-foo-example.tab libvirt/foo.example.com@EXAMPLE.COM
|
||||
Entry for principal libvirt/foo.example.com@EXAMPLE.COM with kvno 4, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/root/libvirt-foo-example.tab.
|
||||
Entry for principal libvirt/foo.example.com@EXAMPLE.COM with kvno 4, encryption type ArcFour with HMAC/md5 added to keytab WRFILE:/root/libvirt-foo-example.tab.
|
||||
Entry for principal libvirt/foo.example.com@EXAMPLE.COM with kvno 4, encryption type DES with HMAC/sha1 added to keytab WRFILE:/root/libvirt-foo-example.tab.
|
||||
Entry for principal libvirt/foo.example.com@EXAMPLE.COM with kvno 4, encryption type DES cbc mode with RSA-MD5 added to keytab WRFILE:/root/libvirt-foo-example.tab.
|
||||
|
||||
kadmin.local: quit
|
||||
|
||||
# scp /root/libvirt-foo-example.tab root@foo.example.com:/etc/libvirt/krb5.tab
|
||||
# rm /root/libvirt-foo-example.tab
|
||||
</pre>
|
||||
<p>
|
||||
Any client application wishing to connect to a Kerberos enabled libvirt server
|
||||
merely needs to run <code>kinit</code> to gain a user principle. This may well
|
||||
be done automatically when a user logs into a desktop session, if PAM is setup
|
||||
to authenticate against Kerberos.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -1,83 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1 >Bindings for other languages</h1>
|
||||
|
||||
<p>
|
||||
Libvirt supports C and C++ directly, and has bindings available
|
||||
for other languages:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>C#</strong>: Arnaud Champion develops
|
||||
<a href="csharp.html">C# bindings</a>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Java</strong>: Daniel Veillard develops
|
||||
<a href="java.html">Java bindings</a>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>OCaml</strong>: Richard Jones develops
|
||||
<a href="http://libvirt.org/ocaml/">OCaml bindings</a>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Perl</strong>: Daniel Berrange develops
|
||||
<a href="http://search.cpan.org/dist/Sys-Virt/">Perl bindings</a>.
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
<strong>PHP</strong>: Radek Hladik started developing
|
||||
<a href="http://libvirt.org/php">PHP bindings</a> in 2010.
|
||||
</p>
|
||||
<p>
|
||||
In February 2011 the binding development has been moved to the libvirt.org website as
|
||||
libvirt-php project.
|
||||
</p>
|
||||
<p>
|
||||
The project is now maintained by Michal Novotny and it's heavily based
|
||||
on Radek's version. For more information, including
|
||||
information on posting patches to libvirt-php, please refer
|
||||
to the <a href="http://libvirt.org/php">PHP bindings</a> site.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
<strong>Python</strong>: Libvirt comes with direct support for
|
||||
the Python language.
|
||||
</p>
|
||||
<p>
|
||||
If your libvirt is installed as packages, rather than compiled
|
||||
by you from source code, ensure you have the appropriate
|
||||
package installed.
|
||||
</p>
|
||||
<p>
|
||||
This is named <b>libvirt-python</b> on RHEL/Fedora,
|
||||
<a href="http://packages.ubuntu.com/search?keywords=python-libvirt"><b>python-libvirt</b></a>
|
||||
on Ubuntu, and may be named differently on others.
|
||||
</p>
|
||||
<p>
|
||||
For usage information, see the
|
||||
<a href="python.html">Python API bindings</a> page.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Ruby</strong>: Chris Lalancette develops
|
||||
<a href="http://libvirt.org/ruby/">Ruby bindings</a>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
For information on using libvirt on <strong>Windows</strong>
|
||||
<a href="windows.html">please see the Windows support page</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Support, requests or help for libvirt bindings are welcome on the
|
||||
<a href="https://www.redhat.com/mailman/listinfo/libvir-list/">mailing list</a>,
|
||||
as usual try to provide enough background information and make sure
|
||||
you use recent version, see the <a href="bugs.html">help page</a>.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,146 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h1>Bug reporting</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="bugzilla">Bug Tracking</a></h2>
|
||||
|
||||
<p>
|
||||
If you are using libvirt binaries from a Linux distribution
|
||||
check below for distribution specific bug reporting policies
|
||||
first.
|
||||
</p>
|
||||
|
||||
<h2><a name="general">General libvirt bug reports</a></h2>
|
||||
|
||||
<p>
|
||||
The <a href="http://bugzilla.redhat.com">Red Hat Bugzilla Server</a>
|
||||
should be used to report bugs and request features in libvirt.
|
||||
Before submitting a ticket, check the existing tickets to see if
|
||||
the bug/feature is already tracked.
|
||||
|
||||
For general libvirt bug reports, from self-built releases, GIT snapshots
|
||||
and any other non-distribution supported builds, enter tickets under
|
||||
the <code>Virtualization Tools</code> product and the <code>libvirt</code>
|
||||
component.
|
||||
</p>
|
||||
<p>
|
||||
It's always a good idea to file bug reports, as the process of
|
||||
filing the report always makes it easier to describe the
|
||||
problem, and the bug number provides a quick way of referring to
|
||||
the problem. However, not everybody in the community pays
|
||||
attention to bugzilla, so after you file a bug, asking questions
|
||||
and submitting patches on <a href="contact.html">the libvirt
|
||||
mailing lists</a> will increase your bug's visibility and
|
||||
encourage people to think about your problem. Don't hesitate to
|
||||
ask questions on the list, as others may know of existing
|
||||
solutions or be interested in collaborating with you on finding
|
||||
a solution. Patches are always appreciated, and it's likely
|
||||
that someone else has the same problem you do!
|
||||
</p>
|
||||
<p>
|
||||
If you decide to write code, though, before you begin please
|
||||
read the <a href="hacking.html">contributor guidelines</a>,
|
||||
especially the first point: "Discuss any large changes on the
|
||||
mailing list first. Post patches early and listen to feedback."
|
||||
Few development experiences are more discouraging than spending
|
||||
a bunch of time writing a patch only to have someone point out a
|
||||
better approach on list.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://bugzilla.redhat.com/buglist.cgi?component=libvirt&product=Virtualization%20Tools">View libvirt tickets</a></li>
|
||||
<li><a href="http://bugzilla.redhat.com/bugzilla/enter_bug.cgi?product=Virtualization%20Tools&component=libvirt">New libvirt ticket</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="distribution">Linux Distribution specific bug reports</a></h2>
|
||||
<ul>
|
||||
<li>
|
||||
If you are using binaries from <strong>Fedora</strong>, enter
|
||||
tickets against the <code>Fedora</code> product and
|
||||
the <code>libvirt</code> component.
|
||||
<ul>
|
||||
<li><a href="http://bugzilla.redhat.com/buglist.cgi?component=libvirt&product=Fedora">View Fedora libvirt tickets</a></li>
|
||||
<li><a href="http://bugzilla.redhat.com/bugzilla/enter_bug.cgi?product=Fedora&component=libvirt">New Fedora libvirt ticket</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
If you are using binaries from <strong>Red Hat Enterprise
|
||||
Linux</strong>, enter tickets against the Red Hat Enterprise
|
||||
Linux product that you're using (e.g., Red Hat Enterprise
|
||||
Linux 6) and the <code>libvirt</code> component. Red Hat
|
||||
bugzilla has <a href="http://bugzilla.redhat.com">additional guidance</a> about getting support if
|
||||
you are a Red Hat customer.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
If you are using binaries from another Linux distribution
|
||||
first follow their own bug reporting guidelines.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
Finally, if you are a contributor to another Linux
|
||||
distribution and would like to have your procedure for
|
||||
filing bugs mentioned here, please mail the libvirt
|
||||
development list.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2><a name="quality">How to file high quality bug reports</a></h2>
|
||||
|
||||
<p>
|
||||
To increase the likelihood of your bug report being addressed it is
|
||||
important to provide as much information as possible. When filing
|
||||
libvirt bugs use this checklist to see if you are providing enough
|
||||
information:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>The version number of the libvirt build, or SHA1 of the GIT
|
||||
commit</li>
|
||||
<li>The hardware architecture being used</li>
|
||||
<li>The name of the hypervisor (Xen, QEMU, KVM)</li>
|
||||
<li>The XML config of the guest domain if relevant</li>
|
||||
<li>For Xen hypervisor, the XenD logfile from /var/log/xen</li>
|
||||
<li>For QEMU/KVM, the domain logfile from /var/log/libvirt/qemu</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
If the bug leads to a tool linked to libvirt crash, then the best
|
||||
is to provide a backtrace along with the scenario used to get the
|
||||
crash, the simplest is to run the program under gdb, reproduce the
|
||||
steps leading to the crash and then issue a gdb "bt -a" command to
|
||||
get the stack trace, attach it to the bug. Note that for the
|
||||
data to be really useful libvirt debug informations must be present
|
||||
for example by installing libvirt debuginfo package on Fedora or
|
||||
Red Hat Enterprise Linux (with debuginfo-install libvirt) prior
|
||||
to running gdb.</p>
|
||||
<p>
|
||||
It may also happen that the libvirt daemon itself crashes or gets stuck,
|
||||
in the first case run it (as root) under gdb, and reproduce the sequence
|
||||
leading to the crash, similary to a normal program provide the
|
||||
"bt" backtrace information to where gdb will have stopped.<br/>
|
||||
But if libvirtd gets stuck, for example seems to stop processing
|
||||
commands, try to attach to the faulty daemon and issue a gdb command
|
||||
"thread apply all bt" to show all the threads backtraces, as in:</p>
|
||||
<pre> # ps -o etime,pid `pgrep libvirt`
|
||||
... note the process id from the output
|
||||
# gdb /usr/sbin/libvirtd
|
||||
.... some informations about gdb and loading debug data
|
||||
(gdb) attach $the_damon_process_id
|
||||
....
|
||||
(gdb) thread apply all bt
|
||||
.... informations to attach to the bug
|
||||
(gdb)
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,118 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1><a name="installation">libvirt Installation</a></h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="compiling">Compiling a release tarball</a></h2>
|
||||
|
||||
<p>
|
||||
libvirt uses the standard configure/make/install steps:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ gunzip -c libvirt-x.x.x.tar.gz | tar xvf -
|
||||
$ cd libvirt-x.x.x
|
||||
$ ./configure</pre>
|
||||
|
||||
<p>
|
||||
The <i>configure</i> script can be given options to change its default
|
||||
behaviour.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To get the complete list of the options it can take, pass it the
|
||||
<i>--help</i> option like this:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ ./configure <i>--help</i></pre>
|
||||
|
||||
<p>
|
||||
When you have determined which options you want to use (if any),
|
||||
continue the process.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note the use of <b>sudo</b> with the <i>make install</i> command
|
||||
below. Using sudo is only required when installing to a location your
|
||||
user does not have write access to. Installing to a system location
|
||||
is a good example of this.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you are installing to a location that your user <i>does</i> have write
|
||||
access to, then you can instead run the <i>make install</i> command
|
||||
without putting <b>sudo</b> before it.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ ./configure <i>[possible options]</i>
|
||||
$ make
|
||||
$ <b>sudo</b> <i>make install</i></pre>
|
||||
|
||||
<p>
|
||||
At this point you <b>may</b> have to run ldconfig or a similar utility
|
||||
to update your list of installed shared libs.
|
||||
</p>
|
||||
|
||||
<h2><a name="building">Building from a GIT checkout</a></h2>
|
||||
|
||||
<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. By default when
|
||||
the <code>configure</code> script is run from within a GIT checkout, it
|
||||
will turn on -Werror for builds. This can be disabled with --disable-werror,
|
||||
but this is not recommended. To build & install libvirt to your home
|
||||
directory the following commands can be run:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ ./autogen.sh --prefix=$HOME/usr
|
||||
$ make
|
||||
$ <b>sudo</b> make install</pre>
|
||||
|
||||
<p>
|
||||
Be aware though, that binaries built with a custom prefix will not
|
||||
interoperate with OS vendor provided binaries, since the UNIX socket
|
||||
paths will all be different. To produce a build that is compatible
|
||||
with normal OS vendor prefixes, use
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ ./autogen.sh --system
|
||||
$ make
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
When doing this for day-to-day development purposes, it is recommended
|
||||
not to install over the OS vendor provided binaries. Instead simply
|
||||
run libvirt directly from the source tree. For example to run
|
||||
a privileged libvirtd instance
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ su -
|
||||
# service libvirtd stop (or systemctl stop libvirtd.service)
|
||||
# /home/to/your/checkout/daemon/libvirtd
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
It is also possible to run virsh directly from the source tree
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ ./tools/virsh ....
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
A normal configuration of libvirt will build hypervisor drivers
|
||||
as loadable modules. When running from a non-installed source
|
||||
tree, libvirtd will attempt to find the modules from the same
|
||||
source tree. If this is not possible though, you can explicitly
|
||||
set <code>LIBVIRT_DRIVER_DIR=/path/to/source/tree/src/.libs</code>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -1,103 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1>Contacting the development team</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="email">Mailing lists</a></h2>
|
||||
|
||||
<p>
|
||||
There are three mailing-lists:
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt><a href="https://www.redhat.com/mailman/listinfo/libvir-list">libvir-list@redhat.com</a> (for development)</dt>
|
||||
<dd>
|
||||
Archives at <a href="https://www.redhat.com/archives/libvir-list">https://www.redhat.com/archives/libvir-list</a>
|
||||
</dd>
|
||||
<dd>
|
||||
This is a high volume mailing list. It is a place for discussions
|
||||
about the <strong>development</strong> of libvirt.
|
||||
</dd>
|
||||
<dd>
|
||||
Topics for discussion include:
|
||||
<ul>
|
||||
<li>New features for libvirt</li>
|
||||
<li>Bug fixing of libvirt</li>
|
||||
<li>New hypervisor drivers</li>
|
||||
<li>Development of language bindings for libvirt API</li>
|
||||
<li>Testing and documentation of libvirt</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><a href="https://www.redhat.com/mailman/listinfo/libvirt-users">libvirt-users@redhat.com</a> (for users)</dt>
|
||||
<dd>
|
||||
Archives at <a href="https://www.redhat.com/archives/libvirt-users">https://www.redhat.com/archives/libvirt-users</a>
|
||||
</dd>
|
||||
<dd>
|
||||
This is a moderate volume mailing list. It is a place for discussions
|
||||
involving libvirt <strong>users</strong>.
|
||||
</dd>
|
||||
<dd>
|
||||
Topics for discussion include:
|
||||
<ul>
|
||||
<li>Usage of libvirt / virsh</li>
|
||||
<li>Administration of libvirt</li>
|
||||
<li>Deployment of libvirt with hypervisors</li>
|
||||
<li>Development of applications on top of / using the libvirt API(s)</li>
|
||||
<li>Any other topics along these lines</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><a href="https://www.redhat.com/mailman/listinfo/libvirt-announce">libvirt-announce@redhat.com</a> (for release notices)</dt>
|
||||
<dd>
|
||||
Archives at <a href="https://www.redhat.com/archives/libvirt-announce">https://www.redhat.com/archives/libvirt-announce</a>
|
||||
</dd>
|
||||
<dd>
|
||||
This is a low volume mailing list, with restricted posting, for
|
||||
announcements of new libvirt releases.
|
||||
</dd>
|
||||
<dd>
|
||||
Subscribe to just this if you want to be notified of new releases,
|
||||
without subscribing to either of the other mailing lists.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
It is recommended but not required that you subscribe before posting
|
||||
to the user and development lists. Posts from non-subscribers will be
|
||||
subject to manual moderation delays. You can subscribe at the linked
|
||||
web pages above.
|
||||
</p>
|
||||
<p>
|
||||
Patches with explanations and provided as attachments are really
|
||||
appreciated, and should be directed to the development mailing list
|
||||
for review and discussion.
|
||||
Wherever possible, please generate the patches by using
|
||||
<code>git format-patch</code> in a git repository clone. Further
|
||||
useful information regarding developing libvirt and/or contributing is
|
||||
available on our <a href="hacking.html">Contributor Guidelines</a>
|
||||
page.
|
||||
</p>
|
||||
|
||||
<h2><a name="irc">IRC discussion</a></h2>
|
||||
|
||||
<p>
|
||||
Some of the libvirt developers may be found on IRC on the <a href="http://oftc.net">OFTC IRC</a>
|
||||
network. Use the settings:
|
||||
</p>
|
||||
<ul>
|
||||
<li>server: irc.oftc.net</li>
|
||||
<li>port: 6667 (the usual IRC port)</li>
|
||||
<li>channel: #virt</li>
|
||||
</ul>
|
||||
<p>
|
||||
NB There is no guarantee that someone will be watching or able to reply
|
||||
promptly, so use the mailing-list if you don't get an answer on the IRC
|
||||
channel.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,502 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1>C# API bindings</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="description">Description</a></h2>
|
||||
|
||||
<p>
|
||||
The C# libvirt bindings are a class library. They use a Microsoft
|
||||
Visual Studio project architecture, and have been tested with Windows
|
||||
.NET, and Mono, on both Linux and Windows.
|
||||
</p>
|
||||
<p>
|
||||
Compiling them produces <b>LibvirtBindings.dll</b>, which can
|
||||
be added as a .NET reference to any .NET project needing access
|
||||
to libvirt.
|
||||
</p>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h2><a name="requirements">Requirements</a></h2>
|
||||
|
||||
<p>
|
||||
These bindings depend upon the libvirt libraries being installed.
|
||||
</p>
|
||||
<p>
|
||||
In the .NET case, this is <b>libvirt-0.dll</b>, produced from
|
||||
compiling libvirt for windows.
|
||||
</p>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<!-- 2010-10-19 JC: Commented out until we have C# tarballs to download
|
||||
<h2><a name="getting">Getting them</a></h2>
|
||||
|
||||
<p>
|
||||
The latest versions of the libvirt C# bindings can be downloaded from:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="ftp://libvirt.org/libvirt/csharp/">libvirt.org FTP server</a></li>
|
||||
<li><a href="http://libvirt.org/sources/csharp/">libvirt.org HTTP server</a></li>
|
||||
</ul>
|
||||
-->
|
||||
|
||||
<h2><a name="git">GIT source repository</a></h2>
|
||||
<p>
|
||||
The C# bindings source code is maintained in a <a
|
||||
href="http://git-scm.com/">git</a> repository available on
|
||||
<a href="http://libvirt.org/git/">libvirt.org</a>:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
git clone git://libvirt.org/libvirt-csharp.git
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
They can also be browsed online:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<a href="http://libvirt.org/git/?p=libvirt-csharp.git;a=summary">http://libvirt.org/git/?p=libvirt-csharp.git;a=summary</a>
|
||||
</pre>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h2><a name="usage">Usage</a></h2>
|
||||
|
||||
<p>
|
||||
The libvirt C# bindings class library exposes the <b>Libvirt</b>
|
||||
namespace. This namespace exposes all of the needed types (enum,
|
||||
struct), plus many classes exposing the libvirt API methods.
|
||||
</p>
|
||||
<p>
|
||||
These classes are grouped into functional areas, with each class
|
||||
exposing libvirt methods related to that area.
|
||||
</p>
|
||||
<p>
|
||||
For example, the libvirt methods related to connections, such as
|
||||
<b>virConnectOpenAuth</b> and <b>virConnectNumOfDomains</b>, are in
|
||||
the <b>Connect</b> class.
|
||||
<br />
|
||||
They are accessed as <b>Connect.OpenAuth</b>, and
|
||||
<b>Connect.NumOfDomains</b> respectively.
|
||||
</p>
|
||||
<p>
|
||||
In the same manner, the other class name mappings are:
|
||||
</p>
|
||||
<table class="top_table">
|
||||
<tr><th>Name of libvirt function</th><th>C# class name</th></tr>
|
||||
<tr><td>virDomain...</td><td>Domain</td></tr>
|
||||
<tr><td>virEvent...</td><td>Event</td></tr>
|
||||
<tr><td>virInterface...</td><td>Interface</td></tr>
|
||||
<tr><td>virNetwork...</td><td>Network</td></tr>
|
||||
<tr><td>virNode...</td><td>Node</td></tr>
|
||||
<tr><td>virSecret...</td><td>Secret</td></tr>
|
||||
<tr><td>virStoragePool...</td><td>StoragePool</td></tr>
|
||||
<tr><td>virStorageVolume...</td><td>StorageVolume</td></tr>
|
||||
<tr><td>virStream...</td><td>Stream</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
There are some additions as well:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
There is a class named <b>Library</b>, exposing the
|
||||
<b>virGetVersion</b> and <b>virInitialize</b> methods
|
||||
</li>
|
||||
<li>
|
||||
There is a class named <b>Errors</b>, exposing the error
|
||||
related methods. For example, <b>virSetErrorFunc</b> and
|
||||
<b>virConnResetLastError</b>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h2><a name="authors">Authors</a></h2>
|
||||
|
||||
<p>
|
||||
The C# bindings are the work of Arnaud Champion
|
||||
<<a href="mailto:arnaud.champion AT devatom.fr">arnaud.champion AT devatom.fr</a>>,
|
||||
based upon the previous work of Jaromír Červenka.
|
||||
</p>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h2><a name="notes">Test Configuration</a></h2>
|
||||
|
||||
<p>
|
||||
Testing is performed using the following configurations:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Windows 7 (64 bits) / .Net 4</li>
|
||||
<li>Windows 7 (64 bits) / Mono 2.6.7 (compiled in 32 bits)</li>
|
||||
<li>Ubuntu 10.10 amd64 / Mono 2.6.7 (compiled in 64 bits)</li>
|
||||
</ul>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h2><a name="type">Type Coverage</a></h2>
|
||||
|
||||
<p>
|
||||
Coverage of the libvirt types is:
|
||||
</p>
|
||||
<table class="top_table">
|
||||
<tr><th>Type</th><th>Name</th><th>Binding?</th><th>Tested?</th><th>Sample Code?</th><th>Works?</th><th>Tested .Net/Windows Works?</th><th>Tested Mono (32-bit)/Windows Works?</th><th>Tested Mono (64-bit)/Linux Works?</th></tr>
|
||||
<tr><td>enum</td><td>virCPUCompareResult</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virConnect</td><td>Yes, an IntPtr as the struct is not public</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virConnectAuth</td><td>Yes</td><td>Yes</td><td>virConnectOpenAuth</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>struct</td><td>virConnectCredential</td><td>Yes</td><td>Yes</td><td>virConnectOpenAuth</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>enum</td><td>virConnectCredentialType</td><td>Yes</td><td>Yes</td><td>virConnectOpenAuth</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>enum</td><td>virConnectFlags</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virDomain</td><td>Yes, an IntPtr as the struct is not public</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virDomainBlockInfo</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virDomainBlockStatsInfo</td><td>Yes</td><td>Yes</td><td>virDomainStats</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>enum</td><td>virDomainCoreDumpFlags</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainCreateFlags</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainDeviceModifyFlags</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventDefinedDetailType</td><td>Yes</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>struct</td><td>virDomainEventGraphicsAddress</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventGraphicsAddressType</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventGraphicsPhase</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virDomainEventGraphicsSubject</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virDomainEventGraphicsSubjectIdentity</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventID</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventIOErrorAction</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventResumedDetailType</td><td>Yes</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventStartedDetailType</td><td>Yes</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventStoppedDetailType</td><td>Yes</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventSuspendedDetailType</td><td>Yes</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventType</td><td>Yes</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventUndefinedDetailType</td><td>Yes</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>enum</td><td>virDomainEventWatchdogAction</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virDomainInfo</td><td>Yes</td><td>Yes</td><td>virConnectSetErrorFunc, virDomainStats</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>struct</td><td>virDomainInterfaceStatsStruct</td><td>Yes</td><td>Yes</td><td>virDomainStats</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>struct</td><td>virDomainJobInfo</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainJobType</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainMemoryFlags</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virDomainMemoryStatStruct</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainMemoryStatTags</td><td>Yes</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainMigrateFlags</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virDomainSnapshot</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainSnapshotDeleteFlags</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainState</td><td>Yes</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virDomainXMLFlags</td><td>Yes</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virEventHandleType</td><td>Yes</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>struct</td><td>virInterface</td><td>Yes, an IntPtr as the struct is not public</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virInterfaceXMLFlags</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virNWFilter</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virNetwork</td><td>Yes, an IntPtr as the struct is not public</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virNodeDevice</td><td>Yes, an IntPtr as the struct is not public</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virNodeInfo</td><td>Yes</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virSchedParameter</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virSchedParameterType</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virSecret</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virSecretUsageType</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virSecurityLabel</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virSecurityModel</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virStoragePoolBuildFlags</td><td>Yes</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virStoragePoolDeleteFlags</td><td>Yes</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virStoragePoolInfo</td><td>Yes</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virStoragePool</td><td>Yes, an IntPtr as the struct is not public</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virStoragePoolState</td><td>Yes</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virStorageVol</td><td>Yes, an IntPtr as the struct is not public</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virStorageVolDeleteFlags</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virStorageVolInfo</td><td>Yes</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virStorageVolType</td><td>Yes</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virStream</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virStreamEventType</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virStreamFlags</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virVcpuInfo</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>enum</td><td>virVcpuState</td><td>No</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>struct</td><td>virError</td><td>Yes</td><td>Yes</td><td>virConnectSetErrorFunc, virDomainStats</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h2><a name="funccover">Function Coverage</a></h2>
|
||||
|
||||
<p>
|
||||
Coverage of the libvirt functions is:
|
||||
</p>
|
||||
<table class="top_table">
|
||||
<tr><th>Name</th><th>Binding?</th><th>Type?</th><th>Tested?</th><th>Sample Code?</th><th>Working?</th><th>Tested .Net/Windows Works?</th><th>Tested Mono (32-bit)/Windows Works?</th><th>Tested Mono (64-bit)/Linux Works?</th></tr>
|
||||
<tr><td>virConnectAuthCallback</td><td>Yes</td><td>delegate</td><td>Yes</td><td>virConnectOpenAuth</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectBaselineCPU</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectClose</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpenAuth</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectCompareCPU</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainEventCallback</td><td>Yes</td><td>delegate</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainEventDeregister</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainEventDeregisterAny</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainEventGenericCallback</td><td>No</td><td>delegate</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainEventGraphicsCallback</td><td>No</td><td>delegate</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainEventIOErrorCallback</td><td>No</td><td>delegate</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainEventIOErrorReasonCallback</td><td>No</td><td>delegate</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainEventRTCChangeCallback</td><td>No</td><td>delegate</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainEventRegister</td><td>Yes</td><td>function</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectDomainEventRegisterAny</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainEventWatchdogCallback</td><td>No</td><td>delegate</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainXMLFromNative</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectDomainXMLToNative</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectFindStoragePoolSources</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectGetCapabilities</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectGetHostname</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectGetLibVersion</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectGetMaxVcpus</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectGetType</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectGetURI</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectGetVersion</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectIsEncrypted</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectIsSecure</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectListDefinedDomains</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpenAuth</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectListDefinedInterfaces </td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectListDefinedNetworks</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectListDefinedStoragePools</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectListDomains</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpenAuth, virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectListInterfaces</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes, if the host handle the method</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectListNWFilters </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectListNetworks</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectListSecrets</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectListStoragePools</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpen</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectNumOfDefinedDomains</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpenAuth</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectNumOfDefinedInterfaces</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectNumOfDefinedNetworks</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectNumOfDefinedStoragePools</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectNumOfDomains</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpenAuth, virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectNumOfInterfaces</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectNumOfNWFilters</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectNumOfNetworks </td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectNumOfSecrets</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectNumOfStoragePools</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpen</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectOpen</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpen, virEventRegisterImpl, virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectOpenAuth</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpenAuth</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnectOpenReadOnly</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virConnectRef</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainAbortJob</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainAttachDevice</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainAttachDeviceFlags</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainBlockPeek</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainBlockStats</td><td>Yes</td><td>function</td><td>Yes</td><td>virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virDomainCoreDump</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainCreate</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainCreateLinux</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainCreateWithFlags</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainCreateXML</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainDefineXML</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainDestroy</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainDetachDevice</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainDetachDeviceFlags</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainFree</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetAutostart</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetBlockInfo</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetConnect</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetID</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetInfo</td><td>Yes</td><td>function</td><td>Yes</td><td>virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virDomainGetJobInfo</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetMaxMemory</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetMaxVcpus</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetName</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpenAuth, virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virDomainGetOSType</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetSchedulerParameters</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetSchedulerType</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetSecurityLabel</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetUUID</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetUUIDString</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetVcpus</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainGetXMLDesc</td><td>Yes</td><td>function</td><td>Yes</td><td>virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virDomainHasCurrentSnapshot</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainHasManagedSaveImage</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainInterfaceStats </td><td>No</td><td>function</td><td>Yes</td><td>virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virDomainIsActive</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainIsPersistent</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainLookupByID</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectOpenAuth, virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virDomainLookupByName</td><td>Yes</td><td>function</td><td>Yes</td><td>virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virDomainLookupByUUID</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainLookupByUUIDString</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainManagedSave </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainManagedSaveRemove</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainMemoryPeek</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainMemoryStats</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainMigrate</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainMigrateSetMaxDowntime</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainMigrateToURI </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainPinVcpu</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainReboot</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainRef </td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainRestore</td><td>Yes </td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainResume </td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainRevertToSnapshot</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSave</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSetAutostart</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSetMaxMemory </td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSetMemory</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSetSchedulerParameters</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSetVcpus</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainShutdown</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSnapshotCreateXML</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSnapshotCurrent</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSnapshotDelete</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSnapshotFree</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSnapshotGetXMLDesc</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSnapshotListNames</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSnapshotLookupByName</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSnapshotNum</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainSuspend</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainUndefine</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virDomainUpdateDeviceFlags</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virEventAddHandleFunc</td><td>Yes</td><td>delegate</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virEventAddTimeoutFunc</td><td>Yes</td><td>delegate</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virEventHandleCallback</td><td>Yes</td><td>delegate</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virEventRegisterImpl</td><td>Yes</td><td>function</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virEventRemoveHandleFunc</td><td>Yes</td><td>delegate</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virEventRemoveTimeoutFunc</td><td>Yes</td><td>delegate</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virEventTimeoutCallback</td><td>Yes</td><td>delegate</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virEventUpdateHandleFunc</td><td>Yes</td><td>delegate</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virEventUpdateTimeoutFunc</td><td>Yes</td><td>delegate</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virFreeCallback</td><td>Yes</td><td>function</td><td>Yes</td><td>virEventRegisterImpl</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virGetVersion</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInitialize</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceCreate</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceDefineXML</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceDestroy</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceFree</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceGetConnect</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceGetMACString</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceGetName</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceGetXMLDesc</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceIsActive</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceLookupByMACString</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceLookupByName</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceRef </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virInterfaceUndefine</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterDefineXML</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterFree</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterGetName</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterGetUUID</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterGetUUIDString</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterGetXMLDesc</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterLookupByName </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterLookupByUUID</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterLookupByUUIDString</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterRef </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNWFilterUndefine</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkCreate</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkCreateXML</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkDefineXML</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkDestroy</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkFree</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkGetAutostart</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkGetBridgeName</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkGetConnect</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkGetName</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkGetUUID</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkGetUUIDString </td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkGetXMLDesc</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkIsActive</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkIsPersistent</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkLookupByName</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkLookupByUUID</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkLookupByUUIDString</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkRef</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkSetAutostart</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNetworkUndefine</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceCreateXML</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceDestroy</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceDettach</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceFree</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceGetName</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceGetParent</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceGetXMLDesc</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceListCaps</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceLookupByName</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceNumOfCaps</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceReAttach</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceRef</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeDeviceReset</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeGetCellsFreeMemory</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeGetFreeMemory</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeGetInfo</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeGetSecurityModel </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeListDevices</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virNodeNumOfDevices</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretDefineXML</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretFree </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretGetConnect</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretGetUUID</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretGetUUIDString </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretGetUsageID</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretGetUsageType</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretGetValue</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretGetXMLDesc</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretLookupByUUID</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretLookupByUUIDString</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretLookupByUsage</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretRef</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretSetValue</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virSecretUndefine</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolBuild</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolCreate</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolCreateXML </td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolDefineXML</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolDelete</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolDestroy</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolFree</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolGetAutostart</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolGetConnect</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolGetInfo</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolGetName</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolGetUUID</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolGetUUIDString</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolGetXMLDesc</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolIsActive</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolIsPersistent</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolListVolumes</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolLookupByName</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolLookupByUUID</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolLookupByUUIDString</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolLookupByVolume</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolNumOfVolumes</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolRef</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolRefresh</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolSetAutostart</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStoragePoolUndefine</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolCreateXML</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolCreateXMLFrom</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolDelete</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolFree</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolGetConnect </td><td>Yes</td><td>function</td><td>No</td><td> </td><td>Maybe</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolGetInfo</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolGetKey</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolGetName</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolGetPath</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolGetXMLDesc </td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolLookupByKey</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolLookupByName</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolLookupByPath</td><td>Yes</td><td>function</td><td>Yes</td><td> </td><td>Yes</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolRef</td><td>Yes</td><td>function</td><td>No</td><td> </td><td>No</td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStorageVolWipe</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamAbort </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamEventAddCallback</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamEventCallback</td><td>No</td><td>delegate</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamEventRemoveCallback</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamEventUpdateCallback</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamFinish </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamFree </td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamNew</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamRecv</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamRecvAll</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamRef</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamSend</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamSendAll</td><td>No</td><td>function</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamSinkFunc</td><td>No</td><td>delegate</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virStreamSourceFunc</td><td>No</td><td>delegate</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td>virGetLastError</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectSetErrorFunc</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virConnSetErrorFunc</td><td>Yes</td><td>function</td><td>Yes</td><td>virConnectSetErrorFunc</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
<tr><td>virErrorFunc</td><td>Yes</td><td>delegate</td><td>Yes</td><td>virConnectSetErrorFunc, virDomainInfos</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -1,48 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Deployment</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="packages">Pre-packaged releases</a></h2>
|
||||
|
||||
<p>
|
||||
The libvirt API is now available in all major Linux distributions,
|
||||
so the simplest deployment approach is to use your distributions'
|
||||
package management software to install the <code>libvirt</code>
|
||||
module.
|
||||
</p>
|
||||
|
||||
<h2><a name="tarball">Self-built releases</a></h2>
|
||||
|
||||
<p>
|
||||
libvirt uses GNU autotools for its build system, so deployment
|
||||
follows the usual process of <code>configure; make ; make install</code>
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
|
||||
# ./configure --prefix=$HOME/usr
|
||||
# make
|
||||
# make install
|
||||
</pre>
|
||||
|
||||
<h2><a name="git">Built from GIT</a></h2>
|
||||
|
||||
<p>
|
||||
When building from GIT it is necessary to generate the autotools
|
||||
support files. This requires having <code>autoconf</code>,
|
||||
<code>automake</code>, <code>libtool</code> and <code>intltool</code>
|
||||
installed. The process can be automated with the <code>autogen.sh</code>
|
||||
script.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
|
||||
# ./autogen.sh --prefix=$HOME/usr
|
||||
# make
|
||||
# make install
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,55 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1>libvirt Application Development Guide</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<p>
|
||||
The guide is both a learning tool for developing with libvirt and an
|
||||
API reference document. It is a work in progress, composed by a
|
||||
professional author from contributions written by members of the
|
||||
libvirt team.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Contributions to the guide are <b>VERY</b> welcome. If you'd like to get
|
||||
your name on this and demonstrate your virtualisation prowess, a solid
|
||||
contribution to the content here will do it. :)
|
||||
</p>
|
||||
|
||||
<h2><a name="online">Browsable online</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://libvirt.org/guide/html/">
|
||||
HTML format using multiple pages</a></li>
|
||||
<li><a href="http://libvirt.org/guide/html-single/">
|
||||
HTML format using one big page</a></li>
|
||||
<li><a href="http://libvirt.org/guide/pdf/Application_Development_Guide.pdf">
|
||||
PDF format</a></li>
|
||||
<li><a href="http://libvirt.org/guide/libvirt-0.7.5-Application_Development_Guide-en-US.epub">
|
||||
ePub format</a></li>
|
||||
<li><a href="http://libvirt.org/guide/txt/Application_Development_Guide.txt">
|
||||
Plain text format</a></li>
|
||||
<li><a href="http://libvirt.org/guide/libvirt-Application_Development_Guide-0.7.5-web-en-US-1-9.el5.src.rpm">
|
||||
Source RPM format</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="git">GIT source repository</a></h2>
|
||||
|
||||
<p>
|
||||
The source is in a git repository:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
git clone git://libvirt.org/libvirt-appdev-guide.git</pre>
|
||||
|
||||
<p>
|
||||
Browsable here:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<a href="http://libvirt.org/git/?p=libvirt-appdev-guide.git;a=summary">http://libvirt.org/git/?p=libvirt-appdev-guide.git;a=summary</a></pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,132 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
||||
xmlns="http://www.devhelp.net/book"
|
||||
xmlns:exsl="http://exslt.org/common"
|
||||
xmlns:str="http://exslt.org/strings"
|
||||
extension-element-prefixes="exsl str"
|
||||
exclude-result-prefixes="exsl str">
|
||||
<!-- The stylesheet for the html pages -->
|
||||
<xsl:import href="html.xsl"/>
|
||||
|
||||
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
|
||||
|
||||
<!-- Build keys for all symbols -->
|
||||
<xsl:key name="symbols" match="/api/symbols/*" use="@name"/>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:document xmlns="http://www.devhelp.net/book" href="libvirt.devhelp"
|
||||
method="xml" encoding="UTF-8" indent="yes">
|
||||
<xsl:apply-templates/>
|
||||
</xsl:document>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="/api">
|
||||
<book title="{@name} Reference Manual" link="index.html" author="" name="{@name}">
|
||||
<xsl:apply-templates select="files"/>
|
||||
<xsl:apply-templates select="symbols"/>
|
||||
</book>
|
||||
<xsl:call-template name="generate_index"/>
|
||||
<xsl:call-template name="generate_general"/>
|
||||
</xsl:template>
|
||||
<xsl:template match="/api/files">
|
||||
<chapters>
|
||||
<sub name="API" link="general.html">
|
||||
<xsl:apply-templates select="file"/>
|
||||
</sub>
|
||||
</chapters>
|
||||
</xsl:template>
|
||||
<xsl:template match="/api/files/file">
|
||||
<xsl:variable name="module" select="@name"/>
|
||||
<xsl:variable name="prev" select="string(preceding-sibling::file[position()=1]/@name)"/>
|
||||
<xsl:variable name="next" select="string(following-sibling::file[position()=1]/@name)"/>
|
||||
<sub name="{@name}" link="libvirt-{@name}.html"/>
|
||||
<xsl:document xmlns="" href="libvirt-{@name}.html" method="xml" indent="yes" encoding="UTF-8">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<title><xsl:value-of select="concat(@name, ': ', summary)"/></title>
|
||||
<meta name="generator" content="Libvirt devhelp stylesheet"/>
|
||||
<link rel="start" href="index.html" title="libvirt Reference Manual"/>
|
||||
<link rel="up" href="general.html" title="API"/>
|
||||
<link rel="stylesheet" href="style.css" type="text/css"/>
|
||||
<link rel="chapter" href="general.html" title="API"/>
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
|
||||
<table class="navigation" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
|
||||
<tr valign="middle">
|
||||
<xsl:if test="$prev != ''">
|
||||
<td><a accesskey="p" href="libvirt-{$prev}.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"/></a></td>
|
||||
</xsl:if>
|
||||
<td><a accesskey="u" href="general.html"><img src="up.png" width="24" height="24" border="0" alt="Up"/></a></td>
|
||||
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"/></a></td>
|
||||
<xsl:if test="$next != ''">
|
||||
<td><a accesskey="n" href="libvirt-{$next}.html"><img src="right.png" width="24" height="24" border="0" alt="Next"/></a></td>
|
||||
</xsl:if>
|
||||
<th width="100%" align="center">libvirt Reference Manual</th>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><span class="refentrytitle"><xsl:value-of select="@name"/></span></h2>
|
||||
<p><xsl:value-of select="@name"/> - <xsl:value-of select="summary"/></p>
|
||||
<p><xsl:value-of select="description"/></p>
|
||||
<xsl:if test="deprecated">
|
||||
<p> WARNING: this module is deprecated !</p>
|
||||
</xsl:if>
|
||||
<p>Author(s): <xsl:value-of select="author"/></p>
|
||||
<div class="refsynopsisdiv">
|
||||
<h2>Synopsis</h2>
|
||||
<pre class="synopsis">
|
||||
<xsl:apply-templates mode="synopsis" select="exports"/>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="refsect1" lang="en">
|
||||
<h2>Description</h2>
|
||||
</div>
|
||||
<div class="refsect1" lang="en">
|
||||
<h2>Details</h2>
|
||||
<div class="refsect2" lang="en">
|
||||
<xsl:apply-templates mode="details" select="/api/symbols/macro[@file=$module]"/>
|
||||
<xsl:apply-templates mode="details" select="/api/symbols/typedef[@file=$module] | /api/symbols/struct[@file=$module]"/>
|
||||
<xsl:apply-templates mode="details" select="/api/symbols/functype[@file=$module]"/>
|
||||
<xsl:apply-templates mode="details" select="/api/symbols/variable[@file=$module]"/>
|
||||
<xsl:apply-templates mode="details" select="/api/symbols/function[@file=$module]"/>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:document>
|
||||
</xsl:template>
|
||||
<xsl:template match="/api/symbols">
|
||||
<functions>
|
||||
<xsl:apply-templates select="macro"/>
|
||||
<xsl:apply-templates select="enum"/>
|
||||
<xsl:apply-templates select="typedef"/>
|
||||
<xsl:apply-templates select="struct"/>
|
||||
<xsl:apply-templates select="functype"/>
|
||||
<xsl:apply-templates select="variable"/>
|
||||
<xsl:apply-templates select="function"/>
|
||||
</functions>
|
||||
</xsl:template>
|
||||
<xsl:template match="/api/symbols/functype">
|
||||
<function name="{@name}" link="libvirt-{@file}.html#{@name}"/>
|
||||
</xsl:template>
|
||||
<xsl:template match="/api/symbols/function">
|
||||
<function name="{@name} ()" link="libvirt-{@file}.html#{@name}"/>
|
||||
</xsl:template>
|
||||
<xsl:template match="/api/symbols/typedef">
|
||||
<function name="{@name}" link="libvirt-{@file}.html#{@name}"/>
|
||||
</xsl:template>
|
||||
<xsl:template match="/api/symbols/enum">
|
||||
<function name="{@name}" link="libvirt-{@file}.html#{@name}"/>
|
||||
</xsl:template>
|
||||
<xsl:template match="/api/symbols/struct">
|
||||
<function name="{@name}" link="libvirt-{@file}.html#{@name}"/>
|
||||
</xsl:template>
|
||||
<xsl:template match="/api/symbols/macro">
|
||||
<function name="{@name}" link="libvirt-{@file}.html#{@name}"/>
|
||||
</xsl:template>
|
||||
<xsl:template match="/api/symbols/variable">
|
||||
<function name="{@name}" link="libvirt-{@file}.html#{@name}"/>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
Binary file not shown.
Before Width: | Height: | Size: 654 B |
@ -1,577 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
||||
xmlns:exsl="http://exslt.org/common"
|
||||
xmlns:str="http://exslt.org/strings"
|
||||
extension-element-prefixes="exsl str"
|
||||
exclude-result-prefixes="exsl str">
|
||||
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
|
||||
|
||||
<!-- This is convoluted but needed to force the current document to
|
||||
be the API one and not the result tree from the tokenize() result,
|
||||
because the keys are only defined on the main document -->
|
||||
<xsl:template mode="dumptoken" match='*'>
|
||||
<xsl:param name="token"/>
|
||||
<xsl:variable name="ref" select="key('symbols', $token)"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$ref">
|
||||
<a href="libvirt-{$ref/@file}.html#{$ref/@name}"><xsl:value-of select="$token"/></a>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$token"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!-- dumps a string, making cross-reference links -->
|
||||
<xsl:template name="dumptext">
|
||||
<xsl:param name="text"/>
|
||||
<xsl:variable name="ctxt" select='.'/>
|
||||
<!-- <xsl:value-of select="$text"/> -->
|
||||
<xsl:for-each select="str:tokenize($text, ' 	')">
|
||||
<xsl:apply-templates select="$ctxt" mode='dumptoken'>
|
||||
<xsl:with-param name="token" select="string(.)"/>
|
||||
</xsl:apply-templates>
|
||||
<xsl:if test="position() != last()">
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<!--
|
||||
|
||||
The following builds the Synopsis section
|
||||
|
||||
-->
|
||||
<xsl:template mode="synopsis" match="function">
|
||||
<xsl:variable name="name" select="string(@name)"/>
|
||||
<xsl:variable name="nlen" select="string-length($name)"/>
|
||||
<xsl:variable name="tlen" select="string-length(return/@type)"/>
|
||||
<xsl:variable name="blen" select="(($nlen + 8) - (($nlen + 8) mod 8)) + (($tlen + 8) - (($tlen + 8) mod 8))"/>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="return/@type"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text>	</xsl:text>
|
||||
<a href="#{@name}"><xsl:value-of select="@name"/></a>
|
||||
<xsl:if test="$blen - 40 < -8">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="$blen - 40 < 0">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>	(</xsl:text>
|
||||
<xsl:if test="not(arg)">
|
||||
<xsl:text>void</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:for-each select="arg">
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="@type"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="position() != last()">
|
||||
<xsl:text>, </xsl:text><br/>
|
||||
<xsl:if test="$blen - 40 > 8">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="$blen - 40 > 0">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>					 </xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:text>);</xsl:text>
|
||||
<xsl:text>
|
||||
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template mode="synopsis" match="functype">
|
||||
<xsl:variable name="name" select="string(@name)"/>
|
||||
<xsl:variable name="nlen" select="string-length($name)"/>
|
||||
<xsl:variable name="tlen" select="string-length(return/@type)"/>
|
||||
<xsl:variable name="blen" select="(($nlen + 8) - (($nlen + 8) mod 8)) + (($tlen + 8) - (($tlen + 8) mod 8))"/>
|
||||
<xsl:text>typedef </xsl:text>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="return/@type"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text> </xsl:text>
|
||||
<a href="#{@name}"><xsl:value-of select="@name"/></a>
|
||||
<xsl:if test="$blen - 40 < -8">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="$blen - 40 < 0">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>	(</xsl:text>
|
||||
<xsl:if test="not(arg)">
|
||||
<xsl:text>void</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:for-each select="arg">
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="@type"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="position() != last()">
|
||||
<xsl:text>, </xsl:text><br/>
|
||||
<xsl:if test="$blen - 40 > 8">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="$blen - 40 > 0">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>					 </xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:text>);</xsl:text>
|
||||
<xsl:text>
|
||||
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template mode="synopsis" match="exports[@type='function']">
|
||||
<xsl:variable name="def" select="key('symbols',@symbol)"/>
|
||||
<xsl:apply-templates mode="synopsis" select="$def"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template mode="synopsis" match="exports[@type='typedef']">
|
||||
<xsl:text>typedef </xsl:text>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="string(key('symbols',@symbol)/@type)"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text> </xsl:text>
|
||||
<a href="#{@symbol}"><xsl:value-of select="@symbol"/></a>
|
||||
<xsl:text>;
|
||||
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template mode="synopsis" match="exports[@type='macro']">
|
||||
<xsl:variable name="def" select="key('symbols',@symbol)"/>
|
||||
<xsl:text>#define </xsl:text>
|
||||
<a href="#{@symbol}"><xsl:value-of select="@symbol"/></a>
|
||||
<xsl:if test="$def/arg">
|
||||
<xsl:text>(</xsl:text>
|
||||
<xsl:for-each select="$def/arg">
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="position() != last()">
|
||||
<xsl:text>, </xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:text>)</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>;
|
||||
</xsl:text>
|
||||
</xsl:template>
|
||||
<xsl:template mode="synopsis" match="exports[@type='enum']">
|
||||
</xsl:template>
|
||||
<xsl:template mode="synopsis" match="exports[@type='struct']">
|
||||
</xsl:template>
|
||||
|
||||
<!--
|
||||
|
||||
The following builds the Details section
|
||||
|
||||
-->
|
||||
<xsl:template mode="details" match="struct">
|
||||
<xsl:variable name="name" select="string(@name)"/>
|
||||
<div class="refsect2" lang="en">
|
||||
<h3><a name="{$name}">Structure </a><xsl:value-of select="$name"/></h3>
|
||||
<pre class="programlisting">
|
||||
<xsl:value-of select="@type"/><xsl:text> {
|
||||
</xsl:text>
|
||||
<xsl:if test="not(field)">
|
||||
<xsl:text>The content of this structure is not made public by the API.
|
||||
</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:for-each select="field">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="@type"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text>	</xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="@info != ''">
|
||||
<xsl:text>	: </xsl:text>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="substring(@info, 1, 70)"/>
|
||||
</xsl:call-template>
|
||||
</xsl:if>
|
||||
<xsl:text>
|
||||
</xsl:text>
|
||||
</xsl:for-each>
|
||||
<xsl:text>} </xsl:text>
|
||||
<xsl:value-of select="$name"/>
|
||||
<xsl:text>;
|
||||
</xsl:text>
|
||||
</pre>
|
||||
<p>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="info"/>
|
||||
</xsl:call-template>
|
||||
</p><xsl:text>
|
||||
</xsl:text>
|
||||
</div><hr/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template mode="details" match="typedef[@type != 'enum']">
|
||||
<xsl:variable name="name" select="string(@name)"/>
|
||||
<div class="refsect2" lang="en">
|
||||
<h3><a name="{$name}">Typedef </a><xsl:value-of select="$name"/></h3>
|
||||
<pre class="programlisting">
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="string(@type)"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="$name"/>
|
||||
<xsl:text>;
|
||||
</xsl:text>
|
||||
</pre>
|
||||
<p>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="info"/>
|
||||
</xsl:call-template>
|
||||
</p><xsl:text>
|
||||
</xsl:text>
|
||||
</div><hr/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template mode="details" match="variable">
|
||||
<xsl:variable name="name" select="string(@name)"/>
|
||||
<div class="refsect2" lang="en">
|
||||
<h3><a name="{$name}">Variable </a><xsl:value-of select="$name"/></h3>
|
||||
<pre class="programlisting">
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="string(@type)"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="$name"/>
|
||||
<xsl:text>;
|
||||
</xsl:text>
|
||||
</pre>
|
||||
<p>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="info"/>
|
||||
</xsl:call-template>
|
||||
</p><xsl:text>
|
||||
</xsl:text>
|
||||
</div><hr/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template mode="details" match="typedef[@type = 'enum']">
|
||||
<xsl:variable name="name" select="string(@name)"/>
|
||||
<div class="refsect2" lang="en">
|
||||
<h3><a name="{$name}">Enum </a><xsl:value-of select="$name"/></h3>
|
||||
<pre class="programlisting">
|
||||
<xsl:text>enum </xsl:text>
|
||||
<a href="#{$name}"><xsl:value-of select="$name"/></a>
|
||||
<xsl:text> {
|
||||
</xsl:text>
|
||||
<xsl:for-each select="/api/symbols/enum[@type=$name]">
|
||||
<xsl:sort select="@value" data-type="number" order="ascending"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<a name="{@name}"><xsl:value-of select="@name"/></a>
|
||||
<xsl:if test="@value">
|
||||
<xsl:text> = </xsl:text>
|
||||
<xsl:value-of select="@value"/>
|
||||
</xsl:if>
|
||||
<xsl:if test="@info">
|
||||
<xsl:text> /* </xsl:text>
|
||||
<xsl:value-of select="@info"/>
|
||||
<xsl:text> */</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>
|
||||
</xsl:text>
|
||||
</xsl:for-each>
|
||||
<xsl:text>};
|
||||
</xsl:text>
|
||||
</pre>
|
||||
<p>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="info"/>
|
||||
</xsl:call-template>
|
||||
</p><xsl:text>
|
||||
</xsl:text>
|
||||
</div><hr/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template mode="details" match="macro">
|
||||
<xsl:variable name="name" select="string(@name)"/>
|
||||
<div class="refsect2" lang="en">
|
||||
<h3><a name="{$name}">Macro </a><xsl:value-of select="$name"/></h3>
|
||||
<pre class="programlisting">
|
||||
<xsl:text>#define </xsl:text>
|
||||
<a href="#{$name}"><xsl:value-of select="$name"/></a>
|
||||
<xsl:if test="arg">
|
||||
<xsl:text>(</xsl:text>
|
||||
<xsl:for-each select="arg">
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="position() != last()">
|
||||
<xsl:text>, </xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:text>)</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>;
|
||||
</xsl:text>
|
||||
</pre>
|
||||
<p>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="info"/>
|
||||
</xsl:call-template>
|
||||
</p>
|
||||
<xsl:if test="arg">
|
||||
<div class="variablelist"><table border="0"><col align="left"/><tbody>
|
||||
<xsl:for-each select="arg">
|
||||
<tr>
|
||||
<td><span class="term"><i><tt><xsl:value-of select="@name"/></tt></i>:</span></td>
|
||||
<td>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="@info"/>
|
||||
</xsl:call-template>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</tbody></table></div>
|
||||
</xsl:if>
|
||||
<xsl:text>
|
||||
</xsl:text>
|
||||
</div><hr/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template mode="details" match="function">
|
||||
<xsl:variable name="name" select="string(@name)"/>
|
||||
<xsl:variable name="nlen" select="string-length($name)"/>
|
||||
<xsl:variable name="tlen" select="string-length(return/@type)"/>
|
||||
<xsl:variable name="blen" select="(($nlen + 8) - (($nlen + 8) mod 8)) + (($tlen + 8) - (($tlen + 8) mod 8))"/>
|
||||
<div class="refsect2" lang="en">
|
||||
<h3><a name="{$name}"></a><xsl:value-of select="$name"/> ()</h3>
|
||||
<pre class="programlisting">
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="return/@type"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text>	</xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="$blen - 40 < -8">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="$blen - 40 < 0">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>	(</xsl:text>
|
||||
<xsl:if test="not(arg)">
|
||||
<xsl:text>void</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:for-each select="arg">
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="@type"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="position() != last()">
|
||||
<xsl:text>, </xsl:text><br/>
|
||||
<xsl:if test="$blen - 40 > 8">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="$blen - 40 > 0">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>					 </xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:text>)</xsl:text><br/>
|
||||
<xsl:text>
|
||||
</xsl:text>
|
||||
</pre>
|
||||
<p>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="info"/>
|
||||
</xsl:call-template>
|
||||
</p><xsl:text>
|
||||
</xsl:text>
|
||||
<xsl:if test="arg | return/@info">
|
||||
<div class="variablelist"><table border="0"><col align="left"/><tbody>
|
||||
<xsl:for-each select="arg">
|
||||
<tr>
|
||||
<td><span class="term"><i><tt><xsl:value-of select="@name"/></tt></i>:</span></td>
|
||||
<td>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="@info"/>
|
||||
</xsl:call-template>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
<xsl:if test="return/@info">
|
||||
<tr>
|
||||
<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
|
||||
<td>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="return/@info"/>
|
||||
</xsl:call-template>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
</tbody></table></div>
|
||||
</xsl:if>
|
||||
</div><hr/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template mode="details" match="functype">
|
||||
<xsl:variable name="name" select="string(@name)"/>
|
||||
<xsl:variable name="nlen" select="string-length($name)"/>
|
||||
<xsl:variable name="tlen" select="string-length(return/@type)"/>
|
||||
<xsl:variable name="blen" select="(($nlen + 8) - (($nlen + 8) mod 8)) + (($tlen + 8) - (($tlen + 8) mod 8))"/>
|
||||
<div class="refsect2" lang="en">
|
||||
<h3><a name="{$name}"></a>Function type <xsl:value-of select="$name"/> </h3>
|
||||
<pre class="programlisting">
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="return/@type"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text>	</xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="$blen - 40 < -8">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="$blen - 40 < 0">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>	(</xsl:text>
|
||||
<xsl:if test="not(arg)">
|
||||
<xsl:text>void</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:for-each select="arg">
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="@type"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="position() != last()">
|
||||
<xsl:text>, </xsl:text><br/>
|
||||
<xsl:if test="$blen - 40 > 8">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="$blen - 40 > 0">
|
||||
<xsl:text>	</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>					 </xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:text>)</xsl:text><br/>
|
||||
<xsl:text>
|
||||
</xsl:text>
|
||||
</pre>
|
||||
<p>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="info"/>
|
||||
</xsl:call-template>
|
||||
</p><xsl:text>
|
||||
</xsl:text>
|
||||
<xsl:if test="arg | return/@info">
|
||||
<div class="variablelist"><table border="0"><col align="left"/><tbody>
|
||||
<xsl:for-each select="arg">
|
||||
<tr>
|
||||
<td><span class="term"><i><tt><xsl:value-of select="@name"/></tt></i>:</span></td>
|
||||
<td>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="@info"/>
|
||||
</xsl:call-template>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
<xsl:if test="return/@info">
|
||||
<tr>
|
||||
<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
|
||||
<td>
|
||||
<xsl:call-template name="dumptext">
|
||||
<xsl:with-param name="text" select="return/@info"/>
|
||||
</xsl:call-template>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
</tbody></table></div>
|
||||
</xsl:if>
|
||||
</div><hr/>
|
||||
</xsl:template>
|
||||
|
||||
<!--
|
||||
|
||||
The following builds the general.html page
|
||||
|
||||
-->
|
||||
<xsl:template name="generate_general">
|
||||
<xsl:variable name="next" select="string(/api/files/file[position()=1]/@name)"/>
|
||||
<xsl:document xmlns="" href="general.html" method="xml" indent="yes" encoding="UTF-8">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<title><xsl:value-of select="concat(@name, ': ', summary)"/></title>
|
||||
<meta name="generator" content="Libvirt devhelp stylesheet"/>
|
||||
<link rel="start" href="index.html" title="libvirt Reference Manual"/>
|
||||
<link rel="up" href="index.html" title="libvirt Reference Manual"/>
|
||||
<link rel="stylesheet" href="style.css" type="text/css"/>
|
||||
<link rel="chapter" href="index.html" title="libvirt Reference Manual"/>
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
|
||||
<table class="navigation" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
|
||||
<tr valign="middle">
|
||||
<td><a accesskey="u" href="index.html"><img src="up.png" width="24" height="24" border="0" alt="Up"/></a></td>
|
||||
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"/></a></td>
|
||||
<xsl:if test="$next != ''">
|
||||
<td><a accesskey="n" href="libvirt-{$next}.html"><img src="right.png" width="24" height="24" border="0" alt="Next"/></a></td>
|
||||
</xsl:if>
|
||||
<th width="100%" align="center">libvirt Reference Manual</th>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><span class="refentrytitle">libvirt API Modules</span></h2>
|
||||
<p>
|
||||
<xsl:for-each select="/api/files/file">
|
||||
<a href="libvirt-{@name}.html"><xsl:value-of select="@name"/></a> - <xsl:value-of select="summary"/><br/>
|
||||
</xsl:for-each>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:document>
|
||||
</xsl:template>
|
||||
|
||||
<!--
|
||||
|
||||
The following builds the index.html page
|
||||
|
||||
-->
|
||||
<xsl:template name="generate_index">
|
||||
<xsl:document xmlns="" href="index.html" method="xml" indent="yes" encoding="UTF-8">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<title>libvirt Reference Manual</title>
|
||||
<meta name="generator" content="Libvirt devhelp stylesheet"/>
|
||||
<link rel="stylesheet" href="style.css" type="text/css"/>
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
|
||||
<table class="navigation" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
|
||||
<tr valign="middle">
|
||||
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"/></a></td>
|
||||
<td><a accesskey="n" href="general.html"><img src="right.png" width="24" height="24" border="0" alt="Next"/></a></td>
|
||||
<th width="100%" align="center">libvirt Reference Manual</th>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><span class="refentrytitle">libvirt Reference Manual</span></h2>
|
||||
<p>Libvir is a C toolkit to interact with the virtualization capabilities of
|
||||
recent versions of Linux (and other OSes). It is free software available
|
||||
under the <a href="http://www.opensource.org/licenses/lgpl-license.html">GNU
|
||||
Lesser General Public License</a>. Virtualization of the Linux Operating
|
||||
System means the ability to run multiple instances of Operating Systems
|
||||
concurrently on a single hardware system where the basic resources are driven
|
||||
by a Linux instance. The library aim at providing long term stable C API
|
||||
initially for the <a href="http://www.cl.cam.ac.uk/Research/SRG/netos/xen/index.html">Xen
|
||||
paravirtualization</a> but should be able to integrate other virtualization
|
||||
mechanisms if needed.</p>
|
||||
<p> If you get lost searching for some specific API use, try
|
||||
<a href="http://libvirt.org/search.php">the online search
|
||||
engine</a> hosted on <a href="http://libvirt.org/">libvirt.org</a>
|
||||
it indexes the project page, the APIs as well as the mailing-list archives. </p>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:document>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
Binary file not shown.
Before Width: | Height: | Size: 459 B |
Binary file not shown.
Before Width: | Height: | Size: 472 B |
@ -1,66 +0,0 @@
|
||||
.synopsis, .classsynopsis
|
||||
{
|
||||
background: #eeeeee;
|
||||
border: solid 1px #aaaaaa;
|
||||
padding: 0.5em;
|
||||
}
|
||||
.programlisting
|
||||
{
|
||||
background: #eeeeff;
|
||||
border: solid 1px #aaaaff;
|
||||
padding: 0.5em;
|
||||
}
|
||||
.variablelist
|
||||
{
|
||||
padding: 4px;
|
||||
margin-left: 3em;
|
||||
}
|
||||
.variablelist td:first-child
|
||||
{
|
||||
vertical-align: top;
|
||||
}
|
||||
table.navigation
|
||||
{
|
||||
background: #ffeeee;
|
||||
border: solid 1px #ffaaaa;
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.navigation a
|
||||
{
|
||||
color: #770000;
|
||||
}
|
||||
.navigation a:visited
|
||||
{
|
||||
color: #550000;
|
||||
}
|
||||
.navigation .title
|
||||
{
|
||||
font-size: 200%;
|
||||
}
|
||||
div.refnamediv
|
||||
{
|
||||
margin-top: 2em;
|
||||
}
|
||||
div.gallery-float
|
||||
{
|
||||
float: left;
|
||||
padding: 10px;
|
||||
}
|
||||
div.gallery-float img
|
||||
{
|
||||
border-style: none;
|
||||
}
|
||||
div.gallery-spacer
|
||||
{
|
||||
clear: both;
|
||||
}
|
||||
a
|
||||
{
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover
|
||||
{
|
||||
text-decoration: underline;
|
||||
color: #FF0000;
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 406 B |
@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Documentation</h1>
|
||||
</body>
|
||||
</html>
|
@ -1,99 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1>Downloads</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="releases">Official Releases</a></h2>
|
||||
|
||||
<p>
|
||||
The latest versions of the libvirt C library can be downloaded from:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="ftp://libvirt.org/libvirt/">libvirt.org FTP server</a></li>
|
||||
<li><a href="http://libvirt.org/sources/">libvirt.org HTTP server</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="hourly">Hourly development snapshots</a></h2>
|
||||
|
||||
<p>
|
||||
Once an hour, an automated snapshot is made from the git server
|
||||
source tree. These snapshots should be usable, but we make no guarantees
|
||||
about their stability:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="ftp://libvirt.org/libvirt/libvirt-git-snapshot.tar.gz">libvirt.org FTP server</a></li>
|
||||
<li><a href="http://libvirt.org/sources/libvirt-git-snapshot.tar.gz">libvirt.org HTTP server</a></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="git">GIT source repository</a></h2>
|
||||
|
||||
<p>
|
||||
Libvirt code source is now maintained in a <a href="http://git-scm.com/">git</a>
|
||||
repository available on <a href="http://libvirt.org/git/">libvirt.org</a>:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
git clone git://libvirt.org/libvirt.git</pre>
|
||||
|
||||
<p>
|
||||
It can also be browsed at:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<a href="http://libvirt.org/git/?p=libvirt.git;a=summary">http://libvirt.org/git/?p=libvirt.git;a=summary</a></pre>
|
||||
|
||||
<br />
|
||||
|
||||
<h1>libvirt Application Development Guide</h1>
|
||||
|
||||
<p>
|
||||
The guide is both a learning tool for developing with libvirt and an
|
||||
API reference document. It is a work in progress, composed by a
|
||||
professional author from contributions written by members of the
|
||||
libvirt team.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Contributions to the guide are <b>VERY</b> welcome. If you'd like to get
|
||||
your name on this and demonstrate your virtualisation prowess, a solid
|
||||
contribution to the content here will do it. :)
|
||||
</p>
|
||||
|
||||
<h2><a name="appdevpdf">Application Development Guide PDF</a></h2>
|
||||
|
||||
<p>
|
||||
PDF download is available here:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://libvirt.org/guide/pdf/Application_Development_Guide.pdf">libvirt App Dev Guide</a> (PDF)</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="appdevgit">Application Development Guide source GIT repository</a></h2>
|
||||
|
||||
<p>
|
||||
The source is also in a git repository:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
git clone git://libvirt.org/libvirt-appdev-guide.git</pre>
|
||||
|
||||
<p>
|
||||
Browsable at:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<a href="http://libvirt.org/git/?p=libvirt-appdev-guide.git;a=summary">http://libvirt.org/git/?p=libvirt-appdev-guide.git;a=summary</a></pre>
|
||||
|
||||
<br />
|
||||
|
||||
<p>
|
||||
Once you've have obtained the libvirt source code, you can compile it
|
||||
using the <a href="compiling.html">instructions here</a>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -1,47 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Internal drivers</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<p>
|
||||
The libvirt public API delegates its implementation to one or
|
||||
more internal drivers, depending on the <a href="uri.html">connection URI</a>
|
||||
passed when initializing the library. There is always a hypervisor driver
|
||||
active, and if the libvirt daemon is available there will usually be a
|
||||
network and storage driver active.
|
||||
</p>
|
||||
|
||||
<h2><a name="hypervisor">Hypervisor drivers</a></h2>
|
||||
|
||||
<p>
|
||||
The hypervisor drivers currently supported by libvirt are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><strong><a href="drvlxc.html">LXC</a></strong> - Linux Containers</li>
|
||||
<li><strong><a href="drvopenvz.html">OpenVZ</a></strong></li>
|
||||
<li><strong><a href="drvqemu.html">QEMU</a></strong></li>
|
||||
<li><strong><a href="drvtest.html">Test</a></strong> - Used for testing</li>
|
||||
<li><strong><a href="drvuml.html">UML</a></strong> - User Mode Linux</li>
|
||||
<li><strong><a href="drvvbox.html">VirtualBox</a></strong></li>
|
||||
<li><strong><a href="drvesx.html">VMware ESX</a></strong></li>
|
||||
<li><strong><a href="drvvmware.html">VMware Workstation/Player</a></strong></li>
|
||||
<li><strong><a href="drvxen.html">Xen</a></strong></li>
|
||||
<li><strong><a href="drvhyperv.html">Microsoft Hyper-V</a></strong></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="stroage">Storage drivers</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><strong><a href="storage.html#StorageBackendDir">Directory backend</a></strong></li>
|
||||
<li><strong><a href="storage.html#StorageBackendFS">Local filesystem backend</a></strong></li>
|
||||
<li><strong><a href="storage.html#StorageBackendNetFS">Network filesystem backend</a></strong></li>
|
||||
<li><strong><a href="storage.html#StorageBackendLogical">Logical Volume Manager (LVM) backend</a></strong></li>
|
||||
<li><strong><a href="storage.html#StorageBackendDisk">Disk backend</a></strong></li>
|
||||
<li><strong><a href="storage.html#StorageBackendISCSI">iSCSI backend</a></strong></li>
|
||||
<li><strong><a href="storage.html#StorageBackendSCSI">SCSI backend</a></strong></li>
|
||||
<li><strong><a href="storage.html#StorageBackendMultipath">Multipath backend</a></strong></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
@ -1,819 +0,0 @@
|
||||
<html><body>
|
||||
<h1>VMware ESX hypervisor driver</h1>
|
||||
<ul id="toc"></ul>
|
||||
<p>
|
||||
The libvirt VMware ESX driver can manage VMware ESX/ESXi 3.5/4.x and
|
||||
VMware GSX 2.0, also called VMware Server 2.0, and possibly later
|
||||
versions. <span class="since">Since 0.8.3</span> the driver can also
|
||||
connect to a VMware vCenter 2.5/4.x (VPX).
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.vmware.com/">VMware ESX and GSX</a>
|
||||
hypervisors
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="prereq">Deployment pre-requisites</a></h2>
|
||||
<p>
|
||||
None. Any out-of-the-box installation of VPX/ESX(i)/GSX should work. No
|
||||
preparations are required on the server side, no libvirtd must be
|
||||
installed on the ESX server. The driver uses version 2.5 of the remote,
|
||||
SOAP based
|
||||
<a href="http://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/">
|
||||
VMware Virtual Infrastructure API</a> (VI API) to communicate with the
|
||||
ESX server, like the VMware Virtual Infrastructure Client (VI client)
|
||||
does. Since version 4.0 this API is called
|
||||
<a href="http://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/">
|
||||
VMware vSphere API</a>.
|
||||
</p>
|
||||
|
||||
<h2><a name="uri">Connections to the VMware ESX driver</a></h2>
|
||||
<p>
|
||||
Some example remote connection URIs for the driver are:
|
||||
</p>
|
||||
<pre>
|
||||
vpx://example-vcenter.com/dc1/srv1 (VPX over HTTPS, select ESX server 'srv1' in datacenter 'dc1')
|
||||
esx://example-esx.com (ESX over HTTPS)
|
||||
gsx://example-gsx.com (GSX over HTTPS)
|
||||
esx://example-esx.com/?transport=http (ESX over HTTP)
|
||||
esx://example-esx.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the server's SSL certificate)
|
||||
</pre>
|
||||
<p>
|
||||
<strong>Note</strong>: In contrast to other drivers, the ESX driver is
|
||||
a client-side-only driver. It connects to the ESX server using HTTP(S).
|
||||
Therefore, the <a href="remote.html">remote transport mechanism</a>
|
||||
provided by the remote driver and libvirtd will not work, and you
|
||||
cannot use URIs like <code>esx+ssh://example.com</code>.
|
||||
</p>
|
||||
|
||||
|
||||
<h3><a name="uriformat">URI Format</a></h3>
|
||||
<p>
|
||||
URIs have this general form (<code>[...]</code> marks an optional part).
|
||||
</p>
|
||||
<pre>
|
||||
type://[username@]hostname[:port]/[[folder/...]datacenter/[folder/...][cluster/]server][?extraparameters]
|
||||
</pre>
|
||||
<p>
|
||||
The <code>type://</code> is either <code>esx://</code> or
|
||||
<code>gsx://</code> or <code>vpx://</code> <span class="since">since 0.8.3</span>.
|
||||
The driver selects the default port depending on the <code>type://</code>.
|
||||
For <code>esx://</code> and <code>vpx://</code> the default HTTPS port
|
||||
is 443, for <code>gsx://</code> it is 8333.
|
||||
If the port parameter is given, it overrides the default port.
|
||||
</p>
|
||||
<p>
|
||||
A <code>vpx://</code> connection is currently restricted to a single
|
||||
ESX server. This might be relaxed in the future. The path part of the
|
||||
URI is used to specify the datacenter and the ESX server in it. If the
|
||||
ESX server is part of a cluster then the cluster has to be specified too.
|
||||
</p>
|
||||
<p>
|
||||
An example: ESX server <code>example-esx.com</code> is managed by
|
||||
vCenter <code>example-vcenter.com</code> and part of cluster
|
||||
<code>cluster1</code>. This cluster is part of datacenter <code>dc1</code>.
|
||||
</p>
|
||||
<pre>
|
||||
vpx://example-vcenter.com/dc1/cluster1/example-esx.com
|
||||
</pre>
|
||||
<p>
|
||||
Datacenters and clusters can be organized in folders, those have to be
|
||||
specified as well. The driver can handle folders
|
||||
<span class="since">since 0.9.7</span>.
|
||||
</p>
|
||||
<pre>
|
||||
vpx://example-vcenter.com/folder1/dc1/folder2/example-esx.com
|
||||
</pre>
|
||||
|
||||
|
||||
<h4><a name="extraparams">Extra parameters</a></h4>
|
||||
<p>
|
||||
Extra parameters can be added to a URI as part of the query string
|
||||
(the part following <code>?</code>). A single parameter is formed by a
|
||||
<code>name=value</code> pair. Multiple parameters are separated by
|
||||
<code>&</code>.
|
||||
</p>
|
||||
<pre>
|
||||
?<span style="color: #E50000">no_verify=1</span>&<span style="color: #00B200">auto_answer=1</span>&<span style="color: #0000E5">proxy=socks://example-proxy.com:23456</span>
|
||||
</pre>
|
||||
<p>
|
||||
The driver understands the extra parameters shown below.
|
||||
</p>
|
||||
<table class="top_table">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Values</th>
|
||||
<th>Meaning</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>transport</code>
|
||||
</td>
|
||||
<td>
|
||||
<code>http</code> or <code>https</code>
|
||||
</td>
|
||||
<td>
|
||||
Overrides the default HTTPS transport. For <code>esx://</code>
|
||||
and <code>vpx://</code> the default HTTP port is 80, for
|
||||
<code>gsx://</code> it is 8222.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>vcenter</code>
|
||||
</td>
|
||||
<td>
|
||||
Hostname of a VMware vCenter or <code>*</code>
|
||||
</td>
|
||||
<td>
|
||||
In order to perform a migration the driver needs to know the
|
||||
VMware vCenter for the ESX server. If set to <code>*</code>,
|
||||
the driver connects to the vCenter known to the ESX server.
|
||||
This parameter in useful when connecting to an ESX server only.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>no_verify</code>
|
||||
</td>
|
||||
<td>
|
||||
<code>0</code> or <code>1</code>
|
||||
</td>
|
||||
<td>
|
||||
If set to 1, this disables libcurl client checks of the server's
|
||||
SSL certificate. The default value it 0. See the
|
||||
<a href="#certificates">Certificates for HTTPS</a> section for
|
||||
details.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>auto_answer</code>
|
||||
</td>
|
||||
<td>
|
||||
<code>0</code> or <code>1</code>
|
||||
</td>
|
||||
<td>
|
||||
If set to 1, the driver answers all
|
||||
<a href="#questions">questions</a> with the default answer.
|
||||
If set to 0, questions are reported as errors. The default
|
||||
value it 0. <span class="since">Since 0.7.5</span>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>proxy</code>
|
||||
</td>
|
||||
<td>
|
||||
<code>[type://]hostname[:port]</code>
|
||||
</td>
|
||||
<td>
|
||||
Allows to specify a proxy for HTTP and HTTPS communication.
|
||||
<span class="since">Since 0.8.2</span>.
|
||||
The optional <code>type</code> part may be one of:
|
||||
<code>http</code>, <code>socks</code>, <code>socks4</code>,
|
||||
<code>socks4a</code> or <code>socks5</code>. The default is
|
||||
<code>http</code> and <code>socks</code> is synonymous for
|
||||
<code>socks5</code>. The optional <code>port</code> allows to
|
||||
override the default port 1080.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<h3><a name="auth">Authentication</a></h3>
|
||||
<p>
|
||||
In order to perform any useful operation the driver needs to log into
|
||||
the ESX server. Therefore, only <code>virConnectOpenAuth</code> can be
|
||||
used to connect to an ESX server, <code>virConnectOpen</code> and
|
||||
<code>virConnectOpenReadOnly</code> don't work.
|
||||
To log into an ESX server or vCenter the driver will request
|
||||
credentials using the callback passed to the
|
||||
<code>virConnectOpenAuth</code> function. The driver passes the
|
||||
hostname as challenge parameter to the callback. This enables the
|
||||
callback to distinguish between requests for ESX server and vCenter.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Note</strong>: During the ongoing driver development, testing
|
||||
is done using an unrestricted <code>root</code> account. Problems may
|
||||
occur if you use a restricted account. Detailed testing with restricted
|
||||
accounts has not been done yet.
|
||||
</p>
|
||||
|
||||
|
||||
<h3><a name="certificates">Certificates for HTTPS</a></h3>
|
||||
<p>
|
||||
By default the ESX driver uses HTTPS to communicate with an ESX server.
|
||||
Proper HTTPS communication requires correctly configured SSL
|
||||
certificates. This certificates are different from the ones libvirt
|
||||
uses for <a href="remote.html">secure communication over TLS</a> to a
|
||||
libvirtd one a remote server.
|
||||
</p>
|
||||
<p>
|
||||
By default the driver tries to verify the server's SSL certificate
|
||||
using the CA certificate pool installed on your client computer. With
|
||||
an out-of-the-box installed ESX server this won't work, because a newly
|
||||
installed ESX server uses auto-generated self-signed certificates.
|
||||
Those are singed by a CA certificate that is typically not known to your
|
||||
client computer and libvirt will report an error like this one:
|
||||
</p>
|
||||
<pre>
|
||||
error: internal error curl_easy_perform() returned an error: Peer certificate cannot be authenticated with known CA certificates (60)
|
||||
</pre>
|
||||
<p>
|
||||
Where are two ways to solve this problem:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Use the <code>no_verify=1</code> <a href="#extraparams">extra parameter</a>
|
||||
to disable server certificate verification.
|
||||
</li>
|
||||
<li>
|
||||
Generate new SSL certificates signed by a CA known to your client
|
||||
computer and replace the original ones on your ESX server. See the
|
||||
section <i>Replace a Default Certificate with a CA-Signed Certificate</i>
|
||||
in the <a href="http://www.vmware.com/pdf/vsphere4/r40/vsp_40_esx_server_config.pdf">ESX Configuration Guide</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a name="connproblems">Connection problems</a></h3>
|
||||
<p>
|
||||
There are also other causes for connection problems than the
|
||||
<a href="#certificates">HTTPS certificate</a> related ones.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
As stated before the ESX driver doesn't need the
|
||||
<a href="remote.html">remote transport mechanism</a>
|
||||
provided by the remote driver and libvirtd, nor does the ESX driver
|
||||
support it. Therefore, using an URI including a transport in the
|
||||
scheme won't work. Only <a href="#uriformat">URIs as described</a>
|
||||
are supported by the ESX driver. Here's a collection of possible
|
||||
error messages:
|
||||
<pre>
|
||||
$ virsh -c esx+tcp://example.com/
|
||||
error: unable to connect to libvirtd at 'example.com': Connection refused
|
||||
</pre>
|
||||
<pre>
|
||||
$ virsh -c esx+tls://example.com/
|
||||
error: Cannot access CA certificate '/etc/pki/CA/cacert.pem': No such file or directory
|
||||
</pre>
|
||||
<pre>
|
||||
$ virsh -c esx+ssh://example.com/
|
||||
error: cannot recv data: ssh: connect to host example.com port 22: Connection refused
|
||||
</pre>
|
||||
<pre>
|
||||
$ virsh -c esx+ssh://example.com/
|
||||
error: cannot recv data: Resource temporarily unavailable
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
<span class="since">Since 0.7.0</span> libvirt contains the ESX
|
||||
driver. Earlier versions of libvirt will report a misleading error
|
||||
about missing certificates when you try to connect to an ESX server.
|
||||
<pre>
|
||||
$ virsh -c esx://example.com/
|
||||
error: Cannot access CA certificate '/etc/pki/CA/cacert.pem': No such file or directory
|
||||
</pre>
|
||||
<p>
|
||||
Don't let this error message confuse you. Setting up certificates
|
||||
as described on the <a href="remote.html#Remote_certificates">remote transport mechanism</a> page
|
||||
does not help, as this is not a certificate related problem.
|
||||
</p>
|
||||
<p>
|
||||
To fix this problem you need to update your libvirt to 0.7.0 or newer.
|
||||
You may also see this error when you use a libvirt version that
|
||||
contains the ESX driver but you or your distro disabled the ESX
|
||||
driver during compilation. <span class="since">Since 0.8.3</span>
|
||||
the error message has been improved in this case:
|
||||
</p>
|
||||
<pre>
|
||||
$ virsh -c esx://example.com/
|
||||
error: invalid argument in libvirt was built without the 'esx' driver
|
||||
</pre>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2><a name="questions">Questions blocking tasks</a></h2>
|
||||
<p>
|
||||
Some methods of the VI API start tasks, for example
|
||||
<code>PowerOnVM_Task()</code>. Such tasks may be blocked by questions
|
||||
if the ESX server detects an issue with the domain that requires user
|
||||
interaction. The ESX driver cannot prompt the user to answer a
|
||||
question, libvirt doesn't have an API for something like this.
|
||||
</p>
|
||||
<p>
|
||||
The VI API provides the <code>AnswerVM()</code> method to
|
||||
programmatically answer a questions. So the driver has two options
|
||||
how to handle such a situation: either answer the questions with the
|
||||
default answer or report the question as an error and cancel the
|
||||
blocked task if possible. The
|
||||
<a href="#uriformat"><code>auto_answer</code></a> query parameter
|
||||
controls the answering behavior.
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name="xmlspecial">Specialties in the domain XML config</a></h2>
|
||||
<p>
|
||||
There are several specialties in the domain XML config for ESX domains.
|
||||
</p>
|
||||
|
||||
<h3><a name="restrictions">Restrictions</a></h3>
|
||||
<p>
|
||||
There are some restrictions for some values of the domain XML config.
|
||||
The driver will complain if this restrictions are violated.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Memory size has to be a multiple of 4096
|
||||
</li>
|
||||
<li>
|
||||
Number of virtual CPU has to be 1 or a multiple of 2
|
||||
</li>
|
||||
<li>
|
||||
Valid MAC address prefixes are <code>00:0c:29</code> and
|
||||
<code>00:50:56</code>. <span class="since">Since 0.7.6</span>
|
||||
arbitrary <a href="#macaddresses">MAC addresses</a> are supported.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a name="datastore">Datastore references</a></h3>
|
||||
<p>
|
||||
Storage is managed in datastores. VMware uses a special path format to
|
||||
reference files in a datastore. Basically, the datastore name is put
|
||||
into squared braces in front of the path.
|
||||
</p>
|
||||
<pre>
|
||||
[datastore] directory/filename
|
||||
</pre>
|
||||
<p>
|
||||
To define a new domain the driver converts the domain XML into a
|
||||
VMware VMX file and uploads it to a datastore known to the ESX server.
|
||||
Because multiple datastores may be known to an ESX server the driver
|
||||
needs to decide to which datastore the VMX file should be uploaded.
|
||||
The driver deduces this information from the path of the source of the
|
||||
first file-based harddisk listed in the domain XML.
|
||||
</p>
|
||||
|
||||
|
||||
<h3><a name="macaddresses">MAC addresses</a></h3>
|
||||
<p>
|
||||
VMware has registered two MAC address prefixes for domains:
|
||||
<code>00:0c:29</code> and <code>00:50:56</code>. These prefixes are
|
||||
split into ranges for different purposes.
|
||||
</p>
|
||||
<table class="top_table">
|
||||
<tr>
|
||||
<th>Range</th>
|
||||
<th>Purpose</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>00:0c:29:00:00:00</code> - <code>00:0c:29:ff:ff:ff</code>
|
||||
</td>
|
||||
<td>
|
||||
An ESX server autogenerates MAC addresses from this range if
|
||||
the VMX file doesn't contain a MAC address when trying to start
|
||||
a domain.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>00:50:56:00:00:00</code> - <code>00:50:56:3f:ff:ff</code>
|
||||
</td>
|
||||
<td>
|
||||
MAC addresses from this range can by manually assigned by the
|
||||
user in the VI client.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>00:50:56:80:00:00</code> - <code>00:50:56:bf:ff:ff</code>
|
||||
</td>
|
||||
<td>
|
||||
A VI client autogenerates MAC addresses from this range for
|
||||
newly defined domains.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
The VMX files generated by the ESX driver always contain a MAC address,
|
||||
because libvirt generates a random one if an interface element in the
|
||||
domain XML file lacks a MAC address.
|
||||
<span class="since">Since 0.7.6</span> the ESX driver sets the prefix
|
||||
for generated MAC addresses to <code>00:0c:29</code>. Before 0.7.6
|
||||
the <code>00:50:56</code> prefix was used. Sometimes this resulted in
|
||||
the generation of out-of-range MAC address that were rejected by the
|
||||
ESX server.
|
||||
</p>
|
||||
<p>
|
||||
Also <span class="since">since 0.7.6</span> every MAC address outside
|
||||
this ranges can be used. For such MAC addresses the ESX server-side
|
||||
check is disabled in the VMX file to stop the ESX server from rejecting
|
||||
out-of-predefined-range MAC addresses.
|
||||
</p>
|
||||
<pre>
|
||||
ethernet0.checkMACAddress = "false"
|
||||
</pre>
|
||||
|
||||
|
||||
<h3><a name="hardware">Available hardware</a></h3>
|
||||
<p>
|
||||
VMware ESX supports different models of SCSI controllers and network
|
||||
cards.
|
||||
</p>
|
||||
|
||||
<h4>SCSI controller models</h4>
|
||||
<dl>
|
||||
<dt><code>auto</code></dt>
|
||||
<dd>
|
||||
This isn't a actual controller model. If specified the ESX driver
|
||||
tries to detect the SCSI controller model referenced in the
|
||||
<code>.vmdk</code> file and use it. Autodetection fails when a
|
||||
SCSI controller has multiple disks attached and the SCSI controller
|
||||
models referenced in the <code>.vmdk</code> files are inconsistent.
|
||||
<span class="since">Since 0.8.3</span>
|
||||
</dd>
|
||||
<dt><code>buslogic</code></dt>
|
||||
<dd>
|
||||
BusLogic SCSI controller for older guests.
|
||||
</dd>
|
||||
<dt><code>lsilogic</code></dt>
|
||||
<dd>
|
||||
LSI Logic SCSI controller for recent guests.
|
||||
</dd>
|
||||
<dt><code>lsisas1068</code></dt>
|
||||
<dd>
|
||||
LSI Logic SAS 1068 controller. <span class="since">Since 0.8.0</span>
|
||||
</dd>
|
||||
<dt><code>vmpvscsi</code></dt>
|
||||
<dd>
|
||||
Special VMware Paravirtual SCSI controller, requires VMware tools inside
|
||||
the guest. See <a href="http://kb.vmware.com/kb/1010398">VMware KB1010398</a>
|
||||
for details. <span class="since">Since 0.8.3</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
Here a domain XML snippet:
|
||||
</p>
|
||||
<pre>
|
||||
...
|
||||
<disk type='file' device='disk'>
|
||||
<source file='[local-storage] Fedora11/Fedora11.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
<address type='drive' controller='0' bus='0' unit='0'/>
|
||||
</disk>
|
||||
<controller type='scsi' index='0' model='<strong>lsilogic</strong>'/>
|
||||
...
|
||||
</pre>
|
||||
<p>
|
||||
The controller element is supported <span class="since">since 0.8.2</span>.
|
||||
Prior to this <code><driver name='lsilogic'/></code> was abused to
|
||||
specify the SCSI controller model. This attribute usage is deprecated now.
|
||||
</p>
|
||||
<pre>
|
||||
...
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='<strong>lsilogic</strong>'/>
|
||||
<source file='[local-storage] Fedora11/Fedora11.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
...
|
||||
</pre>
|
||||
|
||||
|
||||
<h4>Network card models</h4>
|
||||
<dl>
|
||||
<dt><code>vlance</code></dt>
|
||||
<dd>
|
||||
AMD PCnet32 network card for older guests.
|
||||
</dd>
|
||||
<dt><code>vmxnet</code>, <code>vmxnet2</code>, <code>vmxnet3</code></dt>
|
||||
<dd>
|
||||
Special VMware VMXnet network card, requires VMware tools inside
|
||||
the guest. See <a href="http://kb.vmware.com/kb/1001805">VMware KB1001805</a>
|
||||
for details.
|
||||
</dd>
|
||||
<dt><code>e1000</code></dt>
|
||||
<dd>
|
||||
Intel E1000 network card for recent guests.
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
Here a domain XML snippet:
|
||||
</p>
|
||||
<pre>
|
||||
...
|
||||
<interface type='bridge'>
|
||||
<mac address='00:50:56:25:48:c7'/>
|
||||
<source bridge='VM Network'/>
|
||||
<model type='<strong>e1000</strong>'/>
|
||||
</interface>
|
||||
...
|
||||
</pre>
|
||||
|
||||
|
||||
<h2><a name="importexport">Import and export of domain XML configs</a></h2>
|
||||
<p>
|
||||
The ESX driver currently supports a native config format known as
|
||||
<code>vmware-vmx</code> to handle VMware VMX configs.
|
||||
</p>
|
||||
|
||||
|
||||
<h3><a name="xmlimport">Converting from VMware VMX config to domain XML config</a></h3>
|
||||
<p>
|
||||
The <code>virsh domxml-from-native</code> provides a way to convert an
|
||||
existing VMware VMX config into a domain XML config that can then be
|
||||
used by libvirt.
|
||||
</p>
|
||||
<pre>
|
||||
$ cat > demo.vmx << EOF
|
||||
#!/usr/bin/vmware
|
||||
config.version = "8"
|
||||
virtualHW.version = "4"
|
||||
floppy0.present = "false"
|
||||
nvram = "Fedora11.nvram"
|
||||
deploymentPlatform = "windows"
|
||||
virtualHW.productCompatibility = "hosted"
|
||||
tools.upgrade.policy = "useGlobal"
|
||||
powerType.powerOff = "default"
|
||||
powerType.powerOn = "default"
|
||||
powerType.suspend = "default"
|
||||
powerType.reset = "default"
|
||||
displayName = "Fedora11"
|
||||
extendedConfigFile = "Fedora11.vmxf"
|
||||
scsi0.present = "true"
|
||||
scsi0.sharedBus = "none"
|
||||
scsi0.virtualDev = "lsilogic"
|
||||
memsize = "1024"
|
||||
scsi0:0.present = "true"
|
||||
scsi0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Fedora11/Fedora11.vmdk"
|
||||
scsi0:0.deviceType = "scsi-hardDisk"
|
||||
ide0:0.present = "true"
|
||||
ide0:0.clientDevice = "true"
|
||||
ide0:0.deviceType = "cdrom-raw"
|
||||
ide0:0.startConnected = "false"
|
||||
ethernet0.present = "true"
|
||||
ethernet0.networkName = "VM Network"
|
||||
ethernet0.addressType = "vpx"
|
||||
ethernet0.generatedAddress = "00:50:56:91:48:c7"
|
||||
chipset.onlineStandby = "false"
|
||||
guestOSAltName = "Red Hat Enterprise Linux 5 (32-Bit)"
|
||||
guestOS = "rhel5"
|
||||
uuid.bios = "50 11 5e 16 9b dc 49 d7-f1 71 53 c4 d7 f9 17 10"
|
||||
snapshot.action = "keep"
|
||||
sched.cpu.min = "0"
|
||||
sched.cpu.units = "mhz"
|
||||
sched.cpu.shares = "normal"
|
||||
sched.mem.minsize = "0"
|
||||
sched.mem.shares = "normal"
|
||||
toolScripts.afterPowerOn = "true"
|
||||
toolScripts.afterResume = "true"
|
||||
toolScripts.beforeSuspend = "true"
|
||||
toolScripts.beforePowerOff = "true"
|
||||
scsi0:0.redo = ""
|
||||
tools.syncTime = "false"
|
||||
uuid.location = "56 4d b5 06 a2 bd fb eb-ae 86 f7 d8 49 27 d0 c4"
|
||||
sched.cpu.max = "unlimited"
|
||||
sched.swap.derivedName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Fedora11/Fedora11-7de040d8.vswp"
|
||||
tools.remindInstall = "TRUE"
|
||||
EOF
|
||||
|
||||
$ virsh -c esx://example.com domxml-from-native vmware-vmx demo.vmx
|
||||
Enter username for example.com [root]:
|
||||
Enter root password for example.com:
|
||||
<domain type='vmware'>
|
||||
<name>Fedora11</name>
|
||||
<uuid>50115e16-9bdc-49d7-f171-53c4d7f91710</uuid>
|
||||
<memory>1048576</memory>
|
||||
<currentMemory>1048576</currentMemory>
|
||||
<vcpu>1</vcpu>
|
||||
<os>
|
||||
<type arch='i686'>hvm</type>
|
||||
</os>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='[local-storage] Fedora11/Fedora11.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
<address type='drive' controller='0' bus='0' unit='0'/>
|
||||
</disk>
|
||||
<controller type='scsi' index='0' model='lsilogic'/>
|
||||
<interface type='bridge'>
|
||||
<mac address='00:50:56:91:48:c7'/>
|
||||
<source bridge='VM Network'/>
|
||||
</interface>
|
||||
</devices>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
|
||||
<h3><a name="xmlexport">Converting from domain XML config to VMware VMX config</a></h3>
|
||||
<p>
|
||||
The <code>virsh domxml-to-native</code> provides a way to convert a
|
||||
domain XML config into a VMware VMX config.
|
||||
</p>
|
||||
<pre>
|
||||
$ cat > demo.xml << EOF
|
||||
<domain type='vmware'>
|
||||
<name>Fedora11</name>
|
||||
<uuid>50115e16-9bdc-49d7-f171-53c4d7f91710</uuid>
|
||||
<memory>1048576</memory>
|
||||
<currentMemory>1048576</currentMemory>
|
||||
<vcpu>1</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64'>hvm</type>
|
||||
</os>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='[local-storage] Fedora11/Fedora11.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
<address type='drive' controller='0' bus='0' unit='0'/>
|
||||
</disk>
|
||||
<controller type='scsi' index='0' model='lsilogic'/>
|
||||
<interface type='bridge'>
|
||||
<mac address='00:50:56:25:48:c7'/>
|
||||
<source bridge='VM Network'/>
|
||||
</interface>
|
||||
</devices>
|
||||
</domain>
|
||||
EOF
|
||||
|
||||
$ virsh -c esx://example.com domxml-to-native vmware-vmx demo.xml
|
||||
Enter username for example.com [root]:
|
||||
Enter root password for example.com:
|
||||
config.version = "8"
|
||||
virtualHW.version = "4"
|
||||
guestOS = "other-64"
|
||||
uuid.bios = "50 11 5e 16 9b dc 49 d7-f1 71 53 c4 d7 f9 17 10"
|
||||
displayName = "Fedora11"
|
||||
memsize = "1024"
|
||||
numvcpus = "1"
|
||||
scsi0.present = "true"
|
||||
scsi0.virtualDev = "lsilogic"
|
||||
scsi0:0.present = "true"
|
||||
scsi0:0.deviceType = "scsi-hardDisk"
|
||||
scsi0:0.fileName = "/vmfs/volumes/local-storage/Fedora11/Fedora11.vmdk"
|
||||
ethernet0.present = "true"
|
||||
ethernet0.networkName = "VM Network"
|
||||
ethernet0.connectionType = "bridged"
|
||||
ethernet0.addressType = "static"
|
||||
ethernet0.address = "00:50:56:25:48:C7"
|
||||
</pre>
|
||||
|
||||
|
||||
<h2><a name="xmlconfig">Example domain XML configs</a></h2>
|
||||
|
||||
<h3>Fedora11 on x86_64</h3>
|
||||
<pre>
|
||||
<domain type='vmware'>
|
||||
<name>Fedora11</name>
|
||||
<uuid>50115e16-9bdc-49d7-f171-53c4d7f91710</uuid>
|
||||
<memory>1048576</memory>
|
||||
<currentMemory>1048576</currentMemory>
|
||||
<vcpu>1</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64'>hvm</type>
|
||||
</os>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='[local-storage] Fedora11/Fedora11.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
<address type='drive' controller='0' bus='0' unit='0'/>
|
||||
</disk>
|
||||
<controller type='scsi' index='0'/>
|
||||
<interface type='bridge'>
|
||||
<mac address='00:50:56:25:48:c7'/>
|
||||
<source bridge='VM Network'/>
|
||||
</interface>
|
||||
</devices>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
|
||||
<h2><a name="migration">Migration</a></h2>
|
||||
<p>
|
||||
A migration cannot be initiated on an ESX server directly, a VMware
|
||||
vCenter is necessary for this. The <code>vcenter</code> query
|
||||
parameter must be set either to the hostname or IP address of the
|
||||
vCenter managing the ESX server or to <code>*</code>. Setting it
|
||||
to <code>*</code> causes the driver to connect to the vCenter known to
|
||||
the ESX server. If the ESX server is not managed by a vCenter an error
|
||||
is reported.
|
||||
</p>
|
||||
<pre>
|
||||
esx://example.com/?vcenter=example-vcenter.com
|
||||
</pre>
|
||||
<p>
|
||||
Here's an example how to migrate the domain <code>Fedora11</code> from
|
||||
ESX server <code>example-src.com</code> to ESX server
|
||||
<code>example-dst.com</code> implicitly involving vCenter
|
||||
<code>example-vcenter.com</code> using <code>virsh</code>.
|
||||
</p>
|
||||
<pre>
|
||||
$ virsh -c esx://example-src.com/?vcenter=* migrate Fedora11 esx://example-dst.com/?vcenter=*
|
||||
Enter username for example-src.com [root]:
|
||||
Enter root password for example-src.com:
|
||||
Enter username for example-vcenter.com [administrator]:
|
||||
Enter administrator password for example-vcenter.com:
|
||||
Enter username for example-dst.com [root]:
|
||||
Enter root password for example-dst.com:
|
||||
Enter username for example-vcenter.com [administrator]:
|
||||
Enter administrator password for example-vcenter.com:
|
||||
</pre>
|
||||
<p>
|
||||
<span class="since">Since 0.8.3</span> you can directly connect to a vCenter.
|
||||
This simplifies migration a bit. Here's the same migration as above but
|
||||
using <code>vpx://</code> connections and assuming both ESX server are in
|
||||
datacenter <code>dc1</code> and aren't part of a cluster.
|
||||
</p>
|
||||
<pre>
|
||||
$ virsh -c vpx://example-vcenter.com/dc1/example-src.com migrate Fedora11 vpx://example-vcenter.com/dc1/example-dst.com
|
||||
Enter username for example-vcenter.com [administrator]:
|
||||
Enter administrator password for example-vcenter.com:
|
||||
Enter username for example-vcenter.com [administrator]:
|
||||
Enter administrator password for example-vcenter.com:
|
||||
</pre>
|
||||
|
||||
|
||||
<h2><a name="scheduler">Scheduler configuration</a></h2>
|
||||
<p>
|
||||
The driver exposes the ESX CPU scheduler. The parameters listed below
|
||||
are available to control the scheduler.
|
||||
</p>
|
||||
<dl>
|
||||
<dt><code>reservation</code></dt>
|
||||
<dd>
|
||||
The amount of CPU resource in MHz that is guaranteed to be
|
||||
available to the domain. Valid values are 0 and greater.
|
||||
</dd>
|
||||
<dt><code>limit</code></dt>
|
||||
<dd>
|
||||
The CPU utilization of the domain will be
|
||||
limited to this value in MHz, even if more CPU resources are
|
||||
available. If the limit is set to -1, the CPU utilization of the
|
||||
domain is unlimited. If the limit is not set to -1, it must be
|
||||
greater than or equal to the reservation.
|
||||
</dd>
|
||||
<dt><code>shares</code></dt>
|
||||
<dd>
|
||||
Shares are used to determine relative CPU
|
||||
allocation between domains. In general, a domain with more shares
|
||||
gets proportionally more of the CPU resource. Valid values are 0
|
||||
and greater. The special values -1, -2 and -3 represent the
|
||||
predefined shares level <code>low</code>, <code>normal</code> and
|
||||
<code>high</code>.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<h2><a name="tools">VMware tools</a></h2>
|
||||
<p>
|
||||
Some actions require installed VMware tools. If the VMware tools are
|
||||
not installed in the guest and one of the actions below is to be
|
||||
performed the ESX server raises an error and the driver reports it.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>virDomainReboot</code>
|
||||
</li>
|
||||
<li>
|
||||
<code>virDomainShutdown</code>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2><a name="links">Links</a></h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://www.vmware.com/support/developer/vc-sdk/">
|
||||
VMware vSphere Web Services SDK Documentation
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.vmware.com/pdf/esx3_memory.pdf">
|
||||
The Role of Memory in VMware ESX Server 3
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.sanbarrow.com/vmx.html">
|
||||
VMware VMX config parameters
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.vmware.com/pdf/vsp_4_pvscsi_perf.pdf">
|
||||
VMware ESX 4.0 PVSCSI Storage Performance
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</body></html>
|
@ -1,112 +0,0 @@
|
||||
<html><body>
|
||||
<h1>Microsoft Hyper-V hypervisor driver</h1>
|
||||
<ul id="toc"></ul>
|
||||
<p>
|
||||
The libvirt Microsoft Hyper-V driver can manage Hyper-V 2008 R2.
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.microsoft.com/hyper-v-server/">Microsoft Hyper-V</a>
|
||||
hypervisor
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2><a name="uri">Connections to the Microsoft Hyper-V driver</a></h2>
|
||||
<p>
|
||||
Some example remote connection URIs for the driver are:
|
||||
</p>
|
||||
<pre>
|
||||
hyperv://example-hyperv.com (over HTTPS)
|
||||
hyperv://example-hyperv.com/?transport=http (over HTTP)
|
||||
</pre>
|
||||
<p>
|
||||
<strong>Note</strong>: In contrast to other drivers, the Hyper-V driver
|
||||
is a client-side-only driver. It connects to the Hyper-V server using
|
||||
WS-Management over HTTP(S). Therefore, the
|
||||
<a href="remote.html">remote transport mechanism</a> provided by the
|
||||
remote driver and libvirtd will not work, and you cannot use URIs like
|
||||
<code>hyperv+ssh://example.com</code>.
|
||||
</p>
|
||||
|
||||
|
||||
<h3><a name="uriformat">URI Format</a></h3>
|
||||
<p>
|
||||
URIs have this general form (<code>[...]</code> marks an optional part).
|
||||
</p>
|
||||
<pre>
|
||||
hyperv://[username@]hostname[:port]/[?extraparameters]
|
||||
</pre>
|
||||
<p>
|
||||
The default HTTPS ports is 5986. If the port parameter is given, it
|
||||
overrides the default port.
|
||||
</p>
|
||||
|
||||
|
||||
<h4><a name="extraparams">Extra parameters</a></h4>
|
||||
<p>
|
||||
Extra parameters can be added to a URI as part of the query string
|
||||
(the part following <code>?</code>). A single parameter is formed by a
|
||||
<code>name=value</code> pair. Multiple parameters are separated by
|
||||
<code>&</code>.
|
||||
</p>
|
||||
<pre>
|
||||
?transport=http
|
||||
</pre>
|
||||
<p>
|
||||
The driver understands the extra parameters shown below.
|
||||
</p>
|
||||
<table class="top_table">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Values</th>
|
||||
<th>Meaning</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>transport</code>
|
||||
</td>
|
||||
<td>
|
||||
<code>http</code> or <code>https</code>
|
||||
</td>
|
||||
<td>
|
||||
Overrides the default HTTPS transport. The default HTTP port
|
||||
is 5985.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<h3><a name="auth">Authentication</a></h3>
|
||||
<p>
|
||||
In order to perform any useful operation the driver needs to log into
|
||||
the Hyper-V server. Therefore, only <code>virConnectOpenAuth</code> can
|
||||
be used to connect to an Hyper-V server, <code>virConnectOpen</code> and
|
||||
<code>virConnectOpenReadOnly</code> don't work.
|
||||
To log into an Hyper-V server the driver will request credentials using
|
||||
the callback passed to the <code>virConnectOpenAuth</code> function.
|
||||
The driver passes the hostname as challenge parameter to the callback.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Note</strong>: Currently only <code>Basic</code> authentication
|
||||
is supported by libvirt. This method is disabled by default on the
|
||||
Hyper-V server and can be enabled via the WinRM commandline tool.
|
||||
</p>
|
||||
<pre>
|
||||
winrm set winrm/config/service/auth @{Basic="true"}
|
||||
</pre>
|
||||
<p>
|
||||
To allow <code>Basic</code> authentication with HTTP transport WinRM
|
||||
needs to allow unencrypted communication. This can be enabled via the
|
||||
WinRM commandline tool. However, this is not the recommended
|
||||
communication mode.
|
||||
</p>
|
||||
<pre>
|
||||
winrm set winrm/config/service @{AllowUnencrypted="true"}
|
||||
</pre>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,139 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>LXC container driver</h1>
|
||||
<p>
|
||||
The libvirt LXC driver manages "Linux Containers". Containers are sets of processes
|
||||
with private namespaces which can (but don't always) look like separate machines, but
|
||||
do not have their own OS. Here are two example configurations. The first is a very
|
||||
light-weight "application container" which does not have its own root image.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://lxc.sourceforge.net/">LXC</a> Linux
|
||||
container system
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Cgroups Requirements</h2>
|
||||
|
||||
<p>
|
||||
The libvirt LXC driver requires that certain cgroups controllers are
|
||||
mounted on the host OS. The minimum required controllers are 'cpuacct',
|
||||
'memory' and 'devices', while recommended extra controllers are
|
||||
'cpu', 'freezer' and 'blkio'. The /etc/cgconfig.conf & cgconfig
|
||||
init service used to mount cgroups at host boot time. To manually
|
||||
mount them use:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
# mount -t cgroup cgroup /dev/cgroup -o cpuacct,memory,devices,cpu,freezer,blkio
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
NB, the blkio controller in some kernels will not allow creation of nested
|
||||
sub-directories which will prevent correct operation of the libvirt LXC
|
||||
driver. On such kernels, it may be necessary to unmount the blkio controller.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>Environment setup for the container init</h2>
|
||||
|
||||
<p>
|
||||
When the container "init" process is started, it will be given several useful
|
||||
environment variables.
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt>LIBVIRT_LXC_NAME</dt>
|
||||
<dd>The name assigned to the container by libvirt</dd>
|
||||
<dt>LIBVIRT_LXC_UUID</dt>
|
||||
<dd>The UUID assigned to the container by libvirt</dd>
|
||||
<dt>LIBVIRT_LXC_CMDLINE</dt>
|
||||
<dd>The unparsed command line arguments specified in the container configuration</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<h3>Example config version 1</h3>
|
||||
<p></p>
|
||||
<pre>
|
||||
<domain type='lxc'>
|
||||
<name>vm1</name>
|
||||
<memory>500000</memory>
|
||||
<os>
|
||||
<type>exe</type>
|
||||
<init>/bin/sh</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>
|
||||
<interface type='network'>
|
||||
<source network='default'/>
|
||||
</interface>
|
||||
<console type='pty' />
|
||||
</devices>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
In the <emulator> element, be sure you specify the correct path
|
||||
to libvirt_lxc, if it does not live in /usr/libexec on your system.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The next example assumes there is a private root filesystem
|
||||
(perhaps hand-crafted using busybox, or installed from media,
|
||||
debootstrap, whatever) under /opt/vm-1-root:
|
||||
</p>
|
||||
<p></p>
|
||||
<pre>
|
||||
<domain type='lxc'>
|
||||
<name>vm1</name>
|
||||
<memory>32768</memory>
|
||||
<os>
|
||||
<type>exe</type>
|
||||
<init>/init</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='/opt/vm-1-root'/>
|
||||
<target dir='/'/>
|
||||
</filesystem>
|
||||
<interface type='network'>
|
||||
<source network='default'/>
|
||||
</interface>
|
||||
<console type='pty' />
|
||||
</devices>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
In both cases, you can define and start a container using:</p>
|
||||
<pre>
|
||||
virsh --connect lxc:/// define v1.xml
|
||||
virsh --connect lxc:/// start vm1
|
||||
</pre>
|
||||
and then get a console using:
|
||||
<pre>
|
||||
virsh --connect lxc:/// console vm1
|
||||
</pre>
|
||||
<p>Now doing 'ps -ef' will only show processes in the container, for
|
||||
instance. You can undefine it using
|
||||
</p>
|
||||
<pre>
|
||||
virsh --connect lxc:/// undefine vm1
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1,121 +0,0 @@
|
||||
<html> <!-- -*- html -*- -->
|
||||
<body>
|
||||
<h1>OpenVZ container driver</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<p>
|
||||
The OpenVZ driver for libvirt allows use and management of container
|
||||
based virtualization on a Linux host OS. Prior to using the OpenVZ
|
||||
driver, the OpenVZ enabled kernel must be installed & booted, and the
|
||||
OpenVZ userspace tools installed. The libvirt driver has been tested
|
||||
with OpenVZ 3.0.22, but other 3.0.x versions should also work without
|
||||
undue trouble.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://openvz.org/">OpenVZ</a> Linux container
|
||||
system
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="connections">Connections to OpenVZ driver</a></h2>
|
||||
|
||||
<p>
|
||||
The libvirt OpenVZ driver is a single-instance privileged driver,
|
||||
with a driver name of 'openvz'. Some example connection URIs for
|
||||
the libvirt driver are:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
openvz:///system (local access)
|
||||
openvz+unix:///system (local access)
|
||||
openvz://example.com/system (remote access, TLS/x509)
|
||||
openvz+tcp://example.com/system (remote access, SASl/Kerberos)
|
||||
openvz+ssh://root@example.com/system (remote access, SSH tunnelled)
|
||||
</pre>
|
||||
|
||||
<h2><a name="notes">Notes on bridged networking</a></h2>
|
||||
|
||||
<p>
|
||||
Bridged networking enables a guest domain (ie container) to have its
|
||||
network interface connected directly to the host's physical LAN. Before
|
||||
this can be used there are a couple of configuration pre-requisites for
|
||||
the host OS.
|
||||
</p>
|
||||
|
||||
<h3><a name="host">Host network devices</a></h3>
|
||||
|
||||
<p>
|
||||
One or more of the physical devices must be attached to a bridge. The
|
||||
process for this varies according to the operating system in use, so
|
||||
for up to date notes consult the <a href="http://wiki.libvirt.org">Wiki</a>
|
||||
or your operating system's networking documentation. The basic idea is
|
||||
that the host OS should end up with a bridge device "br0" containing a
|
||||
physical device "eth0", or a bonding device "bond0".
|
||||
</p>
|
||||
|
||||
<h3><a name="tools">OpenVZ tools configuration</a></h3>
|
||||
|
||||
<p>
|
||||
OpenVZ releases later than 3.0.23 ship with a standard network device
|
||||
setup script that is able to setup bridging, named
|
||||
<code>/usr/sbin/vznetaddbr</code>. For releases prior to 3.0.23, this
|
||||
script must be created manually by the host OS administrator. The
|
||||
simplest way is to just download the latest version of this script
|
||||
from a newer OpenVZ release, or upstream source repository. Then
|
||||
a generic configuration file <code>/etc/vz/vznet.conf</code>
|
||||
must be created containing
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
#!/bin/bash
|
||||
EXTERNAL_SCRIPT="/usr/sbin/vznetaddbr"
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The host OS is now ready to allow bridging of guest containers, which
|
||||
will work whether the container is started with libvirt, or OpenVZ
|
||||
tools.
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name="example">Example guest domain XML configuration</a></h2>
|
||||
|
||||
<p>
|
||||
The current libvirt OpenVZ driver has a restriction that the
|
||||
domain names must match the OpenVZ container VEID, which by
|
||||
convention start at 100, and are incremented from there. The
|
||||
choice of OS template to use inside the container is determined
|
||||
by the <code>filesystem</code> tag, and the template source name
|
||||
matches the templates known to OpenVZ tools.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<domain type='openvz' id='104'>
|
||||
<name>104</name>
|
||||
<uuid>86c12009-e591-a159-6e9f-91d18b85ef78</uuid>
|
||||
<vcpu>3</vcpu>
|
||||
<os>
|
||||
<type>exe</type>
|
||||
<init>/sbin/init</init>
|
||||
</os>
|
||||
<devices>
|
||||
<filesystem type='template'>
|
||||
<source name='fedora-9-i386-minimal'/>
|
||||
<target dir='/'/>
|
||||
</filesystem>
|
||||
<interface type='bridge'>
|
||||
<mac address='00:18:51:5b:ea:bf'/>
|
||||
<source bridge='br0'/>
|
||||
<target dev='veth101.0'/>
|
||||
</interface>
|
||||
</devices>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,652 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>KVM/QEMU hypervisor driver</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<p>
|
||||
The libvirt KVM/QEMU driver can manage any QEMU emulator from
|
||||
version 0.8.1 or later. It can also manage Xenner, which
|
||||
provides the same QEMU command line syntax and monitor
|
||||
interaction.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.linux-kvm.org/">KVM</a> Linux
|
||||
hypervisor
|
||||
<li>
|
||||
The <a href="http://wiki.qemu.org/Index.html">QEMU</a> emulator
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="prereq">Deployment pre-requisites</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>QEMU emulators</strong>: The driver will probe <code>/usr/bin</code>
|
||||
for the presence of <code>qemu</code>, <code>qemu-system-x86_64</code>,
|
||||
<code>qemu-system-microblaze</code>,
|
||||
<code>qemu-system-microblazeel</code>,
|
||||
<code>qemu-system-mips</code>,<code>qemu-system-mipsel</code>,
|
||||
<code>qemu-system-sparc</code>,<code>qemu-system-ppc</code>. The results
|
||||
of this can be seen from the capabilities XML output.
|
||||
</li>
|
||||
<li>
|
||||
<strong>KVM hypervisor</strong>: The driver will probe <code>/usr/bin</code>
|
||||
for the presence of <code>qemu-kvm</code> and <code>/dev/kvm</code> device
|
||||
node. If both are found, then KVM fullyvirtualized, hardware accelerated
|
||||
guests will be available.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Xenner hypervisor</strong>: The driver will probe <code>/usr/bin</code>
|
||||
for the presence of <code>xenner</code> and <code>/dev/kvm</code> device
|
||||
node. If both are found, then Xen paravirtualized guests can be run using
|
||||
the KVM hardware acceleration.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="uris">Connections to QEMU driver</a></h2>
|
||||
|
||||
<p>
|
||||
The libvirt QEMU driver is a multi-instance driver, providing a single
|
||||
system wide privileged driver (the "system" instance), and per-user
|
||||
unprivileged drivers (the "session" instance). The URI driver protocol
|
||||
is "qemu". Some example conection URIs for the libvirt driver are:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
qemu:///session (local access to per-user instance)
|
||||
qemu+unix:///session (local access to per-user instance)
|
||||
|
||||
qemu:///system (local access to system instance)
|
||||
qemu+unix:///system (local access to system instance)
|
||||
qemu://example.com/system (remote access, TLS/x509)
|
||||
qemu+tcp://example.com/system (remote access, SASl/Kerberos)
|
||||
qemu+ssh://root@example.com/system (remote access, SSH tunnelled)
|
||||
</pre>
|
||||
|
||||
<h2><a name="security">Driver security architecture</a></h2>
|
||||
|
||||
<p>
|
||||
There are multiple layers to security in the QEMU driver, allowing for
|
||||
flexibility in the use of QEMU based virtual machines.
|
||||
</p>
|
||||
|
||||
<h3><a name="securitydriver">Driver instances</a></h3>
|
||||
|
||||
<p>
|
||||
As explained above there are two ways to access the QEMU driver
|
||||
in libvirt. The "qemu:///session" family of URIs connect to a
|
||||
libvirtd instance running as the same user/group ID as the client
|
||||
application. Thus the QEMU instances spawned from this driver will
|
||||
share the same privileges as the client application. The intended
|
||||
use case for this driver is desktop virtualization, with virtual
|
||||
machines storing their disk images in the user's home directory and
|
||||
being managed from the local desktop login session.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The "qemu:///system" family of URIs connect to a
|
||||
libvirtd instance running as the privileged system account 'root'.
|
||||
Thus the QEMU instances spawned from this driver may have much
|
||||
higher privileges than the client application managing them.
|
||||
The intended use case for this driver is server virtualization,
|
||||
where the virtual machines may need to be connected to host
|
||||
resources (block, PCI, USB, network devices) whose access requires
|
||||
elevated privileges.
|
||||
</p>
|
||||
|
||||
<h3><a name="securitydac">POSIX users/groups</a></h3>
|
||||
|
||||
<p>
|
||||
In the "session" instance, the POSIX users/groups model restricts QEMU
|
||||
virtual machines (and libvirtd in general) to only have access to resources
|
||||
with the same user/group ID as the client application. There is no
|
||||
finer level of configuration possible for the "session" instances.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the "system" instance, libvirt releases from 0.7.0 onwards allow
|
||||
control over the user/group that the QEMU virtual machines are run
|
||||
as. A build of libvirt with no configuration parameters set will
|
||||
still run QEMU processes as root:root. It is possible to change
|
||||
this default by using the --with-qemu-user=$USERNAME and
|
||||
--with-qemu-group=$GROUPNAME arguments to 'configure' during
|
||||
build. It is strongly recommended that vendors build with both
|
||||
of these arguments set to 'qemu'. Regardless of this build time
|
||||
default, administrators can set a per-host default setting in
|
||||
the <code>/etc/libvirt/qemu.conf</code> configuration file via
|
||||
the <code>user=$USERNAME</code> and <code>group=$GROUPNAME</code>
|
||||
parameters. When a non-root user or group is configured, the
|
||||
libvirt QEMU driver will change uid/gid to match immediately
|
||||
before executing the QEMU binary for a virtual machine.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If QEMU virtual machines from the "system" instance are being
|
||||
run as non-root, there will be greater restrictions on what
|
||||
host resources the QEMU process will be able to access. The
|
||||
libvirtd daemon will attempt to manage permissions on resources
|
||||
to minimise the likelihood of unintentional security denials,
|
||||
but the administrator / application developer must be aware of
|
||||
some of the consequences / restrictions.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>
|
||||
The directories <code>/var/run/libvirt/qemu/</code>,
|
||||
<code>/var/lib/libvirt/qemu/</code> and
|
||||
<code>/var/cache/libvirt/qemu/</code> must all have their
|
||||
ownership set to match the user / group ID that QEMU
|
||||
guests will be run as. If the vendor has set a non-root
|
||||
user/group for the QEMU driver at build time, the
|
||||
permissions should be set automatically at install time.
|
||||
If a host administrator customizes user/group in
|
||||
<code>/etc/libvirt/qemu.conf</code>, they will need to
|
||||
manually set the ownership on these directories.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
When attaching USB and PCI devices to a QEMU guest,
|
||||
QEMU will need to access files in <code>/dev/bus/usb</code>
|
||||
and <code>/sys/bus/pci/devices</code> respectively. The libvirtd daemon
|
||||
will automatically set the ownership on specific devices
|
||||
that are assigned to a guest at start time. There should
|
||||
not be any need for administrator changes in this respect.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
Any files/devices used as guest disk images must be
|
||||
accessible to the user/group ID that QEMU guests are
|
||||
configured to run as. The libvirtd daemon will automatically
|
||||
set the ownership of the file/device path to the correct
|
||||
user/group ID. Applications / administrators must be aware
|
||||
though that the parent directory permissions may still
|
||||
deny access. The directories containing disk images
|
||||
must either have their ownership set to match the user/group
|
||||
configured for QEMU, or their UNIX file permissions must
|
||||
have the 'execute/search' bit enabled for 'others'.
|
||||
</p>
|
||||
<p>
|
||||
The simplest option is the latter one, of just enabling
|
||||
the 'execute/search' bit. For any directory to be used
|
||||
for storing disk images, this can be achieved by running
|
||||
the following command on the directory itself, and any
|
||||
parent directories
|
||||
</p>
|
||||
<pre>
|
||||
chmod o+x /path/to/directory
|
||||
</pre>
|
||||
<p>
|
||||
In particular note that if using the "system" instance
|
||||
and attempting to store disk images in a user home
|
||||
directory, the default permissions on $HOME are typically
|
||||
too restrictive to allow access.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3><a name="securitycap">Linux process capabilities</a></h3>
|
||||
|
||||
<p>
|
||||
The libvirt QEMU driver has a build time option allowing it to use
|
||||
the <a href="http://people.redhat.com/sgrubb/libcap-ng/index.html">libcap-ng</a>
|
||||
library to manage process capabilities. If this build option is
|
||||
enabled, then the QEMU driver will use this to ensure that all
|
||||
process capabilities are dropped before executing a QEMU virtual
|
||||
machine. Process capabilities are what gives the 'root' account
|
||||
its high power, in particular the CAP_DAC_OVERRIDE capability
|
||||
is what allows a process running as 'root' to access files owned
|
||||
by any user.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the QEMU driver is configured to run virtual machines as non-root,
|
||||
then they will already lose all their process capabilities at time
|
||||
of startup. The Linux capability feature is thus aimed primarily at
|
||||
the scenario where the QEMU processes are running as root. In this
|
||||
case, before launching a QEMU virtual machine, libvirtd will use
|
||||
libcap-ng APIs to drop all process capabilities. It is important
|
||||
for administrators to note that this implies the QEMU process will
|
||||
<strong>only</strong> be able to access files owned by root, and
|
||||
not files owned by any other user.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Thus, if a vendor / distributor has configured their libvirt package
|
||||
to run as 'qemu' by default, a number of changes will be required
|
||||
before an administrator can change a host to run guests as root.
|
||||
In particular it will be necessary to change ownership on the
|
||||
directories <code>/var/run/libvirt/qemu/</code>,
|
||||
<code>/var/lib/libvirt/qemu/</code> and
|
||||
<code>/var/cache/libvirt/qemu/</code> back to root, in addition
|
||||
to changing the <code>/etc/libvirt/qemu.conf</code> settings.
|
||||
</p>
|
||||
|
||||
<h3><a name="securityselinux">SELinux basic confinement</a></h3>
|
||||
|
||||
<p>
|
||||
The basic SELinux protection for QEMU virtual machines is intended to
|
||||
protect the host OS from a compromised virtual machine process. There
|
||||
is no protection between guests.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the basic model, all QEMU virtual machines run under the confined
|
||||
domain <code>root:system_r:qemu_t</code>. It is required that any
|
||||
disk image assigned to a QEMU virtual machine is labelled with
|
||||
<code>system_u:object_r:virt_image_t</code>. In a default deployment,
|
||||
package vendors/distributor will typically ensure that the directory
|
||||
<code>/var/lib/libvirt/images</code> has this label, such that any
|
||||
disk images created in this directory will automatically inherit the
|
||||
correct labelling. If attempting to use disk images in another
|
||||
location, the user/administrator must ensure the directory has be
|
||||
given this requisite label. Likewise physical block devices must
|
||||
be labelled <code>system_u:object_r:virt_image_t</code>.
|
||||
</p>
|
||||
<p>
|
||||
Not all filesystems allow for labelling of individual files. In
|
||||
particular NFS, VFat and NTFS have no support for labelling. In
|
||||
these cases administrators must use the 'context' option when
|
||||
mounting the filesystem to set the default label to
|
||||
<code>system_u:object_r:virt_image_t</code>. In the case of
|
||||
NFS, there is an alternative option, of enabling the <code>virt_use_nfs</code>
|
||||
SELinux boolean.
|
||||
</p>
|
||||
|
||||
<h3><a name="securitysvirt">SELinux sVirt confinement</a></h3>
|
||||
|
||||
<p>
|
||||
The SELinux sVirt protection for QEMU virtual machines builds to the
|
||||
basic level of protection, to also allow individual guests to be
|
||||
protected from each other.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the sVirt model, each QEMU virtual machine runs under its own
|
||||
confined domain, which is based on <code>system_u:system_r:svirt_t:s0</code>
|
||||
with a unique category appended, eg, <code>system_u:system_r:svirt_t:s0:c34,c44</code>.
|
||||
The rules are setup such that a domain can only access files which are
|
||||
labelled with the matching category level, eg
|
||||
<code>system_u:object_r:svirt_image_t:s0:c34,c44</code>. This prevents one
|
||||
QEMU process accessing any file resources that are prevent to another QEMU
|
||||
process.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There are two ways of assigning labels to virtual machines under sVirt.
|
||||
In the default setup, if sVirt is enabled, guests will get an automatically
|
||||
assigned unique label each time they are booted. The libvirtd daemon will
|
||||
also automatically relabel exclusive access disk images to match this
|
||||
label. Disks that are marked as <shared> will get a generic
|
||||
label <code>system_u:system_r:svirt_image_t:s0</code> allowing all guests
|
||||
read/write access them, while disks marked as <readonly> will
|
||||
get a generic label <code>system_u:system_r:svirt_content_t:s0</code>
|
||||
which allows all guests read-only access.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
With statically assigned labels, the application should include the
|
||||
desired guest and file labels in the XML at time of creating the
|
||||
guest with libvirt. In this scenario the application is responsible
|
||||
for ensuring the disk images & similar resources are suitably
|
||||
labelled to match, libvirtd will not attempt any relabelling.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the sVirt security model is active, then the node capabilities
|
||||
XML will include its details. If a virtual machine is currently
|
||||
protected by the security model, then the guest XML will include
|
||||
its assigned labels. If enabled at compile time, the sVirt security
|
||||
model will always be activated if SELinux is available on the host
|
||||
OS. To disable sVirt, and revert to the basic level of SELinux
|
||||
protection (host protection only), the <code>/etc/libvirt/qemu.conf</code>
|
||||
file can be used to change the setting to <code>security_driver="none"</code>
|
||||
</p>
|
||||
|
||||
<h3><a name="securitysvirtaa">AppArmor sVirt confinement</a></h3>
|
||||
|
||||
<p>
|
||||
When using basic AppArmor protection for the libvirtd daemon and
|
||||
QEMU virtual machines, the intention is to protect the host OS
|
||||
from a compromised virtual machine process. There is no protection
|
||||
between guests.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The AppArmor sVirt protection for QEMU virtual machines builds on
|
||||
this basic level of protection, to also allow individual guests to
|
||||
be protected from each other.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the sVirt model, if a profile is loaded for the libvirtd daemon,
|
||||
then each <code>qemu:///system</code> QEMU virtual machine will have
|
||||
a profile created for it when the virtual machine is started if one
|
||||
does not already exist. This generated profile uses a profile name
|
||||
based on the UUID of the QEMU virtual machine and contains rules
|
||||
allowing access to only the files it needs to run, such as its disks,
|
||||
pid file and log files. Just before the QEMU virtual machine is
|
||||
started, the libvirtd daemon will change into this unique profile,
|
||||
preventing the QEMU process from accessing any file resources that
|
||||
are present in another QEMU process or the host machine.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The AppArmor sVirt implementation is flexible in that it allows an
|
||||
administrator to customize the template file in
|
||||
<code>/etc/apparmor.d/libvirt/TEMPLATE</code> for site-specific
|
||||
access for all newly created QEMU virtual machines. Also, when a new
|
||||
profile is generated, two files are created:
|
||||
<code>/etc/apparmor.d/libvirt/libvirt-<uuid></code> and
|
||||
<code>/etc/apparmor.d/libvirt/libvirt-<uuid>.files</code>. The
|
||||
former can be fine-tuned by the administrator to allow custom access
|
||||
for this particular QEMU virtual machine, and the latter will be
|
||||
updated appropriately when required file access changes, such as when
|
||||
a disk is added. This flexibility allows for situations such as
|
||||
having one virtual machine in complain mode with all others in
|
||||
enforce mode.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
While users can define their own AppArmor profile scheme, a typical
|
||||
configuration will include a profile for <code>/usr/sbin/libvirtd</code>,
|
||||
<code>/usr/lib/libvirt/virt-aa-helper</code> (a helper program which the
|
||||
libvirtd daemon uses instead of manipulating AppArmor directly), and
|
||||
an abstraction to be included by <code>/etc/apparmor.d/libvirt/TEMPLATE</code>
|
||||
(typically <code>/etc/apparmor.d/abstractions/libvirt-qemu</code>).
|
||||
An example profile scheme can be found in the examples/apparmor
|
||||
directory of the source distribution.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the sVirt security model is active, then the node capabilities
|
||||
XML will include its details. If a virtual machine is currently
|
||||
protected by the security model, then the guest XML will include
|
||||
its assigned profile name. If enabled at compile time, the sVirt
|
||||
security model will be activated if AppArmor is available on the host
|
||||
OS and a profile for the libvirtd daemon is loaded when libvirtd is
|
||||
started. To disable sVirt, and revert to the basic level of AppArmor
|
||||
protection (host protection only), the <code>/etc/libvirt/qemu.conf</code>
|
||||
file can be used to change the setting to <code>security_driver="none"</code>.
|
||||
</p>
|
||||
|
||||
|
||||
<h3><a name="securityacl">Cgroups device ACLs</a></h3>
|
||||
|
||||
<p>
|
||||
Recent Linux kernels have a capability known as "cgroups" which is used
|
||||
for resource management. It is implemented via a number of "controllers",
|
||||
each controller covering a specific task/functional area. One of the
|
||||
available controllers is the "devices" controller, which is able to
|
||||
setup whitelists of block/character devices that a cgroup should be
|
||||
allowed to access. If the "devices" controller is mounted on a host,
|
||||
then libvirt will automatically create a dedicated cgroup for each
|
||||
QEMU virtual machine and setup the device whitelist so that the QEMU
|
||||
process can only access shared devices, and explicitly disks images
|
||||
backed by block devices.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The list of shared devices a guest is allowed access to is
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
/dev/null, /dev/full, /dev/zero,
|
||||
/dev/random, /dev/urandom,
|
||||
/dev/ptmx, /dev/kvm, /dev/kqemu,
|
||||
/dev/rtc, /dev/hpet, /dev/net/tun
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
In the event of unanticipated needs arising, this can be customized
|
||||
via the <code>/etc/libvirt/qemu.conf</code> file.
|
||||
To mount the cgroups device controller, the following command
|
||||
should be run as root, prior to starting libvirtd
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
mkdir /dev/cgroup
|
||||
mount -t cgroup none /dev/cgroup -o devices
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
libvirt will then place each virtual machine in a cgroup at
|
||||
<code>/dev/cgroup/libvirt/qemu/$VMNAME/</code>
|
||||
</p>
|
||||
|
||||
<h2><a name="imex">Import and export of libvirt domain XML configs</a></h2>
|
||||
|
||||
<p>The QEMU driver currently supports a single native
|
||||
config format known as <code>qemu-argv</code>. The data for this format
|
||||
is expected to be a single line first a list of environment variables,
|
||||
then the QEMu binary name, finally followed by the QEMU command line
|
||||
arguments</p>
|
||||
|
||||
<h3><a name="xmlimport">Converting from QEMU args to domain XML</a></h3>
|
||||
|
||||
<p>
|
||||
The <code>virsh domxml-from-native</code> provides a way to
|
||||
convert an existing set of QEMU args into a guest description
|
||||
using libvirt Domain XML that can then be used by libvirt.
|
||||
Please note that this command is intended to be used to convert
|
||||
existing qemu guests previously started from the command line to
|
||||
be managed through libvirt. It should not be used a method of
|
||||
creating new guests from scratch. New guests should be created
|
||||
using an application calling the libvirt APIs (see
|
||||
the <a href="apps.html">libvirt applications page</a> for some
|
||||
examples) or by manually crafting XML to pass to virsh.
|
||||
</p>
|
||||
|
||||
<pre>$ cat > demo.args <<EOF
|
||||
LC_ALL=C PATH=/bin HOME=/home/test USER=test \
|
||||
LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 \
|
||||
-nographic -monitor pty -no-acpi -boot c -hda \
|
||||
/dev/HostVG/QEMUGuest1 -net none -serial none \
|
||||
-parallel none -usb
|
||||
EOF
|
||||
|
||||
$ virsh domxml-from-native qemu-argv demo.args
|
||||
<domain type='qemu'>
|
||||
<uuid>00000000-0000-0000-0000-000000000000</uuid>
|
||||
<memory>219136</memory>
|
||||
<currentMemory>219136</currentMemory>
|
||||
<vcpu>1</vcpu>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu</emulator>
|
||||
<disk type='block' device='disk'>
|
||||
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
</devices>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
<p>NB, don't include the literral \ in the args, put everything on one line</p>
|
||||
|
||||
<h3><a name="xmlexport">Converting from domain XML to QEMU args</a></h3>
|
||||
|
||||
<p>
|
||||
The <code>virsh domxml-to-native</code> provides a way to convert a
|
||||
guest description using libvirt Domain XML, into a set of QEMU args
|
||||
that can be run manually.
|
||||
</p>
|
||||
|
||||
<pre>$ cat > demo.xml <<EOF
|
||||
<domain type='qemu'>
|
||||
<name>QEMUGuest1</name>
|
||||
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||
<memory>219200</memory>
|
||||
<currentMemory>219200</currentMemory>
|
||||
<vcpu>1</vcpu>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu</emulator>
|
||||
<disk type='block' device='disk'>
|
||||
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
</devices>
|
||||
</domain>
|
||||
EOF
|
||||
|
||||
$ virsh domxml-to-native qemu-argv demo.xml
|
||||
LC_ALL=C PATH=/usr/bin:/bin HOME=/home/test \
|
||||
USER=test LOGNAME=test /usr/bin/qemu -S -M pc \
|
||||
-no-kqemu -m 214 -smp 1 -name QEMUGuest1 -nographic \
|
||||
-monitor pty -no-acpi -boot c -drive \
|
||||
file=/dev/HostVG/QEMUGuest1,if=ide,index=0 -net none \
|
||||
-serial none -parallel none -usb
|
||||
</pre>
|
||||
|
||||
<h2><a name="qemucommand">Pass-through of arbitrary qemu
|
||||
commands</a></h2>
|
||||
|
||||
<p>Libvirt provides an XML namespace and an optional
|
||||
library <code>libvirt-qemu.so</code> for dealing specifically
|
||||
with qemu. When used correctly, these extensions allow testing
|
||||
specific qemu features that have not yet been ported to the
|
||||
generic libvirt XML and API interfaces. However, they
|
||||
are <b>unsupported</b>, in that the library is not guaranteed to
|
||||
have a stable API, abusing the library or XML may result in
|
||||
inconsistent state the crashes libvirtd, and upgrading either
|
||||
qemu-kvm or libvirtd may break behavior of a domain that was
|
||||
relying on a qemu-specific pass-through. If you find yourself
|
||||
needing to use them to access a particular qemu feature, then
|
||||
please post an RFE to the libvirt mailing list to get that
|
||||
feature incorporated into the stable libvirt XML and API
|
||||
interfaces.
|
||||
</p>
|
||||
<p>The library provides two
|
||||
API: <code>virDomainQemuMonitorCommand</code>, for sending an
|
||||
arbitrary monitor command (in either HMP or QMP format) to a
|
||||
qemu guest (<span class="since">Since 0.8.3</span>),
|
||||
and <code>virDomainQemuAttach</code>, for registering a qemu
|
||||
domain that was manually started so that it can then be managed
|
||||
by libvirtd (<span class="since">Since 0.9.4</span>).
|
||||
</p>
|
||||
<p>Additionally, the following XML additions allow fine-tuning of
|
||||
the command line given to qemu when starting a domain
|
||||
(<span class="since">Since 0.8.3</span>). In order to use the
|
||||
XML additions, it is necessary to issue an XML namespace request
|
||||
(the special <code>xmlns:<i>name</i></code> attribute) that
|
||||
pulls in <code>http://libvirt.org/schemas/domain/qemu/1.0</code>;
|
||||
typically, the namespace is given the name
|
||||
of <code>qemu</code>. With the namespace in place, it is then
|
||||
possible to add an element <code><qemu:commandline></code>
|
||||
under <code>driver</code>, with the following sub-elements
|
||||
repeated as often as needed:
|
||||
<dl>
|
||||
<dt><code>qemu:arg</code></dt>
|
||||
<dd>Add an additional command-line argument to the qemu
|
||||
process when starting the domain, given by the value of the
|
||||
attribute <code>value</code>.
|
||||
</dd>
|
||||
<dt><code>qemu:env</code></dt>
|
||||
<dd>Add an additional environment variable to the qemu
|
||||
process when starting the domain, given with the name-value
|
||||
pair recorded in the attributes <code>name</code>
|
||||
and optional <code>value</code>.</dd>
|
||||
</dl>
|
||||
|
||||
<p>Example:</p><pre>
|
||||
<domain type='qemu' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>QEmu-fedora-i686</name>
|
||||
<memory>219200</memory>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
</os>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||
</devices>
|
||||
<qemu:commandline>
|
||||
<qemu:arg value='-newarg'/>
|
||||
<qemu:env name='QEMU_ENV' value='VAL'/>
|
||||
</qemu:commandline>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
<h2><a name="xmlconfig">Example domain XML config</a></h2>
|
||||
|
||||
<h3>QEMU emulated guest on x86_64</h3>
|
||||
|
||||
<pre><domain type='qemu'>
|
||||
<name>QEmu-fedora-i686</name>
|
||||
<uuid>c7a5fdbd-cdaf-9455-926a-d65c16db1809</uuid>
|
||||
<memory>219200</memory>
|
||||
<currentMemory>219200</currentMemory>
|
||||
<vcpu>2</vcpu>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
<boot dev='cdrom'/>
|
||||
</os>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='/home/user/boot.iso'/>
|
||||
<target dev='hdc'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='/home/user/fedora.img'/>
|
||||
<target dev='hda'/>
|
||||
</disk>
|
||||
<interface type='network'>
|
||||
<source network='default'/>
|
||||
</interface>
|
||||
<graphics type='vnc' port='-1'/>
|
||||
</devices>
|
||||
</domain></pre>
|
||||
|
||||
<h3>KVM hardware accelerated guest on i686</h3>
|
||||
|
||||
<pre><domain type='kvm'>
|
||||
<name>demo2</name>
|
||||
<uuid>4dea24b3-1d52-d8f3-2516-782e98a23fa0</uuid>
|
||||
<memory>131072</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<os>
|
||||
<type arch="i686">hvm</type>
|
||||
</os>
|
||||
<clock sync="localtime"/>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu-kvm</emulator>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='/var/lib/libvirt/images/demo2.img'/>
|
||||
<target dev='hda'/>
|
||||
</disk>
|
||||
<interface type='network'>
|
||||
<source network='default'/>
|
||||
<mac address='24:42:53:21:52:45'/>
|
||||
</interface>
|
||||
<graphics type='vnc' port='-1' keymap='de'/>
|
||||
</devices>
|
||||
</domain></pre>
|
||||
|
||||
<h3>Xen paravirtualized guests with hardware acceleration</h3>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Remote management driver</h1>
|
||||
</body>
|
||||
</html>
|
@ -1,25 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Test "mock" driver</h1>
|
||||
|
||||
<h2>Connections to Test driver</h2>
|
||||
|
||||
<p>
|
||||
The libvirt Test driver is a per-process fake hypervisor driver,
|
||||
with a driver name of 'test'. The driver maintains all its state
|
||||
in memory. It can start with a pre-configured default config, or
|
||||
be given a path to a alternate config. Some example conection URIs
|
||||
for the libvirt driver are:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
test:///default (local access, default config)
|
||||
test:///path/to/driver/config.xml (local access, custom config)
|
||||
test+unix:///default (local access, default config, via daemon)
|
||||
test://example.com/default (remote access, TLS/x509)
|
||||
test+tcp://example.com/default (remote access, SASl/Kerberos)
|
||||
test+ssh://root@example.com/default (remote access, SSH tunnelled)
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,91 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>User Mode Linux driver</h1>
|
||||
|
||||
<p>
|
||||
The UML driver for libvirt allows use and management of paravirtualized
|
||||
guests built for User Mode Linux. UML requires no special support in
|
||||
the host kernel, so can be used by any user of any linux system, provided
|
||||
they have enough free RAM for their guest's needs, though there are
|
||||
certain restrictions on network connectivity unless the administrator
|
||||
has pre-created TAP devices.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://user-mode-linux.sourceforge.net/">User
|
||||
Mode Linux</a> paravirtualized kernel
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Connections to UML driver</h2>
|
||||
|
||||
<p>
|
||||
The libvirt UML driver follows the QEMU driver in providing two
|
||||
types of connection. There is one privileged instance per host,
|
||||
which runs as root. This is called the "system" instance, and allows
|
||||
full use of all host resources. Then, there is a per-user unprivileged
|
||||
"session", instance. This has more restricted capabilities, and may
|
||||
require the host administrator to setup certain resources ahead of
|
||||
time to allow full integration with the network. Example connection
|
||||
URIs are
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
uml:///session (local access to per-user instance)
|
||||
uml+unix:///session (local access to per-user instance)
|
||||
|
||||
uml:///system (local access to system instance)
|
||||
uml+unix:///system (local access to system instance)
|
||||
uml://example.com/system (remote access, TLS/x509)
|
||||
uml+tcp://example.com/system (remote access, SASl/Kerberos)
|
||||
uml+ssh://root@example.com/system (remote access, SSH tunnelled)
|
||||
</pre>
|
||||
|
||||
<h2>Example XML configuration</h2>
|
||||
|
||||
<p>
|
||||
User mode Linux driver only supports directly kernel boot at
|
||||
this time. A future driver enhancement may allow a paravirt
|
||||
bootloader in a similar style to Xen's pygrub. For now though,
|
||||
the UML kernel must be stored on the host and referenced
|
||||
explicitly in the "os" element. Since UML is a paravirtualized
|
||||
technology, the kernel "type" is set to "uml"
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There is not yet support for networking in the driver, but
|
||||
disks can be specified in the usual libvirt manner. The main
|
||||
variation is the target device naming scheme "ubd0", and
|
||||
bus type of "uml".
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once booted the primary console is connected toa PTY, and
|
||||
thus accessible with "virsh console" or equivalent tools
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<domain type='uml'>
|
||||
<name>demo</name>
|
||||
<uuid>b4433fc2-a22e-ffb3-0a3d-9c173b395800</uuid>
|
||||
<memory>500000</memory>
|
||||
<currentMemory>500000</currentMemory>
|
||||
<vcpu>1</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64'>uml</type>
|
||||
<kernel>/home/berrange/linux-uml-2.6.26-x86_64</kernel>
|
||||
</os>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='/home/berrange/FedoraCore6-AMD64-root_fs'/>
|
||||
<target dev='ubd0' bus='uml'/>
|
||||
</disk>
|
||||
<console type='pty'/>
|
||||
</devices>
|
||||
</domain>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1,131 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>VirtualBox hypervisor driver</h1>
|
||||
<p>
|
||||
The libvirt VirtualBox driver can manage any VirtualBox version
|
||||
from version 2.2 onwards.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.virtualbox.org/">VirtualBox</a>
|
||||
hypervisor
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Connections to VirtualBox driver</h2>
|
||||
|
||||
<p>
|
||||
The libvirt VirtualBox driver provides per-user drivers (the "session" instance).
|
||||
The uri of the driver protocol is "vbox". Some example connection URIs for the driver are:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
vbox:///session (local access to per-user instance)
|
||||
vbox+unix:///session (local access to per-user instance)
|
||||
vbox+tcp://user@example.com/session (remote access, SASl/Kerberos)
|
||||
vbox+ssh://user@example.com/session (remote access, SSH tunnelled)
|
||||
</pre>
|
||||
|
||||
<h2><a name="xmlconfig">Example domain XML config</a></h2>
|
||||
|
||||
<pre>
|
||||
<domain type='vbox'>
|
||||
<name>vbox</name>
|
||||
<uuid>4dab22b31d52d8f32516782e98ab3fa0</uuid>
|
||||
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<boot dev='cdrom'/>
|
||||
<boot dev='hd'/>
|
||||
<boot dev='fd'/>
|
||||
<boot dev='network'/>
|
||||
</os>
|
||||
|
||||
<memory>654321</memory>
|
||||
<vcpu>1</vcpu>
|
||||
|
||||
<features>
|
||||
<pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
|
||||
<devices>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='/home/user/Downloads/slax-6.0.9.iso'/>
|
||||
<target dev='hdc'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
|
||||
<disk type='file' device='disk'>
|
||||
<source file='/home/user/tmp/vbox.vdi'/>
|
||||
<target dev='hdd'/>
|
||||
</disk>
|
||||
|
||||
<disk type='file' device='floppy'>
|
||||
<source file='/home/user/tmp/WIN98C.IMG'/>
|
||||
<target dev='fda'/>
|
||||
</disk>
|
||||
|
||||
<filesystem type='mount'>
|
||||
<source dir='/home/user/stuff'/>
|
||||
<target dir='my-shared-folder'/>
|
||||
</filesystem>
|
||||
|
||||
<!--BRIDGE-->
|
||||
<interface type='bridge'>
|
||||
<source bridge='eth0'/>
|
||||
<mac address='00:16:3e:5d:c7:9e'/>
|
||||
<model type='am79c973'/>
|
||||
</interface>
|
||||
|
||||
<!--NAT-->
|
||||
<interface type='user'>
|
||||
<mac address='56:16:3e:5d:c7:9e'/>
|
||||
<model type='82540eM'/>
|
||||
</interface>
|
||||
|
||||
<sound model='sb16'/>
|
||||
|
||||
<parallel type='dev'>
|
||||
<source path='/dev/pts/1'/>
|
||||
<target port='0'/>
|
||||
</parallel>
|
||||
|
||||
<parallel type='dev'>
|
||||
<source path='/dev/pts/2'/>
|
||||
<target port='1'/>
|
||||
</parallel>
|
||||
|
||||
<serial type="dev">
|
||||
<source path="/dev/ttyS0"/>
|
||||
<target port="0"/>
|
||||
</serial>
|
||||
|
||||
<serial type="pipe">
|
||||
<source path="/tmp/serial.txt"/>
|
||||
<target port="1"/>
|
||||
</serial>
|
||||
|
||||
<hostdev mode='subsystem' type='usb'>
|
||||
<source>
|
||||
<vendor id='0x1234'/>
|
||||
<product id='0xbeef'/>
|
||||
</source>
|
||||
</hostdev>
|
||||
|
||||
<hostdev mode='subsystem' type='usb'>
|
||||
<source>
|
||||
<vendor id='0x4321'/>
|
||||
<product id='0xfeeb'/>
|
||||
</source>
|
||||
</hostdev>
|
||||
</devices>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,80 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>VMware Workstation / Player hypervisors driver</h1>
|
||||
<p>
|
||||
The libvirt VMware Workstation driver should be able to manage any Workstation and
|
||||
Player version supported by the VMware VIX API. See the compatibility list
|
||||
<a href="http://www.vmware.com/support/developer/vix-api/vix110_reference/">here</a>.
|
||||
</p>
|
||||
<p>
|
||||
This driver uses the "vmrun" utility which is distributed with the VMware VIX API.
|
||||
You can download the VIX API
|
||||
from <a href="http://www.vmware.com/support/developer/vix-api/">here</a>.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.vmware.com/">VMware Workstation and
|
||||
Player</a> hypervisors
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Connections to VMware driver</h2>
|
||||
|
||||
<p>
|
||||
The libvirt VMware driver provides per-user drivers (the "session" instance).
|
||||
Two uris are available:
|
||||
</p>
|
||||
<ul>
|
||||
<li>"vmwareplayer" for VMware Player</li>
|
||||
<li>"vmwarews" for VMware Workstation</li>
|
||||
</ul>
|
||||
<p>
|
||||
Some example connection URIs for the driver are:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
vmwareplayer:///session (local access to VMware Player per-user instance)
|
||||
vmwarews:///session (local access to VMware Workstation per-user instance)
|
||||
vmwarews+tcp://user@example.com/session (remote access to VMware Workstation, SASl/Kerberos)
|
||||
vmwarews+ssh://user@example.com/session (remote access to VMware Workstation, SSH tunnelled)
|
||||
</pre>
|
||||
|
||||
<h2><a name="xmlconfig">Example domain XML config</a></h2>
|
||||
|
||||
<pre>
|
||||
<domain type='vmware'>
|
||||
<name>vmware</name>
|
||||
<uuid>bea92244-8885-4562-828b-3b086731c5b1</uuid>
|
||||
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
</os>
|
||||
|
||||
<memory>524288</memory>
|
||||
<vcpu>1</vcpu>
|
||||
|
||||
<features>
|
||||
<pae/>
|
||||
<acpi/>
|
||||
</features>
|
||||
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='/home/user/tmp/disk.vmdk'/>
|
||||
<target bus='ide' dev='hda'/>
|
||||
</disk>
|
||||
|
||||
<interface type='bridge'>
|
||||
<target dev='/dev/vmnet1'/>
|
||||
<source bridge=''/>
|
||||
<mac address='00:16:3e:5d:c7:9e'/>
|
||||
</interface>
|
||||
</devices>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,330 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Xen hypervisor driver</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<p>
|
||||
The libvirt Xen driver provides the ability to manage virtual machines
|
||||
on any Xen release from 3.0.1 onwards.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.cl.cam.ac.uk/Research/SRG/netos/xen/index.html">Xen</a>
|
||||
hypervisor on Linux and Solaris hosts
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="prereq">Deployment pre-requisites</a></h2>
|
||||
|
||||
<p>
|
||||
The libvirt Xen driver uses a combination of channels to manage Xen
|
||||
virtual machines.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>XenD</strong>: Access to the Xen daemon is a mandatory
|
||||
requirement for the libvirt Xen driver. It requires that the UNIX
|
||||
socket interface be enabled in the <code>/etc/xen/xend-config.sxp</code>
|
||||
configuration file. Specifically the config settings
|
||||
<code>(xend-unix-server yes)</code>. This path is usually restricted
|
||||
to only allow the <code>root</code> user access. As an alternative,
|
||||
the HTTP interface can be used, however, this has significant security
|
||||
implications.
|
||||
</li>
|
||||
<li>
|
||||
<strong>XenStoreD</strong>: Access to the Xenstore daemon enables
|
||||
more efficient codepaths for looking up domain information which
|
||||
lowers the CPU overhead of management.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Hypercalls</strong>: The ability to make direct hypercalls
|
||||
allows the most efficient codepaths in the driver to be used for
|
||||
monitoring domain status.
|
||||
</li>
|
||||
<li>
|
||||
<strong>XM config</strong>: When using Xen releases prior to 3.0.4,
|
||||
there is no inactive domain management in XenD. For such releases,
|
||||
libvirt will automatically process XM configuration files kept in
|
||||
the <code>/etc/xen</code> directory. It is important not to place
|
||||
any other non-config files in this directory.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="uri">Connections to Xen driver</a></h2>
|
||||
|
||||
<p>
|
||||
The libvirt Xen driver is a single-instance privileged driver,
|
||||
with a driver name of 'xen'. Some example conection URIs for
|
||||
the libvirt driver are:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
xen:/// (local access, direct)
|
||||
xen+unix:/// (local access, via daemon)
|
||||
xen://example.com/ (remote access, TLS/x509)
|
||||
xen+tcp://example.com/ (remote access, SASl/Kerberos)
|
||||
xen+ssh://root@example.com/ (remote access, SSH tunnelled)
|
||||
</pre>
|
||||
|
||||
<h2><a name="imex">Import and export of libvirt domain XML configs</a></h2>
|
||||
|
||||
<p>The Xen driver currently supports two native
|
||||
config formats. The first known as <code>xen-xm</code> is the format
|
||||
used by the XM tool for files in <code>/etc/xen</code>. The second
|
||||
known as <code>xen-sxpr</code>, is the format used for interacting
|
||||
with the XenD's legacy HTTP RPC service.</p>
|
||||
|
||||
<h3><a name="xmlimport">Converting from XM config files to domain XML</a></h3>
|
||||
|
||||
<p>
|
||||
The <code>virsh domxml-from-native</code> provides a way to convert an
|
||||
existing set of XM config files into a guest description using libvirt Domain XML
|
||||
that can then be used by libvirt.
|
||||
</p>
|
||||
|
||||
<pre>$ virsh -c xen:/// domxml-from-native xen-xm rhel5.cfg
|
||||
<domain type='xen'>
|
||||
<name>rhel5pv</name>
|
||||
<uuid>8f07fe28-753f-2729-d76d-bdbd892f949a</uuid>
|
||||
<memory>2560000</memory>
|
||||
<currentMemory>307200</currentMemory>
|
||||
<vcpu>4</vcpu>
|
||||
<bootloader>/usr/bin/pygrub</bootloader>
|
||||
<os>
|
||||
<type arch='x86_64' machine='xenpv'>linux</type>
|
||||
</os>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='tap' type='aio'/>
|
||||
<source file='/var/lib/xen/images/rhel5pv.img'/>
|
||||
<target dev='xvda' bus='xen'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='tap' type='qcow'/>
|
||||
<source file='/root/qcow1-xen.img'/>
|
||||
<target dev='xvdd' bus='xen'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
<mac address='00:16:3e:60:36:ba'/>
|
||||
<source bridge='xenbr0'/>
|
||||
</interface>
|
||||
<console type='pty'>
|
||||
<target port='0'/>
|
||||
</console>
|
||||
<input type='mouse' bus='xen'/>
|
||||
<graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'/>
|
||||
</devices>
|
||||
</domain></pre>
|
||||
|
||||
<h3><a name="xmlexport">Converting from domain XML to XM config files</a></h3>
|
||||
|
||||
<p>
|
||||
The <code>virsh domxml-to-native</code> provides a way to convert a
|
||||
guest description using libvirt Domain XML, into the XM config file
|
||||
format.
|
||||
</p>
|
||||
|
||||
<pre>$ virsh -c xen:/// domxml-to-native xen-xm rhel5pv.xml
|
||||
name = "rhel5pv"
|
||||
uuid = "8f07fe28-753f-2729-d76d-bdbd892f949a"
|
||||
maxmem = 2500
|
||||
memory = 300
|
||||
vcpus = 4
|
||||
bootloader = "/usr/bin/pygrub"
|
||||
kernel = "/var/lib/xen/boot_kernel.0YK-cS"
|
||||
ramdisk = "/var/lib/xen/boot_ramdisk.vWgrxK"
|
||||
extra = "ro root=/dev/VolGroup00/LogVol00 rhgb quiet"
|
||||
on_poweroff = "destroy"
|
||||
on_reboot = "restart"
|
||||
on_crash = "restart"
|
||||
sdl = 0
|
||||
vnc = 1
|
||||
vncunused = 1
|
||||
vnclisten = "0.0.0.0"
|
||||
disk = [ "tap:aio:/var/lib/xen/images/rhel5pv.img,xvda,w", "tap:qcow:/root/qcow1-xen.img,xvdd,w" ]
|
||||
vif = [ "mac=00:16:3e:60:36:ba,bridge=virbr0,script=vif-bridge,vifname=vif5.0" ]</pre>
|
||||
|
||||
<h2><a name="xmlconfig">Example domain XML config</a></h2>
|
||||
|
||||
<p>
|
||||
Below are some example XML configurations for Xen guest domains.
|
||||
For full details of the available options, consult the <a href="formatdomain.html">domain XML format</a>
|
||||
guide.
|
||||
</p>
|
||||
|
||||
<h3>Paravirtualized guest bootloader</h3>
|
||||
|
||||
<p>
|
||||
Using a bootloader allows a paravirtualized guest to be booted using
|
||||
a kernel stored inside its virtual disk image
|
||||
</p>
|
||||
|
||||
<pre><domain type='xen' >
|
||||
<name>fc8</name>
|
||||
<bootloader>/usr/bin/pygrub</bootloader>
|
||||
<os>
|
||||
<type>linux</type>
|
||||
</os>
|
||||
<memory>131072</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<devices>
|
||||
<disk type='file'>
|
||||
<source file='/var/lib/xen/images/fc4.img'/>
|
||||
<target dev='sda1'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
<source bridge='xenbr0'/>
|
||||
<mac address='aa:00:00:00:00:11'/>
|
||||
<script path='/etc/xen/scripts/vif-bridge'/>
|
||||
</interface>
|
||||
<console tty='/dev/pts/5'/>
|
||||
</devices>
|
||||
</domain></pre>
|
||||
|
||||
<h3>Paravirtualized guest direct kernel boot</h3>
|
||||
|
||||
<p>
|
||||
For installation of paravirtualized guests it is typical to boot the
|
||||
domain using a kernel and initrd stored in the host OS
|
||||
</p>
|
||||
|
||||
<pre><domain type='xen' >
|
||||
<name>fc8</name>
|
||||
<os>
|
||||
<type>linux</type>
|
||||
<kernel>/var/lib/xen/install/vmlinuz-fedora8-x86_64</kernel>
|
||||
<initrd>/var/lib/xen/install/initrd-vmlinuz-fedora8-x86_64</initrd>
|
||||
<cmdline> kickstart=http://example.com/myguest.ks </cmdline>
|
||||
</os>
|
||||
<memory>131072</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<devices>
|
||||
<disk type='file'>
|
||||
<source file='/var/lib/xen/images/fc4.img'/>
|
||||
<target dev='sda1'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
<source bridge='xenbr0'/>
|
||||
<mac address='aa:00:00:00:00:11'/>
|
||||
<script path='/etc/xen/scripts/vif-bridge'/>
|
||||
</interface>
|
||||
<graphics type='vnc' port='-1'/>
|
||||
<console tty='/dev/pts/5'/>
|
||||
</devices>
|
||||
</domain></pre>
|
||||
|
||||
<h3>Fullyvirtualized guest BIOS boot</h3>
|
||||
|
||||
<p>
|
||||
Fullyvirtualized guests use the emulated BIOS to boot off the primary
|
||||
harddisk, CDROM or Network PXE ROM.
|
||||
</p>
|
||||
|
||||
<pre><domain type='xen' id='3'>
|
||||
<name>fv0</name>
|
||||
<uuid>4dea22b31d52d8f32516782e98ab3fa0</uuid>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<loader>/usr/lib/xen/boot/hvmloader</loader>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<memory>524288</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<features>
|
||||
<pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock sync="localtime"/>
|
||||
<devices>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<interface type='bridge'>
|
||||
<source bridge='xenbr0'/>
|
||||
<mac address='00:16:3e:5d:c7:9e'/>
|
||||
<script path='vif-bridge'/>
|
||||
</interface>
|
||||
<disk type='file'>
|
||||
<source file='/var/lib/xen/images/fv0'/>
|
||||
<target dev='hda'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='/var/lib/xen/images/fc5-x86_64-boot.iso'/>
|
||||
<target dev='hdc'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<disk type='file' device='floppy'>
|
||||
<source file='/root/fd.img'/>
|
||||
<target dev='fda'/>
|
||||
</disk>
|
||||
<graphics type='vnc' port='5904'/>
|
||||
</devices>
|
||||
</domain></pre>
|
||||
|
||||
<h3>Fullyvirtualized guest direct kernel boot</h3>
|
||||
|
||||
<p>
|
||||
With Xen 3.2.0 or later it is possible to bypass the BIOS and directly
|
||||
boot a Linux kernel and initrd as a fullyvirtualized domain. This allows
|
||||
for complete automation of OS installation, for example using the Anaconda
|
||||
kickstart support.
|
||||
</p>
|
||||
|
||||
<pre><domain type='xen' id='3'>
|
||||
<name>fv0</name>
|
||||
<uuid>4dea22b31d52d8f32516782e98ab3fa0</uuid>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<loader>/usr/lib/xen/boot/hvmloader</loader>
|
||||
<kernel>/var/lib/xen/install/vmlinuz-fedora8-x86_64</kernel>
|
||||
<initrd>/var/lib/xen/install/initrd-vmlinuz-fedora8-x86_64</initrd>
|
||||
<cmdline> kickstart=http://example.com/myguest.ks </cmdline>
|
||||
</os>
|
||||
<memory>524288</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<features>
|
||||
<pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock sync="localtime"/>
|
||||
<devices>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<interface type='bridge'>
|
||||
<source bridge='xenbr0'/>
|
||||
<mac address='00:16:3e:5d:c7:9e'/>
|
||||
<script path='vif-bridge'/>
|
||||
</interface>
|
||||
<disk type='file'>
|
||||
<source file='/var/lib/xen/images/fv0'/>
|
||||
<target dev='hda'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='/var/lib/xen/images/fc5-x86_64-boot.iso'/>
|
||||
<target dev='hdc'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<disk type='file' device='floppy'>
|
||||
<source file='/root/fd.img'/>
|
||||
<target dev='fda'/>
|
||||
</disk>
|
||||
<graphics type='vnc' port='5904'/>
|
||||
</devices>
|
||||
</domain></pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,83 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1 >Handling of errors</h1>
|
||||
<p>The main goals of libvirt when it comes to error handling are:</p>
|
||||
<ul>
|
||||
<li>provide as much detail as possible</li>
|
||||
<li>provide the information as soon as possible</li>
|
||||
<li>dont force the library user into one style of error handling</li>
|
||||
</ul>
|
||||
<p>As result the library provide both synchronous, callback based and
|
||||
asynchronous error reporting. When an error happens in the library code the
|
||||
error is logged, allowing to retrieve it later and if the user registered an
|
||||
error callback it will be called synchronously. Once the call to libvirt ends
|
||||
the error can be detected by the return value and the full information for
|
||||
the last logged error can be retrieved.</p>
|
||||
<p>To avoid as much as possible troubles with a global variable in a
|
||||
multithreaded environment, libvirt will associate when possible the errors to
|
||||
the current connection they are related to, that way the error is stored in a
|
||||
dynamic structure which can be made thread specific. Error callback can be
|
||||
set specifically to a connection with</p>
|
||||
<p>So error handling in the code is the following:</p>
|
||||
<ol>
|
||||
<li>if the error can be associated to a connection for example when failing
|
||||
to look up a domain
|
||||
<ol><li>if there is a callback associated to the connection set with <a href="html/libvirt-virterror.html#virConnSetErrorFunc">virConnSetErrorFunc</a>,
|
||||
call it with the error information</li><li>otherwise if there is a global callback set with <a href="html/libvirt-virterror.html#virSetErrorFunc">virSetErrorFunc</a>,
|
||||
call it with the error information</li><li>otherwise call <a href="html/libvirt-virterror.html#virDefaultErrorFunc">virDefaultErrorFunc</a>
|
||||
which is the default error function of the library issuing the error
|
||||
on stderr</li><li>save the error in the connection for later retrieval with <a href="html/libvirt-virterror.html#virConnGetLastError">virConnGetLastError</a></li></ol></li>
|
||||
<li>otherwise like when failing to create an hypervisor connection:
|
||||
<ol><li>if there is a global callback set with <a href="html/libvirt-virterror.html#virSetErrorFunc">virSetErrorFunc</a>,
|
||||
call it with the error information</li><li>otherwise call <a href="html/libvirt-virterror.html#virDefaultErrorFunc">virDefaultErrorFunc</a>
|
||||
which is the default error function of the library issuing the error
|
||||
on stderr</li><li>save the error in the connection for later retrieval with <a href="html/libvirt-virterror.html#virGetLastError">virGetLastError</a></li></ol></li>
|
||||
</ol>
|
||||
<p>In all cases the error information is provided as a <a href="html/libvirt-virterror.html#virErrorPtr">virErrorPtr</a> pointer to
|
||||
read-only structure <a href="html/libvirt-virterror.html#virError">virError</a> containing the
|
||||
following fields:</p>
|
||||
<ul>
|
||||
<li>code: an error number from the <a href="html/libvirt-virterror.html#virErrorNumber">virErrorNumber</a>
|
||||
enum</li>
|
||||
<li>domain: an enum indicating which part of libvirt raised the error see
|
||||
<a href="html/libvirt-virterror.html#virErrorDomain">virErrorDomain</a></li>
|
||||
<li>level: the error level, usually VIR_ERR_ERROR, though there is room for
|
||||
warnings like VIR_ERR_WARNING</li>
|
||||
<li>message: the full human-readable formatted string of the error</li>
|
||||
<li>conn: if available a pointer to the <a href="html/libvirt-libvirt.html#virConnectPtr">virConnectPtr</a>
|
||||
connection to the hypervisor where this happened</li>
|
||||
<li>dom: if available a pointer to the <a href="html/libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain
|
||||
targeted in the operation</li>
|
||||
</ul>
|
||||
<p>and then extra raw information about the error which may be initialized
|
||||
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 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>.
|
||||
For asynchronous error handing, set such a function doing nothing to avoid
|
||||
the error being reported on stderr, and call virConnGetLastError or
|
||||
virGetLastError when an API call returned an error value. It can be a good
|
||||
idea to use <a href="html/libvirt-virterror.html#virResetLastError">virResetError</a> or <a href="html/libvirt-virterror.html#virConnResetLastError">virConnResetLastError</a>
|
||||
once an error has been processed fully.</p>
|
||||
<p>At the python level, there only a global reporting callback function at
|
||||
this point, see the error.py example about it:</p>
|
||||
<pre>def handler(ctxt, err):
|
||||
global errno
|
||||
|
||||
#print "handler(%s, %s)" % (ctxt, err)
|
||||
errno = err
|
||||
|
||||
libvirt.registerErrorHandler(handler, 'context') </pre>
|
||||
<p>the second argument to the registerErrorHandler function is passed as the
|
||||
first argument of the callback like in the C version. The error is a tuple
|
||||
containing the same field as a virError in C, but cast to Python.</p>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user