Browse Source

PageUP/PageDown features

master
Doug Le Tough 4 years ago
parent
commit
247121c89c
338 changed files with 60121 additions and 78 deletions
  1. BIN
      Application_Development_Guide.pdf
  2. +6
    -0
      engine/__init__.py
  3. BIN
      external_docs/libvirt.org.tar.gz
  4. BIN
      external_docs/libvirt.org/32favicon.png
  5. +203
    -0
      external_docs/libvirt.org/acl.html
  6. +327
    -0
      external_docs/libvirt.org/aclpolkit.html
  7. +402
    -0
      external_docs/libvirt.org/api.html
  8. +464
    -0
      external_docs/libvirt.org/api_extension.html
  9. +145
    -0
      external_docs/libvirt.org/api_extension/0001-add-to-xml.patch
  10. +62
    -0
      external_docs/libvirt.org/api_extension/0002-add-new-public-API.patch
  11. +222
    -0
      external_docs/libvirt.org/api_extension/0003-define-internal-driver-API.patch
  12. +188
    -0
      external_docs/libvirt.org/api_extension/0004-implement-the-public-APIs.patch
  13. +421
    -0
      external_docs/libvirt.org/api_extension/0005-implement-the-remote-protocol.patch
  14. +735
    -0
      external_docs/libvirt.org/api_extension/0006-make-old-API-trivially-wrap-to-new-API.patch
  15. +388
    -0
      external_docs/libvirt.org/api_extension/0007-add-virsh-support.patch
  16. +519
    -0
      external_docs/libvirt.org/api_extension/0008-support-new-xml.patch
  17. +197
    -0
      external_docs/libvirt.org/api_extension/0009-support-all-flags-in-test-driver.patch
  18. +122
    -0
      external_docs/libvirt.org/api_extension/0010-improve-vcpu-support-in-qemu-command-line.patch
  19. +169
    -0
      external_docs/libvirt.org/api_extension/0011-complete-vcpu-support-in-qemu-driver.patch
  20. +294
    -0
      external_docs/libvirt.org/api_extension/0012-improve-vcpu-support-in-xen-command-line.patch
  21. +216
    -0
      external_docs/libvirt.org/api_extension/0013-improve-getting-xen-vcpu-counts.patch
  22. +342
    -0
      external_docs/libvirt.org/api_extension/0014-improve-setting-xen-vcpu-counts.patch
  23. +228
    -0
      external_docs/libvirt.org/api_extension/0015-remove-dead-xen-code.patch
  24. +462
    -0
      external_docs/libvirt.org/apps.html
  25. +156
    -0
      external_docs/libvirt.org/archdomain.html
  26. +204
    -0
      external_docs/libvirt.org/archnetwork.html
  27. +156
    -0
      external_docs/libvirt.org/archnode.html
  28. +175
    -0
      external_docs/libvirt.org/archstorage.html
  29. +303
    -0
      external_docs/libvirt.org/auditlog.html
  30. +364
    -0
      external_docs/libvirt.org/auth.html
  31. +136
    -0
      external_docs/libvirt.org/bindings.html
  32. +210
    -0
      external_docs/libvirt.org/bugs.html
  33. +486
    -0
      external_docs/libvirt.org/cgroups.html
  34. +190
    -0
      external_docs/libvirt.org/compiling.html
  35. +149
    -0
      external_docs/libvirt.org/contact.html
  36. +201
    -0
      external_docs/libvirt.org/contribute.html
  37. +202
    -0
      external_docs/libvirt.org/csharp.html
  38. +228
    -0
      external_docs/libvirt.org/deployment.html
  39. +91
    -0
      external_docs/libvirt.org/devguide.html
  40. +116
    -0
      external_docs/libvirt.org/docs.html
  41. +1467
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/css/common.css
  42. +3
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/css/default.css
  43. +2
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/css/lang.css
  44. +38
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/css/overrides.css
  45. +16
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/css/print.css
  46. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/dot.png
  47. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/dot2.png
  48. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/h1-bg.png
  49. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/image_left.png
  50. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/image_right.png
  51. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/important.png
  52. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/note.png
  53. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/shine.png
  54. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/stock-go-back.png
  55. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/stock-go-forward.png
  56. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/stock-go-up.png
  57. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/stock-home.png
  58. +851
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/title_logo.svg
  59. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/warning.png
  60. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/Common_Content/images/watermark-draft.png
  61. +20
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s02.html
  62. +118
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s03.html
  63. +26
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s04.html
  64. +19
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s05.html
  65. +26
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s06.html
  66. +20
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s07.html
  67. +20
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s08.html
  68. +19
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s09.html
  69. +19
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s10.html
  70. +21
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s11.html
  71. +36
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s12.html
  72. +21
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s13.html
  73. +29
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s14.html
  74. +22
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s15.html
  75. +22
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s16.html
  76. +21
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s17.html
  77. +21
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s18.html
  78. +22
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s19.html
  79. +26
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s20.html
  80. +22
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch03s04s21.html
  81. +21
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch07s04s03.html
  82. +21
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch07s04s04.html
  83. +21
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ch07s04s05.html
  84. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/images/159516-libvirt-driver-arch.png
  85. BIN
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/images/guest-state-transition.png
  86. +20
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/index.html
  87. +3
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/ix01.html
  88. +43
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Architecture-Authentication.html
  89. +25
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Architecture-Driver_Model.html
  90. +11
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Architecture-Remote_Management.html
  91. +115
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Architecture-TLS_Cert.html
  92. +63
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Architecture-Transports.html
  93. +67
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Architecture.html
  94. +222
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Connections-Capability_Info_Methods.html
  95. +22
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Connections-Host_Info.html
  96. +210
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Connections-Remote_URIs.html
  97. +135
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Connections-URI_Formats.html
  98. +109
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Connections.html
  99. +64
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Debug.html
  100. +42
    -0
      external_docs/libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/libvirt_application_development_guide_using_python-Error_Handling-Registering_Error_Handler.html

BIN
Application_Development_Guide.pdf View File


+ 6
- 0
engine/__init__.py View File

@ -19,6 +19,7 @@ class Engine(object):
self.network_filters = self.get_network_filters()
self.interfaces = self.get_interfaces()
self.secrets = self.get_secrets()
self.devices = self.get_devices()
def connect(self):
self.connection = libvirt.open('%s%s' % (self.protocol, self.host))
@ -142,6 +143,11 @@ class Engine(object):
volumes.append(volume)
return volumes
def get_devices(self):
self.connect()
devices = self.connection.listAllDevices()
return devices
def debug(self):
debug = 80 * '*'+'\n'
debug += 80 * '*'+'\n'


BIN
external_docs/libvirt.org.tar.gz View File


BIN
external_docs/libvirt.org/32favicon.png View File

Before After
Width: 32  |  Height: 32  |  Size: 783 B

+ 203
- 0
external_docs/libvirt.org/acl.html
File diff suppressed because it is too large
View File


+ 327
- 0
external_docs/libvirt.org/aclpolkit.html View File

