mirror of https://gitee.com/openkylin/libvirt.git
Import Upstream version 8.5.0
This commit is contained in:
commit
396cdcb173
|
@ -0,0 +1,6 @@
|
|||
--recurse
|
||||
--exclude=*.orig
|
||||
--exclude=*.html
|
||||
--exclude=*.html.in
|
||||
--langmap=c:+.h.in
|
||||
--c-kinds=+p
|
|
@ -0,0 +1 @@
|
|||
../.ctags
|
|
@ -0,0 +1,20 @@
|
|||
(
|
||||
(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)
|
||||
))
|
||||
(perl-mode . (
|
||||
(indent-tabs-mode . nil)
|
||||
))
|
||||
)
|
|
@ -0,0 +1,21 @@
|
|||
# EditorConfig is a file format and collection of text editor plugins
|
||||
# for maintaining consistent coding styles between different editors
|
||||
# and IDEs. Most popular editors support this either natively or via
|
||||
# plugin.
|
||||
#
|
||||
# Check https://editorconfig.org for details.
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
|
||||
[*.c]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{rng,xml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
|
@ -0,0 +1,927 @@
|
|||
===============
|
||||
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:
|
||||
|
||||
* Andrea Bolognani <abologna@redhat.com>
|
||||
* Cédric Bosdonnat <cbosdonnat@suse.com>
|
||||
* Christian Ehrhardt <christian.ehrhardt@canonical.com>
|
||||
* Christophe Fergeau <cfergeau@redhat.com>
|
||||
* Cole Robinson <crobinso@redhat.com>
|
||||
* Daniel P. Berrangé <berrange@redhat.com>
|
||||
* Daniel Veillard <veillard@redhat.com>
|
||||
* Eric Blake <eblake@redhat.com>
|
||||
* Erik Skultety <eskultet@redhat.com>
|
||||
* Fabiano Fidêncio <fidencio@redhat.com>
|
||||
* Guido Günther <agx@sigxcpu.org>
|
||||
* Ján Tomko <jtomko@redhat.com>
|
||||
* Jim Fehlig <jfehlig@suse.com>
|
||||
* Jiří Denemark <jdenemar@redhat.com>
|
||||
* Laine Stump <laine@redhat.com>
|
||||
* Martin Kletzander <mkletzan@redhat.com>
|
||||
* Michal Prívozník <mprivozn@redhat.com>
|
||||
* Nikolay Shirokovskiy <nshirokovskiy@openvz.org>
|
||||
* Pavel Hrdina <phrdina@redhat.com>
|
||||
* Peter Krempa <pkrempa@redhat.com>
|
||||
* Pino Toscano <ptoscano@redhat.com>
|
||||
* Richard W.M. Jones <rjones@redhat.com>
|
||||
* Roman Bogorodskiy <bogorodskiy@gmail.com>
|
||||
* Tim Wiederhake <twiederh@redhat.com>
|
||||
|
||||
Previous maintainers:
|
||||
|
||||
* Alex Jia <ajia@redhat.com>
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
* Atsushi SAKAI <sakaia@jp.fujitsu.com>
|
||||
* Chris Lalancette <clalance@redhat.com>
|
||||
* Claudio Bley <claudio.bley@gmail.com>
|
||||
* Dan Smith <danms@us.ibm.com>
|
||||
* Dave Allan <dallan@redhat.com>
|
||||
* Dave Leskovec <dlesko@linux.vnet.ibm.com>
|
||||
* Dmitry Guryanov <dguryanov@parallels.com>
|
||||
* Doug Goldstein <cardoe@gentoo.org>
|
||||
* Gao Feng <gaofeng@cn.fujitsu.com>
|
||||
* Guannan Ren <gren@redhat.com>
|
||||
* Jim Meyering <meyering@redhat.com>
|
||||
* John Ferlan <jferlan@redhat.com>
|
||||
* John Levon <john.levon@sun.com>
|
||||
* Justin Clift <jclift@redhat.com>
|
||||
* Karel Zak <kzak@redhat.com>
|
||||
* Katerina Koukiou <kkoukiou@redhat.com>
|
||||
* Mark McLoughlin <markmc@redhat.com>
|
||||
* Matthias Bolte <matthias.bolte@googlemail.com>
|
||||
* Maxim Nestratov <mnestratov@virtuozzo.com>
|
||||
* Osier Yang <jyang@redhat.com>
|
||||
* Stefan Berger <stefanb@us.ibm.com>
|
||||
* Wen Congyang <wency@cn.fujitsu.com>
|
||||
|
||||
Patches have also been contributed by:
|
||||
|
||||
* Abel Míguez Rodríguez <amiguezr@pdi.ucm.es>
|
||||
* Amit Shah <amit.shah@redhat.com>
|
||||
* Andrew Puch <apuch@redhat.com>
|
||||
* Anton Protopopov <aspsk2@gmail.com>
|
||||
* Ben Guthro <ben.guthro@gmail.com>
|
||||
* Daniel Hokka Zakrisson <daniel@hozac.com>
|
||||
* Dan Wendlandt <dan@nicira.com>
|
||||
* David Lively <dlively@virtualiron.com>
|
||||
* David Lutterkort <dlutter@redhat.com>
|
||||
* Evgeniy Sokolov <evg@openvz.org>
|
||||
* Hugh Brock <hbrock@redhat.com>
|
||||
* Itamar Heim <iheim@redhat.com>
|
||||
* James Morris <jmorris@namei.org>
|
||||
* Javier Fontan <jfontan@gmail.com>
|
||||
* Jeremy Katz <katzj@redhat.com>
|
||||
* Kaitlin Rupert <kaitlin@linux.vnet.ibm.com>
|
||||
* Kazuki Mizushima <mizushima.kazuk@jp.fujitsu.com>
|
||||
* Mads Chr. Olesen <shiyee@shiyee.dk>
|
||||
* Mark Johnson <johnson.nh@gmail.com>
|
||||
* Markus Armbruster <armbru@redhat.com>
|
||||
* Masayuki Sunou <fj1826dm@aa.jp.fujitsu.com>
|
||||
* Matthias Witte <witte@netzquadrat.de>
|
||||
* Michel Ponceau <michel.ponceau@bull.net>
|
||||
* Nobuhiro Itou <fj0873gn@aa.jp.fujitsu.com>
|
||||
* Pete Vetere <pvetere@redhat.com>
|
||||
* Philippe Berthault <philippe.berthault@Bull.net>
|
||||
* Saori Fukuta <fukuta.saori@jp.fujitsu.com>
|
||||
* Shigeki Sakamoto <fj0588di@aa.jp.fujitsu.com>
|
||||
* Shuveb Hussain <shuveb@binarykarma.com>
|
||||
* Stefan de Konink <dekonink@kinkrsoftware.nl>
|
||||
* Takahashi Tomohiro <takatom@jp.fujitsu.com>
|
||||
* Tatsuro Enokura <fj7716hz@aa.jp.fujitsu.com>
|
||||
|
||||
* Adam Litke <agl@us.ibm.com>
|
||||
* Adam Walters <adam@pandorasboxen.com>
|
||||
* Adolfo Jayme Barrientos <fitoschido@gmail.com>
|
||||
* Adrian Brzezinski <adrian.brzezinski@eo.pl>
|
||||
* Akarshan Biswas <akarshan.biswas@gmail.com>
|
||||
* Alan Pevec <apevec@redhat.com>
|
||||
* Aleksandr Alekseev <alexander.alekseev@virtuozzo.com>
|
||||
* Aleksei Zakharov <zaharov@selectel.ru>
|
||||
* Ales Musil <amusil@redhat.com>
|
||||
* Alex Jia <ajia@redhat.com>
|
||||
* Alex Williamson <alex.williamson@redhat.com>
|
||||
* Alexander Burluka <aburluka@parallels.com>
|
||||
* Alexander Burluka <aburluka@virtuozzo.com>
|
||||
* Alexander Larsson <alexl@redhat.com>
|
||||
* Alexander Nusov <alexander.nusov@nfvexpress.com>
|
||||
* Alexander Todorov <atodorov@otb.bg>
|
||||
* Alexander Vasilenko <kaperang07@gmail.com>
|
||||
* Aline Manera <alinefm@br.ibm.com>
|
||||
* Allen, John <John.Allen@amd.com>
|
||||
* Alon Levy <alevy@redhat.com>
|
||||
* Alvaro Polo <apoloval@gmail.com>
|
||||
* Amneesh Singh <natto@weirdnatto.in>
|
||||
* Amy Fong <amy.fong@windriver.com>
|
||||
* Amy Griffis <amy.griffis@hp.com>
|
||||
* Anatole Denis <natolumin@gmail.com>
|
||||
* Andika Triwidada <andika@gmail.com>
|
||||
* Andrea Bolognani <abologna@redhat.com>
|
||||
* Andres Lagar-Cavilla <andres@lagarcavilla.org>
|
||||
* Andrew Melnychenko <andrew@daynix.com>
|
||||
* Andrew Miloradovsky <andrew@interpretmath.pw>
|
||||
* Ani Sinha <ani.sinha@nutanix.com>
|
||||
* Ani Sinha <ani@anisinha.ca>
|
||||
* Anirban Chakraborty <abchak@juniper.net>
|
||||
* Ansis Atteka <aatteka@nicira.com>
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
* Anthony PERARD <anthony.perard@citrix.com>
|
||||
* Antoine Millet <antoine.millet@tdf.fr>
|
||||
* Anton Khramov <anton@endocode.com>
|
||||
* Antoni S. Puimedon <asegurap@redhat.com>
|
||||
* Antoni Segura Puimedon <toni@midokura.com>
|
||||
* Anya Harter <aharter@redhat.com>
|
||||
* Arnaud Patard <apatard@hupstream.com>
|
||||
* Aron Griffis <aron.griffis@hp.com>
|
||||
* Artur Puzio <contact@puzio.waw.pl>
|
||||
* Asad Saeed <asad.saeed@acidseed.com>
|
||||
* Ashish Mittal <Ashish.Mittal@veritas.com>
|
||||
* Ashish Mittal <ashmit602@gmail.com>
|
||||
* Ata E Husain Bohra <ata.husain@hotmail.com>
|
||||
* Atsushi Kumagai <kumagai-atsushi@mxc.nes.nec.co.jp>
|
||||
* Atsushi SAKAI <sakaia@jp.fujitsu.com>
|
||||
* Aurelien Rougemont <beorn@binaries.fr>
|
||||
* Balázs Meskó <meskobalazs@mailbox.org>
|
||||
* Bamvor Jian Zhang <bamv2005@gmail.com>
|
||||
* Bamvor Jian Zhang <bjzhang@suse.com>
|
||||
* Barrett Schonefeld <bschoney@utexas.edu>
|
||||
* Bastian Germann <bastiangermann@fishpost.de>
|
||||
* Bastien Orivel <bastien.orivel@diateam.net>
|
||||
* Beat Jörg <Beat.Joerg@ssatr.ch>
|
||||
* Ben Gray <ben.r.gray@gmail.com>
|
||||
* Benjamin Cama <benoar@dolka.fr>
|
||||
* Bharata B Rao <bharata@linux.vnet.ibm.com>
|
||||
* BiaoXiang Ye <yebiaoxiang@huawei.com>
|
||||
* Bihong Yu <yubihong@huawei.com>
|
||||
* Binfeng Wu <wubinfeng@huawei.com>
|
||||
* Bing Bu Cao <mars@linux.vnet.ibm.com>
|
||||
* Bing Niu <bing.niu@intel.com>
|
||||
* Bjoern Walk <bwalk@linux.ibm.com>
|
||||
* Bjoern Walk <bwalk@linux.vnet.ibm.com>
|
||||
* Bob Liu <bob.liu@oracle.com>
|
||||
* Bobo Du <dubo163@126.com>
|
||||
* Bogdan Purcareata <bogdan.purcareata@freescale.com>
|
||||
* Boris Fiuczynski <fiuczy@linux.ibm.com>
|
||||
* Boris Fiuczynski <fiuczy@linux.vnet.ibm.com>
|
||||
* Brandon Bennett <bbennett@fb.com>
|
||||
* Brian Candler <b.candler@pobox.com>
|
||||
* Brian Turek <brian.turek@gmail.com>
|
||||
* Brijesh Singh <brijesh.singh@amd.com>
|
||||
* Bruno Haible <bruno@clisp.org>
|
||||
* Bryan Kearney <bkearney@redhat.com>
|
||||
* Cao jin <caoj.fnst@cn.fujitsu.com>
|
||||
* Carlos Santos <casantos@redhat.com>
|
||||
* Casey Callendrello <cdc@redhat.com>
|
||||
* Cedric Bosdonnat <cbosdonnat@suse.com>
|
||||
* Chang Liu <lingjiao.lc@taobao.com>
|
||||
* Chao Fan <fanc.fnst@cn.fujitsu.com>
|
||||
* Charles Duffy <charles_duffy@messageone.com>
|
||||
* Chegu Vinod <chegu_vinod@hp.com>
|
||||
* Chen Fan <chen.fan.fnst@cn.fujitsu.com>
|
||||
* Chen Hanxiao <chen_han_xiao@126.com>
|
||||
* Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
|
||||
* Chen Hanxiao <chenhanxiao@gmail.com>
|
||||
* Cheng Lin <cheng.lin130@zte.com.cn>
|
||||
* Chris Coulson <chris.coulson@canonical.com>
|
||||
* Chris J Arges <chris.j.arges@canonical.com>
|
||||
* Chris Jester-Young <cky@cky.nz>
|
||||
* Chris Lalancette <clalance@redhat.com>
|
||||
* Chris Mayo <aklhfex@gmail.com>
|
||||
* Chris St. Pierre <chris.a.st.pierre@gmail.com>
|
||||
* Chris Venteicher <cventeic@redhat.com>
|
||||
* Chris Wong <wongc-redhat@hoku.net>
|
||||
* Chris Wright <chrisw@redhat.com>
|
||||
* Christian Benvenuti <benve@cisco.com>
|
||||
* Christian Ehrhardt <christian.ehrhardt@canonical.com>
|
||||
* Christian Franke <nobody@nowhere.ws>
|
||||
* Christian Kirbach <christian.kirbach@gmail.com>
|
||||
* Christian Loehle <cloehle@linutronix.de>
|
||||
* Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
* Christoffer Dall <cdall@linaro.org>
|
||||
* Christophe Fergeau <cfergeau@redhat.com>
|
||||
* Chuck Short <chuck.short@canonical.com>
|
||||
* Chuck Short <zulcss@gmail.com>
|
||||
* Chunhe Li <lichunhe@huawei.com>
|
||||
* Chunyan Liu <cyliu@suse.com>
|
||||
* Clark Laughlin <clark.laughlin@linaro.org>
|
||||
* Claudio André <claudioandre.br@gmail.com>
|
||||
* Claudio Bley <claudio.bley@gmail.com>
|
||||
* Claudio Fontana <cfontana@suse.de>
|
||||
* Clementine Hayat <clem@lse.epita.fr>
|
||||
* Cole Robinson <crobinso@redhat.com>
|
||||
* Collin L. Walling <walling@linux.vnet.ibm.com>
|
||||
* Collin Walling <walling@linux.ibm.com>
|
||||
* Conrad Meyer <cse.cem@gmail.com>
|
||||
* Corey S. McQuay <csmcquay@linux.vnet.ibm.com>
|
||||
* Cornelia Huck <cohuck@redhat.com>
|
||||
* Cristian Klein <cristiklein@gmail.com>
|
||||
* Cédric Bosdonnat <cbosdonnat@suse.com>
|
||||
* Côme Borsoi <fedora@borsoi.fr>
|
||||
* Dan Horák <dan@danny.cz>
|
||||
* Dan Kenigsberg <danken@redhat.com>
|
||||
* Dan Smith <danms@us.ibm.com>
|
||||
* Dan Zheng <dzheng@redhat.com>
|
||||
* Daniel Berteaud <daniel@firewall-services.com>
|
||||
* Daniel Gollub <gollub@b1-systems.de>
|
||||
* Daniel Hansel <daniel.hansel@linux.vnet.ibm.com>
|
||||
* Daniel Henrique Barboza <danielhb413@gmail.com>
|
||||
* Daniel J Walsh <dwalsh@redhat.com>
|
||||
* Daniel Letai <dani@letai.org.il>
|
||||
* Daniel Liu <srwx4096@gmail.com>
|
||||
* Daniel Nicoletti <dantti12@gmail.com>
|
||||
* Daniel P. Berrangé <berrange@redhat.com>
|
||||
* Daniel Veillard <veillard@redhat.com>
|
||||
* Dario Faggioli <dario.faggioli@citrix.com>
|
||||
* Dario Faggioli <dfaggioli@suse.com>
|
||||
* Darryl L. Pierce <dpierce@redhat.com>
|
||||
* Dave Allan <dallan@redhat.com>
|
||||
* David Dai <zdai@linux.vnet.ibm.com>
|
||||
* David Jorm <dfj@redhat.com>
|
||||
* David Kiarie <davidkiarie4@gmail.com>
|
||||
* David L Stevens <dlstevens@us.ibm.com>
|
||||
* David L. Leskovec <dlesko@linux.vnet.ibm.com>
|
||||
* David Mansfield <dmansfield@gmail.com>
|
||||
* David S. Wang <dwang2@cisco.com>
|
||||
* David Shane Holden <dpejesh@yahoo.com>
|
||||
* David Weber <wb@munzinger.de>
|
||||
* Davidlohr Bueso <dave@gnu.org>
|
||||
* Dawid Zamirski <dzamirski@datto.com>
|
||||
* Dawid Zamirski <dzamirski@dattobackup.com>
|
||||
* Dawid Zamirski <dzrudy@gmail.com>
|
||||
* Deepak C Shetty <dpkshetty@gmail.com>
|
||||
* Denis Kondratenko <denis.kondratenko@gmail.com>
|
||||
* Dennis Chen <xschen@tnsoft.com.cn>
|
||||
* Derbyshev Dmitry <dderbyshev@virtuozzo.com>
|
||||
* Didik Supriadi <didiksupriadi41@gmail.com>
|
||||
* Diego Elio Pettenò <flameeyes@gmail.com>
|
||||
* Diego Michelotto <diego.michelotto@cnaf.infn.it>
|
||||
* Diego Woitasen <diego.woitasen@vhgroup.net>
|
||||
* Dipankar Sarma <dipankar@in.ibm.com>
|
||||
* Dirk Herrendoerfer <d.herrendoerfer@herrendoerfer.name>
|
||||
* Divya Garg <divya.garg@nutanix.com>
|
||||
* Dmitrii Shcherbakov <dmitrii.shcherbakov@canonical.com>
|
||||
* Dmitry Andreev <dandreev@virtuozzo.com>
|
||||
* Dmitry Guryanov <dguryanov@parallels.com>
|
||||
* Dmitry Mishin <dim@virtuozzo.com>
|
||||
* Dmitry Nesterenko <dmitry.nesterenko@virtuozzo.com>
|
||||
* Dmytro Linkin <dlinkin@nvidia.com>
|
||||
* Dominick Grift <dac.override@gmail.com>
|
||||
* Dominik Perpeet <dperpeet@redhat.com>
|
||||
* Don Dugger <n0ano@n0ano.com>
|
||||
* Doug Goldstein <cardoe@cardoe.com>
|
||||
* Douglas Schilling Landgraf <dougsland@redhat.com>
|
||||
* Duncan Rance <libvirt@dunquino.com>
|
||||
* Dustin Kirkland <kirkland@canonical.com>
|
||||
* Dustin Xiong <x_k_123@hotmail.com>
|
||||
* Dusty Mabe <dustymabe@gmail.com>
|
||||
* Dwight Engen <dwight.engen@oracle.com>
|
||||
* Ed Swierk <eswierk@aristanetworks.com>
|
||||
* Edan David <edand@mellanox.com>
|
||||
* Eduardo Costa <eduardobmc@gmail.com>
|
||||
* Eduardo Habkost <ehabkost@redhat.com>
|
||||
* Eduardo Otubo <otubo@linux.vnet.ibm.com>
|
||||
* Eiichi Tsukata <eiichi.tsukata.xh@hitachi.com>
|
||||
* Eiichi Tsukata <eiichi.tsukata@nutanix.com>
|
||||
* Eli Qiao <liyong.qiao@intel.com>
|
||||
* Eli Qiao <taget@linux.vnet.ibm.com>
|
||||
* Emilio Herrera <ehespinosa57@gmail.com>
|
||||
* Eric Blake <eblake@redhat.com>
|
||||
* Eric Farman <farman@linux.ibm.com>
|
||||
* Eric Farman <farman@linux.vnet.ibm.com>
|
||||
* Eric W. Biederman <ebiederm@xmission.com>
|
||||
* Erik Skultety <eskultet@redhat.com>
|
||||
* Ersek Laszlo <lacos@caesar.elte.hu>
|
||||
* Eugen Feller <eugen.feller@inria.fr>
|
||||
* Fabian Affolter <mail@fabian-affolter.ch>
|
||||
* Fabian Freyer <fabian.freyer@physik.tu-berlin.de>
|
||||
* Fabiano Fidêncio <fidencio@redhat.com>
|
||||
* Fangge Jin <fjin@redhat.com>
|
||||
* Farhan Ali <alifm@linux.ibm.com>
|
||||
* Farhan Ali <alifm@linux.vnet.ibm.com>
|
||||
* Federico Simoncelli <fsimonce@redhat.com>
|
||||
* Felix Geyer <debfx@fobos.de>
|
||||
* Felix Geyer <fgeyer@debian.org>
|
||||
* Filip Alac <filipalac@gmail.com>
|
||||
* Florian Vichot <florian.vichot@diateam.net>
|
||||
* Francesc Guasch <frankie@etsetb.upc.edu>
|
||||
* Francesco Romani <fromani@redhat.com>
|
||||
* Franck Ridel <fridel@protonmail.com>
|
||||
* Frank Schreuder <fschreuder@transip.nl>
|
||||
* Fred A. Kemp <anonym@riseup.net>
|
||||
* Frediano Ziglio <frediano.ziglio@citrix.com>
|
||||
* Frediano Ziglio <fziglio@redhat.com>
|
||||
* Frido Roose <frido.roose@gmail.com>
|
||||
* Fritz Elfert <fritz@fritz-elfert.de>
|
||||
* Félix Bouliane <felixbouliane@gmail.com>
|
||||
* Gao feng <gaofeng@cn.fujitsu.com>
|
||||
* Garry Dolley <gdolley@arpnetworks.com>
|
||||
* Gary R Hook <grhookatwork@gmail.com>
|
||||
* Gaurav Agrawal <agrawalgaurav@gnome.org>
|
||||
* Gema Gomez <gema.gomez-solano@linaro.org>
|
||||
* Gene Czarcinski <gene@czarc.net>
|
||||
* Geoff Hickey <ghickey@datagravity.com>
|
||||
* George Dunlap <george.dunlap@citrix.com>
|
||||
* Gerd Hoffmann <kraxel@redhat.com>
|
||||
* Gerd v. Egidy <gerd@egidy.de>
|
||||
* Gerhard Stenzel <gerhard.stenzel@de.ibm.com>
|
||||
* Giuseppe Scrivano <gscrivan@redhat.com>
|
||||
* Gordon Messmer <gordon@dragonsdawn.net>
|
||||
* Gregor Kopka <gregor@kopka.net>
|
||||
* Guan Qiang <hzguanqiang@corp.netease.com>
|
||||
* Guannan Ren <gren@redhat.com>
|
||||
* Gui Jianfeng <guijianfeng@cn.fujitsu.com>
|
||||
* Guido Günther <agx@sigxcpu.org>
|
||||
* Göran Uddeborg <goeran@uddeborg.se>
|
||||
* Halil Pasic <pasic@linux.ibm.com>
|
||||
* Han Cheng <hanc.fnst@cn.fujitsu.com>
|
||||
* Han Han <hhan@redhat.com>
|
||||
* Hao Liu <hliu@redhat.com>
|
||||
* Hao Peng <peng.hao2@zte.com.cn>
|
||||
* Hao Wang <wanghao232@huawei.com>
|
||||
* Haonan Wang <hnwanga1@gmail.com>
|
||||
* Harry Wei <harryxiyou@gmail.com>
|
||||
* Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
|
||||
* Harshavardhana <harsha@gluster.com>
|
||||
* Heath Petersen <HeathPetersen@Kandre.com>
|
||||
* Hela Basa <r45xveza@pm.me>
|
||||
* Helmut Grohne <helmut@subdivi.de>
|
||||
* Hendrik Schwartke <hendrik@os-t.de>
|
||||
* Henning Schild <henning.schild@siemens.com>
|
||||
* Henrik Persson E <henrik.e.persson@ericsson.com>
|
||||
* Hero Phương <herophuong93@gmail.com>
|
||||
* Hiroki Narukawa <hnarukaw@yahoo-corp.jp>
|
||||
* Hongbin Lu <hongbin034@gmail.com>
|
||||
* Hongwei Bi <hwbi2008@gmail.com>
|
||||
* Hu Jianwei <jiahu@redhat.com>
|
||||
* Hu Tao <hutao@cn.fujitsu.com>
|
||||
* Huanle Han <hanxueluo@gmail.com>
|
||||
* Huaqiang <huaqiang.wang@intel.com>
|
||||
* Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
|
||||
* Ian Campbell <Ian.Campbell@citrix.com>
|
||||
* Ian Campbell <ian.campbell@citrix.com>
|
||||
* Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
* Ian Main <imain@redhat.com>
|
||||
* Ian Wienand <iwienand@redhat.com>
|
||||
* Igor Gnatenko <ignatenkobrain@fedoraproject.org>
|
||||
* Ilias Stamatis <stamatis.iliass@gmail.com>
|
||||
* Ilja Livenson <ilja.livenson@gmail.com>
|
||||
* Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com>
|
||||
* Ishmanpreet Kaur Khera <khera.ishman@gmail.com>
|
||||
* Ivan Baldo <ibaldo@adinet.com.uy>
|
||||
* Ivan Kardykov <kardykov@tabit.pro>
|
||||
* Ivan Teterevkov <ivan.teterevkov@nutanix.com>
|
||||
* J.B. Joret <jb@linux.vnet.ibm.com>
|
||||
* Jaak Ristioja <jaak@ristioja.ee>
|
||||
* Jakob Meng <jakobmeng@web.de>
|
||||
* James Chapman <james.p.chapman@intel.com>
|
||||
* James Cowgill <james410@cowgill.org.uk>
|
||||
* James Shubin <james@shubin.ca>
|
||||
* Jamie Strandboge <jamie@canonical.com>
|
||||
* Jan Kiszka <jan.kiszka@siemens.com>
|
||||
* Jan Kuparinen <copper_fin@hotmail.com>
|
||||
* Jan Palus <atler@pld-linux.org>
|
||||
* Jaroslav Safka <jaroslavx.safka@intel.com>
|
||||
* Jaroslav Suchanek <jsuchane@redhat.com>
|
||||
* Jason Andryuk <andryuk@aero.org>
|
||||
* Jason Baron <jbaron@akamai.com>
|
||||
* Jason Dillaman <dillaman@redhat.com>
|
||||
* Jason J. Herne <jjherne@linux.vnet.ibm.com>
|
||||
* Jason Miesionczek <jmiesionczek@datto.com>
|
||||
* Jasper Lievisse Adriaanse <jasper@humppa.nl>
|
||||
* Jasper Lievisse Adriaanse <jasper@openbsd.org>
|
||||
* Jean-Baptiste Holcroft <jean-baptiste@holcroft.fr>
|
||||
* Jean-Baptiste Rouault <jean-baptiste.rouault@diateam.net>
|
||||
* Jean-Marc Liger <jean-marc.liger@parisdescartes.fr>
|
||||
* Jeremy Fitzhardinge <jeremy@goop.org>
|
||||
* Jesse Cook <code.crashenx@gmail.com>
|
||||
* Jesse J. Cook <jesse.j.cook@member.fsf.org>
|
||||
* Jia Zhou <zhou.jia2@zte.com.cn>
|
||||
* Jianan Gao <jgao@redhat.com>
|
||||
* Jiang Kun <jiang.kun2@zte.com.cn>
|
||||
* Jianwei Hu <jiahu@redhat.com>
|
||||
* Jidong Xia <xiajidong@cmss.chinamobile.com>
|
||||
* Jie Wang <wangjie88@huawei.com>
|
||||
* JieWang <wangjie88@huawei.com>
|
||||
* Jim Fehlig <jfehlig@suse.com>
|
||||
* Jim Meyering <meyering@redhat.com>
|
||||
* Jim Paris <jim@jtan.com>
|
||||
* Jin Yan <jinyan12@huawei.com>
|
||||
* Jincheng Miao <jmiao@redhat.com>
|
||||
* Jing Qi <jinqi@redhat.com>
|
||||
* Jingjing Shao <jishao@redhat.com>
|
||||
* Jinsheng Zhang <zhangjl02@inspur.com>
|
||||
* Jiri Denemark <jdenemar@redhat.com>
|
||||
* Joachim Falk <joachim.falk@gmx.de>
|
||||
* Joao Martins <joao.m.martins@oracle.com>
|
||||
* Joel SIMOES <joel.simoes@laposte.net>
|
||||
* Johannes Holmberg <johannes.holmberg@dataductus.se>
|
||||
* John Eckersberg <jeckersb@redhat.com>
|
||||
* John Ferlan <jferlan@redhat.com>
|
||||
* John Levon <john.levon@nutanix.com>
|
||||
* John Levon <john.levon@sun.com>
|
||||
* John Levon <levon@movementarian.org>
|
||||
* John Morrissey <jwm@horde.net>
|
||||
* John Williams <john.williams@petalogix.com>
|
||||
* Jonas Eriksson <jonas.j.eriksson@ericsson.com>
|
||||
* Jonathan Lebon <jlebon@redhat.com>
|
||||
* Jonathan Toppins <jtoppins@cumulusnetworks.com>
|
||||
* Jonathan Watt <jwatt@jwatt.org>
|
||||
* Jonathon Jongsma <jjongsma@redhat.com>
|
||||
* Josh Durgin <josh.durgin@inktank.com>
|
||||
* Josh Stone <jistone@redhat.com>
|
||||
* Jovanka Gulicoska <jovanka.gulicoska@gmail.com>
|
||||
* Juan Hernandez <jhernand@redhat.com>
|
||||
* Juerg Haefliger <juerg.haefliger@hp.com>
|
||||
* Julien Humbert <julroy67@gmail.com>
|
||||
* Julio Faracco <jcfaracco@gmail.com>
|
||||
* Jun Koi <junkoi2004@gmail.com>
|
||||
* Justin Clift <jclift@redhat.com>
|
||||
* Justin Gatzen <justin.gatzen@gmail.com>
|
||||
* Ján Tomko <jtomko@redhat.com>
|
||||
* KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
|
||||
* Kai Kang <kai.kang@windriver.com>
|
||||
* Karel Zak <kzak@redhat.com>
|
||||
* Kashyap Chamarthy <kchamart@redhat.com>
|
||||
* Katerina Koukiou <kkoukiou@redhat.com>
|
||||
* Kay Schubert <kayegypt@web.de>
|
||||
* Ken ICHIKAWA <ichikawa.ken@jp.fujitsu.com>
|
||||
* Kenneth Nagin <NAGIN@il.ibm.com>
|
||||
* Kevin Locke <kevin@kevinlocke.name>
|
||||
* Kiarie Kahurani <davidkiarie4@gmail.com>
|
||||
* Kim InSoo <simmon@nplob.com>
|
||||
* Klaus Ethgen <Klaus@Ethgen.de>
|
||||
* Koichi Murase <myoga.murase@gmail.com>
|
||||
* Konrad Rzeszutek Wilk <konrad@kernel.org>
|
||||
* Konstantin Neumoin <kneumoin@virtuozzo.com>
|
||||
* Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com>
|
||||
* Kristina Hanicova <khanicov@redhat.com>
|
||||
* Kyle DeFrancia <kdef@linux.vnet.ibm.com>
|
||||
* Kyle Mestery <kmestery@cisco.com>
|
||||
* Ladi Prosek <lprosek@redhat.com>
|
||||
* Lai Jiangshan <laijs@cn.fujitsu.com>
|
||||
* Laine Stump <laine@redhat.com>
|
||||
* LanceLiu <liu.lance.89@gmail.com>
|
||||
* Laszlo Ersek <lersek@redhat.com>
|
||||
* Laurent Bigonville <bigon@bigon.be>
|
||||
* Laurent Léonard <laurent@open-minds.org>
|
||||
* Lee Yarwood <lyarwood@redhat.com>
|
||||
* Lei Li <lilei@linux.vnet.ibm.com>
|
||||
* Lei Yang <yanglei209@huawei.com>
|
||||
* Lena Voytek <lena.voytek@canonical.com>
|
||||
* Leno Hou <houqy@linux.vnet.ibm.com>
|
||||
* Leonid Bloch <lb.workbox@gmail.com>
|
||||
* Li Yang <liyang.fnst@cn.fujitsu.com>
|
||||
* Li Zhang <zhlcindy@linux.vnet.ibm.com>
|
||||
* Liang Yan <lyan@digitalocean.com>
|
||||
* Liao Pingfang <liao.pingfang@zte.com.cn>
|
||||
* Lily Zhu <lizhu@redhat.com>
|
||||
* Lin Ma <lma@suse.com>
|
||||
* Lin Ma <lma@suse.de>
|
||||
* Lin Ma <morecache@gmail.com>
|
||||
* Lincoln Myers <lincoln_myers@yahoo.com>
|
||||
* Liu Dayu <liu.dayu@zte.com.cn>
|
||||
* Liu Yiding <liuyd.fnst@fujitsu.com>
|
||||
* Liuji (Jeremy) <jeremy.liu@huawei.com>
|
||||
* Lorin Hochstein <lorin@isi.edu>
|
||||
* Lubomir Rintel <lkundrak@v3.sk>
|
||||
* Ludovic Beliveau <ludovic.beliveau@windriver.com>
|
||||
* Luiz Capitulino <lcapitulino@redhat.com>
|
||||
* Luke Yue <lukedyue@gmail.com>
|
||||
* Luyao Huang <lhuang@redhat.com>
|
||||
* Luyao Zhong <luyao.zhong@intel.com>
|
||||
* Lénaïc Huard <lenaic@lhuard.fr.eu.org>
|
||||
* MATSUDA Daiki <matsudadik@intellilink.co.jp>
|
||||
* MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
|
||||
* Maciej Wolny <maciej.wolny@codethink.co.uk>
|
||||
* Malina Salina <malina.salina@protonmail.com>
|
||||
* Manuel VIVES <manuel.vives@diateam.net>
|
||||
* Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
|
||||
* Marc Hartmayer <mhartmay@linux.ibm.com>
|
||||
* Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
|
||||
* Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
* Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
|
||||
* Marco Bozzolan <bozzolan@gmail.com>
|
||||
* Marcos Paulo de Souza <marcos.souza.org@gmail.com>
|
||||
* Marek Marczykowski <marmarek@invisiblethingslab.com>
|
||||
* Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
|
||||
* Marian Neagul <marian@info.uvt.ro>
|
||||
* Mark Asselstine <mark.asselstine@windriver.com>
|
||||
* Mark McLoughlin <markmc@redhat.com>
|
||||
* Mark Mielke <mark.mielke@gmail.com>
|
||||
* Mark Wu <dwu@redhat.com>
|
||||
* Marko Myllynen <myllynen@redhat.com>
|
||||
* Markus Groß <gross@univention.de>
|
||||
* Markus Schade <markus.schade@hetzner.com>
|
||||
* Marti Raudsepp <marti@juffo.org>
|
||||
* Martin Kletzander <mkletzan@redhat.com>
|
||||
* Martin Pietsch <martin.pietsch@tu-dresden.de>
|
||||
* Martin Pitt <mpitt@debian.org>
|
||||
* Martin Wilck <mwilck@suse.de>
|
||||
* Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||
* Matej Cepl <mcepl@cepl.eu>
|
||||
* Matt Coleman <matt@datto.com>
|
||||
* Matthew Booth <mbooth@redhat.com>
|
||||
* Matthew Rosato <mjrosato@linux.vnet.ibm.com>
|
||||
* Matthias Bolte <matthias.bolte@googlemail.com>
|
||||
* Matthias Dahl <mdvirt@designassembly.de>
|
||||
* Matthias Gatto <matthias.gatto@outscale.com>
|
||||
* Matthieu Coudron <mattator@gmail.com>
|
||||
* Mattias Bolte <matthias.bolte@googlemail.com>
|
||||
* Matwey V. Kornilov <matwey.kornilov@gmail.com>
|
||||
* Mauro Matteo Cascella <mcascell@redhat.com>
|
||||
* Mauro S. M. Rodrigues <maurosr@linux.vnet.ibm.com>
|
||||
* Max Goodhart <c@chromakode.com>
|
||||
* Maxim Kozin <kolomaxes@gmail.com>
|
||||
* Maxim Nestratov <mnestratov@virtuozzo.com>
|
||||
* Maxim Perevedentsev <mperevedentsev@virtuozzo.com>
|
||||
* Maxime Leroy <maxime.leroy@6wind.com>
|
||||
* Maximilian Wilhelm <max@rfc2324.org>
|
||||
* Maxiwell S. Garcia <maxiwell@linux.ibm.com>
|
||||
* Maya Rashish <coypu@sdf.org>
|
||||
* Mehdi Abaakouk <sileht@redhat.com>
|
||||
* Meina Li <meili@redhat.com>
|
||||
* Menno Lageman <menno.lageman@oracle.com>
|
||||
* Michael Avdienko <whitearchey@gmail.com>
|
||||
* Michael Chapman <mike@very.puzzling.org>
|
||||
* Michael Ellerman <michael@ellerman.id.au>
|
||||
* Michael R. Hines <mrhines@us.ibm.com>
|
||||
* Michael Santos <michael.santos@gmail.com>
|
||||
* Michael Weiser <michael.weiser@gmx.de>
|
||||
* Michael Wood <esiotrot@gmail.com>
|
||||
* Michal Dubiel <md@semihalf.com>
|
||||
* Michal Koutný <mkoutny@suse.com>
|
||||
* Michal Novotny <minovotn@redhat.com>
|
||||
* Michal Prívozník <mprivozn@redhat.com>
|
||||
* Michał Smyk <fedora@smyk.it>
|
||||
* Michał Łomnicki <michal.lomnicki@gmail.com>
|
||||
* Michel Normand <normand@linux.vnet.ibm.com>
|
||||
* Michele Paolino <m.paolino@virtualopensystems.com>
|
||||
* Miguel Ángel Arruga Vivas <rosen644835@gmail.com>
|
||||
* Mike Latimer <mlatimer@suse.com>
|
||||
* Mike Perez <thingee@gmail.com>
|
||||
* Mikhail Feoktistov <mfeoktistov@parallels.com>
|
||||
* Mikhail Feoktistov <mfeoktistov@virtuozzo.com>
|
||||
* Milo Casagrande <milo@milo.name>
|
||||
* Milos Vyletel <milos.vyletel@sde.cz>
|
||||
* Miloslav Trmač <mitr@redhat.com>
|
||||
* Minoru Usui <usui@mxm.nes.nec.co.jp>
|
||||
* Mo yuxiang <moyuxiang@huawei.com>
|
||||
* Mooli Tayer <mtayer@redhat.com>
|
||||
* Moshe Levi <moshele@mellanox.com>
|
||||
* Moshe Levi <moshele@nvidia.com>
|
||||
* Moteen Shah <moteenshah.02@gmail.com>
|
||||
* Muha Aliss <muhaaliss@gmail.com>
|
||||
* Nan Zhang <nzhang@redhat.com>
|
||||
* Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
|
||||
* Natanael Copa <ncopa@alpinelinux.org>
|
||||
* Nathan <nathan95@live.it>
|
||||
* Neal Gompa <ngompa13@gmail.com>
|
||||
* Nehal J Wani <nehaljw.kkd1@gmail.com>
|
||||
* Neil Wilson <neil@aldur.co.uk>
|
||||
* Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
* Nick Chevsky <nchevsky@gmail.com>
|
||||
* Nick Shyrokovskiy <nshyrokovskiy@gmail.com>
|
||||
* Nickys Music Group <nickys.music.group@gmail.com>
|
||||
* Nico Pache <npache@redhat.com>
|
||||
* Nicolas Brignone <nmbrignone@gmail.com>
|
||||
* Nicolas Lécureuil <neoclust@mageia.org>
|
||||
* Niels de Vos <ndevos@redhat.com>
|
||||
* Nikolay Shirokovskiy <nshirokovskiy@openvz.org>
|
||||
* Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
|
||||
* Nikos Mavrogiannopoulos <nmav@redhat.com>
|
||||
* Nikunj A. Dadhania <nikunj@linux.vnet.ibm.com>
|
||||
* Nishank Trivedi <nistrive@cisco.com>
|
||||
* Nishith Shah <nishithshah.2211@gmail.com>
|
||||
* Niteesh Dubey <niteesh@linux.ibm.com>
|
||||
* Nitesh Konkar <niteshkonkar.libvirt@gmail.com>
|
||||
* Noella Ashu <ashu.noella207@gmail.com>
|
||||
* Ohad Levy <ohadlevy@gmail.com>
|
||||
* Olaf Hering <olaf@aepfle.de>
|
||||
* Oleg Strikov <oleg.strikov@canonical.com>
|
||||
* Olesya Gerasimenko <gammaray@basealt.ru>
|
||||
* Olga Krishtal <okrishtal@virtuozzo.com>
|
||||
* Olivia Yin <Hong-Hua.Yin@freescale.com>
|
||||
* Olivia Yin <hong-hua.yin@freescale.com>
|
||||
* Olivier Fourdan <ofourdan@redhat.com>
|
||||
* Or Ozeri <oro@il.ibm.com>
|
||||
* Orion Poplawski <orion@nwra.com>
|
||||
* Osier Yang <jyang@redhat.com>
|
||||
* Oskari Saarenmaa <os@ohmu.fi>
|
||||
* Ossi Herrala <oherrala@gmail.com>
|
||||
* Pany <geekpany@gmail.com>
|
||||
* Paolo Bonzini <pbonzini@redhat.com>
|
||||
* Paolo Smiraglia <paolo.smiraglia@gmail.com>
|
||||
* Patrice LACHANCE <patlachance@gmail.com>
|
||||
* Patrick Dignan <pat_dignan@dell.com>
|
||||
* Patrick Magauran <patmagauran.j@gmail.com>
|
||||
* Paul Eggert <eggert@cs.ucla.edu>
|
||||
* Paulo de Rezende Pinatti <ppinatti@linux.ibm.com>
|
||||
* Pavel Boldin <pboldin@mirantis.com>
|
||||
* Pavel Fedin <p.fedin@samsung.com>
|
||||
* Pavel Glushchak <pglushchak@virtuozzo.com>
|
||||
* Pavel Hrdina <phrdina@redhat.com>
|
||||
* Pavel Mores <pmores@redhat.com>
|
||||
* Pavel Raiskup <praiskup@redhat.com>
|
||||
* Pavel Timofeev <timp87@gmail.com>
|
||||
* Paweł Krześniak <pawel.krzesniak@gmail.com>
|
||||
* Peng Liang <liangpeng10@huawei.com>
|
||||
* Peng Liang <tcx4c70@gmail.com>
|
||||
* Peng Zhou <ailvpeng25@gmail.com>
|
||||
* Peter Chubb <Peter.Chubb@data61.csiro.au>
|
||||
* Peter Feiner <peter@gridcentric.ca>
|
||||
* Peter Kieser <peter@kieser.ca>
|
||||
* Peter Krempa <pkrempa@redhat.com>
|
||||
* Peter Robinson <pbrobinson@gmail.com>
|
||||
* Phil Petty <phpetty@cisco.com>
|
||||
* Philipp Hahn <hahn@univention.de>
|
||||
* Pieter Hollants <pieter@hollants.com>
|
||||
* Pino Toscano <ptoscano@redhat.com>
|
||||
* Pino Toscano <toscano.pino@tiscali.it>
|
||||
* Piotr Drąg <piotrdrag@gmail.com>
|
||||
* Pradipta Kr. Banerjee <bpradip@in.ibm.com>
|
||||
* Pradipta Kr. Banerjee <pradipta.banerjee@gmail.com>
|
||||
* Prafull <talep158@gmail.com>
|
||||
* Prafullkumar Tale <talep158@gmail.com>
|
||||
* Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
|
||||
* Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
|
||||
* Prathamesh Chavan <pc44800@gmail.com>
|
||||
* Praveen K Paladugu <prapal@linux.microsoft.com>
|
||||
* Prerna Saxena <prerna@linux.vnet.ibm.com>
|
||||
* Pritesh Kothari <pritesh.kothari@sun.com>
|
||||
* Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
|
||||
* Qiaowei Ren <qiaowei.ren@intel.com>
|
||||
* Radoslaw Biernacki <radoslaw.biernacki@linaro.org>
|
||||
* Radostin Stoyanov <rstoyanov1@gmail.com>
|
||||
* Radu Caragea <dmns_serp@yahoo.com>
|
||||
* Rafael Fonseca <r4f4rfs@gmail.com>
|
||||
* Rainer Müller <raimue@codingfarm.de>
|
||||
* Ramon Medeiros <ramonn@linux.vnet.ibm.com>
|
||||
* Reinier Schoof <reinier@transip.nl>
|
||||
* Richa Marwaha <rmarwah@linux.vnet.ibm.com>
|
||||
* Richard Laager <rlaager@wiktel.com>
|
||||
* Richard W.M. Jones <rjones@redhat.com>
|
||||
* Richard Weinberger <richard@nod.at>
|
||||
* Rick Harris <rconradharris@gmail.com>
|
||||
* Ricky Tigg <ricky.tigg@gmail.com>
|
||||
* Rikard Falkeborn <rikard.falkeborn@gmail.com>
|
||||
* Riku Voipio <riku.voipio@linaro.org>
|
||||
* Robin Lee <cheeselee@fedoraproject.org>
|
||||
* Rohit Kumar <rohit.kumar3@nutanix.com>
|
||||
* Roland Schulz <schullzroll@gmail.com>
|
||||
* Rolf Eike Beer <eike@sf-mail.de>
|
||||
* Roman Bogorodskiy <bogorodskiy@gmail.com>
|
||||
* Roman Bolshakov <r.bolshakov@yadro.com>
|
||||
* Roman Mohr <rmohr@redhat.com>
|
||||
* Rommer <rommer@active.by>
|
||||
* Ron Yorston <rmy@tigress.co.uk>
|
||||
* Roopa Prabhu <roprabhu@cisco.com>
|
||||
* Royce Lv <lvroyce@linux.vnet.ibm.com>
|
||||
* Ruben Kerkhof <ruben@rubenkerkhof.com>
|
||||
* Rudy Zhang <rudyflyzhang@gmail.com>
|
||||
* Rufo Dogav <rufo@rufoa.com>
|
||||
* Ryan Gahagan <rgahagan@cs.utexas.edu>
|
||||
* Ryan Harper <ryanh@us.ibm.com>
|
||||
* Ryan Moeller <ryan@ixsystems.com>
|
||||
* Ryan Schmidt <git@ryandesign.com>
|
||||
* Ryan Woodsmall <rwoodsmall@gmail.com>
|
||||
* Ryota Ozaki <ozaki.ryota@gmail.com>
|
||||
* Sage Weil <sage@newdream.net>
|
||||
* Sahid Orentino Ferdjaoui <sahid.ferdjaoui@canonical.com>
|
||||
* Sahid Orentino Ferdjaoui <sahid.ferdjaoui@cloudwatt.com>
|
||||
* Sam Bobroff <sam.bobroff@au1.ibm.com>
|
||||
* Sam Hartman <hartmans@debian.org>
|
||||
* Sascha Peilicke <saschpe@suse.de>
|
||||
* Sascha Silbe <silbe@linux.vnet.ibm.com>
|
||||
* Satoru Moriya <satoru.moriya@hds.com>
|
||||
* Satoru SATOH <satoru.satoh@gmail.com>
|
||||
* Scott Davis <scott.davis@starlab.io>
|
||||
* Scott Garfinkle <scottgar@linux.vnet.ibm.com>
|
||||
* Scott Garfinkle <seg@us.ibm.com>
|
||||
* Scott Moser <smoser@ubuntu.com>
|
||||
* Scott Shambarger <scott-libvirt@shambarger.net>
|
||||
* Scott Sullivan <ssullivan@liquidweb.com>
|
||||
* Sebastian Mitterle <smitterl@redhat.com>
|
||||
* Sebastian Wiedenroth <wiedi@frubar.net>
|
||||
* Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
|
||||
* SeongHyun Jo <caelus9536@gmail.com>
|
||||
* Serge E. Hallyn <serge.hallyn@canonical.com>
|
||||
* Serge Hallyn <serge.hallyn@ubuntu.com>
|
||||
* Sergey A <sw@atrus.ru>
|
||||
* Sergey Bronnikov <sergeyb@openvz.org>
|
||||
* Sergey Fionov <fionov@gmail.com>
|
||||
* Shahar Klein <shaharklein@yahoo.com>
|
||||
* Shalini Chellathurai Saroja <shalini@linux.ibm.com>
|
||||
* Shalini Chellathurai Saroja <shalini@linux.vnet.ibm.com>
|
||||
* Shanzhi Yu <shyu@redhat.com>
|
||||
* ShaoHe Feng <shaohe.feng@intel.com>
|
||||
* Shaohe Feng <shaohe.feng@intel.com>
|
||||
* Shaojun Yang <yangshaojun@phytium.com.cn>
|
||||
* Sharadha Prabhakar <sharadha.prabhakar@citrix.com>
|
||||
* Shi Lei <shi_lei@massclouds.com>
|
||||
* Shichangkuo <shi.changkuo@h3c.com>
|
||||
* Shivangi Dhir <shivangi.dhir.02@gmail.com>
|
||||
* Shivaprasad G Bhat <sbhat@linux.vnet.ibm.com>
|
||||
* Shivaprasad G Bhat <shivaprasadbhat@gmail.com>
|
||||
* Shotaro Gotanda <g.sho1500@gmail.com>
|
||||
* Shradha Shah <sshah@solarflare.com>
|
||||
* Shuang He <shuang.he@zstack.io>
|
||||
* Silvan Kaiser <silvan@quobyte.com>
|
||||
* Simon Arlott <bugzilla.redhat.simon@arlott.org>
|
||||
* Simon Chopin <chopin.simon@gmail.com>
|
||||
* Simon Kobyda <skobyda@redhat.com>
|
||||
* Simon McVittie <smcv@debian.org>
|
||||
* Simon Rowe <simon.rowe@nutanix.com>
|
||||
* Simone Gotti <simone.gotti@gmail.com>
|
||||
* Soren Hansen <soren@linux2go.dk>
|
||||
* Spencer Shimko <sshimko@tresys.com>
|
||||
* Sri Ramanujam <sramanujam@datto.com>
|
||||
* Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
|
||||
* Stef Walter <stefw@gnome.org>
|
||||
* Stefan Bader <stefan.bader@canonical.com>
|
||||
* Stefan Berger <stefanb@linux.ibm.com>
|
||||
* Stefan Berger <stefanb@us.ibm.com>
|
||||
* Stefan Hajnoczi <stefanha@gmail.com>
|
||||
* Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
* Stefan Hajnoczi <stefanha@redhat.com>
|
||||
* Stefan Schallenberg <infos@nafets.de>
|
||||
* Stefan Seyfried <seife@b1-systems.de>
|
||||
* Stefan Zimmermann <stzi@linux.vnet.ibm.com>
|
||||
* Steve Hodgson <shodgson@solarflare.com>
|
||||
* Steve Yarmie <steve.yarmie@gmail.com>
|
||||
* Steven McDonald <steven.mcdonald@anchor.net.au>
|
||||
* Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
|
||||
* Sukrit Bhatnagar <skrtbhtngr@gmail.com>
|
||||
* Supriya Kannery <supriyak@linux.vnet.ibm.com>
|
||||
* Suyang Chen <dawson0xff@gmail.com>
|
||||
* Syed Humaid <syedhumaidbinharoon@gmail.com>
|
||||
* Szymon Scholz <szymonscholz@gmail.com>
|
||||
* Sławek Kapłoński <slawek@kaplonski.pl>
|
||||
* Taisuke Yamada <tai@rakugaki.org>
|
||||
* Taizo ITO <taizo.ito@hde.co.jp>
|
||||
* Taku Izumi <izumi.taku@jp.fujitsu.com>
|
||||
* Tal Kain <tal.kain@ravellosystems.com>
|
||||
* Tang Chen <tangchen@cn.fujitsu.com>
|
||||
* Taowei <uaedante@gmail.com>
|
||||
* Taowei Luo <uaedante@gmail.com>
|
||||
* Temuri Doghonadze <temuri.doghonadze@gmail.com>
|
||||
* Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
|
||||
* Thang Pham <thang.pham@us.ibm.com>
|
||||
* Thibault VINCENT <thibault.vincent@smartjog.com>
|
||||
* Thierry Parmentelat <thierry.parmentelat@inria.fr>
|
||||
* Thomas Huth <thuth@redhat.com>
|
||||
* Thomas Treutner <thomas@scripty.at>
|
||||
* Thomas Woerner <twoerner@redhat.com>
|
||||
* Thorsten Behrens <tbehrens@suse.com>
|
||||
* Tiago M. Vieira <tmv@redhat.com>
|
||||
* Tim Wiederhake <twiederh@redhat.com>
|
||||
* Tiziano Mueller <dev-zero@gentoo.org>
|
||||
* Tobin Feldman-Fitzthum <tobin@linux.vnet.ibm.com>
|
||||
* Tom Vijlbrief <tom.vijlbrief@xs4all.nl>
|
||||
* Tom Wieczorek <tom@bibbu.net>
|
||||
* Tomas Meszaros <exo@tty.sk>
|
||||
* Tomasz Flendrich <t.flendrich@gmail.com>
|
||||
* Tomoki Sekiyama <tomoki.sekiyama@hds.com>
|
||||
* Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
* Tomáš Janoušek <tomi@nomi.cz>
|
||||
* Tomáš Ryšavý <tom.rysavy.0@gmail.com>
|
||||
* Tony Krowiak <aekrowia@us.ibm.com>
|
||||
* Tony Krowiak <akrowiak@linux.vnet.ibm.com>
|
||||
* Tuguoyi <tu.guoyi@h3c.com>
|
||||
* Tyler Coumbes <coumbes@gmail.com>
|
||||
* Vasiliy Tolstov <v.tolstov@selfip.ru>
|
||||
* Vasiliy Ulyanov <vulyanov@suse.de>
|
||||
* Victor Toso <victortoso@redhat.com>
|
||||
* Viktor Mihajlovski <mihajlov@linux.ibm.com>
|
||||
* Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
|
||||
* Ville Skyttä <ville.skytta@iki.fi>
|
||||
* Vinayak Kale <vkale@nvidia.com>
|
||||
* Vincent Bernat <vincent@bernat.im>
|
||||
* Vineeth Pillai <viremana@linux.microsoft.com>
|
||||
* Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
* Vitor de Lima <vitor.lima@eldorado.org.br>
|
||||
* Vladislav Bogdanov <bubble@hoster-ok.com>
|
||||
* Václav Pavlín <vpavlin@redhat.com>
|
||||
* Wang Huaqiang <huaqiang.wang@intel.com>
|
||||
* Wang King <king.wang@huawei.com>
|
||||
* Wang Rui <moon.wangrui@huawei.com>
|
||||
* Wang Xin <wangxinxin.wang@huawei.com>
|
||||
* Wang Yechao <wang.yechao255@zte.com.cn>
|
||||
* Wang Yufei (James) <james.wangyufei@huawei.com>
|
||||
* Wangjing (King, Euler) <king.wang@huawei.com>
|
||||
* Wangrui (K) <moon.wangrui@huawei.com>
|
||||
* Weblate <noreply@weblate.org>
|
||||
* Wei Huang <wei@redhat.com>
|
||||
* Wei Jiangang <weijg.fnst@cn.fujitsu.com>
|
||||
* Wei Liu <wei.liu2@citrix.com>
|
||||
* Wei Liu <wei.liu@kernel.org>
|
||||
* Weilun Zhu <zhuweilun@huawei.com>
|
||||
* Weiwei Li <nuonuoli@tencent.com>
|
||||
* Wen Congyang <wency@cn.fujitsu.com>
|
||||
* Wido den Hollander <wido@widodh.nl>
|
||||
* Wieland Hoffmann <themineo@googlemail.com>
|
||||
* William Douglas <william.douglas@intel.com>
|
||||
* William Grant <wgrant@ubuntu.com>
|
||||
* William Jon McCann <william.jon.mccann@gmail.com>
|
||||
* Wim ten Have <wim.ten.have@oracle.com>
|
||||
* Wojciech Macek <wma@semihalf.com>
|
||||
* Wolfgang Mauerer <wolfgang.mauerer@siemens.com>
|
||||
* Wout Mertens <Wout.Mertens@gmail.com>
|
||||
* Wout Mertens <wout.mertens@gmail.com>
|
||||
* Wu Zongyong <cordius.wu@huawei.com>
|
||||
* Xian Han Yu <xhyubj@linux.vnet.ibm.com>
|
||||
* Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
|
||||
* Xing Lin <xinglin@cs.utah.edu>
|
||||
* Xu Chao <xu.chao6@zte.com.cn>
|
||||
* Xu He Jie <xuhj@linux.vnet.ibm.com>
|
||||
* Xu Yandong <xuyandong2@huawei.com>
|
||||
* Xuesong Zhang <xuzhang@redhat.com>
|
||||
* Yalan Zhang <yalzhang@redhat.com>
|
||||
* Yalei Li <274268859@qq.com>
|
||||
* Yan Fu <yafu@redhat.com>
|
||||
* Yan Wang <wangyan122@huawei.com>
|
||||
* Yanbing Du <ydu@redhat.com>
|
||||
* Yanbing Du <ydu@ydu-0.nay.redhat.com>
|
||||
* Yang Fei <yangfei85@huawei.com>
|
||||
* Yaniv Kaul <ykaul@redhat.com>
|
||||
* Yanqiu Zhang <yanqzhan@redhat.com>
|
||||
* Yaroslav Kargin <ykargin@virtuozzo.com>
|
||||
* Yasuhiko Kamata <belphegor@belbel.or.jp>
|
||||
* Yi Li <yili@winhong.com>
|
||||
* Yi Min Zhao <zyimin@linux.ibm.com>
|
||||
* Yi Wang <wang.yi59@zte.com.cn>
|
||||
* Yingle Hou <houyingle@hygon.cn>
|
||||
* Yogesh Tillu <tillu.yogesh@gmail.com>
|
||||
* Yohan BELLEGUIC <yohan.belleguic@diateam.net>
|
||||
* Your Name <you@example.com>
|
||||
* Yudai Yamagish <yummy@sfc.wide.ad.jp>
|
||||
* Yue wenyuan <yuewenyuan@huawei.com>
|
||||
* Yufang Zhang <yufang521247@gmail.com>
|
||||
* Yufang Zhang <yuzhang@redhat.com>
|
||||
* Yuji NISHIDA <nishidy@nict.go.jp>
|
||||
* Yuri Chornoivan <yurchor@ukr.net>
|
||||
* Yuri Myasoedov <ymyasoedov@yandex.ru>
|
||||
* Yuri Pudgorodskiy <yur@virtuozzo.com>
|
||||
* Yuto KAWAMURA(kawamuray) <kawamuray.dadada@gmail.com>
|
||||
* Yuval Shaia <yuval.shaia@oracle.com>
|
||||
* Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
|
||||
* Zdenek Styblik <stybla@turnovfree.net>
|
||||
* Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
|
||||
* Zeng Junliang <zengjunliang@huawei.com>
|
||||
* Zhang Bo <oscar.zhangbo@huawei.com>
|
||||
* Zhang Xiaohe <zhangxh@cn.fujitsu.com>
|
||||
* Zhangzijian <zhang.zijian@h3c.com>
|
||||
* Zheng Chuan <zhengchuan@huawei.com>
|
||||
* Zhenyu Ye <yezhenyu2@huawei.com>
|
||||
* Zhenyu Zheng <zheng.zhenyu@outlook.com>
|
||||
* Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
* ZhiPeng Lu <lu.zhipeng@zte.com.cn>
|
||||
* ZhiPeng Lu <luzhipeng@uniudc.com>
|
||||
* Zhimin Feng <fengzhimin1@huawei.com>
|
||||
* Zhou Yimin <zhouyimin@huawei.com>
|
||||
* Zhou yimin <zhouyimin@huawei.com>
|
||||
* Zhuang Yanying <ann.zhuangyanying@huawei.com>
|
||||
* caoxinhua <caoxinhua@huawei.com>
|
||||
* dann frazier <dann.frazier@canonical.com>
|
||||
* dinglimin <dinglimin@cmss.chinamobile.com>
|
||||
* eater <=@eater.me>
|
||||
* gaohaifeng <gaohaifeng.gao@huawei.com>
|
||||
* gongwei <gongwei@smartx.com>
|
||||
* hejia hejia <jiakernel@gmail.com>
|
||||
* hexin <hexin15@baidu.com>
|
||||
* ik.nitk <ik.nitk@gmail.com>
|
||||
* intrigeri <intrigeri@boum.org>
|
||||
* intrigeri <intrigeri@debian.org>
|
||||
* james robson <jrobson@websense.com>
|
||||
* jason lee <ppark5237@gmail.com>
|
||||
* lawrancejing <lawrancejing@gmail.com>
|
||||
* liguang <lig.fnst@cn.fujitsu.com>
|
||||
* luzhipeng <luzhipeng@cestc.cn>
|
||||
* ning.bo <ning.bo9@zte.com.cn>
|
||||
* ramyelkest <ramyelkest@gmail.com>
|
||||
* ryan woodsmall <rwoodsmall@gmail.com>
|
||||
* sannyshao <jishao@redhat.com>
|
||||
* shenjiatong <yshxxsjt715@gmail.com>
|
||||
* simmon <simmon@nplob.com>
|
||||
* tuqiang <tu.qiang35@zte.com.cn>
|
||||
* w00251574 <wangjie88@huawei.com>
|
||||
* wangjian <wangjian161@huawei.com>
|
||||
* weiwei li <weiweili821@gmail.com>
|
||||
* xinhua.Cao <caoxinhua@huawei.com>
|
||||
* xuzhang <xuzhang@redhat.com>
|
||||
* yangdongsheng <yangds.fnst@cn.fujitsu.com>
|
||||
* yuelongguang <yuelongguang@le.com>
|
||||
* zhang bo <oscar.zhangbo@huawei.com>
|
||||
* zhangjl02 <zhangjl02@inspur.com>
|
||||
* zhanglei <zhanglei@smartx.com>
|
||||
* zhenwei pi <pizhenwei@bytedance.com>
|
||||
* Дамјан Георгиевски <gdamjan@gmail.com>
|
||||
* Марк Коренберг <socketpair@gmail.com>
|
||||
* 김인수 <simmon@nplob.com>
|
||||
|
||||
|
||||
The libvirt logo was designed by Diana Fong
|
|
@ -0,0 +1,100 @@
|
|||
===============
|
||||
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:
|
||||
|
||||
* Andrea Bolognani <abologna@redhat.com>
|
||||
* Cédric Bosdonnat <cbosdonnat@suse.com>
|
||||
* Christian Ehrhardt <christian.ehrhardt@canonical.com>
|
||||
* Christophe Fergeau <cfergeau@redhat.com>
|
||||
* Cole Robinson <crobinso@redhat.com>
|
||||
* Daniel P. Berrangé <berrange@redhat.com>
|
||||
* Daniel Veillard <veillard@redhat.com>
|
||||
* Eric Blake <eblake@redhat.com>
|
||||
* Erik Skultety <eskultet@redhat.com>
|
||||
* Fabiano Fidêncio <fidencio@redhat.com>
|
||||
* Guido Günther <agx@sigxcpu.org>
|
||||
* Ján Tomko <jtomko@redhat.com>
|
||||
* Jim Fehlig <jfehlig@suse.com>
|
||||
* Jiří Denemark <jdenemar@redhat.com>
|
||||
* Laine Stump <laine@redhat.com>
|
||||
* Martin Kletzander <mkletzan@redhat.com>
|
||||
* Michal Prívozník <mprivozn@redhat.com>
|
||||
* Nikolay Shirokovskiy <nshirokovskiy@openvz.org>
|
||||
* Pavel Hrdina <phrdina@redhat.com>
|
||||
* Peter Krempa <pkrempa@redhat.com>
|
||||
* Pino Toscano <ptoscano@redhat.com>
|
||||
* Richard W.M. Jones <rjones@redhat.com>
|
||||
* Roman Bogorodskiy <bogorodskiy@gmail.com>
|
||||
* Tim Wiederhake <twiederh@redhat.com>
|
||||
|
||||
Previous maintainers:
|
||||
|
||||
* Alex Jia <ajia@redhat.com>
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
* Atsushi SAKAI <sakaia@jp.fujitsu.com>
|
||||
* Chris Lalancette <clalance@redhat.com>
|
||||
* Claudio Bley <claudio.bley@gmail.com>
|
||||
* Dan Smith <danms@us.ibm.com>
|
||||
* Dave Allan <dallan@redhat.com>
|
||||
* Dave Leskovec <dlesko@linux.vnet.ibm.com>
|
||||
* Dmitry Guryanov <dguryanov@parallels.com>
|
||||
* Doug Goldstein <cardoe@gentoo.org>
|
||||
* Gao Feng <gaofeng@cn.fujitsu.com>
|
||||
* Guannan Ren <gren@redhat.com>
|
||||
* Jim Meyering <meyering@redhat.com>
|
||||
* John Ferlan <jferlan@redhat.com>
|
||||
* John Levon <john.levon@sun.com>
|
||||
* Justin Clift <jclift@redhat.com>
|
||||
* Karel Zak <kzak@redhat.com>
|
||||
* Katerina Koukiou <kkoukiou@redhat.com>
|
||||
* Mark McLoughlin <markmc@redhat.com>
|
||||
* Matthias Bolte <matthias.bolte@googlemail.com>
|
||||
* Maxim Nestratov <mnestratov@virtuozzo.com>
|
||||
* Osier Yang <jyang@redhat.com>
|
||||
* Stefan Berger <stefanb@us.ibm.com>
|
||||
* Wen Congyang <wency@cn.fujitsu.com>
|
||||
|
||||
Patches have also been contributed by:
|
||||
|
||||
* Abel Míguez Rodríguez <amiguezr@pdi.ucm.es>
|
||||
* Amit Shah <amit.shah@redhat.com>
|
||||
* Andrew Puch <apuch@redhat.com>
|
||||
* Anton Protopopov <aspsk2@gmail.com>
|
||||
* Ben Guthro <ben.guthro@gmail.com>
|
||||
* Daniel Hokka Zakrisson <daniel@hozac.com>
|
||||
* Dan Wendlandt <dan@nicira.com>
|
||||
* David Lively <dlively@virtualiron.com>
|
||||
* David Lutterkort <dlutter@redhat.com>
|
||||
* Evgeniy Sokolov <evg@openvz.org>
|
||||
* Hugh Brock <hbrock@redhat.com>
|
||||
* Itamar Heim <iheim@redhat.com>
|
||||
* James Morris <jmorris@namei.org>
|
||||
* Javier Fontan <jfontan@gmail.com>
|
||||
* Jeremy Katz <katzj@redhat.com>
|
||||
* Kaitlin Rupert <kaitlin@linux.vnet.ibm.com>
|
||||
* Kazuki Mizushima <mizushima.kazuk@jp.fujitsu.com>
|
||||
* Mads Chr. Olesen <shiyee@shiyee.dk>
|
||||
* Mark Johnson <johnson.nh@gmail.com>
|
||||
* Markus Armbruster <armbru@redhat.com>
|
||||
* Masayuki Sunou <fj1826dm@aa.jp.fujitsu.com>
|
||||
* Matthias Witte <witte@netzquadrat.de>
|
||||
* Michel Ponceau <michel.ponceau@bull.net>
|
||||
* Nobuhiro Itou <fj0873gn@aa.jp.fujitsu.com>
|
||||
* Pete Vetere <pvetere@redhat.com>
|
||||
* Philippe Berthault <philippe.berthault@Bull.net>
|
||||
* Saori Fukuta <fukuta.saori@jp.fujitsu.com>
|
||||
* Shigeki Sakamoto <fj0588di@aa.jp.fujitsu.com>
|
||||
* Shuveb Hussain <shuveb@binarykarma.com>
|
||||
* Stefan de Konink <dekonink@kinkrsoftware.nl>
|
||||
* Takahashi Tomohiro <takatom@jp.fujitsu.com>
|
||||
* Tatsuro Enokura <fj7716hz@aa.jp.fujitsu.com>
|
||||
|
||||
@contributorslist@
|
||||
|
||||
The libvirt logo was designed by Diana Fong
|
|
@ -0,0 +1,45 @@
|
|||
=======================
|
||||
Contributing to libvirt
|
||||
=======================
|
||||
|
||||
Full, up to date information on how to contribute to libvirt can be
|
||||
found on the libvirt website:
|
||||
|
||||
https://libvirt.org/contribute.html
|
||||
|
||||
To build the same document locally, from the top level directory of
|
||||
your git clone run:
|
||||
|
||||
::
|
||||
|
||||
$ meson build
|
||||
$ ninja -C build
|
||||
|
||||
You'll find the freshly-built document in ``docs/contribute.html``.
|
||||
|
||||
If ``meson setup`` fails because of missing dependencies, you can set
|
||||
up your system by calling
|
||||
|
||||
::
|
||||
|
||||
$ sudo dnf builddep libvirt
|
||||
|
||||
if you're on a RHEL-based distribution or
|
||||
|
||||
::
|
||||
|
||||
$ sudo apt-get build-dep libvirt
|
||||
|
||||
if you're on a Debian-based one.
|
||||
|
||||
Note that, for the RHEL-based case, if you're on a machine where you
|
||||
haven't done any C development before, you will probably also need
|
||||
to run
|
||||
|
||||
::
|
||||
|
||||
$ sudo dnf install gcc make ninja-build rpm-build
|
||||
|
||||
You might still be missing some dependencies if your distribution is
|
||||
shipping an old libvirt version, but that will get you much closer to
|
||||
where you need to be to build successfully from source.
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, 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 or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
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 give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
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 Program or any portion
|
||||
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
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 Program, 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 Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) 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; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, 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 executable. However, as a
|
||||
special exception, the source code 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.
|
||||
|
||||
If distribution of executable or 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 counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program 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.
|
||||
|
||||
5. 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 Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program 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 to
|
||||
this License.
|
||||
|
||||
7. 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 Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program 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 Program.
|
||||
|
||||
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.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program 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.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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 Program
|
||||
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 Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, 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
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. 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 program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 2 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, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,502 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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!
|
|
@ -0,0 +1,72 @@
|
|||
.. image:: https://gitlab.com/libvirt/libvirt/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt/pipelines
|
||||
:alt: GitLab CI Build Status
|
||||
.. image:: https://bestpractices.coreinfrastructure.org/projects/355/badge
|
||||
:target: https://bestpractices.coreinfrastructure.org/projects/355
|
||||
:alt: CII Best Practices
|
||||
.. image:: https://translate.fedoraproject.org/widgets/libvirt/-/libvirt/svg-badge.svg
|
||||
:target: https://translate.fedoraproject.org/engage/libvirt/
|
||||
:alt: Translation status
|
||||
|
||||
==============================
|
||||
Libvirt API for virtualization
|
||||
==============================
|
||||
|
||||
Libvirt provides a portable, long term stable C API for managing the
|
||||
virtualization technologies provided by many operating systems. It
|
||||
includes support for QEMU, KVM, Xen, LXC, bhyve, Virtuozzo, VMware
|
||||
vCenter and ESX, VMware Desktop, Hyper-V, VirtualBox and the POWER
|
||||
Hypervisor.
|
||||
|
||||
For some of these hypervisors, it provides a stateful management
|
||||
daemon which runs on the virtualization host allowing access to the
|
||||
API both by non-privileged local users and remote users.
|
||||
|
||||
Layered packages provide bindings of the libvirt C API into other
|
||||
languages including Python, Perl, PHP, Go, Java, OCaml, as well as
|
||||
mappings into object systems such as GObject, CIM and SNMP.
|
||||
|
||||
Further information about the libvirt project can be found on the
|
||||
website:
|
||||
|
||||
https://libvirt.org
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
The libvirt C API is distributed under the terms of GNU Lesser General
|
||||
Public License, version 2.1 (or later). Some parts of the code that are
|
||||
not part of the C library may have the more restrictive GNU General
|
||||
Public License, version 2.0 (or later). See the files ``COPYING.LESSER``
|
||||
and ``COPYING`` for full license terms & conditions.
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Instructions on building and installing libvirt can be found on the website:
|
||||
|
||||
https://libvirt.org/compiling.html
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
The libvirt project welcomes contributions in many ways. For most components
|
||||
the best way to contribute is to send patches to the primary development
|
||||
mailing list. Further guidance on this can be found on the website:
|
||||
|
||||
https://libvirt.org/contribute.html
|
||||
|
||||
|
||||
Contact
|
||||
=======
|
||||
|
||||
The libvirt project has two primary mailing lists:
|
||||
|
||||
* libvirt-users@redhat.com (**for user discussions**)
|
||||
* libvir-list@redhat.com (**for development only**)
|
||||
|
||||
Further details on contacting the project are available on the website:
|
||||
|
||||
https://libvirt.org/contact.html
|
|
@ -0,0 +1,13 @@
|
|||
# define variables
|
||||
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = @top_builddir@
|
||||
FLAKE8 = @flake8_path@
|
||||
RUNUTF8 = @runutf8@
|
||||
PYTHON = @PYTHON3@
|
||||
GREP = @GREP@
|
||||
SED = @SED@
|
||||
AWK = @AWK@
|
||||
|
||||
# include syntax-check.mk file
|
||||
include $(top_srcdir)/build-aux/syntax-check.mk
|
|
@ -0,0 +1,127 @@
|
|||
## Copyright (C) 2009-2010, 2013 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, see
|
||||
## <http://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# Generated by running the following on Fedora 26:
|
||||
#
|
||||
# nm -D --defined-only /lib64/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 += fgetsgent
|
||||
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 += getsgent
|
||||
NON_REENTRANT += getsgnam
|
||||
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 += sgetsgent
|
||||
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
|
||||
|
||||
# Separate two nothings by space to get one space in a variable
|
||||
space =
|
||||
space +=
|
||||
# The space needs to be in a variable otherwise it would be ignored.
|
||||
# And there must be no spaces around the commas because they would
|
||||
# not be ignored, logically.
|
||||
NON_REENTRANT_RE=$(subst $(space),|,$(NON_REENTRANT))
|
|
@ -0,0 +1,162 @@
|
|||
#!/usr/bin/env perl
|
||||
#
|
||||
# check-spacing.pl: Report any usage of 'function (..args..)'
|
||||
# Also check for other syntax issues, such as correct use of ';'
|
||||
#
|
||||
# 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, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $ret = 0;
|
||||
my $incomment = 0;
|
||||
|
||||
foreach my $file (@ARGV) {
|
||||
open FILE, $file;
|
||||
|
||||
while (defined (my $line = <FILE>)) {
|
||||
my $data = $line;
|
||||
# For temporary modifications
|
||||
my $tmpdata;
|
||||
|
||||
# Kill any quoted , ; = or "
|
||||
$data =~ s/'[";,=]'/'X'/g;
|
||||
|
||||
# Kill any quoted strings
|
||||
$data =~ s,"(?:[^\\\"]|\\.)*","XXX",g;
|
||||
|
||||
next if $data =~ /^#/;
|
||||
|
||||
# Kill contents of multi-line comments
|
||||
# and detect end of multi-line comments
|
||||
if ($incomment) {
|
||||
if ($data =~ m,\*/,) {
|
||||
$incomment = 0;
|
||||
$data =~ s,^.*\*/,*/,;
|
||||
} else {
|
||||
$data = "";
|
||||
}
|
||||
}
|
||||
|
||||
# Kill single line comments, and detect
|
||||
# start of multi-line comments
|
||||
if ($data =~ m,/\*.*\*/,) {
|
||||
$data =~ s,/\*.*\*/,/* */,;
|
||||
} elsif ($data =~ m,/\*,) {
|
||||
$incomment = 1;
|
||||
$data =~ s,/\*.*,/*,;
|
||||
}
|
||||
|
||||
# We need to match things like
|
||||
#
|
||||
# int foo (int bar, bool wizz);
|
||||
# foo (bar, wizz);
|
||||
#
|
||||
# but not match things like:
|
||||
#
|
||||
# typedef int (*foo)(bar wizz)
|
||||
#
|
||||
# we can't do this (efficiently) without
|
||||
# missing things like
|
||||
#
|
||||
# foo (*bar, wizz);
|
||||
#
|
||||
# We also don't want to spoil the $data so it can be used
|
||||
# later on.
|
||||
$tmpdata = $data;
|
||||
while ($tmpdata =~ /(\w+)\s\((?!\*)/) {
|
||||
my $kw = $1;
|
||||
|
||||
# Allow space after keywords only
|
||||
if ($kw =~ /^(?:if|for|while|switch|return)$/) {
|
||||
$tmpdata =~ s/(?:$kw\s\()/XXX(/;
|
||||
} else {
|
||||
print "Whitespace after non-keyword:\n";
|
||||
print "$file:$.: $line";
|
||||
$ret = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# Require whitespace immediately after keywords
|
||||
if ($data =~ /\b(?:if|for|while|switch|return)\(/) {
|
||||
print "No whitespace after keyword:\n";
|
||||
print "$file:$.: $line";
|
||||
$ret = 1;
|
||||
}
|
||||
|
||||
# Forbid whitespace between )( of a function typedef
|
||||
if ($data =~ /\(\*\w+\)\s+\(/) {
|
||||
print "Whitespace between ')' and '(':\n";
|
||||
print "$file:$.: $line";
|
||||
$ret = 1;
|
||||
}
|
||||
|
||||
# Forbid whitespace following ( or prior to )
|
||||
# but allow whitespace before ) on a single line
|
||||
# (optionally followed by a semicolon)
|
||||
if (($data =~ /\s\)/ && not $data =~ /^\s+\);?$/) ||
|
||||
$data =~ /\((?!$)\s/) {
|
||||
print "Whitespace after '(' or before ')':\n";
|
||||
print "$file:$.: $line";
|
||||
$ret = 1;
|
||||
}
|
||||
|
||||
# Forbid whitespace before ";" or ",". Things like below are allowed:
|
||||
#
|
||||
# 1) The expression is empty for "for" loop. E.g.
|
||||
# for (i = 0; ; i++)
|
||||
#
|
||||
# 2) An empty statement. E.g.
|
||||
# while (write(statuswrite, &status, 1) == -1 &&
|
||||
# errno == EINTR)
|
||||
# ;
|
||||
#
|
||||
if ($data =~ /\s[;,]/) {
|
||||
unless ($data =~ /\S; ; / ||
|
||||
$data =~ /^\s+;/) {
|
||||
print "Whitespace before semicolon or comma:\n";
|
||||
print "$file:$.: $line";
|
||||
$ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# Require EOL, macro line continuation, or whitespace after ";".
|
||||
# Allow "for (;;)" as an exception.
|
||||
if ($data =~ /;[^ \\\n;)]/) {
|
||||
print "Invalid character after semicolon:\n";
|
||||
print "$file:$.: $line";
|
||||
$ret = 1;
|
||||
}
|
||||
|
||||
# Require EOL, space, or enum/struct end after comma.
|
||||
if ($data =~ /,[^ \\\n)}]/) {
|
||||
print "Invalid character after comma:\n";
|
||||
print "$file:$.: $line";
|
||||
$ret = 1;
|
||||
}
|
||||
|
||||
# Require spaces around assignment '=', compounds and '=='
|
||||
if ($data =~ /[^ ]\b[!<>&|\-+*\/%\^=]?=/ ||
|
||||
$data =~ /=[^= \\\n]/) {
|
||||
print "Spacing around '=' or '==':\n";
|
||||
print "$file:$.: $line";
|
||||
$ret = 1;
|
||||
}
|
||||
}
|
||||
close FILE;
|
||||
}
|
||||
|
||||
exit $ret;
|
|
@ -0,0 +1,72 @@
|
|||
flake8_path = ''
|
||||
if flake8_prog.found()
|
||||
flake8_path = flake8_prog.path()
|
||||
endif
|
||||
|
||||
if host_machine.system() == 'freebsd' or host_machine.system() == 'darwin'
|
||||
make_prog = find_program('gmake')
|
||||
sed_prog = find_program('gsed')
|
||||
else
|
||||
make_prog = find_program('make')
|
||||
sed_prog = find_program('sed')
|
||||
endif
|
||||
|
||||
if host_machine.system() == 'freebsd'
|
||||
grep_prog = find_program('grep')
|
||||
grep_cmd = run_command(grep_prog, '--version', check: true)
|
||||
if grep_cmd.stdout().startswith('grep (BSD grep')
|
||||
grep_prog = find_program('/usr/local/bin/grep', required: false)
|
||||
if not grep_prog.found()
|
||||
error('GNU grep not found')
|
||||
endif
|
||||
endif
|
||||
elif host_machine.system() == 'darwin'
|
||||
grep_prog = find_program('ggrep')
|
||||
else
|
||||
grep_prog = find_program('grep')
|
||||
endif
|
||||
|
||||
awk_prog = find_program('awk')
|
||||
|
||||
syntax_check_conf = configuration_data({
|
||||
'top_srcdir': meson.source_root(),
|
||||
'top_builddir': meson.build_root(),
|
||||
'flake8_path': flake8_path,
|
||||
'runutf8': ' '.join(runutf8),
|
||||
'PYTHON3': python3_prog.path(),
|
||||
'GREP': grep_prog.path(),
|
||||
'SED': sed_prog.path(),
|
||||
'AWK': awk_prog.path(),
|
||||
})
|
||||
|
||||
configure_file(
|
||||
input: 'Makefile.in',
|
||||
output: '@BASENAME@',
|
||||
configuration: syntax_check_conf,
|
||||
)
|
||||
|
||||
rc = run_command(
|
||||
'sed', '-n',
|
||||
's/^sc_\\([a-zA-Z0-9_-]*\\):.*/\\1/p',
|
||||
meson.current_source_dir() / 'syntax-check.mk',
|
||||
check: true,
|
||||
)
|
||||
|
||||
sc_tests = rc.stdout().strip().split()
|
||||
|
||||
|
||||
# Skip syntax-check if not building from git because we get the list of files
|
||||
# to check using git commands and it fails if we are not in git repository.
|
||||
if git
|
||||
foreach target : sc_tests
|
||||
test(
|
||||
target,
|
||||
make_prog,
|
||||
args: [ '-C', meson.current_build_dir(), 'sc_@0@'.format(target) ],
|
||||
depends: [
|
||||
potfiles_dep,
|
||||
],
|
||||
suite: 'syntax-check',
|
||||
)
|
||||
endforeach
|
||||
endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <meson-config.h>
|
||||
|
||||
/* Enable compile-time and run-time bounds-checking, and some warnings,
|
||||
* without upsetting newer glibc. */
|
||||
|
||||
#if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__
|
||||
# define _FORTIFY_SOURCE 2
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define __GNUC_PREREQ to a sane default if it isn't yet defined.
|
||||
* This is done here so that it's included as early as possible;
|
||||
*/
|
||||
#ifndef __GNUC_PREREQ
|
||||
# define __GNUC_PREREQ(maj, min) \
|
||||
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
||||
#endif
|
||||
|
||||
#if defined(__clang_major__) && defined(__clang_minor__)
|
||||
# ifdef __apple_build_version__
|
||||
# if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
|
||||
# error You need at least XCode Clang v10.0 to compile libvirt
|
||||
# endif
|
||||
# else
|
||||
# if __clang_major__ < 6 || (__clang_major__ == 6 && __clang_minor__ < 4)
|
||||
# error You need at least Clang v6.0 to compile libvirt
|
||||
# endif
|
||||
# endif
|
||||
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||
# if __GNUC__ < 7 || (__GNUC__ == 7 && __GNUC_MINOR__ < 4)
|
||||
# error You need at least GCC v7.4.0 to compile libvirt
|
||||
# endif
|
||||
#else
|
||||
# error You either need at least GCC 7.4.0 or Clang 6.0 or XCode Clang 10.0 to compile libvirt
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
||||
#if WIN32
|
||||
# include <winsock2.h> /* avoid mingw pollution on DATADIR */
|
||||
#endif
|
||||
#mesondefine BINDIR
|
||||
#mesondefine DATADIR
|
||||
#mesondefine LIBDIR
|
||||
#mesondefine LIBEXECDIR
|
||||
#mesondefine LOCALEDIR
|
||||
#mesondefine LOCALSTATEDIR
|
||||
#mesondefine MANDIR
|
||||
#mesondefine PKGDATADIR
|
||||
#mesondefine PREFIX
|
||||
#mesondefine RUNSTATEDIR
|
||||
#mesondefine SBINDIR
|
||||
#mesondefine SYSCONFDIR
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<body>
|
||||
<h1>404 page not found</h1>
|
||||
|
||||
<p>
|
||||
Someone appears to have eaten the <del>penguin</del>
|
||||
page you were looking for. You might want to try
|
||||
</p>
|
||||
<ul>
|
||||
<li>going back to the <a href="https://libvirt.org/">home page</a> to find
|
||||
a collection of links to interesting pages on this site</li>
|
||||
<li>using the search box at the top right corner of the screen to
|
||||
locate the content on this site or mailing list archives</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<body>
|
||||
<h1>Client access control</h1>
|
||||
<p>
|
||||
Libvirt's client access control framework allows administrators
|
||||
to setup fine grained permission rules across client users,
|
||||
managed objects and API operations. This allows client connections
|
||||
to be locked down to a minimal set of privileges.
|
||||
</p>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a id="intro">Access control introduction</a></h2>
|
||||
|
||||
<p>
|
||||
In a default configuration, the libvirtd daemon has three levels
|
||||
of access control. All connections start off in an unauthenticated
|
||||
state, where the only API operations allowed are those required
|
||||
to complete authentication. After successful authentication, a
|
||||
connection either has full, unrestricted access to all libvirt
|
||||
API calls, or is locked down to only "read only" operations,
|
||||
according to what socket a client connection originated on.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The access control framework allows authenticated connections to
|
||||
have fine grained permission rules to be defined by the administrator.
|
||||
Every API call in libvirt has a set of permissions that will
|
||||
be validated against the object being used. For example, the
|
||||
<code>virDomainSetSchedulerParametersFlags</code> method will
|
||||
check whether the client user has the <code>write</code>
|
||||
permission on the <code>domain</code> object instance passed
|
||||
in as a parameter. Further permissions will also be checked
|
||||
if certain flags are set in the API call. In addition to
|
||||
checks on the object passed in to an API call, some methods
|
||||
will filter their results. For example the <code>virConnectListAllDomains</code>
|
||||
method will check the <code>search_domains</code> on the <code>connect</code>
|
||||
object, but will also filter the returned <code>domain</code>
|
||||
objects to only those on which the client user has the
|
||||
<code>getattr</code> permission.
|
||||
</p>
|
||||
|
||||
<h2><a id="drivers">Access control drivers</a></h2>
|
||||
|
||||
<p>
|
||||
The access control framework is designed as a pluggable
|
||||
system to enable future integration with arbitrary access
|
||||
control technologies. By default, the <code>none</code>
|
||||
driver is used, which does no access control checks at
|
||||
all. At this time, libvirt ships with support for using
|
||||
<a href="https://www.freedesktop.org/wiki/Software/polkit/">polkit</a> as a real access
|
||||
control driver. To learn how to use the polkit access
|
||||
driver consult <a href="aclpolkit.html">the configuration
|
||||
docs</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The access driver is configured in the <code>libvirtd.conf</code>
|
||||
configuration file, using the <code>access_drivers</code>
|
||||
parameter. This parameter accepts an array of access control
|
||||
driver names. If more than one access driver is requested,
|
||||
then all must succeed in order for access to be granted.
|
||||
To enable 'polkit' as the driver:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
# augtool -s set '/files/etc/libvirt/libvirtd.conf/access_drivers[1]' polkit
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
And to reset back to the default (no-op) driver
|
||||
</p>
|
||||
|
||||
|
||||
<pre>
|
||||
# augtool -s rm /files/etc/libvirt/libvirtd.conf/access_drivers
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> changes to libvirtd.conf require that
|
||||
the libvirtd daemon be restarted.
|
||||
</p>
|
||||
|
||||
<h2><a id="perms">Objects and permissions</a></h2>
|
||||
|
||||
<p>
|
||||
Libvirt applies access control to all the main object
|
||||
types in its API. Each object type, in turn, has a set
|
||||
of permissions defined. To determine what permissions
|
||||
are checked for specific API call, consult the
|
||||
<a href="html/index.html">API reference manual</a>
|
||||
documentation for the API in question.
|
||||
</p>
|
||||
|
||||
<div id="include" filename="aclperms.htmlinc"/>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,310 @@
|
|||
.. role:: since
|
||||
|
||||
=====================
|
||||
Polkit access control
|
||||
=====================
|
||||
|
||||
Libvirt's client `access control framework <acl.html>`__ allows
|
||||
administrators to setup fine grained permission rules across client
|
||||
users, managed objects and API operations. This allows client
|
||||
connections to be locked down to a minimal set of privileges. The polkit
|
||||
driver provides a simple implementation of the access control framework.
|
||||
|
||||
.. contents::
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
A default install of libvirt will typically use
|
||||
`polkit <https://www.freedesktop.org/wiki/Software/polkit/>`__ to
|
||||
authenticate the initial user connection to libvirtd. This is a very
|
||||
coarse grained check though, either allowing full read-write access to
|
||||
all APIs, or just read-only access. The polkit access control driver in
|
||||
libvirt builds on this capability to allow for fine grained control over
|
||||
the operations a user may perform on an object.
|
||||
|
||||
Permission names
|
||||
----------------
|
||||
|
||||
The libvirt `object names and permission names <acl.html#perms>`__ are
|
||||
mapped onto polkit action names using the simple pattern:
|
||||
|
||||
::
|
||||
|
||||
org.libvirt.api.$object.$permission
|
||||
|
||||
The only caveat is that any underscore characters in the object or
|
||||
permission names are converted to hyphens. So, for example, the
|
||||
``search_storage_vols`` permission on the ``storage_pool`` object maps
|
||||
to the polkit action:
|
||||
|
||||
::
|
||||
|
||||
org.libvirt.api.storage-pool.search-storage-vols
|
||||
|
||||
The default policy for any permission which corresponds to a "read only"
|
||||
operation, is to allow access. All other permissions default to deny
|
||||
access.
|
||||
|
||||
Object identity attributes
|
||||
--------------------------
|
||||
|
||||
To allow polkit authorization rules to be written to match against
|
||||
individual object instances, libvirt provides a number of authorization
|
||||
detail attributes when performing a permission check. The set of
|
||||
attributes varies according to the type of object being checked
|
||||
|
||||
virConnectPtr
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
============== =====================================
|
||||
Attribute Description
|
||||
============== =====================================
|
||||
connect_driver Name of the libvirt connection driver
|
||||
============== =====================================
|
||||
|
||||
virDomainPtr
|
||||
~~~~~~~~~~~~
|
||||
|
||||
============== ============================================
|
||||
Attribute Description
|
||||
============== ============================================
|
||||
connect_driver Name of the libvirt connection driver
|
||||
domain_name Name of the domain, unique to the local host
|
||||
domain_uuid UUID of the domain, globally unique
|
||||
============== ============================================
|
||||
|
||||
virInterfacePtr
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
+-------------------+---------------------------------------------------------+
|
||||
| Attribute | Description |
|
||||
+===================+=========================================================+
|
||||
| connect_driver | Name of the libvirt connection driver |
|
||||
+-------------------+---------------------------------------------------------+
|
||||
| interface_name | Name of the network interface, unique to the local host |
|
||||
+-------------------+---------------------------------------------------------+
|
||||
| interface_macaddr | MAC address of the network interface, not unique |
|
||||
+-------------------+---------------------------------------------------------+
|
||||
|
||||
virNetworkPtr
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
============== =============================================
|
||||
Attribute Description
|
||||
============== =============================================
|
||||
connect_driver Name of the libvirt connection driver
|
||||
network_name Name of the network, unique to the local host
|
||||
network_uuid UUID of the network, globally unique
|
||||
============== =============================================
|
||||
|
||||
virNodeDevicePtr
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
================ =================================================
|
||||
Attribute Description
|
||||
================ =================================================
|
||||
connect_driver Name of the libvirt connection driver
|
||||
node_device_name Name of the node device, unique to the local host
|
||||
================ =================================================
|
||||
|
||||
virNWFilterPtr
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
============== ====================================================
|
||||
Attribute Description
|
||||
============== ====================================================
|
||||
connect_driver Name of the libvirt connection driver
|
||||
nwfilter_name Name of the network filter, unique to the local host
|
||||
nwfilter_uuid UUID of the network filter, globally unique
|
||||
============== ====================================================
|
||||
|
||||
virSecretPtr
|
||||
~~~~~~~~~~~~
|
||||
|
||||
=================== ===========================================
|
||||
Attribute Description
|
||||
=================== ===========================================
|
||||
connect_driver Name of the libvirt connection driver
|
||||
secret_uuid UUID of the secret, globally unique
|
||||
secret_usage_volume Name of the associated volume, if any
|
||||
secret_usage_ceph Name of the associated Ceph server, if any
|
||||
secret_usage_target Name of the associated iSCSI target, if any
|
||||
secret_usage_name Name of the associated TLS secret, if any
|
||||
=================== ===========================================
|
||||
|
||||
virStoragePoolPtr
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
============== ==================================================
|
||||
Attribute Description
|
||||
============== ==================================================
|
||||
connect_driver Name of the libvirt connection driver
|
||||
pool_name Name of the storage pool, unique to the local host
|
||||
pool_uuid UUID of the storage pool, globally unique
|
||||
============== ==================================================
|
||||
|
||||
virStorageVolPtr
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
============== ==================================================
|
||||
Attribute Description
|
||||
============== ==================================================
|
||||
connect_driver Name of the libvirt connection driver
|
||||
pool_name Name of the storage pool, unique to the local host
|
||||
pool_uuid UUID of the storage pool, globally unique
|
||||
vol_name Name of the storage volume, unique to the pool
|
||||
vol_key Key of the storage volume, globally unique
|
||||
============== ==================================================
|
||||
|
||||
Hypervisor Driver connect_driver
|
||||
--------------------------------
|
||||
|
||||
The ``connect_driver`` parameter describes the client's `remote
|
||||
Connection Driver <remote.html>`__ name based on the `URI <uri.html>`__
|
||||
used for the connection.
|
||||
|
||||
:since:`Since 4.1.0`, when calling an API outside the scope of the primary
|
||||
connection driver, the primary driver will attempt to open a secondary
|
||||
connection to the specific API driver in order to process the API. For
|
||||
example, when hypervisor domain processing needs to make an API call
|
||||
within the storage driver or the network filter driver an attempt to
|
||||
open a connection to the "storage" or "nwfilter" driver will be made.
|
||||
Similarly, a "storage" primary connection may need to create a
|
||||
connection to the "secret" driver in order to process secrets for the
|
||||
API. If successful, then calls to those API's will occur in the
|
||||
``connect_driver`` context of the secondary connection driver rather
|
||||
than in the context of the primary driver. This affects the
|
||||
``connect_driver`` returned from rule generation from the
|
||||
``action.loookup`` function. The following table provides a list of the
|
||||
various connection drivers and the ``connect_driver`` name used by each
|
||||
regardless of primary or secondary connection. The access denied error
|
||||
message from libvirt will list the connection driver by name that denied
|
||||
the access.
|
||||
|
||||
Connection Driver Name
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
================= =======================
|
||||
Connection Driver ``connect_driver`` name
|
||||
================= =======================
|
||||
bhyve bhyve
|
||||
esx ESX
|
||||
hyperv Hyper-V
|
||||
interface interface
|
||||
xen Xen
|
||||
lxc LXC
|
||||
network network
|
||||
nodedev nodedev
|
||||
nwfilter NWFilter
|
||||
openvz OPENVZ
|
||||
qemu QEMU
|
||||
secret secret
|
||||
storage storage
|
||||
vbox VBOX
|
||||
vmware VMWARE
|
||||
vz vz
|
||||
================= =======================
|
||||
|
||||
User identity attributes
|
||||
------------------------
|
||||
|
||||
At this point in time, the only attribute provided by libvirt to
|
||||
identify the user invoking the operation is the PID of the client
|
||||
program. This means that the polkit access control driver is only useful
|
||||
if connections to libvirt are restricted to its UNIX domain socket. If
|
||||
connections are being made to a TCP socket, no identifying information
|
||||
is available and access will be denied. Also note that if the client is
|
||||
connecting via an SSH tunnel, it is the local SSH user that will be
|
||||
identified. In future versions, it is expected that more information
|
||||
about the client user will be provided, including the SASL / Kerberos
|
||||
username and/or x509 distinguished name obtained from the authentication
|
||||
provider in use.
|
||||
|
||||
Writing access control policies
|
||||
-------------------------------
|
||||
|
||||
If using versions of polkit prior to 0.106 then it is only possible to
|
||||
validate (user, permission) pairs via the ``.pkla`` files. Fully
|
||||
validation of the (user, permission, object) triple requires the new
|
||||
JavaScript ``.rules`` support that was introduced in version 0.106. The
|
||||
latter is what will be described here.
|
||||
|
||||
Libvirt does not ship any rules files by default. It merely provides a
|
||||
definition of the default behaviour for each action (permission). As
|
||||
noted earlier, permissions which correspond to read-only operations in
|
||||
libvirt will be allowed to all users by default; everything else is
|
||||
denied by default. Defining custom rules requires creation of a file in
|
||||
the ``/etc/polkit-1/rules.d`` directory with a name chosen by the
|
||||
administrator (``100-libvirt-acl.rules`` would be a reasonable choice).
|
||||
See the ``polkit(8)`` manual page for a description of how to write
|
||||
these files in general. The key idea is to create a file containing
|
||||
something like
|
||||
|
||||
::
|
||||
|
||||
polkit.addRule(function(action, subject) {
|
||||
....logic to check 'action' and 'subject'...
|
||||
});
|
||||
|
||||
In this code snippet above, the ``action`` object instance will
|
||||
represent the libvirt permission being checked along with identifying
|
||||
attributes for the object it is being applied to. The ``subject``
|
||||
meanwhile will identify the libvirt client app (with the caveat above
|
||||
about it only dealing with local clients connected via the UNIX socket).
|
||||
On the ``action`` object, the permission name is accessible via the
|
||||
``id`` attribute, while the object identifying attributes are exposed
|
||||
via the ``lookup`` method.
|
||||
|
||||
See `source
|
||||
code <https://gitlab.com/libvirt/libvirt/-/tree/master/examples/polkit>`__
|
||||
for a more complex example.
|
||||
|
||||
Example: restricting ability to connect to drivers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Consider a local user ``berrange`` who has been granted permission to
|
||||
connect to libvirt in full read-write mode. The goal is to only allow
|
||||
them to use the ``QEMU`` driver and not the Xen or LXC drivers which are
|
||||
also available in libvirtd. To achieve this we need to write a rule
|
||||
which checks whether the ``connect_driver`` attribute is ``QEMU``, and
|
||||
match on an action name of ``org.libvirt.api.connect.getattr``. Using
|
||||
the javascript rules format, this ends up written as
|
||||
|
||||
::
|
||||
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "org.libvirt.api.connect.getattr" &&
|
||||
subject.user == "berrange") {
|
||||
if (action.lookup("connect_driver") == 'QEMU') {
|
||||
return polkit.Result.YES;
|
||||
} else {
|
||||
return polkit.Result.NO;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Example: restricting access to a single domain
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Consider a local user ``berrange`` who has been granted permission to
|
||||
connect to libvirt in full read-write mode. The goal is to only allow
|
||||
them to see the domain called ``demo`` on the LXC driver. To achieve
|
||||
this we need to write a rule which checks whether the ``connect_driver``
|
||||
attribute is ``LXC`` and the ``domain_name`` attribute is ``demo``, and
|
||||
match on an action name of ``org.libvirt.api.domain.getattr``. Using the
|
||||
javascript rules format, this ends up written as
|
||||
|
||||
::
|
||||
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "org.libvirt.api.domain.getattr" &&
|
||||
subject.user == "berrange") {
|
||||
if (action.lookup("connect_driver") == 'LXC' &&
|
||||
action.lookup("domain_name") == 'demo') {
|
||||
return polkit.Result.YES;
|
||||
} else {
|
||||
return polkit.Result.NO;
|
||||
}
|
||||
}
|
||||
});
|
|
@ -0,0 +1,171 @@
|
|||
=========================
|
||||
Advanced test suite usage
|
||||
=========================
|
||||
|
||||
The basic requirement before submitting changes to libvirt is that
|
||||
|
||||
::
|
||||
|
||||
$ ninja test
|
||||
|
||||
succeed after each commit.
|
||||
|
||||
The libvirt test suite, however, support additional features: for
|
||||
example, it's possible to look for memory leaks and similar issues
|
||||
by running
|
||||
|
||||
::
|
||||
|
||||
$ meson test --setup valgrind
|
||||
|
||||
`Valgrind <https://valgrind.org/>`__ is a test that checks for
|
||||
memory management issues, such as leaks or use of uninitialized
|
||||
variables.
|
||||
|
||||
Some tests are skipped by default in a development environment,
|
||||
based on the time they take in comparison to the likelihood
|
||||
that those tests will turn up problems during incremental
|
||||
builds. These tests default to being run when building from a
|
||||
tarball or with the configure option -Dexpensive_tests=enabled.
|
||||
|
||||
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 ninja test (or)
|
||||
$ VIR_TEST_DEBUG=2 ninja test
|
||||
|
||||
When debugging failures during development, it is possible to
|
||||
focus in on just the failing subtests by using VIR_TEST_RANGE.
|
||||
I.e. to run all tests from 3 to 20 with the exception of tests
|
||||
6 and 16, use:
|
||||
|
||||
::
|
||||
|
||||
$ VIR_TEST_DEBUG=1 VIR_TEST_RANGE=3-5,7-20,^16 ./run tests/qemuxml2argvtest
|
||||
|
||||
Also, individual tests can be run from inside the ``tests/``
|
||||
directory, like:
|
||||
|
||||
::
|
||||
|
||||
$ ./qemuxml2xmltest
|
||||
|
||||
If you are adding new test cases, or making changes that alter
|
||||
existing test output, you can use the environment variable
|
||||
VIR_TEST_REGENERATE_OUTPUT to quickly update the saved test
|
||||
data. Of course you still need to review the changes VERY
|
||||
CAREFULLY to ensure they are correct.
|
||||
|
||||
::
|
||||
|
||||
$ VIR_TEST_REGENERATE_OUTPUT=1 ./qemuxml2argvtest
|
||||
|
||||
There is also a ``./run`` script at the top level, to make it
|
||||
easier to run programs that have not yet been installed, as
|
||||
well as to wrap invocations of various tests under gdb or
|
||||
Valgrind.
|
||||
|
||||
When running our test suite it may happen that the test result
|
||||
is nondeterministic because of the test suite relying on a
|
||||
particular file in the system being accessible or having some
|
||||
specific value. To catch this kind of errors, the test suite
|
||||
has a module for that prints any path touched that fulfils
|
||||
constraints described above into a file. To enable it just set
|
||||
``VIR_TEST_FILE_ACCESS`` environment variable. Then
|
||||
``VIR_TEST_FILE_ACCESS_OUTPUT`` environment variable can alter
|
||||
location where the file is stored.
|
||||
|
||||
::
|
||||
|
||||
$ VIR_TEST_FILE_ACCESS=1 VIR_TEST_FILE_ACCESS_OUTPUT="/tmp/file_access.txt" ./qemuxml2argvtest
|
||||
|
||||
#. The Valgrind test should produce similar output to
|
||||
``ninja test``. If the output has traces within libvirt API's,
|
||||
then investigation is required in order to determine the cause
|
||||
of the issue. Output such as the following indicates some sort
|
||||
of leak:
|
||||
|
||||
::
|
||||
|
||||
==5414== 4 bytes in 1 blocks are definitely lost in loss record 3 of 89
|
||||
==5414== at 0x4A0881C: malloc (vg_replace_malloc.c:270)
|
||||
==5414== by 0x34DE0AAB85: xmlStrndup (in /usr/lib64/libxml2.so.2.7.8)
|
||||
==5414== by 0x4CC97A6: virDomainVideoDefParseXML (domain_conf.c:7410)
|
||||
==5414== by 0x4CD581D: virDomainDefParseXML (domain_conf.c:10188)
|
||||
==5414== by 0x4CD8C73: virDomainDefParseNode (domain_conf.c:10640)
|
||||
==5414== by 0x4CD8DDB: virDomainDefParse (domain_conf.c:10590)
|
||||
==5414== by 0x41CB1D: testCompareXMLToArgvHelper (qemuxml2argvtest.c:100)
|
||||
==5414== by 0x41E20F: virtTestRun (testutils.c:161)
|
||||
==5414== by 0x41C7CB: mymain (qemuxml2argvtest.c:866)
|
||||
==5414== by 0x41E84A: virtTestMain (testutils.c:723)
|
||||
==5414== by 0x34D9021734: (below main) (in /usr/lib64/libc-2.15.so)
|
||||
|
||||
In this example, the ``virDomainDefParseXML()`` had an error
|
||||
path where the ``virDomainVideoDef *video`` pointer was not
|
||||
properly disposed. By simply adding a
|
||||
``virDomainVideoDefFree(video);`` in the error path, the issue
|
||||
was resolved.
|
||||
|
||||
Another common mistake is calling a printing function, such as
|
||||
``VIR_DEBUG()`` without initializing a variable to be printed.
|
||||
The following example involved a call which could return an
|
||||
error, but not set variables passed by reference to the call.
|
||||
The solution was to initialize the variables prior to the call.
|
||||
|
||||
::
|
||||
|
||||
==4749== Use of uninitialised value of size 8
|
||||
==4749== at 0x34D904650B: _itoa_word (in /usr/lib64/libc-2.15.so)
|
||||
==4749== by 0x34D9049118: vfprintf (in /usr/lib64/libc-2.15.so)
|
||||
==4749== by 0x34D9108F60: __vasprintf_chk (in /usr/lib64/libc-2.15.so)
|
||||
==4749== by 0x4CAEEF7: virVasprintf (stdio2.h:199)
|
||||
==4749== by 0x4C8A55E: virLogVMessage (virlog.c:814)
|
||||
==4749== by 0x4C8AA96: virLogMessage (virlog.c:751)
|
||||
==4749== by 0x4DA0056: virNetTLSContextCheckCertKeyUsage (virnettlscontext.c:225)
|
||||
==4749== by 0x4DA06DB: virNetTLSContextCheckCert (virnettlscontext.c:439)
|
||||
==4749== by 0x4DA1620: virNetTLSContextNew (virnettlscontext.c:562)
|
||||
==4749== by 0x4DA26FC: virNetTLSContextNewServer (virnettlscontext.c:927)
|
||||
==4749== by 0x409C39: testTLSContextInit (virnettlscontexttest.c:467)
|
||||
==4749== by 0x40AB8F: virtTestRun (testutils.c:161)
|
||||
|
||||
Valgrind will also find some false positives or code paths
|
||||
which cannot be resolved by making changes to the libvirt code.
|
||||
For these paths, it is possible to add a filter to avoid the
|
||||
errors. For example:
|
||||
|
||||
::
|
||||
|
||||
==4643== 7 bytes in 1 blocks are possibly lost in loss record 4 of 20
|
||||
==4643== at 0x4A0881C: malloc (vg_replace_malloc.c:270)
|
||||
==4643== by 0x34D90853F1: strdup (in /usr/lib64/libc-2.15.so)
|
||||
==4643== by 0x34EEC2C08A: ??? (in /usr/lib64/libnl.so.1.1)
|
||||
==4643== by 0x34EEC15B81: ??? (in /usr/lib64/libnl.so.1.1)
|
||||
==4643== by 0x34D8C0EE15: call_init.part.0 (in /usr/lib64/ld-2.15.so)
|
||||
==4643== by 0x34D8C0EECF: _dl_init (in /usr/lib64/ld-2.15.so)
|
||||
==4643== by 0x34D8C01569: ??? (in /usr/lib64/ld-2.15.so)
|
||||
|
||||
In this instance, it is acceptable to modify the
|
||||
``tests/.valgrind.supp`` file in order to add a suppression
|
||||
filter. The filter should be unique enough to not suppress real
|
||||
leaks, but it should be generic enough to cover multiple code
|
||||
paths. The format of the entry can be found in the
|
||||
documentation found at the `Valgrind home
|
||||
page <https://valgrind.org/>`__. The following trace was added
|
||||
to ``tests/.valgrind.supp`` in order to suppress the warning:
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
dlInitMemoryLeak1
|
||||
Memcheck:Leak
|
||||
fun:?alloc
|
||||
...
|
||||
fun:call_init.part.0
|
||||
fun:_dl_init
|
||||
...
|
||||
obj:*/lib*/ld-2.*so*
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,266 @@
|
|||
========================
|
||||
The libvirt API concepts
|
||||
========================
|
||||
|
||||
This page describes the main principles and architecture choices behind
|
||||
the definition of the libvirt API:
|
||||
|
||||
.. contents::
|
||||
|
||||
Objects Exposed
|
||||
---------------
|
||||
|
||||
As defined in the `goals section <goals.html>`__, the libvirt API is
|
||||
designed to expose all the resources needed to manage the virtualization
|
||||
support of recent operating systems. The first object manipulated
|
||||
through the API is the ``virConnectPtr``, which represents the
|
||||
connection to a hypervisor. Any application using libvirt is likely to
|
||||
start using the API by calling one of `the virConnectOpen
|
||||
functions <html/libvirt-libvirt-host.html#virConnectOpen>`__. You will
|
||||
note that those functions take a name argument which is actually a
|
||||
`connection URI <uri.html>`__ to select the right hypervisor to open. A
|
||||
URI 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 `connection URI <uri.html>`__
|
||||
page for a full descriptions of the values allowed.
|
||||
|
||||
OnDevice the application obtains a
|
||||
`virConnectPtr <html/libvirt-libvirt-host.html#virConnectPtr>`__
|
||||
connection to the hypervisor it can then use it to manage the
|
||||
hypervisor's available domains and related virtualization resources,
|
||||
such as 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).
|
||||
|
||||
|first class objects exposed by the API|
|
||||
|
||||
The figure above shows the five main objects exported by the API:
|
||||
|
||||
- `virConnectPtr <html/libvirt-libvirt-host.html#virConnectPtr>`__
|
||||
|
||||
Represents the connection to a hypervisor. Use one of the
|
||||
`virConnectOpen <html/libvirt-libvirt-host.html#virConnectOpen>`__
|
||||
functions to obtain connection to the hypervisor which is then used
|
||||
as a parameter to other connection API's.
|
||||
|
||||
- `virDomainPtr <html/libvirt-libvirt-domain.html#virDomainPtr>`__
|
||||
|
||||
Represents one domain either active or defined (i.e. existing as
|
||||
permanent config file and storage but not currently running on that
|
||||
node). The function
|
||||
`virConnectListAllDomains <html/libvirt-libvirt-domain.html#virConnectListAllDomains>`__
|
||||
lists all the domains for the hypervisor.
|
||||
|
||||
- `virNetworkPtr <html/libvirt-libvirt-network.html#virNetworkPtr>`__
|
||||
|
||||
Represents one network either active or defined (i.e. existing as
|
||||
permanent config file and storage but not currently activated). The
|
||||
function
|
||||
`virConnectListAllNetworks <html/libvirt-libvirt-network.html#virConnectListAllNetworks>`__
|
||||
lists all the virtualization networks for the hypervisor.
|
||||
|
||||
- `virStorageVolPtr <html/libvirt-libvirt-storage.html#virStorageVolPtr>`__
|
||||
|
||||
Represents one storage volume generally used as a block device
|
||||
available to one of the domains. The function
|
||||
`virStorageVolLookupByPath <html/libvirt-libvirt-storage.html#virStorageVolLookupByPath>`__
|
||||
finds the storage volume object based on its path on the node.
|
||||
|
||||
- `virStoragePoolPtr <html/libvirt-libvirt-storage.html#virStoragePoolPtr>`__
|
||||
|
||||
Represents a storage pool, which is a logical area used to allocate
|
||||
and store storage volumes. The function
|
||||
`virConnectListAllStoragePools <html/libvirt-libvirt-storage.html#virConnectListAllStoragePools>`__
|
||||
lists all of the virtualization storage pools on the hypervisor. The
|
||||
function
|
||||
`virStoragePoolLookupByVolume <html/libvirt-libvirt-storage.html#virStoragePoolLookupByVolume>`__
|
||||
finds the storage pool containing a given storage volume.
|
||||
|
||||
Most objects 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.
|
||||
|
||||
Domains, networks, and storage pools can be either ``active`` i.e.
|
||||
either running or available for immediate use, or ``defined`` in which
|
||||
case they are inactive but there is a permanent definition available in
|
||||
the system for them. Based on this they can be activated dynamically in
|
||||
order to be used.
|
||||
|
||||
Most objects can also be named in various ways:
|
||||
|
||||
- ``name``
|
||||
|
||||
A user friendly identifier but whose uniqueness cannot be guaranteed
|
||||
between two nodes.
|
||||
|
||||
- ``ID``
|
||||
|
||||
A runtime unique identifier provided by the hypervisor for one given
|
||||
activation of the object; however, it becomes invalid once the
|
||||
resource is deactivated.
|
||||
|
||||
- ``UUID``
|
||||
|
||||
A 16 byte unique identifier as defined in `RFC
|
||||
4122 <https://www.ietf.org/rfc/rfc4122.txt>`__, which is guaranteed
|
||||
to be unique for long term usage and across a set of nodes.
|
||||
|
||||
Functions and Naming Conventions
|
||||
--------------------------------
|
||||
|
||||
The naming of the functions present in the library is usually composed
|
||||
by a prefix describing the object associated to the function and a verb
|
||||
describing the action on that object.
|
||||
|
||||
For each first class object you will find APIs for the following
|
||||
actions:
|
||||
|
||||
- **Lookup** [...LookupBy...]
|
||||
|
||||
Used to perform lookups on objects by some type of identifier, such
|
||||
as:
|
||||
|
||||
- `virDomainLookupByID <html/libvirt-libvirt-domain.html#virDomainLookupByID>`__
|
||||
- `virDomainLookupByName <html/libvirt-libvirt-domain.html#virDomainLookupByName>`__
|
||||
- `virDomainLookupByUUID <html/libvirt-libvirt-domain.html#virDomainLookupByUUID>`__
|
||||
- `virDomainLookupByUUIDString <html/libvirt-libvirt-domain.html#virDomainLookupByUUIDString>`__
|
||||
|
||||
- **Enumeration** [virConnectList..., virConnectNumOf...]
|
||||
|
||||
Used to enumerate a set of object available to a given hypervisor
|
||||
connection such as:
|
||||
|
||||
- `virConnectListDomains <html/libvirt-libvirt-domain.html#virConnectListDomains>`__
|
||||
- `virConnectNumOfDomains <html/libvirt-libvirt-domain.html#virConnectNumOfDomains>`__
|
||||
- `virConnectListNetworks <html/libvirt-libvirt-network.html#virConnectListNetworks>`__
|
||||
- `virConnectListStoragePools <html/libvirt-libvirt-storage.html#virConnectListStoragePools>`__
|
||||
|
||||
- **Description** [...GetInfo]
|
||||
|
||||
Generic accessor providing a set of generic information about an
|
||||
object, such as:
|
||||
|
||||
- `virNodeGetInfo <html/libvirt-libvirt-host.html#virNodeGetInfo>`__
|
||||
- `virDomainGetInfo <html/libvirt-libvirt-domain.html#virDomainGetInfo>`__
|
||||
- `virStoragePoolGetInfo <html/libvirt-libvirt-storage.html#virStoragePoolGetInfo>`__
|
||||
- `virStorageVolGetInfo <html/libvirt-libvirt-storage.html#virStorageVolGetInfo>`__
|
||||
|
||||
- **Accessors** [...Get..., ...Set...]
|
||||
|
||||
Specific accessors used to query or modify data for the given object,
|
||||
such as:
|
||||
|
||||
- `virConnectGetType <html/libvirt-libvirt-host.html#virConnectGetType>`__
|
||||
- `virDomainGetMaxMemory <html/libvirt-libvirt-domain.html#virDomainGetMaxMemory>`__
|
||||
- `virDomainSetMemory <html/libvirt-libvirt-domain.html#virDomainSetMemory>`__
|
||||
- `virDomainGetVcpus <html/libvirt-libvirt-domain.html#virDomainGetVcpus>`__
|
||||
- `virStoragePoolSetAutostart <html/libvirt-libvirt-storage.html#virStoragePoolSetAutostart>`__
|
||||
- `virNetworkGetBridgeName <html/libvirt-libvirt-network.html#virNetworkGetBridgeName>`__
|
||||
|
||||
- **Creation** [...Create, ...CreateXML]
|
||||
|
||||
Used to create and start objects. The ...CreateXML APIs will create
|
||||
the object based on an XML description, while the ...Create APIs will
|
||||
create the object based on existing object pointer, such as:
|
||||
|
||||
- `virDomainCreate <html/libvirt-libvirt-domain.html#virDomainCreate>`__
|
||||
- `virDomainCreateXML <html/libvirt-libvirt-domain.html#virDomainCreateXML>`__
|
||||
- `virNetworkCreate <html/libvirt-libvirt-network.html#virNetworkCreate>`__
|
||||
- `virNetworkCreateXML <html/libvirt-libvirt-network.html#virNetworkCreateXML>`__
|
||||
|
||||
- **Destruction** [...Destroy]
|
||||
|
||||
Used to shutdown or deactivate and destroy objects, such as:
|
||||
|
||||
- `virDomainDestroy <html/libvirt-libvirt-domain.html#virDomainDestroy>`__
|
||||
- `virNetworkDestroy <html/libvirt-libvirt-network.html#virNetworkDestroy>`__
|
||||
- `virStoragePoolDestroy <html/libvirt-libvirt-storage.html#virStoragePoolDestroy>`__
|
||||
|
||||
Note: functions returning vir*Ptr (like the virDomainLookup functions)
|
||||
allocate memory which needs to be freed by the caller by the
|
||||
corresponding vir*Free function (e.g. virDomainFree for a virDomainPtr
|
||||
object).
|
||||
|
||||
For more in-depth details of the storage related APIs see `the storage
|
||||
management page <storage.html>`__.
|
||||
|
||||
The libvirt Drivers
|
||||
-------------------
|
||||
|
||||
Drivers are the basic building block for libvirt functionality to
|
||||
support the capability to handle specific hypervisor driver calls.
|
||||
Drivers are discovered and registered during connection processing as
|
||||
part of the
|
||||
`virInitialize <html/libvirt-libvirt-host.html#virInitialize>`__
|
||||
API. Each driver has a registration API which loads up the driver
|
||||
specific function references for the libvirt APIs to call. The following
|
||||
is a simplistic view of the hypervisor driver mechanism. Consider the
|
||||
stacked list of drivers as a series of modules that can be plugged into
|
||||
the architecture depending on how libvirt is configured to be built.
|
||||
|
||||
|The libvirt driver architecture|
|
||||
|
||||
The driver architecture is also used to support other virtualization
|
||||
components such as storage, storage pools, host device, networking,
|
||||
network interfaces, and network filters.
|
||||
|
||||
See the `libvirt drivers <drivers.html>`__ page for more information on
|
||||
hypervisor and storage specific drivers.
|
||||
|
||||
Not all drivers support every virtualization function possible. The
|
||||
`libvirt API support matrix <hvsupport.html>`__ lists the various
|
||||
functions and support found in each driver by the version support was
|
||||
added into libvirt.
|
||||
|
||||
Daemon and Remote Access
|
||||
------------------------
|
||||
|
||||
Access to libvirt drivers is primarily handled by the libvirtd daemon
|
||||
through the `remote <remote.html>`__ driver via an
|
||||
`RPC <kbase/internals/rpc.html>`__. Some hypervisors do support client-side
|
||||
connections and responses, such as Test, OpenVZ, VMware, VirtualBox
|
||||
(vbox), ESX, Hyper-V, Xen, and Virtuozzo. The libvirtd daemon service is
|
||||
started on the host at system boot time and can also be restarted at any
|
||||
time by a properly privileged user, such as root. The libvirtd daemon
|
||||
uses the same libvirt API
|
||||
`virInitialize <html/libvirt-libvirt-host.html#virInitialize>`__
|
||||
sequence as applications for client-side driver registrations, but then
|
||||
extends the registered driver list to encompass all known drivers
|
||||
supported for all driver types supported on the host.
|
||||
|
||||
The libvirt client `applications <apps.html>`__ use a `URI <uri.html>`__
|
||||
to obtain the ``virConnectPtr``. The ``virConnectPtr`` keeps track of
|
||||
the driver connection plus a variety of other connections (network,
|
||||
interface, storage, etc.). The ``virConnectPtr`` is then used as a
|
||||
parameter to other virtualization functions
|
||||
(see `Functions and Naming Conventions`_).
|
||||
Depending upon the driver being used, calls will be routed through the remote
|
||||
driver to the libvirtd daemon. The daemon will reference the connection
|
||||
specific driver in order to retrieve the requested information and then
|
||||
pass back status and/or data through the connection back to the
|
||||
application. The application can then decide what to do with that data,
|
||||
such as display, write log data, etc. `Migration <migration.html>`__ is
|
||||
an example of many facets of the architecture in use.
|
||||
|
||||
|The libvirt daemon and remote architecture|
|
||||
|
||||
The key takeaway from the above diagram is that there is a remote driver
|
||||
which handles transactions for a majority of the drivers. The libvirtd
|
||||
daemon running on the host will receive transaction requests from the
|
||||
remote driver and will then query the hypervisor driver as specified in
|
||||
the ``virConnectPtr`` in order to fetch the data. The data will then be
|
||||
returned through the remote driver to the client application for
|
||||
processing.
|
||||
|
||||
If you are interested in contributing to libvirt, read the
|
||||
`FAQ <https://wiki.libvirt.org/page/FAQ>`__ and
|
||||
`hacking <hacking.html>`__ guidelines to gain an understanding of basic
|
||||
rules and guidelines. In order to add new API functionality follow the
|
||||
instructions regarding `implementing a new API in
|
||||
libvirt <api_extension.html>`__.
|
||||
|
||||
.. |first class objects exposed by the API| image:: images/libvirt-object-model.png
|
||||
.. |The libvirt driver architecture| image:: images/libvirt-driver-arch.png
|
||||
.. |The libvirt daemon and remote architecture| image:: images/libvirt-daemon-arch.png
|
|
@ -0,0 +1,291 @@
|
|||
=================================
|
||||
Implementing a new API in Libvirt
|
||||
=================================
|
||||
|
||||
.. contents::
|
||||
|
||||
This document walks you through the process of implementing a new API in
|
||||
libvirt. 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.
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
https://libvirt.org/downloads.html
|
||||
|
||||
Once you have a working development environment, the steps to create a
|
||||
new API are:
|
||||
|
||||
#. define the public API
|
||||
#. define the internal driver API
|
||||
#. implement the public API
|
||||
#. implement the remote protocol:
|
||||
|
||||
#. define the wire protocol format
|
||||
#. implement the RPC client
|
||||
#. implement the server side dispatcher
|
||||
|
||||
#. use new API where appropriate in drivers
|
||||
#. add virsh support
|
||||
#. add common handling for new API
|
||||
#. for each driver that can support the new API:
|
||||
|
||||
#. add prerequisite support
|
||||
#. fully implement new API
|
||||
|
||||
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.
|
||||
|
||||
Submit new code in the form of 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 to break
|
||||
the changes 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.
|
||||
|
||||
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.
|
||||
|
||||
Defining the public API
|
||||
-----------------------
|
||||
|
||||
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:
|
||||
|
||||
``src/conf/schemas/domaincommon.rng docs/formatdomain.rst``
|
||||
|
||||
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:
|
||||
|
||||
``include/libvirt/libvirt-$MODULE.h.in src/libvirt_public.syms``
|
||||
|
||||
Please consult our `coding
|
||||
style <coding-style.html#xml-element-and-attribute-naming>`__ guide on
|
||||
elements and attribute names.
|
||||
|
||||
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.
|
||||
|
||||
Defining the internal API
|
||||
-------------------------
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
The driver structs are defined in:
|
||||
|
||||
``src/driver-$MODULE.h``
|
||||
|
||||
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 ``NULL`` stub
|
||||
for the new function.
|
||||
|
||||
Implementing the public API
|
||||
---------------------------
|
||||
|
||||
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:
|
||||
|
||||
#. SHOULD log a message with VIR_DEBUG() indicating that it is being
|
||||
called and its parameters;
|
||||
#. MUST call virResetLastError();
|
||||
#. SHOULD confirm that the connection is valid with
|
||||
virCheckConnectReturn() or virCheckConnectGoto();
|
||||
#. **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 with virCheckReadOnlyGoto();**
|
||||
#. SHOULD do basic validation of the parameters that are being passed
|
||||
in, using helpers like virCheckNonNullArgGoto();
|
||||
#. MUST confirm that the driver for this connection exists and that it
|
||||
implements this function;
|
||||
#. MUST call the internal API;
|
||||
#. SHOULD log a message with VIR_DEBUG() indicating that it is
|
||||
returning, its return value, and status.
|
||||
#. MUST return status to the caller.
|
||||
|
||||
The public API calls are implemented in:
|
||||
|
||||
``src/libvirt-$MODULE.c``
|
||||
|
||||
Implementing the remote protocol
|
||||
--------------------------------
|
||||
|
||||
Implementing the remote protocol is essentially a straightforward
|
||||
exercise which is probably most easily understood by referring to the
|
||||
existing code.
|
||||
|
||||
Defining the wire protocol format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Defining the wire protocol involves making additions to:
|
||||
|
||||
``src/remote/remote_protocol.x``
|
||||
|
||||
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.
|
||||
|
||||
Second, add values to the remote_procedure enum for each new function
|
||||
added to the API.
|
||||
|
||||
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:
|
||||
|
||||
``src/remote/remote_daemon_dispatch_stubs.h src/remote/remote_daemon_dispatch.h src/remote/remote_daemon_dispatch.c src/remote/remote_protocol.c src/remote/remote_protocol.h``
|
||||
|
||||
Implement the RPC client
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Implementing the RPC client uses the rpcgen generated .h files. The
|
||||
remote method calls go in:
|
||||
|
||||
``src/remote/remote_driver.c``
|
||||
|
||||
Each remote method invocation does the following:
|
||||
|
||||
#. locks the remote driver;
|
||||
#. sets up the method arguments;
|
||||
#. invokes the remote function;
|
||||
#. checks the return value, if necessary;
|
||||
#. extracts any returned data;
|
||||
#. frees any returned data;
|
||||
#. unlocks the remote driver.
|
||||
|
||||
Implement the server side dispatcher
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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:
|
||||
|
||||
``src/remote/remote_daemon_dispatch.c``
|
||||
|
||||
Again, this step uses the .h files generated by make rpcgen.
|
||||
|
||||
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:
|
||||
|
||||
``src/remote_protocol-structs``
|
||||
|
||||
This file should only have new lines added; modifications to existing
|
||||
lines probably imply a backwards-incompatible API change.
|
||||
|
||||
Use the new API internally
|
||||
--------------------------
|
||||
|
||||
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.
|
||||
|
||||
Expose the new API in virsh
|
||||
---------------------------
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
``tools/virsh-$MODULE.c tools/virsh.pod``
|
||||
|
||||
Implement the driver methods
|
||||
----------------------------
|
||||
|
||||
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.
|
||||
|
||||
Implement common handling
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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 virDomainDef
|
||||
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.
|
||||
|
||||
Implement driver handling
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Any cleanups resulting from the changes should be added as separate
|
||||
patches at the end of the series.
|
||||
|
||||
Once you have working functionality, run ninja test 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.
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
|
@ -0,0 +1,338 @@
|
|||
==========================
|
||||
Applications using libvirt
|
||||
==========================
|
||||
|
||||
This page provides an illustration of the wide variety of applications
|
||||
using the libvirt management API.
|
||||
|
||||
.. contents::
|
||||
|
||||
Add an application
|
||||
------------------
|
||||
|
||||
To add an application not listed on this page, send a message to the
|
||||
`mailing list <contact.html>`__, 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
|
||||
graphics are available for your website to advertise support for
|
||||
libvirt:
|
||||
|
||||
|libvirt powered 96| |libvirt powered 128| |libvirt powered 192| |libvirt powered 256|
|
||||
|
||||
Command line tools
|
||||
------------------
|
||||
|
||||
`guestfish <https://libguestfs.org>`__
|
||||
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.
|
||||
virsh
|
||||
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.
|
||||
`virt-clone <https://virt-manager.org/>`__
|
||||
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.
|
||||
`virt-df <https://people.redhat.com/rjones/virt-df/>`__
|
||||
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.
|
||||
`virt-image <https://virt-manager.org/>`__
|
||||
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.
|
||||
`virt-install <https://virt-manager.org/>`__
|
||||
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.
|
||||
`virt-top <https://people.redhat.com/rjones/virt-top/>`__
|
||||
Watch the CPU, memory, network and disk utilization of all virtual
|
||||
machines running on a host.
|
||||
`virt-what <https://people.redhat.com/~rjones/virt-what/>`__
|
||||
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.
|
||||
`stap <https://sourceware.org/systemtap/>`__
|
||||
SystemTap is a tool used to gather rich information about a running
|
||||
system through the use of scripts. Starting from v2.4, the front-end
|
||||
application stap can use libvirt to gather data within virtual
|
||||
machines.
|
||||
`vagrant-libvirt <https://github.com/pradels/vagrant-libvirt/>`__
|
||||
Vagrant-Libvirt is a Vagrant plugin that uses libvirt to manage
|
||||
virtual machines. It is a command line tool for developers that makes
|
||||
it very fast and easy to deploy and re-deploy an environment of vm's.
|
||||
`virt-lightning <https://github.com/virt-lightning/virt-lightning>`__
|
||||
Virt-Lightning uses libvirt, cloud-init and libguestfs to allow
|
||||
anyone to quickly start a new VM. Very much like a container CLI, but
|
||||
with a virtual machine.
|
||||
|
||||
Configuration Management
|
||||
------------------------
|
||||
|
||||
`LCFG <https://wiki.lcfg.org/bin/view/LCFG/LcfgLibvirt>`__
|
||||
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.
|
||||
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.
|
||||
|
||||
Continuous Integration
|
||||
----------------------
|
||||
|
||||
`BuildBot <https://docs.buildbot.net/latest/manual/configuration/workers-libvirt.html>`__
|
||||
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.
|
||||
|
||||
`Jenkins <https://plugins.jenkins.io/libvirt-slave/>`__
|
||||
This plugin for Jenkins adds a way to control guest domains hosted on
|
||||
Xen or QEMU/KVM. You configure a Jenkins Agent, selecting the guest
|
||||
domain and hypervisor. When you need to build a job on a specific
|
||||
Agent, 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.
|
||||
|
||||
Conversion
|
||||
----------
|
||||
|
||||
`virt-p2v <https://libguestfs.org/virt-p2v.1.html>`__
|
||||
Convert a physical machine to run on KVM. 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. (Note this
|
||||
tool is included with libguestfs)
|
||||
`virt-v2v <https://libguestfs.org/virt-v2v.1.html>`__
|
||||
virt-v2v converts guests from a foreign hypervisor to run on KVM,
|
||||
managed by libvirt. It can convert guests from VMware or Xen to run
|
||||
on OpenStack, oVirt (RHEV-M), or local libvirt. It will enable VirtIO
|
||||
drivers in the converted guest if possible. (Note this tool is
|
||||
included with libguestfs)
|
||||
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.
|
||||
`vmware2libvirt <https://launchpad.net/virt-goodies>`__
|
||||
Part of the *virt-goodies* package, vmware2libvirt is a python script
|
||||
for migrating a vmware image to libvirt.
|
||||
|
||||
Desktop applications
|
||||
--------------------
|
||||
|
||||
`virt-manager <https://virt-manager.org/>`__
|
||||
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 up to managing 10-20 hosts
|
||||
and their VMs.
|
||||
`virt-viewer <https://virt-manager.org/>`__
|
||||
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.
|
||||
`qt-virt-manager <https://f1ash.github.io/qt-virt-manager>`__
|
||||
The Qt GUI for create and control VMs and another virtual entities
|
||||
(aka networks, storages, interfaces, secrets, network filters).
|
||||
Contains integrated LXC/SPICE/VNC viewer for accessing the graphical
|
||||
or text console associated with a virtual machine or container.
|
||||
`qt-remote-viewer <https://f1ash.github.io/qt-virt-manager/#virtual-machines-viewer>`__
|
||||
The Qt VNC/SPICE viewer for access to remote desktops or VMs.
|
||||
`GNOME Boxes <https://gnomeboxes.org/>`__
|
||||
A GNOME application to access virtual machines.
|
||||
|
||||
Infrastructure as a Service (IaaS)
|
||||
----------------------------------
|
||||
|
||||
`Eucalyptus <https://github.com/eucalyptus/eucalyptus>`__
|
||||
Eucalyptus is an on-premise Infrastructure as a Service cloud
|
||||
software platform that is open source and AWS-compatible. Eucalyptus
|
||||
uses libvirt virtualization API to directly interact with Xen and KVM
|
||||
hypervisors.
|
||||
`Nimbus <https://www.nimbusproject.org/>`__
|
||||
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.
|
||||
`OpenStack <https://www.openstack.org>`__
|
||||
OpenStack is a "cloud operating system" usable for both public and
|
||||
private clouds. Its various parts take care of compute, storage and
|
||||
networking resources and interface with the user using a dashboard.
|
||||
Compute part uses libvirt to manage VM life-cycle, monitoring and so
|
||||
on.
|
||||
`KubeVirt <https://kubevirt.io/>`__
|
||||
KubeVirt is a virtual machine management add-on for Kubernetes. The
|
||||
aim is to provide a common ground for virtualization solutions on top
|
||||
of Kubernetes.
|
||||
`Cherrypop <https://github.com/gustavfranssonnyvell/cherrypop>`__
|
||||
A cloud software with no masters or central points. Nodes autodetect
|
||||
other nodes and autodistribute virtual machines and autodivide up the
|
||||
workload. Also there is no minimum limit for hosts, well, one might
|
||||
be nice. It's perfect for setting up low-end servers in a cloud or a
|
||||
cloud where you want the most bang for the bucks.
|
||||
`ZStack <https://en.zstack.io/>`__
|
||||
ZStack is an open source IaaS software that aims to automate the
|
||||
management of all resources (compute, storage, networking, etc.) in a
|
||||
datacenter by using APIs, thus conforming to the principles of a
|
||||
software-defined datacenter. The key strengths of ZStack in terms of
|
||||
management are scalability, performance, and a fast, user-friendly
|
||||
deployment.
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
`libguestfs <https://libguestfs.org>`__
|
||||
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#.
|
||||
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.
|
||||
`libvirt-sandbox <https://sandbox.libvirt.org>`__
|
||||
A library and command line tools for simplifying the creation of
|
||||
application sandboxes using virtualization technology. It currently
|
||||
supports either KVM, QEMU or LXC as backends. Integration with
|
||||
systemd facilitates sandboxing of system services like apache.
|
||||
`Ruby Libvirt Object bindings <https://github.com/ohadlevy/virt#readme>`__
|
||||
Allows using simple ruby objects to manipulate hypervisors, guests,
|
||||
storage, network etc. It is based on top of the `native ruby
|
||||
bindings <https://libvirt.org/ruby>`__.
|
||||
|
||||
LiveCD / Appliances
|
||||
-------------------
|
||||
|
||||
`virt-p2v <https://libguestfs.org/virt-v2v/>`__
|
||||
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.
|
||||
|
||||
Monitoring
|
||||
----------
|
||||
|
||||
`collectd <https://collectd.org/plugins/libvirt.shtml>`__
|
||||
The libvirt-plugin is part of `collectd <https://collectd.org/>`__
|
||||
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.
|
||||
`Host sFlow <https://sflow.net/>`__
|
||||
Host sFlow is a lightweight agent running on KVM hypervisors that
|
||||
links to libvirt library and exports standardized cpu, memory,
|
||||
network and disk metrics for all virtual machines.
|
||||
`Munin <https://honk.sigxcpu.org/projects/libvirt/#munin>`__
|
||||
The plugins provided by Guido Günther allow to monitor various things
|
||||
like network and block I/O with
|
||||
`Munin <https://munin-monitoring.org/>`__.
|
||||
`Nagios-virt <https://people.redhat.com/rjones/nagios-virt/>`__
|
||||
Nagios-virt is a configuration tool to add monitoring of your
|
||||
virtualised domains to `Nagios <https://www.nagios.org/>`__. 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.
|
||||
`PCP <https://pcp.io/man/man1/pmdalibvirt.1.html>`__
|
||||
The PCP libvirt PMDA (plugin) is part of the
|
||||
`PCP <https://pcp.io/>`__ toolkit and provides hypervisor and guest
|
||||
information and complete set of guest performance metrics. It
|
||||
supports pCPU, vCPU, memory, block device, network interface, and
|
||||
performance event metrics for each virtual guest.
|
||||
|
||||
Provisioning
|
||||
------------
|
||||
|
||||
`Foreman <https://theforeman.org>`__
|
||||
Foreman is an open source web based application aimed to be a Single
|
||||
Address For All Machines Life Cycle Management. Foreman:
|
||||
|
||||
- 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...)
|
||||
- Integrates with Puppet (and acts as web front end to it).
|
||||
- Takes care of provisioning until the point puppet is running,
|
||||
allowing Puppet to do what it does best.
|
||||
- Shows you Systems Inventory (based on Facter) and provides real
|
||||
time information about hosts status based on Puppet reports.
|
||||
|
||||
Web applications
|
||||
----------------
|
||||
|
||||
`AbiCloud <https://www.abiquo.com/>`__
|
||||
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.
|
||||
`Kimchi <https://kimchi-project.github.io/kimchi/>`__
|
||||
Kimchi is an HTML5 based management tool for KVM. It is designed to
|
||||
make it as easy as possible to get started with KVM and create your
|
||||
first guest. Kimchi manages KVM guests through libvirt. The
|
||||
management interface is accessed over the web using a browser that
|
||||
supports HTML5.
|
||||
`oVirt <https://ovirt.org/>`__
|
||||
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.
|
||||
`VMmanager <https://ispsystem.com/en/software/vmmanager>`__
|
||||
VMmanager is a software solution for virtualization management that
|
||||
can be used both for hosting virtual machines and building a cloud.
|
||||
VMmanager can manage not only one server, but a large cluster of
|
||||
hypervisors. It delivers a number of functions, such as live
|
||||
migration that allows for load balancing between cluster nodes,
|
||||
monitoring CPU, memory.
|
||||
`mist.io <https://mist.io/>`__
|
||||
Mist.io is an open source project and a service that can assist you
|
||||
in managing your virtual machines on a unified way, providing a
|
||||
simple interface for all of your infrastructure (multiple public
|
||||
cloud providers, OpenStack based public/private clouds, Docker
|
||||
servers, bare metal servers and now KVM hypervisors).
|
||||
`Ravada <https://ravada.upc.edu/>`__
|
||||
Ravada is an open source tool for managing Virtual Desktop
|
||||
Infrastructure (VDI). It is very easy to install and use. Following
|
||||
the documentation, you'll be ready to deploy virtual machines in
|
||||
minutes. The only requirements for the users are a Web browser and a
|
||||
lightweight remote viewer.
|
||||
`Virtlyst <https://github.com/cutelyst/Virtlyst>`__
|
||||
Virtlyst is an open source web application built with C++11, Cutelyst
|
||||
and Qt. It features:
|
||||
|
||||
- Low memory usage (around 5 MiB of RAM)
|
||||
- Look and feel easily customized with HTML templates that use the
|
||||
Django syntax
|
||||
- VNC/Spice console directly in the browser using websockets on the
|
||||
same HTTP port
|
||||
- Host and Domain statistics graphs (CPU, Memory, IO, Network)
|
||||
- Connect to multiple libvirtd instances (over local Unix domain
|
||||
socket, SSH, TCP and TLS)
|
||||
- Manage Storage Pools, Storage Volumes, Networks, Interfaces, and
|
||||
Secrets
|
||||
- Create and launch VMs
|
||||
- Configure VMs with easy panels or go pro and edit the VM's XML
|
||||
`Cockpit <https://cockpit-project.org/>`__
|
||||
Cockpit is a web-based graphical interface for servers. With
|
||||
`cockpit-machines <https://github.com/cockpit-project/cockpit-machines>`__
|
||||
it can create and manage virtual machines via libvirt.
|
||||
|
||||
Other
|
||||
-----
|
||||
|
||||
`Cuckoo Sandbox <https://cuckoosandbox.org/>`__
|
||||
Cuckoo Sandbox is a malware analysis system. You can throw any
|
||||
suspicious file at it and in a matter of seconds Cuckoo will provide
|
||||
you back some detailed results outlining what such file did when
|
||||
executed inside an isolated environment. And libvirt is one of the
|
||||
backends that can be used for the isolated environment.
|
||||
|
||||
.. |libvirt powered 96| image:: logos/logo-square-powered-96.png
|
||||
.. |libvirt powered 128| image:: logos/logo-square-powered-128.png
|
||||
.. |libvirt powered 192| image:: logos/logo-square-powered-192.png
|
||||
.. |libvirt powered 256| image:: logos/logo-square-powered-256.png
|
|
@ -0,0 +1,321 @@
|
|||
=========
|
||||
Audit log
|
||||
=========
|
||||
|
||||
.. contents::
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
A number of the libvirt virtualization drivers (QEMU/KVM and LXC)
|
||||
include support for logging details of important operations to the
|
||||
host's audit subsystem. This provides administrators / auditors with a
|
||||
canonical historical record of changes to virtual machines' /
|
||||
containers' lifecycle states and their configuration. On hosts which are
|
||||
running the Linux audit daemon, the logs will usually end up in
|
||||
``/var/log/audit/audit.log``
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The libvirt audit integration is enabled by default on any host which
|
||||
has the Linux audit subsystem active, and disabled otherwise. It is
|
||||
possible to alter this behaviour in the ``/etc/libvirt/libvirtd.conf``
|
||||
configuration file, via the ``audit_level`` parameter
|
||||
|
||||
- ``audit_level=0`` - libvirt auditing is disabled regardless of host
|
||||
audit subsystem enablement.
|
||||
- ``audit_level=1`` - libvirt auditing is enabled if the host audit
|
||||
subsystem is enabled, otherwise it is disabled. This is the default
|
||||
behaviour.
|
||||
- ``audit_level=2`` - libvirt auditing is enabled regardless of host
|
||||
audit subsystem enablement. If the host audit subsystem is disabled,
|
||||
then libvirtd will refuse to complete startup and exit with an error.
|
||||
|
||||
In addition to have formal messages sent to the audit subsystem it is
|
||||
possible to tell libvirt to inject messages into its own logging layer.
|
||||
This will result in messages ending up in the systemd journal or
|
||||
``/var/log/libvirt/libvirtd.log`` on non-systemd hosts. This is disabled
|
||||
by default, but can be requested by setting the ``audit_logging=1``
|
||||
configuration parameter in the same file mentioned above.
|
||||
|
||||
Message types
|
||||
-------------
|
||||
|
||||
Libvirt defines three core audit message types each of which will be
|
||||
described below. There are a number of common fields that will be
|
||||
reported for all message types.
|
||||
|
||||
``pid``
|
||||
Process ID of the libvirtd daemon generating the audit record.
|
||||
``uid``
|
||||
User ID of the libvirtd daemon process generating the audit record.
|
||||
``subj``
|
||||
Security context of the libvirtd daemon process generating the audit
|
||||
record.
|
||||
``msg``
|
||||
String containing a list of key=value pairs specific to the type of
|
||||
audit record being reported.
|
||||
|
||||
Some fields in the ``msg`` string are common to audit records
|
||||
|
||||
``virt``
|
||||
Type of virtualization driver used. One of ``qemu`` or ``lxc``
|
||||
``vm``
|
||||
Host driver unique name of the guest
|
||||
``uuid``
|
||||
Globally unique identifier for the guest
|
||||
``exe``
|
||||
Path of the libvirtd daemon
|
||||
``hostname``
|
||||
Currently unused
|
||||
``addr``
|
||||
Currently unused
|
||||
``terminal``
|
||||
Currently unused
|
||||
``res``
|
||||
Result of the action, either ``success`` or ``failed``
|
||||
|
||||
VIRT_CONTROL
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Reports change in the lifecycle state of a virtual machine. The ``msg``
|
||||
field will include the following sub-fields
|
||||
|
||||
``op``
|
||||
Type of operation performed. One of ``start``, ``stop`` or ``init``
|
||||
``reason``
|
||||
The reason which caused the operation to happen
|
||||
``vm-pid``
|
||||
ID of the primary/leading process associated with the guest
|
||||
``init-pid``
|
||||
ID of the ``init`` process in a container. Only if ``op=init`` and
|
||||
``virt=lxc``
|
||||
``pid-ns``
|
||||
Namespace ID of the ``init`` process in a container. Only if
|
||||
``op=init`` and ``virt=lxc``
|
||||
|
||||
VIRT_MACHINE_ID
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Reports the association of a security context with a guest. The ``msg``
|
||||
field will include the following sub-fields
|
||||
|
||||
``model``
|
||||
The security driver type. One of ``selinux`` or ``apparmor``
|
||||
``vm-ctx``
|
||||
Security context for the guest process
|
||||
``img-ctx``
|
||||
Security context for the guest disk images and other assigned host
|
||||
resources
|
||||
|
||||
VIRT_RESOURCE
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Reports the usage of a host resource by a guest. The fields include will
|
||||
vary according to the type of device being reported. When the guest is
|
||||
initially booted records will be generated for all assigned resources.
|
||||
If any changes are made to the running guest configuration, for example
|
||||
hotplug devices, or adjust resources allocation, further records will be
|
||||
generated.
|
||||
|
||||
Virtual CPU
|
||||
^^^^^^^^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``vcpu``
|
||||
``old-vcpu``
|
||||
Original vCPU count, or 0
|
||||
``new-vcpu``
|
||||
Updated vCPU count
|
||||
|
||||
Memory
|
||||
^^^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``mem``
|
||||
``old-mem``
|
||||
Original memory size in bytes, or 0
|
||||
``new-mem``
|
||||
Updated memory size in bytes
|
||||
|
||||
Disk
|
||||
^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``disk``
|
||||
``old-disk``
|
||||
Original host file or device path acting as the disk backing file
|
||||
``new-disk``
|
||||
Updated host file or device path acting as the disk backing file
|
||||
|
||||
Network interface
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``net``
|
||||
``old-net``
|
||||
Original MAC address of the guest network interface
|
||||
``new-net``
|
||||
Updated MAC address of the guest network interface
|
||||
|
||||
If there is a host network interface associated with the guest NIC then
|
||||
further records may be generated
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``net``
|
||||
``net``
|
||||
MAC address of the host network interface
|
||||
``rdev``
|
||||
Name of the host network interface
|
||||
|
||||
Filesystem
|
||||
^^^^^^^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``fs``
|
||||
``old-fs``
|
||||
Original host directory, file or device path backing the filesystem
|
||||
``new-fs``
|
||||
Updated host directory, file or device path backing the filesystem
|
||||
|
||||
Host device
|
||||
^^^^^^^^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``hostdev`` or ``dev``
|
||||
``dev``
|
||||
The unique bus identifier of the USB, PCI or SCSI device, if
|
||||
``resrc=dev``
|
||||
``disk``
|
||||
The path of the block device assigned to the guest, if
|
||||
``resrc=hostdev``
|
||||
``chardev``
|
||||
The path of the character device assigned to the guest, if
|
||||
``resrc=hostdev``
|
||||
|
||||
TPM
|
||||
^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``tpm`` or ``tpm-emulator``
|
||||
``device``
|
||||
The path of the host TPM device assigned to the guest
|
||||
|
||||
RNG
|
||||
^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``rng``
|
||||
``old-rng``
|
||||
Original path of the host entropy source for the RNG
|
||||
``new-rng``
|
||||
Updated path of the host entropy source for the RNG
|
||||
|
||||
console/serial/parallel/channel
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``chardev``
|
||||
``old-chardev``
|
||||
Original path of the backing character device for given emulated
|
||||
device
|
||||
``new-chardev``
|
||||
Updated path of the backing character device for given emulated
|
||||
device
|
||||
|
||||
smartcard
|
||||
^^^^^^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``smartcard``
|
||||
``old-smartcard``
|
||||
Original path of the backing character device, certificate store or
|
||||
"nss-smartcard-device" for host smartcard passthrough.
|
||||
``new-smartcard``
|
||||
Updated path of the backing character device, certificate store or
|
||||
"nss-smartcard-device" for host smartcard passthrough.
|
||||
|
||||
Redirected device
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``redir``
|
||||
``bus``
|
||||
The bus type, only ``usb`` allowed
|
||||
``device``
|
||||
The device type, only ``USB redir`` allowed
|
||||
|
||||
Control group
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``cgroup``
|
||||
``cgroup``
|
||||
The name of the cgroup controller
|
||||
|
||||
Shared memory
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The ``msg`` field will include the following sub-fields
|
||||
|
||||
``resrc``
|
||||
The type of resource assigned. Set to ``shmem``
|
||||
``reason``
|
||||
The reason which caused the resource to be assigned to happen
|
||||
``size``
|
||||
The size of the shared memory region
|
||||
``shmem``
|
||||
Name of the shared memory region
|
||||
``source``
|
||||
Path of the backing character device for given emulated device
|
|
@ -0,0 +1,324 @@
|
|||
=========================
|
||||
Connection authentication
|
||||
=========================
|
||||
|
||||
.. contents::
|
||||
|
||||
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. Once authenticated, libvirt can apply
|
||||
fine grained `access control <acl.html>`_ to the operations
|
||||
performed by a client.
|
||||
|
||||
Client configuration
|
||||
====================
|
||||
|
||||
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:
|
||||
|
||||
* The file path specified by the ``$LIBVIRT_AUTH_FILE`` environment
|
||||
variable.
|
||||
* The file path specified by the ``authfile=/some/file`` URI
|
||||
query parameter
|
||||
* The file ``$XDG_CONFIG_HOME/libvirt/auth.conf``
|
||||
* The file ``/etc/libvirt/auth.conf``
|
||||
|
||||
The auth configuration file uses the traditional ``.ini``
|
||||
style syntax. There are two types of groups that can be present in
|
||||
the config. First there are one or more ``credential``
|
||||
sets, which provide the actual authentication credentials. The keys
|
||||
within the group may be:
|
||||
|
||||
* ``username``: the user login name to act as. This
|
||||
is relevant for ESX, Xen, HyperV and SSH, but probably not
|
||||
the one you want for libvirtd with SASL.
|
||||
* ``authname``: the name to authorize as. This is
|
||||
what is commonly required for libvirtd with SASL.
|
||||
* ``password``: the secret password.
|
||||
* ``realm``: the domain realm for SASL, mostly unused.
|
||||
|
||||
Each set of credentials has a name, which is part of the group
|
||||
entry name. Overall the syntax is
|
||||
|
||||
::
|
||||
|
||||
[credentials-$NAME]
|
||||
credname1=value1
|
||||
credname2=value2
|
||||
|
||||
|
||||
For example, to define two sets of credentials used for production
|
||||
and test machines, using libvirtd, and a further ESX server for
|
||||
development:
|
||||
|
||||
::
|
||||
|
||||
[credentials-test]
|
||||
authname=fred
|
||||
password=123456
|
||||
|
||||
[credentials-prod]
|
||||
authname=bar
|
||||
password=letmein
|
||||
|
||||
[credentials-dev]
|
||||
username=joe
|
||||
password=hello
|
||||
|
||||
[credentials-defgrp]
|
||||
username=defuser
|
||||
password=defpw
|
||||
|
||||
The second set of groups provide mappings of credentials to
|
||||
specific machine services. The config file group names compromise
|
||||
the service type and host:
|
||||
|
||||
::
|
||||
|
||||
[auth-$SERVICE-$HOSTNAME]
|
||||
credentials=$CREDENTIALS
|
||||
|
||||
For example, following the previous example, here is how to
|
||||
map some machines. For convenience libvirt supports a default
|
||||
mapping of credentials to machines:
|
||||
|
||||
::
|
||||
|
||||
[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-libvirt-default]
|
||||
credentials=defgrp
|
||||
|
||||
[auth-esx-dev1.example.com]
|
||||
credentials=dev
|
||||
|
||||
[auth-esx-default]
|
||||
credentials=defgrp
|
||||
|
||||
The following service types are known to libvirt:
|
||||
|
||||
* ``esx`` - used for connections to an ESX or VirtualCenter server
|
||||
* ``hyperv`` - used for connections to an HyperV server
|
||||
* ``libvirt`` - used for connections to a libvirtd
|
||||
server, which is configured with SASL auth
|
||||
* ``ssh`` - used for connections to a remote QEMU driver over SSH
|
||||
|
||||
|
||||
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
|
||||
|
||||
Server configuration
|
||||
====================
|
||||
|
||||
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
|
||||
``/etc/libvirt/libvirtd.conf``. Each of the libvirt sockets can
|
||||
have its authentication mechanism configured independently. There is
|
||||
currently a choice of ``none``, ``polkit``, and ``sasl``.
|
||||
The SASL scheme can be further configured to choose between a large
|
||||
number of different mechanisms.
|
||||
|
||||
UNIX socket permissions/group
|
||||
-----------------------------
|
||||
|
||||
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 ``root`` user to connect. The read-only socket will
|
||||
be open access (mode 0777) to allow any user to connect.
|
||||
|
||||
To allow non-root users greater access, the ``libvirtd.conf`` file
|
||||
can be edited to change the permissions via the ``unix_sock_rw_perms``,
|
||||
config parameter and to set a user group via the ``unix_sock_group``
|
||||
parameter. For example, setting the former to mode ``0770`` and the
|
||||
latter ``wheel`` would let any user in the wheel group connect to
|
||||
the libvirt daemon.
|
||||
|
||||
UNIX socket PolicyKit auth
|
||||
--------------------------
|
||||
|
||||
If libvirt contains support for PolicyKit, then access control options are
|
||||
more advanced. The ``auth_unix_rw`` parameter will default to
|
||||
``polkit``, and the file permissions will default to ``0777``
|
||||
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 ``sudo``
|
||||
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.
|
||||
|
||||
The default policy can be overridden by creating a new policy file in the
|
||||
``/etc/polkit-1/rules.d`` directory. Information on the options
|
||||
available can be found by reading the ``polkit(8)`` man page. The
|
||||
two libvirt actions are named ``org.libvirt.unix.manage`` for full
|
||||
management access, and ``org.libvirt.unix.monitor`` for read-only
|
||||
access.
|
||||
|
||||
As an example, creating ``/etc/polkit-1/rules.d/80-libvirt-manage.rules``
|
||||
with the following gives the user ``fred`` full management access
|
||||
when accessing from an active local session:
|
||||
|
||||
::
|
||||
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "org.libvirt.unix.manage" &&
|
||||
subject.local && subject.active && subject.user == "fred") {
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
});
|
||||
|
||||
Older versions of PolicyKit used policy files ending with .pkla in the
|
||||
local override directory ``/etc/polkit-1/localauthority/50-local.d/``.
|
||||
Compatibility with this older format is provided by
|
||||
`polkit-pkla-compat <https://pagure.io/polkit-pkla-compat>`_. As an
|
||||
example, this gives the user ``fred`` full management access:
|
||||
|
||||
::
|
||||
|
||||
[Allow fred libvirt management permissions]
|
||||
Identity=unix-user:fred
|
||||
Action=org.libvirt.unix.manage
|
||||
ResultAny=yes
|
||||
ResultInactive=yes
|
||||
ResultActive=yes
|
||||
|
||||
SASL pluggable authentication
|
||||
-----------------------------
|
||||
|
||||
Libvirt integrates with the ``cyrus-sasl`` library to provide a pluggable
|
||||
authentication system using the SASL protocol. SASL can be used in combination
|
||||
with libvirtd's TLS or TCP socket listeners. When used with the TCP listener,
|
||||
the SASL mechanism is required to provide session encryption in addition to
|
||||
authentication. Only a very few SASL mechanisms are able to do this, and of
|
||||
those that can do it, only the ``GSSAPI`` plugin is considered acceptably secure
|
||||
by modern standards. ``GSSAPI`` is the default mechanism enabled in the libvirt
|
||||
SASL configuration. It uses the Kerberos v5 authentication protocol underneath,
|
||||
and assuming the Kerberos client/server are configured with modern ciphers
|
||||
(AES), it provides strong session encryption capabilities. All other SASL
|
||||
mechanisms should only be used with the libvirtd TLS or UNIX socket listeners.
|
||||
|
||||
Username/password auth
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To provide a simple username/password auth scheme on the libvirt UNIX socket
|
||||
or TLS listeners, however, it is possible to use the ``SCRAM`` mechanism, in its
|
||||
``SCRAM-SHA-256`` variant. The ``auth_unix_ro``, ``auth_unix_rw``, ``auth_tls``
|
||||
config params in ``libvirtd.conf`` can be used to turn on SASL auth in these
|
||||
listeners.
|
||||
|
||||
Since the libvirt SASL config file defaults to using ``GSSAPI`` (Kerberos), a
|
||||
config change is required to enable plain password auth. This is done by
|
||||
editing ``/etc/sasl2/libvirt.conf`` to set the ``mech_list``
|
||||
parameter to ``scram-sha-256``.
|
||||
|
||||
**Note:** previous versions of libvirt suggested ``DIGEST-MD5`` and
|
||||
``SCRAM-SHA-1`` mechanisms. **Use of these is strongly discouraged as they are
|
||||
not considered secure by modern standards.** It is possible to replace them with
|
||||
use of ``SCRAM-SHA-256``, while still using the same password database.
|
||||
|
||||
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 ``saslpasswd2`` command. When running this command it is
|
||||
important to tell it that the appname is ``libvirt``. As an example, to add
|
||||
a user ``fred``, run
|
||||
|
||||
::
|
||||
|
||||
# saslpasswd2 -a libvirt fred
|
||||
Password: xxxxxx
|
||||
Again (for verification): xxxxxx
|
||||
|
||||
To see a list of all accounts the ``sasldblistusers2`` command can be used.
|
||||
This command expects to be given the path to the libvirt user database, which
|
||||
is kept in ``/etc/libvirt/passwd.db``
|
||||
|
||||
::
|
||||
|
||||
# sasldblistusers2 -f /etc/libvirt/passwd.db
|
||||
fred@t60wlan.home.berrange.com: userPassword
|
||||
|
||||
Finally, to disable a user's access, the ``saslpasswd2`` command can be used
|
||||
again:
|
||||
|
||||
::
|
||||
|
||||
# saslpasswd2 -a libvirt -d fred
|
||||
|
||||
**Note: the SASL ``passwd.db`` file stores passwords in clear text, so
|
||||
care should be taken not to let its contents be disclosed to unauthorized
|
||||
users.**
|
||||
|
||||
GSSAPI/Kerberos auth
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The plain TCP listener of the libvirt daemon defaults to using SASL for
|
||||
authentication. The libvirt SASL config also defaults to ``GSSAPI``, so there
|
||||
is no need to edit the SASL config when using ``GSSAPI``. If the libvirtd TLS
|
||||
or UNIX listeners are used, then the Kerberos session encryption will be
|
||||
disabled since it is not required in these scenarios - only the plain TCP
|
||||
listener needs encryption.
|
||||
|
||||
Some operating systems do not install the SASL kerberos plugin by default. It
|
||||
may be necessary to install a sub-package such as ``cyrus-sasl-gssapi``.
|
||||
To check whether the Kerberos plugin is installed run the ``pluginviewer``
|
||||
program and verify that ``gssapi`` is listed, e.g.:
|
||||
|
||||
::
|
||||
|
||||
# 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
|
||||
|
||||
Next it is necessary for the administrator of the Kerberos realm to
|
||||
issue a principal for the libvirt server. There needs to be one
|
||||
principal per host running the libvirt daemon. The principal should be
|
||||
named ``libvirt/full.hostname@KERBEROS.REALM``. This is
|
||||
typically done by running the ``kadmin.local`` command on the
|
||||
Kerberos server, though some Kerberos servers have alternate ways of
|
||||
setting up service principals. Once created, the principal should be
|
||||
exported to a keytab, copied to the host running the libvirt daemon
|
||||
and placed in ``/etc/libvirt/krb5.tab``
|
||||
|
||||
::
|
||||
|
||||
# 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
|
||||
|
||||
Any client application wishing to connect to a Kerberos enabled libvirt server
|
||||
merely needs to run ``kinit`` to gain a user principal. This may well
|
||||
be done automatically when a user logs into a desktop session, if PAM is set up
|
||||
to authenticate against Kerberos.
|
|
@ -0,0 +1,37 @@
|
|||
==============
|
||||
Best practices
|
||||
==============
|
||||
|
||||
These are a few guidelines to keep in mind when submitting patches
|
||||
to libvirt: following them will maximise the chance of your patches
|
||||
being reviewed in a timely manner and being accepted into libvirt
|
||||
with minimal back-and-forth.
|
||||
|
||||
- Discuss any large changes on the mailing list first. Post
|
||||
patches early and listen to feedback.
|
||||
|
||||
- In your commit message, make the summary line reasonably short
|
||||
(60 characters is typical), followed by a blank line, followed
|
||||
by any longer description of why your patch makes sense. If the
|
||||
patch fixes a regression, and you know what commit introduced
|
||||
the problem, mentioning that is useful. If the patch resolves a
|
||||
upstream bug reported in GitLab, put "Fixes: #NNN" in the commit
|
||||
message. For a downstream bug, mention the URL of the bug instead.
|
||||
In both cases also summarize the issue rather than making all
|
||||
readers follow the link. You can use 'git shortlog -30' to get
|
||||
an idea of typical summary lines.
|
||||
|
||||
- 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. Moreover, please keep in mind that it's required to
|
||||
be able to compile cleanly (**including** ``ninja test``) after
|
||||
each patch. A feature does not have to work until the end of a
|
||||
series, but intermediate patches must compile and not cause
|
||||
test-suite failures (this is to preserve the usefulness of
|
||||
``git bisect``, among other things).
|
||||
|
||||
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 <https://people.redhat.com/rjones/how-to-supply-code-to-open-source-projects/>`__.
|
|
@ -0,0 +1,62 @@
|
|||
========================================================
|
||||
Bindings for other languages and integration API modules
|
||||
========================================================
|
||||
|
||||
.. contents::
|
||||
|
||||
Libvirt supports C and C++ directly, and has bindings available for
|
||||
other languages:
|
||||
|
||||
- **C#**: Arnaud Champion develops `C# bindings <csharp.html>`__.
|
||||
|
||||
- **Go**: Daniel Berrange develops `Go
|
||||
bindings <https://pkg.go.dev/libvirt.org/go/libvirt>`__.
|
||||
|
||||
- **Java**: Daniel Veillard develops `Java bindings <java.html>`__.
|
||||
|
||||
- **OCaml**: Richard Jones develops `OCaml
|
||||
bindings <https://libvirt.org/ocaml/>`__.
|
||||
|
||||
- **Perl**: Daniel Berrange develops `Perl
|
||||
bindings <https://search.cpan.org/dist/Sys-Virt/>`__.
|
||||
|
||||
- **PHP**: Radek Hladik started developing `PHP
|
||||
bindings <https://libvirt.org/php>`__ in 2010.
|
||||
|
||||
In February 2011 the binding development has been moved to the
|
||||
libvirt.org website as libvirt-php project.
|
||||
|
||||
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 `PHP
|
||||
bindings <https://libvirt.org/php>`__ site.
|
||||
|
||||
- **Python**: Libvirt's python bindings are split to a separate
|
||||
`package <https://gitlab.com/libvirt/libvirt-python>`__ since version
|
||||
1.2.0, older versions came with direct support for the Python
|
||||
language.
|
||||
|
||||
If your libvirt is installed as packages, rather than compiled by you
|
||||
from source code, ensure you have the appropriate package installed.
|
||||
|
||||
This is named **libvirt-python** on RHEL/Fedora,
|
||||
`python-libvirt <https://packages.ubuntu.com/search?keywords=python-libvirt>`__
|
||||
on Ubuntu, and may be named differently on others.
|
||||
|
||||
For usage information, see the `Python API bindings <python.html>`__
|
||||
page.
|
||||
|
||||
- **Ruby**: Chris Lalancette develops `Ruby
|
||||
bindings <https://libvirt.org/ruby/>`__.
|
||||
|
||||
Integration API modules:
|
||||
|
||||
- **D-Bus**: Pavel Hrdina develops `D-Bus API <dbus.html>`__.
|
||||
|
||||
For information on using libvirt on **Windows** `please see the Windows
|
||||
support page <windows.html>`__.
|
||||
|
||||
Support, requests or help for libvirt bindings are welcome on the
|
||||
`mailing list <https://listman.redhat.com/mailman/listinfo/libvir-list/>`__,
|
||||
as usual try to provide enough background information and make sure you
|
||||
use recent version, see the `help page <bugs.html>`__.
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<TileColor>#b91d47</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
|
@ -0,0 +1,120 @@
|
|||
=============
|
||||
Bug reporting
|
||||
=============
|
||||
|
||||
.. contents::
|
||||
|
||||
Security Issues
|
||||
---------------
|
||||
|
||||
If you think that an issue with libvirt may have security implications, **please
|
||||
do not** publicly report it in the bug tracker, mailing lists, or irc. Libvirt
|
||||
has `a dedicated process for handling (potential) security
|
||||
issues <securityprocess.html>`__ that should be used instead. So if your issue
|
||||
has security implications, ignore the rest of this page and follow the `security
|
||||
process <securityprocess.html>`__ instead.
|
||||
|
||||
Bug Tracking
|
||||
------------
|
||||
|
||||
If you are using libvirt binaries from a Linux distribution check below for
|
||||
distribution specific bug reporting policies first.
|
||||
|
||||
General libvirt bug reports
|
||||
---------------------------
|
||||
|
||||
Bugs in upstream libvirt code should be reported as issues in the appropriate
|
||||
`project on GitLab. <https://gitlab.com/libvirt>`__ Before submitting a ticket,
|
||||
check the existing tickets to see if the bug/feature is already tracked.
|
||||
|
||||
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 frequent attention to issues, so after you file a bug, asking questions and
|
||||
submitting patches on `the libvirt mailing lists <contact.html>`__ 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!
|
||||
|
||||
If you decide to write code, though, before you begin please read the
|
||||
`contributor guidelines <hacking.html>`__, 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.
|
||||
|
||||
- `View libvirt.git tickets <https://gitlab.com/libvirt/libvirt/-/issues>`__
|
||||
- `New libvirt.git ticket <https://gitlab.com/libvirt/libvirt/-/issues/new>`__
|
||||
|
||||
Note bugs in language bindings and other sub-projects should be reported to
|
||||
their corresponding git repository rather than the main libvirt.git linked
|
||||
above.
|
||||
|
||||
Linux Distribution specific bug reports
|
||||
---------------------------------------
|
||||
|
||||
- If you are using binaries from **Fedora**, enter tickets against the
|
||||
``Fedora`` product and the ``libvirt`` component.
|
||||
|
||||
- `View Fedora libvirt
|
||||
tickets <https://bugzilla.redhat.com/buglist.cgi?component=libvirt&product=Fedora>`__
|
||||
- `New Fedora libvirt
|
||||
ticket <https://bugzilla.redhat.com/bugzilla/enter_bug.cgi?product=Fedora&component=libvirt>`__
|
||||
|
||||
- If you are using binaries from **Red Hat Enterprise Linux**, enter tickets
|
||||
against the Red Hat Enterprise Linux product that you're using (e.g., Red Hat
|
||||
Enterprise Linux 6) and the ``libvirt`` component. Red Hat bugzilla has
|
||||
`additional guidance <https://bugzilla.redhat.com>`__ about getting support
|
||||
if you are a Red Hat customer.
|
||||
|
||||
- If you are using binaries from another Linux distribution first follow their
|
||||
own bug reporting guidelines.
|
||||
|
||||
- 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.
|
||||
|
||||
How to file high quality bug reports
|
||||
------------------------------------
|
||||
|
||||
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:
|
||||
|
||||
- The version number of the libvirt build, or SHA1 of the GIT commit
|
||||
- The hardware architecture being used
|
||||
- The name of the hypervisor (Xen, QEMU, KVM)
|
||||
- The XML config of the guest domain if relevant
|
||||
- For Xen hypervisor, the domain logfiles from /var/log/xen and
|
||||
/var/log/libvirt/libxl
|
||||
- For QEMU/KVM, the domain logfile from /var/log/libvirt/qemu
|
||||
|
||||
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 information 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.
|
||||
|
||||
| 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, similarly to a normal program provide the "bt" backtrace
|
||||
information to where gdb will have stopped.
|
||||
| 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:
|
||||
|
||||
::
|
||||
|
||||
# ps -o etime,pid `pgrep libvirt`
|
||||
... note the process id from the output
|
||||
# gdb /usr/sbin/libvirtd
|
||||
.... some information about gdb and loading debug data
|
||||
(gdb) attach $the_daemon_process_id
|
||||
....
|
||||
(gdb) thread apply all bt
|
||||
.... information to attach to the bug
|
||||
(gdb)
|
|
@ -0,0 +1,364 @@
|
|||
==================================
|
||||
Control Groups Resource Management
|
||||
==================================
|
||||
|
||||
.. contents::
|
||||
|
||||
The QEMU and LXC drivers make use of the Linux "Control Groups" facility for
|
||||
applying resource management to their virtual machines and containers.
|
||||
|
||||
Required controllers
|
||||
--------------------
|
||||
|
||||
The control groups filesystem supports multiple "controllers". By default the
|
||||
init system (such as systemd) should mount all controllers compiled into the
|
||||
kernel at ``/sys/fs/cgroup/$CONTROLLER-NAME``. Libvirt will never attempt to
|
||||
mount any controllers itself, merely detect where they are mounted.
|
||||
|
||||
The QEMU driver is capable of using the ``cpuset``, ``cpu``, ``cpuacct``,
|
||||
``memory``, ``blkio`` and ``devices`` controllers. None of them are compulsory.
|
||||
If any controller is not mounted, the resource management APIs which use it will
|
||||
cease to operate. It is possible to explicitly turn off use of a controller,
|
||||
even when mounted, via the ``/etc/libvirt/qemu.conf`` configuration file.
|
||||
|
||||
The LXC driver is capable of using the ``cpuset``, ``cpu``, ``cpuacct``,
|
||||
``freezer``, ``memory``, ``blkio`` and ``devices`` controllers. The ``cpuacct``,
|
||||
``devices`` and ``memory`` controllers are compulsory. Without them mounted, no
|
||||
containers can be started. If any of the other controllers are not mounted, the
|
||||
resource management APIs which use them will cease to operate.
|
||||
|
||||
Current cgroups layout
|
||||
----------------------
|
||||
|
||||
As of libvirt 1.0.5 or later, the cgroups layout created by libvirt has been
|
||||
simplified, in order to facilitate the setup of resource control policies by
|
||||
administrators / management applications. The new layout is based on the
|
||||
concepts of "partitions" and "consumers". A "consumer" is a cgroup which holds
|
||||
the processes for a single virtual machine or container. A "partition" is a
|
||||
cgroup which does not contain any processes, but can have resource controls
|
||||
applied. A "partition" will have zero or more child directories which may be
|
||||
either "consumer" or "partition".
|
||||
|
||||
As of libvirt 1.1.1 or later, the cgroups layout will have some slight
|
||||
differences when running on a host with systemd 205 or later. The overall tree
|
||||
structure is the same, but there are some differences in the naming conventions
|
||||
for the cgroup directories. Thus the following docs split in two, one describing
|
||||
systemd hosts and the other non-systemd hosts.
|
||||
|
||||
Systemd cgroups integration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
On hosts which use systemd, each consumer maps to a systemd scope unit, while
|
||||
partitions map to a system slice unit.
|
||||
|
||||
Systemd scope naming
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The systemd convention is for the scope name of virtual machines / containers to
|
||||
be of the general format ``machine-$NAME.scope``. Libvirt forms the ``$NAME``
|
||||
part of this by concatenating the driver type with the id and truncated name of
|
||||
the guest, and then escaping any systemd reserved characters. So for a guest
|
||||
``demo`` running under the ``lxc`` driver, we get a ``$NAME`` of
|
||||
``lxc-12345-demo`` which when escaped is ``lxc\x2d12345\x2ddemo``. So the
|
||||
complete scope name is ``machine-lxc\x2d12345\x2ddemo.scope``. The scope names
|
||||
map directly to the cgroup directory names.
|
||||
|
||||
Systemd slice naming
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The systemd convention for slice naming is that a slice should include the name
|
||||
of all of its parents prepended on its own name. So for a libvirt partition
|
||||
``/machine/engineering/testing``, the slice name will be
|
||||
``machine-engineering-testing.slice``. Again the slice names map directly to the
|
||||
cgroup directory names. Systemd creates three top level slices by default,
|
||||
``system.slice`` ``user.slice`` and ``machine.slice``. All virtual machines or
|
||||
containers created by libvirt will be associated with ``machine.slice`` by
|
||||
default.
|
||||
|
||||
Systemd cgroup layout
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Given this, a possible systemd cgroups layout involving 3 qemu guests, 3 lxc
|
||||
containers and 3 custom child slices, would be:
|
||||
|
||||
::
|
||||
|
||||
$ROOT
|
||||
|
|
||||
+- system.slice
|
||||
| |
|
||||
| +- libvirtd.service
|
||||
|
|
||||
+- machine.slice
|
||||
|
|
||||
+- machine-qemu\x2d1\x2dvm1.scope
|
||||
| |
|
||||
| +- libvirt
|
||||
| |
|
||||
| +- emulator
|
||||
| +- vcpu0
|
||||
| +- vcpu1
|
||||
|
|
||||
+- machine-qemu\x2d2\x2dvm2.scope
|
||||
| |
|
||||
| +- libvirt
|
||||
| |
|
||||
| +- emulator
|
||||
| +- vcpu0
|
||||
| +- vcpu1
|
||||
|
|
||||
+- machine-qemu\x2d3\x2dvm3.scope
|
||||
| |
|
||||
| +- libvirt
|
||||
| |
|
||||
| +- emulator
|
||||
| +- vcpu0
|
||||
| +- vcpu1
|
||||
|
|
||||
+- machine-engineering.slice
|
||||
| |
|
||||
| +- machine-engineering-testing.slice
|
||||
| | |
|
||||
| | +- machine-lxc\x2d11111\x2dcontainer1.scope
|
||||
| |
|
||||
| +- machine-engineering-production.slice
|
||||
| |
|
||||
| +- machine-lxc\x2d22222\x2dcontainer2.scope
|
||||
|
|
||||
+- machine-marketing.slice
|
||||
|
|
||||
+- machine-lxc\x2d33333\x2dcontainer3.scope
|
||||
|
||||
Prior libvirt 7.1.0 the topology doesn't have extra ``libvirt`` directory.
|
||||
|
||||
Non-systemd cgroups layout
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
On hosts which do not use systemd, each consumer has a corresponding cgroup
|
||||
named ``$VMNAME.libvirt-{qemu,lxc}``. Each consumer is associated with exactly
|
||||
one partition, which also have a corresponding cgroup usually named
|
||||
``$PARTNAME.partition``. The exceptions to this naming rule is the top level
|
||||
default partition for virtual machines and containers ``/machine``.
|
||||
|
||||
Given this, a possible non-systemd cgroups layout involving 3 qemu guests, 3 lxc
|
||||
containers and 2 custom child slices, would be:
|
||||
|
||||
::
|
||||
|
||||
$ROOT
|
||||
|
|
||||
+- machine
|
||||
|
|
||||
+- qemu-1-vm1.libvirt-qemu
|
||||
| |
|
||||
| +- emulator
|
||||
| +- vcpu0
|
||||
| +- vcpu1
|
||||
|
|
||||
+- qeme-2-vm2.libvirt-qemu
|
||||
| |
|
||||
| +- emulator
|
||||
| +- vcpu0
|
||||
| +- vcpu1
|
||||
|
|
||||
+- qemu-3-vm3.libvirt-qemu
|
||||
| |
|
||||
| +- emulator
|
||||
| +- vcpu0
|
||||
| +- vcpu1
|
||||
|
|
||||
+- engineering.partition
|
||||
| |
|
||||
| +- testing.partition
|
||||
| | |
|
||||
| | +- lxc-11111-container1.libvirt-lxc
|
||||
| |
|
||||
| +- production.partition
|
||||
| |
|
||||
| +- lxc-22222-container2.libvirt-lxc
|
||||
|
|
||||
+- marketing.partition
|
||||
|
|
||||
+- lxc-33333-container3.libvirt-lxc
|
||||
|
||||
Using custom partitions
|
||||
-----------------------
|
||||
|
||||
If there is a need to apply resource constraints to groups of virtual machines
|
||||
or containers, then the single default partition ``/machine`` may not be
|
||||
sufficiently flexible. The administrator may wish to sub-divide the default
|
||||
partition, for example into "testing" and "production" partitions, and then
|
||||
assign each guest to a specific sub-partition. This is achieved via a small
|
||||
element addition to the guest domain XML config, just below the main ``domain``
|
||||
element
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<resource>
|
||||
<partition>/machine/production</partition>
|
||||
</resource>
|
||||
...
|
||||
|
||||
Note that the partition names in the guest XML are using a generic naming
|
||||
format, not the low level naming convention required by the underlying host OS.
|
||||
That is, you should not include any of the ``.partition`` or ``.slice`` suffixes
|
||||
in the XML config. Given a partition name ``/machine/production``, libvirt will
|
||||
automatically apply the platform specific translation required to get
|
||||
``/machine/production.partition`` (non-systemd) or
|
||||
``/machine.slice/machine-production.slice`` (systemd) as the underlying cgroup
|
||||
name
|
||||
|
||||
Libvirt will not auto-create the cgroups directory to back this partition. In
|
||||
the future, libvirt / virsh will provide APIs / commands to create custom
|
||||
partitions, but currently this is left as an exercise for the administrator.
|
||||
|
||||
**Note:** the ability to place guests in custom partitions is only available
|
||||
with libvirt >= 1.0.5, using the new cgroup layout. The legacy cgroups layout
|
||||
described later in this document did not support customization per guest.
|
||||
|
||||
Creating custom partitions (systemd)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Given the XML config above, the admin on a systemd based host would need to
|
||||
create a unit file ``/etc/systemd/system/machine-production.slice``
|
||||
|
||||
::
|
||||
|
||||
# cat > /etc/systemd/system/machine-testing.slice <<EOF
|
||||
[Unit]
|
||||
Description=VM testing slice
|
||||
Before=slices.target
|
||||
Wants=machine.slice
|
||||
EOF
|
||||
# systemctl start machine-testing.slice
|
||||
|
||||
Creating custom partitions (non-systemd)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Given the XML config above, the admin on a non-systemd based host would need to
|
||||
create a cgroup named '/machine/production.partition'
|
||||
|
||||
::
|
||||
|
||||
# cd /sys/fs/cgroup
|
||||
# for i in blkio cpu,cpuacct cpuset devices freezer memory net_cls perf_event
|
||||
do
|
||||
mkdir $i/machine/production.partition
|
||||
done
|
||||
# for i in cpuset.cpus cpuset.mems
|
||||
do
|
||||
cat cpuset/machine/$i > cpuset/machine/production.partition/$i
|
||||
done
|
||||
|
||||
Resource management APIs/commands
|
||||
---------------------------------
|
||||
|
||||
Since libvirt aims to provide an API which is portable across hypervisors, the
|
||||
concept of cgroups is not exposed directly in the API or XML configuration. It
|
||||
is considered to be an internal implementation detail. Instead libvirt provides
|
||||
a set of APIs for applying resource controls, which are then mapped to
|
||||
corresponding cgroup tunables
|
||||
|
||||
Scheduler tuning
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Parameters from the "cpu" controller are exposed via the ``schedinfo`` command
|
||||
in virsh.
|
||||
|
||||
::
|
||||
|
||||
# virsh schedinfo demo
|
||||
Scheduler : posix
|
||||
cpu_shares : 1024
|
||||
vcpu_period : 100000
|
||||
vcpu_quota : -1
|
||||
emulator_period: 100000
|
||||
emulator_quota : -1
|
||||
|
||||
Block I/O tuning
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Parameters from the "blkio" controller are exposed via the ``bkliotune`` command
|
||||
in virsh.
|
||||
|
||||
::
|
||||
|
||||
# virsh blkiotune demo
|
||||
weight : 500
|
||||
device_weight :
|
||||
|
||||
Memory tuning
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Parameters from the "memory" controller are exposed via the ``memtune`` command
|
||||
in virsh.
|
||||
|
||||
::
|
||||
|
||||
# virsh memtune demo
|
||||
hard_limit : 580192
|
||||
soft_limit : unlimited
|
||||
swap_hard_limit: unlimited
|
||||
|
||||
Network tuning
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The ``net_cls`` is not currently used. Instead traffic filter policies are set
|
||||
directly against individual virtual network interfaces.
|
||||
|
||||
Legacy cgroups layout
|
||||
---------------------
|
||||
|
||||
Prior to libvirt 1.0.5, the cgroups layout created by libvirt was different from
|
||||
that described above, and did not allow for administrator customization. Libvirt
|
||||
used a fixed, 3-level hierarchy ``libvirt/{qemu,lxc}/$VMNAME`` which was rooted
|
||||
at the point in the hierarchy where libvirtd itself was located. So if libvirtd
|
||||
was placed at ``/system/libvirtd.service`` by systemd, the groups for each
|
||||
virtual machine / container would be located at
|
||||
``/system/libvirtd.service/libvirt/{qemu,lxc}/$VMNAME``. In addition to this,
|
||||
the QEMU drivers further child groups for each vCPU thread and the emulator
|
||||
thread(s). This leads to a hierarchy that looked like
|
||||
|
||||
::
|
||||
|
||||
$ROOT
|
||||
|
|
||||
+- system
|
||||
|
|
||||
+- libvirtd.service
|
||||
|
|
||||
+- libvirt
|
||||
|
|
||||
+- qemu
|
||||
| |
|
||||
| +- vm1
|
||||
| | |
|
||||
| | +- emulator
|
||||
| | +- vcpu0
|
||||
| | +- vcpu1
|
||||
| |
|
||||
| +- vm2
|
||||
| | |
|
||||
| | +- emulator
|
||||
| | +- vcpu0
|
||||
| | +- vcpu1
|
||||
| |
|
||||
| +- vm3
|
||||
| |
|
||||
| +- emulator
|
||||
| +- vcpu0
|
||||
| +- vcpu1
|
||||
|
|
||||
+- lxc
|
||||
|
|
||||
+- container1
|
||||
|
|
||||
+- container2
|
||||
|
|
||||
+- container3
|
||||
|
||||
Although current releases are much improved, historically the use of deep
|
||||
hierarchies has had a significant negative impact on the kernel scalability. The
|
||||
legacy libvirt cgroups layout highlighted these problems, to the detriment of
|
||||
the performance of virtual machines and containers.
|
|
@ -0,0 +1,229 @@
|
|||
==============================
|
||||
Libvirt Continuous Integration
|
||||
==============================
|
||||
|
||||
.. contents::
|
||||
|
||||
The libvirt project uses GitLab CI for automated testing.
|
||||
|
||||
Linux builds and cross-compiled Windows builds happen on GitLab CI's shared
|
||||
runners, while FreeBSD and macOS coverage is achieved by triggering `Cirrus CI
|
||||
<https://cirrus-ci.com/>`_ jobs behind the scenes.
|
||||
|
||||
Most of the tooling used to build CI pipelines is maintained as part of the
|
||||
`libvirt-ci <https://gitlab.com/libvirt/libvirt-ci>`_ subproject.
|
||||
|
||||
GitLab CI Dashboard
|
||||
===================
|
||||
|
||||
The dashboard below shows the current status of the GitLab CI jobs for each
|
||||
repository:
|
||||
|
||||
Core project
|
||||
------------
|
||||
|
||||
.. list-table::
|
||||
:widths: 80 20
|
||||
:header-rows: 1
|
||||
|
||||
* - Project
|
||||
- Pipeline
|
||||
|
||||
* - libvirt
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt/pipelines
|
||||
:alt: libvirt pipeline status
|
||||
|
||||
|
||||
Language bindings
|
||||
-----------------
|
||||
|
||||
.. list-table::
|
||||
:widths: 80 20
|
||||
:header-rows: 1
|
||||
|
||||
* - Project
|
||||
- Pipeline
|
||||
|
||||
* - libvirt-csharp
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-csharp/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-csharp/pipelines
|
||||
:alt: libvirt-csharp pipeline status
|
||||
|
||||
* - libvirt-go-module
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-go-module/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-go-module/pipelines
|
||||
:alt: libvirt-go-module pipeline status
|
||||
|
||||
* - libvirt-java
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-java/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-java/pipelines
|
||||
:alt: libvirt-java pipeline status
|
||||
|
||||
* - libvirt-ocaml
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-ocaml/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-ocaml/pipelines
|
||||
:alt: libvirt-ocaml pipeline status
|
||||
|
||||
* - libvirt-perl
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-perl/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-perl/pipelines
|
||||
:alt: libvirt-perl pipeline status
|
||||
|
||||
* - libvirt-php
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-php/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-php/pipelines
|
||||
:alt: libvirt-php pipeline status
|
||||
|
||||
* - libvirt-python
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-python/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-python/pipelines
|
||||
:alt: libvirt-python pipeline status
|
||||
|
||||
* - libvirt-ruby
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-ruby/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-ruby/pipelines
|
||||
:alt: libvirt-ruby pipeline status
|
||||
|
||||
* - libvirt-rust
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-rust/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-rust/pipelines
|
||||
:alt: libvirt-rust pipeline status
|
||||
|
||||
|
||||
Object mappings
|
||||
---------------
|
||||
|
||||
.. list-table::
|
||||
:widths: 80 20
|
||||
:header-rows: 1
|
||||
|
||||
* - Project
|
||||
- Pipeline
|
||||
|
||||
* - libvirt-cim
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-cim/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-cim/pipelines
|
||||
:alt: libvirt-cim pipeline status
|
||||
|
||||
* - libvirt-dbus
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-dbus/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-dbus/pipelines
|
||||
:alt: libvirt-dbus pipeline status
|
||||
|
||||
* - libvirt-glib
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-glib/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-glib/pipelines
|
||||
:alt: libvirt-glib pipeline status
|
||||
|
||||
* - libvirt-go-xml-module
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-go-xml-module/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-go-xml-module/pipelines
|
||||
:alt: libvirt-go-xml-module pipeline status
|
||||
|
||||
* - libvirt-snmp
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-snmp/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-snmp/pipelines
|
||||
:alt: libvirt-snmp pipeline status
|
||||
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
.. list-table::
|
||||
:widths: 80 20
|
||||
:header-rows: 1
|
||||
|
||||
* - Project
|
||||
- Pipeline
|
||||
|
||||
* - libvirt-ci
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-ci/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-ci/pipelines
|
||||
:alt: libvirt-ci pipeline status
|
||||
|
||||
* - libvirt-test-API
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-test-API/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-test-API/pipelines
|
||||
:alt: libvirt-test-API pipeline status
|
||||
|
||||
* - libvirt-tck
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-tck/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-tck/pipelines
|
||||
:alt: libvirt-tck pipeline status
|
||||
|
||||
|
||||
Documentation / websites
|
||||
------------------------
|
||||
|
||||
.. list-table::
|
||||
:widths: 80 20
|
||||
:header-rows: 1
|
||||
|
||||
* - Project
|
||||
- Pipeline
|
||||
* - libvirt-publican
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-publican/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-publican/pipelines
|
||||
:alt: libvirt-publican pipeline status
|
||||
|
||||
* - libvirt-appdev-guide-python
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-appdev-guide-python/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-appdev-guide-python/pipelines
|
||||
:alt: libvirt-appdev-guide-python pipeline status
|
||||
|
||||
* - libvirt-wiki
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-wiki/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-wiki/pipelines
|
||||
:alt: libvirt-wiki pipeline status
|
||||
|
||||
* - virttools-planet
|
||||
- .. image:: https://gitlab.com/libvirt/virttools-planet/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/virttools-planet/pipelines
|
||||
:alt: virttools-planet pipeline status
|
||||
|
||||
* - virttools-web
|
||||
- .. image:: https://gitlab.com/libvirt/virttools-web/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/virttools-web/pipelines
|
||||
:alt: virttools-web pipeline status
|
||||
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
|
||||
.. list-table::
|
||||
:widths: 80 20
|
||||
:header-rows: 1
|
||||
|
||||
* - Project
|
||||
- Pipeline
|
||||
|
||||
* - libvirt-console-proxy
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-console-proxy/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-console-proxy/pipelines
|
||||
:alt: libvirt-console-proxy pipeline status
|
||||
|
||||
* - libvirt-designer
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-designer/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-designer/pipelines
|
||||
:alt: libvirt-designer pipeline status
|
||||
|
||||
* - libvirt-devaddr
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-devaddr/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-devaddr/pipelines
|
||||
:alt: libvirt-devaddr pipeline status
|
||||
|
||||
* - libvirt-sandbox
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-sandbox/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-sandbox/pipelines
|
||||
:alt: libvirt-sandbox pipeline status
|
||||
|
||||
* - libvirt-sandbox-image
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-sandbox-image/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-sandbox-image/pipelines
|
||||
:alt: libvirt-sandbox-image pipeline status
|
||||
|
||||
* - libvirt-security-notice
|
||||
- .. image:: https://gitlab.com/libvirt/libvirt-security-notice/badges/master/pipeline.svg
|
||||
:target: https://gitlab.com/libvirt/libvirt-security-notice/pipelines
|
||||
:alt: libvirt-security-notice pipeline status
|
|
@ -0,0 +1,997 @@
|
|||
============
|
||||
Coding style
|
||||
============
|
||||
|
||||
.. contents::
|
||||
|
||||
Naming conventions
|
||||
==================
|
||||
|
||||
When reading libvirt code, a number of different naming
|
||||
conventions will be evident due to various changes in thinking
|
||||
over the course of the project's lifetime. The conventions
|
||||
documented below should be followed when creating any entirely new
|
||||
files in libvirt. When working on existing files, while it is
|
||||
desirable to apply these conventions, keeping a consistent style
|
||||
with existing code in that particular file is generally more
|
||||
important. The overall guiding principal is that every file, enum,
|
||||
struct, function, macro and typedef name must have a 'vir' or
|
||||
'VIR' prefix. All local scope variable names are exempt, and
|
||||
global variables are exempt, unless exported in a header file.
|
||||
|
||||
File names
|
||||
File naming varies depending on the subdirectory. The preferred
|
||||
style is to have a 'vir' prefix, followed by a name which
|
||||
matches the name of the functions / objects inside the file.
|
||||
For example, a file containing an object 'virHashtable' is
|
||||
stored in files 'virhashtable.c' and 'virhashtable.h'.
|
||||
Sometimes, methods which would otherwise be declared 'static'
|
||||
need to be exported for use by a test suite. For this purpose a
|
||||
second header file should be added with a suffix of 'priv',
|
||||
e.g. 'virhashtablepriv.h'. Use of underscores in file names is
|
||||
discouraged when using the 'vir' prefix style. The 'vir' prefix
|
||||
naming applies to src/util, src/rpc and tests/ directories.
|
||||
Most other directories do not follow this convention.
|
||||
|
||||
Enum type & field names
|
||||
All enums should have a 'vir' prefix in their typedef name, and
|
||||
each following word should have its first letter in uppercase.
|
||||
The enum name should match the typedef name with a leading
|
||||
underscore. The enum member names should be in all uppercase,
|
||||
and use an underscore to separate each word. The enum member
|
||||
name prefix should match the enum typedef name.
|
||||
|
||||
::
|
||||
|
||||
typedef enum _virSocketType virSocketType;
|
||||
enum _virSocketType {
|
||||
VIR_SOCKET_TYPE_IPV4,
|
||||
VIR_SOCKET_TYPE_IPV6,
|
||||
};
|
||||
|
||||
Struct type names
|
||||
All structs should have a 'vir' prefix in their typedef name,
|
||||
and each following word should have its first letter in
|
||||
uppercase. The struct name should be the same as the typedef
|
||||
name with a leading underscore. For types that are part of the
|
||||
public API, a second typedef should be given for a pointer to
|
||||
the struct with a 'Ptr' suffix. Do not introduce new such
|
||||
typedefs for internal types.
|
||||
|
||||
::
|
||||
|
||||
typedef struct _virSomeType virSomeType;
|
||||
typedef virSomeType *virSomeTypePtr;
|
||||
struct _virSomeType {
|
||||
...
|
||||
};
|
||||
|
||||
Function names
|
||||
All functions should have a 'vir' prefix in their name,
|
||||
followed by one or more words with first letter of each word
|
||||
capitalized. Underscores should not be used in function names.
|
||||
If the function is operating on an object, then the function
|
||||
name prefix should match the object typedef name, otherwise it
|
||||
should match the filename. Following this comes the verb /
|
||||
action name, and finally an optional subject name. For example,
|
||||
given an object 'virSomeType', all functions should have a
|
||||
name 'virSomeType$VERB' or 'virSomeType$VERB$SUBJECT", e.g.
|
||||
'virHashTableLookup' or 'virHashTableGetValue'.
|
||||
|
||||
Macro names
|
||||
All macros should have a "VIR" prefix in their name, followed
|
||||
by one or more uppercase words separated by underscores. The
|
||||
macro argument names should be in lowercase. Aside from having
|
||||
a "VIR" prefix there are no common practices for the rest of
|
||||
the macro name.
|
||||
|
||||
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, the project includes a file .dir-locals.el that
|
||||
sets up the preferred indentation. 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,L3
|
||||
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
|
||||
https://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 -l100 -lc100 \
|
||||
-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.
|
||||
|
||||
The maximum permitted line length is 100 characters, but lines
|
||||
should aim to be approximately 80 characters.
|
||||
|
||||
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.
|
||||
|
||||
Bracket spacing
|
||||
---------------
|
||||
|
||||
The keywords ``if``, ``for``, ``while``, and ``switch`` must have
|
||||
a single space following them before the opening bracket. E.g.
|
||||
|
||||
::
|
||||
|
||||
if(foo) // Bad
|
||||
if (foo) // Good
|
||||
|
||||
Function implementations must **not** have any whitespace between
|
||||
the function name and the opening bracket. E.g.
|
||||
|
||||
::
|
||||
|
||||
int foo (int wizz) // Bad
|
||||
int foo(int wizz) // Good
|
||||
|
||||
Function calls must **not** have any whitespace between the
|
||||
function name and the opening bracket. E.g.
|
||||
|
||||
::
|
||||
|
||||
bar = foo (wizz); // Bad
|
||||
bar = foo(wizz); // Good
|
||||
|
||||
Function typedefs must **not** have any whitespace between the
|
||||
closing bracket of the function name and opening bracket of the
|
||||
arg list. E.g.
|
||||
|
||||
::
|
||||
|
||||
typedef int (*foo) (int wizz); // Bad
|
||||
typedef int (*foo)(int wizz); // Good
|
||||
|
||||
There must not be any whitespace immediately following any opening
|
||||
bracket, or immediately prior to any closing bracket. E.g.
|
||||
|
||||
::
|
||||
|
||||
int foo( int wizz ); // Bad
|
||||
int foo(int wizz); // Good
|
||||
|
||||
Commas
|
||||
------
|
||||
|
||||
Commas should always be followed by a space or end of line, and
|
||||
never have leading space; this is enforced during 'make
|
||||
syntax-check'.
|
||||
|
||||
::
|
||||
|
||||
call(a,b ,c);// Bad
|
||||
call(a, b, c); // Good
|
||||
|
||||
When declaring an enum or using a struct initializer that occupies
|
||||
more than one line, use a trailing comma. That way, future edits
|
||||
to extend the list only have to add a line, rather than modify an
|
||||
existing line to add the intermediate comma. Any sentinel
|
||||
enumerator value with a name ending in \_LAST is exempt, since you
|
||||
would extend such an enum before the \_LAST element. Another
|
||||
reason to favor trailing commas is that it requires less effort to
|
||||
produce via code generators. Note that the syntax checker is
|
||||
unable to enforce a style of trailing commas, so there are
|
||||
counterexamples in existing code which do not use it; also, while
|
||||
C99 allows trailing commas, remember that JSON and XDR do not.
|
||||
|
||||
::
|
||||
|
||||
enum {
|
||||
VALUE_ONE,
|
||||
VALUE_TWO // Bad
|
||||
};
|
||||
enum {
|
||||
VALUE_THREE,
|
||||
VALUE_FOUR, // Good
|
||||
};
|
||||
|
||||
Semicolons
|
||||
----------
|
||||
|
||||
Semicolons should never have a space beforehand. Inside the
|
||||
condition of a ``for`` loop, there should always be a space or
|
||||
line break after each semicolon, except for the special case of an
|
||||
infinite loop (although more infinite loops use ``while``). While
|
||||
not enforced, loop counters generally use post-increment.
|
||||
|
||||
::
|
||||
|
||||
for (i = 0 ;i < limit ; ++i) { // Bad
|
||||
for (i = 0; i < limit; i++) { // Good
|
||||
for (;;) { // ok
|
||||
while (1) { // Better
|
||||
|
||||
Empty loop bodies are better represented with curly braces and a
|
||||
comment, although use of a semicolon is not currently rejected.
|
||||
|
||||
::
|
||||
|
||||
while ((rc = waitpid(pid, &st, 0) == -1) &&
|
||||
errno == EINTR); // ok
|
||||
while ((rc = waitpid(pid, &st, 0) == -1) &&
|
||||
errno == EINTR) { // Better
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
Curly braces
|
||||
------------
|
||||
|
||||
Curly braces around an ``if``, ``while``, ``for`` etc. can be omitted if the
|
||||
body and the condition itself occupy only 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.
|
||||
|
||||
::
|
||||
|
||||
while (expr) // single line body; {} is optional
|
||||
single_line_stmt();
|
||||
|
||||
::
|
||||
|
||||
while (expr(arg1,
|
||||
arg2)) // indentation makes it obvious it is single line,
|
||||
single_line_stmt(); // {} is optional (not enforced either way)
|
||||
|
||||
::
|
||||
|
||||
while (expr1 &&
|
||||
expr2) { // multi-line, at same indentation, {} required
|
||||
single_line_stmt();
|
||||
}
|
||||
|
||||
However, the moment your loop/if/else body extends on to 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;
|
||||
}
|
||||
|
||||
Use hanging braces for compound statements: the opening brace of a
|
||||
compound statement should be on the same line as the condition
|
||||
being tested. Only top-level function bodies, nested scopes, and
|
||||
compound structure declarations should ever have { on a line by
|
||||
itself.
|
||||
|
||||
::
|
||||
|
||||
void
|
||||
foo(int a, int b)
|
||||
{ // correct - function body
|
||||
int 2d[][] = {
|
||||
{ // correct - complex initialization
|
||||
1, 2,
|
||||
},
|
||||
};
|
||||
if (a)
|
||||
{ // BAD: compound brace on its own line
|
||||
do_stuff();
|
||||
}
|
||||
{ // correct - nested scope
|
||||
int tmp;
|
||||
if (a < b) { // correct - hanging brace
|
||||
tmp = b;
|
||||
b = a;
|
||||
a = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Conditional expressions
|
||||
-----------------------
|
||||
|
||||
For readability reasons new code should avoid shortening
|
||||
comparisons to 0 for numeric types:
|
||||
|
||||
::
|
||||
|
||||
size nfoos = 0;
|
||||
|
||||
GOOD:
|
||||
if (nfoos != 0)
|
||||
if (nfoos == 0)
|
||||
|
||||
BAD:
|
||||
if (nfoos)
|
||||
if (!nfoos)
|
||||
|
||||
Prefer the shortened version for boolean values. Boolean values
|
||||
should never be compared against the literal ``true``, as a
|
||||
logical non-false value need not be ``1``.
|
||||
|
||||
::
|
||||
|
||||
bool hasFoos = false;
|
||||
|
||||
GOOD:
|
||||
if (hasFoos)
|
||||
if (!hasFoos)
|
||||
|
||||
BAD:
|
||||
if (hasFoos == true)
|
||||
if (hasFoos != false)
|
||||
if (hasFoos == false)
|
||||
if (hasFoos != true)
|
||||
|
||||
Pointer comparisons may be shortened. All long forms are okay.
|
||||
|
||||
::
|
||||
|
||||
virFoo *foo = NULL;
|
||||
|
||||
GOOD:
|
||||
if (foo) # or: if (foo != NULL)
|
||||
if (!foo) # or: if (foo == NULL)
|
||||
|
||||
New code should avoid the ternary operator as much as possible.
|
||||
Specifically it must never span more than one line or nest:
|
||||
|
||||
::
|
||||
|
||||
BAD:
|
||||
char *foo = baz ?
|
||||
virDoSomethingReallyComplex(driver, vm, something, baz->foo) :
|
||||
NULL;
|
||||
|
||||
char *foo = bar ? bar->baz ? bar->baz->foo : "nobaz" : "nobar";
|
||||
|
||||
Preprocessor
|
||||
------------
|
||||
|
||||
Macros defined with an ALL_CAPS name should generally be assumed
|
||||
to be unsafe with regards to arguments with side-effects (that is,
|
||||
MAX(a++, b--) might increment a or decrement b too many or too few
|
||||
times). Exceptions to this rule are explicitly documented for
|
||||
macros in viralloc.h and virstring.h.
|
||||
|
||||
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(WITH_POSIX_FALLOCATE) && !defined(WITH_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.
|
||||
- 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 a
|
||||
minor caveat: 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.
|
||||
|
||||
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.
|
||||
|
||||
Defining Local Variables
|
||||
------------------------
|
||||
|
||||
Always define local variables at the top of the block in which they
|
||||
are used (before any pure code). Although modern C compilers allow
|
||||
defining a local variable in the middle of a block of code, this
|
||||
practice can lead to bugs, and must be avoided in all libvirt
|
||||
code. As indicated in these examples, it is okay to initialize
|
||||
variables where they are defined, even if the initialization involves
|
||||
calling another function.
|
||||
|
||||
::
|
||||
|
||||
GOOD:
|
||||
int
|
||||
bob(char *loblaw)
|
||||
{
|
||||
int x;
|
||||
int y = lawBlog();
|
||||
char *z = NULL;
|
||||
|
||||
x = y + 20;
|
||||
...
|
||||
}
|
||||
|
||||
BAD:
|
||||
int
|
||||
bob(char *loblaw)
|
||||
{
|
||||
int x;
|
||||
int y = lawBlog();
|
||||
|
||||
x = y + 20;
|
||||
|
||||
char *z = NULL; // <===
|
||||
...
|
||||
}
|
||||
|
||||
Prefer variable definitions on separate lines. This allows for smaller,
|
||||
easier to understand diffs when changing them. Define variables in the
|
||||
smallest possible scope.
|
||||
|
||||
::
|
||||
|
||||
GOOD:
|
||||
int count = 0;
|
||||
int nnodes;
|
||||
|
||||
BAD:
|
||||
int count = 0, nnodes;
|
||||
|
||||
Attribute annotations
|
||||
---------------------
|
||||
|
||||
Use the following annotations to help the compiler and/or static
|
||||
analysis tools understand the code better:
|
||||
|
||||
``ATTRIBUTE_NONNULL``
|
||||
passing NULL for this parameter is not allowed
|
||||
|
||||
``ATTRIBUTE_PACKED``
|
||||
force a structure to be packed
|
||||
|
||||
``G_GNUC_FALLTHROUGH``
|
||||
allow code reuse by multiple switch cases
|
||||
|
||||
``G_GNUC_NO_INLINE``
|
||||
the function is mocked in the test suite
|
||||
|
||||
``G_GNUC_NORETURN``
|
||||
the function never returns
|
||||
|
||||
``G_GNUC_NULL_TERMINATED``
|
||||
last parameter must be NULL
|
||||
|
||||
``G_GNUC_PRINTF``
|
||||
validate that the formatting string matches parameters
|
||||
|
||||
``G_GNUC_UNUSED``
|
||||
parameter is unused in this implementation of the function
|
||||
|
||||
``G_GNUC_WARN_UNUSED_RESULT``
|
||||
the return value must be checked
|
||||
|
||||
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 particularly dangerous in a
|
||||
multi-threaded application. 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 replacement
|
||||
functions provided by libvirt:
|
||||
|
||||
::
|
||||
|
||||
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.
|
||||
|
||||
::
|
||||
|
||||
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.
|
||||
|
||||
::
|
||||
|
||||
dst = g_strdup(src);
|
||||
dst = g_strndup(src, n);
|
||||
|
||||
You should avoid using strdup or strndup directly as they do not
|
||||
handle out-of-memory errors, and do not allow a NULL source. Use
|
||||
``g_strdup`` and ``g_strndup`` from GLib which abort on OOM and
|
||||
handle NULL source by returning NULL.
|
||||
|
||||
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 either the
|
||||
`GString <https://developer.gnome.org/glib/stable/glib-Strings.html>`__
|
||||
type from GLib or the virBuffer API. If formatting XML or QEMU
|
||||
command line is needed, use the virBuffer API described in
|
||||
virbuffer.h, since it has helper functions for those.
|
||||
|
||||
Typical usage is as follows:
|
||||
|
||||
::
|
||||
|
||||
char *
|
||||
somefunction(...)
|
||||
{
|
||||
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
...
|
||||
|
||||
virBufferAddLit(&buf, "<domain>\n");
|
||||
|
||||
...
|
||||
|
||||
if (some_error)
|
||||
return NULL; /* g_auto will free the memory used so far */
|
||||
|
||||
...
|
||||
|
||||
virBufferAddLit(&buf, "</domain>\n");
|
||||
|
||||
...
|
||||
|
||||
if (virBufferCheckError(&buf) < 0)
|
||||
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 WITH_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,
|
||||
libvirt/virterror.h, libvirt/libvirt-qemu.h, or
|
||||
libvirt/libvirt-lxc.h. They are included by "internal.h" already
|
||||
and there are some special reasons why you cannot include these
|
||||
files explicitly. One of the special cases, "libvirt/libvirt.h" is
|
||||
included prior to "internal.h" in "remote_protocol.x", to avoid
|
||||
exposing \*_LAST enum elements.
|
||||
|
||||
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 virCommandAddEnvFormat in
|
||||
vircommand.h:
|
||||
|
||||
::
|
||||
|
||||
void virCommandAddEnvFormat(virCommand *cmd, const char *format, ...)
|
||||
G_GNUC_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 GString or virBuffer for
|
||||
incremental allocations, g_strdup_printf for a one-shot
|
||||
allocation, and g_snprintf for fixed-width buffers. Only use
|
||||
g_sprintf, if you can prove the buffer won't overflow.
|
||||
|
||||
Error message format
|
||||
--------------------
|
||||
|
||||
Error messages visible to the user should be short and
|
||||
descriptive. All error messages are translated using gettext and
|
||||
thus must be wrapped in ``_()`` macro. To simplify the translation
|
||||
work, the error message must not be concatenated from various
|
||||
parts. To simplify searching for the error message in the code the
|
||||
strings should not be broken even if they result into a line
|
||||
longer than 80 columns and any formatting modifier should be
|
||||
enclosed by quotes or other obvious separator. If a string used
|
||||
with ``%s`` can be NULL the NULLSTR macro must be used.
|
||||
|
||||
::
|
||||
|
||||
GOOD: virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to connect to remote host '%s'"), hostname)
|
||||
|
||||
BAD: virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to %s to remote host '%s'"),
|
||||
"connect", hostname);
|
||||
|
||||
BAD: virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to connect "
|
||||
"to remote host '%s'),
|
||||
hostname);
|
||||
|
||||
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. g_free()
|
||||
and most of the functions named XXXFree() in libvirt is required
|
||||
to handle NULL as its arg. This does not apply to libvirt's public
|
||||
APIs. 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. Note that most of libvirt's type declarations can
|
||||
be marked with either ``g_autofree`` or ``g_autoptr`` which uses
|
||||
the compiler's ``__attribute__((cleanup))`` that calls the
|
||||
appropriate free function when the variable goes out of scope.
|
||||
|
||||
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 <https://web.archive.org/web/20130521051957/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
|
||||
retry: If needing to jump upwards (e.g., retry on EINTR)
|
||||
|
||||
Top-level labels should be indented by one space (putting them on
|
||||
the beginning of the line confuses function context detection in
|
||||
git):
|
||||
|
||||
::
|
||||
|
||||
int foo()
|
||||
{
|
||||
/* ... do stuff ... */
|
||||
cleanup:
|
||||
/* ... do other stuff ... */
|
||||
}
|
||||
|
||||
|
||||
XML element and attribute naming
|
||||
--------------------------------
|
||||
|
||||
New elements and/or attributes should be short and descriptive.
|
||||
In general, they should reflect what the feature does instead of
|
||||
how exactly it is named in given hypervisor because this creates
|
||||
an abstraction that other drivers can benefit from (for instance
|
||||
if the same feature is named differently in two hypervisors).
|
||||
That is not to say an element or attribute can't have the same
|
||||
name as in a hypervisor, but proceed with caution.
|
||||
|
||||
Single worded names are preferred, but if more words must be
|
||||
used then they shall be joined in camelCase style.
|
|
@ -0,0 +1,32 @@
|
|||
====================
|
||||
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 'ninja test',
|
||||
and make sure you don't raise errors.
|
||||
|
||||
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 ninja test 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 'ninja test' 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.
|
||||
- (ir)regular pulls from other repositories or automated updates,
|
||||
such as the keycodemap submodule updates, pulling in new
|
||||
translations or updating the container images for the CI system
|
|
@ -0,0 +1,100 @@
|
|||
====================
|
||||
libvirt Installation
|
||||
====================
|
||||
|
||||
.. contents::
|
||||
|
||||
Compiling a release tarball
|
||||
---------------------------
|
||||
|
||||
libvirt uses the standard setup/build/install steps and mandates that
|
||||
the build directory is different from the source directory:
|
||||
|
||||
::
|
||||
|
||||
$ xz -dc libvirt-x.x.x.tar.xz | tar xvf -
|
||||
$ cd libvirt-x.x.x
|
||||
$ meson build
|
||||
|
||||
The *meson* script can be given options to change its default behaviour.
|
||||
|
||||
**Note:** Please ensure that you have the appropriate minimal ``meson`` version
|
||||
installed in your build environment. The minimal version for a specific package
|
||||
can be checked in the top level ``meson.build`` file in the ``meson_version``
|
||||
field.
|
||||
|
||||
To get the complete list of the options run the following command:
|
||||
|
||||
::
|
||||
|
||||
$ meson configure
|
||||
|
||||
When you have determined which options you want to use (if any),
|
||||
continue the process.
|
||||
|
||||
Note the use of **sudo** with the *ninja install* 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.
|
||||
|
||||
If you are installing to a location that your user *does* have write
|
||||
access to, then you can instead run the *ninja install* command without
|
||||
putting **sudo** before it.
|
||||
|
||||
::
|
||||
|
||||
$ meson build [possible options]
|
||||
$ ninja -C build
|
||||
$ sudo ninja -C build install
|
||||
|
||||
At this point you **may** have to run ldconfig or a similar utility to
|
||||
update your list of installed shared libs.
|
||||
|
||||
Building from a GIT checkout
|
||||
----------------------------
|
||||
|
||||
The libvirt build process uses Meson build system. By default when the
|
||||
``meson`` is run from within a GIT checkout, it will turn on -Werror for
|
||||
builds. This can be disabled with --werror=false, but this is not
|
||||
recommended.
|
||||
|
||||
To build & install libvirt to your home directory the following commands
|
||||
can be run:
|
||||
|
||||
::
|
||||
|
||||
$ meson build --prefix=$HOME/usr
|
||||
$ ninja -C build
|
||||
$ sudo ninja -C build install
|
||||
|
||||
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
|
||||
|
||||
::
|
||||
|
||||
$ meson build -Dsystem=true
|
||||
$ ninja -C build
|
||||
|
||||
|
||||
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
|
||||
|
||||
::
|
||||
|
||||
$ su -
|
||||
# service libvirtd stop (or systemctl stop libvirtd.service)
|
||||
# /home/to/your/checkout/build/src/libvirtd
|
||||
|
||||
|
||||
It is also possible to run virsh directly from the build tree using the
|
||||
./run script (which sets some environment variables):
|
||||
|
||||
::
|
||||
|
||||
$ pwd
|
||||
/home/to/your/checkout/build
|
||||
$ ./run ./tools/virsh ....
|
|
@ -0,0 +1,87 @@
|
|||
===================================
|
||||
Contacting the project contributors
|
||||
===================================
|
||||
|
||||
.. contents::
|
||||
|
||||
Security Issues
|
||||
---------------
|
||||
|
||||
If you think that an issue with libvirt may have security implications, **please
|
||||
do not** publicly report it in the bug tracker, mailing lists, or irc. Libvirt
|
||||
has `a dedicated process for handling (potential) security
|
||||
issues <securityprocess.html>`__ that should be used instead. So if your issue
|
||||
has security implications, ignore the rest of this page and follow the `security
|
||||
process <securityprocess.html>`__ instead.
|
||||
|
||||
Mailing lists
|
||||
-------------
|
||||
|
||||
There are three mailing-lists:
|
||||
|
||||
**libvir-list@redhat.com** (for development)
|
||||
Archives
|
||||
https://listman.redhat.com/archives/libvir-list
|
||||
List info
|
||||
https://listman.redhat.com/mailman/listinfo/libvir-list
|
||||
|
||||
This is a high volume mailing list. It is a place for discussions about the
|
||||
**development** of libvirt.
|
||||
Topics for discussion include:
|
||||
|
||||
- New features for libvirt
|
||||
- Bug fixing of libvirt
|
||||
- New hypervisor drivers
|
||||
- Development of language bindings for libvirt API
|
||||
- Testing and documentation of libvirt
|
||||
|
||||
**libvirt-users@redhat.com** (for users)
|
||||
Archives
|
||||
https://listman.redhat.com/archives/libvirt-users
|
||||
List info
|
||||
https://listman.redhat.com/mailman/listinfo/libvirt-users
|
||||
|
||||
This is a moderate volume mailing list. It is a place for discussions
|
||||
involving libvirt **users**.
|
||||
Topics for discussion include:
|
||||
|
||||
- Usage of libvirt / virsh
|
||||
- Administration of libvirt
|
||||
- Deployment of libvirt with hypervisors
|
||||
- Development of applications on top of / using the libvirt API(s)
|
||||
- Any other topics along these lines
|
||||
|
||||
**libvirt-announce@redhat.com** (for release notices)
|
||||
Archives
|
||||
https://listman.redhat.com/archives/libvirt-announce
|
||||
List info
|
||||
https://listman.redhat.com/mailman/listinfo/libvirt-announce
|
||||
|
||||
This is a low volume mailing list, with restricted posting, for announcements
|
||||
of new libvirt releases.
|
||||
Subscribe to just this if you want to be notified of new releases, without
|
||||
subscribing to either of the other mailing lists.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
``git format-patch`` in a git repository clone. Further useful information
|
||||
regarding developing libvirt and/or contributing is available on our
|
||||
`Contributor Guidelines <hacking.html>`__ page.
|
||||
|
||||
IRC
|
||||
---
|
||||
|
||||
Some of the libvirt developers may be found on IRC on the `OFTC
|
||||
IRC <https://oftc.net>`__ network. Use the settings:
|
||||
|
||||
- server: irc.oftc.net
|
||||
- port: 6697 (the usual IRC TLS port)
|
||||
- channel: #virt
|
||||
|
||||
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.
|
|
@ -0,0 +1,105 @@
|
|||
=======================
|
||||
Contributing to libvirt
|
||||
=======================
|
||||
|
||||
This page provides guidance on how to contribute to the libvirt project.
|
||||
|
||||
.. contents::
|
||||
|
||||
Contributions required
|
||||
----------------------
|
||||
|
||||
The libvirt project is always looking for new contributors to participate in
|
||||
ongoing activities. While code development is a major part of the project,
|
||||
assistance is needed in many other areas including documentation writing, bug
|
||||
triage, testing, application integration, website / wiki content management,
|
||||
translation, branding, social media and more. The only requirement is an
|
||||
interest in virtualization and desire to help.
|
||||
|
||||
The following is a non-exhaustive list of areas in which people can contribute
|
||||
to libvirt. If you have ideas for other contributions feel free to follow them.
|
||||
|
||||
- **Software development**. The official upstream code are kept in various `Git
|
||||
repositories <https://gitlab.com/libvirt/>`__. The core library / daemon (and
|
||||
thus the bulk of coding) is written in C, but there are language bindings
|
||||
written in Python, Perl, Java, Ruby, Php, OCaml and Go. There are also higher
|
||||
level wrappers mapping libvirt into other object frameworks, such GLib, CIM
|
||||
and SNMP. For those interested in working on the core parts of libvirt, the
|
||||
`contributor guidelines <hacking.html>`__ are mandatory reading
|
||||
- **Translation**. All the libvirt modules aim to support translations where
|
||||
appropriate. All translation is handling outside of the normal libvirt review
|
||||
process, using the `Fedora
|
||||
instance <https://translate.fedoraproject.org/projects/libvirt/libvirt>`__ of
|
||||
the Weblate tool. Thus people wishing to contribute to translation should
|
||||
join the Fedora translation team
|
||||
- **Documentation**. There are docbook guides on various aspects of libvirt,
|
||||
particularly application development guides for the C library and Python, and
|
||||
a virsh command reference. There is thus scope for work by people who are
|
||||
familiar with using or developing against libvirt, to write further content
|
||||
for these guides. There is also a need for people to review existing content
|
||||
for copy editing and identifying gaps in the docs
|
||||
- **Website / wiki curation**. The bulk of the website is maintained in the
|
||||
primary GIT repository, while the wiki site uses mediawiki. In both cases
|
||||
there is a need for people to both write new content and curate existing
|
||||
content to identify outdated information, improve its organization and target
|
||||
gaps.
|
||||
- **Testing**. There are a number of tests suites that can run automated tests
|
||||
against libvirt. The coverage of the tests is never complete, so there is a
|
||||
need for people to create new test suites and / or provide environments to
|
||||
actually run the tests in a variety of deployment scenarios.
|
||||
- **Code analysis**. The libvirt project has access to the coverity tool to run
|
||||
static analysis against the codebase, however, there are other types of code
|
||||
analysis that can be useful. In particular fuzzing of the inputs can be very
|
||||
effective at identifying problematic edge cases.
|
||||
- **Security handling**. Downstream (operating system) vendors who distribute
|
||||
libvirt may wish to propose a person to be part of the security handling
|
||||
team, to get early access to information about forthcoming vulnerability
|
||||
fixes.
|
||||
- **Evangelism**. Work done by the project is of no benefit unless the
|
||||
(potential) user community knows that it exists. Thus it is critically
|
||||
important to the health and future growth of the project, that there are a
|
||||
people who evangelize the work created by the project. This can take many
|
||||
forms, writing blog posts (about usage of features, personal user
|
||||
experiences, areas for future work, and more), syndicating docs and blogs via
|
||||
social media, giving user group and/or conference talks about libvirt.
|
||||
- **User assistance**. Since documentation is never perfect, there are
|
||||
inevitably cases where users will struggle to attain a deployment goal they
|
||||
have, or run into trouble with managing an existing deployment. While some
|
||||
users may be able to contact a software vendor to obtain support, it is
|
||||
common to rely on community help forums such as `libvirt users mailing
|
||||
list <contact.html#mailing-lists>`__, or sites such as
|
||||
`stackoverflow. <https://stackoverflow.com/questions/tagged/libvirt>`__
|
||||
People who are familiar with libvirt and have ability & desire to help other
|
||||
users are encouraged to participate in these help forums.
|
||||
|
||||
Communication
|
||||
-------------
|
||||
|
||||
For full details on contacting other project contributors read the
|
||||
`contact <contact.html>`__ page. There are two main channels that libvirt uses
|
||||
for communication between contributors:
|
||||
|
||||
Mailing lists
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The project has a number of `mailing lists <contact.html#mailing-lists>`__ for
|
||||
general communication between contributors. In general any design discussions
|
||||
and review of contributions will take place on the mailing lists, so it is
|
||||
important for all contributors to follow the traffic.
|
||||
|
||||
Instant messaging / chat
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Contributors to libvirt are encouraged to join the `IRC
|
||||
channel <contact.html#irc>`__ used by the project, where they can have live
|
||||
conversations with others members.
|
||||
|
||||
Student / outreach coding programs
|
||||
----------------------------------
|
||||
|
||||
Since 2016, the libvirt project directly participates as an organization in the
|
||||
`Google Summer of Code
|
||||
program <https://wiki.libvirt.org/page/Google_Summer_of_Code_Ideas>`__. Prior to
|
||||
this the project had a number of students in the program via a joint application
|
||||
with the QEMU project. People are encouraged to look at both the libvirt and
|
||||
QEMU programs to identify potentially interesting projects to work on.
|
|
@ -0,0 +1,38 @@
|
|||
===============
|
||||
C# API bindings
|
||||
===============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
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.
|
||||
|
||||
Compiling them produces **LibvirtBindings.dll**, which can be added as a .NET
|
||||
reference to any .NET project needing access to libvirt.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
These bindings depend upon the libvirt libraries being installed.
|
||||
|
||||
In the .NET case, this is **libvirt-0.dll**, produced from compiling libvirt for
|
||||
windows.
|
||||
|
||||
GIT source repository
|
||||
---------------------
|
||||
|
||||
The C# bindings source code is maintained in a ``git`` repository available on
|
||||
`gitlab.com <https://gitlab.com/libvirt/libvirt-csharp>`__:
|
||||
|
||||
::
|
||||
|
||||
git clone https://gitlab.com/libvirt/libvirt-csharp.git
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
The C# bindings are the work of Arnaud Champion <`arnaud.champion AT
|
||||
devatom.fr <mailto:arnaud.champion%20AT%20devatom.fr>`__>, based upon the
|
||||
previous work of Jaromír Červenka.
|
|
@ -0,0 +1,62 @@
|
|||
@font-face {
|
||||
font-family: 'LibvirtOverpass';
|
||||
src: url('../fonts/overpass-regular.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'LibvirtOverpass';
|
||||
src: url('../fonts/overpass-italic.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'LibvirtOverpass';
|
||||
src: url('../fonts/overpass-bold.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'LibvirtOverpass';
|
||||
src: url('../fonts/overpass-bold-italic.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'LibvirtOverpassLight';
|
||||
src: url('../fonts/overpass-light.woff') format('woff');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'LibvirtOverpassLight';
|
||||
src: url('../fonts/overpass-light-italic.woff') format('woff');
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'LibvirtOverpassMono';
|
||||
src: url('../fonts/overpass-mono-regular.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'LibvirtOverpassMono';
|
||||
src: url('../fonts/overpass-mono-bold.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'LibvirtOverpassMonoLight';
|
||||
src: url('../fonts/overpass-mono-light.woff') format('woff');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
body {
|
||||
margin: 0em;
|
||||
padding: 0px;
|
||||
color: rgb(0,0,0);
|
||||
background: #ffffff;
|
||||
font-family: LibvirtOverpass;
|
||||
}
|
||||
|
||||
p, ul, ol, dl {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
dt {
|
||||
margin-left: 1em;
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
dt code, dt .literal {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dl dd {
|
||||
margin-left: 2em;
|
||||
margin-right: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: bold;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 0em;
|
||||
font-size: 1.6em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 1.0em;
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 1.0em;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-top: 1.0em;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin-top: 0.75em;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
margin-top: 0.75em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
code, pre, tt {
|
||||
font-family: LibvirtOverpassMono;
|
||||
}
|
||||
|
||||
dd code, p code, tt {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 90%;
|
||||
}
|
|
@ -0,0 +1,638 @@
|
|||
#nav {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
height: 100px;
|
||||
background: rgb(0, 95, 97);
|
||||
border-bottom: 3px solid rgb(60, 133, 124);
|
||||
width: 100%;
|
||||
display: table;
|
||||
}
|
||||
|
||||
#home {
|
||||
background-image: url(../logos/logo-banner-light-256.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left center;
|
||||
height: 100px;
|
||||
width: 269px;
|
||||
margin-left: 1em;
|
||||
text-indent: 100%; white-space: nowrap; overflow: hidden;
|
||||
}
|
||||
|
||||
#home a {
|
||||
color: rgb(0, 95, 97);
|
||||
height: 100px;
|
||||
width: 269px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#jumplinks {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
font-size: 16pt;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#jumplinks ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#jumplinks li {
|
||||
display: inline;
|
||||
padding-left: 2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#jumplinks a {
|
||||
color: rgb(255, 255, 255);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#jumplinks a:hover {
|
||||
color: rgb(255, 230, 0);
|
||||
}
|
||||
|
||||
#search {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
width: 13em;
|
||||
text-align: right;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
#search input {
|
||||
border: 0px;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
#search input[type=text] {
|
||||
background: rgb(230, 230, 230);
|
||||
color: rgb(0, 0, 0);
|
||||
width: 10em;
|
||||
padding: 0px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
#search input[type=submit] {
|
||||
background: rgb(60, 133, 124);
|
||||
color: rgb(255, 255, 255);
|
||||
width: 3em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#search input[type=submit]:active,
|
||||
#search input[type=submit]:hover {
|
||||
color: rgb(255, 230, 0);
|
||||
}
|
||||
|
||||
#body {
|
||||
border: 0px;
|
||||
left: 0px;
|
||||
margin: 0px;
|
||||
margin-top: 120px;
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
main,
|
||||
.document {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 0px;
|
||||
padding-bottom: 1em;
|
||||
max-width: 95%;
|
||||
width: 70em;
|
||||
}
|
||||
|
||||
main#index,
|
||||
#index.document,
|
||||
main#hvsupport,
|
||||
#hvsupport.document,
|
||||
main#documentation,
|
||||
#documentation.document,
|
||||
main#knowledge-base,
|
||||
#knowledge-base.document
|
||||
{
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
pre {
|
||||
border: 1px solid #999999;
|
||||
background: #eeeeee;
|
||||
color: black;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgb(0, 95, 97);
|
||||
}
|
||||
|
||||
div.api {
|
||||
border: 1px solid #999999;
|
||||
background: #eeeeee;
|
||||
color: black;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
div.api pre {
|
||||
margin: 0px;
|
||||
border: 0px;
|
||||
background: inherit;
|
||||
padding: inherit;
|
||||
}
|
||||
|
||||
div.api table {
|
||||
margin: 0px;
|
||||
padding-left: 2em;
|
||||
border-spacing: 0px;
|
||||
}
|
||||
|
||||
div.api table td, div.variablelist table td {
|
||||
vertical-align: top;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
h1 a, h2 a, h3 a, h4 a, h5 a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
#changelog .author {
|
||||
color: #3c857c;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p.image {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
min-width: 60%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table th {
|
||||
background: rgb(0, 95, 97);
|
||||
color: rgb(255, 255, 255);
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
table th a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
table td, table th {
|
||||
border: 1px solid rgb(60, 133, 124);
|
||||
}
|
||||
|
||||
table td {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
table tr:hover td, table col:hover td {
|
||||
background: #eeeeee;
|
||||
}
|
||||
|
||||
table tr td:hover {
|
||||
background: #c5dbd8;
|
||||
}
|
||||
|
||||
#projects {
|
||||
margin: 0px;
|
||||
border: 0px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#projects dl {
|
||||
margin: 0px;
|
||||
border: 0px solid white;
|
||||
height: 180px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
#projects #p1 {
|
||||
margin-left: 25%;
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
#projects #p2 {
|
||||
margin-left: 50%;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
#projects #p3 {
|
||||
margin-left: 75%;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
#projects dt, #projects dd {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
#projects #p1 dt, #projects #p1 dd {
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
#projects #p2 dt, #projects #p2 dd {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
#projects #p3 dt, #projects #p3 dd {
|
||||
width: 99%;
|
||||
}
|
||||
|
||||
#projects span {
|
||||
font-size: 0.8em;
|
||||
display: block;
|
||||
padding-left: 1em;
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
|
||||
#projects a {
|
||||
font-size: 0.8em;
|
||||
display: block;
|
||||
padding-left: 0.8em;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
#projects a {
|
||||
color: white;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
#projects span {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
span.since {
|
||||
color: #3c857c;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
span.removed {
|
||||
color: darkred;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
img.diagram {
|
||||
background: rgb(230,230,230);
|
||||
border: 2px dotted rgb(178,178,178);
|
||||
padding: 1em;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
|
||||
table tbody td.y {
|
||||
background: rgb(220,255,220);
|
||||
text-align: center;
|
||||
}
|
||||
table tbody td.n {
|
||||
background: rgb(255,220,220);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.api {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.api .type {
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
color: darkslateblue;
|
||||
}
|
||||
|
||||
.api .keyword {
|
||||
font-weight: bold;
|
||||
color: #A2F;
|
||||
}
|
||||
|
||||
.api .comment {
|
||||
color: #080;
|
||||
margin-left: 2em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.api .comment:before {
|
||||
content: ": ";
|
||||
position: absolute;
|
||||
left: -1.3em;
|
||||
}
|
||||
|
||||
.api .undisclosed {
|
||||
font-style: italic;
|
||||
letter-spacing: .3ex;
|
||||
font-weight: bolder;
|
||||
text-transform: uppercase;
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
.api .directive {
|
||||
color: teal;
|
||||
}
|
||||
|
||||
.api :link:hover, .api :link:focus {
|
||||
color: blue;
|
||||
border-color: blue;
|
||||
}
|
||||
|
||||
.api :link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.api table td,.api table th {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.api table tr:hover td, .api table col:hover td {
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
.api table tr td:hover {
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
dl.variablelist > dt {
|
||||
display: block;
|
||||
float: left;
|
||||
font-style: italic;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
.variablelist dd {
|
||||
padding-left: 10em;
|
||||
}
|
||||
|
||||
dl.variablelist > dt:after {
|
||||
content: ": ";
|
||||
}
|
||||
|
||||
div.description pre.code {
|
||||
border: 1px dashed grey;
|
||||
background-color: inherit;
|
||||
padding: 5px 10px 5px 10px;
|
||||
margin-left: 2.5em;
|
||||
}
|
||||
|
||||
a.headerlink {
|
||||
text-decoration: none!important;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
h1:hover > a.headerlink,
|
||||
h2:hover > a.headerlink,
|
||||
h3:hover > a.headerlink,
|
||||
h4:hover > a.headerlink,
|
||||
h5:hover > a.headerlink,
|
||||
h6:hover > a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
div.panel,
|
||||
#documentation section,
|
||||
#documentation .section,
|
||||
#knowledge-base section,
|
||||
#knowledge-base .section
|
||||
{
|
||||
width: 24%;
|
||||
margin-left: 7%;
|
||||
float: left;
|
||||
background: rgb(230, 230, 230);
|
||||
}
|
||||
|
||||
div.panel h2,
|
||||
#documentation section h2,
|
||||
#documentation .section h1,
|
||||
#knowledge-base section h2,
|
||||
#knowledge-base .section h1 {
|
||||
margin-top: 0px;
|
||||
padding: 0.5em;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
background: rgb(0, 95, 97);
|
||||
color: rgb(255, 255, 255);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#index.document h1 {
|
||||
border: 0px;
|
||||
text-indent: 100%; white-space: nowrap; overflow: hidden;
|
||||
background: url(../logos/logo-banner-dark-800.png) no-repeat center center;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
#documentation > h1,
|
||||
#knowledge-base > h1 {
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
br.clear {
|
||||
clear: both;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
clear: both;
|
||||
border-top: 3px solid rgb(60, 133, 124);
|
||||
margin-top: 2em;
|
||||
padding: 1em;
|
||||
background: rgb(0, 95, 97);
|
||||
color: rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: rgb(255, 230, 0);
|
||||
}
|
||||
|
||||
#conduct {
|
||||
float: right;
|
||||
text-align: right;
|
||||
font-size: smaller;
|
||||
margin-right: 3em;
|
||||
}
|
||||
|
||||
#conduct a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#contact, #community, #contribute {
|
||||
float: left;
|
||||
padding: 0px;
|
||||
margin-left: 3em;
|
||||
}
|
||||
|
||||
#footer h3 {
|
||||
margin:0px;
|
||||
font-size: 1em;
|
||||
color: rgb(60, 133, 124);
|
||||
}
|
||||
|
||||
#footer ul {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
div.panel dd,
|
||||
#documentation dd,
|
||||
#knowledge-base dd {
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
div.panel a,
|
||||
#documentation a,
|
||||
#knowledge-base a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div.panel ul,
|
||||
div.panel p,
|
||||
div.panel dl,
|
||||
#documentation ul,
|
||||
#documentation p,
|
||||
#documentation dl,
|
||||
#knowledge-base ul,
|
||||
#knowledge-base p,
|
||||
#knowledge-base dl {
|
||||
padding: 0.5em;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
div.panel ul,
|
||||
#documentation ul,
|
||||
#knowledge-base ul {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
div.panel dt,
|
||||
#documentation dt,
|
||||
#knowledge-base dt {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
div.panel dd,
|
||||
#documentation dd,
|
||||
#knowledge-base dd {
|
||||
margin: 0px;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
dl.mail dt {
|
||||
background: rgb(0, 97, 95);
|
||||
color: rgb(255, 255, 255);
|
||||
font-weight: bold;
|
||||
padding: 0.5em;
|
||||
}
|
||||
dl.mail dt a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
dl.mail dt a:hover {
|
||||
color: rgb(255, 230, 0);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
td.enumvalue {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#advancedsearch {
|
||||
display: none;
|
||||
vertical-align: bottom;
|
||||
position: absolute;
|
||||
padding: 1em;
|
||||
padding-top: 0em;
|
||||
margin-top: 0em;
|
||||
top: 100px;
|
||||
right: 0px;
|
||||
width: 13em;
|
||||
text-align: left;
|
||||
color: white;
|
||||
background: rgb(0, 95, 97);
|
||||
border-left: 3px solid rgb(60, 133, 124);
|
||||
border-bottom: 3px solid rgb(60, 133, 124);
|
||||
}
|
||||
|
||||
/* Use div.advancedsearch, not #advancedsearch because the
|
||||
* 'advancedsearch' class is set dynamically when javascript
|
||||
* loads. This ensures that the advancedsearch options are
|
||||
* not displayed when javascript is disabled.
|
||||
*/
|
||||
#search:hover div.advancedsearch {
|
||||
display: table;
|
||||
}
|
||||
|
||||
#advancedsearch span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#advancedsearch input[type=radio] {
|
||||
height: inherit;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#advancedsearch label {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.removedhv {
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
.literal, code {
|
||||
font-family: monospace;
|
||||
background: #eeeeee;
|
||||
}
|
||||
|
||||
.contents li p {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
td.gitmirror {
|
||||
font-size: smaller;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
td.gitmirror a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
th p, td p {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
/* Elements with id 'contents' contain the table of contents generated by docutils */
|
||||
|
||||
#contents {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
background: rgb(230, 230, 230);
|
||||
padding: 0.5em;
|
||||
padding-left: 0px;
|
||||
display: inline-block;
|
||||
border: 1px solid #999999;
|
||||
}
|
||||
|
||||
#contents p.topic-title {
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
@import url(fonts.css);
|
||||
@import url(generic.css);
|
||||
@import url(libvirt.css);
|
||||
@import url(mobile.css);
|
|
@ -0,0 +1,17 @@
|
|||
docs_css_files = [
|
||||
'fonts.css',
|
||||
'generic.css',
|
||||
'libvirt.css',
|
||||
'main.css',
|
||||
'mobile.css',
|
||||
]
|
||||
|
||||
install_data(docs_css_files, install_dir: docs_html_dir / 'css')
|
||||
|
||||
foreach file : docs_css_files
|
||||
# This hack enables us to view the web pages
|
||||
# from within the uninstalled build tree
|
||||
configure_file(input: file, output: file, copy: true)
|
||||
|
||||
install_web_files += '@0@:@1@'.format(meson.current_source_dir() / file, docs_html_dir / 'css')
|
||||
endforeach
|
|
@ -0,0 +1,101 @@
|
|||
@media (max-width: 1000px) {
|
||||
#home {
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin: 0px;
|
||||
background: white url(../logos/logo-banner-dark-256.png) no-repeat center center;
|
||||
height: 94px;
|
||||
}
|
||||
#home a {
|
||||
width: 100%;
|
||||
}
|
||||
#search {
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin: 0px;
|
||||
background: white;
|
||||
padding: 0px;
|
||||
height: 2em;
|
||||
}
|
||||
#search form {
|
||||
padding: 5px;
|
||||
}
|
||||
body.index h1 {
|
||||
display: none;
|
||||
}
|
||||
#jumplinks {
|
||||
padding: 0px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin: 0px;
|
||||
height: 1.3em;
|
||||
font-size: 1em;
|
||||
border-top: 3px solid rgb(60, 133, 124);
|
||||
border-bottom: 3px solid rgb(60, 133, 124);
|
||||
}
|
||||
#jumplinks ul {
|
||||
display: block;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
#jumplinks li {
|
||||
margin: 0px;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
#nav {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#search.navhide {
|
||||
display: none !IMPORTANT;
|
||||
}
|
||||
#home.navhide {
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
z-index: 9001;
|
||||
width: 6em;
|
||||
display: block;
|
||||
margin: 0px;
|
||||
background: inherit;
|
||||
height: 1.3em;
|
||||
border-top: 3px solid rgb(60, 133, 124);
|
||||
border-bottom: 3px solid rgb(60, 133, 124);
|
||||
font-size: 1em;
|
||||
text-indent: 0px;
|
||||
font-weight: bold;
|
||||
padding-left: 1em;
|
||||
}
|
||||
#home.navhide a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
#home.navhide a:hover {
|
||||
color: rgb(255, 230, 0);
|
||||
}
|
||||
#jumplinks.navhide {
|
||||
position: fixed;
|
||||
text-align: right;
|
||||
top: 0px;
|
||||
z-index: 9000;
|
||||
background: rgb(0, 95, 97);
|
||||
}
|
||||
#jumplinks.navhide ul {
|
||||
z-index: 9001;
|
||||
}
|
||||
#body {
|
||||
margin-top: 180px;
|
||||
}
|
||||
div.panel {
|
||||
width: 80%;
|
||||
float: none;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
#advancedsearch {
|
||||
margin-top: 4em;
|
||||
border: 0px;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,735 @@
|
|||
===============
|
||||
Libvirt Daemons
|
||||
===============
|
||||
|
||||
.. contents::
|
||||
|
||||
A libvirt deployment for accessing one of the stateful drivers will require
|
||||
one or more daemons to be deployed on the virtualization host. There are a
|
||||
number of ways the daemons can be configured which will be outlined in this
|
||||
page.
|
||||
|
||||
Architectural options
|
||||
=====================
|
||||
|
||||
Monolithic vs modular daemons
|
||||
-----------------------------
|
||||
|
||||
Traditionally libvirt provided a single monolithic daemon called ``libvirtd``
|
||||
which exposed support for all the stateful drivers, both primary hypervisor
|
||||
drivers and secondary supporting drivers. It also enables secure remote access
|
||||
from clients running off host.
|
||||
|
||||
Work is underway for the monolithic daemon to be replaced by a new set of
|
||||
modular daemons ``virt${DRIVER}d``, each one servicing a single stateful
|
||||
driver. A further ``virtproxyd`` daemon will provide secure remote access, as
|
||||
well as backcompatibility for clients using the UNIX socket path of the
|
||||
monolithic daemon.
|
||||
|
||||
The change to modular daemons should not affect API functionality used by
|
||||
management applications. It will, however, have an impact on host provisioning
|
||||
tools since there are new systemd services and configuration files to be
|
||||
managed.
|
||||
|
||||
Currently both monolithic and modular daemons are built by default, but the RPC
|
||||
client still prefers connecting to the monolithic daemon. It is intended to
|
||||
switch the RPC client to prefer the modular daemons in the near future. At
|
||||
least 1 year after this switch (but not more than 2 years), the monolithic
|
||||
daemon will be deleted entirely.
|
||||
|
||||
Operating modes
|
||||
---------------
|
||||
|
||||
The libvirt daemons, whether monolithic or modular, can often operate in two
|
||||
modes
|
||||
|
||||
* *System mode* - the daemon is running as the root user account, enabling
|
||||
access to its full range of functionality. A read-write connection to
|
||||
daemons in system mode **typically implies privileges equivalent to having
|
||||
a root shell**. Suitable `authentication mechanisms <auth.html>`__ **must
|
||||
be enabled** to secure it against untrustworthy clients/users.
|
||||
|
||||
* *Session mode* - the daemon is running as any non-root user account,
|
||||
providing access to a more restricted range of functionality. Only client
|
||||
apps/users running under **the same UID are permitted to connect**, thus a
|
||||
connection does not imply any elevation of privileges.
|
||||
|
||||
Not all drivers support session mode and as such the corresponding
|
||||
modular daemon may not support running in this mode
|
||||
|
||||
|
||||
Monolithic driver daemon
|
||||
========================
|
||||
|
||||
The monolithic daemon is known as ``libvirtd`` and has historically been the
|
||||
default in libvirt. It is configured via the file ``/etc/libvirt/libvirtd.conf``
|
||||
|
||||
|
||||
Monolithic sockets
|
||||
------------------
|
||||
|
||||
When running in system mode, ``libvirtd`` exposes three UNIX domain sockets, and
|
||||
optionally, one or two TCP sockets:
|
||||
|
||||
* ``/var/run/libvirt/libvirt-sock`` - the primary socket for accessing libvirt
|
||||
APIs, with full read-write privileges. A connection to this socket gives the
|
||||
client privileges that are equivalent to having a root shell. This is the
|
||||
socket that most management applications connect to by default.
|
||||
|
||||
* ``/var/run/libvirt/libvirt-sock-ro`` - the secondary socket for accessing
|
||||
libvirt APIs, with limited read-only privileges. A connection to this socket
|
||||
gives the ability to query the existence of objects and monitor some aspects
|
||||
of their operation. This is the socket that most management applications
|
||||
connect to when requesting read only mode. Typically this is what a
|
||||
monitoring app would use.
|
||||
|
||||
* ``/var/run/libvirt/libvirt-admin-sock`` - the administrative socket for
|
||||
controlling operation of the daemon itself (as opposed to drivers it is
|
||||
running). This can be used to dynamically reconfigure some aspects of the
|
||||
daemon and monitor/control connected clients.
|
||||
|
||||
* ``TCP 16509`` - the non-TLS socket for remotely accessing the libvirt APIs,
|
||||
with full read-write privileges. A connection to this socket gives the
|
||||
client privileges that are equivalent to having a root shell. Since it does
|
||||
not use TLS, an `authentication mechanism <auth.html>`__ that provides
|
||||
encryption must be used. Only the GSSAPI/Kerberos mechanism is capable of
|
||||
satisfying this requirement. In general applications should not use this
|
||||
socket except for debugging in a development/test environment.
|
||||
|
||||
* ``TCP 16514`` - the TLS socket for remotely accessing the libvirt APIs,
|
||||
with full read-write privileges. A connection to this socket gives the
|
||||
client privileges that are equivalent to having a root shell. Access control
|
||||
can be enforced either through validation of `x509 certificates
|
||||
<kbase/tlscerts.html>`__, and/or by enabling an `authentication mechanism
|
||||
<auth.html>`__.
|
||||
|
||||
NB, some distros will use ``/run`` instead of ``/var/run``.
|
||||
|
||||
When running in session mode, ``libvirtd`` exposes two UNIX domain sockets:
|
||||
|
||||
* ``$XDG_RUNTIME_DIR/libvirt/libvirt-sock`` - the primary socket for accessing
|
||||
libvirt APIs, with full read-write privileges. A connection to this socket
|
||||
does not alter the privileges that the client already has. This is the
|
||||
socket that most management applications connect to by default.
|
||||
|
||||
* ``$XDG_RUNTIME_DIR/libvirt/libvirt-admin-sock`` - the administrative socket
|
||||
for controlling operation of the daemon itself (as opposed to drivers it is
|
||||
running). This can be used to dynamically reconfigure some aspects of the
|
||||
daemon and monitor/control connected clients.
|
||||
|
||||
Notice that the session mode does not have a separate read-only socket. Since
|
||||
the clients must be running as the same user as the daemon itself, there is
|
||||
not any security benefit from attempting to enforce a read-only mode.
|
||||
|
||||
``$XDG_RUNTIME_DIR`` commonly points to a per-user private location on tmpfs,
|
||||
such as ``/run/user/$UID``.
|
||||
|
||||
|
||||
Monolithic Systemd Integration
|
||||
------------------------------
|
||||
|
||||
When the ``libvirtd`` daemon is managed by ``systemd`` a number of desirable
|
||||
features are available, most notably socket activation.
|
||||
|
||||
Libvirt ships a number of unit files for controlling ``libvirtd``:
|
||||
|
||||
* ``libvirtd.service`` - the main unit file for launching the ``libvirtd``
|
||||
daemon in system mode. The command line arguments passed can be configured by
|
||||
editing ``/etc/sysconfig/libvirtd``. This is typically only needed to control
|
||||
the use of the auto shutdown timeout value. It is recommended that this
|
||||
service unit be configured to start on boot. This is because various
|
||||
libvirt drivers support autostart of their objects. If it is known that
|
||||
autostart is not required, this unit can be left to start on demand.
|
||||
|
||||
* ``libvirtd.socket`` - the unit file corresponding to the main read-write
|
||||
UNIX socket ``/var/run/libvirt/libvirt-sock``. This socket is recommended to
|
||||
be started on boot by default.
|
||||
|
||||
* ``libvirtd-ro.socket`` - the unit file corresponding to the main read-only
|
||||
UNIX socket ``/var/run/libvirt/libvirt-sock-ro``. This socket is recommended
|
||||
to be started on boot by default.
|
||||
|
||||
* ``libvirtd-admin.socket`` - the unit file corresponding to the administrative
|
||||
UNIX socket ``/var/run/libvirt/libvirt-admin-sock``. This socket is
|
||||
recommended to be started on boot by default.
|
||||
|
||||
* ``libvirtd-tcp.socket`` - the unit file corresponding to the TCP 16509 port
|
||||
for non-TLS remote access. This socket should not be configured to start on
|
||||
boot until the administrator has configured a suitable authentication
|
||||
mechanism.
|
||||
|
||||
* ``libvirtd-tls.socket`` - the unit file corresponding to the TCP 16509 port
|
||||
for TLS remote access. This socket should not be configured to start on boot
|
||||
until the administrator has deployed x509 certificates and optionally
|
||||
configured a suitable authentication mechanism.
|
||||
|
||||
NB, some distros will use ``/etc/default`` instead of ``/etc/sysconfig``.
|
||||
|
||||
The socket unit files are newly introduced in 5.6.0. On newly installed hosts
|
||||
the UNIX socket units should be enabled by default. When upgrading an existing
|
||||
host from a previous version of libvirt, the socket unit files will be masked
|
||||
if ``libvirtd`` is currently configured to use the ``--listen`` argument, since
|
||||
the ``--listen`` argument is mutually exclusive with use of socket activation.
|
||||
|
||||
When systemd socket activation is used a number of configuration settings in
|
||||
``libvirtd.conf`` are no longer honoured. Instead these settings must be
|
||||
controlled via the system unit files
|
||||
|
||||
* ``listen_tcp`` - TCP socket usage is enabled by starting the
|
||||
``libvirtd-tcp.socket`` unit file.
|
||||
|
||||
* ``listen_tls`` - TLS socket usage is enabled by starting the
|
||||
``libvirtd-tls.socket`` unit file.
|
||||
|
||||
* ``tcp_port`` - Port for the non-TLS TCP socket, controlled via the
|
||||
``ListenStream`` parameter in the ``libvirtd-tcp.socket`` unit file.
|
||||
|
||||
* ``tls_port`` - Port for the TLS TCP socket, controlled via the
|
||||
``ListenStream`` parameter in the ``libvirtd-tls.socket`` unit file.
|
||||
|
||||
* ``listen_addr`` - IP address to listen on, independently controlled via the
|
||||
``ListenStream`` parameter in the ``libvirtd-tcp.socket`` or
|
||||
``libvirtd-tls.socket`` unit files.
|
||||
|
||||
* ``unix_sock_group`` - UNIX socket group owner, controlled via the
|
||||
``SocketGroup`` parameter in the ``libvirtd.socket`` and
|
||||
``libvirtd-ro.socket`` unit files
|
||||
|
||||
* ``unix_sock_ro_perms`` - read-only UNIX socket permissions, controlled via the
|
||||
``SocketMode`` parameter in the ``libvirtd-ro.socket`` unit file
|
||||
|
||||
* ``unix_sock_rw_perms`` - read-write UNIX socket permissions, controlled via
|
||||
the ``SocketMode`` parameter in the ``libvirtd.socket`` unit file
|
||||
|
||||
* ``unix_sock_admin_perms`` - admin UNIX socket permissions, controlled via the
|
||||
``SocketMode`` parameter in the ``libvirtd-admin.socket`` unit file
|
||||
|
||||
* ``unix_sock_dir`` - directory in which all UNIX sockets are created
|
||||
independently controlled via the ``ListenStream`` parameter in any of the
|
||||
``libvirtd.socket``, ``libvirtd-ro.socket`` and ``libvirtd-admin.socket`` unit
|
||||
files.
|
||||
|
||||
Modular driver daemons
|
||||
======================
|
||||
|
||||
The modular daemons are named after the driver which they are running, with
|
||||
the pattern ``virt${DRIVER}d`` and will become the default in future libvirt.
|
||||
They are configured via the files ``/etc/libvirt/virt${DRIVER}d.conf``
|
||||
|
||||
The following modular daemons currently exist for hypervisor drivers
|
||||
|
||||
* ``virtqemud`` - the QEMU management daemon, for running virtual machines
|
||||
on UNIX platforms, optionally with KVM acceleration, in either system or
|
||||
session mode
|
||||
* ``virtxend`` - the Xen management daemon, for running virtual machines
|
||||
on the Xen hypervisor, in system mode only
|
||||
* ``virtlxcd`` - the Linux Container management daemon, for running LXC guests
|
||||
in system mode only
|
||||
* ``virtbhyved`` - the BHyve management daemon, for running virtual machines
|
||||
on FreeBSD with the BHyve hypervisor, in system mode.
|
||||
* ``virtvboxd`` - the VirtualBox management daemon, for running virtual machines
|
||||
on UNIX platforms.
|
||||
|
||||
The additional modular daemons service secondary drivers
|
||||
|
||||
* ``virtinterfaced`` - the host NIC management daemon, in system mode only
|
||||
* ``virtnetworkd`` - the virtual network management daemon, in system mode only
|
||||
* ``virtnodedevd`` - the host physical device management daemon, in system mode
|
||||
only
|
||||
* ``virtnwfilterd`` - the host firewall management daemon, in system mode only
|
||||
* ``virtsecretd`` - the host secret management daemon, in system or session mode
|
||||
* ``virtstoraged`` - the host storage management daemon, in system or session
|
||||
mode
|
||||
|
||||
|
||||
Modular Sockets
|
||||
---------------
|
||||
|
||||
When running in system mode, ``virt${DRIVER}d`` exposes three UNIX domain
|
||||
sockets:
|
||||
|
||||
* ``/var/run/libvirt/virt${DRIVER}d-sock`` - the primary socket for accessing
|
||||
libvirt APIs, with full read-write privileges. For many of the daemons, a
|
||||
connection to this socket gives the client privileges that are equivalent to
|
||||
having a root shell. This is the socket that most management applications
|
||||
connect to by default.
|
||||
|
||||
* ``/var/run/libvirt/virt${DRIVER}d-sock-ro`` - the secondary socket for
|
||||
accessing libvirt APIs, with limited read-only privileges. A connection to
|
||||
this socket gives the ability to query the existence of objects and monitor
|
||||
some aspects of their operation. This is the socket that most management
|
||||
applications connect to when requesting read only mode. Typically this is
|
||||
what a monitoring app would use.
|
||||
|
||||
* ``/var/run/libvirt/virt${DRIVER}d-admin-sock`` - the administrative socket for
|
||||
controlling operation of the daemon itself (as opposed to drivers it is
|
||||
running). This can be used to dynamically reconfigure some aspects of the
|
||||
daemon and monitor/control connected clients.
|
||||
|
||||
NB, some distros will use ``/run`` instead of ``/var/run``.
|
||||
|
||||
When running in session mode, ``virt${DRIVER}d`` exposes two UNIX domain sockets:
|
||||
|
||||
* ``$XDG_RUNTIME_DIR/libvirt/virt${DRIVER}d-sock`` - the primary socket for
|
||||
accessing libvirt APIs, with full read-write privileges. A connection to this
|
||||
socket does not alter the privileges that the client already has. This is the
|
||||
socket that most management applications connect to by default.
|
||||
|
||||
* ``$XDG_RUNTIME_DIR/libvirt/virt${DRIVER}d-admin-sock`` - the administrative
|
||||
socket for controlling operation of the daemon itself (as opposed to drivers
|
||||
it is running). This can be used to dynamically reconfigure some aspects of
|
||||
the daemon and monitor/control connected clients.
|
||||
|
||||
Notice that the session mode does not have a separate read-only socket. Since
|
||||
the clients must be running as the same user as the daemon itself, there is
|
||||
not any security benefit from attempting to enforce a read-only mode.
|
||||
|
||||
``$XDG_RUNTIME_DIR`` commonly points to a per-user private location on tmpfs,
|
||||
such as ``/run/user/$UID``.
|
||||
|
||||
Modular Systemd Integration
|
||||
---------------------------
|
||||
|
||||
When the ``virt${DRIVER}d`` daemon is managed by ``systemd`` a number of
|
||||
desirable features are available, most notably socket activation.
|
||||
|
||||
Libvirt ships a number of unit files for controlling ``virt${DRIVER}d``:
|
||||
|
||||
* ``virt${DRIVER}d.service`` - the main unit file for launching the
|
||||
``virt${DRIVER}d`` daemon in system mode. The command line arguments passed
|
||||
can be configured by editing ``/etc/sysconfig/virt${DRIVER}d``. This is
|
||||
typically only needed to control the use of the auto shutdown timeout value.
|
||||
It is recommended that this service unit be configured to start on boot.
|
||||
This is because various libvirt drivers support autostart of their objects.
|
||||
If it is known that autostart is not required, this unit can be left to start
|
||||
on demand.
|
||||
|
||||
* ``virt${DRIVER}d.socket`` - the unit file corresponding to the main read-write
|
||||
UNIX socket ``/var/run/libvirt/virt${DRIVER}d-sock``. This socket is
|
||||
recommended to be started on boot by default.
|
||||
|
||||
* ``virt${DRIVER}d-ro.socket`` - the unit file corresponding to the main
|
||||
read-only UNIX socket ``/var/run/libvirt/virt${DRIVER}d-sock-ro``. This
|
||||
socket is recommended to be started on boot by default.
|
||||
|
||||
* ``virt${DRIVER}d-admin.socket`` - the unit file corresponding to the
|
||||
administrative UNIX socket ``/var/run/libvirt/virt${DRIVER}d-admin-sock``.
|
||||
This socket is recommended to be started on boot by default.
|
||||
|
||||
NB, some distros will use ``/etc/default`` instead of ``/etc/sysconfig``.
|
||||
|
||||
The socket unit files are newly introduced in 5.6.0. On newly installed hosts
|
||||
the UNIX socket units should be enabled by default. When upgrading an existing
|
||||
host from a previous version of libvirt, the socket unit files will be masked
|
||||
if ``virt${DRIVER}d`` is currently configured to use the ``--listen`` argument,
|
||||
since the ``--listen`` argument is mutually exclusive with use of socket
|
||||
activation.
|
||||
|
||||
When systemd socket activation is used a number of configuration settings in
|
||||
``virt${DRIVER}d.conf`` are no longer honoured. Instead these settings must be
|
||||
controlled via the system unit files:
|
||||
|
||||
* ``unix_sock_group`` - UNIX socket group owner, controlled via the
|
||||
``SocketGroup`` parameter in the ``virt${DRIVER}d.socket`` and
|
||||
``virt${DRIVER}d-ro.socket`` unit files
|
||||
|
||||
* ``unix_sock_ro_perms`` - read-only UNIX socket permissions, controlled via the
|
||||
``SocketMode`` parameter in the ``virt${DRIVER}d-ro.socket`` unit file
|
||||
|
||||
* ``unix_sock_rw_perms`` - read-write UNIX socket permissions, controlled via
|
||||
the ``SocketMode`` parameter in the ``virt${DRIVER}d.socket`` unit file
|
||||
|
||||
* ``unix_sock_admin_perms`` - admin UNIX socket permissions, controlled via the
|
||||
``SocketMode`` parameter in the ``virt${DRIVER}d-admin.socket`` unit file
|
||||
|
||||
* ``unix_sock_dir`` - directory in which all UNIX sockets are created
|
||||
independently controlled via the ``ListenStream`` parameter in any of the
|
||||
``virt${DRIVER}d.socket``, ``virt${DRIVER}d-ro.socket`` and
|
||||
``virt${DRIVER}d-admin.socket`` unit files.
|
||||
|
||||
Switching to modular daemons
|
||||
----------------------------
|
||||
|
||||
If a host is currently set to use the monolithic ``libvirtd`` daemon and needs
|
||||
to be migrated to the modular daemons a number of services need to be
|
||||
changed. The steps below outline the process on hosts using the systemd init
|
||||
service.
|
||||
|
||||
While it is technically possible to do this while virtual machines are running,
|
||||
it is recommended that virtual machines be stopped or live migrated to a new
|
||||
host first.
|
||||
|
||||
#. Stop the current monolithic daemon and its socket units
|
||||
|
||||
::
|
||||
|
||||
$ systemctl stop libvirtd.service
|
||||
$ systemctl stop libvirtd{,-ro,-admin,-tcp,-tls}.socket
|
||||
|
||||
#. Disable future start of the monolithic daemon
|
||||
|
||||
::
|
||||
|
||||
$ systemctl disable libvirtd.service
|
||||
$ systemctl disable libvirtd{,-ro,-admin,-tcp,-tls}.socket
|
||||
|
||||
For stronger protection it is valid to use ``mask`` instead of ``disable``
|
||||
too.
|
||||
|
||||
#. Enable the new daemons for the particular virtualizationd driver desired,
|
||||
and any of the secondary drivers to accompany it. The following example
|
||||
enables the QEMU driver and all the secondary drivers:
|
||||
|
||||
::
|
||||
|
||||
$ for drv in qemu interface network nodedev nwfilter secret storage
|
||||
do
|
||||
systemctl unmask virt${drv}d.service
|
||||
systemctl unmask virt${drv}d{,-ro,-admin}.socket
|
||||
systemctl enable virt${drv}d.service
|
||||
systemctl enable virt${drv}d{,-ro,-admin}.socket
|
||||
done
|
||||
|
||||
#. Start the sockets for the same set of daemons. There is no need to start the
|
||||
services as they will get started when the first socket connection is
|
||||
established
|
||||
|
||||
::
|
||||
|
||||
$ for drv in qemu network nodedev nwfilter secret storage
|
||||
do
|
||||
systemctl start virt${drv}d{,-ro,-admin}.socket
|
||||
done
|
||||
|
||||
#. If connections from remote hosts need to be supported the proxy daemon
|
||||
must be enabled and started
|
||||
|
||||
::
|
||||
|
||||
$ systemctl unmask virtproxyd.service
|
||||
$ systemctl unmask virtproxyd{,-ro,-admin}.socket
|
||||
$ systemctl enable virtproxyd.service
|
||||
$ systemctl enable virtproxyd{,-ro,-admin}.socket
|
||||
$ systemctl start virtproxyd{,-ro,-admin}.socket
|
||||
|
||||
The UNIX sockets allow for remote access using SSH tunneling. If ``libvirtd``
|
||||
had TCP or TLS sockets configured, those should be started too
|
||||
|
||||
::
|
||||
|
||||
$ systemctl unmask virtproxyd-tls.socket
|
||||
$ systemctl enable virtproxyd-tls.socket
|
||||
$ systemctl start virtproxyd-tls.socket
|
||||
|
||||
Checking whether modular/monolithic mode is in use
|
||||
==================================================
|
||||
|
||||
New distributions are likely to use the modular mode although the upgrade
|
||||
process preserves whichever mode was in use before the upgrade.
|
||||
|
||||
To determine whether modular or monolithic mode is in use on a host running
|
||||
``systemd`` as the init system you can take the following steps:
|
||||
|
||||
#. Check whether the modular daemon infrastructure is in use
|
||||
|
||||
First check whether the modular daemon you are interested (see
|
||||
`Modular driver daemons`_ for a summary of which daemons are provided by
|
||||
libvirt) in is running:
|
||||
|
||||
#. Check ``.socket`` for socket activated services
|
||||
|
||||
::
|
||||
|
||||
# systemctl is-active virtqemud.socket
|
||||
active
|
||||
|
||||
#. Check ``.service`` for always-running daemons
|
||||
|
||||
::
|
||||
|
||||
# systemctl is-active virtqemud.service
|
||||
active
|
||||
|
||||
If either of the above is ``active`` your system is using the modular daemons.
|
||||
|
||||
#. Check whether the monolithic daemon is in use
|
||||
|
||||
#. Check ``libvirtd.socket``
|
||||
|
||||
::
|
||||
|
||||
# systemctl is-active libvirtd.socket
|
||||
active
|
||||
|
||||
#. Check ``libvirtd.service`` for always-running daemon
|
||||
|
||||
::
|
||||
|
||||
# systemctl is-active libvirtd.service
|
||||
active
|
||||
|
||||
If either of the above is ``active`` your system is using the monolithic
|
||||
daemon.
|
||||
|
||||
#. To determine which of the above will be in use on the next boot of the system,
|
||||
substitute ``is-enabled`` for ``is-active`` in the above examples.
|
||||
|
||||
Proxy daemon
|
||||
============
|
||||
|
||||
Proxy sockets
|
||||
-------------
|
||||
|
||||
When running in system mode, ``virtproxyd`` exposes three UNIX domain sockets,
|
||||
and optionally, one or two TCP sockets. These sockets are identical to those
|
||||
provided by the traditional ``libvirtd`` so refer to earlier documentation in
|
||||
this page.
|
||||
|
||||
When running in session mode, ``virtproxyd`` exposes two UNIX domain sockets,
|
||||
which are again identical to those provided by ``libvirtd``.
|
||||
|
||||
Proxy Systemd Integration
|
||||
-------------------------
|
||||
|
||||
When the ``virtproxyd`` daemon is managed by ``systemd`` a number of desirable
|
||||
features are available, most notably socket activation.
|
||||
|
||||
Libvirt ships a number of unit files for controlling ``virtproxyd``:
|
||||
|
||||
* ``virtproxyd.service`` - the main unit file for launching the ``virtproxyd``
|
||||
daemon in system mode. The command line arguments passed can be configured by
|
||||
editing ``/etc/sysconfig/virtproxyd``. This is typically only needed to
|
||||
control the use of the auto shutdown timeout value.
|
||||
|
||||
* ``virtproxyd.socket`` - the unit file corresponding to the main read-write
|
||||
UNIX socket ``/var/run/libvirt/libvirt-sock``. This socket is recommended to
|
||||
be started on boot by default.
|
||||
|
||||
* ``virtproxyd-ro.socket`` - the unit file corresponding to the main read-only
|
||||
UNIX socket ``/var/run/libvirt/libvirt-sock-ro``. This socket is recommended
|
||||
to be started on boot by default.
|
||||
|
||||
* ``virtproxyd-admin.socket`` - the unit file corresponding to the
|
||||
administrative UNIX socket ``/var/run/libvirt/libvirt-admin-sock``. This
|
||||
socket is recommended to be started on boot by default.
|
||||
|
||||
* ``virtproxyd-tcp.socket`` - the unit file corresponding to the TCP 16509 port
|
||||
for non-TLS remote access. This socket should not be configured to start on
|
||||
boot until the administrator has configured a suitable authentication
|
||||
mechanism.
|
||||
|
||||
* ``virtproxyd-tls.socket`` - the unit file corresponding to the TCP 16509 port
|
||||
for TLS remote access. This socket should not be configured to start on boot
|
||||
until the administrator has deployed x509 certificates and optionally
|
||||
configured a suitable authentication mechanism.
|
||||
|
||||
NB, some distros will use ``/etc/default`` instead of ``/etc/sysconfig``.
|
||||
|
||||
The socket unit files are newly introduced in 5.6.0. On newly installed hosts
|
||||
the UNIX socket units should be enabled by default. When upgrading an existing
|
||||
host from a previous version of libvirt, the socket unit files will be masked
|
||||
if ``virtproxyd`` is currently configured to use the ``--listen`` argument, since
|
||||
the ``--listen`` argument is mutually exclusive with use of socket activation.
|
||||
|
||||
When systemd socket activation is used a number of configuration settings in
|
||||
``virtproxyd.conf`` are no longer honoured. Instead these settings must be
|
||||
controlled via the system unit files. Refer to the earlier documentation on
|
||||
the ``libvirtd`` service socket configuration for further information.
|
||||
|
||||
|
||||
Logging daemon
|
||||
==============
|
||||
|
||||
The ``virtlogd`` daemon provides a service for managing log files associated
|
||||
with QEMU virtual machines. The QEMU process is given one or more pipes, the
|
||||
other end of which are owned by the ``virtlogd`` daemon. It will then write
|
||||
data on those pipes to log files, while enforcing a maximum file size and
|
||||
performing log rollover at the size limit.
|
||||
|
||||
Since the daemon holds open anonymous pipe file descriptors, it must never be
|
||||
stopped while any QEMU virtual machines are running. To enable software updates
|
||||
to be applied, the daemon is capable of re-executing itself while keeping all
|
||||
file descriptors open. This can be triggered by sending the daemon ``SIGUSR1``
|
||||
|
||||
Logging Sockets
|
||||
---------------
|
||||
|
||||
When running in system mode, ``virtlogd`` exposes two UNIX domain sockets:
|
||||
|
||||
* ``/var/run/libvirt/virtlogd-sock`` - the primary socket for accessing
|
||||
libvirt APIs, with full read-write privileges. Access to the socket is
|
||||
restricted to the root user.
|
||||
|
||||
* ``/var/run/libvirt/virtlogd-admin-sock`` - the administrative socket for
|
||||
controlling operation of the daemon itself (as opposed to drivers it is
|
||||
running). This can be used to dynamically reconfigure some aspects of the
|
||||
daemon and monitor/control connected clients.
|
||||
|
||||
NB, some distros will use ``/run`` instead of ``/var/run``.
|
||||
|
||||
When running in session mode, ``virtlogd`` exposes two UNIX domain sockets:
|
||||
|
||||
* ``$XDG_RUNTIME_DIR/libvirt/virtlogd-sock`` - the primary socket for
|
||||
accessing libvirt APIs, with full read-write privileges. Access to the
|
||||
socket is restricted to the unprivileged user running the daemon.
|
||||
|
||||
* ``$XDG_RUNTIME_DIR/libvirt/virtlogd-admin-sock`` - the administrative
|
||||
socket for controlling operation of the daemon itself (as opposed to drivers
|
||||
it is running). This can be used to dynamically reconfigure some aspects of
|
||||
the daemon and monitor/control connected clients.
|
||||
|
||||
``$XDG_RUNTIME_DIR`` commonly points to a per-user private location on tmpfs,
|
||||
such as ``/run/user/$UID``.
|
||||
|
||||
Logging Systemd Integration
|
||||
---------------------------
|
||||
|
||||
When the ``virtlogd`` daemon is managed by ``systemd`` a number of desirable
|
||||
features are available, most notably socket activation.
|
||||
|
||||
Libvirt ships a number of unit files for controlling ``virtlogd``:
|
||||
|
||||
* ``virtlogd.service`` - the main unit file for launching the
|
||||
``virtlogd`` daemon in system mode. The command line arguments passed
|
||||
can be configured by editing ``/etc/sysconfig/virtlogd``. This is
|
||||
typically only needed to control the use of the auto shutdown timeout value.
|
||||
|
||||
* ``virtlogd.socket`` - the unit file corresponding to the main read-write
|
||||
UNIX socket ``/var/run/libvirt/virtlogd-sock``. This socket is recommended
|
||||
to be started on boot by default.
|
||||
|
||||
* ``virtlogd-admin.socket`` - the unit file corresponding to the administrative
|
||||
UNIX socket ``/var/run/libvirt/virtlogd-admin-sock``. This socket is
|
||||
recommended to be started on boot by default.
|
||||
|
||||
NB, some distros will use ``/etc/default`` instead of ``/etc/sysconfig``.
|
||||
|
||||
When systemd socket activation is used a number of configuration settings in
|
||||
``virtlogd.conf`` are no longer honoured. Instead these settings must be
|
||||
controlled via the system unit files:
|
||||
|
||||
* ``unix_sock_group`` - UNIX socket group owner, controlled via the
|
||||
``SocketGroup`` parameter in the ``virtlogd.socket`` and
|
||||
``virtlogd-ro.socket`` unit files
|
||||
|
||||
* ``unix_sock_ro_perms`` - read-only UNIX socket permissions, controlled via the
|
||||
``SocketMode`` parameter in the ``virtlogd-ro.socket`` unit file
|
||||
|
||||
* ``unix_sock_rw_perms`` - read-write UNIX socket permissions, controlled via
|
||||
the ``SocketMode`` parameter in the ``virtlogd.socket`` unit file
|
||||
|
||||
* ``unix_sock_admin_perms`` - admin UNIX socket permissions, controlled via the
|
||||
``SocketMode`` parameter in the ``virtlogd-admin.socket`` unit file
|
||||
|
||||
* ``unix_sock_dir`` - directory in which all UNIX sockets are created
|
||||
independently controlled via the ``ListenStream`` parameter in any of the
|
||||
``virtlogd.socket`` and ``virtlogd-admin.socket`` unit files.
|
||||
|
||||
Locking daemon
|
||||
==============
|
||||
|
||||
The ``virtlockd`` daemon provides a service for holding locks against file
|
||||
images and devices serving as backing storage for virtual disks. The locks
|
||||
will be held for as long as there is a QEMU process running with the disk
|
||||
open.
|
||||
|
||||
To ensure continuity of locking, the daemon holds open anonymous file
|
||||
descriptors, it must never be stopped while any QEMU virtual machines are
|
||||
running. To enable software updates to be applied, the daemon is capable of
|
||||
re-executing itself while keeping all file descriptors open. This can be
|
||||
triggered by sending the daemon ``SIGUSR1``
|
||||
|
||||
Locking Sockets
|
||||
---------------
|
||||
|
||||
When running in system mode, ``virtlockd`` exposes two UNIX domain sockets:
|
||||
|
||||
* ``/var/run/libvirt/virtlockd-sock`` - the primary socket for accessing
|
||||
libvirt APIs, with full read-write privileges. Access to the socket is
|
||||
restricted to the root user.
|
||||
|
||||
* ``/var/run/libvirt/virtlockd-admin-sock`` - the administrative socket for
|
||||
controlling operation of the daemon itself (as opposed to drivers it is
|
||||
running). This can be used to dynamically reconfigure some aspects of the
|
||||
daemon and monitor/control connected clients.
|
||||
|
||||
NB, some distros will use ``/run`` instead of ``/var/run``.
|
||||
|
||||
When running in session mode, ``virtlockd`` exposes two UNIX domain sockets:
|
||||
|
||||
* ``$XDG_RUNTIME_DIR/libvirt/virtlockd-sock`` - the primary socket for
|
||||
accessing libvirt APIs, with full read-write privileges. Access to the
|
||||
socket is restricted to the unprivileged user running the daemon.
|
||||
|
||||
* ``$XDG_RUNTIME_DIR/libvirt/virtlockd-admin-sock`` - the administrative
|
||||
socket for controlling operation of the daemon itself (as opposed to drivers
|
||||
it is running). This can be used to dynamically reconfigure some aspects of
|
||||
the daemon and monitor/control connected clients.
|
||||
|
||||
``$XDG_RUNTIME_DIR`` commonly points to a per-user private location on tmpfs,
|
||||
such as ``/run/user/$UID``.
|
||||
|
||||
Locking Systemd Integration
|
||||
---------------------------
|
||||
|
||||
When the ``virtlockd`` daemon is managed by ``systemd`` a number of desirable
|
||||
features are available, most notably socket activation.
|
||||
|
||||
Libvirt ships a number of unit files for controlling ``virtlockd``:
|
||||
|
||||
* ``virtlockd.service`` - the main unit file for launching the
|
||||
``virtlockd`` daemon in system mode. The command line arguments passed
|
||||
can be configured by editing ``/etc/sysconfig/virtlockd``. This is
|
||||
typically only needed to control the use of the auto shutdown timeout value.
|
||||
|
||||
* ``virtlockd.socket`` - the unit file corresponding to the main read-write
|
||||
UNIX socket ``/var/run/libvirt/virtlockd-sock``. This socket is recommended
|
||||
to be started on boot by default.
|
||||
|
||||
* ``virtlockd-admin.socket`` - the unit file corresponding to the administrative
|
||||
UNIX socket ``/var/run/libvirt/virtlockd-admin-sock``. This socket is
|
||||
recommended to be started on boot by default.
|
||||
|
||||
NB, some distros will use ``/etc/default`` instead of ``/etc/sysconfig``.
|
||||
|
||||
When systemd socket activation is used a number of configuration settings in
|
||||
``virtlockd.conf`` are no longer honoured. Instead these settings must be
|
||||
controlled via the system unit files:
|
||||
|
||||
* ``unix_sock_group`` - UNIX socket group owner, controlled via the
|
||||
``SocketGroup`` parameter in the ``virtlockd.socket`` and
|
||||
``virtlockd-ro.socket`` unit files
|
||||
|
||||
* ``unix_sock_ro_perms`` - read-only UNIX socket permissions, controlled via the
|
||||
``SocketMode`` parameter in the ``virtlockd-ro.socket`` unit file
|
||||
|
||||
* ``unix_sock_rw_perms`` - read-write UNIX socket permissions, controlled via
|
||||
the ``SocketMode`` parameter in the ``virtlockd.socket`` unit file
|
||||
|
||||
* ``unix_sock_admin_perms`` - admin UNIX socket permissions, controlled via the
|
||||
``SocketMode`` parameter in the ``virtlockd-admin.socket`` unit file
|
||||
|
||||
* ``unix_sock_dir`` - directory in which all UNIX sockets are created
|
||||
independently controlled via the ``ListenStream`` parameter in any of the
|
||||
``virtlockd.socket`` and ``virtlockd-admin.socket`` unit files.
|
||||
|
||||
Changing command line options for daemons
|
||||
=========================================
|
||||
|
||||
Two ways exist to override the defaults in the provided service files:
|
||||
either a systemd "drop-in" configuration file, or a ``/etc/sysconfig/$daemon``
|
||||
file must be created. For example, to change the command line option
|
||||
for a debug session of ``libvirtd``, create a file
|
||||
``/etc/systemd/system/libvirtd.service.d/debug.conf`` with the following content:
|
||||
|
||||
::
|
||||
|
||||
[Unit]
|
||||
Description=Virtualization daemon, with override from debug.conf
|
||||
|
||||
[Service]
|
||||
Environment=G_DEBUG=fatal-warnings
|
||||
Environment=LIBVIRTD_ARGS="--listen --verbose"
|
||||
|
||||
After changes to systemd "drop-in" configuration files it is required to run
|
||||
``systemctl daemon-reload``.
|
|
@ -0,0 +1,75 @@
|
|||
==================
|
||||
D-Bus API bindings
|
||||
==================
|
||||
|
||||
.. contents::
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
libvirt-dbus wraps libvirt API to provide a high-level object-oriented API
|
||||
better suited for dbus-based applications.
|
||||
|
||||
GIT source repository
|
||||
---------------------
|
||||
|
||||
The D-Bus bindings source code is maintained in a `git <https://git-scm.com/>`__
|
||||
repository available on
|
||||
`gitlab.com <https://gitlab.com/libvirt/libvirt-dbus>`__:
|
||||
|
||||
::
|
||||
|
||||
git clone https://gitlab.com/libvirt/libvirt-dbus.git
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
libvirt-dbus exports libvirt API using D-Bus objects with methods and properties
|
||||
described by interfaces. Currently only local connection to libvirt is exported
|
||||
and the list of supported drivers depends on the type of the bus connection
|
||||
(session or system).
|
||||
|
||||
The name of the libvirt-dbus service is ``org.libvirt``. libvirt-dbus
|
||||
distributes an interface XML descriptions which can be usually found at
|
||||
``/usr/share/dbus-1/interfaces/``.
|
||||
|
||||
By default unprivileged user has access only to the session D-Bus connection. In
|
||||
order to allow specific user "foo" to access the system D-Bus connection you
|
||||
need to create a file ``/etc/dbus-1/system.d/org.libvirt.conf`` that contains:
|
||||
|
||||
::
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
|
||||
<busconfig>
|
||||
|
||||
<policy user="foo">
|
||||
<allow send_destination="org.libvirt"/>
|
||||
</policy>
|
||||
|
||||
</busconfig>
|
||||
|
||||
To get a list of supported drivers for the specific bus connection you can run
|
||||
these commands (not all drivers may be available on the host):
|
||||
|
||||
::
|
||||
|
||||
gdbus introspect --xml --session --dest org.libvirt --object-path /org/libvirt
|
||||
gdbus introspect --xml --system --dest org.libvirt --object-path /org/libvirt
|
||||
|
||||
Every object is introspectable so you can get a list of available interfaces
|
||||
with methods, signals and properties running this command:
|
||||
|
||||
::
|
||||
|
||||
gdbus introspect --xml --system --dest org.libvirt --object-path /org/libvirt/QEMU
|
||||
|
||||
To get a list of domains for specific connection driver you can run this
|
||||
command:
|
||||
|
||||
::
|
||||
|
||||
gdbus call --system --dest org.libvirt --object-path /org/libvirt/QEMU \
|
||||
--method org.libvirt.Connect.ListDomains 0
|
|
@ -0,0 +1,163 @@
|
|||
=============
|
||||
Documentation
|
||||
=============
|
||||
|
||||
Deployment / operation
|
||||
----------------------
|
||||
|
||||
`Applications <apps.html>`__
|
||||
Applications known to use libvirt
|
||||
|
||||
`Manual pages <manpages/index.html>`__
|
||||
Manual pages for libvirt tools / daemons
|
||||
|
||||
`Windows <windows.html>`__
|
||||
Downloads for Windows
|
||||
|
||||
`macOS <macos.html>`__
|
||||
Working with libvirt on macOS
|
||||
|
||||
`Migration <migration.html>`__
|
||||
Migrating guests between machines
|
||||
|
||||
`Daemons <daemons.html>`__
|
||||
Overview of the daemons provided by libvirt
|
||||
|
||||
`Remote access <remote.html>`__
|
||||
Enable remote access over TCP
|
||||
|
||||
`TLS certs <kbase/tlscerts.html>`__
|
||||
Generate and deploy x509 certificates for TLS
|
||||
|
||||
`Authentication <auth.html>`__
|
||||
Configure authentication for the libvirt daemon
|
||||
|
||||
`Access control <acl.html>`__
|
||||
Configure access control libvirt APIs with `polkit <aclpolkit.html>`__
|
||||
|
||||
`Logging <logging.html>`__
|
||||
The library and the daemon logging support
|
||||
|
||||
`Audit log <auditlog.html>`__
|
||||
Audit trail logs for host operations
|
||||
|
||||
`Firewall <firewall.html>`__
|
||||
Firewall and network filter configuration
|
||||
|
||||
`Hooks <hooks.html>`__
|
||||
Hooks for system specific management
|
||||
|
||||
`NSS module <nss.html>`__
|
||||
Enable domain host name translation to IP addresses
|
||||
|
||||
`FAQ <https://wiki.libvirt.org/page/FAQ>`__
|
||||
Frequently asked questions
|
||||
|
||||
Application development
|
||||
-----------------------
|
||||
|
||||
`API reference <html/index.html>`__
|
||||
Reference manual for the C public API, split in
|
||||
`common <html/libvirt-libvirt-common.html>`__,
|
||||
`domain <html/libvirt-libvirt-domain.html>`__,
|
||||
`domain checkpoint <html/libvirt-libvirt-domain-checkpoint.html>`__,
|
||||
`domain snapshot <html/libvirt-libvirt-domain-snapshot.html>`__,
|
||||
`error <html/libvirt-virterror.html>`__,
|
||||
`event <html/libvirt-libvirt-event.html>`__,
|
||||
`host <html/libvirt-libvirt-host.html>`__,
|
||||
`interface <html/libvirt-libvirt-interface.html>`__,
|
||||
`network <html/libvirt-libvirt-network.html>`__,
|
||||
`node device <html/libvirt-libvirt-nodedev.html>`__,
|
||||
`network filter <html/libvirt-libvirt-nwfilter.html>`__,
|
||||
`secret <html/libvirt-libvirt-secret.html>`__,
|
||||
`storage <html/libvirt-libvirt-storage.html>`__,
|
||||
`stream <html/libvirt-libvirt-stream.html>`__ and
|
||||
`admin <html/index-admin.html>`__,
|
||||
`QEMU <html/index-qemu.html>`__,
|
||||
`LXC <html/index-lxc.html>`__ libs
|
||||
|
||||
`Language bindings and API modules <bindings.html>`__
|
||||
Bindings of the libvirt API for
|
||||
`c# <csharp.html>`__,
|
||||
`go <https://pkg.go.dev/libvirt.org/go/libvirt>`__,
|
||||
`java <java.html>`__,
|
||||
`ocaml <https://libvirt.org/ocaml/>`__,
|
||||
`perl <https://search.cpan.org/dist/Sys-Virt/>`__,
|
||||
`python <python.html>`__,
|
||||
`php <php.html>`__,
|
||||
`ruby <https://libvirt.org/ruby/>`__
|
||||
and integration API modules for
|
||||
`D-Bus <dbus.html>`__
|
||||
|
||||
`XML schemas <format.html>`__
|
||||
Description of the XML schemas for
|
||||
`domains <formatdomain.html>`__,
|
||||
`networks <formatnetwork.html>`__,
|
||||
`network ports <formatnetworkport.html>`__,
|
||||
`network filtering <formatnwfilter.html>`__,
|
||||
`storage <formatstorage.html>`__,
|
||||
`storage encryption <formatstorageencryption.html>`__,
|
||||
`capabilities <formatcaps.html>`__,
|
||||
`domain capabilities <formatdomaincaps.html>`__,
|
||||
`storage pool capabilities <formatstoragecaps.html>`__,
|
||||
`node devices <formatnode.html>`__,
|
||||
`secrets <formatsecret.html>`__,
|
||||
`snapshots <formatsnapshot.html>`__,
|
||||
`checkpoints <formatcheckpoint.html>`__,
|
||||
`backup jobs <formatbackup.html>`__
|
||||
|
||||
`URI format <uri.html>`__
|
||||
The URI formats used for connecting to libvirt
|
||||
|
||||
`CGroups <cgroups.html>`__
|
||||
Control groups integration
|
||||
|
||||
`Drivers <drivers.html>`__
|
||||
Hypervisor specific driver information
|
||||
|
||||
`Support guarantees <support.html>`__
|
||||
Details of support status for various interfaces
|
||||
|
||||
`Driver support <hvsupport.html>`__
|
||||
matrix of API support per hypervisor per release
|
||||
|
||||
`Knowledge Base <kbase/index.html>`__
|
||||
Task oriented guides to key features
|
||||
|
||||
Project development
|
||||
-------------------
|
||||
|
||||
`Contributor guidelines <hacking.html>`__
|
||||
General hacking guidelines for contributors
|
||||
|
||||
`Docs style guide <styleguide.html>`__
|
||||
Style guidelines for reStructuredText docs
|
||||
|
||||
`Project strategy <strategy.html>`__
|
||||
Sets a vision for future direction & technical choices
|
||||
|
||||
`CI Testing <ci.html>`__
|
||||
Details of the Continuous Integration testing strategy
|
||||
|
||||
`Bug reports <bugs.html>`__
|
||||
How and where to report bugs and request features
|
||||
|
||||
`Compiling <compiling.html>`__
|
||||
How to compile libvirt
|
||||
|
||||
`Goals <goals.html>`__
|
||||
Terminology and goals of libvirt API
|
||||
|
||||
`API concepts <api.html>`__
|
||||
The libvirt API concepts
|
||||
|
||||
`API extensions <api_extension.html>`__
|
||||
Adding new public libvirt APIs
|
||||
|
||||
`Functional testing <testsuites.html>`__
|
||||
Testing libvirt with
|
||||
`TCK test suite <testtck.html>`__ and
|
||||
`Libvirt-test-API <testapi.html>`__
|
||||
|
||||
`New repo setup <newreposetup.html>`__
|
||||
Procedure for configuring new git repositories for libvirt
|
|
@ -0,0 +1,392 @@
|
|||
=========
|
||||
Downloads
|
||||
=========
|
||||
|
||||
.. contents::
|
||||
|
||||
Project modules
|
||||
---------------
|
||||
|
||||
The libvirt project maintains a number of inter-related modules beyond the core
|
||||
C library/daemon.
|
||||
|
||||
Libvirt
|
||||
~~~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Module
|
||||
- Releases
|
||||
- GIT Repo
|
||||
- Bug Tracker
|
||||
- GIT Mirrors
|
||||
- Resources
|
||||
|
||||
* - libvirt
|
||||
- `libvirt <https://libvirt.org/sources/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt>`__
|
||||
- `api ref <html/index.html>`__
|
||||
`changes <news.html>`__
|
||||
|
||||
Language bindings
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Module
|
||||
- Releases
|
||||
- GIT Repo
|
||||
- Bug Tracker
|
||||
- GIT Mirrors
|
||||
- Resources
|
||||
|
||||
* - C#
|
||||
- `libvirt <https://libvirt.org/sources/csharp/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-csharp>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-csharp/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-csharp>`__
|
||||
-
|
||||
|
||||
* - Go
|
||||
- `libvirt <https://libvirt.org/go/libvirt>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-go-module>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-go-module/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-go-module>`__
|
||||
- `api ref <https://pkg.go.dev/libvirt.org/go/libvirt>`__
|
||||
|
||||
* - Java
|
||||
- `libvirt <https://libvirt.org/sources/java/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-java>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-java/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-java>`__
|
||||
-
|
||||
|
||||
* - OCaml
|
||||
- `libvirt <https://libvirt.org/sources/ocaml/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-ocaml>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-ocaml/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-ocaml>`__
|
||||
-
|
||||
|
||||
* - Perl (Sys::Virt)
|
||||
- `cpan <https://metacpan.org/release/Sys-Virt/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-perl>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-perl/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-perl>`__
|
||||
- `api ref <https://metacpan.org/release/Sys-Virt/>`__
|
||||
`changes <https://libvirt.org/git/?p=libvirt-perl.git;a=blob;f=Changes;hb=HEAD>`__
|
||||
|
||||
* - PHP
|
||||
- `libvirt <https://libvirt.org/sources/php/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-php>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-php/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-php>`__
|
||||
-
|
||||
|
||||
* - Python
|
||||
- `libvirt <https://libvirt.org/sources/python/>`__
|
||||
`pypi <https://pypi.python.org/pypi/libvirt-python>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-python>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-python/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-python>`__
|
||||
-
|
||||
|
||||
* - Ruby
|
||||
- `libvirt <https://libvirt.org/sources/ruby/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-ruby>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-ruby/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-ruby>`__
|
||||
-
|
||||
|
||||
* - Rust
|
||||
- `crates.io <https://crates.io/crates/virt>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-rust>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-rust/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-rust>`__
|
||||
- `api ref <https://docs.rs/virt>`__
|
||||
|
||||
Integration modules
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Module
|
||||
- Releases
|
||||
- GIT Repo
|
||||
- Bug Tracker
|
||||
- GIT Mirrors
|
||||
- Resources
|
||||
|
||||
* - GLib / GConfig / GObject
|
||||
- `libvirt <https://libvirt.org/sources/glib/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-glib>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-glib/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-glib>`__
|
||||
-
|
||||
|
||||
* - Go XML
|
||||
- `libvirt <https://libvirt.org/go/libvirtxml>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-go-xml-module>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-go-xml-module/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-go-xml-module>`__
|
||||
- `api ref <https://pkg.go.dev/libvirt.org/go/libvirtxml>`__
|
||||
|
||||
* - D-Bus
|
||||
- `libvirt <https://libvirt.org/sources/dbus/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-dbus>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-dbus/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-dbus>`__
|
||||
-
|
||||
|
||||
* - Console Proxy
|
||||
- `libvirt <https://libvirt.org/sources/consoleproxy/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-console-proxy>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-console-proxy/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-console-proxy>`__
|
||||
-
|
||||
|
||||
* - CIM provider
|
||||
- `libvirt <https://libvirt.org/sources/CIM/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-cim>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-cim/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-cim>`__
|
||||
-
|
||||
|
||||
* - CIM utils
|
||||
- `libvirt <https://libvirt.org/sources/CIM/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libcmpiutil>`__
|
||||
- `issues <https://gitlab.com/libvirt/libcmpiutil/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libcmpiutil>`__
|
||||
-
|
||||
|
||||
* - SNMP
|
||||
- `libvirt <https://libvirt.org/sources/snmp/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-snmp>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-snmp/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-snmp>`__
|
||||
-
|
||||
|
||||
* - Application Sandbox
|
||||
- `libvirt <https://libvirt.org/sources/sandbox/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-sandbox>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-sandbox/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-sandbox>`__
|
||||
-
|
||||
|
||||
Testing
|
||||
~~~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Module
|
||||
- Releases
|
||||
- GIT Repo
|
||||
- Bug Tracker
|
||||
- GIT Mirrors
|
||||
|
||||
* - TCK
|
||||
- `libvirt <https://libvirt.org/sources/tck/>`__
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-tck>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-tck/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-tck>`__
|
||||
|
||||
* - Test API
|
||||
-
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-test-API>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-test-API/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-test-API>`__
|
||||
|
||||
* - Continuous Integration Config
|
||||
-
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-ci>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-ci/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-ci>`__
|
||||
|
||||
* - CIM Test
|
||||
-
|
||||
- `gitlab <https://gitlab.com/libvirt/cimtest>`__
|
||||
- `issues <https://gitlab.com/libvirt/cimtest/-/issues>`__
|
||||
- `github <https://github.com/libvirt/cimtest>`__
|
||||
|
||||
Documentation
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Module
|
||||
- GIT Repo
|
||||
- Bug Tracker
|
||||
- GIT Mirrors
|
||||
|
||||
* - Publican Brand
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-publican>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-publican/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-publican>`__
|
||||
|
||||
* - App Development Guide
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-appdev-guide>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-appdev-guide/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-appdev-guide>`__
|
||||
|
||||
* - App Development Guide Python
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-appdev-guide-python>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-appdev-guide-python/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-appdev-guide-python>`__
|
||||
|
||||
* - virsh Command Reference
|
||||
- `gitlab <https://gitlab.com/libvirt/libvirt-virshcmdref>`__
|
||||
- `issues <https://gitlab.com/libvirt/libvirt-virshcmdref/-/issues>`__
|
||||
- `github <https://github.com/libvirt/libvirt-virshcmdref>`__
|
||||
|
||||
Primary download site
|
||||
---------------------
|
||||
|
||||
Most modules have releases made available for download on the project site via
|
||||
HTTPS. Some modules are instead made available at alternative locations, for
|
||||
example, the Perl binding is made available only on CPAN.
|
||||
|
||||
- `libvirt.org HTTPS server <https://libvirt.org/sources/>`__
|
||||
|
||||
Primary release schedule
|
||||
------------------------
|
||||
|
||||
The core libvirt module follows a time based plan, with releases made once a
|
||||
month on the 1st of each month give or take a few days. The only exception is at
|
||||
the start of the year where there are two 6 weeks gaps (first release in the
|
||||
middle of Jan, then skip the Feb release), giving a total of 11 releases a year.
|
||||
The Python and Perl modules will aim to release at the same time as the core
|
||||
libvirt module. Other modules have independent ad-hoc releases with no fixed
|
||||
time schedule.
|
||||
|
||||
Release numbering
|
||||
-----------------
|
||||
|
||||
Since libvirt 2.0.0, a time based version numbering rule is applied to the core
|
||||
library releases. As such, the changes in version number have do not have any
|
||||
implications with respect to the scope of features or bugfixes included, the
|
||||
stability of the code, or the API / ABI compatibility (libvirt API / ABI is
|
||||
guaranteed stable forever). The rules applied for changing the libvirt version
|
||||
number are:
|
||||
|
||||
``major``
|
||||
incremented by 1 for the first release of the year (the Jan 15th release)
|
||||
``minor``
|
||||
reset to 0 with every major increment, otherwise incremented by 1 for each
|
||||
monthly release from git master
|
||||
``micro``
|
||||
always 0 for releases from git master, incremented by 1 for each stable
|
||||
maintenance release
|
||||
|
||||
Prior to 2.0.0, the major/minor numbers were incremented fairly arbitrarily, and
|
||||
maintenance releases appended a fourth digit. The language bindings will aim to
|
||||
use the same version number as the most recent core library API they support.
|
||||
The other modules have their own distinct release numbering sequence, though
|
||||
they generally aim to follow the above rules for incrementing major/minor/micro
|
||||
digits.
|
||||
|
||||
Maintenance releases
|
||||
--------------------
|
||||
|
||||
In the git repository are several stable maintenance branches for the core
|
||||
library, matching the pattern ``vmajor.minor-maint``; these branches are forked
|
||||
off the corresponding ``vmajor.minor.0`` formal release, and may have further
|
||||
releases of the form ``vmajor.minor.micro``. These maintenance branches should
|
||||
only contain bug fixes, and no new features, backported from the master branch,
|
||||
and are supported as long as at least one downstream distribution expresses
|
||||
interest in a given branch. These maintenance branches are considered during CVE
|
||||
analysis. In contrast to the primary releases which are made once a month, there
|
||||
is no formal schedule for the maintenance releases, which are made whenever
|
||||
there is a need to make available key bugfixes to downstream consumers. The
|
||||
language bindings and other modules generally do not provide stable branch
|
||||
releases.
|
||||
|
||||
For more details about contents of maintenance releases, see `the wiki
|
||||
page <https://wiki.libvirt.org/page/Maintenance_Releases>`__.
|
||||
|
||||
GIT source repository
|
||||
---------------------
|
||||
|
||||
All modules maintained by the libvirt project have their primary source
|
||||
available in the `libvirt group on GitLab <https://gitlab.com/libvirt/>`__.
|
||||
Each module can be cloned anonymously using:
|
||||
|
||||
::
|
||||
|
||||
git clone https://gitlab.com/libvirt/[module name].git
|
||||
|
||||
In addition to this primary repository, there are mirrored read-only git
|
||||
repositories on GitHub:
|
||||
|
||||
::
|
||||
|
||||
https://github.com/libvirt/
|
||||
|
||||
And there are also read-only mirrors on libvirt.org:
|
||||
|
||||
::
|
||||
|
||||
git clone https://libvirt.org/git/[module name].git
|
||||
|
||||
Note that for most repositories, development happens via merge requests
|
||||
on GitLab. However, for the main `libvirt.git` repository all patch review and
|
||||
discussion only occurs on the `libvir-list <contact.html>`__ mailing list.
|
||||
|
||||
The GitHub repository is read-only and pull requests and issues there are ignored.
|
||||
|
||||
Signing keys
|
||||
------------
|
||||
|
||||
Source RPM packages and tarballs for libvirt and libvirt-python published on
|
||||
this project site are signed with a GPG signature. You should always verify the
|
||||
package signature before using the source to compile binary packages. The
|
||||
following key is currently used to generate the GPG signatures:
|
||||
|
||||
::
|
||||
|
||||
pub 4096R/10084C9C 2020-07-20 Jiří Denemark <jdenemar@redhat.com>
|
||||
Fingerprint=453B 6531 0595 5628 5547 1199 CA68 BE80 1008 4C9C
|
||||
|
||||
It can be downloaded from `this
|
||||
site <https://libvirt.org/sources/gpg_key.asc>`__ or from public GPG key
|
||||
servers.
|
||||
|
||||
Releases prior to libvirt-6.6 were signed with the following GPG key:
|
||||
|
||||
::
|
||||
|
||||
pub dsa1024 2000-05-31 [SC]
|
||||
C744 15BA 7C9C 7F78 F02E 1DC3 4606 B8A5 DE95 BC1F
|
||||
uid [ unknown] Daniel Veillard (Red Hat work email) <veillard@redhat.com>
|
||||
uid [ unknown] Daniel Veillard <Daniel.Veillard@w3.org>
|
||||
|
||||
::
|
||||
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
|
||||
Starting from libvirt-6.6.0 the upstream releases will be done by Jiří Denemark
|
||||
signed with his PGP key:
|
||||
|
||||
pub 4096R/10084C9C 2020-07-20 Jiří Denemark <jdenemar@redhat.com>
|
||||
Fingerprint=453B 6531 0595 5628 5547 1199 CA68 BE80 1008 4C9C
|
||||
|
||||
This message is signed by the old signing key which was used for previous
|
||||
releases.
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQEzBAEBCAAdFiEE20ZoG7ka3OoXD6LUFViLJllr6l0FAl/8H9cACgkQFViLJllr
|
||||
6l3iVwgAm9n703/QoIfPbxT5qGQzWK6LNriEcG2R9MLgFcW+UuGA9cqIBLhH1RaJ
|
||||
q7Gc3gK0dgE2HAF6DxuG5+nkDY6LdmonLOVFWQkMCh41JHFrV6tw8y9hc/RNOb/m
|
||||
gFAl4HpwYisjTRvsTRcpR3ElK6lI0Yu4GY4gJxj5qH4L5exR+kkylwuAxqP+wuyY
|
||||
b/L/tP76F4+Q9SSPj0M01NRVC7V8m3yvnok5y374vtxvRFome0WMELn81vphxBLx
|
||||
X7LQ1LyjvRs0HhN5MutJES5FYDzArTYZfZJozJgE465XrHxMMCbXbZ/AgAs/aD+5
|
||||
x+m2mFplbS57tMEoMBP/ezbbL5wpvA==
|
||||
=KnaO
|
||||
-----END PGP SIGNATURE-----
|
|
@ -0,0 +1,31 @@
|
|||
================
|
||||
Internal drivers
|
||||
================
|
||||
|
||||
- `Hypervisor drivers`_
|
||||
- `Storage drivers <storage.html>`__
|
||||
- `Node device driver <drvnodedev.html>`__
|
||||
- `Secret driver <drvsecret.html>`__
|
||||
|
||||
The libvirt public API delegates its implementation to one or more internal
|
||||
drivers, depending on the `connection URI <uri.html>`__ 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.
|
||||
|
||||
Hypervisor drivers
|
||||
------------------
|
||||
|
||||
The hypervisor drivers currently supported by libvirt are:
|
||||
|
||||
- `LXC <drvlxc.html>`__ - Linux Containers
|
||||
- `OpenVZ <drvopenvz.html>`__
|
||||
- `QEMU/KVM/HVF <drvqemu.html>`__
|
||||
- `Test <drvtest.html>`__ - Used for testing
|
||||
- `VirtualBox <drvvbox.html>`__
|
||||
- `VMware ESX <drvesx.html>`__
|
||||
- `VMware Workstation/Player <drvvmware.html>`__
|
||||
- `Xen <drvxen.html>`__
|
||||
- `Microsoft Hyper-V <drvhyperv.html>`__
|
||||
- `Virtuozzo <drvvirtuozzo.html>`__
|
||||
- `Bhyve <drvbhyve.html>`__ - The BSD Hypervisor
|
||||
- `Cloud Hypervisor <drvch.html>`__
|
|
@ -0,0 +1,584 @@
|
|||
.. role:: since
|
||||
|
||||
============
|
||||
Bhyve driver
|
||||
============
|
||||
|
||||
.. contents::
|
||||
|
||||
Bhyve is a FreeBSD hypervisor. It first appeared in FreeBSD 10.0. However, it's
|
||||
recommended to keep tracking FreeBSD 10-STABLE to make sure all new features of
|
||||
bhyve are supported. In order to enable bhyve on your FreeBSD host, you'll need
|
||||
to load the ``vmm`` kernel module. Additionally, ``if_tap`` and ``if_bridge``
|
||||
modules should be loaded for networking support. Also, :since:`since 3.2.0` the
|
||||
``virt-host-validate(1)`` supports the bhyve host validation and could be used
|
||||
like this:
|
||||
|
||||
::
|
||||
|
||||
$ virt-host-validate bhyve
|
||||
BHYVE: Checking for vmm module : PASS
|
||||
BHYVE: Checking for if_tap module : PASS
|
||||
BHYVE: Checking for if_bridge module : PASS
|
||||
BHYVE: Checking for nmdm module : PASS
|
||||
$
|
||||
|
||||
Additional information on bhyve could be obtained on
|
||||
`bhyve.org <https://bhyve.org/>`__.
|
||||
|
||||
Connections to the Bhyve driver
|
||||
-------------------------------
|
||||
|
||||
The libvirt bhyve driver is a single-instance privileged driver. Some sample
|
||||
connection URIs are:
|
||||
|
||||
::
|
||||
|
||||
bhyve:///system (local access)
|
||||
bhyve+unix:///system (local access)
|
||||
bhyve+ssh://root@example.com/system (remote access, SSH tunnelled)
|
||||
|
||||
Example guest domain XML configurations
|
||||
---------------------------------------
|
||||
|
||||
Example config
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The bhyve driver in libvirt is in its early stage and under active development.
|
||||
So it supports only limited number of features bhyve provides.
|
||||
|
||||
Note: in older libvirt versions, only a single network device and a single disk
|
||||
device were supported per-domain. However, :since:`since 1.2.6` the libvirt
|
||||
bhyve driver supports up to 31 PCI devices.
|
||||
|
||||
Note: the Bhyve driver in libvirt will boot whichever device is first. If you
|
||||
want to install from CD, put the CD device first. If not, put the root HDD
|
||||
first.
|
||||
|
||||
Note: Only the SATA bus is supported. Only ``cdrom``- and ``disk``-type disks
|
||||
are supported.
|
||||
|
||||
::
|
||||
|
||||
<domain type='bhyve'>
|
||||
<name>bhyve</name>
|
||||
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
|
||||
<memory>219136</memory>
|
||||
<currentMemory>219136</currentMemory>
|
||||
<vcpu>1</vcpu>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
</os>
|
||||
<features>
|
||||
<apic/>
|
||||
<acpi/>
|
||||
</features>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file'>
|
||||
<driver name='file' type='raw'/>
|
||||
<source file='/path/to/bhyve_freebsd.img'/>
|
||||
<target dev='hda' bus='sata'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='file' type='raw'/>
|
||||
<source file='/path/to/cdrom.iso'/>
|
||||
<target dev='hdc' bus='sata'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
<model type='virtio'/>
|
||||
<source bridge="virbr0"/>
|
||||
</interface>
|
||||
</devices>
|
||||
</domain>
|
||||
|
||||
(The <disk> sections may be swapped in order to install from *cdrom.iso*.)
|
||||
|
||||
Example config (Linux guest)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Note the addition of <bootloader>.
|
||||
|
||||
::
|
||||
|
||||
<domain type='bhyve'>
|
||||
<name>linux_guest</name>
|
||||
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
|
||||
<memory>131072</memory>
|
||||
<currentMemory>131072</currentMemory>
|
||||
<vcpu>1</vcpu>
|
||||
<bootloader>/usr/local/sbin/grub-bhyve</bootloader>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
</os>
|
||||
<features>
|
||||
<apic/>
|
||||
<acpi/>
|
||||
</features>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='file' type='raw'/>
|
||||
<source file='/path/to/guest_hdd.img'/>
|
||||
<target dev='hda' bus='sata'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='file' type='raw'/>
|
||||
<source file='/path/to/cdrom.iso'/>
|
||||
<target dev='hdc' bus='sata'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
<model type='virtio'/>
|
||||
<source bridge="virbr0"/>
|
||||
</interface>
|
||||
</devices>
|
||||
</domain>
|
||||
|
||||
Example config (Linux UEFI guest, VNC, tablet)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is an example to boot into Fedora 25 installation:
|
||||
|
||||
::
|
||||
|
||||
<domain type='bhyve'>
|
||||
<name>fedora_uefi_vnc_tablet</name>
|
||||
<memory unit='G'>4</memory>
|
||||
<vcpu>2</vcpu>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<loader readonly="yes" type="pflash">/usr/local/share/uefi-firmware/BHYVE_UEFI.fd</loader>
|
||||
</os>
|
||||
<features>
|
||||
<apic/>
|
||||
<acpi/>
|
||||
</features>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='file' type='raw'/>
|
||||
<source file='/path/to/Fedora-Workstation-Live-x86_64-25-1.3.iso'/>
|
||||
<target dev='hdc' bus='sata'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='file' type='raw'/>
|
||||
<source file='/path/to/linux_uefi.img'/>
|
||||
<target dev='hda' bus='sata'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
<model type='virtio'/>
|
||||
<source bridge="virbr0"/>
|
||||
</interface>
|
||||
<serial type="nmdm">
|
||||
<source master="/dev/nmdm0A" slave="/dev/nmdm0B"/>
|
||||
</serial>
|
||||
<graphics type='vnc' port='5904'>
|
||||
<listen type='address' address='127.0.0.1'/>
|
||||
</graphics>
|
||||
<controller type='usb' model='nec-xhci'/>
|
||||
<input type='tablet' bus='usb'/>
|
||||
</devices>
|
||||
</domain>
|
||||
|
||||
Please refer to the `Using UEFI bootrom, VNC, and USB tablet`_ section for a
|
||||
more detailed explanation.
|
||||
|
||||
Guest usage / management
|
||||
------------------------
|
||||
|
||||
Connecting to a guest console
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Guest console connection is supported through the ``nmdm`` device. It could be
|
||||
enabled by adding the following to the domain XML ( :since:`Since 1.2.4` ):
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<devices>
|
||||
<serial type="nmdm">
|
||||
<source master="/dev/nmdm0A" slave="/dev/nmdm0B"/>
|
||||
</serial>
|
||||
</devices>
|
||||
...
|
||||
|
||||
Make sure to load the ``nmdm`` kernel module if you plan to use that.
|
||||
|
||||
Then ``virsh console`` command can be used to connect to the text console of a
|
||||
guest.
|
||||
|
||||
**NB:** Some versions of bhyve have a bug that prevents guests from booting
|
||||
until the console is opened by a client. This bug was fixed in `FreeBSD
|
||||
changeset r262884 <https://svnweb.freebsd.org/changeset/base/262884>`__. If an
|
||||
older version is used, one either has to open a console manually with
|
||||
``virsh console`` to let a guest boot or start a guest using:
|
||||
|
||||
::
|
||||
|
||||
start --console domname
|
||||
|
||||
**NB:** A bootloader configured to require user interaction will prevent the
|
||||
domain from starting (and thus ``virsh console`` or ``start --console`` from
|
||||
functioning) until the user interacts with it manually on the VM host. Because
|
||||
users typically do not have access to the VM host, interactive bootloaders are
|
||||
unsupported by libvirt. *However,* if you happen to run into this scenario and
|
||||
also happen to have access to the Bhyve host machine, you may select a boot
|
||||
option and allow the domain to finish starting by using an alternative terminal
|
||||
client on the VM host to connect to the domain-configured null modem device. One
|
||||
example (assuming ``/dev/nmdm0B`` is configured as the slave end of the domain
|
||||
serial device) is:
|
||||
|
||||
::
|
||||
|
||||
cu -l /dev/nmdm0B
|
||||
|
||||
Converting from domain XML to Bhyve args
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh domxml-to-native`` command can preview the actual ``bhyve`` commands
|
||||
that will be executed for a given domain. It outputs two lines, the first line
|
||||
is a ``bhyveload`` command and the second is a ``bhyve`` command.
|
||||
|
||||
Please note that the ``virsh domxml-to-native`` doesn't do any real actions
|
||||
other than printing the command, for example, it doesn't try to find a proper
|
||||
TAP interface and create it, like what is done when starting a domain; and
|
||||
always returns ``tap0`` for the network interface. So if you're going to run
|
||||
these commands manually, most likely you might want to tweak them.
|
||||
|
||||
::
|
||||
|
||||
# virsh -c "bhyve:///system" domxml-to-native --format bhyve-argv --xml /path/to/bhyve.xml
|
||||
/usr/sbin/bhyveload -m 214 -d /home/user/vm1.img vm1
|
||||
/usr/sbin/bhyve -c 2 -m 214 -A -I -H -P -s 0:0,hostbridge \
|
||||
-s 3:0,virtio-net,tap0,mac=52:54:00:5d:74:e3 -s 2:0,virtio-blk,/home/user/vm1.img \
|
||||
-s 1,lpc -l com1,/dev/nmdm0A vm1
|
||||
|
||||
Using ZFS volumes
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
It's possible to use ZFS volumes as disk devices :since:`since 1.2.8` . An
|
||||
example of domain XML device entry for that will look like:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<disk type='volume' device='disk'>
|
||||
<source pool='zfspool' volume='vol1'/>
|
||||
<target dev='vdb' bus='virtio'/>
|
||||
</disk>
|
||||
...
|
||||
|
||||
Please refer to the `Storage documentation <storage.html>`__ for more details on
|
||||
storage management.
|
||||
|
||||
Using grub2-bhyve or Alternative Bootloaders
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It's possible to boot non-FreeBSD guests by specifying an explicit bootloader,
|
||||
e.g. ``grub-bhyve(1)``. Arguments to the bootloader may be specified as well. If
|
||||
the bootloader is ``grub-bhyve`` and arguments are omitted, libvirt will try and
|
||||
infer boot ordering from user-supplied <boot order='N'> configuration in the
|
||||
domain. Failing that, it will boot the first disk in the domain (either
|
||||
``cdrom``- or ``disk``-type devices). If the disk type is ``disk``, it will
|
||||
attempt to boot from the first partition in the disk image.
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<bootloader>/usr/local/sbin/grub-bhyve</bootloader>
|
||||
<bootloader_args>...</bootloader_args>
|
||||
...
|
||||
|
||||
Caveat: ``bootloader_args`` does not support any quoting. Filenames, etc, must
|
||||
not have spaces or they will be tokenized incorrectly.
|
||||
|
||||
Using UEFI bootrom, VNC, and USB tablet
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:since:`Since 3.2.0` , in addition to
|
||||
`Using grub2-bhyve or Alternative Bootloaders`_, non-FreeBSD
|
||||
guests could be also booted using an UEFI boot ROM, provided both guest OS and
|
||||
installed ``bhyve(1)`` version support UEFI. To use that, ``loader`` should be
|
||||
specified in the ``os`` section:
|
||||
|
||||
::
|
||||
|
||||
<domain type='bhyve'>
|
||||
...
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<loader readonly="yes" type="pflash">/usr/local/share/uefi-firmware/BHYVE_UEFI.fd</loader>
|
||||
</os>
|
||||
...
|
||||
|
||||
This uses the UEFI firmware provided by the
|
||||
`sysutils/bhyve-firmware <https://www.freshports.org/sysutils/bhyve-firmware/>`__
|
||||
FreeBSD port.
|
||||
|
||||
VNC and the tablet input device could be configured this way:
|
||||
|
||||
::
|
||||
|
||||
<domain type='bhyve'>
|
||||
<devices>
|
||||
...
|
||||
<graphics type='vnc' port='5904'>
|
||||
<listen type='address' address='127.0.0.1'/>
|
||||
</graphics>
|
||||
<controller type='usb' model='nec-xhci'/>
|
||||
<input type='tablet' bus='usb'/>
|
||||
</devices>
|
||||
...
|
||||
</domain>
|
||||
|
||||
This way, VNC will be accessible on ``127.0.0.1:5904``.
|
||||
|
||||
Please note that the tablet device requires to have a USB controller of the
|
||||
``nec-xhci`` model. Currently, only a single controller of this type and a
|
||||
single tablet are supported per domain.
|
||||
|
||||
:since:`Since 3.5.0` , it's possible to configure how the video device is
|
||||
exposed to the guest using the ``vgaconf`` attribute:
|
||||
|
||||
::
|
||||
|
||||
<domain type='bhyve'>
|
||||
<devices>
|
||||
...
|
||||
<graphics type='vnc' port='5904'>
|
||||
<listen type='address' address='127.0.0.1'/>
|
||||
</graphics>
|
||||
<video>
|
||||
<driver vgaconf='on'/>
|
||||
<model type='gop' heads='1' primary='yes'/>
|
||||
</video>
|
||||
...
|
||||
</devices>
|
||||
...
|
||||
</domain>
|
||||
|
||||
If not specified, bhyve's default mode for ``vgaconf`` will be used. Please
|
||||
refer to the
|
||||
`bhyve(8) <https://www.freebsd.org/cgi/man.cgi?query=bhyve&sektion=8&manpath=FreeBSD+12-current>`__
|
||||
manual page and the `bhyve wiki <https://wiki.freebsd.org/bhyve>`__ for more
|
||||
details on using the ``vgaconf`` option.
|
||||
|
||||
:since:`Since 3.7.0` , it's possible to use ``autoport`` to let libvirt allocate
|
||||
VNC port automatically (instead of explicitly specifying it with the ``port``
|
||||
attribute):
|
||||
|
||||
::
|
||||
|
||||
<graphics type='vnc' autoport='yes'>
|
||||
|
||||
:since:`Since 6.8.0` , it's possible to set framebuffer resolution using the
|
||||
``resolution`` sub-element:
|
||||
|
||||
::
|
||||
|
||||
<video>
|
||||
<model type='gop' heads='1' primary='yes'>
|
||||
<resolution x='800' y='600'/>
|
||||
</model>
|
||||
</video>
|
||||
|
||||
:since:`Since 6.8.0` , VNC server can be configured to use password based
|
||||
authentication:
|
||||
|
||||
::
|
||||
|
||||
<graphics type='vnc' port='5904' passwd='foobar'>
|
||||
<listen type='address' address='127.0.0.1'/>
|
||||
</graphics>
|
||||
|
||||
Note: VNC password authentication is known to be cryptographically weak.
|
||||
Additionally, the password is passed as a command line argument in clear text.
|
||||
Make sure you understand the risks associated with this feature before using it.
|
||||
|
||||
Clock configuration
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Originally bhyve supported only localtime for RTC. Support for UTC time was
|
||||
introduced in `FreeBSD changeset
|
||||
r284894 <https://svnweb.freebsd.org/changeset/base/284894>`__ for *10-STABLE*
|
||||
and in `changeset r279225 <https://svnweb.freebsd.org/changeset/base/279225>`__
|
||||
for *-CURRENT*. It's possible to use this in libvirt :since:`since 1.2.18` ,
|
||||
just place the following to domain XML:
|
||||
|
||||
::
|
||||
|
||||
<domain type="bhyve">
|
||||
...
|
||||
<clock offset='utc'/>
|
||||
...
|
||||
</domain>
|
||||
|
||||
Please note that if you run the older bhyve version that doesn't support UTC
|
||||
time, you'll fail to start a domain. As UTC is used as a default when you do not
|
||||
specify clock settings, you'll need to explicitly specify 'localtime' in this
|
||||
case:
|
||||
|
||||
::
|
||||
|
||||
<domain type="bhyve">
|
||||
...
|
||||
<clock offset='localtime'/>
|
||||
...
|
||||
</domain>
|
||||
|
||||
e1000 NIC
|
||||
~~~~~~~~~
|
||||
|
||||
As of `FreeBSD changeset
|
||||
r302504 <https://svnweb.freebsd.org/changeset/base/302504>`__ bhyve supports
|
||||
Intel e1000 network adapter emulation. It's supported in libvirt :since:`since
|
||||
3.1.0` and could be used as follows:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<interface type='bridge'>
|
||||
<source bridge='virbr0'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
...
|
||||
|
||||
Sound device
|
||||
~~~~~~~~~~~~
|
||||
|
||||
As of `FreeBSD changeset
|
||||
r349355 <https://svnweb.freebsd.org/changeset/base/349355>`__ bhyve supports
|
||||
sound device emulation. It's supported in libvirt :since:`since 6.7.0` .
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<sound model='ich7'>
|
||||
<audio id='1'/>
|
||||
</sound>
|
||||
<audio id='1' type='oss'>
|
||||
<input dev='/dev/dsp0'/>
|
||||
<output dev='/dev/dsp0'/>
|
||||
</audio>
|
||||
...
|
||||
|
||||
Here, the ``sound`` element specifies the sound device as it's exposed to the
|
||||
guest, with ``ich7`` being the only supported model now, and the ``audio``
|
||||
element specifies how the guest device is mapped to the host sound device.
|
||||
|
||||
Virtio-9p filesystem
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As of `FreeBSD changeset
|
||||
r366413 <https://svnweb.freebsd.org/changeset/base/366413>`__ bhyve supports
|
||||
sharing arbitrary directory tree between the guest and the host. It's supported
|
||||
in libvirt :since:`since 6.9.0` .
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<filesystem>
|
||||
<source dir='/shared/dir'/>
|
||||
<target dir='shared_dir'/>
|
||||
</filesystem>
|
||||
...
|
||||
|
||||
This share could be made read only by adding the ``<readonly/>`` sub-element.
|
||||
|
||||
In the Linux guest, this could be mounted using:
|
||||
|
||||
::
|
||||
|
||||
mount -t 9p shared_dir /mnt/shared_dir
|
||||
|
||||
Wiring guest memory
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:since:`Since 4.4.0` , it's possible to specify that guest memory should be
|
||||
wired and cannot be swapped out as follows:
|
||||
|
||||
::
|
||||
|
||||
<domain type="bhyve">
|
||||
...
|
||||
<memoryBacking>
|
||||
<locked/>
|
||||
</memoryBacking>
|
||||
...
|
||||
</domain>
|
||||
|
||||
CPU topology
|
||||
~~~~~~~~~~~~
|
||||
|
||||
:since:`Since 4.5.0` , it's possible to specify guest CPU topology, if bhyve
|
||||
supports that. Support for specifying guest CPU topology was added to bhyve in
|
||||
`FreeBSD changeset r332298 <https://svnweb.freebsd.org/changeset/base/332298>`__
|
||||
for *-CURRENT*. Example:
|
||||
|
||||
::
|
||||
|
||||
<domain type="bhyve">
|
||||
...
|
||||
<cpu>
|
||||
<topology sockets='1' cores='2' threads='1'/>
|
||||
</cpu>
|
||||
...
|
||||
</domain>
|
||||
|
||||
Ignoring unknown MSRs reads and writes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:since:`Since 5.1.0` , it's possible to make bhyve ignore accesses to
|
||||
unimplemented Model Specific Registers (MSRs). Example:
|
||||
|
||||
::
|
||||
|
||||
<domain type="bhyve">
|
||||
...
|
||||
<features>
|
||||
...
|
||||
<msrs unknown='ignore'/>
|
||||
...
|
||||
</features>
|
||||
...
|
||||
</domain>
|
||||
|
||||
Pass-through of arbitrary bhyve commands
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:since:`Since 5.1.0` , it's possible to pass additional command-line arguments
|
||||
to the bhyve process when starting the domain using the ``<bhyve:commandline>``
|
||||
element under ``domain``. To supply an argument, use the element ``<bhyve:arg>``
|
||||
with the attribute ``value`` set to additional argument to be added. The arg
|
||||
element may be repeated multiple times. To use this XML addition, it is
|
||||
necessary to issue an XML namespace request (the special ``xmlns:name``
|
||||
attribute) that pulls in ``http://libvirt.org/schemas/domain/bhyve/1.0``;
|
||||
typically, the namespace is given the name of ``bhyve``.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
<domain type="bhyve" xmlns:bhyve="http://libvirt.org/schemas/domain/bhyve/1.0">
|
||||
...
|
||||
<bhyve:commandline>
|
||||
<bhyve:arg value='-somebhyvearg'/>
|
||||
</bhyve:commandline>
|
||||
</domain>
|
||||
|
||||
Note that these extensions are for testing and development purposes only. They
|
||||
are **unsupported**, using them may result in inconsistent state, and upgrading
|
||||
either bhyve or libvirtd maybe break behavior of a domain that was relying on a
|
||||
specific commands pass-through.
|
|
@ -0,0 +1,55 @@
|
|||
=======================
|
||||
Cloud Hypervisor driver
|
||||
=======================
|
||||
|
||||
.. contents::
|
||||
|
||||
Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that
|
||||
runs on top of KVM. The project focuses on exclusively running modern,
|
||||
cloud workloads, on top of a limited set of hardware architectures and
|
||||
platforms. Cloud workloads refers to those that are usually run by
|
||||
customers inside a cloud provider. For our purposes this means modern
|
||||
operating systems with most I/O handled by paravirtualised devices
|
||||
(i.e. virtio), no requirement for legacy devices, and 64-bit CPUs.
|
||||
|
||||
The libvirt Cloud Hypervisor driver is intended to be run as a session
|
||||
driver without privileges. The cloud-hypervisor binary itself should be
|
||||
``setcap cap_net_admin+ep`` (in order to create tap interfaces).
|
||||
|
||||
Expected connection URI would be
|
||||
|
||||
``ch:///session``
|
||||
|
||||
|
||||
Example guest domain XML configurations
|
||||
=======================================
|
||||
|
||||
The Cloud Hypervisor driver in libvirt is in its early stage under active
|
||||
development only supporting a limited number of Cloud Hypervisor features.
|
||||
|
||||
Firmware is from
|
||||
`hypervisor-fw <https://github.com/cloud-hypervisor/rust-hypervisor-firmware/releases>`__
|
||||
|
||||
**Note: Only virtio devices are supported**
|
||||
|
||||
::
|
||||
|
||||
<domain type='kvm'>
|
||||
<name>cloudhypervisor</name>
|
||||
<uuid>4dea22b3-1d52-d8f3-2516-782e98ab3fa0</uuid>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<kernel>hypervisor-fw</kernel>
|
||||
</os>
|
||||
<memory unit='G'>2</memory>
|
||||
<devices>
|
||||
<disk type='file'>
|
||||
<source file='disk.raw'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<interface type='ethernet'>
|
||||
<model type='virtio'/>
|
||||
</interface>
|
||||
</devices>
|
||||
<vcpu>2</vcpu>
|
||||
</domain>
|
|
@ -0,0 +1,679 @@
|
|||
.. role:: since
|
||||
|
||||
============================
|
||||
VMware ESX hypervisor driver
|
||||
============================
|
||||
|
||||
.. contents::
|
||||
|
||||
The libvirt VMware ESX driver can manage VMware ESX/ESXi 3.5/4.x/5.x and VMware
|
||||
GSX 2.0, also called VMware Server 2.0, and possibly later versions.
|
||||
:since:`Since 0.8.3` the driver can also connect to a VMware vCenter 2.5/4.x/5.x
|
||||
(VPX).
|
||||
|
||||
Project Links
|
||||
-------------
|
||||
|
||||
- The `VMware ESX and GSX <https://www.vmware.com/>`__ hypervisors
|
||||
|
||||
Deployment pre-requisites
|
||||
-------------------------
|
||||
|
||||
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 `VMware
|
||||
Virtual Infrastructure
|
||||
API <https://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/>`__
|
||||
(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
|
||||
`VMware vSphere
|
||||
API <https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/>`__.
|
||||
|
||||
Connections to the VMware ESX driver
|
||||
------------------------------------
|
||||
|
||||
Some example remote connection URIs for the driver are:
|
||||
|
||||
::
|
||||
|
||||
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)
|
||||
|
||||
**Note**: 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 `remote
|
||||
transport mechanism <remote.html>`__ provided by the remote driver and libvirtd
|
||||
will not work, and you cannot use URIs like ``esx+ssh://example.com``.
|
||||
|
||||
URI Format
|
||||
~~~~~~~~~~
|
||||
|
||||
URIs have this general form (``[...]`` marks an optional part).
|
||||
|
||||
::
|
||||
|
||||
type://[username@]hostname[:port]/[[folder/...]datacenter/[folder/...][cluster/]server][?extraparameters]
|
||||
|
||||
The ``type://`` is either ``esx://`` or ``gsx://`` or ``vpx://`` :since:`since
|
||||
0.8.3` . The driver selects the default port depending on the ``type://``. For
|
||||
``esx://`` and ``vpx://`` the default HTTPS port is 443, for ``gsx://`` it is
|
||||
8333. If the port parameter is given, it overrides the default port.
|
||||
|
||||
A ``vpx://`` 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.
|
||||
|
||||
An example: ESX server ``example-esx.com`` is managed by vCenter
|
||||
``example-vcenter.com`` and part of cluster ``cluster1``. This cluster is part
|
||||
of datacenter ``dc1``.
|
||||
|
||||
::
|
||||
|
||||
vpx://example-vcenter.com/dc1/cluster1/example-esx.com
|
||||
|
||||
Datacenters and clusters can be organized in folders, those have to be specified
|
||||
as well. The driver can handle folders :since:`since 0.9.7` .
|
||||
|
||||
::
|
||||
|
||||
vpx://example-vcenter.com/folder1/dc1/folder2/example-esx.com
|
||||
|
||||
Extra parameters
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Extra parameters can be added to a URI as part of the query string (the part
|
||||
following ``?``). A single parameter is formed by a ``name=value`` pair.
|
||||
Multiple parameters are separated by ``&``.
|
||||
|
||||
::
|
||||
|
||||
?no_verify=1&auto_answer=1&proxy=socks://example-proxy.com:23456
|
||||
|
||||
The driver understands the extra parameters shown below.
|
||||
|
||||
+-----------------+-----------------------------+-----------------------------+
|
||||
| Name | Values | Meaning |
|
||||
+=================+=============================+=============================+
|
||||
| ``transport`` | ``http`` or ``https`` | Overrides the default HTTPS |
|
||||
| | | transport. For ``esx://`` |
|
||||
| | | and ``vpx://`` the default |
|
||||
| | | HTTP port is 80, for |
|
||||
| | | ``gsx://`` it is 8222. |
|
||||
+-----------------+-----------------------------+-----------------------------+
|
||||
| ``vcenter`` | Hostname of a VMware | In order to perform a |
|
||||
| | vCenter or ``*`` | migration the driver needs |
|
||||
| | | to know the VMware vCenter |
|
||||
| | | for the ESX server. If set |
|
||||
| | | to ``*``, the driver |
|
||||
| | | connects to the vCenter |
|
||||
| | | known to the ESX server. |
|
||||
| | | This parameter in useful |
|
||||
| | | when connecting to an ESX |
|
||||
| | | server only. |
|
||||
+-----------------+-----------------------------+-----------------------------+
|
||||
| ``no_verify`` | ``0`` or ``1`` | If set to 1, this disables |
|
||||
| | | libcurl client checks of |
|
||||
| | | the server's SSL |
|
||||
| | | certificate. The default |
|
||||
| | | value is 0. See the |
|
||||
| | | `Certificates for HTTPS`_ |
|
||||
| | | section for details. |
|
||||
+-----------------+-----------------------------+-----------------------------+
|
||||
| ``auto_answer`` | ``0`` or ``1`` | If set to 1, the driver |
|
||||
| | | answers all |
|
||||
| | | `Questions blocking tasks`_ |
|
||||
| | | with the default answer. If |
|
||||
| | | set to 0, questions are |
|
||||
| | | reported as errors. The |
|
||||
| | | default value is 0. |
|
||||
| | | :since:`Since 0.7.5` . |
|
||||
+-----------------+-----------------------------+-----------------------------+
|
||||
| ``proxy`` | ``[type://]host[:port]`` | Allows to specify a proxy |
|
||||
| | | for HTTP and HTTPS |
|
||||
| | | communication. |
|
||||
| | | :since:`Since 0.8.2` . The |
|
||||
| | | optional ``type`` part may |
|
||||
| | | be one of: ``http``, |
|
||||
| | | ``socks``, ``socks4``, |
|
||||
| | | ``socks4a`` or ``socks5``. |
|
||||
| | | The default is ``http`` and |
|
||||
| | | ``socks`` is synonymous for |
|
||||
| | | ``socks5``. The optional |
|
||||
| | | ``port`` allows to override |
|
||||
| | | the default port 1080. |
|
||||
+-----------------+-----------------------------+-----------------------------+
|
||||
|
||||
Authentication
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
In order to perform any useful operation the driver needs to log into the ESX
|
||||
server. Therefore, only ``virConnectOpenAuth`` can be used to connect to an ESX
|
||||
server, ``virConnectOpen`` and ``virConnectOpenReadOnly`` don't work. To log
|
||||
into an ESX server or vCenter the driver will request credentials using the
|
||||
callback passed to the ``virConnectOpenAuth`` 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.
|
||||
|
||||
**Note**: During the ongoing driver development, testing is done using an
|
||||
unrestricted ``root`` account. Problems may occur if you use a restricted
|
||||
account. Detailed testing with restricted accounts has not been done yet.
|
||||
|
||||
Certificates for HTTPS
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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 `secure communication
|
||||
over TLS <remote.html>`__ to a libvirtd one a remote server.
|
||||
|
||||
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 signed by a CA certificate
|
||||
that is typically not known to your client computer and libvirt will report an
|
||||
error like this one:
|
||||
|
||||
::
|
||||
|
||||
error: internal error curl_easy_perform() returned an error: Peer certificate cannot be authenticated with known CA certificates (60)
|
||||
|
||||
Where are two ways to solve this problem:
|
||||
|
||||
- Use the ``no_verify=1`` `Extra parameters`_ to disable server
|
||||
certificate verification.
|
||||
- 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 *Replace a
|
||||
Default Certificate with a CA-Signed Certificate* in the `ESX Configuration
|
||||
Guide <https://www.vmware.com/pdf/vsphere4/r40/vsp_40_esx_server_config.pdf>`__
|
||||
|
||||
Connection problems
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are also other causes for connection problems than those related to
|
||||
`Certificates for HTTPS`_ .
|
||||
|
||||
- As stated before the ESX driver doesn't need the `remote transport
|
||||
mechanism <remote.html>`__ 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 URIs as described in `URI Format`_ are
|
||||
supported by the ESX driver. Here's a collection of possible error messages:
|
||||
|
||||
::
|
||||
|
||||
$ virsh -c esx+tcp://example.com/
|
||||
error: unable to connect to libvirtd at 'example.com': Connection refused
|
||||
|
||||
::
|
||||
|
||||
$ virsh -c esx+tls://example.com/
|
||||
error: Cannot access CA certificate '/etc/pki/CA/cacert.pem': No such file or directory
|
||||
|
||||
::
|
||||
|
||||
$ virsh -c esx+ssh://example.com/
|
||||
error: cannot recv data: ssh: connect to host example.com port 22: Connection refused
|
||||
|
||||
::
|
||||
|
||||
$ virsh -c esx+ssh://example.com/
|
||||
error: cannot recv data: Resource temporarily unavailable
|
||||
|
||||
- :since:`Since 0.7.0` 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.
|
||||
|
||||
::
|
||||
|
||||
$ virsh -c esx://example.com/
|
||||
error: Cannot access CA certificate '/etc/pki/CA/cacert.pem': No such file or directory
|
||||
|
||||
Don't let this error message confuse you. Setting up certificates as
|
||||
described on the `tls certificates <kbase/tlscerts.html>`__ page does not
|
||||
help, as this is not a certificate related problem.
|
||||
|
||||
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.
|
||||
:since:`Since 0.8.3` the error message has been improved in this case:
|
||||
|
||||
::
|
||||
|
||||
$ virsh -c esx://example.com/
|
||||
error: invalid argument in libvirt was built without the 'esx' driver
|
||||
|
||||
Questions blocking tasks
|
||||
------------------------
|
||||
|
||||
Some methods of the VI API start tasks, for example ``PowerOnVM_Task()``. 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.
|
||||
|
||||
The VI API provides the ``AnswerVM()`` 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 ``auto_answer`` query
|
||||
parameter (see `URI Format`_) controls the answering behavior.
|
||||
|
||||
Specialities in the domain XML config
|
||||
-------------------------------------
|
||||
|
||||
There are several specialities in the domain XML config for ESX domains.
|
||||
|
||||
Restrictions
|
||||
~~~~~~~~~~~~
|
||||
|
||||
There are some restrictions for some values of the domain XML config. The driver
|
||||
will complain if this restrictions are violated.
|
||||
|
||||
- Memory size has to be a multiple of 4096
|
||||
- Number of virtual CPU has to be 1 or a multiple of 2. :since:`Since 4.10.0`
|
||||
any number of vCPUs is supported.
|
||||
- Valid MAC address prefixes are ``00:0c:29`` and ``00:50:56``. :since:`Since
|
||||
0.7.6` arbitrary `MAC addresses`_ are supported.
|
||||
|
||||
Datastore references
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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.
|
||||
|
||||
::
|
||||
|
||||
[datastore] directory/filename
|
||||
|
||||
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.
|
||||
|
||||
MAC addresses
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
VMware has registered two MAC address prefixes for domains: ``00:0c:29`` and
|
||||
``00:50:56``. These prefixes are split into ranges for different purposes.
|
||||
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| Range | Purpose |
|
||||
+======================================+======================================+
|
||||
| ``00:0c:29:00:00:00`` - | An ESX server autogenerates MAC |
|
||||
| ``00:0c:29:ff:ff:ff`` | addresses from this range if the VMX |
|
||||
| | file doesn't contain a MAC address |
|
||||
| | when trying to start a domain. |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| ``00:50:56:00:00:00`` - | MAC addresses from this range can by |
|
||||
| ``00:50:56:3f:ff:ff`` | manually assigned by the user in the |
|
||||
| | VI client. |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| ``00:50:56:80:00:00`` - | A VI client autogenerates MAC |
|
||||
| ``00:50:56:bf:ff:ff`` | addresses from this range for newly |
|
||||
| | defined domains. |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
|
||||
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. :since:`Since 0.7.6` the ESX driver sets the prefix for
|
||||
generated MAC addresses to ``00:0c:29``. Before 0.7.6 the ``00:50:56`` prefix
|
||||
was used. Sometimes this resulted in the generation of out-of-range MAC address
|
||||
that were rejected by the ESX server.
|
||||
|
||||
Also :since:`since 0.7.6` 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.
|
||||
|
||||
::
|
||||
|
||||
ethernet0.checkMACAddress = "false"
|
||||
|
||||
:since:`Since 6.6.0` , one can force libvirt to keep the provided MAC address
|
||||
when it's in the reserved VMware range by adding a ``type="static"`` attribute
|
||||
to the ``<mac/>`` element. Note that this attribute is useless if the provided
|
||||
MAC address is outside of the reserved VMWare ranges.
|
||||
|
||||
Available hardware
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
VMware ESX supports different models of SCSI controllers and network cards.
|
||||
|
||||
SCSI controller models
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``auto``
|
||||
This isn't an actual controller model. If specified the ESX driver tries to
|
||||
detect the SCSI controller model referenced in the ``.vmdk`` file and use it.
|
||||
Autodetection fails when a SCSI controller has multiple disks attached and
|
||||
the SCSI controller models referenced in the ``.vmdk`` files are
|
||||
inconsistent. :since:`Since 0.8.3`
|
||||
``buslogic``
|
||||
BusLogic SCSI controller for older guests.
|
||||
``lsilogic``
|
||||
LSI Logic SCSI controller for recent guests.
|
||||
``lsisas1068``
|
||||
LSI Logic SAS 1068 controller. :since:`Since 0.8.0`
|
||||
``vmpvscsi``
|
||||
Special VMware Paravirtual SCSI controller, requires VMware tools inside the
|
||||
guest. See `VMware KB1010398 <https://kb.vmware.com/kb/1010398>`__ for
|
||||
details. :since:`Since 0.8.3`
|
||||
|
||||
Here a domain XML snippet:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<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'/>
|
||||
...
|
||||
|
||||
The controller element is supported :since:`since 0.8.2` . Prior to this
|
||||
``<driver name='lsilogic'/>`` was abused to specify the SCSI controller model.
|
||||
This attribute usage is deprecated now.
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='lsilogic'/>
|
||||
<source file='[local-storage] Fedora11/Fedora11.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
...
|
||||
|
||||
Network card models
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``vlance``
|
||||
AMD PCnet32 network card for older guests.
|
||||
``vmxnet``, ``vmxnet2``, ``vmxnet3``
|
||||
Special VMware VMXnet network card, requires VMware tools inside the guest.
|
||||
See `VMware KB1001805 <https://kb.vmware.com/kb/1001805>`__ for details.
|
||||
``e1000``
|
||||
Intel E1000 network card for recent guests.
|
||||
|
||||
Here a domain XML snippet:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<interface type='bridge'>
|
||||
<mac address='00:50:56:25:48:c7'/>
|
||||
<source bridge='VM Network'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
...
|
||||
|
||||
Import and export of domain XML configs
|
||||
---------------------------------------
|
||||
|
||||
The ESX driver currently supports a native config format known as ``vmware-vmx``
|
||||
to handle VMware VMX configs.
|
||||
|
||||
Converting from VMware VMX config to domain XML config
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh domxml-from-native`` provides a way to convert an existing VMware
|
||||
VMX config into a domain XML config that can then be used by libvirt.
|
||||
|
||||
::
|
||||
|
||||
$ 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>
|
||||
|
||||
Converting from domain XML config to VMware VMX config
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh domxml-to-native`` provides a way to convert a domain XML config
|
||||
into a VMware VMX config.
|
||||
|
||||
::
|
||||
|
||||
$ 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"
|
||||
|
||||
Example domain XML configs
|
||||
--------------------------
|
||||
|
||||
Fedora11 on x86_64
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<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>
|
||||
|
||||
Migration
|
||||
---------
|
||||
|
||||
A migration cannot be initiated on an ESX server directly, a VMware vCenter is
|
||||
necessary for this. The ``vcenter`` query parameter must be set either to the
|
||||
hostname or IP address of the vCenter managing the ESX server or to ``*``.
|
||||
Setting it to ``*`` 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.
|
||||
|
||||
::
|
||||
|
||||
esx://example.com/?vcenter=example-vcenter.com
|
||||
|
||||
Here's an example how to migrate the domain ``Fedora11`` from ESX server
|
||||
``example-src.com`` to ESX server ``example-dst.com`` implicitly involving
|
||||
vCenter ``example-vcenter.com`` using ``virsh``.
|
||||
|
||||
::
|
||||
|
||||
$ 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:
|
||||
|
||||
:since:`Since 0.8.3` you can directly connect to a vCenter. This simplifies
|
||||
migration a bit. Here's the same migration as above but using ``vpx://``
|
||||
connections and assuming both ESX server are in datacenter ``dc1`` and aren't
|
||||
part of a cluster.
|
||||
|
||||
::
|
||||
|
||||
$ 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:
|
||||
|
||||
Scheduler configuration
|
||||
-----------------------
|
||||
|
||||
The driver exposes the ESX CPU scheduler. The parameters listed below are
|
||||
available to control the scheduler.
|
||||
|
||||
``reservation``
|
||||
The amount of CPU resource in MHz that is guaranteed to be available to the
|
||||
domain. Valid values are 0 and greater.
|
||||
``limit``
|
||||
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.
|
||||
``shares``
|
||||
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 ``low``, ``normal`` and ``high``.
|
||||
|
||||
VMware tools
|
||||
------------
|
||||
|
||||
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.
|
||||
|
||||
- ``virDomainGetHostname``
|
||||
- ``virDomainInterfaceAddresses`` (only for the
|
||||
``VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT`` source)
|
||||
- ``virDomainReboot``
|
||||
- ``virDomainShutdown``
|
||||
|
||||
Links
|
||||
-----
|
||||
|
||||
- `VMware vSphere Web Services SDK
|
||||
Documentation <https://www.vmware.com/support/developer/vc-sdk/>`__
|
||||
- `The Role of Memory in VMware ESX Server
|
||||
3 <https://www.vmware.com/pdf/esx3_memory.pdf>`__
|
||||
- `VMware VMX config parameters <https://www.sanbarrow.com/vmx.html>`__
|
||||
- `VMware ESX 4.0 PVSCSI Storage
|
||||
Performance <https://www.vmware.com/pdf/vsp_4_pvscsi_perf.pdf>`__
|
|
@ -0,0 +1,121 @@
|
|||
===================================
|
||||
Microsoft Hyper-V hypervisor driver
|
||||
===================================
|
||||
|
||||
.. contents::
|
||||
|
||||
The libvirt Microsoft Hyper-V driver can manage Hyper-V 2012 R2 and newer.
|
||||
|
||||
Project Links
|
||||
-------------
|
||||
|
||||
- The `Microsoft Hyper-V <https://docs.microsoft.com/en-us/windows-server/virtualization/hyper-v/hyper-v-on-windows-server>`__
|
||||
hypervisor
|
||||
|
||||
Connections to the Microsoft Hyper-V driver
|
||||
-------------------------------------------
|
||||
|
||||
Some example remote connection URIs for the driver are:
|
||||
|
||||
::
|
||||
|
||||
hyperv://example-hyperv.com (over HTTPS)
|
||||
hyperv://example-hyperv.com/?transport=http (over HTTP)
|
||||
|
||||
**Note**: 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 `remote transport mechanism <remote.html>`__ provided by the
|
||||
remote driver and libvirtd will not work, and you cannot use URIs like
|
||||
``hyperv+ssh://example.com``.
|
||||
|
||||
URI Format
|
||||
~~~~~~~~~~
|
||||
|
||||
URIs have this general form (``[...]`` marks an optional part).
|
||||
|
||||
::
|
||||
|
||||
hyperv://[username@]hostname[:port]/[?extraparameters]
|
||||
|
||||
The default HTTPS ports is 5986. If the port parameter is given, it overrides
|
||||
the default port.
|
||||
|
||||
Extra parameters
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Extra parameters can be added to a URI as part of the query string (the part
|
||||
following ``?``). A single parameter is formed by a ``name=value`` pair.
|
||||
Multiple parameters are separated by ``&``.
|
||||
|
||||
::
|
||||
|
||||
?transport=http
|
||||
|
||||
The driver understands the extra parameters shown below.
|
||||
|
||||
+---------------+-----------------------+-------------------------------------+
|
||||
| Name | Values | Meaning |
|
||||
+===============+=======================+=====================================+
|
||||
| ``transport`` | ``http`` or ``https`` | Overrides the default HTTPS |
|
||||
| | | transport. The default HTTP port is |
|
||||
| | | 5985. |
|
||||
+---------------+-----------------------+-------------------------------------+
|
||||
|
||||
Authentication
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
In order to perform any useful operation the driver needs to log into the
|
||||
Hyper-V server. Therefore, only ``virConnectOpenAuth`` can be used to connect to
|
||||
an Hyper-V server, ``virConnectOpen`` and ``virConnectOpenReadOnly`` don't work.
|
||||
To log into an Hyper-V server the driver will request credentials using the
|
||||
callback passed to the ``virConnectOpenAuth`` function. The driver passes the
|
||||
hostname as challenge parameter to the callback.
|
||||
|
||||
**Note**: Currently only ``Basic`` 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.
|
||||
|
||||
::
|
||||
|
||||
winrm set winrm/config/service/auth @{Basic="true"}
|
||||
|
||||
To allow ``Basic`` 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.
|
||||
|
||||
::
|
||||
|
||||
winrm set winrm/config/service @{AllowUnencrypted="true"}
|
||||
|
||||
Version Numbers
|
||||
---------------
|
||||
|
||||
Since Microsoft's build numbers are almost always over 1000, this driver needs
|
||||
to pack the value differently compared to the format defined by
|
||||
``virConnectGetVersion``. To preserve all of the digits, the following format is
|
||||
used:
|
||||
|
||||
::
|
||||
|
||||
major * 100000000 + minor * 1000000 + micro
|
||||
|
||||
This results in ``virsh version`` producing unexpected output.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Windows Release
|
||||
- Kernel Version
|
||||
- libvirt Representation
|
||||
|
||||
* - Windows Server 2012 R2
|
||||
- 6.3.9600
|
||||
- 603.9.600
|
||||
|
||||
* - Windows Server 2016
|
||||
- 10.0.14393
|
||||
- 1000.14.393
|
||||
|
||||
* - Windows Server 2019
|
||||
- 10.0.17763
|
||||
- 1000.17.763
|
|
@ -0,0 +1,670 @@
|
|||
.. role:: since
|
||||
|
||||
====================
|
||||
LXC container driver
|
||||
====================
|
||||
|
||||
.. contents::
|
||||
|
||||
The libvirt LXC driver manages "Linux Containers". At their simplest, containers
|
||||
can just be thought of as a collection of processes, separated from the main
|
||||
host processes via a set of resource namespaces and constrained via control
|
||||
groups resource tunables. The libvirt LXC driver has no dependency on the LXC
|
||||
userspace tools hosted on sourceforge.net. It directly utilizes the relevant
|
||||
kernel features to build the container environment. This allows for sharing of
|
||||
many libvirt technologies across both the QEMU/KVM and LXC drivers. In
|
||||
particular sVirt for mandatory access control, auditing of operations,
|
||||
integration with control groups and many other features.
|
||||
|
||||
Control groups Requirements
|
||||
---------------------------
|
||||
|
||||
In order to control the resource usage of processes inside containers, 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'. Libvirt
|
||||
will not mount the cgroups filesystem itself, leaving this up to the init system
|
||||
to take care of. Systemd will do the right thing in this respect, while for
|
||||
other init systems the ``cgconfig`` init service will be required. For further
|
||||
information, consult the general libvirt `cgroups
|
||||
documentation <cgroups.html>`__.
|
||||
|
||||
Namespace requirements
|
||||
----------------------
|
||||
|
||||
In order to separate processes inside a container from those in the primary
|
||||
"host" OS environment, the libvirt LXC driver requires that certain kernel
|
||||
namespaces are compiled in. Libvirt currently requires the 'mount', 'ipc',
|
||||
'pid', and 'uts' namespaces to be available. If separate network interfaces are
|
||||
desired, then the 'net' namespace is required. If the guest configuration
|
||||
declares a `UID or GID mapping <formatdomain.html#container-boot>`__, the
|
||||
'user' namespace will be enabled to apply these. **A suitably configured UID/GID
|
||||
mapping is a pre-requisite to making containers secure, in the absence of sVirt
|
||||
confinement.**
|
||||
|
||||
Default container setup
|
||||
-----------------------
|
||||
|
||||
Command line arguments
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When the container "init" process is started, it will typically not be given any
|
||||
command line arguments (eg the equivalent of the bootloader args visible in
|
||||
``/proc/cmdline``). If any arguments are desired, then must be explicitly set in
|
||||
the container XML configuration via one or more ``initarg`` elements. For
|
||||
example, to run ``systemd --unit emergency.service`` would use the following XML
|
||||
|
||||
::
|
||||
|
||||
<os>
|
||||
<type arch='x86_64'>exe</type>
|
||||
<init>/bin/systemd</init>
|
||||
<initarg>--unit</initarg>
|
||||
<initarg>emergency.service</initarg>
|
||||
</os>
|
||||
|
||||
Environment variables
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When the container "init" process is started, it will be given several useful
|
||||
environment variables. The following standard environment variables are mandated
|
||||
by `systemd container
|
||||
interface <https://www.freedesktop.org/wiki/Software/systemd/ContainerInterface>`__
|
||||
to be provided by all container technologies on Linux.
|
||||
|
||||
``container``
|
||||
The fixed string ``libvirt-lxc`` to identify libvirt as the creator
|
||||
``container_uuid``
|
||||
The UUID assigned to the container by libvirt
|
||||
``PATH``
|
||||
The fixed string ``/bin:/usr/bin``
|
||||
``TERM``
|
||||
The fixed string ``linux``
|
||||
``HOME``
|
||||
The fixed string ``/``
|
||||
|
||||
In addition to the standard variables, the following libvirt specific
|
||||
environment variables are also provided
|
||||
|
||||
``LIBVIRT_LXC_NAME``
|
||||
The name assigned to the container by libvirt
|
||||
``LIBVIRT_LXC_UUID``
|
||||
The UUID assigned to the container by libvirt
|
||||
``LIBVIRT_LXC_CMDLINE``
|
||||
The unparsed command line arguments specified in the container configuration.
|
||||
Use of this is discouraged, in favour of passing arguments directly to the
|
||||
container init process via the ``initarg`` config element.
|
||||
|
||||
Filesystem mounts
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the absence of any explicit configuration, the container will inherit the
|
||||
host OS filesystem mounts. A number of mount points will be made read only, or
|
||||
re-mounted with new instances to provide container specific data. The following
|
||||
special mounts are setup by libvirt
|
||||
|
||||
- ``/dev`` a new "tmpfs" pre-populated with authorized device nodes
|
||||
- ``/dev/pts`` a new private "devpts" instance for console devices
|
||||
- ``/sys`` the host "sysfs" instance remounted read-only
|
||||
- ``/proc`` a new instance of the "proc" filesystem
|
||||
- ``/proc/sys`` the host "/proc/sys" bind-mounted read-only
|
||||
- ``/sys/fs/selinux`` the host "selinux" instance remounted read-only
|
||||
- ``/sys/fs/cgroup/NNNN`` the host cgroups controllers bind-mounted to only
|
||||
expose the sub-tree associated with the container
|
||||
- ``/proc/meminfo`` a FUSE backed file reflecting memory limits of the
|
||||
container
|
||||
|
||||
Device nodes
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The container init process will be started with ``CAP_MKNOD`` capability removed
|
||||
and blocked from re-acquiring it. As such it will not be able to create any
|
||||
device nodes in ``/dev`` or anywhere else in its filesystems. Libvirt itself
|
||||
will take care of pre-populating the ``/dev`` filesystem with any devices that
|
||||
the container is authorized to use. The current devices that will be made
|
||||
available to all containers are
|
||||
|
||||
- ``/dev/zero``
|
||||
- ``/dev/null``
|
||||
- ``/dev/full``
|
||||
- ``/dev/random``
|
||||
- ``/dev/urandom``
|
||||
- ``/dev/stdin`` symlinked to ``/proc/self/fd/0``
|
||||
- ``/dev/stdout`` symlinked to ``/proc/self/fd/1``
|
||||
- ``/dev/stderr`` symlinked to ``/proc/self/fd/2``
|
||||
- ``/dev/fd`` symlinked to ``/proc/self/fd``
|
||||
- ``/dev/ptmx`` symlinked to ``/dev/pts/ptmx``
|
||||
- ``/dev/console`` symlinked to ``/dev/pts/0``
|
||||
|
||||
In addition, for every console defined in the guest configuration, a symlink
|
||||
will be created from ``/dev/ttyN`` symlinked to the corresponding ``/dev/pts/M``
|
||||
pseudo TTY device. The first console will be ``/dev/tty1``, with further
|
||||
consoles numbered incrementally from there.
|
||||
|
||||
Since /dev/ttyN and /dev/console are linked to the pts devices. The tty device
|
||||
of login program is pts device. The pam module securetty may prevent root user
|
||||
from logging in container. If you want root user to log in container
|
||||
successfully, add the pts device to the file /etc/securetty of container.
|
||||
|
||||
Further block or character devices will be made available to containers
|
||||
depending on their configuration.
|
||||
|
||||
Security considerations
|
||||
-----------------------
|
||||
|
||||
The libvirt LXC driver is fairly flexible in how it can be configured, and as
|
||||
such does not enforce a requirement for strict security separation between a
|
||||
container and the host. This allows it to be used in scenarios where only
|
||||
resource control capabilities are important, and resource sharing is desired.
|
||||
Applications wishing to ensure secure isolation between a container and the host
|
||||
must ensure that they are writing a suitable configuration.
|
||||
|
||||
Network isolation
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
If the guest configuration does not list any network interfaces, the ``network``
|
||||
namespace will not be activated, and thus the container will see all the host's
|
||||
network interfaces. This will allow apps in the container to bind to/connect
|
||||
from TCP/UDP addresses and ports from the host OS. It also allows applications
|
||||
to access UNIX domain sockets associated with the host OS, which are in the
|
||||
abstract namespace. If access to UNIX domains sockets in the abstract namespace
|
||||
is not wanted, then applications should set the ``<privnet/>`` flag in the
|
||||
``<features>....</features>`` element.
|
||||
|
||||
Filesystem isolation
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If the guest configuration does not list any filesystems, then the container
|
||||
will be set up with a root filesystem that matches the host's root filesystem.
|
||||
As noted earlier, only a few locations such as ``/dev``, ``/proc`` and ``/sys``
|
||||
will be altered. This means that, in the absence of restrictions from sVirt, a
|
||||
process running as user/group N:M inside the container will be able to access
|
||||
almost exactly the same files as a process running as user/group N:M in the
|
||||
host.
|
||||
|
||||
There are multiple options for restricting this. It is possible to simply map
|
||||
the existing root filesystem through to the container in read-only mode.
|
||||
Alternatively a completely separate root filesystem can be configured for the
|
||||
guest. In both cases, further sub-mounts can be applied to customize the content
|
||||
that is made visible. Note that in the absence of sVirt controls, it is still
|
||||
possible for the root user in a container to unmount any sub-mounts applied. The
|
||||
user namespace feature can also be used to restrict access to files based on the
|
||||
UID/GID mappings.
|
||||
|
||||
Sharing the host filesystem tree, also allows applications to access UNIX
|
||||
domains sockets associated with the host OS, which are in the filesystem
|
||||
namespaces. It should be noted that a number of init systems including at least
|
||||
``systemd`` and ``upstart`` have UNIX domain socket which are used to control
|
||||
their operation. Thus, if the directory/filesystem holding their UNIX domain
|
||||
socket is exposed to the container, it will be possible for a user in the
|
||||
container to invoke operations on the init service in the same way it could if
|
||||
outside the container. This also applies to other applications in the host which
|
||||
use UNIX domain sockets in the filesystem, such as DBus, Libvirtd, and many
|
||||
more. If this is not desired, then applications should either specify the
|
||||
UID/GID mapping in the configuration to enable user namespaces and thus block
|
||||
access to the UNIX domain socket based on permissions, or should ensure the
|
||||
relevant directories have a bind mount to hide them. This is particularly
|
||||
important for the ``/run`` or ``/var/run`` directories.
|
||||
|
||||
User and group isolation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If the guest configuration does not list any ID mapping, then the user and group
|
||||
IDs used inside the container will match those used outside the container. In
|
||||
addition, the capabilities associated with a process in the container will infer
|
||||
the same privileges they would for a process in the host. This has obvious
|
||||
implications for security, since a root user inside the container will be able
|
||||
to access any file owned by root that is visible to the container, and perform
|
||||
more or less any privileged kernel operation. In the absence of additional
|
||||
protection from sVirt, this means that the root user inside a container is
|
||||
effectively as powerful as the root user in the host. There is no security
|
||||
isolation of the root user.
|
||||
|
||||
The ID mapping facility was introduced to allow for stricter control over the
|
||||
privileges of users inside the container. It allows apps to define rules such as
|
||||
"user ID 0 in the container maps to user ID 1000 in the host". In addition the
|
||||
privileges associated with capabilities are somewhat reduced so that they cannot
|
||||
be used to escape from the container environment. A full description of user
|
||||
namespaces is outside the scope of this document, however LWN has `a good
|
||||
write-up on the topic <https://lwn.net/Articles/532593/>`__. From the libvirt
|
||||
point of view, the key thing to remember is that defining an ID mapping for
|
||||
users and groups in the container XML configuration causes libvirt to activate
|
||||
the user namespace feature.
|
||||
|
||||
Location of configuration files
|
||||
-------------------------------
|
||||
|
||||
The LXC driver comes with sane default values. However, during its
|
||||
initialization it reads a configuration file which offers system administrator
|
||||
to override some of that default. The file is located under
|
||||
``/etc/libvirt/lxc.conf``
|
||||
|
||||
Systemd Socket Activation Integration
|
||||
-------------------------------------
|
||||
|
||||
The libvirt LXC driver provides the ability to pass across pre-opened file
|
||||
descriptors when starting LXC guests. This allows for libvirt LXC to support
|
||||
systemd's `socket activation
|
||||
capability <https://0pointer.de/blog/projects/socket-activated-containers.html>`__,
|
||||
where an incoming client connection in the host OS will trigger the startup of a
|
||||
container, which runs another copy of systemd which gets passed the server
|
||||
socket, and then activates the actual service handler in the container.
|
||||
|
||||
Let us assume that you already have a LXC guest created, running a systemd
|
||||
instance as PID 1 inside the container, which has an SSHD service configured.
|
||||
The goal is to automatically activate the container when the first SSH
|
||||
connection is made. The first step is to create a couple of unit files for the
|
||||
host OS systemd instance. The ``/etc/systemd/system/mycontainer.service`` unit
|
||||
file specifies how systemd will start the libvirt LXC container
|
||||
|
||||
::
|
||||
|
||||
[Unit]
|
||||
Description=My little container
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/virsh -c lxc:///system start --pass-fds 3 mycontainer
|
||||
ExecStop=/usr/bin/virsh -c lxc:///system destroy mycontainer
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
KillMode=none
|
||||
|
||||
The ``--pass-fds 3`` argument specifies that the file descriptor number 3 that
|
||||
``virsh`` inherits from systemd, is to be passed into the container. Since
|
||||
``virsh`` will exit immediately after starting the container, the
|
||||
``RemainAfterExit`` and ``KillMode`` settings must be altered from their
|
||||
defaults.
|
||||
|
||||
Next, the ``/etc/systemd/system/mycontainer.socket`` unit file is created to get
|
||||
the host systemd to listen on port 23 for TCP connections. When this unit file
|
||||
is activated by the first incoming connection, it will cause the
|
||||
``mycontainer.service`` unit to be activated with the FD corresponding to the
|
||||
listening TCP socket passed in as FD 3.
|
||||
|
||||
::
|
||||
|
||||
[Unit]
|
||||
Description=The SSH socket of my little container
|
||||
|
||||
[Socket]
|
||||
ListenStream=23
|
||||
|
||||
Port 23 was picked here so that the container doesn't conflict with the host's
|
||||
SSH which is on the normal port 22. That's it in terms of host side
|
||||
configuration.
|
||||
|
||||
Inside the container, the ``/etc/systemd/system/sshd.socket`` unit file must be
|
||||
created
|
||||
|
||||
::
|
||||
|
||||
[Unit]
|
||||
Description=SSH Socket for Per-Connection Servers
|
||||
|
||||
[Socket]
|
||||
ListenStream=23
|
||||
Accept=yes
|
||||
|
||||
The ``ListenStream`` value listed in this unit file, must match the value used
|
||||
in the host file. When systemd in the container receives the pre-opened FD from
|
||||
libvirt during container startup, it looks at the ``ListenStream`` values to
|
||||
figure out which FD to give to which service. The actual service to start is
|
||||
defined by a correspondingly named ``/etc/systemd/system/sshd@.service``
|
||||
|
||||
::
|
||||
|
||||
[Unit]
|
||||
Description=SSH Per-Connection Server for %I
|
||||
|
||||
[Service]
|
||||
ExecStart=-/usr/sbin/sshd -i
|
||||
StandardInput=socket
|
||||
|
||||
Finally, make sure this SSH service is set to start on boot of the container, by
|
||||
running the following command inside the container:
|
||||
|
||||
::
|
||||
|
||||
# mkdir -p /etc/systemd/system/sockets.target.wants/
|
||||
# ln -s /etc/systemd/system/sshd.socket /etc/systemd/system/sockets.target.wants/
|
||||
|
||||
This example shows how to activate the container based on an incoming SSH
|
||||
connection. If the container was also configured to have an httpd service, it
|
||||
may be desirable to activate it upon either an httpd or a sshd connection
|
||||
attempt. In this case, the ``mycontainer.socket`` file in the host would simply
|
||||
list multiple socket ports. Inside the container a separate ``xxxxx.socket``
|
||||
file would need to be created for each service, with a corresponding
|
||||
``ListenStream`` value set.
|
||||
|
||||
Container security
|
||||
------------------
|
||||
|
||||
sVirt SELinux
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
In the absence of the "user" namespace being used, containers cannot be
|
||||
considered secure against exploits of the host OS. The sVirt SELinux driver
|
||||
provides a way to secure containers even when the "user" namespace is not used.
|
||||
The cost is that writing a policy to allow execution of arbitrary OS is not
|
||||
practical. The SELinux sVirt policy is typically tailored to work with a simpler
|
||||
application confinement use case, as provided by the "libvirt-sandbox" project.
|
||||
|
||||
Auditing
|
||||
~~~~~~~~
|
||||
|
||||
The LXC driver is integrated with libvirt's auditing subsystem, which causes
|
||||
audit messages to be logged whenever there is an operation performed against a
|
||||
container which has impact on host resources. So for example, start/stop, device
|
||||
hotplug will all log audit messages providing details about what action occurred
|
||||
and any resources associated with it. There are the following 3 types of audit
|
||||
messages
|
||||
|
||||
- ``VIRT_MACHINE_ID`` - details of the SELinux process and image security
|
||||
labels assigned to the container.
|
||||
- ``VIRT_CONTROL`` - details of an action / operation performed against a
|
||||
container. There are the following types of operation
|
||||
|
||||
- ``op=start`` - a container has been started. Provides the machine name,
|
||||
uuid and PID of the ``libvirt_lxc`` controller process
|
||||
- ``op=init`` - the init PID of the container has been started. Provides the
|
||||
machine name, uuid and PID of the ``libvirt_lxc`` controller process and
|
||||
PID of the init process (in the host PID namespace)
|
||||
- ``op=stop`` - a container has been stopped. Provides the machine name,
|
||||
uuid
|
||||
|
||||
- ``VIRT_RESOURCE`` - details of a host resource associated with a container
|
||||
action.
|
||||
|
||||
Device access
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
All containers are launched with the CAP_MKNOD capability cleared and removed
|
||||
from the bounding set. Libvirt will ensure that the /dev filesystem is
|
||||
pre-populated with all devices that a container is allowed to use. In addition,
|
||||
the cgroup "device" controller is configured to block read/write/mknod from all
|
||||
devices except those that a container is authorized to use.
|
||||
|
||||
Example configurations
|
||||
----------------------
|
||||
|
||||
Example config version 1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<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>
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
::
|
||||
|
||||
<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>
|
||||
|
||||
Altering the available capabilities
|
||||
-----------------------------------
|
||||
|
||||
By default the libvirt LXC driver drops some capabilities among which CAP_MKNOD.
|
||||
However :since:`since 1.2.6` libvirt can be told to keep or drop some
|
||||
capabilities using a domain configuration like the following:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<features>
|
||||
<capabilities policy='default'>
|
||||
<mknod state='on'/>
|
||||
<sys_chroot state='off'/>
|
||||
</capabilities>
|
||||
</features>
|
||||
...
|
||||
|
||||
The capabilities children elements are named after the capabilities as defined
|
||||
in ``man 7 capabilities``. An ``off`` state tells libvirt to drop the
|
||||
capability, while an ``on`` state will force to keep the capability even though
|
||||
this one is dropped by default.
|
||||
|
||||
The ``policy`` attribute can be one of ``default``, ``allow`` or ``deny``. It
|
||||
defines the default rules for capabilities: either keep the default behavior
|
||||
that is dropping a few selected capabilities, or keep all capabilities or drop
|
||||
all capabilities. The interest of ``allow`` and ``deny`` is that they guarantee
|
||||
that all capabilities will be kept (or removed) even if new ones are added
|
||||
later.
|
||||
|
||||
The following example, drops all capabilities but CAP_MKNOD:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<features>
|
||||
<capabilities policy='deny'>
|
||||
<mknod state='on'/>
|
||||
</capabilities>
|
||||
</features>
|
||||
...
|
||||
|
||||
Note that allowing capabilities that are normally dropped by default can
|
||||
seriously affect the security of the container and the host.
|
||||
|
||||
Inherit namespaces
|
||||
------------------
|
||||
|
||||
Libvirt allows you to inherit the namespace from container/process just like lxc
|
||||
tools or docker provides to share the network namespace. The following can be
|
||||
used to share required namespaces. If we want to share only one then the other
|
||||
namespaces can be ignored. The netns option is specific to sharenet. It can be
|
||||
used in cases we want to use existing network namespace rather than creating new
|
||||
network namespace for the container. In this case privnet option will be
|
||||
ignored.
|
||||
|
||||
::
|
||||
|
||||
<domain type='lxc' xmlns:lxc='http://libvirt.org/schemas/domain/lxc/1.0'>
|
||||
...
|
||||
<lxc:namespace>
|
||||
<lxc:sharenet type='netns' value='red'/>
|
||||
<lxc:shareuts type='name' value='container1'/>
|
||||
<lxc:shareipc type='pid' value='12345'/>
|
||||
</lxc:namespace>
|
||||
</domain>
|
||||
|
||||
The use of namespace passthrough requires libvirt >= 1.2.19
|
||||
|
||||
Container usage / management
|
||||
----------------------------
|
||||
|
||||
As with any libvirt virtualization driver, LXC containers can be managed via a
|
||||
wide variety of libvirt based tools. At the lowest level the ``virsh`` command
|
||||
can be used to perform many tasks, by passing the ``-c lxc:///system`` argument.
|
||||
As an alternative to repeating the URI with every command, the
|
||||
``LIBVIRT_DEFAULT_URI`` environment variable can be set to ``lxc:///system``.
|
||||
The examples that follow outline some common operations with virsh and LXC. For
|
||||
further details about usage of virsh consult its manual page.
|
||||
|
||||
Defining (saving) container configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh define`` command takes an XML configuration document and loads it
|
||||
into libvirt, saving the configuration on disk
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system define myguest.xml
|
||||
|
||||
Viewing container configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh dumpxml`` command can be used to view the current XML configuration
|
||||
of a container. By default the XML output reflects the current state of the
|
||||
container. If the container is running, it is possible to explicitly request the
|
||||
persistent configuration, instead of the current live configuration using the
|
||||
``--inactive`` flag
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system dumpxml myguest
|
||||
|
||||
Starting containers
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh start`` command can be used to start a container from a previously
|
||||
defined persistent configuration
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system start myguest
|
||||
|
||||
It is also possible to start so called "transient" containers, which do not
|
||||
require a persistent configuration to be saved by libvirt, using the
|
||||
``virsh create`` command.
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system create myguest.xml
|
||||
|
||||
Stopping containers
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh shutdown`` command can be used to request a graceful shutdown of the
|
||||
container. By default this command will first attempt to send a message to the
|
||||
init process via the ``/dev/initctl`` device node. If no such device node
|
||||
exists, then it will send SIGTERM to PID 1 inside the container.
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system shutdown myguest
|
||||
|
||||
If the container does not respond to the graceful shutdown request, it can be
|
||||
forcibly stopped using the ``virsh destroy``
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system destroy myguest
|
||||
|
||||
Rebooting a container
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh reboot`` command can be used to request a graceful shutdown of the
|
||||
container. By default this command will first attempt to send a message to the
|
||||
init process via the ``/dev/initctl`` device node. If no such device node
|
||||
exists, then it will send SIGHUP to PID 1 inside the container.
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system reboot myguest
|
||||
|
||||
Undefining (deleting) a container configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh undefine`` command can be used to delete the persistent
|
||||
configuration of a container. If the guest is currently running, this will turn
|
||||
it into a "transient" guest.
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system undefine myguest
|
||||
|
||||
Connecting to a container console
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh console`` command can be used to connect to the text console
|
||||
associated with a container.
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system console myguest
|
||||
|
||||
If the container has been configured with multiple console devices, then the
|
||||
``--devname`` argument can be used to choose the console to connect to. In LXC,
|
||||
multiple consoles will be named as 'console0', 'console1', 'console2', etc.
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system console myguest --devname console1
|
||||
|
||||
Running commands in a container
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh lxc-enter-namespace`` command can be used to enter the namespaces
|
||||
and security context of a container and then execute an arbitrary command.
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system lxc-enter-namespace myguest -- /bin/ls -al /dev
|
||||
|
||||
Monitoring container utilization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virt-top`` command can be used to monitor the activity and resource
|
||||
utilization of all containers on a host
|
||||
|
||||
::
|
||||
|
||||
# virt-top -c lxc:///system
|
||||
|
||||
Converting LXC container configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh domxml-from-native`` command can be used to convert most of the LXC
|
||||
container configuration into a domain XML fragment
|
||||
|
||||
::
|
||||
|
||||
# virsh -c lxc:///system domxml-from-native lxc-tools /var/lib/lxc/myguest/config
|
||||
|
||||
This conversion has some limitations due to the fact that the domxml-from-native
|
||||
command output has to be independent of the host. Here are a few things to take
|
||||
care of before converting:
|
||||
|
||||
- Replace the fstab file referenced by lxc.mount by the corresponding
|
||||
lxc.mount.entry lines.
|
||||
- Replace all relative sizes of tmpfs mount entries to absolute sizes. Also
|
||||
make sure that tmpfs entries all have a size option (default is 50%).
|
||||
- Define lxc.cgroup.memory.limit_in_bytes to properly limit the memory
|
||||
available to the container. The conversion will use 64MiB as the default.
|
|
@ -0,0 +1,348 @@
|
|||
.. role:: since
|
||||
|
||||
======================
|
||||
Host device management
|
||||
======================
|
||||
|
||||
.. contents::
|
||||
|
||||
Libvirt provides management of both physical and virtual host devices
|
||||
(historically also referred to as node devices) like USB, PCI, SCSI, and network
|
||||
devices. This also includes various virtualization capabilities which the
|
||||
aforementioned devices provide for utilization, for example SR-IOV, NPIV, MDEV,
|
||||
DRM, etc.
|
||||
|
||||
The node device driver provides means to list and show details about host
|
||||
devices (``virsh nodedev-list``, ``virsh nodedev-info``, and
|
||||
``virsh nodedev-dumpxml``), which are generic and can be used with all devices.
|
||||
It also provides the means to manage virtual devices. Persistently-defined
|
||||
virtual devices are only supported for mediated devices, while transient devices
|
||||
are supported by both mediated devices and NPIV (`more info about
|
||||
NPIV) <https://wiki.libvirt.org/page/NPIV_in_libvirt>`__).
|
||||
|
||||
Persistent virtual devices are managed with ``virsh nodedev-define`` and
|
||||
``virsh nodedev-undefine``. Persistent devices can be configured to start
|
||||
manually or automatically using ``virsh nodedev-autostart``. Inactive devices
|
||||
can be made active with ``virsh nodedev-start``.
|
||||
|
||||
Transient virtual devices are started and stopped with the commands
|
||||
``virsh nodedev-create`` and ``virsh nodedev-destroy``.
|
||||
|
||||
Devices on the host system are arranged in a tree-like hierarchy, with the root
|
||||
node being called ``computer``. The node device driver supports udev backend
|
||||
(HAL backend was removed in ``6.8.0``).
|
||||
|
||||
Details of the XML format of a host device can be found
|
||||
`here <formatnode.html>`__. Of particular interest is the ``capability``
|
||||
element, which describes features supported by the device. Some specific device
|
||||
types are addressed in more detail below.
|
||||
|
||||
Basic structure of a node device
|
||||
--------------------------------
|
||||
|
||||
::
|
||||
|
||||
<device>
|
||||
<name>pci_0000_00_17_0</name>
|
||||
<path>/sys/devices/pci0000:00/0000:00:17.0</path>
|
||||
<parent>computer</parent>
|
||||
<driver>
|
||||
<name>ahci</name>
|
||||
</driver>
|
||||
<capability type='pci'>
|
||||
...
|
||||
</capability>
|
||||
</device>
|
||||
|
||||
PCI host devices
|
||||
----------------
|
||||
|
||||
``capability``
|
||||
When used as top level element, the supported values for the ``type``
|
||||
attribute are ``pci`` and ``phys_function`` (see `SR-IOV capability`_ below).
|
||||
|
||||
::
|
||||
|
||||
<device>
|
||||
<name>pci_0000_04_00_1</name>
|
||||
<path>/sys/devices/pci0000:00/0000:00:06.0/0000:04:00.1</path>
|
||||
<parent>pci_0000_00_06_0</parent>
|
||||
<driver>
|
||||
<name>igb</name>
|
||||
</driver>
|
||||
<capability type='pci'>
|
||||
<domain>0</domain>
|
||||
<bus>4</bus>
|
||||
<slot>0</slot>
|
||||
<function>1</function>
|
||||
<product id='0x10c9'>82576 Gigabit Network Connection</product>
|
||||
<vendor id='0x8086'>Intel Corporation</vendor>
|
||||
<iommuGroup number='15'>
|
||||
<address domain='0x0000' bus='0x04' slot='0x00' function='0x1'/>
|
||||
</iommuGroup>
|
||||
<numa node='0'/>
|
||||
<pci-express>
|
||||
<link validity='cap' port='1' speed='2.5' width='2'/>
|
||||
<link validity='sta' speed='2.5' width='2'/>
|
||||
</pci-express>
|
||||
</capability>
|
||||
</device>
|
||||
|
||||
The XML format for a PCI device stays the same for any further capabilities it
|
||||
supports, a single nested ``<capability>`` element will be included for each
|
||||
capability the device supports.
|
||||
|
||||
SR-IOV capability
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Single root input/output virtualization (SR-IOV) allows sharing of the PCIe
|
||||
resources by multiple virtual environments. That is achieved by slicing up a
|
||||
single full-featured physical resource called physical function (PF) into
|
||||
multiple devices called virtual functions (VFs) sharing their configuration with
|
||||
the underlying PF. Despite the SR-IOV specification, the amount of VFs that can
|
||||
be created on a PF varies among manufacturers.
|
||||
|
||||
Suppose the NIC above in `PCI host devices`_ was also SR-IOV capable, it would
|
||||
also include a nested ``<capability>`` element enumerating all virtual
|
||||
functions available on the physical device (physical port) like in the example
|
||||
below.
|
||||
|
||||
::
|
||||
|
||||
<capability type='pci'>
|
||||
...
|
||||
<capability type='virt_functions' maxCount='7'>
|
||||
<address domain='0x0000' bus='0x04' slot='0x10' function='0x1'/>
|
||||
<address domain='0x0000' bus='0x04' slot='0x10' function='0x3'/>
|
||||
<address domain='0x0000' bus='0x04' slot='0x10' function='0x5'/>
|
||||
<address domain='0x0000' bus='0x04' slot='0x10' function='0x7'/>
|
||||
<address domain='0x0000' bus='0x04' slot='0x11' function='0x1'/>
|
||||
<address domain='0x0000' bus='0x04' slot='0x11' function='0x3'/>
|
||||
<address domain='0x0000' bus='0x04' slot='0x11' function='0x5'/>
|
||||
</capability>
|
||||
...
|
||||
</capability>
|
||||
|
||||
A SR-IOV child device on the other hand, would then report its top level
|
||||
capability type as a ``phys_function`` instead:
|
||||
|
||||
::
|
||||
|
||||
<device>
|
||||
...
|
||||
<capability type='phys_function'>
|
||||
<address domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
|
||||
</capability>
|
||||
...
|
||||
</device>
|
||||
|
||||
MDEV capability
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
A device capable of creating mediated devices will include a nested capability
|
||||
``mdev_types`` which enumerates all supported mdev types on the physical device,
|
||||
along with the type attributes available through sysfs. A detailed description
|
||||
of the XML format for the ``mdev_types`` capability can be found
|
||||
`here <formatnode.html#mdev-types-capability>`__.
|
||||
|
||||
The following example shows how we might represent an NVIDIA GPU device that
|
||||
supports mediated devices. See below for more info on
|
||||
`Mediated devices (MDEVs)`_.
|
||||
|
||||
::
|
||||
|
||||
<device>
|
||||
...
|
||||
<driver>
|
||||
<name>nvidia</name>
|
||||
</driver>
|
||||
<capability type='pci'>
|
||||
...
|
||||
<capability type='mdev_types'>
|
||||
<type id='nvidia-11'>
|
||||
<name>GRID M60-0B</name>
|
||||
<deviceAPI>vfio-pci</deviceAPI>
|
||||
<availableInstances>16</availableInstances>
|
||||
</type>
|
||||
<!-- Here would come the rest of the available mdev types -->
|
||||
</capability>
|
||||
...
|
||||
</capability>
|
||||
</device>
|
||||
|
||||
VPD capability
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
A device that exposes a PCI/PCIe VPD capability will include a nested capability
|
||||
``vpd`` which presents data stored in the Vital Product Data (VPD). VPD provides
|
||||
a device name and a number of other standard-defined read-only fields (change
|
||||
level, manufacture id, part number, serial number) and vendor-specific read-only
|
||||
fields. Additionally, if a device supports it, read-write fields (asset tag,
|
||||
vendor-specific fields or system fields) may also be present. The VPD capability
|
||||
is optional for PCI/PCIe devices and the set of exposed fields may vary
|
||||
depending on a device. The XML format follows the binary format described in
|
||||
"I.3. VPD Definitions" in PCI Local Bus (2.2+) and the identical format in PCIe
|
||||
4.0+. At the time of writing, the support for exposing this capability is only
|
||||
present on Linux-based systems (kernel version v2.6.26 is the first one to
|
||||
expose VPD via sysfs which Libvirt relies on). Reading the VPD contents requires
|
||||
root privileges, therefore, ``virsh nodedev-dumpxml`` must be executed
|
||||
accordingly. A description of the XML format for the ``vpd`` capability can be
|
||||
found `here <formatnode.html#vpd-capability>`__.
|
||||
|
||||
The following example shows a VPD representation for a device that exposes the
|
||||
VPD capability with read-only and read-write fields. Among other things, the VPD
|
||||
of this particular device includes a unique board serial number.
|
||||
|
||||
::
|
||||
|
||||
<device>
|
||||
<name>pci_0000_42_00_0</name>
|
||||
<capability type='pci'>
|
||||
<class>0x020000</class>
|
||||
<domain>0</domain>
|
||||
<bus>66</bus>
|
||||
<slot>0</slot>
|
||||
<function>0</function>
|
||||
<product id='0xa2d6'>MT42822 BlueField-2 integrated ConnectX-6 Dx network controller</product>
|
||||
<vendor id='0x15b3'>Mellanox Technologies</vendor>
|
||||
<capability type='virt_functions' maxCount='16'/>
|
||||
<capability type='vpd'>
|
||||
<name>BlueField-2 DPU 25GbE Dual-Port SFP56, Crypto Enabled, 16GB on-board DDR, 1GbE OOB management, Tall Bracket</name>
|
||||
<fields access='readonly'>
|
||||
<change_level>B1</change_level>
|
||||
<manufacture_id>foobar</manufacture_id>
|
||||
<part_number>MBF2H332A-AEEOT</part_number>
|
||||
<serial_number>MT2113X00000</serial_number>
|
||||
<vendor_field index='0'>PCIeGen4 x8</vendor_field>
|
||||
<vendor_field index='2'>MBF2H332A-AEEOT</vendor_field>
|
||||
<vendor_field index='3'>3c53d07eec484d8aab34dabd24fe575aa</vendor_field>
|
||||
<vendor_field index='A'>MLX:MN=MLNX:CSKU=V2:UUID=V3:PCI=V0:MODL=BF2H332A</vendor_field>
|
||||
</fields>
|
||||
<fields access='readwrite'>
|
||||
<asset_tag>fooasset</asset_tag>
|
||||
<vendor_field index='0'>vendorfield0</vendor_field>
|
||||
<vendor_field index='2'>vendorfield2</vendor_field>
|
||||
<vendor_field index='A'>vendorfieldA</vendor_field>
|
||||
<system_field index='B'>systemfieldB</system_field>
|
||||
<system_field index='0'>systemfield0</system_field>
|
||||
</fields>
|
||||
</capability>
|
||||
<iommuGroup number='65'>
|
||||
<address domain='0x0000' bus='0x42' slot='0x00' function='0x0'/>
|
||||
</iommuGroup>
|
||||
<numa node='0'/>
|
||||
<pci-express>
|
||||
<link validity='cap' port='0' speed='16' width='8'/>
|
||||
<link validity='sta' speed='8' width='8'/>
|
||||
</pci-express>
|
||||
</capability>
|
||||
</device>
|
||||
|
||||
Mediated devices (MDEVs)
|
||||
------------------------
|
||||
|
||||
Mediated devices ( :since:`Since 3.2.0` ) are software devices defining resource
|
||||
allocation on the backing physical device which in turn allows the parent
|
||||
physical device's resources to be divided into several mediated devices, thus
|
||||
sharing the physical device's performance among multiple guests. Unlike SR-IOV
|
||||
however, where a PCIe device appears as multiple separate PCIe devices on the
|
||||
host's PCI bus, mediated devices only appear on the mdev virtual bus. Therefore,
|
||||
no detach/reattach procedure from/to the host driver procedure is involved even
|
||||
though mediated devices are used in a direct device assignment manner. A
|
||||
detailed description of the XML format for the ``mdev`` capability can be found
|
||||
`here <formatnode.html#mdev>`__.
|
||||
|
||||
Example of a mediated device
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<device>
|
||||
<name>mdev_4b20d080_1b54_4048_85b3_a6a62d165c01</name>
|
||||
<path>/sys/devices/pci0000:00/0000:00:02.0/4b20d080-1b54-4048-85b3-a6a62d165c01</path>
|
||||
<parent>pci_0000_06_00_0</parent>
|
||||
<driver>
|
||||
<name>vfio_mdev</name>
|
||||
</driver>
|
||||
<capability type='mdev'>
|
||||
<type id='nvidia-11'/>
|
||||
<uuid>4b20d080-1b54-4048-85b3-a6a62d165c01</uuid>
|
||||
<iommuGroup number='12'/>
|
||||
</capability>
|
||||
</device>
|
||||
|
||||
The support of mediated device's framework in libvirt's node device driver
|
||||
covers the following features:
|
||||
|
||||
- list available mediated devices on the host ( :since:`Since 3.4.0` )
|
||||
- display device details ( :since:`Since 3.4.0` )
|
||||
- create transient mediated devices ( :since:`Since 6.5.0` )
|
||||
- define persistent mediated devices ( :since:`Since 7.3.0` )
|
||||
|
||||
Because mediated devices are instantiated from vendor specific templates, simply
|
||||
called 'types', information describing these types is contained within the
|
||||
parent device's capabilities (see the example in `PCI host devices`_).
|
||||
To list all devices capable of creating mediated devices, the following command
|
||||
can be used.
|
||||
|
||||
::
|
||||
|
||||
$ virsh nodedev-list --cap mdev_types
|
||||
|
||||
To see the supported mediated device types on a specific physical device use the
|
||||
following:
|
||||
|
||||
::
|
||||
|
||||
$ virsh nodedev-dumpxml <device>
|
||||
|
||||
Before creating a mediated device, unbind the device from the respective device
|
||||
driver, eg. subchannel I/O driver for a CCW device. Then bind the device to the
|
||||
respective VFIO driver. For a CCW device, also unbind the corresponding
|
||||
subchannel of the CCW device from the subchannel I/O driver and then bind the
|
||||
subchannel (instead of the CCW device) to the vfio_ccw driver. The below example
|
||||
shows the unbinding and binding steps for a CCW device.
|
||||
|
||||
::
|
||||
|
||||
device="0.0.1234"
|
||||
subchannel="0.0.0123"
|
||||
echo $device > /sys/bus/ccw/devices/$device/driver/unbind
|
||||
echo $subchannel > /sys/bus/css/devices/$subchannel/driver/unbind
|
||||
echo $subchannel > /sys/bus/css/drivers/vfio_ccw/bind
|
||||
|
||||
To instantiate a transient mediated device, create an XML file representing the
|
||||
device. See above for information about the mediated device xml format.
|
||||
|
||||
::
|
||||
|
||||
$ virsh nodedev-create <xml-file>
|
||||
Node device '<device-name>' created from '<xml-file>'
|
||||
|
||||
If you would like to persistently define the device so that it will be
|
||||
maintained across host reboots, use ``virsh nodedev-define`` instead of
|
||||
``nodedev-create``:
|
||||
|
||||
::
|
||||
|
||||
$ virsh nodedev-define <xml-file>
|
||||
Node device '<device-name>' defined from '<xml-file>'
|
||||
|
||||
To start an instance of this device definition, use the following command:
|
||||
|
||||
::
|
||||
|
||||
$ virsh nodedev-start <device-name>
|
||||
|
||||
Active mediated device instances can be stopped using
|
||||
``virsh nodedev-destroy``, and persistent device definitions can be
|
||||
removed using ``virsh nodedev-undefine``.
|
||||
|
||||
If a mediated device is defined persistently, it can also be set to be
|
||||
automatically started whenever the host reboots or when the parent device
|
||||
becomes available. In order to autostart a mediated device, use the following
|
||||
command:
|
||||
|
||||
::
|
||||
|
||||
$ virsh nodedev-autostart <device-name>
|
|
@ -0,0 +1,97 @@
|
|||
=======================
|
||||
OpenVZ container driver
|
||||
=======================
|
||||
|
||||
.. contents::
|
||||
|
||||
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.
|
||||
|
||||
Project Links
|
||||
-------------
|
||||
|
||||
- The `OpenVZ <https://openvz.org/>`__ Linux container system
|
||||
|
||||
Connections to OpenVZ driver
|
||||
----------------------------
|
||||
|
||||
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:
|
||||
|
||||
::
|
||||
|
||||
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)
|
||||
|
||||
Notes on bridged networking
|
||||
---------------------------
|
||||
|
||||
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.
|
||||
|
||||
Host network devices
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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 `Wiki <https://wiki.libvirt.org>`__ 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".
|
||||
|
||||
OpenVZ tools configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
OpenVZ releases later than 3.0.23 ship with a standard network device setup
|
||||
script that is able to setup bridging, named ``/usr/sbin/vznetaddbr``. 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 ``/etc/vz/vznet.conf`` must be created containing
|
||||
|
||||
::
|
||||
|
||||
#!/bin/bash
|
||||
EXTERNAL_SCRIPT="/usr/sbin/vznetaddbr"
|
||||
|
||||
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.
|
||||
|
||||
Example guest domain XML configuration
|
||||
--------------------------------------
|
||||
|
||||
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 ``filesystem`` tag, and the template source name matches the
|
||||
templates known to OpenVZ tools.
|
||||
|
||||
::
|
||||
|
||||
<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>
|
|
@ -0,0 +1,741 @@
|
|||
.. role:: since
|
||||
.. role:: removed
|
||||
|
||||
==============================
|
||||
QEMU/KVM/HVF hypervisor driver
|
||||
==============================
|
||||
|
||||
The libvirt KVM/QEMU driver can manage any QEMU emulator from version 3.1.0 or
|
||||
later.
|
||||
|
||||
It supports multiple QEMU accelerators: software
|
||||
emulation also known as TCG, hardware-assisted virtualization on Linux
|
||||
with KVM and hardware-assisted virtualization on macOS with
|
||||
Hypervisor.framework (:since:`since 8.1.0`).
|
||||
|
||||
.. contents::
|
||||
|
||||
Project Links
|
||||
-------------
|
||||
|
||||
- The `KVM <https://www.linux-kvm.org/>`__ Linux hypervisor
|
||||
- The `QEMU <https://wiki.qemu.org/Index.html>`__ emulator
|
||||
- `Hypervisor.framework <https://developer.apple.com/documentation/hypervisor>`__ reference
|
||||
|
||||
Deployment pre-requisites
|
||||
-------------------------
|
||||
|
||||
- **QEMU emulators**: The driver will probe ``/usr/bin`` for the presence of
|
||||
``qemu``, ``qemu-system-x86_64``, ``qemu-system-microblaze``,
|
||||
``qemu-system-microblazeel``, ``qemu-system-mips``,\ ``qemu-system-mipsel``,
|
||||
``qemu-system-sparc``,\ ``qemu-system-ppc``. The results of this can be seen
|
||||
from the capabilities XML output.
|
||||
- **KVM hypervisor**: The driver will probe ``/usr/bin`` for the presence of
|
||||
``qemu-kvm`` and ``/dev/kvm`` device node. If both are found, then KVM fully
|
||||
virtualized, hardware accelerated guests will be available.
|
||||
- **Hypervisor.framework (HVF)**: The driver will probe ``sysctl`` for the
|
||||
presence of ``Hypervisor.framework``. If it is found it will be possible to
|
||||
create hardware accelerated guests.
|
||||
|
||||
Connections to QEMU driver
|
||||
--------------------------
|
||||
|
||||
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 connection URIs for the libvirt driver are:
|
||||
|
||||
::
|
||||
|
||||
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)
|
||||
|
||||
Embedded driver
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Since 6.1.0 the QEMU driver has experimental support for operating in an
|
||||
embedded mode. In this scenario, rather than connecting to the libvirtd daemon,
|
||||
the QEMU driver runs in the client application process directly. To use this the
|
||||
client application must have registered & be running an instance of the event
|
||||
loop. To open the driver in embedded mode the app use the new URI path and
|
||||
specify a virtual root directory under which the driver will create content. The
|
||||
path to the root directory must be absolute. Passing a relative path results in
|
||||
an error.
|
||||
|
||||
::
|
||||
|
||||
qemu:///embed?root=/some/dir
|
||||
|
||||
Broadly speaking the range of functionality is intended to be on a par with that
|
||||
seen when using the traditional system or session libvirt connections to QEMU.
|
||||
The features will of course differ depending on whether the application using
|
||||
the embedded driver is running privileged or unprivileged. For example PCI
|
||||
device assignment or TAP based networking are only available when running
|
||||
privileged. While the embedded mode is still classed as experimental some
|
||||
features may change their default settings between releases.
|
||||
|
||||
By default if the application uses any APIs associated with secondary drivers,
|
||||
these will result in a connection being opened to the corresponding driver in
|
||||
libvirtd. For example, this allows a virtual machine from the embedded QEMU to
|
||||
connect its NIC to a virtual network or connect its disk to a storage volume.
|
||||
Some of the secondary drivers will also be able to support running in embedded
|
||||
mode. Currently this is supported by the secrets driver, to allow for use of VMs
|
||||
with encrypted disks
|
||||
|
||||
Directory tree
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Under the specified root directory the following locations will be used
|
||||
|
||||
::
|
||||
|
||||
/some/dir
|
||||
|
|
||||
+- log
|
||||
| |
|
||||
| +- qemu
|
||||
| +- swtpm
|
||||
|
|
||||
+- etc
|
||||
| |
|
||||
| +- qemu
|
||||
| +- pki
|
||||
| |
|
||||
| +- qemu
|
||||
|
|
||||
+- run
|
||||
| |
|
||||
| +- qemu
|
||||
| +- swtpm
|
||||
|
|
||||
+- cache
|
||||
| |
|
||||
| +- qemu
|
||||
|
|
||||
+- lib
|
||||
|
|
||||
+- qemu
|
||||
+- swtpm
|
||||
|
||||
Note that UNIX domain sockets used for QEMU virtual machines had a maximum
|
||||
filename length of 108 characters. Bear this in mind when picking a root
|
||||
directory to avoid risk of exhausting the filename space. The application is
|
||||
responsible for recursively purging the contents of this directory tree once
|
||||
they no longer require a connection, though it can also be left intact for reuse
|
||||
when opening a future connection.
|
||||
|
||||
API usage with event loop
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To use the QEMU driver in embedded mode the application must register an event
|
||||
loop with libvirt. Many of the QEMU driver API calls will rely on the event loop
|
||||
processing data. With this in mind, applications must **NEVER** invoke API calls
|
||||
from the event loop thread itself, only other threads. Not following this rule
|
||||
will lead to deadlocks in the API. This restriction was lifted starting from
|
||||
6.2.0 release, when QMP processing moved to a dedicated thread. However, it is
|
||||
important to let the event loop run after each API call, even the ones made from
|
||||
the event loop thread itself.
|
||||
|
||||
Location of configuration files
|
||||
-------------------------------
|
||||
|
||||
The QEMU driver comes with sane default values. However, during its
|
||||
initialization it reads a configuration file which offers system administrator
|
||||
or an user to override some of that default. The location of the file depends on
|
||||
the connection URI, as follows:
|
||||
|
||||
=================== ======================================
|
||||
``qemu:///system`` ``/etc/libvirt/qemu.conf``
|
||||
``qemu:///session`` ``$XDG_CONFIG_HOME/libvirt/qemu.conf``
|
||||
``qemu:///embed`` ``$rootdir/etc/qemu.conf``
|
||||
=================== ======================================
|
||||
|
||||
If ``$XDG_CONFIG_HOME`` is not set in the environment, it defaults to
|
||||
``$HOME/.config``. For the embed URI the ``$rootdir`` represents the specified
|
||||
root directory from the connection URI.
|
||||
|
||||
Please note, that it is very likely that the only qemu.conf file that will exist
|
||||
after installing libvirt is the ``/etc/libvirt/qemu.conf``, if users of the
|
||||
session daemon or the embed driver want to override a built in value, then they
|
||||
need to create the file before connecting to the respective URI.
|
||||
|
||||
Driver security architecture
|
||||
----------------------------
|
||||
|
||||
There are multiple layers to security in the QEMU driver, allowing for
|
||||
flexibility in the use of QEMU based virtual machines.
|
||||
|
||||
Driver instances
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
POSIX users/groups
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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.
|
||||
|
||||
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 ``/etc/libvirt/qemu.conf`` configuration file via the
|
||||
``user=$USERNAME`` and ``group=$GROUPNAME`` 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.
|
||||
|
||||
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.
|
||||
|
||||
- The directories ``/var/run/libvirt/qemu/``, ``/var/lib/libvirt/qemu/`` and
|
||||
``/var/cache/libvirt/qemu/`` 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 ``/etc/libvirt/qemu.conf``, they will need to manually set the
|
||||
ownership on these directories.
|
||||
|
||||
- When attaching USB and PCI devices to a QEMU guest, QEMU will need to access
|
||||
files in ``/dev/bus/usb`` and ``/sys/bus/pci/devices`` 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.
|
||||
|
||||
- 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'.
|
||||
|
||||
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
|
||||
|
||||
::
|
||||
|
||||
chmod o+x /path/to/directory
|
||||
|
||||
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.
|
||||
|
||||
The libvirt maintainers **strongly recommend against** running QEMU as the root
|
||||
user/group. This should not be required in most supported usage scenarios, as
|
||||
libvirt will generally do the right thing to grant QEMU access to files it is
|
||||
permitted to use when it is running non-root.
|
||||
|
||||
Linux process capabilities
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In versions of libvirt prior to 6.0.0, even if QEMU was configured to run as the
|
||||
root user / group, libvirt would strip all process capabilities. This meant that
|
||||
QEMU could only read/write files owned by root, or with open permissions. In
|
||||
reality, stripping capabilities did not have any security benefit, as it was
|
||||
trivial to get commands to run in another context with full capabilities, for
|
||||
example, by creating a cronjob.
|
||||
|
||||
Thus since 6.0.0, if QEMU is running as root, it will keep all process
|
||||
capabilities. Behaviour when QEMU is running non-root is unchanged, it still has
|
||||
no capabilities.
|
||||
|
||||
SELinux basic confinement
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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.
|
||||
|
||||
In the basic model, all QEMU virtual machines run under the confined domain
|
||||
``root:system_r:qemu_t``. It is required that any disk image assigned to a QEMU
|
||||
virtual machine is labelled with ``system_u:object_r:virt_image_t``. In a
|
||||
default deployment, package vendors/distributor will typically ensure that the
|
||||
directory ``/var/lib/libvirt/images`` 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 ``system_u:object_r:virt_image_t``.
|
||||
|
||||
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 ``system_u:object_r:virt_image_t``. In the case of NFS, there is an
|
||||
alternative option, of enabling the ``virt_use_nfs`` SELinux boolean.
|
||||
|
||||
SELinux sVirt confinement
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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.
|
||||
|
||||
In the sVirt model, each QEMU virtual machine runs under its own confined
|
||||
domain, which is based on ``system_u:system_r:svirt_t:s0`` with a unique
|
||||
category appended, eg, ``system_u:system_r:svirt_t:s0:c34,c44``. The rules are
|
||||
setup such that a domain can only access files which are labelled with the
|
||||
matching category level, eg ``system_u:object_r:svirt_image_t:s0:c34,c44``. This
|
||||
prevents one QEMU process accessing any file resources that are prevent to
|
||||
another QEMU process.
|
||||
|
||||
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
|
||||
``system_u:system_r:svirt_image_t:s0`` allowing all guests read/write access
|
||||
them, while disks marked as <readonly> will get a generic label
|
||||
``system_u:system_r:svirt_content_t:s0`` which allows all guests read-only
|
||||
access.
|
||||
|
||||
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.
|
||||
|
||||
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 ``/etc/libvirt/qemu.conf`` file
|
||||
can be used to change the setting to ``security_driver="none"``
|
||||
|
||||
AppArmor sVirt confinement
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
In the sVirt model, if a profile is loaded for the libvirtd daemon, then each
|
||||
``qemu:///system`` 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.
|
||||
|
||||
The AppArmor sVirt implementation is flexible in that it allows an administrator
|
||||
to customize the template file in ``/etc/apparmor.d/libvirt/TEMPLATE`` for
|
||||
site-specific access for all newly created QEMU virtual machines. Also, when a
|
||||
new profile is generated, two files are created:
|
||||
``/etc/apparmor.d/libvirt/libvirt-<uuid>`` and
|
||||
``/etc/apparmor.d/libvirt/libvirt-<uuid>.files``. 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.
|
||||
|
||||
While users can define their own AppArmor profile scheme, a typical
|
||||
configuration will include a profile for ``/usr/sbin/libvirtd``,
|
||||
``/usr/lib/libvirt/virt-aa-helper`` or ``/usr/libexec/virt-aa-helper``\ (a
|
||||
helper program which the libvirtd daemon uses instead of manipulating AppArmor
|
||||
directly), and an abstraction to be included by
|
||||
``/etc/apparmor.d/libvirt/TEMPLATE`` (typically
|
||||
``/etc/apparmor.d/abstractions/libvirt-qemu``). An example profile scheme can be
|
||||
found in the examples/apparmor directory of the source distribution.
|
||||
|
||||
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 ``/etc/libvirt/qemu.conf`` file can be
|
||||
used to change the setting to ``security_driver="none"``.
|
||||
|
||||
Cgroups device ACLs
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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 access control lists 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
|
||||
access control list so that the QEMU process can only access shared devices, and
|
||||
explicitly assigned disks images backed by block devices.
|
||||
|
||||
The list of shared devices a guest is allowed access to is
|
||||
|
||||
::
|
||||
|
||||
/dev/null, /dev/full, /dev/zero,
|
||||
/dev/random, /dev/urandom,
|
||||
/dev/ptmx, /dev/kvm,
|
||||
|
||||
In the event of unanticipated needs arising, this can be customized via the
|
||||
``/etc/libvirt/qemu.conf`` file. To mount the cgroups device controller, the
|
||||
following command should be run as root, prior to starting libvirtd
|
||||
|
||||
::
|
||||
|
||||
mkdir /dev/cgroup
|
||||
mount -t cgroup none /dev/cgroup -o devices
|
||||
|
||||
libvirt will then place each virtual machine in a cgroup at
|
||||
``/dev/cgroup/libvirt/qemu/$VMNAME/``
|
||||
|
||||
Import and export of libvirt domain XML configs
|
||||
-----------------------------------------------
|
||||
|
||||
The QEMU driver currently supports a single native config format known as
|
||||
``qemu-argv``. 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
|
||||
|
||||
Converting from QEMU args to domain XML
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Note:** this operation is :removed:`deleted as of 5.5.0` and will return an
|
||||
error.
|
||||
|
||||
The ``virsh domxml-from-native`` 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 `libvirt applications page <apps.html>`__ for some examples) or by
|
||||
manually crafting XML to pass to virsh.
|
||||
|
||||
Converting from domain XML to QEMU args
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh domxml-to-native`` provides a way to convert a guest description
|
||||
using libvirt Domain XML, into a set of QEMU args that would be used by libvirt
|
||||
to start the qemu process.
|
||||
|
||||
Note that currently the command line formatted by libvirt is no longer suited
|
||||
for manually running qemu as the configuration expects various resources and
|
||||
open file descriptors passed to the process which are usually prepared by
|
||||
libvirtd as well as certain features being configured via the monitor.
|
||||
|
||||
The qemu arguments as returned by ``virsh domxml-to-native`` thus are not
|
||||
trivially usable outside of libvirt.
|
||||
|
||||
Pass-through of arbitrary qemu commands
|
||||
---------------------------------------
|
||||
|
||||
Libvirt provides an XML namespace and an optional library ``libvirt-qemu.so``
|
||||
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 **unsupported**, 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.
|
||||
|
||||
The library provides two API: ``virDomainQemuMonitorCommand``, for sending an
|
||||
arbitrary monitor command (in either HMP or QMP format) to a qemu guest (
|
||||
:since:`Since 0.8.3` ), and ``virDomainQemuAttach``, for registering a qemu
|
||||
domain that was manually started so that it can then be managed by libvirtd (
|
||||
:since:`Since 0.9.4` , :removed:`removed as of 5.5.0` ).
|
||||
|
||||
Additionally, the following XML additions allow fine-tuning of the command line
|
||||
given to qemu when starting a domain ( :since:`Since 0.8.3` ). In order to use
|
||||
the XML additions, it is necessary to issue an XML namespace request (the
|
||||
special ``xmlns:name`` attribute) that pulls in
|
||||
``http://libvirt.org/schemas/domain/qemu/1.0``; typically, the namespace is
|
||||
given the name of ``qemu``. With the namespace in place, it is then possible to
|
||||
add an element ``<qemu:commandline>`` under ``domain``, with the following
|
||||
sub-elements repeated as often as needed:
|
||||
|
||||
``qemu:arg``
|
||||
Add an additional command-line argument to the qemu process when starting the
|
||||
domain, given by the value of the attribute ``value``.
|
||||
``qemu:env``
|
||||
Add an additional environment variable to the qemu process when starting the
|
||||
domain, given with the name-value pair recorded in the attributes ``name``
|
||||
and optional ``value``.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
<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>
|
||||
|
||||
QEMU feature configuration for testing
|
||||
--------------------------------------
|
||||
|
||||
In some cases e.g. when developing a new feature or for testing it may be
|
||||
required to control a given qemu feature (or qemu capability) to test it before
|
||||
it's complete or disable it for debugging purposes. :since:`Since 5.5.0` it's
|
||||
possible to use the same special qemu namespace as above
|
||||
(``http://libvirt.org/schemas/domain/qemu/1.0``) and use ``<qemu:capabilities>``
|
||||
element to add (``<qemu:add capability="capname"/>``) or remove
|
||||
(``<qemu:del capability="capname"/>``) capability bits. The naming of the
|
||||
feature bits is the same libvirt uses in the status XML. Note that this feature
|
||||
is meant for experiments only and should _not_ be used in production.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
<domain type='qemu' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>testvm</name>
|
||||
|
||||
[...]
|
||||
|
||||
<qemu:capabilities>
|
||||
<qemu:add capability='blockdev'/>
|
||||
<qemu:del capability='drive'/>
|
||||
</qemu:capabilities>
|
||||
</domain>
|
||||
|
||||
Control of QEMU deprecation warnings
|
||||
------------------------------------
|
||||
|
||||
The following knob controls how QEMU behaves towards deprecated commands and
|
||||
arguments used by libvirt:
|
||||
|
||||
::
|
||||
|
||||
<domain type='qemu' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>testvm</name>
|
||||
|
||||
[...]
|
||||
|
||||
<qemu:deprecation behavior='crash'/>
|
||||
|
||||
This setting is meant for developers and CI efforts to make it obvious when
|
||||
libvirt relies on fields which are deprecated so that it can be fixes as soon
|
||||
as possible.
|
||||
|
||||
Possible options are:
|
||||
|
||||
``none``
|
||||
(default) qemu is supposed to accept and output deprecated fields and commands
|
||||
|
||||
``omit``
|
||||
qemu is instructed to omit deprecated fields on output, behaviour towards
|
||||
fields and commands from libvirtd is not changed
|
||||
|
||||
``reject``
|
||||
qemu is instructed to report an error if a deprecated command or field is
|
||||
used by libvirtd
|
||||
|
||||
``crash``
|
||||
qemu crashes when an deprecated command or field is used by libvirtd
|
||||
|
||||
For both "reject" and "crash" qemu is instructed to omit any deprecated fields
|
||||
on output.
|
||||
|
||||
The "reject" option is less harsh towards the VMs but some code paths ignore
|
||||
errors reported by qemu and thus it may not be obvious that a deprecated
|
||||
command/field was used, thus it's suggested to use the "crash" option instead.
|
||||
|
||||
In cases when qemu doesn't support configuring the behaviour this setting is
|
||||
silently ignored to allow testing older qemu versions without having to
|
||||
reconfigure libvirtd.
|
||||
|
||||
*DO NOT* use in production.
|
||||
|
||||
Overriding properties of QEMU devices
|
||||
-------------------------------------
|
||||
|
||||
For development or testing the ``<qemu:override>`` tag allows to override
|
||||
specific properties of devices instantiated by libvirt.
|
||||
|
||||
The ``<qemu:device>`` sub-element groups overrides for a device identified via
|
||||
the ``alias`` attribute. The alias corresponds to the ``<alias name=''>``
|
||||
property of a device. It's strongly recommended to use user-specified aliases
|
||||
for devices with overridden properties.
|
||||
|
||||
Sub element ``<qemu:frontend>`` encapsulates all overrides of properties for the
|
||||
device frontend and overrides what libvirt formats via ``-device``.
|
||||
:since:`Since 8.2.0`.
|
||||
|
||||
The individual properties are overridden by a ``<qemu:property>`` element. The
|
||||
``name`` specifies the name of the property to override. In case when libvirt
|
||||
doesn't configure the property a property with the name is added to the
|
||||
commandline. The ``type`` attribute specifies a type of the argument used. The
|
||||
type must correspond with the type that is expected by QEMU. Supported values
|
||||
for the type attribute are: ``string``, ``number``, ``bool`` (allowed values for
|
||||
``bool`` are ``true`` and ``false``) and ``remove``. The ``remove`` type is
|
||||
special and instructs libvirt to remove the property without replacement.
|
||||
|
||||
The overrides are applied only to initial device configuration passed to QEMU
|
||||
via the commandline. Later hotplug operations will not apply any modifications.
|
||||
|
||||
Configuring override for a device alias which is not used or attempting to
|
||||
remove a device property which is not formatted by libvirt will cause failure
|
||||
to startup the VM.
|
||||
|
||||
*Note:* The libvirt project doesn't guarantee any form of compatibility and
|
||||
stability of devices with overridden properties. The domain is tainted when
|
||||
such configuration is used.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>testvm</name>
|
||||
|
||||
[...]
|
||||
|
||||
<qemu:override>
|
||||
<qemu:device alias='ua-devalias'>
|
||||
<qemu:frontend>
|
||||
<qemu:property name='propname1' type='string' value='test'/>
|
||||
<qemu:property name='propname2' type='unsigned' value='123'/>
|
||||
<qemu:property name='propname2' type='signed' value='-123'/>
|
||||
<qemu:property name='propname3' type='bool' value='false'/>
|
||||
<qemu:property name='propname4' type='remove'/>
|
||||
</qemu:frontend>
|
||||
</qemu:device>
|
||||
</qemu:override>
|
||||
</domain>
|
||||
|
||||
Example domain XML config
|
||||
-------------------------
|
||||
|
||||
QEMU emulated guest on x86_64
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<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>
|
||||
|
||||
KVM hardware accelerated guest on i686
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<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>
|
||||
|
||||
HVF hardware accelerated guest on x86_64
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<domain type='hvf'>
|
||||
<name>hvf-demo</name>
|
||||
<uuid>4dea24b3-1d52-d8f3-2516-782e98a23fa0</uuid>
|
||||
<memory>131072</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<os>
|
||||
<type arch="x86_64">hvm</type>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
</features>
|
||||
<clock sync="localtime"/>
|
||||
<devices>
|
||||
<emulator>/usr/local/bin/qemu-system-x86_64</emulator>
|
||||
<controller type='scsi' index='0' model='virtio-scsi'/>
|
||||
<disk type='volume' device='disk'>
|
||||
<driver name='qemu' type='qcow2'/>
|
||||
<source pool='default' volume='myos'/>
|
||||
<target bus='scsi' dev='sda'/>
|
||||
</disk>
|
||||
<interface type='user'>
|
||||
<mac address='24:42:53:21:52:45'/>
|
||||
<model type='virtio'/>
|
||||
</interface>
|
||||
<graphics type='vnc' port='-1'/>
|
||||
</devices>
|
||||
</domain>
|
|
@ -0,0 +1,65 @@
|
|||
=============================
|
||||
Secret information management
|
||||
=============================
|
||||
|
||||
The secrets driver in libvirt provides a simple interface for storing and
|
||||
retrieving secret information.
|
||||
|
||||
Connections to SECRET driver
|
||||
----------------------------
|
||||
|
||||
The libvirt SECRET driver is a multi-instance driver, providing a single system
|
||||
wide privileged driver (the "system" instance), and per-user unprivileged
|
||||
drivers (the "session" instance). A connection to the secret driver is
|
||||
automatically available when opening a connection to one of the stateful primary
|
||||
hypervisor drivers. It is none the less also possible to explicitly open just
|
||||
the secret driver, using the URI protocol "secret" Some example connection URIs
|
||||
for the driver are:
|
||||
|
||||
::
|
||||
|
||||
secret:///session (local access to per-user instance)
|
||||
secret+unix:///session (local access to per-user instance)
|
||||
|
||||
secret:///system (local access to system instance)
|
||||
secret+unix:///system (local access to system instance)
|
||||
secret://example.com/system (remote access, TLS/x509)
|
||||
secret+tcp://example.com/system (remote access, SASl/Kerberos)
|
||||
secret+ssh://root@example.com/system (remote access, SSH tunnelled)
|
||||
|
||||
Embedded driver
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Since 6.1.0 the secret driver has experimental support for operating in an
|
||||
embedded mode. In this scenario, rather than connecting to the libvirtd daemon,
|
||||
the secret driver runs in the client application process directly. To open the
|
||||
driver in embedded mode the app use the new URI path and specify a virtual root
|
||||
directory under which the driver will create content.
|
||||
|
||||
::
|
||||
|
||||
secret:///embed?root=/some/dir
|
||||
|
||||
Under the specified root directory the following locations will be used
|
||||
|
||||
::
|
||||
|
||||
/some/dir
|
||||
|
|
||||
+- etc
|
||||
| |
|
||||
| +- secrets
|
||||
|
|
||||
+- run
|
||||
|
|
||||
+- secrets
|
||||
|
||||
The application is responsible for recursively purging the contents of this
|
||||
directory tree once they no longer require a connection, though it can also be
|
||||
left intact for reuse when opening a future connection.
|
||||
|
||||
The range of functionality is intended to be on a par with that seen when using
|
||||
the traditional system or session libvirt connections to QEMU. Normal practice
|
||||
would be to open the secret driver in embedded mode any time one of the other
|
||||
drivers is opened in embedded mode so that the two drivers can interact
|
||||
in-process.
|
|
@ -0,0 +1,21 @@
|
|||
==================
|
||||
Test "mock" driver
|
||||
==================
|
||||
|
||||
The libvirt ``test`` driver is a per-process fake hypervisor driver.
|
||||
|
||||
Connections to Test driver
|
||||
--------------------------
|
||||
|
||||
The driver maintains all its state in memory. It can start with
|
||||
a pre-configured default config, or be given a path to an alternate config. Some
|
||||
example connection URIs for the libvirt driver are:
|
||||
|
||||
::
|
||||
|
||||
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)
|
|
@ -0,0 +1,161 @@
|
|||
.. role:: since
|
||||
|
||||
============================
|
||||
VirtualBox hypervisor driver
|
||||
============================
|
||||
|
||||
The libvirt VirtualBox driver can manage any VirtualBox version from version 4.0
|
||||
onwards ( :since:`since libvirt 3.0.0` ).
|
||||
|
||||
Project Links
|
||||
-------------
|
||||
|
||||
- The `VirtualBox <https://www.virtualbox.org/>`__ hypervisor
|
||||
|
||||
Connections to VirtualBox driver
|
||||
--------------------------------
|
||||
|
||||
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:
|
||||
|
||||
::
|
||||
|
||||
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)
|
||||
|
||||
**NOTE: as of libvirt 1.0.6, the VirtualBox driver will always run inside the
|
||||
libvirtd daemon, instead of being built-in to the libvirt.so library directly.
|
||||
This change was required due to the fact that VirtualBox code is LGPLv2-only
|
||||
licensed, which is not compatible with the libvirt.so license of
|
||||
LGPLv2-or-later. The daemon will be auto-started when the first connection to
|
||||
VirtualBox is requested. This change also means that it will not be possible to
|
||||
use VirtualBox URIs on the Windows platform, until additional work is completed
|
||||
to get the libvirtd daemon working there.**
|
||||
|
||||
Example domain XML config
|
||||
-------------------------
|
||||
|
||||
::
|
||||
|
||||
<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>
|
||||
<!--Set IDE controller model to PIIX4 (default PIIX3)-->
|
||||
<controller type='ide' model='piix4'/>
|
||||
|
||||
<controller type='scsi' index='0'/>
|
||||
|
||||
<!--VirtualBox SAS Controller-->
|
||||
<controller type='scsi' index='1' model='lsisas1068'/>
|
||||
|
||||
<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>
|
||||
|
||||
<!--Attach to the SCSI controller (index=0, default)-->
|
||||
<disk type='file' device='disk'>
|
||||
<source file='/home/user/tmp/vbox2.vdi'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
|
||||
<!--Attach to the SAS controller (index=1)-->
|
||||
<disk type='file' device='disk'>
|
||||
<source file='/home/user/tmp/vbox3.vdi'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
<address type='drive' controller='1' bus='0' target='0' unit='0'/>
|
||||
</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>
|
||||
|
||||
<graphics type='desktop'/>
|
||||
|
||||
<!--Activate the VRDE server with a port in 3389-3689 range-->
|
||||
<graphics type='rdp' autoport='yes' multiUser='yes'/>
|
||||
|
||||
<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>
|
|
@ -0,0 +1,60 @@
|
|||
================
|
||||
Virtuozzo driver
|
||||
================
|
||||
|
||||
The libvirt vz driver can manage Virtuozzo starting from version 6.0.
|
||||
|
||||
Project Links
|
||||
-------------
|
||||
|
||||
- The `Virtuozzo <https://www.virtuozzo.com/>`__ Solution.
|
||||
|
||||
Connections to the Virtuozzo driver
|
||||
-----------------------------------
|
||||
|
||||
The libvirt Virtuozzo driver is a single-instance privileged driver, with a
|
||||
driver name of 'virtuozzo'. Some example connection URIs for the libvirt driver
|
||||
are:
|
||||
|
||||
::
|
||||
|
||||
vz:///system (local access)
|
||||
vz+unix:///system (local access)
|
||||
vz://example.com/system (remote access, TLS/x509)
|
||||
vz+tcp://example.com/system (remote access, SASl/Kerberos)
|
||||
vz+ssh://root@example.com/system (remote access, SSH tunnelled)
|
||||
|
||||
Example guest domain XML configuration
|
||||
--------------------------------------
|
||||
|
||||
Virtuozzo driver require at least one hard disk for new domains at this time. It
|
||||
is used for defining directory, where VM should be created.
|
||||
|
||||
::
|
||||
|
||||
<domain type='vz'>
|
||||
<name>demo</name>
|
||||
<uuid>54cdecad-4492-4e31-a209-33cc21d64057</uuid>
|
||||
<description>some description</description>
|
||||
<memory unit='KiB'>1048576</memory>
|
||||
<currentMemory unit='KiB'>1048576</currentMemory>
|
||||
<vcpu placement='static'>2</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64'>hvm</type>
|
||||
</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'>
|
||||
<source file='/storage/vol1'/>
|
||||
<target dev='hda'/>
|
||||
</disk>
|
||||
<video>
|
||||
<model type='vga' vram='33554432' heads='1'>
|
||||
<acceleration accel3d='no' accel2d='no'/>
|
||||
</model>
|
||||
</video>
|
||||
</devices>
|
||||
</domain>
|
|
@ -0,0 +1,72 @@
|
|||
=======================================================
|
||||
VMware Workstation / Player / Fusion hypervisors driver
|
||||
=======================================================
|
||||
|
||||
The libvirt VMware driver should be able to manage any Workstation, Player,
|
||||
Fusion version supported by the VMware VIX API. See the compatibility list
|
||||
`here <https://www.vmware.com/support/developer/vix-api/vix110_reference/>`__.
|
||||
|
||||
This driver uses the "vmrun" utility which is distributed with the VMware VIX
|
||||
API. You can download the VIX API from
|
||||
`here <https://www.vmware.com/support/developer/vix-api/>`__.
|
||||
|
||||
Project Links
|
||||
-------------
|
||||
|
||||
- The `VMware Workstation and Player <https://www.vmware.com/>`__ hypervisors
|
||||
- The `VMware Fusion <https://www.vmware.com/fusion>`__ hypervisor
|
||||
|
||||
Connections to VMware driver
|
||||
----------------------------
|
||||
|
||||
The libvirt VMware driver provides per-user drivers (the "session" instance).
|
||||
Three uris are available:
|
||||
|
||||
- "vmwareplayer" for VMware Player
|
||||
- "vmwarews" for VMware Workstation
|
||||
- "vmwarefusion" for VMware Fusion
|
||||
|
||||
Some example connection URIs for the driver are:
|
||||
|
||||
::
|
||||
|
||||
vmwareplayer:///session (local access to VMware Player per-user instance)
|
||||
vmwarews:///session (local access to VMware Workstation per-user instance)
|
||||
vmwarefusion:///session (local access to VMware Fusion 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)
|
||||
|
||||
Example domain XML config
|
||||
-------------------------
|
||||
|
||||
::
|
||||
|
||||
<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>
|
|
@ -0,0 +1,338 @@
|
|||
.. role:: since
|
||||
|
||||
===============================
|
||||
libxl hypervisor driver for Xen
|
||||
===============================
|
||||
|
||||
.. contents::
|
||||
|
||||
The libvirt libxl driver provides the ability to manage virtual machines on any
|
||||
Xen release from 4.6.0 onwards.
|
||||
|
||||
Project Links
|
||||
-------------
|
||||
|
||||
- The `Xen <https://www.xenproject.org>`__ hypervisor on Linux and Solaris
|
||||
hosts
|
||||
|
||||
Deployment pre-requisites
|
||||
-------------------------
|
||||
|
||||
The libvirt libxl driver uses Xen's libxl API, also known as libxenlight, to
|
||||
implement libvirt's hypervisor driver functionality. libxl provides a
|
||||
consolidated interface for managing a Xen host and its virtual machines, unlike
|
||||
old versions of Xen where applications often had to communicate with xend,
|
||||
xenstored, and the hypervisor itself via hypercalls. With libxl the only
|
||||
pre-requisit is a properly installed Xen host with the libxl toolstack running
|
||||
in a service domain (often Domain-0).
|
||||
|
||||
Connections to libxl driver
|
||||
---------------------------
|
||||
|
||||
The libvirt libxl driver is a single-instance privileged driver, with a driver
|
||||
name of 'xen'. Some example connection URIs for the libxl driver are:
|
||||
|
||||
::
|
||||
|
||||
xen:///system (local access, direct)
|
||||
xen+unix:///system (local access, via daemon)
|
||||
xen://example.com/system (remote access, TLS/x509)
|
||||
xen+tcp://example.com/system (remote access, SASl/Kerberos)
|
||||
xen+ssh://root@example.com/system (remote access, SSH tunnelled)
|
||||
|
||||
Location of configuration files
|
||||
-------------------------------
|
||||
|
||||
The libxl driver comes with sane default values. However, during its
|
||||
initialization it reads a configuration file which offers system administrator
|
||||
to override some of that default. The file is located under
|
||||
``/etc/libvirt/libxl.conf``
|
||||
|
||||
Import and export of libvirt domain XML configs
|
||||
-----------------------------------------------
|
||||
|
||||
The libxl driver currently supports three native config formats. The first,
|
||||
known as ``xen-xm``, is the original Xen virtual machine config format used by
|
||||
the legacy xm/xend toolstack. The second, known as ``xen-sxpr``, is also one of
|
||||
the original formats that was used by xend's legacy HTTP RPC service (
|
||||
:since:`removed in 5.6.0` )
|
||||
|
||||
The third format is ``xen-xl``, which is the virtual machine config format
|
||||
supported by modern Xen. The ``xen-xl`` format is described in the xl.cfg(5) man
|
||||
page.
|
||||
|
||||
Converting from XM config files to domain XML
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh domxml-from-native`` provides a way to convert an existing set of
|
||||
xl, xm, or sxpr config files to libvirt Domain XML, which can then be used by
|
||||
libvirt.
|
||||
|
||||
::
|
||||
|
||||
$ virsh -c xen:///system 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>
|
||||
|
||||
Converting from domain XML to XM config files
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``virsh domxml-to-native`` provides a way to convert a guest description
|
||||
using libvirt Domain XML into xl, xm, or sxpr config format.
|
||||
|
||||
::
|
||||
|
||||
$ virsh -c xen:///system 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" ]
|
||||
|
||||
Pass-through of arbitrary command-line arguments to the qemu device model
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
:since:`Since 6.7.0` , the Xen driver supports passing arbitrary command-line
|
||||
arguments to the qemu device model used by Xen with the ``<xen:commandline>``
|
||||
element under ``domain``. In order to use command-line pass-through, an XML
|
||||
namespace request must be issued that pulls in
|
||||
``http://libvirt.org/schemas/domain/xen/1.0``. With the namespace in place, it
|
||||
is then possible to add ``<xen:arg>``\ sub-elements to ``<xen:commandline>``
|
||||
describing each argument passed to the device model when starting the domain.
|
||||
|
||||
The following example illustrates passing arguments to the QEMU device model
|
||||
that define a floppy drive, which Xen does not support through its public APIs:
|
||||
|
||||
::
|
||||
|
||||
<domain type="xen" xmlns:xen="http://libvirt.org/schemas/domain/xen/1.0">
|
||||
...
|
||||
<xen:commandline>
|
||||
<xen:arg value='-drive'/>
|
||||
<xen:arg value='file=/path/to/image,format=raw,if=none,id=drive-fdc0-0-0'/>
|
||||
<xen:arg value='-global'/>
|
||||
<xen:arg value='isa-fdc.driveA=drive-fdc0-0-0'/>
|
||||
</xen:commandline>
|
||||
</domain>
|
||||
|
||||
Example domain XML config
|
||||
-------------------------
|
||||
|
||||
Below are some example XML configurations for Xen guest domains. For full
|
||||
details of the available options, consult the `domain XML
|
||||
format <formatdomain.html>`__ guide.
|
||||
|
||||
Paravirtualized guest bootloader
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Using a bootloader allows a paravirtualized guest to be booted using a kernel
|
||||
stored inside its virtual disk image
|
||||
|
||||
::
|
||||
|
||||
<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>
|
||||
|
||||
Paravirtualized guest direct kernel boot
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For installation of paravirtualized guests it is typical to boot the domain
|
||||
using a kernel and initrd stored in the host OS
|
||||
|
||||
::
|
||||
|
||||
<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>
|
||||
|
||||
Fullyvirtualized guest BIOS boot
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Fullyvirtualized guests use the emulated BIOS to boot off the primary harddisk,
|
||||
CDROM or Network PXE ROM.
|
||||
|
||||
::
|
||||
|
||||
<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>
|
||||
|
||||
Fullyvirtualized guest direct kernel boot
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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.
|
||||
|
||||
::
|
||||
|
||||
<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>
|
|
@ -0,0 +1,109 @@
|
|||
==================
|
||||
Handling of errors
|
||||
==================
|
||||
|
||||
The main goals of libvirt when it comes to error handling are:
|
||||
|
||||
- provide as much detail as possible
|
||||
- provide the information as soon as possible
|
||||
- dont force the library user into one style of error handling
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
So error handling in the code is the following:
|
||||
|
||||
#. if the error can be associated to a connection for example when failing to
|
||||
look up a domain
|
||||
|
||||
#. if there is a callback associated to the connection set with
|
||||
`virConnSetErrorFunc <html/libvirt-virterror.html#virConnSetErrorFunc>`__,
|
||||
call it with the error information
|
||||
#. otherwise if there is a global callback set with
|
||||
`virSetErrorFunc <html/libvirt-virterror.html#virSetErrorFunc>`__, call it
|
||||
with the error information
|
||||
#. otherwise call
|
||||
`virDefaultErrorFunc <html/libvirt-virterror.html#virDefaultErrorFunc>`__
|
||||
which is the default error function of the library issuing the error on
|
||||
stderr
|
||||
#. save the error in the connection for later retrieval with
|
||||
`virConnGetLastError <html/libvirt-virterror.html#virConnGetLastError>`__
|
||||
|
||||
#. otherwise like when failing to create a hypervisor connection:
|
||||
|
||||
#. if there is a global callback set with
|
||||
`virSetErrorFunc <html/libvirt-virterror.html#virSetErrorFunc>`__, call it
|
||||
with the error information
|
||||
#. otherwise call
|
||||
`virDefaultErrorFunc <html/libvirt-virterror.html#virDefaultErrorFunc>`__
|
||||
which is the default error function of the library issuing the error on
|
||||
stderr
|
||||
#. save the error in the connection for later retrieval with
|
||||
`virGetLastError <html/libvirt-virterror.html#virGetLastError>`__
|
||||
|
||||
In all cases the error information is provided as a
|
||||
`virErrorPtr <html/libvirt-virterror.html#virErrorPtr>`__ pointer to read-only
|
||||
structure `virError <html/libvirt-virterror.html#virError>`__ containing the
|
||||
following fields:
|
||||
|
||||
- code: an error number from the
|
||||
`virErrorNumber <html/libvirt-virterror.html#virErrorNumber>`__ enum
|
||||
- domain: an enum indicating which part of libvirt raised the error see
|
||||
`virErrorDomain <html/libvirt-virterror.html#virErrorDomain>`__
|
||||
- level: the error level, usually VIR_ERR_ERROR, though there is room for
|
||||
warnings like VIR_ERR_WARNING
|
||||
- message: the full human-readable formatted string of the error
|
||||
- conn: if available a pointer to the
|
||||
`virConnectPtr <html/libvirt-libvirt-host.html#virConnectPtr>`__ connection
|
||||
to the hypervisor where this happened
|
||||
- dom: if available a pointer to the
|
||||
`virDomainPtr <html/libvirt-libvirt-domain.html#virDomainPtr>`__ domain
|
||||
targeted in the operation
|
||||
|
||||
and then extra raw information about the error which may be initialized to 0 or
|
||||
NULL if unused
|
||||
|
||||
- str1, str2, str3: string information, usually str1 is the error message
|
||||
format
|
||||
- int1, int2: integer information
|
||||
|
||||
So usually, setting up specific error handling with libvirt consist of
|
||||
registering a handler with
|
||||
`virSetErrorFunc <html/libvirt-virterror.html#virSetErrorFunc>`__ or with
|
||||
`virConnSetErrorFunc <html/libvirt-virterror.html#virConnSetErrorFunc>`__, check
|
||||
the value of the code value, take appropriate action, if needed let libvirt
|
||||
print the error on stderr by calling
|
||||
`virDefaultErrorFunc <html/libvirt-virterror.html#virDefaultErrorFunc>`__. 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
|
||||
`virResetError <html/libvirt-virterror.html#virResetLastError>`__ or
|
||||
`virConnResetLastError <html/libvirt-virterror.html#virConnResetLastError>`__
|
||||
once an error has been processed fully.
|
||||
|
||||
At the python level, there only a global reporting callback function at this
|
||||
point, see the error.py example about it:
|
||||
|
||||
::
|
||||
|
||||
def handler(ctxt, err):
|
||||
global errno
|
||||
|
||||
#print "handler(%s, %s)" % (ctxt, err)
|
||||
errno = err
|
||||
|
||||
libvirt.registerErrorHandler(handler, 'context')
|
||||
|
||||
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.
|
Binary file not shown.
After Width: | Height: | Size: 872 B |
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,506 @@
|
|||
=========================================
|
||||
Firewall and network filtering in libvirt
|
||||
=========================================
|
||||
|
||||
.. contents::
|
||||
|
||||
There are three pieces of libvirt functionality which do network filtering of
|
||||
some type. At a high level they are:
|
||||
|
||||
- The virtual network driver
|
||||
|
||||
This provides an isolated bridge device (ie no physical NICs attached).
|
||||
Guest TAP devices are attached to this bridge. Guests can talk to each
|
||||
other and the host, and optionally the wider world.
|
||||
|
||||
- The QEMU driver MAC filtering
|
||||
|
||||
This provides a generic filtering of MAC addresses to prevent the guest
|
||||
spoofing its MAC address. This is mostly obsoleted by the next item, so
|
||||
won't be discussed further.
|
||||
|
||||
- The network filter driver
|
||||
|
||||
This provides fully configurable, arbitrary network filtering of traffic on
|
||||
guest NICs. Generic rulesets are defined at the host level to control
|
||||
traffic in some manner. Rules sets are then associated with individual NICs
|
||||
of a guest. While not as expressive as directly using iptables/ebtables,
|
||||
this can still do nearly everything you would want to on a guest NIC
|
||||
filter.
|
||||
|
||||
The virtual network driver
|
||||
--------------------------
|
||||
|
||||
The typical configuration for guests is to use bridging of the physical NIC on
|
||||
the host to connect the guest directly to the LAN. In RHEL6 there is also the
|
||||
possibility of using macvtap/sr-iov and VEPA connectivity. None of this stuff
|
||||
plays nicely with wireless NICs, since they will typically silently drop any
|
||||
traffic with a MAC address that doesn't match that of the physical NIC.
|
||||
|
||||
Thus the virtual network driver in libvirt was invented. This takes the form of
|
||||
an isolated bridge device (ie one with no physical NICs attached). The TAP
|
||||
devices associated with the guest NICs are attached to the bridge device. This
|
||||
immediately allows guests on a single host to talk to each other and to the host
|
||||
OS (modulo host IPtables rules).
|
||||
|
||||
libvirt then uses iptables to control what further connectivity is available.
|
||||
There are three configurations possible for a virtual network at time of
|
||||
writing:
|
||||
|
||||
- isolated: all off-node traffic is completely blocked
|
||||
- nat: outbound traffic to the LAN is allowed, but MASQUERADED
|
||||
- forward: outbound traffic to the LAN is allowed
|
||||
|
||||
The latter 'forward' case requires the virtual network be on a separate sub-net
|
||||
from the main LAN, and that the LAN admin has configured routing for this
|
||||
subnet. In the future we intend to add support for IP subnetting and/or
|
||||
proxy-arp. This allows for the virtual network to use the same subnet as the
|
||||
main LAN and should avoid need for the LAN admin to configure special routing.
|
||||
|
||||
Libvirt will optionally also provide DHCP services to the virtual network using
|
||||
DNSMASQ. In all cases, we need to allow DNS/DHCP queries to the host OS. Since
|
||||
we can't predict whether the host firewall setup is already allowing this, we
|
||||
insert 4 rules into the head of the INPUT chain
|
||||
|
||||
::
|
||||
|
||||
target prot opt in out source destination
|
||||
ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
|
||||
ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
|
||||
ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
|
||||
ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
|
||||
|
||||
Note we have restricted our rules to just the bridge associated with the virtual
|
||||
network, to avoid opening undesirable holes in the host firewall wrt the
|
||||
LAN/WAN.
|
||||
|
||||
The next rules depend on the type of connectivity allowed, and go in the main
|
||||
FORWARD chain:
|
||||
|
||||
- | type=isolated
|
||||
| Allow traffic between guests. Deny inbound. Deny outbound.
|
||||
|
||||
::
|
||||
|
||||
target prot opt in out source destination
|
||||
ACCEPT all -- virbr1 virbr1 0.0.0.0/0 0.0.0.0/0
|
||||
REJECT all -- * virbr1 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
|
||||
REJECT all -- virbr1 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
|
||||
|
||||
- | type=nat
|
||||
| Allow inbound related to an established connection. Allow outbound, but
|
||||
only from our expected subnet. Allow traffic between guests. Deny all other
|
||||
inbound. Deny all other outbound.
|
||||
|
||||
::
|
||||
|
||||
target prot opt in out source destination
|
||||
ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 state RELATED,ESTABLISHED
|
||||
ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0
|
||||
ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
|
||||
REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
|
||||
REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
|
||||
|
||||
- | type=routed
|
||||
| Allow inbound, but only to our expected subnet. Allow outbound, but only
|
||||
from our expected subnet. Allow traffic between guests. Deny all other
|
||||
inbound. Deny all other outbound.
|
||||
|
||||
::
|
||||
|
||||
target prot opt in out source destination
|
||||
ACCEPT all -- * virbr2 0.0.0.0/0 192.168.124.0/24
|
||||
ACCEPT all -- virbr2 * 192.168.124.0/24 0.0.0.0/0
|
||||
ACCEPT all -- virbr2 virbr2 0.0.0.0/0 0.0.0.0/0
|
||||
REJECT all -- * virbr2 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
|
||||
REJECT all -- virbr2 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
|
||||
|
||||
- Finally, with type=nat, there is also an entry in the POSTROUTING chain to
|
||||
apply masquerading:
|
||||
|
||||
::
|
||||
|
||||
target prot opt in out source destination
|
||||
MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
|
||||
|
||||
firewalld and the virtual network driver
|
||||
----------------------------------------
|
||||
|
||||
If `firewalld <https://firewalld.org>`__ is active on the host, libvirt will
|
||||
attempt to place the bridge interface of a libvirt virtual network into the
|
||||
firewalld zone named "libvirt" (thus making all guest->host traffic on that
|
||||
network subject to the rules of the "libvirt" zone). This is done because, if
|
||||
firewalld is using its nftables backend (available since firewalld 0.6.0) the
|
||||
default firewalld zone (which would be used if libvirt didn't explicitly set the
|
||||
zone) prevents forwarding traffic from guests through the bridge, as well as
|
||||
preventing DHCP, DNS, and most other traffic from guests to host. The zone named
|
||||
"libvirt" is installed into the firewalld configuration by libvirt (not by
|
||||
firewalld), and allows forwarded traffic through the bridge as well as DHCP,
|
||||
DNS, TFTP, and SSH traffic to the host - depending on firewalld's backend this
|
||||
will be implemented via either iptables or nftables rules. libvirt's own rules
|
||||
outlined above will \*always\* be iptables rules regardless of which backend is
|
||||
in use by firewalld.
|
||||
|
||||
NB: It is possible to manually set the firewalld zone for a network's interface
|
||||
with the "zone" attribute of the network's "bridge" element.
|
||||
|
||||
NB: Prior to libvirt 5.1.0, the firewalld "libvirt" zone did not exist, and
|
||||
prior to firewalld 0.7.0 a feature crucial to making the "libvirt" zone operate
|
||||
properly (rich rule priority settings) was not implemented in firewalld. In
|
||||
cases where one or the other of the two packages is missing the necessary
|
||||
functionality, it's still possible to have functional guest networking by
|
||||
setting the firewalld backend to "iptables" (in firewalld prior to 0.6.0, this
|
||||
was the only backend available).
|
||||
|
||||
The network filter driver
|
||||
-------------------------
|
||||
|
||||
This driver provides a fully configurable network filtering capability that
|
||||
leverages ebtables, iptables and ip6tables. This was written by the libvirt guys
|
||||
at IBM and although its XML schema is defined by libvirt, the conceptual model
|
||||
is closely aligned with the DMTF CIM schema for network filtering:
|
||||
|
||||
https://www.dmtf.org/standards/cim/cim_schema_v2230/CIM_Network.pdf
|
||||
|
||||
The filters are managed in libvirt as a top level, standalone object. This
|
||||
allows the filters to then be referenced by any libvirt object that requires
|
||||
their functionality, instead tying them only to use by guest NICs. In the
|
||||
current implementation, filters can be associated with individual guest NICs via
|
||||
the libvirt domain XML format. In the future we might allow filters to be
|
||||
associated with the virtual network objects. Further we're expecting to define a
|
||||
new 'virtual switch' object to remove the complexity of configuring
|
||||
bridge/sriov/vepa networking modes. This make also end up making use of network
|
||||
filters.
|
||||
|
||||
There are a new set of virsh commands for managing network filters:
|
||||
|
||||
- ``virsh nwfilter-define``
|
||||
define or update a network filter from an XML file
|
||||
- ``virsh nwfilter-undefine``
|
||||
undefine a network filter
|
||||
- ``virsh nwfilter-dumpxml``
|
||||
network filter information in XML
|
||||
- ``virsh nwfilter-list``
|
||||
list network filters
|
||||
- ``virsh nwfilter-edit``
|
||||
edit XML configuration for a network filter
|
||||
|
||||
There are equivalently named C APIs for each of these commands.
|
||||
|
||||
As with all objects libvirt manages, network filters are configured using an XML
|
||||
format. At a high level the format looks like this:
|
||||
|
||||
::
|
||||
|
||||
<filter name='no-spamming' chain='XXXX'>
|
||||
<uuid>d217f2d7-5a04-0e01-8b98-ec2743436b74</uuid>
|
||||
|
||||
<rule ...>
|
||||
....
|
||||
</rule>
|
||||
|
||||
<filterref filter='XXXX'/>
|
||||
</filter>
|
||||
|
||||
Every filter has a name and UUID which serve as unique identifiers. A filter can
|
||||
have zero-or-more ``<rule>`` elements which are used to actually define network
|
||||
controls. Filters can be arranged into a DAG, so zero-or-more ``<filterref/>``
|
||||
elements are also allowed. Cycles in the graph are not allowed.
|
||||
|
||||
The ``<rule>`` element is where all the interesting stuff happens. It has three
|
||||
attributes, an action, a traffic direction and an optional priority. E.g.:
|
||||
|
||||
::
|
||||
|
||||
<rule action='drop' direction='out' priority='500'>
|
||||
|
||||
Within the rule there are a wide variety of elements allowed, which do protocol
|
||||
specific matching. Supported protocols currently include ``mac``, ``arp``,
|
||||
``rarp``, ``ip``, ``ipv6``, ``tcp/ip``, ``icmp/ip``, ``igmp/ip``, ``udp/ip``,
|
||||
``udplite/ip``, ``esp/ip``, ``ah/ip``, ``sctp/ip``, ``tcp/ipv6``, ``icmp/ipv6``,
|
||||
``igmp/ipv6``, ``udp/ipv6``, ``udplite/ipv6``, ``esp/ipv6``, ``ah/ipv6``,
|
||||
``sctp/ipv6``. Each protocol defines what is valid inside the <rule> element.
|
||||
The general pattern though is:
|
||||
|
||||
::
|
||||
|
||||
<protocol match='yes|no' attribute1='value1' attribute2='value2'/>
|
||||
|
||||
So, eg a TCP protocol, matching ports 0-1023 would be expressed as:
|
||||
|
||||
::
|
||||
|
||||
<tcp match='yes' srcportstart='0' srcportend='1023'/>
|
||||
|
||||
Attributes can included references to variables defined by the object using the
|
||||
rule. So the guest XML format allows each NIC to have a MAC address and IP
|
||||
address defined. These are made available to filters via the variables ``$IP``
|
||||
and ``$MAC``.
|
||||
|
||||
So to define a filter that prevents IP address spoofing we can simply match on
|
||||
source IP address ``!= $IP`` like this:
|
||||
|
||||
::
|
||||
|
||||
<filter name='no-ip-spoofing' chain='ipv4'>
|
||||
<rule action='drop' direction='out'>
|
||||
<ip match='no' srcipaddr='$IP' />
|
||||
</rule>
|
||||
</filter>
|
||||
|
||||
I'm not going to go into details on all the other protocol matches you can do,
|
||||
because it'll take far too much space. You can read about the options
|
||||
`here <formatnwfilter.html#supported-protocols>`__.
|
||||
|
||||
Out of the box in RHEL6/Fedora rawhide, libvirt ships with a set of default
|
||||
useful rules:
|
||||
|
||||
::
|
||||
|
||||
# virsh nwfilter-list
|
||||
UUID Name
|
||||
----------------------------------------------------------------
|
||||
15b1ab2b-b1ac-1be2-ed49-2042caba4abb allow-arp
|
||||
6c51a466-8d14-6d11-46b0-68b1a883d00f allow-dhcp
|
||||
7517ad6c-bd90-37c8-26c9-4eabcb69848d allow-dhcp-server
|
||||
7680776c-77aa-496f-90d6-13097664b925 allow-dhcpv6
|
||||
9cdaad60-7631-4172-8ccb-ef774be7485b allow-dhcpv6-server
|
||||
3d38b406-7cf0-8335-f5ff-4b9add35f288 allow-incoming-ipv4
|
||||
908543c1-902e-45f6-a6ca-1a0ad35e7599 allow-incoming-ipv6
|
||||
5ff06320-9228-2899-3db0-e32554933415 allow-ipv4
|
||||
ce8904cc-ad3a-4454-896c-53452882f817 allow-ipv6
|
||||
db0b1767-d62b-269b-ea96-0cc8b451144e clean-traffic
|
||||
6d6ddcc8-1242-4c43-ac63-63af80493132 clean-traffic-gateway
|
||||
4cf38077-c7d5-4e25-99bb-6c4c9efad294 no-arp-ip-spoofing
|
||||
0b11a636-ce58-497f-be90-17f63c92487a no-arp-mac-spoofing
|
||||
f88f1932-debf-4aa1-9fbe-f10d3aa4bc95 no-arp-spoofing
|
||||
772f112d-52e4-700c-0250-e178a3d91a7a no-ip-multicast
|
||||
7ee20370-8106-765d-f7ff-8a60d5aaf30b no-ip-spoofing
|
||||
f8a51c43-a08f-49b3-b9e2-393d54522dc0 no-ipv6-multicast
|
||||
a7f0afe9-a428-44b8-8566-c8ee2a669271 no-ipv6-spoofing
|
||||
d5d3c490-c2eb-68b1-24fc-3ee362fc8af3 no-mac-broadcast
|
||||
fb57c546-76dc-a372-513f-e8179011b48a no-mac-spoofing
|
||||
dba10ea7-446d-76de-346f-335bd99c1d05 no-other-l2-traffic
|
||||
f5c78134-9da4-0c60-a9f0-fb37bc21ac1f no-other-rarp-traffic
|
||||
7637e405-4ccf-42ac-5b41-14f8d03d8cf3 qemu-announce-self
|
||||
9aed52e7-f0f3-343e-fe5c-7dcb27b594e5 qemu-announce-self-rarp
|
||||
|
||||
Most of these are just building blocks. The interesting one here is
|
||||
'clean-traffic'. This pulls together all the building blocks into one filter
|
||||
that you can then associate with a guest NIC. This stops the most common bad
|
||||
things a guest might try, IP spoofing, arp spoofing and MAC spoofing. To look at
|
||||
the rules for any of these just do:
|
||||
|
||||
::
|
||||
|
||||
virsh nwfilter-dumpxml FILTERNAME|UUID
|
||||
|
||||
They are all stored in ``/etc/libvirt/nwfilter``, but don't edit the files there
|
||||
directly. Use ``virsh nwfilter-define`` to update them. This ensures the guests
|
||||
have their iptables/ebtables rules recreated.
|
||||
|
||||
To associate the clean-traffic filter with a guest, edit the guest XML config
|
||||
and change the ``<interface>`` element to include a ``<filterref>`` and also
|
||||
specify the ``<ip address/>`` that the guest is allowed to use:
|
||||
|
||||
::
|
||||
|
||||
<interface type='bridge'>
|
||||
<mac address='52:54:00:56:44:32'/>
|
||||
<source bridge='br1'/>
|
||||
<ip address='10.33.8.131'/>
|
||||
<target dev='vnet0'/>
|
||||
<model type='virtio'/>
|
||||
<filterref filter='clean-traffic'/>
|
||||
</interface>
|
||||
|
||||
If no ``<ip address>`` is included, the network filter driver will activate its
|
||||
'learning mode'. This uses libpcap to snoop on network traffic the guest sends
|
||||
and attempts to identify the first IP address it uses. It then locks traffic to
|
||||
this address. Obviously this isn't entirely secure, but it does offer some
|
||||
protection against the guest being trojaned once up and running. In the future
|
||||
we intend to enhance the learning mode so that it looks for DHCPOFFERS from a
|
||||
trusted DHCP server and only allows the offered IP address to be used.
|
||||
|
||||
Now, how is all this implemented...?
|
||||
|
||||
The network filter driver uses a combination of ebtables, iptables and
|
||||
ip6tables, depending on which protocols are referenced in a filter. The out of
|
||||
the box 'clean-traffic' filter rules only require use of ebtables. If you want
|
||||
to do matching at tcp/udp/etc protocols (eg to add a new filter
|
||||
'no-email-spamming' to block port 25), then iptables will also be used.
|
||||
|
||||
The driver attempts to keep its rules separate from those that the host admin
|
||||
might already have configured. So the first thing it does with ebtables, is to
|
||||
add two hooks in POSTROUTING and PREROUTING chains, to redirect traffic to
|
||||
custom chains. These hooks match on the TAP device name of the guest NIC, so
|
||||
they should not interact badly with any administrator defined rules:
|
||||
|
||||
::
|
||||
|
||||
Bridge chain: PREROUTING, entries: 1, policy: ACCEPT
|
||||
-i vnet0 -j libvirt-I-vnet0
|
||||
|
||||
Bridge chain: POSTROUTING, entries: 1, policy: ACCEPT
|
||||
-o vnet0 -j libvirt-O-vnet0
|
||||
|
||||
To keep things manageable and easy to follow, the driver will then create
|
||||
further sub-chains for each protocol then it needs to match against:
|
||||
|
||||
::
|
||||
|
||||
Bridge chain: libvirt-I-vnet0, entries: 5, policy: ACCEPT
|
||||
-p IPv4 -j I-vnet0-ipv4
|
||||
-p ARP -j I-vnet0-arp
|
||||
-p 0x8035 -j I-vnet0-rarp
|
||||
-p 0x835 -j ACCEPT
|
||||
-j DROP
|
||||
|
||||
Bridge chain: libvirt-O-vnet0, entries: 4, policy: ACCEPT
|
||||
-p IPv4 -j O-vnet0-ipv4
|
||||
-p ARP -j O-vnet0-arp
|
||||
-p 0x8035 -j O-vnet0-rarp
|
||||
-j DROP
|
||||
|
||||
Finally, here comes the actual implementation of the filters. This example shows
|
||||
the 'clean-traffic' filter implementation. I'm not going to explain what this is
|
||||
doing now. :-)
|
||||
|
||||
::
|
||||
|
||||
Bridge chain: I-vnet0-ipv4, entries: 2, policy: ACCEPT
|
||||
-s ! 52:54:0:56:44:32 -j DROP
|
||||
-p IPv4 --ip-src ! 10.33.8.131 -j DROP
|
||||
|
||||
Bridge chain: O-vnet0-ipv4, entries: 1, policy: ACCEPT
|
||||
-j ACCEPT
|
||||
|
||||
Bridge chain: I-vnet0-arp, entries: 6, policy: ACCEPT
|
||||
-s ! 52:54:0:56:44:32 -j DROP
|
||||
-p ARP --arp-mac-src ! 52:54:0:56:44:32 -j DROP
|
||||
-p ARP --arp-ip-src ! 10.33.8.131 -j DROP
|
||||
-p ARP --arp-op Request -j ACCEPT
|
||||
-p ARP --arp-op Reply -j ACCEPT
|
||||
-j DROP
|
||||
|
||||
Bridge chain: O-vnet0-arp, entries: 5, policy: ACCEPT
|
||||
-p ARP --arp-op Reply --arp-mac-dst ! 52:54:0:56:44:32 -j DROP
|
||||
-p ARP --arp-ip-dst ! 10.33.8.131 -j DROP
|
||||
-p ARP --arp-op Request -j ACCEPT
|
||||
-p ARP --arp-op Reply -j ACCEPT
|
||||
-j DROP
|
||||
|
||||
Bridge chain: I-vnet0-rarp, entries: 2, policy: ACCEPT
|
||||
-p 0x8035 -s 52:54:0:56:44:32 -d Broadcast --arp-op Request_Reverse --arp-ip-src 0.0.0.0 --arp-ip-dst 0.0.0.0 --arp-mac-src 52:54:0:56:44:32 --arp-mac-dst 52:54:0:56:44:32 -j ACCEPT
|
||||
-j DROP
|
||||
|
||||
Bridge chain: O-vnet0-rarp, entries: 2, policy: ACCEPT
|
||||
-p 0x8035 -d Broadcast --arp-op Request_Reverse --arp-ip-src 0.0.0.0 --arp-ip-dst 0.0.0.0 --arp-mac-src 52:54:0:56:44:32 --arp-mac-dst 52:54:0:56:44:32 -j ACCEPT
|
||||
-j DROP
|
||||
|
||||
NB, we would have liked to include the prefix 'libvirt-' in all of our chain
|
||||
names, but unfortunately the kernel limits names to a very short maximum length.
|
||||
So only the first two custom chains can include that prefix. The others just
|
||||
include the TAP device name + protocol name.
|
||||
|
||||
If I define a new filter 'no-spamming' and then add this to the 'clean-traffic'
|
||||
filter, I can illustrate how iptables usage works:
|
||||
|
||||
::
|
||||
|
||||
# cat > /root/spamming.xml <<EOF
|
||||
<filter name='no-spamming' chain='root'>
|
||||
<uuid>d217f2d7-5a04-0e01-8b98-ec2743436b74</uuid>
|
||||
<rule action='drop' direction='out' priority='500'>
|
||||
<tcp dstportstart='25' dstportend='25'/>
|
||||
</rule>
|
||||
</filter>
|
||||
EOF
|
||||
# virsh nwfilter-define /root/spamming.xml
|
||||
# virsh nwfilter-edit clean-traffic
|
||||
|
||||
...add ``<filterref filter='no-spamming'/>``
|
||||
|
||||
All active guests immediately have their iptables/ebtables rules rebuilt.
|
||||
|
||||
The network filter driver deals with iptables in a very similar way. First it
|
||||
separates out its rules from those the admin may have defined, by adding a
|
||||
couple of hooks into the INPUT/FORWARD chains:
|
||||
|
||||
::
|
||||
|
||||
Chain INPUT (policy ACCEPT 13M packets, 21G bytes)
|
||||
target prot opt in out source destination
|
||||
libvirt-host-in all -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
|
||||
Chain FORWARD (policy ACCEPT 5532K packets, 3010M bytes)
|
||||
target prot opt in out source destination
|
||||
libvirt-in all -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
libvirt-out all -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
libvirt-in-post all -- * * 0.0.0.0/0 0.0.0.0/0
|
||||
|
||||
These custom chains then do matching based on the TAP device name, so they won't
|
||||
open holes in the admin defined matches for the LAN/WAN (if any).
|
||||
|
||||
::
|
||||
|
||||
Chain libvirt-host-in (1 references)
|
||||
target prot opt in out source destination
|
||||
HI-vnet0 all -- * * 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-in vnet0
|
||||
|
||||
Chain libvirt-in (1 references)
|
||||
target prot opt in out source destination
|
||||
FI-vnet0 all -- * * 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-in vnet0
|
||||
|
||||
Chain libvirt-in-post (1 references)
|
||||
target prot opt in out source destination
|
||||
ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in vnet0
|
||||
|
||||
Chain libvirt-out (1 references)
|
||||
target prot opt in out source destination
|
||||
FO-vnet0 all -- * * 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-out vnet0
|
||||
|
||||
Finally, we can see the interesting bit which is the actual implementation of my
|
||||
filter to block port 25 access:
|
||||
|
||||
::
|
||||
|
||||
Chain FI-vnet0 (1 references)
|
||||
target prot opt in out source destination
|
||||
DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:25
|
||||
|
||||
Chain FO-vnet0 (1 references)
|
||||
target prot opt in out source destination
|
||||
DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:25
|
||||
|
||||
Chain HI-vnet0 (1 references)
|
||||
target prot opt in out source destination
|
||||
DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:25
|
||||
|
||||
One thing in looking at this you may notice is that if there are many guests all
|
||||
using the same filters, we will be duplicating the iptables rules over and over
|
||||
for each guest. This is merely a limitation of the current rules engine
|
||||
implementation. At the libvirt object modelling level you can clearly see we've
|
||||
designed the model so filter rules are defined in one place, and indirectly
|
||||
referenced by guests. Thus it should be possible to change the implementation in
|
||||
the future so we can share the actual iptables/ebtables rules for each guest to
|
||||
create a more scalable system. The stuff in current libvirt is more or less the
|
||||
very first working implementation we've had of this, so there's not been much
|
||||
optimization work done yet.
|
||||
|
||||
Also notice that at the XML level we don't expose the fact we are using iptables
|
||||
or ebtables at all. The rule definition is done in terms of network protocols.
|
||||
Thus if we ever find a need, we could plug in an alternative implementation that
|
||||
calls out to a different firewall implementation instead of ebtables/iptables
|
||||
(providing that implementation was suitably expressive of course)
|
||||
|
||||
Finally, in terms of problems we have in deployment. The biggest problem is that
|
||||
if the admin does ``service iptables restart`` all our work gets blown away.
|
||||
We've experimented with using lokkit to record our custom rules in a persistent
|
||||
config file, but that caused different problem. Admins who were not using lokkit
|
||||
for their config found that all their own rules got blown away. So we threw away
|
||||
our lokkit code. Instead we document that if you run
|
||||
``service iptables restart``, you need to send SIGHUP to libvirt to make it
|
||||
recreate its rules.
|
||||
|
||||
More in depth documentation on this is `here <formatnwfilter.html>`__.
|
|
@ -0,0 +1,104 @@
|
|||
=======
|
||||
License
|
||||
=======
|
||||
|
||||
Copyright (C) 2015 Red Hat, Inc.,
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
=====================
|
||||
SIL OPEN FONT LICENSE
|
||||
=====================
|
||||
|
||||
Version 1.1 - 26 February 2007
|
||||
|
||||
PREAMBLE
|
||||
========
|
||||
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development
|
||||
of collaborative font projects, to support the font creation efforts of
|
||||
academic and linguistic communities, and to provide a free and open framework
|
||||
in which fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The fonts,
|
||||
including any derivative works, can be bundled, embedded, redistributed and/or
|
||||
sold with any software provided that any reserved names are not used by
|
||||
derivative works. The fonts and derivatives, however, cannot be released under
|
||||
any other type of license. The requirement for fonts to remain under this
|
||||
license does not apply to any document created using the fonts or their
|
||||
derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
===========
|
||||
|
||||
“Font Software” refers to the set of files released by the Copyright Holder(s)
|
||||
under this license and clearly marked as such. This may include source files,
|
||||
build scripts and documentation.
|
||||
|
||||
“Reserved Font Name” refers to any names specified as such after the copyright
|
||||
statement(s).
|
||||
|
||||
“Original Version” refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
“Modified Version” refers to any derivative made by adding to, deleting, or
|
||||
substituting—in part or in whole—any of the components of the Original Version,
|
||||
by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
“Author” refers to any designer, engineer, programmer, technical writer or
|
||||
other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
=======================
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
the Font Software, to use, study, copy, merge, embed, modify, redistribute, and
|
||||
sell modified and unmodified copies of the Font Software, subject to the
|
||||
following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in Original
|
||||
or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy contains
|
||||
the above copyright notice and this license. These can be included either as
|
||||
stand-alone text files, human-readable headers or in the appropriate machine-
|
||||
readable metadata fields within text or binary files as long as those fields
|
||||
can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font Name(s)
|
||||
unless explicit written permission is granted by the corresponding Copyright
|
||||
Holder. This restriction only applies to the primary font name as presented to
|
||||
the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software
|
||||
shall not be used to promote, endorse or advertise any Modified Version, except
|
||||
to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s)
|
||||
or with their explicit written permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, must be
|
||||
distributed entirely under this license, and must not be distributed under any
|
||||
other license. The requirement for fonts to remain under this license does not
|
||||
apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
===========
|
||||
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
==========
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
||||
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL,
|
||||
INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE
|
||||
THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -0,0 +1,23 @@
|
|||
fonts = [
|
||||
'LICENSE.rst',
|
||||
'overpass-bold-italic.woff',
|
||||
'overpass-bold.woff',
|
||||
'overpass-italic.woff',
|
||||
'overpass-light-italic.woff',
|
||||
'overpass-light.woff',
|
||||
'overpass-mono-bold.woff',
|
||||
'overpass-mono-light.woff',
|
||||
'overpass-mono-regular.woff',
|
||||
'overpass-mono-semibold.woff',
|
||||
'overpass-regular.woff',
|
||||
]
|
||||
|
||||
install_data(fonts, install_dir: docs_html_dir / 'fonts')
|
||||
|
||||
foreach file : fonts
|
||||
# This hack enables us to view the web pages
|
||||
# from within the uninstalled build tree
|
||||
configure_file(input: file, output: file, copy: true)
|
||||
|
||||
install_web_files += '@0@:@1@'.format(meson.current_source_dir() / file, docs_html_dir / 'fonts')
|
||||
endforeach
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,35 @@
|
|||
==========
|
||||
XML Format
|
||||
==========
|
||||
|
||||
Objects in the libvirt API are configured using XML documents to allow for ease
|
||||
of extension in future releases. Each XML document has an associated Relax-NG
|
||||
schema that can be used to validate documents prior to usage.
|
||||
|
||||
- `Domains <formatdomain.html>`__
|
||||
- `Networks <formatnetwork.html>`__
|
||||
- `Network filtering <formatnwfilter.html>`__
|
||||
- `Network ports <formatnetworkport.html>`__
|
||||
- `Storage <formatstorage.html>`__
|
||||
- `Storage encryption <formatstorageencryption.html>`__
|
||||
- `Capabilities <formatcaps.html>`__
|
||||
- `Domain capabilities <formatdomaincaps.html>`__
|
||||
- `Storage Pool capabilities <formatstoragecaps.html>`__
|
||||
- `Node devices <formatnode.html>`__
|
||||
- `Secrets <formatsecret.html>`__
|
||||
- `Snapshots <formatsnapshot.html>`__
|
||||
- `Checkpoints <formatcheckpoint.html>`__
|
||||
- `Backup jobs <formatbackup.html>`__
|
||||
|
||||
Command line validation
|
||||
-----------------------
|
||||
|
||||
The ``virt-xml-validate`` tool provides a simple command line for validating XML
|
||||
documents prior to giving them to libvirt. It uses the locally installed RNG
|
||||
schema documents. It will auto-detect which schema to use for validation based
|
||||
on the name of the top level element in the input document. Thus it merely
|
||||
requires the XML document filename to be passed on the command line
|
||||
|
||||
::
|
||||
|
||||
$ virt-xml-validate /path/to/XML/file
|
|
@ -0,0 +1,168 @@
|
|||
Backup XML format
|
||||
=================
|
||||
|
||||
.. contents::
|
||||
|
||||
Backup XML
|
||||
----------
|
||||
|
||||
Creating a backup, whether full or incremental, is done via
|
||||
``virDomainBackupBegin()``, which takes an XML description of the actions to
|
||||
perform, as well as an optional second XML document `describing a
|
||||
checkpoint <formatcheckpoint.html>`__ to create at the same point in time. See
|
||||
also `a comparison <kbase/domainstatecapture.html>`__ between the various state
|
||||
capture APIs.
|
||||
|
||||
There are two general modes for backups: a push mode (where the hypervisor
|
||||
writes out the data to the destination file, which may be local or remote), and
|
||||
a pull mode (where the hypervisor creates an NBD server that a third-party
|
||||
client can then read as needed, and which requires the use of temporary storage,
|
||||
typically local, until the backup is complete).
|
||||
|
||||
The instructions for beginning a backup job are provided as attributes and
|
||||
elements of the top-level ``domainbackup`` element. This element includes an
|
||||
optional attribute ``mode`` which can be either "push" or "pull" (default push).
|
||||
``virDomainBackupGetXMLDesc()`` can be used to see the actual values selected
|
||||
for elements omitted during creation (for example, learning which port the NBD
|
||||
server is using in the pull model or what file names libvirt generated when none
|
||||
were supplied). The following child elements and attributes are supported:
|
||||
|
||||
``incremental``
|
||||
An optional element giving the name of an existing checkpoint of the domain,
|
||||
which will be used to make this backup an incremental one. In the push model,
|
||||
only changes since the named checkpoint are written to the destination. In
|
||||
the pull model, the NBD server uses the NBD_OPT_SET_META_CONTEXT extension to
|
||||
advertise to the client which portions of the export contain changes since
|
||||
the named checkpoint. If omitted, a full backup is performed.
|
||||
|
||||
``server``
|
||||
Present only for a pull mode backup. Contains the same attributes as the
|
||||
```protocol`` element of a disk <formatdomain.html#hard-drives-floppy-disks-cdroms>`__ attached
|
||||
via NBD in the domain (such as transport, socket, name, port, or tls),
|
||||
necessary to set up an NBD server that exposes the content of each disk at
|
||||
the time the backup is started.
|
||||
|
||||
Note that for the QEMU hypervisor the TLS environment in controlled using
|
||||
``backup_tls_x509_cert_dir``, ``backup_tls_x509_verify``, and
|
||||
``backup_tls_x509_secret_uuid`` properties in ``/etc/libvirt/qemu.conf``.
|
||||
|
||||
``disks``
|
||||
An optional listing of instructions for disks participating in the backup (if
|
||||
omitted, all disks participate and libvirt attempts to generate filenames by
|
||||
appending the current timestamp as a suffix). If the entire element was
|
||||
omitted on input, then all disks participate in the backup, otherwise, only
|
||||
the disks explicitly listed which do not also use ``backup='no'`` will
|
||||
participate. On output, this is the state of each of the domain's disk in
|
||||
relation to the backup operation.
|
||||
|
||||
``disk``
|
||||
This sub-element describes the backup properties of a specific disk, with
|
||||
the following attributes and child elements:
|
||||
|
||||
``name``
|
||||
A mandatory attribute which must match the ``<target dev='name'/>`` of
|
||||
one of the `disk devices <formatdomain.html#hard-drives-floppy-disks-cdroms>`__ specified
|
||||
for the domain at the time of the checkpoint.
|
||||
|
||||
``backup``
|
||||
Setting this attribute to ``yes``\ (default) specifies that the disk
|
||||
should take part in the backup and using ``no`` excludes the disk from
|
||||
the backup.
|
||||
|
||||
``backupmode``
|
||||
This attribute overrides the implied backup mode inherited from the
|
||||
definition of the backup itself. Value ``full`` forces a full backup
|
||||
even if the backup calls for an incremental backup, and ``incremental``
|
||||
coupled with the attribute ``incremental='CHECKPOINTNAME`` for the disk
|
||||
forces an incremental backup from ``CHECKPOINTNAME``.
|
||||
|
||||
``incremental``
|
||||
An optional attribute giving the name of an existing checkpoint of the
|
||||
domain which overrides the one set by the ``<incremental>`` element.
|
||||
|
||||
``exportname``
|
||||
Allows modification of the NBD export name for the given disk. By
|
||||
default equal to disk target. Valid only for pull mode backups.
|
||||
|
||||
``exportbitmap``
|
||||
Allows modification of the name of the bitmap describing dirty blocks
|
||||
for an incremental backup exported via NBD export name for the given
|
||||
disk. Valid only for pull mode backups.
|
||||
|
||||
``type``
|
||||
A mandatory attribute to describe the type of the disk, except when
|
||||
``backup='no'`` is used. Valid values include ``file``, or ``block``.
|
||||
Similar to a disk declaration for a domain, the choice of type controls
|
||||
what additional sub-elements are needed to describe the destination.
|
||||
|
||||
``index``
|
||||
Output only. The value can be used to refer to the scratch or output
|
||||
file of the backup in APIs such as ``virDomainSetBlockThreshold``.
|
||||
|
||||
``target``
|
||||
Valid only for push mode backups, this is the primary sub-element that
|
||||
describes the file name of the backup destination, similar to the
|
||||
``source`` sub-element of a domain disk. An optional sub-element
|
||||
``driver`` can also be used, with an attribute ``type`` to specify a
|
||||
destination format different from qcow2. See documentation for
|
||||
``scratch`` below for additional configuration.
|
||||
|
||||
``scratch``
|
||||
Valid only for pull mode backups, this is the primary sub-element that
|
||||
describes the file name of the local scratch file to be used in
|
||||
facilitating the backup, and is similar to the ``source`` sub-element
|
||||
of a domain disk. Currently only ``file`` and ``block`` scratch storage
|
||||
is supported. The ``file`` scratch file is created and deleted by
|
||||
libvirt in the given location. A ``block`` scratch device must exist
|
||||
prior to starting the backup and is formatted. The block device must
|
||||
have enough space for the corresponding disk data including format
|
||||
overhead. If ``VIR_DOMAIN_BACKUP_BEGIN_REUSE_EXTERNAL`` flag is used
|
||||
the file for a scratch of ``file`` type must exist with the correct
|
||||
format and size to hold the copy and is used without modification. The
|
||||
file is not deleted after the backup but the contents of the file don't
|
||||
make sense outside of the backup. The same applies for the block device
|
||||
which must be formatted appropriately. Similarly to the domain
|
||||
```disk`` <formatdomain.html#hard-drives-floppy-disks-cdroms>`__ definition ``scratch``
|
||||
and ``target`` can contain ``seclabel`` and/or ``encryption``
|
||||
subelements to configure the corresponding properties.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Use ``virDomainBackupBegin()`` to perform a full backup using push mode. The
|
||||
example lets libvirt pick the destination and format for 'vda', fully specifies
|
||||
that we want a raw backup of 'vdb', and omits 'vdc' from the operation.
|
||||
|
||||
::
|
||||
|
||||
<domainbackup>
|
||||
<disks>
|
||||
<disk name='vda' backup='yes'/>
|
||||
<disk name='vdb' type='file'>
|
||||
<target file='/path/to/vdb.backup'/>
|
||||
<driver type='raw'/>
|
||||
</disk>
|
||||
<disk name='vdc' backup='no'/>
|
||||
</disks>
|
||||
</domainbackup>
|
||||
|
||||
If the previous full backup also passed a parameter describing `checkpoint
|
||||
XML <formatcheckpoint.html>`__ that resulted in a checkpoint named
|
||||
``1525889631``, we can make another call to ``virDomainBackupBegin()`` to
|
||||
perform an incremental backup of just the data changed since that checkpoint,
|
||||
this time using the following XML to start a pull model export of the 'vda' and
|
||||
'vdb' disks, where a third-party NBD client connecting to '/path/to/server'
|
||||
completes the backup (omitting 'vdc' from the explicit list has the same effect
|
||||
as the backup='no' from the previous example):
|
||||
|
||||
::
|
||||
|
||||
<domainbackup mode="pull">
|
||||
<incremental>1525889631</incremental>
|
||||
<server transport="unix" socket="/path/to/server"/>
|
||||
<disks>
|
||||
<disk name='vda' backup='yes' type='file'>
|
||||
<scratch file='/path/to/file1.scratch'/>
|
||||
</disk>
|
||||
</disks>
|
||||
</domainbackup>
|
|
@ -0,0 +1,197 @@
|
|||
.. role:: since
|
||||
|
||||
==============================
|
||||
Driver capabilities XML format
|
||||
==============================
|
||||
|
||||
.. contents::
|
||||
|
||||
Element and attribute overview
|
||||
------------------------------
|
||||
|
||||
As new virtualization engine support gets added to libvirt, and to handle cases
|
||||
like QEMU supporting a variety of emulations, a query interface has been added
|
||||
in 0.2.1 allowing to list the set of supported virtualization capabilities on
|
||||
the host:
|
||||
|
||||
::
|
||||
|
||||
char * virConnectGetCapabilities (virConnectPtr conn);
|
||||
|
||||
The value returned is an XML document listing the virtualization capabilities of
|
||||
the host and virtualization engine to which ```conn`` is connected. One can test
|
||||
it using ``virsh`` command line tool command '``capabilities``', it dumps the
|
||||
XML associated to the current connection.
|
||||
|
||||
As can be seen in the `Examples`_, the capabilities XML
|
||||
consists of the ``capabilities`` element which have exactly one ``host`` child
|
||||
element to report information on host capabilities, and zero or more ``guest``
|
||||
element to express the set of architectures the host can run at the moment.
|
||||
|
||||
Host capabilities
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``<host/>`` element consists of the following child elements:
|
||||
|
||||
``uuid``
|
||||
The host UUID.
|
||||
``cpu``
|
||||
The host CPU architecture and features.
|
||||
``power_management``
|
||||
whether host is capable of memory suspend, disk hibernation, or hybrid
|
||||
suspend.
|
||||
``migration_features``
|
||||
This element exposes information on the hypervisor's migration capabilities,
|
||||
like live migration, supported URI transports, and so on.
|
||||
``topology``
|
||||
This element embodies the host internal topology. Management applications may
|
||||
want to learn this information when orchestrating new guests - e.g. due to
|
||||
reduce inter-NUMA node transfers. Note that the ``sockets`` value reported
|
||||
here is per-NUMA-node; this is in contrast to the value given in domain
|
||||
definitions, which is interpreted as a total number of sockets for the
|
||||
domain.
|
||||
``secmodel``
|
||||
To find out default security labels for different security models you need to
|
||||
parse this element. In contrast with the former elements, this is repeated
|
||||
for each security model the libvirt daemon currently supports.
|
||||
|
||||
Guest capabilities
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
While the previous section (`Host capabilities`_) aims at host capabilities,
|
||||
this one focuses on capabilities available to a guest using a given hypervisor.
|
||||
The ``<guest/>`` element will typically wrap up the following elements:
|
||||
|
||||
``os_type``
|
||||
This expresses what kind of operating system the hypervisor is able to run.
|
||||
Possible values are:
|
||||
|
||||
``xen``
|
||||
for XEN PV
|
||||
``linux``
|
||||
legacy alias for ``xen``
|
||||
``xenpvh``
|
||||
for XEN PVH
|
||||
``hvm``
|
||||
Unmodified operating system
|
||||
``exe``
|
||||
Container based virtualization
|
||||
``arch``
|
||||
This element brings some information on supported guest architecture.
|
||||
Possible subelements are:
|
||||
|
||||
``wordsize``
|
||||
Size of CPU word in bits, for example 64.
|
||||
``emulator``
|
||||
Emulator (device model) path, for use in
|
||||
`emulator <formatdomain.html#devices>`__ element of domain XML.
|
||||
``loader``
|
||||
Loader path, for use in `loader <formatdomain.html#bios-bootloader>`__
|
||||
element of domain XML.
|
||||
``machine``
|
||||
Machine type, for use in
|
||||
`machine <formatdomain.html#operating-system-booting>`__ attribute of
|
||||
os/type element in domain XML. For example Xen supports ``xenfv`` for HVM,
|
||||
``xenpv`` for PV, or ``xenpvh`` for PVH.
|
||||
``domain``
|
||||
The ``type`` attribute of this element specifies the type of hypervisor
|
||||
required to run the domain. Use in
|
||||
`type <formatdomain.html#element-and-attribute-overview>`__ attribute of
|
||||
the domain root element.
|
||||
``features``
|
||||
This optional element encases possible features that can be used with a guest
|
||||
of described type. Possible subelements are:
|
||||
|
||||
``pae``
|
||||
If present, 32-bit guests can use PAE address space extensions,
|
||||
:since:`since 0.4.1`
|
||||
``nonpae``
|
||||
If present, 32-bit guests can be run without requiring PAE, :since:`since
|
||||
0.4.1`
|
||||
``ia64_be``
|
||||
If present, IA64 guests can be run in big-endian mode, :since:`since
|
||||
0.4.1`
|
||||
``acpi``
|
||||
If this element is present, the ``default`` attribute describes whether
|
||||
the hypervisor exposes ACPI to the guest by default, and the ``toggle``
|
||||
attribute describes whether the user can override this default.
|
||||
:since:`Since 0.4.1`
|
||||
``apic``
|
||||
If this element is present, the ``default`` attribute describes whether
|
||||
the hypervisor exposes APIC to the guest by default, and the ``toggle``
|
||||
attribute describes whether the user can override this default.
|
||||
:since:`Since 0.4.1`
|
||||
``cpuselection``
|
||||
If this element is present, the hypervisor supports the ``<cpu>`` element
|
||||
within a domain definition for fine-grained control over the CPU presented
|
||||
to the guest. :since:`Since 0.7.5`
|
||||
``deviceboot``
|
||||
If this element is present, the ``<boot order='...'/>`` element can be
|
||||
used inside devices, rather than the older boot specification by category.
|
||||
:since:`Since 0.8.8`
|
||||
``disksnapshot``
|
||||
If this element is present, the ``default`` attribute describes whether
|
||||
external disk snapshots are supported. If absent, external snapshots may
|
||||
still be supported, but it requires attempting the API and checking for an
|
||||
error to find out for sure. :since:`Since 1.2.3`
|
||||
|
||||
Examples
|
||||
~~~~~~~~
|
||||
|
||||
For example, in the case of a 64-bit machine with hardware virtualization
|
||||
capabilities enabled in the chip and BIOS you will see:
|
||||
|
||||
::
|
||||
|
||||
<capabilities>
|
||||
<host>
|
||||
<cpu>
|
||||
<arch>x86_64</arch>
|
||||
<features>
|
||||
<vmx/>
|
||||
</features>
|
||||
<model>core2duo</model>
|
||||
<vendor>Intel</vendor>
|
||||
<topology sockets="1" dies="1" cores="2" threads="1"/>
|
||||
<feature name="lahf_lm"/>
|
||||
<feature name='xtpr'/>
|
||||
...
|
||||
</cpu>
|
||||
<power_management>
|
||||
<suspend_mem/>
|
||||
<suspend_disk/>
|
||||
<suspend_hybrid/>
|
||||
</power_management>
|
||||
</host>
|
||||
|
||||
<!-- xen-3.0-x86_64 -->
|
||||
<guest>
|
||||
<os_type>xen</os_type>
|
||||
<arch name="x86_64">
|
||||
<wordsize>64</wordsize>
|
||||
<domain type="xen"></domain>
|
||||
<emulator>/usr/lib64/xen/bin/qemu-dm</emulator>
|
||||
</arch>
|
||||
<features>
|
||||
</features>
|
||||
</guest>
|
||||
|
||||
<!-- hvm-3.0-x86_32 -->
|
||||
<guest>
|
||||
<os_type>hvm</os_type>
|
||||
<arch name="i686">
|
||||
<wordsize>32</wordsize>
|
||||
<domain type="xen"></domain>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<machine>pc</machine>
|
||||
<machine>isapc</machine>
|
||||
<loader>/usr/lib/xen/boot/hvmloader</loader>
|
||||
</arch>
|
||||
<features>
|
||||
<cpuselection/>
|
||||
<deviceboot/>
|
||||
</features>
|
||||
</guest>
|
||||
|
||||
...
|
||||
</capabilities>
|
|
@ -0,0 +1,172 @@
|
|||
.. role:: since
|
||||
|
||||
Checkpoint XML format
|
||||
=====================
|
||||
|
||||
.. contents::
|
||||
|
||||
Checkpoint XML
|
||||
--------------
|
||||
|
||||
One method of capturing domain disk backups is via the use of incremental
|
||||
backups. Right now, incremental backups are only supported for the QEMU
|
||||
hypervisor when using qcow2 disks at the active layer; if other disk formats are
|
||||
in use, capturing disk backups requires different libvirt APIs (see `domain
|
||||
state capture <kbase/domainstatecapture.html>`__ for a comparison between APIs).
|
||||
|
||||
Libvirt is able to facilitate incremental backups by tracking disk checkpoints,
|
||||
which are points in time against which it is easy to compute which portion of
|
||||
the disk has changed. Given a full backup (a backup created from the creation of
|
||||
the disk to a given point in time), coupled with the creation of a disk
|
||||
checkpoint at that time, and an incremental backup (a backup created from just
|
||||
the dirty portion of the disk between the first checkpoint and the second backup
|
||||
operation), it is possible to do an offline reconstruction of the state of the
|
||||
disk at the time of the second backup without having to copy as much data as a
|
||||
second full backup would require. Most disk checkpoints are created in
|
||||
conjunction with a backup via ``virDomainBackupBegin()``, although a future API
|
||||
addition of ``virDomainSnapshotCreateXML2()`` will also make this possible when
|
||||
creating external snapshots; however, libvirt also exposes enough support to
|
||||
create disk checkpoints independently from a backup operation via
|
||||
``virDomainCheckpointCreateXML()`` since 5.6.0. Likewise, the creation of
|
||||
checkpoints when external snapshots exist is currently forbidden, although
|
||||
future work will make it possible to integrate these two concepts.
|
||||
|
||||
Attributes of libvirt checkpoints are stored as child elements of the
|
||||
``domaincheckpoint`` element. At checkpoint creation time, normally only the
|
||||
``name``, ``description``, and ``disks`` elements are settable. The rest of the
|
||||
fields are ignored on creation and will be filled in by libvirt in for
|
||||
informational purposes by ``virDomainCheckpointGetXMLDesc()``. However, when
|
||||
redefining a checkpoint, with the ``VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE`` flag
|
||||
of ``virDomainCheckpointCreateXML()``, all of the XML fields described here are
|
||||
relevant on input, even the fields that are normally described as readonly for
|
||||
output.
|
||||
|
||||
The top-level ``domaincheckpoint`` element may contain the following elements:
|
||||
|
||||
``name``
|
||||
The optional name for this checkpoint. If the name is omitted, libvirt will
|
||||
create a name based on the time of the creation.
|
||||
|
||||
``description``
|
||||
An optional human-readable description of the checkpoint. If the description
|
||||
is omitted when initially creating the checkpoint, then this field will be
|
||||
empty.
|
||||
|
||||
``disks``
|
||||
On input, this is an optional listing of specific instructions for disk
|
||||
checkpoints; it is needed when making a checkpoint on only a subset of the
|
||||
disks associated with a domain. In particular, since QEMU checkpoints require
|
||||
qcow2 disks, this element may be needed on input for excluding guest disks
|
||||
that are not in qcow2 format. If the entire element was omitted on input,
|
||||
then all disks participate in the checkpoint, otherwise, only the disks
|
||||
explicitly listed which do not also use ``checkpoint='no'`` will participate.
|
||||
On output, this is the checkpoint state of each of the domain's disks.
|
||||
|
||||
``disk``
|
||||
This sub-element describes the checkpoint properties of a specific disk
|
||||
with the following attributes:
|
||||
|
||||
``name``
|
||||
A mandatory attribute which must match either the
|
||||
``<target dev='name'/>`` or an unambiguous ``<source file='name'/>`` of
|
||||
one of the `disk devices <formatdomain.html#hard-drives-floppy-disks-cdroms>`__ specified
|
||||
for the domain at the time of the checkpoint.
|
||||
|
||||
``checkpoint``
|
||||
An optional attribute; possible values are ``no`` when the disk does
|
||||
not participate in this checkpoint; or ``bitmap`` if the disk will
|
||||
track all changes since the creation of this checkpoint via a bitmap.
|
||||
|
||||
``bitmap``
|
||||
The attribute ``bitmap`` is only valid if ``checkpoint='bitmap'``; it
|
||||
describes the name of the tracking bitmap (defaulting to the checkpoint
|
||||
name).
|
||||
|
||||
``size``
|
||||
The attribute ``size`` is ignored on input; on output, it is only
|
||||
present if the ``VIR_DOMAIN_CHECKPOINT_XML_SIZE`` flag was used to
|
||||
perform a dynamic query of the estimated size in bytes of the changes
|
||||
made since the checkpoint was created.
|
||||
|
||||
Note that updating the backup ``size`` may be expensive and
|
||||
the actual required size may increase if the guest OS is actively
|
||||
writing to the disk.
|
||||
|
||||
``creationTime``
|
||||
A readonly representation of the time this checkpoint was created. The time
|
||||
is specified in seconds since the Epoch, UTC (i.e. Unix time).
|
||||
|
||||
``parent``
|
||||
Readonly, present if this checkpoint has a parent. The parent name is given
|
||||
by the sub-element ``name``. The parent relationship allows tracking a list
|
||||
of related checkpoints.
|
||||
|
||||
``domain``
|
||||
A readonly representation of the inactive `domain
|
||||
configuration <formatdomain.html>`__ at the time the checkpoint was created.
|
||||
This element may be omitted for output brevity by supplying the
|
||||
``VIR_DOMAIN_CHECKPOINT_XML_NO_DOMAIN`` flag. The domain will have
|
||||
security-sensitive information omitted unless the flag
|
||||
``VIR_DOMAIN_CHECKPOINT_XML_SECURE`` is provided on a read-write connection.
|
||||
|
||||
``virDomainCheckpointCreateXML()`` requires that the ``<domain>`` is present
|
||||
when used with ``VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE``.
|
||||
:since:`Since 7.0.0` the ``<domain>`` element can be omitted when redefining
|
||||
a checkpoint, but hypervisors may not support certain operations if it's
|
||||
missing.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Using this XML to create a checkpoint of just vda on a qemu domain with two
|
||||
disks and a prior checkpoint:
|
||||
|
||||
::
|
||||
|
||||
<domaincheckpoint>
|
||||
<description>Completion of updates after OS install</description>
|
||||
<disks>
|
||||
<disk name='vda' checkpoint='bitmap'/>
|
||||
<disk name='vdb' checkpoint='no'/>
|
||||
</disks>
|
||||
</domaincheckpoint>
|
||||
|
||||
will result in XML similar to this from ``virDomainCheckpointGetXMLDesc()``:
|
||||
|
||||
::
|
||||
|
||||
<domaincheckpoint>
|
||||
<name>1525889631</name>
|
||||
<description>Completion of updates after OS install</description>
|
||||
<parent>
|
||||
<name>1525111885</name>
|
||||
</parent>
|
||||
<creationTime>1525889631</creationTime>
|
||||
<disks>
|
||||
<disk name='vda' checkpoint='bitmap' bitmap='1525889631'/>
|
||||
<disk name='vdb' checkpoint='no'/>
|
||||
</disks>
|
||||
<domain type='qemu'>
|
||||
<name>fedora</name>
|
||||
<uuid>93a5c045-6457-2c09-e56c-927cdf34e178</uuid>
|
||||
<memory>1048576</memory>
|
||||
...
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2'/>
|
||||
<source file='/path/to/file1'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk' snapshot='external'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/path/to/file2'/>
|
||||
<target dev='vdb' bus='virtio'/>
|
||||
</disk>
|
||||
...
|
||||
</devices>
|
||||
</domain>
|
||||
</domaincheckpoint>
|
||||
|
||||
With that checkpoint created, the qcow2 image is now tracking all changes that
|
||||
occur in the image since the checkpoint via the persistent bitmap named
|
||||
``1525889631``.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,600 @@
|
|||
.. role:: since
|
||||
|
||||
==============================
|
||||
Domain capabilities XML format
|
||||
==============================
|
||||
|
||||
.. contents::
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Sometimes, when a new domain is to be created it may come handy to know the
|
||||
capabilities of the hypervisor so the correct combination of devices and drivers
|
||||
is used. For example, when management application is considering the mode for a
|
||||
host device's passthrough there are several options depending not only on host,
|
||||
but on hypervisor in question too. If the hypervisor is qemu then it needs to be
|
||||
more recent to support VFIO, while legacy KVM is achievable just fine with older
|
||||
qemus.
|
||||
|
||||
The main difference between
|
||||
`virConnectGetCapabilities <html/libvirt-libvirt-host.html#virConnectGetCapabilities>`__
|
||||
and the emulator capabilities API is, the former one aims more on the host
|
||||
capabilities (e.g. NUMA topology, security models in effect, etc.) while the
|
||||
latter one specializes on the hypervisor capabilities.
|
||||
|
||||
While the `Driver Capabilities <formatcaps.html>`__ provides the host
|
||||
capabilities (e.g NUMA topology, security models in effect, etc.), the Domain
|
||||
Capabilities provides the hypervisor specific capabilities for Management
|
||||
Applications to query and make decisions regarding what to utilize.
|
||||
|
||||
The Domain Capabilities can provide information such as the correct combination
|
||||
of devices and drivers that are supported. Knowing which host and hypervisor
|
||||
specific options are available or supported would allow the management
|
||||
application to choose an appropriate mode for a pass-through host device as well
|
||||
as which adapter to utilize.
|
||||
|
||||
Some XML elements may be entirely omitted from the domaincapabilities XML,
|
||||
depending on what the libvirt driver has filled in. Applications should only act
|
||||
on what is explicitly reported in the domaincapabilities XML. For example, if
|
||||
<disk supported='yes'/> is present, you can safely assume the driver supports
|
||||
<disk> devices. If <disk supported='no'/> is present, you can safely assume the
|
||||
driver does NOT support <disk> devices. If the <disk> block is omitted entirely,
|
||||
the driver is not indicating one way or the other whether it supports <disk>
|
||||
devices, and applications should not interpret the missing block to mean any
|
||||
thing in particular.
|
||||
|
||||
Element and attribute overview
|
||||
------------------------------
|
||||
|
||||
A new query interface was added to the virConnect API's to retrieve the XML
|
||||
listing of the set of domain capabilities ( :since:`Since 1.2.7` ):
|
||||
|
||||
``virConnectGetDomainCapabilities`` (`API docs <html/libvirt-libvirt-domain.html#virConnectGetDomainCapabilities>`__)
|
||||
|
||||
The root element that emulator capability XML document starts with has name
|
||||
``domainCapabilities``. It contains at least four direct child elements:
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
<path>/usr/bin/qemu-system-x86_64</path>
|
||||
<domain>kvm</domain>
|
||||
<machine>pc-i440fx-2.1</machine>
|
||||
<arch>x86_64</arch>
|
||||
...
|
||||
</domainCapabilities>
|
||||
|
||||
``path``
|
||||
The full path to the emulator binary.
|
||||
``domain``
|
||||
Describes the `virtualization type <formatdomain.html#element-and-attribute-overview>`__ (or so
|
||||
called domain type).
|
||||
``machine``
|
||||
The domain's `machine type <formatdomain.html#bios-bootloader>`__. Since not
|
||||
every hypervisor has a sense of machine types this element might be omitted
|
||||
in such drivers.
|
||||
``arch``
|
||||
The domain's `architecture <formatdomain.html#bios-bootloader>`__.
|
||||
|
||||
CPU Allocation
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Before any devices capability occurs, there might be info on domain wide
|
||||
capabilities, e.g. virtual CPUs:
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<vcpu max='255'/>
|
||||
...
|
||||
</domainCapabilities>
|
||||
|
||||
``vcpu``
|
||||
The maximum number of supported virtual CPUs
|
||||
|
||||
BIOS bootloader
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes users might want to tweak some BIOS knobs or use UEFI. For cases like
|
||||
that, `os <formatdomain.html#bios-bootloader>`__ element exposes what values can
|
||||
be passed to its children.
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<os supported='yes'>
|
||||
<enum name='firmware'>
|
||||
<value>bios</value>
|
||||
<value>efi</value>
|
||||
</enum>
|
||||
<loader supported='yes'>
|
||||
<value>/usr/share/OVMF/OVMF_CODE.fd</value>
|
||||
<enum name='type'>
|
||||
<value>rom</value>
|
||||
<value>pflash</value>
|
||||
</enum>
|
||||
<enum name='readonly'>
|
||||
<value>yes</value>
|
||||
<value>no</value>
|
||||
</enum>
|
||||
<enum name='secure'>
|
||||
<value>yes</value>
|
||||
<value>no</value>
|
||||
</enum>
|
||||
</loader>
|
||||
</os>
|
||||
...
|
||||
<domainCapabilities>
|
||||
|
||||
The ``firmware`` enum corresponds to the ``firmware`` attribute of the ``os``
|
||||
element in the domain XML. The presence of this enum means libvirt is capable of
|
||||
the so-called firmware auto-selection feature. And the listed firmware values
|
||||
represent the accepted input in the domain XML. Note that the ``firmware`` enum
|
||||
reports only those values for which a firmware "descriptor file" exists on the
|
||||
host. Firmware descriptor file is a small JSON document that describes details
|
||||
about a given BIOS or UEFI binary on the host, e.g. the firmware binary path,
|
||||
its architecture, supported machine types, NVRAM template, etc. This ensures
|
||||
that the reported values won't cause a failure on guest boot.
|
||||
|
||||
For the ``loader`` element, the following can occur:
|
||||
|
||||
``value``
|
||||
List of known firmware binary paths. Currently this is used only to advertise
|
||||
the known location of OVMF binaries for QEMU. OVMF binaries will only be
|
||||
listed if they actually exist on host.
|
||||
``type``
|
||||
Whether the boot loader is a typical BIOS (``rom``) or a UEFI firmware
|
||||
(``pflash``). Each ``value`` sub-element under the ``type`` enum represents a
|
||||
possible value for the ``type`` attribute for the <loader/> element in the
|
||||
domain XML. E.g. the presence of ``pfalsh`` under the ``type`` enum means
|
||||
that a domain XML can use UEFI firmware via: <loader/> type="pflash"
|
||||
...>/path/to/the/firmware/binary/</loader>.
|
||||
``readonly``
|
||||
Options for the ``readonly`` attribute of the <loader/> element in the domain
|
||||
XML.
|
||||
``secure``
|
||||
Options for the ``secure`` attribute of the <loader/> element in the domain
|
||||
XML. Note that the value ``yes`` is listed only if libvirt detects a firmware
|
||||
descriptor file that has path to an OVMF binary that supports Secure boot,
|
||||
and lists its architecture and supported machine type.
|
||||
|
||||
CPU configuration
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``cpu`` element exposes options usable for configuring `guest
|
||||
CPUs <formatdomain.html#cpu-model-and-topology>`__.
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<cpu>
|
||||
<mode name='host-passthrough' supported='yes'>
|
||||
<enum name='hostPassthroughMigratable'>
|
||||
<value>on</value>
|
||||
<value>off</value>
|
||||
</enum>
|
||||
</mode>
|
||||
<mode name='maximum' supported='yes'>
|
||||
<enum name='maximumMigratable'>
|
||||
<value>on</value>
|
||||
<value>off</value>
|
||||
</enum>
|
||||
</mode>
|
||||
<mode name='host-model' supported='yes'>
|
||||
<model fallback='allow'>Broadwell</model>
|
||||
<vendor>Intel</vendor>
|
||||
<feature policy='disable' name='aes'/>
|
||||
<feature policy='require' name='vmx'/>
|
||||
</mode>
|
||||
<mode name='custom' supported='yes'>
|
||||
<model usable='no' deprecated='no'>Broadwell</model>
|
||||
<model usable='yes' deprecated='no'>Broadwell-noTSX</model>
|
||||
<model usable='no' deprecated='yes'>Haswell</model>
|
||||
...
|
||||
</mode>
|
||||
</cpu>
|
||||
...
|
||||
<domainCapabilities>
|
||||
|
||||
Each CPU mode understood by libvirt is described with a ``mode`` element which
|
||||
tells whether the particular mode is supported and provides (when applicable)
|
||||
more details about it:
|
||||
|
||||
``host-passthrough``
|
||||
The ``hostPassthroughMigratable`` enum shows possible values of the
|
||||
``migratable`` attribute for the <cpu> element with
|
||||
``mode='host-passthrough'`` in the domain XML.
|
||||
``host-model``
|
||||
If ``host-model`` is supported by the hypervisor, the ``mode`` describes the
|
||||
guest CPU which will be used when starting a domain with ``host-model`` CPU.
|
||||
The hypervisor specifics (such as unsupported CPU models or features, machine
|
||||
type, etc.) may be accounted for in this guest CPU specification and thus the
|
||||
CPU can be different from the one shown in host capabilities XML. This is
|
||||
indicated by the ``fallback`` attribute of the ``model`` sub element:
|
||||
``allow`` means not all specifics were accounted for and thus the CPU a guest
|
||||
will see may be different; ``forbid`` indicates that the CPU a guest will see
|
||||
should match this CPU definition.
|
||||
``custom``
|
||||
The ``mode`` element contains a list of supported CPU models, each described
|
||||
by a dedicated ``model`` element. The ``usable`` attribute specifies whether
|
||||
the model can be used directly on the host. When usable='no' the
|
||||
corresponding model cannot be used without disabling some features that the
|
||||
CPU of such model is expected to have. A special value ``unknown`` indicates
|
||||
libvirt does not have enough information to provide the usability data. The
|
||||
``deprecated`` attribute reflects the hypervisor's policy on usage of this
|
||||
model :since:`(since 7.1.0)` .
|
||||
|
||||
I/O Threads
|
||||
~~~~~~~~~~~
|
||||
|
||||
The ``iothread`` elements indicates whether or not `I/O
|
||||
threads <formatdomain.html#iothreads-allocation>`__ are supported.
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<iothread supported='yes'/>
|
||||
...
|
||||
<domainCapabilities>
|
||||
|
||||
Memory Backing
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The ``memory backing`` element indicates whether or not `memory
|
||||
backing <formatdomain.html#memory-backing>`__ is supported.
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<memoryBacking supported='yes'>
|
||||
<enum name='sourceType'>
|
||||
<value>anonymous</value>
|
||||
<value>file</value>
|
||||
<value>memfd</value>
|
||||
</enum>
|
||||
</memoryBacking>
|
||||
...
|
||||
<domainCapabilities>
|
||||
|
||||
``sourceType``
|
||||
Options for the ``type`` attribute of the <memoryBacking><source> element.
|
||||
|
||||
Devices
|
||||
~~~~~~~
|
||||
|
||||
Another set of XML elements describe the supported devices and their
|
||||
capabilities. All devices occur as children of the main ``devices`` element.
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<devices>
|
||||
<disk supported='yes'>
|
||||
<enum name='diskDevice'>
|
||||
<value>disk</value>
|
||||
<value>cdrom</value>
|
||||
<value>floppy</value>
|
||||
<value>lun</value>
|
||||
</enum>
|
||||
...
|
||||
</disk>
|
||||
<hostdev supported='no'/>
|
||||
</devices>
|
||||
</domainCapabilities>
|
||||
|
||||
Reported capabilities are expressed as an enumerated list of available options
|
||||
for each of the element or attribute. For example, the <disk/> element has an
|
||||
attribute ``device`` which can support the values ``disk``, ``cdrom``,
|
||||
``floppy``, or ``lun``.
|
||||
|
||||
Hard drives, floppy disks, CDROMs
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Disk capabilities are exposed under the ``disk`` element. For instance:
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<devices>
|
||||
<disk supported='yes'>
|
||||
<enum name='diskDevice'>
|
||||
<value>disk</value>
|
||||
<value>cdrom</value>
|
||||
<value>floppy</value>
|
||||
<value>lun</value>
|
||||
</enum>
|
||||
<enum name='bus'>
|
||||
<value>ide</value>
|
||||
<value>fdc</value>
|
||||
<value>scsi</value>
|
||||
<value>virtio</value>
|
||||
<value>xen</value>
|
||||
<value>usb</value>
|
||||
<value>sata</value>
|
||||
<value>sd</value>
|
||||
</enum>
|
||||
</disk>
|
||||
...
|
||||
</devices>
|
||||
</domainCapabilities>
|
||||
|
||||
``diskDevice``
|
||||
Options for the ``device`` attribute of the <disk/> element.
|
||||
``bus``
|
||||
Options for the ``bus`` attribute of the <target/> element for a <disk/>.
|
||||
|
||||
Graphical framebuffers
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Graphics device capabilities are exposed under the ``graphics`` element. For
|
||||
instance:
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<devices>
|
||||
<graphics supported='yes'>
|
||||
<enum name='type'>
|
||||
<value>sdl</value>
|
||||
<value>vnc</value>
|
||||
<value>spice</value>
|
||||
</enum>
|
||||
</graphics>
|
||||
...
|
||||
</devices>
|
||||
</domainCapabilities>
|
||||
|
||||
``type``
|
||||
Options for the ``type`` attribute of the <graphics/> element.
|
||||
|
||||
Video device
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Video device capabilities are exposed under the ``video`` element. For instance:
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<devices>
|
||||
<video supported='yes'>
|
||||
<enum name='modelType'>
|
||||
<value>vga</value>
|
||||
<value>cirrus</value>
|
||||
<value>vmvga</value>
|
||||
<value>qxl</value>
|
||||
<value>virtio</value>
|
||||
</enum>
|
||||
</video>
|
||||
...
|
||||
</devices>
|
||||
</domainCapabilities>
|
||||
|
||||
``modelType``
|
||||
Options for the ``type`` attribute of the <video><model> element.
|
||||
|
||||
Host device assignment
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Some host devices can be passed through to a guest (e.g. USB, PCI and SCSI).
|
||||
Well, only if the following is enabled:
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<devices>
|
||||
<hostdev supported='yes'>
|
||||
<enum name='mode'>
|
||||
<value>subsystem</value>
|
||||
<value>capabilities</value>
|
||||
</enum>
|
||||
<enum name='startupPolicy'>
|
||||
<value>default</value>
|
||||
<value>mandatory</value>
|
||||
<value>requisite</value>
|
||||
<value>optional</value>
|
||||
</enum>
|
||||
<enum name='subsysType'>
|
||||
<value>usb</value>
|
||||
<value>pci</value>
|
||||
<value>scsi</value>
|
||||
</enum>
|
||||
<enum name='capsType'>
|
||||
<value>storage</value>
|
||||
<value>misc</value>
|
||||
<value>net</value>
|
||||
</enum>
|
||||
<enum name='pciBackend'>
|
||||
<value>default</value>
|
||||
<value>kvm</value>
|
||||
<value>vfio</value>
|
||||
<value>xen</value>
|
||||
</enum>
|
||||
</hostdev>
|
||||
</devices>
|
||||
</domainCapabilities>
|
||||
|
||||
``mode``
|
||||
Options for the ``mode`` attribute of the <hostdev/> element.
|
||||
``startupPolicy``
|
||||
Options for the ``startupPolicy`` attribute of the <hostdev/> element.
|
||||
``subsysType``
|
||||
Options for the ``type`` attribute of the <hostdev/> element in case of
|
||||
``mode="subsystem"``.
|
||||
``capsType``
|
||||
Options for the ``type`` attribute of the <hostdev/> element in case of
|
||||
``mode="capabilities"``.
|
||||
``pciBackend``
|
||||
Options for the ``name`` attribute of the <driver/> element.
|
||||
|
||||
RNG device
|
||||
^^^^^^^^^^
|
||||
|
||||
RNG device capabilities are exposed under the ``rng`` element. For instance:
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<devices>
|
||||
<rng supported='yes'>
|
||||
<enum name='model'>
|
||||
<value>virtio</value>
|
||||
<value>virtio-transitional</value>
|
||||
<value>virtio-non-transitional</value>
|
||||
</enum>
|
||||
<enum name='backendModel'>
|
||||
<value>random</value>
|
||||
<value>egd</value>
|
||||
<value>builtin</value>
|
||||
</enum>
|
||||
</rng>
|
||||
...
|
||||
</devices>
|
||||
</domainCapabilities>
|
||||
|
||||
``model``
|
||||
Options for the ``model`` attribute of the <rng> element.
|
||||
``backendModel``
|
||||
Options for the ``model`` attribute of the <rng><backend> element.
|
||||
|
||||
Filesystem device
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Filesystem device capabilities are exposed under the ``filesystem`` element. For
|
||||
instance:
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<devices>
|
||||
<filesystem supported='yes'>
|
||||
<enum name='driverType'>
|
||||
<value>default</value>
|
||||
<value>path</value>
|
||||
<value>handle</value>
|
||||
<value>virtiofs</value>
|
||||
</enum>
|
||||
</filesystem>
|
||||
...
|
||||
</devices>
|
||||
</domainCapabilities>
|
||||
|
||||
``driverType``
|
||||
Options for the ``type`` attribute of the <filesystem><driver> element.
|
||||
|
||||
Features
|
||||
~~~~~~~~
|
||||
|
||||
One more set of XML elements describe the supported features and their
|
||||
capabilities. All features occur as children of the main ``features`` element.
|
||||
|
||||
::
|
||||
|
||||
<domainCapabilities>
|
||||
...
|
||||
<features>
|
||||
<gic supported='yes'>
|
||||
<enum name='version'>
|
||||
<value>2</value>
|
||||
<value>3</value>
|
||||
</enum>
|
||||
</gic>
|
||||
<vmcoreinfo supported='yes'/>
|
||||
<genid supported='yes'/>
|
||||
<backingStoreInput supported='yes'/>
|
||||
<backup supported='yes'/>
|
||||
<sev>
|
||||
<cbitpos>47</cbitpos>
|
||||
<reduced-phys-bits>1</reduced-phys-bits>
|
||||
</sev>
|
||||
</features>
|
||||
</domainCapabilities>
|
||||
|
||||
Reported capabilities are expressed as an enumerated list of possible values for
|
||||
each of the elements or attributes. For example, the ``gic`` element has an
|
||||
attribute ``version`` which can support the values ``2`` or ``3``.
|
||||
|
||||
For information about the purpose of each feature, see the `relevant
|
||||
section <formatdomain.html#hypervisor-features>`__ in the domain XML documentation.
|
||||
|
||||
GIC capabilities
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
GIC capabilities are exposed under the ``gic`` element.
|
||||
|
||||
``version``
|
||||
Options for the ``version`` attribute of the ``gic`` element.
|
||||
|
||||
vmcoreinfo
|
||||
^^^^^^^^^^
|
||||
|
||||
Reports whether the vmcoreinfo feature can be enabled.
|
||||
|
||||
genid
|
||||
^^^^^
|
||||
|
||||
Reports whether the genid feature can be used by the domain.
|
||||
|
||||
backingStoreInput
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Reports whether the hypervisor will obey the <backingStore> elements configured
|
||||
for a <disk> when booting the guest, hotplugging the disk to a running guest, or
|
||||
similar. :since:`(Since 5.10)`
|
||||
|
||||
backup
|
||||
^^^^^^
|
||||
|
||||
Reports whether the hypervisor supports the backup, checkpoint, and related
|
||||
features. (``virDomainBackupBegin``, ``virDomainCheckpointCreateXML`` etc). The
|
||||
presence of the ``backup`` element even if ``supported='no'`` implies that the
|
||||
``VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA`` flag for ``virDomainUndefine`` is
|
||||
supported.
|
||||
|
||||
s390-pv capability
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Reports whether the hypervisor supports the Protected Virtualization. In order
|
||||
to use Protected Virtualization with libvirt have a look at the `launchSecurity
|
||||
element in the domain XML <formatdomain.html#launch-security>`__. For more
|
||||
details on the Protected Virtualization feature please see `Protected
|
||||
Virtualization on s390 <kbase/s390_protected_virt.html>`__.
|
||||
|
||||
SEV capabilities
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
AMD Secure Encrypted Virtualization (SEV) capabilities are exposed under the
|
||||
``sev`` element. SEV is an extension to the AMD-V architecture which supports
|
||||
running virtual machines (VMs) under the control of a hypervisor. When
|
||||
supported, guest owner can create a VM whose memory contents will be
|
||||
transparently encrypted with a key unique to that VM.
|
||||
|
||||
For more details on the SEV feature, please follow resources in the AMD
|
||||
developer's document store. In order to use SEV with libvirt have a look at `SEV
|
||||
in domain XML <formatdomain.html#launch-security>`__
|
||||
|
||||
``cbitpos``
|
||||
When memory encryption is enabled, one of the physical address bits (aka the
|
||||
C-bit) is utilized to mark if a memory page is protected. The C-bit position
|
||||
is Hypervisor dependent.
|
||||
``reducedPhysBits``
|
||||
When memory encryption is enabled, we lose certain bits in physical address
|
||||
space. The number of bits we lose is hypervisor dependent.
|
||||
``maxGuests``
|
||||
The maximum number of SEV guests that can be launched on the host. This value
|
||||
may be configurable in the firmware for some hosts.
|
||||
``maxESGuests``
|
||||
The maximum number of SEV-ES guests that can be launched on the host. This
|
||||
value may be configurable in the firmware for some hosts.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,175 @@
|
|||
.. role:: since
|
||||
|
||||
=======================
|
||||
Network port XML format
|
||||
=======================
|
||||
|
||||
.. contents::
|
||||
|
||||
This page provides an introduction to the network port XML format. This stores
|
||||
information about the connection between a virtual interface of a virtual
|
||||
domain, and the virtual network it is attached to.
|
||||
|
||||
Element and attribute overview
|
||||
------------------------------
|
||||
|
||||
The root element required for all virtual network ports is named ``networkport``
|
||||
and has no configurable attributes The network port XML format is available
|
||||
:since:`since 5.5.0`
|
||||
|
||||
General metadata
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The first elements provide basic metadata about the virtual network port.
|
||||
|
||||
::
|
||||
|
||||
<networkport>
|
||||
<uuid>7ae63b5f-fe96-4af0-a7c3-da04ba1b3f54</uuid>
|
||||
<owner>
|
||||
<uuid>06578fc1-c686-46fa-bc2c-220893b466a6</uuid>
|
||||
<name>myguest</name>
|
||||
</owner>
|
||||
<group>webfront</group>
|
||||
<mac address='52:54:0:7b:35:93'/>
|
||||
...
|
||||
|
||||
``uuid``
|
||||
The content of the ``uuid`` element provides a globally unique identifier for
|
||||
the virtual network port. The format must be RFC 4122 compliant, eg
|
||||
``3e3fce45-4f53-4fa7-bb32-11f34168b82b``. If omitted when defining/creating a
|
||||
new network port, a random UUID is generated.
|
||||
The ``owner`` node records the domain object that is the owner of the network
|
||||
port. It contains two child nodes:
|
||||
|
||||
``uuid``
|
||||
The content of the ``uuid`` element provides a globally unique identifier
|
||||
for the virtual domain.
|
||||
``name``
|
||||
The unique name of the virtual domain
|
||||
``group``
|
||||
The port group in the virtual network to which the port belongs. Can be
|
||||
omitted if no port groups are defined on the network.
|
||||
``mac``
|
||||
The ``address`` attribute provides the MAC address of the virtual port that
|
||||
will be see by the guest. The MAC address must not start with 0xFE as this
|
||||
byte is reserved for use on the host side of the port.
|
||||
|
||||
Common elements
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The following elements are common to one or more of the plug types listed later
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<bandwidth>
|
||||
<inbound average='1000' peak='5000' floor='200' burst='1024'/>
|
||||
<outbound average='128' peak='256' burst='256'/>
|
||||
</bandwidth>
|
||||
<rxfilters trustGuest='yes'/>
|
||||
<port isolated='yes'/>
|
||||
<virtualport type='802.1Qbg'>
|
||||
<parameters managerid='11' typeid='1193047' typeidversion='2'/>
|
||||
</virtualport>
|
||||
...
|
||||
|
||||
``bandwidth``
|
||||
This part of the network port XML provides setting quality of service.
|
||||
Incoming and outgoing traffic can be shaped independently. The ``bandwidth``
|
||||
element and its child elements are described in the
|
||||
`QoS <formatnetwork.html#quality-of-service>`__ section of the Network XML. In
|
||||
addition the ``classID`` attribute may exist to provide the ID of the traffic
|
||||
shaping class that is active.
|
||||
``rxfilters``
|
||||
The ``rxfilters`` element property ``trustGuest`` provides the capability for
|
||||
the host to detect and trust reports from the guest regarding changes to the
|
||||
interface mac address and receive filters by setting the attribute to
|
||||
``yes``. The default setting for the attribute is ``no`` for security reasons
|
||||
and support depends on the guest network device model as well as the type of
|
||||
connection on the host - currently it is only supported for the virtio device
|
||||
model and for macvtap connections on the host.
|
||||
``port``
|
||||
:since:`Since 6.1.0.` The ``port`` element property ``isolated``, when set to
|
||||
``yes`` (default setting is ``no``) is used to isolate this port's network
|
||||
traffic from other ports on the same network that also have
|
||||
``<port isolated='yes'/>``. This setting is only supported for emulated
|
||||
network devices connected to a Linux host bridge via a standard tap device.
|
||||
``virtualport``
|
||||
The ``virtualport`` element describes metadata that needs to be provided to
|
||||
the underlying network subsystem. It is described in the domain XML
|
||||
`interface documentation <formatdomain.html#network-interfaces>`__.
|
||||
|
||||
Plugs
|
||||
~~~~~
|
||||
|
||||
The ``plug`` element has varying content depending on the value of the ``type``
|
||||
attribute.
|
||||
|
||||
Network
|
||||
^^^^^^^
|
||||
|
||||
The ``network`` plug type refers to a managed virtual network plug that is based
|
||||
on a traditional software bridge device privately managed by libvirt.
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<plug type='network' bridge='virbr0'/>
|
||||
...
|
||||
|
||||
The ``bridge`` attribute provides the name of the privately managed bridge
|
||||
device associated with the virtual network.
|
||||
|
||||
Bridge
|
||||
^^^^^^
|
||||
|
||||
The ``bridge`` plug type refers to an externally managed traditional software
|
||||
bridge.
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<plug type='bridge' bridge='br2'/>
|
||||
...
|
||||
|
||||
The ``bridge`` attribute provides the name of the externally managed bridge
|
||||
device associated with the virtual network.
|
||||
|
||||
Direct
|
||||
^^^^^^
|
||||
|
||||
The ``direct`` plug type refers to a connection directly to a physical network
|
||||
interface.
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<plug type='direct' dev='ens3' mode='vepa'/>
|
||||
...
|
||||
|
||||
The ``dev`` attribute provides the name of the physical network interface to
|
||||
which the port will be connected. The ``mode`` attribute describes how the
|
||||
connection will be setup and takes the same values described in the `domain
|
||||
XML <formatdomain.html#direct-attachment-to-physical-interface>`__.
|
||||
|
||||
Host PCI
|
||||
^^^^^^^^
|
||||
|
||||
The ``hostdev-pci`` plug type refers to the passthrough of a physical PCI device
|
||||
rather than emulation.
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<plug type='hostdev-pci' managed='yes'>
|
||||
<driver name='vfio'/>
|
||||
<address domain='0x0001' bus='0x02' slot='0x03' function='0x4'/>
|
||||
</plug>
|
||||
...
|
||||
|
||||
The ``managed`` attribute indicates who is responsible for managing the PCI
|
||||
device in the host. When set to the value ``yes`` libvirt is responsible for
|
||||
automatically detaching the device from host drivers and resetting it if needed.
|
||||
If the value is ``no``, some other party must ensure the device is not attached
|
||||
to any host drivers.
|
|
@ -0,0 +1,556 @@
|
|||
.. role:: since
|
||||
|
||||
=======================
|
||||
Node devices XML format
|
||||
=======================
|
||||
|
||||
.. contents::
|
||||
|
||||
Node Device XML
|
||||
---------------
|
||||
|
||||
There are several libvirt functions, all with the prefix ``virNodeDevice``,
|
||||
which deal with management of host devices that can be handed to guests via
|
||||
passthrough as <hostdev> elements in `the domain
|
||||
XML <formatdomain.html#host-device-assignment>`__. These devices are represented as a
|
||||
hierarchy, where a device on a bus has a parent of the bus controller device;
|
||||
the root of the hierarchy is the node named "computer".
|
||||
|
||||
When represented in XML, a node device uses the top-level ``device`` element,
|
||||
with the following elements present according to the type of device:
|
||||
|
||||
``name``
|
||||
The name for this device. The name will be alphanumeric, with words separated
|
||||
by underscore. For many devices, the name is just the bus type and address,
|
||||
as in "pci_0000_00_02_1" or "usb_1_5_3", but some devices are able to provide
|
||||
more specific names, such as "net_eth1_00_27_13_6a_fe_00". This is a
|
||||
read-only field that is reported by the device driver. If this element is set
|
||||
when defining a new device, it will be ignored.
|
||||
``path``
|
||||
Fully qualified sysfs path to the device. This is a read-only field that is
|
||||
reported by the device driver. If this element is set when defining a new
|
||||
device, it will be ignored.
|
||||
``parent``
|
||||
This element identifies the parent node in the device hierarchy. The value of
|
||||
the element will correspond with the device parent's ``name`` element or
|
||||
``computer`` if the device does not have any parent.
|
||||
``driver``
|
||||
This elements reports the driver in use for this device. The presence of this
|
||||
element in the output XML depends on whether the underlying device manager
|
||||
(most likely udev) exposes information about the driver.
|
||||
``devnode``
|
||||
This node appears for each associated ``/dev`` special file. A mandatory
|
||||
attribute ``type`` specify the kind of file path, which may be either ``dev``
|
||||
for the main name, or ``link`` for additional symlinks.
|
||||
``capability``
|
||||
This node appears for each capability that libvirt associates with a node. A
|
||||
mandatory attribute ``type`` lists which category the device belongs to.
|
||||
The `capability types`_ section below describes them further.
|
||||
|
||||
``capability`` types
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Based on the capbility type there are further more specific attributes to a
|
||||
device described below.
|
||||
|
||||
``system``
|
||||
^^^^^^^^^^
|
||||
|
||||
Describes the overall host. Sub-elements include:
|
||||
|
||||
``product``
|
||||
If present, a simple text string giving the product name of the system.
|
||||
``hardware``
|
||||
Describes the hardware of the system, including sub-elements for
|
||||
``vendor``, ``version``, ``serial``, and ``uuid``.
|
||||
``firmware``
|
||||
Describes the firmware of the system, including sub-elements for
|
||||
``vendor``, ``version``, and ``release_date``.
|
||||
|
||||
``pci``
|
||||
^^^^^^^
|
||||
|
||||
Describes a device on the host's PCI bus. Sub-elements include:
|
||||
|
||||
``class``
|
||||
Optional element for combined class, subclass and programming interface
|
||||
codes as 6-digit hexadecimal number. :since:`Since 5.2.0`
|
||||
``domain``
|
||||
Which domain the device belongs to.
|
||||
``bus``
|
||||
Which bus within the domain.
|
||||
``slot``
|
||||
Which slot within the bus.
|
||||
``function``
|
||||
Which function within the slot.
|
||||
``product``
|
||||
Product details from the device ROM, including an attribute ``id`` with
|
||||
the hexadecimal product id, and an optional text description of that
|
||||
id.
|
||||
``vendor``
|
||||
Vendor details from the device ROM, including an attribute ``id`` with
|
||||
the hexadecimal vendor id, and an optional text name of that vendor.
|
||||
``iommuGroup``
|
||||
This optional element describes the "IOMMU group" this device belongs
|
||||
to. If the element exists, it has a mandatory ``number`` attribute
|
||||
which tells the group number used for management of the group (all
|
||||
devices in group "n" will be found in "/sys/kernel/iommu_groups/n"). It
|
||||
will also have a list of ``address`` subelements, each containing the
|
||||
PCI address of a device in the same group. The toplevel device will
|
||||
itself be included in this list.
|
||||
``capability``
|
||||
This optional element can occur multiple times. If it exists, it has a
|
||||
mandatory ``type`` attribute which will be set to:
|
||||
|
||||
``phys_function``
|
||||
That means there will be a single ``address`` subelement which
|
||||
contains the PCI address of the SRIOV Physical Function (PF) that is
|
||||
the parent of this device (and this device is, by implication, an
|
||||
SRIOV Virtual Function (VF)).
|
||||
``virt_functions``
|
||||
In this case this device is an SRIOV PF, and the capability element
|
||||
will have a list of ``address`` subelements, one for each VF on this
|
||||
PF. If the host system supports reporting it (via the
|
||||
"sriov_totalvfs" file in the device's sysfs directory) the
|
||||
capability element will also have an attribute named ``maxCount``
|
||||
which is the maximum number of SRIOV VFs supported by this device,
|
||||
which could be higher than the number of VFs that are currently
|
||||
active :since:`since 1.3.0` ; in this case, even if there are
|
||||
currently no active VFs the virtual_functions capabililty will still
|
||||
be shown.
|
||||
``pci-bridge`` or ``cardbus-bridge``
|
||||
This shows merely that the lower 7 bits of PCI header type have
|
||||
either value of 1 or 2 respectively. Usually this means such device
|
||||
cannot be used for PCI passthrough. :since:`Since 1.3.3`
|
||||
``mdev_types``
|
||||
This device is capable of creating mediated devices. The
|
||||
sub-elements are summarized in `mdev_types capability`_.
|
||||
``vpd``
|
||||
This device exposes a VPD PCI/PCIe capability. The sub-elements are
|
||||
summarized in `vpd capability`_.
|
||||
``numa``
|
||||
This optional element contains information on the PCI device with
|
||||
respect to NUMA. For example, the optional ``node`` attribute tells
|
||||
which NUMA node is the PCI device associated with.
|
||||
``pci-express``
|
||||
This optional element contains information on PCI Express part of the
|
||||
device. For example, it can contain a child element ``link`` which
|
||||
addresses the PCI Express device's link. While a device has its own
|
||||
capabilities (``validity='cap'``), the actual run time capabilities are
|
||||
negotiated on the device initialization (``validity='sta'``). The
|
||||
``link`` element then contains three attributes: ``port`` which says in
|
||||
which port is the device plugged in, ``speed`` (in GigaTransfers per
|
||||
second) and ``width`` for the number of lanes used. Since the port
|
||||
can't be negotiated, it's not exposed in
|
||||
``./pci-express/link/[`validity='sta']``.
|
||||
|
||||
``usb_device``
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Describes a device on the host's USB bus, based on its location within the bus.
|
||||
Sub-elements include:
|
||||
|
||||
``bus``
|
||||
Which bus the device belongs to.
|
||||
``device``
|
||||
Which device within the bus.
|
||||
``product``
|
||||
Product details from the device ROM, including an attribute ``id`` with
|
||||
the hexadecimal product id, and an optional text description of that
|
||||
id.
|
||||
``vendor``
|
||||
Vendor details from the device ROM, including an attribute ``id`` with
|
||||
the hexadecimal vendor id, and an optional text name of that vendor.
|
||||
|
||||
``usb``
|
||||
^^^^^^^
|
||||
|
||||
Describes a USB device, based on its advertised driver interface. Sub-elements
|
||||
include:
|
||||
|
||||
``number``
|
||||
The device number.
|
||||
``class``
|
||||
The device class.
|
||||
``subclass``
|
||||
The device subclass.
|
||||
``protocol``
|
||||
The device protocol.
|
||||
``description``
|
||||
If present, a description of the device.
|
||||
|
||||
``net``
|
||||
^^^^^^^
|
||||
|
||||
Describes a device capable for use as a network interface. Sub-elements
|
||||
include:
|
||||
|
||||
``interface``
|
||||
The interface name tied to this device.
|
||||
``address``
|
||||
If present, the MAC address of the device.
|
||||
``link``
|
||||
Optional to reflect the status of the link. It has two optional
|
||||
attributes: ``speed`` in Mbits per second and ``state`` to tell the
|
||||
state of the link. So far, the whole element is just for output, not
|
||||
setting.
|
||||
``feature``
|
||||
If present, the hw offloads supported by this network interface.
|
||||
Possible features are:
|
||||
|
||||
``rx``
|
||||
rx-checksumming
|
||||
``tx``
|
||||
tx-checksumming
|
||||
``sg``
|
||||
scatter-gather
|
||||
``tso``
|
||||
tcp-segmentation-offload
|
||||
``ufo``
|
||||
udp-fragmentation-offload
|
||||
``gso``
|
||||
generic-segmentation-offload
|
||||
``gro``
|
||||
generic-receive-offload
|
||||
``lro``
|
||||
large-receive-offload
|
||||
``rxvlan``
|
||||
rx-vlan-offload
|
||||
``txvlan``
|
||||
tx-vlan-offload
|
||||
``ntuple``
|
||||
ntuple-filters
|
||||
``rxhash``
|
||||
receive-hashing
|
||||
``rdma``
|
||||
remote-direct-memory-access
|
||||
``txudptnl``
|
||||
tx-udp-tunnel-segmentation
|
||||
``switchdev``
|
||||
kernel-forward-plane-offload
|
||||
``capability``
|
||||
A network protocol exposed by the device, where the attribute ``type``
|
||||
can be "80203" for IEEE 802.3, or "80211" for various flavors of IEEE
|
||||
802.11.
|
||||
|
||||
``scsi_host``
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Describes a SCSI host device. Sub-elements include:
|
||||
|
||||
``host``
|
||||
The SCSI host number.
|
||||
``unique_id``
|
||||
On input, this optionally provides the value from the 'unique_id' file
|
||||
found in the scsi_host's directory. To view the values of all
|
||||
'unique_id' files, use
|
||||
``find -H /sys/class/scsi_host/host{0..9}/unique_id | xargs grep '[0-9]'``.
|
||||
On output, if the unique_id file exists, the value from the file will
|
||||
be displayed. This can be used in order to help uniquely identify the
|
||||
scsi_host adapter in a `Storage Pool <formatstorage.html>`__.
|
||||
:since:`Since 1.2.7`
|
||||
``capability``
|
||||
Current capabilities include "vports_ops" (indicates vport operations
|
||||
are supported) and "fc_host". "vport_ops" could contain two optional
|
||||
sub-elements: ``vports``, and ``max_vports``. ``vports`` shows the
|
||||
number of vport in use. ``max_vports`` shows the maximum vports the HBA
|
||||
supports. "fc_host" implies following sub-elements: ``wwnn``, ``wwpn``,
|
||||
and optionally ``fabric_wwn``.
|
||||
|
||||
``scsi``
|
||||
^^^^^^^^
|
||||
|
||||
Describes a SCSI device. Sub-elements include:
|
||||
|
||||
``host``
|
||||
The SCSI host containing the device.
|
||||
``bus``
|
||||
The bus within the host.
|
||||
``target``
|
||||
The target within the bus.
|
||||
``lun``
|
||||
The lun within the target.
|
||||
``type``
|
||||
The type of SCSI device.
|
||||
|
||||
``storage``
|
||||
^^^^^^^^^^^
|
||||
|
||||
Describes a device usable for storage. Sub-elements include:
|
||||
|
||||
``block``
|
||||
A block device file name that accesses the storage present on the
|
||||
device.
|
||||
``bus``
|
||||
If present, the name of the bus the device is found on.
|
||||
``drive_type``
|
||||
The type of the drive, such as "disk" or "cdrom".
|
||||
``model``
|
||||
Any model information available from the device.
|
||||
``vendor``
|
||||
Any vendor information available from the device.
|
||||
``serial``
|
||||
Any serial number information available from the device.
|
||||
``size``
|
||||
For fixed-size storage, the amount of storage available.
|
||||
``capability``
|
||||
If present, an additional capability is listed via the attribute
|
||||
``type``. Current capabilities include "hotpluggable" and "removable",
|
||||
with the latter implying the following sub-elements:
|
||||
``media_available`` (0 or 1), ``media_size``, and ``media_label``.
|
||||
|
||||
``drm``
|
||||
^^^^^^^
|
||||
|
||||
Describes a Direct Rendering Manager (DRM) device. Sub-elements include:
|
||||
|
||||
``type``
|
||||
The type of DRM device. Could be ``primary``, ``control`` or ``render``.
|
||||
|
||||
``mdev``
|
||||
^^^^^^^^
|
||||
|
||||
Describes a mediated device. :since:`Since 3.4.0` Sub-elements include:
|
||||
|
||||
``type``
|
||||
Describes a mediated device type which acts as an abstract template
|
||||
defining a resource allocation for instances of this device type. The
|
||||
element has one attribute ``id`` which holds an official
|
||||
vendor-supplied identifier for the type.
|
||||
``iommuGroup``
|
||||
This element supports a single attribute ``number`` which holds the
|
||||
IOMMU group number to which the mediated device belongs. This is a
|
||||
read-only field that is reported by the device driver.
|
||||
``attr``
|
||||
This optional element can occur multiple times. It represents a
|
||||
vendor-specific attribute that is used to configure this mediated
|
||||
device. It has two required attributes: ``name`` and ``value``. Note
|
||||
that the order in which attributes are set may be important for some
|
||||
devices. The order that they appear in the xml definition determines
|
||||
the order that they will be written to the device.
|
||||
``uuid``
|
||||
This element represents the UUID of the mediated device.
|
||||
|
||||
``ccw``
|
||||
^^^^^^^
|
||||
|
||||
Describes a Command Channel Word (CCW) device commonly found on the S390
|
||||
architecture. Sub-elements include:
|
||||
|
||||
``cssid``
|
||||
The channel subsystem identifier.
|
||||
``ssid``
|
||||
The subchannel-set identifier.
|
||||
``devno``
|
||||
The device number.
|
||||
|
||||
``css``
|
||||
^^^^^^^
|
||||
|
||||
Describes a subchannel in the Channel SubSystem (CSS) commonly found on the
|
||||
S390 architecture. Sub-elements include:
|
||||
|
||||
``cssid``
|
||||
The channel subsystem identifier.
|
||||
``ssid``
|
||||
The subchannel-set identifier.
|
||||
``devno``
|
||||
The subchannel number.
|
||||
``capability``
|
||||
This optional element can occur multiple times. If it exists, it has a
|
||||
mandatory ``type`` attribute which will be set to:
|
||||
|
||||
``mdev_types``
|
||||
:since:`Since 6.10.0` This device is capable of creating mediated
|
||||
devices. The sub-elements are summarized in `mdev_types capability`_.
|
||||
|
||||
``vdpa``
|
||||
^^^^^^^^
|
||||
|
||||
Describes a virtual datapath acceleration (vDPA) network device. :since:`Since
|
||||
6.9.0` . Sub-elements include:
|
||||
|
||||
``chardev``
|
||||
The path to the character device that is used to access the device.
|
||||
|
||||
``ap_card``
|
||||
^^^^^^^^^^^
|
||||
|
||||
Describes the Adjunct Processor (AP) Card device on a S390 host. Sub-elements
|
||||
include:
|
||||
|
||||
``ap-adapter``
|
||||
AP Card identifier.
|
||||
|
||||
``ap_queue``
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Describes the AP queue on a s390 host. An AP queue is an AP domain on an AP
|
||||
adapter which is specified by an adapter identifier and a domain identifier.
|
||||
Sub-elements include:
|
||||
|
||||
``ap-adapter``
|
||||
The ap-adapter of an AP queue identifies the AP card to which this AP
|
||||
queue belongs.
|
||||
``ap-domain``
|
||||
The ap-domain of an AP queue identifies the AP domain to which this AP
|
||||
queue belongs.
|
||||
AP Queue identifier.
|
||||
|
||||
``ap_matrix``
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Describes an AP Matrix device on a S390 architecture providing cryptographic
|
||||
host resources usable for virtualization. Sub-elements include:
|
||||
|
||||
``capability``
|
||||
This optional element can occur multiple times. If it exists, it has a
|
||||
mandatory ``type`` attribute which will be set to:
|
||||
|
||||
``mdev_types``
|
||||
:since:`Since 6.10.0` This device is capable of creating mediated
|
||||
devices. The sub-elements are summarized in `mdev_types capability`_
|
||||
|
||||
``mdev_types`` capability
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
`pci`_, `css`_ and `ap_matrix`_ devices can be capable of creating mediated
|
||||
devices. If they indeed are capable, then the parent ``capability`` element for
|
||||
``mdev_types`` type will contain a list of ``type`` elements, which list all
|
||||
mdev types supported on the physical device. :since:`Since 3.4.0` Each ``type``
|
||||
element has a single ``id`` attribute that holds an official vendor-supplied
|
||||
identifier for the type. It supports the following sub-elements:
|
||||
|
||||
``name``
|
||||
The ``name`` element holds a vendor-supplied code name for the given mediated
|
||||
device type. This is an optional element.
|
||||
``deviceAPI``
|
||||
The value of this element describes how an instance of the given type will be
|
||||
presented to the guest by the VFIO framework.
|
||||
``availableInstances``
|
||||
This element reports the current state of resource allocation. In other
|
||||
words, how many instances of the given type can still be successfully created
|
||||
on the physical device.
|
||||
|
||||
``vpd`` capability
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
`pci`_ devices can expose a VPD capability which is optional per
|
||||
PCI Local Bus 2.2+ and PCIe 4.0+ specifications. If the VPD capability is
|
||||
present, then the parent ``capability`` element with the ``vpd`` type will
|
||||
contain a ``name`` element (containing a manufacturer-provided device name) and
|
||||
optionally one or two ``fields`` elements with an ``access`` attribute set to
|
||||
``readonly`` or ``readwrite``.
|
||||
|
||||
The read-only ``fields`` element may contain the following elements:
|
||||
|
||||
``change_level``
|
||||
An engineering change level for this add-in card.
|
||||
``manufacture_id``
|
||||
An extension to the Vendor ID (or Subsystem Vendor ID) in the Configuration
|
||||
Space header which allows vendors the flexibility to identify an additional
|
||||
level of detail pertaining to the sourcing of a PCI device.
|
||||
``part_number``
|
||||
An extension to the Device ID (or Subsystem ID) in the Configuration Space
|
||||
header specifying a part number of an add-in card.
|
||||
``serial_number``
|
||||
A unique add-in card Serial Number.
|
||||
``vendor_field``
|
||||
Zero or many of those elements with an ``index`` attribute (since-character
|
||||
upper-case ASCII alphanumeric indexes). Contents will vary depending on a
|
||||
vendor.
|
||||
|
||||
All fields are optional and are not guaranteed to be present for a generic PCI
|
||||
device.
|
||||
|
||||
The read-write ``fields`` element may contain the following elements:
|
||||
|
||||
``asset_tag``
|
||||
A system asset identifier provided by the system owner.
|
||||
``vendor_field``
|
||||
Zero or many of those elements with an ``index`` attribute (since-character
|
||||
upper-case ASCII alphanumeric indexes). Contents will vary depending on a
|
||||
vendor.
|
||||
``system_field``
|
||||
Zero or many of those elements with an ``index`` attribute (since-character
|
||||
upper-case ASCII alphanumeric indexes, except for letter 'A'). May store
|
||||
system-specific data related to a PCI device.
|
||||
|
||||
All fields are optional and are not guaranteed to be present for a generic PCI
|
||||
device. Read-write fields are not possible to alter via Libvirt at the time of
|
||||
writing but their content is refreshed on each invocation in case this is done
|
||||
by means external to Libvirt.
|
||||
|
||||
The device name and all fields may contain only the following characters:
|
||||
``[0-9a-zA-F -_,.:;=]``. The device name may be as large as 65535 bytes while
|
||||
fields are limited with 255 bytes.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
The following are some example node device XML outputs:
|
||||
|
||||
::
|
||||
|
||||
<device>
|
||||
<name>computer</name>
|
||||
<capability type='system'>
|
||||
<product>2241B36</product>
|
||||
<hardware>
|
||||
<vendor>LENOVO</vendor>
|
||||
<version>ThinkPad T500</version>
|
||||
<serial>R89055N</serial>
|
||||
<uuid>c9488981-5049-11cb-9c1c-993d0230b4cd</uuid>
|
||||
</hardware>
|
||||
<firmware>
|
||||
<vendor>LENOVO</vendor>
|
||||
<version>6FET82WW (3.12 )</version>
|
||||
<release_date>11/26/2009</release_date>
|
||||
</firmware>
|
||||
</capability>
|
||||
</device>
|
||||
|
||||
<device>
|
||||
<name>net_eth1_00_27_13_6a_fe_00</name>
|
||||
<parent>pci_0000_00_19_0</parent>
|
||||
<capability type='net'>
|
||||
<interface>eth1</interface>
|
||||
<address>00:27:13:6a:fe:00</address>
|
||||
<capability type='80203'/>
|
||||
</capability>
|
||||
</device>
|
||||
|
||||
<device>
|
||||
<name>pci_0000_02_00_0</name>
|
||||
<path>/sys/devices/pci0000:00/0000:00:04.0/0000:02:00.0</path>
|
||||
<parent>pci_0000_00_04_0</parent>
|
||||
<driver>
|
||||
<name>igb</name>
|
||||
</driver>
|
||||
<capability type='pci'>
|
||||
<class>0x020000</class>
|
||||
<domain>0</domain>
|
||||
<bus>2</bus>
|
||||
<slot>0</slot>
|
||||
<function>0</function>
|
||||
<product id='0x10c9'>82576 Gigabit Network Connection</product>
|
||||
<vendor id='0x8086'>Intel Corporation</vendor>
|
||||
<capability type='virt_functions'>
|
||||
<address domain='0x0000' bus='0x02' slot='0x10' function='0x0'/>
|
||||
<address domain='0x0000' bus='0x02' slot='0x10' function='0x2'/>
|
||||
<address domain='0x0000' bus='0x02' slot='0x10' function='0x4'/>
|
||||
<address domain='0x0000' bus='0x02' slot='0x10' function='0x6'/>
|
||||
<address domain='0x0000' bus='0x02' slot='0x11' function='0x0'/>
|
||||
<address domain='0x0000' bus='0x02' slot='0x11' function='0x2'/>
|
||||
<address domain='0x0000' bus='0x02' slot='0x11' function='0x4'/>
|
||||
</capability>
|
||||
<iommuGroup number='12'>
|
||||
<address domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
|
||||
<address domain='0x0000' bus='0x02' slot='0x00' function='0x1'/>
|
||||
</iommuGroup>
|
||||
<pci-express>
|
||||
<link validity='cap' port='1' speed='2.5' width='1'/>
|
||||
<link validity='sta' speed='2.5' width='1'/>
|
||||
</pci-express>
|
||||
</capability>
|
||||
</device>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,332 @@
|
|||
.. role:: since
|
||||
|
||||
=================
|
||||
Secret XML format
|
||||
=================
|
||||
|
||||
.. contents::
|
||||
|
||||
Secret XML
|
||||
----------
|
||||
|
||||
Secrets stored by libvirt may have attributes associated with them, using the
|
||||
``secret`` element. The ``secret`` element has two optional attributes, each
|
||||
with values '``yes``' and '``no``', and defaulting to '``no``':
|
||||
|
||||
``ephemeral``
|
||||
This secret must only be kept in memory, never stored persistently.
|
||||
``private``
|
||||
The value of the secret must not be revealed to any caller of libvirt, nor to
|
||||
any other node.
|
||||
|
||||
The top-level ``secret`` element may contain the following elements:
|
||||
|
||||
``uuid``
|
||||
An unique identifier for this secret (not necessarily in the UUID format). If
|
||||
omitted when defining a new secret, a random UUID is generated.
|
||||
``description``
|
||||
A human-readable description of the purpose of the secret.
|
||||
``usage``
|
||||
Specifies what this secret is used for. A mandatory ``type`` attribute
|
||||
specifies the usage category, currently only ``volume``, ``ceph``, ``iscsi``,
|
||||
``tls``, and ``vtpm`` are defined. Specific usage categories are described
|
||||
below.
|
||||
|
||||
Usage type "volume"
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This secret is associated with a volume, whether the format is either for a
|
||||
"luks" encrypted volume. Each volume will have a unique secret associated with
|
||||
it and it is safe to delete the secret after the volume is deleted. The
|
||||
``<usage type='volume'>`` element must contain a single ``volume`` element that
|
||||
specifies the path of the volume this secret is associated with. For example,
|
||||
create a volume-secret.xml file as follows:
|
||||
|
||||
::
|
||||
|
||||
<secret ephemeral='no' private='yes'>
|
||||
<description>Super secret name of my first puppy</description>
|
||||
<uuid>0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f</uuid>
|
||||
<usage type='volume'>
|
||||
<volume>/var/lib/libvirt/images/puppyname.img</volume>
|
||||
</usage>
|
||||
</secret>
|
||||
|
||||
Define the secret and set the passphrase as follows:
|
||||
|
||||
::
|
||||
|
||||
# virsh secret-define volume-secret.xml
|
||||
Secret 0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f created
|
||||
|
||||
See `Setting secret values in virsh`_ on how to set the value of the secret
|
||||
using ``virsh secret-set-value``.
|
||||
|
||||
The volume type secret can be supplied either in volume XML during creation of a
|
||||
`storage volume <formatstorage.html#storage-volume-xml>`__ in order to provide
|
||||
the passphrase to encrypt the volume or in domain XML
|
||||
`disk device <formatdomain.html#hard-drives-floppy-disks-cdroms>`__ in order to provide the
|
||||
passphrase to decrypt the volume, :since:`since 2.1.0` . An example follows:
|
||||
|
||||
::
|
||||
|
||||
# cat luks-secret.xml
|
||||
<secret ephemeral='no' private='yes'>
|
||||
<description>LUKS Sample Secret</description>
|
||||
<uuid>f52a81b2-424e-490c-823d-6bd4235bc57</uuid>
|
||||
<usage type='volume'>
|
||||
<volume>/var/lib/libvirt/images/luks-sample.img</volume>
|
||||
</usage>
|
||||
</secret>
|
||||
|
||||
# virsh secret-define luks-secret.xml
|
||||
Secret f52a81b2-424e-490c-823d-6bd4235bc57 created
|
||||
|
||||
See `Setting secret values in virsh`_ on how to set the value of the secret
|
||||
using ``virsh secret-set-value``.
|
||||
|
||||
The volume type secret can be supplied in domain XML for a luks storage volume
|
||||
`encryption <formatstorageencryption.html>`__ as follows:
|
||||
|
||||
::
|
||||
|
||||
<encryption format='luks'>
|
||||
<secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc57'/>
|
||||
</encryption>
|
||||
|
||||
Usage type "ceph"
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
This secret is associated with a Ceph RBD (rados block device). The
|
||||
``<usage type='ceph'>`` element must contain a single ``name`` element that
|
||||
specifies a usage name for the secret. The Ceph secret can then be used by UUID
|
||||
or by this usage name via the ``<auth>`` element of a `disk
|
||||
device <formatdomain.html#hard-drives-floppy-disks-cdroms>`__ or a `storage pool
|
||||
(rbd) <formatstorage.html>`__. :since:`Since 0.9.7` . The following is an
|
||||
example of the steps to be taken. First create a ceph-secret.xml file:
|
||||
|
||||
::
|
||||
|
||||
<secret ephemeral='no' private='yes'>
|
||||
<description>CEPH passphrase example</description>
|
||||
<usage type='ceph'>
|
||||
<name>ceph_example</name>
|
||||
</usage>
|
||||
</secret>
|
||||
|
||||
Next, use ``virsh secret-define ceph-secret.xml`` to define the secret and
|
||||
``virsh secret-set-value`` using the generated UUID value and a base64 generated
|
||||
secret value in order to define the chosen secret pass phrase.
|
||||
|
||||
::
|
||||
|
||||
# virsh secret-define ceph-secret.xml
|
||||
Secret 1b40a534-8301-45d5-b1aa-11894ebb1735 created
|
||||
#
|
||||
# virsh secret-list
|
||||
UUID Usage
|
||||
-----------------------------------------------------------
|
||||
1b40a534-8301-45d5-b1aa-11894ebb1735 cephx ceph_example
|
||||
|
||||
See `Setting secret values in virsh`_ on how to set the value of the secret
|
||||
using ``virsh secret-set-value``.
|
||||
|
||||
The ceph secret can then be used by UUID or by the usage name via the ``<auth>``
|
||||
element in a domain's `<disk> <formatdomain.html#hard-drives-floppy-disks-cdroms>`__ element as
|
||||
follows:
|
||||
|
||||
::
|
||||
|
||||
<auth username='myname'>
|
||||
<secret type='ceph' usage='ceph_example'/>
|
||||
</auth>
|
||||
|
||||
As well as the ``<auth>`` element in a `storage pool
|
||||
(rbd) <formatstorage.html>`__ ``<source>`` element as follows:
|
||||
|
||||
::
|
||||
|
||||
<auth type='ceph' username='myname'>
|
||||
<secret usage='ceph_example'/>
|
||||
</auth>
|
||||
|
||||
Usage type "iscsi"
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This secret is associated with an iSCSI target for CHAP authentication. The
|
||||
``<usage type='iscsi'>`` element must contain a single ``target`` element that
|
||||
specifies a usage name for the secret. The iSCSI secret can then be used by UUID
|
||||
or by this usage name via the ``<auth>`` element of a `disk
|
||||
device <formatdomain.html#hard-drives-floppy-disks-cdroms>`__ or a `storage pool
|
||||
(iscsi) <formatstorage.html>`__. :since:`Since 1.0.4` . The following is an
|
||||
example of the XML that may be used to generate a secret for iSCSI CHAP
|
||||
authentication. Assume the following sample entry in an iSCSI authentication
|
||||
file:
|
||||
|
||||
::
|
||||
|
||||
<target iqn.2013-07.com.example:iscsi-pool>
|
||||
backing-store /home/tgtd/iscsi-pool/disk1
|
||||
backing-store /home/tgtd/iscsi-pool/disk2
|
||||
incominguser myname mysecret
|
||||
</target>
|
||||
|
||||
Define an iscsi-secret.xml file to describe the secret. Use the ``incominguser``
|
||||
username used in your iSCSI authentication configuration file as the value for
|
||||
the ``username`` attribute. The ``description`` attribute should contain
|
||||
configuration specific data. The ``target`` name may be any name of your
|
||||
choosing to be used as the ``usage`` when used in the pool or disk XML
|
||||
description.
|
||||
|
||||
::
|
||||
|
||||
<secret ephemeral='no' private='yes'>
|
||||
<description>Passphrase for the iSCSI example.com server</description>
|
||||
<usage type='iscsi'>
|
||||
<target>libvirtiscsi</target>
|
||||
</usage>
|
||||
</secret>
|
||||
|
||||
Next, use ``virsh secret-define iscsi-secret.xml`` to define the secret and
|
||||
``virsh secret-set-value`` using the generated UUID value and a base64 generated
|
||||
secret value in order to define the chosen secret pass phrase. The pass phrase
|
||||
must match the password used in the iSCSI authentication configuration file.
|
||||
|
||||
::
|
||||
|
||||
# virsh secret-define secret.xml
|
||||
Secret c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 created
|
||||
|
||||
# virsh secret-list
|
||||
UUID Usage
|
||||
-----------------------------------------------------------
|
||||
c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 iscsi libvirtiscsi
|
||||
|
||||
|
||||
See `Setting secret values in virsh`_ on how to set the value of the secret
|
||||
using ``virsh secret-set-value``.
|
||||
|
||||
The iSCSI secret can then be used by UUID or by the usage name via the
|
||||
``<auth>`` element in a domain's `<disk> <formatdomain.html#hard-drives-floppy-disks-cdroms>`__
|
||||
element as follows:
|
||||
|
||||
::
|
||||
|
||||
<auth username='myname'>
|
||||
<secret type='iscsi' usage='libvirtiscsi'/>
|
||||
</auth>
|
||||
|
||||
As well as the ``<auth>`` element in a `storage pool
|
||||
(iscsi) <formatstorage.html>`__ ``<source>`` element as follows:
|
||||
|
||||
::
|
||||
|
||||
<auth type='chap' username='myname'>
|
||||
<secret usage='libvirtiscsi'/>
|
||||
</auth>
|
||||
|
||||
Usage type "tls"
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
This secret may be used in order to provide the passphrase for the private key
|
||||
used to provide TLS credentials. The ``<usage type='tls'>`` element must contain
|
||||
a single ``name`` element that specifies a usage name for the secret.
|
||||
:since:`Since 2.3.0` . The following is an example of the expected XML and
|
||||
processing to define the secret:
|
||||
|
||||
::
|
||||
|
||||
# cat tls-secret.xml
|
||||
<secret ephemeral='no' private='yes'>
|
||||
<description>sample tls secret</description>
|
||||
<usage type='tls'>
|
||||
<name>TLS_example</name>
|
||||
</usage>
|
||||
</secret>
|
||||
|
||||
# virsh secret-define tls-secret.xml
|
||||
Secret 718c71bd-67b5-4a2b-87ec-a24e8ca200dc created
|
||||
|
||||
# virsh secret-list
|
||||
UUID Usage
|
||||
-----------------------------------------------------------
|
||||
718c71bd-67b5-4a2b-87ec-a24e8ca200dc tls TLS_example
|
||||
|
||||
A secret may also be defined via the
|
||||
`virSecretDefineXML <html/libvirt-libvirt-secret.html#virSecretDefineXML>`__
|
||||
API. Once the secret is defined, a secret value will need to be set. The secret
|
||||
would be the passphrase used to access the TLS credentials. The following is a
|
||||
simple example of using ``virsh secret-set-value`` to set the secret value. The
|
||||
`virSecretSetValue <html/libvirt-libvirt-secret.html#virSecretSetValue>`__ API
|
||||
may also be used to set a more secure secret without using printable/readable
|
||||
characters.
|
||||
|
||||
Usage type "vtpm"
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
This secret is associated with a virtualized TPM (vTPM) and serves as a
|
||||
passphrase for deriving a key from for encrypting the state of the vTPM. The
|
||||
``<usage type='vtpm'>`` element must contain a single ``name`` element that
|
||||
specifies a usage name for the secret. The vTPM secret can then be used by UUID
|
||||
via the ``<encryption>`` element of a `tpm <formatdomain.html#tpm-device>`__
|
||||
when using an emulator. :since:`Since 5.6.0` . The following is an example of
|
||||
the steps to be taken. First create a vtpm-secret.xml file:
|
||||
|
||||
::
|
||||
|
||||
# cat vtpm-secret.xml
|
||||
<secret ephemeral='no' private='yes'>
|
||||
<description>sample vTPM secret</description>
|
||||
<usage type='vtpm'>
|
||||
<name>VTPM_example</name>
|
||||
</usage>
|
||||
</secret>
|
||||
|
||||
# virsh secret-define vtpm-secret.xml
|
||||
Secret 6dd3e4a5-1d76-44ce-961f-f119f5aad935 created
|
||||
|
||||
# virsh secret-list
|
||||
UUID Usage
|
||||
----------------------------------------------------------------------------------------
|
||||
6dd3e4a5-1d76-44ce-961f-f119f5aad935 vtpm VTPM_example
|
||||
|
||||
A secret may also be defined via the
|
||||
`virSecretDefineXML <html/libvirt-libvirt-secret.html#virSecretDefineXML>`__
|
||||
API. Once the secret is defined, a secret value will need to be set. The secret
|
||||
would be the passphrase used to decrypt the vTPM state. The following is a
|
||||
simple example of using ``virsh secret-set-value`` to set the secret value. The
|
||||
`virSecretSetValue <html/libvirt-libvirt-secret.html#virSecretSetValue>`__ API
|
||||
may also be used to set a more secure secret without using printable/readable
|
||||
characters.
|
||||
|
||||
Setting secret values in virsh
|
||||
------------------------------
|
||||
|
||||
To set the value of the secret you can use the following virsh commands. If the
|
||||
secret is a password-like string (printable characters, no newline) you can use:
|
||||
|
||||
::
|
||||
|
||||
# virsh secret-set-value --interactive 6dd3e4a5-1d76-44ce-961f-f119f5aad935
|
||||
Enter new value for secret:
|
||||
Secret value set
|
||||
|
||||
Another secure option is to read the secret from a file. This way the secret can
|
||||
contain any bytes (even NUL and non-printable characters). The length of the
|
||||
secret is the length of the input file. Alternatively the ``--plain`` option can
|
||||
be omitted if the file contents are base64-encoded.
|
||||
|
||||
::
|
||||
|
||||
# virsh secret-set-value 6dd3e4a5-1d76-44ce-961f-f119f5aad935 --file --plain secretinfile
|
||||
Secret value set
|
||||
|
||||
**WARNING** The following approach is **insecure** and deprecated. The secret
|
||||
can also be set via an argument. Note that other users may see the actual secret
|
||||
in the process listing! The secret must be base64 encoded.
|
||||
|
||||
::
|
||||
|
||||
# MYSECRET=`printf %s "open sesame" | base64`
|
||||
# virsh secret-set-value 6dd3e4a5-1d76-44ce-961f-f119f5aad935 $MYSECRET
|
||||
Secret value set
|
|
@ -0,0 +1,305 @@
|
|||
.. role:: since
|
||||
|
||||
===================
|
||||
Snapshot XML format
|
||||
===================
|
||||
|
||||
.. contents::
|
||||
|
||||
Snapshot XML
|
||||
------------
|
||||
|
||||
Snapshots are one form of `domain state
|
||||
capture <kbase/domainstatecapture.html>`__. There are several types of
|
||||
snapshots:
|
||||
|
||||
disk snapshot
|
||||
Contents of disks (whether a subset or all disks associated with the domain)
|
||||
are saved at a given point of time, and can be restored back to that state.
|
||||
On a running guest, a disk snapshot is likely to be only crash-consistent
|
||||
rather than clean (that is, it represents the state of the disk on a sudden
|
||||
power outage, and may need fsck or journal replays to be made consistent); on
|
||||
an inactive guest, a disk snapshot is clean if the disks were clean when the
|
||||
guest was last shut down. Disk snapshots exist in two forms: internal (file
|
||||
formats such as qcow2 track both the snapshot and changes since the snapshot
|
||||
in a single file) and external (the snapshot is one file, and the changes
|
||||
since the snapshot are in another file).
|
||||
memory state (or VM state)
|
||||
Tracks only the state of RAM and all other resources in use by the VM. If the
|
||||
disks are unmodified between the time a VM state snapshot is taken and
|
||||
restored, then the guest will resume in a consistent state; but if the disks
|
||||
are modified externally in the meantime, this is likely to lead to data
|
||||
corruption.
|
||||
full system
|
||||
A combination of disk snapshots for all disks as well as VM memory state,
|
||||
which can be used to resume the guest from where it left off with symptoms
|
||||
similar to hibernation (that is, TCP connections in the guest may have timed
|
||||
out, but no files or processes are lost).
|
||||
|
||||
Libvirt can manage all three types of snapshots. For now, VM state (memory)
|
||||
snapshots are created only by the ``virDomainSave()``, ``virDomainSaveFlags``,
|
||||
``virDomainSaveParams`` and ``virDomainManagedSave()`` functions, and restored
|
||||
via the ``virDomainRestore()``, ``virDomainRestoreFlags()``,
|
||||
``virDomainRestoreParams``, ``virDomainCreate()``, and
|
||||
``virDomainCreateWithFlags()`` functions (as well as via domain autostart). With
|
||||
managed snapshots, libvirt tracks all information internally; with save images,
|
||||
the user tracks the snapshot file, but libvirt provides functions such as
|
||||
``virDomainSaveImageGetXMLDesc()`` to work with those files.
|
||||
|
||||
Full system snapshots are created by ``virDomainSnapshotCreateXML()`` with no
|
||||
flags, while disk snapshots are created by the same function with the
|
||||
``VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY`` flag. Regardless of the flags provided,
|
||||
restoration of the snapshot is handled by the ``virDomainRevertToSnapshot()``
|
||||
function. For these types of snapshots, libvirt tracks each snapshot as a
|
||||
separate ``virDomainSnapshotPtr`` object, and maintains a tree relationship of
|
||||
which snapshots descended from an earlier point in time.
|
||||
|
||||
Attributes of libvirt snapshots are stored as child elements of the
|
||||
``domainsnapshot`` element. At snapshot creation time, normally only the
|
||||
``name``, ``description``, and ``disks`` elements are settable; the rest of the
|
||||
fields are ignored on creation, and will be filled in by libvirt in for
|
||||
informational purposes by ``virDomainSnapshotGetXMLDesc()``. However, when
|
||||
redefining a snapshot ( :since:`since 0.9.5` ), with the
|
||||
``VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE`` flag of
|
||||
``virDomainSnapshotCreateXML()``, all of the XML described here is relevant on
|
||||
input, even the fields that are normally described as readonly for output.
|
||||
|
||||
Snapshots are maintained in a hierarchy. A domain can have a current snapshot,
|
||||
which is the most recent snapshot compared to the current state of the domain
|
||||
(although a domain might have snapshots without a current snapshot, if snapshots
|
||||
have been deleted in the meantime). Creating or reverting to a snapshot sets
|
||||
that snapshot as current, and the prior current snapshot is the parent of the
|
||||
new snapshot. Branches in the hierarchy can be formed by reverting to a snapshot
|
||||
with a child, then creating another snapshot. For now, the creation of external
|
||||
snapshots when checkpoints exist is forbidden, although future work will make it
|
||||
possible to integrate these two concepts.
|
||||
|
||||
The top-level ``domainsnapshot`` element may contain the following elements:
|
||||
|
||||
``name``
|
||||
|
||||
The optional name for this snapshot. If the name is omitted, libvirt will
|
||||
create a name based on the time of the creation.
|
||||
|
||||
``description``
|
||||
|
||||
An optional human-readable description of the snapshot. If the description
|
||||
is omitted when initially creating the snapshot, then this field will be
|
||||
empty.
|
||||
|
||||
``memory``
|
||||
|
||||
On input, this is an optional request for how to handle VM memory state. For
|
||||
an offline domain or a disk-only snapshot, attribute ``snapshot`` must be
|
||||
``no``, since there is no VM state saved; otherwise, the attribute can be
|
||||
``internal`` if the memory state is piggy-backed with other internal disk
|
||||
state, or ``external`` along with a second attribute ``file`` giving the
|
||||
absolute path of the file holding the VM memory state. :since:`Since 1.0.1`
|
||||
|
||||
``disks``
|
||||
|
||||
On input, this is an optional listing of specific instructions for disk
|
||||
snapshots; it is needed when making a snapshot of only a subset of the disks
|
||||
associated with a domain, or when overriding the domain defaults for how to
|
||||
snapshot each disk, or for providing specific control over what file name is
|
||||
created in an external snapshot. On output, this is fully populated to show
|
||||
the state of each disk in the snapshot, including any properties that were
|
||||
generated by the hypervisor defaults. For full system snapshots, this field
|
||||
is ignored on input and omitted on output (a full system snapshot implies
|
||||
that all disks participate in the snapshot process). This element has a list
|
||||
of ``disk`` sub-elements, describing anywhere from zero to all of the disks
|
||||
associated with the domain. :since:`Since 0.9.5`
|
||||
|
||||
``disk``
|
||||
|
||||
This sub-element describes the snapshot properties of a specific disk.
|
||||
The attribute ``name`` is mandatory, and must match either the ``<target
|
||||
dev='name'/>`` (recommended) or an unambiguous ``<source file='name'/>``
|
||||
of one of the `disk devices <formatdomain.html#hard-drives-floppy-disks-cdroms>`__
|
||||
specified for the domain at the time of the snapshot. The attribute
|
||||
``snapshot`` is optional, and the possible values are the same as the
|
||||
``snapshot`` attribute for `disk devices
|
||||
<formatdomain.html#hard-drives-floppy-disks-cdroms>`__ (``no``, ``internal``, or
|
||||
``external``). Some hypervisors like ESX require that if specified, the
|
||||
snapshot mode must not override any snapshot mode attached to the
|
||||
corresponding domain disk, while others like qemu allow this field to
|
||||
override the domain default.
|
||||
|
||||
:since:`Since 8.2.0` the ``snapshot`` attribute supports the ``manual``
|
||||
value which instructs the hypervisor to create the snapshot and keep a
|
||||
synchronized state by pausing the VM which allows to snapshot disk
|
||||
storage from outside of the hypervisor if the storage provider supports
|
||||
it. The caller is responsible for resuming a VM paused by requesting a
|
||||
``manual`` snapshot. When reverting such snapshot, the expectation is that
|
||||
the storage is configured in a way where the hypervisor will see the
|
||||
correct image state.
|
||||
|
||||
:since:`Since 1.2.2` the ``disk`` element supports an optional attribute
|
||||
``type`` if the ``snapshot`` attribute is set to ``external``. This
|
||||
attribute specifies the snapshot target storage type and allows to
|
||||
overwrite the default ``file`` type. The ``type`` attribute along with
|
||||
the format of the ``source`` sub-element is identical to the ``source``
|
||||
element used in domain disk definitions. See the `disk devices
|
||||
<formatdomain.html#hard-drives-floppy-disks-cdroms>`__ section documentation for further
|
||||
information. Libvirt currently supports the ``type`` element in the qemu
|
||||
driver and supported values are ``file``, ``block`` and ``network``
|
||||
:since:`(since 1.2.2)`.
|
||||
|
||||
``source``
|
||||
|
||||
If the snapshot mode is external (whether specified or inherited),
|
||||
then there is an optional sub-element ``source``, with an attribute
|
||||
``file`` giving the name of the new file. If ``source`` is not given
|
||||
and the disk is backed by a local image file (not a block device or
|
||||
remote storage), a file name is generated that consists of the
|
||||
existing file name with anything after the trailing dot replaced by
|
||||
the snapshot name. Remember that with external snapshots, the original
|
||||
file name becomes the read-only snapshot, and the new file name
|
||||
contains the read-write delta of all disk changes since the snapshot.
|
||||
|
||||
The ``source`` element also may contain the ``seclabel`` element
|
||||
(described in the `domain XML documentation
|
||||
<formatdomain.html#security-label>`__) which can be used to override the
|
||||
domain security labeling policy for ``source``.
|
||||
|
||||
``driver``
|
||||
|
||||
An optional sub-element ``driver``, with an attribute ``type`` giving
|
||||
the driver type (such as qcow2), of the new file created by the
|
||||
external snapshot of the new file. Optionally ``metadata_cache``
|
||||
sub-element can be used with same semantics as the identically named
|
||||
subelement of the domain definition disk's driver.
|
||||
|
||||
``creationTime``
|
||||
|
||||
A readonly representation of the time this snapshot was created. The time is
|
||||
specified in seconds since the Epoch, UTC (i.e. Unix time).
|
||||
|
||||
``state``
|
||||
|
||||
A readonly representation of the state of the domain at the time this
|
||||
snapshot was taken. If a full system snapshot was created, then this is the
|
||||
state of the domain at that time. When the domain is reverted to this
|
||||
snapshot, the domain's state will default to this state, unless overridden
|
||||
by ``virDomainRevertToSnapshot()`` flags to revert to a running or paused
|
||||
state. Additionally, this field can be the value "disk-snapshot" (
|
||||
:since:`since 0.9.5`) when it represents only a disk snapshot (no VM memory
|
||||
state), and reverting to this snapshot will default to an inactive guest.
|
||||
|
||||
``parent``
|
||||
|
||||
Readonly, present only if this snapshot has a parent. The parent name is
|
||||
given by the sub-element ``name``. The parent relationship allows tracking a
|
||||
tree of related snapshots.
|
||||
|
||||
``domain``
|
||||
|
||||
A readonly representation of the domain that this snapshot was taken
|
||||
against. Older versions of libvirt stored only a single child element,
|
||||
uuid; reverting to a snapshot like this is risky if the current state of the
|
||||
domain differs from the state that the domain was created in, and requires
|
||||
the use of the ``VIR_DOMAIN_SNAPSHOT_REVERT_FORCE`` flag in
|
||||
``virDomainRevertToSnapshot()``. Newer versions of libvirt ( :since:`since
|
||||
0.9.5` ) store the entire inactive `domain configuration
|
||||
<formatdomain.html>`__ at the time of the snapshot ( :since:`since 0.9.5` ).
|
||||
The domain will have security-sensitive information omitted unless the flag
|
||||
``VIR_DOMAIN_SNAPSHOT_XML_SECURE`` is provided on a read-write connection.
|
||||
|
||||
``cookie``
|
||||
|
||||
An optional readonly representation of a save image cookie containing
|
||||
additional data libvirt may need to properly restore a domain from an active
|
||||
snapshot when such data cannot be stored directly in the ``domain`` to
|
||||
maintain compatibility with older libvirt or hypervisor.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Using this XML to create a disk snapshot of just vda on a qemu domain with two
|
||||
disks:
|
||||
|
||||
::
|
||||
|
||||
<domainsnapshot>
|
||||
<description>Snapshot of OS install and updates</description>
|
||||
<disks>
|
||||
<disk name='vda'>
|
||||
<source file='/path/to/new'/>
|
||||
</disk>
|
||||
<disk name='vdb' snapshot='no'/>
|
||||
<disk name='vdc'>
|
||||
<source file='/path/to/newc'>
|
||||
<seclabel model='dac' relabel='no'/>
|
||||
</source>
|
||||
</disk>
|
||||
</disks>
|
||||
</domainsnapshot>
|
||||
|
||||
will result in XML similar to this from ``virDomainSnapshotGetXMLDesc()``:
|
||||
|
||||
::
|
||||
|
||||
<domainsnapshot>
|
||||
<name>1270477159</name>
|
||||
<description>Snapshot of OS install and updates</description>
|
||||
<state>running</state>
|
||||
<creationTime>1270477159</creationTime>
|
||||
<parent>
|
||||
<name>bare-os-install</name>
|
||||
</parent>
|
||||
<memory snapshot='no'/>
|
||||
<disks>
|
||||
<disk name='vda' snapshot='external'>
|
||||
<driver type='qcow2'/>
|
||||
<source file='/path/to/new'/>
|
||||
</disk>
|
||||
<disk name='vdb' snapshot='no'/>
|
||||
</disks>
|
||||
<domain>
|
||||
<name>fedora</name>
|
||||
<uuid>93a5c045-6457-2c09-e56c-927cdf34e178</uuid>
|
||||
<memory>1048576</memory>
|
||||
...
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/path/to/old'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk' snapshot='external'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/path/to/old2'/>
|
||||
<target dev='vdb' bus='virtio'/>
|
||||
</disk>
|
||||
...
|
||||
</devices>
|
||||
</domain>
|
||||
</domainsnapshot>
|
||||
|
||||
With that snapshot created, ``/path/to/old`` is the read-only backing file to
|
||||
the new active file ``/path/to/new``. The ``<domain>`` element within the
|
||||
snapshot xml records the state of the domain just before the snapshot; a call to
|
||||
``virDomainGetXMLDesc()`` will show that the domain has been changed to reflect
|
||||
the snapshot:
|
||||
|
||||
::
|
||||
|
||||
<domain>
|
||||
<name>fedora</name>
|
||||
<uuid>93a5c045-6457-2c09-e56c-927cdf34e178</uuid>
|
||||
<memory>1048576</memory>
|
||||
...
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2'/>
|
||||
<source file='/path/to/new'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk' snapshot='external'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/path/to/old2'/>
|
||||
<target dev='vdb' bus='virtio'/>
|
||||
</disk>
|
||||
...
|
||||
</devices>
|
||||
</domain>
|
|
@ -0,0 +1,833 @@
|
|||
.. role:: since
|
||||
|
||||
==================================
|
||||
Storage pool and volume XML format
|
||||
==================================
|
||||
|
||||
.. contents::
|
||||
|
||||
Storage pool XML
|
||||
----------------
|
||||
|
||||
Although all storage pool backends share the same public APIs and XML format,
|
||||
they have varying levels of capabilities. Some may allow creation of volumes,
|
||||
others may only allow use of pre-existing volumes. Some may have constraints on
|
||||
volume size, or placement.
|
||||
|
||||
The top level tag for a storage pool document is 'pool'. It has a single
|
||||
attribute ``type``, which is one of ``dir``, ``fs``, ``netfs``, ``disk``,
|
||||
``iscsi``, ``logical``, ``scsi`` (all :since:`since 0.4.1` ), ``mpath`` (
|
||||
:since:`since 0.7.1` ), ``rbd`` ( :since:`since 0.9.13` ), ``sheepdog`` (
|
||||
:since:`since 0.10.0` ), ``gluster`` ( :since:`since 1.2.0` ), ``zfs`` (
|
||||
:since:`since 1.2.8` ), ``vstorage`` ( :since:`since 3.1.0` ), or
|
||||
``iscsi-direct`` ( :since:`since 4.7.0` ). This corresponds to the storage
|
||||
backend drivers listed further along in this document.
|
||||
|
||||
Storage pool general metadata
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<pool type="iscsi">
|
||||
<name>virtimages</name>
|
||||
<uuid>3e3fce45-4f53-4fa7-bb32-11f34168b82b</uuid>
|
||||
<allocation>10000000</allocation>
|
||||
<capacity>50000000</capacity>
|
||||
<available>40000000</available>
|
||||
...
|
||||
|
||||
``name``
|
||||
Providing a name for the pool which is unique to the host. This is mandatory
|
||||
when defining a pool. :since:`Since 0.4.1`
|
||||
``uuid``
|
||||
Providing an identifier for the pool which is globally unique. This is
|
||||
optional when defining a pool, a UUID will be generated if omitted.
|
||||
:since:`Since 0.4.1`
|
||||
``allocation``
|
||||
Providing the total storage allocation for the pool. This may be larger than
|
||||
the sum of the allocation of all volumes due to metadata overhead. This value
|
||||
is in bytes. This is not applicable when creating a pool. :since:`Since
|
||||
0.4.1`
|
||||
``capacity``
|
||||
Providing the total storage capacity for the pool. Due to underlying device
|
||||
constraints it may not be possible to use the full capacity for storage
|
||||
volumes. This value is in bytes. This is not applicable when creating a pool.
|
||||
:since:`Since 0.4.1`
|
||||
``available``
|
||||
Providing the free space available for allocating new volumes in the pool.
|
||||
Due to underlying device constraints it may not be possible to allocate the
|
||||
entire free space to a single volume. This value is in bytes. This is not
|
||||
applicable when creating a pool. :since:`Since 0.4.1`
|
||||
|
||||
Features
|
||||
~~~~~~~~
|
||||
|
||||
Some pools support optional features:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<features>
|
||||
<cow state='no'>
|
||||
</features>
|
||||
...
|
||||
|
||||
Valid features are:
|
||||
|
||||
``cow``
|
||||
Controls whether the filesystem performs copy-on-write (COW) for images in
|
||||
the pool. This may only be set for directory / filesystem pools on the
|
||||
``btrfs`` filesystem. If not set then libvirt will attempt to disable COW
|
||||
on any btrfs filesystems. :since:`Since 6.6.0`.
|
||||
|
||||
Source elements
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
A single ``source`` element is contained within the top level ``pool`` element.
|
||||
This tag is used to describe the source of the storage pool. The set of child
|
||||
elements that it will contain depend on the pool type, but come from the
|
||||
following child elements:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<source>
|
||||
<host name="iscsi.example.com"/>
|
||||
<device path="iqn.2013-06.com.example:iscsi-pool"/>
|
||||
<auth type='chap' username='myname'>
|
||||
<secret usage='mycluster_myname'/>
|
||||
</auth>
|
||||
<vendor name="Acme"/>
|
||||
<product name="model"/>
|
||||
</source>
|
||||
...
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<source>
|
||||
<device path='/dev/mapper/mpatha' part_separator='no'/>
|
||||
<format type='gpt'/>
|
||||
</source>
|
||||
...
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<source>
|
||||
<adapter type='scsi_host' name='scsi_host1'/>
|
||||
</source>
|
||||
...
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<source>
|
||||
<adapter type='scsi_host'>
|
||||
<parentaddr unique_id='1'>
|
||||
<address domain='0x0000' bus='0x00' slot='0x1f' addr='0x2'/>
|
||||
</parentaddr>
|
||||
</adapter>
|
||||
</source>
|
||||
...
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<source>
|
||||
<adapter type='fc_host' parent='scsi_host5' wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/>
|
||||
</source>
|
||||
...
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<source>
|
||||
<host name='localhost'/>
|
||||
<dir path='/var/lib/libvirt/images'/>
|
||||
<format type='nfs'/>
|
||||
<protocol ver='3'/>
|
||||
</source>
|
||||
...
|
||||
|
||||
``device``
|
||||
Provides the source for pools backed by physical devices (pool types ``fs``,
|
||||
``logical``, ``disk``, ``iscsi``, ``iscsi-direct``, ``zfs``, ``vstorage``).
|
||||
May be repeated multiple times depending on backend driver. Contains a
|
||||
required attribute ``path`` which is either the fully qualified path to the
|
||||
block device node or for ``iscsi`` or ``iscsi-direct`` the iSCSI Qualified
|
||||
Name (IQN). :since:`Since 0.4.1`
|
||||
|
||||
An optional attribute ``part_separator`` for each ``path`` may be supplied.
|
||||
Valid values for the attribute may be either "yes" or "no". This attribute is
|
||||
to be used for a ``disk`` pool type using a ``path`` to a device mapper
|
||||
multipath device. Setting the attribute to "yes" causes libvirt to attempt to
|
||||
generate and find target volume path's using a "p" separator. The default
|
||||
algorithm used by device mapper is to add the "p" separator only when the
|
||||
source device path ends with a number; however, it's possible to configure
|
||||
the devmapper device to not use 'user_friendly_names' thus creating
|
||||
partitions with the "p" separator even when the device source path does not
|
||||
end with a number. :since:`Since 1.3.1`
|
||||
|
||||
``dir``
|
||||
Provides the source for pools backed by directories (pool types ``dir``,
|
||||
``netfs``, ``gluster``), or optionally to select a subdirectory within a pool
|
||||
that resembles a filesystem (pool type ``gluster``). May only occur once.
|
||||
Contains a single attribute ``path`` which is the fully qualified path to the
|
||||
backing directory or for a ``netfs`` pool type using ``format`` type "cifs",
|
||||
the path to the Samba share without the leading slash. :since:`Since 0.4.1`
|
||||
``adapter``
|
||||
Provides the source for pools backed by SCSI adapters (pool type ``scsi``).
|
||||
May only occur once.
|
||||
|
||||
``name``
|
||||
The SCSI adapter name (e.g. "scsi_host1", although a name such as "host1"
|
||||
is still supported for backwards compatibility, it is not recommended).
|
||||
The scsi_host name to be used can be determined from the output of a
|
||||
``virsh nodedev-list scsi_host`` command followed by a
|
||||
combination of ``lspci`` and
|
||||
``virsh nodedev-dumpxml scsi_hostN`` commands to find the
|
||||
``scsi_hostN`` to be used. :since:`Since 0.6.2`
|
||||
|
||||
It is further recommended to utilize the ``parentaddr`` element since it's
|
||||
possible to have the path to which the scsi_hostN uses change between
|
||||
system reboots. :since:`Since 1.2.7`
|
||||
|
||||
``type``
|
||||
Specifies the adapter type. Valid values are "scsi_host" or "fc_host". If
|
||||
omitted and the ``name`` attribute is specified, then it defaults to
|
||||
"scsi_host". To keep backwards compatibility, this attribute is optional
|
||||
**only** for the "scsi_host" adapter, but is mandatory for the "fc_host"
|
||||
adapter. :since:`Since 1.0.5` A "fc_host" capable scsi_hostN can be
|
||||
determined by using ``virsh nodedev-list --cap fc_host``. :since:`Since
|
||||
1.2.8`
|
||||
|
||||
Note: Regardless of whether a "scsi_host" adapter type is defined using a
|
||||
``name`` or a ``parentaddr``, it should refer to a real scsi_host adapter
|
||||
as found through a ``virsh nodedev-list scsi_host`` and
|
||||
``virsh nodedev-dumpxml scsi_hostN`` on one of the scsi_host's
|
||||
displayed. It should not refer to a "fc_host" capable scsi_hostN nor
|
||||
should it refer to the vHBA created for some "fc_host" adapter. For a vHBA
|
||||
the ``nodedev-dumpxml`` output parent setting will be the "fc_host"
|
||||
capable scsi_hostN value. Additionally, do not refer to an iSCSI
|
||||
scsi_hostN for the "scsi_host" source. An iSCSI scsi_hostN's
|
||||
``nodedev-dumpxml`` output parent field is generally "computer". This is a
|
||||
libvirt created parent value indicating no parent was defined for the node
|
||||
device.
|
||||
|
||||
``wwnn`` and ``wwpn``
|
||||
The required "World Wide Node Name" (``wwnn``) and "World Wide Port Name"
|
||||
(``wwpn``) are used by the "fc_host" adapter to uniquely identify the vHBA
|
||||
device in the Fibre Channel storage fabric. If the vHBA device already
|
||||
exists as a Node Device, then libvirt will use it; otherwise, the vHBA
|
||||
will be created using the provided values. It is considered a
|
||||
configuration error use the values from the HBA as those would be for a
|
||||
"scsi_host" ``type`` pool instead. The ``wwnn`` and ``wwpn`` have very
|
||||
specific format requirements based on the hypervisor being used, thus care
|
||||
should be taken if you decide to generate your own to follow the
|
||||
standards; otherwise, the pool will fail to start with an opaque error
|
||||
message indicating failure to write to the vport_create file during vport
|
||||
create/delete due to "No such file or directory". :since:`Since 1.0.4`
|
||||
|
||||
``parent``
|
||||
Used by the "fc_host" adapter type to optionally specify the parent
|
||||
scsi_host device defined in the `Node Device <formatnode.html>`__ database
|
||||
as the `NPIV <https://wiki.libvirt.org/page/NPIV_in_libvirt>`__ virtual
|
||||
Host Bus Adapter (vHBA). The value provided must be a vport capable
|
||||
scsi_host. The value is not the scsi_host of the vHBA created by 'virsh
|
||||
nodedev-create', rather it is the parent of that vHBA. If the value is not
|
||||
provided, libvirt will determine the parent based either finding the
|
||||
wwnn,wwpn defined for an existing scsi_host or by creating a vHBA.
|
||||
Providing the parent attribute is also useful for the duplicate pool
|
||||
definition checks. This is more important in environments where both the
|
||||
"fc_host" and "scsi_host" source adapter pools are being used in order to
|
||||
ensure a new definition doesn't duplicate using the scsi_hostN of some
|
||||
existing storage pool. :since:`Since 1.0.4`
|
||||
``parent_wwnn`` and ``parent_wwpn``
|
||||
Instead of the ``parent`` to specify which scsi_host to use by name, it's
|
||||
possible to provide the wwnn and wwpn of the parent to be used for the
|
||||
vHBA in order to ensure that between reboots or after a hardware
|
||||
configuration change that the scsi_host parent name doesn't change. Both
|
||||
the parent_wwnn and parent_wwpn must be provided. :since:`Since 3.0.0`
|
||||
``parent_fabric_wwn``
|
||||
Instead of the ``parent`` to specify which scsi_host to use by name, it's
|
||||
possible to provide the fabric_wwn on which the scsi_host exists. This
|
||||
provides flexibility for choosing a scsi_host that may be available on the
|
||||
fabric rather than requiring a specific parent by wwnn or wwpn to be
|
||||
available. :since:`Since 3.0.0`
|
||||
``managed``
|
||||
An optional attribute to instruct the SCSI storage backend to manage
|
||||
destroying the vHBA when the pool is destroyed. For configurations that do
|
||||
not provide an already created vHBA from a 'virsh nodedev-create', libvirt
|
||||
will set this property to "yes". For configurations that have already
|
||||
created a vHBA via 'virsh nodedev-create' and are using the wwnn/wwpn from
|
||||
that vHBA and optionally the scsi_host parent, setting this attribute to
|
||||
"yes" will allow libvirt to destroy the node device when the pool is
|
||||
destroyed. If this attribute is set to "no" or not defined in the XML,
|
||||
then libvirt will not destroy the vHBA. :since:`Since 1.2.11`
|
||||
|
||||
``parentaddr``
|
||||
Used by the "scsi_host" adapter type instead of the ``name`` attribute to
|
||||
more uniquely identify the SCSI host. Using a combination of the
|
||||
``unique_id`` attribute and the ``address`` element to formulate a PCI
|
||||
address, a search will be performed of the ``/sys/class/scsi_host/hostNN``
|
||||
links for a matching PCI address with a matching ``unique_id`` value in
|
||||
the ``/sys/class/scsi_host/hostNN/unique_id`` file. The value in the
|
||||
"unique_id" file will be unique enough for the specific PCI address. The
|
||||
``hostNN`` will be used by libvirt as the basis to define which SCSI host
|
||||
is to be used for the currently booted system. :since:`Since 1.2.7`
|
||||
|
||||
``address``
|
||||
The PCI address of the scsi_host device to be used. Using a PCI address
|
||||
provides consistent naming across system reboots and kernel reloads.
|
||||
The address will have four attributes: ``domain`` (a 2-byte hex
|
||||
integer, not currently used by qemu), ``bus`` (a hex value between 0
|
||||
and 0xff, inclusive), ``slot`` (a hex value between 0x0 and 0x1f,
|
||||
inclusive), and ``function`` (a value between 0 and 7, inclusive). The
|
||||
PCI address can be determined by listing the ``/sys/bus/pci/devices``
|
||||
and the ``/sys/class/scsi_host`` directories in order to find the
|
||||
expected scsi_host device. The address will be provided in a format
|
||||
such as "0000:00:1f:2" which can be used to generate the expected PCI
|
||||
address "domain='0x0000' bus='0x00' slot='0x1f' function='0x0'".
|
||||
Optionally, using the combination of the commands 'virsh nodedev-list
|
||||
scsi_host' and 'virsh nodedev-dumpxml' for a specific list entry and
|
||||
converting the resulting ``path`` element as the basis to formulate the
|
||||
correctly formatted PCI address.
|
||||
|
||||
``unique_id``
|
||||
Required ``parentaddr`` attribute used to determine which of the
|
||||
scsi_host adapters for the provided PCI address should be used. The
|
||||
value is determine by contents of the ``unique_id`` file for the
|
||||
specific scsi_host adapter. For a PCI address of "0000:00:1f:2", the
|
||||
unique identifier files can be found using the command
|
||||
``find -H /sys/class/scsi_host/host*/unique_id | xargs grep '[0-9]'``.
|
||||
Optionally, the ``virsh nodedev-dumpxml scsi_hostN``' of a specific
|
||||
scsi_hostN list entry will list the ``unique_id`` value.
|
||||
``host``
|
||||
Provides the source for pools backed by storage from a remote server (pool
|
||||
types ``netfs``, ``iscsi``, ``iscsi-direct``, ``rbd``, ``sheepdog``,
|
||||
``gluster``). Will be used in combination with a ``directory`` or ``device``
|
||||
element. Contains an attribute ``name`` which is the hostname or IP address
|
||||
of the server. May optionally contain a ``port`` attribute for the protocol
|
||||
specific port number. Duplicate storage pool definition checks may perform a
|
||||
cursory check that the same host name by string comparison in the new pool
|
||||
does not match an existing pool's source host name when combined with the
|
||||
``directory`` or ``device`` element. Name resolution of the provided hostname
|
||||
or IP address is left to the storage driver backend interactions with the
|
||||
remote server. See the `storage driver page <storage.html>`__ for any
|
||||
restrictions for specific storage backends. :since:`Since 0.4.1`
|
||||
``initiator``
|
||||
Required by the ``iscsi-direct`` pool in order to provide the iSCSI Qualified
|
||||
Name (IQN) to communicate with the pool's ``device`` target IQN. There is one
|
||||
sub-element ``iqn`` with the ``name`` attribute to describe the IQN for the
|
||||
initiator. :since:`Since 4.7.0`
|
||||
``auth``
|
||||
If present, the ``auth`` element provides the authentication credentials
|
||||
needed to access the source by the setting of the ``type`` attribute (pool
|
||||
types ``iscsi``, ``iscsi-direct``, ``rbd``). The ``type`` must be either
|
||||
"chap" or "ceph". Use "ceph" for Ceph RBD (Rados Block Device) network
|
||||
sources and use "iscsi" for CHAP (Challenge-Handshake Authentication
|
||||
Protocol) iSCSI targets. Additionally a mandatory attribute ``username``
|
||||
identifies the username to use during authentication as well as a sub-element
|
||||
``secret`` with a mandatory attribute ``type``, to tie back to a `libvirt
|
||||
secret object <formatsecret.html>`__ that holds the actual password or other
|
||||
credentials. The domain XML intentionally does not expose the password, only
|
||||
the reference to the object that manages the password. The ``secret`` element
|
||||
requires either a ``uuid`` attribute with the UUID of the secret object or a
|
||||
``usage`` attribute matching the key that was specified in the secret object.
|
||||
:since:`Since 0.9.7 for "ceph" and 1.1.1 for "chap"`
|
||||
``name``
|
||||
Provides the source for pools backed by storage from a named element (pool
|
||||
types ``logical``, ``rbd``, ``sheepdog``, ``gluster``). Contains a string
|
||||
identifier. :since:`Since 0.4.5`
|
||||
``format``
|
||||
Provides information about the format of the pool (pool types ``fs``,
|
||||
``netfs``, ``disk``, ``logical``). This contains a single attribute ``type``
|
||||
whose value is backend specific. This is typically used to indicate
|
||||
filesystem type, or network filesystem type, or partition table type, or LVM
|
||||
metadata type. All drivers are required to have a default value for this, so
|
||||
it is optional. :since:`Since 0.4.1`
|
||||
``protocol``
|
||||
For a ``netfs`` Storage Pool provide a mechanism to define which NFS protocol
|
||||
version number will be used to contact the server's NFS service. The
|
||||
attribute ``ver`` accepts an unsigned integer as the version number to use.
|
||||
:since:`Since 5.1.0`
|
||||
``vendor``
|
||||
Provides optional information about the vendor of the storage device. This
|
||||
contains a single attribute ``name`` whose value is backend specific.
|
||||
:since:`Since 0.8.4`
|
||||
``product``
|
||||
Provides an optional product name of the storage device. This contains a
|
||||
single attribute ``name`` whose value is backend specific. :since:`Since
|
||||
0.8.4`
|
||||
|
||||
Storage pool target elements
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A single ``target`` element is contained within the top level ``pool`` element
|
||||
for some types of pools (pool types ``dir``, ``fs``, ``netfs``, ``logical``,
|
||||
``disk``, ``iscsi``, ``scsi``, ``mpath``, ``zfs``). This tag is used to describe
|
||||
the mapping of the storage pool into the host filesystem. It can contain the
|
||||
following child elements:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<target>
|
||||
<path>/dev/disk/by-path</path>
|
||||
<permissions>
|
||||
<owner>107</owner>
|
||||
<group>107</group>
|
||||
<mode>0744</mode>
|
||||
<label>virt_image_t</label>
|
||||
</permissions>
|
||||
</target>
|
||||
</pool>
|
||||
|
||||
``path``
|
||||
Provides the location at which the pool will be mapped into the local
|
||||
filesystem namespace, as an absolute path. For a filesystem/directory based
|
||||
pool it will be a fully qualified name of the directory in which volumes will
|
||||
be created. For device based pools it will be a fully qualified name of the
|
||||
directory in which devices nodes exist. For the latter ``/dev/`` may seem
|
||||
like the logical choice, however, devices nodes there are not guaranteed
|
||||
stable across reboots, since they are allocated on demand. It is preferable
|
||||
to use a stable location such as one of the
|
||||
``/dev/disk/by-{path|id|uuid|label}`` locations. For ``logical`` and ``zfs``
|
||||
pool types, a provided value is ignored and a default path generated. For a
|
||||
Multipath pool (type ``mpath``), the provided value is ignored and the
|
||||
default value of "/dev/mapper" is used. :since:`Since 0.4.1`
|
||||
``permissions``
|
||||
This is currently only useful for directory or filesystem based pools, which
|
||||
are mapped as a directory into the local filesystem namespace. It provides
|
||||
information about the permissions to use for the final directory when the
|
||||
pool is built. There are 4 child elements. The ``mode`` element contains the
|
||||
octal permission set. The ``mode`` defaults to 0711 when not provided. The
|
||||
``owner`` element contains the numeric user ID. The ``group`` element
|
||||
contains the numeric group ID. If ``owner`` or ``group`` aren't specified
|
||||
when creating a directory, the UID and GID of the libvirtd process are used.
|
||||
The ``label`` element contains the MAC (eg SELinux) label string.
|
||||
:since:`Since 0.4.1` For running directory or filesystem based pools, these
|
||||
fields will be filled with the values used by the existing directory.
|
||||
:since:`Since 1.2.16`
|
||||
|
||||
Device extents
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
If a storage pool exposes information about its underlying placement /
|
||||
allocation scheme, the ``device`` element within the ``source`` element may
|
||||
contain information about its available extents. Some pools have a constraint
|
||||
that a volume must be allocated entirely within a single constraint (eg disk
|
||||
partition pools). Thus the extent information allows an application to determine
|
||||
the maximum possible size for a new volume
|
||||
|
||||
For storage pools supporting extent information, within each ``device`` element
|
||||
there will be zero or more ``freeExtent`` elements. Each of these elements
|
||||
contains two attributes, ``start`` and ``end`` which provide the boundaries of
|
||||
the extent on the device, measured in bytes. :since:`Since 0.4.1`
|
||||
|
||||
Refresh overrides
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The optional ``refresh`` element can control how the pool and associated volumes
|
||||
are refreshed (pool type ``rbd``). The ``allocation`` attribute of the
|
||||
``volume`` child element controls the method used for computing the allocation
|
||||
of a volume. The valid attribute values are ``default`` to compute the actual
|
||||
usage or ``capacity`` to use the logical capacity for cases where computing the
|
||||
allocation is too expensive. The following XML snippet shows the syntax:
|
||||
|
||||
::
|
||||
|
||||
<pool type="rbd">
|
||||
<name>myrbdpool</name>
|
||||
...
|
||||
<source/>
|
||||
...
|
||||
<refresh>
|
||||
<volume allocation='capacity'/>
|
||||
</refresh>
|
||||
...
|
||||
</pool>
|
||||
|
||||
:since:`Since 5.2.0`
|
||||
|
||||
Storage Pool Namespaces
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Usage of Storage Pool Namespaces provides a mechanism to provide pool type
|
||||
specific data in a free form or arbitrary manner via XML syntax targeted solely
|
||||
for the needs of the specific pool type which is not otherwise supported in
|
||||
standard XML. For the "fs" and "netfs" pool types this provides a mechanism to
|
||||
provide additional mount options on the command line. For the "rbd" pool this
|
||||
provides a mechanism to override default settings for RBD configuration options.
|
||||
|
||||
Usage of namespaces comes with no support guarantees. It is intended for
|
||||
developers testing out a concept prior to requesting an explicitly supported XML
|
||||
option in libvirt, and thus should never be used in production.
|
||||
|
||||
``fs:mount_opts``
|
||||
Provides an XML namespace mechanism to optionally utilize specifically named
|
||||
options for the mount command via the "-o" option for the ``fs`` or ``netfs``
|
||||
type storage pools. In order to designate that the Storage Pool will be using
|
||||
the mechanism, the ``pool`` element must be modified to provide the XML
|
||||
namespace attribute syntax as follows:
|
||||
|
||||
xmlns:fs='http://libvirt.org/schemas/storagepool/fs/1.0'
|
||||
|
||||
The ``fs:mount_opts`` defines the mount options by specifying multiple
|
||||
``fs:option`` subelements with the attribute ``name`` specifying the mount
|
||||
option to be added. The value of the named option is not checked since it's
|
||||
possible options don't exist on all distributions. It is expected that proper
|
||||
and valid options will be supplied for the target host.
|
||||
|
||||
The following XML snippet shows the syntax required in order to utilize for a
|
||||
netfs pool:
|
||||
|
||||
::
|
||||
|
||||
<pool type="netfs" xmlns:fs='http://libvirt.org/schemas/storagepool/fs/1.0'>
|
||||
<name>nfsimages</name>
|
||||
...
|
||||
<source>
|
||||
...
|
||||
</source>
|
||||
...
|
||||
<target>
|
||||
...
|
||||
</target>
|
||||
<fs:mount_opts>
|
||||
<fs:option name='sync'/>
|
||||
<fs:option name='lazytime'/>
|
||||
</fs:mount_opts>
|
||||
</pool>
|
||||
...
|
||||
|
||||
:since:`Since 5.1.0.`
|
||||
|
||||
``rbd:config_opts``
|
||||
Provides an XML namespace mechanism to optionally utilize specifically named
|
||||
options for the RBD configuration options via the rados_conf_set API for the
|
||||
``rbd`` type storage pools. In order to designate that the Storage Pool will
|
||||
be using the mechanism, the ``pool`` element must be modified to provide the
|
||||
XML namespace attribute syntax as follows:
|
||||
|
||||
xmlns:rbd='http://libvirt.org/schemas/storagepool/rbd/1.0'
|
||||
|
||||
The ``rbd:config_opts`` defines the configuration options by specifying
|
||||
multiple ``rbd:option`` subelements with the attribute ``name`` specifying
|
||||
the configuration option to be added and ``value`` specifying the
|
||||
configuration option value. The name and value for each option is only
|
||||
checked to be not empty. The name and value provided are not checked since
|
||||
it's possible options don't exist on all distributions. It is expected that
|
||||
proper and valid options will be supplied for the target host.
|
||||
|
||||
The following XML snippet shows the syntax required in order to utilize
|
||||
|
||||
::
|
||||
|
||||
<pool type="rbd" xmlns:rbd='http://libvirt.org/schemas/storagepool/rbd/1.0'>
|
||||
<name>myrbdpool</name>
|
||||
...
|
||||
<source>
|
||||
...
|
||||
</source>
|
||||
...
|
||||
<target>
|
||||
...
|
||||
</target>
|
||||
...
|
||||
<rbd:config_opts>
|
||||
<rbd:option name='client_mount_timeout' value='45'/>
|
||||
<rbd:option name='rados_mon_op_timeout' value='20'/>
|
||||
<rbd:option name='rados_osd_op_timeout' value='10'/>
|
||||
</rbd:config_opts>
|
||||
</pool>
|
||||
|
||||
:since:`Since 5.1.0.`
|
||||
|
||||
Storage volume XML
|
||||
------------------
|
||||
|
||||
A storage volume will generally be either a file or a device node; :since:`since
|
||||
1.2.0` , an optional output-only attribute ``type`` lists the actual type (file,
|
||||
block, dir, network, netdir or ploop), which is also available from
|
||||
``virStorageVolGetInfo()``. The storage volume XML format is available
|
||||
:since:`since 0.4.1`
|
||||
|
||||
Storage volume general metadata
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<volume type='file'>
|
||||
<name>sparse.img</name>
|
||||
<key>/var/lib/xen/images/sparse.img</key>
|
||||
<allocation>0</allocation>
|
||||
<capacity unit="T">1</capacity>
|
||||
...
|
||||
|
||||
``name``
|
||||
Providing a name for the volume which is unique to the pool. This is
|
||||
mandatory when defining a volume. For a disk pool, the name must be
|
||||
combination of the ``source`` device path device and next partition number to
|
||||
be created. For example, if the ``source`` device path is /dev/sdb and there
|
||||
are no partitions on the disk, then the name must be sdb1 with the next name
|
||||
being sdb2 and so on. :since:`Since 0.4.1`
|
||||
``key``
|
||||
Providing an identifier for the volume which identifies a single volume. In
|
||||
some cases it's possible to have two distinct keys identifying a single
|
||||
volume. This field cannot be set when creating a volume: it is always
|
||||
generated. :since:`Since 0.4.1`
|
||||
``allocation``
|
||||
Providing the total storage allocation for the volume. This may be smaller
|
||||
than the logical capacity if the volume is sparsely allocated. It may also be
|
||||
larger than the logical capacity if the volume has substantial metadata
|
||||
overhead. This value is in bytes. If omitted when creating a volume, the
|
||||
volume will be fully allocated at time of creation. If set to a value smaller
|
||||
than the capacity, the pool has the **option** of deciding to sparsely
|
||||
allocate a volume. It does not have to honour requests for sparse allocation
|
||||
though. Different types of pools may treat sparse volumes differently. For
|
||||
example, the ``logical`` pool will not automatically expand volume's
|
||||
allocation when it gets full; the user is responsible for doing that or
|
||||
configuring dmeventd to do so automatically.
|
||||
By default this is specified in bytes, but an optional attribute ``unit`` can
|
||||
be specified to adjust the passed value. Values can be: 'B' or 'bytes' for
|
||||
bytes, 'KB' (kilobytes, 10\ :sup:`3` or 1000 bytes), 'K' or 'KiB' (kibibytes,
|
||||
2\ :sup:`10` or 1024 bytes), 'MB' (megabytes, 10\ :sup:`6` or 1,000,000
|
||||
bytes), 'M' or 'MiB' (mebibytes, 2\ :sup:`20` or 1,048,576 bytes), 'GB'
|
||||
(gigabytes, 10\ :sup:`9` or 1,000,000,000 bytes), 'G' or 'GiB' (gibibytes,
|
||||
2\ :sup:`30` or 1,073,741,824 bytes), 'TB' (terabytes, 10\ :sup:`12` or
|
||||
1,000,000,000,000 bytes), 'T' or 'TiB' (tebibytes, 2\ :sup:`40` or
|
||||
1,099,511,627,776 bytes), 'PB' (petabytes, 10\ :sup:`15` or
|
||||
1,000,000,000,000,000 bytes), 'P' or 'PiB' (pebibytes, 2\ :sup:`50` or
|
||||
1,125,899,906,842,624 bytes), 'EB' (exabytes, 10\ :sup:`18` or
|
||||
1,000,000,000,000,000,000 bytes), or 'E' or 'EiB' (exbibytes, 2\ :sup:`60` or
|
||||
1,152,921,504,606,846,976 bytes). :since:`Since 0.4.1`, multi-character
|
||||
``unit`` :since:`since 0.9.11`.
|
||||
``capacity``
|
||||
Providing the logical capacity for the volume. This value is in bytes by
|
||||
default, but a ``unit`` attribute can be specified with the same semantics as
|
||||
for ``allocation`` This is compulsory when creating a volume. :since:`Since
|
||||
0.4.1`
|
||||
``physical``
|
||||
This output only element provides the host physical size of the target
|
||||
storage volume. The default output ``unit`` will be in bytes. :since:`Since
|
||||
3.0.0`
|
||||
``source``
|
||||
Provides information about the underlying storage allocation of the volume.
|
||||
This may not be available for some pool types. :since:`Since 0.4.1`
|
||||
``target``
|
||||
Provides information about the representation of the volume on the local
|
||||
host. :since:`Since 0.4.1`
|
||||
|
||||
Storage volume target elements
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A single ``target`` element is contained within the top level ``volume``
|
||||
element. This tag is used to describe the mapping of the storage volume into the
|
||||
host filesystem. It can contain the following child elements:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<target>
|
||||
<path>/var/lib/virt/images/sparse.img</path>
|
||||
<format type='qcow2'/>
|
||||
<permissions>
|
||||
<owner>107</owner>
|
||||
<group>107</group>
|
||||
<mode>0744</mode>
|
||||
<label>virt_image_t</label>
|
||||
</permissions>
|
||||
<timestamps>
|
||||
<atime>1341933637.273190990</atime>
|
||||
<mtime>1341930622.047245868</mtime>
|
||||
<ctime>1341930622.047245868</ctime>
|
||||
</timestamps>
|
||||
<encryption type='...'>
|
||||
...
|
||||
</encryption>
|
||||
<compat>1.1</compat>
|
||||
<nocow/>
|
||||
<clusterSize unit='KiB'>64</clusterSize>
|
||||
<features>
|
||||
<lazy_refcounts/>
|
||||
<extended_l2/>
|
||||
</features>
|
||||
</target>
|
||||
|
||||
``path``
|
||||
Provides the location at which the volume can be accessed on the local
|
||||
filesystem, as an absolute path. This is a readonly attribute, so shouldn't
|
||||
be specified when creating a volume. :since:`Since 0.4.1`
|
||||
``format``
|
||||
Provides information about the pool specific volume format. For disk pools it
|
||||
will provide the partition table format type, but is not preserved after a
|
||||
pool refresh or libvirtd restart. Use extended in order to create an extended
|
||||
disk extent partition. For filesystem or directory pools it will provide the
|
||||
file format type, eg cow, qcow, vmdk, raw. If omitted when creating a volume,
|
||||
the pool's default format will be used. The actual format is specified via
|
||||
the ``type`` attribute. Consult the `storage driver page <storage.html>`__
|
||||
for the list of valid volume format type values for each specific pool. The
|
||||
``format`` will be ignored on input for pools without a volume format type
|
||||
value and the default pool format will be used. :since:`Since 0.4.1`
|
||||
``permissions``
|
||||
Provides information about the permissions to use when creating volumes. This
|
||||
is currently only useful for directory or filesystem based pools, where the
|
||||
volumes allocated are simple files. For pools where the volumes are device
|
||||
nodes, the hotplug scripts determine permissions. There are 4 child elements.
|
||||
The ``mode`` element contains the octal permission set. The ``mode`` defaults
|
||||
to 0600 when not provided. The ``owner`` element contains the numeric user
|
||||
ID. The ``group`` element contains the numeric group ID. If ``owner`` or
|
||||
``group`` aren't specified when creating a supported volume, the UID and GID
|
||||
of the libvirtd process are used. The ``label`` element contains the MAC (eg
|
||||
SELinux) label string. For existing directory or filesystem based volumes,
|
||||
these fields will be filled with the values used by the existing file.
|
||||
:since:`Since 0.4.1`
|
||||
``timestamps``
|
||||
Provides timing information about the volume. Up to four sub-elements are
|
||||
present, where ``atime``, ``btime``, ``ctime`` and ``mtime`` hold the access,
|
||||
birth, change and modification time of the volume, where known. The used time
|
||||
format is <seconds>.<nanoseconds> since the beginning of the epoch (1 Jan
|
||||
1970). If nanosecond resolution is 0 or otherwise unsupported by the host OS
|
||||
or filesystem, then the nanoseconds part is omitted. This is a readonly
|
||||
attribute and is ignored when creating a volume. :since:`Since 0.10.0`
|
||||
``encryption``
|
||||
If present, specifies how the volume is encrypted. See the `Storage
|
||||
Encryption <formatstorageencryption.html>`__ page for more information.
|
||||
``compat``
|
||||
Specify compatibility level. So far, this is only used for ``type='qcow2'``
|
||||
volumes. Valid values are ``0.10`` and ``1.1`` so far, specifying QEMU
|
||||
version the images should be compatible with. If the ``feature`` element is
|
||||
present, 1.1 is used. :since:`Since 1.1.0` If omitted, 0.10 is used.
|
||||
:since:`Since 1.1.2`
|
||||
``nocow``
|
||||
Turn off COW of the newly created volume. So far, this is only valid for a
|
||||
file image in btrfs file system. It will improve performance when the file
|
||||
image is used in VM. To create non-raw file images, it requires QEMU version
|
||||
since 2.1. :since:`Since 1.2.7`
|
||||
``clusterSize``
|
||||
Changes the qcow2 cluster size which can affect image file size and
|
||||
performance. :since:`Since 7.4.0`
|
||||
``features``
|
||||
Format-specific features. Only used for ``qcow2`` now. Valid sub-elements
|
||||
are:
|
||||
|
||||
- ``<lazy_refcounts/>`` - allow delayed reference counter updates.
|
||||
:since:`Since 1.1.0`
|
||||
- ``<extended_l2/>`` - enables subcluster allocation for qcow2 images. QCOW2
|
||||
clusters are split into 32 subclusters decreasing the size of L2 cache
|
||||
needed. It's recommended to increase ``clusterSize``.
|
||||
|
||||
Backing store elements
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A single ``backingStore`` element is contained within the top level ``volume``
|
||||
element. This tag is used to describe the optional copy on write, backing store
|
||||
for the storage volume. It can contain the following child elements:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
<backingStore>
|
||||
<path>/var/lib/virt/images/master.img</path>
|
||||
<format type='raw'/>
|
||||
<permissions>
|
||||
<owner>107</owner>
|
||||
<group>107</group>
|
||||
<mode>0744</mode>
|
||||
<label>virt_image_t</label>
|
||||
</permissions>
|
||||
</backingStore>
|
||||
</volume>
|
||||
|
||||
``path``
|
||||
Provides the location at which the backing store can be accessed on the local
|
||||
filesystem, as an absolute path. If omitted, there is no backing store for
|
||||
this volume. :since:`Since 0.6.0`
|
||||
``format``
|
||||
Provides information about the pool specific backing store format. For disk
|
||||
pools it will provide the partition type. For filesystem or directory pools
|
||||
it will provide the file format type, eg cow, qcow, vmdk, raw. The actual
|
||||
format is specified via the type attribute. Consult the pool-specific docs
|
||||
for the list of valid values. Most file formats require a backing store of
|
||||
the same format, however, the qcow2 format allows a different backing store
|
||||
format. :since:`Since 0.6.0`
|
||||
``permissions``
|
||||
Provides information about the permissions of the backing file. See volume
|
||||
``permissions`` documentation for explanation of individual fields.
|
||||
:since:`Since 0.6.0`
|
||||
|
||||
Example configuration
|
||||
---------------------
|
||||
|
||||
Here are a couple of examples, for a more complete set demonstrating every type
|
||||
of storage pool, consult the `storage driver page <storage.html>`__
|
||||
|
||||
File based storage pool
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<pool type="dir">
|
||||
<name>virtimages</name>
|
||||
<target>
|
||||
<path>/var/lib/virt/images</path>
|
||||
</target>
|
||||
</pool>
|
||||
|
||||
iSCSI based storage pool
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<pool type="iscsi">
|
||||
<name>virtimages</name>
|
||||
<source>
|
||||
<host name="iscsi.example.com"/>
|
||||
<device path="iqn.2013-06.com.example:iscsi-pool"/>
|
||||
<auth type='chap' username='myuser'>
|
||||
<secret usage='libvirtiscsi'/>
|
||||
</auth>
|
||||
</source>
|
||||
<target>
|
||||
<path>/dev/disk/by-path</path>
|
||||
</target>
|
||||
</pool>
|
||||
|
||||
Storage volume
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<volume>
|
||||
<name>sparse.img</name>
|
||||
<allocation>0</allocation>
|
||||
<capacity unit="T">1</capacity>
|
||||
<target>
|
||||
<path>/var/lib/virt/images/sparse.img</path>
|
||||
<permissions>
|
||||
<owner>107</owner>
|
||||
<group>107</group>
|
||||
<mode>0744</mode>
|
||||
<label>virt_image_t</label>
|
||||
</permissions>
|
||||
</target>
|
||||
</volume>
|
||||
|
||||
Storage volume using LUKS
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
<volume>
|
||||
<name>MyLuks.img</name>
|
||||
<capacity unit="G">5</capacity>
|
||||
<target>
|
||||
<path>/var/lib/virt/images/MyLuks.img</path>
|
||||
<format type='raw'/>
|
||||
<encryption format='luks'>
|
||||
<secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/>
|
||||
</encryption>
|
||||
</target>
|
||||
</volume>
|
|
@ -0,0 +1,79 @@
|
|||
.. role:: since
|
||||
|
||||
====================================
|
||||
Storage Pool Capabilities XML format
|
||||
====================================
|
||||
|
||||
.. contents::
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The Storage Pool Capabilities XML will provide the information to determine what
|
||||
types of Storage Pools exist, whether the pool is supported, and if relevant the
|
||||
source format types, the required source elements, and the target volume format
|
||||
types.
|
||||
|
||||
Element and attribute overview
|
||||
------------------------------
|
||||
|
||||
A query interface was added to the virConnect API's to retrieve the XML listing
|
||||
of the set of Storage Pool Capabilities ( :since:`Since 5.2.0` ):
|
||||
|
||||
``virConnectGetStoragePoolCapabilities`` (`API docs <html/libvirt-libvirt-storage.html#virConnectGetStoragePoolCapabilities>`__)
|
||||
|
||||
The root element that emulator capability XML document starts with is named
|
||||
``storagepoolCapabilities``. There will be any number of ``pool`` child elements
|
||||
with two attributes ``type`` and ``supported``. Each ``pool`` element may have a
|
||||
``poolOptions`` or ``volOptions`` subelements to describe the available
|
||||
features. Sample XML output is:
|
||||
|
||||
::
|
||||
|
||||
<storagepoolCapabilities>
|
||||
<pool type='dir' supported='yes'>
|
||||
<volOptions>
|
||||
<defaultFormat type='raw'</>
|
||||
<enum name='targetFormatType'>
|
||||
<value>none</value>
|
||||
<value>raw</value>
|
||||
...
|
||||
</enum>
|
||||
</volOptions>
|
||||
</pool>
|
||||
<pool type='fs' supported='yes'>
|
||||
<poolOptions>
|
||||
<defaultFormat type='auto'</>
|
||||
<enum name='sourceFormatType'>
|
||||
<value>auto</value>
|
||||
<value>ext2</value>
|
||||
...
|
||||
</enum>
|
||||
</poolOptions>
|
||||
<volOptions>
|
||||
<defaultFormat type='raw'</>
|
||||
<enum name='targetFormatType'>
|
||||
<value>none</value>
|
||||
<value>raw</value>
|
||||
...
|
||||
</enum>
|
||||
</volOptions>
|
||||
</pool>
|
||||
...
|
||||
</storagepoolCapabilities>
|
||||
|
||||
The following section describes subelements of the ``poolOptions`` and
|
||||
``volOptions`` subelements
|
||||
|
||||
``defaultFormat``
|
||||
For the ``poolOptions``, the ``type`` attribute describes the default format
|
||||
name used for the pool source. For the ``volOptions``, the ``type`` attribute
|
||||
describes the default volume name used for each volume.
|
||||
``enum``
|
||||
Each enum uses a name from the list below with any number of ``value`` value
|
||||
subelements describing the valid values.
|
||||
|
||||
``sourceFormatType``
|
||||
Lists all the possible ``poolOptions`` source pool format types.
|
||||
``targetFormatType``
|
||||
Lists all the possible ``volOptions`` target volume format types.
|
|
@ -0,0 +1,139 @@
|
|||
.. role:: since
|
||||
|
||||
====================================
|
||||
Storage volume encryption XML format
|
||||
====================================
|
||||
|
||||
.. contents::
|
||||
|
||||
Storage volume encryption XML
|
||||
-----------------------------
|
||||
|
||||
Storage volumes may be encrypted, the XML snippet described below is used to
|
||||
represent the details of the encryption. It can be used as a part of a domain or
|
||||
storage configuration.
|
||||
|
||||
The top-level tag of volume encryption specification is ``encryption``, with a
|
||||
mandatory attribute ``format``. Currently defined values of ``format`` are
|
||||
``default``, ``qcow``, ``luks``, and ``luks2``. Each value of ``format`` implies
|
||||
some expectations about the content of the ``encryption`` tag. Other format
|
||||
values may be defined in the future.
|
||||
|
||||
The ``encryption`` tag supports an optional ``engine`` tag, which allows
|
||||
selecting which component actually handles the encryption. Currently defined
|
||||
values of ``engine`` are ``qemu`` and ``librbd``. Both ``qemu`` and ``librbd``
|
||||
require using the qemu driver. The ``librbd`` engine requires qemu version >=
|
||||
6.1.0, both ceph cluster and librbd1 >= 16.1.0, and is only applicable for RBD
|
||||
network disks. If the engine tag is not specified, the ``qemu`` engine will be
|
||||
used by default (assuming the qemu driver is used). Note that ``librbd`` engine
|
||||
is currently only supported by the qemu VM driver, and is not supported by the
|
||||
storage driver. Furthermore, the storage driver currently ignores the ``engine``
|
||||
tag.
|
||||
|
||||
The ``encryption`` tag can currently contain a sequence of ``secret`` tags, each
|
||||
with mandatory attributes ``type`` and either ``uuid`` or ``usage`` (
|
||||
:since:`since 2.1.0` ). The only currently defined value of ``type`` is
|
||||
``volume``. The ``uuid`` is "uuid" of the ``secret`` while ``usage`` is the
|
||||
"usage" subelement field. A secret value can be set in libvirt by the
|
||||
`virSecretSetValue <html/libvirt-libvirt-secret.html#virSecretSetValue>`__ API.
|
||||
Alternatively, if supported by the particular volume format and driver,
|
||||
automatically generate a secret value at the time of volume creation, and store
|
||||
it using the specified ``uuid``.
|
||||
|
||||
``qcow`` format
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
:since:`Since 4.5.0,` encryption formats ``default`` and ``qcow`` may no longer
|
||||
be used to create an encrypted volume. Usage of qcow encrypted volumes in QEMU
|
||||
began phasing out in QEMU 2.3 and by QEMU 2.9 creation of a qcow encrypted
|
||||
volume via qemu-img required usage of secret objects, but that support was not
|
||||
added to libvirt.
|
||||
|
||||
``luks`` format
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The ``luks`` format is specific to a luks encrypted volume and the secret is
|
||||
used in order to either encrypt during volume creation or decrypt the volume for
|
||||
usage by the domain. A single ``<secret type='passphrase'...>`` element is
|
||||
expected. :since:`Since 2.1.0` .
|
||||
|
||||
For volume creation, it is possible to specify the encryption algorithm used to
|
||||
encrypt the luks volume. The following two optional elements may be provided for
|
||||
that purpose. It is hypervisor dependent as to which algorithms are supported.
|
||||
The default algorithm used by the storage driver backend when using qemu-img to
|
||||
create the volume is 'aes-256-cbc' using 'essiv' for initialization vector
|
||||
generation and 'sha256' hash algorithm for both the cipher and the
|
||||
initialization vector generation.
|
||||
|
||||
``cipher``
|
||||
This element describes the cipher algorithm to be used to either encrypt or
|
||||
decrypt the luks volume. This element has the following attributes:
|
||||
|
||||
``name``
|
||||
The name of the cipher algorithm used for data encryption, such as 'aes',
|
||||
'des', 'cast5', 'serpent', 'twofish', etc. Support of the specific
|
||||
algorithm is storage driver implementation dependent.
|
||||
``size``
|
||||
The size of the cipher in bits, such as '256', '192', '128', etc. Support
|
||||
of the specific size for a specific cipher is hypervisor dependent.
|
||||
``mode``
|
||||
An optional cipher algorithm mode such as 'cbc', 'xts', 'ecb', etc.
|
||||
Support of the specific cipher mode is hypervisor dependent.
|
||||
``hash``
|
||||
An optional master key hash algorithm such as 'md5', 'sha1', 'sha256',
|
||||
etc. Support of the specific hash algorithm is hypervisor dependent.
|
||||
``ivgen``
|
||||
This optional element describes the initialization vector generation
|
||||
algorithm used in conjunction with the ``cipher``. If the ``cipher`` is not
|
||||
provided, then an error will be generated by the parser.
|
||||
|
||||
``name``
|
||||
The name of the algorithm, such as 'plain', 'plain64', 'essiv', etc.
|
||||
Support of the specific algorithm is hypervisor dependent.
|
||||
``hash``
|
||||
An optional hash algorithm such as 'md5', 'sha1', 'sha256', etc. Support
|
||||
of the specific ivgen hash algorithm is hypervisor dependent.
|
||||
|
||||
``luks2`` format
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``luks2`` format is currently supported only by the ``librbd`` engine, and
|
||||
can only be applied to RBD network disks (RBD images). Since the ``librbd``
|
||||
engine is currently not supported by the libvirt storage driver, you cannot use
|
||||
it to control such disks. However, pre-formatted RBD luks2 disks can be loaded
|
||||
to a qemu VM using the qemu VM driver. A single
|
||||
``<secret type='passphrase'...>`` element is expected.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Assuming a `luks volume type secret <formatsecret.html#usage-type-volume>`__ is
|
||||
already defined, a simple example specifying use of the ``luks`` format for
|
||||
either volume creation without a specific cipher being defined or as part of a
|
||||
domain volume definition:
|
||||
|
||||
::
|
||||
|
||||
<encryption format='luks'>
|
||||
<secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/>
|
||||
</encryption>
|
||||
|
||||
Here is an example specifying use of the ``luks`` format for a specific cipher
|
||||
algorithm for volume creation. :since:`Since 6.10.0,` the ``target`` format can
|
||||
also support ``qcow2`` type with ``luks`` encryption.
|
||||
|
||||
::
|
||||
|
||||
<volume>
|
||||
<name>twofish.luks</name>
|
||||
<capacity unit='G'>5</capacity>
|
||||
<target>
|
||||
<path>/var/lib/libvirt/images/demo.luks</path>
|
||||
<format type='raw'/>
|
||||
<encryption format='luks'>
|
||||
<secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/>
|
||||
<cipher name='twofish' size='256' mode='cbc' hash='sha256'/>
|
||||
<ivgen name='plain64' hash='sha256'/>
|
||||
</encryption>
|
||||
</target>
|
||||
</volume>
|
|
@ -0,0 +1,54 @@
|
|||
=====================
|
||||
Adoption of GLib APIs
|
||||
=====================
|
||||
|
||||
Libvirt has adopted use of the `GLib
|
||||
library <https://developer.gnome.org/glib/stable/>`__. Due to
|
||||
libvirt's long history of development, there are many APIs in
|
||||
libvirt, for which GLib provides an alternative solution. The
|
||||
general rule to follow is that the standard GLib solution will be
|
||||
preferred over historical libvirt APIs. Existing code will be
|
||||
ported over to use GLib APIs over time, but new code should use
|
||||
the GLib APIs straight away where possible.
|
||||
|
||||
The following is a list of libvirt APIs that should no longer be
|
||||
used in new code, and their suggested GLib replacements:
|
||||
|
||||
Memory allocation
|
||||
``VIR_ALLOC``, ``VIR_REALLOC``, ``VIR_RESIZE_N``,
|
||||
``VIR_EXPAND_N``, ``VIR_SHRINK_N``, ``VIR_FREE``
|
||||
|
||||
https://developer.gnome.org/glib/stable/glib-Memory-Allocation.html
|
||||
|
||||
Prefer the GLib APIs ``g_new0``/``g_renew``/ ``g_free`` in most
|
||||
cases. There should rarely be a need to use
|
||||
``g_malloc``/``g_realloc``. **NEVER MIX** use of the classic
|
||||
libvirt memory allocation APIs and GLib APIs within a single
|
||||
method. Keep the style consistent, converting existing code to
|
||||
GLib style in a separate, prior commit.
|
||||
|
||||
Array operations
|
||||
``VIR_APPEND_ELEMENT``, ``VIR_INSERT_ELEMENT``, ``VIR_DELETE_ELEMENT``
|
||||
|
||||
https://developer.gnome.org/glib/stable/glib-Arrays.html
|
||||
|
||||
Instead of using plain C arrays, it is preferrable to use one of
|
||||
the GLib types, ``GArray``, ``GPtrArray`` or ``GByteArray``.
|
||||
These all use a struct to track the array memory and size
|
||||
together and efficiently resize.
|
||||
|
||||
String arrays
|
||||
``virStringList*``, ``virStringListCount*``
|
||||
|
||||
https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html
|
||||
|
||||
Prefer the NULL-terminated variant instead of storing the count
|
||||
separately. Prefer ``g_str*v`` functions instead of their ``vir*``
|
||||
counterparts. For use with ``g_auto`` GLib provides the ``GStrv`` type.
|
||||
|
||||
Objects
|
||||
``virObject``
|
||||
|
||||
https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html
|
||||
|
||||
Prefer ``GObject`` instead.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue