contrib: Update talk.

This commit is contained in:
Richard W.M. Jones
2011-11-01 17:51:00 +00:00
parent fdcd33a155
commit acd06dbe32
7 changed files with 378 additions and 11 deletions

View File

@@ -7,7 +7,7 @@
counter-reset: chapter;
}
body p {
body > p, body > img, body > pre, body > table {
margin-left: 2em;
}
@@ -26,8 +26,7 @@
}
h2 {
background-color: #f3f3f3;
margin-top: 2em;
margin-top: 4em;
color: rgb(204,0,0);
counter-increment: chapter;
counter-reset: section;
@@ -35,20 +34,20 @@
h2:before {
font-size: 80%;
color: #666;
content: counter(chapter) " ";
content: counter(chapter) " ... ";
}
pre {
background-color: #fcfcfc;
border-top: 1px dotted #888;
border-bottom: 1px dotted #888;
border-left: 6px solid rgb(204,0,0);
border-top: 1px dotted #eee;
border-bottom: 1px dotted #eee;
border-left: 2px solid rgb(204,0,0);
padding: 5px;
margin-left: 1em;
}
p.sourcelnk {
text-align: right;
text-align: left;
font-size: 70%;
}
</style>
@@ -89,7 +88,7 @@ free (fstype);
<table width="100%">
<tr><td valign="top">
<pre style="font-size: 80%;">
<pre>
("<b>vfs_type</b>",
(RString "fstype",
[Device "device"], []),
@@ -110,7 +109,7 @@ For example a string such as C&lt;ext3&gt; or C&lt;ntfs&gt;.");
</td>
<td valign="top">
<pre style="font-size: 80%;">
<pre>
char *
<b>do_vfs_type</b> (const char *device)
{
@@ -175,7 +174,7 @@ get_blkid_tag (const char *device, const char *tag)
<img src="tools.svg" />
<table>
<tr><td valign="top">
<tr><td valign="top" style="padding-bottom: 1.5em;">
<pre>
<b>guestfish -N fs -m /dev/sda1 &lt;&lt;EOF</b>
<font style="color: green;">mkdir /etc
@@ -212,6 +211,80 @@ F15x32:/dev/vg_f15x32/lv_root 5.5G 3.4G 1.8G 63%
<h2>Inspection</h2>
<pre>
$ <b>virt-inspector -c qemu:///system -d Win7x32</b>
<font style="color: #888;">&lt;?xml version="1.0"?&gt;</font>
<font style="color: #888;">&lt;operatingsystems&gt;</font>
<font style="color: #888;">&lt;operatingsystem&gt;</font>
<font style="color: #888;">&lt;root&gt;</font>/dev/sda2<font style="color: #888;">&lt;/root&gt;</font>
<font style="color: #888;">&lt;name&gt;</font>windows<font style="color: #888;">&lt;/name&gt;</font>
<font style="color: #888;">&lt;arch&gt;</font>i386<font style="color: #888;">&lt;/arch&gt;</font>
<font style="color: #888;">&lt;distro&gt;</font>windows<font style="color: #888;">&lt;/distro&gt;</font>
<font style="color: #888;">&lt;product_name&gt;</font>Windows 7 Enterprise<font style="color: #888;">&lt;/product_name&gt;</font>
<font style="color: #888;">&lt;product_variant&gt;</font>Client<font style="color: #888;">&lt;/product_variant&gt;</font>
<font style="color: #888;">&lt;major_version&gt;</font>6<font style="color: #888;">&lt;/major_version&gt;</font>
<font style="color: #888;">&lt;minor_version&gt;</font>1<font style="color: #888;">&lt;/minor_version&gt;</font>
<font style="color: #888;">&lt;windows_systemroot&gt;</font>/Windows<font style="color: #888;">&lt;/windows_systemroot&gt;</font>
<font style="color: #888;">&lt;windows_current_control_set&gt;</font>ControlSet001<font style="color: #888;">&lt;/windows_current_control_set&gt;</font>
<font style="color: #888;">&lt;hostname&gt;</font>win7x32<font style="color: #888;">&lt;/hostname&gt;</font>
<i>... etc ...</i>
</pre>
<p class="sourcelnk"><a href="win7.xml">full&nbsp;XML&nbsp;...</a></p>
<table>
<tr><td colspan="2" align="middle">
<small><i>Click to enlarge the images</i></small>
</td></tr>
<tr><td width="50%">
<a href="virt-manager.png"><img src="virt-manager-t.png"></a>
</td><td width="50%" align="middle" valign="top">
<a href="vmm-icons.png"><img src="vmm-icons-t.png"></a>
</td></tr>
</table>
<pre>
char **roots;
size_t i;
char *type, *distro, *product_name;
int major, minor;
roots = <b>guestfs_inspect_os</b> (g);
if (roots == NULL)
exit (EXIT_FAILURE);
if (roots[0] == NULL) {
fprintf (stderr, "no operating systems found\n");
exit (EXIT_FAILURE);
}
for (i = 0; roots[i] != NULL; ++i) {
type = <b>guestfs_inspect_get_type</b> (g, roots[i]);
distro = <b>guestfs_inspect_get_distro</b> (g, roots[i]);
product_name = <b>guestfs_inspect_get_product_name</b> (g, roots[i]);
major = <b>guestfs_inspect_get_major_version</b> (g, roots[i]);
minor = <b>guestfs_inspect_get_minor_version</b> (g, roots[i]);
printf ("Root: %s\n"
" Type: %s\n"
" Distro: %s\n"
" Version: %d.%d\n"
" Product name: %s\n\n");
roots[i],
type ? : "unknown", distro ? : "unknown", major, minor,
product_name ? : "");
free (type);
free (distro);
free (product_name);
free (roots[i]);
}
free (roots);
</pre>
<p class="sourcelnk"><a href="http://git.annexia.org/?p=libguestfs.git;a=blob;f=rescue/virt-rescue.c;h=0c0036460434f1365d9591d6b2b805d999b07056;hb=HEAD#l351">full&nbsp;source&nbsp;...</a></p>

View File

@@ -5,3 +5,133 @@ distributed before the talk.
----------------------------------------------------------------------
[1 The Idea]
The "big idea" behind libguestfs is to read and write disk
images by reusing all the qemu, Linux kernel and userspace
code.
This gives us tremendous power in a relatively small
library: we can handle all Linux filesystems, all Windows
filesystems, LVM, BSD, containers like raw and qcow, CD ISOs,
USB keys, regular hard disks, and lots more.
If you give us a btrfs filesystem in a BSD partition wrapped
in a qcow2 file -- that is something we can handle.
libguestfs -- as the name suggests -- is a plain, ordinary
shared library written in C that you can link to C programs.
You're all very smart people and you will have guessed
already that we don't in fact run qemu as a library inside
libguestfs as this diagram suggests. Instead we fork
qemu or KVM, running a small "appliance" which has
the usual kernel, a small Linux distribution with tools
like mkfs, lvcreate and parted, and a libguestfs daemon.
The library and the daemon talk to each other over a
virtio-serial connection.
The qemu instance is connected to the disks we are
examining using the ordinary qemu -drive option.
[2 The Stable API]
Consider how you might send commands to the daemon.
Example: Create a filesystem (mkfs).
One thing you might do is to send shell commands over
the virtio-serial connection. It would send "mkfs -t ..."
This is something that is possible using the libguestfs
API, but we don't encourage it. There are three reasons
why we don't encourage and support this: one is that
because we're calling this from a C program, it's hard
to construct shell commands and deal with quoting issues.
Secondly it's hard to parse the result from commands
(think about parted or lvs which are two commands that
produce quite complex output that is hard to parse).
Thirdly the command line isn't very long-term stable,
with some commands appearing and changing over time.
I'd emphasize again that we do let you send shell
commands over to the daemon if that's what you want to do.
What we support, though, is a long-term stable API and ABI.
It's slightly (but not very much) higher level than shell
commands.
I've got an example on the page. This is the guestfs_vfs_type
API which returns the name of the filesystem on a device.
Like libvirt, we are serious about the long term stability
of the API and ABI, and if you write your program against
this API, you'll never have to change the program or even
recompile it.
Because there are 100s of commands that you might want to
run, we made it exceptionally simple to add new APIs.
Shown below is the actual code used to implement "vfs-type".
On the right is the code fragment that runs in the daemon.
This is a short C function which handles constructing the
command line and parsing out the result. Although there
is parsing code here, the good thing is that it only exists
in one place, and we can update it from time to time if
the underlying shell commands change.
On the left is the metadata for this API function. It
has a description of the parameters and return value,
some tests (not shown), and a fragment of documentation.
That's ALL you have to write. From that, we generate
header files, bindings in all the different languages,
RPC for the virtio-serial connection, documentation, etc.
Currently we generate about a quarter of a million lines
of code and documentation.
[3 Tools written around the API]
Around this stable API, myself and the libguestfs team
have written a number of tools. There are also people
in the community writing other tools.
A few of them are shown on this diagram, in fact there
are many more than are shown here.
Starting at the top, "guestfish" is a shell for the API,
letting you write simple shell scripts. If you look at
the code examples below, you can see a small guestfish
script that creates a new raw format partitioned filesystem
with some content.
Going round clockwise:
The libguestfs API is a mix of high-level calls like
mkfs, lvremove, vfs-type; and also low level POSIX calls
like mkdir and writing to files.
"guestmount" lets you mount an existing filesystem from
a guest and access it as a regular mountpoint on the host.
guestmount intelligently caches and prefetches data so it's
quite usable and fast from the command line or graphical
programs like the GNOME Nautilus file browser.
"virt-rescue" lets you use the appliance directly, and
it's a useful way to rescue guests by hand.
You just want to hammer out some shell commands manually.
"virt-win-reg" lets you read and write Windows Registry
entries. There is a rather complex example below right.
Now we come round to the "inspection" tools, and these
three tools let you inspect an unknown guest to find out
what operating system it contains, what applications are
installed, what filesystems, how the filesystems are used
and much more. I cover that in the next section, but if
you look below you'll see an example of running "virt-df".
Finally there are now tools to resize guests, make them
sparse, align them, and check their alignment. These
last tools are ones that we eventually hope will become
obsolete.
[4 Inspection]

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
contrib/intro/vmm-icons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

164
contrib/intro/win7.xml Normal file
View File

@@ -0,0 +1,164 @@
<?xml version="1.0"?>
<operatingsystems>
<operatingsystem>
<root>/dev/sda2</root>
<name>windows</name>
<arch>i386</arch>
<distro>windows</distro>
<product_name>Windows 7 Enterprise</product_name>
<product_variant>Client</product_variant>
<major_version>6</major_version>
<minor_version>1</minor_version>
<windows_systemroot>/Windows</windows_systemroot>
<windows_current_control_set>ControlSet001</windows_current_control_set>
<hostname>win7x32</hostname>
<format>installed</format>
<mountpoints>
<mountpoint dev="/dev/sda2">/</mountpoint>
</mountpoints>
<filesystems>
<filesystem dev="/dev/sda2">
<type>ntfs</type>
<uuid>F2E8996AE8992E3B</uuid>
</filesystem>
</filesystems>
<drive_mappings>
<drive_mapping name="C">/dev/sda2</drive_mapping>
</drive_mappings>
<applications>
<application>
<name>Microsoft .NET Framework 4 Client Profile</name>
<display_name>Microsoft .NET Framework 4 Client Profile</display_name>
<version>4.0.30319</version>
<install_path>C:\Windows\Microsoft.NET\Framework\v4.0.30319\SetupCache\Client</install_path>
<publisher>Microsoft Corporation</publisher>
<url>http://go.microsoft.com/fwlink/?LinkId=164164</url>
</application>
<application>
<name>Mozilla Firefox (3.6.12)</name>
<display_name>Mozilla Firefox (3.6.12)</display_name>
<version>3.6.12 (en-GB)</version>
<install_path>C:\Program Files\Mozilla Firefox</install_path>
<publisher>Mozilla</publisher>
<url>http://www.mozilla.com/en-GB/</url>
<description>Mozilla Firefox</description>
</application>
<application>
<name>VLC media player</name>
<display_name>VLC media player 1.1.5</display_name>
<version>1.1.5</version>
<install_path>C:\Program Files\VideoLAN\VLC</install_path>
<publisher>VideoLAN</publisher>
<url>http://www.videolan.org/</url>
</application>
<application>
<name>{3C3901C5-3455-3E0A-A214-0B093A5070A6}</name>
<display_name>Microsoft .NET Framework 4 Client Profile</display_name>
<version>4.0.30319</version>
<publisher>Microsoft Corporation</publisher>
<url>http://go.microsoft.com/fwlink/?LinkId=164164</url>
</application>
<application>
<name>{3C3901C5-3455-3E0A-A214-0B093A5070A6}.KB2468871</name>
<display_name>Update for Microsoft .NET Framework 4 Client Profile (KB2468871)</display_name>
<version>1</version>
<publisher>Microsoft Corporation</publisher>
<url>http://support.microsoft.com</url>
<description>This update is for Microsoft .NET Framework 4 Client Profile.&#13;
If you later install a more recent service pack, this update will be uninstalled automatically.&#13;
For more information, visit http://support.microsoft.com/kb/2468871.</description>
</application>
<application>
<name>{3C3901C5-3455-3E0A-A214-0B093A5070A6}.KB2518870</name>
<display_name>Security Update for Microsoft .NET Framework 4 Client Profile (KB2518870)</display_name>
<version>1</version>
<publisher>Microsoft Corporation</publisher>
<url>http://support.microsoft.com</url>
<description>This security update is for Microsoft .NET Framework 4 Client Profile.&#13;
If you later install a more recent service pack, this security update will be uninstalled automatically.&#13;
For more information, visit http://support.microsoft.com/kb/2518870.</description>
</application>
<application>
<name>{3C3901C5-3455-3E0A-A214-0B093A5070A6}.KB2533523</name>
<display_name>Update for Microsoft .NET Framework 4 Client Profile (KB2533523)</display_name>
<version>1</version>
<publisher>Microsoft Corporation</publisher>
<url>http://support.microsoft.com</url>
<description>This update is for Microsoft .NET Framework 4 Client Profile.&#13;
If you later install a more recent service pack, this update will be uninstalled automatically.&#13;
For more information, visit http://support.microsoft.com/kb/2533523.</description>
</application>
<application>
<name>{3C3901C5-3455-3E0A-A214-0B093A5070A6}.KB2539636</name>
<display_name>Security Update for Microsoft .NET Framework 4 Client Profile (KB2539636)</display_name>
<version>1</version>
<publisher>Microsoft Corporation</publisher>
<url>http://support.microsoft.com</url>
<description>This security update is for Microsoft .NET Framework 4 Client Profile.&#13;
If you later install a more recent service pack, this security update will be uninstalled automatically.&#13;
For more information, visit http://support.microsoft.com/kb/2539636.</description>
</application>
</applications>
<icon>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</icon>
</operatingsystem>
</operatingsystems>