@ -0,0 +1,327 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
This file is autogenerated from aclpolkit.html.in
Do not edit this file. Changes will be lost.
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="main.css" />
<link rel="SHORTCUT ICON" href="32favicon.png" />
<title>libvirt: Polkit access control</title>
<meta name="description" content="libvirt, virtualization, virtualization API" />
</head>
<body>
<div id="body">
<div id="content">
<h1>Polkit access control</h1>
<p>
Libvirt's client <a href="acl.html" shape="rect">access control framework</a> 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.
</p>
<ul><li>
<a href="#intro">Introduction</a>
</li><li>
<a href="#perms">Permission names</a>
</li><li>
<a href="#attrs">Object identity attributes</a>
<ul><li>
<a href="#object_connect">virConnectPtr</a>
</li><li>
<a href="#object_domain">virDomainPtr</a>
</li><li>
<a href="#object_interface">virInterfacePtr</a>
</li><li>
<a href="#object_network">virNetworkPtr</a>
</li><li>
<a href="#object_node_device">virNodeDevicePtr</a>
</li><li>
<a href="#object_nwfilter">virNWFilterPtr</a>
</li><li>
<a href="#object_secret">virSecretPtr</a>
</li><li>
<a href="#object_storage_pool">virStoragePoolPtr</a>
</li><li>
<a href="#object_storage_vol">virStorageVolPtr</a>
</li></ul>
</li><li>
<a href="#user">User identity attributes</a>
</li><li>
<a href="#checks">Writing access control policies</a>
<ul><li>
<a href="#exconnect">Example: restricting ability to connect to drivers</a>
</li><li>
<a href="#exdomain">Example: restricting access to a single domain</a>
</li></ul>
</li></ul>
<h2>
<a name="intro" shape="rect" id="intro">Introduction</a>
<a class="headerlink" href="#intro" title="Permalink to this headline"></a>
</h2>
<p>
A default install of libvirt will typically use
<a href="http://www.freedesktop.org/wiki/Software/polkit/" shape="rect">polkit</a>
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.
</p>
<h2>
<a name="perms" shape="rect" id="perms">Permission names</a>
<a class="headerlink" href="#perms" title="Permalink to this headline"></a>
</h2>
<p>
The libvirt <a href="acl.html#perms" shape="rect">object names and permission names</a>
are mapped onto polkit action names using the simple pattern:
</p>
<pre xml:space="preserve">org.libvirt.api.$object.$permission
</pre>
<p>
The only caveat is that any underscore characters in the
object or permission names are converted to hyphens. So,
for example, the <code>search_storage_vols</code> permission
on the <code>storage_pool</code> object maps to the polkit
action:
</p>
<pre xml:space="preserve">org.libvirt.api.storage-pool.search-storage-vols
</pre>
<p>
The default policy for any permission which corresponds to
a "read only" operation, is to allow access. All other
permissions default to deny access.
</p>
<h2>
<a name="attrs" shape="rect" id="attrs">Object identity attributes</a>
<a class="headerlink" href="#attrs" title="Permalink to this headline"></a>
</h2>
<p>
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
</p>
<h3>
<a name="object_connect" shape="rect" id="object_connect">virConnectPtr</a>
<a class="headerlink" href="#object_connect" title="Permalink to this headline"></a>
</h3>
<table class="acl"><thead><tr><th rowspan="1" colspan="1">Attribute</th><th rowspan="1" colspan="1">Description</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">connect_driver</td><td rowspan="1" colspan="1">Name of the libvirt connection driver</td></tr></tbody></table>
<h3>
<a name="object_domain" shape="rect" id="object_domain">virDomainPtr</a>
<a class="headerlink" href="#object_domain" title="Permalink to this headline"></a>
</h3>
<table class="acl"><thead><tr><th rowspan="1" colspan="1">Attribute</th><th rowspan="1" colspan="1">Description</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">connect_driver</td><td rowspan="1" colspan="1">Name of the libvirt connection driver</td></tr><tr><td rowspan="1" colspan="1">domain_name</td><td rowspan="1" colspan="1">Name of the domain, unique to the local host</td></tr><tr><td rowspan="1" colspan="1">domain_uuid</td><td rowspan="1" colspan="1">UUID of the domain, globally unique</td></tr></tbody></table>
<h3>
<a name="object_interface" shape="rect" id="object_interface">virInterfacePtr</a>
<a class="headerlink" href="#object_interface" title="Permalink to this headline"></a>
</h3>
<table class="acl"><thead><tr><th rowspan="1" colspan="1">Attribute</th><th rowspan="1" colspan="1">Description</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">connect_driver</td><td rowspan="1" colspan="1">Name of the libvirt connection driver</td></tr><tr><td rowspan="1" colspan="1">interface_name</td><td rowspan="1" colspan="1">Name of the network interface, unique to the local host</td></tr><tr><td rowspan="1" colspan="1">interface_macaddr</td><td rowspan="1" colspan="1">MAC address of the network interface, not unique</td></tr></tbody></table>
<h3>
<a name="object_network" shape="rect" id="object_network">virNetworkPtr</a>
<a class="headerlink" href="#object_network" title="Permalink to this headline"></a>
</h3>
<table class="acl"><thead><tr><th rowspan="1" colspan="1">Attribute</th><th rowspan="1" colspan="1">Description</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">connect_driver</td><td rowspan="1" colspan="1">Name of the libvirt connection driver</td></tr><tr><td rowspan="1" colspan="1">network_name</td><td rowspan="1" colspan="1">Name of the network, unique to the local host</td></tr><tr><td rowspan="1" colspan="1">network_uuid</td><td rowspan="1" colspan="1">UUID of the network, globally unique</td></tr></tbody></table>
<h3>
<a name="object_node_device" shape="rect" id="object_node_device">virNodeDevicePtr</a>
<a class="headerlink" href="#object_node_device" title="Permalink to this headline"></a>
</h3>
<table class="acl"><thead><tr><th rowspan="1" colspan="1">Attribute</th><th rowspan="1" colspan="1">Description</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">connect_driver</td><td rowspan="1" colspan="1">Name of the libvirt connection driver</td></tr><tr><td rowspan="1" colspan="1">node_device_name</td><td rowspan="1" colspan="1">Name of the node device, unique to the local host</td></tr></tbody></table>
<h3>
<a name="object_nwfilter" shape="rect" id="object_nwfilter">virNWFilterPtr</a>
<a class="headerlink" href="#object_nwfilter" title="Permalink to this headline"></a>
</h3>
<table class="acl"><thead><tr><th rowspan="1" colspan="1">Attribute</th><th rowspan="1" colspan="1">Description</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">connect_driver</td><td rowspan="1" colspan="1">Name of the libvirt connection driver</td></tr><tr><td rowspan="1" colspan="1">nwfilter_name</td><td rowspan="1" colspan="1">Name of the network filter, unique to the local host</td></tr><tr><td rowspan="1" colspan="1">nwfilter_uuid</td><td rowspan="1" colspan="1">UUID of the network filter, globally unique</td></tr></tbody></table>
<h3>
<a name="object_secret" shape="rect" id="object_secret">virSecretPtr</a>
<a class="headerlink" href="#object_secret" title="Permalink to this headline"></a>
</h3>
<table class="acl"><thead><tr><th rowspan="1" colspan="1">Attribute</th><th rowspan="1" colspan="1">Description</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">connect_driver</td><td rowspan="1" colspan="1">Name of the libvirt connection driver</td></tr><tr><td rowspan="1" colspan="1">secret_uuid</td><td rowspan="1" colspan="1">UUID of the secret, globally unique</td></tr><tr><td rowspan="1" colspan="1">secret_usage_volume</td><td rowspan="1" colspan="1">Name of the associated volume, if any</td></tr><tr><td rowspan="1" colspan="1">secret_usage_ceph</td><td rowspan="1" colspan="1">Name of the associated Ceph server, if any</td></tr><tr><td rowspan="1" colspan="1">secret_usage_target</td><td rowspan="1" colspan="1">Name of the associated iSCSI target, if any</td></tr><tr><td rowspan="1" colspan="1">secret_usage_name</td><td rowspan="1" colspan="1">Name of the associated TLS secret, if any</td></tr></tbody></table>
<h3>
<a name="object_storage_pool" shape="rect" id="object_storage_pool">virStoragePoolPtr</a>
<a class="headerlink" href="#object_storage_pool" title="Permalink to this headline"></a>
</h3>
<table class="acl"><thead><tr><th rowspan="1" colspan="1">Attribute</th><th rowspan="1" colspan="1">Description</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">connect_driver</td><td rowspan="1" colspan="1">Name of the libvirt connection driver</td></tr><tr><td rowspan="1" colspan="1">pool_name</td><td rowspan="1" colspan="1">Name of the storage pool, unique to the local host</td></tr><tr><td rowspan="1" colspan="1">pool_uuid</td><td rowspan="1" colspan="1">UUID of the storage pool, globally unique</td></tr></tbody></table>
<h3>
<a name="object_storage_vol" shape="rect" id="object_storage_vol">virStorageVolPtr</a>
<a class="headerlink" href="#object_storage_vol" title="Permalink to this headline"></a>
</h3>
<table class="acl"><thead><tr><th rowspan="1" colspan="1">Attribute</th><th rowspan="1" colspan="1">Description</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">connect_driver</td><td rowspan="1" colspan="1">Name of the libvirt connection driver</td></tr><tr><td rowspan="1" colspan="1">pool_name</td><td rowspan="1" colspan="1">Name of the storage pool, unique to the local host</td></tr><tr><td rowspan="1" colspan="1">pool_uuid</td><td rowspan="1" colspan="1">UUID of the storage pool, globally unique</td></tr><tr><td rowspan="1" colspan="1">vol_name</td><td rowspan="1" colspan="1">Name of the storage volume, unique to the pool</td></tr><tr><td rowspan="1" colspan="1">vol_key</td><td rowspan="1" colspan="1">Key of the storage volume, globally unique</td></tr></tbody></table>
<h2>
<a name="user" shape="rect" id="user">User identity attributes</a>
<a class="headerlink" href="#user" title="Permalink to this headline"></a>
</h2>
<p>
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.
</p>
<h2>
<a name="checks" shape="rect" id="checks">Writing access control policies</a>
<a class="headerlink" href="#checks" title="Permalink to this headline"></a>
</h2>
<p>
If using versions of polkit prior to 0.106 then it is only
possible to validate (user, permission) pairs via the <code>.pkla</code>
files. Fully validation of the (user, permission, object) triple
requires the new JavaScript <code>.rules</code> support that
was introduced in version 0.106. The latter is what will be
described here.
</p>
<p>
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
<code>/etc/polkit-1/rules.d</code> directory with a name
chosen by the administrator (<code>100-libvirt-acl.rules</code>
would be a reasonable choice). See the <code>polkit(8)</code>
manual page for a description of how to write these files
in general. The key idea is to create a file containing
something like
</p>
<pre xml:space="preserve">
polkit.addRule(function(action, subject) {
....logic to check 'action' and 'subject'...
});
</pre>
<p>
In this code snippet above, the <code>action</code> object
instance will represent the libvirt permission being checked
along with identifying attributes for the object it is being
applied to. The <code>subject</code> 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 <code>action</code> object, the permission name is
accessible via the <code>id</code> attribute, while the
object identifying attributes are exposed via the
<code>lookup</code> method.
</p>
<p>
See
<a href="http://libvirt.org/git/?p=libvirt.git;a=tree;f=examples/polkit;hb=HEAD" shape="rect">source code</a>
for a more complex example.
</p>
<h3>
<a name="exconnect" shape="rect" id="exconnect">Example: restricting ability to connect to drivers</a>
<a class="headerlink" href="#exconnect" title="Permalink to this headline"></a>
</h3>
<p>
Consider a local user <code>berrange</code>
who has been granted permission to connect to libvirt in
full read-write mode. The goal is to only allow them to
use the <code>QEMU</code> 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 <code>connect_driver</code> attribute
is <code>QEMU</code>, and match on an action
name of <code>org.libvirt.api.connect.getattr</code>. Using
the javascript rules format, this ends up written as
</p>
<pre xml:space="preserve">
polkit.addRule(function(action, subject) {
if (action.id == "org.libvirt.api.connect.getattr" &amp;&amp;
subject.user == "berrange") {
if (action.lookup("connect_driver") == 'QEMU') {
return polkit.Result.YES;
} else {
return polkit.Result.NO;
}
}
});
</pre>
<h3>
<a name="exdomain" shape="rect" id="exdomain">Example: restricting access to a single domain</a>
<a class="headerlink" href="#exdomain" title="Permalink to this headline"></a>
</h3>
<p>
Consider a local user <code>berrange</code>
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 <code>demo</code> on the LXC driver.
To achieve this we need to write a rule which checks
whether the <code>connect_driver</code> attribute
is <code>LXC</code> and the <code>domain_name</code>
attribute is <code>demo</code>, and match on a action
name of <code>org.libvirt.api.domain.getattr</code>. Using
the javascript rules format, this ends up written as
</p>
<pre xml:space="preserve">
polkit.addRule(function(action, subject) {
if (action.id == "org.libvirt.api.domain.getattr" &amp;&amp;
subject.user == "berrange") {
if (action.lookup("connect_driver") == 'LXC' &amp;&amp;
action.lookup("domain_name") == 'demo') {
return polkit.Result.YES;
} else {
return polkit.Result.NO;
}
}
});
</pre>
</div>
</div>
<div id="nav">
<div id="home">
<a href="index.html">Home</a>
</div>
<div id="jumplinks">
<ul><li>
<a href="downloads.html">Download</a>
</li><li>
<a href="contribute.html">Contribute</a>
</li><li>
<a href="docs.html">Learn</a>
</li></ul>
</div>
<div id="search">
<form action="search.php" enctype="application/x-www-form-urlencoded" method="get"><div>
<input name="query" type="text" size="12" value="" />
<input name="submit" type="submit" value="Go" />
</div></form>
</div>
</div>
<div id="footer">
<div id="contact">
<h3>Contact</h3>
<ul><li>
<a href="contact.html#email">email</a>
</li><li>
<a href="contact.html#irc">irc</a>
</li></ul>
</div>
<div id="community">
<h3>Community</h3>
<ul><li>
<a href="https://twitter.com/hashtag/libvirt">twitter</a>
</li><li>
<a href="https://plus.google.com/communities/109522598353007505282">google+</a>
</li><li>
<a href="http://stackoverflow.com/questions/tagged/libvirt">stackoverflow</a>
</li><li>
<a href="http://serverfault.com/questions/tagged/libvirt">serverfault</a>
</li></ul>
</div>
<div id="conduct">
Participants in the libvirt project agree to abide by <a href="governance.html#codeofconduct">the project code of conduct</a></div>
<br class="clear" />
</div>
</body>
</html>

