Compare commits

...

429 Commits

Author SHA1 Message Date
Richard W.M. Jones
1394d4a69b Version 1.19.28. 2012-08-02 17:35:32 +01:00
Richard W.M. Jones
863168467f examples: Use add_drive_opts function in examples.
In libguestfs 1.20, you will be able to use 'add_drive'
instead of 'add_drive_opts' (except in the C bindings).

However until libguestfs 1.20 is the minimum stable version
people will still be using old versions where you have to use
'add_drive_opts'.  This makes the examples confusing.

Therefore continue to use 'add_drive_opts' in the examples
for now.
2012-08-02 17:21:47 +01:00
Richard W.M. Jones
b3d0cc0588 grep: Add optargs to grep API and deprecate fgrep etc.
This commit makes grep into an optargs API, with flags for extended,
fixed, [case-]insensitive and compressed.

At the same time it deprecates: egrep, fgrep, grepi, egrepi, fgrepi,
zgrep, zegrep, zfgrep, zgrepi, zegrepi and zfgrepi.
2012-08-02 14:05:54 +01:00
Wanlong Gao
d40b502876 xfs: add new api xfs-growfs
New api xfs_growfs for expanding a XFS filesystem.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-08-02 10:20:57 +01:00
Richard W.M. Jones
9b9c372114 Revert "appliance: Add '-drive detect-zero=on' flag if qemu supports it."
This reverts commit fe2253088f.
2012-08-01 18:44:19 +01:00
Richard W.M. Jones
981c7b7310 Reviewed and revised TODO file. 2012-07-31 22:55:58 +01:00
Richard W.M. Jones
4efa0f8f38 m4: Sort .gitignore with LANG=C. Also add pipe2.m4 (used by RHEL 6). 2012-07-31 13:41:51 +01:00
Richard W.M. Jones
f21b866f31 build: On x86 search for qemu-system-i386 not qemu-system-i686.
host_cpu can be set to i686.  The qemu binary is called
qemu-system-i386.  Apply some sed to fix this.
2012-07-31 13:36:01 +01:00
Eric Blake
06780a92b3 build: Allow building with new glibc headers and -O0.
This is a patch taken from libvirt.  See:

http://libvirt.org/git/?p=libvirt.git;a=commitdiff;h=2af63b1c349
2012-07-31 13:15:34 +01:00
Richard W.M. Jones
499497fab0 9p: Add a regression test for 9p functionality in qemu. 2012-07-30 23:49:47 +01:00
Richard W.M. Jones
77326fa4ad appliance: Exclude kernel* packages explicitly.
febootstrap >= 3.19 will no longer exclude the kernel package
by default.
2012-07-30 23:49:47 +01:00
Richard W.M. Jones
54db02b60a Version 1.19.27. 2012-07-30 19:27:09 +01:00
Richard W.M. Jones
7b2f6bd665 libguestfs-make-fixed-appliance: Don't reference obsolete development version. 2012-07-30 17:32:10 +01:00
Richard W.M. Jones
b075b4d1fe New API: utsname
Typical output:

><fs> utsname
uts_sysname: Linux
uts_release: 3.5.0-1.fc18.x86_64
uts_version: #1 SMP Mon Jul 23 17:43:39 UTC 2012
uts_machine: x86_64
2012-07-30 15:16:45 +01:00
Richard W.M. Jones
b61a8a50bc sysprep: Describe more directly how to use qemu-img for snapshotting. 2012-07-28 21:28:23 +01:00
Richard W.M. Jones
dcc0ebc8e0 tests: Consistent use of $(top_builddir)/run --test when building test guests. 2012-07-26 22:02:07 +01:00
Richard W.M. Jones
590774ed9e build: Use $(top_builddir)/run in Makefile.am's.
Not necessary, but this makes all invocations of 'run' consistent.
There is no functional change.
2012-07-26 21:58:17 +01:00
Richard W.M. Jones
96d34d883f Version 1.19.26. 2012-07-26 19:01:28 +01:00
Richard W.M. Jones
fe2253088f appliance: Add '-drive detect-zero=on' flag if qemu supports it.
NB: The patch to implement this feature in qemu is not upstream, and
may never make it upstream.  However this is so useful for
virt-sparsify that I decided to add this to libguestfs while we see
what qemu decides to do.
2012-07-26 18:33:37 +01:00
Richard W.M. Jones
0f837ec068 ruby: Allow optional arguments hash to be really optional.
Allow optargs functions to be called as either:

  g.mkfs_opts(fs, device)

or:

  g.mkfs_opts(fs, device, { optargs hash })

This also preserves backwards compatibility with once_has_no_optargs
functions such as mkfs.
2012-07-26 11:57:02 +01:00
Richard W.M. Jones
5f30912d74 ruby: In event wrapper, ignore callback functions which have type T_ZOMBIE.
Note that in old versions of Ruby, T_ZOMBIE was not defined.
2012-07-26 11:56:49 +01:00
Richard W.M. Jones
7b84b49603 ruby: Set LD_LIBRARY_PATH for Ruby libs in run script.
This lets you use './run gdb ruby ...' and get accurate
debugging information.
2012-07-25 22:56:54 +01:00
Richard W.M. Jones
208d1c1a09 sparsify: Detect qemu-img version and use qcow2 v3 for overlay if available.
qcow2 v3 is generally more efficient, although unfortunately it
doesn't support automatically sparsifying zero writes.

Note this *only* uses qcow2 v3 for the intermediate overlay file, not
for the final output (since we want the output to be broadly
compatible with old hypervisors).
2012-07-25 16:51:42 +01:00
Richard W.M. Jones
0b3b5f984c sparsify: Change code that generates qemu-img -o argument.
This is just code motion.
2012-07-25 16:28:12 +01:00
Richard W.M. Jones
42bf3274e4 sysprep: Generate new random UUIDs for LVM2 PVs and VGs (thanks Kazuo Moriwaka). 2012-07-25 14:47:15 +01:00
Richard W.M. Jones
e64bf3fb29 New APIs: pvchange-uuid, pvchange-uuid-all, vgchange-uuid, vgchange-uuid-all.
These APIs will allow sysprep to change the UUIDs of all PVs and VGs
in the system.

LVs don't have UUIDs AFAICT, or at least there seems to be no way to
change them if they do have them.
2012-07-25 14:47:15 +01:00
Richard W.M. Jones
2b59b5f1d2 sysprep: Change perform callback to perform_on_filesystems and perform_on_devices.
Operations that need to work directly on guest block devices will fail
because the block devices are busy.  Therefore add a phase with the
filesystems unmounted, and allow operations to specify that they need
to work in this phase.
2012-07-25 14:47:15 +01:00
Matthew Booth
1fb95e6566 fish: Use minimal permissions when initially creating history file 2012-07-25 14:17:37 +01:00
Richard W.M. Jones
b7ff02354d sysprep: Tidy up the Makefile.
This is just code motion.
2012-07-25 10:15:47 +01:00
Richard W.M. Jones
4fa51f11da sysprep: operation machine-id: return `Created_files.
This operation can create the /etc/machine-id file, so it may need to
be relabelled by SELinux.

This fixes commit e68336d72a.
2012-07-25 10:09:28 +01:00
Wanlong Gao
e68336d72a sysprep: remove the local machine ID
remove the local machine ID, leave it empty, let it be generated
during next booting.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>

RWMJ:
 - Whitespace change.
 - Remove completed items from TODO.
2012-07-25 08:56:38 +01:00
Wanlong Gao
a121f1d654 sysprep: remove the auto generated abrt data
remove the automatically generated abrt data.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>

RWMJ:
 - Remove copy and pasted line.
 - Use C<> in description.
2012-07-25 08:55:20 +01:00
Masami HIRATA
d74e7fad28 Mac OS X: Use u_int64_t/uint64_t instead of unsigned hyper in .x file
Signed-off-by: Masami HIRATA <msmhrt@gmail.com>

RWMJ:
  Fixed whitespace in generator_xdr.ml
2012-07-24 19:40:40 +01:00
Masami HIRATA
61c9ea496e Mac OS X: Use libtool --mode=execute instead of LD_LIBRARY_PATH
because Mac OS X doesn't support LD_LIBRARY_PATH

Signed-off-by: Masami HIRATA <msmhrt@gmail.com>
2012-07-24 19:40:40 +01:00
Masami HIRATA
7d3f190d90 Mac OS X: Use gnulib stat-time module explicitly.
Signed-off-by: Masami HIRATA <msmhrt@gmail.com>
2012-07-24 19:40:40 +01:00
Masami HIRATA
a887dd5109 lib: Use <sys/socket.h> and <sys/un.h> for sockaddr_un
Signed-off-by: Masami HIRATA <msmhrt@gmail.com>
2012-07-24 19:40:39 +01:00
Masami HIRATA
399887defd Mac OS X: Use real files for gtk-doc (not the symlink)
Signed-off-by: Masami HIRATA <msmhrt@gmail.com>
2012-07-24 19:40:39 +01:00
Masami HIRATA
9519c60ce5 Mac OS X: don't check glibc-style extended printf formatters unless --enable-daemon
Signed-off-by: Masami HIRATA <msmhrt@gmail.com>

RWMJ:
 - Test was in the wrong place (before --enable-daemon had been
   detected) so I moved it later.
2012-07-24 19:40:14 +01:00
Masami HIRATA
7dab208765 Mac OS X: #define UNIX_PATH_MAX 104
See http://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man4/unix.4.html

Signed-off-by: Masami HIRATA <msmhrt@gmail.com>
2012-07-24 19:18:37 +01:00
Masami HIRATA
6e3f8d2511 Mac OS X: Added check of #include <endian.h>
Mac OS X doesn't have endian.h

Signed-off-by: Masami HIRATA <msmhrt@gmail.com>
2012-07-24 19:18:37 +01:00
Masami HIRATA
a47fa7a65e Mac OS X: Use gnulib fstatat module explicitly.
Signed-off-by: Masami HIRATA <msmhrt@gmail.com>
2012-07-24 19:18:37 +01:00
Masami HIRATA
d6ef91d7c4 Mac OS X: Use gnulib memmem module explicitly.
m4/.gitignore: Update.

Signed-off-by: Masami HIRATA <msmhrt@gmail.com>
2012-07-24 19:18:37 +01:00
Masami HIRATA
ef1a8446a6 configure: Use $(PERL) instead of perl
Signed-off-by: Masami HIRATA <msmhrt@gmail.com>
2012-07-24 19:18:36 +01:00
Masami HIRATA
8f3a839aa8 configure: Add -nographic command line option to qemu.
Without this option, configure will fail when there is no display.

Signed-off-by: Masami HIRATA <msmhrt@gmail.com>
2012-07-24 19:18:36 +01:00
Richard W.M. Jones
ebe826f23f Version 1.19.25. 2012-07-24 14:48:39 +01:00
Richard W.M. Jones
67e1c90605 launch: libvirt: Suppress printing of libvirt errors to stderr and other cleanups. 2012-07-24 14:26:55 +01:00
Richard W.M. Jones
493e80ab4e launch: libvirt: Use SELinux-mandated directory for sockets (RHBZ#842307).
Note this does not yet enable sVirt confinement of the appliance.
That requires at least that SELinux policy goes upstream, plus there
may still be bugs.
2012-07-24 14:03:36 +01:00
Richard W.M. Jones
97aeaa86d0 todo: More suggestions for virt-sysprep (thanks Kazuo Moriwaka). 2012-07-24 13:42:06 +01:00
Richard W.M. Jones
5d0ef09963 launch: libvirt: Move free to end of function.
This is just code motion.
2012-07-24 13:01:08 +01:00
Richard W.M. Jones
507aa9ac35 launch: libvirt: Add is_blk utility.
This is just code motion.
2012-07-24 13:01:08 +01:00
Wanlong Gao
d8b2c1afee umount: use Dev_or_Path for the argument type
Use Dev_or_Path instead of String.

Remove the RESOLVE_DEVICE since Dev_or_Path will generate
REQUIRE_ROOT_OR_RESOLVE_DEVICE instead.

RWMJ:
Note a change in semantics: this now requires root.  However this is
OK and still works with mkmountpoint and friends because
'is_root_mounted' works even if something is mounted below the root.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-07-24 13:01:08 +01:00
Richard W.M. Jones
c03cdcc25c launch: libvirt: Set <emulator> in libvirt XML if g->qemu is not the default. 2012-07-24 10:21:32 +01:00
Richard W.M. Jones
40e5317cfb xfs-info: Fix description to refer to 'pathordevice' param. 2012-07-24 10:16:31 +01:00
Wanlong Gao
f4094b91d2 xfs_info: resolve device when doing xfs_info on a device
Resolve device first, like do_umount.
Use Dev_or_Path.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-07-24 10:10:30 +01:00
Wanlong Gao
bda974e64c umount: add force umount and lazy umount
Add the option force and lazy for force and lazy umount.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-07-24 09:06:27 +01:00
Richard W.M. Jones
6bdc4b30ea Version 1.19.24. 2012-07-23 21:53:55 +01:00
Richard W.M. Jones
2b059535b1 tests: Skip regression test for 790721 if attach-method is not 'appliance'. 2012-07-23 21:41:47 +01:00
Richard W.M. Jones
941ec968b8 lib: Initialize libvirt and libxml2 once when the library loads. 2012-07-23 21:26:18 +01:00
Richard W.M. Jones
bf00be0e17 launch: Make get-pid and max-disks APIs into virtual methods of the current attach-method. 2012-07-23 20:17:25 +01:00
Richard W.M. Jones
3614d76b37 tests: Move debug-drives testing API to launch.c and change the output.
It should work with any attach-method.
2012-07-23 20:17:24 +01:00
Richard W.M. Jones
a6366f5dae python: Set file encoding to utf-8. 2012-07-23 20:17:24 +01:00
Richard W.M. Jones
bc917a0efc tests/protocol: Skip these tests if default attach-method is not 'appliance'. 2012-07-23 18:44:07 +01:00
Richard W.M. Jones
b6afb98a79 tests: Fix get-attach-method test.
If ./configure --with-default-attach-method is set to something other
than 'appliance', then this will legitimately return a different
string.  Simply test that it runs, rather than testing the output.

This fixes commit 20a5b4de7d.
2012-07-23 18:44:07 +01:00
Richard W.M. Jones
c65ee25a75 tests: Remove get-pid test.
If the libvirt attach-method is used, then there is no known PID
(libvirt hides it).
2012-07-23 18:44:02 +01:00
Richard W.M. Jones
0a1b2f85e6 launch: libvirt: Use <driver name="qemu" type=[format] />.
We were using format= which was bogus and libvirt was ignoring it and
forcing raw format instead.

Also in its default configuration libvirt won't do disk format
autodetection at all, so we must do it instead.
2012-07-23 18:08:16 +01:00
Richard W.M. Jones
f9e484ca45 launch: libvirt: You can't set O_CLOEXEC flag using fcntl + F_SETFL.
And in any case there is no point, since proto.c already sets the
SOCK_CLOEXEC flag (using accept4) on this socket.

The code now matches the code in launch-appliance.c.
2012-07-23 18:08:16 +01:00
Richard W.M. Jones
793a482015 launch: libvirt: Use accept4 to set socket flags correctly. 2012-07-23 18:08:16 +01:00
Richard W.M. Jones
5fb0f4e07e launch: libvirt: Add <on_reboot>destroy</on_reboot> to libvirt XML.
This causes libvirt to add the qemu -no-reboot option, which
reflects existing behaviour.
2012-07-23 16:43:14 +01:00
Richard W.M. Jones
20a5b4de7d launch: Allow default attach-method to be set in environment or configure.
You can now choose the default attach method in two ways:

(1) Set the LIBGUESTFS_ATTACH_METHOD environment variable.

(2)  ./configure --with-default-attach-method=appliance|libvirt|...

Note that (1) overrides (2).
2012-07-23 15:24:57 +01:00
Richard W.M. Jones
7a691e6665 java: Set '-encoding utf8' for javac and javadoc commands. 2012-07-23 15:24:07 +01:00
Richard W.M. Jones
7f519bdc06 java: JAVAC_FLAGS -> EXTRA_JAVAC_FLAGS.
This is just a rename.
2012-07-23 15:18:12 +01:00
Richard W.M. Jones
99f108b840 launch: libvirt: Move remaining to-do items to TODO file. 2012-07-23 14:28:03 +01:00
Richard W.M. Jones
68836022d2 launch: libvirt: Add a hack to detect if KVM is available.
We need to select the <domain type=...> attribute depending on whether
KVM is detected in the libvirt capabilities.

This is a hack because it doesn't try to parse the libvirt
capabilities XML.
2012-07-23 13:14:16 +01:00
Richard W.M. Jones
890a4fbc87 launch: libvirt: Use <cpu model="host-model"/> (thanks Dan Berrange).
This ensures maximum performance of the appliance, particularly for
things like MD where the guest needs to use optimal SSE instructions.
2012-07-23 13:05:46 +01:00
Richard W.M. Jones
67f7a30cc9 launch: libvirt: Change disk XML according to whether host path is device or file (thanks Dan Berrange). 2012-07-23 13:02:25 +01:00
Richard W.M. Jones
f2d7305091 launch: libvirt: Use "guestfs-" prefix on random names (thanks Dan Berrange). 2012-07-23 12:46:37 +01:00
Richard W.M. Jones
ef75c4c568 launch: libvirt: Enforce minimum version of libvirt 0.9.13. 2012-07-23 12:45:31 +01:00
Richard W.M. Jones
524bb29526 launch: libvirt: Use snapshot=on instead of <readonly/>.
For compatibility with the appliance backend, devices added readonly
are in fact added writable with snapshots on top.  This is necessary
because options like 'mount -o ro' usually require write access to the
disk (eg. to replay journals).
2012-07-23 12:37:22 +01:00
Richard W.M. Jones
abcd6f0c15 Version 1.19.23. 2012-07-22 14:40:43 +01:00
Richard W.M. Jones
aa0efa9eb4 launch: Add libvirt backend.
Complete the attach-method libvirt backend.

This backend uses libvirt to create a transient KVM domain to run the
appliance.

Note that this still will only work with local libvirt URIs since the
<kernel>, <initrd> and appliance links in the libvirt XML refer to
local files, and virtio serial only works locally (limitation of
libvirt).  Remote support will be added later.
2012-07-22 09:32:04 +01:00
Richard W.M. Jones
42ba262003 Add attach-method "libvirt" or "libvirt:<URI>".
With this commit, you can set the attach method to libvirt,
but calling launch will give an error.
2012-07-21 15:47:50 +01:00
Richard W.M. Jones
f32b93416a launch: Make 'drive_name' into a common function.
This is just code motion.
2012-07-21 15:47:50 +01:00
Richard W.M. Jones
fa3b204f4a appliance: Push appliance building lock into guestfs___build_appliance.
Since we will be calling guestfs___build_appliance from the libvirt
code in future, there's no point having two places where we have to
acquire the lock.  Push the lock down into this function instead.

Because "glthread/lock.h" includes <errno.h> we have to add this
header to the file too.
2012-07-21 14:26:24 +01:00
Wanlong Gao
a58368b3db fuse:remove the unused macro when fuse is not available
Just make gcc happy when fuse is not available.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-07-21 08:30:44 +01:00
Richard W.M. Jones
ec8e3b6cad launch: Abstract attach method operations.
g->attach_ops points to a structure which contains the
operations supported by each attach method backend
(ie. appliance, unix, etc.).
2012-07-20 15:10:46 +01:00
Richard W.M. Jones
08cad54349 launch: Move the command line building code entirely into launch-appliance.c.
Although we still use the handle as convenient temporary
storage.
2012-07-20 13:49:10 +01:00
Richard W.M. Jones
52fa23d74f launch: Move guestfs_config API and build list of qemu parameters in handle.
Move and rewrite guestfs_config so it accumulates a list of qemu
parameters in the handle.  These are added to the appliance at launch
time (with attach method == unix:...  you'll now get an error).
2012-07-20 13:43:55 +01:00
Richard W.M. Jones
4df6beee54 launch: Move launch timing / messages code into launch.c. 2012-07-20 13:43:13 +01:00
Richard W.M. Jones
54fd9a10a6 lib: Use bool (from <stdbool.h>) for a few fields in the handle. 2012-07-20 13:43:13 +01:00
Richard W.M. Jones
709e28e6d5 lib: Rearrange fields in guestfs handle.
Arrange the fields more logically.  This is just code motion.
2012-07-20 13:43:13 +01:00
Richard W.M. Jones
a6e0e0d6bf add-cdrom: Rewrite description emphasising that this API should not be used. 2012-07-20 13:43:13 +01:00
Richard W.M. Jones
184b9d7c11 ocaml: Skip mount-local test if /dev/fuse is not writable. 2012-07-20 08:35:13 +01:00
Richard W.M. Jones
9d314c7c3f launch: Remove some dead code from the appliance method. 2012-07-19 19:06:23 +01:00
Richard W.M. Jones
4c261da5ba lib: Split launch.c into separate files.
launch-appliance.c contains the code associated with the 'appliance'
attach-method.  Mostly.  In fact there are a few APIs which don't fit
so nicely:

 - config: deprecated API which fiddles with the qemu command
   line directly

 - max-disks: depends on the qemu implementation (virtio-scsi
   or not)

 - debug-drives: used for testing only

launch-unix.c contains the code associated with 'unix:<path>'.

launch.c is the common code for launching, along with a few other APIs
such as guestfs_add_drive_opts.

This commit also reduces the number of headers to just those
which are required.
2012-07-19 17:49:25 +01:00
Richard W.M. Jones
80d102c49d Remove debug-cmdline API.
Note that debug* calls are not part of the stable API and can be
removed or changed at any time.
2012-07-19 17:12:44 +01:00
Richard W.M. Jones
eca544d87d lib: Use safe_asprintf when constructing attach_method.
Just a small code cleanup / simplification.
2012-07-19 16:26:06 +01:00
Richard W.M. Jones
2e4089f300 build: Rename most C files that contain underscore with dash.
This is just code motion.

Some files cannot be renamed.  Notably rpcgen input and output files
must not contain dash characters, else rpcgen breaks.
2012-07-19 16:11:47 +01:00
Richard W.M. Jones
6054051a9d fish: Rename fish/virt.c to fish/domain.c
This file handles the -d option for guestfish and other C command line
utilities.  Renaming this file makes it less confusing.
2012-07-19 16:11:26 +01:00
Richard W.M. Jones
d1d29ab488 build: Rename src/virt.c to src/libvirtdomain.c
This file contains the code implementing guestfs_add_domain
(for adding a libvirt domain) so this name is less confusing.
2012-07-19 16:11:26 +01:00
Richard W.M. Jones
d88f4ca634 build: Arrange libguestfs_la_SOURCES in order. 2012-07-19 16:11:26 +01:00
Richard W.M. Jones
a8b4ea1f0c Remove references to long-obsolete Ocaml_inspector module from .gitignore. 2012-07-19 16:11:24 +01:00
Richard W.M. Jones
f514d462cd podwrapper: Fix setting of GIT_DIR in git subcommand.
This fixes commit 1e17a32060.
2012-07-19 16:10:48 +01:00
Richard W.M. Jones
805d642565 license: Use latest license files from gnu.org.
COPYING from https://www.gnu.org/licenses/gpl-2.0.txt
COPYING.LIB from https://www.gnu.org/licenses/lgpl-2.1.txt

(Note this change shouldn't alter the licensing of libguestfs)
2012-07-19 14:17:31 +01:00
Richard W.M. Jones
719297a220 Version 1.19.22.
Includes rebuilt gnulib to work around test problems with
test-getlogin_r.
2012-07-19 13:51:16 +01:00
Richard W.M. Jones
6e1b5f0fea gnulib: Don't include or run getlogin_r test (thanks Jim Meyering).
See:
https://lists.gnu.org/archive/html/bug-gnulib/2012-07/msg00194.html
2012-07-19 12:43:55 +01:00
Richard W.M. Jones
fc86db3b3b build: Return 77 from skipped tests. 2012-07-19 11:22:40 +01:00
Richard W.M. Jones
1b94ea204d Version 1.19.21. 2012-07-18 21:51:20 +01:00
Richard W.M. Jones
a0a517869c tests: Rewrite parallel mount-local test in C. 2012-07-18 20:09:40 +01:00
Richard W.M. Jones
eef11f33f9 ocaml: Test mount-local, without parallel test.
Unfortunately the parallel test keeps hitting this bug:
https://bugzilla.redhat.com/show_bug.cgi?id=838081
which could be a bug in the OCaml runtime.

Just test simple mount-local.  We will write a parallel test in C to
replace this.
2012-07-18 13:45:21 +01:00
Richard W.M. Jones
50780a84f6 tar-in: Add --no-same-owner flag to tar command when target filesystem doesn't support chown (RHBZ#840572).
When using tar-in or tools built around it such as virt-make-fs, if
the target filesystem is vfat then unpacking the tarball would fail
because tar tries to chown(2) files and fails.

You would see errors such as:

tar: <file>: Cannot change ownership to uid 500, gid 500: Operation not permitted

This change detects whether the target filesystem supports chown(2).
If not, it adds the --no-same-owner flag to tar to stop it from trying
to change the ownership of newly created files.
2012-07-18 12:33:16 +01:00
Richard W.M. Jones
781857a86b daemon: Make 'random_name' into a utility function.
This is mostly code motion, although the precise contract of this
function changes slightly to make it more generally useful
2012-07-18 12:32:21 +01:00
Richard W.M. Jones
9c2b9c2df6 virt-make-fs: Suggest guestfish for complex layouts in man page. 2012-07-18 11:14:19 +01:00
Richard W.M. Jones
b25aea33fa build: Change how make.sh, packagelist, excludelist are updated.
Add proper dependencies for these files, but also use 'cmp' to ensure
they only get overwritten if the new files have actually changed, so
we don't rebuild the appliance unnecessarily.
2012-07-18 10:03:29 +01:00
Wanlong Gao
87206e4e9e New API: add new api xfs_info
Add xfs_info to show the geometry of the xfs filesystem.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>

RWMJ:
 - Updated po/POTFILES.
 - Use xfs_ prefix for all struct fields.
 - Return uninitialized fields as -1 / empty string.
 - Copyedit the description.
2012-07-18 09:37:17 +01:00
Wanlong Gao
2f89f584c0 augeas: make functions as noreturn
Just make gcc happy.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-07-18 09:05:32 +01:00
Richard W.M. Jones
8e75e21b23 podwrapper: Use UTF8 in output, send errors to stderr.
This fixes commit 1e17a32060.
2012-07-17 20:04:24 +01:00
Richard W.M. Jones
d76ea07814 Version 1.19.20. 2012-07-17 15:38:52 +01:00
Richard W.M. Jones
973581780d case_sensitive_path: Allow trailing path element to be missing (RHBZ#840115).
case_sensitive_path is undefined when the final path element doesn't
exist.  Currently it returns an error, but this means that creating a
new file doesn't work as expected:

  $ guestfish --rw -i -d windows touch 'win:c:\blah'
  libguestfs: error: case_sensitive_path: blah no file or directory found with this name

We should allow this case (provided there is no trailing slash) so
that new files or directories can be created.
2012-07-17 14:37:03 +01:00
Richard W.M. Jones
ac0373bdec case_sensitive_path: Move variables to top of function.
This is just code motion.
2012-07-17 13:46:48 +01:00
Richard W.M. Jones
4bc110e2bc docs: Use L<...> for links.
Instead of working around bugs, podwrapper has been fixed so that
links work in all output formats.
2012-07-17 13:18:39 +01:00
Richard W.M. Jones
182b4a6660 podwrapper: Subclass Pod::Man so we can fix the way links are generated. 2012-07-17 13:18:34 +01:00
Richard W.M. Jones
9967ad3fa1 podwrapper: Define $VERSION in subclass.
The superclass sometimes uses this and will give an undefined
error if it's missing.
2012-07-17 13:18:34 +01:00
Richard W.M. Jones
60c42dd2a1 podwrapper: Tidy up the program name.
Messages now look like this:

  podwrapper.pl: wrote guestfs-examples.3
  podwrapper.pl: wrote ../html/guestfs-examples.3.html
2012-07-17 13:18:34 +01:00
Richard W.M. Jones
f6846d74c9 perl: In examples, call $g->shutdown, $g->close. 2012-07-17 12:34:51 +01:00
Richard W.M. Jones
a99ea198b2 perl: Use $g instead of $h in documentation.
$g is the "standard" name for libguestfs handles.
2012-07-17 12:33:45 +01:00
Richard W.M. Jones
8d0baf7b85 docs: febootstrap is in section 8 of the manual, not section 1. 2012-07-16 23:04:17 +01:00
Richard W.M. Jones
1e17a32060 Replace podwrapper shell script with custom Perl script.
This uses Pod::Simple so it properly parses the input POD and can
generate proper custom output as required specifically by libguestfs.

One immediate benefit is that links between and within manual pages
now work mostly correctly.
2012-07-16 22:53:01 +01:00
Richard W.M. Jones
0bf1e5b665 Fix pod.css for new HTML output from Perl 5.16.
There used to be a <div> around the table of contents, but that
is no longer present.
2012-07-16 22:13:24 +01:00
Richard W.M. Jones
3a442e6617 configure: Make generated files read-only.
Some of the generated files anyway.
2012-07-16 21:58:34 +01:00
Richard W.M. Jones
f2ea617e22 build: Change calls to podwrapper.sh to use $(PODWRAPPER).
This will allow us to easily change the location of this
script in future.
2012-07-16 18:56:57 +01:00
Richard W.M. Jones
c7d342a94a virt-make-fs: Add --floppy option to make preconfigured vfd's. 2012-07-16 16:47:44 +01:00
Richard W.M. Jones
24b7979ea2 virt-make-fs: Recognize "msdos" as a partition or filesystem type.
Set MBR partition type byte accordingly.
2012-07-16 16:26:26 +01:00
Richard W.M. Jones
d69a03e448 Revert "ocaml: Calling Gc.compact before g#mount_local works around RHBZ#838081."
This reverts commit ad7c4498f6.

Reverted because we still see core dumps.
2012-07-16 14:01:46 +01:00
Richard W.M. Jones
2bd080fd5a Version 1.19.19. 2012-07-16 13:29:40 +01:00
Richard W.M. Jones
98f2d221cf run: Update comments. 2012-07-16 13:29:39 +01:00
Richard W.M. Jones
95d26f0240 generator: Rename 'ntfsresize_opts' API to 'ntfsresize'.
By using the once_had_no_optargs flag, this change is backwards
compatible for callers.
2012-07-14 13:08:21 +01:00
Richard W.M. Jones
e055bf4cab generator: Rename 'mkfs_opts' API to 'mkfs'.
By using the once_had_no_optargs flag, this change is backwards
compatible for callers.
2012-07-14 12:43:13 +01:00
Richard W.M. Jones
7486fc6f43 generator: Rename 'add_drive_opts' API to 'add_drive'.
By using the once_had_no_optargs flag, this change is backwards
compatible for callers (except Haskell, PHP and GObject as discussed
in earlier commit).
2012-07-14 12:42:24 +01:00
Richard W.M. Jones
b48ae2eadf generator: In non-C bindings, generate '*_opts' alias.
In C, a function called 'func' which has once_had_no_optargs=true will
(because of the previous commit) generate 'func_opts' and a
backwards-compatibility function called 'func'.

This commit changes some of the non-C bindings so that they also
generate 'func_opts' which is merely a wrapper that calls 'func'.

This avoids incompatibility when we rename 'mkfs_opts' etc back to
plain 'mkfs', and it also makes it easier to translate between other
language bindings and C code.

NB: Some bindings do not include aliases:

  PHP:     There's no way to easily alias methods in PHP < 5.3, and we
           can't assume everyone has this minimum version.

  GObject: Very complex to add aliases, but we should probably do this
           at some point.

  Haskell: No support for optargs in these bindings.  Unfortunately
           this means that we can no longer bind 'Guestfs.add_drive'
           (since it will be changed to add optional arguments) making
           the Haskell bindings even less useful than they were already.
2012-07-14 11:13:49 +01:00
Richard W.M. Jones
98757e151a generator: Allow non-optargs functions to gain optargs.
This commit adds a flag (once_had_no_optargs) which can be used to add
optargs to functions that currently don't have any.

The idea is that if 'func' currently has no optargs, we can safely add
optargs provided we are backwards compatible for existing callers.

In C that means we leave 'guestfs_func' alone and provide an extra
function 'guestfs_func_opts' that takes the optargs ('guestfs_func'
becomes a wrapper that calls 'guestfs_func_opts').

In the C generator this means there are two names for each function
(although the two names are normally identical).  'c_name' is the name
that we export publicly (eg. [guestfs_] 'func_opts').  'name' is the
internal name of the function (eg. 'func') which is used for
everything apart from the public interface, and also to generate the
no-optargs compat function.

In other languages that can add optional arguments safely, we simply
add the arguments to the existing 'func', so for example in Perl:

  $g->func (required_args)
  $g->func (required_args, optional_args)

can be used.

Note that this commit does not cause any change to the output of the
generator.  I verified this by diffing the output before and after.
2012-07-14 10:20:58 +01:00
Richard W.M. Jones
9eb6060456 generator: Rearrange some C generator code into sub-functions.
This is just code motion.  I verified this by comparing the
generator output before and after this commit.
2012-07-13 14:02:43 +01:00
Richard W.M. Jones
0da2dbef26 java: Generate overloaded non-optargs method for each optargs method.
For example the existing method:

  public void mkfs_opts (String fstype, String device, Map<..> optargs);

is now accompanied by this overloaded method which is a simple wrapper:

  public void mkfs_opts (String fstype, String device)
    throws LibGuestFSException
  {
    mkfs_opts (fstype, device, null);
  }
2012-07-13 14:02:43 +01:00
Richard W.M. Jones
60805c9217 generator: Add c_optarg_prefix for each action.
This updates commit 9286f556c6.
2012-07-13 09:00:25 +01:00
Richard W.M. Jones
9286f556c6 generator: Add c_function (C function name) to each action struct.
This field, which is generated internally by the generator, is the
name of the C function corresponding to each action.

For actions that have NO optional arguments, it's just "guestfs_<name>".

For actions that have any optional arguments, it is
"guestfs_<name>_argv" (since any binding has to construct the optional
argument struct explicitly).

In a future commit, this mapping may become more complex.

This commit also "fixes" the C# bindings which didn't handle optional
arguments properly at all.  In fact, it doesn't fix this, it just
changes it enough that it probably now compiles.  We should either
compile and test the bindings routinely with Mono, or drop them, since
they are starting to bit-rot.

In the GObject bindings, I have added a space between the C function
name and the first paren.

Apart from the C# and GObject changes, this is just code motion.  It
was verified by diffing the output of the generator before and after.
2012-07-12 12:50:49 +01:00
Richard W.M. Jones
e80f368732 generator: Change the way that camel-case names are generated.
Store the camel-case name directly in the struct instead
of generating it on the fly in only the GObject bindings.

This is just code motion.  Tested by verifying that the generator
output is identical.
2012-07-12 11:11:31 +01:00
Richard W.M. Jones
e452a0b8ca tests: Rename test0* functions as internal_test*.
The internal_* prefix is reserved for internal functions
such as these tests.
2012-07-11 23:56:10 +01:00
Richard W.M. Jones
7a0478bed0 tests: Better way to ensure 'g' is used and return success or error. 2012-07-11 23:55:11 +01:00
Richard W.M. Jones
39d1a7dbc9 generator: Use a struct instead of a tuple to describe each action.
Each action changes from a tuple like this:

  ("cat", (RString "content", [Pathname "path"], []), 4,
   [ProtocolLimitWarning],
   [InitISOFS, Always, TestOutput (
      [["cat"; "/known-2"]], "abcdef\n")],
   "list the contents of a file",
   "[...]");

to a slightly longer but more readable struct:

  { defaults with
    name = "cat";
    style = RString "content", [Pathname "path"], [];
    proc_nr = Some 4;
    protocol_limit_warning = true;
    tests = [
      InitISOFS, Always, TestOutput (
      [["cat"; "/known-2"]], "abcdef\n")
    ];
    shortdesc = "list the contents of a file";
    longdesc = "[...]" };

["defaults" is a struct which contains the defaults for every field,
allowing us to use the "{ defaults with ... }" syntax to just update
the fields we want to be different from the defaults.]

This is a mechanical change and there is no change to the output of
the generator.  I checked the output before and after with diff to
verify this.  There are no changes in the output apart from UUIDs
which are expected to change with each run.
2012-07-11 19:55:16 +01:00
Richard W.M. Jones
7b619d47f6 todo: Tidy up test0 functions. 2012-07-11 15:05:57 +01:00
Richard W.M. Jones
196742cd46 generator: Add a note in generator/README about safely extending functions. 2012-07-11 10:47:18 +01:00
Richard W.M. Jones
cf0defedb8 generator: Move note in comment to generator/README file. 2012-07-11 10:46:56 +01:00
Richard W.M. Jones
ec0c7e0a1a fuse: Cleaner code and documentation for safe cleanups. 2012-07-10 19:03:19 +01:00
Richard W.M. Jones
f883e4d8d3 tests/guests: Add temp files to CLEANFILES. 2012-07-10 18:59:04 +01:00
Richard W.M. Jones
1c8403885c Update translations from Transifex. 2012-07-10 18:44:45 +01:00
Richard W.M. Jones
33bb7408f6 podwrapper: Fix shell script.
This fixes commit f9a5e3ed86.
2012-07-10 13:46:17 +01:00
Hilko Bengen
f9a5e3ed86 podwrapper.sh: Take date from ChangeLog or from the latest git commit. 2012-07-10 10:34:37 +02:00
Richard W.M. Jones
afb30b1b8a Version 1.19.18. 2012-07-09 18:36:46 +01:00
Richard W.M. Jones
8df259496a fuse: Add regression test for RHBZ#838592. 2012-07-09 17:44:50 +01:00
Richard W.M. Jones
5546ea6d68 fuse: Add guestmount --pid-file option (RHBZ#838592). 2012-07-09 16:10:24 +01:00
Richard W.M. Jones
bfbfe6dd78 fuse: Link to mount-local documentation in guestmount man page. 2012-07-09 15:24:26 +01:00
Richard W.M. Jones
1cde66165a fuse: Document race condition possible with fusermount.
See also:
https://bugzilla.redhat.com/show_bug.cgi?id=835466#c9
2012-07-09 15:23:52 +01:00
Richard W.M. Jones
b749dc7074 fuse: Document Device or resource busy errors from fusermount. 2012-07-09 15:23:09 +01:00
Richard W.M. Jones
bd3e42a8de Revert "launch: Correction in comment."
This reverts commit 6e5a85bb9b.

It turns out this is a bug in QEMU after all.
2012-07-08 12:55:44 +01:00
Richard W.M. Jones
e6dec15948 extra-tests: Add a test using upstream qemu. 2012-07-07 16:19:55 +01:00
Richard W.M. Jones
6e5a85bb9b launch: Correction in comment.
https://bugs.launchpad.net/qemu/+bug/1021649 is invalid, probably
caused by a Fedora ROM.

This updates commit 52d188e32f.
2012-07-07 15:49:22 +01:00
Richard W.M. Jones
1596b6026d Update gnulib to latest version. 2012-07-07 12:39:46 +01:00
Richard W.M. Jones
ac25512175 Version 1.19.17. 2012-07-06 14:11:38 +01:00
Richard W.M. Jones
ad7c4498f6 ocaml: Calling Gc.compact before g#mount_local works around RHBZ#838081. 2012-07-06 13:47:07 +01:00
Richard W.M. Jones
52d188e32f qemu: Use sgabios by default (thanks Dan Berrange). 2012-07-06 10:29:26 +01:00
Richard W.M. Jones
1b87f89b5c todo: Investigate qemu caching modes. 2012-07-04 16:44:35 +01:00
Richard W.M. Jones
a95fc92388 Version 1.19.16. 2012-07-04 16:17:44 +01:00
Richard W.M. Jones
7996e08824 qemu or qemu-kvm >= 1.1.0 is required.
Earlier versions of qemu contained a bug in the qcow2 code which
causes qemu to segfault when shutting down and flushing its internal
cache, and this can result in data loss.
2012-07-04 16:17:44 +01:00
Richard W.M. Jones
ffbf1475f7 New API: guestfs_shutdown: Cleanly shutdown the backend.
The new API splits orderly close into a two-step process:

  if (guestfs_shutdown (g) == -1) {
    /* handle the error, eg. qemu error */
  }
  guestfs_close (g);

Note that the explicit shutdown step is only necessary in the case
where you have made changes to the disk image and want to handle write
errors.  Read the documentation for further information.

This change also:

 - deprecates guestfs_kill_subprocess

 - turns guestfs_kill_subprocess into the same as guestfs_shutdown

 - changes guestfish and other tools to call shutdown + close
   where necessary (not for read-only tools)

 - updates documentation

 - updates examples
2012-07-03 21:27:29 +01:00
Richard W.M. Jones
bcc4ffb52b close: Warn if qemu exits unsuccessfully.
Currently guestfs_close has no method to return an error indication,
so this commit simply prints the error on stderr.
2012-07-03 18:14:06 +01:00
Richard W.M. Jones
fc3c6fff4b close: Rearrange the order in which the handle is closed and freed.
The order is now:

 - remove the handle from the list of handles
 - send close trace message
 - sync and shutdown qemu
 - run user close callback
 - free temporary directory
 - free memory

This commit ought to be no functional change.
2012-07-03 14:45:42 +01:00
Richard W.M. Jones
27ebf517fa perl, python, ruby: Fix comments on call to close method.
Make the comments consistent.

Also make the Perl example call $g->close explicitly so it is
consistent with the other examples.
2012-07-03 14:45:42 +01:00
Richard W.M. Jones
917550a117 examples: In create_disk example, don't call set_autosync.
This is now set by default in all supported versions of libguestfs.
It's just confusing if the examples refer to it.
2012-07-03 14:45:42 +01:00
Richard W.M. Jones
c0a3c9ce70 daemon: Run fsync on block devices after sync (RHBZ#836710).
On Linux, sync(2) does not actually issue a write barrier, thus it
doesn't force a flush of the underlying hardware write cache (or
qemu's disk cache in the virtual case).

This can be a problem, because libguestfs relies on running sync in
the appliance, followed by killing qemu (using SIGTERM).

In most cases, this is fine, because killing qemu with SIGTERM should
cause it to flush out the disk cache before it exits.  However we have
found various bugs in qemu which cause qemu to crash while doing the
flush, leaving the data unwritten (see RHBZ#836913).

The solution is to issue fsync(2) to the block devices.  This has a
write barrier, so it ensures that qemu writes out its cache long
before we get around to killing qemu.
2012-07-02 21:13:21 +01:00
Richard W.M. Jones
cb24ceedd8 daemon: Code tidy up in devsparts.
No functional change.
2012-07-02 16:42:17 +01:00
Richard W.M. Jones
0437a79056 Add notes about how qemu cache=none works internally.
This is just a comment and has no functional effect.
2012-07-02 14:16:35 +01:00
Richard W.M. Jones
1608ca182b Rename qemu option cache=off to cache=none.
Note that qemu treats these identically, so this change has
no functional effect.
2012-07-02 14:16:35 +01:00
Richard W.M. Jones
906f8e3ae2 appliance: Update paths to udevd.
systemd is playing a WTF game with udevd, moving it around and
renaming it unnecessarily in each release.  Chase all known locations.
2012-07-02 12:34:11 +01:00
Richard W.M. Jones
100271c7bc appliance: Update comment to note that systemd package now contains udevd. 2012-07-02 12:33:42 +01:00
Richard W.M. Jones
757b089053 Version 1.19.15. 2012-06-29 21:03:42 +01:00
Richard W.M. Jones
5489304c8d tests: Add a test of /dev/disk/by-id paths (RHBZ#627675). 2012-06-29 20:19:13 +01:00
Richard W.M. Jones
339f3647f8 tests: Use qemu-img to create an overlay for testing, instead of copying.
Replace:

  cp tests/guests/fedora.img test.img

with the longer but possibly more space-efficient equivalent:

  qemu-img create -F raw -b tests/guests/fedora.img -f qcow2 test.qcow2
2012-06-29 20:19:13 +01:00
Richard W.M. Jones
ea8421c5d2 inspect: Check partition exists when doing fstab mapping.
If the partition name we're about to return doesn't really exist,
then don't perform the mapping.
2012-06-29 20:19:13 +01:00
Richard W.M. Jones
7eaa99994e inspect: Guess device name from /dev/disk/by-id/*-partN path (RHBZ#627675).
See https://bugzilla.redhat.com/show_bug.cgi?id=836573#c3
for an explanation.

Useful function 'is_partition' shows how to tell if a device name
represents a partition.
2012-06-29 20:19:09 +01:00
Richard W.M. Jones
47b8225b05 inspect: Refactor resolve_fstab_device code into multiple functions.
This is mostly code motion, although it also fixes a memory leak in an
extremely rare failure case, and it generally tidies up the existing
code.
2012-06-29 19:04:21 +01:00
Richard W.M. Jones
152b179a19 New API: guestfs_nr_devices
This returns the number of whole block devices added.  It is usually
simpler to call this than to list the devices and count them, which
is what we do in some places in the current codebase.
2012-06-29 19:04:21 +01:00
Richard W.M. Jones
cba4916909 ruby: Fix detection of library (thanks Hilko Bengen).
On Debian, the Ruby C extensions library isn't '-lruby', it's
something like '-lruby1.8' or '-lruby-1.9.1' and these can even be
parallel-installed.

Fix detection so we use Ruby's own rbconfig.rb file to find the right
library to use.
2012-06-29 14:54:44 +01:00
Richard W.M. Jones
b07d096882 ruby: Changing spacing in configure file.
No functional change.
2012-06-29 14:54:05 +01:00
Richard W.M. Jones
b9f858e5ee ruby: Remove useless AC_SUBST in configure file. 2012-06-29 14:18:10 +01:00
Richard W.M. Jones
a176f508cb Update API support from tarballs. 2012-06-28 17:19:14 +01:00
Richard W.M. Jones
27efd99ddb tests: Reformat TESTS_ENVIRONMENT so all use a standard format.
No functional change.
2012-06-28 13:49:32 +01:00
Richard W.M. Jones
2f1a602c4b python: Set PYTHON in run script. 2012-06-28 13:47:35 +01:00
Richard W.M. Jones
04a533ca8c ocaml: Set CAML_LD_LIBRARY_PATH in run script. 2012-06-28 13:46:31 +01:00
Richard W.M. Jones
e7d2d3cb89 ruby: Use run --tests for tests. 2012-06-28 13:41:40 +01:00
Richard W.M. Jones
8439e97f76 java: Use run --tests for tests.
Java-specific environment variables are set in the run script.
2012-06-28 13:40:33 +01:00
Richard W.M. Jones
1b56aedc2b gobject: Use run --test for tests, and set GJS in run script. 2012-06-28 13:35:55 +01:00
Richard W.M. Jones
2d56e5af90 run: Rearrangement and add comments.
No functional change.
2012-06-28 13:32:53 +01:00
Richard W.M. Jones
927ef14c58 run: Set MALLOC_PERTURB_ to a random value.
MALLOC_PERTURB_ is a glibc feature which causes malloc to wipe memory
before and after it is used, allowing both use-after-free and
uninitialized reads to be detected with relatively little performance
penalty:

  http://udrepper.livejournal.com/11429.html?nojs=1

Modify the ./run script so that it always sets this.

We were already using MALLOC_PERTURB_ in most tests.  Since ./run is
now setting this, we can remove it from individual Makefiles.  Most
TESTS_ENVIRONMENT will now simply look like this:

  TESTS_ENVIRONMENT = $(top_builddir)/run --test
2012-06-28 13:19:39 +01:00
Richard W.M. Jones
b3df3ba5c8 Version 1.19.14. 2012-06-28 08:56:18 +01:00
Richard W.M. Jones
cadfab1a20 tests: Fix 'run --test' so it cleans up its temporary file.
This fixes commit 05d4e07918.
2012-06-27 16:34:23 +01:00
Richard W.M. Jones
1d17a6e9d8 Ensure #include <config.h> occurs in every C file. 2012-06-27 15:49:06 +01:00
Richard W.M. Jones
6777425636 src/actions.c: Include <config.h> in this generated file.
On RHEL 5, because _GNU_SOURCE was not defined, open_memstream was not
being declared, resulting in miscompilation and a segfault in the
trace code whenever open_memstream returned a pointer >= 0x80000000
(which would be truncated to a 32 bit int and then sign-extended).
2012-06-27 15:37:03 +01:00
Richard W.M. Jones
6afb7336e3 gobject: bindtests: gjs exception behaviour changed, fix test.
When libguestfs calls 'error (g, "error")', gjs in F17 throws
error.message == "Error invoking Guestfs.test0rinterr: error"

In F18, error.message is simply the string "error".

Fix the test so it works for both cases.
2012-06-27 10:55:59 +01:00
Richard W.M. Jones
b3a5403cda Version 1.19.13. 2012-06-26 23:49:00 +01:00
Richard W.M. Jones
2eacd4a191 fuse: Use the ./run --test script to run tests. 2012-06-26 23:43:06 +01:00
Richard W.M. Jones
05d4e07918 tests: Add ./run --test option.
This option, when added via
  TESTS_ENVIRONMENT = [...] $(top_builddir)/run --test
allows us to run the tests and only print the full output (including
debugging etc) when the test fails.
2012-06-26 23:34:30 +01:00
Richard W.M. Jones
bbb7d75c91 ./run: Fix indenting for shell script. 2012-06-26 23:00:29 +01:00
Richard W.M. Jones
0977c8408a ocaml: Allow parallel mount-local test to be skipped.
FUSE is not very reliable on RHEL 5.
2012-06-26 18:39:05 +01:00
Richard W.M. Jones
8d88b06277 FAQ: Add Gentoo (thanks Agostino Sarubbo). 2012-06-26 17:46:05 +01:00
Richard W.M. Jones
eb8eb3b9d5 Version 1.19.12. 2012-06-26 15:32:36 +01:00
Richard W.M. Jones
c87956837e launch: Avoid double-close when qemu exits early.
The stdin and stdout of the qemu process are aliased to g->fd:

  g->fd[0] = wfd[1];
  g->fd[1] = rfd[0];

However if the child exits early, then child_cleanup closes g->fd[0],
g->fd[1], AND the code at the cleanup1 label closes wfd[1], rfd[0],
resulting in a double-close.

Avoid this case by setting wfd[1], rfd[0] to -1.  In the cleanup1
label, only close wfd[1], rfd[0] if they are not -1, and add the same
for g->fd[0], g->fd[1].
2012-06-26 14:53:33 +01:00
Richard W.M. Jones
9e221e55b6 launch: Ensure errno from test_qemu_cmd is captured and printed. 2012-06-26 13:38:57 +01:00
Richard W.M. Jones
11317b5d12 launch: Set g->sock = -1 to avoid double-close.
This fixes commit ef5c02c6ee.
2012-06-26 13:31:58 +01:00
Richard W.M. Jones
ef5c02c6ee launch: Log errors from close syscall. 2012-06-26 11:50:12 +01:00
Richard W.M. Jones
90d0beb3c5 tests: Add thread IDs to test of bug 790721. 2012-06-26 09:17:56 +01:00
Richard W.M. Jones
8fc2127975 sysprep: Don't check for /dev/fuse before running the test.
The program doesn't actually require FUSE when used without
any --script options.
2012-06-25 15:21:32 +01:00
Richard W.M. Jones
f27770e141 fish: Allow mount-local test to be skipped with environment variable.
The test uses FUSE, so we need a way to disable it on RHEL 5.
2012-06-25 15:21:32 +01:00
Richard W.M. Jones
2afa0eeb90 tests: Allow SELinux tests to be skipped with an environment variable. 2012-06-25 15:21:32 +01:00
Richard W.M. Jones
030e318049 Version 1.19.11. 2012-06-25 11:29:16 +01:00
Richard W.M. Jones
729bb9c6b5 launch: Treat /dev/null specially, for old KVM.
Old KVM can't add /dev/null readonly.  Treat /dev/null as a special
case.

We also fix a few tests where /dev/null was being used with
format=qcow2.  This was always incorrect behaviour, but qemu appears
to tolerate it.
2012-06-25 11:20:35 +01:00
Richard W.M. Jones
78a515ec4a lib: Remove obsolete NETWORK, ROUTER definitions in header file.
These haven't been used since we switched over to virtio-serial.
2012-06-25 09:02:18 +01:00
Richard W.M. Jones
a0a86484be Version 1.19.10. 2012-06-22 22:06:30 +01:00
Richard W.M. Jones
461455ca7c tests/xml: Fix compilation of test on RHEL 5 with old libvirt.
Old <libvirt.h> had a conflicting definition of virDomainGetXMLDesc:

fake_libvirt_xml.c:36: error: conflicting types for 'virDomainGetXMLDesc'
/usr/include/libvirt/libvirt.h:715: error: previous declaration of 'virDomainGetXMLDesc' was here

The difference is not material ('int' vs. 'unsigned int').

Avoid the error by not including <libvirt.h>.
2012-06-22 13:18:58 +01:00
Richard W.M. Jones
9e7644346d tests: Add workaround for missing O_CLOEXEC. 2012-06-22 13:18:52 +01:00
Richard W.M. Jones
35882ba977 tests: Fix broken workarounds for missing O_CLOEXEC. 2012-06-22 13:18:49 +01:00
Richard W.M. Jones
ef1514aa1e test-virt-resize: Replace truncate with guestfish sparse.
Another instance of 'truncate' command.

See commit 39df80dcc0 for an
explanation.
2012-06-22 13:18:43 +01:00
Richard W.M. Jones
4d3ec25b47 part-get-bootable: Fix when partitions are missing or unordered (RHBZ#602997).
The original fix for this in
commit 511c82df46 was not complete, in
that it did not fix the case of the old (pre '-m' option) parted.
This doesn't matter for Fedora, but it matters for RHEL 5 which has
this ancient parted.
2012-06-22 11:30:00 +01:00
Richard W.M. Jones
8098d062b4 ruby: Add a replacement rb_hash_lookup function for Ruby 1.8.5.
This function was first added to Ruby in 1.8.7.
2012-06-22 11:29:57 +01:00
Richard W.M. Jones
823ba05ebd ruby: Fix libruby test.
If -lruby was not available, this used to define HAVE_LIBRUBY=0.
However this meant that the later test -n "$HAVE_LIBRUBY" would
be successful, whereas it should fail in this case.
2012-06-22 10:58:00 +01:00
Richard W.M. Jones
6cb74d46ba virt-format: Don't call wipefs unless API is available.
This API is optional.  Don't call it unless it's available
in the appliance.
2012-06-22 10:57:55 +01:00
Richard W.M. Jones
145f35badf tests: Add SKIP_TEST_* variables to allow these tests to be skipped.
By setting these variables, we can skip tests that fail on
RHEL 5.
2012-06-22 10:57:47 +01:00
Richard W.M. Jones
6352953ea9 FAQ: Mention update-guestfs-appliance (thanks Steven Dake). 2012-06-19 08:31:45 +01:00
Richard W.M. Jones
489da3ccdf build: Workaround for AC_PROG_SED not existing.
This didn't exist on ancient autoconf in RHEL 5.
2012-06-18 23:00:43 +01:00
Richard W.M. Jones
bc7f1a5ef1 build: Define abs_builddir if not defined already.
This is missing on RHEL 5.

This updates commit 50aa9533e4.
2012-06-18 21:45:13 +01:00
Richard W.M. Jones
baee3f52ef Version 1.19.9. 2012-06-18 16:33:15 +01:00
Richard W.M. Jones
d7c9c6a0d9 fuse: Skip 'truncate' tests if this command is missing. 2012-06-18 15:33:10 +01:00
Richard W.M. Jones
39df80dcc0 tests: Replace truncate command with 'guestfish sparse'.
RHEL 5 didn't have the truncate command, but we can replace:

  truncate -s SIZE FILE

with the roughly equivalent command:

  guestfish sparse FILE SIZE
2012-06-18 15:33:04 +01:00
Richard W.M. Jones
4846b84476 fuse: Add replacement for fuse_opt_add_opt_escaped.
RHEL 5-era FUSE didn't have this function.

I copied the function out of upstream FUSE, since the license is
compatible.
2012-06-18 15:32:52 +01:00
Richard W.M. Jones
50aa9533e4 build: Define builddir and abs_srcdir when they are missing.
RHEL 5-era autoconf did not define these, so define them manually
when they are missing.

Define builddir as '.'  The scripts require this.  It won't work
in the srcdir != builddir case, but we don't care about that for
RHEL 5.

This commit also moves the builddir / abs_srcdir variable setting
above the include of subdir-rules.mk, in case that include uses
these variables.

Useful script:

  for f in $(find -name Makefile.am | xargs fgrep '$(abs_srcdir)' -l) ; do
    if ! grep -q '^abs_srcdir' $f; then
      echo missing in $f
    fi
  done
2012-06-18 15:32:47 +01:00
Richard W.M. Jones
dd216fedbd ocaml: Use OCAMLOPTFLAGS when compiling .cmx (ie. native code) files. 2012-06-18 15:32:38 +01:00
Richard W.M. Jones
87de366701 configure: Look for mkisofs as well as genisoimage.
For our purposes, the two tools are compatible.
2012-06-18 15:32:12 +01:00
Richard W.M. Jones
60a2f8706b Ignore .gdb_history file. 2012-06-14 17:37:11 +01:00
Richard W.M. Jones
7b1cd65c44 ppc64: is_openable function needed on all platforms now.
This fixes commit 295d6af48d.
2012-06-14 17:36:17 +01:00
Richard W.M. Jones
cd6005128d Version 1.19.8. 2012-06-14 16:21:09 +01:00
Richard W.M. Jones
81ee155b9d tests: Add tests for extended attrs and SELinux, direct and via FUSE.
Note that the SELinux + FUSE test is disabled because of:

https://bugzilla.redhat.com/show_bug.cgi?id=811217
https://bugzilla.redhat.com/show_bug.cgi?id=812798#c42
2012-06-14 16:12:57 +01:00
Richard W.M. Jones
abbace6888 virtio-scsi: Increase udev timeout.
In Koji, when you've got 200+ disks, udev times out before all the
udev events have been processed.
2012-06-14 14:22:07 +01:00
Richard W.M. Jones
d43e3d63de virt-edit: Document CVE-2012-2690. 2012-06-14 12:25:06 +01:00
Richard W.M. Jones
199cc2853c Require febootstrap >= 3.17. 2012-06-14 09:57:28 +01:00
Richard W.M. Jones
8b15fb3e22 Version 1.19.7. 2012-06-13 23:25:50 +01:00
Richard W.M. Jones
4c828dc568 tests: Add a test which adds the maximum number of disks and uses them. 2012-06-13 23:17:13 +01:00
Richard W.M. Jones
8735e92a1d virt-df: Use guestfs_max_disks instead of hard-coding limit of 25.
And comprehensively fix it so it works with > 26 disks.
2012-06-13 23:07:26 +01:00
Richard W.M. Jones
a9d7d044f5 New API: device-index.
This returns the index of the device, eg. /dev/sdb => 1.
Or you can think of it as the order that the device was
added, or the index of the device in guestfs_list_devices.
2012-06-13 23:07:26 +01:00
Richard W.M. Jones
46ed232dc2 New API: guestfs_canonical_device_name.
This API makes device names canonical, eg. /dev/vda1 -> /dev/sda1.
2012-06-13 23:07:26 +01:00
Richard W.M. Jones
998ebc333d lvm-filter: Make it work with > 26 devices.
Thanks Alasdair Kergon.
2012-06-13 23:07:26 +01:00
Richard W.M. Jones
c0a087b823 daemon: Fix order of devices in guestfs_list_devices when > 26 disks.
Sort the device names correctly, not just treating them as
strings.  As a result, /dev/sdz < /dev/sdaa.
2012-06-13 22:10:36 +01:00
Richard W.M. Jones
4165e28b53 New API: guestfs_max_disks.
Returns the maximum number of disks that may be added to a handle.
2012-06-13 22:05:45 +01:00
Richard W.M. Jones
919b7e3f6c Update documentation on maximum number of disks. 2012-06-13 22:05:44 +01:00
Richard W.M. Jones
cef979b289 appliance: Add lsscsi to package list. 2012-06-13 22:05:44 +01:00
Richard W.M. Jones
dbd489f95d virtio-scsi: Fix disk name calculation.
This fixes commit 0c0a7d0d86.
2012-06-13 22:05:39 +01:00
Richard W.M. Jones
69e2616b6c Require febootstrap >= 3.16. 2012-06-13 11:27:50 +01:00
Richard W.M. Jones
6e981fe586 Version 1.19.6. 2012-06-12 23:04:16 +01:00
Richard W.M. Jones
320adf4778 tests/md: Don't hard code /dev/vda in expected output of tests.
Use a small sed script to canonicalize the device names.
2012-06-12 22:31:28 +01:00
Richard W.M. Jones
9a5c0d3908 tests: Fix spelling in comment. 2012-06-12 22:31:28 +01:00
Richard W.M. Jones
7509cdf18e tests/lvm: Don't hard-code /dev/vda in test.
Hard-coding it breaks virtio-scsi because the devices are called
/dev/sda etc.
2012-06-12 22:31:05 +01:00
Richard W.M. Jones
62c5b6db58 daemon: Always pass -F option to mke2fs.
Apparently e2fsprogs only knows that "/dev/sda" is a whole device, but
doesn't think that "/dev/vda" is.  On switching the default device
over to virtio-scsi, that causes mke2fs without -F option to complain
and ask for an interactive prompt.  Adding -F forces it to go ahead
anyway.

This caused several less-used APIs to break with virtio-scsi.
2012-06-12 21:16:35 +01:00
Richard W.M. Jones
0c0a7d0d86 appliance: Add support for virtio-scsi.
This requires febootstrap >= 3.15.
2012-06-12 21:16:32 +01:00
Richard W.M. Jones
e0b5ecc801 Record output of qemu -device '?'.
This allows us to find out what qemu devices are supported
at runtime.
2012-06-12 19:19:03 +01:00
Richard W.M. Jones
295d6af48d Require QEMU >= 1.0.
QEMU 1.0 was released at the end of 2011.

Remove all the cruft about detecting broken -machine type which
was only required for QEMU 0.15.

This also reverts commit 30ecbf3ec2.
Even on ARM you can pass -machine accel=kvm:tcg and qemu does the
right thing, so I'm not sure why we wanted to disable that.
2012-06-12 16:02:10 +01:00
Richard W.M. Jones
7652b5aece Remove ./configure --with-drive-if and --with-net-if options.
These were used to select the default drive and network interface.
They both default to 'virtio'.

These were added back in the day when virtio was buggy, so that
packagers could revert to using ide/ne2k_pci to work around distro
bugs.  However virtio has been stable in qemu for a very long time, so
it seems unlikely that any packager would need to use these, and in
any case it would be better to do this detection at runtime (cf. for
virtio-scsi).
2012-06-12 14:52:21 +01:00
Richard W.M. Jones
7590924022 New API: fstrim - allow filesystem trim. 2012-06-12 14:33:57 +01:00
Richard W.M. Jones
668a0cebdf Version 1.19.5. 2012-06-09 22:00:46 +01:00
Richard W.M. Jones
251b131e0a tests: Allow regression test for bug 690819 to be skipped. 2012-06-09 21:13:09 +01:00
Richard W.M. Jones
42475dd21f blockdev_getbsz: Remove test.
The output of this test depends on page size, so on ppc64
it returns 64K.
2012-06-09 20:50:25 +01:00
Richard W.M. Jones
20137c8731 fish: Change test-escapes so test is not endian-sensitive.
The test used the external 'od' command to compare the output of
guestfish with what it's supposed to be.  Unfortunately by default
this outputs groups of 2-byte words, with the words' endianness
affected by the current hardware endianness.  For example:

x86-64$ echo -n ab | od
0000000 061141
0000002

ppc64$ echo -n ab | od
0000000 060542
0000002

By using 'od -b' instead we can output bytes instead of words, and
there is no endianness issue, and the output is clearer:

x86-64$ echo -n ab | od -b
0000000 141 142
0000002

ppc64$ echo -n ab | od -b
0000000 141 142
0000002
2012-06-09 20:18:09 +01:00
Richard W.M. Jones
ac2f9a42fb btrfs: Modify test to correctly detect btrfs availability. 2012-06-09 14:52:39 +01:00
Richard W.M. Jones
011666ae77 btrfs: Modify btrfs availability to test if the kernel supports btrfs.
This is closer to the real meaning of "availability of btrfs", since
just having the btrfs tool doesn't help much if it's not supported by
the kernel too.
2012-06-09 14:52:39 +01:00
Richard W.M. Jones
4ba6aa3eae New API: filesystem-available: tests for filesystem availability.
This also creates an internal filesystem_available function within the
daemon.
2012-06-09 14:52:39 +01:00
Richard W.M. Jones
4f671c829e ppc64: Update README with notes about ppc64 support. 2012-06-08 19:36:34 +01:00
Hilko Bengen
6cf15e8841 out-of-tree build/install fix for translations 2012-06-08 01:24:39 +02:00
Richard W.M. Jones
52af9a88b8 Version 1.19.4. 2012-06-07 14:42:13 +01:00
Richard W.M. Jones
f90c01a5dc Enhance BUGS script.
Since RHBZ was updated, the old python-bugzilla program broke.  When
it was fixed, I found the (undocumented) ordering of the results from
the old tool was no longer true.

This commit adds a small Perl script to sort the output predictably.
Now bugs are sorted by both bug state and bug number, so the output
should be more stable than before.

Re-enable creation of the BUGS file in 'make dist'
(this reverts commit 91f3456244).

Also the BUGS file has been updated.
2012-06-07 09:21:23 +01:00
Richard W.M. Jones
4e5d3b06fb arm: Use #if defined instead of #ifdef.
No functional change.
2012-06-06 23:09:47 +01:00
Richard W.M. Jones
1bdfc88eba ocaml: Fix parameters to ocaml_guestfs_create.
The first parameter (not used) is a unit, so declare it properly.
2012-06-06 13:42:17 +01:00
Richard W.M. Jones
450493cf6b ppc64: Avoid "defined by not used" warning for is_openable function. 2012-06-02 10:35:06 +01:00
Richard W.M. Jones
bbb21f923a Version 1.19.3. 2012-05-31 23:24:22 +01:00
Hilko Bengen
3893dc0b94 Split off GObject tests that require an appliance 2012-05-28 20:01:47 +02:00
Hilko Bengen
148e806826 Fix out-of-tree build for GObject bindings 2012-05-28 20:01:47 +02:00
Richard W.M. Jones
bcbb6bb760 xattr: Refuse to set or get oversized extended attributes.
See:
https://www.redhat.com/archives/libguestfs/2012-May/msg00152.html
2012-05-28 17:55:07 +01:00
Richard W.M. Jones
a7868dd3c9 appliance: 'udevd' has been renamed, since it joined systemd. 2012-05-28 16:09:40 +01:00
Richard W.M. Jones
a7e4a6c692 appliance: Move udev (common package name) to the common section.
This should be just code motion.
2012-05-28 10:01:45 -04:00
Richard W.M. Jones
a81165eb00 Version 1.19.2. 2012-05-27 21:53:21 +01:00
Richard W.M. Jones
42dd5fa5b9 Update to latest gnulib. 2012-05-26 23:07:03 +01:00
Richard W.M. Jones
fe68cd77cb Version 1.19.1. 2012-05-25 16:52:19 +01:00
Richard W.M. Jones
8e8a576429 tests: Add a test of non-ASCII character fidelity on various filesystem types (RHBZ#823887).
Thanks Laszlo Ersek.
2012-05-25 16:38:54 +01:00
Richard W.M. Jones
6445bc5952 doc: Add documentation covering use of utf8 option when mounting vfat (RHBZ#823887). 2012-05-25 15:46:26 +01:00
Richard W.M. Jones
73071b3163 trace: Fix display of non-printing characters.
Previously the code would drop the first character in any sequence of
non-printing characters that occurred within a string.

Fix for commit e6f18c59d5.
2012-05-25 15:46:18 +01:00
Richard W.M. Jones
fba81add94 trace: Fix escaping of non-printable signed characters.
Fix for commit e6f18c59d5.
2012-05-25 15:46:08 +01:00
Wanlong Gao
3936412e33 sysprep: remove the data and log files of puppet
Remove the data(keys) and log files of puppet.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-25 08:34:03 +01:00
Richard W.M. Jones
f00066d22b inspection: Don't fail if /etc/HOSTNAME or /etc/hostname are empty files (RHBZ#823821).
Change guestfs___first_line_of_file so that if the file is empty this
returns an empty string instead of an error.  This is consistent with
the behaviour of this function in the case where the file starts with
a \n character, where it would previously have returned an empty
string.

Change all callers so that they handle this case.

Then change the hostname parsing code so that it doesn't give up when
/etc/HOSTNAME is empty, but falls through to the next alternative, and
similarly for /etc/hostname.

Thanks Todd Mummert for finding and diagnosing this bug.
2012-05-24 15:40:36 +01:00
Richard W.M. Jones
cffb7fefc8 inspection: Use parse_release_file to parse ttylinux release file.
parse_release_file should be used to set fs->product_name, instead of
calling guestfs___first_line_of_file directory, although currently the
two are equivalent.

This is code motion and fixes
commit b648b1813f.
2012-05-24 15:38:46 +01:00
Richard W.M. Jones
ee9ab52bc3 fish/mount: Add better error message when -m (mount) fails (RHBZ#824043). 2012-05-24 14:54:54 +01:00
Richard W.M. Jones
216a6d16ab fish: Remove inaccurate comment from code. 2012-05-24 14:50:00 +01:00
Richard W.M. Jones
d5d9ceee8b virt-make-fs: When writing vfat, add utf8 option to mount (RHBZ#823885). 2012-05-24 14:40:52 +01:00
Richard W.M. Jones
975a41db20 virt-make-fs: Provide a clearer error message when mkfs fails (RHBZ#823883). 2012-05-24 12:30:50 +01:00
Richard W.M. Jones
f904fa8223 appliance: Include 'bzip2' in appliance (RHBZ#824716).
Missing package caused this error in compress-device-out:

libguestfs: error: compress_device_out: compression type bzip2 is not supported

Thanks Mohua Li.
2012-05-24 08:48:51 +01:00
Richard W.M. Jones
b8b5ed65c2 FAQ: Add section about using libguestfs in closed source programs. 2012-05-23 11:46:23 +01:00
Richard W.M. Jones
144d7cd988 FAQ: Add a note about "child process died unexpectedly".
This is a common search term on the main website, and there is no good
information provided by Google at present.
2012-05-23 11:19:34 +01:00
Richard W.M. Jones
c7d3aa9cd6 FAQ: Update Ubuntu instructions. 2012-05-23 11:16:19 +01:00
Wanlong Gao
0e05e9f6ce TODO: sysprep todo list clearance
Remove the implemented features from TODO list.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-22 15:34:01 +01:00
Richard W.M. Jones
54028b9b66 java: Remove unnecessary imports from the generated Java code. 2012-05-22 14:55:50 +01:00
Richard W.M. Jones
87d604f88c debug: Add setenv debugging command. 2012-05-22 13:50:19 +01:00
Richard W.M. Jones
f774f8fd8d Version 1.19.0. 2012-05-21 16:27:04 +01:00
Richard W.M. Jones
1f3b8b395b New stable branch: Version 1.18.0. 2012-05-21 16:18:41 +01:00
Richard W.M. Jones
91f3456244 build: Temporarily disable generation of 'BUGS' file.
Red Hat Bugzilla is broken: RHBZ#823510.
2012-05-21 15:24:32 +01:00
Richard W.M. Jones
d51631034a Update API support. 2012-05-21 14:35:07 +01:00
Richard W.M. Jones
695b3c9633 Update PO files from Transifex. 2012-05-21 14:34:46 +01:00
Richard W.M. Jones
27b9c1c755 Update road map for 1.18 branch. 2012-05-21 14:18:43 +01:00
Richard W.M. Jones
d1f6325e10 Update release notes for 1.18 branch. 2012-05-21 14:16:58 +01:00
Richard W.M. Jones
a119e057d1 sysprep: Credit Wanlong Gao, Fujitsu under 'AUTHORS' section. 2012-05-18 11:15:39 +01:00
Wanlong Gao
f5e0c0e3ee sysprep: remove kerberos data in the guest
Remove the generated kerberos data in the guest.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-18 11:12:07 +01:00
Wanlong Gao
b6d4c29212 sysprep: remove ca certificates in the guest
Remove the ca certificates.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-18 11:12:03 +01:00
Richard W.M. Jones
020e7aa505 Version 1.17.43. 2012-05-17 19:52:03 +01:00
Richard W.M. Jones
88a854cf7f virt-ls: Don't initialize path = NULL. 2012-05-17 17:19:09 +01:00
Richard W.M. Jones
32765e440c virt-ls: Fix --checksum option (RHBZ#822490). 2012-05-17 17:11:16 +01:00
Wanlong Gao
b9331a2d73 NEW API: add new api btrfs-fsck
Add the new API btrfs-fsck to check the btrfs filesystem.
Btrfs is currently under heavy development, and not suitable for
any uses other than benchmarking and review. But it'll be useful
in the near future.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-15 16:07:45 +01:00
Wanlong Gao
a84d02e8d8 btrfs: change the return value of btrfs-set-seeding
Change the return value from "r" to "0".

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-15 16:04:22 +01:00
Wanlong Gao
e9f6ce2492 gobject: remove old generated files further
also remove guestfs-gobject.c

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-15 09:13:12 +01:00
Richard W.M. Jones
7fffaf204e gobject: Remove old generated files. 2012-05-15 08:38:46 +01:00
Richard W.M. Jones
2040a15ac7 sysprep: Add missing 'utils.mli' to SOURCES.
Consequently this file was also missing from the tarball.
2012-05-14 23:03:54 +01:00
Richard W.M. Jones
2fd2c85f6a doc: Add notes on how GPT works on 4k sector disks.
I used scsi_debug to create a 4k sector virtual disk:

  modprobe scsi_debug dev_size_mb=128 sector_size=4096

I then used 'gdisk' to create lots of partitions, and used 'hexdump'
to examine what was written to disk.
2012-05-14 17:47:57 +01:00
Richard W.M. Jones
e8ec521dc6 todo: Notes about partitioning tools. 2012-05-14 15:33:21 +01:00
Wanlong Gao
18451abdf5 New API: add new api btrfs-set-seeding to enable or disable seeding.
Add the new API btrfs-set-seeding to support the seeding-device
feature for btrfs.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-14 13:21:53 +01:00
Wanlong Gao
a75020a066 TODO: add note for libblkid
Add the note about compatible in TODO for libblkid.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-14 13:13:32 +01:00
Richard W.M. Jones
b42dcb05dc examples: Further fixes to mount-local example program.
* Set PS1 prompt properly for bash shells.
* Touch a file into the root directory of the new filesystem.

This fixes commit 46b6766156.
2012-05-14 12:19:31 +01:00
Richard W.M. Jones
2c50a5da46 example: Various fixes to mount-local example program.
* Move MOUNT_OPTIONS to #define at top.
* Move SIZE_MB to #define at top.
* Set PS1 in subshell (doesn't work - why?).
* Hide libguestfs errors from guestfs_mount_local_run.

This fixes commit 46b6766156.
2012-05-14 10:49:16 +01:00
Richard W.M. Jones
a219fede92 debian: examples: Don't break when O_CLOEXEC is not defined.
This affected Debian 6.

This fixes commit 46b6766156.
2012-05-14 10:24:53 +01:00
Richard W.M. Jones
9cf19466f0 Version 1.17.42. 2012-05-13 23:18:44 +01:00
Richard W.M. Jones
034733e981 examples: Add mount options "acl,user_xattr" to mount-local example.
This fixes commit 46b6766156.
2012-05-13 23:01:15 +01:00
Richard W.M. Jones
46b6766156 examples: Add an example of using the mount-local API from C. 2012-05-13 22:53:01 +01:00
Richard W.M. Jones
7201a48d18 examples: Add if HAVE_HIVEX ... endif around virt_dhcp_address example. 2012-05-13 22:20:32 +01:00
Richard W.M. Jones
157f6fb18b qemu: Move -nodefaults etc logically together.
This is just code motion.
2012-05-12 17:22:36 +01:00
Richard W.M. Jones
eb29a9424c arm: Add configure flag '--with-qemu-options'.
This flag allows extra QEMU options to be passed on the command line.

This is useful mainly on arm (see the notes in the updated README
file).
2012-05-12 17:21:24 +01:00
Richard W.M. Jones
30ecbf3ec2 arm: Disable -machine, -enable-kvm options except on x86, x86-64.
Presently KVM is only applicable to x86 and x86-64 (although that will
change in future, and there are rumoured to be implementations for
some current non-x86 architectures).  In any case having these options
breaks ARM, so disable them for non-x86 architectures at the moment.
2012-05-12 16:59:48 +01:00
Richard W.M. Jones
10725acf96 arm: On Linux ARM kernels, the serial console is ttyAMA0.
Cope with unnecessary lack of standardization.
2012-05-12 16:59:48 +01:00
Richard W.M. Jones
5c59790845 arm: Disable test for -no-hpet during launch. 2012-05-12 16:59:48 +01:00
Richard W.M. Jones
a3718c6b8b arm: Set minimum LIBGUESTFS_MEMSIZE at 128.
For ARM Versatile ("versatilepb") architecture, memsize must be set to
256 (megabytes) else the appliance is unable to boot.  Previously
setting LIBGUESTFS_MEMSIZE=256 was not allowed.

Versatile Express has larger limits.
2012-05-12 16:59:48 +01:00
Richard W.M. Jones
77afc92fcd configure: Fix valgrind --vgdb test. 2012-05-12 16:59:48 +01:00
Richard W.M. Jones
0e960614ab configure: Add a comment about vmchannel_test. 2012-05-12 16:59:47 +01:00
Richard W.M. Jones
e275786cb2 Version 1.17.41. 2012-05-11 14:20:23 +01:00
Richard W.M. Jones
a50db3be60 doc: Add a note about compiling under clang. 2012-05-11 13:50:56 +01:00
Richard W.M. Jones
a1680f03b7 configure: Allow systemtap/DTrace userspace probes to be disabled.
'./configure --disable-probes' will disable these probes.  Otherwise
they are autodetected as before.

The <sys/sdt.h> produces lots of errors when you try to compile with
these probes enabled under clang, so it is necessary to provide a way
to disable them for clang users.
2012-05-11 13:47:29 +01:00
Richard W.M. Jones
042a0b063b FAQ: Fix typo in download (thanks badnews@IRC) 2012-05-10 23:00:31 +01:00
Wanlong Gao
1581dbe79f sysprep: remove blkid tab in the guest
Remove blkid tab cache in the guest.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-10 16:27:59 +01:00
Richard W.M. Jones
5647567826 configure: Replace 'echo -n' with 'AS_ECHO_N' macro (thanks Eric Blake). 2012-05-09 16:29:39 +01:00
Richard W.M. Jones
7b72c12428 Update to latest gnulib. 2012-05-09 16:13:57 +01:00
Richard W.M. Jones
5764ac12cf bootstrap: Remove autopoint, po stuff from bootstrap script.
It's not needed since we no longer use gettextize cruft.
2012-05-09 16:13:57 +01:00
Richard W.M. Jones
d0ec0b4c8c Version 1.17.40. 2012-05-08 22:58:05 +01:00
Richard W.M. Jones
af1439bc9f Updated PO files from Transifex. 2012-05-08 17:32:49 +01:00
Wanlong Gao
a79b22a613 sysprep: remove pam data
Remove the generated pam data in the guest.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-05-08 12:31:12 +01:00
Richard W.M. Jones
dd23234f73 test-tool: Implement -V / --version option. 2012-05-05 14:55:03 +01:00
Richard W.M. Jones
3ea36903f2 Update API support. 2012-05-03 18:05:32 +01:00
Richard W.M. Jones
eaa05ff012 Version 1.17.39. 2012-05-03 16:50:25 +01:00
Richard W.M. Jones
e0f36898cb virt-df: Don't fail immediately if a disk is not accessible (RHBZ#789504). 2012-05-03 15:38:08 +01:00
Richard W.M. Jones
bd91bd76d1 virt-alignment-scan: Don't fail immediately if a disk is not accessible (RHBZ#789504). 2012-05-03 15:37:59 +01:00
Richard W.M. Jones
9e2cdd309b virt-alignment-scan, virt-df: Add newlines after error messages. 2012-05-03 15:23:14 +01:00
Richard W.M. Jones
a2cc317c03 virt-make-fs: Add a test of btrfs (regression test for RHBZ#816098). 2012-05-03 14:32:25 +01:00
Richard W.M. Jones
c53ea071c6 virt-make-fs: Simplify test code.
This is just code motion.
2012-05-03 14:32:24 +01:00
Richard W.M. Jones
0cc3525142 virt-make-fs: Fix estimation when making btrfs (RHBZ#816098).
This also disables data and metadata duplication, which is not very
useful on a constructed filesystem on a virtual disk.
2012-05-03 14:32:24 +01:00
Richard W.M. Jones
93734c78d8 virt-make-fs: Use mount instead of mount_options. 2012-05-03 14:32:24 +01:00
Richard W.M. Jones
e60556d927 virt-make-fs: Fix filesystem type check when estimating ntfs. 2012-05-03 14:32:24 +01:00
Richard W.M. Jones
00202b9c29 tests: Regression test for RHBZ#701814.
This commit adds a tests/xml directory, and an LD_PRELOAD module which
can fake arbitrary libvirt XML from an external file (and is therefore
a much more flexible test than using the libvirt test:// driver
alone).

Also added is one regression test for:
https://bugzilla.redhat.com/show_bug.cgi?id=701814

Loading the given libvirt XML using Sys::Guestfs::Lib::open_guest
used to fail with the error:

  format parameter is empty or contains disallowed characters at /home/rjones/d/libguestfs/perl/blib/lib/Sys/Guestfs/Lib.pm line 256.

Thanks to Tom Horsley for supplying the test data.
2012-05-03 12:30:05 +01:00
Richard W.M. Jones
f072a21f3a perl: Don't fail if 'type' (disk format) attribute is missing in libvirt XML (RHBZ#701814).
Old versions of libvirt allowed you to define disks like this:

    <disk type='file' device='disk'>
      <driver name='qemu'/>
      ...

Since the <driver> element does not have a 'type' attribute (which
defines the format), we are supposed to do autodetection, so the
format should be undefined.

However what actually happened was that the code in
Sys::Guestfs::Lib::open_guest received format as an empty string from
the xpath query, causing libguestfs to give an error.

If the xpath query returns the format as an empty string, undefine it.
2012-05-03 12:30:05 +01:00
Richard W.M. Jones
66a525ce5a fish: Add a regression test for the 'glob' command. 2012-05-02 16:35:43 +01:00
Richard W.M. Jones
620ad8eb1a fish: glob command now expands /dev/ patterns (RHBZ#635971).
For example:

><fs> glob echo /dev/*
/dev/vda
/dev/vda1
/dev/vda2
/dev/vda3
><fs> glob echo /dev/v*/*
/dev/vg_f16x64/lv_root
/dev/vg_f16x64/lv_swap
2012-05-02 16:33:23 +01:00
Richard W.M. Jones
79bf966cea fish: Move 'feature_available' function to global.
This is just code motion.
2012-05-02 15:34:02 +01:00
Richard W.M. Jones
29c5e052e4 fish: Clean up glob code and make it return error if malloc fails.
This commit tidies up the code for the 'glob' command.  It also makes
the command return an error if malloc fails (previously it would just
print a message but not return any error indication).
2012-05-02 14:44:54 +01:00
Richard W.M. Jones
1304236c6c fish: Add --pipe-error flag to allow detection of errors in pipe commands (RHBZ#803533).
For a test case, see:
https://bugzilla.redhat.com/show_bug.cgi?id=803533

In guestfish, we use the gnulib closeout module which sets up an
atexit handler to detect if there were any errors on stdout when the
program exits.  This is so we can fail correctly in out of disk space
cases like:

 guestfish [...] > output

However the atexit handler just checks that there was any error on
stdout (using ferror).  If a pipe command such as:

 ><fs> command_with_lots_of_output | head

ran at any time during the session, the error flag would be set
(because the underlying writes failed with EPIPE errors).

So the commit first adds a test for ferror (stdout) after each command
that we issue.  This brings error handling closer to the point of
failure, and so is generally a good thing.

Secondly we reset the error flag after detecting and dealing with the
error, so that avoids the redundant 'guestfish: write error' message
produced by gnulib closeout.

Thirdly we add a --pipe-error flag which causes guestfish commands to
fail on pipe commands line the one above.  The default is off for
backwards compatibility reasons.
2012-05-02 13:55:18 +01:00
Richard W.M. Jones
95a67b1e6a Update release notes. 2012-05-01 19:49:54 +01:00
Richard W.M. Jones
500cc67f29 Version 1.17.38. 2012-05-01 14:08:39 +01:00
Richard W.M. Jones
e6bfb55f65 Turn libguestfs FAQ into a man page: guestfs-faq(1). 2012-05-01 13:55:53 +01:00
Richard W.M. Jones
922052c70f doc: Rewrite description section in man page guestfs(3).
Make the introduction in the man page shorter and punchier, so it
leads readers directly to other pages of interest.
2012-05-01 11:18:57 +01:00
Richard W.M. Jones
51f43402f6 Version 1.17.37. 2012-05-01 09:44:10 +01:00
Richard W.M. Jones
027fefd517 Add gettext support for OCaml tools (virt-resize, virt-sparsify, virt-sysprep).
Note that this support is optional: To enable it, install the
ocaml-gettext library from
http://forge.ocamlcore.org/projects/ocaml-gettext .  If this library
is not installed, then configure detects this and inserts dummy
gettext functions that do nothing.
2012-05-01 09:39:35 +01:00
Richard W.M. Jones
75514ab57a Remove gettextize.
Replace the sociopathic nonsense in gettextize with a simple
Makefile.am which does the same ... and is faster.
2012-05-01 08:58:15 +01:00
Richard W.M. Jones
6aa95e87c1 Remove "convenience header" "gettext.h" and use <libintl.h> instead.
gettextize provides a local file called "gettext.h".  Remove this and
use <libintl.h> from glibc headers instead.

Most of this change is mechanical: #include <libintl.h> in every C
file which uses any gettext function.  But also we remove the
gettext.h file, and adjust the "_" macros.

Note that this effectively removes the ./configure --disable-nls
option, although we don't know if that ever worked.
2012-05-01 08:57:55 +01:00
Richard W.M. Jones
ea74856d95 configure: There are now more OCaml tools than just virt-resize.
virt-resize, virt-sparsify, virt-sysprep are all OCaml tools, so
change what is printed in the report.
2012-04-30 15:08:34 +01:00
Richard W.M. Jones
79822d46e3 configure: Comment fix. 2012-04-30 15:08:34 +01:00
Richard W.M. Jones
bb73cf0941 Move 'libguestfs.pc' (pkgconfig file) to src/ directory.
Since it describes the C library, it's better in the src/ directory.
2012-04-30 15:08:34 +01:00
Richard W.M. Jones
a23e84ee02 todo: virt-sparsify whitelist option. 2012-04-30 09:42:36 +01:00
Richard W.M. Jones
cc79854037 debug: 'progress' (unsupported debug command) now checks argument is reasonable (RHBZ#816839).
Thanks Yuyu Zhou.
2012-04-27 15:35:50 +01:00
Richard W.M. Jones
d448ae0c2b gobject: Fix installation of headers.
RPM build errors:
error: Installed (but unpackaged) file(s) found:
   /usr/include/optargs-add_domain.h
   /usr/include/optargs-add_drive_opts.h
   /usr/include/optargs-btrfs_filesystem_resize.h
   /usr/include/optargs-compress_device_out.h
   /usr/include/optargs-compress_out.h
   /usr/include/optargs-copy_device_to_device.h
   /usr/include/optargs-copy_device_to_file.h
   /usr/include/optargs-copy_file_to_device.h
   /usr/include/optargs-copy_file_to_file.h
   /usr/include/optargs-e2fsck.h
   /usr/include/optargs-inspect_get_icon.h
   /usr/include/optargs-md_create.h
   /usr/include/optargs-mkfs_btrfs.h
   /usr/include/optargs-mkfs_opts.h
   /usr/include/optargs-mount_9p.h
   /usr/include/optargs-mount_local.h
   /usr/include/optargs-ntfsclone_out.h
   /usr/include/optargs-ntfsfix.h
   /usr/include/optargs-ntfsresize_opts.h
   /usr/include/optargs-set_e2attrs.h
   /usr/include/optargs-test0.h
   /usr/include/optargs-tune2fs.h
   /usr/include/optargs-umount_local.h
   /usr/include/session.h
   /usr/include/struct-application.h
   /usr/include/struct-btrfssubvolume.h
   /usr/include/struct-dirent.h
   /usr/include/struct-inotify_event.h
   /usr/include/struct-int_bool.h
   /usr/include/struct-isoinfo.h
   /usr/include/struct-lvm_lv.h
   /usr/include/struct-lvm_pv.h
   /usr/include/struct-lvm_vg.h
   /usr/include/struct-mdstat.h
   /usr/include/struct-partition.h
   /usr/include/struct-stat.h
   /usr/include/struct-statvfs.h
   /usr/include/struct-version.h
   /usr/include/struct-xattr.h
   /usr/include/tristate.h

We want to put these headers into the subdirectory, but not
guestfs-gobject.h.  This isn't easy with automake.
2012-04-27 09:11:33 +01:00
Richard W.M. Jones
1f0964536b gobject: Fix whitespace in Makefile.am. 2012-04-27 09:10:33 +01:00
Wanlong Gao
23f8cab1e8 sysprep: Remove the data of dovecot
Remove the data of dovecot.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-04-27 08:51:03 +01:00
Wanlong Gao
ac75e46c5a sysprep: remove the logfiles configured by logrotate
Remove the logfiles configured by /etc/logrotate.d/*.
Omit the logfile of "samba" and "sssd" which we removed
them separately .

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-04-27 08:49:07 +01:00
Richard W.M. Jones
e493884a76 Version 1.17.36. 2012-04-26 18:03:58 +01:00
Richard W.M. Jones
819cba54e6 btrfs: Fix btrfs test so it works with btrfs-progs in Rawhide.
See: http://bugzilla.redhat.com/816346
2012-04-26 17:55:54 +01:00
Richard W.M. Jones
a505423e58 lib: Remove the BUSY state.
Originally this state was intended so that in some way you could find
out if the appliance was running a command.  However there was never a
thread-safe way to access the state of the handle, so in effect you
could never do anything useful safely with this information.

This commit completely removes the BUSY state.

The only visible change is to the guestfs_is_busy API.  Previously you
could never call this safely from another thread.  If you called it
from the same thread it would always return false (since the current
thread can't be running a libguestfs command at that point by
definition).  Now it always returns false.
2012-04-26 16:48:47 +01:00
Richard W.M. Jones
eafefab937 gobject: Use generator_built macro to ensure generated files are rebuilt properly. 2012-04-26 15:52:59 +01:00
Matthew Booth
d58cb029a3 gobject: Move headers into a subdirectory
The gobject bindings generate a large number of header files, which pollute
/usr/include when installed. This patch moves them all into a guestfs-gobject/
subdirectory. guestfs-gobject.h remains in the same place.

This change also moves generated source files into src/, because it makes the
gobject directory a bit tidier.
2012-04-26 14:02:26 +01:00
Richard W.M. Jones
317ba894b3 btrfs: Fix docs for btrfs_subvolume_set_default (thanks Matt Booth).
This fixes commit 87ea7a0409.
2012-04-26 13:55:30 +01:00
Matthew Booth
8fb67ee66a gobject: Implement libguestfs events as signals
Implement libguestfs events as GObject signals. Callback arguments are passed in
a boxed object.

Note that this patch fixes the length of the uint64_t array in the callback
arguments at 16, whereas it is actually arbitrary length. This is to make it
introspectable. There is currently no way to pass an arbitrary length array to a
callback, and have its type introspected.
2012-04-26 13:35:34 +01:00
Matthew Booth
6c88c3758b gobject: Wrap literal sections in POD in CDATA sections 2012-04-26 13:35:33 +01:00
Matthew Booth
a2dc83cf03 gobject: NFC generated code formatting fix 2012-04-26 13:35:33 +01:00
Richard W.M. Jones
8cb30dc805 rescue: Add --scratch option.
This lets you create temporary scratch disks.
2012-04-26 12:56:34 +01:00
Richard W.M. Jones
39d79e677b fish: Add opaque field to the drives list for programs to use.
Not used at present.
2012-04-26 12:56:01 +01:00
Richard W.M. Jones
2cc4314ecc Version 1.17.35. 2012-04-25 23:08:24 +01:00
Richard W.M. Jones
beaa528855 appliance: Remove some unnecessary errors.
virt-rescue prints errors such as:

  rm: cannot remove `/proc': Is a directory
  mkdir: cannot create directory `/proc': File exists
  rm: cannot remove `/sys': Is a directory
  mkdir: cannot create directory `/sys': File exists

People have reported these errors (which are nothing to worry about)
as bugs in the past, so avoid them where possible.
2012-04-25 22:58:25 +01:00
Richard W.M. Jones
2d414112f7 btrfs: Enhance the btrfs device test.
This enhances commit 87ea7a0409.
2012-04-25 19:42:26 +01:00
Richard W.M. Jones
12c5394d4c tests: Add some more substantial test data.
The two tarballs:

  8252 bytes   tests/data/filesanddirs-10M.tar.xz
 41152 bytes   tests/data/filesanddirs-100M.tar.xz

contain, as their names suggest, highly compressed files and
directories, with unpacked size respectively around 10M and 100M (the
precise size after unpacking depends on the filesystem).

These can be used for testing purposes.
2012-04-25 19:26:57 +01:00
Richard W.M. Jones
e188eb8268 btrfs-device-delete: Use correct (sysroot-prefixed) path to filesystem.
This fixes commit 87ea7a0409.
2012-04-25 19:08:56 +01:00
Richard W.M. Jones
87ea7a0409 New btrfs APIs.
Bind the easy parts of the 'btrfs' program.

The new APIs are:

btrfs-device-add: add devices to a btrfs filesystem
btrfs-device-delete: remove devices from a btrfs filesystem
btrfs-filesystem-sync: sync a btrfs filesystem
btrfs-filesystem-balance: balance a btrfs filesystem
btrfs-subvolume-create: create a btrfs snapshot
btrfs-subvolume-delete: delete a btrfs snapshot
btrfs-subvolume-list: list btrfs snapshots and subvolumes
btrfs-subvolume-set-default: set default btrfs subvolume
btrfs-subvolume-snapshot: create a writable btrfs snapshot
2012-04-25 17:32:30 +01:00
Richard W.M. Jones
3cc9703f90 btrfs: Modify mkfs-btrfs API so it takes a list of devices.
btrfs filesystems can span multiple filesystems.

Note this changes the API, but this API has not yet been released in a
stable version of libguestfs.
2012-04-25 16:33:31 +01:00
Wanlong Gao
bd1a699c15 TODO: remove sssd and samba in sysprep
remove the TODO of sssd and samba in sysprep.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-04-25 11:53:04 +01:00
Wanlong Gao
046d6c20e7 sysprep: fix typo of the object
Fix the typo of the OBJECT.
I'm sorry for the copy and paste typo.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-04-25 11:53:04 +01:00
Wanlong Gao
303b159134 sysprep: remove the db and log of samba
Remove the db and log of samba.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-04-25 11:53:01 +01:00
Wanlong Gao
580ae3297a sysprep: remove the db and log of sssd
Remove the db and log of sssd.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-04-25 11:52:56 +01:00
Richard W.M. Jones
a98d9f4840 todo: Suggest 'virt-customize' tool. 2012-04-24 19:36:33 +01:00
Richard W.M. Jones
0e49186814 todo: Debian APT cache is now removed (thanks Wanlong Gao).
This updates commit 7fc7c3aa5b.
2012-04-24 19:26:09 +01:00
Richard W.M. Jones
5fab4db8de bugs: Update BUGS file. 2012-04-24 19:24:10 +01:00
Richard W.M. Jones
d16868b938 bugs: Print count of bugs in each section. 2012-04-24 19:24:00 +01:00
Richard W.M. Jones
37a3cdbc13 generator: Add explicit types to pod memoization code.
This is just code motion.
2012-04-24 17:38:48 +01:00
Richard W.M. Jones
a2d30626cb Version 1.17.34. 2012-04-24 17:17:59 +01:00
Wanlong Gao
7fc7c3aa5b sysprep: remove the cache of package manager
Remove the cache of package manager like yum and apt.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>

RWMJ:
- Small code cleanup.
2012-04-24 08:32:08 +01:00
Wanlong Gao
95515c4576 sysprep: flag the system for reconfiguration
Flag the system for reconfiguration by touching /.unconfigured .

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>

RWMJ:
- Updated so this is disabled by default, since it requires
  user intervention at next boot.
2012-04-23 15:37:28 +01:00
Wanlong Gao
148b51fe0b sysprep: remove user accounts
Remove user accounts from /etc/passwd, /etc/group,
/etc/shadow, and the home directory of the user,
except the root user.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>

RWMJ:
- Updated to use Augeas to delete accounts.
- Disable this by default, since it is very invasive.
2012-04-23 15:37:24 +01:00
437 changed files with 125380 additions and 53231 deletions

48
.gitignore vendored
View File

@@ -22,10 +22,10 @@
bindtests.tmp
cscope.out
.deps
.gdb_history
.libs
Makefile
Makefile.in
pod2htm?.tmp
/ABOUT-NLS
/aclocal.m4
@@ -61,8 +61,8 @@ pod2htm?.tmp
/csharp/Libguestfs.cs
/daemon/actions.h
/daemon/errnostring.c
/daemon/errnostring_gperf.c
/daemon/errnostring_gperf.gperf
/daemon/errnostring-gperf.c
/daemon/errnostring-gperf.gperf
/daemon/errnostring.h
/daemon/guestfsd
/daemon/guestfsd.exe
@@ -91,18 +91,21 @@ pod2htm?.tmp
/examples/create_disk
/examples/display_icon
/examples/guestfs-examples.3
/examples/guestfs-faq.1
/examples/guestfs-performance.1
/examples/guestfs-recipes.1
/examples/guestfs-testing.1
/examples/inspect_vm
/examples/mount_local
/examples/stamp-guestfs-examples.pod
/examples/stamp-guestfs-faq.pod
/examples/stamp-guestfs-performance.pod
/examples/stamp-guestfs-recipes.pod
/examples/stamp-guestfs-testing.pod
/examples/virt-dhcp-address
/fish/cmds.c
/fish/cmds_gperf.c
/fish/cmds_gperf.gperf
/fish/cmds-gperf.c
/fish/cmds-gperf.gperf
/fish/completion.c
/fish/event-names.c
/fish/fish-cmds.h
@@ -155,6 +158,7 @@ pod2htm?.tmp
/html/guestfs.3.html
/html/guestfs-erlang.3.html
/html/guestfs-examples.3.html
/html/guestfs-faq.1.html
/html/guestfs-java.3.html
/html/guestfs-ocaml.3.html
/html/guestfs-performance.1.html
@@ -199,7 +203,6 @@ pod2htm?.tmp
/java/doc-stamp
/java/examples/guestfs-java.3
/java/examples/stamp-guestfs-java.pod
/libguestfs.pc
/libguestfs.spec
/libguestfs-*.tar.gz
/libtool
@@ -224,9 +227,7 @@ pod2htm?.tmp
/ocaml/examples/guestfs-ocaml.3
/ocaml/examples/inspect_vm
/ocaml/examples/stamp-guestfs-ocaml.pod
/ocaml/guestfs_c_actions.c
/ocaml/guestfs_inspector.ml
/ocaml/guestfs_inspector.mli
/ocaml/guestfs-c-actions.c
/ocaml/guestfs.ml
/ocaml/guestfs.mli
/ocamlinit-stamp
@@ -243,8 +244,8 @@ pod2htm?.tmp
/ocaml/t/guestfs_400_events.opt
/ocaml/t/guestfs_400_progress.bc
/ocaml/t/guestfs_400_progress.opt
/ocaml/t/guestfs_500_parallel_mount_local.bc
/ocaml/t/guestfs_500_parallel_mount_local.opt
/ocaml/t/guestfs_500_mount_local.bc
/ocaml/t/guestfs_500_mount_local.opt
/perl/bindtests.pl
/perl/blib
/perl/examples/guestfs-perl.3
@@ -291,27 +292,14 @@ pod2htm?.tmp
/php/extension/php_guestfs_php.h
/php/extension/run-tests.php
/php/extension/tmp-php.ini
/po/boldquot.sed
/po/ChangeLog
/po-docs/*/*.1
/po-docs/*/*.3
/po-docs/*/*.pl
/po-docs/po4a.conf
/po-docs/*/*.pod
/po-docs/*/stamp-update-po
/podwrapper.sh
/po/en@boldquot.header
/po/en@quot.header
/podwrapper.pl
/po/*.gmo
/po/insert-header.sin
/po/LINGUAS
/po/Makevars.template
/po/POTFILES
/po/quot.sed
/po/remove-potcdate.sed
/po/Rules-quot
/po/stamp-it
/po/stamp-po
/python/bindtests.py
/python/examples/guestfs-python.3
/python/examples/stamp-guestfs-python.pod
@@ -324,6 +312,7 @@ pod2htm?.tmp
/rescue/virt-rescue
/rescue/virt-rescue.1
/resize/.depend
/resize/resize_gettext.ml
/resize/stamp-virt-resize.pod
/resize/utils_tests
/resize/virt-resize
@@ -340,14 +329,15 @@ pod2htm?.tmp
/ruby/Rakefile
/run
/sparsify/.depend
/sparsify/sparsify_gettext.ml
/sparsify/stamp-virt-sparsify.pod
/sparsify/virt-sparsify
/sparsify/virt-sparsify.1
/src/actions.c
/src/bindtests.c
/src/errnostring.c
/src/errnostring_gperf.c
/src/errnostring_gperf.gperf
/src/errnostring-gperf.c
/src/errnostring-gperf.gperf
/src/errnostring.h
/src/guestfs.3
/src/guestfs-actions.pod
@@ -358,6 +348,7 @@ pod2htm?.tmp
/src/guestfs_protocol.h
/src/guestfs_protocol.x
/src/guestfs-structs.pod
/src/libguestfs.pc
/src/libguestfs.syms
/src/.libs/libguestfs.so
/src/stamp-guestfs.pod
@@ -367,6 +358,7 @@ pod2htm?.tmp
/sysprep/stamp-script2.sh
/sysprep/stamp-virt-sysprep.pod
/sysprep/sysprep-extra-options.pod
/sysprep/sysprep_gettext.ml
/sysprep/sysprep-operations.pod
/sysprep/virt-sysprep
/sysprep/virt-sysprep.1
@@ -390,6 +382,7 @@ pod2htm?.tmp
/tests/c-api/tests.c
/tests/c-api/test*.tmp
/tests/c-api/test-user-cancel
/tests/charsets/test-charset-fidelity
/tests/data/100kallnewlines
/tests/data/100kallspaces
/tests/data/100kallzeroes
@@ -412,6 +405,7 @@ pod2htm?.tmp
/tests/guests/stamp-fedora-md.img
/tests/guests/ubuntu.img
/tests/guests/windows.img
/tests/mount-local/test-parallel-mount-local
/tests/regressions/rhbz501893
/tests/regressions/rhbz790721
/test-tool/libguestfs-test-tool

Submodule .gnulib updated: b64318247b...e630af09e1

View File

@@ -4,6 +4,7 @@ Charles Duffy <cduffy@messageone.com>
Daniel Berrange <berrange@redhat.com>
Daniel Cabrera <logan@fedoraproject.org>
Douglas Schilling Landgraf <dougsland@redhat.com>
Eric Blake <eblake@redhat.com>
Erik Nolte <erik_nolte@acm.org>
Geert Warrink <geert.warrink@onsnet.nu>
Guido Günther <agx@sigxcpu.org>
@@ -13,6 +14,7 @@ Jim Meyering <jim@meyering.net>
Jiri Popelka <jpopelka@redhat.com>
Karel Klíč <kklic@redhat.com>
Marcin Gibula <m.gibula@e24cloud.com>
Masami HIRATA <msmhrt@gmail.com>
Matthew Booth <mbooth@redhat.com>
Maxim Koltsov <kolmax94@gmail.com>
Michael Scherer <misc@zarb.org>

361
BUGS
View File

@@ -1,5 +1,5 @@
NOTE: This file is automatically generated from "update-bugs.sh".
Last updated: 2012-04-22
Last updated: 2012-08-02
This contains a local list of the bugs that are open against
libguestfs. Bugs are tracked in the Red Hat Bugzilla database
@@ -20,42 +20,84 @@ When reporting a new bug, please check:
--------------------------------------------------
Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
507278 NEW https://bugzilla.redhat.com/show_bug.cgi?id=507278
libguestfs fails to build on Fedora sparc64
547488 NEW https://bugzilla.redhat.com/show_bug.cgi?id=547488
guestfish cannot tab complete filenames that contain spaces
554829 NEW https://bugzilla.redhat.com/show_bug.cgi?id=554829
SELinux handling could be done better.
555803 NEW https://bugzilla.redhat.com/show_bug.cgi?id=555803
guestfs_tgz_out does not detect failure of tar command
563450 NEW https://bugzilla.redhat.com/show_bug.cgi?id=563450
list-devices returns devices of different types out of order
572337 NEW https://bugzilla.redhat.com/show_bug.cgi?id=572337
libguestfs should support gptsync
578103 NEW https://bugzilla.redhat.com/show_bug.cgi?id=578103
[RFE] Tool to Compare Windows Registry Entries
593511 NEW https://bugzilla.redhat.com/show_bug.cgi?id=593511
[RFE] function to get partition name
596354 NEW https://bugzilla.redhat.com/show_bug.cgi?id=596354
guestfish.1.html and guestfs.3.html declared "XHTML 1.0 Strict" but are not in fact well-formed XML
604041 NEW https://bugzilla.redhat.com/show_bug.cgi?id=604041
guestmount absolute symlinks don't work
624334 NEW https://bugzilla.redhat.com/show_bug.cgi?id=624334
blockdev-setbsz succeeds, but does not affect blockdev-getbsz
624335 NEW https://bugzilla.redhat.com/show_bug.cgi?id=624335
blockdev-setbsz succeeds, but does not affect blockdev-getbsz
637251 NEW https://bugzilla.redhat.com/show_bug.cgi?id=637251
virt-inspector fails to recognize data-only NTFS disk image
660687 NEW https://bugzilla.redhat.com/show_bug.cgi?id=660687
guestmount: "touch" command fails: touch: setting times of `timestamp': Invalid argument
672485 NEW https://bugzilla.redhat.com/show_bug.cgi?id=672485
[RFE] virt-edit/tar/inspector do not support encrypted system
676020 NEW https://bugzilla.redhat.com/show_bug.cgi?id=676020
After using virt-resize with an ntfs partition windows is not booting
684486 NEW https://bugzilla.redhat.com/show_bug.cgi?id=684486
Guest fails to boot after virt-resize
691659 NEW https://bugzilla.redhat.com/show_bug.cgi?id=691659
libguestfs fails to run under JRuby 1.6.0
693064 NEW https://bugzilla.redhat.com/show_bug.cgi?id=693064
Symbolic links on ntfs-3g are not followed correctly by some commands
701814 NEW https://bugzilla.redhat.com/show_bug.cgi?id=701814
virt-win-reg fails on a libvirt guest that has no defined disk format: "format parameter is empty or contains disallowed characters"
696445 NEW https://bugzilla.redhat.com/show_bug.cgi?id=696445
Backport virt-inspector for virt-v2v
696451 NEW https://bugzilla.redhat.com/show_bug.cgi?id=696451
libguestfs: unknown filesystem label SWAP-sda2
696484 NEW https://bugzilla.redhat.com/show_bug.cgi?id=696484
[RFE] virt-v2v show the warning info after convert rhel4u8 guest if comment a line of swap in the fstab
700342 NEW https://bugzilla.redhat.com/show_bug.cgi?id=700342
virt-inspector resports unknown filesystem UUID
709326 NEW https://bugzilla.redhat.com/show_bug.cgi?id=709326
virt-inspector cannot detect ReactOS
728224 NEW https://bugzilla.redhat.com/show_bug.cgi?id=728224
configure can't find qemu on PPC
737261 NEW https://bugzilla.redhat.com/show_bug.cgi?id=737261
libguestfs grub-install API needs grub1
745282 NEW https://bugzilla.redhat.com/show_bug.cgi?id=745282
[RFE] Support to use virt-filesystems with remote libvirt systems
745576 NEW https://bugzilla.redhat.com/show_bug.cgi?id=745576
libguestfs (or qemu?) hangs if sparse file runs out of disk space
745606 NEW https://bugzilla.redhat.com/show_bug.cgi?id=745606
libguestfs: error: part_list: could not parse row from output of parted print command
761565 NEW https://bugzilla.redhat.com/show_bug.cgi?id=761565
Missing deps on netpbm-progs and icoutils
767852 NEW https://bugzilla.redhat.com/show_bug.cgi?id=767852
dependency on fuse suggested
770075 NEW https://bugzilla.redhat.com/show_bug.cgi?id=770075
FEBOOTSTRAP_MODULES fails if modules directory is not under /lib
@@ -68,12 +110,6 @@ Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
785603 NEW https://bugzilla.redhat.com/show_bug.cgi?id=785603
copy-out can't find root directory
786187 NEW https://bugzilla.redhat.com/show_bug.cgi?id=786187
list-filesystems error mentions "list-devices"
789504 NEW https://bugzilla.redhat.com/show_bug.cgi?id=789504
virt-df (other tools?) should not give up if a guest disk is missing
790837 NEW https://bugzilla.redhat.com/show_bug.cgi?id=790837
Use of atexit to clean up handles is wrong in multithreaded programs
@@ -83,8 +119,29 @@ Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
801117 NEW https://bugzilla.redhat.com/show_bug.cgi?id=801117
libguestfs cannot get icon for Windows 8 preview
803533 NEW https://bugzilla.redhat.com/show_bug.cgi?id=803533
guestfish: write error
801640 NEW https://bugzilla.redhat.com/show_bug.cgi?id=801640
[RFE] the error reported by resize2fs-M need to be more clear
802389 NEW https://bugzilla.redhat.com/show_bug.cgi?id=802389
event handlers for 'close' event doesn't work in remote mode
803643 NEW https://bugzilla.redhat.com/show_bug.cgi?id=803643
inspect-is-multipart return false when inspection results should be true
803650 NEW https://bugzilla.redhat.com/show_bug.cgi?id=803650
inspect-is-live return false when inspection results should be true
803657 NEW https://bugzilla.redhat.com/show_bug.cgi?id=803657
[RFE] inspect-is-netinst : support more distributions
805417 NEW https://bugzilla.redhat.com/show_bug.cgi?id=805417
RFE: support inspection of installation ISOs of WinVista, Win7, Win2008 & Win2008r2
806176 NEW https://bugzilla.redhat.com/show_bug.cgi?id=806176
libguestfs doesn't use the external tools (wrestool ...) to get icon even these tools are installed
806179 NEW https://bugzilla.redhat.com/show_bug.cgi?id=806179
RFE: support inspection of icon for more Windows guests
808193 NEW https://bugzilla.redhat.com/show_bug.cgi?id=808193
g.launch() crashes on RHEL 5
@@ -110,239 +167,87 @@ Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
815149 NEW https://bugzilla.redhat.com/show_bug.cgi?id=815149
virt-alignment-scan gives error "part_list: could not parse row from output of parted print command: /dev/vda:4194304B:virtblk:512:512:msdos:Virtio Block Device"
563450 NEW https://bugzilla.redhat.com/show_bug.cgi?id=563450
list-devices returns devices of different types out of order
816839 NEW https://bugzilla.redhat.com/show_bug.cgi?id=816839
data overflow error when debug progress -1
696445 NEW https://bugzilla.redhat.com/show_bug.cgi?id=696445
Backport virt-inspector for virt-v2v
819086 NEW https://bugzilla.redhat.com/show_bug.cgi?id=819086
look for qemu-kvm on /usr/libexec
806176 NEW https://bugzilla.redhat.com/show_bug.cgi?id=806176
libguestfs doesn't use the external tools (wrestool ...) to get icon even these tools are installed
822538 NEW https://bugzilla.redhat.com/show_bug.cgi?id=822538
libguestfs tools hang on qcow2 encrypted disks
813329 NEW https://bugzilla.redhat.com/show_bug.cgi?id=813329
virt-p2v can not convert physical host on MD device
822626 NEW https://bugzilla.redhat.com/show_bug.cgi?id=822626
virt-ls error: "libguestfs: error: checksum: path: parameter cannot be NULL"
547488 NEW https://bugzilla.redhat.com/show_bug.cgi?id=547488
guestfish cannot tab complete filenames that contain spaces
824021 NEW https://bugzilla.redhat.com/show_bug.cgi?id=824021
inspection cannot recognize guest which uses btrfs subvolumes for root
672485 NEW https://bugzilla.redhat.com/show_bug.cgi?id=672485
[RFE] virt-edit/tar/inspector do not support encrypted system
824782 NEW https://bugzilla.redhat.com/show_bug.cgi?id=824782
virt-resize cannot resize PowerPC guests
745282 NEW https://bugzilla.redhat.com/show_bug.cgi?id=745282
[RFE] Support to use virt-filesystems with remote libvirt systems
830135 NEW https://bugzilla.redhat.com/show_bug.cgi?id=830135
libguestfs should support mount-local APIs in RHEL 6 (for OpenStack)
801640 NEW https://bugzilla.redhat.com/show_bug.cgi?id=801640
[RFE] the error reported by resize2fs-M need to be more clear
832602 NEW https://bugzilla.redhat.com/show_bug.cgi?id=832602
"error in chunked encoding" when trying to extract (tar-out) a truncated ISO image
803643 NEW https://bugzilla.redhat.com/show_bug.cgi?id=803643
inspect-is-multipart return false when inspection results should be true
833362 NEW https://bugzilla.redhat.com/show_bug.cgi?id=833362
virt-make-fs test fails on ppc64 because filesystem block size is 64k
803650 NEW https://bugzilla.redhat.com/show_bug.cgi?id=803650
inspect-is-live return false when inspection results should be true
834712 NEW https://bugzilla.redhat.com/show_bug.cgi?id=834712
virt-resize test failed once: lvresize_free: New size (91 extents) matches existing size (91 extents)
803657 NEW https://bugzilla.redhat.com/show_bug.cgi?id=803657
[RFE] inspect-is-netinst : support more distributions
835622 NEW https://bugzilla.redhat.com/show_bug.cgi?id=835622
virt-sparsify to LVM thin raw volume isn't sparse
805417 NEW https://bugzilla.redhat.com/show_bug.cgi?id=805417
RFE: support inspection of installation ISOs of WinVista, Win7, Win2008 & Win2008r2
836501 NEW https://bugzilla.redhat.com/show_bug.cgi?id=836501
dependency on fuse suggested
806179 NEW https://bugzilla.redhat.com/show_bug.cgi?id=806179
RFE: support inspection of icon for more Windows guests
837691 NEW https://bugzilla.redhat.com/show_bug.cgi?id=837691
Data loss when writing to qcow2-format disk files
507278 NEW https://bugzilla.redhat.com/show_bug.cgi?id=507278
libguestfs fails to build on Fedora sparc64
837941 NEW https://bugzilla.redhat.com/show_bug.cgi?id=837941
Data loss when writing to qcow2-format disk files
554829 NEW https://bugzilla.redhat.com/show_bug.cgi?id=554829
SELinux handling could be done better.
838081 NEW https://bugzilla.redhat.com/show_bug.cgi?id=838081
ocaml/t/guestfs_500_parallel_mount_local crashes in caml_thread_reinitialize
555803 NEW https://bugzilla.redhat.com/show_bug.cgi?id=555803
guestfs_tgz_out does not detect failure of tar command
838609 NEW https://bugzilla.redhat.com/show_bug.cgi?id=838609
guestmount + fusermount allows a race condition when unmounting and immediately using the disk image
572337 NEW https://bugzilla.redhat.com/show_bug.cgi?id=572337
libguestfs should support gptsync
838904 NEW https://bugzilla.redhat.com/show_bug.cgi?id=838904
make-debian-img.sh failed: /dev/debian/root: not found: device not cleared. Aborting. Failed to wipe start of new LV.
578103 NEW https://bugzilla.redhat.com/show_bug.cgi?id=578103
[RFE] Tool to Compare Windows Registry Entries
840474 NEW https://bugzilla.redhat.com/show_bug.cgi?id=840474
cannot install libguestfs due to missing dependency
592910 NEW https://bugzilla.redhat.com/show_bug.cgi?id=592910
'guestfish --remote run' hangs in a shell command substitution context
843188 NEW https://bugzilla.redhat.com/show_bug.cgi?id=843188
Ruby bindings segfault in event callbacks when the Ruby GC is invoked.
593511 NEW https://bugzilla.redhat.com/show_bug.cgi?id=593511
[RFE] function to get partition name
843199 NEW https://bugzilla.redhat.com/show_bug.cgi?id=843199
Ruby bindings segfault in event callbacks when the Ruby GC is invoked.
596354 NEW https://bugzilla.redhat.com/show_bug.cgi?id=596354
guestfish.1.html and guestfs.3.html declared "XHTML 1.0 Strict" but are not in fact well-formed XML
604041 NEW https://bugzilla.redhat.com/show_bug.cgi?id=604041
guestmount absolute symlinks don't work
624334 NEW https://bugzilla.redhat.com/show_bug.cgi?id=624334
blockdev-setbsz succeeds, but does not affect blockdev-getbsz
624335 NEW https://bugzilla.redhat.com/show_bug.cgi?id=624335
blockdev-setbsz succeeds, but does not affect blockdev-getbsz
627675 NEW https://bugzilla.redhat.com/show_bug.cgi?id=627675
libguestfs inspector code cannot handle /dev/disk/by-id/* paths
635971 NEW https://bugzilla.redhat.com/show_bug.cgi?id=635971
glob mkfs ext2 /dev/vd[b-t]1 does not expand
637251 NEW https://bugzilla.redhat.com/show_bug.cgi?id=637251
virt-inspector fails to recognize data-only NTFS disk image
646036 NEW https://bugzilla.redhat.com/show_bug.cgi?id=646036
libguestfs fails to launch
660687 NEW https://bugzilla.redhat.com/show_bug.cgi?id=660687
guestmount: "touch" command fails: touch: setting times of `timestamp': Invalid argument
696451 NEW https://bugzilla.redhat.com/show_bug.cgi?id=696451
libguestfs: unknown filesystem label SWAP-sda2
696484 NEW https://bugzilla.redhat.com/show_bug.cgi?id=696484
[RFE] virt-v2v show the warning info after convert rhel4u8 guest if comment a line of swap in the fstab
700342 NEW https://bugzilla.redhat.com/show_bug.cgi?id=700342
virt-inspector resports unknown filesystem UUID
802389 NEW https://bugzilla.redhat.com/show_bug.cgi?id=802389
event handlers for 'close' event doesn't work in remote mode
691389 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=691389
Extended attributes don't work over guestmount (FUSE)
713678 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=713678
Not all febootstrap messages are redirected to log callbacks
721160 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=721160
Missing btrfs support
755729 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=755729
Error message for resize2fs-M needs tweaking
583974 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=583974
mount hangs there when you lack proper permission to guest image
539746 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=539746
launch fails when run inside a Xen guest, when no non-PV kernels are installed
845234 NEW https://bugzilla.redhat.com/show_bug.cgi?id=845234
RFE: virt-ls on Windows guest doesn't support drive letters
503134 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=503134
guestfish's list splitting does not recognize internal quoting
539746 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=539746
launch fails when run inside a Xen guest, when no non-PV kernels are installed
541618 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=541618
guestfish not able to mount freebsd ufs2 partitions automatically
619334 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=619334
RFE: Enable coredump capture in the appliance
--------------------------------------------------
Bugs in MODIFIED, POST or ON_QA state are fixed.
You can help by testing the fixes.
691389 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=691389
Extended attributes don't work over guestmount (FUSE)
750889 MODIFIED https://bugzilla.redhat.com/show_bug.cgi?id=750889
Python code incompatible with Python v3.
713678 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=713678
Not all febootstrap messages are redirected to log callbacks
784647 MODIFIED https://bugzilla.redhat.com/show_bug.cgi?id=784647
Libguestfs uses deprecated net-tools
657499 MODIFIED https://bugzilla.redhat.com/show_bug.cgi?id=657499
checksum: wrong check sum type causes umount to fail
719879 ON_QA https://bugzilla.redhat.com/show_bug.cgi?id=719879
Rebase libguestfs in RHEL 6.3
729076 ON_QA https://bugzilla.redhat.com/show_bug.cgi?id=729076
libguestfs confuses Hp_recovery partition with Windows root filesystem
749828 ON_QA https://bugzilla.redhat.com/show_bug.cgi?id=749828
p2v does not support raid devices
741183 ON_QA https://bugzilla.redhat.com/show_bug.cgi?id=741183
[RFE] Write a tool to align the partition(s) in a Windows XP image to a multiple of 8 sectors
--------------------------------------------------
These bugs are in the VERIFIED state.
731742 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=731742
libguestfs should escape special/non-printing characters in debug output
760221 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=760221
RFE: Support inspection of cciss devices
769359 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=769359
virt-resize on RHEL 6 kernel fails to re-read the partition table
785305 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=785305
ocaml (bytecode) bindings segfault in 'add_drive_opts'
788642 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=788642
virt-edit doesn't preserve file permissions
790958 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=790958
multiprovider build error: RuntimeError: link: /tmp/.guestfs-0/kernel /tmp/.guestfs-0/kernel.10139: File exists
797760 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=797760
virt-resize on Windows XP in sysprep state causes "UNMOUNTABLE_BOOT_VOLUME" BSOD
798197 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=798197
virt-resize confuses format and output_format variables; using --output-format sets the input format
798980 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=798980
Libguestfs live support should be disabled in RHEL 6 packages
799695 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=799695
guestfs.h fails to compile with c++ compiler
801788 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=801788
libguestfs holds open file descriptors when handle is launched
803699 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=803699
libguestfs inspection fails on Windows XP: libguestfs: error: hivex: could not locate HKLMSYSTEMMountedDevices
809401 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=809401
inspection doesn't recognize Fedora 17+ (because of grub2 and UsrMove)
811673 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=811673
guestfs_last_error not set when qemu fails early during launch
812092 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=812092
libguestfs cannot open disk images which are symlinks to files that contain ':' (colon) character
647174 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=647174
RHEL6: virt-clone should remove old udev rules when changing MAC address
789960 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=789960
guestfsd crash when try to mount non-exist disk
799798 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=799798
set_autosync: this function can only be called in the config state at /usr/share/perl5/vendor_perl/Sys/VirtConvert/GuestfsHandle.pm line 107
807557 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=807557
virt-sysprep: wrong params are passed to virt-inspector
807905 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=807905
mkfs blocksize option breaks when creating btrfs
811112 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=811112
[RFE][virt-sysprep] hostname can not be changed on rhel system
811117 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=811117
[RFE][virt-sysprep] net-hwaddr not removed from "ifcfg-*" files on rhel
679737 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=679737
libguestfs: improve error message when zerofree is not available in the appliance
785668 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=785668
aug-defnode: daemon crash
795322 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=795322
add_ro should return error if not running in a config state
796520 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=796520
[RFE] Prevent user from running some appliance configure commands after appliance boot up
801273 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=801273
Document for set-pgroup need to be updated
(76 bugs)
End of BUGS file.

14
COPYING
View File

@@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@@ -56,7 +56,7 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it

View File

@@ -1,112 +1,125 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LIBRARY GENERAL PUBLIC LICENSE
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
@@ -255,7 +268,7 @@ distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also compile or
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
@@ -282,23 +295,31 @@ of these things:
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Accompany the work with a written offer, valid for at
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
d) Verify that the user has already received a copy of these
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
@@ -347,7 +368,7 @@ Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
@@ -390,7 +411,7 @@ excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
@@ -411,7 +432,7 @@ decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
@@ -434,9 +455,9 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Libraries
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
@@ -453,19 +474,18 @@ convey the exclusion of warranty; and each file should have at least the
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
Lesser General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.

View File

@@ -38,10 +38,17 @@ SUBDIRS += tests/qemu
SUBDIRS += tests/guests
SUBDIRS += tests/c-api
SUBDIRS += tests/protocol
SUBDIRS += tests/disks
SUBDIRS += tests/lvm
SUBDIRS += tests/luks
SUBDIRS += tests/md
SUBDIRS += tests/selinux
SUBDIRS += tests/ntfsclone
SUBDIRS += tests/btrfs
SUBDIRS += tests/charsets
SUBDIRS += tests/xml
SUBDIRS += tests/mount-local
SUBDIRS += tests/9p
SUBDIRS += tests/regressions
endif
@@ -135,11 +142,9 @@ EXTRA_DIST = \
contrib/visualize-alignment/README \
contrib/visualize-alignment/tracetops.ml \
html/pod.css \
libguestfs.pc libguestfs.pc.in \
libtool-kill-dependency_libs.sh \
logo/fish.svg logo/fish.png \
m4/.gitignore \
po/remove-potcdate.sin \
update-bugs.sh
# The website.
@@ -147,6 +152,7 @@ HTMLFILES = \
html/guestfs.3.html \
html/guestfs-examples.3.html \
html/guestfs-erlang.3.html \
html/guestfs-faq.1.html \
html/guestfs-java.3.html \
html/guestfs-ocaml.3.html \
html/guestfs-performance.1.html \
@@ -212,7 +218,9 @@ dist-hook:
mv AUTHORS-t AUTHORS
cp AUTHORS $(distdir)/AUTHORS
# Update the list of translatable files in po/POTFILES.in.
# Update the list of translatable files (po/POTFILES po/POTFILES-ml).
# This has to be in the top-level Makefile.am so that we have access
# to DIST_SUBDIRS.
all-local:
cd $(srcdir); \
find $(DIST_SUBDIRS) \
@@ -229,12 +237,10 @@ all-local:
grep -v '^po-docs/' | \
grep -v '^images/' | \
LC_ALL=C sort | \
sed 's,^\./,,' > po/POTFILES.in
# Pkgconfig.
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libguestfs.pc
sed 's,^\./,,' > po/POTFILES
cd $(srcdir); \
find resize sparsify sysprep -name '*.ml' | \
LC_ALL=C sort > po/POTFILES-ml
# Make clean.
@@ -247,7 +253,7 @@ CLEANFILES = \
# is NOT a substitute for proper testing!
quickcheck:
./run test-tool/libguestfs-test-tool $(QUICKCHECK_TEST_TOOL_ARGS)
$(top_builddir)/run test-tool/libguestfs-test-tool $(QUICKCHECK_TEST_TOOL_ARGS)
# Run extra-tests in tests/extra/ subdirectory.

59
README
View File

@@ -46,7 +46,7 @@ For basic functionality and the C tools:
- look at appliance/packagelist.in and install as many of the packages
that apply to your distro as possible
- recent QEMU >= 0.13 (0.14 or later is better) with virtio-serial support
- QEMU >= 1.1.0.
- kernel >= 2.6.34 with virtio-serial support enabled.
@@ -55,11 +55,12 @@ For basic functionality and the C tools:
to make complex changes to the ./configure command line to get it
to work if you don't have virtio)
- febootstrap >= 3.3 (it is best to use the latest version)
- febootstrap >= 3.17
Notes: (1) febootstrap 2.x WILL NOT WORK
(2) febootstrap 3.x is distro-independent, and is required on
Debian and other distros as well as Fedora
(3) that is the minimum version, but later versions are better
- XDR, rpcgen (on Linux these are provided by glibc)
@@ -89,8 +90,9 @@ For basic functionality and the C tools:
- systemtap/DTrace userspace probes (optional)
http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps
- perldoc (pod2man, pod2text, pod2html) to generate the manual pages
and other documentation.
- perl Pod::Man and Pod::Simple are required. These are used to
generate man pages and other documentation. Every recent Perl
distribution ought to include both.
- Readline to have nicer command-line editing in guestfish (optional)
@@ -100,6 +102,8 @@ For basic functionality and the C tools:
- OCaml if you want to rebuild the generated files, and
also to build the OCaml bindings (optional)
- ocaml-gettext if you want to translate OCaml tools (optional)
- po4a for translating manpages and POD files.
This is optional when compiling from the tarball, but mandatory
if you compile from git.
@@ -270,6 +274,53 @@ appliance. You will need to port the febootstrap first
(http://people.redhat.com/~rjones/febootstrap/).
Note on using clang (from LLVM) instead of GCC
----------------------------------------------------------------------
export CC=clang
./configure --disable-probes
make
SystemTap/DTrace-style userspace probe points don't work under the
clang compiler, which is why you may need to disable them.
Don't enable GCC warnings (ie. *don't* use
'./configure --enable-gcc-warnings').
Note on using non-x86 architectures
----------------------------------------------------------------------
In theory libguestfs should work on non-x86 architectures. Usually if
it doesn't it's because qemu isn't available or cannot boot the
kernel.
For ARM you will need to specify the exact machine type and CPU
variant that is required to boot the Linux kernel (there's no way to
know this except by looking at how the Linux kernel was configured).
For example:
./configure \
--with-qemu="qemu-system-arm" \
--with-qemu-options="-M versatilepb -cpu arm926"
./configure \
--with-qemu="qemu-system-arm" \
--with-qemu-options="-M vexpress-a9 -cpu cortex-a9"
Note that since virtio is required by libguestfs, and virtio is a
PCI-based architecture, whatever architecture qemu emulates must
support PCI also.
For PPC64 you will need to specify the IBM pSeries machine type:
./configure \
--with-qemu="qemu-system-ppc64" \
--with-qemu-options="-M pseries"
After building libguestfs, run 'make quickcheck' and pay close
attention to the qemu command line and kernel output.
Copyright and license information
----------------------------------------------------------------------

View File

@@ -1,8 +1,6 @@
Release notes for libguestfs 1.18.0
-----------------------------------
UPDATED TO COMMIT 36f1eb922530b254631781bd6475ff6348f511af
These release notes only cover the differences from the previous
stable/dev branch split (1.16.0). For detailed changelogs, please see
the git repository, or the ChangeLog file distributed in the tarball.
@@ -12,9 +10,7 @@ New features
virt tools:
- virt-sysprep has been rewritten and expanded (thanks Wanlong Gao)
- virt-edit preserves permissions, UID, GID and SELinux context
when editing files
http://libguestfs.org/virt-sysprep.1.html
- virt-sparsify --zero is a new option that zeroes the named
partition or filesystem
@@ -22,10 +18,12 @@ New features
- virt-sparsify can now safely sparsify Linux swap partitions
- virt-sparsify fixed so it cleans up after ^C
http://libguestfs.org/virt-sparsify.1.html
- a new tool 'libguestfs-make-fixed-appliance' is provided to build
fixed appliances that can be copied to other machines that don't
have febootstrap support
http://libguestfs.org/libguestfs-make-fixed-appliance.1.html
- virt-filesystems now displays the parents (containers) of MD
devices and volume groups
@@ -33,11 +31,27 @@ New features
- virt-alignment-scan, run with no args, displays alignment information
for all libvirt domains
- comma and colon characters in filenames now handled correctly by
all virt tools
- virt-df and virt-alignment-scan will display information from all
guests even when a disk is inaccessible
- virt-rescue new --scratch option to make scratch disks
https://rwmj.wordpress.com/2012/04/26/virt-rescue-scratch/#content
- virt-make-fs can now be used to create btrfs
- virt-edit preserves permissions, UID, GID and SELinux context
when editing files
- guestfish passes the close event over stdout and remote correctly
- guestfish new '--pipe-error' option lets you detect errors in pipe
commands
- guestfish globs now expand device names
- comma and colon characters in filenames now handled correctly by
all virt tools
inspection:
- added support for Fedora 17+
@@ -51,8 +65,19 @@ New features
API:
- broad support for btrfs added, including adding multiple devices,
fsck, snapshots (thanks Wanlong Gao)
- the new 'mount-local' API brings FUSE support directly into the
core libguestfs API
https://rwmj.wordpress.com/2012/05/14/tip-using-mount-local-api-from-c/#content
- new man page: guestfs-performance(1), which contains performance
tuning tips.
tuning tips
http://libguestfs.org/guestfs-performance.1.html
- new man page: guestfs-faq(1), Frequently Asked Questions
http://libguestfs.org/guestfs-faq.1.html
- ENOTSUP (from guestfs_last_errno) is now returned for APIs that
are not supported
@@ -63,12 +88,25 @@ New features
- 'display_icon' program displays the icon associated with a guest
- 'mount_local.c' example shows how to use the mount-local API
Security
(no security problems were found or fixed in this release)
New APIs
btrfs-device-add: Add devices to a btrfs filesystem.
btrfs-device-delete: Remove devices from a btrfs filesystem.
btrfs-filesystem-sync: Sync a btrfs filesystem.
btrfs-filesystem-balance: Balance a btrfs filesystem.
btrfs-fsck: Check btrfs filesystem.
btrfs-set-seeding: Enable or disable seeding.
btrfs-subvolume-create: Create a btrfs snapshot.
btrfs-subvolume-delete: Delete a btrfs snapshot.
btrfs-subvolume-list: List btrfs snapshots and subvolumes.
btrfs-subvolume-set-default: Set default btrfs subvolume.
btrfs-subvolume-snapshot: Create a writable btrfs snapshot.
get-e2attrs: List ext2 file attributes of a file.
get-e2generation: Get ext2 file generation of a file.
isoinfo, isoinfo-device: Get information from the header of ISO files.
@@ -90,6 +128,8 @@ Internals
- The debian/ subdirectory has been removed. We recommend you use
the official Debian packages made by Hilko Bengen.
http://people.debian.org/~bengen/libguestfs/
http://packages.debian.org/search?keywords=libguestfs
- O_CLOEXEC / SOCK_CLOEXEC is now used for almost all file
descriptors that the library opens.
@@ -106,6 +146,8 @@ Internals
- use ./configure --enable-valgrind-daemon to use valgrind on the
daemon; many errors have been fixed
- use ./configure --with-qemu-options to pass extra options to qemu
- the daemon now has a growable strings buffer type (DECLARE_STRINGSBUF)
- the <guestfs.h> header file works with C++ and we have a regression
@@ -116,10 +158,13 @@ Internals
- .gitignore fixed to use absolute paths
- gobject bindings have been expanded (thanks Matt Booth)
- gobject bindings have been expanded, including mapping libguestfs
events to gobject signals (thanks Matt Booth)
- gobject documentation is generated properly (thanks Matt Booth)
- gobject header files now live in a subdirectory
- CompareWithString test in the generator now works
- FUInt32, FUInt64 struct field types now use the correct XDR type
@@ -144,10 +189,19 @@ Internals
- guestfish --listen now cleans up properly
- the BUSY state has been removed
- gettextize has been removed, replaced by a simple Makefile.am
- gettext support now covers virt-resize, virt-sparsify and virt-sysprep
- better support for the arm architecture
Bugs fixed
[./bugs-in-changelog.sh 1.16.0..]
- 822490 virt-ls error: "libguestfs: error: checksum: path: parameter cannot be NULL"
- 816839 data overflow error when debug progress -1
- 816098 virt-make-fs fails to make a btrfs filesystem because it doesn't allocate enough space
- 811872 inspection fails on ubuntu 10.04 guest with encrypted swap
- 811650 guestfs_last_error not set when qemu fails early during launch
- 811649 libguestfs cannot open disk images which are symlinks to files that contain ':' (colon) character
@@ -158,20 +212,29 @@ Bugs fixed
- 805070 virt-filesystems should show 'parents' of LV and RAID devices
- 804464 libguestfs cannot be built when LINGUAS is different then ja or uk
- 803664 libguestfs inspection fails on Windows XP: libguestfs: error: hivex: could not locate HKLM\SYSTEM\MountedDevices
- 803533 guestfish: write error
- 802389 event handlers for 'close' event doesn't work in remote mode
- 802109 libguestfs uses putc on stderr, results in many individual 1 byte writes of debug messages
- 801640 [RFE] the error reported by resize2fs-M need to be more clear
- 801298 Possible null dereference and resource leaks
- 801273 Document for set-pgroup need to be updated
- 798196 virt-resize confuses format and output_format variables; using --output-format sets the input format
- 797986 virt-resize on Windows XP in sysprep state causes "UNMOUNTABLE_BOOT_VOLUME" BSOD
- 796520 [RFE] Prevent user from running some appliance configure commands after appliance boot up
- 790721 multiprovider build error: RuntimeError: link: /tmp/.guestfs-0/kernel /tmp/.guestfs-0/kernel.10139: File exists
- 789960 guestfsd crash when try to mount non-exist disk
- 789504 virt-df (other tools?) should not give up if a guest disk is missing
- 788641 virt-edit doesn't preserve file permissions
- 786215 libguestfs inspection does not recognize FreeDOS operating system
- 786188 libguestfs inspection does not recognize FreeDOS install CD
- 785668 aug-defnode: daemon crash
- 784647 Libguestfs uses deprecated net-tools
- 769304 virt-resize on RHEL 6 kernel fails to re-read the partition table
- 755729 Error message for resize2fs-M needs tweaking
- 701814 virt-win-reg fails on a libvirt guest that has no defined disk format: "format parameter is empty or contains disallowed characters"
- 679737 libguestfs: improve error message when zerofree is not available in the appliance
- 635971 glob mkfs ext2 /dev/vd[b-t]1 does not expand
Release notes for libguestfs 1.16.0
-----------------------------------

View File

@@ -12,19 +12,19 @@ Before you read this:
(4) For general "might be good to have" items, see 'TODO'.
For next major stable release (1.18)
For next major stable release (1.20)
------------------------------------
* Allow remote libvirt volumes to be accessed. This requires some
enhancements to libvirt which have been agreed but not yet
implemented.
Bugs assigned to 1.18 (put "1.18" in the Devel Whiteboard field in
Bugs assigned to 1.20 (put "1.20" in the Devel Whiteboard field in
Bugzilla):
https://bugzilla.redhat.com/buglist.cgi?query_format=advanced&field0-0-0=cf_devel_whiteboard&bug_status=NEW&bug_status=ASSIGNED&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=FAILS_QA&bug_status=RELEASE_PENDING&bug_status=POST&bug_status=PASSES_QA&type0-0-0=anywords&value0-0-0=1.18&component=libguestfs&product=Virtualization%20Tools
https://bugzilla.redhat.com/buglist.cgi?query_format=advanced&field0-0-0=cf_devel_whiteboard&bug_status=NEW&bug_status=ASSIGNED&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=FAILS_QA&bug_status=RELEASE_PENDING&bug_status=POST&bug_status=PASSES_QA&type0-0-0=anywords&value0-0-0=1.20&component=libguestfs&product=Virtualization%20Tools
Beyond 1.18
Beyond 1.20
-----------
* Make 'guestfish --ro' be the default, and get users to use

110
TODO
View File

@@ -192,6 +192,9 @@ would make more sense to just use libblkid for this.
There are some places where we call out to the 'blkid' program. This
might be replaced by direct use of the library (if this is easier).
But it is very hard to be compatible between RHEL6 and RHEL5 when
using direct library.
Visualization
-------------
@@ -373,20 +376,12 @@ Return libosinfo mappings from inspection API.
virt-sysprep ideas
------------------
- touch /.unconfigured ?
- other Spacewalk / RHN IDs (?)
- Kerberos keys
- Puppet registration
- user accounts
- Windows sysprep
(see: https://github.com/clalancette/oz/blob/e74ce83283d468fd987583d6837b441608e5f8f0/oz/Windows.py )
- blue skies: change the background image
- (librarian suggests ...)
. install a firstboot script virt-sysprep --script=/tmp/foo.sh
. run an external shell script
. run external guestfish script virt-sysprep --fish=/tmp/foo.fish
. rm /var/cache/apt/archives/*
- /var/run/* and pam_faillock's data files
- if drives are encrypted, then dm-crypt key should be changed
and drives all re-encrypted
- /etc/pki
@@ -398,13 +393,34 @@ virt-sysprep ideas
- secure erase of inodes etc using scrub (Steve Grubb)
- other directories that could require cleaning include:
/var/run/*
/var/lib/sss/db/*
/var/lib/samba/*
/var/lib/samba/*/*
(thanks Marko Myllynen, James Antill)
- remove or modify UUIDs in /etc/fstab (eg. on Ubuntu)
(thanks Joshua Daniel Franklin)
Kazuo Moriwaka adds:
- "yum clean all" (or the equivalent) to remove yum caches
- swap devices (both of block device and file) should be wiped. This may
good for security purpose, and size. I found virt-sparsify can clear
swap partition.
- --script is nice. Defining default sysprep script directory
like /usr/lib/guestfs/sysprep-scripts.d/ may be useful to integrate
other package maintainer(or ISV)'s effort.
- To achieve better (or crazy) coverage, a simple examination will be
help:
Install the same kickstart into VM twice, and diff the trees.
Many autogenerated IDs and configs can be found :)
As well as 'virt-sysprep' there is a case for a 'virt-customize' tool
which can customize templated guests. This would be useful within
companies/organizations that want to offer multiple guests, but all
customized with the organization logo etc. Some ideas:
- change the background image to some custom desktop
- change the sign-on messages (/etc/issue.net etc)
- firstboot script (as suggested by librarian above)
- Windows login script/service
Launch remote sessions over ssh
-------------------------------
@@ -460,7 +476,79 @@ during the conversion, since current behaviour is very bad when this
happens (it usually causes virt-sparsify to hang). This requires
writing a small C binding to statvfs for OCaml.
'virt-sparsify --whitelist' option to generate skeletons (for
debugging, bug forensics, diagnosis). The whilelist option would
specify a list of files to be *preserved*. All other files in the
image would be replaced by equivalent files of zeroes, thus minimizing
the size of the debug image that needs to be shipped to us by the
customer.
Optimize the appliance
----------------------
Pass -cpu host. Anything else?
[The libvirt attach-method uses 'host-model' which is basically
the same as this]
Sort out partitioning
---------------------
Ignoring some legacy APIs, we currently have a mixed selection of
'part-*' APIs, implemented using parted. We don't like parted or
libparted very much, and would love to replace it with something else.
The part-* APIs are quirky, but not too bad and we should maintain and
extend them instead of making another set of APIs.
One option is to write "libmbr" and "libgpt" libraries that would just
do MBR and GPT respectively, and do it directly and do it well. They
wouldn't try to abstract anything (so, unlike libparted). We could
then reimplement the part-* APIs on top of these hopefully sensible
libraries. This is a lot of work.
Another option is to look for tools or libraries to replace parted.
For GPT there is a fairly obvious candidate: Rod Smith's GPT fdisk
(http://www.rodsbooks.com/gdisk/). Rod has spent a lot of time
studying GPT, and seems to know more about it than any sane man
should. There is a command line tool designed for scripts called
'sgdisk'. The tools are packaged for many Linux distros. Even if
this approach works, it doesn't solve the MBR problem, so likely we'd
have to write a library for that (or perhaps go back to sfdisk but
using a very abstracted interface over sfdisk).
qemu caching
------------
(Suggested by Paolo Bonzini and Kevin Wolf)
Measure the effect of cache=none, cache=directsync,
cache=writethrough, cache=writeback.
It's doubtful that using cache=none is useful, since it disables the
host cache making read-heavy workloads slower (they rely entirely on
the smaller appliance kernel's cache). And in libguestfs we don't
necessarily care about ongoing data integrity while writing, as long
as data is reliably written out when g.sync, g.shutdown or g.close
return. Also in libguestfs we effectively control the whole stack, so
we can ensure write barriers happen when we want.
libvirt attach-method
---------------------
Since libguestfs 1.19.24 this mostly works. Here are some suggested
items to work on:
- SELinux labelling of guestfsd.sock, console.sock
https://bugzilla.redhat.com/show_bug.cgi?id=842307
Once this is fixed, remove <seclabel type=none> from libvirt XML
- Check feature parity between src/launch-appliance.c and
src/launch-libvirt.c.
- Remote support. (This requires work on libvirt)
virt-sparsify should use discard
--------------------------------
This requires some changes to qemu to make discard work properly
throughout the entire stack.

View File

@@ -26,11 +26,11 @@ bin_PROGRAMS = virt-alignment-scan
SHARED_SOURCE_FILES = \
../fish/config.c \
../fish/domain.c \
../fish/inspect.c \
../fish/keys.c \
../fish/options.h \
../fish/options.c \
../fish/virt.c
../fish/options.c
virt_alignment_scan_SOURCES = \
$(SHARED_SOURCE_FILES) \
@@ -62,7 +62,7 @@ noinst_DATA = $(top_builddir)/html/virt-alignment-scan.1.html
virt-alignment-scan.1 $(top_builddir)/html/virt-alignment-scan.1.html: stamp-virt-alignment-scan.pod
stamp-virt-alignment-scan.pod: virt-alignment-scan.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man virt-alignment-scan.1 \
--html $(top_builddir)/html/virt-alignment-scan.1.html \
$<
@@ -70,10 +70,6 @@ stamp-virt-alignment-scan.pod: virt-alignment-scan.pod
# Tests.
# random_val := $(shell awk 'BEGIN{srand(); print 1+int(255*rand())}' < /dev/null)
# TESTS_ENVIRONMENT = \
# MALLOC_PERTURB_=$(random_val) \
# $(top_builddir)/run
# TESTS_ENVIRONMENT = $(top_builddir)/run --test
# TESTS = test-virt-alignment-scan.sh

View File

@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#include <assert.h>
#ifdef HAVE_LIBVIRT
@@ -88,7 +89,7 @@ static void add_domains_by_id (virConnectPtr conn, int *ids, size_t n);
static void add_domains_by_name (virConnectPtr conn, char **names, size_t n);
static void add_domain (virDomainPtr dom);
static int add_disk (guestfs_h *g, const char *filename, const char *format, int readonly, void *domain_vp);
static void add_disks_to_handle_reverse (struct disk *disk);
static size_t add_disks_to_handle_reverse (struct disk *disk, size_t *errors_r);
static void reset_guestfs_handle (void);
void
@@ -97,7 +98,7 @@ get_domains_from_libvirt (int uuid, size_t *worst_alignment_ptr)
virErrorPtr err;
virConnectPtr conn;
int n;
size_t i;
size_t i, count, errors;
const char *prefix;
nr_domains = 0;
@@ -108,7 +109,7 @@ get_domains_from_libvirt (int uuid, size_t *worst_alignment_ptr)
if (!conn) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not connect to libvirt (code %d, domain %d): %s"),
_("%s: could not connect to libvirt (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
@@ -117,7 +118,7 @@ get_domains_from_libvirt (int uuid, size_t *worst_alignment_ptr)
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not get number of running domains (code %d, domain %d): %s"),
_("%s: could not get number of running domains (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
@@ -127,7 +128,7 @@ get_domains_from_libvirt (int uuid, size_t *worst_alignment_ptr)
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not list running domains (code %d, domain %d): %s"),
_("%s: could not list running domains (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
@@ -138,7 +139,7 @@ get_domains_from_libvirt (int uuid, size_t *worst_alignment_ptr)
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not get number of inactive domains (code %d, domain %d): %s"),
_("%s: could not get number of inactive domains (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
@@ -148,7 +149,7 @@ get_domains_from_libvirt (int uuid, size_t *worst_alignment_ptr)
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not list inactive domains (code %d, domain %d): %s"),
_("%s: could not list inactive domains (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
@@ -170,8 +171,14 @@ get_domains_from_libvirt (int uuid, size_t *worst_alignment_ptr)
/* Sort the domains alphabetically by name for display. */
qsort (domains, nr_domains, sizeof (struct domain), compare_domain_names);
errors = 0;
for (i = 0; i < nr_domains; ++i) {
add_disks_to_handle_reverse (domains[i].disks);
if (domains[i].disks == NULL)
continue;
count = add_disks_to_handle_reverse (domains[i].disks, &errors);
if (count == 0)
continue;
if (guestfs_launch (g) == -1)
exit (EXIT_FAILURE);
@@ -189,6 +196,12 @@ get_domains_from_libvirt (int uuid, size_t *worst_alignment_ptr)
for (i = 0; i < nr_domains; ++i)
free_domain (&domains[i]);
free (domains);
if (errors > 0) {
fprintf (stderr, _("%s: failed to analyze a disk, see error(s) above\n"),
program_name);
exit (EXIT_FAILURE);
}
}
static void
@@ -296,13 +309,15 @@ add_disk (guestfs_h *g,
return 0;
}
static void
add_disks_to_handle_reverse (struct disk *disk)
static size_t
add_disks_to_handle_reverse (struct disk *disk, size_t *errors_r)
{
if (disk == NULL)
return;
size_t nr_disks_added;
add_disks_to_handle_reverse (disk->next);
if (disk == NULL)
return 0;
nr_disks_added = add_disks_to_handle_reverse (disk->next, errors_r);
struct guestfs_add_drive_opts_argv optargs = { .bitmask = 0 };
@@ -314,8 +329,12 @@ add_disks_to_handle_reverse (struct disk *disk)
optargs.format = disk->format;
}
if (guestfs_add_drive_opts_argv (g, disk->filename, &optargs) == -1)
exit (EXIT_FAILURE);
if (guestfs_add_drive_opts_argv (g, disk->filename, &optargs) == -1) {
(*errors_r)++;
return nr_disks_added;
}
return nr_disks_added+1;
}
/* Close and reopen the libguestfs handle. */

View File

@@ -246,7 +246,7 @@ main (int argc, char *argv[])
void
scan (size_t *worst_alignment, const char *prefix)
{
char **devices;
char **devices, *p;
size_t i, j;
size_t alignment;
uint64_t start;
@@ -262,11 +262,11 @@ scan (size_t *worst_alignment, const char *prefix)
exit (EXIT_FAILURE);
/* Canonicalize the name of the device for printing. */
if (STRPREFIX (devices[i], "/dev/") &&
(devices[i][5] == 'h' || devices[i][5] == 'v') &&
devices[i][6] == 'd' &&
c_isalpha (devices[i][7]))
devices[i][5] = 's';
p = guestfs_canonical_device_name (g, devices[i]);
if (p == NULL)
exit (EXIT_FAILURE);
free (devices[i]);
devices[i] = p;
for (j = 0; j < parts->len; ++j) {
/* Start offset of the partition in bytes. */

View File

@@ -15,6 +15,9 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# Old RHEL 5 autoconf doesn't have builddir.
builddir ?= .
include $(top_srcdir)/subdir-rules.mk
EXTRA_DIST = \
@@ -39,26 +42,29 @@ superminfs_DATA = \
# This used to be a configure-generated file (as is update.sh still).
# However config.status always touches the destination file, which
# means the appliance got rebuilt too often.
make.sh: make.sh.in
make.sh: make.sh.in $(top_builddir)/config.log $(top_builddir)/config.status
cd $(top_builddir) && \
./config.status --file=appliance/$@-t:appliance/$<
chmod +x $@-t
mv $@-t $@
cmp -s $@ $@-t || mv $@-t $@
rm -f $@-t
PACKAGELIST_CPP_FLAGS = -D$(DISTRO)=1
if VALGRIND_DAEMON
PACKAGELIST_CPP_FLAGS += -DVALGRIND_DAEMON=1
endif
packagelist: packagelist.in
packagelist: packagelist.in Makefile
cpp -undef $(PACKAGELIST_CPP_FLAGS) < $< | \
grep -v '^[[:space:]]*$$' | grep -v '^#' > $@-t
mv $@-t $@
cmp -s $@ $@-t || mv $@-t $@
rm -f $@-t
excludelist: excludelist.in
excludelist: excludelist.in Makefile
cpp -undef $(PACKAGELIST_CPP_FLAGS) < $< | \
grep -v '^[[:space:]]*$$' | grep -v '^#' > $@-t
mv $@-t $@
cmp -s $@ $@-t || mv $@-t $@
rm -f $@-t
supermin.d/base.img supermin.d/hostfiles: stamp-supermin
stamp-supermin: make.sh packagelist excludelist
@@ -94,7 +100,7 @@ man_MANS = libguestfs-make-fixed-appliance.1
libguestfs-make-fixed-appliance.1 $(top_builddir)/html/libguestfs-make-fixed-appliance.1.html: stamp-libguestfs-make-fixed-appliance.pod
stamp-libguestfs-make-fixed-appliance.pod: libguestfs-make-fixed-appliance.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man libguestfs-make-fixed-appliance.1 \
--html $(top_builddir)/html/libguestfs-make-fixed-appliance.1.html \
$<

View File

@@ -32,19 +32,24 @@
/* Plymouth is a graphical boot thing - not needed. */
^plymouth
/* Linux firmware. Note that febootstrap itself excludes the kernel
* which is also not needed since we get the kernel, modules etc
* from the host at appliance boot.
*/
/* Linux firmware. */
^linux-firmware
/* Keyboard maps - appliance is not interactive. */
^kbd-misc
#ifdef REDHAT
/* Linux kernel. febootstrap <= 3.18 used to exclude the kernel
* package (only) by default, but since 3.19 it doesn't do this any
* longer.
*/
^kernel
^fedora-logos
^redhat-logos
^dracut
#endif
#ifdef DEBIAN

View File

@@ -12,9 +12,11 @@ export RUNLEVEL PREVLEVEL
mkdir -p /sysroot
rm -f /proc; mkdir /proc
if [ ! -d /proc ]; then rm -f /proc; fi
mkdir -p /proc
mount -t proc /proc /proc
rm -f /sys; mkdir /sys
if [ ! -d /sys ]; then rm -f /sys; fi
mkdir -p /sys
mount -t sysfs /sys /sys
mkdir -p /run/lock
@@ -29,36 +31,39 @@ if [ ! -L /etc/init.d/udev -a -x /etc/init.d/udev ]; then
fi
elif [ -x /sbin/start_udev ] && /sbin/start_udev; then
:
elif [ -x /sbin/udevd ]; then
echo -e '\000\000\000\000' > /proc/sys/kernel/hotplug
/sbin/udevd --daemon
udevadm trigger
udevadm settle
elif [ -x /lib/udev/udevd ]; then
echo -e '\000\000\000\000' > /proc/sys/kernel/hotplug
/lib/udev/udevd --daemon
udevadm trigger
udevadm settle
else
echo No udev, creating /dev manually
mount -t tmpfs none /dev
mkdir /dev/pts /dev/shm /dev/mapper
mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts
# Must do each MAKEDEV individually, because if one device fails,
# MAKEDEV will quit without creating the rest (RHBZ#507374).
for dev in mem null port zero core full ram tty console fd \
hda hdb hdc hdd sda sdb sdc sdd loop sd; do
MAKEDEV $dev ||:
# Find udevd and run it directly.
for f in /sbin/udevd /lib/udev/udevd \
/lib/systemd/systemd-udevd /usr/lib/systemd/systemd-udevd \
/usr/lib/udev/udevd; do
if [ -x "$f" ]; then UDEVD="$f"; fi
done
mknod /dev/ptmx c 5 2; chmod 0666 /dev/ptmx
mknod /dev/random c 1 8; chmod 0666 /dev/random
mknod /dev/urandom c 1 9; chmod 0444 /dev/urandom
ln -sf /proc/self/fd/0 /dev/stdin
ln -sf /proc/self/fd/1 /dev/stdout
ln -sf /proc/self/fd/2 /dev/stderr
if [ -n "$UDEVD" ]; then
echo -e '\000\000\000\000' > /proc/sys/kernel/hotplug
$UDEVD --daemon
udevadm trigger
udevadm settle --timeout=600
else
echo No udevd, creating /dev manually.
mount -t tmpfs none /dev
mkdir /dev/pts /dev/shm /dev/mapper
mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts
# Must do each MAKEDEV individually, because if one device fails,
# MAKEDEV will quit without creating the rest (RHBZ#507374).
for dev in mem null port zero core full ram tty console fd \
hda hdb hdc hdd sda sdb sdc sdd loop sd; do
MAKEDEV $dev ||:
done
mknod /dev/ptmx c 5 2; chmod 0666 /dev/ptmx
mknod /dev/random c 1 8; chmod 0666 /dev/random
mknod /dev/urandom c 1 9; chmod 0444 /dev/urandom
ln -sf /proc/self/fd/0 /dev/stdin
ln -sf /proc/self/fd/1 /dev/stdout
ln -sf /proc/self/fd/2 /dev/stderr
modprobe virtio_pci
modprobe virtio_net
modprobe virtio_pci
modprobe virtio_net
fi
fi
if grep -sq selinux=1 /proc/cmdline; then

View File

@@ -130,7 +130,7 @@ Then copy all four files:
into a directory somewhere, eg. /usr/local/lib/guestfs/appliance/
Then build libguestfs (>= 1.16.7 or >= 1.17.10) from source, disabling
Then build libguestfs (>= 1.16.7 or >= 1.18) from source, disabling
the normal appliance and daemon:
./configure --disable-appliance --disable-daemon

View File

@@ -39,8 +39,7 @@
ntfs-3g
reiserfs-utils
libselinux
systemd /* for /sbin/reboot */
udev
systemd /* for /sbin/reboot and udevd */
util-linux-ng
vim-minimal
xz
@@ -64,7 +63,6 @@
ntfs-3g
ntfsprogs
reiserfsprogs
udev
ufsutils
util-linux
vim-tiny
@@ -87,7 +85,6 @@
ntfsprogs
ntfs-3g
reiserfsprogs
udev
util-linux-ng
xz
#endif /* ARCHLINUX */
@@ -96,6 +93,7 @@ acl
attr
bash
binutils
bzip2
coreutils
cpio
dosfstools
@@ -109,6 +107,7 @@ iproute
jfsutils
libxml2
lsof
lsscsi
lvm2
lzop
mdadm
@@ -124,6 +123,7 @@ psmisc
scrub
strace
tar
udev
#ifndef UBUNTU
/* on Ubuntu contains a file in /lib64 which conflicts with libc6 that has
* /lib64 as a symbolic link

View File

@@ -26,13 +26,6 @@ git submodule init || exit $?
git submodule update || exit $?
GNULIB_SRCDIR=.gnulib
ls po/*.po 2>/dev/null | sed 's|.*/||; s|\.po$||' > po/LINGUAS
# Run autopoint, to get po/Makevars.template:
# Also, released autopoint has the tendency to install macros that have
# been obsoleted in current gnulib, so run this before gnulib-tool.
autopoint --force
# Autoreconf runs aclocal before libtoolize, which causes spurious
# warnings if the initial aclocal is confused by the libtoolized
# (or worse out-of-date) macro directory.
@@ -54,6 +47,7 @@ connect
dup3
error
filevercmp
fstatat
fsusage
fts
full-read
@@ -72,11 +66,13 @@ ignore-value
lock
maintainer-makefile
manywarnings
memmem
mkdtemp
netdb
netinet_in
openat
perror
pipe2
pread
progname
read-file
@@ -85,6 +81,7 @@ select
setenv
sleep
socket
stat-time
strchrnul
strerror
strndup
@@ -101,8 +98,12 @@ xstrtoll
xvasprintf
'
# If any tests fail, avoid including them by adding them to
# this list.
avoid="--avoid=dummy --avoid=getlogin_r-tests"
$gnulib_tool \
--avoid=dummy \
$avoid \
--with-tests \
--m4-base=m4 \
--source-base=gnulib/lib \

View File

@@ -31,11 +31,11 @@ bin_PROGRAMS = virt-cat virt-filesystems virt-ls
SHARED_SOURCE_FILES = \
../fish/config.c \
../fish/domain.c \
../fish/inspect.c \
../fish/keys.c \
../fish/options.h \
../fish/options.c \
../fish/virt.c
../fish/options.c
virt_cat_SOURCES = \
$(SHARED_SOURCE_FILES) \
@@ -102,7 +102,7 @@ noinst_DATA = \
virt-cat.1 $(top_builddir)/html/virt-cat.1.html: stamp-virt-cat.pod
stamp-virt-cat.pod: virt-cat.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man virt-cat.1 \
--html $(top_builddir)/html/virt-cat.1.html \
$<
@@ -111,7 +111,7 @@ stamp-virt-cat.pod: virt-cat.pod
virt-ls.1 $(top_builddir)/html/virt-ls.1.html: stamp-virt-ls.pod
stamp-virt-ls.pod: virt-ls.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man virt-ls.1 \
--html $(top_builddir)/html/virt-ls.1.html \
$<
@@ -120,7 +120,7 @@ stamp-virt-ls.pod: virt-ls.pod
virt-filesystems.1 $(top_builddir)/html/virt-filesystems.1.html: stamp-virt-filesystems.pod
stamp-virt-filesystems.pod: virt-filesystems.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man virt-filesystems.1 \
--html $(top_builddir)/html/virt-filesystems.1.html \
$<
@@ -128,11 +128,7 @@ stamp-virt-filesystems.pod: virt-filesystems.pod
# Tests.
random_val := $(shell awk 'BEGIN{srand(); print 1+int(255*rand())}' < /dev/null)
TESTS_ENVIRONMENT = \
MALLOC_PERTURB_=$(random_val) \
$(top_builddir)/run
TESTS_ENVIRONMENT = $(top_builddir)/run --test
if ENABLE_APPLIANCE
TESTS = test-virt-cat.sh test-virt-filesystems.sh test-virt-ls.sh

View File

@@ -82,8 +82,6 @@ static int output = 0;
#define NR_COLUMNS 8
static int columns;
static char *canonical_device (const char *dev);
static void do_output_title (void);
static void do_output (void);
static void do_output_end (void);
@@ -466,7 +464,9 @@ do_output_filesystems (void)
(STREQ (fses[i+1], "swap") || STREQ (fses[i+1], "unknown")))
goto next;
dev = canonical_device (fses[i]);
dev = guestfs_canonical_device_name (g, fses[i]);
if (dev == NULL)
exit (EXIT_FAILURE);
/* Only bother to look these up if we will be displaying them,
* otherwise pass them as NULL.
@@ -639,7 +639,9 @@ do_output_pvs (void)
char uuid[33];
const char *parents[1] = { NULL };
dev = canonical_device (pvs->val[i].pv_name);
dev = guestfs_canonical_device_name (g, pvs->val[i].pv_name);
if (!dev)
exit (EXIT_FAILURE);
memcpy (uuid, pvs->val[i].pv_uuid, 32);
uuid[32] = '\0';
@@ -693,7 +695,9 @@ do_output_partitions (void)
int64_t size = -1;
int mbr_id = -1;
dev = canonical_device (parts[i]);
dev = guestfs_canonical_device_name (g, parts[i]);
if (!dev)
exit (EXIT_FAILURE);
if ((columns & COLUMN_SIZE)) {
size = guestfs_blockdev_getsize64 (g, parts[i]);
@@ -708,7 +712,9 @@ do_output_partitions (void)
if ((columns & COLUMN_MBR))
mbr_id = get_mbr_id (parts[i], parent_name);
char *p = canonical_device (parent_name);
char *p = guestfs_canonical_device_name (g, parent_name);
if (!p)
exit (EXIT_FAILURE);
free (parent_name);
parent_name = p;
@@ -742,7 +748,9 @@ do_output_blockdevs (void)
char *dev;
char **parents;
dev = canonical_device (devices[i]);
dev = guestfs_canonical_device_name (g, devices[i]);
if (!dev)
exit (EXIT_FAILURE);
if ((columns & COLUMN_SIZE)) {
size = guestfs_blockdev_getsize64 (g, devices[i]);
@@ -766,26 +774,6 @@ do_output_blockdevs (void)
free (devices);
}
/* /dev/vda1 -> /dev/sda. Returns a string which the caller must free. */
static char *
canonical_device (const char *dev)
{
char *ret = strdup (dev);
if (ret == NULL) {
perror ("strdup");
exit (EXIT_FAILURE);
}
if (STRPREFIX (ret, "/dev/") &&
(ret[5] == 'h' || ret[5] == 'v') &&
ret[6] == 'd' &&
c_isalpha (ret[7]) &&
(c_isdigit (ret[8]) || ret[8] == '\0'))
ret[5] = 's';
return ret;
}
/* Returns an empty list of parents. Note this must be freed using
* free_strings.
*/
@@ -841,8 +829,11 @@ parents_of_md (char *device)
exit (EXIT_FAILURE);
}
for (i = 0; i < stats->len; ++i)
ret[i] = canonical_device (stats->val[i].mdstat_device);
for (i = 0; i < stats->len; ++i) {
ret[i] = guestfs_canonical_device_name (g, stats->val[i].mdstat_device);
if (!ret[i])
exit (EXIT_FAILURE);
}
ret[stats->len] = NULL;
@@ -902,8 +893,11 @@ parents_of_vg (char *vg)
break;
}
if (j < pvs->len)
ret[i] = canonical_device (pvs->val[j].pv_name);
if (j < pvs->len) {
ret[i] = guestfs_canonical_device_name (g, pvs->val[j].pv_name);
if (!ret[i])
exit (EXIT_FAILURE);
}
else {
fprintf (stderr, "%s: warning: unknown PV UUID ignored\n", __func__);
ret[i] = strndup (pvuuids[i], 32);

View File

@@ -781,7 +781,7 @@ show_file (const char *dir, const char *name,
const struct guestfs_xattr_list *xattrs)
{
char filetype[2];
char *path = NULL, *csum = NULL, *link = NULL;
char *path, *csum = NULL, *link = NULL;
/* Display the basic fields. */
output_start_line ();
@@ -833,6 +833,8 @@ show_file (const char *dir, const char *name,
output_xattrs (xattrs);
*/
path = full_path (dir, name);
if (checksum && is_reg (stat->mode)) {
csum = guestfs_checksum (g, checksum, path);
if (!csum)
@@ -841,7 +843,6 @@ show_file (const char *dir, const char *name,
output_string (csum);
}
path = full_path (dir, name);
output_string (path);
if (is_lnk (stat->mode))

View File

@@ -19,8 +19,8 @@
# add extra information using --with-extra="..." which may be any
# freeform string.
m4_define([libguestfs_major], [1])
m4_define([libguestfs_minor], [17])
m4_define([libguestfs_release], [33])
m4_define([libguestfs_minor], [19])
m4_define([libguestfs_release], [28])
AC_INIT([libguestfs],libguestfs_major.libguestfs_minor.libguestfs_release)
AC_CONFIG_AUX_DIR([build-aux])
@@ -63,13 +63,30 @@ AC_DEFINE([PACKAGE_VERSION_MINOR],[libguestfs_minor],[Minor version number])
AC_DEFINE([PACKAGE_VERSION_RELEASE],[libguestfs_release],[Release number])
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_EXTRA],["$libguestfs_extra"],[Extra version string])
dnl Default attach method.
AC_MSG_CHECKING([if the user specified a default attach method])
AC_ARG_WITH([default-attach-method],
[AS_HELP_STRING([--with-default-attach-method="appliance|libvirt|..."],
[set default attach method @<:@default=appliance@:>@])],
[DEFAULT_ATTACH_METHOD="$withval"],
[DEFAULT_ATTACH_METHOD=appliance])
AC_MSG_RESULT([$DEFAULT_ATTACH_METHOD])
AC_DEFINE_UNQUOTED([DEFAULT_ATTACH_METHOD],["$DEFAULT_ATTACH_METHOD"],
[default attach method])
dnl Early gnulib initialization.
gl_EARLY
gl_INIT
AC_PROG_LIBTOOL
AC_PROG_SED
# Define $(SED).
m4_ifdef([AC_PROG_SED],[
AC_PROG_SED
],[
dnl ... else hope for the best
AC_SUBST([SED], "sed")
])
dnl Check for basic C environment.
AC_PROG_CC_STDC
@@ -141,9 +158,12 @@ if test "$gl_gcc_warnings" = yes; then
AC_SUBST([WARN_CFLAGS])
AC_DEFINE([lint], [1], [Define to 1 if the compiler is checking for lint.])
AC_DEFINE([_FORTIFY_SOURCE], [2],
[enable compile-time and run-time bounds-checking, and some warnings])
AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks])
AH_VERBATIM([FORTIFY_SOURCE],
[/* Enable compile-time and run-time bounds-checking, and some warnings. */
#if __OPTIMIZE__
# define _FORTIFY_SOURCE 2
#endif])
fi
AC_C_PROTOTYPES
@@ -198,6 +218,7 @@ AC_CHECK_HEADERS([\
dnl Functions.
AC_CHECK_FUNCS([\
fsync \
futimens \
getxattr \
htonl \
@@ -235,21 +256,22 @@ AC_CHECK_LIB([ncurses], [UP], [], [
])
LIBS="$old_LIBS"
dnl For modified printf in the daemon, we need glibc either (old-style)
dnl register_printf_function or (new-style) register_printf_specifier.
AC_CHECK_FUNC([register_printf_specifier],[
AC_DEFINE([HAVE_REGISTER_PRINTF_SPECIFIER],[1],
[Define to 1 if you have new-style register_printf_specifier])
],[
AC_CHECK_FUNC([register_printf_function],[
AC_DEFINE([HAVE_REGISTER_PRINTF_FUNCTION],[1],
[Define to 1 if you have old-style register_printf_function])
],[
AC_MSG_FAILURE(
[No support for glibc-style extended printf formatters.
dnl GNU gettext tools (optional).
AC_CHECK_PROG([XGETTEXT],[xgettext],[xgettext],[no])
AC_CHECK_PROG([MSGCAT],[msgcat],[msgcat],[no])
AC_CHECK_PROG([MSGFMT],[msgfmt],[msgfmt],[no])
AC_CHECK_PROG([MSGMERGE],[msgmerge],[msgmerge],[no])
This means you either have a very old glibc (pre-2.0) or you
are using some other libc where this is not supported.])])])
dnl Check they are the GNU gettext tools.
AC_MSG_CHECKING([msgfmt is GNU tool])
if $MSGFMT --version >/dev/null 2>&1 && $MSGFMT --version | grep -q 'GNU gettext'; then
msgfmt_is_gnu=yes
else
msgfmt_is_gnu=no
fi
AC_MSG_RESULT([$msgfmt_is_gnu])
AM_CONDITIONAL([HAVE_GNU_GETTEXT],
[test "x$XGETTEXT" != "xno" && test "x$MSGCAT" != "xno" && test "x$MSGFMT" != "xno" && test "x$MSGMERGE" != "xno" && test "x$msgfmt_is_gnu" != "xno"])
dnl Build the daemon?
AC_MSG_CHECKING([if we should build the daemon])
@@ -306,6 +328,22 @@ if test "x$enable_daemon" = "xyes"; then
fi
AC_MSG_RESULT([$DAEMON_SUPERMIN_DIR])
AC_SUBST([DAEMON_SUPERMIN_DIR])
dnl For modified printf in the daemon, we need glibc either (old-style)
dnl register_printf_function or (new-style) register_printf_specifier.
AC_CHECK_FUNC([register_printf_specifier],[
AC_DEFINE([HAVE_REGISTER_PRINTF_SPECIFIER],[1],
[Define to 1 if you have new-style register_printf_specifier])
],[
AC_CHECK_FUNC([register_printf_function],[
AC_DEFINE([HAVE_REGISTER_PRINTF_FUNCTION],[1],
[Define to 1 if you have old-style register_printf_function])
],[
AC_MSG_FAILURE(
[No support for glibc-style extended printf formatters.
This means you either have a very old glibc (pre-2.0) or you
are using some other libc where this is not supported.])])])
fi
AM_CONDITIONAL([INSTALL_DAEMON],[test "x$enable_install_daemon" = "xyes"])
AM_CONDITIONAL([VALGRIND_DAEMON],[test "x$enable_valgrind_daemon" = "xyes"])
@@ -368,6 +406,14 @@ AM_CONDITIONAL([HAVE_RPCGEN],[test "x$RPCGEN" != "xno"])
AC_CHECK_LIB([portablexdr],[xdrmem_create],[],[
AC_SEARCH_LIBS([xdrmem_create],[rpc xdr nsl])
])
AC_SEARCH_LIBS([xdr_u_int64_t],[portablexdr rpc xdr nsl],[
AC_DEFINE([HAVE_XDR_U_INT64_T],[1],[Define to 1 if xdr_u_int64_t() exists])
])
AC_SEARCH_LIBS([xdr_uint64_t],[portablexdr rpc xdr nsl],[
AC_DEFINE([HAVE_XDR_UINT64_T],[1],[Define to 1 if xdr_uint64_t() exists])
])
AM_CONDITIONAL([HAVE_XDR_U_INT64_T],[test "x$ac_cv_search_xdr_u_int64_t" != "xno"])
AM_CONDITIONAL([HAVE_XDR_UINT64_T],[test "x$ac_cv_search_xdr_uint64_t" != "xno"])
dnl Check for Augeas (optional).
PKG_CHECK_MODULES([AUGEAS], [augeas],
@@ -401,9 +447,19 @@ fi
AC_SUBST([SELINUX_LIB])
dnl Check for systemtap/DTrace userspace probes (optional).
dnl http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps
AC_CHECK_HEADERS([sys/sdt.h])
dnl AC_CHECK_PROG([DTRACE],[dtrace],[dtrace],[no])
dnl Since the probe points break under clang, allow this to be disabled.
AC_ARG_ENABLE([probes],
AS_HELP_STRING([--disable-probes], [Disable systemtap/DTrace userspace probes]),
[],
[enable_probes=yes])
AS_IF([test "x$enable_probes" != "xno"],[
dnl http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps
AC_CHECK_HEADERS([sys/sdt.h])
dnl AC_CHECK_PROG([DTRACE],[dtrace],[dtrace],[no])
AS_IF([test "x$ac_cv_header_sys_sdt_h" = "xyes"],[
AC_DEFINE([ENABLE_PROBES],[1],[enable systemtap/DTrace userspace probes])
])
])
dnl Check for cpio which isn't in the default Pardus install amazingly.
AC_CHECK_PROG([CPIO],[cpio],[cpio],[no])
@@ -415,40 +471,31 @@ AC_CHECK_PROG([GPERF],[gperf],[gperf],[no])
test "x$GPERF" = "xno" &&
AC_MSG_ERROR([gperf must be installed])
dnl Check for pod2man, pod2text, pod2html.
AC_CHECK_PROG([POD2MAN],[pod2man],[pod2man],[no])
test "x$POD2MAN" = "xno" &&
AC_MSG_ERROR([pod2man must be installed])
AC_CHECK_PROG([POD2TEXT],[pod2text],[pod2text],[no])
test "x$POD2TEXT" = "xno" &&
AC_MSG_ERROR([pod2text must be installed])
AC_CHECK_PROG([POD2HTML],[pod2html],[pod2html],[no])
test "x$POD2HTML" = "xno" &&
AC_MSG_ERROR([pod2html must be installed])
dnl Check for perl.
AC_CHECK_PROG([PERL],[perl],[perl],[no])
test "x$PERL" = "xno" &&
AC_MSG_ERROR([perl must be installed])
dnl Check if pod2man, pod2text take --stderr and -u options (not in RHEL 5).
AC_MSG_CHECKING([if pod2man takes --stderr option])
if "$POD2MAN" --stderr >&AS_MESSAGE_LOG_FD 2>&1; then
AC_MSG_RESULT([yes])
POD2_STDERR_OPTION="--stderr"
dnl Check for Pod::Man, Pod::Simple.
AC_MSG_CHECKING([for Pod::Man])
if ! $PERL -MPod::Man -e1 >&AS_MESSAGE_LOG_FD 2>&1; then
AC_MSG_ERROR([perl Pod::Man must be installed])
else
AC_MSG_RESULT([yes])
fi
AC_MSG_CHECKING([for Pod::Simple])
if ! $PERL -MPod::Simple -e1 >&AS_MESSAGE_LOG_FD 2>&1; then
AC_MSG_ERROR([perl Pod::Simple must be installed])
else
AC_MSG_RESULT([no])
POD2_STDERR_OPTION=""
fi
AC_SUBST([POD2_STDERR_OPTION])
AC_MSG_CHECKING([if pod2man takes -u option])
if "$POD2MAN" -u >&AS_MESSAGE_LOG_FD 2>&1; then
AC_MSG_RESULT([yes])
POD2_UTF8_OPTION="-u"
else
AC_MSG_RESULT([no])
POD2_UTF8_OPTION=""
fi
AC_SUBST([POD2_UTF8_OPTION])
dnl Check for genisoimage.
AC_PATH_PROGS([GENISOIMAGE],[genisoimage],[no],
dnl Define the path to the podwrapper program.
PODWRAPPER="$PERL $(pwd)/podwrapper.pl"
AC_SUBST([PODWRAPPER])
dnl Check for genisoimage/mkisofs
AC_PATH_PROGS([GENISOIMAGE],[genisoimage mkisofs],[no],
[$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin])
test "x$GENISOIMAGE" = "xno" && AC_MSG_ERROR([genisoimage must be installed])
@@ -498,7 +545,8 @@ fi
dnl Check for QEMU for running binaries on this $host_cpu, fall
dnl back to basic 'qemu'. Allow the user to override it.
default_qemu="qemu-kvm kvm qemu-system-$host_cpu qemu"
qemu_system="`echo qemu-system-$host_cpu | $SED 's/i@<:@456@:>@86/i386/g'`"
default_qemu="qemu-kvm kvm $qemu_system qemu"
AC_ARG_WITH([qemu],
[AS_HELP_STRING([--with-qemu],
[set default QEMU binary @<:@default=[qemu-kvm] qemu-system-<host> qemu@:>@])],
@@ -509,7 +557,24 @@ AC_PATH_PROGS([QEMU],[$with_qemu],[no],
test "x$QEMU" = "xno" && AC_MSG_ERROR([qemu must be installed])
AC_DEFINE_UNQUOTED([QEMU],["$QEMU"],[Location of qemu binary.])
dnl Does the user wish to specify -M, -cpu or other qemu options?
AC_MSG_CHECKING([if the user specified extra options for qemu command line])
AC_ARG_WITH([qemu-options],
[AS_HELP_STRING([--with-qemu-options="-M ... -cpu ... etc"],
[pass extra options for qemu command line @<:@default=no@:>@])],
[QEMU_OPTIONS="$withval"],
[QEMU_OPTIONS=no])
AS_IF([test "x$QEMU_OPTIONS" = "xno"],[
AC_MSG_RESULT([no])
QEMU_OPTIONS=
],[
AC_MSG_RESULT([$QEMU_OPTIONS])
])
AC_DEFINE_UNQUOTED([QEMU_OPTIONS],["$QEMU_OPTIONS"],
[extra options for qemu command line])
dnl Check that the chosen qemu has virtio-serial support.
dnl For historical reasons this can be disabled by setting vmchannel_test=no.
if test "x$vmchannel_test" != "xno"; then
AC_MSG_CHECKING([that $QEMU -help works])
if $QEMU -help >&AS_MESSAGE_LOG_FD 2>&1; then
@@ -524,53 +589,37 @@ working.
])
fi
dnl qemu 0.15 was released with broken support for '-machine',
dnl requiring you to add the machine type: '-machine pc,[...]'.
dnl The problem is that 'pc' is only applicable for PC-like
dnl hardware, so we cannot do this as a general solution. Since
dnl qemu 0.15, this problem has been fixed so now the default
dnl machine type is chosen (qemu commit 2645c6dcaf6ea2a51a).
dnl
dnl We need to work out if this qemu is the broken version, so we
dnl can add 'pc' just for this broken version.
dnl
dnl Note that old qemu didn't support the '-machine' option at all.
dnl
dnl We use the -kernel option for testing this, because this option
dnl is processed very late, after qemu has set up the machine.
AC_MSG_CHECKING([for broken '-machine accel=tcg' option in $QEMU])
LC_ALL=C $QEMU -nographic -machine accel=tcg -kernel /NO_SUCH_FILE \
> config1.tmp 2>&1
LC_ALL=C $QEMU -nographic -machine pc,accel=tcg -kernel /NO_SUCH_FILE \
> config2.tmp 2>&1
if cmp -s config1.tmp config2.tmp; then
AC_MSG_RESULT([no])
else
AC_MSG_CHECKING([that $QEMU -version works])
if $QEMU -version >&AS_MESSAGE_LOG_FD 2>&1; then
AC_MSG_RESULT([yes])
AC_DEFINE([QEMU_MACHINE_TYPE_IS_BROKEN],[1],[qemu -machine accel=tcg option is broken (in qemu 0.15 only)])
fi
rm config1.tmp config2.tmp
else
AC_MSG_RESULT([no])
AC_MSG_FAILURE(
[$QEMU -version: command failed.
dnl See if the '-machine [pc,]accel=tcg' option is required in
dnl order to run the virtio-serial test below. This happens when
dnl we run qemu-kvm inside a VM without forcing TCG:
dnl
dnl Could not access KVM kernel module: No such file or directory
dnl failed to initialize KVM: No such file or directory
dnl No accelerator found!
AC_MSG_CHECKING([if -machine @<:@pc,@:>@accel=tcg option is required to test virtio-serial feature])
if $QEMU -nographic -device \? >/dev/null 2>&1; then
:
elif $QEMU -machine accel=tcg -nographic -device \? >/dev/null 2>&1; then
QEMU_EXTRA_OPTIONS_FOR_TEST="-machine accel=tcg"
elif $QEMU -machine pc,accel=tcg -nographic -device \? >/dev/null 2>&1; then
QEMU_EXTRA_OPTIONS_FOR_TEST="-machine pc,accel=tcg"
# else nothing ... it'll fail below.
This could be a very old version of qemu, or qemu might not be
working.
])
fi
AC_MSG_CHECKING([for $QEMU version >= 1])
if $QEMU -version | grep -sq 'version @<:@1-@:>@'; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AC_MSG_FAILURE([$QEMU version must be >= 1.0.])
fi
AC_MSG_CHECKING([that $QEMU -nographic -machine accel=kvm:tcg -device ? works])
if $QEMU -nographic -machine accel=kvm:tcg -device \? >&AS_MESSAGE_LOG_FD 2>&1; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AC_MSG_FAILURE([$QEMU -nographic -machine accel=kvm:tcg -device ? doesn't work.])
fi
AC_MSG_RESULT([$QEMU_EXTRA_OPTIONS_FOR_TEST])
AC_MSG_CHECKING([for virtio-serial support in $QEMU])
if $QEMU $QEMU_EXTRA_OPTIONS_FOR_TEST -nographic -device \? 2>&1 | grep -sq virtio-serial; then
if $QEMU $QEMU_OPTIONS -nographic -machine accel=kvm:tcg -device \? 2>&1 | grep -sq virtio-serial; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
@@ -586,8 +635,10 @@ and/or KVM. Please read the relevant section in the README file for
more information about this.
You can override this test by setting the environment variable
vmchannel_test=no However if you don't have the right support
in your qemu, then this just delays the pain.
vmchannel_test=no
However if you don't have the right support in your qemu, then this
just delays the pain.
If I am using the wrong qemu or you want to compile qemu from source
and install it in another location, then you should configure with
@@ -596,29 +647,6 @@ the --with-qemu option.
fi
fi
dnl Set default drive interface used by the guestfs_add_drive_opts call
dnl ('-drive ...,if=...' option to qemu).
dnl
dnl If you encounter performance problems with virtio (RHBZ#509383)
dnl then try '--with-drive-if=ide'.
AC_ARG_WITH([drive-if],
[AS_HELP_STRING([--with-drive-if],
[set default driver (ide|scsi|virtio) @<:@default=virtio@:>@])],
[],
[with_drive_if=virtio])
AC_DEFINE_UNQUOTED([DRIVE_IF],["$with_drive_if"],[Default drive interface.])
dnl Set interface used by the network. Normally you should
dnl leave this at the default (virtio-net-pci) but you can use the
dnl alternative (ne2k_pci) because of bugs in virtio networking
dnl eg. https://bugzilla.redhat.com/show_bug.cgi?id=516022
AC_ARG_WITH([net-if],
[AS_HELP_STRING([--with-net-if],
[set default net driver (virtio-net-pci|ne2k_pci) @<:@default=virtio-net-pci@:>@])],
[],
[with_net_if=virtio-net-pci])
AC_DEFINE_UNQUOTED([NET_IF],["$with_net_if"],[Default network interface.])
dnl Enable packet dumps when in verbose mode. This generates lots
dnl of debug info, only useful for people debugging the RPC mechanism.
AC_ARG_ENABLE([packet-dump],
@@ -652,9 +680,6 @@ AS_IF([test "x$with_readline" != xno],
LIBS="$old_LIBS"
])
dnl For i18n.
AM_GNU_GETTEXT([external])
dnl Check for PCRE (required)
PKG_CHECK_MODULES([PCRE], [libpcre])
@@ -681,6 +706,10 @@ PKG_CHECK_MODULES([LIBXML2], [libxml-2.0],
[AC_SUBST([LIBXML2_CFLAGS])
AC_SUBST([LIBXML2_LIBS])
AC_DEFINE([HAVE_LIBXML2],[1],[libxml2 found at compile time.])
old_LIBS="$LIBS"
LIBS="$LIBS $LIBXML2_LIBS"
AC_CHECK_FUNCS([xmlBufferDetach])
LIBS="$old_LIBS"
],
[AC_MSG_WARN([libxml2 not found, some core features will be disabled])])
AM_CONDITIONAL([HAVE_LIBXML2],[test "x$LIBXML2_LIBS" != "x"])
@@ -714,7 +743,12 @@ AS_IF([test "x$enable_fuse" != "xno"],
[PKG_CHECK_MODULES([FUSE],[fuse],
[AC_SUBST([FUSE_CFLAGS])
AC_SUBST([FUSE_LIBS])
AC_DEFINE([HAVE_FUSE],[1],[Define to 1 if you have FUSE])],
AC_DEFINE([HAVE_FUSE],[1],[Define to 1 if you have FUSE])
old_LIBS="$LIBS"
LIBS="$FUSE_LIBS $LIBS"
AC_CHECK_FUNCS([fuse_opt_add_opt_escaped])
LIBS="$old_LIBS"
],
[enable_fuse=no
AC_MSG_WARN([FUSE library and headers are missing, so optional FUSE module won't be built])
])
@@ -731,7 +765,7 @@ AM_CONDITIONAL([HAVE_CXX], [$CXX --version])
dnl If valgrind is present (it's not required), check whether or not
dnl it supports the new 'valgrind --vgdb' option.
AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind],[no])
AS_IF([test "x$valgrind" != "xno"],[
AS_IF([test "x$VALGRIND" != "xno"],[
AC_MSG_CHECKING([if $VALGRIND supports the --vgdb option])
if $VALGRIND --help | grep -sq -- --vgdb; then
AC_MSG_RESULT([yes])
@@ -742,7 +776,7 @@ AS_IF([test "x$valgrind" != "xno"],[
fi
])
dnl Check for OCaml (optional, for OCaml bindings).
dnl Check for OCaml (optional, for OCaml bindings and OCaml tools).
OCAMLC=no
OCAMLFIND=no
AC_ARG_ENABLE([ocaml],
@@ -762,23 +796,107 @@ AM_CONDITIONAL([HAVE_OCAML],
AM_CONDITIONAL([HAVE_OCAMLDOC],
[test "x$OCAMLDOC" != "xno"])
dnl Check for Perl (optional, for Perl bindings).
PERL=no
OCAML_PKG_gettext=no
AS_IF([test "x$OCAMLC" != "xno"],[
dnl Check for ocaml-gettext package to translate OCaml tools.
AC_CHECK_OCAML_PKG(gettext)
dnl Write gettext modules for each OCaml tool. If OCaml gettext
dnl is not available then we write dummy functions.
for program in resize sparsify sysprep; do
output=$program/${program}_gettext.ml
AC_MSG_NOTICE([creating $output])
rm -f $output
cat <<EOF > $output
(* This file is generated automatically by ./configure. *)
(** Gettext functions for virt-$program.
The ${program}_gettext module provides gettext functions for
$program, or dummy functions if ocaml-gettext was not available
at configure time.
{b Note}: Don't translate debug strings, or strings which are
meant to be read/written only by machine.
There are two ways to translate constant strings in OCaml programs.
For ordinary strings, replace [["string"]] with [[s_"string"]]. Since
this is a function call to a function called [[s_]], you may have
to put parentheses around the expression.
For format strings, use:
{v
printf (f_"zeroing filesystem %s") filename;
v}
Note for format strings, the parentheses are almost always required,
and they just go around the [[(f_"string")]], {i not} around the other
arguments of the printf function.
At build time, a program parses the OCaml code into an abstract
syntax tree and statically determines all calls to the special
[[s_]] and [[f_]] functions, which means: (a) You can be very loose
with syntax, unlike ordinary xgettext, but (b) you cannot rename
these functions.
*)
EOF
if test "x$OCAML_PKG_gettext" != "xno"; then
# ocaml-gettext available: real module.
cat <<EOF >>$output
module Gettext = Gettext.Program (
struct
let textdomain = "$PACKAGE_NAME"
let codeset = None
let dir = None
let dependencies = [[]]
end
) (GettextStub.Native)
EOF
else
# No gettext: module containing dummy gettext functions.
cat <<EOF >>$output
module Gettext = struct
external s_ : string -> string = "%identity"
external f_ : ('a, 'b, 'c, 'd, 'e, 'f) format6
-> ('a, 'b, 'c, 'd, 'e, 'f) format6
= "%identity"
let sn_ : string -> string -> int -> string
= fun s p n -> if n = 1 then s else p
let fn_ : ('a, 'b, 'c, 'd, 'e, 'f) format6
-> ('a, 'b, 'c, 'd, 'e, 'f) format6
-> int -> ('a, 'b, 'c, 'd, 'e, 'f) format6
= fun s p n -> if n = 1 then s else p
end
EOF
fi
chmod -w $output
done
])
AM_CONDITIONAL([HAVE_OCAML_PKG_GETTEXT],
[test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_gettext" != "xno"])
AC_CHECK_PROG([OCAML_GETTEXT],[ocaml-gettext],[ocaml-gettext],[no])
AM_CONDITIONAL([HAVE_OCAML_GETTEXT],
[test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_gettext" != "xno" && test "x$OCAML_GETTEXT" != "xno"])
dnl Check for Perl (optional, for Perl bindings and Perl tools).
AC_ARG_ENABLE([perl],
AS_HELP_STRING([--disable-perl], [Disable Perl language bindings]),
[],
[enable_perl=yes])
AS_IF([test "x$enable_perl" != "xno"],
[
PERL=
AC_CHECK_PROG([PERL],[perl],[perl],[no])
AS_IF([test "x$enable_perl" != "xno"],[
dnl Check for Perl modules that must be present to compile and
dnl test the Perl bindings.
missing_perl_modules=no
for pm in Test::More ExtUtils::MakeMaker; do
AC_MSG_CHECKING([for $pm])
if ! perl -M$pm -e1 >&AS_MESSAGE_LOG_FD 2>&1; then
if ! $PERL -M$pm -e1 >&AS_MESSAGE_LOG_FD 2>&1; then
AC_MSG_RESULT([no])
missing_perl_modules=yes
else
@@ -869,18 +987,40 @@ AM_CONDITIONAL([HAVE_PYTHON],
dnl Check for Ruby and rake (optional, for Ruby bindings).
AC_ARG_ENABLE([ruby],
AS_HELP_STRING([--disable-ruby], [Disable Ruby language bindings]),
[],
[enable_ruby=yes])
AS_IF([test "x$enable_ruby" != "xno"],
[
AC_CHECK_PROG([RUBY],[ruby],[ruby],[no])
AC_CHECK_PROG([RAKE],[rake],[rake],[no])
AC_CHECK_LIB([ruby],[ruby_init],[HAVE_LIBRUBY=1],[HAVE_LIBRUBY=0])
AC_SUBST([RAKE])
AS_HELP_STRING([--disable-ruby], [Disable Ruby language bindings]),
[],
[enable_ruby=yes])
AS_IF([test "x$enable_ruby" != "xno"],[
AC_CHECK_PROG([RUBY],[ruby],[ruby],[no])
AC_CHECK_PROG([RAKE],[rake],[rake],[no])
AS_IF([test -n "$RUBY" && test -n "$RAKE"],[
dnl Find the library. Note on Debian it's not -lruby.
AC_MSG_CHECKING([for C library for Ruby extensions])
ruby_cmd='puts RbConfig::CONFIG@<:@"RUBY_SO_NAME"@:>@'
echo running: $RUBY -rrbconfig -e \'$ruby_cmd\' >&AS_MESSAGE_LOG_FD
$RUBY -rrbconfig -e "$ruby_cmd" >conftest 2>&AS_MESSAGE_LOG_FD
libruby="$(cat conftest)"
rm conftest
AS_IF([test -n "$libruby"],[
AC_MSG_RESULT([-l$libruby])
AC_CHECK_LIB([$libruby],[ruby_init],
[have_libruby=1],[have_libruby=])
dnl Symbols that we substitute when missing.
AS_IF([test -n "$have_libruby"],[
old_LIBS="$LIBS"
LIBS="$LIBS -l$libruby"
AC_CHECK_FUNCS([rb_hash_lookup])
LIBS="$old_LIBS"
])
],[
AC_MSG_RESULT([not found])
])
])
])
AM_CONDITIONAL([HAVE_RUBY],
[test "x$RAKE" != "xno" && test -n "$HAVE_LIBRUBY"])
[test -n "$RUBY" && test -n "$RAKE" && test -n "$have_libruby"])
dnl Check for Java.
AC_ARG_WITH(java_home,
@@ -987,20 +1127,20 @@ if test "x$with_java_home" != "xno"; then
dnl Need extra version flag?
AC_MSG_CHECKING([extra javac flags])
JAVAC_FLAGS=
EXTRA_JAVAC_FLAGS=
javac_version=`$JAVAC -version 2>&1`
case "$javac_version" in
*Eclipse*)
JAVAC_FLAGS="-source 1.5" ;;
EXTRA_JAVAC_FLAGS="-source 1.5" ;;
esac
AC_MSG_RESULT([$JAVAC_FLAGS])
AC_MSG_RESULT([$EXTRA_JAVAC_FLAGS])
dnl Extra lint flags?
AC_MSG_CHECKING([extra javac lint flags])
if $JAVAC -X >/dev/null 2>&1 && \
$JAVAC -X 2>&1 | grep -q -- '-Xlint:.*all'; then
AC_MSG_RESULT([-Xlint:all])
JAVAC_FLAGS="$JAVAC_FLAGS -Xlint:all"
EXTRA_JAVAC_FLAGS="$EXTRA_JAVAC_FLAGS -Xlint:all"
else
AC_MSG_RESULT([no])
fi
@@ -1028,7 +1168,7 @@ AC_SUBST(JAVAH)
AC_SUBST(JAVADOC)
AC_SUBST(JAR)
AC_SUBST(JNI_CFLAGS)
AC_SUBST(JAVAC_FLAGS)
AC_SUBST(EXTRA_JAVAC_FLAGS)
AC_SUBST(JAR_INSTALL_DIR)
AC_SUBST(JNI_INSTALL_DIR)
AC_SUBST(JNI_VERSION_INFO)
@@ -1177,11 +1317,11 @@ dnl Produce output files.
AC_CONFIG_HEADERS([config.h])
dnl http://www.mail-archive.com/automake@gnu.org/msg10204.html
AC_CONFIG_FILES([appliance/libguestfs-make-fixed-appliance],
[chmod +x appliance/libguestfs-make-fixed-appliance])
AC_CONFIG_FILES([podwrapper.sh],
[chmod +x podwrapper.sh])
[chmod +x,-w appliance/libguestfs-make-fixed-appliance])
AC_CONFIG_FILES([podwrapper.pl],
[chmod +x,-w podwrapper.pl])
AC_CONFIG_FILES([run],
[chmod +x run])
[chmod +x,-w run])
AC_CONFIG_FILES([Makefile
align/Makefile
appliance/Makefile
@@ -1206,7 +1346,6 @@ AC_CONFIG_FILES([Makefile
inspector/Makefile
java/Makefile
java/examples/Makefile
libguestfs.pc
ocaml/META
ocaml/Makefile
ocaml/examples/Makefile
@@ -1217,7 +1356,7 @@ AC_CONFIG_FILES([Makefile
po-docs/Makefile
po-docs/ja/Makefile
po-docs/uk/Makefile
po/Makefile.in
po/Makefile
python/Makefile
python/examples/Makefile
rescue/Makefile
@@ -1227,19 +1366,27 @@ AC_CONFIG_FILES([Makefile
ruby/examples/Makefile
sparsify/Makefile
src/Makefile
src/libguestfs.pc
sysprep/Makefile
test-tool/Makefile
tests/9p/Makefile
tests/btrfs/Makefile
tests/c-api/Makefile
tests/charsets/Makefile
tests/data/Makefile
tests/disks/Makefile
tests/extra/Makefile
tests/guests/Makefile
tests/luks/Makefile
tests/lvm/Makefile
tests/md/Makefile
tests/mount-local/Makefile
tests/ntfsclone/Makefile
tests/protocol/Makefile
tests/qemu/Makefile
tests/regressions/Makefile
tests/selinux/Makefile
tests/xml/Makefile
tools/Makefile])
AC_OUTPUT
@@ -1253,33 +1400,35 @@ echo "This is how we have configured the optional components for you today:"
echo
echo "Daemon .............................. $enable_daemon"
echo "Appliance ........................... $enable_appliance"
echo "QEMU ................................ $QEMU"
echo -n "OCaml bindings ...................... "
echo "QEMU ................................ $QEMU $QEMU_OPTIONS"
AS_ECHO_N(["OCaml bindings ...................... "])
if test "x$HAVE_OCAML_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo -n "Perl bindings ....................... "
AS_ECHO_N(["Perl bindings ....................... "])
if test "x$HAVE_PERL_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo -n "Python bindings ..................... "
AS_ECHO_N(["Python bindings ..................... "])
if test "x$HAVE_PYTHON_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo -n "Ruby bindings ....................... "
AS_ECHO_N(["Ruby bindings ....................... "])
if test "x$HAVE_RUBY_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo -n "Java bindings ....................... "
AS_ECHO_N(["Java bindings ....................... "])
if test "x$HAVE_JAVA_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo -n "Haskell bindings .................... "
AS_ECHO_N(["Haskell bindings .................... "])
if test "x$HAVE_HASKELL_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo -n "PHP bindings ........................ "
AS_ECHO_N(["PHP bindings ........................ "])
if test "x$HAVE_PHP_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo -n "Erlang bindings ..................... "
AS_ECHO_N(["Erlang bindings ..................... "])
if test "x$HAVE_ERLANG_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo "guestfish and C virt tools .......... yes"
echo -n "Perl virt tools ..................... "
AS_ECHO_N(["Perl virt tools ..................... "])
if test "x$HAVE_TOOLS_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo -n "virt-resize ......................... "
AS_ECHO_N(["OCaml virt tools .................... "])
if test "x$HAVE_OCAML_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo "FUSE filesystem ..................... $enable_fuse"
echo -n "gobject bindings .................... "
AS_ECHO_N(["gobject bindings .................... "])
if test "x$HAVE_GOBJECT_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo -n "gobject introspection ............... "
AS_ECHO_N(["gobject introspection ............... "])
if test "x$HAVE_INTROSPECTION_TRUE" = "x"; then echo "yes"; else echo "no"; fi
AS_ECHO_N(["GNU gettext for i18n ................ "])
if test "x$HAVE_GNU_GETTEXT_TRUE" = "x"; then echo "yes"; else echo "no"; fi
echo
echo "If any optional component is configured 'no' when you expected 'yes'"
echo "then you should check the preceding messages."

View File

@@ -28,8 +28,8 @@ BUILT_SOURCES = \
$(generator_built) \
guestfs_protocol.c \
guestfs_protocol.h \
errnostring_gperf.c \
errnostring_gperf.gperf \
errnostring-gperf.c \
errnostring-gperf.gperf \
errnostring.c \
errnostring.h
@@ -57,16 +57,16 @@ $(libsrcdir)/guestfs_protocol.h: force
# of warnings so we must compile it in a separate mini-library.
noinst_LIBRARIES += liberrnostring.a
liberrnostring_a_SOURCES = \
errnostring_gperf.c \
errnostring-gperf.c \
errnostring.h \
errnostring.c
liberrnostring_a_CFLAGS =
errnostring_gperf.c: errnostring_gperf.gperf
errnostring-gperf.c: errnostring-gperf.gperf
rm -f $@
$(GPERF) -t $< > $@-t
mv $@-t $@
errnostring_gperf.gperf: $(libsrcdir)/errnostring_gperf.gperf
errnostring-gperf.gperf: $(libsrcdir)/errnostring-gperf.gperf
rm -f $@
ln $< $@
errnostring.c: $(libsrcdir)/errnostring.c
@@ -106,7 +106,7 @@ guestfsd_SOURCES = \
dmesg.c \
dropcaches.c \
du.c \
echo_daemon.c \
echo-daemon.c \
ext2.c \
fallocate.c \
file.c \
@@ -114,6 +114,7 @@ guestfsd_SOURCES = \
fill.c \
find.c \
fsck.c \
fstrim.c \
glob.c \
grep.c \
grub.c \
@@ -162,10 +163,13 @@ guestfsd_SOURCES = \
umask.c \
upload.c \
utimens.c \
utsname.c \
wc.c \
xattr.c \
xfs.c \
zero.c \
zerofree.c
guestfsd_LDADD = \
liberrnostring.a \
libprotocol.a \

View File

@@ -389,85 +389,85 @@ optgroup_augeas_available (void)
return 0;
}
int
int __attribute__((noreturn))
do_aug_init (const char *root, int flags)
{
abort ();
}
int
int __attribute__((noreturn))
do_aug_close (void)
{
abort ();
}
int
int __attribute__((noreturn))
do_aug_defvar (const char *name, const char *expr)
{
abort ();
}
guestfs_int_int_bool *
guestfs_int_int_bool * __attribute__((noreturn))
do_aug_defnode (const char *name, const char *expr, const char *val)
{
abort ();
}
char *
char * __attribute__((noreturn))
do_aug_get (const char *path)
{
abort ();
}
int
int __attribute__((noreturn))
do_aug_set (const char *path, const char *val)
{
abort ();
}
int
int __attribute__((noreturn))
do_aug_clear (const char *path)
{
abort ();
}
int
int __attribute__((noreturn))
do_aug_insert (const char *path, const char *label, int before)
{
abort ();
}
int
int __attribute__((noreturn))
do_aug_rm (const char *path)
{
abort ();
}
int
int __attribute__((noreturn))
do_aug_mv (const char *src, const char *dest)
{
abort ();
}
char **
char ** __attribute__((noreturn))
do_aug_match (const char *path)
{
abort ();
}
int
int __attribute__((noreturn))
do_aug_save (void)
{
abort ();
}
int
int __attribute__((noreturn))
do_aug_load (void)
{
abort ();
}
char **
char ** __attribute__((noreturn))
do_aug_ls (const char *path)
{
abort ();

View File

@@ -22,9 +22,12 @@
#include <stdlib.h>
#include <string.h>
#include "c-ctype.h"
#include "guestfs_protocol.h"
#include "daemon.h"
#include "actions.h"
#include "optgroups.h"
int
do_available (char *const *groups)
@@ -70,3 +73,79 @@ do_available_all_groups (void)
return groups.argv; /* caller frees */
}
/* Search for filesystem in /proc/filesystems, ignoring "nodev". */
static int
test_proc_filesystems (const char *filesystem)
{
size_t len = strlen (filesystem) + 32;
char regex[len];
char *err;
int r;
snprintf (regex, len, "^[[:space:]]*%s$", filesystem);
r = commandr (NULL, &err, "grep", regex, "/proc/filesystems", NULL);
if (r == -1 || r >= 2) {
fprintf (stderr, "grep /proc/filesystems: %s", err);
free (err);
return -1;
}
free (err);
return r == 0;
}
/* Do modprobe, ignore any errors. */
static void
modprobe (const char *module)
{
command (NULL, NULL, "modprobe", module, NULL);
}
/* Internal function for testing if a filesystem is available. Note
* this must not call reply_with_error functions.
*/
int
filesystem_available (const char *filesystem)
{
int r;
r = test_proc_filesystems (filesystem);
if (r == -1 || r > 0)
return r;
/* Not found: try to modprobe the module, then test again. */
if (optgroup_linuxmodules_available ()) {
modprobe (filesystem);
r = test_proc_filesystems (filesystem);
if (r == -1)
return -1;
}
return r;
}
int
do_filesystem_available (const char *filesystem)
{
size_t i, len = strlen (filesystem);
int r;
for (i = 0; i < len; ++i) {
if (!c_isalnum (filesystem[i]) && filesystem[i] != '_') {
reply_with_error ("filesystem name contains non-alphanumeric characters");
return -1;
}
}
r = filesystem_available (filesystem);
if (r == -1) {
reply_with_error ("error testing for filesystem availability; "
"enable verbose mode and look at preceeding output");
return -1;
}
return r;
}

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2011 Red Hat Inc.
* Copyright (C) 2011-2012 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,18 +28,17 @@
#include "actions.h"
#include "optgroups.h"
#define MAX_ARGS 64
int
optgroup_btrfs_available (void)
{
return prog_exists ("btrfs");
return prog_exists ("btrfs") && filesystem_available ("btrfs") > 0;
}
/* Takes optional arguments, consult optargs_bitmask. */
int
do_btrfs_filesystem_resize (const char *filesystem, int64_t size)
{
const size_t MAX_ARGS = 64;
char *buf;
char *err;
int r;
@@ -87,13 +86,21 @@ do_btrfs_filesystem_resize (const char *filesystem, int64_t size)
/* Takes optional arguments, consult optargs_bitmask. */
int
do_mkfs_btrfs (const char *device,
do_mkfs_btrfs (char *const *devices,
int64_t allocstart, int64_t bytecount, const char *datatype,
int leafsize, const char *label, const char *metadata,
int nodesize, int sectorsize)
{
size_t nr_devices = count_strings (devices);
if (nr_devices == 0) {
reply_with_error ("list of devices must be non-empty");
return -1;
}
size_t MAX_ARGS = nr_devices + 64;
const char *argv[MAX_ARGS];
size_t i = 0;
size_t i = 0, j;
int r;
char *err;
char allocstart_s[64];
@@ -180,6 +187,469 @@ do_mkfs_btrfs (const char *device,
ADD_ARG (argv, i, sectorsize_s);
}
for (j = 0; j < nr_devices; ++j)
ADD_ARG (argv, i, devices[j]);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
if (r == -1) {
reply_with_error ("%s: %s", devices[0], err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_btrfs_subvolume_snapshot (const char *source, const char *dest)
{
const size_t MAX_ARGS = 64;
const char *argv[MAX_ARGS];
size_t i = 0;
char *source_buf, *dest_buf;
char *err;
int r;
source_buf = sysroot_path (source);
if (source_buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
dest_buf = sysroot_path (dest);
if (dest_buf == NULL) {
reply_with_perror ("malloc");
free (source_buf);
return -1;
}
ADD_ARG (argv, i, "btrfs");
ADD_ARG (argv, i, "subvolume");
ADD_ARG (argv, i, "snapshot");
ADD_ARG (argv, i, source_buf);
ADD_ARG (argv, i, dest_buf);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (source_buf);
free (dest_buf);
if (r == -1) {
reply_with_error ("%s: %s: %s", source, dest, err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_btrfs_subvolume_delete (const char *subvolume)
{
const size_t MAX_ARGS = 64;
const char *argv[MAX_ARGS];
size_t i = 0;
char *subvolume_buf;
char *err;
int r;
subvolume_buf = sysroot_path (subvolume);
if (subvolume_buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
ADD_ARG (argv, i, "btrfs");
ADD_ARG (argv, i, "subvolume");
ADD_ARG (argv, i, "delete");
ADD_ARG (argv, i, subvolume_buf);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (subvolume_buf);
if (r == -1) {
reply_with_error ("%s: %s", subvolume, err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_btrfs_subvolume_create (const char *dest)
{
const size_t MAX_ARGS = 64;
const char *argv[MAX_ARGS];
size_t i = 0;
char *dest_buf;
char *err;
int r;
dest_buf = sysroot_path (dest);
if (dest_buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
ADD_ARG (argv, i, "btrfs");
ADD_ARG (argv, i, "subvolume");
ADD_ARG (argv, i, "create");
ADD_ARG (argv, i, dest_buf);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (dest_buf);
if (r == -1) {
reply_with_error ("%s: %s", dest, err);
free (err);
return -1;
}
free (err);
return 0;
}
guestfs_int_btrfssubvolume_list *
do_btrfs_subvolume_list (const char *fs)
{
const size_t MAX_ARGS = 64;
guestfs_int_btrfssubvolume_list *ret;
char *fs_buf;
const char *argv[MAX_ARGS];
size_t i = 0;
char *out, *err, **lines, *pos;
size_t nr_subvolumes;
int r;
fs_buf = sysroot_path (fs);
if (fs_buf == NULL) {
reply_with_perror ("malloc");
return NULL;
}
ADD_ARG (argv, i, "btrfs");
ADD_ARG (argv, i, "subvolume");
ADD_ARG (argv, i, "list");
ADD_ARG (argv, i, fs_buf);
ADD_ARG (argv, i, NULL);
r = commandv (&out, &err, argv);
free (fs_buf);
if (r == -1) {
reply_with_error ("%s: %s", fs, err);
free (err);
return NULL;
}
free (err);
lines = split_lines (out);
free (out);
if (!lines)
return NULL;
/* Output is:
*
* ID 256 top level 5 path test1
* ID 257 top level 5 path dir/test2
* ID 258 top level 5 path test3
*
* "ID <n>" is the subvolume ID. "top level <n>" is the top level
* subvolume ID. "path <str>" is the subvolume path, relative to
* the top of the filesystem.
*/
nr_subvolumes = count_strings (lines);
ret = malloc (sizeof *ret);
if (!ret) {
reply_with_perror ("malloc");
free_stringslen (lines, nr_subvolumes);
return NULL;
}
ret->guestfs_int_btrfssubvolume_list_len = nr_subvolumes;
ret->guestfs_int_btrfssubvolume_list_val =
calloc (nr_subvolumes, sizeof (struct guestfs_int_btrfssubvolume));
if (ret->guestfs_int_btrfssubvolume_list_val == NULL) {
reply_with_perror ("malloc");
free (ret);
free_stringslen (lines, nr_subvolumes);
return NULL;
}
for (i = 0; i < nr_subvolumes; ++i) {
/* To avoid allocations, reuse the 'line' buffer to store the
* path. Thus we don't need to free 'line', since it will be
* freed by the calling (XDR) code.
*/
char *line = lines[i];
if (sscanf (line, "ID %" SCNu64 " top level %" SCNu64 " path ",
&ret->guestfs_int_btrfssubvolume_list_val[i].btrfssubvolume_id,
&ret->guestfs_int_btrfssubvolume_list_val[i].btrfssubvolume_top_level_id) != 2) {
unexpected_output:
reply_with_error ("unexpected output from 'btrfs subvolume list' command: %s", line);
free_stringslen (lines, nr_subvolumes);
free (ret->guestfs_int_btrfssubvolume_list_val);
free (ret);
return NULL;
}
pos = strstr (line, " path ");
if (pos == NULL)
goto unexpected_output;
pos += 6;
memmove (line, pos, strlen (pos) + 1);
ret->guestfs_int_btrfssubvolume_list_val[i].btrfssubvolume_path = line;
}
return ret;
}
int
do_btrfs_subvolume_set_default (int64_t id, const char *fs)
{
const size_t MAX_ARGS = 64;
const char *argv[MAX_ARGS];
size_t i = 0;
char *fs_buf;
char buf[64];
char *err;
int r;
snprintf (buf, sizeof buf, "%" PRIi64, id);
fs_buf = sysroot_path (fs);
if (fs_buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
ADD_ARG (argv, i, "btrfs");
ADD_ARG (argv, i, "subvolume");
ADD_ARG (argv, i, "set-default");
ADD_ARG (argv, i, buf);
ADD_ARG (argv, i, fs_buf);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (fs_buf);
if (r == -1) {
reply_with_error ("%s: %s", fs, err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_btrfs_filesystem_sync (const char *fs)
{
const size_t MAX_ARGS = 64;
const char *argv[MAX_ARGS];
size_t i = 0;
char *fs_buf;
char *err;
int r;
fs_buf = sysroot_path (fs);
if (fs_buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
ADD_ARG (argv, i, "btrfs");
ADD_ARG (argv, i, "filesystem");
ADD_ARG (argv, i, "sync");
ADD_ARG (argv, i, fs_buf);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (fs_buf);
if (r == -1) {
reply_with_error ("%s: %s", fs, err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_btrfs_filesystem_balance (const char *fs)
{
const size_t MAX_ARGS = 64;
const char *argv[MAX_ARGS];
size_t i = 0;
char *fs_buf;
char *err;
int r;
fs_buf = sysroot_path (fs);
if (fs_buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
ADD_ARG (argv, i, "btrfs");
ADD_ARG (argv, i, "filesystem");
ADD_ARG (argv, i, "balance");
ADD_ARG (argv, i, fs_buf);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (fs_buf);
if (r == -1) {
reply_with_error ("%s: %s", fs, err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_btrfs_device_add (char *const *devices, const char *fs)
{
size_t nr_devices = count_strings (devices);
if (nr_devices == 0)
return 0;
size_t MAX_ARGS = nr_devices + 8;
const char *argv[MAX_ARGS];
size_t i = 0, j;
char *fs_buf;
char *err;
int r;
fs_buf = sysroot_path (fs);
if (fs_buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
ADD_ARG (argv, i, "btrfs");
ADD_ARG (argv, i, "device");
ADD_ARG (argv, i, "add");
for (j = 0; j < nr_devices; ++j)
ADD_ARG (argv, i, devices[j]);
ADD_ARG (argv, i, fs_buf);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (fs_buf);
if (r == -1) {
reply_with_error ("%s: %s", fs, err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_btrfs_device_delete (char *const *devices, const char *fs)
{
size_t nr_devices = count_strings (devices);
if (nr_devices == 0)
return 0;
size_t MAX_ARGS = nr_devices + 8;
const char *argv[MAX_ARGS];
size_t i = 0, j;
char *fs_buf;
char *err;
int r;
fs_buf = sysroot_path (fs);
if (fs_buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
ADD_ARG (argv, i, "btrfs");
ADD_ARG (argv, i, "device");
ADD_ARG (argv, i, "delete");
for (j = 0; j < nr_devices; ++j)
ADD_ARG (argv, i, devices[j]);
ADD_ARG (argv, i, fs_buf);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (fs_buf);
if (r == -1) {
reply_with_error ("%s: %s", fs, err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_btrfs_set_seeding (const char *device, int svalue)
{
char *err;
int r;
const char *s_value = svalue ? "1" : "0";
r = commandr (NULL, &err, "btrfstune", "-S", s_value, device, NULL);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
free (err);
return -1;
}
free (err);
return 0;
}
/* Takes optional arguments, consult optargs_bitmask. */
int
do_btrfs_fsck (const char *device, int64_t superblock, int repair)
{
char *err;
int r;
size_t i = 0;
const size_t MAX_ARGS = 64;
const char *argv[MAX_ARGS];
char super_s[64];
ADD_ARG (argv, i, "btrfsck");
/* Optional arguments. */
if (optargs_bitmask & GUESTFS_BTRFS_FSCK_SUPERBLOCK_BITMASK) {
if (superblock < 0) {
reply_with_error ("super block offset must be >= 0");
return -1;
}
snprintf (super_s, sizeof super_s, "%" PRIi64, superblock);
ADD_ARG (argv, i, "--super");
ADD_ARG (argv, i, super_s);
}
if (!(optargs_bitmask & GUESTFS_BTRFS_FSCK_REPAIR_BITMASK))
repair = 0;
if (repair)
ADD_ARG (argv, i, "--repair");
ADD_ARG (argv, i, device);
ADD_ARG (argv, i, NULL);

View File

@@ -79,6 +79,9 @@ extern void sort_strings (char **argv, size_t len);
extern void free_strings (char **argv);
extern void free_stringslen (char **argv, size_t len);
extern void sort_device_names (char **argv, size_t len);
extern int compare_device_names (const char *a, const char *b);
extern char **split_lines (char *str);
#define command(out,err,name,...) commandf((out),(err),0,(name),__VA_ARGS__)
@@ -109,6 +112,8 @@ extern int prog_exists (const char *prog);
extern void udev_settle (void);
extern int random_name (char *template);
/* This just stops gcc from giving a warning about our custom printf
* formatters %Q and %R. See guestfs(3)/EXTENDING LIBGUESTFS for more
* info about these.
@@ -151,6 +156,9 @@ struct optgroup {
};
extern struct optgroup optgroups[];
/*-- in available.c --*/
extern int filesystem_available (const char *filesystem);
/*-- in sync.c --*/
/* Use this as a replacement for sync(2). */
extern int sync_disks (void);

View File

@@ -61,6 +61,7 @@ static char *debug_ll (const char *subcmd, size_t argc, char *const *const argv)
static char *debug_progress (const char *subcmd, size_t argc, char *const *const argv);
static char *debug_qtrace (const char *subcmd, size_t argc, char *const *const argv);
static char *debug_segv (const char *subcmd, size_t argc, char *const *const argv);
static char *debug_setenv (const char *subcmd, size_t argc, char *const *const argv);
static char *debug_sh (const char *subcmd, size_t argc, char *const *const argv);
static struct cmd cmds[] = {
@@ -75,6 +76,7 @@ static struct cmd cmds[] = {
{ "progress", debug_progress },
{ "qtrace", debug_qtrace },
{ "segv", debug_segv },
{ "setenv", debug_setenv },
{ "sh", debug_sh },
{ NULL, NULL }
};
@@ -286,6 +288,28 @@ debug_env (const char *subcmd, size_t argc, char *const *const argv)
return out;
}
/* Set an environment variable in the daemon and future subprocesses. */
static char *
debug_setenv (const char *subcmd, size_t argc, char *const *const argv)
{
char *ret;
if (argc != 2) {
reply_with_error ("setenv: two arguments expected");
return NULL;
}
setenv (argv[0], argv[1], 1);
ret = strdup ("ok");
if (NULL == ret) {
reply_with_perror ("strdup");
return NULL;
}
return ret;
}
/* Return binaries in the appliance.
* See tests/regressions/rhbz727178.sh
*/
@@ -429,8 +453,12 @@ debug_progress (const char *subcmd, size_t argc, char *const *const argv)
char *secs_str = argv[0];
unsigned secs;
if (sscanf (secs_str, "%u", &secs) != 1 || secs == 0)
if (sscanf (secs_str, "%u", &secs) != 1)
goto error;
if (secs == 0 || secs > 1000000) { /* RHBZ#816839 */
reply_with_error ("progress: argument is 0, less than 0, or too large");
return NULL;
}
unsigned i;
unsigned tsecs = secs * 10; /* 1/10ths of seconds */

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009 Red Hat Inc.
* Copyright (C) 2009-2012 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,9 +38,11 @@ static char **
foreach_block_device (block_dev_func_t func)
{
DECLARE_STRINGSBUF (r);
DIR *dir;
int err = 0;
struct dirent *d;
char dev_path[256];
int fd;
dir = opendir ("/sys/block");
if (!dir) {
@@ -48,16 +50,15 @@ foreach_block_device (block_dev_func_t func)
return NULL;
}
while(1) {
for (;;) {
errno = 0;
struct dirent *d = readdir(dir);
if(NULL == d) break;
d = readdir(dir);
if (!d) break;
if (STREQLEN (d->d_name, "sd", 2) ||
STREQLEN (d->d_name, "hd", 2) ||
STREQLEN (d->d_name, "vd", 2) ||
STREQLEN (d->d_name, "sr", 2)) {
char dev_path[256];
snprintf (dev_path, sizeof dev_path, "/dev/%s", d->d_name);
/* Ignore the root device. */
@@ -68,7 +69,7 @@ foreach_block_device (block_dev_func_t func)
* CD-ROM device even though we didn't request it. Try to
* detect this by seeing if the device contains media.
*/
int fd = open (dev_path, O_RDONLY|O_CLOEXEC);
fd = open (dev_path, O_RDONLY|O_CLOEXEC);
if (fd == -1) {
perror (dev_path);
continue;
@@ -76,7 +77,7 @@ foreach_block_device (block_dev_func_t func)
close (fd);
/* Call the map function for this device */
if((*func)(d->d_name, &r) != 0) {
if ((*func)(d->d_name, &r) != 0) {
err = 1;
break;
}
@@ -84,7 +85,7 @@ foreach_block_device (block_dev_func_t func)
}
/* Check readdir didn't fail */
if(0 != errno) {
if (errno != 0) {
reply_with_perror ("readdir: /sys/block");
free_stringslen (r.argv, r.size);
closedir (dir);
@@ -106,7 +107,7 @@ foreach_block_device (block_dev_func_t func)
/* Sort the devices. */
if (r.size > 0)
sort_strings (r.argv, r.size);
sort_device_names (r.argv, r.size);
/* NULL terminate the list */
if (end_stringsbuf (&r) == -1) {
@@ -241,3 +242,43 @@ do_part_to_partnum (const char *part)
return r;
}
int
do_device_index (const char *device)
{
char **devices;
size_t i;
int ret = -1;
devices = do_list_devices ();
if (devices == NULL)
return -1;
for (i = 0; devices[i] != NULL; ++i) {
if (STREQ (device, devices[i]))
ret = (int) i;
free (devices[i]);
}
free (devices);
if (ret == -1)
reply_with_error ("device not found");
return ret;
}
int
do_nr_devices (void)
{
char **devices;
size_t i;
devices = do_list_devices ();
if (devices == NULL)
return -1;
for (i = 0; devices[i] != NULL; ++i)
free (devices[i]);
free (devices);
return (int) i;
}

View File

@@ -377,7 +377,7 @@ do_mke2journal (int blocksize, const char *device)
snprintf (blocksize_s, sizeof blocksize_s, "%d", blocksize);
r = command (NULL, &err,
prog, "-O", "journal_dev", "-b", blocksize_s,
prog, "-F", "-O", "journal_dev", "-b", blocksize_s,
device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
@@ -409,7 +409,7 @@ do_mke2journal_L (int blocksize, const char *label, const char *device)
snprintf (blocksize_s, sizeof blocksize_s, "%d", blocksize);
r = command (NULL, &err,
prog, "-O", "journal_dev", "-b", blocksize_s,
prog, "-F", "-O", "journal_dev", "-b", blocksize_s,
"-L", label,
device, NULL);
if (r == -1) {
@@ -436,7 +436,7 @@ do_mke2journal_U (int blocksize, const char *uuid, const char *device)
snprintf (blocksize_s, sizeof blocksize_s, "%d", blocksize);
r = command (NULL, &err,
prog, "-O", "journal_dev", "-b", blocksize_s,
prog, "-F", "-O", "journal_dev", "-b", blocksize_s,
"-U", uuid,
device, NULL);
if (r == -1) {
@@ -468,7 +468,7 @@ do_mke2fs_J (const char *fstype, int blocksize, const char *device,
snprintf (jdev, len+32, "device=%s", journal);
r = command (NULL, &err,
prog, "-t", fstype, "-J", jdev, "-b", blocksize_s,
prog, "-F", "-t", fstype, "-J", jdev, "-b", blocksize_s,
device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
@@ -505,7 +505,7 @@ do_mke2fs_JL (const char *fstype, int blocksize, const char *device,
snprintf (jdev, len+32, "device=LABEL=%s", label);
r = command (NULL, &err,
prog, "-t", fstype, "-J", jdev, "-b", blocksize_s,
prog, "-F", "-t", fstype, "-J", jdev, "-b", blocksize_s,
device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
@@ -536,7 +536,7 @@ do_mke2fs_JU (const char *fstype, int blocksize, const char *device,
snprintf (jdev, len+32, "device=UUID=%s", uuid);
r = command (NULL, &err,
prog, "-t", fstype, "-J", jdev, "-b", blocksize_s,
prog, "-F", "-t", fstype, "-J", jdev, "-b", blocksize_s,
device, NULL);
if (r == -1) {
reply_with_error ("%s", err);

97
daemon/fstrim.c Normal file
View File

@@ -0,0 +1,97 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2012 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "guestfs_protocol.h"
#include "daemon.h"
#include "actions.h"
#include "optgroups.h"
#define MAX_ARGS 64
int
optgroup_fstrim_available (void)
{
return prog_exists ("fstrim");
}
/* Takes optional arguments, consult optargs_bitmask. */
int
do_fstrim (const char *path,
int64_t offset, int64_t length, int64_t minimumfreeextent)
{
const char *argv[MAX_ARGS];
size_t i = 0;
char offset_s[64], length_s[64], mfe_s[64];
char *err;
int r;
ADD_ARG (argv, i, "fstrim");
if ((optargs_bitmask & GUESTFS_FSTRIM_OFFSET_BITMASK)) {
if (offset < 0) {
reply_with_error ("offset < 0");
return -1;
}
snprintf (offset_s, sizeof offset_s, "%" PRIi64, offset);
ADD_ARG (argv, i, "-o");
ADD_ARG (argv, i, offset_s);
}
if ((optargs_bitmask & GUESTFS_FSTRIM_LENGTH_BITMASK)) {
if (length <= 0) {
reply_with_error ("length <= 0");
return -1;
}
snprintf (length_s, sizeof length_s, "%" PRIi64, length);
ADD_ARG (argv, i, "-l");
ADD_ARG (argv, i, length_s);
}
if ((optargs_bitmask & GUESTFS_FSTRIM_MINIMUMFREEEXTENT_BITMASK)) {
if (minimumfreeextent <= 0) {
reply_with_error ("minimumfreeextent <= 0");
return -1;
}
snprintf (mfe_s, sizeof mfe_s, "%" PRIi64, minimumfreeextent);
ADD_ARG (argv, i, "-m");
ADD_ARG (argv, i, mfe_s);
}
ADD_ARG (argv, i, path);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}

View File

@@ -28,13 +28,40 @@
#include "daemon.h"
#include "actions.h"
#define MAX_ARGS 64
static char **
grep (const char *prog, const char *flag, const char *regex, const char *path)
grep (const char *regex, const char *path,
int extended, int fixed, int insensitive, int compressed)
{
const char *argv[MAX_ARGS];
size_t i = 0;
char *out, *err;
int fd, flags, r;
char **lines;
if (extended && fixed) {
reply_with_error ("can't use 'extended' and 'fixed' flags at the same time");
return NULL;
}
if (!compressed)
ADD_ARG (argv, i, "grep");
else
ADD_ARG (argv, i, "zgrep");
if (extended)
ADD_ARG (argv, i, "-E");
if (fixed)
ADD_ARG (argv, i, "-F");
if (insensitive)
ADD_ARG (argv, i, "-i");
ADD_ARG (argv, i, regex);
ADD_ARG (argv, i, NULL);
CHROOT_IN;
fd = open (path, O_RDONLY|O_CLOEXEC);
CHROOT_OUT;
@@ -48,9 +75,9 @@ grep (const char *prog, const char *flag, const char *regex, const char *path)
* suppress this error and return an empty list.
*/
flags = COMMAND_FLAG_CHROOT_COPY_FILE_TO_STDIN | fd;
r = commandrf (&out, &err, flags, prog, flag, regex, NULL);
r = commandrvf (&out, &err, flags, argv);
if (r == -1 || r > 1) {
reply_with_error ("%s %s %s: %s", prog, flag, regex, err);
reply_with_error ("%s: %s", regex, err);
free (out);
free (err);
return NULL;
@@ -65,75 +92,85 @@ grep (const char *prog, const char *flag, const char *regex, const char *path)
return lines;
}
/* Takes optional arguments, consult optargs_bitmask. */
char **
do_grep (const char *regex, const char *path)
do_grep (const char *regex, const char *path,
int extended, int fixed, int insensitive, int compressed)
{
/* The "--" is not really needed, but it helps when we don't need a flag. */
return grep ("grep", "--", regex, path);
if (!(optargs_bitmask & GUESTFS_GREP_EXTENDED_BITMASK))
extended = 0;
if (!(optargs_bitmask & GUESTFS_GREP_FIXED_BITMASK))
fixed = 0;
if (!(optargs_bitmask & GUESTFS_GREP_INSENSITIVE_BITMASK))
insensitive = 0;
if (!(optargs_bitmask & GUESTFS_GREP_COMPRESSED_BITMASK))
compressed = 0;
return grep (regex, path, extended, fixed, insensitive, compressed);
}
char **
do_egrep (const char *regex, const char *path)
{
return grep ("egrep", "--", regex, path);
return grep (regex, path, 1, 0, 0, 0);
}
char **
do_fgrep (const char *regex, const char *path)
{
return grep ("fgrep", "--", regex, path);
return grep (regex, path, 0, 1, 0, 0);
}
char **
do_grepi (const char *regex, const char *path)
{
return grep ("grep", "-i", regex, path);
return grep (regex, path, 0, 0, 1, 0);
}
char **
do_egrepi (const char *regex, const char *path)
{
return grep ("egrep", "-i", regex, path);
return grep (regex, path, 1, 0, 1, 0);
}
char **
do_fgrepi (const char *regex, const char *path)
{
return grep ("fgrep", "-i", regex, path);
return grep (regex, path, 0, 1, 1, 0);
}
char **
do_zgrep (const char *regex, const char *path)
{
return grep ("zgrep", "--", regex, path);
return grep (regex, path, 0, 0, 0, 1);
}
char **
do_zegrep (const char *regex, const char *path)
{
return grep ("zegrep", "--", regex, path);
return grep (regex, path, 1, 0, 0, 1);
}
char **
do_zfgrep (const char *regex, const char *path)
{
return grep ("zfgrep", "--", regex, path);
return grep (regex, path, 0, 1, 0, 1);
}
char **
do_zgrepi (const char *regex, const char *path)
{
return grep ("zgrep", "-i", regex, path);
return grep (regex, path, 0, 0, 1, 1);
}
char **
do_zegrepi (const char *regex, const char *path)
{
return grep ("zegrep", "-i", regex, path);
return grep (regex, path, 1, 0, 1, 1);
}
char **
do_zfgrepi (const char *regex, const char *path)
{
return grep ("zfgrep", "-i", regex, path);
return grep (regex, path, 0, 1, 1, 1);
}

View File

@@ -40,6 +40,7 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <assert.h>
#ifdef HAVE_PRINTF_H
# include <printf.h>
@@ -514,6 +515,69 @@ free_stringslen (char **argv, size_t len)
free (argv);
}
/* Compare device names (including partition numbers if present).
* https://rwmj.wordpress.com/2011/01/09/how-are-linux-drives-named-beyond-drive-26-devsdz/
*/
int
compare_device_names (const char *a, const char *b)
{
size_t a_devlen, b_devlen;
int r;
int a_partnum, b_partnum;
/* Skip /dev/ prefix if present. */
if (STRPREFIX (a, "/dev/"))
a += 5;
if (STRPREFIX (b, "/dev/"))
b += 5;
/* Skip sd/hd/vd. */
assert (a[1] == 'd');
a += 2;
assert (b[1] == 'd');
b += 2;
/* Get device name part, that is, just 'a', 'ab' etc. */
a_devlen = strcspn (a, "0123456789");
b_devlen = strcspn (b, "0123456789");
/* If device name part is longer, it is always greater, eg.
* "/dev/sdz" < "/dev/sdaa".
*/
if (a_devlen != b_devlen)
return a_devlen - b_devlen;
/* Device name parts are the same length, so do a regular compare. */
r = strncmp (a, b, a_devlen);
if (r != 0)
return r;
/* Compare partitions numbers. */
a += a_devlen;
b += a_devlen;
r = sscanf (a, "%d", &a_partnum);
assert (r == 1);
r = sscanf (b, "%d", &b_partnum);
assert (r == 1);
return a_partnum - b_partnum;
}
static int
compare_device_names_vp (const void *vp1, const void *vp2)
{
char * const *p1 = (char * const *) vp1;
char * const *p2 = (char * const *) vp2;
return compare_device_names (*p1, *p2);
}
void
sort_device_names (char **argv, size_t len)
{
qsort (argv, len, sizeof (char *), compare_device_names_vp);
}
/* Easy ways to run external commands. For full documentation, see
* 'commandrvf' below.
*/
@@ -1126,6 +1190,52 @@ prog_exists (const char *prog)
return 0;
}
/* Pass a template such as "/sysroot/XXXXXXXX.XXX". This updates the
* template to contain a randomly named file. Any 'X' characters
* after the final '/' are replaced with random characters.
*
* Notes: You should probably use an 8.3 path, so it's compatible with
* all filesystems including basic FAT. Also this only substitutes
* lowercase ASCII letters and numbers, again for compatibility with
* lowest common denominator filesystems.
*
* This doesn't create a file or check whether or not the file exists
* (it would be extremely unlikely to exist as long as the RNG is
* working).
*
* If there is an error, -1 is returned.
*/
int
random_name (char *template)
{
int fd;
unsigned char c;
char *p;
fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC);
if (fd == -1)
return -1;
p = strrchr (template, '/');
if (p == NULL)
abort (); /* internal error - bad template */
while (*p) {
if (*p == 'X') {
if (read (fd, &c, 1) != 1) {
close (fd);
return -1;
}
*p = "0123456789abcdefghijklmnopqrstuvwxyz"[c % 36];
}
p++;
}
close (fd);
return 0;
}
/* LVM and other commands aren't synchronous, especially when udev is
* involved. eg. You can create or remove some device, but the /dev
* device node won't appear until some time later. This means that

View File

@@ -245,7 +245,7 @@ make_filter_string (char *const *devices)
size_t i;
size_t len = 64;
for (i = 0; devices[i] != NULL; ++i)
len += strlen (devices[i]) + 16;
len += 2 * strlen (devices[i]) + 64;
char *filter = malloc (len);
if (filter == NULL) {
@@ -255,19 +255,22 @@ make_filter_string (char *const *devices)
char *p = filter;
for (i = 0; devices[i] != NULL; ++i) {
/* Because of the way matching works in LVM, each match clause
* should be either:
* "a|^/dev/sda|", for whole block devices, or
* "a|^/dev/sda1$|", for single partitions
* (the assumption being we have <= 26 block devices XXX).
/* Because of the way matching works in LVM (yes, they wrote their
* own regular expression engine!), each match clause should be either:
*
* for single partitions:
* "a|^/dev/sda1$|",
* for whole block devices:
* "a|^/dev/sda$|", "a|^/dev/sda[0-9]|",
*/
size_t slen = strlen (devices[i]);
char str[slen+16];
char str[2*slen+64];
if (c_isdigit (devices[i][slen-1]))
snprintf (str, slen+16, "\"a|^%s$|\", ", devices[i]);
else
snprintf (str, slen+16, "\"a|^%s|\", ", devices[i]);
if (c_isdigit (devices[i][slen-1])) /* single partition */
snprintf (str, 2*slen+64, "\"a|^%s$|\", ", devices[i]);
else /* whole block device */
snprintf (str, 2*slen+64, "\"a|^%s$|\", \"a|^%s[0-9]|\", ",
devices[i], devices[i]);
strcpy (p, str);
p += strlen (str);

View File

@@ -960,3 +960,87 @@ do_vgmeta (const char *vg, size_t *size_r)
return buf; /* caller will free */
}
int
do_pvchange_uuid (const char *device)
{
char *err;
int r;
r = command (NULL, &err,
"lvm", "pvchange", "-u", device, NULL);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
}
int
do_pvchange_uuid_all (void)
{
char *err;
int r;
r = command (NULL, &err,
"lvm", "pvchange", "-u", "-a", NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
}
int
do_vgchange_uuid (const char *vg)
{
char *err;
int r;
r = command (NULL, &err,
"lvm", "vgchange", "-u", vg, NULL);
if (r == -1) {
reply_with_error ("%s: %s", vg, err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
}
int
do_vgchange_uuid_all (void)
{
char *err;
int r;
r = command (NULL, &err,
"lvm", "vgchange", "-u", NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
}

View File

@@ -33,8 +33,8 @@
/* Takes optional arguments, consult optargs_bitmask. */
int
do_mkfs_opts (const char *fstype, const char *device, int blocksize,
const char *features, int inode, int sectorsize)
do_mkfs (const char *fstype, const char *device, int blocksize,
const char *features, int inode, int sectorsize)
{
const char *argv[MAX_ARGS];
size_t i = 0;
@@ -100,7 +100,7 @@ do_mkfs_opts (const char *fstype, const char *device, int blocksize,
}
/* Process blocksize parameter if set. */
if (optargs_bitmask & GUESTFS_MKFS_OPTS_BLOCKSIZE_BITMASK) {
if (optargs_bitmask & GUESTFS_MKFS_BLOCKSIZE_BITMASK) {
if (blocksize <= 0 || !is_power_of_2 (blocksize)) {
reply_with_error ("block size must be > 0 and a power of 2");
return -1;
@@ -146,12 +146,12 @@ do_mkfs_opts (const char *fstype, const char *device, int blocksize,
}
}
if (optargs_bitmask & GUESTFS_MKFS_OPTS_FEATURES_BITMASK) {
if (optargs_bitmask & GUESTFS_MKFS_FEATURES_BITMASK) {
ADD_ARG (argv, i, "-O");
ADD_ARG (argv, i, features);
}
if (optargs_bitmask & GUESTFS_MKFS_OPTS_INODE_BITMASK) {
if (optargs_bitmask & GUESTFS_MKFS_INODE_BITMASK) {
if (!extfs) {
reply_with_error ("inode size (-I) can only be set on ext2/3/4 filesystems");
return -1;
@@ -167,7 +167,7 @@ do_mkfs_opts (const char *fstype, const char *device, int blocksize,
ADD_ARG (argv, i, inode_str);
}
if (optargs_bitmask & GUESTFS_MKFS_OPTS_SECTORSIZE_BITMASK) {
if (optargs_bitmask & GUESTFS_MKFS_SECTORSIZE_BITMASK) {
if (!STREQ (fstype, "ufs")) {
reply_with_error ("sector size (-S) can only be set on ufs filesystems");
return -1;
@@ -197,16 +197,9 @@ do_mkfs_opts (const char *fstype, const char *device, int blocksize,
return 0;
}
int
do_mkfs (const char *fstype, const char *device)
{
optargs_bitmask = 0;
return do_mkfs_opts (fstype, device, 0, 0, 0, 0);
}
int
do_mkfs_b (const char *fstype, int blocksize, const char *device)
{
optargs_bitmask = GUESTFS_MKFS_OPTS_BLOCKSIZE_BITMASK;
return do_mkfs_opts (fstype, device, blocksize, 0, 0, 0);
optargs_bitmask = GUESTFS_MKFS_BLOCKSIZE_BITMASK;
return do_mkfs (fstype, device, blocksize, 0, 0, 0);
}

View File

@@ -29,6 +29,8 @@
#include "daemon.h"
#include "actions.h"
#define MAX_ARGS 64
/* You must mount something on "/" first before many operations.
* Hence we have an internal function which can test if something is
* mounted on *or under* the sysroot directory. (It has to be *or
@@ -154,7 +156,8 @@ do_mount_vfs (const char *options, const char *vfstype,
"mount", "-o", options, device, mp, NULL);
free (mp);
if (r == -1) {
reply_with_error ("%s on %s: %s", device, mountpoint, error);
reply_with_error ("%s on %s (options: '%s'): %s",
device, mountpoint, options, error);
free (error);
return -1;
}
@@ -182,16 +185,17 @@ do_mount_options (const char *options, const char *device,
return do_mount_vfs (options, NULL, device, mountpoint);
}
/* Again, use the external /bin/umount program, so that /etc/mtab
* is kept updated.
*/
/* Takes optional arguments, consult optargs_bitmask. */
int
do_umount (const char *pathordevice)
do_umount (const char *pathordevice,
int force, int lazyunmount)
{
int r;
char *err;
char *buf;
int is_dev;
const char *argv[MAX_ARGS];
size_t i = 0;
is_dev = STREQLEN (pathordevice, "/dev/", 5);
buf = is_dev ? strdup (pathordevice)
@@ -201,10 +205,25 @@ do_umount (const char *pathordevice)
return -1;
}
if (is_dev)
RESOLVE_DEVICE (buf, , { free (buf); return -1; });
if (!(optargs_bitmask & GUESTFS_UMOUNT_FORCE_BITMASK))
force = 0;
if (!(optargs_bitmask & GUESTFS_UMOUNT_LAZYUNMOUNT_BITMASK))
lazyunmount = 0;
r = command (NULL, &err, "umount", buf, NULL);
/* Use the external /bin/umount program, so that /etc/mtab is kept
* updated.
*/
ADD_ARG (argv, i, "umount");
if (force)
ADD_ARG (argv, i, "-f");
if (lazyunmount)
ADD_ARG (argv, i, "-l");
ADD_ARG (argv, i, buf);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (buf);
if (r == -1) {

View File

@@ -64,7 +64,7 @@ do_ntfs_3g_probe (int rw, const char *device)
/* Takes optional arguments, consult optargs_bitmask. */
int
do_ntfsresize_opts (const char *device, int64_t size, int force)
do_ntfsresize (const char *device, int64_t size, int force)
{
char *err;
int r;
@@ -75,7 +75,7 @@ do_ntfsresize_opts (const char *device, int64_t size, int force)
ADD_ARG (argv, i, "ntfsresize");
ADD_ARG (argv, i, "-P");
if (optargs_bitmask & GUESTFS_NTFSRESIZE_OPTS_SIZE_BITMASK) {
if (optargs_bitmask & GUESTFS_NTFSRESIZE_SIZE_BITMASK) {
if (size <= 0) {
reply_with_error ("size is zero or negative");
return -1;
@@ -86,7 +86,7 @@ do_ntfsresize_opts (const char *device, int64_t size, int force)
ADD_ARG (argv, i, size_str);
}
if (optargs_bitmask & GUESTFS_NTFSRESIZE_OPTS_FORCE_BITMASK && force)
if (optargs_bitmask & GUESTFS_NTFSRESIZE_FORCE_BITMASK && force)
ADD_ARG (argv, i, "--force");
ADD_ARG (argv, i, device);
@@ -103,17 +103,11 @@ do_ntfsresize_opts (const char *device, int64_t size, int force)
return 0;
}
int
do_ntfsresize (const char *device)
{
return do_ntfsresize_opts (device, 0, 0);
}
int
do_ntfsresize_size (const char *device, int64_t size)
{
optargs_bitmask = GUESTFS_NTFSRESIZE_OPTS_SIZE_BITMASK;
return do_ntfsresize_opts (device, size, 0);
optargs_bitmask = GUESTFS_NTFSRESIZE_SIZE_BITMASK;
return do_ntfsresize (device, size, 0);
}
/* Takes optional arguments, consult optargs_bitmask. */

View File

@@ -199,7 +199,9 @@ do_part_disk (const char *device, const char *parttype)
*
* - aligned operations are faster
* - absolute minimum recommended alignment is 64K (1M would be better)
* - GPT requires at least 34 sectors at the end of the disk.
* - GPT requires at least 34 sectors* at the end of the disk.
*
* *=except for 4k sector disks, where only 6 sectors are required
*/
const char *startstr = "128s";
const char *endstr = "-128s";
@@ -694,10 +696,22 @@ do_part_get_bootable (const char *device, int partnum)
}
size_t col = p - lines[header];
/* Look for the line corresponding to this partition number. */
row = start + partnum - 1;
if (row >= count_strings (lines) || !STRPREFIX (lines[row], " ")) {
reply_with_error ("partition number out of range: %d", partnum);
/* Partitions may not be in any order, so we have to look for
* the matching partition number (RHBZ#602997).
*/
int pnum;
for (row = start; lines[row] != NULL; ++row) {
if (sscanf (lines[row], " %d", &pnum) != 1) {
reply_with_error ("could not parse row from output of parted print command: %s", lines[row]);
free_strings (lines);
return -1;
}
if (pnum == partnum)
break;
}
if (lines[row] == NULL) {
reply_with_error ("partition number %d not found", partnum);
free_strings (lines);
return -1;
}

View File

@@ -78,14 +78,17 @@ do_realpath (const char *path)
#endif /* !HAVE_REALPATH */
static int find_path_element (int fd_cwd, char *name, size_t *name_len_ret);
static int find_path_element (int fd_cwd, int is_end, char *name, size_t *name_len_ret);
char *
do_case_sensitive_path (const char *path)
{
char ret[PATH_MAX+1] = "/";
char name[NAME_MAX+1];
size_t next = 1;
int fd_cwd;
int fd_cwd, fd2, err, is_end;
size_t i;
char *retp;
/* 'fd_cwd' here is a surrogate for the current working directory, so
* that we don't have to actually call chdir(2).
@@ -100,7 +103,7 @@ do_case_sensitive_path (const char *path)
* and follow it.
*/
while (*path) {
size_t i = strcspn (path, "/");
i = strcspn (path, "/");
if (i == 0) {
path++;
continue;
@@ -116,18 +119,18 @@ do_case_sensitive_path (const char *path)
goto error;
}
char name[NAME_MAX+1];
memcpy (name, path, i);
name[i] = '\0';
/* Skip to next element in path (for the next loop iteration). */
path += i;
is_end = *path == 0;
/* Read the current directory looking (case insensitively) for
* this element of the path. This replaces 'name' with the
* correct case version.
*/
if (find_path_element (fd_cwd, name, &i) == -1)
if (find_path_element (fd_cwd, is_end, name, &i) == -1)
goto error;
/* Add the real name of this path element to the return value. */
@@ -143,22 +146,18 @@ do_case_sensitive_path (const char *path)
next += i;
/* Is it a directory? Try going into it. */
int fd2 = openat (fd_cwd, name, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
int err = errno;
fd2 = openat (fd_cwd, name, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
err = errno;
close (fd_cwd);
fd_cwd = fd2;
errno = err;
if (fd_cwd == -1) {
/* ENOTDIR is OK provided we've reached the end of the path. */
if (errno != ENOTDIR) {
reply_with_perror ("openat: %s", name);
goto error;
}
/* Some errors are OK provided we've reached the end of the path. */
if (is_end && (errno == ENOTDIR || errno == ENOENT))
break;
if (*path) {
reply_with_error ("%s: non-directory element in path", name);
goto error;
}
reply_with_perror ("openat: %s", name);
goto error;
}
}
@@ -166,7 +165,7 @@ do_case_sensitive_path (const char *path)
close (fd_cwd);
ret[next] = '\0';
char *retp = strdup (ret);
retp = strdup (ret);
if (retp == NULL) {
reply_with_perror ("strdup");
return NULL;
@@ -182,7 +181,8 @@ do_case_sensitive_path (const char *path)
/* 'fd_cwd' is a file descriptor pointing to an open directory.
* 'name' is a buffer of NAME_MAX+1 characters in size which initially
* contains the path element to search for.
* contains the path element to search for. 'is_end' is a flag
* indicating if this is the last path element.
*
* We search the directory looking for a path element that case
* insensitively matches 'name' and update the 'name' buffer.
@@ -191,7 +191,7 @@ do_case_sensitive_path (const char *path)
* and return -1.
*/
static int
find_path_element (int fd_cwd, char *name, size_t *name_len_ret)
find_path_element (int fd_cwd, int is_end, char *name, size_t *name_len_ret)
{
int fd2;
DIR *dir;
@@ -224,6 +224,14 @@ find_path_element (int fd_cwd, char *name, size_t *name_len_ret)
return -1;
}
if (d == NULL && is_end) {
/* Last path element: return it as-is, assuming that the user will
* create a new file or directory (RHBZ#840115).
*/
closedir (dir);
return 0;
}
if (d == NULL) {
reply_with_error ("%s: no file or directory found with this name", name);
closedir (dir);

View File

@@ -23,7 +23,11 @@
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/types.h>
#include "daemon.h"
#include "actions.h"
@@ -32,6 +36,10 @@
static int sync_win32 (void);
#endif
#ifdef HAVE_FSYNC
static void fsync_devices (void);
#endif
int
do_sync (void)
{
@@ -52,6 +60,18 @@ sync_disks (void)
{
#if defined(HAVE_SYNC)
sync ();
/* On Linux, sync(2) doesn't perform a barrier, so qemu (which may
* have a writeback cache, even with cache=none) will still have
* some unwritten data. Force the data out of any qemu caches, by
* calling fsync on all block devices. Note we still need the
* call to sync above in order to schedule the writes.
* Thanks to: Avi Kivity, Kevin Wolf.
*/
#ifdef HAVE_FSYNC
fsync_devices ();
#endif
return 0;
#elif defined(WIN32)
return sync_win32 ();
@@ -60,6 +80,64 @@ sync_disks (void)
#endif
}
#ifdef HAVE_FSYNC
static void
fsync_devices (void)
{
DIR *dir;
struct dirent *d;
char dev_path[256];
int fd;
dir = opendir ("/sys/block");
if (!dir) {
perror ("opendir: /sys/block");
return;
}
for (;;) {
errno = 0;
d = readdir(dir);
if (!d) break;
if (STREQLEN (d->d_name, "sd", 2) ||
STREQLEN (d->d_name, "hd", 2) ||
STREQLEN (d->d_name, "vd", 2) ||
STREQLEN (d->d_name, "sr", 2)) {
snprintf (dev_path, sizeof dev_path, "/dev/%s", d->d_name);
/* Ignore the root device. */
if (is_root_device (dev_path))
continue;
fd = open (dev_path, O_RDONLY|O_CLOEXEC);
if (fd == -1) {
perror (dev_path);
continue;
}
/* fsync the device. */
if (verbose)
fprintf (stderr, "fsync %s\n", dev_path);
if (fsync (fd) == -1)
perror ("fsync");
if (close (fd) == -1)
perror ("close");
}
}
/* Check readdir didn't fail */
if (errno != 0)
perror ("readdir: /sys/block");
/* Close the directory handle */
if (closedir (dir) == -1)
perror ("closedir");
}
#endif /* HAVE_FSYNC */
#ifdef WIN32
static int
sync_win32 (void)

View File

@@ -36,6 +36,51 @@ optgroup_xz_available (void)
return prog_exists ("xz");
}
/* Detect if chown(2) is supported on the target directory. */
static int
is_chown_supported (const char *dir)
{
size_t len = sysroot_len + strlen (dir) + 64;
char buf[len];
int fd, r, saved_errno;
/* Create a randomly named file. */
snprintf (buf, len, "%s%s/XXXXXXXX.XXX", sysroot, dir);
if (random_name (buf) == -1) {
reply_with_perror ("random_name");
return -1;
}
/* Maybe 'dir' is not a directory or filesystem not writable? */
fd = open (buf, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0666);
if (fd == -1) {
reply_with_perror ("%s", dir);
return -1;
}
/* This is the test. */
r = fchown (fd, 1000, 1000);
saved_errno = errno;
/* Make sure the test file is removed. */
close (fd);
unlink (buf);
if (r == -1 && saved_errno == EPERM) {
/* This means chown is not supported by the filesystem. */
return 0;
}
if (r == -1) {
/* Some other error? */
reply_with_perror_errno (saved_errno, "unexpected error in fchown");
return -1;
}
/* Else chown is supported. */
return 1;
}
/* Read the error file. Returns a string that the caller must free. */
static char *
read_error_file (char *error_file)
@@ -75,7 +120,11 @@ do_tXz_in (const char *dir, const char *filter)
FILE *fp;
char *cmd;
char error_file[] = "/tmp/tarXXXXXX";
int fd;
int fd, chown_supported;
chown_supported = is_chown_supported (dir);
if (chown_supported == -1)
return -1;
fd = mkstemp (error_file);
if (fd == -1) {
@@ -86,8 +135,10 @@ do_tXz_in (const char *dir, const char *filter)
close (fd);
/* "tar -C /sysroot%s -xf -" but we have to quote the dir. */
if (asprintf_nowarn (&cmd, "tar -C %R -%sxf - 2> %s",
dir, filter, error_file) == -1) {
if (asprintf_nowarn (&cmd, "tar -C %R -%sxf - %s2> %s",
dir, filter,
chown_supported ? "" : "--no-same-owner ",
error_file) == -1) {
err = errno;
r = cancel_receive ();
errno = err;

62
daemon/utsname.c Normal file
View File

@@ -0,0 +1,62 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2012 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>
#include "guestfs_protocol.h"
#include "daemon.h"
#include "actions.h"
guestfs_int_utsname *
do_utsname (void)
{
struct utsname uts;
guestfs_int_utsname *ret;
if (uname (&uts) == -1) {
reply_with_perror ("utsname");
return NULL;
}
ret = malloc (sizeof *ret);
if (ret == NULL) {
reply_with_perror ("malloc");
return NULL;
}
ret->uts_sysname = strdup (uts.sysname);
ret->uts_release = strdup (uts.release);
ret->uts_version = strdup (uts.version);
ret->uts_machine = strdup (uts.machine);
if (!ret->uts_sysname || !ret->uts_release ||
!ret->uts_version || !ret->uts_machine) {
reply_with_perror ("strdup");
free (ret->uts_sysname);
free (ret->uts_release);
free (ret->uts_version);
free (ret->uts_machine);
free (ret);
return NULL;
}
return ret;
}

View File

@@ -19,6 +19,7 @@
#include <config.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
#include "guestfs_protocol.h"
@@ -174,6 +175,12 @@ getxattrs (const char *path,
goto error;
}
if (vlen > XATTR_SIZE_MAX) {
/* The next call to getxattr will fail anyway, so ... */
reply_with_error ("extended attribute is too large");
goto error;
}
r->guestfs_int_xattr_list_val[j].attrname = strdup (&buf[i]);
r->guestfs_int_xattr_list_val[j].attrval.attrval_val = malloc (vlen);
r->guestfs_int_xattr_list_val[j].attrval.attrval_len = vlen;
@@ -222,6 +229,11 @@ _setxattr (const char *xattr, const char *val, int vallen, const char *path,
{
int r;
if (vallen > XATTR_SIZE_MAX) {
reply_with_error ("extended attribute is too large");
return -1;
}
CHROOT_IN;
r = setxattr (path, xattr, val, vallen, 0);
CHROOT_OUT;
@@ -372,6 +384,11 @@ do_lxattrlist (const char *path, char *const *names)
goto error;
}
if (vlen > XATTR_SIZE_MAX) {
reply_with_error ("extended attribute is too large");
goto error;
}
entry[j+1].attrname = strdup (&buf[i]);
entry[j+1].attrval.attrval_val = malloc (vlen);
entry[j+1].attrval.attrval_len = vlen;
@@ -442,6 +459,12 @@ do_getxattr (const char *path, const char *name, size_t *size_r)
}
len = r;
if (len > XATTR_SIZE_MAX) {
reply_with_error ("extended attribute is too large");
return NULL;
}
buf = malloc (len);
if (buf == NULL) {
reply_with_perror ("malloc");
@@ -484,6 +507,12 @@ do_lgetxattr (const char *path, const char *name, size_t *size_r)
}
len = r;
if (len > XATTR_SIZE_MAX) {
reply_with_error ("extended attribute is too large");
return NULL;
}
buf = malloc (len);
if (buf == NULL) {
reply_with_perror ("malloc");

461
daemon/xfs.c Normal file
View File

@@ -0,0 +1,461 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2012 Fujitsu Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include <unistd.h>
#include "daemon.h"
#include "actions.h"
#include "optgroups.h"
#define MAX_ARGS 64
int
optgroup_xfs_available (void)
{
return prog_exists ("mkfs.xfs");
}
static char *
split_strdup (char *string)
{
char *end = string;
while (*end != ' ' && *end != ',' && *end != '\0') end++;
size_t len = end - string;
char *ret = malloc (len + 1);
if (!ret) {
reply_with_perror ("malloc");
return NULL;
}
strncpy (ret, string, len);
ret[len] = '\0';
return ret;
}
static int
parse_uint32 (uint32_t *ret, const char *str)
{
uint32_t r;
if (sscanf (str, "%" SCNu32, &r) != 1) {
reply_with_error ("cannot parse numeric field from isoinfo: %s", str);
return -1;
}
*ret = r;
return 0;
}
static int
parse_uint64 (uint64_t *ret, const char *str)
{
uint64_t r;
if (sscanf (str, "%" SCNu64, &r) != 1) {
reply_with_error ("cannot parse numeric field from isoinfo: %s", str);
return -1;
}
*ret = r;
return 0;
}
/* Typical crazy output from the xfs_info command:
*
* meta-data=/dev/sda1 isize=256 agcount=4, agsize=6392 blks
* = sectsz=512 attr=2
* data = bsize=4096 blocks=25568, imaxpct=25
* = sunit=0 swidth=0 blks
* naming =version 2 bsize=4096 ascii-ci=0
* log =internal bsize=4096 blocks=1200, version=2
* = sectsz=512 sunit=0 blks, lazy-count=1
* realtime =none extsz=4096 blocks=0, rtextents=0
*
* We may need to revisit this parsing code if the output changes
* in future.
*/
static guestfs_int_xfsinfo *
parse_xfs_info (char **lines)
{
guestfs_int_xfsinfo *ret;
char *buf = NULL, *p;
size_t i;
ret = malloc (sizeof *ret);
if (ret == NULL) {
reply_with_error ("malloc");
return NULL;
}
/* Initialize fields to NULL or -1 so the caller can tell which fields
* were updated in the code below.
*/
ret->xfs_mntpoint = NULL;
ret->xfs_inodesize = -1;
ret->xfs_agcount = -1;
ret->xfs_agsize = -1;
ret->xfs_sectsize = -1;
ret->xfs_attr = -1;
ret->xfs_blocksize = -1;
ret->xfs_datablocks = -1;
ret->xfs_imaxpct = -1;
ret->xfs_sunit = -1;
ret->xfs_swidth = -1;
ret->xfs_dirversion = -1;
ret->xfs_dirblocksize = -1;
ret->xfs_cimode = -1;
ret->xfs_logname = NULL;
ret->xfs_logblocksize = -1;
ret->xfs_logblocks = -1;
ret->xfs_logversion = -1;
ret->xfs_logsectsize = -1;
ret->xfs_logsunit = -1;
ret->xfs_lazycount = -1;
ret->xfs_rtname = NULL;
ret->xfs_rtextsize = -1;
ret->xfs_rtblocks = -1;
ret->xfs_rtextents = -1;
for (i = 0; lines[i] != NULL; ++i) {
if ((p = strstr (lines[i], "meta-data="))) {
ret->xfs_mntpoint = split_strdup (p + 10);
if (ret->xfs_mntpoint == NULL) goto error;
}
if ((p = strstr (lines[i], "isize="))) {
buf = split_strdup (p + 6);
if (buf == NULL) goto error;
if (parse_uint32 (&ret->xfs_inodesize, buf) == -1)
goto error;
free (buf);
}
if ((p = strstr (lines[i], "agcount="))) {
buf = split_strdup (p + 8);
if (buf == NULL) goto error;
if (parse_uint32 (&ret->xfs_agcount, buf) == -1)
goto error;
free (buf);
}
if ((p = strstr (lines[i], "agsize="))) {
buf = split_strdup (p + 7);
if (buf == NULL) goto error;
if (parse_uint32 (&ret->xfs_agsize, buf) == -1)
goto error;
free (buf);
}
if ((p = strstr (lines[i], "sectsz="))) {
buf = split_strdup (p + 7);
if (buf == NULL) goto error;
if (i == 1) {
if (parse_uint32 (&ret->xfs_sectsize, buf) == -1)
goto error;
free (buf);
} else if (i == 6) {
if (parse_uint32 (&ret->xfs_logsectsize, buf) == -1)
goto error;
free (buf);
} else goto error;
}
if ((p = strstr (lines[i], "attr="))) {
buf = split_strdup (p + 5);
if (buf == NULL) goto error;
if (parse_uint32 (&ret->xfs_attr, buf) == -1)
goto error;
free (buf);
}
if ((p = strstr (lines[i], "bsize="))) {
buf = split_strdup (p + 6);
if (buf == NULL) goto error;
if (i == 2) {
if (parse_uint32 (&ret->xfs_blocksize, buf) == -1)
goto error;
free (buf);
} else if (i == 4) {
if (parse_uint32 (&ret->xfs_dirblocksize, buf) == -1)
goto error;
free (buf);
} else if (i == 5) {
if (parse_uint32 (&ret->xfs_logblocksize, buf) == -1)
goto error;
free (buf);
} else goto error;
}
if ((p = strstr (lines[i], "blocks="))) {
buf = split_strdup (p + 7);
if (buf == NULL) goto error;
if (i == 2) {
if (parse_uint64 (&ret->xfs_datablocks, buf) == -1)
goto error;
free (buf);
} else if (i == 5) {
if (parse_uint32 (&ret->xfs_logblocks, buf) == -1)
goto error;
free (buf);
} else if (i == 7) {
if (parse_uint64 (&ret->xfs_rtblocks, buf) == -1)
goto error;
free (buf);
} else goto error;
}
if ((p = strstr (lines[i], "imaxpct="))) {
buf = split_strdup (p + 8);
if (buf == NULL) goto error;
if (parse_uint32 (&ret->xfs_imaxpct, buf) == -1)
goto error;
free (buf);
}
if ((p = strstr (lines[i], "sunit="))) {
buf = split_strdup (p + 6);
if (buf == NULL) goto error;
if (i == 3) {
if (parse_uint32 (&ret->xfs_sunit, buf) == -1)
goto error;
free (buf);
} else if (i == 6) {
if (parse_uint32 (&ret->xfs_logsunit, buf) == -1)
goto error;
free (buf);
} else goto error;
}
if ((p = strstr (lines[i], "swidth="))) {
buf = split_strdup (p + 7);
if (buf == NULL) goto error;
if (parse_uint32 (&ret->xfs_swidth, buf) == -1)
goto error;
free (buf);
}
if ((p = strstr (lines[i], "naming =version "))) {
buf = split_strdup (p + 18);
if (buf == NULL) goto error;
if (parse_uint32 (&ret->xfs_dirversion, buf) == -1)
goto error;
free (buf);
}
if ((p = strstr (lines[i], "ascii-ci="))) {
buf = split_strdup (p + 9);
if (buf == NULL) goto error;
if (parse_uint32 (&ret->xfs_cimode, buf) == -1)
goto error;
free (buf);
}
if ((p = strstr (lines[i], "log ="))) {
ret->xfs_logname = split_strdup (p + 10);
if (ret->xfs_logname == NULL) goto error;
}
if ((p = strstr (lines[i], "version="))) {
buf = split_strdup (p + 8);
if (buf == NULL) goto error;
if (parse_uint32 (&ret->xfs_logversion, buf) == -1)
goto error;
free (buf);
}
if ((p = strstr (lines[i], "lazy-count="))) {
buf = split_strdup (p + 11);
if (buf == NULL) goto error;
if (parse_uint32 (&ret->xfs_lazycount, buf) == -1)
goto error;
free (buf);
}
if ((p = strstr (lines[i], "realtime ="))) {
ret->xfs_rtname = split_strdup (p + 10);
if (ret->xfs_rtname == NULL) goto error;
}
if ((p = strstr (lines[i], "rtextents="))) {
buf = split_strdup (p + 10);
if (buf == NULL) goto error;
if (parse_uint64 (&ret->xfs_rtextents, buf) == -1)
goto error;
free (buf);
}
}
if (ret->xfs_mntpoint == NULL) {
ret->xfs_mntpoint = strdup ("");
if (ret->xfs_mntpoint == NULL) goto error;
}
if (ret->xfs_logname == NULL) {
ret->xfs_logname = strdup ("");
if (ret->xfs_logname == NULL) goto error;
}
if (ret->xfs_rtname == NULL) {
ret->xfs_rtname = strdup ("");
if (ret->xfs_rtname == NULL) goto error;
}
return ret;
error:
free (buf);
free (ret->xfs_mntpoint);
free (ret->xfs_logname);
free (ret->xfs_rtname);
free (ret);
return NULL;
}
guestfs_int_xfsinfo *
do_xfs_info (const char *pathordevice)
{
int r;
char *buf;
char *out = NULL, *err = NULL;
char **lines = NULL;
guestfs_int_xfsinfo *ret = NULL;
int is_dev;
is_dev = STREQLEN (pathordevice, "/dev/", 5);
buf = is_dev ? strdup (pathordevice)
: sysroot_path (pathordevice);
if (buf == NULL) {
reply_with_perror ("malloc");
return NULL;
}
r = command (&out, &err, "xfs_info", buf, NULL);
free (buf);
if (r == -1) {
reply_with_error ("%s", err);
goto error;
}
lines = split_lines (out);
if (lines == NULL)
goto error;
ret = parse_xfs_info (lines);
error:
free (err);
free (out);
if (lines)
free_strings (lines);
return ret;
}
char *
do_xfs_growfs (const char *path,
int datasec, int logsec, int rtsec,
int64_t datasize, int64_t logsize, int64_t rtsize,
int64_t rtextsize, int32_t maxpct)
{
int r;
char *buf;
char *out = NULL, *err = NULL;
const char *argv[MAX_ARGS];
char datasize_s[64];
char logsize_s[64];
char rtsize_s[64];
char rtextsize_s[64];
char maxpct_s[32];
size_t i = 0;
buf = sysroot_path (path);
if (buf == NULL) {
reply_with_perror ("malloc");
return NULL;
}
ADD_ARG (argv, i, "xfs_growfs");
/* Optional arguments */
if (!(optargs_bitmask & GUESTFS_XFS_GROWFS_DATASEC_BITMASK))
datasec = 0;
if (!(optargs_bitmask & GUESTFS_XFS_GROWFS_LOGSEC_BITMASK))
logsec = 0;
if (!(optargs_bitmask & GUESTFS_XFS_GROWFS_RTSEC_BITMASK))
rtsec = 0;
if (datasec)
ADD_ARG (argv, i, "-d");
if (logsec)
ADD_ARG (argv, i, "-l");
if (rtsec)
ADD_ARG (argv, i, "-r");
if (optargs_bitmask & GUESTFS_XFS_GROWFS_DATASIZE_BITMASK) {
if (datasize < 0) {
reply_with_error ("datasize must be >= 0");
goto error;
}
snprintf (datasize_s, sizeof datasize_s, "%" PRIi64, datasize);
ADD_ARG (argv, i, "-D");
ADD_ARG (argv, i, datasize_s);
}
if (optargs_bitmask & GUESTFS_XFS_GROWFS_LOGSIZE_BITMASK) {
if (logsize < 0) {
reply_with_error ("logsize must be >= 0");
goto error;
}
snprintf(logsize_s, sizeof logsize_s, "%" PRIi64, logsize);
ADD_ARG (argv, i, "-L");
ADD_ARG (argv, i, logsize_s);
}
if (optargs_bitmask & GUESTFS_XFS_GROWFS_RTSIZE_BITMASK) {
if (rtsize < 0) {
reply_with_error ("rtsize must be >= 0");
goto error;
}
snprintf(rtsize_s, sizeof rtsize_s, "%" PRIi64, rtsize);
ADD_ARG (argv, i, "-R");
ADD_ARG (argv, i, rtsize_s);
}
if (optargs_bitmask & GUESTFS_XFS_GROWFS_RTEXTSIZE_BITMASK) {
if (rtextsize < 0) {
reply_with_error ("rtextsize must be >= 0");
goto error;
}
snprintf(rtextsize_s, sizeof rtextsize_s, "%" PRIi64, rtextsize);
ADD_ARG (argv, i, "-e");
ADD_ARG (argv, i, rtextsize_s);
}
if (optargs_bitmask & GUESTFS_XFS_GROWFS_MAXPCT_BITMASK) {
if (maxpct < 0) {
reply_with_error ("maxpct must be >= 0");
goto error;
}
snprintf(maxpct_s, sizeof maxpct_s, "%" PRIi32, maxpct);
ADD_ARG (argv, i, "-m");
ADD_ARG (argv, i, maxpct_s);
}
ADD_ARG (argv, i, buf);
ADD_ARG (argv, i, NULL);
r = commandv (&out, &err, argv);
free (buf);
if (r == -1) {
reply_with_error ("%s: %s", path, err);
goto error;
}
free (err);
return out;
error:
if (buf) free (buf);
if (err) free (err);
return NULL;
}

View File

@@ -228,35 +228,6 @@ do_is_zero_device (const char *device)
return 1;
}
static int
random_name (char *p)
{
int fd;
unsigned char c;
fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC);
if (fd == -1) {
reply_with_perror ("/dev/urandom");
return -1;
}
while (*p) {
if (*p == 'X') {
if (read (fd, &c, 1) != 1) {
reply_with_perror ("read: /dev/urandom");
close (fd);
return -1;
}
*p = "0123456789abcdefghijklmnopqrstuvwxyz"[c % 36];
}
p++;
}
close (fd);
return 0;
}
/* Current implementation is to create a file of all zeroes, then
* delete it. The description of this function is left open in order
* to allow better implementations in future, including
@@ -277,8 +248,10 @@ do_zero_free_space (const char *dir)
* compatible with any filesystem type inc. FAT.
*/
snprintf (filename, sysroot_len+len+14, "%s%s/XXXXXXXX.XXX", sysroot, dir);
if (random_name (&filename[sysroot_len+len]) == -1)
if (random_name (filename) == -1) {
reply_with_perror ("random_name");
return -1;
}
if (verbose)
printf ("random filename: %s\n", filename);

View File

@@ -28,11 +28,11 @@ bin_PROGRAMS = virt-df
SHARED_SOURCE_FILES = \
../fish/config.c \
../fish/domain.c \
../fish/inspect.c \
../fish/keys.c \
../fish/options.h \
../fish/options.c \
../fish/virt.c
../fish/options.c
virt_df_SOURCES = \
$(SHARED_SOURCE_FILES) \
@@ -66,7 +66,7 @@ noinst_DATA = $(top_builddir)/html/virt-df.1.html
virt-df.1 $(top_builddir)/html/virt-df.1.html: stamp-virt-df.pod
stamp-virt-df.pod: virt-df.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man virt-df.1 \
--html $(top_builddir)/html/virt-df.1.html \
$<
@@ -74,11 +74,7 @@ stamp-virt-df.pod: virt-df.pod
# Tests.
random_val := $(shell awk 'BEGIN{srand(); print 1+int(255*rand())}' < /dev/null)
TESTS_ENVIRONMENT = \
MALLOC_PERTURB_=$(random_val) \
$(top_builddir)/run
TESTS_ENVIRONMENT = $(top_builddir)/run --test
if ENABLE_APPLIANCE
TESTS = test-virt-df.sh

44
df/df.c
View File

@@ -30,6 +30,7 @@
#endif
#include "progname.h"
#include "c-ctype.h"
#include "guestfs.h"
#include "options.h"
@@ -115,17 +116,50 @@ df_on_handle (const char *name, const char *uuid, char **devices, int offset)
return ret;
}
/* dev is a device or partition name such as "/dev/sda" or "/dev/sda1".
* See if dev occurs somewhere in the list of devices.
*/
static int
find_dev_in_devices (const char *dev, char **devices)
{
size_t i;
guestfs_error_handler_cb old_error_cb;
void *old_error_data;
size_t i, len;
char *whole_disk;
int free_whole_disk;
int ret = 0;
for (i = 0; devices[i] != NULL; ++i) {
if (STRPREFIX (dev, devices[i]))
return 1;
/* Convert 'dev' to a whole disk name. */
len = strlen (dev);
if (len > 0 && c_isdigit (dev[len-1])) {
old_error_cb = guestfs_get_error_handler (g, &old_error_data);
guestfs_set_error_handler (g, NULL, NULL);
whole_disk = guestfs_part_to_dev (g, dev);
guestfs_set_error_handler (g, old_error_cb, old_error_data);
if (!whole_disk) /* probably an MD device or similar */
return 0;
free_whole_disk = 1;
}
else {
whole_disk = (char *) dev;
free_whole_disk = 0;
}
return 0;
for (i = 0; devices[i] != NULL; ++i) {
if (STREQ (whole_disk, devices[i])) {
ret = 1;
break;
}
}
if (free_whole_disk)
free (whole_disk);
return ret;
}
static void

View File

@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#include <assert.h>
#ifdef HAVE_LIBVIRT
@@ -40,21 +41,14 @@
#if defined(HAVE_LIBVIRT) && defined(HAVE_LIBXML2)
/* Limit the number of devices we will ever add to the appliance. The
* overall limit in current libguestfs is 25: 26 = number of letters
* in the English alphabet since we are only confident that
* /dev/sd[a-z] will work because of various limits, minus 1 because
* that may be used by the ext2 initial filesystem. (RHBZ#635373).
*/
#define MAX_DISKS 25
/* The list of domains and disks that we build up in
* get_domains_from_libvirt.
*/
struct disk {
struct disk *next;
char *filename;
char *format; /* could be NULL */
char *format; /* could be NULL */
int failed; /* flag if disk failed when adding */
};
struct domain {
@@ -92,19 +86,24 @@ free_domain (struct domain *domain)
free (domain->uuid);
}
static void add_domains_by_id (virConnectPtr conn, int *ids, size_t n);
static void add_domains_by_name (virConnectPtr conn, char **names, size_t n);
static void add_domain (virDomainPtr dom);
static void add_domains_by_id (virConnectPtr conn, int *ids, size_t n, size_t max_disks);
static void add_domains_by_name (virConnectPtr conn, char **names, size_t n, size_t max_disks);
static void add_domain (virDomainPtr dom, size_t max_disks);
static int add_disk (guestfs_h *g, const char *filename, const char *format, int readonly, void *domain_vp);
static void multi_df (struct domain *, size_t n);
static void multi_df (struct domain *, size_t n, size_t *errors);
void
get_domains_from_libvirt (void)
{
virErrorPtr err;
virConnectPtr conn;
int n;
size_t i, j, nr_disks_added;
int n, r;
size_t i, j, nr_disks_added, errors, max_disks;
r = guestfs_max_disks (g);
if (r == -1)
exit (EXIT_FAILURE);
max_disks = (size_t) r;
nr_domains = 0;
domains = NULL;
@@ -114,7 +113,7 @@ get_domains_from_libvirt (void)
if (!conn) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not connect to libvirt (code %d, domain %d): %s"),
_("%s: could not connect to libvirt (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
@@ -123,7 +122,7 @@ get_domains_from_libvirt (void)
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not get number of running domains (code %d, domain %d): %s"),
_("%s: could not get number of running domains (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
@@ -133,18 +132,18 @@ get_domains_from_libvirt (void)
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not list running domains (code %d, domain %d): %s"),
_("%s: could not list running domains (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
add_domains_by_id (conn, ids, n);
add_domains_by_id (conn, ids, n, max_disks);
n = virConnectNumOfDefinedDomains (conn);
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not get number of inactive domains (code %d, domain %d): %s"),
_("%s: could not get number of inactive domains (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
@@ -154,12 +153,12 @@ get_domains_from_libvirt (void)
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not list inactive domains (code %d, domain %d): %s"),
_("%s: could not list inactive domains (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
add_domains_by_name (conn, names, n);
add_domains_by_name (conn, names, n, max_disks);
/* You must free these even though the libvirt documentation doesn't
* mention it.
@@ -180,24 +179,25 @@ get_domains_from_libvirt (void)
/* To minimize the number of times we have to launch the appliance,
* shuffle as many domains together as we can, but not exceeding
* MAX_DISKS per request. If --one-per-guest was requested then only
* max_disks per request. If --one-per-guest was requested then only
* request disks from a single guest each time.
* Interesting application for NP-complete knapsack problem here.
*/
errors = 0;
if (one_per_guest) {
for (i = 0; i < nr_domains; ++i)
multi_df (&domains[i], 1);
multi_df (&domains[i], 1, &errors);
} else {
for (i = 0; i < nr_domains; /**/) {
nr_disks_added = 0;
/* Make a request with domains [i..j-1]. */
for (j = i; j < nr_domains; ++j) {
if (nr_disks_added + domains[j].nr_disks > MAX_DISKS)
if (nr_disks_added + domains[j].nr_disks > max_disks)
break;
nr_disks_added += domains[j].nr_disks;
}
multi_df (&domains[i], j-i);
multi_df (&domains[i], j-i, &errors);
i = j;
}
@@ -207,10 +207,16 @@ get_domains_from_libvirt (void)
for (i = 0; i < nr_domains; ++i)
free_domain (&domains[i]);
free (domains);
if (errors > 0) {
fprintf (stderr, _("%s: failed to analyze a disk, see error(s) above\n"),
program_name);
exit (EXIT_FAILURE);
}
}
static void
add_domains_by_id (virConnectPtr conn, int *ids, size_t n)
add_domains_by_id (virConnectPtr conn, int *ids, size_t n, size_t max_disks)
{
size_t i;
virDomainPtr dom;
@@ -219,7 +225,7 @@ add_domains_by_id (virConnectPtr conn, int *ids, size_t n)
if (ids[i] != 0) { /* RHBZ#538041 */
dom = virDomainLookupByID (conn, ids[i]);
if (dom) { /* transient errors are possible here, ignore them */
add_domain (dom);
add_domain (dom, max_disks);
virDomainFree (dom);
}
}
@@ -227,7 +233,8 @@ add_domains_by_id (virConnectPtr conn, int *ids, size_t n)
}
static void
add_domains_by_name (virConnectPtr conn, char **names, size_t n)
add_domains_by_name (virConnectPtr conn, char **names, size_t n,
size_t max_disks)
{
size_t i;
virDomainPtr dom;
@@ -235,14 +242,14 @@ add_domains_by_name (virConnectPtr conn, char **names, size_t n)
for (i = 0; i < n; ++i) {
dom = virDomainLookupByName (conn, names[i]);
if (dom) { /* transient errors are possible here, ignore them */
add_domain (dom);
add_domain (dom, max_disks);
virDomainFree (dom);
}
}
}
static void
add_domain (virDomainPtr dom)
add_domain (virDomainPtr dom, size_t max_disks)
{
struct domain *domain;
@@ -278,10 +285,10 @@ add_domain (virDomainPtr dom)
exit (EXIT_FAILURE);
domain->nr_disks = n;
if (domain->nr_disks > MAX_DISKS) {
if (domain->nr_disks > max_disks) {
fprintf (stderr,
_("%s: ignoring %s, it has too many disks (%zu > %d)"),
program_name, domain->name, domain->nr_disks, MAX_DISKS);
_("%s: ignoring %s, it has too many disks (%zu > %zu)\n"),
program_name, domain->name, domain->nr_disks, max_disks);
free_domain (domain);
nr_domains--;
return;
@@ -296,7 +303,7 @@ add_disk (guestfs_h *g,
struct domain *domain = domain_vp;
struct disk *disk;
disk = malloc (sizeof *disk);
disk = calloc (1, sizeof *disk);
if (disk == NULL) {
perror ("malloc");
return -1;
@@ -323,33 +330,29 @@ add_disk (guestfs_h *g,
return 0;
}
static size_t
count_strings (char **argv)
{
size_t i;
for (i = 0; argv[i] != NULL; ++i)
;
return i;
}
static void reset_guestfs_handle (void);
static void add_disks_to_handle_reverse (struct disk *disk);
static size_t add_disks_to_handle_reverse (struct disk *disk, size_t *errors_r);
static size_t count_non_failed_disks (struct disk *disk);
static char **duplicate_first_n (char **, size_t n);
/* Perform 'df' operation on the domain(s) given in the list. */
static void
multi_df (struct domain *domains, size_t n)
multi_df (struct domain *domains, size_t n, size_t *errors_r)
{
size_t i;
size_t nd;
size_t count;
int r;
char **devices;
char **domain_devices;
/* Add all the disks to the handle (since they were added in reverse
* order, we must add them here in reverse too).
*/
for (i = 0; i < n; ++i)
add_disks_to_handle_reverse (domains[i].disks);
for (i = 0, count = 0; i < n; ++i)
count += add_disks_to_handle_reverse (domains[i].disks, errors_r);
if (count == 0)
return;
/* Launch the handle. */
if (guestfs_launch (g) == -1)
@@ -359,31 +362,28 @@ multi_df (struct domain *domains, size_t n)
if (devices == NULL)
exit (EXIT_FAILURE);
/* Check the number of disks we think we added is the same as the
* number of devices returned by libguestfs.
*/
nd = 0;
for (i = 0; i < n; ++i)
nd += domains[i].nr_disks;
assert (nd == count_strings (devices));
for (i = 0, nd = 0; i < n; ++i) {
/* Find out how many non-failed disks this domain has. */
count = count_non_failed_disks (domains[i].disks);
if (count == 0)
continue;
nd = 0;
for (i = 0; i < n; ++i) {
/* So that &devices[nd] is a NULL-terminated list of strings. */
char *p = devices[nd + domains[i].nr_disks];
devices[nd + domains[i].nr_disks] = NULL;
/* Duplicate the devices into a separate list for convenience.
* Note this doesn't duplicate the strings themselves.
*/
domain_devices = duplicate_first_n (&devices[nd], count);
r = df_on_handle (domains[i].name, domains[i].uuid, &devices[nd], nd);
/* Restore devices to original. */
devices[nd + domains[i].nr_disks] = p;
nd += domains[i].nr_disks;
r = df_on_handle (domains[i].name, domains[i].uuid, domain_devices, nd);
nd += count;
free (domain_devices);
/* Something broke in df_on_handle. Give up on the remaining
* devices for this handle, but keep going on the next handle.
*/
if (r == -1)
if (r == -1) {
(*errors_r)++;
break;
}
}
for (i = 0; devices[i] != NULL; ++i)
@@ -394,13 +394,15 @@ multi_df (struct domain *domains, size_t n)
reset_guestfs_handle ();
}
static void
add_disks_to_handle_reverse (struct disk *disk)
static size_t
add_disks_to_handle_reverse (struct disk *disk, size_t *errors_r)
{
if (disk == NULL)
return;
size_t nr_disks_added;
add_disks_to_handle_reverse (disk->next);
if (disk == NULL)
return 0;
nr_disks_added = add_disks_to_handle_reverse (disk->next, errors_r);
struct guestfs_add_drive_opts_argv optargs = { .bitmask = 0 };
@@ -412,8 +414,13 @@ add_disks_to_handle_reverse (struct disk *disk)
optargs.format = disk->format;
}
if (guestfs_add_drive_opts_argv (g, disk->filename, &optargs) == -1)
exit (EXIT_FAILURE);
if (guestfs_add_drive_opts_argv (g, disk->filename, &optargs) == -1) {
(*errors_r)++;
disk->failed = 1;
return nr_disks_added;
}
return nr_disks_added+1;
}
/* Close and reopen the libguestfs handle. */
@@ -436,4 +443,32 @@ reset_guestfs_handle (void)
guestfs_set_trace (g, trace);
}
static size_t
count_non_failed_disks (struct disk *disk)
{
if (disk == NULL)
return 0;
else if (disk->failed)
return count_non_failed_disks (disk->next);
else
return 1 + count_non_failed_disks (disk->next);
}
static char **
duplicate_first_n (char **strs, size_t n)
{
char **ret;
ret = malloc ((n+1) * sizeof (char *));
if (ret == NULL) {
perror ("malloc");
exit (EXIT_FAILURE);
}
memcpy (ret, strs, n * sizeof (char *));
ret[n] = NULL;
return ret;
}
#endif

View File

@@ -24,6 +24,7 @@
#include <string.h>
#include <inttypes.h>
#include <xvasprintf.h>
#include <libintl.h>
#include <math.h>
#include <assert.h>
@@ -81,7 +82,7 @@ print_title (void)
}
}
static void canonical_device (char *dev, int offset);
static char *adjust_device_offset (const char *device, int offset);
void
print_stat (const char *name, const char *uuid_param,
@@ -101,13 +102,17 @@ print_stat (const char *name, const char *uuid_param,
float percent;
int hopts = human_round_to_nearest|human_autoscale|human_base_1024|human_SI;
size_t i, len;
char *dev;
/* Make the device canonical. */
len = strlen (dev_param) + 1;
char dev[len];
strcpy (dev, dev_param);
if (offset >= 0)
canonical_device (dev, offset);
/* Make a canonical name, adjusting the device offset if necessary. */
dev = guestfs_canonical_device_name (g, dev_param);
if (!dev)
exit (EXIT_FAILURE);
if (offset >= 0) {
char *p = dev;
dev = adjust_device_offset (p, offset);
free (p);
}
if (!inodes) { /* 1K blocks */
if (!human) {
@@ -189,20 +194,8 @@ print_stat (const char *name, const char *uuid_param,
putchar ('\n');
}
}
/* /dev/vda1 -> /dev/sda, adjusting the device offset. */
static void
canonical_device (char *dev, int offset)
{
if (STRPREFIX (dev, "/dev/") &&
(dev[5] == 'h' || dev[5] == 'v') &&
dev[6] == 'd' &&
c_isalpha (dev[7]) &&
(c_isdigit (dev[8]) || dev[8] == '\0')) {
dev[5] = 's';
dev[7] -= offset;
}
free (dev);
}
/* Function to quote CSV fields on output without requiring an
@@ -240,3 +233,72 @@ write_csv_field (const char *field)
}
putchar ('"');
}
static char *drive_name (int index, char *ret);
static char *
adjust_device_offset (const char *device, int offset)
{
int index;
int part_num;
char *whole_device;
int free_whole_device;
size_t len;
char *ret;
/* Could be a whole disk or a partition. guestfs_device_index will
* only work with the whole disk name.
*/
len = strlen (device);
if (len > 0 && c_isdigit (device[len-1])) {
whole_device = guestfs_part_to_dev (g, device);
if (whole_device == NULL)
exit (EXIT_FAILURE);
free_whole_device = 1;
part_num = guestfs_part_to_partnum (g, device);
if (part_num == -1)
exit (EXIT_FAILURE);
} else {
whole_device = (char *) device;
free_whole_device = 0;
part_num = 0;
}
index = guestfs_device_index (g, whole_device);
if (index == -1)
exit (EXIT_FAILURE);
if (free_whole_device)
free (whole_device);
assert (index >= offset);
index -= offset;
/* Construct the final device name. */
ret = malloc (128);
if (!ret) {
perror ("malloc");
exit (EXIT_FAILURE);
}
strcpy (ret, "/dev/sd");
drive_name (index, &ret[7]);
len = strlen (ret);
if (part_num > 0)
snprintf (&ret[len], 128-len, "%d", part_num);
return ret;
}
/* https://rwmj.wordpress.com/2011/01/09/how-are-linux-drives-named-beyond-drive-26-devsdz/ */
static char *
drive_name (int index, char *ret)
{
if (index >= 26)
ret = drive_name (index/26 - 1, ret);
index %= 26;
*ret++ = 'a' + index;
*ret = '\0';
return ret;
}

View File

@@ -27,11 +27,11 @@ bin_PROGRAMS = virt-edit
SHARED_SOURCE_FILES = \
../fish/config.c \
../fish/domain.c \
../fish/inspect.c \
../fish/keys.c \
../fish/options.h \
../fish/options.c \
../fish/virt.c
../fish/options.c
virt_edit_SOURCES = \
$(SHARED_SOURCE_FILES) \
@@ -58,7 +58,7 @@ noinst_DATA = $(top_builddir)/html/virt-edit.1.html
virt-edit.1 $(top_builddir)/html/virt-edit.1.html: stamp-virt-edit.pod
stamp-virt-edit.pod: virt-edit.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man virt-edit.1 \
--html $(top_builddir)/html/virt-edit.1.html \
$<
@@ -66,11 +66,7 @@ stamp-virt-edit.pod: virt-edit.pod
# Tests.
random_val := $(shell awk 'BEGIN{srand(); print 1+int(255*rand())}' < /dev/null)
TESTS_ENVIRONMENT = \
MALLOC_PERTURB_=$(random_val) \
$(top_builddir)/run
TESTS_ENVIRONMENT = $(top_builddir)/run --test
if ENABLE_APPLIANCE
TESTS = test-virt-edit.sh

View File

@@ -3,15 +3,17 @@
export LANG=C
set -e
rm -f test.qcow2
# Make a copy of the Fedora image so we can write to it then
# discard it.
cp ../tests/guests/fedora.img test.img
qemu-img create -F raw -b ../tests/guests/fedora.img -f qcow2 test.qcow2
# Edit interactively. We have to simulate this by setting $EDITOR.
# The command will be: echo newline >> /tmp/file
export EDITOR='echo newline >>'
./virt-edit -a test.img /etc/test3
if [ "$(../cat/virt-cat -a test.img /etc/test3)" != "a
./virt-edit -a test.qcow2 /etc/test3
if [ "$(../cat/virt-cat -a test.qcow2 /etc/test3)" != "a
b
c
d
@@ -25,8 +27,8 @@ unset EDITOR
# Edit non-interactively, only if we have 'perl' binary.
if perl --version >/dev/null 2>&1; then
./virt-edit -a test.img /etc/test3 -e 's/^[a-f]/$lineno/'
if [ "$(../cat/virt-cat -a test.img /etc/test3)" != "1
./virt-edit -a test.qcow2 /etc/test3 -e 's/^[a-f]/$lineno/'
if [ "$(../cat/virt-cat -a test.qcow2 /etc/test3)" != "1
2
3
4
@@ -40,7 +42,7 @@ fi
# Verify the mode of /etc/test3 is still 0600 and the UID:GID is 10:11.
# See tests/guests/guest-aux/make-fedora-img.pl and RHBZ#788641.
if [ "$(../fish/guestfish -i -a test.img --ro lstat /etc/test3 | grep -E '^(mode|uid|gid):' | sort)" != "gid: 11
if [ "$(../fish/guestfish -i -a test.qcow2 --ro lstat /etc/test3 | grep -E '^(mode|uid|gid):' | sort)" != "gid: 11
mode: 33152
uid: 10" ]; then
echo "$0: error: editing /etc/test3 did not preserve permissions or ownership"
@@ -48,4 +50,4 @@ uid: 10" ]; then
fi
# Discard test image.
rm test.img
rm test.qcow2

View File

@@ -298,7 +298,7 @@ main (int argc, char *argv[])
free (root);
/* Cleanly unmount the disks after editing. */
if (guestfs_umount_all (g) == -1 || guestfs_sync (g) == -1)
if (guestfs_shutdown (g) == -1)
exit (EXIT_FAILURE);
guestfs_close (g);

View File

@@ -326,6 +326,20 @@ C<touch>, C<write> or C<upload> instead:
guestfish --rw -i -d domname upload localfile /newfile
=head1 CVE-2012-2690
Old versions of both virt-edit and the guestfish C<edit> command
created a new file containing the changes but did not set the
permissions, etc of the new file to match the old one. The result of
this was that if you edited a security sensitive file such as
C</etc/shadow> then it would be left world-readable after the edit.
This issue was assigned CVE-2012-2690, and is fixed in
libguestfs E<ge> 1.16.
For further information, see
L<https://bugzilla.redhat.com/show_bug.cgi?id=788642>
=head1 ENVIRONMENT VARIABLES
=over 4

View File

@@ -16,6 +16,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -29,7 +29,7 @@ noinst_DATA = $(top_builddir)/html/guestfs-erlang.3.html
guestfs-erlang.3 $(top_builddir)/html/guestfs-erlang.3.html: stamp-guestfs-erlang.pod
stamp-guestfs-erlang.pod: guestfs-erlang.pod create_disk.erl inspect_vm.erl
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--section 3 \
--man guestfs-erlang.3 \
--html $(top_builddir)/html/guestfs-erlang.3.html \

View File

@@ -16,10 +16,6 @@ main(_) ->
% Set the trace flag so that we can see each libguestfs call.
ok = guestfs:set_trace(G, true),
% Set the autosync flag so that the disk will be synchronized
% automatically when the libguestfs handle is closed.
ok = guestfs:set_autosync(G, true),
% Attach the disk image to libguestfs.
ok = guestfs:add_drive_opts(G, Output,
[{format, "raw"}, {readonly, false}]),
@@ -55,10 +51,11 @@ main(_) ->
% the disk image.
ok = guestfs:upload(G, "/etc/resolv.conf", "/foo/resolv.conf"),
% Because 'autosync' was set (above) we can just close the handle
% and the disk contents will be synchronized. You can also do
% this manually by calling guestfs:umount_all and guestfs:sync.
%
% Because we wrote to the disk and we want to detect write
% errors, call guestfs:shutdown. You don't need to do this:
% guestfs:close will do it implicitly.
ok = guestfs:shutdown(G),
% Note also that handles are automatically closed if they are
% reaped by the garbage collector. You only need to call close
% if you want to close the handle right away.

View File

@@ -18,12 +18,14 @@
EXTRA_DIST = \
LICENSE \
guestfs-examples.pod \
guestfs-faq.pod \
guestfs-performance.pod \
guestfs-recipes.pod \
guestfs-testing.pod
CLEANFILES = \
stamp-guestfs-examples.pod \
stamp-guestfs-faq.pod \
stamp-guestfs-performance.pod \
stamp-guestfs-recipes.pod \
stamp-guestfs-testing.pod
@@ -35,6 +37,9 @@ endif
if HAVE_HIVEX
noinst_PROGRAMS += virt-dhcp-address
endif
if HAVE_FUSE
noinst_PROGRAMS += mount_local
endif
if HAVE_LIBVIRT
copy_over_SOURCES = copy_over.c
@@ -73,6 +78,19 @@ inspect_vm_CFLAGS = \
inspect_vm_LDADD = \
$(top_builddir)/src/libguestfs.la
if HAVE_FUSE
mount_local_SOURCES = mount_local.c
mount_local_CFLAGS = \
-DGUESTFS_WARN_DEPRECATED=1 \
-I$(top_srcdir)/src -I$(top_builddir)/src \
$(FUSE_CFLAGS) \
$(WARN_CFLAGS) $(WERROR_CFLAGS)
mount_local_LDADD = \
$(FUSE_LIBS) -lulockmgr \
$(top_builddir)/src/libguestfs.la
endif
if HAVE_HIVEX
virt_dhcp_address_SOURCES = virt-dhcp-address.c
virt_dhcp_address_CFLAGS = \
-DGUESTFS_WARN_DEPRECATED=1 \
@@ -82,14 +100,17 @@ virt_dhcp_address_CFLAGS = \
virt_dhcp_address_LDADD = \
$(HIVEX_LIBS) \
$(top_builddir)/src/libguestfs.la
endif
man_MANS = \
guestfs-examples.3 \
guestfs-faq.1 \
guestfs-performance.1 \
guestfs-recipes.1 \
guestfs-testing.1
noinst_DATA = \
$(top_builddir)/html/guestfs-examples.3.html \
$(top_builddir)/html/guestfs-faq.1.html \
$(top_builddir)/html/guestfs-performance.1.html \
$(top_builddir)/html/guestfs-recipes.1.html \
$(top_builddir)/html/guestfs-testing.1.html
@@ -97,7 +118,7 @@ noinst_DATA = \
guestfs-examples.3 $(top_builddir)/html/guestfs-examples.3.html: stamp-guestfs-examples.pod
stamp-guestfs-examples.pod: guestfs-examples.pod create_disk.c inspect_vm.c
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--section 3 \
--man guestfs-examples.3 \
--html $(top_builddir)/html/guestfs-examples.3.html \
@@ -106,10 +127,20 @@ stamp-guestfs-examples.pod: guestfs-examples.pod create_disk.c inspect_vm.c
$<
touch $@
guestfs-faq.1 $(top_builddir)/html/guestfs-faq.1.html: stamp-guestfs-faq.pod
stamp-guestfs-faq.pod: guestfs-faq.pod
$(PODWRAPPER) \
--section 1 \
--man guestfs-faq.1 \
--html $(top_builddir)/html/guestfs-faq.1.html \
$<
touch $@
guestfs-performance.1 $(top_builddir)/html/guestfs-performance.1.html: stamp-guestfs-performance.pod
stamp-guestfs-performance.pod: guestfs-performance.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--section 1 \
--man guestfs-performance.1 \
--html $(top_builddir)/html/guestfs-performance.1.html \
@@ -119,7 +150,7 @@ stamp-guestfs-performance.pod: guestfs-performance.pod
guestfs-recipes.1 $(top_builddir)/html/guestfs-recipes.1.html: stamp-guestfs-recipes.pod
stamp-guestfs-recipes.pod: guestfs-recipes.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--section 1 \
--man guestfs-recipes.1 \
--html $(top_builddir)/html/guestfs-recipes.1.html \
@@ -129,7 +160,7 @@ stamp-guestfs-recipes.pod: guestfs-recipes.pod
guestfs-testing.1 $(top_builddir)/html/guestfs-testing.1.html: stamp-guestfs-testing.pod
stamp-guestfs-testing.pod: guestfs-testing.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--section 1 \
--man guestfs-testing.1 \
--html $(top_builddir)/html/guestfs-testing.1.html \

View File

@@ -21,7 +21,6 @@
#include <pthread.h>
#include <guestfs.h>
#include <libvirt/libvirt.h>
struct threaddata {
const char *src;
@@ -66,9 +65,6 @@ main (int argc, char *argv[])
struct timeval start_t, end_t;
int64_t ms;
/* This is required when using libvirt from multiple threads. */
virInitialize ();
if (argc != 5) {
usage ();
exit (EXIT_FAILURE);
@@ -145,7 +141,7 @@ main (int argc, char *argv[])
}
/* Clean up. */
if (guestfs_umount_all (destg) == -1)
if (guestfs_shutdown (destg) == -1)
exit (EXIT_FAILURE);
guestfs_close (destg);
@@ -193,10 +189,6 @@ start_srcthread (void *arg)
}
/* Clean up. */
if (guestfs_umount_all (srcg) == -1) {
pthread_cancel (threaddata->mainthread);
exit (EXIT_FAILURE);
}
guestfs_close (srcg);
return NULL;

View File

@@ -37,11 +37,6 @@ main (int argc, char *argv[])
/* Set the trace flag so that we can see each libguestfs call. */
guestfs_set_trace (g, 1);
/* Set the autosync flag so that the disk will be synchronized
* automatically when the libguestfs handle is closed.
*/
guestfs_set_autosync (g, 1);
/* Add the disk image to libguestfs. */
if (guestfs_add_drive_opts (g, "disk.img",
GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", /* raw format */
@@ -104,10 +99,13 @@ main (int argc, char *argv[])
if (guestfs_upload (g, "/etc/resolv.conf", "/foo/resolv.conf") == -1)
exit (EXIT_FAILURE);
/* Because 'autosync' was set (above) we can just close the handle
* and the disk contents will be synchronized. You can also do
* this manually by calling guestfs_umount_all and guestfs_sync.
/* Because we wrote to the disk and we want to detect write
* errors, call guestfs_shutdown. You don't need to do this:
* guestfs_close will do it implicitly.
*/
if (guestfs_shutdown (g) == -1)
exit (EXIT_FAILURE);
guestfs_close (g);
/* Free up the lists. */

684
examples/guestfs-faq.pod Normal file
View File

@@ -0,0 +1,684 @@
=encoding utf8
=head1 NAME
guestfs-faq - libguestfs Frequently Asked Questions (FAQ)
=head1 ABOUT LIBGUESTFS
=head2 What is libguestfs?
libguestfs is a way to create, access and modify disk images. You can
look inside disk images, modify the files they contain, create them
from scratch, resize them, and much more. It's especially useful from
scripts and programs and from the command line.
libguestfs is a C library (hence "lib-"), and a set of tools built on
this library, and a set of bindings in many different programming
languages.
For more information about what libguestfs can do read the
introduction on the home page (L<http://libguestfs.org>).
=head2 What are the virt tools?
Virt tools (website: L<http://virt-tools.org>) are a whole set of
virtualization management tools aimed at system administrators. Some
of them come from libguestfs, some from libvirt and many others from
other open source projects. So virt tools is a superset of
libguestfs. However libguestfs comes with many important tools. See
L<http://libguestfs.org> for a full list.
=head2 Does libguestfs need { libvirt / KVM / Red Hat / Fedora }?
No!
libvirt is not a requirement for libguestfs.
libguestfs works with any disk image, including ones created in
VMware, KVM, qemu, VirtualBox, Xen, and many other hypervisors, and
ones which you have created from scratch.
Red Hat sponsors (ie. pays for) development of libguestfs and a huge
number of other open source projects. But you can run libguestfs and
the virt tools on many different Linux distros and Mac OS X. Some
virt tools have been ported to Windows.
=head2 How does libguestfs compare to other tools?
=over 4
=item I<vs. kpartx>
Libguestfs takes a different approach from kpartx. kpartx needs root,
and mounts filesystems on the host kernel (which can be insecure - see
L<guestfs(3)/SECURITY>). Libguestfs isolates your host kernel from
guests, is more flexible, scriptable, supports LVM, doesn't require
root, is isolated from other processes, and cleans up after itself.
Libguestfs is more than just file access because you can use it to
create images from scratch.
=item I<vs. vdfuse>
vdfuse is like kpartx but for VirtualBox images. See the kpartx
comparison above. You can use libguestfs on the partition files
exposed by vdfuse, although it's not necessary since libguestfs can
access VirtualBox images directly.
=item I<vs. qemu-nbd>
nbd is like kpartx but for qcow2 images. See the kpartx comparison
above. You can use libguestfs and qemu-nbd together for access to
block devices over the network.
=item I<vs. mounting filesystems in the host>
Mounting guest filesystems in the host is insecure and should be
avoided completely for untrusted guests. Use libguestfs to provide a
layer of protection against filesystem exploits. See also
L<guestmount(1)>.
=item I<vs. parted>
Libguestfs supports LVM. Libguestfs uses parted and provides most
parted features through the libguestfs API.
=back
=head1 GETTING HELP AND REPORTING BUGS
=head2 How do I know what version I'm using?
The simplest method is:
guestfish --version
Libguestfs development happens along an unstable branch and we
periodically create a stable branch which we backport stable patches
to. To find out more, read L<guestfs(3)/LIBGUESTFS VERSION NUMBERS>.
=head2 How can I get help?
What mailing lists or chat rooms are available?
If you are a Red Hat customer using Red Hat Enterprise Linux, please
contact Red Hat Support: L<http://redhat.com/support>
There is a mailing list, mainly for development, but users are also
welcome to ask questions about libguestfs and the virt tools:
L<https://www.redhat.com/mailman/listinfo/libguestfs>
You can also talk to us on IRC channel C<#libguestfs> on FreeNode.
We're not always around, so please stay in the channel after asking
your question and someone will get back to you.
For other virt tools (not ones supplied with libguestfs) there is a
general virt tools mailing list:
L<https://www.redhat.com/mailman/listinfo/virt-tools-list>
=head2 How do I report bugs?
Please use the following link to enter a bug in Bugzilla:
L<https://bugzilla.redhat.com/enter_bug.cgi?component=libguestfs&product=Virtualization+Tools>
Include as much detail as you can and a way to reproduce the problem.
Include the full output of L<libguestfs-test-tool(1)>.
=head1 COMMON ERRORS
=head2 "child process died unexpectedly"
This error indicates that qemu failed or the host kernel could not boot.
To get further information about the failure, you have to run:
libguestfs-test-tool
If, after using this, you still don't understand the failure, contact
us (see previous section).
=head1 COMMON PROBLEMS
See also L<guestfs(3)/LIBGUESTFS GOTCHAS> for some "gotchas" with
using the libguestfs API.
=head2 Non-ASCII characters don't appear on VFAT filesystems.
Typical symptoms of this problem:
=over 4
=item *
You get an error when you create a file where the filename contains
non-ASCII characters, particularly non 8-bit characters from Asian
languages (Chinese, Japanese, etc). The filesystem is VFAT.
=item *
When you list a directory from a VFAT filesystem, filenames appear as
question marks.
=back
This is a design flaw of the GNU/Linux system.
VFAT stores long filenames as UTF-16 characters. When opening or
returning filenames, the Linux kernel has to translate these to some
form of 8 bit string. UTF-8 would be the obvious choice, except for
Linux users who persist in using non-UTF-8 locales (the user's locale
is not known to the kernel because it's a function of libc).
Therefore you have to tell the kernel what translation you want done
when you mount the filesystem. The two methods are the C<iocharset>
parameter (which is not relevant to libguestfs) and the C<utf8> flag.
So to use a VFAT filesystem you must add the C<utf8> flag when
mounting. From guestfish, use:
><fs> mount-options utf8 /dev/sda1 /
or on the guestfish command line:
guestfish [...] -m /dev/sda1:/:utf8
or from the API:
guestfs_mount_options (g, "utf8", "/dev/sda1", "/");
The kernel will then translate filenames to and from UTF-8 strings.
We considered adding this mount option transparently, but
unfortunately there are several problems with doing that:
=over 4
=item *
On some Linux systems, the C<utf8> mount option doesn't work. We
don't precisely understand what systems or why, but this was reliably
reported by one user.
=item *
It would prevent you from using the C<iocharset> parameter because it
is incompatible with C<utf8>. It is probably not a good idea to use
this parameter, but we don't want to prevent it.
=back
=head2 Non-ASCII characters appear as underscore (_) on ISO9660 filesystems.
The filesystem was not prepared correctly with mkisofs or genisoimage.
Make sure the filesystem was created using Joliet and/or Rock Ridge
extensions. libguestfs does not require any special mount options to
handle the filesystem.
=head1 DOWNLOADING, INSTALLING, COMPILING LIBGUESTFS
=begin html
<!-- old anchor for the next section -->
<a name="binaries"/>
=end html
=head2 Where can I get the latest binaries for ...?
=over 4
=item Fedora E<ge> 11, RHEL E<ge> 5.3, EPEL 5
Use:
yum install '*guestf*'
For the latest builds, see:
L<http://koji.fedoraproject.org/koji/packageinfo?packageID=8391>
=item Red Hat Enterprise Linux 6
It is part of the default install. On RHEL 6 (only) you have to
install C<libguestfs-winsupport> to get Windows guest support.
=item RHEL 6.3
Preview packages are available here:
L<http://people.redhat.com/~rjones/libguestfs-RHEL-6.3-preview/>
=item Debian Squeeze (6)
Use Hilko Bengen's backport repository:
L<http://people.debian.org/~bengen/libguestfs/>
=item Debian Wheezy and later (7+)
Official Debian packages are available:
L<http://packages.debian.org/search?keywords=libguestfs>
(thanks Hilko Bengen).
=item Ubuntu
We don't have an Ubuntu maintainer, and the packages supplied by
Canonical (which are outside our control) are often broken. Try
compiling from source (next section).
Canonical decided to change the permissions on the kernel so that it's
not readable except by root. This is completely stupid, but they
won't change it
(L<https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725>).
So every user should do this:
sudo chmod 0644 /boot/vmlinuz*
=item Ubuntu 10.04
See:
L<http://libguestfs.org/download/binaries/ubuntu1004-packages/>
=item Ubuntu 12.04
libguestfs in this version of Ubuntu works, but you need to update
febootstrap and seabios to the latest versions.
You need febootstrap E<ge> 3.14-2 from:
L<http://packages.ubuntu.com/precise/febootstrap>
After installing or updating febootstrap, rebuild the appliance:
sudo update-guestfs-appliance
You need seabios E<ge> 0.6.2-0ubuntu2.1 or E<ge> 0.6.2-0ubuntu3 from:
L<http://packages.ubuntu.com/precise-updates/seabios>
or
L<http://packages.ubuntu.com/quantal/seabios>
Also you need to do (see above):
sudo chmod 0644 /boot/vmlinuz*
=item Gentoo
Libguestfs was added to Gentoo in 2012-07. Do:
emerge libguestfs
=item Other Linux distro
Compile from source (next section).
=item Other non-Linux distro
You'll have to compile from source, and port it.
=back
=head2 How can I compile and install libguestfs from source?
If your Linux distro has a working port of febootstrap (that is,
Fedora, Red Hat Enterprise Linux >= 6.3, Debian, Ubuntu and ArchLinux)
then you should just be able to compile from source in the usual way.
Download the latest tarball from L<http://libguestfs.org/download>,
unpack it, and start by reading the README file.
If you I<don't> have febootstrap, you will need to use the "fixed
appliance method". See:
L<http://libguestfs.org/download/binaries/appliance/>
Patches to port febootstrap to more Linux distros are welcome.
=head2 Why do I get an error when I try to rebuild from the source
RPMs supplied by Red Hat / Fedora?
Because of the complexity of building the libguestfs appliance, the
source RPMs provided cannot be rebuilt directly using C<rpmbuild> or
C<mock>.
If you use Koji (which is open source software and may be installed
locally), then the SRPMs can be rebuilt in Koji.
L<https://fedoraproject.org/wiki/Koji>
If you don't have or want to use Koji, then you have to give
libguestfs access to the network so it can download the RPMs for
building the appliance. You also need to set an RPM macro to tell
libguestfs to use the network. Put the following line into a file
called C<$HOME/.rpmmacros>:
%libguestfs_buildnet 1
If you are using mock, do:
mock -D '%libguestfs_buildnet 1' [etc]
=head2 Libguestfs has a really long list of dependencies!
That's because it does a lot of things.
=head2 How can I speed up libguestfs builds?
By far the most important thing you can do is to install and properly
configure Squid. Note that the default configuration that ships with
Squid is rubbish, so configuring it is not optional.
A very good place to start with Squid configuration is here:
L<https://fedoraproject.org/wiki/Extras/MockTricks#Using_Squid_to_Speed_Up_Mock_package_downloads>
Make sure Squid is running, and that the environment variables
C<$http_proxy> and C<$ftp_proxy> are pointing to it.
With Squid running and correctly configured, appliance builds should
be reduced to a few minutes.
=head1 SPEED, DISK SPACE USED BY LIBGUESTFS
Note: Most of the information in this section has moved:
L<guestfs-performance(1)>.
=head2 Upload or write seem very slow.
In libguestfs E<lt> 1.13.16, the mount command
(L<guestfs(3)/guestfs_mount>) enabled option C<-o sync> implicitly.
This causes very poor write performance, and was one of the main
gotchas for new libguestfs users.
For libguestfs E<lt> 1.13.16, replace mount with C<mount-options>,
leaving the first parameter as an empty string.
You can also do this with more recent versions of libguestfs, but if
you know that you are using libguestfs ≥ 1.13.16 then it's safe to use
plain mount.
If the underlying disk is not fully allocated (eg. sparse raw or
qcow2) then writes can be slow because the host operating system has
to do costly disk allocations while you are writing. The solution is
to use a fully allocated format instead, ie. non-sparse raw, or qcow2
with the C<preallocation=metadata> option.
=head2 Libguestfs uses too much disk space!
libguestfs caches a large-ish appliance in:
/var/tmp/.guestfs-<UID>
If the environment variable C<TMPDIR> is defined, then
C<$TMPDIR/.guestfs-E<lt>UIDE<gt>> is used instead.
It is safe to delete this directory when you are not using libguestfs.
=head1 USING LIBGUESTFS IN YOUR OWN PROGRAMS
=head2 The API has hundreds of methods, where do I start?
We recommend you start by reading the API overview:
L<guestfs(3)/API OVERVIEW>.
Although the API overview covers the C API, it is still worth reading
even if you are going to use another programming language, because the
API is the same, just with simple logical changes to the names of the
calls:
C guestfs_ln_sf (g, target, linkname);
Python g.ln_sf (target, linkname);
OCaml g#ln_sf target linkname;
Perl $g->ln_sf (target, linkname);
Shell (guestfish) ln-sf target linkname
PHP guestfs_ln_sf ($g, $target, $linkname);
Once you're familiar with the API overview, you should look at this
list of starting points for other language bindings:
L<guestfs(3)/USING LIBGUESTFS WITH OTHER PROGRAMMING LANGUAGES>.
=begin html
<!-- old anchor for the next section -->
<a name="debug"/>
=end html
=head2 Can I use libguestfs in my proprietary / closed source / commercial program?
In general, yes. However this is not legal advice. You should read
the license that comes with libguestfs, and if you have specific
questions about your obligations when distributing libguestfs, contact
a lawyer. In the source tree the license is in the file
C<COPYING.LIB> (LGPLv2+ for the library and bindings) and C<COPYING>
(GPLv2+ for the standalone programs).
=head1 DEBUGGING LIBGUESTFS
=head2 How do I debug when using any libguestfs program or tool
(eg. virt-v2v or virt-df)?
There are two C<LIBGUESTFS_*> environment variables you can set in
order to get more information from libguestfs.
=over 4
=item C<LIBGUESTFS_TRACE>
Set this to 1 and libguestfs will print out each command / API call in
a format which is similar to guestfish commands.
=item C<LIBGUESTFS_DEBUG>
Set this to 1 in order to enable massive amounts of debug messages.
If you think there is some problem inside the libguestfs appliance,
then you should use this option.
=back
To set these from the shell, do this before running the program:
export LIBGUESTFS_TRACE=1
export LIBGUESTFS_DEBUG=1
For csh/tcsh the equivalent commands would be:
setenv LIBGUESTFS_TRACE 1
setenv LIBGUESTFS_DEBUG 1
For further information, see: L<guestfs(3)/ENVIRONMENT VARIABLES>.
=head2 How do I debug when using guestfish?
You can use the same environment variables above. Alternatively use
the guestfish options -x (to trace commands) or -v (to get the full
debug output), or both.
For further information, see: L<guestfish(1)>.
=head2 How do I debug when using the API?
Call L<guestfs(3)/guestfs_set_trace> to enable command traces, and/or
L<guestfs(3)/guestfs_set_verbose> to enable debug messages.
For best results, call these functions as early as possible, just
after creating the guestfs handle if you can, and definitely before
calling launch.
=head2 How do I capture debug output and put it into my logging system?
Use the event API. For examples, see:
L<guestfs(3)/SETTING CALLBACKS TO HANDLE EVENTS>.
=head2 Digging deeper into the appliance boot process.
Enable debugging and then read this documentation on the appliance
boot process: L<guestfs(3)/INTERNALS>.
=head2 libguestfs hangs or fails during run/launch.
Enable debugging and look at the full output. If you cannot work out
what is going on, file a bug report, including the I<complete> output
of L<libguestfs-test-tool(1)>.
=head1 DESIGN/INTERNALS OF LIBGUESTFS
=head2 Why don't you do everything through the FUSE / filesystem
interface?
We offer a command called L<guestmount(1)> which lets you mount guest
filesystems on the host. This is implemented as a FUSE module. Why
don't we just implement the whole of libguestfs using this mechanism,
instead of having the large and rather complicated API?
The reasons are twofold. Firstly, libguestfs offers API calls for
doing things like creating and deleting partitions and logical
volumes, which don't fit into a filesystem model very easily. Or
rather, you could fit them in: for example, creating a partition could
be mapped to C<mkdir /fs/hda1> but then you'd have to specify some
method to choose the size of the partition (maybe C<echo 100M E<gt>
/fs/hda1/.size>), and the partition type, start and end sectors etc.,
but once you've done that the filesystem-based API starts to look more
complicated than the call-based API we currently have.
The second reason is for efficiency. FUSE itself is reasonably
efficient, but it does make lots of small, independent calls into the
FUSE module. In guestmount these have to be translated into messages
to the libguestfs appliance which has a big overhead (in time and
round trips). For example, reading a file in 64 KB chunks is
inefficient because each chunk would turn into a single round trip.
In the libguestfs API it is much more efficient to download an entire
file or directory through one of the streaming calls like
C<guestfs_download> or C<guestfs_tar_out>.
=head2 Why don't you do everything through GVFS?
The problems are similar to the problems with FUSE.
GVFS is a better abstraction than POSIX/FUSE. There is an FTP backend
for GVFS, which is encouraging because FTP is conceptually similar to
the libguestfs API. However the GVFS FTP backend makes multiple
simultaneous connections in order to keep interactivity, which we
can't easily do with libguestfs.
=head2 Can I use C<guestfish --ro> as a way to backup my virtual machines?
Usually this is not a good idea. The question is answered in more
detail in this mailing list posting:
L<https://www.redhat.com/archives/libguestfs/2010-August/msg00024.html>
=head2 What's the difference between guestfish and virt-rescue?
A lot of people are confused by the two superficially similar tools we
provide:
$ guestfish --ro -a guest.img
><fs> run
><fs> fsck /dev/sda1
$ virt-rescue --ro guest.img
><rescue> /sbin/fsck /dev/sda1
And the related question which then arises is why you can't type in
full shell commands with all the --options in guestfish (but you can
in L<virt-rescue(1)>).
L<guestfish(1)> is a program providing structured access to the
L<guestfs(3)> API. It happens to be a nice interactive shell too, but
its primary purpose is structured access from shell scripts. Think of
it more like a language binding, like Python and other bindings, but
for shell. The key differentiating factor of guestfish (and the
libguestfs API in general) is the ability to automate changes.
L<virt-rescue(1)> is a free-for-all freeform way to boot the
libguestfs appliance and make arbitrary changes to your VM. It's not
structured, you can't automate it, but for making quick ad-hoc fixes
to your guests, it can be quite useful.
But, libguestfs also has a "backdoor" into the appliance allowing you
to send arbitrary shell commands. It's not as flexible as
virt-rescue, because you can't interact with the shell commands, but
here it is anyway:
><fs> debug sh "cmd arg1 arg2 ..."
Note that you should B<not> rely on this. It could be removed or
changed in future. If your program needs some operation, please add it
to the libguestfs API instead.
=head2 What's the deal with C<guestfish -i>?
Why does virt-cat only work on a real VM image, but virt-df works on
any disk image?
What does "no root device found in this operating system image" mean?
These questions are all related at a fundamental level which may not
be immediately obvious.
At the L<guestfs(3)> API level, a "disk image" is just a pile of
partitions and filesystems.
In contrast, when the virtual machine boots, it mounts those
filesystems into a consistent hierarchy such as:
/ (/dev/sda2)
|
+-- /boot (/dev/sda1)
|
+-- /home (/dev/vg_external/Homes)
|
+-- /usr (/dev/vg_os/lv_usr)
|
+-- /var (/dev/vg_os/lv_var)
(or drive letters on Windows).
The API first of all sees the disk image at the "pile of filesystems"
level. But it also has a way to inspect the disk image to see if it
contains an operating system, and how the disks are mounted when the
operating system boots: L<guestfs(3)/INSPECTION>.
Users expect some tools (like L<virt-cat(1)>) to work with VM paths:
virt-cat fedora.img /var/log/messages
How does virt-cat know that C</var> is a separate partition? The
trick is that virt-cat performs inspection on the disk image, and uses
that to translate the path correctly.
Some tools (including L<virt-cat(1)>, L<virt-edit(1)>, L<virt-ls(1)>)
use inspection to map VM paths. Other tools, such as L<virt-df(1)>
and L<virt-filesystems(1)> operate entirely at the raw "big pile of
filesystems" level of the libguestfs API, and don't use inspection.
L<guestfish(1)> is in an interesting middle ground. If you use the
I<-a> and I<-m> command line options, then you have to tell guestfish
exactly how to add disk images and where to mount partitions. This is
the raw API level.
If you use the I<-i> option, libguestfs performs inspection and mounts
the filesystems for you.
The error C<no root device found in this operating system image> is
related to this. It means inspection was unable to locate an
operating system within the disk image you gave it. You might see
this from programs like virt-cat if you try to run them on something
which is just a disk image, not a virtual machine disk image.
=head1 SEE ALSO
L<guestfish(1)>,
L<guestfs(3)>,
L<http://libguestfs.org/>.
=head1 AUTHORS
Richard W.M. Jones (C<rjones at redhat dot com>)
=head1 COPYRIGHT
Copyright (C) 2012 Red Hat Inc. L<http://libguestfs.org/>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

View File

@@ -2,10 +2,6 @@
=begin comment
pod2man and pod2html have differing bugs which makes it hard to write
URLs here. The only way which works for both sorts of output is to
just write the URL directly. Do NOT use L<...> for URLs.
We break with tradition here and don't use ALL CAPS for the section
headings, as this makes them much easier to read.
@@ -25,7 +21,7 @@ libguestfs, L<guestfish(1)> and the virt tools.
The link below contains a small program which can be used to audit a
Linux virtual machine to see what setuid and setgid files it contains.
https://rwmj.wordpress.com/2010/12/15/tip-audit-virtual-machine-for-setuid-files/#content
L<https://rwmj.wordpress.com/2010/12/15/tip-audit-virtual-machine-for-setuid-files/#content>
=head1 Change the background image in a Windows XP VM
@@ -34,8 +30,8 @@ background image for a user of a Windows XP VM. Unfortunately the
technique appears to be substantially different for each version of
Windows.
https://lists.fedoraproject.org/pipermail/virt/2011-May/002655.html
https://lists.fedoraproject.org/pipermail/virt/2011-May/002658.html
L<https://lists.fedoraproject.org/pipermail/virt/2011-May/002655.html>
L<https://lists.fedoraproject.org/pipermail/virt/2011-May/002658.html>
=head1 Cloning a virtual machine (Linux)
@@ -43,12 +39,12 @@ The guestfish technique described in the link below works well for
most Linux VMs. Depending on the Linux distro you may need to change
the paths slightly.
https://rwmj.wordpress.com/2010/09/24/tip-my-procedure-for-cloning-a-fedora-vm/#content
L<https://rwmj.wordpress.com/2010/09/24/tip-my-procedure-for-cloning-a-fedora-vm/#content>
Avoid L<virt-clone(1)>. Currently what to do about virt-clone is
under discussion.
https://www.redhat.com/archives/virt-tools-list/2011-May/msg00019.html
L<https://www.redhat.com/archives/virt-tools-list/2011-May/msg00019.html>
=head1 Cloning a virtual machine (Windows)
@@ -57,8 +53,8 @@ straightforward. Currently there is code in the Aeolus Oz project
which does this (using libguestfs). As part of our review of the
virt-clone tool, we may add sysprepping ability.
https://github.com/clalancette/oz
https://www.redhat.com/archives/virt-tools-list/2011-May/msg00019.html
L<https://github.com/clalancette/oz>
L<https://www.redhat.com/archives/virt-tools-list/2011-May/msg00019.html>
=head1 Convert a CD-ROM / DVD / ISO to a tarball
@@ -75,7 +71,7 @@ To export just a subdirectory, eg. C</files>, do:
You can use the L<guestfish(1)> I<-N> option to create empty disk
images. The useful guide below explains the options available.
https://rwmj.wordpress.com/2010/09/08/new-guestfish-n-options-in-1-5-9/#content
L<https://rwmj.wordpress.com/2010/09/08/new-guestfish-n-options-in-1-5-9/#content>
=head1 Dump raw filesystem content from inside a disk image or VM
@@ -152,7 +148,7 @@ To get the output as a compressed tarball, do:
Although it sounds tempting, this is usually not a reliable way to get
a backup from a running guest. See the entry in the FAQ:
http://libguestfs.org/FAQ.html#backup
L<http://libguestfs.org/FAQ.html#backup>
=head1 Find out which user is using the most space
@@ -181,7 +177,7 @@ using the most space in their home directory:
The link below explains the many different possible techniques for
getting the last assigned DHCP address of a virtual machine.
https://rwmj.wordpress.com/2011/03/31/tip-code-for-getting-dhcp-address-from-a-virtual-machine-disk-image/#content
L<https://rwmj.wordpress.com/2011/03/31/tip-code-for-getting-dhcp-address-from-a-virtual-machine-disk-image/#content>
In the libguestfs source examples directory you will find the latest
version of the C<virt-dhcp-address.c> program.
@@ -217,7 +213,7 @@ language:
The link below contains a program to print the default boot kernel for
a Linux VM.
https://rwmj.wordpress.com/2010/10/30/tip-use-augeas-to-get-the-default-boot-kernel-for-a-vm/#content
L<https://rwmj.wordpress.com/2010/10/30/tip-use-augeas-to-get-the-default-boot-kernel-for-a-vm/#content>
It uses Augeas, and the technique is generally applicable for many
different tasks, such as:
@@ -246,7 +242,7 @@ listing who was logged in recently
=back
http://augeas.net/
L<http://augeas.net/>
=head1 Install RPMs in a guest
@@ -256,7 +252,7 @@ script that installs them next time the guest is booted. You could
use this technique to install vital security updates in an offline
guest.
https://rwmj.wordpress.com/2010/12/01/tip-install-rpms-in-a-guest/#content
L<https://rwmj.wordpress.com/2010/12/01/tip-install-rpms-in-a-guest/#content>
=head1 List applications installed in a VM
@@ -318,21 +314,21 @@ The link below contains a script that can be used to list out the
services from a Windows VM, and whether those services run at boot
time or are loaded on demand.
https://rwmj.wordpress.com/2010/12/10/tip-list-services-in-a-windows-guest/#content
L<https://rwmj.wordpress.com/2010/12/10/tip-list-services-in-a-windows-guest/#content>
=head1 Make a disk image sparse
The link below contains some guides for making a disk image sparse (or
reintroducing sparseness).
https://rwmj.wordpress.com/2010/10/19/tip-making-a-disk-image-sparse/#content
L<https://rwmj.wordpress.com/2010/10/19/tip-making-a-disk-image-sparse/#content>
=head1 Monitor disk usage over time
You can use L<virt-df(1)> to monitor disk usage of your guests over
time. The link below contains a guide.
http://virt-tools.org/learning/advanced-virt-df/
L<http://virt-tools.org/learning/advanced-virt-df/>
=head1 Reading the Windows Event Log from Windows Vista (or later)
@@ -340,7 +336,7 @@ L<guestfish(1)> plus the tools described in the link below can be used
to read out the Windows Event Log from any virtual machine running
Windows Vista or a later version.
https://rwmj.wordpress.com/2011/04/17/decoding-the-windows-event-log-using-guestfish/#content
L<https://rwmj.wordpress.com/2011/04/17/decoding-the-windows-event-log-using-guestfish/#content>
=head1 Remove root password (Linux)
@@ -356,7 +352,7 @@ password from a Windows VM, or to be more precise, it gives you a
command prompt the next time you log in which you can use to bypass
any security:
https://mdbooth.wordpress.com/2010/10/18/resetting-a-windows-guests-administrator-password-with-guestfish/
L<https://mdbooth.wordpress.com/2010/10/18/resetting-a-windows-guests-administrator-password-with-guestfish/>
=head1 Unpack a live CD
@@ -364,14 +360,14 @@ Linux live CDs often contain multiple layers of disk images wrapped
like a Russian doll. You can use L<guestfish(1)> to look inside these
multiple layers, as outlined in the guide below.
https://rwmj.wordpress.com/2009/07/15/unpack-the-russian-doll-of-a-f11-live-cd/#content
L<https://rwmj.wordpress.com/2009/07/15/unpack-the-russian-doll-of-a-f11-live-cd/#content>
=head1 Uploading and downloading files
The link below contains general tips on uploading (copying in)
and downloading (copying out) files from VMs.
https://rwmj.wordpress.com/2010/12/02/tip-uploading-and-downloading/#content
L<https://rwmj.wordpress.com/2010/12/02/tip-uploading-and-downloading/#content>
=head1 Use libguestfs tools on VMware ESX guests
@@ -379,7 +375,7 @@ The link below explains how to use libguestfs, L<guestfish(1)> and the
virt tools on any VMware ESX guests, by first sharing the VMware VMFS
over sshfs.
https://rwmj.wordpress.com/2011/05/10/tip-use-libguestfs-on-vmware-esx-guests/#content
L<https://rwmj.wordpress.com/2011/05/10/tip-use-libguestfs-on-vmware-esx-guests/#content>
=head1 SEE ALSO

View File

@@ -40,7 +40,7 @@ After a few runs, the time should settle down to a few seconds (under
How to check for hardware virt:
http://virt-tools.org/learning/check-hardware-virt/
L<http://virt-tools.org/learning/check-hardware-virt/>
If the command above does not work at all, use
L<libguestfs-test-tool(1)>.
@@ -135,8 +135,8 @@ Run:
Now try to load this into your favorite spreadsheet or database. Are
the results reproduced faithfully in the spreadsheet/database?
http://www.postgresql.org/docs/8.1/static/sql-copy.html
http://dev.mysql.com/doc/refman/5.1/en/load-data.html
L<http://www.postgresql.org/docs/8.1/static/sql-copy.html>
L<http://dev.mysql.com/doc/refman/5.1/en/load-data.html>
=head2 B<*> Edit a file in a B<shut off> guest.

206
examples/mount_local.c Normal file
View File

@@ -0,0 +1,206 @@
/* Demonstrate the use of the 'mount-local' API.
*
* Run this program as (eg) mount_local /tmp/test.img. Note that
* '/tmp/test.img' is created or overwritten. Follow the instructions
* on screen.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <guestfs.h>
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
/* Define a list of filesystem mount options (used on the libguestfs
* side, nothing to do with FUSE). An empty string may be used here
* instead.
*/
#define MOUNT_OPTIONS "acl,user_xattr"
/* Size of the disk (megabytes). */
#define SIZE_MB 512
static void
usage (void)
{
fprintf (stderr,
"Usage: mount_local disk.img\n"
"\n"
"NOTE: disk.img will be created or overwritten.\n"
"\n");
}
int
main (int argc, char *argv[])
{
guestfs_h *g;
int fd, r;
char tempdir[] = "/tmp/mlXXXXXX";
pid_t pid;
char *shell, *p;
guestfs_error_handler_cb old_error_cb;
void *old_error_data;
if (argc != 2) {
usage ();
exit (EXIT_FAILURE);
}
printf ("\n"
"This is the 'mount-local' demonstration program. Follow the\n"
"instructions on screen.\n"
"\n"
"Creating and formatting the disk image, please wait a moment ...\n");
fflush (stdout);
/* Create the output disk image: raw sparse. */
fd = open (argv[1], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
if (fd == -1) {
perror (argv[1]);
exit (EXIT_FAILURE);
}
if (ftruncate (fd, SIZE_MB * 1024 * 1024) == -1) {
perror ("truncate");
close (fd);
exit (EXIT_FAILURE);
}
if (close (fd) == -1) {
perror ("close");
exit (EXIT_FAILURE);
}
/* Guestfs handle. */
g = guestfs_create ();
if (g == NULL) {
perror ("could not create libguestfs handle");
exit (EXIT_FAILURE);
}
/* Create the disk image and format it with a partition and a filesystem. */
if (guestfs_add_drive_opts (g, argv[1],
GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
-1) == -1)
exit (EXIT_FAILURE);
if (guestfs_launch (g) == -1)
exit (EXIT_FAILURE);
if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1)
exit (EXIT_FAILURE);
if (guestfs_mkfs (g, "ext2", "/dev/sda1") == -1)
exit (EXIT_FAILURE);
/* Mount the empty filesystem. */
if (guestfs_mount_options (g, MOUNT_OPTIONS, "/dev/sda1", "/") == -1)
exit (EXIT_FAILURE);
/* Create a file in the new filesystem. */
if (guestfs_touch (g, "/PUT_FILES_AND_DIRECTORIES_HERE") == -1)
exit (EXIT_FAILURE);
/* Create a temporary mount directory. */
if (mkdtemp (tempdir) == NULL) {
perror ("mkdtemp");
exit (EXIT_FAILURE);
}
/* Mount the filesystem. */
if (guestfs_mount_local (g, tempdir, -1) == -1)
exit (EXIT_FAILURE);
/* Fork the shell for the user. */
pid = fork ();
if (pid == -1) {
perror ("fork");
exit (EXIT_FAILURE);
}
if (pid == 0) { /* Child. */
if (chdir (tempdir) == -1) {
perror (tempdir);
_exit (EXIT_FAILURE);
}
printf ("\n"
"The _current directory_ is a FUSE filesystem backed by the disk\n"
"image which is managed by libguestfs. Any files or directories\n"
"you copy into here (up to %d MB) will be saved into the disk\n"
"image. You can also delete files, create certain special files\n"
"and so on.\n"
"\n"
"When you have finished adding files, hit ^D or exit to exit the\n"
"shell and return to the mount-local program.\n"
"\n",
SIZE_MB);
shell = getenv ("SHELL");
if (!shell)
r = system ("/bin/sh");
else {
/* Set a magic prompt. We only know how to do this for bash. */
p = strrchr (shell, '/');
if (p && strcmp (p+1, "bash") == 0) {
size_t len = 64 + strlen (shell);
char buf[len];
snprintf (buf, len, "PS1='mount-local-shell> ' %s --norc -i", shell);
r = system (buf);
} else
r = system (shell);
}
if (r == -1) {
fprintf (stderr, "error: failed to run sub-shell (%s) "
"(is $SHELL set correctly?)\n",
shell);
//FALLTHROUGH
}
chdir ("/");
guestfs_umount_local (g, GUESTFS_UMOUNT_LOCAL_RETRY, 1, -1);
_exit (EXIT_SUCCESS);
}
/* Note that we are *not* waiting for the child yet. We want to
* run the FUSE code in parallel with the subshell.
*/
/* We're going to hide libguestfs errors here, but in a real program
* you would probably want to log them somewhere.
*/
old_error_cb = guestfs_get_error_handler (g, &old_error_data);
guestfs_set_error_handler (g, NULL, NULL);
/* Now run the FUSE thread. */
if (guestfs_mount_local_run (g) == -1)
exit (EXIT_FAILURE);
guestfs_set_error_handler (g, old_error_cb, old_error_data);
waitpid (pid, NULL, 0);
/* Shutdown the handle explicitly so write errors can be detected. */
if (guestfs_shutdown (g) == -1)
exit (EXIT_FAILURE);
guestfs_close (g);
printf ("\n"
"Any files or directories that you copied in have been saved into\n"
"the disk image called '%s'.\n"
"\n"
"Try opening the disk image with guestfish to see those files:\n"
"\n"
" guestfish -a %s -m /dev/sda1\n"
"\n",
argv[1], argv[1]);
exit (EXIT_SUCCESS);
}

View File

@@ -169,7 +169,9 @@ print_dhcp_address_linux (guestfs_h *g, char *root, const char *logfile)
char **lines, *p;
size_t len;
lines = guestfs_egrep (g, "dhclient.*: bound to ", logfile);
lines = guestfs_grep_opts (g, "dhclient.*: bound to ", logfile,
GUESTFS_GREP_OPTS_EXTENDED, 1,
-1);
if (lines == NULL)
exit (EXIT_FAILURE);

View File

@@ -28,7 +28,7 @@ bin_PROGRAMS = guestfish
generator_built = \
cmds.c \
cmds_gperf.gperf \
cmds-gperf.gperf \
completion.c \
event-names.c \
fish-cmds.h \
@@ -39,7 +39,7 @@ generator_built = \
BUILT_SOURCES = \
$(generator_built) \
cmds_gperf.c \
cmds-gperf.c \
rc_protocol.h \
rc_protocol.c
@@ -64,19 +64,19 @@ EXTRA_DIST = \
# files must not include other guestfish files.
SHARED_SOURCE_FILES = \
config.c \
domain.c \
inspect.c \
keys.c \
options.h \
options.c \
progress.h \
progress.c \
virt.c
progress.c
guestfish_SOURCES = \
$(generator_built) \
$(SHARED_SOURCE_FILES) \
alloc.c \
cmds_gperf.h \
cmds-gperf.h \
copy.c \
destpaths.c \
display.c \
@@ -92,11 +92,11 @@ guestfish_SOURCES = \
man.c \
more.c \
prep.c \
prep_disk.c \
prep_part.c \
prep_fs.c \
prep_lv.c \
prep_boot.c \
prep-disk.c \
prep-part.c \
prep-fs.c \
prep-lv.c \
prep-boot.c \
rc.c \
reopen.c \
setenv.c \
@@ -111,10 +111,10 @@ librc_protocol_la_CFLAGS = -Wall -Wno-unused -fno-strict-aliasing
# Build the command lookup perfect hash code. The generated code has
# lots of warnings so we must compile it in a separate mini-library.
libcmds_la_SOURCES = cmds_gperf.c
libcmds_la_SOURCES = cmds-gperf.c
libcmds_la_CFLAGS =
cmds_gperf.c: cmds_gperf.gperf
cmds-gperf.c: cmds-gperf.gperf
rm -f $@
$(GPERF) -t $< > $@-t
mv $@-t $@
@@ -138,16 +138,25 @@ noinst_LTLIBRARIES = libcmds.la librc_protocol.la
guestfish_LDADD += libcmds.la librc_protocol.la ../gnulib/lib/libgnu.la
if HAVE_RPCGEN
RPCGEN_DEFS =
if HAVE_XDR_U_INT64_T
RPCGEN_DEFS += -DHAVE_XDR_U_INT64_T=1
else
if HAVE_XDR_UINT64_T
RPCGEN_DEFS += -DHAVE_XDR_UINT64_T=1
endif
endif
rc_protocol.c: rc_protocol.x
rm -f $@-t $@-t2
$(RPCGEN) -c -o $@-t $<
$(RPCGEN) $(RPCGEN_DEFS) -c -o $@-t $<
sed 's,\.\./\(\.\./\)*fish,.,' < $@-t > $@-t2
rm $@-t
mv $@-t2 $@
rc_protocol.h: rc_protocol.x
rm -f $@-t
$(RPCGEN) -h -o $@-t $<
$(RPCGEN) $(RPCGEN_DEFS) -h -o $@-t $<
mv $@-t $@
endif
@@ -173,7 +182,7 @@ noinst_DATA = \
guestfish.1 $(top_builddir)/html/guestfish.1.html: stamp-guestfish.pod
stamp-guestfish.pod: guestfish.pod guestfish-actions.pod guestfish-commands.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man guestfish.1 \
--html $(top_builddir)/html/guestfish.1.html \
--insert $(srcdir)/guestfish-actions.pod:@ACTIONS@ \
@@ -184,7 +193,7 @@ stamp-guestfish.pod: guestfish.pod guestfish-actions.pod guestfish-commands.pod
virt-copy-in.1 $(top_builddir)/html/virt-copy-in.1.html: stamp-virt-copy-in.pod
stamp-virt-copy-in.pod: virt-copy-in.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man virt-copy-in.1 \
--html $(top_builddir)/html/virt-copy-in.1.html \
$<
@@ -193,7 +202,7 @@ stamp-virt-copy-in.pod: virt-copy-in.pod
virt-copy-out.1 $(top_builddir)/html/virt-copy-out.1.html: stamp-virt-copy-out.pod
stamp-virt-copy-out.pod: virt-copy-out.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man virt-copy-out.1 \
--html $(top_builddir)/html/virt-copy-out.1.html \
$<
@@ -202,7 +211,7 @@ stamp-virt-copy-out.pod: virt-copy-out.pod
virt-tar-in.1 $(top_builddir)/html/virt-tar-in.1.html: stamp-virt-tar-in.pod
stamp-virt-tar-in.pod: virt-tar-in.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man virt-tar-in.1 \
--html $(top_builddir)/html/virt-tar-in.1.html \
$<
@@ -211,7 +220,7 @@ stamp-virt-tar-in.pod: virt-tar-in.pod
virt-tar-out.1 $(top_builddir)/html/virt-tar-out.1.html: stamp-virt-tar-out.pod
stamp-virt-tar-out.pod: virt-tar-out.pod
$(top_builddir)/podwrapper.sh \
$(PODWRAPPER) \
--man virt-tar-out.1 \
--html $(top_builddir)/html/virt-tar-out.1.html \
$<
@@ -229,11 +238,7 @@ bashcompletion_DATA = guestfish-bash-completion.sh
# Tests.
random_val := $(shell awk 'BEGIN{srand(); print 1+int(255*rand())}' < /dev/null)
TESTS_ENVIRONMENT = \
MALLOC_PERTURB_=$(random_val) \
$(top_builddir)/run
TESTS_ENVIRONMENT = $(top_builddir)/run --test
TESTS = \
test-a.sh \
@@ -248,8 +253,9 @@ TESTS += \
test-copy.sh \
test-edit.sh \
test-find0.sh \
test-glob.sh \
test-mount-local.sh \
test-read_file.sh \
test-read-file.sh \
test-remote.sh \
test-reopen.sh \
test-stringlist.sh \
@@ -265,8 +271,9 @@ EXTRA_DIST += \
test-escapes.sh \
test-events.sh \
test-find0.sh \
test-glob.sh \
test-mount-local.sh \
test-read_file.sh \
test-read-file.sh \
test-remote.sh \
test-reopen.sh \
test-stringlist.sh \

View File

@@ -25,6 +25,7 @@
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <libintl.h>
#include "xstrtol.h"

View File

@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#ifdef HAVE_LIBCONFIG
#include <libconfig.h>

View File

@@ -23,6 +23,7 @@
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <libintl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>

View File

@@ -24,6 +24,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libintl.h>
#include <sys/types.h>
#include <sys/stat.h>

View File

@@ -24,6 +24,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libintl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
@@ -32,7 +33,6 @@
static char *generate_random_name (const char *filename);
static int copy_attributes (const char *src, const char *dest);
static int feature_available (guestfs_h *g, const char *feature);
/* guestfish edit command, suggested by Ján Ondrej, implemented by RWMJ */
@@ -241,22 +241,3 @@ copy_attributes (const char *src, const char *dest)
return 0;
}
static int
feature_available (guestfs_h *g, const char *feature)
{
/* If there's an error we should ignore it, so to do that we have to
* temporarily replace the error handler with a null one.
*/
guestfs_error_handler_cb old_error_cb;
void *old_error_data;
old_error_cb = guestfs_get_error_handler (g, &old_error_data);
guestfs_set_error_handler (g, NULL, NULL);
const char *groups[] = { feature, NULL };
int r = guestfs_available (g, (char * const *) groups);
guestfs_set_error_handler (g, old_error_cb, old_error_data);
return r == 0 ? 1 : 0;
}

View File

@@ -23,6 +23,7 @@
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <libintl.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

View File

@@ -30,6 +30,7 @@
#include <sys/wait.h>
#include <locale.h>
#include <langinfo.h>
#include <libintl.h>
#ifdef HAVE_LIBREADLINE
#include <readline/readline.h>
@@ -73,6 +74,7 @@ static void add_history_line (const char *);
static int override_progress_bars = -1;
static struct progress_bar *bar = NULL;
static int pipe_error = 0;
/* Currently open libguestfs handle. */
guestfs_h *g = NULL;
@@ -125,6 +127,7 @@ usage (int status)
" -m|--mount dev[:mnt[:opts]] Mount dev on mnt (if omitted, /)\n"
" -n|--no-sync Don't autosync\n"
" -N|--new type Create prepared disk (test1.img, ...)\n"
" --pipe-error Pipe commands can detect write errors\n"
" --progress-bars Enable progress bars even when not interactive\n"
" --no-progress-bars Disable progress bars\n"
" --remote[=pid] Send commands to remote %s\n"
@@ -157,6 +160,7 @@ main (int argc, char *argv[])
/* Set global program name that is not polluted with libtool artifacts. */
set_program_name (argv[0]);
/* Initialize gnulib closeout module. */
atexit (close_stdout);
setlocale (LC_ALL, "");
@@ -189,6 +193,7 @@ main (int argc, char *argv[])
{ "new", 1, 0, 'N' },
{ "no-dest-paths", 0, 0, 'D' },
{ "no-sync", 0, 0, 'n' },
{ "pipe-error", 0, 0, 0 },
{ "progress-bars", 0, 0, 0 },
{ "no-progress-bars", 0, 0, 0 },
{ "remote", 2, 0, 0 },
@@ -279,6 +284,8 @@ main (int argc, char *argv[])
remote_control_csh = 1;
} else if (STREQ (long_options[option_index].name, "live")) {
live = 1;
} else if (STREQ (long_options[option_index].name, "pipe-error")) {
pipe_error = 1;
} else {
fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
program_name, long_options[option_index].name, option_index);
@@ -546,6 +553,9 @@ main (int argc, char *argv[])
else
cmdline (argv, optind, argc);
if (guestfs_shutdown (g) == -1)
exit (EXIT_FAILURE);
guestfs_close (g);
out_after_handle_close:
@@ -1128,6 +1138,15 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd,
perror ("failed to flush standard output");
return -1;
}
if (ferror (stdout)) {
if (!pipecmd || pipe_error) {
fprintf (stderr, "%s: write error%s\n", program_name,
pipecmd ? " on pipe" : "");
r = -1;
}
/* We've dealt with this error, so clear the flag. */
clearerr (stdout);
}
if (pipecmd) {
close (1);
@@ -1436,7 +1455,7 @@ cleanup_readline (void)
int fd;
if (histfile[0] != '\0') {
fd = open (histfile, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0644);
fd = open (histfile, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0600);
if (fd == -1) {
perror (histfile);
return;
@@ -1774,3 +1793,22 @@ progress_callback (guestfs_h *g, void *data,
progress_bar_set (bar, position, total);
}
int
feature_available (guestfs_h *g, const char *feature)
{
/* If there's an error we should ignore it, so to do that we have to
* temporarily replace the error handler with a null one.
*/
guestfs_error_handler_cb old_error_cb;
void *old_error_data;
old_error_cb = guestfs_get_error_handler (g, &old_error_data);
guestfs_set_error_handler (g, NULL, NULL);
const char *groups[] = { feature, NULL };
int r = guestfs_available (g, (char * const *) groups);
guestfs_set_error_handler (g, old_error_cb, old_error_data);
return r == 0 ? 1 : 0;
}

View File

@@ -31,21 +31,8 @@
#define SOCK_CLOEXEC 0
#endif
#ifdef HAVE_GETTEXT
#include "gettext.h"
#define _(str) dgettext(PACKAGE, (str))
#define N_(str) dgettext(PACKAGE, (str))
#else
#define _(str) str
#define N_(str) str
#endif
#if !ENABLE_NLS
#undef textdomain
#define textdomain(Domainname) /* empty */
#undef bindtextdomain
#define bindtextdomain(Domainname, Dirname) /* empty */
#endif
#define STREQ(a,b) (strcmp((a),(b)) == 0)
#define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
@@ -89,6 +76,7 @@ extern void free_file_in (char *s);
extern char *file_out (const char *arg);
extern void extended_help_message (void);
extern void progress_callback (guestfs_h *g, void *data, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len);
extern int feature_available (guestfs_h *g, const char *feature);
/* in cmds.c (auto-generated) */
extern void list_commands (void);

View File

@@ -22,12 +22,21 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fnmatch.h>
#include <libintl.h>
#include "fish.h"
/* A bit tricky because in the case where there are multiple
* paths we have to perform a Cartesian product.
*/
static char **expand_pathname (guestfs_h *g, const char *path);
static char **expand_devicename (guestfs_h *g, const char *device);
static int add_strings_matching (char **pp, const char *glob, char ***ret, size_t *size_r);
static int add_string (const char *str, char ***ret, size_t *size_r);
static char **single_element_list (const char *element);
static void glob_issue (char *cmd, size_t argc, char ***globs, size_t *posn, size_t *count, int *r);
int
@@ -66,52 +75,31 @@ run_glob (const char *cmd, size_t argc, char *argv[])
for (i = 1; i < argc; ++i) {
char **pp;
/* Only if it begins with '/' can it possibly be a globbable path. */
if (argv[i][0] == '/') {
pp = guestfs_glob_expand (g, argv[i]);
if (pp == NULL) { /* real error in glob_expand */
fprintf (stderr, _("glob: guestfs_glob_expand call failed: %s\n"),
argv[i]);
goto error0;
/* If it begins with "/dev/" then treat it as a globbable device
* name.
*/
if (STRPREFIX (argv[i], "/dev/")) {
pp = expand_devicename (g, argv[i]);
if (pp == NULL) {
r = -1;
goto error;
}
/* If there were no matches, then we add a single element list
* containing just the original argv[i] string.
*/
if (pp[0] == NULL) {
char **pp2;
pp2 = realloc (pp, sizeof (char *) * 2);
if (pp2 == NULL) {
perror ("realloc");
free (pp);
goto error0;
}
pp = pp2;
pp[0] = strdup (argv[i]);
if (pp[0] == NULL) {
perror ("strdup");
free (pp);
goto error0;
}
pp[1] = NULL;
}
/* If it begins with "/" it might be a globbable pathname. */
else if (argv[i][0] == '/') {
pp = expand_pathname (g, argv[i]);
if (pp == NULL) {
r = -1;
goto error;
}
}
/* Doesn't begin with '/' */
else {
pp = malloc (sizeof (char *) * 2);
pp = single_element_list (argv[i]);
if (pp == NULL) {
perror ("malloc");
goto error0;
r = -1;
goto error;
}
pp[0] = strdup (argv[i]);
if (pp[0] == NULL) {
perror ("strdup");
free (pp);
goto error0;
}
pp[1] = NULL;
}
globs[i] = pp;
@@ -122,13 +110,180 @@ run_glob (const char *cmd, size_t argc, char *argv[])
glob_issue (argv[0], argc, globs, posn, count, &r);
/* Free resources. */
error0:
error:
for (i = 1; i < argc; ++i)
if (globs[i])
free_strings (globs[i]);
return r;
}
static char **
expand_pathname (guestfs_h *g, const char *path)
{
char **pp;
pp = guestfs_glob_expand (g, path);
if (pp == NULL) { /* real error in glob_expand */
fprintf (stderr, _("glob: guestfs_glob_expand call failed: %s\n"), path);
return NULL;
}
if (pp[0] != NULL)
return pp; /* Return the non-empty list of matches. */
/* If there were no matches, then we add a single element list
* containing just the original string.
*/
free (pp);
return single_element_list (path);
}
/* Glob-expand device patterns, such as "/dev/sd*" (RHBZ#635971).
*
* There is no 'guestfs_glob_expand_device' function because the
* equivalent can be implemented using functions like
* 'guestfs_list_devices'.
*
* It's not immediately clear what it means to expand a pattern like
* "/dev/sd*". Should that include device name translation? Should
* the result include partitions as well as devices?
*
* Should "/dev/" + "*" return every possible device and filesystem?
* How about VGs? LVs?
*
* To solve this what we do is build up a list of every device,
* partition, etc., then glob against that list.
*
* Notes for future work (XXX):
* - This doesn't handle device name translation. It wouldn't be
* too hard to add.
* - Could have an API function for returning all device-like things.
*/
static char **
expand_devicename (guestfs_h *g, const char *device)
{
char **pp = NULL;
char **ret = NULL;
size_t size = 0;
pp = guestfs_list_devices (g);
if (pp == NULL) goto error;
if (add_strings_matching (pp, device, &ret, &size) == -1) goto error;
free_strings (pp);
pp = guestfs_list_partitions (g);
if (pp == NULL) goto error;
if (add_strings_matching (pp, device, &ret, &size) == -1) goto error;
free_strings (pp);
pp = guestfs_list_md_devices (g);
if (pp == NULL) goto error;
if (add_strings_matching (pp, device, &ret, &size) == -1) goto error;
free_strings (pp);
if (feature_available (g, "lvm2")) {
pp = guestfs_lvs (g);
if (pp == NULL) goto error;
if (add_strings_matching (pp, device, &ret, &size) == -1) goto error;
free_strings (pp);
pp = NULL;
}
/* None matched? Add the original glob pattern. */
if (ret == NULL)
ret = single_element_list (device);
return ret;
error:
if (pp)
free_strings (pp);
if (ret)
free_strings (ret);
return NULL;
}
/* Using fnmatch, find strings in the list 'pp' which match pattern
* 'glob'. Add strings which match to the 'ret' array. '*size_r' is
* the current size of the 'ret' array, which is updated with the new
* size.
*/
static int
add_strings_matching (char **pp, const char *glob,
char ***ret, size_t *size_r)
{
size_t i;
int r;
for (i = 0; pp[i] != NULL; ++i) {
errno = 0;
r = fnmatch (glob, pp[i], FNM_PATHNAME);
if (r == 0) { /* matches - add it */
if (add_string (pp[i], ret, size_r) == -1)
return -1;
}
else if (r != FNM_NOMATCH) { /* error */
/* I checked the glibc impl and it returns random negative
* numbers for errors. It doesn't always set errno. Do our
* best here to record the error state.
*/
fprintf (stderr, "glob: fnmatch: error (r = %d, errno = %d)\n",
r, errno);
return -1;
}
}
return 0;
}
static int
add_string (const char *str, char ***ret, size_t *size_r)
{
char **new_ret = *ret;
size_t size = *size_r;
new_ret = realloc (new_ret, (size + 2) * (sizeof (char *)));
if (!new_ret) {
perror ("realloc");
return -1;
}
*ret = new_ret;
new_ret[size] = strdup (str);
if (new_ret[size] == NULL) {
perror ("strdup");
return -1;
}
size++;
new_ret[size] = NULL;
*size_r = size;
return 0;
}
/* Return a single element list containing 'element'. */
static char **
single_element_list (const char *element)
{
char **pp;
pp = malloc (sizeof (char *) * 2);
if (pp == NULL) {
perror ("malloc");
return NULL;
}
pp[0] = strdup (element);
if (pp[0] == NULL) {
perror ("strdup");
free (pp);
return NULL;
}
pp[1] = NULL;
return pp;
}
static void
glob_issue (char *cmd, size_t argc,
char ***globs, size_t *posn, size_t *count,

View File

@@ -253,7 +253,7 @@ auto-detection for C<another.img>.
If you have untrusted raw-format guest disk images, you should use
this option to specify the disk format. This avoids a possible
security problem with malicious guests (CVE-2010-3851). See also
L</add-drive-opts>.
L</add>.
=item B<-i>
@@ -350,6 +350,18 @@ alternative to the I<-a> option: whereas I<-a> adds an existing disk,
I<-N> creates a preformatted disk with a filesystem and adds it.
See L</PREPARED DISK IMAGES> below.
=item B<--pipe-error>
If writes fail to pipe commands (see L</PIPES> below), then the
command returns an error.
The default (also for historical reasons) is to ignore such errors so
that:
><fs> command_with_lots_of_output | head
doesn't give an error.
=item B<--progress-bars>
Enable progress bars, even when guestfish is used non-interactively.
@@ -582,11 +594,11 @@ Some commands take optional arguments. These arguments appear in this
documentation as C<[argname:..]>. You can use them as in these
examples:
add-drive-opts filename
add filename
add-drive-opts filename readonly:true
add filename readonly:true
add-drive-opts filename format:qcow2 readonly:false
add filename format:qcow2 readonly:false
Each optional argument can appear at most once. All optional
arguments must appear after the required ones.
@@ -1161,6 +1173,11 @@ home directory can be used. See L</FILES>.
Pass additional options to the guest kernel.
=item LIBGUESTFS_ATTACH_METHOD
Choose the default way to create the appliance. See
L<guestfs(3)/guestfs_set_attach_method>.
=item LIBGUESTFS_DEBUG
Set C<LIBGUESTFS_DEBUG=1> to enable verbose messages. This has the

View File

@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include "fish.h"

View File

@@ -24,6 +24,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libintl.h>
#include <sys/types.h>
#include <sys/stat.h>

View File

@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#include "c-ctype.h"

View File

@@ -23,6 +23,7 @@
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <libintl.h>
#include "guestfs.h"

View File

@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include "fish.h"

View File

@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <libintl.h>
#include <sys/wait.h>
#include "fish.h"

View File

@@ -24,6 +24,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libintl.h>
#include "fish.h"

View File

@@ -20,6 +20,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#include "c-ctype.h"
@@ -102,8 +104,7 @@ add_drives (struct drv *drv, char next_drive)
return next_drive;
}
static void display_mountpoints_on_failure (const char *mp_device);
static void canonical_device_name (char *dev);
static void display_mountpoints_on_failure (const char *mp_device, const char *user_supplied_options);
/* List is built in reverse order, so mount them in reverse order. */
void
@@ -122,13 +123,9 @@ mount_mps (struct mp *mp)
else
options = "";
/* Don't use guestfs_mount here because that will default to mount
* options -o sync,noatime. For more information, see guestfs(3)
* section "LIBGUESTFS GOTCHAS".
*/
r = guestfs_mount_options (g, options, mp->device, mp->mountpoint);
if (r == -1) {
display_mountpoints_on_failure (mp->device);
display_mountpoints_on_failure (mp->device, mp->options);
exit (EXIT_FAILURE);
}
}
@@ -138,9 +135,10 @@ mount_mps (struct mp *mp)
* message listing the mountpoints.
*/
static void
display_mountpoints_on_failure (const char *mp_device)
display_mountpoints_on_failure (const char *mp_device,
const char *user_supplied_options)
{
char **fses;
char **fses, *p;
size_t i;
fses = guestfs_list_filesystems (g);
@@ -151,13 +149,22 @@ display_mountpoints_on_failure (const char *mp_device)
return;
}
fprintf (stderr,
_("%s: '%s' could not be mounted. Did you mean one of these?\n"),
fprintf (stderr, _("%s: '%s' could not be mounted.\n"),
program_name, mp_device);
if (user_supplied_options)
fprintf (stderr, _("%s: Check mount(8) man page to ensure options '%s'\n"
"%s: are supported by the filesystem that is being mounted.\n"),
program_name, user_supplied_options, program_name);
fprintf (stderr, _("%s: Did you mean to mount one of these filesystems?\n"),
program_name);
for (i = 0; fses[i] != NULL; i += 2) {
canonical_device_name (fses[i]);
fprintf (stderr, "\t%s (%s)\n", fses[i], fses[i+1]);
p = guestfs_canonical_device_name (g, fses[i]);
fprintf (stderr, "%s: \t%s (%s)\n", program_name,
p ? p : fses[i], fses[i+1]);
free (p);
free (fses[i]);
free (fses[i+1]);
}
@@ -165,17 +172,6 @@ display_mountpoints_on_failure (const char *mp_device)
free (fses);
}
static void
canonical_device_name (char *dev)
{
if (STRPREFIX (dev, "/dev/") &&
(dev[5] == 'h' || dev[5] == 'v') &&
dev[6] == 'd' &&
c_isalpha (dev[7]) &&
(c_isdigit (dev[8]) || dev[8] == '\0'))
dev[5] = 's';
}
void
free_drives (struct drv *drv)
{

View File

@@ -19,22 +19,12 @@
#ifndef OPTIONS_H
#define OPTIONS_H
#ifdef HAVE_GETTEXT
#include "gettext.h"
#ifndef _
#define _(str) dgettext(PACKAGE, (str))
#endif
#ifndef N_
#define N_(str) dgettext(PACKAGE, (str))
#endif
#else
#ifndef _
#define _(str) str
#endif
#ifndef _
#define N_(str) str
#endif
#endif
#ifndef STREQ
#define STREQ(a,b) (strcmp((a),(b)) == 0)
@@ -105,6 +95,11 @@ struct drv {
void (*data_free)(void*); /* function to free 'data' */
} N;
};
/* Opaque pointer. Not used by the options-parsing code, and so
* available for the program to use for any purpose.
*/
void *opaque;
};
struct mp {

View File

@@ -23,6 +23,7 @@
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include "fish.h"
#include "prepopts.h"

View File

@@ -23,6 +23,7 @@
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include "fish.h"
#include "prepopts.h"

View File

@@ -23,6 +23,7 @@
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include "fish.h"
#include "prepopts.h"

View File

@@ -23,6 +23,7 @@
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include "fish.h"
#include "prepopts.h"

View File

@@ -23,6 +23,7 @@
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include "fish.h"
#include "prepopts.h"

View File

@@ -23,6 +23,7 @@
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include "fish.h"
#include "prepopts.h"

View File

@@ -23,6 +23,7 @@
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <libintl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>

View File

@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include "fish.h"
@@ -39,6 +40,9 @@ run_reopen (const char *cmd, size_t argc, char *argv[])
return -1;
}
if (guestfs_shutdown (g) == -1)
return -1;
/* Open the new handle first, so we can copy the settings from the
* old one to the new one, and also so if it fails we still have an
* open handle.

View File

@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#include "fish.h"

View File

@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include "fish.h"

Some files were not shown because too many files have changed in this diff Show More