Sophie

Sophie

distrib > Mageia > 3 > i586 > by-pkgid > 0b7d91ce0c9dc6614b6f54c3313f2e91 > files > 79

libvirt-devel-1.0.2-8.7.mga3.i586.rpm

<?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 internals/locking.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: Resource Lock Manager</title>
    <meta name="description" content="libvirt, virtualization, virtualization API" />
  </head>
  <body>
    <div id="header">
      <div id="headerLogo"></div>
      <div id="headerSearch">
        <form action="../search.php" enctype="application/x-www-form-urlencoded" method="get"><div>
            <input id="query" name="query" type="text" size="12" value="" />
            <input id="submit" name="submit" type="submit" value="Search" />
          </div></form>
      </div>
    </div>
    <div id="body">
      <div id="menu">
        <ul class="l0"><li>
            <div>
              <a title="Front page of the libvirt website" class="inactive" href="../index.html">Home</a>
            </div>
          </li><li>
            <div>
              <a title="Details of new features and bugs fixed in each release" class="inactive" href="../news.html">News</a>
            </div>
          </li><li>
            <div>
              <a title="Applications known to use libvirt" class="inactive" href="../apps.html">Applications</a>
            </div>
          </li><li>
            <div>
              <a title="Get the latest source releases, binary builds and get access to the source repository" class="inactive" href="../downloads.html">Downloads</a>
            </div>
          </li><li>
            <div>
              <a title="Information for users, administrators and developers" class="active" href="../docs.html">Documentation</a>
              <ul class="l1"><li>
                  <div>
                    <a title="How to compile libvirt" class="inactive" href="../compiling.html">Compiling</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Information about deploying and using libvirt" class="inactive" href="../deployment.html">Deployment</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Overview of the logical subsystems in the libvirt API" class="inactive" href="../intro.html">Architecture</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Description of the XML formats used in libvirt" class="inactive" href="../format.html">XML format</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Hypervisor specific driver information" class="inactive" href="../drivers.html">Drivers</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Reference manual for the C public API" class="inactive" href="../html/index.html">API reference</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Bindings of the libvirt API for other languages" class="inactive" href="../bindings.html">Language bindings</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Working on the internals of libvirt API, driver and daemon code" class="active" href="../internals.html">Internals</a>
                    <ul class="l2"><li>
                        <div>
                          <a title="General hacking guidelines for contributors" class="inactive" href="../hacking.html">Contributor guidelines</a>
                        </div>
                      </li><li>
                        <div>
                          <a title="Adding new public libvirt APIs" class="inactive" href="../api_extension.html">API extensions</a>
                        </div>
                      </li><li>
                        <div>
                          <a title="Spawning commands from libvirt driver code" class="inactive" href="../internals/command.html">Spawning commands</a>
                        </div>
                      </li><li>
                        <div>
                          <a title="RPC protocol information and API / dispatch guide" class="inactive" href="../internals/rpc.html">RPC protocol &amp; APIs</a>
                        </div>
                      </li><li>
                        <div>
                          <span class="active">Lock managers</span>
                        </div>
                      </li></ul>
                  </div>
                </li><li>
                  <div>
                    <a title="A guide and reference for developing with libvirt" class="inactive" href="../devguide.html">Development Guide</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Command reference for virsh" class="inactive" href="../virshcmdref.html">Virsh Commands</a>
                  </div>
                </li></ul>
            </div>
          </li><li>
            <div>
              <a title="User contributed content" class="inactive" href="http://wiki.libvirt.org">Wiki</a>
            </div>
          </li><li>
            <div>
              <a title="Frequently asked questions" class="inactive" href="http://wiki.libvirt.org/page/FAQ">FAQ</a>
            </div>
          </li><li>
            <div>
              <a title="How and where to report bugs and request features" class="inactive" href="../bugs.html">Bug reports</a>
            </div>
          </li><li>
            <div>
              <a title="How to contact the developers via email and IRC" class="inactive" href="../contact.html">Contact</a>
            </div>
          </li><li>
            <div>
              <a title="Available test suites for libvirt" class="inactive" href="../testsuites.html">Test suites</a>
            </div>
          </li><li>
            <div>
              <a title="Miscellaneous links of interest related to libvirt" class="inactive" href="../relatedlinks.html">Related Links</a>
            </div>
          </li><li>
            <div>
              <a title="Overview of all content on the website" class="inactive" href="../sitemap.html">Sitemap</a>
            </div>
          </li></ul>
      </div>
      <div id="content">
        <h1>Resource Lock Manager</h1>
        <ul><li>
            <a href="#goals">Goals</a>
          </li><li>
            <a href="#requirement">Requirements</a>
          </li><li>
            <a href="#design">Design</a>
          </li><li>
            <a href="#impl">Plugin Implementations</a>
          </li><li>
            <a href="#qemuIntegrate">QEMU Driver integration</a>
          </li><li>
            <a href="#usagePatterns">Lock usage patterns</a>
            <ul><li>
                <a href="#usageLockAcquire">Lock acquisition</a>
              </li><li>
                <a href="#usageLockAttach">Lock release</a>
              </li></ul>
          </li></ul>
        <p>
      This page describes the design of the resource lock manager
      that is used for locking disk images, to ensure exclusive
      access to content.
    </p>
        <h2>
          <a name="goals" id="goals">Goals</a>
        </h2>
        <p>
      The high level goal is to prevent the same disk image being
      used by more than one QEMU instance at a time (unless the
      disk is marked as shareable, or readonly). The scenarios
      to be prevented are thus:
    </p>
        <ol><li>
        Two different guests running configured to point at the
        same disk image.
      </li><li>
        One guest being started more than once on two different
        machines due to admin mistake
      </li><li>
        One guest being started more than once on a single machine
        due to libvirt driver bug on a single machine.
      </li></ol>
        <h2>
          <a name="requirement" id="requirement">Requirements</a>
        </h2>
        <p>
      The high level goal leads to a set of requirements
      for the lock manager design
    </p>
        <ol><li>
        A lock must be held on a disk whenever a QEMU process
        has the disk open
      </li><li>
        The lock scheme must allow QEMU to be configured with
        readonly, shared write, or exclusive writable disks
      </li><li>
        A lock handover must be performed during the migration
        process where 2 QEMU processes will have the same disk
        open concurrently.
      </li><li>
        The lock manager must be able to identify and kill the
        process accessing the resource if the lock is revoked.
      </li><li>
        Locks can be acquired for arbitrary VM related resources,
        as determined by the management application.
      </li></ol>
        <h2>
          <a name="design" id="design">Design</a>
        </h2>
        <p>
      Within a lock manager the following series of operations
      will need to be supported.
    </p>
        <ul><li>
        <strong>Register object</strong>
        Register the identity of an object against which
        locks will be acquired
      </li><li>
        <strong>Add resource</strong>
        Associate a resource with an object for future
        lock acquisition / release
      </li><li>
        <strong>Acquire locks</strong>
        Acquire the locks for all resources associated
        with the object
      </li><li>
        <strong>Release locks</strong>
        Release the locks for all resources associated
        with the object
      </li><li>
        <strong>Inquire locks</strong>
        Get a representation of the state of the locks
        for all resources associated with the object
      </li></ul>
        <h2>
          <a name="impl" id="impl">Plugin Implementations</a>
        </h2>
        <p>
      Lock manager implementations are provided as LGPLv2+
      licensed, dlopen()able library modules. The plugins
      will be loadable from the following location:
    </p>
        <pre>