+ 402
- 0
external_docs/libvirt.org/api.html View File

@ -0,0 +1,402 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
This file is autogenerated from api.html.in
Do not edit this file. Changes will be lost.
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="main.css" />
<link rel="SHORTCUT ICON" href="32favicon.png" />
<title>libvirt: The libvirt API concepts</title>
<meta name="description" content="libvirt, virtualization, virtualization API" />
</head>
<body>
<div id="body">
<div id="content">
<h1>The libvirt API concepts</h1>
<p> This page describes the main principles and architecture choices
behind the definition of the libvirt API:</p>
<ul><li>
<a href="#Objects">Objects Exposed</a>
</li><li>
<a href="#Functions">Functions and Naming Conventions</a>
</li><li>
<a href="#Drivers">The libvirt Drivers</a>
</li><li>
<a href="#Remote">Daemon and Remote Access</a>
</li></ul>
<h2>
<a name="Objects" shape="rect" id="Objects">Objects Exposed</a>
<a class="headerlink" href="#Objects" title="Permalink to this headline"></a>
</h2>
<p> As defined in the <a href="goals.html" shape="rect">goals section</a>, 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 <code>virConnectPtr</code>, which
represents the connection to a hypervisor. Any application using libvirt
is likely to start using the
API by calling one of <a href="html/libvirt-libvirt-host.html#virConnectOpen" shape="rect">the virConnectOpen functions</a>. You will note that those functions take
a name argument which is actually a <a href="uri.html" shape="rect">connection URI</a>
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 <a href="uri.html" shape="rect">connection
URI</a> page for a full descriptions of the values allowed.</p>
<p> OnDevice the application obtains a
<a href="/html/libvirt-libvirt-host.html#virConnectPtr" shape="rect">
<code>virConnectPtr</code>
</a>
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).</p>
<p class="image">
<img alt="first class objects exposed by the API" src="libvirt-object-model.png" />
</p>
<p> The figure above shows the five main objects exported by the API:</p>
<ul><li>
<a href="html/libvirt-libvirt-host.html#virConnectPtr" shape="rect">
<code>virConnectPtr</code>
</a>
<p>Represents the connection to a hypervisor. Use one of the
<a href="html/libvirt-libvirt-host.html#virConnectOpen" shape="rect">virConnectOpen</a>
functions to obtain connection to the hypervisor which is then used
as a parameter to other connection API's.</p></li><li>
<a href="html/libvirt-libvirt-domain.html#virDomainPtr" shape="rect">
<code>virDomainPtr</code>
</a>
<p>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
<a href="html/libvirt-libvirt-domain.html#virConnectListAllDomains" shape="rect">
<code>virConnectListAllDomains</code>
</a>
lists all the domains for the hypervisor.</p></li><li>
<a href="html/libvirt-libvirt-network.html#virNetworkPtr" shape="rect">
<code>virNetworkPtr</code>
</a>
<p>Represents one network either active or defined (i.e. existing
as permanent config file and storage but not currently activated).
The function
<a href="html/libvirt-libvirt-network.html#virConnectListAllNetworks" shape="rect">
<code>virConnectListAllNetworks</code>
</a>
lists all the virtualization networks for the hypervisor.</p></li><li>
<a href="html/libvirt-libvirt-storage.html#virStorageVolPtr" shape="rect">
<code>virStorageVolPtr</code>
</a>
<p>Represents one storage volume generally used
as a block device available to one of the domains. The function
<a href="html/libvirt-libvirt-storage.html#virStorageVolLookupByPath" shape="rect">
<code>virStorageVolLookupByPath</code>
</a>
finds the storage volume object based on its path on the node.</p></li><li>
<a href="html/libvirt-libvirt-storage.html#virStoragePoolPtr" shape="rect">
<code>virStoragePoolPtr</code>
</a>
<p>Represents a storage pool, which is a logical area
used to allocate and store storage volumes. The function
<a href="html/libvirt-libvirt-storage.html#virConnectListAllStoragePools" shape="rect">
<code>virConnectListAllStoragePools</code>
</a>
lists all of the virtualization storage pools on the hypervisor.
The function
<a href="html/libvirt-libvirt-storage.html#virStoragePoolLookupByVolume" shape="rect">
<code>virStoragePoolLookupByVolume</code>
</a>
finds the storage pool containing a given storage volume.</p></li></ul>
<p> 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.</p>
<p> Domains, networks, and storage pools can be either <code>active</code>
i.e. either running or available for immediate use, or
<code>defined</code> in which case they are inactive but there is
a permanent definition available in the system for them. Based on this
they can be activated dynamically in order to be used.</p>
<p> Most objects can also be named in various ways:</p>
<ul><li><code>name</code>
<p>A user friendly identifier but whose uniqueness
cannot be guaranteed between two nodes.</p></li><li><code>ID</code>
<p>A runtime unique identifier
provided by the hypervisor for one given activation of the object;
however, it becomes invalid once the resource is deactivated.</p></li><li><code>UUID</code>
<p> A 16 byte unique identifier
as defined in <a href="http://www.ietf.org/rfc/rfc4122.txt" shape="rect">RFC 4122</a>,
which is guaranteed to be unique for long term usage and across a
set of nodes.</p></li></ul>
<h2>
<a name="Functions" shape="rect" id="Functions">Functions and Naming Conventions</a>
<a class="headerlink" href="#Functions" title="Permalink to this headline"></a>
</h2>
<p> 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.</p>
<p> For each first class object you will find APIs
for the following actions:</p>
<ul><li><b>Lookup</b> [...LookupBy...]
<p>Used to perform lookups on objects by some type of identifier,
such as:</p>
<ul><li>
<a href="html/libvirt-libvirt-domain.html#virDomainLookupByID" shape="rect">
<code>virDomainLookupByID</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-domain.html#virDomainLookupByName" shape="rect">
<code>virDomainLookupByName</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-domain.html#virDomainLookupByUUID" shape="rect">
<code>virDomainLookupByUUID</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-domain.html#virDomainLookupByUUIDString" shape="rect">
<code>virDomainLookupByUUIDString</code>
</a>
</li></ul>
</li><li><b>Enumeration</b> [virConnectList..., virConnectNumOf...]
<p>Used to enumerate a set of object available to an given
hypervisor connection such as:</p>
<ul><li>
<a href="html/libvirt-libvirt-domain.html#virConnectListDomains" shape="rect">
<code>virConnectListDomains</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-domain.html#virConnectNumOfDomains" shape="rect">
<code>virConnectNumOfDomains</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-network.html#virConnectListNetworks" shape="rect">
<code>virConnectListNetworks</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-storage.html#virConnectListStoragePools" shape="rect">
<code>virConnectListStoragePools</code>
</a>
</li></ul>
</li><li><b>Description</b> [...GetInfo]
<p>Generic accessor providing a set of generic information about an
object, such as: </p>
<ul><li>
<a href="html/libvirt-libvirt-host.html#virNodeGetInfo" shape="rect">
<code>virNodeGetInfo</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-domain.html#virDomainGetInfo" shape="rect">
<code>virDomainGetInfo</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-storage.html#virStoragePoolGetInfo" shape="rect">
<code>virStoragePoolGetInfo</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-storage.html#virStorageVolGetInfo" shape="rect">
<code>virStorageVolGetInfo</code>
</a>
</li></ul>
</li><li><b>Accessors</b> [...Get..., ...Set...]
<p>Specific accessors used to query or modify data for the given object,
such as: </p>
<ul><li>
<a href="html/libvirt-libvirt-host.html#virConnectGetType" shape="rect">
<code>virConnectGetType</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-domain.html#virDomainGetMaxMemory" shape="rect">
<code>virDomainGetMaxMemory</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-domain.html#virDomainSetMemory" shape="rect">
<code>virDomainSetMemory</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-domain.html#virDomainGetVcpus" shape="rect">
<code>virDomainGetVcpus</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-storage.html#virStoragePoolSetAutostart" shape="rect">
<code>virStoragePoolSetAutostart</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-network.html#virNetworkGetBridgeName" shape="rect">
<code>virNetworkGetBridgeName</code>
</a>
</li></ul>
</li><li><b>Creation</b> [...Create, ...CreateXML]
<p>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: </p>
<ul><li>
<a href="html/libvirt-libvirt-domain.html#virDomainCreate" shape="rect">
<code>virDomainCreate</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-domain.html#virDomainCreateXML" shape="rect">
<code>virDomainCreateXML</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-network.html#virNetworkCreate" shape="rect">
<code>virNetworkCreate</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-network.html#virNetworkCreateXML" shape="rect">
<code>virNetworkCreateXML</code>
</a>
</li></ul>
</li><li><b>Destruction</b> [...Destroy]
<p>Used to shutdown or deactivate and destroy objects, such as: </p>
<ul><li>
<a href="html/libvirt-libvirt-domain.html#virDomainDestroy" shape="rect">
<code>virDomainDestroy</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-network.html#virNetworkDestroy" shape="rect">
<code>virNetworkDestroy</code>
</a>
</li><li>
<a href="html/libvirt-libvirt-storage.html#virStoragePoolDestroy" shape="rect">
<code>virStoragePoolDestroy</code>
</a>
</li></ul>
</li></ul>
<p>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).
</p>
<p> For more in-depth details of the storage related APIs see
<a href="storage.html" shape="rect">the storage management page</a>.
</p>
<h2>
<a name="Drivers" shape="rect" id="Drivers">The libvirt Drivers</a>
<a class="headerlink" href="#Drivers" title="Permalink to this headline"></a>
</h2>
<p>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
<a href="html/libvirt-libvirt-host.html#virInitialize" shape="rect">
<code>virInitialize</code>
</a>
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.</p>
<p class="image">
<img alt="The libvirt driver architecture" src="libvirt-driver-arch.png" />
</p>
<p>The driver architecture is also used to support other virtualization
components such as storage, storage pools, host device, networking,
network interfaces, and network filters.</p>
<p>See the <a href="drivers.html" shape="rect">libvirt drivers</a> page for more
information on hypervisor and storage specific drivers.</p>
<p>Not all drivers support every virtualization function possible.
The <a href="hvsupport.html" shape="rect">libvirt API support matrix</a> lists
the various functions and support found in each driver by the version
support was added into libvirt.
</p>
<h2>
<a name="Remote" shape="rect" id="Remote">Daemon and Remote Access</a>
<a class="headerlink" href="#Remote" title="Permalink to this headline"></a>
</h2>
<p>Access to libvirt drivers is primarily handled by the libvirtd
daemon through the <a href="remote.html" shape="rect">remote</a> driver via an
<a href="internals/rpc.html" shape="rect">RPC</a>. Some hypervisors do support
client-side connections and responses, such as Test, OpenVZ, VMware,
Power VM (phyp), 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
<a href="html/libvirt-libvirt-host.html#virInitialize" shape="rect">
<code>virInitialize</code>
</a>
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. </p>
<p>The libvirt client <a href="apps.html" shape="rect">applications</a> use a
<a href="uri.html" shape="rect">URI</a> to obtain the <code>virConnectPtr</code>.
The <code>virConnectPtr</code> keeps track of the driver connection
plus a variety of other connections (network, interface, storage, etc.).
The <code>virConnectPtr</code> is then used as a parameter to other
virtualization <a href="#Functions" shape="rect">functions</a>. 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. <a href="migration.html" shape="rect">Migration</a>
is an example of many facets of the architecture in use.</p>
<p class="image">
<img alt="The libvirt daemon and remote architecture" src="libvirt-daemon-arch.png" />
</p>
<p>
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 <code>virConnectPtr</code> in order to fetch the data. The data will
then be returned through the remote driver to the client application
for processing.
</p>
<p>If you are interested in contributing to libvirt, read the
<a href="http://wiki.libvirt.org/page/FAQ" shape="rect">FAQ</a> and
<a href="hacking.html" shape="rect">hacking</a> guidelines to gain an understanding
of basic rules and guidelines. In order to add new API functionality
follow the instructions regarding
<a href="api_extension.html" shape="rect">implementing a new API in libvirt</a>.
</p>
</div>
</div>
<div id="nav">
<div id="home">
<a href="index.html">Home</a>
</div>
<div id="jumplinks">
<ul><li>
<a href="downloads.html">Download</a>
</li><li>
<a href="contribute.html">Contribute</a>
</li><li>
<a href="docs.html">Learn</a>
</li></ul>
</div>
<div id="search">
<form action="search.php" enctype="application/x-www-form-urlencoded" method="get"><div>
<input name="query" type="text" size="12" value="" />
<input name="submit" type="submit" value="Go" />
</div></form>
</div>
</div>
<div id="footer">
<div id="contact">
<h3>Contact</h3>
<ul><li>
<a href="contact.html#email">email</a>
</li><li>
<a href="contact.html#irc">irc</a>
</li></ul>
</div>
<div id="community">
<h3>Community</h3>
<ul><li>
<a href="https://twitter.com/hashtag/libvirt">twitter</a>
</li><li>
<a href="https://plus.google.com/communities/109522598353007505282">google+</a>
</li><li>
<a href="http://stackoverflow.com/questions/tagged/libvirt">stackoverflow</a>
</li><li>
<a href="http://serverfault.com/questions/tagged/libvirt">serverfault</a>
</li></ul>
</div>
<div id="conduct">
Participants in the libvirt project agree to abide by <a href="governance.html#codeofconduct">the project code of conduct</a></div>
<br class="clear" />
</div>
</body>
</html>

+ 464
- 0
external_docs/libvirt.org/api_extension.html View File

@ -0,0 +1,464 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
This file is autogenerated from api_extension.html.in
Do not edit this file. Changes will be lost.
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="main.css" />
<link rel="SHORTCUT ICON" href="32favicon.png" />
<title>libvirt: Implementing a new API in Libvirt</title>
<meta name="description" content="libvirt, virtualization, virtualization API" />
</head>
<body>
<div id="body">
<div id="content">
<h1>Implementing a new API in Libvirt</h1>
<ul><li>
<a href="#publicapi">Defining the public API</a>
</li><li>
<a href="#internalapi">Defining the internal API</a>
</li><li>
<a href="#implpublic">Implementing the public API</a>
</li><li>
<a href="#remoteproto">Implementing the remote protocol</a>
<ul><li>
<a href="#wireproto">Defining the wire protocol format</a>
</li><li>
<a href="#rpcclient">Implement the RPC client</a>
</li><li>
<a href="#serverdispatch">Implement the server side dispatcher</a>
</li></ul>
</li><li>
<a href="#internaluseapi">Use the new API internally</a>
</li><li>
<a href="#virshuseapi">Expose the new API in virsh</a>
</li><li>
<a href="#driverimpl">Implement the driver methods</a>
<ul><li>
<a href="#commonimpl">Implement common handling</a>
</li><li>
<a href="#drivercode">Implement driver handling</a>
</li></ul>
</li></ul>
<p>
This document walks you through the process of implementing a new
API in libvirt. It uses as an example the addition of an API for
separating maximum from current vcpu usage of a domain, over
the course of a fifteen-patch series.
Remember that new API consists of any new public functions, as
well as the addition of flags or extensions of XML used by
existing functions. The example in this document adds both new
functions and an XML extension. Not all libvirt API additions
require quite as many patches.
</p>
<p>
Before you begin coding, it is critical that you propose your
changes on the libvirt mailing list and get feedback on your ideas to
make sure what you're proposing fits with the general direction of the
project. Even before doing a proof of concept implementation, send an
email giving an overview of the functionality you think should be
added to libvirt. Someone may already be working on the feature you
want. Also, recognize that everything you write is likely to undergo
significant rework as you discuss it with the other developers, so
don't wait too long before getting feedback. In the vcpu example
below, list feedback was first requested
<a href="https://www.redhat.com/archives/libvir-list/2010-September/msg00423.html" shape="rect">here</a>
and resulted in several rounds of improvements before coding
began. In turn, this example is slightly rearranged from the actual
order of the commits.
</p>
<p>
Adding a new API to libvirt is not difficult, but there are quite a
few steps. This document assumes that you are familiar with C
programming and have checked out the libvirt code from the source code
repository and successfully built the existing tree. Instructions on
how to check out and build the code can be found at:
</p>
<p>
<a href="http://libvirt.org/downloads.html" shape="rect">http://libvirt.org/downloads.html</a>
</p>
<p>
Once you have a working development environment, the steps to create a
new API are:
</p>
<ol><li>define the public API</li><li>define the internal driver API</li><li>implement the public API</li><li>implement the remote protocol:
<ol><li>define the wire protocol format</li><li>implement the RPC client</li><li>implement the server side dispatcher</li></ol>
</li><li>use new API where appropriate in drivers</li><li>add virsh support</li><li>add common handling for new API</li><li>for each driver that can support the new API:
<ol><li>add prerequisite support</li><li>fully implement new API</li></ol>
</li></ol>
<p>
It is, of course, possible to implement the pieces in any order, but
if the development tasks are completed in the order listed, the code
will compile after each step. Given the number of changes required,
verification after each step is highly recommended.
</p>
<p>
Submit new code in the form shown in the example code: one patch
per step. That's not to say submit patches before you have working
functionality--get the whole thing working and make sure you're happy
with it. Then use git or some other version control system that lets
you rewrite your commit history and break patches into pieces so you
don't drop a big blob of code on the mailing list in one go.
Also, you should follow the upstream tree, and rebase your
series to adapt your patches to work with any other changes
that were accepted upstream during your development.
</p>
<p>
Don't mix anything else into the patches you submit. The patches
should be the minimal changes required to implement the functionality
you're adding. If you notice a bug in unrelated code (i.e., code you
don't have to touch to implement your API change) during development,
create a patch that just addresses that bug and submit it
separately.
</p>
<p>With that said, let's begin.</p>
<h2>
<a name="publicapi" shape="rect" id="publicapi">Defining the public API</a>
<a class="headerlink" href="#publicapi" title="Permalink to this headline"></a>
</h2>
<p>The first task is to define the public API. If the new API
involves an XML extension, you have to enhance the RelaxNG
schema and document the new elements or attributes:</p>
<p>
<code>
docs/schemas/domain.rng<br />
docs/formatdomain.html.in
</code>
</p>
<p>If the API extension involves a new function, you have to add a
declaration in the public header, and arrange to export the
function name (symbol) so other programs can link against the
libvirt library and call the new function:</p>
<p>
<code>
include/libvirt/libvirt.h.in
src/libvirt_public.syms
</code>
</p>
<p>
This task is in many ways the most important to get right, since once
the API has been committed to the repository, it's libvirt's policy
never to change it. Mistakes in the implementation are bugs that you
can fix. Make a mistake in the API definition and you're stuck with
it, so think carefully about the interface and don't be afraid to
rework it as you go through the process of implementing it.
</p>
<p class="example">See <a href="api_extension/0001-add-to-xml.patch" shape="rect">0001-add-to-xml.patch</a>
and <a href="api_extension/0002-add-new-public-API.patch" shape="rect">0002-add-new-public-API.patch</a>
for example code.</p>
<h2>
<a name="internalapi" shape="rect" id="internalapi">Defining the internal API</a>
<a class="headerlink" href="#internalapi" title="Permalink to this headline"></a>
</h2>
<p>
Each public API call is associated with a driver, such as a host
virtualization driver, a network virtualization driver, a storage
virtualization driver, a state driver, or a device monitor. Adding
the internal API is ordinarily a matter of adding a new member to the
struct representing one of these drivers.
</p>
<p>
Of course, it's possible that the new API will involve the creation of
an entirely new driver type, in which case the changes will include the
creation of a new struct type to represent the new driver type.
</p>
<p>The driver structs are defined in:</p>
<p>
<code>src/driver.h</code>
</p>
<p>
To define the internal API, first typedef the driver function
prototype and then add a new field for it to the relevant driver
struct. Then, update all existing instances of the driver to
provide a <code>NULL</code> stub for the new function.
</p>
<p class="example">See <a href="api_extension/0003-define-internal-driver-API.patch" shape="rect">0003-define-internal-driver-API.patch</a></p>
<h2>
<a name="implpublic" shape="rect" id="implpublic">Implementing the public API</a>
<a class="headerlink" href="#implpublic" title="Permalink to this headline"></a>
</h2>
<p>
Implementing the public API is largely a formality in which we wire up
public API to the internal driver API. The public API implementation
takes care of some basic validity checks before passing control to the
driver implementation. In RFC 2119 vocabulary, this function:
</p>
<ol class="ordinarylist"><li>SHOULD log a message with VIR_DEBUG() indicating that it is
being called and its parameters;</li><li>MUST call virResetLastError();</li><li>SHOULD confirm that the connection is valid with
virCheckConnectReturn() or virCheckConnectGoto();</li><li><strong>SECURITY: If the API requires a connection with write
privileges, MUST confirm that the connection flags do not
indicate that the connection is read-only with
virCheckReadOnlyGoto();</strong></li><li>SHOULD do basic validation of the parameters that are being
passed in, using helpers like virCheckNonNullArgGoto();</li><li>MUST confirm that the driver for this connection exists and that
it implements this function;</li><li>MUST call the internal API;</li><li>SHOULD log a message with VIR_DEBUG() indicating that it is
returning, its return value, and status.</li><li>MUST return status to the caller.</li></ol>
<p>The public API calls are implemented in:</p>
<p>
<code>src/libvirt.c</code>
</p>
<p class="example">See <a href="api_extension/0004-implement-the-public-APIs.patch" shape="rect">0004-implement-the-public-APIs.patch</a></p>
<h2>
<a name="remoteproto" shape="rect" id="remoteproto">Implementing the remote protocol</a>
<a class="headerlink" href="#remoteproto" title="Permalink to this headline"></a>
</h2>
<p>
Implementing the remote protocol is essentially a
straightforward exercise which is probably most easily
understood by referring to the existing code and the example
patch. It involves several related changes, including the
regeneration of derived files, with further details below.
</p>
<p class="example">See <a href="api_extension/0005-implement-the-remote-protocol.patch" shape="rect">0005-implement-the-remote-protocol.patch</a></p>
<h3>
<a name="wireproto" shape="rect" id="wireproto">Defining the wire protocol format</a>
<a class="headerlink" href="#wireproto" title="Permalink to this headline"></a>
</h3>
<p>
Defining the wire protocol involves making additions to:
</p>
<p>
<code>src/remote/remote_protocol.x</code>
</p>
<p>
First, create two new structs for each new function that you're adding
to the API. One struct describes the parameters to be passed to the
remote function, and a second struct describes the value returned by
the remote function. The one exception to this rule is that functions
that return only 0 or -1 for status do not require a struct for returned
data.
</p>
<p>
Second, add values to the remote_procedure enum for each new function
added to the API.
</p>
<p>
Once these changes are in place, it's necessary to run 'make rpcgen'
in the src directory to create the .c and .h files required by the
remote protocol code. This must be done on a Linux host using the
GLibC rpcgen program. Other rpcgen versions may generate code which
results in bogus compile time warnings. This regenerates the
following files:
</p>
<p>
<code>
daemon/remote_dispatch_args.h
daemon/remote_dispatch_prototypes.h
daemon/remote_dispatch_table.h
src/remote/remote_protocol.c
src/remote/remote_protocol.h
</code>
</p>
<h3>
<a name="rpcclient" shape="rect" id="rpcclient">Implement the RPC client</a>
<a class="headerlink" href="#rpcclient" title="Permalink to this headline"></a>
</h3>
<p>
Implementing the uses the rpcgen generated .h files. The remote
method calls go in:
</p>
<p>
<code>src/remote/remote_internal.c</code>
</p>
<p>Each remote method invocation does the following:</p>
<ol class="ordinarylist"><li>locks the remote driver;</li><li>sets up the method arguments;</li><li>invokes the remote function;</li><li>checks the return value, if necessary;</li><li>extracts any returned data;</li><li>frees any returned data;</li><li>unlocks the remote driver.</li></ol>
<h3>
<a name="serverdispatch" shape="rect" id="serverdispatch">Implement the server side dispatcher</a>
<a class="headerlink" href="#serverdispatch" title="Permalink to this headline"></a>
</h3>
<p>
Implementing the server side of the remote function call is simply a
matter of deserializing the parameters passed in from the remote
caller and passing them to the corresponding internal API function.
The server side dispatchers are implemented in:
</p>
<p>
<code>daemon/remote.c</code>
</p>
<p>Again, this step uses the .h files generated by make rpcgen.</p>
<p>
After all three pieces of the remote protocol are complete, and
the generated files have been updated, it will be necessary to
update the file:</p>
<p>
<code>src/remote_protocol-structs</code>
</p>
<p>
This file should only have new lines added; modifications to
existing lines probably imply a backwards-incompatible API change.
</p>
<p class="example">See <a href="api_extension/0005-implement-the-remote-protocol.patch" shape="rect">0005-implement-the-remote-protocol.patch</a></p>
<h2>
<a name="internaluseapi" shape="rect" id="internaluseapi">Use the new API internally</a>
<a class="headerlink" href="#internaluseapi" title="Permalink to this headline"></a>
</h2>
<p>
Sometimes, a new API serves as a superset of existing API, by
adding more granularity in what can be managed. When this is
the case, it makes sense to share a common implementation by
making the older API become a trivial wrapper around the new
API, rather than duplicating the common code. This step should
not introduce any semantic differences for the old API, and is
not necessary if the new API has no relation to existing API.
</p>
<p class="example">See <a href="api_extension/0006-make-old-API-trivially-wrap-to-new-API.patch" shape="rect">0006-make-old-API-trivially-wrap-to-new-API.patch</a></p>
<h2>
<a name="virshuseapi" shape="rect" id="virshuseapi">Expose the new API in virsh</a>
<a class="headerlink" href="#virshuseapi" title="Permalink to this headline"></a>
</h2>
<p>
All new API should be manageable from the virsh command line
shell. This proves that the API is sufficient for the intended
purpose, and helps to identify whether the proposed API needs
slight changes for easier usage. However, remember that virsh
is used to connect to hosts running older versions of libvirtd,
so new commands should have fallbacks to an older API if
possible; implementing the virsh hooks at this point makes it
very easy to test these fallbacks. Also remember to document
virsh additions.
</p>
<p>
A virsh command is composed of a few pieces of code. You need to
define an array of vshCmdInfo structs for each new command that
contain the help text and the command description text. You also need
an array of vshCmdOptDef structs to describe the command options.
Once you have those pieces in place you can write the function
implementing the virsh command. Finally, you need to add the new
command to the commands[] array. The following files need changes:
</p>
<p>
<code>
tools/virsh.c<br />
tools/virsh.pod
</code>
</p>
<p class="example">See <a href="api_extension/0007-add-virsh-support.patch" shape="rect">0007-add-virsh-support.patch</a></p>
<h2>
<a name="driverimpl" shape="rect" id="driverimpl">Implement the driver methods</a>
<a class="headerlink" href="#driverimpl" title="Permalink to this headline"></a>
</h2>
<p>
So, after all that, we get to the fun part. All functionality in
libvirt is implemented inside a driver. Thus, here is where you
implement whatever functionality you're adding to libvirt. You'll
either need to add additional files to the src directory or extend
files that are already there, depending on what functionality you're
adding.
</p>
<h3>
<a name="commonimpl" shape="rect" id="commonimpl">Implement common handling</a>
<a class="headerlink" href="#commonimpl" title="Permalink to this headline"></a>
</h3>
<p>
If the new API is applicable to more than one driver, it may
make sense to provide some utility routines, or to factor some
of the work into the dispatcher, to avoid reimplementing the
same code in every driver. In the example code, this involved
adding a member to the virDomainDefPtr struct for mapping
between the XML API addition and the in-memory representation of
a domain, along with updating all clients to use the new member.
Up to this point, there have been no changes to existing
semantics, and the new APIs will fail unless they are used in
the same way as the older API wrappers.
</p>
<p class="example">See <a href="api_extension/0008-support-new-xml.patch" shape="rect">0008-support-new-xml.patch</a></p>
<h3>
<a name="drivercode" shape="rect" id="drivercode">Implement driver handling</a>
<a class="headerlink" href="#drivercode" title="Permalink to this headline"></a>
</h3>
<p>
The remaining patches should only touch one driver at a time.
It is possible to implement all changes for a driver in one
patch, but for review purposes it may still make sense to break
things into simpler steps. Here is where the new APIs finally
start working.
</p>
<p>
In the example patches, three separate drivers are supported:
test, qemu, and xen. It is always a good idea to patch the test
driver in addition to the target driver, to prove that the API
can be used for more than one driver. The example updates the
test driver in one patch:
</p>
<p class="example">See <a href="api_extension/0009-support-all-flags-in-test-driver.patch" shape="rect">0009-support-all-flags-in-test-driver.patch</a></p>
<p>
The qemu changes were easier to split into two phases, one for
updating the mapping between the new XML and the hypervisor
command line arguments, and one for supporting all possible
flags of the new API:
</p>
<p class="example">See <a href="api_extension/0010-improve-vcpu-support-in-qemu-command-line.patch" shape="rect">0010-improve-vcpu-support-in-qemu-command-line.patch</a>
and <a href="api_extension/0011-complete-vcpu-support-in-qemu-driver.patch" shape="rect">0011-complete-vcpu-support-in-qemu-driver.patch</a></p>
<p>
Finally, the example breaks the xen driver changes across four
patches. One maps the XML changes to the hypervisor command,
the next two are independently implementing the getter and
setter APIs, and the last one provides cleanup of code that was
rendered dead by the new API.
</p>
<p class="example">See <a href="api_extension/0012-improve-vcpu-support-in-xen-command-line.patch" shape="rect">0012-improve-vcpu-support-in-xen-command-line.patch</a>,
<a href="api_extension/0013-improve-getting-xen-vcpu-counts.patch" shape="rect">0013-improve-getting-xen-vcpu-counts.patch</a>,
<a href="api_extension/0014-improve-setting-xen-vcpu-counts.patch" shape="rect">0014-improve-setting-xen-vcpu-counts.patch</a>,
and <a href="api_extension/0015-remove-dead-xen-code.patch" shape="rect">0015-remove-dead-xen-code.patch</a></p>
<p>
The exact details of the example code are probably uninteresting
unless you're concerned with virtual cpu management.
</p>
<p>
Once you have working functionality, run make check and make
syntax-check on each patch of the series before submitting
patches. It may also be worth writing tests for the libvirt-TCK
testsuite to exercise your new API, although those patches are
not kept in the libvirt repository.
</p>
</div>
</div>
<div id="nav">
<div id="home">
<a href="index.html">Home</a>
</div>
<div id="jumplinks">
<ul><li>
<a href="downloads.html">Download</a>
</li><li>
<a href="contribute.html">Contribute</a>
</li><li>
<a href="docs.html">Learn</a>
</li></ul>
</div>
<div id="search">
<form action="search.php" enctype="application/x-www-form-urlencoded" method="get"><div>
<input name="query" type="text" size="12" value="" />
<input name="submit" type="submit" value="Go" />
</div></form>
</div>
</div>
<div id="footer">
<div id="contact">
<h3>Contact</h3>
<ul><li>
<a href="contact.html#email">email</a>
</li><li>
<a href="contact.html#irc">irc</a>
</li></ul>
</div>
<div id="community">
<h3>Community</h3>
<ul><li>
<a href="https://twitter.com/hashtag/libvirt">twitter</a>
</li><li>
<a href="https://plus.google.com/communities/109522598353007505282">google+</a>
</li><li>
<a href="http://stackoverflow.com/questions/tagged/libvirt">stackoverflow</a>
</li><li>
<a href="http://serverfault.com/questions/tagged/libvirt">serverfault</a>
</li></ul>
</div>
<div id="conduct">
Participants in the libvirt project agree to abide by <a href="governance.html#codeofconduct">the project code of conduct</a></div>
<br class="clear" />
</div>
</body>
</html>