/usr/{lib,lib64}/libvirt/lock_manager/$NAME.so
</pre>
        <p>
      The lock manager plugin must export a single ELF
      symbol named <code>virLockDriverImpl</code>, which is
      a static instance of the <code>virLockDriver</code>
      struct. The struct is defined in the header file
    </p>
        <pre>
      #include &lt;libvirt/plugins/lock_manager.h&gt;
    </pre>
        <p>
      All callbacks in the struct must be initialized
      to non-NULL pointers. The semantics of each
      callback are defined in the API docs embedded
      in the previously mentioned header file
    </p>
        <h2>
          <a name="qemuIntegrate" id="qemuIntegrate">QEMU Driver integration</a>
        </h2>
        <p>
      With the QEMU driver, the lock plugin will be set
      in the <code>/etc/libvirt/qemu.conf</code> configuration
      file by specifying the lock manager name.
    </p>
        <pre>
      lockManager="sanlock"
    </pre>
        <p>
      By default the lock manager will be a 'no op' implementation
      for backwards compatibility
    </p>
        <h2>
          <a name="usagePatterns" id="usagePatterns">Lock usage patterns</a>
        </h2>
        <p>
      The following pseudo code illustrates the common
      patterns of operations invoked on the lock
      manager plugin callbacks.
    </p>
        <h3>
          <a name="usageLockAcquire" id="usageLockAcquire">Lock acquisition</a>
        </h3>
        <p>
      Initial lock acquisition will be performed from the
      process that is to own the lock. This is typically
      the QEMU child process, in between the fork+exec
      pairing. When adding further resources on the fly,
      to an existing object holding locks, this will be
      done from the libvirtd process.
    </p>
        <pre>
      virLockManagerParam params[] = {
        { .type = VIR_LOCK_MANAGER_PARAM_TYPE_UUID,
          .key = "uuid",
        },
        { .type = VIR_LOCK_MANAGER_PARAM_TYPE_STRING,
          .key = "name",
          .value = { .str = dom-&gt;def-&gt;name },
        },
        { .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
          .key = "id",
          .value = { .i = dom-&gt;def-&gt;id },
        },
        { .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
          .key = "pid",
          .value = { .i = dom-&gt;pid },
        },
        { .type = VIR_LOCK_MANAGER_PARAM_TYPE_CSTRING,
          .key = "uri",
          .value = { .cstr = driver-&gt;uri },
        },
      };
      mgr = virLockManagerNew(lockPlugin,
                              VIR_LOCK_MANAGER_TYPE_DOMAIN,
                              ARRAY_CARDINALITY(params),
                              params,
                              0)));

      foreach (initial disks)
          virLockManagerAddResource(mgr,
                                    VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
                                    $path, 0, NULL, $flags);

      if (virLockManagerAcquire(lock, NULL, 0) &lt; 0);
        ...abort...
    </pre>
        <h3>
          <a name="usageLockAttach" id="usageLockAttach">Lock release</a>
        </h3>
        <p>
      The locks are all implicitly released when the process
      that acquired them exits, however, a process may
      voluntarily give up the lock by running
    </p>
        <pre>
      char *state = NULL;
      virLockManagerParam params[] = {
        { .type = VIR_LOCK_MANAGER_PARAM_TYPE_UUID,
          .key = "uuid",
        },
        { .type = VIR_LOCK_MANAGER_PARAM_TYPE_STRING,
          .key = "name",
          .value = { .str = dom-&gt;def-&gt;name },
        },
        { .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
          .key = "id",
          .value = { .i = dom-&gt;def-&gt;id },
        },
        { .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
          .key = "pid",
          .value = { .i = dom-&gt;pid },
        },
        { .type = VIR_LOCK_MANAGER_PARAM_TYPE_CSTRING,
          .key = "uri",
          .value = { .cstr = driver-&gt;uri },
        },
      };
      mgr = virLockManagerNew(lockPlugin,
                              VIR_LOCK_MANAGER_TYPE_DOMAIN,
                              ARRAY_CARDINALITY(params),
                              params,
                              0)));

      foreach (initial disks)
          virLockManagerAddResource(mgr,
                                    VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
                                    $path, 0, NULL, $flags);

      virLockManagerRelease(mgr, &amp; state, 0);
    </pre>
        <p>
      The returned state string can be passed to the
      <code>virLockManagerAcquire</code> method to
      later re-acquire the exact same locks. This
      state transfer is commonly used when performing
      live migration of virtual machines. By validating
      the state the lock manager can ensure no other
      VM has re-acquire the same locks on a different
      host. The state can also be obtained without
      releasing the locks, by calling the
      <code>virLockManagerInquire</code> method.
    </p>
      </div>
    </div>
    <div id="footer">
      <p id="sponsor">
	    Sponsored by:<br /><a href="http://et.redhat.com/"><img src="../et.png" alt="Project sponsored by Red Hat Emerging Technology" /></a></p>
    </div>
  </body>
</html>