+ 145
- 0
external_docs/libvirt.org/api_extension/0001-add-to-xml.patch View File

@ -0,0 +1,145 @@
From a74f4e44649906dcd82151f7ef837f66d7fa2ab1 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 27 Sep 2010 17:36:06 -0600
Subject: [PATCH 01/15] vcpu: add current attribute to <vcpu> element
Syntax agreed on in
https://www.redhat.com/archives/libvir-list/2010-September/msg00476.html
<domain ...>
<vcpu current='x'>y</vcpu>
...
can now be used to specify 1 <= x <= y current vcpus, in relation
to the boot-time max of y vcpus. If current is omitted, then
current and max are assumed to be the same value.
* docs/schemas/domain.rng: Add new attribute.
* docs/formatdomain.html.in: Document it.
* tests/qemuxml2argvdata/qemuxml2argv-smp.xml: Add to
domainschematest.
* tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml: Likewise.
---
docs/formatdomain.html.in | 9 +++++--
docs/schemas/domain.rng | 5 ++++
tests/qemuxml2argvdata/qemuxml2argv-smp.xml | 28 +++++++++++++++++++++++++++
tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml | 22 +++++++++++++++++++++
4 files changed, 61 insertions(+), 3 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smp.xml
create mode 100644 tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index a8a1fac..96de121 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -200,7 +200,7 @@
&lt;swap_hard_limit&gt;2097152&lt;/swap_hard_limit&gt;
&lt;min_guarantee&gt;65536&lt;/min_guarantee&gt;
&lt;/memtune&gt;
- &lt;vcpu cpuset="1-4,^3,6"&gt;2&lt;/vcpu&gt;
+ &lt;vcpu cpuset="1-4,^3,6" current="1"&gt;2&lt;/vcpu&gt;
...</pre>
<dl>
@@ -238,7 +238,7 @@
minimum memory allocation for the guest. The units for this value are
kilobytes (i.e. blocks of 1024 bytes)</dd>
<dt><code>vcpu</code></dt>
- <dd>The content of this element defines the number of virtual
+ <dd>The content of this element defines the maximum number of virtual
CPUs allocated for the guest OS, which must be between 1 and
the maximum supported by the hypervisor. <span class="since">Since
0.4.4</span>, this element can contain an optional
@@ -246,7 +246,10 @@
list of physical CPU numbers that virtual CPUs can be pinned
to. Each element in that list is either a single CPU number,
a range of CPU numbers, or a caret followed by a CPU number to
- be excluded from a previous range.
+ be excluded from a previous range. <span class="since">Since
+ 0.8.5</span>, the optional attribute <code>current</code> can
+ be used to specify whether fewer than the maximum number of
+ virtual CPUs should be enabled.
</dd>
</dl>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index f230263..a934a77 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -337,6 +337,11 @@
<ref name="cpuset"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="current">
+ <ref name="countCPU"/>
+ </attribute>
+ </optional>
<ref name="countCPU"/>
</element>
</optional>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smp.xml b/tests/qemuxml2argvdata/qemuxml2argv-smp.xml
new file mode 100644
index 0000000..975f873
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smp.xml
@@ -0,0 +1,28 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu current='1'>2</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <topology sockets='2' cores='1' threads='1'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
new file mode 100644
index 0000000..d061e11
--- /dev/null
+++ b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
@@ -0,0 +1,22 @@
+<domain type='xen' id='15'>
+ <name>pvtest</name>
+ <uuid>596a5d2171f48fb2e068e2386a5c413e</uuid>
+ <os>
+ <type>linux</type>
+ <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel>
+ <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd>
+ <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os </cmdline>
+ </os>
+ <memory>430080</memory>
+ <vcpu current='2'>4</vcpu>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <source file='/root/some.img'/>
+ <target dev='xvda'/>
+ </disk>
+ <console tty='/dev/pts/4'/>
+ </devices>
+</domain>
--
1.7.2.3

+ 62
- 0
external_docs/libvirt.org/api_extension/0002-add-new-public-API.patch View File

@ -0,0 +1,62 @@
From ea3f5c68093429c6ad507b45689cdf209c2c257b Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 24 Sep 2010 16:48:45 -0600
Subject: [PATCH 02/15] vcpu: add new public API
API agreed on in
https://www.redhat.com/archives/libvir-list/2010-September/msg00456.html,
but modified for enum names to be consistent with virDomainDeviceModifyFlags.
* include/libvirt/libvirt.h.in (virDomainVcpuFlags)
(virDomainSetVcpusFlags, virDomainGetVcpusFlags): New
declarations.
* src/libvirt_public.syms: Export new symbols.
---
include/libvirt/libvirt.h.in | 15 +++++++++++++++
src/libvirt_public.syms | 2 ++
2 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 2eba61e..d0cc4c0 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -915,8 +915,23 @@ struct _virVcpuInfo {
};
typedef virVcpuInfo *virVcpuInfoPtr;
+/* Flags for controlling virtual CPU hot-plugging. */
+typedef enum {
+ /* Must choose at least one of these two bits; SetVcpus can choose both */
+ VIR_DOMAIN_VCPU_LIVE = (1 << 0), /* Affect active domain */
+ VIR_DOMAIN_VCPU_CONFIG = (1 << 1), /* Affect next boot */
+
+ /* Additional flags to be bit-wise OR'd in */
+ VIR_DOMAIN_VCPU_MAXIMUM = (1 << 2), /* Max rather than current count */
+} virDomainVcpuFlags;
+
int virDomainSetVcpus (virDomainPtr domain,
unsigned int nvcpus);
+int virDomainSetVcpusFlags (virDomainPtr domain,
+ unsigned int nvcpus,
+ unsigned int flags);
+int virDomainGetVcpusFlags (virDomainPtr domain,
+ unsigned int flags);
int virDomainPinVcpu (virDomainPtr domain,
unsigned int vcpu,
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index fceb516..a8091b1 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -409,6 +409,8 @@ LIBVIRT_0.8.5 {
global:
virDomainSetMemoryParameters;
virDomainGetMemoryParameters;
+ virDomainGetVcpusFlags;
+ virDomainSetVcpusFlags;
} LIBVIRT_0.8.2;
# .... define new API here using predicted next version number ....
--
1.7.2.3

+ 222
- 0
external_docs/libvirt.org/api_extension/0003-define-internal-driver-API.patch View File

@ -0,0 +1,222 @@
From dd255d64053e9960cd375994ce8f056522e12acc Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 27 Sep 2010 09:18:22 -0600
Subject: [PATCH 03/15] vcpu: define internal driver API
* src/driver.h (virDrvDomainSetVcpusFlags)
(virDrvDomainGetVcpusFlags): New typedefs.
(_virDriver): New callback members.
* src/esx/esx_driver.c (esxDriver): Add stub for driver.
* src/lxc/lxc_driver.c (lxcDriver): Likewise.
* src/opennebula/one_driver.c (oneDriver): Likewise.
* src/openvz/openvz_driver.c (openvzDriver): Likewise.
* src/phyp/phyp_driver.c (phypDriver): Likewise.
* src/qemu/qemu_driver.c (qemuDriver): Likewise.
* src/remote/remote_driver.c (remote_driver): Likewise.
* src/test/test_driver.c (testDriver): Likewise.