Compare commits

...

624 Commits

Author SHA1 Message Date
Richard W.M. Jones
34b106c391 Version 1.21.36. 2013-05-02 14:28:00 +01:00
Richard W.M. Jones
333337b6a9 debian: Add OCaml .depend files to DISTCLEANFILES.
Otherwise debuild complains that these files have been created after
it does a 'make distclean'.
2013-05-02 13:18:12 +01:00
Richard W.M. Jones
5faba45fe1 tests/c-api: Various code refactorings.
- Don't use fixed names for the disks.  This will allow us to
  parallelize this test.

- Add a new "GETKEY:<key>" String parameter which can retrieve keys
  from the handle.  The temporary disk names are stored as keys.

- Don't test the close callback.  However this uses the close callback
  mechanism to delete the temporary disks, and in any case close
  callbacks are well tested by the language binding tests.

- The generated code now produces a static array of tests (instead of
  a 'perform_tests' function), making it possible to parallelize.
2013-05-01 11:13:31 +01:00
Richard W.M. Jones
f003c50c52 tests/c-api: Remove global guestfs handle.
This will allow us to parallelize these tests.
2013-05-01 09:34:39 +01:00
Richard W.M. Jones
76950a0e8d tests/c-api: Warn about deprecated functions in main program.
And replace deprecated guestfs_set_close_callback with
non-deprecated guestfs_set_event_callback.
2013-05-01 09:33:51 +01:00
Richard W.M. Jones
9d5236d73c tests/c-api: Factor out common init_* into separate functions. 2013-05-01 09:09:55 +01:00
Richard W.M. Jones
02fbf566e8 java: Standardize Java test numbering. 2013-05-01 08:38:40 +01:00
Mike Kelly
ad1e9e7eac ssh: fix setting the username part
Right now, we'd always be setting a NULL username.
2013-04-30 22:32:43 +01:00
Richard W.M. Jones
3c43019f8d ruby: Standardize test names and numbering. 2013-04-30 17:47:11 +01:00
Richard W.M. Jones
a24639d7d3 python: Standardize test numbering. 2013-04-30 17:34:22 +01:00
Richard W.M. Jones
897a69604d perl: Make the 030-create-flags test same as canonical OCaml version. 2013-04-30 15:42:31 +01:00
Richard W.M. Jones
dc3b783b51 ocaml: Set close-on-exit flag to true in this test so handle is cleaned up.
Otherwise the valgrind test fails since the handle resources
are leaked.
2013-04-30 15:41:08 +01:00
Richard W.M. Jones
a2a6cfba56 Version 1.21.35. 2013-04-30 15:08:58 +01:00
Richard W.M. Jones
1623f540b1 erlang: Make separated builds work correctly.
Set ERL_LIBS and also create a phony 'ebin' directory for the
guestfs.beam (library) so that the tests run against the local copy
not the installed version, and so that separated builds work.
2013-04-30 13:54:15 +01:00
Richard W.M. Jones
327403f3ac erlang: Add a CLEANFILES rule. 2013-04-30 13:54:15 +01:00
Richard W.M. Jones
d9f5829ebe python: Fix for separated builds.
Ensure that ./run sets PYTHONPATH to include the Python source
directory (location of guestfs.py).
2013-04-30 13:54:14 +01:00
Richard W.M. Jones
4ea016dae9 perl: Fix build and test to work with separated builds.
This is inspired largely by Hilko Bengen's equivalent
hivex patch here:

887466794a
2013-04-30 13:54:14 +01:00
Richard W.M. Jones
440183b440 perl: run-bindtests: Don't set PERL5LIB.
This environment variable should already be set properly
by 'run', there is no need to set it from this test script.
2013-04-30 12:52:44 +01:00
Richard W.M. Jones
21dd1c50c9 ./run: Set s= (srcdir). Use absolute paths. 2013-04-30 12:50:25 +01:00
Richard W.M. Jones
93e64b4448 tests/mountable: Fix incorrect use of inspect-os API (RHBZ#957380). 2013-04-29 19:25:14 +01:00
Mike Kelly
4e5ed8ff7b Make a 1G test image instead, avoiding a size bug
mkfs_btrfs: /dev/vda2: device /dev/vda2 is too small (must be at least
256 MB) at .../libguestfs/tests/guests/guest-aux/make-fedora-img.pl line
140.
2013-04-29 18:00:49 +01:00
Mike Kelly
0da34f968c Refactor image partition sizing 2013-04-29 18:00:49 +01:00
Richard W.M. Jones
852beefc4c Version 1.21.34. 2013-04-29 16:41:06 +01:00
Richard W.M. Jones
d02af3a311 perl: Almost standardize the Perl tests.
This needs more work, but brings them mostly up to the same
standard form as the OCaml tests and the test documentation.
2013-04-29 16:10:49 +01:00
Richard W.M. Jones
f82a9dbf0f ocaml: Standardize the test sequence for all bindings; implement this for OCaml.
The idea behind this change is to have a consistent set of
tests across all bindings, while at the same time saving time.
For background see:

https://www.redhat.com/archives/libguestfs/2013-April/thread.html#00069
2013-04-29 15:57:25 +01:00
Richard W.M. Jones
cc93840d31 tests: Add a regression test for RHBZ#957772. 2013-04-29 15:28:13 +01:00
Richard W.M. Jones
c5f356a603 daemon: Properly quote arguments for tar-out, base64-out commands (RHBZ#957772).
This fixes commit c78ec7e085
which was an attempt to fix RHBZ#908322.
2013-04-29 15:27:21 +01:00
Richard W.M. Jones
79688aff74 ./run: ruby: Set $RAKE and fix Ruby tests.
This wasn't set which caused Ruby tests to silently not run
without any indication.
2013-04-25 20:10:37 +01:00
Richard W.M. Jones
0d989d52a6 ruby: Fix segfault in regression test.
This was revealed by the regression test for RHBZ#664558.
Unfortunately because Ruby tests had been silently disabled,
this regression test was never run.
2013-04-25 20:10:34 +01:00
Richard W.M. Jones
2ea9d82a23 ruby: Fix optargs test. 2013-04-25 20:10:34 +01:00
Richard W.M. Jones
cd4c2c6caa Version 1.21.33. 2013-04-25 14:59:19 +01:00
Richard W.M. Jones
a30b41f735 tools: The programs are located in the source directory. 2013-04-25 14:21:55 +01:00
Richard W.M. Jones
9e9be1cee7 python: Test programs are located in the source directory. 2013-04-25 14:21:55 +01:00
Richard W.M. Jones
a9c81f1919 fish: Add $srcdir in several places where test files exist in the source directory. 2013-04-25 14:21:55 +01:00
Richard W.M. Jones
7af69445f2 tests/rsync: This test only copies generated files. 2013-04-25 14:21:55 +01:00
Richard W.M. Jones
5057a8f344 tests: Add $srcdir in several places for test files located in source directory. 2013-04-25 14:21:55 +01:00
Richard W.M. Jones
073da79e5b tests/xml: Get XML data file from source directory. 2013-04-25 14:21:55 +01:00
Richard W.M. Jones
423a2d9dde tests/btrfs: Get data files from source directory. 2013-04-25 14:21:55 +01:00
Richard W.M. Jones
59b9ee181b tests/selinux: Pick up run-test.pl script from source directory. 2013-04-25 14:21:55 +01:00
Richard W.M. Jones
86025d33a8 tests/guests: Various fixes for separated builds.
This now correctly builds all the phony guests when
builddir != srcdir.
2013-04-25 14:21:55 +01:00
Richard W.M. Jones
5d6a08e2c8 tests/guests: Don't include fake Windows binary hive files in git.
This means that people compiling from git will be required to have the
'hivexregedit' command (from hivex).
2013-04-25 14:21:51 +01:00
Richard W.M. Jones
c0d1a74023 tests/guests: Ensure hard to generate files are cleaned by 'make distclean'.
This allows us to switch from non-separated to separated builds
without breaking (the user must do 'make distclean' between the
switch).
2013-04-25 12:33:31 +01:00
Richard W.M. Jones
c3bf39a1f9 perl: Fix 'make check' to find bindtests.pl in source directory.
Despite this change, separated builds are still broken, apparently
because ExtUtils::MakeMaker doesn't support this sort of
configuration, or else we're using it wrong.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
b7da435003 tests/c-api: Allow FileIn paths to be prefixed by "$srcdir".
Since tests involving FileIn will often wish to read from local files,
it makes sense that they would want to open files in $srcdir.

Therefore allow such paths to be prefixed by "$srcdir" which is
substituted at run time by the same named environment variable (set by
automake).

This fixes separated builds in tests/c-api directory.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
a1e51676fd Remove many uses of $(builddir).
"$(builddir)" is always "."

Therefore most uses of $(builddir) are suspect and should be
removed or replaced with "."
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
c1898ee996 appliance: Fix rule for building supermin.d/init.img.
Use a temporary directory instead of copy hack.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
b426540b7f tests/data: Add a comment noting a bug in the Makefile.
abssymlink is an intentionally dangling symlink, but this confuses
make which thinks it has to rebuild the rule every time.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
71ca0f8ece tests/data: Don't prepend build paths with $(builddir).
It's both unnecessary and confuses make.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
618a4372cf tests/data: Fix initrd when doing separated builds.
Otherwise the initrd contains paths like '../../tests/data/empty'
which obviously causes the tests to fail.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
0ec2726a52 php: Disallow separated builds.
As it stands, this will just break.  Until it is fixed, give a
diagnostic message.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
13c0b780a3 gobject: Fix separated builds. 2013-04-25 12:22:31 +01:00
Richard W.M. Jones
a8b26aaab9 haskell: Fix separated builds. 2013-04-25 12:22:31 +01:00
Richard W.M. Jones
aab50b9c50 java: Allow source directory to be prepended by make.
Fix for separated builds.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
1d252d7149 java: Bindtests.java is generated in the source directory.
Fix for separated builds.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
5ab516d068 ocaml: bindtests.ml is generated in the source directory.
This seems to be necessary because separated builds don't recognize
the *.ml file as being a source file (unlike, for example, *.c files).
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
fdbe6d81f4 generator: Place generator, stamp-generator, build files into builddir.
Previously the generator binary was (deliberately) placed into the
source directory.  However there was no real reason for this to
happen.  Always put the build products into the builddir.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
e72855e4fa generator: Make stamp-generator in the Makefile.
Since stamp-generator is a Makefile thing, make it in the Makefile,
not in the generator itself.

Also this ensures stamp-generator is created in the builddir, not in
the source directory (fixing separated builds).
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
88271bab7c configure: Make sure that certain build directories exist.
When builddir != srcdir, this ensures that certain build directories
which might not exist are created by configure.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
c4255fd0e3 tests/data: Ensure all generated image files are removed by 'make clean'.
Otherwise the build breaks if you switch from a non-separated build to
a separated build.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
3f450de0a9 Fix 'make distclean'.
Because the generator subdirectory is cleaned first, and other
directories recurse into the generator directory, 'make distclean'
would fail (because generator/Makefile would be deleted by that
point).

Change subdirs-rules.mk so it doesn't fail if generator/Makefile has
been deleted already.
2013-04-25 12:22:31 +01:00
Richard W.M. Jones
88b59ea92f subdirs-rules: Remove 'appliance' rule.
It was used in only one place (perl/Makefile.am).

If users want to build just the appliance, then they could do 'make -C
appliance'.
2013-04-25 12:22:07 +01:00
Richard W.M. Jones
1add24e774 configure: Create resize/ subdirectory if building in a different builddir. 2013-04-24 16:24:09 +01:00
Richard W.M. Jones
6c71ab2208 Version 1.21.32. 2013-04-23 11:07:05 +01:00
Richard W.M. Jones
d99e26d2f3 tests/guests: Add make-guests-all-good.pl to EXTRA_DIST.
This fixes commit 2ae72dcaf8.
2013-04-23 11:06:48 +01:00
Richard W.M. Jones
83659caadb release notes: Fix unterminated C<...> sequence in POD. 2013-04-23 11:06:43 +01:00
Richard W.M. Jones
fecc74e080 tests: sysprep: Specify list of operations explicitly.
This commit makes no functional change on its own, but it allows us to
filter out failing operations on Ubuntu.
2013-04-22 16:18:19 +01:00
Richard W.M. Jones
50003c8cba grub-install: Change test to use /dev/sda instead of /dev/vda.
The previous test for grub-install hard-coded /dev/vda (ie. assuming
virtio-blk instead of more modern virtio-scsi).

This changes the test to hard-code /dev/sda instead.  However this
change is still not correct since /dev/sda will be adjusted by block
device name translation in the call to grub-install, but not what is
written to /boot/grub/device.map.

Since we no longer support grub-install on Fedora, this won't affect
things, but Ubuntu still has a 'grub-install' command (although it's
actually from grub2).
2013-04-22 14:02:05 +01:00
Richard W.M. Jones
2e6e77fd02 gobject: Link libguestfs-gobject library with GIO.
So that we get the g_cancellable_* symbols.
2013-04-19 16:05:48 +01:00
Richard W.M. Jones
1eaf338acd gobject: Link libguestfs-gobject library with GOBJECT_LIBS.
There's no such thing as a _LIBS variable in automake, so
this line was effectively being ignored.
2013-04-19 15:52:54 +01:00
Richard W.M. Jones
6a5495ea3c virt-ls: Use string instead of small array.
This works around the following warning:

virt-ls.c: In function 'show_file':
virt-ls.c:574:1: error: stack protector not protecting function: all local arrays are less than 4 bytes long [-Werror=stack-protector]
2013-04-19 15:37:40 +01:00
Richard W.M. Jones
2da8d49590 examples: Don't ignore return value of chdir.
GCC 4.7.3 whinges about this.
2013-04-19 15:29:50 +01:00
Richard W.M. Jones
2ae72dcaf8 tests: guests: Auto-generated guests-all-good.xml.
Only include guests which we successfully created, so for example if
there's no NTFS support then the Windows guest won't be included.
2013-04-17 20:35:36 +01:00
Richard W.M. Jones
0c605eb94f tests: guests: Display some information about each phony guest for debugging.
This adds debugging output like this:

  fedora-btrfs.img: file size bytes: 536870912
  fedora-btrfs.img: allocated bytes: 12963840
  fedora-btrfs.img: MD5 hash:        7e8eded44fc832b0f88b0dc5eebf490c
2013-04-17 18:00:18 +01:00
Richard W.M. Jones
b7ccdd7cf3 tests: Mark 'skipped' function with __attribute__((printf)).
With recent GCC, you get this warning:

tests-main.c: In function 'skipped':
tests-main.c:256:3: error: function might be possible candidate for 'gnu_printf' format attribute [-Werror=suggest-attribute=format]
2013-04-17 17:03:13 +01:00
Richard W.M. Jones
6af706846f Version 1.21.31. 2013-04-17 08:55:28 +01:00
Richard W.M. Jones
3b0e432875 fish: options: Allow Unix domain sockets to be specified in --add URIs.
You can now use a URI such as:

 guestfish -a nbd://?socket=/tmp/sock

(a NBD connection to Unix domain socket /tmp/sock).
2013-04-16 23:25:36 +01:00
Richard W.M. Jones
44092e06ce fish: options: Format server name as "tcp:host[:port]".
This is safer, because otherwise a URI could contain some clever
"unix:..." string as the hostname, tricking qemu into opening a Unix
domain socket at an uncontrolled location.

This fixes commit 349300af08.
2013-04-16 19:37:20 +01:00
Richard W.M. Jones
87690b10ff df: Move variable decl to top of function.
Since this code is no longer conditional, we don't need to have the
extra { ... } inside the case statement.

This tidies up commit 2f0a4d7c18.
2013-04-16 19:37:20 +01:00
Richard W.M. Jones
f5544e8c93 Version 1.21.30. 2013-04-16 18:41:32 +01:00
Richard W.M. Jones
2f0a4d7c18 Require libxml2.
libxml2 is very commonly available on Linux distros and has also been
ported (and is widely available) on Mac OS X and Windows.  Therefore
simply require libxml2, and remove a lot of conditional code.
2013-04-16 16:46:01 +01:00
Richard W.M. Jones
349300af08 fish: Add -a URI (add remote storage) to options.
Add a remote drive by doing:

 guestfish -a ssh://example.com/path/to/disk.img

There are several different protocols supported, as explained in the
man page.

This affects all virt-* tools that use the common guestfish options
parsing code.
2013-04-16 15:28:31 +01:00
Richard W.M. Jones
b48e416d27 fish: options: Whitespace change. 2013-04-16 13:57:01 +01:00
Richard W.M. Jones
cfda2693c6 Add support for SSH (Secure Shell) block device. 2013-04-16 09:13:07 +01:00
Richard W.M. Jones
ca11cd104d FAQ: Add a quick summary to the debugging section of the FAQ. 2013-04-15 09:51:24 +01:00
Richard W.M. Jones
848db89b7f Version 1.21.29. 2013-04-13 10:48:08 +01:00
Richard W.M. Jones
288a24eebe tests: Split C API tests into regular C file + generated tests file. 2013-04-13 07:26:46 +01:00
Richard W.M. Jones
883aea9b1d tests: Replace TestOutputHashtable with TestResult and C test. 2013-04-13 07:26:02 +01:00
Richard W.M. Jones
c43f762257 tests: Replace TestOutputBuffer with TestResult and C test. 2013-04-13 07:26:02 +01:00
Richard W.M. Jones
424fe36d32 tests: Replace TestOutputFileMD5 with TestResult and C test. 2013-04-13 07:26:02 +01:00
Richard W.M. Jones
0a49838135 tests: Remove TestOutputLength (not used by any tests). 2013-04-13 07:26:02 +01:00
Richard W.M. Jones
685c5fb3b1 tests: Replace TestOutput/TestOutputDevice with TestResult{String,Device}. 2013-04-13 07:26:02 +01:00
Richard W.M. Jones
45840581d6 tests: Replace TestOutputList{,OfDevices} with TestResult.
This adds helper C functions 'is_string_list' and 'is_device_list'
allowing these tests to be carried out in generic C code instead of as
specialized tests.
2013-04-13 07:25:57 +01:00
Richard W.M. Jones
45599a8895 tests: Replace TestOutputStruct with TestResult. 2013-04-12 21:26:23 +01:00
Richard W.M. Jones
24fdf05d30 tests: Replace TestOutputInt{,Op} with TestResult. 2013-04-12 21:26:23 +01:00
Richard W.M. Jones
c9ef854f83 tests: Replace TestOutputTrue/False with TestResultTrue/False. 2013-04-12 21:26:23 +01:00
Richard W.M. Jones
008be5dbfa tests: More flexible re-implementation of C API tests.
Instead of using the various 'TestOutput', 'TestOutputList' etc
macros, it makes better sense to let the tests contain fragments of C
code to perform the checks.

Several new macros are added:

- 'TestResult': This macro takes a C expression which is evaluated to
test the result of commands.  For example to compare if a string
result has some value:

   TestResult (* command sequence *), "STREQ (ret, \"abcd\")"

The variable "ret" contains the result from the last command in the
sequence.  But also, variables "ret1", "ret2", etc contain the results
from the last but one command, the command before that, and so forth,
allowing much more flexible tests to be written.

- 'TestResultTrue', 'TestResultFalse': Wrappers that test the last
command for true/false.
2013-04-12 21:26:23 +01:00
Richard W.M. Jones
e327351304 tests: 'If' and 'Unless' conditions never used, so remove them. 2013-04-12 21:26:23 +01:00
Richard W.M. Jones
09b4cc45a3 is_lv: Does not need to depend on lvm2.
It only uses 'stat', not any lvm binaries.
2013-04-12 21:26:23 +01:00
Richard W.M. Jones
e4ef9a8281 valgrind suppressions: Suppress libmagic leaks. 2013-04-12 21:26:23 +01:00
Richard W.M. Jones
a7107854ba debian: packagelist: Add mtools. 2013-04-11 23:23:20 +01:00
Olaf Hering
3acf6768f0 add --with-supermin-extra-options configure option
Useful to pass --use-installed and other options to supermin.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
2013-04-11 22:20:55 +01:00
Richard W.M. Jones
c2013308ed Update translations from Transifex. 2013-04-11 14:42:54 +01:00
Richard W.M. Jones
f4d5f3d6a2 Update gnulib to latest. 2013-04-11 14:42:54 +01:00
Richard W.M. Jones
142b874ce8 Remove use of gnulib progname module.
It's simpler to use the glibc 'program_invocation_short_name(3)'
feature, and fall back to a generic solution.  Also remove risky
assignments to argv[0].
2013-04-11 14:42:54 +01:00
Richard W.M. Jones
f2b90b374f New APIs: set-program, get-program.
These set or get the program name in the handle.  Most programs
will never need to call this, since we set this, if possible,
using the glibc 'program_invocation_short_name(3)' feature.
2013-04-11 12:52:54 +01:00
Richard W.M. Jones
1a06ac25f5 fish: Add help for prepared disk images to the man page.
Also the long description for each prepared disk image can now contain
Perl POD markup.
2013-04-10 12:28:14 +01:00
Richard W.M. Jones
b72daebaf4 inspection: Don't fail if libosinfo database is not found (RHBZ#948324). 2013-04-10 10:01:17 +01:00
Richard W.M. Jones
2cf0b5c19b fish: welcome message: guestfish can edit disk images. 2013-04-09 23:26:39 +01:00
Richard W.M. Jones
abe07ce2ca "guestfish" now means the "guest filesystem shell".
Remove the word "interactive" which implies that guestfish can only
(or often) be used interactively.
2013-04-09 23:21:42 +01:00
Richard W.M. Jones
6a7327dfa9 Version 1.21.28. 2013-04-09 18:45:15 +01:00
Richard W.M. Jones
c396d4cd32 examples: Update debug-logging.c example.
This updates commit e3546ad2ce.
2013-04-09 17:30:16 +01:00
Richard W.M. Jones
e3546ad2ce examples: Add example program showing enabling debugging and capturing log messages. 2013-04-08 20:10:37 +01:00
Richard W.M. Jones
6582d4ad9f Update release notes for future 1.22 release. 2013-04-05 10:33:58 +01:00
Richard W.M. Jones
a3de6eddd4 pod: Fix "wide character in print" warnings by declaring encoding correctly. 2013-04-05 10:33:25 +01:00
Richard W.M. Jones
dfa25a46e3 Fix typo in extlinux documentation.
This fixes commit dee1dd64c3.
2013-04-04 22:14:25 +01:00
Richard W.M. Jones
f9f3c7c5ac Version 1.21.27. 2013-04-04 21:04:32 +01:00
Richard W.M. Jones
dee1dd64c3 New APIs: Add support for syslinux and extlinux (bootloaders).
This also adds tests of SYSLINUX and EXTLINUX which create bootable
guests.
2013-04-04 18:31:41 +01:00
Richard W.M. Jones
e73cd348c8 Don't delete iconv locale data from the appliance.
- /usr/lib{,64}/gconv/*:

This is the iconv data, required for APIs like iconv_open to work.  In
particular, the mtools 'mcopy' program fails completely if it cannot
use iconv.  'mcopy' is used by SYSLINUX to copy files to the disk.

The error you would have seen is:

  Error converting to codepage 850 Invalid argument
  Cannot initialize 'S:'
  Bad target s:/ldlinux.sys

- /usr/bin/localedef and /usr/sbin/build-locale-archive:

These are not really needed, but both are simply small binaries so we
might as well not delete them.
2013-04-04 18:23:32 +01:00
Richard W.M. Jones
3cdca7616a daemon/copy: Ensure errno is preserved along error paths. 2013-04-04 14:58:32 +01:00
Richard W.M. Jones
33c087ea9c Add 'sparse' option to copy-{device,file}-to-{device,file} calls.
Setting the 'sparse' optional boolean causes writes to be omitted if
the block to be written contains all zero bytes.

This should help with sparse backing files (eg. raw, qcow2, dm-thin, etc).

Also, modify virt-resize to use this option by default when copying
devices.  The savings in virt-resize can be quite startling, eg
'du -sh' (ie. true size) of a resized disk image:

8.1G      /tmp/f15x32-resized.img    # before this change
3.2G      /tmp/f15x32-resized.img    # after this change
2013-04-04 14:58:32 +01:00
Richard W.M. Jones
289fd29f0b php: Fix segfault when function has an OStringList optional argument.
How this PHP/Zend stuff is supposed to work is not documented, but at
least with these changes it no longer segfaults.
2013-04-04 11:49:27 +01:00
Richard W.M. Jones
ba0199c487 python: Let RHashtable be returned as a Python dict.
The initial proposal was suggested by Matt Booth and discussed on the
mailing list here:

https://www.redhat.com/archives/libguestfs/2013-April/msg00007.html
2013-04-03 19:18:07 +01:00
Richard W.M. Jones
3dcb572bda Better error messages for FUSE and other things not supported.
The bare message "FUSE not supported" wasn't actionable.
2013-04-03 12:33:24 +01:00
Richard W.M. Jones
d0a8cca9a1 FAQ: In Fedora >= 19, the RPM detects if it can access the network when building. 2013-04-02 15:53:37 +01:00
Richard W.M. Jones
387b232126 Version 1.21.26. 2013-04-02 15:29:59 +01:00
Richard W.M. Jones
667482ca9a perl: Remove Sys::Guestfs::Lib.
See announcement on the mailing list for more details about this change:

https://www.redhat.com/archives/libguestfs/2013-April/msg00001.html
2013-04-02 15:26:05 +01:00
Richard W.M. Jones
2287b988ee perl: Remove use of Sys::Guestfs::Lib::open_guest function.
This obsolete function does all sorts of libvirt/XML things, which can
now be replaced by using ordinary API calls; especially $g->add_domain.
2013-04-02 13:30:19 +01:00
Richard W.M. Jones
ecda39bed4 tests/data: Update README and comments about initrd binary files.
These are used for testing the C, not Perl, file_architecture API.
2013-04-02 13:06:10 +01:00
Richard W.M. Jones
1cb38ab924 New API: feature-available.
This API is an easier to use version of the existing guestfs_available,
because the new API returns true/false instead of throwing an error
when a feature from the list is not available.

In truth we've had this implementation internally in the library
and several tools and in Sys::Guestfs::Lib for a long time.  This
change just turns it into a publicly consumable API.
2013-04-02 12:38:50 +01:00
Richard W.M. Jones
288b2b2d4f virt-ls, virt-edit: Remove references to Sys::Guestfs::Lib and other irrelevant Perl libraries. 2013-04-02 10:15:25 +01:00
Richard W.M. Jones
6fa1177b0a java: Make test cases depend on jar file.
This fixes parallel builds.  The error you would have seen was:

  error: error reading libguestfs-1.21.25.jar; zip file is empty
2013-04-01 20:29:17 +01:00
Richard W.M. Jones
1a2e03c323 java: 'make clean' should remove whole api/ directory.
This directory (containing HTML documentation) can be removed
completely when making clean.  CLEANFILES cannot recursively remove a
directory, so use a clean-local rule instead.
2013-04-01 20:28:16 +01:00
Richard W.M. Jones
ce49e1fdc0 build: Change various check rules so they implicitly act like 'make -k'.
Rules such as 'make check-valgrind' are implemented using a for-loop.
They would always exit after the first error, even if 'make -k' was
used at the top-level.  Since 'make -k'-style behaviour is generally
more useful, change these for-loops so they run all the tests, and
report errors at the end.
2013-04-01 13:32:15 +01:00
Richard W.M. Jones
599f5d7ddc make clean: Remove *~ (editor backup) files. 2013-04-01 13:32:15 +01:00
Richard W.M. Jones
5f5ce4f59f make clean: Clean contents of tmp directory. 2013-04-01 11:40:35 +01:00
Richard W.M. Jones
b050d7e4bf valgrind: Write separate log files in tmp/valgrind-<DATE>-<PID>.log
Current code wrote a single valgrind.log in the top-level directory.
This was overwritten with each valgrinded program, which wasn't much
use.  The new version writes multiple separate valgrind-*.log files
containing the date and PID (so each is unique).

It would nice if valgrind could delete log files that don't contain
errors, but this doesn't appear to be possible.
2013-04-01 11:35:26 +01:00
Richard W.M. Jones
68990840b6 "attach method" is from now on known as "backend".
This large, but mainly mechanical commit, renames "attach method"
everywhere to "backend".

Backwards compatibility of the API (guestfs_{set,get}_attach_method)
and environment (LIBGUESTFS_ATTACH_METHOD) is maintained, but in new
code use guestfs_{set,get}_backend and LIBGUESTFS_BACKEND instead.

The default backend (launching qemu directly) is now called 'direct'
instead of 'appliance', although you can still use 'appliance' as a
synonym.
2013-04-01 11:16:18 +01:00
Richard W.M. Jones
f2b1a01e76 build: Clarify output of 'make help'. 2013-04-01 11:16:18 +01:00
Richard W.M. Jones
72f5a6b004 Version 1.21.25. 2013-03-30 22:57:29 +00:00
Richard W.M. Jones
75f2fcd687 docs: Remove obsolete sections from libguestfs gotchas.
These refer to old behaviour in long-unsupported versions
of libguestfs.
2013-03-30 19:44:39 +00:00
Richard W.M. Jones
806289ec66 docs: Refresh API overview section. 2013-03-30 19:43:52 +00:00
Richard W.M. Jones
b2eef58571 docs: Alternate ways to list filesystems through the API. 2013-03-30 19:28:29 +00:00
Richard W.M. Jones
8e76cb4512 FAQ: Update distro support section. 2013-03-30 19:09:12 +00:00
Richard W.M. Jones
02a4e5ac6a debian: Allow test-virt-alignment-scan-guests.sh test to be skipped. 2013-03-30 18:17:09 +00:00
Richard W.M. Jones
2a090e0667 tests/guests: Add 'guests-all-good.xml{.in}' libvirt test guest set.
This differs from 'guests.xml' in that there are no guests with
missing disks, etc., so we can use this to test virt-alignment-scan
accurately.
2013-03-30 16:33:08 +00:00
Richard W.M. Jones
429ffda329 parallel: Propagate errors from worker threads and exit with error code.
In virt-df and virt-alignment-scan, ensure that errors that happen in
worker threads are propagated all the way up and result in
exit(EXIT_FAILURE).

Note that this makes the align/test-virt-alignment-scan-guests.sh test
fail (for a genuine reason).  This is fixed in the following commit.

This updates commit 8b90f55dc7.
2013-03-30 16:33:08 +00:00
Richard W.M. Jones
30702c7f54 Version 1.21.24. 2013-03-29 22:07:18 +00:00
Richard W.M. Jones
f55a2dbf29 java: Make bindtests depend on jar file so parallel builds work.
This fixes commit c36ced5e21.
2013-03-29 22:02:46 +00:00
Richard W.M. Jones
8b90f55dc7 virt-alignment-scan: Don't call exit(3) from this multi-threaded program.
For more information see:
https://bugzilla.redhat.com/show_bug.cgi?id=790837#c2
2013-03-29 21:28:49 +00:00
Richard W.M. Jones
d6ea2f5911 daemon: file: Remove extraneous space after output of 'file' command (RHBZ#928995). 2013-03-29 20:04:11 +00:00
Richard W.M. Jones
a9ad3088bf daemon: parse_btrfsvol: Perform device name translation before trying to stat the device.
If using (eg) virtio-blk, the canonical name won't work unless device
name translation is done first.

This fixes commit 47b929b7893b3a76ff22760d245cb80720ae6345..
2013-03-29 10:50:28 +00:00
Richard W.M. Jones
bb276e8a26 daemon: parse_btrfsvol: Move variable decls to top, whitespace fixes.
This fixes commit 47b929b789.
2013-03-28 23:30:51 +00:00
Richard W.M. Jones
a28a430b10 daemon: Fix parse_btrfsvol to use STRPREFIX instead of bogus strncmp.
This fixes commit 47b929b789.
2013-03-28 23:30:51 +00:00
Richard W.M. Jones
c50cde67cc java: Format CLEANFILES rule. 2013-03-28 20:24:25 +00:00
Richard W.M. Jones
c36ced5e21 java: Enable parallel builds.
This reverts commit 89404ec0ba.
2013-03-28 20:20:09 +00:00
Richard W.M. Jones
6185aa4e38 ocaml tools: Enable parallel builds.
In particular, building virt-sysprep is slow because there are so many
modules.  Enable parallel builds.  If it breaks, we should fix it, not
work around it.
2013-03-28 20:15:51 +00:00
Richard W.M. Jones
dce94f3e26 ocaml: Fix and enable parallel builds.
We only have to serialize the two calls to ocamlmklib, since both will
try to create a file called 'libmlguestfs.a'.  Apart from that,
parallel builds here should be fine.
2013-03-28 20:13:36 +00:00
Richard W.M. Jones
b13c935bbd ocaml: Break circular dependency of mlguestfs.cma{,x} <-> guestfs.cm{o,x} 2013-03-28 20:12:47 +00:00
Richard W.M. Jones
3c34db9808 Use new-style demand-loaded bash-completion scripts. 2013-03-28 18:46:06 +00:00
Richard W.M. Jones
df7f57a193 Version 1.21.23. 2013-03-28 15:18:43 +00:00
Richard W.M. Jones
924aa44c1f bash completion: Extend this script to work with other virt tools. 2013-03-28 15:15:45 +00:00
Richard W.M. Jones
6c9a7fe561 Add --long-options option to most tools.
For example:

$ guestfish --long-options
--add
--cmd-help
--connect
--csh
--domain
--echo-keys
[etc.]

The idea of this is to make it easier to write a bash completion
script that accurately expands --<TAB> options for each command.
2013-03-28 14:46:20 +00:00
Richard W.M. Jones
b98de580c9 fish: Better tab completion for guestfish. 2013-03-28 14:00:42 +00:00
Richard W.M. Jones
05ba393724 OCaml tools: Use Common_gettext and Common_utils modules.
Share these modules across all three tools virt-resize, virt-sparsify
and virt-sysprep.

This is mostly code motion.
2013-03-28 14:00:42 +00:00
Richard W.M. Jones
69e0f86cab osinfo: Fix declaration of guestfs___osinfo_map to work when libxml2 is not installed. 2013-03-23 18:57:39 +00:00
Richard W.M. Jones
186bb67c6e Add support for: Gluster, Ceph (rbd), Sheepdog.
These are not tested at all, and so probably won't work.  However the
code and infrastructure is in place so we can fix bugs easily as they
arise.
2013-03-19 12:39:51 +00:00
Richard W.M. Jones
97be29893e build: Add 'make check-valgrind-with-appliance'. 2013-03-19 12:24:40 +00:00
Richard W.M. Jones
62d940d2dd build: Small rearrangement of Makefile.am check-slow rule. 2013-03-19 12:24:40 +00:00
Richard W.M. Jones
55ce68784f build: Fix 'make extra-tests' to call 'check-valgrind' instead of rule that doesn't exist. 2013-03-19 12:24:40 +00:00
Richard W.M. Jones
71de9ef039 build: Turn off warning about overlength-strings.
ISO apparently specified a limit of 4096 bytes/characters for strings.
The description of the guestfish command 'add-drive' is now longer
than this limit, causing this warning.

Turn off this warning, since GCC has no problems with these strings.
2013-03-19 12:24:37 +00:00
Richard W.M. Jones
a535befbeb nbd: Update and clarify the documentation for NBD. 2013-03-18 22:35:43 +00:00
Richard W.M. Jones
66df6ae908 drives: Make parse_servers return an int (number of servers).
This is just a code refactoring.
2013-03-18 22:35:24 +00:00
Richard W.M. Jones
f8941b09e6 Version 1.21.22. 2013-03-18 19:46:24 +00:00
Richard W.M. Jones
dc4c959ce1 nbd: Allow 'unix' transport & socket to be specified.
This allows the server string to contain "unix:/path/to/socket",
thus using a Unix domain socket to connect to the NBD server.
2013-03-18 17:59:19 +00:00
Richard W.M. Jones
43b6d75a08 tests: nbd: Ensure qemu-nbd subprocess is always killed.
Even if the test fails/dies for some other reason.
2013-03-18 16:45:55 +00:00
Richard W.M. Jones
f750c3e72d drives: Factor out common code for making a file= qemu parameter. 2013-03-18 16:45:55 +00:00
Richard W.M. Jones
9c32c73afd drives: Allow multiple servers to be passed to add_drives.
This changes the existing (non-published-in-stable) API for
add_drives{_opt} so that instead of having separate 'server' and
'port' parameters, now we have a single 'server' parameter which is a
list of strings.

This is so we will be able to cope with protocols such as Ceph which
allows multiple servers, or Sheepdog which can use an implicit local
server (ie. zero servers specified).

NBD still requires exactly one server.
2013-03-18 16:45:55 +00:00
Richard W.M. Jones
766393d854 inspection: Remove unused #includes. 2013-03-18 15:47:34 +00:00
Richard W.M. Jones
6641758221 drives: Add a common guestfs___free_drive_source function.
This refactors the code to introduce a common function.
2013-03-18 14:58:50 +00:00
Richard W.M. Jones
612a3f06b4 drives: Whitespace change. 2013-03-18 14:58:36 +00:00
Richard W.M. Jones
cec0c55a35 drives: Change internal struct drive_source.
This is just code refactoring.
2013-03-18 12:04:24 +00:00
Richard W.M. Jones
856c2f6a47 nbd: Note that readonly connections are not supported by the appliance attach-method.
This documents the problem and links to the upstream bug.
2013-03-18 09:55:36 +00:00
Richard W.M. Jones
ae3011d518 lib: Remove -Wswitch-default.
This warning is actively dangerous.  Because it forces you to use a
'default:' case in every switch statement, it means you can no longer
detect missing cases in enums.
2013-03-16 21:22:03 +00:00
Richard W.M. Jones
bf1c3196b5 lib: Add missing cases in switch statements.
These were being hidden by misguided use of the dangerous
-Wswitch-default flag.
2013-03-16 20:23:14 +00:00
Richard W.M. Jones
2af946b3bf Version 1.21.21. 2013-03-15 22:42:38 +00:00
Richard W.M. Jones
af1c53d104 appliance: Make sure cachedir has mode 0755 (RHBZ#921292).
See https://bugzilla.redhat.com/show_bug.cgi?id=921292#c4
2013-03-15 22:40:06 +00:00
Richard W.M. Jones
e7c78881fc appliance: Use ignore_value() macro instead of casting return to (void). 2013-03-15 22:39:45 +00:00
Richard W.M. Jones
c83221a869 drives: add_drive was only called from one place, so inline it.
This is just code motion.
2013-03-15 20:47:55 +00:00
Richard W.M. Jones
694a091d3f lib: Add direct support for the NBD (Network Block Device) protocol.
You can now add remote NBD drives using:

 ><fs> add-drive "" format:raw protocol:nbd server:localhost

(Note that you also need to add port:NNNN if the server is running on
a non-standard port).

The corresponding qemu-nbd service can be started by doing:

 qemu-nbd disk.img -t

This commit also adds a test.
2013-03-15 20:47:54 +00:00
Richard W.M. Jones
e7e2b56569 drives: Make drv->readonly flag into a bool. 2013-03-14 22:34:56 +00:00
Richard W.M. Jones
b1df9a9df1 drives: Refactor code to separate 'struct drive' creation from adding drives. 2013-03-14 22:28:22 +00:00
Richard W.M. Jones
33ec3eca29 launch: Move code concerned with adding drives to 'src/drives.c'.
Apart from adding a few comments, this is entirely code motion.
2013-03-14 22:06:16 +00:00
Richard W.M. Jones
a2b88b8637 Add ./configure --with-extra-packages="..." option.
This adds extra packages to the appliance.  It's useful for adding
debugging packages.
2013-03-14 13:50:49 +00:00
Hilko Bengen
85dd52f470 Mount /run as tmpfs inside appliance (workaround for febootstrap's /init) 2013-03-14 13:01:07 +00:00
Richard W.M. Jones
e29a130d8f erlang: Use $(ERLANG_LIB_DIR) to get Erlang libdir.
Instead of previous custom hack which didn't work properly on Debian.

Thanks: Hilko Bengen.
2013-03-14 12:47:40 +00:00
Richard W.M. Jones
04acc32abf README: Discourage general users from doing 'make install'.
It causes plenty of problems with people have multiple parallel
versions of libguestfs installed, and there's no benefit because you
can easily run libguestfs and tools from the build directory.
2013-03-14 12:20:52 +00:00
Richard W.M. Jones
87c9ec881c ruby: Support 'make INSTALLDIRS=vendor install' for Ruby as well as Perl.
As with Perl, you can now set INSTALLDIRS to control where Ruby places
its files (ie. in the site dir, which is the default, or in the vendor
dir).

The difference in file layout between 'make install' and
'make INSTALLDIRS=vendor install' is shown below (for Fedora 18).

--- /tmp/site	2013-03-14 12:14:35.740015694 +0000
+++ /tmp/vendor	2013-03-14 12:14:13.668093944 +0000
@@ -119,21 +119,20 @@
 ./usr/lib64/ocaml/guestfs/mlguestfs.cmxa
 ./usr/lib64/ocaml/stublibs/dllmlguestfs.so
 ./usr/lib64/ocaml/stublibs/dllmlguestfs.so.owner
-./usr/lib64/perl5/auto/Sys/Guestfs/Guestfs.bs
-./usr/lib64/perl5/auto/Sys/Guestfs/Guestfs.so
-./usr/lib64/perl5/auto/Sys/Guestfs/.packlist
 ./usr/lib64/perl5/perllocal.pod
-./usr/lib64/perl5/Sys/bindtests.pl
-./usr/lib64/perl5/Sys/Guestfs/Lib.pm
-./usr/lib64/perl5/Sys/Guestfs.pm
+./usr/lib64/perl5/vendor_perl/auto/Sys/Guestfs/Guestfs.bs
+./usr/lib64/perl5/vendor_perl/auto/Sys/Guestfs/Guestfs.so
+./usr/lib64/perl5/vendor_perl/auto/Sys/Guestfs/.packlist
+./usr/lib64/perl5/vendor_perl/Sys/bindtests.pl
+./usr/lib64/perl5/vendor_perl/Sys/Guestfs/Lib.pm
+./usr/lib64/perl5/vendor_perl/Sys/Guestfs.pm
 ./usr/lib64/php/modules/guestfs_php.so
 ./usr/lib64/pkgconfig/libguestfs-gobject-1.0.pc
 ./usr/lib64/pkgconfig/libguestfs.pc
 ./usr/lib64/python2.7/site-packages/guestfs.py
 ./usr/lib64/python2.7/site-packages/libguestfsmod.la
 ./usr/lib64/python2.7/site-packages/libguestfsmod.so
-./usr/local/lib64/ruby/site_ruby/_guestfs.so
-./usr/local/share/ruby/site_ruby/guestfs.rb
+./usr/lib64/ruby/vendor_ruby/_guestfs.so
 ./usr/sbin/libguestfs-make-fixed-appliance
 ./usr/share/doc/libguestfs/example-debian-netinst-cd.xml
 ./usr/share/doc/libguestfs/example-debian.xml
@@ -406,3 +405,4 @@
 ./usr/share/man/uk/man3/guestfs-perl.3
 ./usr/share/man/uk/man3/guestfs-python.3
 ./usr/share/man/uk/man3/guestfs-ruby.3
+./usr/share/ruby/vendor_ruby/guestfs.rb

For prompting me to fix this, thanks: Hilko Bengen.
2013-03-14 12:19:22 +00:00
Richard W.M. Jones
0fd925da77 launch: Print attach-method, tmpdir, umask, euid when launching.
These are only printed when debugging is enabled, but should help
debugging hard-to-pin-down permissions problems.
2013-03-14 10:47:00 +00:00
Richard W.M. Jones
df656c9d5a tests: Make it easier to grep failures out of the log file. 2013-03-14 08:56:29 +00:00
Richard W.M. Jones
3e4d3f415c Version 1.21.20. 2013-03-13 18:45:30 +00:00
Richard W.M. Jones
1b644ad64e utils: Fix error messages for external commands that fail (RHBZ#921040).
This adds a common utility function (guestfs___exit_status_to_string)
and a common error function (guestfs___external_command_failed), and
uses them all over the library and tools when converting exit status
in error messages etc.
2013-03-13 18:34:17 +00:00
Richard W.M. Jones
50a3fa5f42 lib: Move common errors to src/errors.c.
This is just code motion.
2013-03-13 17:20:41 +00:00
Richard W.M. Jones
e9d3074294 rescue: Remove dead code.
This pty code was defended by #if 0 ... #endif and was dead code.
2013-03-13 17:20:41 +00:00
Richard W.M. Jones
368b4c6480 Ignore case when generating AUTHORS file. 2013-03-13 10:57:36 +00:00
infernix
b17c3a7eb3 launch: appliance: Add custom parameters last.
This allows custom parameters to modify parameters added by
libguestfs, eg. by doing:

  -set drive.hd0.file=rbd:foo/bar

[infernix adds the comment below:]

This works for recent versions of QEMU. The way to use this is:

guestfish
><fs> add-drive /dev/null
><fs> config -set drive.hd0.file=rbd:pool/volume
><fs> run

This will probably work for more types (sheepdog, iscsi et al), but
with the caveat that the libguestfs layers are bypassed so you'll
*always* end up directly accessing the disk in rw mode.
2013-03-12 17:58:32 +00:00
Richard W.M. Jones
0b285cd8a6 docs: Update documentation on attach-methods.
Add better instructions for getting the default attach-method.

Update libguestfs-test-tool(1) to show how to enable and disable
libvirt.
2013-03-12 13:19:26 +00:00
Richard W.M. Jones
6e4f9be492 php: Pass all libvirt environment variables down to PHP test scripts.
Including LIBVIRTD_* and VIRTLOCKD_*.

This updates commit cd40cf7139.
2013-03-12 12:35:17 +00:00
Richard W.M. Jones
49622ab63b Version 1.21.19. 2013-03-11 23:03:38 +00:00
Richard W.M. Jones
5e5026b730 qemu-img info: Use --output json and YAJL (JSON parser) to safely parse output (RHBZ#920225).
The old parser is still used if either YAJL is not available or
qemu-img info doesn't support the --output json option.
2013-03-11 19:10:04 +00:00
Richard W.M. Jones
2f8960f784 qemu-img info: Prefix parsing functions as old_parser_*.
Prefix functions in this file with old_parser_... to make it clear
this is the old / slightly unsafe human output parser, which is
shortly to be replaced by a safer JSON parser.

This is just code motion.
2013-03-11 16:27:13 +00:00
Richard W.M. Jones
cd40cf7139 php: Fix tests.
- Use ./run script to run the tests.
- Set environment variables correctly, including $PATH.
- Test the locally built, not installed, copy of libguestfs.
2013-03-11 16:04:17 +00:00
Richard W.M. Jones
becc4fecf4 php: Revise README-PHP documentation. 2013-03-11 14:29:13 +00:00
Richard W.M. Jones
c64e99782f docs: Note that $PATH affects libguestfs.
If $PATH is not set, libguestfs and/or libvirt tend to break.
2013-03-11 14:28:40 +00:00
Richard W.M. Jones
350c478d7b launch: libvirt: Unset $PATH can cause libvirt launch to fail.
Note this fact in the error message that is printed in this situation.
2013-03-11 14:27:56 +00:00
Richard W.M. Jones
02159e9aa8 launch: libvirt: Print proper dotted libvirt version. 2013-03-11 14:05:33 +00:00
Richard W.M. Jones
fe3798f366 php: Print libguestfs error string if test fails. 2013-03-11 13:44:50 +00:00
Richard W.M. Jones
d44752a110 php: Fix test, /dev/null format must be "raw". 2013-03-11 13:44:33 +00:00
Richard W.M. Jones
7a968beb46 lib: Give values for each state in 'enum state'.
The values of CONFIG, LAUNCHING and READY and (kind of) exposed
through the API so shouldn't change.

Use a bad sentinel for NO_HANDLE since that indicates a serious error.
2013-03-11 12:34:22 +00:00
Richard W.M. Jones
99e5ffd1de lib: Add comment for libguestfs handle. 2013-03-11 12:32:30 +00:00
Richard W.M. Jones
d9efcfb556 RHEL 5: tests/xml: Define O_CLOEXEC in LD_PRELOAD library. 2013-03-11 11:04:38 +00:00
Richard W.M. Jones
1b5b397da8 RHEL 5: tests: Use gnulib.
Gnulib defines O_CLOEXEC which is missing on RHEL 5.
2013-03-10 20:08:59 +00:00
Richard W.M. Jones
d16bb6b70c RHEL 5: Replacement for 'Unix.isatty stdout' for old OCaml versions.
Unix.isatty missing on RHEL 5-era OCaml 3.09.3.
2013-03-09 22:32:30 +00:00
Richard W.M. Jones
e73944faf4 RHEL 5: gnulib: Use module mkstemps.
RHEL 5 glibc doesn't have this function.
2013-03-09 18:53:51 +00:00
Richard W.M. Jones
bb0617859f RHEL 5: inspect: Add macro for be32toh if one is not defined in the header files. 2013-03-09 18:53:51 +00:00
Richard W.M. Jones
74297e6109 Add suppression for memory leak in libmagic. 2013-03-08 17:03:37 +00:00
Richard W.M. Jones
52c3edd5e0 filearch: Use a more logical way to construct the cpio command. 2013-03-08 14:02:19 +00:00
Richard W.M. Jones
801487f2a7 filearch: Don't print errno if cpio command fails, print command status instead.
errno is meaningless here.
2013-03-08 13:51:18 +00:00
Richard W.M. Jones
22d82d00b4 generator: Small fix for OCaml 3.12.1.
OCaml 3.12.1 (unlike 4.00.1) doesn't let you use printf formatters
in this way:

  printf (if foo then "&%s" else "%s") str
2013-03-08 13:17:45 +00:00
Hilko Bengen
0ee24ccf8a Move Ruby-related checks from autoconf to extconf.rb; add extra check for rb_alloc_func_t
Ruby ships its own config.h which may or may not define the same
relevant constants as our autoconf-generated config.h. Instead of
trying to specify the exact path to the wanted header file we may just
as well simply use Ruby's autoconf-inspired checks and macros.
2013-03-08 12:47:24 +00:00
Richard W.M. Jones
3a895ba794 df/parallel.c: Fix if libvirt is not available at compile time. 2013-03-07 23:29:21 +00:00
Richard W.M. Jones
ef33ea359d Version 1.21.18. 2013-03-07 21:53:16 +00:00
Hilko Bengen
6557d0c082 out-of-tree build: Fix link creation 2013-03-07 21:26:05 +00:00
Hilko Bengen
a568dec4cf Still build the libguestfs-specific parts when --disable-appliance is passed to configure 2013-03-07 21:26:03 +00:00
Hilko Bengen
43b37d02a1 out-of-tree build: Fix localized manpages 2013-03-07 21:17:30 +00:00
Hilko Bengen
0a50e64435 out-of-tree build: don't distribute extconf.rb.in template, use generated exconf.rb
Apparently, the file will only be autogenerated in $(builddir) if it
is not already present in $(srcdir).
2013-03-07 21:14:11 +00:00
Richard W.M. Jones
bb1f665d7f protocol: Handle log messages from connection layer centrally.
Previously described as a "gross hack and massive layering violation".
2013-03-07 18:23:45 +00:00
Richard W.M. Jones
ed41fcd75c protocol: Abstract out socket operations from protocol code.
This creates an abstract layer below the protocol code which handles
the socket operations.  This will make it easier to introduce libvirt
virSocketPtr operations in future.

In the handle, g->conn contains the connection to the appliance.
g->conn is NULL when we're not connected.

poll(2) is used instead of select(2).

All error messages about launch failing or the appliance unexpectedly
dying are handled by two common error message functions, and these
contain a better explanation of what to do.
2013-03-07 18:15:09 +00:00
Richard W.M. Jones
06b39b8098 protocol: Remove message_summary code.
Produces lots of output, and not very helpful.
2013-03-07 16:29:12 +00:00
Richard W.M. Jones
2c8e7ba9b4 launch: unix: Set g->daemon_sock = -1 after closing it.
This ensures we don't accidentally use the closed fd.
2013-03-07 11:40:44 +00:00
Richard W.M. Jones
9ae639948a lib: Rename g->fd to console_sock and g->sock to daemon_sock.
This just renames the fields in the handle to more descriptive names.
There is no functional change.
2013-03-07 11:39:44 +00:00
Richard W.M. Jones
f9381847f1 launch: appliance: Set FD_CLOEXEC flag on console socket.
The earlier (pipe-based) code never set this flag, but that was a bug,
potentially allowing the file descriptor to be leaked to subprocesses.

Set the FD_CLOEXEC flag, but also ensure it is cleared in the child
process just before qemu is exec'd (otherwise qemu would not have a
console).
2013-03-07 11:12:04 +00:00
Richard W.M. Jones
6e7cbb09a9 launch: appliance: Use socketpair instead of pipe for qemu stdin/stdout.
The libvirt backend already uses a Unix socket for the appliance
console, and so for the libvirt backend the fields g->fd[0] == g->fd[1].

Change the appliance backend to use a socketpair, so we need just a
single file descriptor for qemu stdin/stdout (ie. appliance console).

Consequently we can remove the array int fd[2] in the handle and
replace it with a single file descriptor.
2013-03-07 09:50:36 +00:00
Richard W.M. Jones
8136ca3719 proto: send_to_daemon is not an exported function.
This function is only used inside src/proto.c, so rename
it from guestfs___send_to_daemon to just send_to_daemon.
2013-03-06 21:13:14 +00:00
Richard W.M. Jones
7de25c2bca valgrind: Add suppression for memory leak found in libselinux. 2013-03-06 14:39:07 +00:00
Richard W.M. Jones
c44c5ee268 debug: Add command to generate lots of debug messages. 2013-03-06 11:18:14 +00:00
Richard W.M. Jones
ba08a51094 launch: libvirt: When debugging, print permissions of appliance and sockets.
When debugging is enabled, this prints out the permissions (ie.
ls -laZ) of the appliance and sockets directories.  This should be
helpful for debugging RHBZ#913774.
2013-03-05 17:03:21 +00:00
Richard W.M. Jones
59f01c4a70 launch: libvirt: Rename 'is_root' as 'current_proc_is_root', and documentation. 2013-03-05 16:49:46 +00:00
Richard W.M. Jones
ed354e8f8b launch: libvirt: When root, set socket permissions to 0660 (vs 0775).
Since qemu connects to both, there was no point at all in having these
sockets be readable by other, nor executable by anyone.

The sockets should now end up as:

  srw-rw---- root.qemu
2013-03-05 16:49:46 +00:00
Richard W.M. Jones
a4a2a181c2 fuse: tests: Set FD_CLOEXEC flag on file descriptor.
This is not required here, but it helps if the test code matches what
the documentations says you should do.
2013-03-05 15:26:41 +00:00
Richard W.M. Jones
f7789acdab Version 1.21.17. 2013-03-05 14:47:10 +00:00
Richard W.M. Jones
6039689344 guestmount: Add --no-fork flag.
This prevent guestmount from daemonizing.
2013-03-05 14:40:27 +00:00
Richard W.M. Jones
0120a087f4 Add guestunmount.1.html to the website.
This fixes commit 3e9e40aee3.
2013-03-05 14:05:35 +00:00
Richard W.M. Jones
3e9e40aee3 fuse: Add guestunmount program to handle unmounting (RHBZ#916780). 2013-03-05 13:12:25 +00:00
Richard W.M. Jones
09442d0588 fuse: guestfs_umount_local is not thread-safe.
Despite what the documentation may have said, it certainly was not
safe to call guestfs_umount_local from another thread.

guestfs_umount_local could generate events, call the error handler, or
access other fields in the handle, with no locking at all.

We should aim to make guestfs_umount_local thread-safe in future.

See also:
https://bugzilla.redhat.com/show_bug.cgi?id=917706
2013-03-04 15:31:41 +00:00
Richard W.M. Jones
d08f5ebd9a generator: Generate guestfs_user_cancel.
This function is now generated, so bindings in various languages
are made automatically.

Note that the function previously returned void, but now it returns
int (although always 0).  We don't believe that this is an ABI break
since existing programs will continue to work.
2013-03-04 15:24:26 +00:00
Richard W.M. Jones
ac2f6c4ef2 generator: Add 'wrapper' flag to control when wrapper is generated.
Non-daemon functions normally have a wrapper function called
eg. guestfs_name.  The "real" (ie. hand-written) function is called
eg. guestfs__name.  The wrapper deals with checking parameters and
doing trace messages.

This commit allows the wrapper function to be omitted.  The reason is
so that we can handle a few functions that have to be thread-safe
(currently just: guestfs_user_cancel).  The wrapper is not thread safe
because it can call events and/or the error handler.
2013-03-04 15:24:05 +00:00
Richard W.M. Jones
4236929fbb generator: Typo in comment: "Checking" -> "Check". 2013-03-04 15:07:50 +00:00
Richard W.M. Jones
9b7de52d58 threads: Note that even innocent-looking functions need a mutex.
RWMJ was caught out by this one ...
2013-03-04 15:07:50 +00:00
Richard W.M. Jones
66351f7494 trace: Put trace buffer on the stack instead of in the handle.
This makes more sense, and makes the code slightly closer to being
thread safe (although it's still NOT thread safe).
2013-03-04 15:07:50 +00:00
Richard W.M. Jones
8e2b920fe6 FAQ: Add question about running fsck on live filesystems. 2013-03-01 16:25:41 +00:00
Richard W.M. Jones
7d8b97559b Version 1.21.16. 2013-03-01 15:55:18 +00:00
Richard W.M. Jones
7f5bedd53b lib: Check calls to xmlXPathEvalExpression for nodesetval == NULL.
libxml2 xmlXPathEvalExpression can return an unusual nodeset:

  $1 = {type = XPATH_NODESET, nodesetval = 0x0, boolval = 0, floatval = 0,
    stringval = 0x0, user = 0x0, index = 0, user2 = 0x0, index2 = 0}

Note that the nodeset is non-NULL, but the nodesetval is NULL.

Check every call site and fix those that don't deal with this
correctly.
2013-03-01 14:44:51 +00:00
Richard W.M. Jones
3adb0d6d01 add-domain: Move 'connect_live' function.
This is just code motion.
2013-03-01 14:12:47 +00:00
Richard W.M. Jones
e78a2c5df3 add-domain: Pass SELinux label from guest to appliance (RHBZ#912499).
When adding a domain (ie. guestfs_add_domain), read the SELinux
<label/> and <imagelabel/> from the guest and use them for the
appliance.  The appliance is statically labelled the same as the
guest, so it is able to read its disks.

However tell libvirt not to try relabelling the disks, to prevent
libvirt from disturbing the existing labels on the disks (in
particular when the libvirt connection is closed, we don't want
libvirt to try to restore some other label on the disks).

Updated with feedback from Matthew Booth.
2013-03-01 14:12:33 +00:00
Richard W.M. Jones
26df366d3b launch: libvirt: Allow the SELinux label to be set on qcow2 overlay files.
When a disk is opened readonly, the libvirt attach-method privately
creates a qcow2 overlay on top.

This commit lets that overlay get an SELinux label, and sets it to the
imagelabel specified by guestfs_internal_set_libvirt_selinux_label.

The above only applies to the libvirt attach-method.
2013-02-28 15:49:28 +00:00
Richard W.M. Jones
b9ee8baa49 New internal API: internal_set_libvirt_selinux_norelabel_disks.
If set, this causes <seclabel model=selinux relabel=no> to be added to
the disk element in the libvirt XML.

It has no effect *except* on the libvirt attach method when SELinux
and sVirt is being used.
2013-02-28 15:49:27 +00:00
Richard W.M. Jones
617eb88c5e New internal API: internal_set_libvirt_selinux_label
This internal API sets two SELinux labels in the handle (the process
label and the image label -- they are closely related).

If using the libvirt attach-method with SELinux and sVirt, then this
will cause the following XML to be added to the appliance definition:

<seclabel type=static model=selinux relabel=yes>
  <label>[LABEL HERE]</label>
  <imagelabel>[IMAGELABEL HERE]</imagelabel>
</seclabel>

It is ignored by other attach-methods.
2013-02-28 15:49:27 +00:00
Richard W.M. Jones
a6a703253b add-domain: Refactor domain XML parsing code.
This is just code motion.
2013-02-28 15:49:27 +00:00
Richard W.M. Jones
d01ac17559 test-tool: Give an error if there are extra arguments on the command line. 2013-02-28 15:22:06 +00:00
Richard W.M. Jones
3f1e7f1078 launch: libvirt: Refactor SELinux warning code.
This is just code motion.
2013-02-28 13:38:25 +00:00
Richard W.M. Jones
93feaa4ae8 parallel: Don't access the global handle from multiple threads.
libguestfs handles are not thread safe, and it's not safe even to read
settings from the handle from multiple threads (eg. guestfs_get_trace).
Stop doing this in the parallel library.  This caused fairly
reproducible segfaults when you enabled '-x' and/or '-v'.

This fixes commit 34e77af1bf.
2013-02-28 13:38:25 +00:00
Richard W.M. Jones
ce7cffa85a libutils: Don't include "guestfs-internal.h".
This mini-library shouldn't access library-internal stuff.  It should
only use the "guestfs-internal-frontend.h" header.
2013-02-27 14:07:25 +00:00
Richard W.M. Jones
1ea7752e95 lib: Move 'for_each_disk' function back into libvirt-domain.c.
This function is no longer called from anywhere outside the library,
or even outside libvirt-domain.c.

This is just code motion, except for the size_t changes which are
required in order to avoid signed overflow optimization error:

  assuming signed overflow does not occur when simplifying conditional
  to constant [-Werror=strict-overflow]
2013-02-27 11:33:05 +00:00
Richard W.M. Jones
4c5c555eeb generator: Line up GUESTFS_EVENT_ALL. 2013-02-26 22:11:40 +00:00
Richard W.M. Jones
c29660588f generator: Remove "deprecated macros for internal functions".
No need for these since these are internal functions that only code
under our control should have been calling.
2013-02-26 22:08:53 +00:00
Richard W.M. Jones
1ea73f4bdf Version 1.21.15. 2013-02-26 18:48:15 +00:00
Richard W.M. Jones
db30fe0cb0 lib: Fix memory leak in guestfs_list_filesystems.
This fixes commit 6e7f052ef4.
2013-02-26 18:48:15 +00:00
Richard W.M. Jones
b6cbd980fb tests: Add tests of guests to virt-df and virt-alignment-scan. 2013-02-26 18:48:14 +00:00
Richard W.M. Jones
5ff3845d28 tests: guests: Add blank disks plus libvirt test:// XML.
You can now run virt-df and virt-alignment-scan on all of the test
guests by doing:

./run ./df/virt-df -c test:///path/to/tests/guests/guests.xml
./run ./align/virt-alignment-scan -c test:///path/to/tests/guests/guests.xml

which is kinda cool.
2013-02-26 18:48:14 +00:00
Richard W.M. Jones
fe939cf842 lib: Turn guestfs___for_each_disk back into an internal library function.
Since the refactoring of virt-df and virt-alignment-scan, those
tools no longer use this function.
2013-02-26 17:02:32 +00:00
Richard W.M. Jones
6e3aab2f0c Partial rewrite of virt-alignment-scan to use parallel threads.
See previous commit (virt-df equivalent change) for the rationale.
2013-02-26 17:02:32 +00:00
Richard W.M. Jones
34e77af1bf Partial rewrite of virt-df to use parallel threads instead of single appliance.
Previously when you asked virt-df to show stats for all your libvirt
guests, it used a single appliance and tried to attach as many disks
as possible to it, even disks from different guests.

However this has been problematic: Not only is the code to do this
horrendously complex, but it's also insecure, and it doesn't interact
well with sVirt labels (see RHBZ#912499 comment 7).

In the meantime we discovered that running parallel appliances gives
you most of the performance of using a single appliance, but with a
lot less complexity and better guest isolation (see the documentation
in commit 680450f3b4).

Therefore this is a partial rewrite of virt-df so that in this case it
now uses parallel appliances.

Notes:

The '--one-per-guest' option is now the default and only way to do
things; this option now does nothing.

By default, the amount of parallelism to use is controlled by the
amount of free memory seen when virt-df starts up (subject to some
minima and maxima).  The user can control this through new command
line option '-P'.
2013-02-26 17:02:32 +00:00
Richard W.M. Jones
76266be549 lib: Export guestfs___add_libvirt_dom for use by virt-df and virt-alignment-scan.
See the comment in guestfs-internal-frontend.h in this commit.
2013-02-26 17:02:32 +00:00
Richard W.M. Jones
556e109765 tools: Introduce a mini-library for estimating max threads based on free memory.
This mini-library runs the 'free -m' command and greps the output to
estimate the max. number of libguestfs appliances we could run in
parallel in the remaining free memory.
2013-02-26 17:02:23 +00:00
Richard W.M. Jones
f8b92c0668 df: Always have TESTS= line even if appliance is disabled. 2013-02-26 17:02:23 +00:00
Richard W.M. Jones
a885dd025d virt-alignment-scan: Set LANG=C in test. 2013-02-26 17:02:23 +00:00
Richard W.M. Jones
4a6c8021b5 lib: Add a global MIN macro to guestfs-internal-all.h. 2013-02-26 10:13:00 +00:00
Richard W.M. Jones
d02610853d Version 1.21.14. 2013-02-25 17:39:11 +00:00
Hilko Bengen
ff0269e80f out-of-tree build: fix test-tool
(Not entirely sure whether using Gnulib to replace standard functions
is a good idea at all.)

link with libgnu:
  CCLD   libguestfs-test-tool
libguestfs_test_tool-test-tool.o: In function `main':
/home/bengen/src/deb/pkg-libvirt/libguestfs/debian/build-default/test-tool/../../../test-tool/test-tool.c:103: undefined reference to `rpl_getopt_long'
/home/bengen/src/deb/pkg-libvirt/libguestfs/debian/build-default/test-tool/../../../test-tool/test-tool.c:113: undefined reference to `rpl_optarg'
/home/bengen/src/deb/pkg-libvirt/libguestfs/debian/build-default/test-tool/../../../test-tool/test-tool.c:125: undefined reference to `rpl_optarg'
/home/bengen/src/deb/pkg-libvirt/libguestfs/debian/build-default/test-tool/../../../test-tool/test-tool.c:126: undefined reference to `rpl_optarg'
/home/bengen/src/deb/pkg-libvirt/libguestfs/debian/build-default/test-tool/../../../test-tool/test-tool.c:109: undefined reference to `rpl_optarg'
libguestfs_test_tool-test-tool.o: In function `set_qemu':
/home/bengen/src/deb/pkg-libvirt/libguestfs/debian/build-default/test-tool/../../../test-tool/test-tool.c:382: undefined reference to `rpl_perror'
/home/bengen/src/deb/pkg-libvirt/libguestfs/debian/build-default/test-tool/../../../test-tool/test-tool.c:366: undefined reference to `rpl_perror'
libguestfs_test_tool-test-tool.o: In function `make_files':
/home/bengen/src/deb/pkg-libvirt/libguestfs/debian/build-default/test-tool/../../../test-tool/test-tool.c:416: undefined reference to `rpl_perror'
/home/bengen/src/deb/pkg-libvirt/libguestfs/debian/build-default/test-tool/../../../test-tool/test-tool.c:428: undefined reference to `rpl_perror'
2013-02-25 16:21:48 +00:00
Hilko Bengen
cd1558b89e out-of-tree build: fix daemon
CC     guestfsd-9p.o
In file included from ../../../daemon/9p.c:32:0:
../../../daemon/daemon.h:33:34: fatal error: guestfs-internal-all.h: No such file or directory
2013-02-25 16:21:48 +00:00
Richard W.M. Jones
680450f3b4 docs: Update guestfs-performance with parallel scaling numbers and test script. 2013-02-25 16:01:15 +00:00
Olaf Hering
ff80a54011 lib: avoid pragma usage in inspect-fs-windows
pragma GCC diagnostic is a gcc 4.6+ feature, compilation fails with
older compilers:

inspect-fs-windows.c: In function 'map_registry_disk_blob':
inspect-fs-windows.c:502: error: #pragma GCC diagnostic not allowed inside functions
inspect-fs-windows.c:503: error: #pragma GCC diagnostic not allowed inside functions
inspect-fs-windows.c:505: error: #pragma GCC diagnostic not allowed inside functions
make[3]: *** [libguestfs_la-inspect-fs-windows.lo] Error 1

Use memcpy instead of pragma to fix compile error.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
2013-02-25 11:18:36 +00:00
Richard W.M. Jones
455d6b1845 recipes: Add example converting from one format/filesystem to another. 2013-02-23 20:59:26 +00:00
Richard W.M. Jones
fadec0687f daemon: protocol: Fix memory leak when receiving FileIn file (RHBZ#914934).
This fixes commit 950951c67d.
2013-02-23 20:32:33 +00:00
Richard W.M. Jones
4136850f3c tests: Add a regression test for RHBZ#914931.
This involves adding a new test API which crashes the appliance in the
middle of a simulated upload, then a test which uses that API to test
for the libguestfs (library-side) crash.
2013-02-23 20:23:51 +00:00
Richard W.M. Jones
7953128ca6 protocol: Don't segfault if appliance crashes during FileIn upload (RHBZ#914931).
Instead of the segfault you now get a more informative error:

*stdin*:0: libguestfs: error: connection to daemon was closed unexpectedly.
This usually means the libguestfs appliance crashed.  Please enable
debugging (LIBGUESTFS_DEBUG=1) and rerun the command, then look at the
debug messages output prior to this error.
libguestfs: error: /dev/stdout: write: Broken pipe
libguestfs: error: file receive cancelled by daemon
2013-02-23 20:23:39 +00:00
Richard W.M. Jones
d950e1a3bc run: Refer to README and correct documentation for linking to script.
Any link works, even a hard link.
2013-02-23 08:19:10 +00:00
Richard W.M. Jones
1ca842d98b run: Relicense as LGPLv2+.
To allow reuse in other projects and because of the equivalent change
made by Eric Blake to the libvirt 'run' script.
2013-02-23 08:15:23 +00:00
Richard W.M. Jones
37796d70bf Update API support. 2013-02-20 23:20:45 +00:00
Richard W.M. Jones
b49eefdb15 Version 1.21.13. 2013-02-20 22:23:20 +00:00
Richard W.M. Jones
9d6aa8b537 Use guestfs___count_strings instead of custom versions in various places. 2013-02-20 22:18:10 +00:00
Richard W.M. Jones
907fbfff53 python: Use guestfs___free_string_list instead of custom version. 2013-02-20 22:18:10 +00:00
Richard W.M. Jones
4ede94ab7b ocaml: Use guestfs___free_string_list instead of custom-coded one.
It should be possible to add the guestfs___free_string_list to
dllmlguestfs.so, but I cannot work out exactly how to do this.  As a
result we end up using src/utils.c directly.
2013-02-20 22:18:10 +00:00
Richard W.M. Jones
6ee164d47a ocaml: Missing #include <config.h> in generated file. 2013-02-20 22:18:10 +00:00
Richard W.M. Jones
27e6347b75 lua: Use guestfs___free_string_list instead of custom-coded version. 2013-02-20 22:18:09 +00:00
Richard W.M. Jones
0b7acf50b6 fish: Use guestfs___{free_string_list,count_strings} utility functions.
Instead of custom-coded versions.
2013-02-20 19:32:11 +00:00
Richard W.M. Jones
e27295c578 libutils: Add guestfs___count_strings utility function to common library. 2013-02-20 19:24:21 +00:00
Richard W.M. Jones
7ef461948e erlang: Use guestfs___free_string_list from libutils, instead of custom version. 2013-02-20 19:16:47 +00:00
Richard W.M. Jones
04723b4dd1 lib: Create libutils convenience library.
The libutils convenience library is a place for code shared between
the main library, language bindings and virt tools.  Note that the
code is statically linked into both the library, each binding and each
tool, but this is an improvement because (a) the source is shared and
(b) libguestfs.so can export fewer private functions.

Currently it contains the cleanup functions, and the functions
guestfs___free_string_list function and guestfs___for_each_disk.

guestfs___for_each_disk has changed so that it no longer
unconditionally sets the error in the guestfs handle.  Instead callers
can control error handling.
2013-02-20 19:15:05 +00:00
Richard W.M. Jones
a4953090e1 lib: Rename guestfs_error_errno as guestfs___error_errno, etc.
These are internal functions.  Very old versions of libguestfs used to
export them, but they haven't been (and shouldn't be) exported for a
long time.

Also remove the unused guestfs_error function.
2013-02-20 17:09:52 +00:00
Richard W.M. Jones
1a2465c187 build: Remove long and mostly irrelevant comment about libtool versioning. 2013-02-20 16:05:11 +00:00
Richard W.M. Jones
2101324965 build: Rearrange src/Makefile.am into a more logical order.
This is just code motion.
2013-02-20 16:03:14 +00:00
Richard W.M. Jones
6566621345 tests: Add valgrind suppression for libvirt 1.0.2 memory leak.
Leak reported as RHBZ#913145.
2013-02-20 14:20:08 +00:00
Richard W.M. Jones
b7ab6de628 tests: Add valgrind suppression variant for new manifestation of an old libvirt memory leak. 2013-02-20 14:19:37 +00:00
Richard W.M. Jones
61162bdce1 lib: Use CLEANUP_* macros to simplify XPath query code. 2013-02-20 13:50:43 +00:00
Richard W.M. Jones
b10a6cfe24 rescue: Improve error messages in the test script. 2013-02-20 11:28:50 +00:00
Richard W.M. Jones
175d6ba432 faq: Add section for developers, including how to send patches and propose features. 2013-02-20 10:30:44 +00:00
Richard W.M. Jones
065861ce6b docs: Rewrite security section (thanks Dan Berrange). 2013-02-20 10:08:21 +00:00
Richard W.M. Jones
8671cfa343 Version 1.21.12. 2013-02-19 19:19:29 +00:00
Richard W.M. Jones
a1c89bf03d build: Only add 'serial-tests' for automake >= 1.12 (thanks Hilko Bengen).
Earlier versions of automake complain if they get a configuration
parameter which they don't understand.  The error is:

configure.ac:27: error: option 'serial-tests' not recognized

Use some m4 hackery to work around this.
2013-02-19 19:19:22 +00:00
Richard W.M. Jones
c7ba91761c handle: Define DEFAULT_MEMSIZE, MIN_MEMSIZE constants.
This is just code motion.
2013-02-19 14:30:20 +00:00
Richard W.M. Jones
70514c7f7e ruby: Add binding for guestfs_event_to_string. 2013-02-19 13:41:58 +00:00
Richard W.M. Jones
0f849029d1 python: Add binding for guestfs_event_to_string. 2013-02-19 13:41:58 +00:00
Richard W.M. Jones
e9d83e94a2 perl: Add binding for guestfs_event_to_string. 2013-02-19 13:41:58 +00:00
Richard W.M. Jones
7e71c9fb34 java: Use guestfs_event_to_string instead of generated code. 2013-02-19 13:41:58 +00:00
Richard W.M. Jones
2a8de9001e fish: Use guestfs_event_to_string instead of guestfish-specific generated functions. 2013-02-19 13:41:57 +00:00
Richard W.M. Jones
5c513060b1 ocaml: Add binding for Guestfs.event_to_string and use it in events test. 2013-02-19 13:41:57 +00:00
Richard W.M. Jones
b793fafcb7 New C only API: guestfs_event_to_string. 2013-02-19 13:41:57 +00:00
Richard W.M. Jones
6902f093ff handle: Translatable string in guestfs_parse_environment. 2013-02-18 14:02:21 +00:00
Richard W.M. Jones
0e0eec76d9 generator: Whitespace changes. 2013-02-18 13:04:24 +00:00
Richard W.M. Jones
cbfa394bfc lib: Fix memory leak when the 'lpj' setting is read from dmesg.
It was failing to clean up and close the 'struct command' buffer,
because commit 94d90f03e2 added an
incomplete patch to use CLEANUP_CMD_CLOSE.

This fixes commit 94d90f03e2.
2013-02-15 14:44:22 +00:00
Richard W.M. Jones
5c6895bda1 java: Print a better error message when JVM version is too old.
This fixes commit 87d1f7714f.
2013-02-15 14:25:25 +00:00
Richard W.M. Jones
87d1f7714f java: Note that JVM >= 1.6 is now required. 2013-02-15 12:57:19 +00:00
Richard W.M. Jones
c598e14052 appliance: Use a glibc trick to try to display a stack trace if a program in the appliance segfaults. 2013-02-14 22:15:25 +00:00
Richard W.M. Jones
989d3c7691 Version 1.21.11. 2013-02-14 18:10:02 +00:00
Richard W.M. Jones
9021351c8e tests: mountable: Add test-mountable-inspect.sh to EXTRA_DIST.
This fixes commit 7d976657e6.
2013-02-14 16:33:29 +00:00
Matthew Booth
52b7418670 Fix API doc errors 2013-02-13 10:38:59 +00:00
Matthew Booth
f0f8d7ce78 gobject: Fix doc generation of L<guestfs(3)/CVE-2010-3851> 2013-02-13 10:30:51 +00:00
Richard W.M. Jones
23f8bd4fac daemon: Fix RESOLVE_MOUNTABLE, internal_parse_mountable.
- The mountable->volume field was not being initialized on the
  device path.

- XDR string fields cannot be NULL.

This fixes commit 7d976657e6.
2013-02-12 17:09:44 +00:00
Richard W.M. Jones
db554cf271 tests: mountable: Print error message if guestfs_create fails. 2013-02-12 17:02:33 +00:00
Richard W.M. Jones
4f7d1b3ae7 tests: Add Fedora btrfs phony guest to target list.
This fixes commit 754e819438.
2013-02-12 17:01:44 +00:00
Richard W.M. Jones
77c57ab843 tests: Reorder the tests so test guest is created before it's used by mountable test.
This fixes commit 7d976657e6.
2013-02-12 17:00:10 +00:00
Richard W.M. Jones
1399005d7e examples: Ensure each example program is documented. 2013-02-12 16:31:10 +00:00
Richard W.M. Jones
e84d6e6102 examples: Rename example programs, replacing '_' with '-'. 2013-02-12 16:31:10 +00:00
Matthew Booth
4215d0ca68 mountable: Test inspection of fedora image 2013-02-12 15:51:15 +00:00
Matthew Booth
7ba0e10501 inspect: Update inspect_os to use mountables
This fixes inspection of guests which use btrfs subvolumes.
2013-02-12 15:51:15 +00:00
Matthew Booth
7d976657e6 New internal API: internal_parse_mountable 2013-02-12 15:51:06 +00:00
Matthew Booth
b0abf10b9f build: Minor cleanup in daemon/Makefile.am 2013-02-12 15:29:19 +00:00
Matthew Booth
754e819438 btrfs: Make a stub Fedora btrfs guest for inspection testing 2013-02-12 13:49:26 +00:00
Matthew Booth
6e7f052ef4 mountable: Make list-filesystems return btrfsvols 2013-02-12 13:45:54 +00:00
Matthew Booth
bcb933a0c1 btrfs: Update btrfs_subvolume_list to take Mountable_or_Path
btrfs_subvolume_list can now take either the path of a mounted btrfs
filesystem, or a mountable describing the location of a btrfs
filesystem, or one of its volumes. In the latter case, the filesystem
will be automatically mounted outside of /sysroot before running the
btrfs tool, and unmounted afterwards.
2013-02-12 13:39:14 +00:00
Matthew Booth
72aaf56fed mount: Add mount_vfs_nochroot
This internal function allows mounting a mountable outside /sysroot.
2013-02-12 13:38:51 +00:00
Richard W.M. Jones
ec6a4de37a faq: Add common questions about virt-resize/virt-sparsify in place support. 2013-02-12 12:04:35 +00:00
Richard W.M. Jones
954e315d21 faq: Fix some small typos in section on virt-sparsify. 2013-02-12 11:56:16 +00:00
Richard W.M. Jones
6c5577e403 faq: Update RHEL information. 2013-02-12 11:55:45 +00:00
Richard W.M. Jones
cd47df1fe5 test-tool: Point to SELinux documentation for further information. 2013-02-12 10:55:26 +00:00
Richard W.M. Jones
0e79b9dd03 examples: Add all the C examples to the guestfs-examples(3) man page. 2013-02-11 21:44:39 +00:00
Richard W.M. Jones
09c4f94c9d build: Separate out *_CPPFLAGS from *_CFLAGS.
This is pretty pointless.
2013-02-11 21:36:27 +00:00
Richard W.M. Jones
bbb637f962 test-tool: Get rid of the "=== Test starts here ===" banner.
It confuses things, because that is not always the start
of the output.
2013-02-11 21:22:25 +00:00
Richard W.M. Jones
ee61d16e3e test-tool: Display SELinux status in output of libguestfs-test-tool. 2013-02-11 21:21:01 +00:00
Richard W.M. Jones
45b4271579 Version 1.21.10. 2013-02-11 19:38:55 +00:00
Richard W.M. Jones
05444da983 tests: Add a regression test for stack overflow in events (RHBZ#909624).
Note this is a check-slow test since generating 1,000,000 progress
events take a few minutes.
2013-02-11 18:15:48 +00:00
Richard W.M. Jones
b3cf5d1d96 proto: Fix stack overflow when there are many progress events (RHBZ#909624).
Thanks: Eric Blake.
2013-02-11 18:15:48 +00:00
Richard W.M. Jones
a43f88b1c5 daemon: Allow rate to be specified in 'debug progress'.
There are now two forms of the 'debug progress' command:

(1) debug progress <n> (the original form) generates ordinary
rate-limited progress messages for <n> seconds.

(2) debug progress <n> <rate> generates progress messages every <rate>
microseconds for <n> seconds.

The second form omit the usual rate-limiting, and so wouldn't
be generated like this from an ordinary API call.  However this
is useful for testing events (see RHBZ#909624).
2013-02-11 18:02:55 +00:00
Matthew Booth
942e139562 mountable: Implement Mountable_or_Path
A Mountable_or_Path argument is passed as a mountable_t. A new type is
added to mountable_t to handle already mounted paths.
2013-02-11 16:54:42 +00:00
Richard W.M. Jones
93d4fddaef lib: Add format attribute for GCC 4.8 in two places. 2013-02-11 16:10:17 +00:00
Richard W.M. Jones
984431a9ef daemon: Force disable -Wsuggest-attribute=format warning around asprintf_nowarn, for GCC 4.8. 2013-02-11 16:10:17 +00:00
Richard W.M. Jones
f226133c1a lib: Define GUESTFS_GCC_VERSION in the internal header.
Note that you have to use this as follows:

#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= x0y0z /* gcc >= x.y.z */

since GUESTFS_GCC_VERSION is not defined unless it's GCC.
2013-02-11 16:10:17 +00:00
Matthew Booth
ef2276654e generator: Create Mountable_or_Path, initially identical to Dev_or_Path 2013-02-11 15:43:53 +00:00
Matthew Booth
47b929b789 mountable: Implement Mountable support for all apis which take it
A Mountable is passed from the library to the daemon as a string. The daemon
stub parses it into a mountable_t, which it passes to the implementation.

Update all implementations which now take a mountable_t.
2013-02-11 15:42:58 +00:00
Matthew Booth
d5817537fa generator: Convert relevant arguments from Device to Mountable
This change updates the api style of all apis which should take Mountable
descriptions rather than block devices. It also updates the documentation
accordingly, but doesn't implement any functional changes.
2013-02-11 15:39:31 +00:00
Richard W.M. Jones
007c2f236d test-tool: Document how to change SELinux settings. 2013-02-11 14:14:36 +00:00
Richard W.M. Jones
b1a89d3b1c test-tool: Document how to run with alternate libvirt. 2013-02-11 14:13:44 +00:00
Richard W.M. Jones
3877cab329 test-tool: exec qemu in the wrapper script.
This ensures that libvirt can control qemu directly, eg. being able to
send it signals.
2013-02-11 13:41:40 +00:00
Richard W.M. Jones
20fd81147d test-tool: On i386, upstream qemu program is now called 'qemu-system-i386'.
For a while, the upstream qemu i386 emulator has been called
'qemu-system-i386' (instead of just 'qemu').  Fix test-tool so it
calls the right program.
2013-02-11 13:21:51 +00:00
Richard W.M. Jones
df983d1994 test-tool: Don't call guestfs_set_qemu before guestfs handle is initialized (RHBZ#909836).
Because of evolution of the code, if the user used the --qemu or
--qemudir options, libguestfs-test-tool would segfault because
guestfs_set_qemu was being called before the guestfs handle was
opened.

Change the code so this doesn't happen, and also remove the global 'g'
variable to make the code a bit more robust.

Bug found by Amit Shah.
2013-02-11 13:21:51 +00:00
Richard W.M. Jones
e4495b24bc daemon: link: Remove use of PATH_MAX.
Replace readlink calls with gnulib areadlink function.
2013-02-11 13:21:51 +00:00
Richard W.M. Jones
c3afef3eec daemon: xattr: Remove use of PATH_MAX. 2013-02-11 13:21:51 +00:00
Richard W.M. Jones
09f3913734 daemon: realpath: Remove use of both PATH_MAX and NAME_MAX. 2013-02-11 13:21:51 +00:00
Richard W.M. Jones
9c9ceec6b7 daemon: initrd: Remove use of PATH_MAX and other cleanups.
- Move variables to the top.
- Rearrange comments to make more sense.
2013-02-11 13:21:51 +00:00
Richard W.M. Jones
1703c6841b daemon: find0: Remove use of PATH_MAX. 2013-02-11 13:21:51 +00:00
Richard W.M. Jones
e527aed895 getline: Rename &n parameter as &allocsize.
The second parameter passed into getline(3) is the size of the
allocated buffer, *NOT* the length of the returned line.  This can be
confusing, so rename this parameter as 'allocsize' consistently
throughout the code.

This is just code motion.
2013-02-11 13:21:51 +00:00
Richard W.M. Jones
e0a3a7c1e5 docs: Improve reasons for using libguestfs-make-fixed-appliance.
Thanks: Richard Harman.
2013-02-09 22:38:24 +00:00
Richard W.M. Jones
d6c0ff055d launch: libvirt: Make it clear that setsockcreatecon debug message is just a warning.
This was disturbing to some users, but other users saw the warning
when it was really something they should pay attention to.  Make it
clear that it's a warning, unless people are really using SELinux +
sVirt.

Thanks: Richard Harman.
2013-02-09 21:29:35 +00:00
Richard W.M. Jones
8ad8e1075b Version 1.21.9. 2013-02-09 21:02:11 +00:00
Richard W.M. Jones
d538af8a0a rescue: Count the mountable filesystems when displaying the 'suggest' message. 2013-02-09 20:53:18 +00:00
Richard W.M. Jones
4255db65e5 tools: Use CLEANUP_* macros in several C tools. 2013-02-09 20:37:03 +00:00
Richard W.M. Jones
20a562321c generator: Export libxml2 CLEANUP_* macros unconditionally.
These call abort() if libxml2 is not actually installed, but that
should never happen inside the library or tools.
2013-02-09 17:49:11 +00:00
Richard W.M. Jones
94d90f03e2 lib: Define CLEANUP_CMD_CLOSE macro and use it throughout the library. 2013-02-08 18:14:41 +00:00
Richard W.M. Jones
59b296fecc tools, tests: Use "guestfs-internal-frontend.h" header.
Instead of redefining STREQ, etc.
2013-02-08 16:15:25 +00:00
Richard W.M. Jones
30029b7ffb lib: Use CLEANUP_FREE_<struct>, CLEANUP_FREE_<struct>_LIST macros in a few places in the library. 2013-02-08 16:12:04 +00:00
Richard W.M. Jones
5f54da6fdf lib: Add CLEANUP_FREE_<struct>, CLEANUP_FREE_<struct>_LIST macros for API structs.
For example:

 {
   CLEANUP_FREE_STAT struct guestfs_stat *stat = guestfs_stat (g, "/foo");

   // stat is freed automatically when we leave the scope.
 }

The new header file "guestfs-internal-frontend-cleanups.h"
includes definitions for these.  It should not be included
directly.
2013-02-08 16:12:04 +00:00
Richard W.M. Jones
5e770c8f6a lib: Allow guestfs_free_* functions to be safely called with a NULL pointer.
This is so they work just like 'free'.
2013-02-08 16:12:04 +00:00
Richard W.M. Jones
7b7cfa62e3 lib: Remove explicit defines of _BSD_SOURCE.
An equivalent is defined already in <config.h>.
2013-02-08 16:12:04 +00:00
Richard W.M. Jones
cab1a0c1d9 generator: Add #ifndef defense around guestfs-internal-actions.h file. 2013-02-08 15:48:52 +00:00
Matthew Booth
8fb2306be4 generator: Add new Mountable argument type
This type is initially identical to Device.
2013-02-08 14:59:00 +00:00
Matthew Booth
6e7f95b669 inspect: Fix improperly ignored error in check_filesystem 2013-02-08 14:53:05 +00:00
Matthew Booth
7d6b5bb837 inspect: Don't re-implement list_filesystems in inspect_os 2013-02-08 14:42:37 +00:00
Matthew Booth
dd58db7329 Fix bogus partition number passed to guestfs___check_for_filesystem_on
Partition number was being passed to guestfs___check_for_filesystem_on
based on an index in list_partition. However, this ignores the
possibility of multiple block devices.

This change makes guestfs___check_for_filesystem_on examine the
passed-in device directly to determine if it is a whole device, or
what its partition number is.
2013-02-08 14:42:37 +00:00
Matthew Booth
a7d7e8176f New API: is_whole_device 2013-02-08 14:42:37 +00:00
Matthew Booth
3045c0cbaf btrfs: Fix btrfs_subvolume_list on F18 (RHBZ#903620).
The output of btrfs subvolume list has changed in F18 to include generation,
which breaks the parsing in btrfs_subvolume_list. This change replaces sscanf
with a more robust regular expression. The new regular expression should also
handle the addition of future unexpected columns.
2013-02-08 09:09:25 +00:00
Richard W.M. Jones
c78ec7e085 daemon: Check parameter of base64-out and tar-out before running external command (RHBZ#908322).
For base64-out, check the filename parameter exists and is not a
directory.

For tar-out, check the dir parameter exists and is a directory.
2013-02-06 14:56:56 +00:00
Matthew Booth
ca056d53bd generator: Add visibility to action struct
The visibility field in action replaces in_fish, in_docs and internal.
The defined types are:

VPublic:
  A public API. This is exported and documented in all language
  bindings, and in guestfish.

VStateTest:
  A public API which queries the library state machine. It is exported
  and documented in all language bindings, but not guestfish.

VBindTest:
  An internal API used only for testing language bindings. It is
  guarded by GUESTFS_PRIVATE in the C api, but exported by all other
  language bindings as it is required for testing. If language
  bindings offer any way to guard use of these apis, that mechanism
  should be used. It is not documented anywhere.

VDebug:
  A debugging API. It is exported by all language bindings, and in
  guestfish, but is not documented anywhere.

VInternal:
  An internal-only API. It is guarded by GUESTFS_PRIVATE in the C api,
  and not exported at all in any other language binding. It is not
  documented anywhere.
2013-02-06 13:53:28 +00:00
Richard W.M. Jones
f9bafde5e7 daemon: download: Add extra check that download file is not a directory (RHBZ#908321). 2013-02-06 13:27:26 +00:00
Richard W.M. Jones
f473a173b8 daemon: Add more information to certain calls to perror.
Replace selected calls to 'perror (filename)' with:

  fprintf (stderr, "syscall: %s: %m\n", filename);

so that more information is available about precisely which syscall
failed.

Note this is *not* reply_with_perror.  These messages are only printed
in verbose output, for the benefit of debugging.
2013-02-06 13:14:07 +00:00
Richard W.M. Jones
f631e84102 9p: Missing call to reply_with_perror. 2013-02-06 12:59:00 +00:00
Richard W.M. Jones
c98ef8d089 Version 1.21.8. 2013-02-05 20:27:25 +00:00
Richard W.M. Jones
a0a4ee5245 Use 'supermin' and 'supermin-helper' in preference to febootstrap.
Febootstrap has been renamed upstream to 'supermin':
https://www.redhat.com/archives/libguestfs/2013-February/msg00004.html

This commit changes libguestfs so it can use either program to build
the supermin appliance.
2013-02-05 15:31:05 +00:00
Richard W.M. Jones
72dd398679 daemon: Call wipefs before mkfs to work around pathological behaviour in btrfs.
See: RHBZ#907554, http://www.spinics.net/lists/linux-btrfs/msg21197.html
2013-02-04 21:54:15 +00:00
Richard W.M. Jones
7e25e0780e FAQ: Update section on sVirt. 2013-02-04 21:54:08 +00:00
Richard W.M. Jones
4075ed9247 build: Add src/guestfs-internal-{all,frontend}.h to EXTRA_DIST.
This fixes commit ec3b75e5ff.
2013-02-04 13:12:28 +00:00
Richard W.M. Jones
776ffbfaec Version 1.21.7. 2013-02-04 13:03:25 +00:00
Richard W.M. Jones
4940bd9a9e fish: Be stricter about boolean values.
Previously I noticed that bfan used this command without any error:

><fs> hivex-open /WINDOWS/system32/config/software write:ture
                                                   ^^^^^^^^^^

This was because the code allowed any string to be evaluated as a
boolean.

The new code is stricter.  It allows the following strings only case
insensitive (everything else is an error):

  1
  true
  t
  yes
  y
  on

  0
  false
  f
  no
  n
  off
2013-02-04 12:45:02 +00:00
Richard W.M. Jones
d012b729fa ruby: Include "guestfs-internal-frontend.h" in extension.
Also undefine '_' symbol defined by Ruby's internal headers.

This fixes commit ec3b75e5ff.
2013-02-04 12:17:52 +00:00
Richard W.M. Jones
9e27a1556c perl: Include "guestfs-internal-frontend.h" in XS file.
Also undefine '_' symbol defined by Perl's internal headers.

This fixes commit ec3b75e5ff.
2013-02-04 11:49:04 +00:00
Richard W.M. Jones
5e4f03ccf2 README: Format the list of requirements better. 2013-02-02 15:24:23 +00:00
Richard W.M. Jones
0d18a8b407 Update copyright dates for 2013. 2013-02-02 13:56:19 +00:00
Richard W.M. Jones
791ad3e9e6 fish: Use CLEANUP_* macros in a lot of places. 2013-02-01 16:18:42 +00:00
Richard W.M. Jones
6c1aca5ae2 fish: Use CLEANUP_FREE in parse_config. 2013-02-01 15:54:13 +00:00
Richard W.M. Jones
4b20a20d33 Remove TMP_TEMPLATE_ON_STACK macro. 2013-02-01 14:48:35 +00:00
Richard W.M. Jones
42bffcd00a Remove all occurrences of the bad_cast (lowercase) function.
Not to be confused with the libxml2 macro 'BAD_CAST' which converts
from 'signed char *' to 'unsigned char *'.

The 'bad_cast' function was defined and used all over the place as a
replacement for a '(char *)' cast.  I think it is better to make these
casts explicit, instead of hiding them in an obscure function.
2013-02-01 14:16:51 +00:00
Richard W.M. Jones
ec3b75e5ff Rearrange internal header files.
This commit rearranges the internal header files.

"src/guestfs-internal.h" is just for the library, as before.

"src/guestfs-internal-frontend.h" is for use by all library, bindings,
tools C code, but NOT the daemon.

"src/guestfs-internal-all.h" is for use by all C code including the
daemon.

This is just code motion, but it has some important consequences:

(1) We can use the CLEANUP_* macros in bindings and tools code.

(2) We can get rid of TMP_TEMPLATE_ON_STACK.

(3) We will (in future) be able to stop bindings and tools code from
using the safe_* allocation functions (which are NOT safe to use
outside the library alone).
2013-02-01 14:07:25 +00:00
Cole Robinson
63c324e6c4 tests: Handle changing QEMUDIR
qemu-wrapper isn't regenerated if QEMUDIR is changed, so just
delete it and force regeneration.

Additionally we can drop the silent binary check, since
check-with-upstream-qemu-1 already does a similar test with --version
that will actually report an error to the user.
2013-01-31 16:30:28 +00:00
Matthew Booth
27b995c841 Make internal-only functions and structures private
Certain functions are intended to be internal only, but we currently
export them anyway. This change moves them into a separate section of
guestfs.h protected by a GUESTFS_PRIVATE variable. This change also
enables private structs, but doesn't implement any.

This change only affects the C api. Language bindings aren't affected,
but probably should be in the future.
2013-01-30 17:27:01 +00:00
Matthew Booth
1dd9bf73b7 build: Fix haskell dependencies and parallel build
Without this change all the tests in the haskell bindings are rebuilt
every time. The primary motivation for this change is to fix this.

The fix for the above also allows parallel builds to be re-enabled.
2013-01-30 10:53:02 +00:00
Matthew Booth
63c50c7847 build: Add common rule for sources shared between daemon and library 2013-01-29 16:24:08 +00:00
Richard W.M. Jones
be4a3d77c4 daemon: hivex: Rewrite filename param of hivex_commit to include sysroot (RHBZ#905341). 2013-01-29 10:21:51 +00:00
Richard W.M. Jones
908c45567c Version 1.21.6. 2013-01-28 18:42:05 +00:00
Richard W.M. Jones
950951c67d daemon: Use the new CLEANUP_* macros to simplify code. 2013-01-28 18:01:43 +00:00
Richard W.M. Jones
233055974d daemon: Add CLEANUP_* macros which automatically free memory when leaving scope.
cf commit 98b64650c8
2013-01-28 18:01:39 +00:00
Richard W.M. Jones
071de5ccfb daemon: Allow free_strings (NULL) and free_stringslen (NULL, ..).
Equivalent to free (NULL).
2013-01-28 18:01:20 +00:00
Richard W.M. Jones
3a8a62c3e4 lib: Further use of CLEANUP_* macros. 2013-01-28 18:01:19 +00:00
Richard W.M. Jones
cd3b626a33 launch: libvirt: Use CLEANUP_* macros.
Also implement macros for cleaning up libxml2 objects.
2013-01-28 18:01:19 +00:00
Richard W.M. Jones
5a3da36626 inspect: Use CLEANUP_* macros in inspection code. 2013-01-28 18:01:19 +00:00
Richard W.M. Jones
98b64650c8 lib: Add CLEANUP_* macros which automatically free things when leaving scope.
Use the macro like this to create temporary variables which are
automatically cleaned up when the scope is exited:

  {
    CLEANUP_FREE char *foo = safe_strdup (bar);
    ...
    // no need to call free (foo)!
  }

The following code is also valid.  The initialization of foo as 'NULL'
prevents any chance of free being called on an uninitialized pointer.
It may not be required in all cases.

  {
    CLEANUP_FREE char *foo = NULL;
    ...
    foo = safe_malloc (100);
    ...
    // no need to call free (foo)!
  }

This is also valid:

  {
    CLEANUP_FREE char *foo = ..., *bar = ...;
    ...
    // no need to call free (foo) or free (bar)!
  }

The CLEANUP_FREE_STRING_LIST macro calls guestfs___free_string_list
on its argument.  The argument may be NULL.

The CLEANUP_HASH_FREE macro calls hash_free on its argument.  The
argument may be NULL.

Important implementation note:
------------------------------

On GCC and LLVM, this is implemented using __attribute__((cleanup(...))).

There is no known way to implement this macro on other C compilers, so
this construct will cause a resource leak.

Important note about close/fclose:
----------------------------------

We did NOT implement 'CLEANUP_CLOSE' or 'CLEANUP_FCLOSE' macros.  The
reason is that I am not convinced that these can be used safely.  It
would be OK to use these to collect file handles along failure paths,
but you would still want a regular call to 'close'/'fclose' since you
must test for errors, and so you end up having to do:

  if (close (fd) == -1) {
    // failure case
    // avoid double-close in cleanup handler:
    fd = -1;
    ...
  }
  // avoid double-close in cleanup handler:
  fd = -1;
  ...
2013-01-28 18:01:19 +00:00
Richard W.M. Jones
acb85dafb1 Allow guestfs___free_string_list (NULL).
Equivalent to free (NULL).
2013-01-28 18:01:19 +00:00
Richard W.M. Jones
aab796c608 perl, python, ruby: Add definition of EVENT_ALL in these languages. 2013-01-28 18:01:19 +00:00
Richard W.M. Jones
27c81f3175 generator: Define all_events_bitmask.
In the C bindings, use this more accurate mask instead of 'all bits
set'.

In the Java bindings, use this instead of open coding.
2013-01-28 18:01:19 +00:00
Richard W.M. Jones
ded72a96f0 header: Minor whitespace fix. 2013-01-28 18:01:19 +00:00
Richard W.M. Jones
f3976de591 header: Deprecate LIBGUESTFS_HAVE_* in favour of GUESTFS_HAVE_*. 2013-01-28 18:01:19 +00:00
Richard W.M. Jones
d3068a3aff header: Link to guestfs-examples(3) man page from header file. 2013-01-28 18:01:19 +00:00
Matthew Booth
a0d874725d Update vim line length to 70
Apparently this makes it the same as emacs or something.
2013-01-24 15:00:49 +00:00
Richard W.M. Jones
abb1d46636 python: Inherit from 'object' base class.
This fixes the following Debian bug:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698771

For an overview, see this question and the links from there:
http://stackoverflow.com/questions/4015417/python-class-inherits-object
2013-01-24 13:09:16 +00:00
Richard W.M. Jones
ec8939fd47 launch: libvirt: Add 'is_root' flag to the params struct.
This is just code motion, but it allows us to read this flag inside
the 'construct_libvirt_xml_seclabel' function in future (as a possible
way to fix RHBZ#890291).
2013-01-22 14:43:37 +00:00
Richard W.M. Jones
085b86a95a libvirt: Add debugging when opening libvirt handle.
When debugging is enabled, this produces output like below.  This is
useful when diagnosing what URI libguestfs is using.

libguestfs: opening libvirt handle: URI = NULL, auth = virConnectAuthPtrDefault, flags = 0
libguestfs: successfully opened libvirt handle: conn = 0xb05580
2013-01-22 13:50:57 +00:00
Richard W.M. Jones
875dc11364 launch: libvirt: Refactor seclabel code.
This is just code motion.
2013-01-22 13:45:11 +00:00
Richard W.M. Jones
ed5a083891 Version 1.21.5. 2013-01-21 22:16:07 +00:00
Richard W.M. Jones
4d8bdf0357 fuse: Use guestfs_rename to implement rename(2) syscall (RHBZ#895910). 2013-01-21 17:00:04 +00:00
Richard W.M. Jones
159e8f8c3a New API: rename: Rename file within the same filesystem (RHBZ#895910). 2013-01-21 17:00:04 +00:00
Matthew Booth
f956457b5d docs: Fix cut/paste error in pread_device 2013-01-21 15:57:23 +00:00
Richard W.M. Jones
28e34290ff fuse: If guestfs_last_errno returns 0, don't return no error to FUSE layer.
guestfs_last_errno (g) == 0 doesn't mean "no error".  It means the
errno was not captured.  In this case we have to substitute some sort
of errno, so choose EINVAL arbitrarily.
2013-01-21 14:42:48 +00:00
Richard W.M. Jones
533082e282 daemon: Change ln, ln-f (hard-link) APIs to use link(2) instead of external ln (RHBZ#895905).
The reasons to do this are twofold:

(a) It's probably a tiny bit faster.

(b) It lets us capture the real errno if the link(2) syscall fails.

The errno is also passed through guestmount, fixing RHBZ#895905:

+ guestmount -a test1.img -m /dev/sda1:/ -m /dev/sda2:/boot /tmp/mnt
+ touch /tmp/mnt/foo
+ cd /tmp/mnt
+ ln foo boot/foo
ln: failed to create hard link ‘boot/foo’ => ‘foo’: Invalid cross-device link
2013-01-21 14:23:07 +00:00
Richard W.M. Jones
ebc86ae6d7 Fix checksums-out command (RHBZ#895904).
This was broken by the earlier
commit 0306c98d31.

This commit also adds a regression test.
2013-01-21 11:14:56 +00:00
Richard W.M. Jones
e18e20793f tests: virt-make-fs: Allow btrfs to be skipped. 2013-01-21 08:15:54 +00:00
Richard W.M. Jones
2974b5d666 tests/qemu: Don't require LVM for these tests. 2013-01-18 17:23:43 +00:00
Richard W.M. Jones
64b229e8ff Version 1.21.4. 2013-01-18 08:18:24 +00:00
Richard W.M. Jones
d8f14591d1 daemon: lvm: Fix various paths relative to new lvm_system_dir.
This fixes commit 9fd41abd40.
2013-01-18 07:13:54 +00:00
Richard W.M. Jones
312d02afe4 tests: Don't construct the guests in parallel.
In automake 1.13, check_DATA is now built in parallel, resulting in it
trying to build 4 or 5 guests in parallel.
2013-01-18 07:13:53 +00:00
Hilko Bengen
aa83e7c7b8 Fix packagelist for current Debian-based systems 2013-01-18 07:02:15 +00:00
Hilko Bengen
111f444d69 inspector: Fix tests for out-of-tree builds 2013-01-18 07:01:09 +00:00
Hilko Bengen
9637bddc33 erlang: fix bindtests for out-of-tree build 2013-01-18 07:01:07 +00:00
Richard W.M. Jones
24c4178749 appliance: Add libcap to the appliance (thanks Skippy VonDrake). 2013-01-18 06:42:13 +00:00
Richard W.M. Jones
2c68aca9d7 automake: Force serial-tests.
automake 1.13 started to use stupid parallel tests by default,
breaking everything.
2013-01-17 18:21:20 +00:00
Richard W.M. Jones
9c8e47247b FAQ: Document "Could not allocate dynamic translator buffer" and how to fix it. 2013-01-17 18:10:14 +00:00
Matthew Booth
c61b589f9b gobject: Add pkg-config for gobject bindings 2013-01-17 15:06:09 +00:00
Olaf Hering
9fd41abd40 daemon: copy entire lvm directory
cp will fail if /etc/lvm is an empty directory. Copy the entire
directory and adjust environment variable.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

RWMJ:
 - Fixed a couple of whitespace issues.
2013-01-17 14:13:03 +00:00
Richard W.M. Jones
a710c42f0f Version 1.21.3. 2013-01-17 09:43:59 +00:00
Richard W.M. Jones
a0e9d310d1 ruby: Use updated package names, but allow fallback to the old names (RHBZ#894545).
Thanks Dominic Cleal.
2013-01-16 14:33:49 +00:00
Richard W.M. Jones
d4763a2e24 daemon: Suppress two false positives from Coverity.
Using // coverity[...] or /* coverity[...] */ comments in the source
it is possible to suppress specific Coverity errors.  The suppressed
error should occur in the line following the comment.

In this case I have suppressed two false positives from Coverity:

(a) We deliberately assign to a NULL pointer in order to cause a
segfault, for testing how the library reacts when this happens.
Coverity flags this, but it is not an error in this case.

(b) Coverity does not model global variables (a known shortcoming).
Therefore the code 'errno = posix_memalign (...)' cannot be modelled
by Coverity, even though the code is correct.  Coverity raises a false
positive about this.

(Thanks Kamil Dudka, Coverity)
2013-01-16 11:30:07 +00:00
Richard W.M. Jones
ce828c6afc podwrapper: Refresh podwrapper man page.
This also adds a rule so you can do:

 make podwrapper.1

if you want to read the documentation as a man page.
2013-01-15 18:40:17 +00:00
Richard W.M. Jones
0d2d26d8e7 java: Implement the event API. 2013-01-15 18:40:17 +00:00
Richard W.M. Jones
3f08d50863 java: Use defined constants for flags in call to guestfs_create_flags. 2013-01-15 18:40:17 +00:00
Richard W.M. Jones
05a67bcc25 java: Change synopsis in man page to show use of add_drive. 2013-01-15 18:40:16 +00:00
Richard W.M. Jones
7d89baa3e9 java: Tidy up javadoc. 2013-01-15 18:40:16 +00:00
Richard W.M. Jones
f58b6c5953 Refresh README file. 2013-01-15 18:40:16 +00:00
Richard W.M. Jones
20e23ab2a3 Update copyright dates for 2013.
On generated files in git and README.
2013-01-15 18:40:16 +00:00
Richard W.M. Jones
e051b270a2 haskell: Use unused bogus data types. 2012-12-29 14:28:47 +00:00
Richard W.M. Jones
bff29314df haskell: Typo in man page, lists -> list. 2012-12-29 13:57:24 +00:00
Richard W.M. Jones
60d744e32f haskell: Implement 'head' and 'tail' by hiding the Prelude functions. 2012-12-29 13:38:13 +00:00
Richard W.M. Jones
406e372469 haskell: Use 'import Guestfs as G' in test code.
The code is equivalent but shorter.
2012-12-29 13:35:07 +00:00
Richard W.M. Jones
67d59d0153 haskell: Document current state of Haskell bindings. 2012-12-29 13:26:38 +00:00
Richard W.M. Jones
1881be1e56 haskell: Fix RHashtable in the generator. 2012-12-29 13:16:07 +00:00
Richard W.M. Jones
3a72944597 haskell: Use .NOTPARALLEL in this directory. 2012-12-29 13:16:07 +00:00
Richard W.M. Jones
7718cb5afe haskell: Fix RStringList in generator. 2012-12-28 21:36:07 +00:00
Richard W.M. Jones
5ede0b21b0 haskell: Add tests of config functions. 2012-12-28 20:44:36 +00:00
Richard W.M. Jones
c9e0ff8831 haskell: Allow non-appliance tests to run when !ENABLE_APPLIANCE. 2012-12-28 20:19:20 +00:00
Richard W.M. Jones
604f9a79db haskell: Renumber tests according to Perl scheme. 2012-12-28 20:17:31 +00:00
Richard W.M. Jones
3e7dcc384a haskell: Enable RString, RConstString in generator. 2012-12-28 20:11:23 +00:00
Richard W.M. Jones
beebade874 haskell: Enable RBool in generator. 2012-12-28 19:59:31 +00:00
Richard W.M. Jones
11e111ec01 haskell: Replace deprecated INCLUDE directive.
The INCLUDE directive is obsolete.  You must now put the name of the
include file before the C function name.
2012-12-28 19:55:01 +00:00
Richard W.M. Jones
9ae248e03f arm: Recomment vexpress-a15 instead of vexpress-a9.
Neither works (because of lack of PCI) but A15 emulation is probably
better than A9 emulation.
2012-12-27 20:02:31 +00:00
Richard W.M. Jones
6c9aaf394f launch: appliance: Fix parsing of QEMU_OPTIONS.
If there was no quoting character, the options could run off the end
of the string and into whatever string which happened to be following
in memory.

This bug was revealed when libguestfs was compiled on arm.
2012-12-27 20:01:15 +00:00
Richard W.M. Jones
bcdaa46313 launch: appliance: Small refactoring of virtio-scsi detection code.
This is just code motion.
2012-12-27 19:36:33 +00:00
Richard W.M. Jones
a9d70d1ae4 Fix whitespace in configure.ac.
Standardize on 4 spaces for indentation in configure.ac file.
This is just a change of whitespace.
2012-12-27 18:55:34 +00:00
Richard W.M. Jones
364ee94b8d arm: Prevent -Wcast-align warnings.
See link below for a general description of the problem:

f8b62e4cd2
2012-12-27 18:08:55 +00:00
Richard W.M. Jones
5af94b5692 arm: Only use -device sga if qemu supports this device.
qemu-system-arm does not have the sgabios device.
2012-12-27 15:57:15 +00:00
Richard W.M. Jones
741c8606db lib: Remove useless cast.
'strings' is declared as char **, so the return type of
this expression will already be char *.  The cast is both
useless and potentially hides errors.
2012-12-27 15:27:20 +00:00
Richard W.M. Jones
4a877452f5 build: Fix ./configure --with-febootstrap-yum-config option.
This fixes commit bfddae7cee.

Also tested that all variants actually work.
2012-12-24 09:48:41 +00:00
Richard W.M. Jones
4b5d27869f Version 1.21.2. 2012-12-22 22:42:29 +00:00
Richard W.M. Jones
bfddae7cee build: Change --with-febootstrap-yum-config to --with-febootstrap-packager-config
For the rationale behind this renaming, see:
b8cbe191d0

You can still, for the time being, use
./configure --with-febootstrap-yum-config
but it's preferred to switch to the new option.  The new option is
identical, just renamed.

Qe still pass the deprecated --yum-config option to febootstrap
itself, since both old and new febootstrap support this.
2012-12-22 17:28:10 +00:00
Richard W.M. Jones
e73cf67762 inspection: Set fs->device field on swap devices.
For some reason the fs->device field was not set for swap devices.

Apparently this did not matter before (this bug has existed since at
least libguestfs 1.16), but in commit 6ee80b8dac we started to depend
on the fs->device field being non-NULL.  This resulted in segfaults
when inspecting any guest which had a swap device, eg:

 #0  __strcmp_sse42 () at ../sysdeps/x86_64/multiarch/strcmp-sse42.S:164
 #1  0x00007ffff7d740cb in parent_device_already_probed (g=0x703a70,
                        partition=0x6f79b0 "/dev/vda4") at inspect.c:156
 #2  0x00007ffff7d73e00 in guestfs__inspect_os (g=0x703a70) at inspect.c:83
 #3  0x00007ffff7cee11d in guestfs_inspect_os (g=0x703a70) at actions-1.c:397

This commit sets fs->device to the device name.

(Thanks Matthew Booth for first noticing this problem.)
2012-12-20 15:36:36 +00:00
Richard W.M. Jones
6628cc7ef6 Pass noapic on i686 kernel command line.
qemu 1.2 i686 TCG is buggy and hangs when emulating APIC.
https://bugzilla.redhat.com/show_bug.cgi?id=857026
2012-12-20 12:09:49 +00:00
Richard W.M. Jones
eca01c3105 faq: Suggest 'approx' (apt proxy) to speed up Debian builds.
Thanks Hilko Bengen.
2012-12-18 20:39:46 +00:00
Richard W.M. Jones
d1ad89520e tests: Skip windows.img tests if it is zero-sized.
If ntfs-3g is not installed, then tests/guests creates a 'windows.img'
file which is zero-sized.

This is problematical because other tests which use this image will
fail at best, or hit RHBZ#847549 (qemu/virtio-scsi bug) at worst.

Change the tests which use windows.img so they skip if 'windows.img'
has zero size.
2012-12-18 17:35:51 +00:00
Richard W.M. Jones
a34072e25b build: Add 'make print-subdirs' rule, useful for selectively running tests.
If you want to selectively run tests, or if the test suite fails half
way through, use:

  make print-subdirs

to print the subdirectories, select the ones you want to run / the
remaining ones, and do:

  make check SUBDIRS="..."
2012-12-18 16:28:23 +00:00
Richard W.M. Jones
fa162417ed daemon: Make gdisk into an optional dependency and optgroup.
Also document that gdisk is a dependency at all.

This fixes commit 956e30effa.
2012-12-18 11:52:41 +00:00
Richard W.M. Jones
2434a86da4 lua: tests: If $LUA is not set, set it to 'lua' instead of '/usr/bin/lua'. 2012-12-18 08:55:06 +00:00
Richard W.M. Jones
3f88f88c80 lua: Fix misapplied patch.
This fixes commit 5b70120293.
2012-12-18 08:53:34 +00:00
Richard W.M. Jones
8be9743e74 ruby: Disable -Wstrict-prototypes warning for Ruby headers. 2012-12-18 08:43:52 +00:00
Richard W.M. Jones
034d393bb1 docs: Properly document attach methods in the guestfs(3) man page. 2012-12-17 23:01:56 +00:00
Richard W.M. Jones
62f98d64a5 lua: Fix Lua configure test on Fedora.
On Debian, the lua pkg-config file is called "lua5.1.pc" (etc)
whereas on Fedora it's called "lua.pc" for all versions.
2012-12-17 23:01:56 +00:00
Hilko Bengen
5b70120293 lua: Use correct binary for tests 2012-12-17 22:24:53 +01:00
Hilko Bengen
f07e89c5f9 lua: Add ifdefs for Lua 5.2 compatibility 2012-12-17 22:24:53 +01:00
Hilko Bengen
05103cc693 lua: Use pkg-config to determine Lua version, parameters 2012-12-17 22:24:52 +01:00
Richard W.M. Jones
8237ac89c5 daemon: Use pvcreate --force option (RHBZ#887971).
pvcreate fails if the partition contains a swap space signature.  Use
more force to stop it from complaining.
2012-12-17 19:27:12 +00:00
Richard W.M. Jones
4ad6b28d83 Version 1.21.1. 2012-12-17 12:49:32 +00:00
Richard W.M. Jones
eab324bbbb list-filesystems: Ignore MBR type 0x42 (Windows dynamic disks) (RHBZ#887520). 2012-12-17 12:39:55 +00:00
Richard W.M. Jones
6f02e33c6f sparsify: Document that virt-sparsify doesn't work well on multi-disk VMs.
See: http://bugzilla.redhat.com/887826
2012-12-17 12:24:29 +00:00
Richard W.M. Jones
79339798b3 launch: libvirt: Improve loop invariant from previous commit.
This fixes commit 11b6293d1b.
2012-12-16 21:29:35 +00:00
Richard W.M. Jones
11b6293d1b launch: libvirt: Parse capabilities XML and fail early if qemu/KVM not supported (RHBZ#886915). 2012-12-16 20:56:39 +00:00
Richard W.M. Jones
c4ad2c0ce3 daemon: Fold stdout on stderr when running e2fsck.
User Phill Bandelow noted that virt-resize fails with an e2fsck error
on a host where the system clock had been accidentally set in the
past.

Unfortunately this was hard to diagnose because guestfsd 'ate' the
stdout of the e2fsck program.  I have verified by code inspection that
e2fsck prints messages on stdout.

Thus this changes the daemon to fold stdout and stderr together so we
get to see all error messages from e2fsck when it fails.
2012-12-16 18:38:41 +00:00
Richard W.M. Jones
22fe98ad9f build: Improve 'make help' output description of 'make extra-tests'. 2012-12-15 20:20:38 +00:00
Richard W.M. Jones
eca2dd2e8c build: Better formatting for 'make help' output.
This is just whitespace changes.
2012-12-15 20:15:12 +00:00
Richard W.M. Jones
486efb002a build: Show 'make -k check' as a possibility in 'make help' output.
Thanks to Cole Robinson for this suggestion.
2012-12-15 20:10:25 +00:00
Richard W.M. Jones
448a02373d ruby: Enable C compiler warnings.
This has the desirable side effect that the correct CFLAGS get passed
to the C compiler when building the Ruby extension.
2012-12-15 19:42:02 +00:00
Richard W.M. Jones
1571aef9cc python: Enable C compiler warnings. 2012-12-15 19:42:02 +00:00
Richard W.M. Jones
62e775c350 Change the handling of private functions, safe_malloc etc.
Rename guestfs_safe_malloc et al to guestfs___safe_malloc etc.

To use the private functions, code now has to define
-DGUESTFS_PRIVATE_FUNCTIONS=1.  This will make it easier for us in
future to work out which programs are using these functions and to
minimize both the number of programs and the functions they are
calling.

Note that the Perl, Python, OCaml, Ruby and Java bindings use
guestfs_safe_* calls.  None of the other bindings do.  This is a bug
(in the bindings using those functions): these functions will call the
out of memory callback on failure.  This function defaults to abort(),
and since this happens from a language binding, there is no way to
change this default.
2012-12-15 19:41:29 +00:00
Richard W.M. Jones
27f6878e2a guestfs.h: Fix use of __attribute__ and GCC < 4.
I guess no one uses GCC 3 any more, because if they did, including
<guestfs.h> would not work since GUESTFS_DLL_PUBLIC would not have
been defined.

At the same time, ensure that __attribute__((noreturn)) is only used
when the compiler is GCC >= 3.1.
2012-12-15 17:03:11 +00:00
Richard W.M. Jones
95df8a7c0c inspection: Don't call guestfs_hivex_close if previous guestfs_hivex_open call failed.
(Thanks Skippy VonDrake)
2012-12-14 22:04:25 +00:00
Matthew Booth
a9051eb98e daemon: Add sentinel attribute to commandf and commandrf
Causes a compiler warning to be emitted if you omit the trailing NULL argument.
2012-12-14 16:58:05 +00:00
Matthew Booth
956e30effa Add support for getting and setting GPT partition type GUIDs
New APIs:
  part_set_gpt_type
  part_get_gpt_type
2012-12-14 16:58:05 +00:00
Matthew Booth
2aa731e7c4 daemon: Remove redundant fork in commandrvf
Currently the code is doing a redundant fork when passed the
COMMAND_FLAG_CHROOT_COPY_FILE_TO_STDIN flag. The additional
sub-process does a chroot() which has no effect because all file
handles are already open at that point, then simply copies its input
to its output.

This change simply replaces the above with a dup2 of the passed file
handle to STDIN of the command process.

RWMJ:
  Don't initialize 'pid' variable.
2012-12-14 16:21:58 +00:00
Richard W.M. Jones
d7a806ca1a configure: Change minor from .20 to .21 for new development branch. 2012-12-13 17:53:36 +00:00
Matthew Booth
e92f9666de daemon: NFC Use symbolic names in commandrvf
Improve readability of commandrvf() by replacing bare int values for
file descriptors with their symbolic names STD{IN,OUT,ERR}_FILENO.

Also add PIPE_READ and PIPE_WRITE for referencing relevant ends of a pipe.
2012-12-13 17:53:20 +00:00
Matthew Booth
52cd07a0ac daemon: fix directory outside current root when executing commands
When executing a command, we temporarily chroot, fork and exec the
command, then chroot back. We intentionally don't chdir in the parent
process so that we can 'jailbreak' the chroot later. However, this has
the effect that commands are executed with a current working directory
which is outside the current root.  This unusual state can cause
errors in executed commands which don't anticipate it.

This change does a chdir("/") before executing and command. This
happens inside the fork, so the jailbreak isn't affected in the
parent.
2012-12-13 17:15:01 +00:00
Richard W.M. Jones
f784c87859 Version 1.20.0. 2012-12-13 14:18:30 +00:00
Richard W.M. Jones
25652a6d5c proto: Free drives array when qemu subprocess dies abruptly.
Commit ed7fda161e changed the g->drives
linked list into an array, and also made a subtle change to the
(undocumented) semantics of drives in the rare case when qemu is
relaunched.

Every time we go back to the CONFIG state, we should free the drives
array.  However there was one place where this was not happening.
This was caught by the tests of the protocol, but only when using the
default (appliance) method, not the libvirt method which we were more
interested in testing in Fedora.

When testing on Debian using the appliance method, we therefore hit
this bug for the first time.

This relates to or fixes the following commits:
  commit 9df159b34a
  commit 33f49d85c2
  commit ed7fda161e
2012-12-13 11:50:08 +00:00
Richard W.M. Jones
585dd44e17 debian: Allow test-disk-labels test to be skipped. 2012-12-13 11:50:08 +00:00
Richard W.M. Jones
14c7e9e52a launch: appliance: Disable virtio-scsi if qemu <= 1.1.
Debian Wheezy (7) ships with old qemu 1.1 which claims to support
virtio-scsi but in reality it's broken.

Disable virtio-scsi in this case.
2012-12-13 11:50:08 +00:00
Richard W.M. Jones
9508b750fd launch: appliance: Parse qemu version. 2012-12-13 10:38:45 +00:00
Richard W.M. Jones
c6558c75dd docs: Add website index.html.in to stable release documentation. 2012-12-13 08:50:12 +00:00
Richard W.M. Jones
5a293885a3 release notes: Update bugs list because one more bug was fixed. 2012-12-12 17:36:26 +00:00
Richard W.M. Jones
903e4864c0 Update gnulib to latest version for libguestfs 1.20 release. 2012-12-11 23:24:00 +00:00
Richard W.M. Jones
668683bd3d docs: Add gnulib update to stable release documentation. 2012-12-11 22:00:19 +00:00
Richard W.M. Jones
29cec9e235 build: Fix 'make help' output.
check-valgrind-local-tests -> check-valgrind-local-guests
2012-12-11 21:55:58 +00:00
Richard W.M. Jones
1a70df0ba6 Update API support ready for libguestfs 1.20 release. 2012-12-11 21:21:16 +00:00
Richard W.M. Jones
858bd9ffe0 launch: libvirt: Label sockets with svirt_socket_t (RHBZ#853393). 2012-12-11 20:33:28 +00:00
Richard W.M. Jones
966ebadb14 Update AUTHORS and BUGS files. 2012-12-11 17:16:13 +00:00
Richard W.M. Jones
436593f81f Push and pull latest translations from Transifex. 2012-12-11 17:15:49 +00:00
Richard W.M. Jones
557b8c6a0d Update ROADMAP for libguestfs 1.20 release. 2012-12-11 17:02:04 +00:00
Richard W.M. Jones
aeff59daa8 Update release notes and get ready for the libguestfs 1.20 release. 2012-12-11 16:58:57 +00:00
Richard W.M. Jones
0efe61b19d Add support for Windows dynamic disks (libldm / ldmtool) (RHBZ#782167).
New APIs:

  list-ldm-volumes
  list-ldm-partitions
  ldmtool-create-all
  ldmtool-remove-all
  ldmtool-scan
  ldmtool-scan-devices
  ldmtool-diskgroup-name
  ldmtool-diskgroup-volumes
  ldmtool-diskgroup-disks
  ldmtool-volume-type
  ldmtool-volume-hint
  ldmtool-volume-partitions
2012-12-11 15:20:19 +00:00
Matthew Booth
a93ea64959 inspect: Remove unused is_mountable field from filesystem struct 2012-12-11 15:20:19 +00:00
Matthew Booth
66ada9ed31 inspect: Remove unused is_swap field from filesystem struct 2012-12-11 15:20:19 +00:00
Matthew Booth
4fd5b89e36 inspect: Remove unused content field from filesystem struct
RWMJ: Don't remove entire if-clauses.
2012-12-11 15:20:09 +00:00
Richard W.M. Jones
91b3233e4a docs: Copy-edit documentation of the private data area. 2012-12-10 19:58:38 +00:00
Richard W.M. Jones
b554d7de82 guestfs-performance: Some copy-editing. 2012-12-10 17:23:57 +00:00
Richard W.M. Jones
7d2ae9f30f daemon: Generate the code when libraries are statically not available.
Since we as developers rarely test the case where some library is
statically not available, that side of the code was hardly tested,
except by unfortunate users in the field who often hit cases where
functions were missing or misdeclared.  In fact, when making this
change I noticed several bugs like that.

Change it so that this code is autogenerated, and therefore always
correct and up to date.

Previous code which looked like this:

  int
  optgroup_acl_available (void)
  {
    return 0;
  }

  char * __attribute__((noreturn))
  do_acl_get_file (const char *path, const char *acltype)
  {
    abort ();
  }

  /* etc */

is replaced by a single line:

  OPTGROUP_ACL_NOT_AVAILABLE
2012-12-10 16:20:34 +00:00
Richard W.M. Jones
5802b30ae5 generator: Change optgroups so second element is a list of functions.
Before this commit it was a list of function names (ie. strings)
making it hard if you wanted to get back to the original function
definition.
2012-12-10 16:14:42 +00:00
Richard W.M. Jones
2a2719d889 generate: Simplify generate_prototype ~single_line feature.
This is just code refactoring.
2012-12-10 16:13:15 +00:00
Richard W.M. Jones
74763eafa7 daemon: Make sure *.h files have guards against double-inclusion.
This is just code cleanup.
2012-12-10 15:49:48 +00:00
Richard W.M. Jones
82344085aa erlang: Add more tests.
Since I made lots of changes to the Erlang bindings (prompted by
Coverity), I wasn't confident that something didn't break because
there were no real tests before.
2012-12-10 13:21:06 +00:00
Richard W.M. Jones
bc05e91f0e ./run: Add Erlang support to run script. 2012-12-10 12:41:47 +00:00
Cole Robinson
cac8c56423 tests: Fix qemu-wrapper.sh generation 2012-12-09 12:12:04 +00:00
Richard W.M. Jones
6ab4d505f1 launch: libvirt: Avoid double-close of console socket on error path (found by Coverity). 2012-12-08 16:42:38 +00:00
Richard W.M. Jones
98391ab9c6 xfs: Remove potential double-free of 'buf' in multiple places (found by Coverity). 2012-12-08 16:42:38 +00:00
Richard W.M. Jones
ac6f94fb3e lua: Add comment about unsolved, hard to fix race (found by Coverity). 2012-12-08 16:42:38 +00:00
Richard W.M. Jones
0c6bc2f42f erlang: Avoid unintentional sign extension (found by Coverity).
Comment from Coverity:

  libguestfs-1.19.66/erlang/erl-guestfs-proto.c:115: sign_extension:
  Suspicious implicit sign extension: "buf[0]" with type "unsigned char"
  (8 bits, unsigned) is promoted in "(buf[0] << 24) | (buf[1] << 16) |
  (buf[2] << 8) | buf[3]" to type "int" (32 bits, signed), then
  sign-extended to type "unsigned long" (64 bits, unsigned).  If
  "(buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]" is greater
  than 0x7FFFFFFF, the upper bits of the result will all be 1.
2012-12-08 16:42:38 +00:00
Richard W.M. Jones
96e59eee66 lib: 'tmpfile' is never NULL (found by Coverity). 2012-12-08 16:42:38 +00:00
Richard W.M. Jones
359c8f8902 fish: Close 'sock' in remote control code (found by Coverity). 2012-12-08 16:42:38 +00:00
Richard W.M. Jones
b18a1b4e66 md: Free up 'ret' along error path (found by Coverity). 2012-12-08 16:42:38 +00:00
Richard W.M. Jones
a23d065c49 lib: Free up the right list if guestfs_internal_lstatlist returns an error (found by Coverity).
We were freeing up a list, but not the right list.
2012-12-08 16:42:38 +00:00
Richard W.M. Jones
6d94de3f20 fish: Don't leak stdout_saved_fd on error path (found by Coverity). 2012-12-08 16:42:38 +00:00
Richard W.M. Jones
855f023d2e lua: Don't leak memory for returned objects (found by Coverity). 2012-12-08 16:42:38 +00:00
Richard W.M. Jones
9733665bc6 python: Don't leak memory along error paths (found by Coverity). 2012-12-08 16:42:38 +00:00
Richard W.M. Jones
a1e37b7ea5 perl: Use safe_malloc instead of malloc (found by Coverity). 2012-12-08 16:42:37 +00:00
Richard W.M. Jones
3fe5f0a971 php: Return SUCCESS from PHP_MINIT_FUNCTION (found by Coverity). 2012-12-08 16:42:37 +00:00
Richard W.M. Jones
489cb059c2 fish: Don't segfault here is 'words' happens to be NULL (found by Coverity). 2012-12-08 16:42:37 +00:00
Richard W.M. Jones
40bfce7629 lib: Avoid segfault if guestfs_internal_readlinklist returns an error (found by Coverity). 2012-12-08 16:42:37 +00:00
Richard W.M. Jones
42e0cf77f3 inspect: Remove dead code (found by Coverity). 2012-12-08 16:42:37 +00:00
Richard W.M. Jones
9df159b34a launch: appliance: Really add dummy appliance slot (found by Coverity).
In the previous code, appliance was unconditionally set to NULL and so
we never added the dummy appliance slot to g->drives.  This probably
doesn't matter, since hotplugging doesn't work for the 'appliance'
attach-method.  Despite that, it's better to get this right.

This fixes commit ed7fda161e.
2012-12-08 16:42:37 +00:00
Richard W.M. Jones
e9e5a0f94e daemon: Fix error checking in function (found by Coverity). 2012-12-08 16:42:37 +00:00
Richard W.M. Jones
7941f6785e fish: copy-out: Fail on some errors when creating output directory (found by Coverity).
However it's not an error if the output directory already exists.
2012-12-08 16:42:37 +00:00
Richard W.M. Jones
15d5c94377 daemon: Explicitly ignore return value from modprobe command (found by Coverity). 2012-12-08 16:42:37 +00:00
Richard W.M. Jones
baf5a06224 fish: Ignore failure of mkdir (noted by Coverity). 2012-12-08 16:40:54 +00:00
Richard W.M. Jones
091b98a9ea tmpdirs: Explicitly ignore return value from guestfs___cmd_run to keep Coverity happy.
We don't care if this command fails.
2012-12-08 13:26:04 +00:00
Richard W.M. Jones
aa785c85d9 lib: Explicitly ignore return value from guestfs_parse_environment in guestfs_create (found by Coverity).
The purpose of adding guestfs_create_flags was so that users could
check for errors from guestfs_parse_environment if they need to.
2012-12-08 13:26:04 +00:00
Richard W.M. Jones
59b51274eb Check for error from some guestfs_set_* calls (found by Coverity).
For some guestfs_set_* calls, add checks for error, when error might
possibly occur.  eg. It's plausible that guestfs_set_network might
fail if the attach-method being used doesn't support it (although this
doesn't happen at the moment).

In other cases, don't check for errors, eg. if the error doesn't
matter or there's nothing we could plausibly do about it.
2012-12-08 13:25:59 +00:00
Richard W.M. Jones
8331d46384 virt-rescue: Document a method to capture core dumps from within the rescue environment. 2012-12-07 15:25:04 +00:00
Richard W.M. Jones
bb0de6938a daemon: Fix noreturn error in acl and capabilities code.
This is an improvement over the original fix in
commit fe4cdb2a47.
2012-12-07 15:24:49 +00:00
Richard W.M. Jones
f5e9e2780b configure.ac: Fix comment.
I spent a lot of time looking at how gnulib "manywarnings" works, and
this comment reflects my improved understanding.
2012-12-07 15:24:18 +00:00
Richard W.M. Jones
47511ddbc9 Add NOT_SUPPORTED macro to daemon and library.
This convenience macro returns errno == ENOTSUP.
2012-12-07 15:24:06 +00:00
Richard W.M. Jones
77e9b1a9e8 appliance: Add (default commented out) section containing debugging tools. 2012-12-07 12:09:20 +00:00
Richard W.M. Jones
52744cc232 tests: charset: Fix broken Makefile.am escaping.
This fixes commit 5a2e320ec9.
2012-12-04 15:21:49 +00:00
Richard W.M. Jones
5a2e320ec9 configure: Add --enable-code-profiling and --enable-code-coverage flags.
These configure flags enable code profiling (with gprof) and code
coverage (with gcov) respectively.

Although this is a nice idea, it's not currently very useful.

Libtool mangles filenames in such a way that gcov cannot locate its
datafiles.

Profiling is of dubious utility with libguestfs which is not CPU-bound
and relies extensively on running external programs (oprofile-like
system profiling that took into account libguestfs + qemu or
libguestfs + qemu + the appliance + filesystem tools *would* be
useful).

Also neither flag will help in capturing data from the appliance.
2012-12-04 14:11:14 +00:00
Evaggelos Balaskas
f92b4a7d83 packagelist.in for archlinux
latest archlinux has some small changes:

btrfs-progs-unstable --> btrfs-progs
genisoimage --> cdrkit
iproute --> iproute2
module-init-tools --> kmod
procps --> procps-ng
udev --> systemd
util-linux-ng --> util-linux

and could you plz add the below packages

lrzip
less
sed

RWMJ: I took this opportunity to make some general cleanups to the file:

- add 'less' and 'sed' for everyone
- 'module-init-tools' & 'kmod'[1]
- 'procps' & 'procps-ng'[1]
- 'util-linux' & 'util-linux-ng'[1]
- sort the ArchLinux packages into order

[1] Note that febootstrap is supposed to ignore packages it doesn't
know about.
2012-12-03 22:15:39 +00:00
Richard W.M. Jones
57009f0136 build: Make 'check-valgrind' fail noisily if valgrind is not installed.
The way the existing configure script worked, @VG@ would be empty, and
it would run all the way through the check-valgrind rule successfully
without actually running anything under valgrind.
2012-12-03 18:45:59 +00:00
Richard W.M. Jones
3cced0950c docs: Minor copyedits to the release notes. 2012-12-01 19:01:31 +00:00
Richard W.M. Jones
e35045720b Update release notes. 2012-12-01 14:56:25 +00:00
Richard W.M. Jones
443ea95faf Version 1.19.66. 2012-12-01 13:38:58 +00:00
Richard W.M. Jones
b57ab59b8e doc: Document problems with hibernated Windows guests and Windows 8 "fast startup" (RHBZ#882299). 2012-12-01 13:25:56 +00:00
Richard W.M. Jones
921b716b0b test-tool: Parse the environment separately.
This lets us report bugs when parsing the environment.
2012-12-01 12:04:13 +00:00
Richard W.M. Jones
e8d6d6f737 test-tool: Create the handle later.
Although this leads to a small amount of code duplication with the -V
option, the overall effect is cleaner.

This is just code motion.
2012-12-01 12:04:13 +00:00
Richard W.M. Jones
6b5f9221b4 tmpdirs: Make relative TMPDIR (etc) absolute, and check it's a directory (RHBZ#882417).
This fixes commit 1efed122c0.
2012-12-01 12:04:09 +00:00
Richard W.M. Jones
575895d8b0 test-tool: Print tmpdir properly.
It was actually printing cachedir.

This fixes commit f9ab256f0e.
2012-12-01 11:14:57 +00:00
Richard W.M. Jones
3d59ed5458 inspection: Get icon for Windows 8 (RHBZ#801117). 2012-12-01 09:41:33 +00:00
Richard W.M. Jones
c08fbc9cb4 contrib: Useful script to extract all logos/icons from a Windows guest. 2012-12-01 09:09:56 +00:00
Richard W.M. Jones
160977987f inspection: Temporary logo for Windows 8.
See the comment from the code:

  NB about Windows 8: No location we've found so far contains a
  suitable icon for Win8.  In particular, explorer.exe definitely
  does *not* contain any Windows logo as a resource (I checked).
  Therefore the "basket icon" that this produces is just a stand-in
  until we have a better idea for solving this problem.

and:

  https://bugzilla.redhat.com/show_bug.cgi?id=801117
2012-11-30 23:00:33 +00:00
Richard W.M. Jones
f5ae46dca7 inspection, virt-sysprep: Use /etc/hostname on F18+, RHEL7+ (RHBZ#881953, RHBZ#858696). 2012-11-30 12:37:48 +00:00
Richard W.M. Jones
fe4cdb2a47 daemon: Avoid gcc warning about noreturn function in acl & cap code.
acl.c: In function 'do_acl_get_file':
acl.c:158:1: error: function might be candidate for attribute 'noreturn' [-Werror=suggest-attribute=noreturn]
2012-11-30 09:01:05 +00:00
Richard W.M. Jones
a8f6e06b30 Version 1.19.65. 2012-11-29 19:40:00 +00:00
Richard W.M. Jones
6ee80b8dac inspection: Don't probe partitions when we've probed the whole device (RHBZ#798979).
So we don't get multiple <operatingsystem> entries, particularly for
install ISOs.
2012-11-29 18:27:26 +00:00
Richard W.M. Jones
90e7981082 inspection: Read libosinfo database in order to inspect OS install CD/DVD/ISOs (RHBZ#803650, RHBZ#805417). 2012-11-29 18:22:00 +00:00
Richard W.M. Jones
31101db4c7 lib: Indent CFLAGS in Makefile.am.
This is just a whitespace change.
2012-11-29 17:07:39 +00:00
Richard W.M. Jones
5693799614 inspection: Move variable decls to top of function.
This is just code motion.
2012-11-29 17:07:39 +00:00
Richard W.M. Jones
fc6f34d5cd inspection: Implement "openbsd" type and distro. 2012-11-29 17:07:39 +00:00
Richard W.M. Jones
0e5eef87d0 daemon: isoinfo: Fix parsing of bogus dates.
eg:

$ isoinfo --debug -d -i ubuntu-12.04-desktop-amd64.iso
CD-ROM is in ISO 9660 format
System id:
Volume id: Ubuntu 12.04 LTS amd64
Volume set id:
Publisher id:
[...]
Creation Date:     2012 04 25 16:13:46.00
Modification Date: 2012 04 25 16:13:46.00
Expiration Date:                :  :  .
Effective Date:                 :  :  .
[...]
2012-11-29 17:07:39 +00:00
Richard W.M. Jones
380ce2eeaa fish: Make type == drv_N field private to guestfish.
The -N option / drv_N type only makes sense when we are compiling
guestfish, and just serves to complicate non-guestfish code.
2012-11-29 11:45:39 +00:00
Richard W.M. Jones
9e7daf2ee8 virt-df: Better output when multiple -a/-d options are specified (RHBZ#880801).
This is very well explained in the bugzilla comments:
https://bugzilla.redhat.com/show_bug.cgi?id=880801#c1

With this change, the disk name has a one or more plus signs ('+')
appended to show that there are additional disks:

  $ virt-df -a Win7x32TwoDisks-a -a Win7x32TwoDisks-b
  Filesystem                   1K-blocks    Used  Available  Use%
  Win7x32TwoDisks-a+:/dev/sda1    102396   24712      77684   25%
  Win7x32TwoDisks-a+:/dev/sda2  12478460 7403416    5075044   60%
  Win7x32TwoDisks-a+:/dev/sdb1    521212   55728     465484   11%
2012-11-29 11:45:39 +00:00
Richard W.M. Jones
6255cc8343 Add .mailmap to EXTRA_DIST. 2012-11-27 08:48:39 +00:00
Wanlong Gao
36232b0bbe Add the .mailmap and change the method to generate AUTHORS
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
2012-11-27 08:45:23 +00:00
Richard W.M. Jones
567747f78e lib: lpj: Refactor code.
Only run one grep command to grep any number of files.
2012-11-26 09:37:58 +00:00
Richard W.M. Jones
8243c0c6f6 lib: lpj: Only return first match in read_all function.
If there where several lpj=.. matches then the earlier matches would
be leaked.  Only return the first one and don't leak memory.
2012-11-26 08:58:26 +00:00
Richard W.M. Jones
d2c75dd0ff lib: Get lpj= from /var/log/boot.msg (thanks Olaf Hering). 2012-11-25 18:11:19 +00:00
602 changed files with 113273 additions and 71750 deletions

82
.gitignore vendored
View File

@@ -9,6 +9,9 @@
*.cmxa
*.diff
*.eml
*.gcda
*.gcno
*.gcov
*.hi
*.jar
*.la
@@ -23,6 +26,7 @@ bindtests.tmp
cscope.out
.deps
.gdb_history
gmon.out
.libs
Makefile
Makefile.in
@@ -41,6 +45,15 @@ Makefile.in
/appliance/stamp-supermin
/appliance/supermin.d
/autom4te.cache
/bash/virt-cat
/bash/virt-df
/bash/virt-edit
/bash/virt-filesystems
/bash/virt-format
/bash/virt-inspector
/bash/virt-ls
/bash/virt-sysprep
/bash/virt-sparsify
/build-aux
/cat/stamp-virt-*.pod
/cat/virt-cat
@@ -91,17 +104,20 @@ Makefile.in
/erlang/examples/stamp-guestfs-erlang.pod
/erlang/guestfs.beam
/erlang/guestfs.erl
/examples/copy_over
/examples/create_disk
/examples/display_icon
/erlang/libguestfs-1.*
/erlang/test.img
/examples/copy-over
/examples/create-disk
/examples/debug-logging
/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/libvirt_auth
/examples/mount_local
/examples/inspect-vm
/examples/libvirt-auth
/examples/mount-local
/examples/stamp-guestfs-examples.pod
/examples/stamp-guestfs-faq.pod
/examples/stamp-guestfs-performance.pod
@@ -118,6 +134,7 @@ Makefile.in
/fish/guestfish.1
/fish/guestfish-actions.pod
/fish/guestfish-commands.pod
/fish/guestfish-prepopts.pod
/fish/prepopts.c
/fish/prepopts.h
/fish/rc_protocol.c
@@ -136,7 +153,11 @@ Makefile.in
/format/virt-format.1
/fuse/guestmount
/fuse/guestmount.1
/fuse/guestunmount
/fuse/guestunmount.1
/fuse/stamp-guestmount.pod
/fuse/stamp-guestunmount.pod
/fuse/test-guestunmount-fd
/generator/.depend
/generator/files-generated.txt
/generator/generator
@@ -155,8 +176,9 @@ Makefile.in
/guestfsd-in-wine.log
/haskell/Bindtests
/haskell/Bindtests.hs
/haskell/Guestfs005Load
/haskell/Guestfs010Basic
/haskell/Guestfs010Load
/haskell/Guestfs030Config
/haskell/Guestfs050LVCreate
/haskell/Guestfs.hs
/html/guestfish.1.html
/html/guestfs.3.html
@@ -175,6 +197,7 @@ Makefile.in
/html/guestfs-testing.1.html
/html/guestfsd.8.html
/html/guestmount.1.html
/html/guestunmount.1.html
/html/libguestfs-make-fixed-appliance.1.html
/html/libguestfs-test-tool.1.html
/html/virt-alignment-scan.1.html
@@ -246,20 +269,9 @@ Makefile.in
/ocaml/guestfs.mli
/ocamlinit-stamp
/ocaml/META
/ocaml/t/guestfs_005_load.bc
/ocaml/t/guestfs_005_load.opt
/ocaml/t/guestfs_010_basic.bc
/ocaml/t/guestfs_010_basic.opt
/ocaml/t/guestfs_070_threads.bc
/ocaml/t/guestfs_070_threads.opt
/ocaml/t/guestfs_080_optargs.bc
/ocaml/t/guestfs_080_optargs.opt
/ocaml/t/guestfs_400_events.bc
/ocaml/t/guestfs_400_events.opt
/ocaml/t/guestfs_400_progress.bc
/ocaml/t/guestfs_400_progress.opt
/ocaml/t/guestfs_500_mount_local.bc
/ocaml/t/guestfs_500_mount_local.opt
/ocaml/stamp-mlguestfs
/ocaml/t/*.bc
/ocaml/t/*.opt
/perl/bindtests.pl
/perl/blib
/perl/examples/guestfs-perl.3
@@ -274,6 +286,7 @@ Makefile.in
/perl/MYMETA.json
/perl/MYMETA.yml
/perl/pm_to_blib
/perl/run-perl-tests
/php/extension/acinclude.m4
/php/extension/aclocal.m4
/php/extension/autom4te.cache
@@ -287,6 +300,7 @@ Makefile.in
/php/extension/config.sub
/php/extension/configure
/php/extension/configure.in
/php/extension/env
/php/extension/guestfs_php.c
/php/extension/guestfs_php_*.diff
/php/extension/guestfs_php_*.exp
@@ -314,6 +328,7 @@ Makefile.in
/po-docs/po4a.conf
/po-docs/*/*.pod
/po-docs/*/stamp-update-po
/podwrapper.1
/podwrapper.pl
/po/*.gmo
/python/bindtests.py
@@ -329,8 +344,8 @@ Makefile.in
/rescue/virt-rescue
/rescue/virt-rescue.1
/resize/.depend
/resize/resize_gettext.ml
/resize/resize_utils_tests
/resize/common_gettext.ml
/resize/common_utils_tests
/resize/stamp-virt-resize.pod
/resize/virt-resize
/resize/virt-resize.1
@@ -339,6 +354,7 @@ Makefile.in
/ruby/examples/guestfs-ruby.3
/ruby/examples/stamp-guestfs-ruby.pod
/ruby/ext/guestfs/extconf.h
/ruby/ext/guestfs/extconf.rb
/ruby/ext/guestfs/_guestfs.bundle
/ruby/ext/guestfs/_guestfs.c
/ruby/ext/guestfs/_guestfs.so
@@ -346,23 +362,25 @@ Makefile.in
/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/actions-variants.c
/src/bindtests.c
/src/cleanup-structs.c
/src/errnostring.c
/src/errnostring-gperf.c
/src/errnostring-gperf.gperf
/src/errnostring.h
/src/event-string.c
/src/free-structs.c
/src/guestfs.3
/src/guestfs-actions.pod
/src/guestfs-availability.pod
/src/guestfs.h
/src/guestfs-internal-actions.h
/src/guestfs-internal-frontend-cleanups.h
/src/guestfs_protocol.c
/src/guestfs_protocol.h
/src/guestfs_protocol.x
@@ -378,7 +396,6 @@ Makefile.in
/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
@@ -393,12 +410,14 @@ Makefile.in
/tests/c-api/test-create-handle
/tests/c-api/test-debug-to-file
/tests/c-api/test-environment
/tests/c-api/test-event-string
/tests/c-api/test*.img
/tests/c-api/test-just-header
/tests/c-api/test-just-header-cxx
/tests/c-api/test-last-errno
/tests/c-api/test.log
/tests/c-api/test-private-data
/tests/c-api/test-pwd
/tests/c-api/tests
/tests/c-api/tests.c
/tests/c-api/test*.tmp
@@ -416,20 +435,30 @@ Makefile.in
/tests/data/initrd-x86_64.img.gz
/tests/data/test-grep.txt.gz
/tests/data/test.iso
/tests/guests/blank-*.img
/tests/guests/debian.img
/tests/guests/fedora.img
/tests/guests/fedora-btrfs.img
/tests/guests/fedora-md1.img
/tests/guests/fedora-md2.img
/tests/guests/guests.xml
/tests/guests/guests-all-good.xml
/tests/guests/guest-aux/fedora-name.db
/tests/guests/guest-aux/fedora-packages.db
/tests/guests/guest-aux/windows-software
/tests/guests/guest-aux/windows-system
/tests/guests/stamp-fedora-md.img
/tests/guests/ubuntu.img
/tests/guests/windows.img
/tests/mount-local/test-parallel-mount-local
/tests/mountable/test-internal-parse-mountable
/tests/parallel/test-parallel
/tests/regressions/rhbz501893
/tests/regressions/rhbz790721
/tests/regressions/rhbz914931
/tests/rsync/rsyncd.pid
/tests/syslinux/extlinux-guest.img
/tests/syslinux/syslinux-guest.img
/test-tool/libguestfs-test-tool
/test-tool/libguestfs-test-tool.1
/test-tool/libguestfs-test-tool-helper
@@ -437,4 +466,3 @@ Makefile.in
/tools/test.img
/tools/virt-*.1
/tools/virt-*.pl
/valgrind.log*

Submodule .gnulib updated: 0cd711b27b...076ac82d1d

View File

@@ -5,5 +5,5 @@
set sw=2
set ts=2
set tw=80
set tw=70
set expandtab

13
.mailmap Normal file
View File

@@ -0,0 +1,13 @@
Jim Meyering <meyering@redhat.com> <jim@meyering.net>
Jim Meyering <meyering@redhat.com> <meyering@vv.meyering.net.meyering.net>
Richard W.M. Jones <rjones@redhat.com> Richard Jones <rich@hakodate.home.annexia.org>
Richard W.M. Jones <rjones@redhat.com> Richard Jones <rich@koneko.home.annexia.org>
Richard W.M. Jones <rjones@redhat.com> Richard Jones <rich@koneko.local>
Richard W.M. Jones <rjones@redhat.com> Richard Jones <rjones@centos5x32.home.annexia.org>
Richard W.M. Jones <rjones@redhat.com> Richard Jones <rjones@debian5x64.home.annexia.org>
Richard W.M. Jones <rjones@redhat.com> Richard Jones <rjones@redhat.com>
Richard W.M. Jones <rjones@redhat.com> Richard Jones <rjones@trick.home.annexia.org>
Richard W.M. Jones <rjones@redhat.com> Richard Jones <rjones@ubuntu910x64.home.annexia.org>
Richard W.M. Jones <rjones@redhat.com> <rich@annexia.org>
Richard W.M. Jones <rjones@redhat.com> rjones <rjones>
Wanlong Gao <gaowanlong@cn.fujitsu.com> <wanlong.gao@gmail.com>

View File

@@ -1,16 +1,20 @@
Angus Salkeld <asalkeld@redhat.com>
Ani Peter <apeter@redhat.com>
Charles Duffy <cduffy@messageone.com>
Cole Robinson <crobinso@redhat.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>
Evaggelos Balaskas <ebalaskas@ebalaskas.gr>
Geert Warrink <geert.warrink@onsnet.nu>
Guido Günther <agx@sigxcpu.org>
Hilko Bengen <bengen@debian.org>
Hilko Bengen <bengen@hilluzination.de>
infernix <infernix@infernix.net>
Jaswinder Singh <jsingh@redhat.com>
Jim Meyering <jim@meyering.net>
Jim Meyering <meyering@redhat.com>
Jiri Popelka <jpopelka@redhat.com>
John Eckersberg <jeckersb@redhat.com>
Karel Klíč <kklic@redhat.com>
@@ -19,13 +23,14 @@ Masami HIRATA <msmhrt@gmail.com>
Matthew Booth <mbooth@redhat.com>
Maxim Koltsov <kolmax94@gmail.com>
Michael Scherer <misc@zarb.org>
Mike Kelly <pioto@pioto.org>
Nikita A Menkovich <menkovich@gmail.com>
Nikos Skalkotos <skalkoto@gmail.com>
Olaf Hering <olaf@aepfle.de>
Piotr Drąg <piotrdrag@gmail.com>
Qin Guan <qguan@redhat.com>
Rajesh Ranjan <rranjan@redhat.com>
Richard W.M. Jones <rich@annexia.org>
Richard W.M. Jones <rjones@redhat.com>
Sandeep Shedmake <sshedmak@redhat.com>
Shankar Prasad <svenkate@redhat.com>
Thomas S Hatch <thatch45@gmail.com>

239
BUGS
View File

@@ -1,5 +1,5 @@
NOTE: This file is automatically generated from "update-bugs.sh".
Last updated: 2012-11-24
Last updated: 2013-05-02
This contains a local list of the bugs that are open against
libguestfs. Bugs are tracked in the Red Hat Bugzilla database
@@ -29,9 +29,6 @@ Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
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
@@ -44,9 +41,6 @@ Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
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
@@ -65,9 +59,6 @@ Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
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
693064 NEW https://bugzilla.redhat.com/show_bug.cgi?id=693064
Symbolic links on ntfs-3g are not followed correctly by some commands
@@ -92,30 +83,18 @@ Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
745576 NEW https://bugzilla.redhat.com/show_bug.cgi?id=745576
libguestfs (or qemu?) hangs if sparse file runs out of disk space
761565 NEW https://bugzilla.redhat.com/show_bug.cgi?id=761565
Missing deps on netpbm-progs and icoutils
770075 NEW https://bugzilla.redhat.com/show_bug.cgi?id=770075
FEBOOTSTRAP_MODULES fails if modules directory is not under /lib
770076 NEW https://bugzilla.redhat.com/show_bug.cgi?id=770076
FEBOOTSTRAP_KERNEL causes appliance build to fail
782167 NEW https://bugzilla.redhat.com/show_bug.cgi?id=782167
libguestfs doesn't recognize Windows Dynamic disks in some configurations, eg. spanned
785603 NEW https://bugzilla.redhat.com/show_bug.cgi?id=785603
copy-out can't find root directory
copy-out "No such file or directory"
790837 NEW https://bugzilla.redhat.com/show_bug.cgi?id=790837
Use of atexit to clean up handles is wrong in multithreaded programs
798979 NEW https://bugzilla.redhat.com/show_bug.cgi?id=798979
Ubuntu install CDs from oneiric onwards are not recognized: "multi-boot operating systems are not supported"
801117 NEW https://bugzilla.redhat.com/show_bug.cgi?id=801117
libguestfs cannot get icon for Windows 8 preview
803650 NEW https://bugzilla.redhat.com/show_bug.cgi?id=803650
inspect-is-live return false when inspection results should be true
@@ -128,18 +107,6 @@ Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
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
811265 NEW https://bugzilla.redhat.com/show_bug.cgi?id=811265
the list-filesystems can detect the reiserFS,but can not mount it.and minix filesystem too.
811395 NEW https://bugzilla.redhat.com/show_bug.cgi?id=811395
virt-inspector to detect ia64 Windows 2k3 install media
811398 NEW https://bugzilla.redhat.com/show_bug.cgi?id=811398
virt-inspector fails to detect Win2k, Win2k8, Win2k8r2, WinVista, Win7 install media
812970 NEW https://bugzilla.redhat.com/show_bug.cgi?id=812970
virt-rescue cannot set ><rescue> prompt, on Ubuntu 12.04
@@ -173,39 +140,147 @@ Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
837941 NEW https://bugzilla.redhat.com/show_bug.cgi?id=837941
Data loss when writing to qcow2-format disk files
838081 NEW https://bugzilla.redhat.com/show_bug.cgi?id=838081
ocaml/t/guestfs_500_parallel_mount_local crashes in caml_thread_reinitialize
843188 NEW https://bugzilla.redhat.com/show_bug.cgi?id=843188
Ruby bindings segfault in event callbacks when the Ruby GC is invoked.
845234 NEW https://bugzilla.redhat.com/show_bug.cgi?id=845234
RFE: virt-ls on Windows guest doesn't support drive letters
846676 NEW https://bugzilla.redhat.com/show_bug.cgi?id=846676
guestfs_launch() hangs with Debian qemu-kvm 1.1.0
848464 NEW https://bugzilla.redhat.com/show_bug.cgi?id=848464
gobject javascript bindings cannot use 64 bit integers
857763 NEW https://bugzilla.redhat.com/show_bug.cgi?id=857763
libguestfs 'file-architecture' returns 'ARM' for arm binaries
863696 NEW https://bugzilla.redhat.com/show_bug.cgi?id=863696
[F18] libguestfs fails to mount a disk image file(in this case qcow2) as 'root'
864871 NEW https://bugzilla.redhat.com/show_bug.cgi?id=864871
libvirt error: could not create appliance through libvirt: unable to set security context 'unconfined_u:object_r:svirt_image_t:s0:cXXX,cYYY' on '.../console.sock'
865923 NEW https://bugzilla.redhat.com/show_bug.cgi?id=865923
Check that new qemu -machine option doesn't break libguestfs.
866994 NEW https://bugzilla.redhat.com/show_bug.cgi?id=866994
tgz-out causes memory leak in guestfsd
869179 NEW https://bugzilla.redhat.com/show_bug.cgi?id=869179
libguestfs fail to startup on latest rhel7 tree
880806 NEW https://bugzilla.redhat.com/show_bug.cgi?id=880806
virt-df with two -a options displays incorrect disk image name
887826 NEW https://bugzilla.redhat.com/show_bug.cgi?id=887826
RFE: virt-sparsify cannot handle multi-disk virtual machines (eg. if they use LVM, MD, LDM, etc)
889089 NEW https://bugzilla.redhat.com/show_bug.cgi?id=889089
Block device /dev/sd* didn't translate to /dev/vd*
890027 NEW https://bugzilla.redhat.com/show_bug.cgi?id=890027
virt-sysprep: Setting the hostname on Fedora 18 is stupidly over-complicated
891909 NEW https://bugzilla.redhat.com/show_bug.cgi?id=891909
Can't make install with non-standard prefix as non-root
892271 NEW https://bugzilla.redhat.com/show_bug.cgi?id=892271
virt-format fail to format the same disk more than twice with lvm enable
892272 NEW https://bugzilla.redhat.com/show_bug.cgi?id=892272
Specify QEMU interface emulation will break libguestfs
892275 NEW https://bugzilla.redhat.com/show_bug.cgi?id=892275
checksums-out fail to compute the checksums of all regular files in directory
892291 NEW https://bugzilla.redhat.com/show_bug.cgi?id=892291
guestmount: link() incorrectly returns ENOENT, when it should be EXDEV
892834 NEW https://bugzilla.redhat.com/show_bug.cgi?id=892834
guestmount: rename() incorrectly follows symbolic links
895898 NEW https://bugzilla.redhat.com/show_bug.cgi?id=895898
RFE: Allow interface to be specified with libvirt attach-method
895946 NEW https://bugzilla.redhat.com/show_bug.cgi?id=895946
Got incorrect block count number when resize ntfs file system via "ntfsresize_opts"
903890 NEW https://bugzilla.redhat.com/show_bug.cgi?id=903890
scrub-freespace didn't remove the scrub file, cause the file system 100% full
903972 NEW https://bugzilla.redhat.com/show_bug.cgi?id=903972
Command "acl-set-file" is inconvenient to use
903987 NEW https://bugzilla.redhat.com/show_bug.cgi?id=903987
Command "acl-set-file" is inconvenient to use
905322 NEW https://bugzilla.redhat.com/show_bug.cgi?id=905322
"No such file or directory" when execute "hivex-commit"
906190 NEW https://bugzilla.redhat.com/show_bug.cgi?id=906190
Need add a line break behind the output of command "hivex-value-value"
906766 NEW https://bugzilla.redhat.com/show_bug.cgi?id=906766
virt-resize cannot resize RHEL 5 guest with GPT partition table type
906777 NEW https://bugzilla.redhat.com/show_bug.cgi?id=906777
In tests, set_label sometimes fails
908255 NEW https://bugzilla.redhat.com/show_bug.cgi?id=908255
error message didn't translate to user language
909666 NEW https://bugzilla.redhat.com/show_bug.cgi?id=909666
Unexpected non-tail recursion in recv_from_daemon results in stack overflow in very long-running API calls that send progress messages
909667 NEW https://bugzilla.redhat.com/show_bug.cgi?id=909667
Unexpected non-tail recursion in recv_from_daemon results in stack overflow in very long-running API calls that send progress messages
910115 NEW https://bugzilla.redhat.com/show_bug.cgi?id=910115
RFE: support ntfsresize --bad-sectors option in virt-resize
910269 NEW https://bugzilla.redhat.com/show_bug.cgi?id=910269
Tracker: Bugs in other packages that stop libguestfs working on current Rawhide
910270 NEW https://bugzilla.redhat.com/show_bug.cgi?id=910270
Tracker: Bugs in other packages that stop libguestfs working on Fedora 18
911674 NEW https://bugzilla.redhat.com/show_bug.cgi?id=911674
swapon label test fails (RHEL 7 only)
911678 NEW https://bugzilla.redhat.com/show_bug.cgi?id=911678
libguestfs: error: cpio command failed: Resource temporarily unavailable (RHEL 7 only)
913774 NEW https://bugzilla.redhat.com/show_bug.cgi?id=913774
libguestfs: could not create appliance through libvirt when URI is qemu:///system or running as root (which causes system to be used implicitly)
913815 NEW https://bugzilla.redhat.com/show_bug.cgi?id=913815
febootstrap: no ext2 root device found when running libguestfs-test-tools
916130 NEW https://bugzilla.redhat.com/show_bug.cgi?id=916130
libguestfs can't rebuild in mock
917706 NEW https://bugzilla.redhat.com/show_bug.cgi?id=917706
guestfs_umount_local is not thread safe
920617 NEW https://bugzilla.redhat.com/show_bug.cgi?id=920617
RFE: virt-inspector (or another tool) should produce OVF output for oVirt / RHEV
921299 NEW https://bugzilla.redhat.com/show_bug.cgi?id=921299
virt-p2v fails with permissions problem on kernel module.
921710 NEW https://bugzilla.redhat.com/show_bug.cgi?id=921710
9p support should be disabled in libguestfs in RHEL 7
922891 NEW https://bugzilla.redhat.com/show_bug.cgi?id=922891
Tracker: Bugs in other packages that stop libguestfs working on Fedora 19
923355 NEW https://bugzilla.redhat.com/show_bug.cgi?id=923355
guestfish prints literal "n" in error messages
927447 NEW https://bugzilla.redhat.com/show_bug.cgi?id=927447
[suse] virt tools hang on disk image, but libguestfs-test-tool runs OK
950444 NEW https://bugzilla.redhat.com/show_bug.cgi?id=950444
inspection fails if libosinfo is not installed
953907 NEW https://bugzilla.redhat.com/show_bug.cgi?id=953907
virt-sysprep does not correctly set the hostname on Debian/Ubuntu
954185 NEW https://bugzilla.redhat.com/show_bug.cgi?id=954185
rsync command fails with linking error "libldap-2.4.so.2: cannot open shared object file: No such file or directory"
957796 NEW https://bugzilla.redhat.com/show_bug.cgi?id=957796
tar-out and base64-out quoting error
958183 NEW https://bugzilla.redhat.com/show_bug.cgi?id=958183
Rebase libguestfs in RHEL 6.5
503134 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=503134
guestfish's list splitting does not recognize internal quoting
@@ -224,50 +299,36 @@ Bugs in NEW or ASSIGNED state are open and waiting for someone to fix.
803643 ASSIGNED https://bugzilla.redhat.com/show_bug.cgi?id=803643
inspect-is-multipart return false when inspection results should be true
(68 bugs)
(93 bugs)
--------------------------------------------------
Bugs in MODIFIED, POST or ON_QA state are fixed.
You can help by testing the fixes.
837691 ON_QA https://bugzilla.redhat.com/show_bug.cgi?id=837691
Data loss when writing to qcow2-format disk files
889536 MODIFIED https://bugzilla.redhat.com/show_bug.cgi?id=889536
[RFE]It's better to emphasize "libguestfs-winsupport" in V2V manpage or error output
(1 bugs)
889537 MODIFIED https://bugzilla.redhat.com/show_bug.cgi?id=889537
Libguestfs live support should be disabled in RHEL 7 packages
--------------------------------------------------
These bugs are in the VERIFIED state.
801640 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=801640
[RFE] the error reported by resize2fs-M need to be more clear
816839 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=816839
data overflow error when debug progress -1
822626 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=822626
virt-ls error: "libguestfs: error: checksum: path: parameter cannot be NULL"
830135 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=830135
libguestfs should support mount-local APIs in RHEL 6 (for OpenStack)
836501 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=836501
dependency on fuse suggested
838609 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=838609
guestmount + fusermount allows a race condition when unmounting and immediately using the disk image
853763 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=853763
virt-sparsify should use a more robust method to detect the input format
858126 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=858126
virt-inspector fail to work with some windows guests
858128 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=858128
libguestfs fail to list devices added by add-drive-ro-with-if twice
858648 VERIFIED https://bugzilla.redhat.com/show_bug.cgi?id=858648
889538 MODIFIED https://bugzilla.redhat.com/show_bug.cgi?id=889538
libguestfs can not be installed with recent iptables
(10 bugs)
909573 MODIFIED https://bugzilla.redhat.com/show_bug.cgi?id=909573
patch libguestfs to use 'supermin' instead of 'febootstrap' in RHEL 7
947438 MODIFIED https://bugzilla.redhat.com/show_bug.cgi?id=947438
Some obsolete tools should be removed from libguestfs RHEL 7 package
949486 MODIFIED https://bugzilla.redhat.com/show_bug.cgi?id=949486
libguestfs-1.20.5-3.el7.x86_64 dependency problem
957616 MODIFIED https://bugzilla.redhat.com/show_bug.cgi?id=957616
libguestfs-1.21.31-1.1.el7.1.1.x86_64 won't install due to missing dependency
957797 ON_QA https://bugzilla.redhat.com/show_bug.cgi?id=957797
tar-out and base64-out quoting error
(8 bugs)
End of BUGS file.

View File

@@ -1,5 +1,5 @@
# libguestfs
# Copyright (C) 2009-2012 Red Hat Inc.
# Copyright (C) 2009-2013 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
@@ -30,9 +30,7 @@ SUBDIRS += tests/data generator src examples po
if ENABLE_DAEMON
SUBDIRS += daemon
endif
if ENABLE_APPLIANCE
SUBDIRS += appliance
endif
# Tests - order is important.
if ENABLE_APPLIANCE
@@ -43,6 +41,7 @@ SUBDIRS += tests/tmpdirs
SUBDIRS += tests/protocol
SUBDIRS += tests/parallel
SUBDIRS += tests/disks
SUBDIRS += tests/mountable
SUBDIRS += tests/lvm
SUBDIRS += tests/luks
SUBDIRS += tests/md
@@ -57,6 +56,8 @@ SUBDIRS += tests/rsync
SUBDIRS += tests/bigdirs
SUBDIRS += tests/disk-labels
SUBDIRS += tests/hotplug
SUBDIRS += tests/nbd
SUBDIRS += tests/syslinux
SUBDIRS += tests/regressions
endif
@@ -69,6 +70,9 @@ SUBDIRS += fish
# virt-tools in C.
SUBDIRS += align cat df edit format inspector rescue
# bash-completion
SUBDIRS += bash
# Language bindings.
if HAVE_PERL
SUBDIRS += perl perl/examples
@@ -129,6 +133,7 @@ EXTRA_DIST = \
BUGS HACKING ROADMAP TODO \
.gitignore \
.lvimrc \
.mailmap \
.tx/config \
bugs-in-changelog.sh \
autogen.sh \
@@ -190,6 +195,7 @@ HTMLFILES = \
html/guestfsd.8.html \
html/guestfish.1.html \
html/guestmount.1.html \
html/guestunmount.1.html \
html/libguestfs-make-fixed-appliance.1.html \
html/libguestfs-test-tool.1.html \
html/virt-alignment-scan.1.html \
@@ -240,10 +246,7 @@ dist-hook:
$(top_srcdir)/update-bugs.sh > BUGS-t
mv BUGS-t BUGS
cp BUGS $(distdir)/BUGS
git log --pretty="format:%an <%ae>" | sort -u | uniq -w 10 | \
grep -v rjones | \
grep -v "Richard Jones" \
> AUTHORS-t
git shortlog -se | awk -F'\t' '{print $$2}' | sort -f > AUTHORS-t
mv AUTHORS-t AUTHORS
cp AUTHORS $(distdir)/AUTHORS
@@ -290,13 +293,31 @@ stamp-guestfs-release-notes.pod: guestfs-release-notes.pod
$<
touch $@
# NB. podwrapper is an internal tool, so the man page mustn't be installed.
noinst_MANS = podwrapper.1
podwrapper.1: podwrapper.pl
$(PODWRAPPER) \
--section 1 \
--man $@-t \
--license GPLv2+ \
$<
mv $@-t $@
# Make clean.
CLEANFILES = \
*~ \
html/*.html \
pod2htm?.tmp \
podwrapper.1 \
qemu-wrapper.sh \
stamp-guestfs-release-notes.pod
stamp-guestfs-release-notes.pod \
tmp/guestfs.* \
tmp/run-* \
tmp/valgrind-*.log
clean-local:
-rm -rf tmp/libguestfs??????
# If you don't want to run all of the tests ('make check') then this
# will just run libguestfs-test-tool for a quick check. Note this
@@ -309,86 +330,122 @@ quickcheck:
extra-tests:
$(MAKE) -j1 \
valgrind \
valgrind-local-guests \
check-with-appliance \
check-valgrind \
check-valgrind-local-guests \
check-direct \
check-valgrind-direct \
check-with-upstream-qemu \
check-with-upstream-libvirt \
check-slow
check-valgrind: build-test-guests
@for f in `grep -l '^$@:' $(SUBDIRS:%=%/Makefile.am)`; do \
@errors=0; \
for f in `grep -l '^$@:' $(SUBDIRS:%=%/Makefile.am)`; do \
echo $(MAKE) -C `dirname $$f` $@; \
$(MAKE) -C `dirname $$f` $@ || exit $$?; \
done
$(MAKE) -C `dirname $$f` $@ || (( errors++ )); \
done; \
exit $$(( $$errors ? 1 : 0 ))
check-valgrind-local-guests:
@GUESTS=`$(top_builddir)/run ./pick-guests.pl 5`; \
errors=0; \
for f in `grep -l '^$@:' $(SUBDIRS:%=%/Makefile.am)`; do \
echo $(MAKE) GUESTS="$$GUESTS" -C `dirname $$f` $@; \
$(MAKE) GUESTS="$$GUESTS" -C `dirname $$f` $@ || exit $$?; \
done
$(MAKE) GUESTS="$$GUESTS" -C `dirname $$f` $@ || (( errors++ )); \
done; \
exit $$(( $$errors ? 1 : 0 ))
check-slow: build-test-guests
for f in `grep -l '^$@:' $(SUBDIRS:%=%/Makefile.am)`; do \
echo $(MAKE) -C `dirname $$f` $@; \
$(MAKE) -C `dirname $$f` $@ || exit $$?; \
done
build-test-guests:
$(MAKE) -C tests/guests check
check-with-appliance:
@method=`$(top_builddir)/run ./fish/guestfish get-attach-method`; \
if [ "$$method" != "appliance" ]; then \
$(MAKE) LIBGUESTFS_ATTACH_METHOD=appliance check || exit $$?; \
check-direct:
@backend=`$(top_builddir)/run ./fish/guestfish get-backend`; \
if [ "$$backend" != "direct" ]; then \
$(MAKE) LIBGUESTFS_BACKEND=direct check || exit $$?; \
fi
check-with-appliance: check-direct
check-valgrind-direct:
@backend=`$(top_builddir)/run ./fish/guestfish get-backend`; \
if [ "$$backend" != "direct" ]; then \
$(MAKE) LIBGUESTFS_BACKEND=direct check-valgrind || exit $$?; \
fi
check-valgrind-with-appliance: check-valgrind-direct
QEMUDIR = $(HOME)/d/qemu
QEMUBINARY = $(QEMUDIR)/x86_64-softmmu/qemu-system-x86_64
check-with-upstream-qemu:
@if $(QEMUBINARY) --help >/dev/null 2>&1; then \
$(MAKE) check-with-upstream-qemu-1 || exit $$?; \
fi
rm -f $(top_builddir)/qemu-wrapper.sh
$(MAKE) check-with-upstream-qemu-1 || exit $$?
check-with-upstream-qemu-1: $(top_builddir)/qemu-wrapper.sh
$(QEMUBINARY) --version
$(MAKE) LIBGUESTFS_QEMU=$(top_builddir)/qemu-wrapper.sh check
$(MAKE) LIBGUESTFS_QEMU=$(abs_top_builddir)/qemu-wrapper.sh check
$(top_builddir)/qemu-wrapper.sh: Makefile
rm -f $@ $@-t
echo exec "$(QEMUBINARY)" -L "$(QEMUDIR)/pc-bios" "$$@" > $@-t
echo -e "#!/bin/sh\nexec" "$(QEMUBINARY)" -L "$(QEMUDIR)/pc-bios" \"\$$@\" > $@-t
chmod +x,-w $@-t
mv $@-t $@
LIBVIRTDIR = $(HOME)/d/libvirt
check-with-upstream-libvirt:
@method=`$(top_builddir)/run ./fish/guestfish get-attach-method`; \
if [ "$$method" = "libvirt" ] && [ -x "$(LIBVIRTDIR)/run" ]; then \
@backend=`$(top_builddir)/run ./fish/guestfish get-backend`; \
if [ "$$backend" = "libvirt" ] && [ -x "$(LIBVIRTDIR)/run" ]; then \
$(LIBVIRTDIR)/run $(MAKE) check || exit $$?; \
fi
check-slow: build-test-guests
@errors=0; \
for f in `grep -l '^$@:' $(SUBDIRS:%=%/Makefile.am)`; do \
echo $(MAKE) -C `dirname $$f` $@; \
$(MAKE) -C `dirname $$f` $@ || (( errors++ )); \
done; \
exit $$(( $$errors ? 1 : 0 ))
build-test-guests:
$(MAKE) -C tests/guests check
# Print subdirs.
#
# If you want to selectively run tests, or if the test suite fails half
# way through, use:
#
# make print-subdirs
#
# to print the subdirectories, select the ones you want to run / the
# remaining ones, and do:
#
# make check SUBDIRS="..."
print-subdirs:
@echo $(SUBDIRS)
# Provide help on common Makefile targets.
help:
@echo
@echo "make Build everything."
@echo "make Build everything."
@echo
@echo "make check Run the standard tests."
@echo "make check-valgrind Run a subset of the tests under valgrind."
@echo "make check-valgrind-local-tests Test under valgrind using local guests."
@echo "make check-with-appliance Test using appliance attach-method."
@echo "make check-with-upstream-qemu Test using upstream qemu."
@echo "make check-with-upstream-libvirt Test using upstream libvirt."
@echo "make check-slow Slow/long-running tests."
@echo "make extra-tests Same as check-* (but not 'make check')"
@echo "make syntax-check Check syntax and style problems in the code."
@echo "make check Run the standard tests"
@echo "make -k check ... and display all errors at once."
@echo
@echo "make install Install everything."
@echo "make extra-tests Runs all of the following tests:"
@echo " make check-valgrind Run a subset of the tests under valgrind."
@echo " make check-valgrind-local-guests Test under valgrind using local guests."
@echo " make check-direct Test using direct backend."
@echo " make check-valgrind-direct Test valgrind + direct backend."
@echo " make check-with-upstream-qemu Test using upstream qemu."
@echo " make check-with-upstream-libvirt Test using upstream libvirt."
@echo " make check-slow Slow/long-running tests."
@echo
@echo "make clean Clean everything."
@echo "make syntax-check Check syntax and style problems in the code."
@echo "make print-subdirs Print subdirectories."
@echo
@echo "make install Install everything."
@echo
@echo "make clean Clean everything."
@echo
@echo "To run programs without installing:"
@echo " ./run ./fish/guestfish [or any other program]"

313
README
View File

@@ -41,128 +41,189 @@ Debian/Ubuntu users:
The full requirements are described below.
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
- QEMU >= 1.1.0.
- kernel >= 2.6.34 with virtio-serial support enabled.
- virtio-block and virtio-net drivers should be compiled into your
host kernel (strictly speaking this is optional, but you will have
to make complex changes to the ./configure command line to get it
to work if you don't have virtio)
- febootstrap >= 3.20
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)
- cpio
- gperf
- pcre (Perl Compatible Regular Expressions C library)
- genisoimage (NOT mkisofs any more)
- hivex >= 1.2.7 (http://libguestfs.org/download) (optional)
- libmagic (the library that corresponds to the 'file' command) (optional)
- libvirt (optional, >= 0.10.2 to use the libvirt launch method)
- libxml2 (optional)
- libconfig (optional)
- augeas >= 0.5.0 (http://augeas.net/) (optional)
- Berkeley DB 'db_dump' and 'db_load' utilities
(db4-utils or db4.X-util or similar) (optional)
- systemtap/DTrace userspace probes (optional)
http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps
- 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)
- xmllint (part of libxml2) to validate virt-inspector
RELAX NG schema (optional)
- OCaml compiler. Optional when compiling from the tarball, but
mandatory if you compile from git.
- 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.
- getfacl, getfattr libraries and programs (optional)
- Linux capabilities library (libcap) (optional)
- netpbm, icoutils (optional)
These programs are used to render icons from guests.
- Perl Expect module (optional)
This is used to test virt-rescue.
To build FUSE support in the core library, and guestmount:
- FUSE libraries and kernel module (optional)
To build language bindings:
- OCaml compiler to build the OCaml bindings (optional, but see above)
- Perl if you want to build the perl bindings (optional)
- Python if you want to build the python bindings (optional)
- Ruby, rake if you want to build the ruby bindings (optional)
- Java, JNI, jpackage-utils if you want to build the java
bindings (optional)
- GHC if you want to build the Haskell bindings (optional)
- PHP, phpize if you want to build the PHP bindings (optional)
To build the Perl tools:
- Perl Sys::Virt module (optional)
- Perl Win::Hivex module (optional)
- Perl Pod::Usage module (optional)
- Perl Test::More module (from perl Test::Simple) (optional)
- Perl String::ShellQuote module (optional)
- perl-libintl for translating perl code (optional)
R = Required
O = Optional
+==============+=============+===+=========================================+
| Package name | Min.version | | Notes |
+==============+=============+===+=========================================+
| Install as many packages listed in appliance/packagelist.in as possible. |
| This installs the disk management tools required by the appliance. The |
| list below is *additional* packages needed on the host. |
+--------------+-------------+---+-----------------------------------------+
| qemu | 1.2.0 | R | 1.1 may work, but has broken virtio-scsi|
+--------------+-------------+---+-----------------------------------------+
| qemu-img | | R | |
+--------------+-------------+---+-----------------------------------------+
| kernel | 2.6.34 | R | Make sure the following are enabled |
| | | | compiled in or as a module: |
| | | | - virtio-pci |
| | | | - virtio-serial |
| | | | - virtio-block |
| | | | - virtio-net |
+--------------+-------------+---+-----------------------------------------+
| supermin | 4.1.0 | R | This is required on all distros. |
| febootstrap | 3.20 | | 'supermin' is the new name for |
| | | | 'febootstrap'. |
| | | | For alternatives, see: |
| | | | libguestfs.org/download/binaries/appliance/
| | | | febootstrap 2.x WILL NOT WORK |
+--------------+-------------+---+-----------------------------------------+
| glibc | | R | We use various glibc-isms. |
| | | | Also glibc provides XDR, rpcgen. |
+--------------+-------------+---+-----------------------------------------+
| GCC or LLVM | | R | We use __attribute__((cleanup)). |
+--------------+-------------+---+-----------------------------------------+
| Perl | | R | Various build and test programs need |
| | | | Perl. Not needed at runtime except if |
| | | | you need to run a handful of virt-* |
| | | | tools that are still written in Perl. |
+--------------+-------------+---+-----------------------------------------+
| Pod::Man | | R | Part of Perl core. |
+--------------+-------------+---+-----------------------------------------+
| Pod::Simple | | R | Part of Perl core. |
+--------------+-------------+---+-----------------------------------------+
| OCaml | |R/O| Required if compiling from git. |
| | | | Optional if compiling from tarball. |
| | | | To build generated files and OCaml bindings.
+--------------+-------------+---+-----------------------------------------+
| autotools | |R/O| Required if compiling from git. |
| | | | Optional if compiling from tarball. |
| | | | Autotools-based build system. |
+--------------+-------------+---+-----------------------------------------+
| cpio | | R | |
+--------------+-------------+---+-----------------------------------------+
| gperf | | R | |
+--------------+-------------+---+-----------------------------------------+
| PCRE | | R | Perl-compatible Regular Expression lib. |
+--------------+-------------+---+-----------------------------------------+
| genisoimage | | R | mkisofs may work. |
+--------------+-------------+---+-----------------------------------------+
| libxml2 | | R | Popular XML library. |
+--------------+-------------+---+-----------------------------------------+
| po4a | |R/O| Required if compiling from git. |
| | | | Optional if compiling from tarball. |
| | | | For localizing man pages. |
+--------------+-------------+---+-----------------------------------------+
| hivex | 1.2.7 |R/O| Require if compiling from git. |
| | | | Windows Registry hive parser. |
+--------------+-------------+---+-----------------------------------------+
| libmagic | | O | The library used by the 'file' command. |
+--------------+-------------+---+-----------------------------------------+
| libvirt | | O | >= 0.10.2 is needed if you want to use |
| | | | libvirt to manage transient VMs. |
+--------------+-------------+---+-----------------------------------------+
| xmllint | | O | Part of libxml2. Used for tests only. |
+--------------+-------------+---+-----------------------------------------+
| libconfig | | O | Used to parse libguestfs's own config |
| | | | files eg. /etc/libguestfs-tools.conf. |
+--------------+-------------+---+-----------------------------------------+
| libselinux | | O | Used by the libvirt backend to securely |
| | | | confine the appliance (sVirt). |
+--------------+-------------+---+-----------------------------------------+
| augeas | 0.5.0 | O | To inspect configuration of Linux guests.
+--------------+-------------+---+-----------------------------------------+
| db utils | | O | db_dump, db_load etc. Usually found in |
| | | | a package called db-utils, db4-utils, |
| | | | db4.X-utils, Berkeley DB utils, etc. |
+--------------+-------------+---+-----------------------------------------+
| systemtap | | O | For userspace probes. |
+--------------+-------------+---+-----------------------------------------+
| readline | | O | For nicer command line in guestfish. |
+--------------+-------------+---+-----------------------------------------+
| acl | | O | Library (libacl) and programs for |
| | | | handling POSIX ACLs. |
+--------------+-------------+---+-----------------------------------------+
| libcap | | O | Library (libcap) and programs for |
| | | | handling Linux capabilities. |
+--------------+-------------+---+-----------------------------------------+
| libldm | | O | Library (libldm) and 'ldmtool' for |
| | | | handling Windows Dynamic Disks. |
+--------------+-------------+---+-----------------------------------------+
| yajl | 2 | O | JSON parser for parsing output of |
| | | | ldmtool and qemu-img info commands. |
+--------------+-------------+---+-----------------------------------------+
| gdisk | | O | GPT disk support. |
+--------------+-------------+---+-----------------------------------------+
| netpbm | | O | Render icons from guests. |
+--------------+-------------+---+-----------------------------------------+
| icoutils | | O | Render icons from Windows guests. |
+--------------+-------------+---+-----------------------------------------+
| Expect | | O | Perl module used to test virt-rescue. |
+--------------+-------------+---+-----------------------------------------+
| FUSE | | O | fusermount, libfuse, and kernel module |
| | | | are all needed if you want guestmount |
| | | | and/or 'mount-local' support. |
+--------------+-------------+---+-----------------------------------------+
| static glibc | | O | Used for testing only. |
+--------------+-------------+---+-----------------------------------------+
| qemu-nbd | | O | Used for testing only. |
+--------------+-------------+---+-----------------------------------------+
| findlib | | O | For the OCaml bindings. |
+--------------+-------------+---+-----------------------------------------+
| ocaml-gettext| | O | For localizing OCaml virt-* tools. |
+--------------+-------------+---+-----------------------------------------+
| Python | 2.2 | O | For the Python bindings. |
+--------------+-------------+---+-----------------------------------------+
| Ruby | | O | >= 1.9 is better than 1.8. |
+--------------+-------------+---+-----------------------------------------+
| rake | | O | For the Ruby bindings. |
+--------------+-------------+---+-----------------------------------------+
| rubygem-minitest | O | For the Ruby bindings. |
+--------------+-------------+---+-----------------------------------------+
| Java | 1.6 | O | Java + JNI + jpackage-utils are needed |
| | | | for the Java bindings. |
+--------------+-------------+---+-----------------------------------------+
| GHC | | O | For the Haskell bindings. |
+--------------+-------------+---+-----------------------------------------+
| PHP | | O | For the PHP bindings. |
+--------------+-------------+---+-----------------------------------------+
| phpize | | O | For the PHP bindings. |
+--------------+-------------+---+-----------------------------------------+
| glib2 | | O | For the GObject bindings. |
+--------------+-------------+---+-----------------------------------------+
| gobject-introspection | O | For the GObject bindings. |
+--------------+-------------+---+-----------------------------------------+
| gjs | | O | For testing the GObject bindings. |
+--------------+-------------+---+-----------------------------------------+
| LUA | | O | For the LUA bindings. |
+--------------+-------------+---+-----------------------------------------+
| Erlang | | O | For the Erlang bindings. |
+--------------+-------------+---+-----------------------------------------+
| erl_interface| | O | For the Erlang bindings. |
+--------------+-------------+---+-----------------------------------------+
| valgrind | | O | For testing for memory problems. |
+--------------+-------------+---+-----------------------------------------+
| Sys::Virt | | O | Perl bindings for libvirt. |
+--------------+-------------+---+-----------------------------------------+
| Win::Hivex | | O | Perl bindings for hivex. |
+--------------+-------------+---+-----------------------------------------+
| Pod::Usage | | O | Perl module used by tests. |
+--------------+-------------+---+-----------------------------------------+
| Test::More | | O | Perl module used by tests. |
+--------------+-------------+---+-----------------------------------------+
| String::Shellquote | O | Perl module used by some virt-* tools. |
+--------------+-------------+---+-----------------------------------------+
| XML::XPath | | O | Perl module used by some virt-* tools. |
+--------------+-------------+---+-----------------------------------------+
| XML::XPath::XMLParser | O | Perl module used by some virt-* tools. |
+--------------+-------------+---+-----------------------------------------+
| perl-libintl | | O | Perl module for localization. |
+--------------+-------------+---+-----------------------------------------+
| bash-completion | O | For tab-completion of commands in bash. |
+==============+=============+===+=========================================+
R = Required
O = Optional
Building
----------------------------------------------------------------------
Then make the daemon, library and root filesystem:
Build the daemon, library and root filesystem:
./configure
make
Finally run the tests:
Run the tests:
make check
@@ -180,11 +241,20 @@ some libvirt guests installed, that these guests' disks are accessible
by the current user, and these tests may fail for other reasons which
are not necessarily because of real problems.
If everything works, you can install the library and tools by running
this command as root:
make help
lists all 'make' targets.
You may install the library by running the following command as root.
However *most users should probably not do this*. Instead, './run'
the programs from the build directory as described below.
make install
Distro packagers should use this instead:
make INSTALLDIRS=vendor [DESTDIR=...] install
You can run guestfish, guestmount and the virt tools without needing
to install, using the "./run" script in the top directory. This
script sets up some environment variables. For example:
@@ -198,8 +268,7 @@ command will also work:
../run ./guestfish [...]
You can also make a symlink (note: NOT a hard link) from your $PATH to
the run script, eg:
You can also make a link from your $PATH to the run script, eg:
cd ~/bin
ln -s ~/libguestfs/run libguestfs-run
@@ -283,7 +352,7 @@ distributions. Non-Linux ports are trickier, but we will accept
patches if they aren't too invasive.
The main porting issues are with the dependencies needed to build the
appliance. You will need to port the febootstrap first
appliance. You will need to port febootstrap first
(http://people.redhat.com/~rjones/febootstrap/).
@@ -318,11 +387,11 @@ For example:
--with-qemu-options="-M versatilepb -cpu arm926"
./configure \
--with-qemu="qemu-system-arm" \
--with-qemu-options="-M vexpress-a9 -cpu cortex-a9"
--with-qemu-options="-M vexpress-a15 -cpu cortex-a15"
Note that since virtio is required by libguestfs, and virtio is a
PCI-based architecture, whatever architecture qemu emulates must
support PCI also.
PCI-based architecture, whatever architecture qemu emulates MUST
support PCI.
For PPC64 you will need to specify the IBM pSeries machine type:
@@ -337,7 +406,7 @@ attention to the qemu command line and kernel output.
Copyright and license information
----------------------------------------------------------------------
Copyright (C) 2009-2012 Red Hat Inc.
Copyright (C) 2009-2013 Red Hat Inc.
The library is distributed under the LGPLv2+. The programs are
distributed under the GPLv2+. Please see the files COPYING and

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.20)
For next major stable release (1.22)
------------------------------------
* 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.20 (put "1.20" in the Devel Whiteboard field in
Bugs assigned to 1.22 (put "1.22" 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.20&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.22&component=libguestfs&product=Virtualization%20Tools
Beyond 1.20
Beyond 1.22
-----------
* Make 'guestfish --ro' be the default, and get users to use

16
TODO
View File

@@ -361,14 +361,14 @@ Interactive disk creator
An interactive disk creator program.
Attach method for disconnected operation
----------------------------------------
Backend for disconnected operation
----------------------------------
http://libguestfs.org/guestfs.3.html#guestfs_set_attach_method
http://libguestfs.org/guestfs.3.html#guestfs_set_backend
"Librarian" has an idea that he should be able to attach to a regular
appliance, but disconnect from it and reconnect to it later. This
would be some sort of modified attach method (see link above).
would be some sort of modified backend (see link above).
The complexity here is that we would no longer have access to
stdin/stdout (or we'd have to direct that somewhere else).
@@ -427,7 +427,7 @@ Launch remote sessions over ssh
-------------------------------
We had an idea you could add a launch method that uses ssh, ie. all
febootstrap and qemu commands happen the same as now, but prefixed by
supermin and qemu commands happen the same as now, but prefixed by
ssh so it happens on a remote machine.
Note that proper remote support and integration with libvirt is
@@ -490,7 +490,7 @@ Optimize the appliance
Pass -cpu host. Anything else?
[The libvirt attach-method uses 'host-model' which is basically
[The libvirt backend uses 'host-model' which is basically
the same as this]
Sort out partitioning
@@ -534,8 +534,8 @@ 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
---------------------
libvirt backend
---------------
Since libguestfs 1.19.24 this mostly works. Here are some suggested
items to work on:

View File

@@ -19,6 +19,7 @@ include $(top_srcdir)/subdir-rules.mk
EXTRA_DIST = \
test-virt-alignment-scan.sh \
test-virt-alignment-scan-guests.sh \
virt-alignment-scan.pod
CLEANFILES = stamp-virt-alignment-scan.pod
@@ -26,6 +27,12 @@ CLEANFILES = stamp-virt-alignment-scan.pod
bin_PROGRAMS = virt-alignment-scan
SHARED_SOURCE_FILES = \
../df/domains.c \
../df/domains.h \
../df/estimate-max-threads.c \
../df/estimate-max-threads.h \
../df/parallel.c \
../df/parallel.h \
../fish/config.c \
../fish/domain.c \
../fish/inspect.c \
@@ -35,25 +42,32 @@ SHARED_SOURCE_FILES = \
virt_alignment_scan_SOURCES = \
$(SHARED_SOURCE_FILES) \
domains.c \
scan.c \
scan.h
scan.c
virt_alignment_scan_CFLAGS = \
virt_alignment_scan_CPPFLAGS = \
-DGUESTFS_WARN_DEPRECATED=1 \
-DGUESTFS_PRIVATE=1 \
-I$(top_srcdir)/src -I$(top_builddir)/src \
-I$(top_srcdir)/df \
-I$(top_srcdir)/fish \
-I$(srcdir)/../gnulib/lib -I../gnulib/lib \
-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
-DLOCALEBASEDIR=\""$(datadir)/locale"\"
virt_alignment_scan_CFLAGS = \
-pthread \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
$(GPROF_CFLAGS) $(GCOV_CFLAGS) \
$(LIBCONFIG_CFLAGS) \
$(LIBXML2_CFLAGS) \
$(LIBVIRT_CFLAGS)
virt_alignment_scan_LDADD = \
$(LIBCONFIG_LIBS) \
$(top_builddir)/src/libutils.la \
$(top_builddir)/src/libguestfs.la \
../gnulib/lib/libgnu.la \
$(LIBXML2_LIBS) \
$(LIBVIRT_LIBS) \
../gnulib/lib/libgnu.la \
-lm
# Manual pages and HTML files for the website.
@@ -78,7 +92,8 @@ TESTS =
if ENABLE_APPLIANCE
TESTS += \
test-virt-alignment-scan.sh
test-virt-alignment-scan.sh \
test-virt-alignment-scan-guests.sh
endif
check-valgrind:

View File

@@ -1,359 +0,0 @@
/* virt-alignment-scan
* 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 <libintl.h>
#ifdef HAVE_LIBVIRT
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
#endif
#include "progname.h"
#if defined(HAVE_LIBVIRT) && defined(HAVE_LIBXML2)
#define GUESTFS_PRIVATE_FOR_EACH_DISK 1
#endif
#include "guestfs.h"
#include "options.h"
#include "scan.h"
#if defined(HAVE_LIBVIRT) && defined(HAVE_LIBXML2)
/* 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 */
};
struct domain {
char *name;
char *uuid;
struct disk *disks;
size_t nr_disks;
};
struct domain *domains = NULL;
size_t nr_domains;
static int
compare_domain_names (const void *p1, const void *p2)
{
const struct domain *d1 = p1;
const struct domain *d2 = p2;
return strcmp (d1->name, d2->name);
}
static void
free_domain (struct domain *domain)
{
struct disk *disk, *next;
for (disk = domain->disks; disk; disk = next) {
next = disk->next;
free (disk->filename);
free (disk->format);
free (disk);
}
free (domain->name);
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 int add_disk (guestfs_h *g, const char *filename, const char *format, int readonly, void *domain_vp);
static size_t add_disks_to_handle_reverse (struct disk *disk, size_t *errors_r);
static void reset_guestfs_handle (void);
void
get_domains_from_libvirt (int uuid, size_t *worst_alignment_ptr)
{
virErrorPtr err;
virConnectPtr conn;
int n;
size_t i, count, errors;
const char *prefix;
nr_domains = 0;
domains = NULL;
/* Get the list of all domains. */
conn = virConnectOpenReadOnly (libvirt_uri);
if (!conn) {
err = virGetLastError ();
fprintf (stderr,
_("%s: could not connect to libvirt (code %d, domain %d): %s\n"),
program_name, err->code, err->domain, err->message);
exit (EXIT_FAILURE);
}
n = virConnectNumOfDomains (conn);
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%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);
}
int ids[n];
n = virConnectListDomains (conn, ids, n);
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%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);
n = virConnectNumOfDefinedDomains (conn);
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%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);
}
char *names[n];
n = virConnectListDefinedDomains (conn, names, n);
if (n == -1) {
err = virGetLastError ();
fprintf (stderr,
_("%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);
/* You must free these even though the libvirt documentation doesn't
* mention it.
*/
for (i = 0; i < (size_t) n; ++i)
free (names[i]);
virConnectClose (conn);
/* No domains? */
if (nr_domains == 0)
return;
/* 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) {
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);
prefix = !uuid ? domains[i].name : domains[i].uuid;
/* Perform the scan. */
scan (worst_alignment_ptr, prefix);
if (i < nr_domains - 1)
reset_guestfs_handle ();
}
/* Free up domains structure. */
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)
{
size_t i;
virDomainPtr dom;
for (i = 0; i < n; ++i) {
if (ids[i] != 0) { /* RHBZ#538041 */
dom = virDomainLookupByID (conn, ids[i]);
if (dom) { /* transient errors are possible here, ignore them */
add_domain (dom);
virDomainFree (dom);
}
}
}
}
static void
add_domains_by_name (virConnectPtr conn, char **names, size_t n)
{
size_t i;
virDomainPtr dom;
for (i = 0; i < n; ++i) {
dom = virDomainLookupByName (conn, names[i]);
if (dom) { /* transient errors are possible here, ignore them */
add_domain (dom);
virDomainFree (dom);
}
}
}
static void
add_domain (virDomainPtr dom)
{
struct domain *domain;
domains = realloc (domains, (nr_domains + 1) * sizeof (struct domain));
if (domains == NULL) {
perror ("realloc");
exit (EXIT_FAILURE);
}
domain = &domains[nr_domains];
nr_domains++;
domain->name = strdup (virDomainGetName (dom));
if (domain->name == NULL) {
perror ("strdup");
exit (EXIT_FAILURE);
}
char uuid[VIR_UUID_STRING_BUFLEN];
if (virDomainGetUUIDString (dom, uuid) == 0) {
domain->uuid = strdup (uuid);
if (domain->uuid == NULL) {
perror ("strdup");
exit (EXIT_FAILURE);
}
}
else
domain->uuid = NULL;
domain->disks = NULL;
int n = guestfs___for_each_disk (g, dom, add_disk, domain);
if (n == -1)
exit (EXIT_FAILURE);
domain->nr_disks = n;
}
static int
add_disk (guestfs_h *g,
const char *filename, const char *format, int readonly,
void *domain_vp)
{
struct domain *domain = domain_vp;
struct disk *disk;
disk = malloc (sizeof *disk);
if (disk == NULL) {
perror ("malloc");
return -1;
}
disk->next = domain->disks;
domain->disks = disk;
disk->filename = strdup (filename);
if (disk->filename == NULL) {
perror ("malloc");
return -1;
}
if (format) {
disk->format = strdup (format);
if (disk->format == NULL) {
perror ("malloc");
return -1;
}
}
else
disk->format = NULL;
return 0;
}
static size_t
add_disks_to_handle_reverse (struct disk *disk, size_t *errors_r)
{
size_t nr_disks_added;
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 };
optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK;
optargs.readonly = 1;
if (disk->format) {
optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK;
optargs.format = disk->format;
}
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. */
static void
reset_guestfs_handle (void)
{
/* Copy the settings from the old handle. */
int verbose = guestfs_get_verbose (g);
int trace = guestfs_get_trace (g);
guestfs_close (g);
g = guestfs_create ();
if (g == NULL) {
fprintf (stderr, _("guestfs_create: failed to create handle\n"));
exit (EXIT_FAILURE);
}
guestfs_set_verbose (g, verbose);
guestfs_set_trace (g, trace);
}
#endif

View File

@@ -25,20 +25,32 @@
#include <inttypes.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <locale.h>
#include <assert.h>
#include <libintl.h>
#include <pthread.h>
#ifdef HAVE_LIBVIRT
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
#endif
#include "progname.h"
#include "guestfs.h"
#include "options.h"
#include "scan.h"
#include "parallel.h"
#include "domains.h"
/* This just needs to be larger than any alignment we care about. */
static size_t worst_alignment = UINT_MAX;
static pthread_mutex_t worst_alignment_mutex = PTHREAD_MUTEX_INITIALIZER;
static int scan (guestfs_h *g, const char *prefix, FILE *fp);
#ifdef HAVE_LIBVIRT
static int scan_work (guestfs_h *g, size_t i, FILE *fp);
#endif
/* These globals are shared with options.c. */
guestfs_h *g;
@@ -52,12 +64,7 @@ const char *libvirt_uri = NULL;
int inspector = 0;
static int quiet = 0; /* --quiet */
static inline char *
bad_cast (char const *s)
{
return (char *) s;
}
static int uuid = 0; /* --uuid */
static void __attribute__((noreturn))
usage (int status)
@@ -78,6 +85,7 @@ usage (int status)
" -d|--domain guest Add disks from libvirt guest\n"
" --format[=raw|..] Force disk format for -a option\n"
" --help Display brief help\n"
" -P nr_threads Use at most nr_threads\n"
" -q|--quiet No output, just exit code\n"
" -v|--verbose Verbose messages\n"
" -V|--version Display version and exit\n"
@@ -92,22 +100,20 @@ usage (int status)
int
main (int argc, char *argv[])
{
/* Set global program name that is not polluted with libtool artifacts. */
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEBASEDIR);
textdomain (PACKAGE);
enum { HELP_OPTION = CHAR_MAX + 1 };
static const char *options = "a:c:d:qvVx";
static const char *options = "a:c:d:P:qvVx";
static const struct option long_options[] = {
{ "add", 1, 0, 'a' },
{ "connect", 1, 0, 'c' },
{ "domain", 1, 0, 'd' },
{ "format", 2, 0, 0 },
{ "help", 0, 0, HELP_OPTION },
{ "long-options", 0, 0, 0 },
{ "quiet", 0, 0, 'q' },
{ "uuid", 0, 0, 0, },
{ "verbose", 0, 0, 'v' },
@@ -119,10 +125,9 @@ main (int argc, char *argv[])
const char *format = NULL;
int c;
int option_index;
int uuid = 0;
/* This just needs to be larger than any alignment we care about. */
size_t worst_alignment = UINT_MAX;
int exit_code;
size_t max_threads = 0;
int r;
g = guestfs_create ();
if (g == NULL) {
@@ -130,15 +135,15 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
argv[0] = bad_cast (program_name);
for (;;) {
c = getopt_long (argc, argv, options, long_options, &option_index);
if (c == -1) break;
switch (c) {
case 0: /* options which are long only */
if (STREQ (long_options[option_index].name, "format")) {
if (STREQ (long_options[option_index].name, "long-options"))
display_long_options (long_options);
else if (STREQ (long_options[option_index].name, "format")) {
if (!optarg || STREQ (optarg, ""))
format = NULL;
else
@@ -164,6 +169,13 @@ main (int argc, char *argv[])
OPTION_d;
break;
case 'P':
if (sscanf (optarg, "%zu", &max_threads) != 1) {
fprintf (stderr, _("%s: -P option is not numeric\n"), program_name);
exit (EXIT_FAILURE);
}
break;
case 'q':
quiet = 1;
break;
@@ -200,16 +212,25 @@ main (int argc, char *argv[])
if (optind != argc)
usage (EXIT_FAILURE);
/* The user didn't specify any drives to scan. */
/* virt-alignment-scan has two modes. If the user didn't specify
* any drives, then we do the scan on every libvirt guest. That's
* the if-clause below. If the user specified domains/drives, then
* we assume they belong to a single guest. That's the else-clause
* below.
*/
if (drvs == NULL) {
#if defined(HAVE_LIBVIRT) && defined(HAVE_LIBXML2)
get_domains_from_libvirt (uuid, &worst_alignment);
#if defined(HAVE_LIBVIRT)
get_all_libvirt_domains (libvirt_uri);
r = start_threads (max_threads, g, scan_work);
free_domains ();
if (r == -1)
exit (EXIT_FAILURE);
#else
fprintf (stderr, _("%s: compiled without support for libvirt and/or libxml2.\n"),
fprintf (stderr, _("%s: compiled without support for libvirt.\n"),
program_name);
exit (EXIT_FAILURE);
#endif
} else {
} else { /* Single guest. */
if (uuid) {
fprintf (stderr, _("%s: --uuid option cannot be used with -a or -d\n"),
program_name);
@@ -226,9 +247,12 @@ main (int argc, char *argv[])
free_drives (drvs);
/* Perform the scan. */
scan (&worst_alignment, NULL);
r = scan (g, NULL, stdout);
guestfs_close (g);
if (r == -1)
exit (EXIT_FAILURE);
}
/* Decide on an appropriate exit code. */
@@ -242,30 +266,30 @@ main (int argc, char *argv[])
exit (exit_code);
}
void
scan (size_t *worst_alignment, const char *prefix)
static int
scan (guestfs_h *g, const char *prefix, FILE *fp)
{
char **devices, *p;
size_t i, j;
size_t alignment;
uint64_t start;
struct guestfs_partition_list *parts;
int err;
devices = guestfs_list_devices (g);
CLEANUP_FREE_STRING_LIST char **devices = guestfs_list_devices (g);
if (devices == NULL)
exit (EXIT_FAILURE);
return -1;
for (i = 0; devices[i] != NULL; ++i) {
parts = guestfs_part_list (g, devices[i]);
CLEANUP_FREE char *name = NULL;
CLEANUP_FREE_PARTITION_LIST struct guestfs_partition_list *parts =
guestfs_part_list (g, devices[i]);
if (parts == NULL)
exit (EXIT_FAILURE);
return -1;
/* Canonicalize the name of the device for printing. */
p = guestfs_canonical_device_name (g, devices[i]);
if (p == NULL)
exit (EXIT_FAILURE);
free (devices[i]);
devices[i] = p;
name = guestfs_canonical_device_name (g, devices[i]);
if (name == NULL)
return -1;
for (j = 0; j < parts->len; ++j) {
/* Start offset of the partition in bytes. */
@@ -273,10 +297,10 @@ scan (size_t *worst_alignment, const char *prefix)
if (!quiet) {
if (prefix)
printf ("%s:", prefix);
fprintf (fp, "%s:", prefix);
printf ("%s%d %12" PRIu64 " ",
devices[i], (int) parts->val[j].part_num, start);
fprintf (fp, "%s%d %12" PRIu64 " ",
name, (int) parts->val[j].part_num, start);
}
/* What's the alignment? */
@@ -288,30 +312,60 @@ scan (size_t *worst_alignment, const char *prefix)
if (!quiet) {
if (alignment < 10)
printf ("%12" PRIu64 " ", UINT64_C(1) << alignment);
fprintf (fp, "%12" PRIu64 " ", UINT64_C(1) << alignment);
else if (alignment < 64)
printf ("%12" PRIu64 "K ", UINT64_C(1) << (alignment - 10));
fprintf (fp, "%12" PRIu64 "K ", UINT64_C(1) << (alignment - 10));
else
printf ("- ");
fprintf (fp, "- ");
}
if (alignment < *worst_alignment)
*worst_alignment = alignment;
err = pthread_mutex_lock (&worst_alignment_mutex);
assert (err == 0);
if (alignment < worst_alignment)
worst_alignment = alignment;
err = pthread_mutex_unlock (&worst_alignment_mutex);
assert (err == 0);
if (alignment < 12) { /* Bad in general: < 4K alignment */
if (!quiet)
printf ("bad (%s)\n", _("alignment < 4K"));
fprintf (fp, "bad (%s)\n", _("alignment < 4K"));
} else if (alignment < 16) { /* Bad on NetApps: < 64K alignment */
if (!quiet)
printf ("bad (%s)\n", _("alignment < 64K"));
fprintf (fp, "bad (%s)\n", _("alignment < 64K"));
} else {
if (!quiet)
printf ("ok\n");
fprintf (fp, "ok\n");
}
}
guestfs_free_partition_list (parts);
free (devices[i]);
}
free (devices);
return 0;
}
#if defined(HAVE_LIBVIRT)
/* The multi-threaded version. This callback is called from the code
* in "parallel.c".
*/
static int
scan_work (guestfs_h *g, size_t i, FILE *fp)
{
struct guestfs___add_libvirt_dom_argv optargs;
optargs.bitmask =
GUESTFS___ADD_LIBVIRT_DOM_READONLY_BITMASK |
GUESTFS___ADD_LIBVIRT_DOM_READONLYDISK_BITMASK;
optargs.readonly = 1;
optargs.readonlydisk = "read";
if (guestfs___add_libvirt_dom (g, domains[i].dom, &optargs) == -1)
return -1;
if (guestfs_launch (g) == -1)
return -1;
return scan (g, !uuid ? domains[i].name : domains[i].uuid, fp);
}
#endif /* HAVE_LIBVIRT */

View File

@@ -0,0 +1,35 @@
#!/bin/bash -
# libguestfs
# Copyright (C) 2013 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.
export LANG=C
if [ -n "$SKIP_TEST_VIRT_ALIGNMENT_SCAN_GUESTS_SH" ]; then
echo "$0: skipping test because SKIP_TEST_VIRT_ALIGNMENT_SCAN_GUESTS_SH is set."
exit 77
fi
guestsdir="$(cd ../tests/guests && pwd)"
libvirt_uri="test://$guestsdir/guests-all-good.xml"
$VG ./virt-alignment-scan -c "$libvirt_uri"
r=$?
# 0, 2 and 3 are reasonable non-error exit codes. Others are errors.
if [ $r -ne 0 -a $r -ne 2 -a $r -ne 3 ]; then
exit $r
fi

View File

@@ -16,6 +16,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
export LANG=C
$VG ./virt-alignment-scan -a ../tests/guests/fedora.img
r=$?

View File

@@ -117,6 +117,12 @@ Add I<file> which should be a disk image from a virtual machine.
The format of the disk image is auto-detected. To override this and
force a particular format use the I<--format=..> option.
=item B<-a URI>
=item B<--add URI>
Add a remote disk. See L<guestfish(1)/ADDING REMOTE STORAGE>.
=item B<-c> URI
=item B<--connect> URI
@@ -158,6 +164,18 @@ 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).
=item B<-P> nr_threads
Since libguestfs 1.22, virt-alignment-scan is multithreaded and
examines guests in parallel. By default the number of threads to use
is chosen based on the amount of free memory available at the time
that virt-alignment-scan is started. You can force
virt-alignment-scan to use at most C<nr_threads> by using the I<-P>
option.
Note that I<-P 0> means to autodetect, and I<-P 1> means to use a
single thread.
=item B<-q>
=item B<--quiet>

View File

@@ -35,15 +35,23 @@ superminfsdir = $(libdir)/guestfs/supermin.d
fs_DATA =
superminfs_DATA = \
supermin.d/base.img \
supermin.d/daemon.img \
supermin.d/init.img \
supermin.d/hostfiles \
supermin.d/udev-rules.img
# 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.
if ENABLE_DAEMON
superminfs_DATA += \
supermin.d/daemon.img
endif
if ENABLE_APPLIANCE
superminfs_DATA += \
supermin.d/base.img \
supermin.d/hostfiles
endif
# This used to be a configure-generated file. However config.status
# always touches the destination file, which means the appliance got
# rebuilt too often.
make.sh: make.sh.in $(top_builddir)/config.log $(top_builddir)/config.status
cd $(top_builddir) && \
./config.status --file=appliance/$@-t:appliance/$<
@@ -51,7 +59,7 @@ make.sh: make.sh.in $(top_builddir)/config.log $(top_builddir)/config.status
cmp -s $@ $@-t || mv $@-t $@
rm -f $@-t
PACKAGELIST_CPP_FLAGS = -D$(DISTRO)=1
PACKAGELIST_CPP_FLAGS = -D$(DISTRO)=1 -DEXTRA_PACKAGES="$(EXTRA_PACKAGES)"
if VALGRIND_DAEMON
PACKAGELIST_CPP_FLAGS += -DVALGRIND_DAEMON=1
endif
@@ -70,13 +78,11 @@ excludelist: excludelist.in Makefile
supermin.d/base.img supermin.d/hostfiles: stamp-supermin
stamp-supermin: make.sh packagelist excludelist
mkdir -p supermin.d
rm -f $@ supermin.d/base.img supermin.d/hostfiles
./make.sh
touch $@
supermin.d/daemon.img: ../daemon/guestfsd guestfsd.suppressions
mkdir -p supermin.d
rm -f $@ $@-t
rm -rf tmp-d
mkdir -p tmp-d$(DAEMON_SUPERMIN_DIR) tmp-d/etc
@@ -87,20 +93,20 @@ supermin.d/daemon.img: ../daemon/guestfsd guestfsd.suppressions
mv $@-t $@
supermin.d/init.img: init
cmp -s $(srcdir)/init $(builddir)/init || cp $(srcdir)/init $(builddir)/init
mkdir -p supermin.d
rm -f $@ $@-t
echo "init" | cpio --quiet -o -H newc > $@-t
rm -rf init.tmp $@ $@-t
mkdir init.tmp
cp $< init.tmp
(cd init.tmp; echo "init" | cpio --quiet -o -H newc) > $@-t
rm -r init.tmp
mv $@-t $@
# We should put this file in /lib/udev/rules.d, but put it in /etc so
# we don't have to deal with all the UsrMove crap in Fedora.
supermin.d/udev-rules.img: 99-guestfs-serial.rules
mkdir -p supermin.d
rm -f $@ $@-t
rm -rf tmp-u
mkdir -p tmp-u/etc/udev/rules.d
for f in $^; do ln $$f tmp-u/etc/udev/rules.d/$$f; done
for f in $^; do ln $$f tmp-u/etc/udev/rules.d/$$(basename $$f); done
( cd tmp-u && find | cpio --quiet -o -H newc ) > $@-t
rm -rf tmp-u
mv $@-t $@
@@ -132,7 +138,5 @@ stamp-libguestfs-make-fixed-appliance.pod: libguestfs-make-fixed-appliance.pod
CLEANFILES = packagelist excludelist \
libguestfs-make-fixed-appliance.1 \
stamp-libguestfs-make-fixed-appliance.pod
clean-local:
rm -rf supermin.d
stamp-libguestfs-make-fixed-appliance.pod \
supermin.d/*

View File

@@ -10,6 +10,16 @@ RUNLEVEL=S
PREVLEVEL=N
export RUNLEVEL PREVLEVEL
# Try to print a stack trace for segfaults inside the appliance.
for d in /lib64 /lib; do
f=$d/libSegFault.so
if [ -f "$f" ]; then
LD_PRELOAD=$f
export LD_PRELOAD
break
fi
done
mkdir -p /sysroot
if [ ! -d /proc ]; then rm -f /proc; fi
@@ -18,6 +28,9 @@ mount -t proc /proc /proc
if [ ! -d /sys ]; then rm -f /sys; fi
mkdir -p /sys
mount -t sysfs /sys /sys
# taken from initramfs-tools/init --Hilko Bengen
mkdir -p /run
mount -t tmpfs -o "nosuid,size=20%,mode=0755" tmpfs /run
mkdir -p /run/lock
# devtmpfs is required since udev 176
@@ -91,6 +104,9 @@ modprobe dm_mod ||:
lvm vgscan --ignorelockingfailure
lvm vgchange -ay --ignorelockingfailure
# Scan for Windows dynamic disks.
ldmtool create all
# Improve virtio-blk performance (RHBZ#509383).
for f in /sys/block/vd*/queue/rotational; do echo 1 > $f; done

View File

@@ -15,11 +15,33 @@ libguestfs-make-fixed-appliance - Make a "fixed appliance" for libguestfs
libguestfs-make-fixed-appliance lets you make a pre-built binary
appliance for libguestfs.
B<Note that ordinary users should not need to run this tool>. The
only reason to use it is if you want to make a self-contained
libguestfs appliance that can be copied to another machine or platform
that doesn't support L<febootstrap(8)>. To understand why you might
need to use this tool, read the section L</FIXED APPLIANCE> below.
B<Note that ordinary users should not need to run this tool>.
Some reasons why you I<might> want to use this include:
=over 4
=item *
You want to make a self-contained libguestfs appliance that can be
copied to another machine or platform that doesn't support
L<supermin(8)>.
=item *
You have multiple users on the same machine and want to avoid the
storage duplication and start-up overhead of having multiple cached
copies of the appliance.
=item *
You want to have very predictable performance from libguestfs (see
L<guestfs-performance(1)>).
=back
For deeper understanding of why you might need this tool, read the
section L</FIXED APPLIANCE> below.
Instead of running this tool, you can download fixed appliances from
L<http://libguestfs.org/download/binaries/appliance/>. These
@@ -107,21 +129,21 @@ looking for an appliance. The path is built into libguestfs, or can
be set using the C<LIBGUESTFS_PATH> environment variable.
Normally a supermin appliance is located on this path (see
L<febootstrap(8)/SUPERMIN APPLIANCE>). libguestfs reconstructs this
into a full appliance by running L<febootstrap-supermin-helper(8)>.
L<supermin(8)/SUPERMIN APPLIANCE>). libguestfs reconstructs this
into a full appliance by running L<supermin-helper(8)>.
However, a simpler "fixed appliance" can also be used. libguestfs
detects this by looking for a directory on the path containing four
files called C<kernel>, C<initrd>, C<root> and C<README.fixed> (note
the C<README.fixed> file must be present as well).
If the fixed appliance is found, libguestfs skips febootstrap entirely
If the fixed appliance is found, libguestfs skips supermin entirely
and just runs qemu with the kernel, initrd and root disk from the
fixed appliance.
Thus the fixed appliance can be used when a platform or Linux distro
does not support febootstrap. You build the fixed appliance on a
platform that does support febootstrap, and copy it over, and use that
does not support supermin. You build the fixed appliance on a
platform that does support supermin, and copy it over, and use that
to run libguestfs.
=head1 LICENSING
@@ -144,8 +166,8 @@ libguestfs, please see the L<guestfs(3)> manual page.
=head1 SEE ALSO
L<guestfs(3)>,
L<febootstrap(8)>,
L<febootstrap-supermin-helper(8)>,
L<supermin(8)>,
L<supermin-helper(8)>,
L<xz(1)>,
L<http://libguestfs.org/>,
L<http://qemu.org/>.
@@ -156,4 +178,4 @@ Richard W.M. Jones (C<rjones at redhat dot com>)
=head1 COPYRIGHT
Copyright (C) 2009-2012 Red Hat Inc.
Copyright (C) 2009-2013 Red Hat Inc.

View File

@@ -1,6 +1,6 @@
#!/bin/bash -
# @configure_input@
# Copyright (C) 2009-2012 Red Hat Inc.
# Copyright (C) 2009-2013 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
@@ -27,13 +27,18 @@ while read regexp <&5; do
done
exec 5<&-
# Run febootstrap on the package list.
if [ "x@FEBOOTSTRAP_YUM_CONFIG@" != "xno" ]; then
extra="--yum-config @FEBOOTSTRAP_YUM_CONFIG@"
# Run supermin on the package list.
# NB: Keep using --yum-config (deprecated alias) here since both old
# and new supermin still support it.
if [ "x@SUPERMIN_PACKAGER_CONFIG@" != "xno" ]; then
extra="--yum-config @SUPERMIN_PACKAGER_CONFIG@"
fi
if [ "x@SUPERMIN_EXTRA_OPTIONS@" != "xno" ]; then
extra="$extra @SUPERMIN_EXTRA_OPTIONS@"
fi
echo @FEBOOTSTRAP@ -v -o supermin.d --names $(< packagelist ) $excludes $extra
@FEBOOTSTRAP@ -v -o supermin.d --names $(< packagelist ) $excludes $extra
echo @SUPERMIN@ -v -o supermin.d --names $(< packagelist ) $excludes $extra
@SUPERMIN@ -v -o supermin.d --names $(< packagelist ) $excludes $extra
# Remove some things that we don't want in the appliance. This is
# copied from the old febootstrap-minimize. However minimization is
@@ -41,10 +46,6 @@ echo @FEBOOTSTRAP@ -v -o supermin.d --names $(< packagelist ) $excludes $extra
< supermin.d/hostfiles \
grep -v '^/usr/lib/locale' |
grep -v '^/usr/share/locale' |
grep -v '^/usr/lib/gconv' |
grep -v '^/usr/lib64/gconv' |
grep -v '^/usr/bin/localedef' |
grep -v '^/usr/sbin/build-locale-archive' |
grep -v '^/usr/share/man/' |
grep -v '^/usr/share/doc/' |
grep -v '^/usr/share/info/' |

View File

@@ -11,6 +11,10 @@
*
* There is also a list of packages which are excluded if they appear
* as dependencies of the packages below. See: excludelist.in
*
* To add arbitrary extra packages, use:
*
* ./configure --with-extra-packages="gdb valgrind [etc]"
*/
/* Basically the same with a few minor tweaks. */
@@ -26,24 +30,30 @@
e2fsprogs
/* e4fsprogs only exists on RHEL 5, will be ignored everywhere else. */
e4fsprogs
genisoimage
gfs-utils
gfs2-utils
grub
hfsplus-tools
hivex
iproute
iputils
kernel
libcap
libldm /* only Fedora has this for now, but we should add it to others later*/
MAKEDEV
nilfs-utils
ntfsprogs
ntfs-3g
openssh-clients
pcre
reiserfs-utils
libselinux
syslinux-extlinux
systemd /* for /sbin/reboot and udevd */
util-linux-ng
vim-minimal
xz
yajl
zfs-fuse
#endif /* REDHAT */
@@ -52,43 +62,56 @@
btrfs-tools
cryptsetup
e2fsprogs
extlinux
genisoimage
gfs-tools
gfs2-tools
grub-pc
hfsplus
iproute
libaugeas0
libcap2
libhivex0
libpcre3
libyajl2
linux-image
/* syslinux 'suggests' mtools, but in reality it's a hard dependency: */
mtools
nilfs-tools
ntfs-3g
ntfsprogs
openssh-client
reiserfsprogs
sysvinit /* for /sbin/reboot */
ufsutils
util-linux
vim-tiny
xz-utils
zfs-fuse
#endif /* DEBIAN */
#ifdef ARCHLINUX
linux
vim
btrfs-progs-unstable
cryptsetup
augeas
hivex
zfs-fuse
btrfs-progs
cdrkit
cryptsetup
e2fsprogs
grub
hivex
iproute2
iputils
libcap
linux
lrzip
nilfs-utils
ntfsprogs
ntfs-3g
pcre
reiserfsprogs
util-linux-ng
systemd
vim
xz
yajl
zfs-fuse
#endif /* ARCHLINUX */
acl
@@ -103,11 +126,12 @@ dosfstools
file
findutils
gawk
genisoimage
gdisk
grep
gzip
iproute
jfsutils
kmod
less
libxml2
lsof
lsscsi
@@ -122,12 +146,17 @@ ocfs2-tools
*/
parted
procps
procps-ng
psmisc
rsync
scrub
sed
strace
syslinux
tar
udev
util-linux
util-linux-ng
#ifndef UBUNTU
/* on Ubuntu contains a file in /lib64 which conflicts with libc6 that has
* /lib64 as a symbolic link
@@ -139,3 +168,6 @@ zerofree
#ifdef VALGRIND_DAEMON
valgrind
#endif
/* Define this by doing: ./configure --with-extra-packages="..." */
EXTRA_PACKAGES

68
bash/Makefile.am Normal file
View File

@@ -0,0 +1,68 @@
# libguestfs
# Copyright (C) 2013 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 $(top_srcdir)/subdir-rules.mk
scripts = \
guestfish \
guestmount \
virt-alignment-scan \
virt-cat \
virt-df \
virt-edit \
virt-filesystems \
virt-format \
virt-inspector \
virt-ls \
virt-rescue \
virt-resize \
virt-sparsify \
virt-sysprep
EXTRA_DIST = \
README \
$(scripts)
# Some of the scripts are simply symbolic links.
virt-cat:
ln -sf virt-alignment-scan $@
virt-df:
ln -sf virt-alignment-scan $@
virt-edit:
ln -sf virt-alignment-scan $@
virt-filesystems:
ln -sf virt-alignment-scan $@
virt-format:
ln -sf virt-alignment-scan $@
virt-inspector:
ln -sf virt-alignment-scan $@
virt-ls:
ln -sf virt-alignment-scan $@
virt-sysprep:
ln -sf virt-alignment-scan $@
virt-sparsify:
ln -sf virt-resize $@
if HAVE_BASH_COMPLETION
# Bash completion script.
bashcompletiondir = $(BASH_COMPLETIONS_DIR)
bashcompletion_DATA = $(scripts)
endif

3
bash/README Normal file
View File

@@ -0,0 +1,3 @@
This directory contains the scripts for tab-completing commands in
bash. Note these new-style demand-loaded scripts require
'bash-completion' >= 1.99.

72
bash/guestfish Normal file
View File

@@ -0,0 +1,72 @@
# guestfish bash completion script -*- shell-script -*-
# Copyright (C) 2010-2013 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.
# List all local libvirt domains.
_guestfs_virsh_list ()
{
local flag_ro=$1 flags
if [ "$flag_ro" -eq 1 ]; then
flags="--all"
else
flags="--inactive"
fi
virsh list $flags | head -n -1 | tail -n +3 | awk '{print $2}'
}
_guestfish ()
{
local cur prev words cword split
local longopts flag_ro=0 c=1 word cmds doms
_init_completion -s || return
longopts="$(guestfish --long-options)"
# See if user has specified certain options anywhere on the
# command line before the current word.
while [ $c -lt $COMP_CWORD ]; do
word="${COMP_WORDS[c]}"
case "$word" in
-r|--ro) flag_ro=1 ;;
esac
c=$((++c))
done
case "$prev" in
-a|--add)
COMPREPLY=( $(compgen "$cur") )
return ;;
-d|--domain)
doms=$(_guestfs_virsh_list "$flag_ro")
COMPREPLY=( $(compgen -W "$doms" -- "$cur") )
return ;;
esac
case "$cur" in
--*)
# --options
COMPREPLY=( $(compgen -W "$longopts" -- "$cur") )
return ;;
*)
# Might be a guestfish command.
cmds=$(guestfish -h| head -n -1 | tail -n +2 | awk '{print $1}')
COMPREPLY=( $(compgen -W "$cmds" -- "$cur") )
return ;;
esac
} &&
complete -o default -F _guestfish guestfish

67
bash/guestmount Normal file
View File

@@ -0,0 +1,67 @@
# guestmount bash completion script -*- shell-script -*-
# Copyright (C) 2010-2013 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.
# List all local libvirt domains.
_guestfs_virsh_list ()
{
local flag_ro=$1 flags
if [ "$flag_ro" -eq 1 ]; then
flags="--all"
else
flags="--inactive"
fi
virsh list $flags | head -n -1 | tail -n +3 | awk '{print $2}'
}
_guestmount ()
{
local cur prev words cword split
local longopts flag_ro=0 c=1 word doms
_init_completion -s || return
longopts="$(guestmount --long-options)"
# See if user has specified certain options anywhere on the
# command line before the current word.
while [ $c -lt $COMP_CWORD ]; do
word="${COMP_WORDS[c]}"
case "$word" in
-r|--ro) flag_ro=1 ;;
esac
c=$((++c))
done
case "$prev" in
-d|--domain)
doms=$(_guestfs_virsh_list "$flag_ro")
COMPREPLY=( $(compgen -W "$doms" -- "$cur") )
return ;;
esac
case "$cur" in
--*)
# --options
COMPREPLY=( $(compgen -W "$longopts" -- "$cur") )
return ;;
*)
COMPREPLY=( $(compgen "$cur") )
return ;;
esac
} &&
complete -o default -F _guestmount guestmount

108
bash/virt-alignment-scan Normal file
View File

@@ -0,0 +1,108 @@
# virt-tools bash completion script -*- shell-script -*-
# Copyright (C) 2010-2013 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.
# List all local libvirt domains.
_guestfs_virsh_list ()
{
local flag_ro=$1 flags
if [ "$flag_ro" -eq 1 ]; then
flags="--all"
else
flags="--inactive"
fi
virsh list $flags | head -n -1 | tail -n +3 | awk '{print $2}'
}
_guestfs_virttools ()
{
local cur prev words cword split
local longopts="$1" flag_ro="$2" doms
_init_completion -s || return
case "$prev" in
-d|--domain)
doms=$(_guestfs_virsh_list "$flag_ro")
COMPREPLY=( $(compgen -W "$doms" -- "$cur") )
return ;;
esac
case "$cur" in
--*)
# --options
COMPREPLY=( $(compgen -W "$longopts" -- "$cur") )
return ;;
*)
COMPREPLY=( $(compgen "$cur") )
return ;;
esac
}
_virt_alignment_scan ()
{
_guestfs_virttools "$(virt-alignment-scan --long-options)" 1
} &&
complete -o default -F _virt_alignment_scan virt-alignment-scan
_virt_cat ()
{
_guestfs_virttools "$(virt-cat --long-options)" 1
} &&
complete -o default -F _virt_cat virt-cat
_virt_df ()
{
_guestfs_virttools "$(virt-df --long-options)" 1
} &&
complete -o default -F _virt_df virt-df
_virt_edit ()
{
_guestfs_virttools "$(virt-edit --long-options)" 0
} &&
complete -o default -F _virt_edit virt-edit
_virt_filesystems ()
{
_guestfs_virttools "$(virt-filesystems --long-options)" 1
} &&
complete -o default -F _virt_filesystems virt-filesystems
_virt_format ()
{
_guestfs_virttools "$(virt-format --long-options)" 0
} &&
complete -o default -F _virt_format virt-format
_virt_inspector ()
{
_guestfs_virttools "$(virt-inspector --long-options)" 1
} &&
complete -o default -F _virt_inspector virt-inspector
_virt_ls ()
{
_guestfs_virttools "$(virt-ls --long-options)" 1
} &&
complete -o default -F _virt_ls virt-ls
_virt_sysprep ()
{
_guestfs_virttools "$(virt-sysprep --long-options)" 0
} &&
complete -o default -F _virt_sysprep virt-sysprep

67
bash/virt-rescue Normal file
View File

@@ -0,0 +1,67 @@
# virt-rescue bash completion script -*- shell-script -*-
# Copyright (C) 2010-2013 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.
# List all local libvirt domains.
_guestfs_virsh_list ()
{
local flag_ro=$1 flags
if [ "$flag_ro" -eq 1 ]; then
flags="--all"
else
flags="--inactive"
fi
virsh list $flags | head -n -1 | tail -n +3 | awk '{print $2}'
}
_virt_rescue ()
{
local cur prev words cword split
local longopts flag_ro=0 c=1 word doms
_init_completion -s || return
longopts="$(virt-rescue --long-options)"
# See if user has specified certain options anywhere on the
# command line before the current word.
while [ $c -lt $COMP_CWORD ]; do
word="${COMP_WORDS[c]}"
case "$word" in
-r|--ro) flag_ro=1 ;;
esac
c=$((++c))
done
case "$prev" in
-d|--domain)
doms=$(_guestfs_virsh_list "$flag_ro")
COMPREPLY=( $(compgen -W "$doms" -- "$cur") )
return ;;
esac
case "$cur" in
--*)
# --options
COMPREPLY=( $(compgen -W "$longopts" -- "$cur") )
return ;;
*)
COMPREPLY=( $(compgen "$cur") )
return ;;
esac
} &&
complete -o default -F _virt_rescue virt-rescue

46
bash/virt-resize Normal file
View File

@@ -0,0 +1,46 @@
# virt-resize, virt-sparsify bash completion script -*- shell-script -*-
# Copyright (C) 2010-2013 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.
_guestfs_options_only ()
{
local cur prev words cword split
local longopts="$1"
_init_completion -s || return
case "$cur" in
--*)
# --options
COMPREPLY=( $(compgen -W "$longopts" -- "$cur") )
return ;;
*)
COMPREPLY=( $(compgen "$cur") )
return ;;
esac
}
_virt_resize ()
{
_guestfs_options_only "$(virt-resize --long-options)"
} &&
complete -o default -F _virt_resize virt-resize
_virt_sparsify ()
{
_guestfs_options_only "$(virt-sparsify --long-options)"
} &&
complete -o default -F _virt_sparsify virt-sparsify

View File

@@ -38,6 +38,8 @@ gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
modules='
accept4
areadlink
areadlinkat
arpa_inet
byteswap
c-ctype
@@ -68,13 +70,13 @@ maintainer-makefile
manywarnings
memmem
mkdtemp
mkstemps
netdb
netinet_in
openat
perror
pipe2
pread
progname
read-file
readlink
select

View File

@@ -1,6 +1,6 @@
#!/bin/bash -
# bugs-in-changelog.sh
# Copyright (C) 2009-2012 Red Hat Inc.
# Copyright (C) 2009-2013 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

View File

@@ -41,54 +41,75 @@ virt_cat_SOURCES = \
$(SHARED_SOURCE_FILES) \
virt-cat.c
virt_cat_CFLAGS = \
virt_cat_CPPFLAGS = \
-DGUESTFS_WARN_DEPRECATED=1 \
-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
-I$(top_srcdir)/src -I$(top_builddir)/src \
-I$(top_srcdir)/fish \
-I$(srcdir)/../gnulib/lib -I../gnulib/lib \
-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
-I$(srcdir)/../gnulib/lib -I../gnulib/lib
virt_cat_CFLAGS = \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
$(LIBCONFIG_CFLAGS)
$(GPROF_CFLAGS) $(GCOV_CFLAGS) \
$(LIBCONFIG_CFLAGS) \
$(LIBXML2_CFLAGS)
virt_cat_LDADD = \
$(LIBCONFIG_LIBS) \
$(top_builddir)/src/libutils.la \
$(top_builddir)/src/libguestfs.la \
$(LIBXML2_LIBS) \
$(LIBVIRT_LIBS) \
../gnulib/lib/libgnu.la
virt_filesystems_SOURCES = \
$(SHARED_SOURCE_FILES) \
virt-filesystems.c
virt_filesystems_CFLAGS = \
virt_filesystems_CPPFLAGS = \
-DGUESTFS_WARN_DEPRECATED=1 \
-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
-I$(top_srcdir)/src -I$(top_builddir)/src \
-I$(top_srcdir)/fish \
-I$(srcdir)/../gnulib/lib -I../gnulib/lib \
-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
-I$(srcdir)/../gnulib/lib -I../gnulib/lib
virt_filesystems_CFLAGS = \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
$(LIBCONFIG_CFLAGS)
$(GPROF_CFLAGS) $(GCOV_CFLAGS) \
$(LIBCONFIG_CFLAGS) \
$(LIBXML2_CFLAGS)
virt_filesystems_LDADD = \
$(LIBCONFIG_LIBS) \
$(top_builddir)/src/libutils.la \
$(top_builddir)/src/libguestfs.la \
$(LIBXML2_LIBS) \
$(LIBVIRT_LIBS) \
../gnulib/lib/libgnu.la
virt_ls_SOURCES = \
$(SHARED_SOURCE_FILES) \
virt-ls.c
virt_ls_CFLAGS = \
virt_ls_CPPFLAGS = \
-DGUESTFS_WARN_DEPRECATED=1 \
-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
-I$(top_srcdir)/src -I$(top_builddir)/src \
-I$(top_srcdir)/fish \
-I$(srcdir)/../gnulib/lib -I../gnulib/lib \
-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
-I$(srcdir)/../gnulib/lib -I../gnulib/lib
virt_ls_CFLAGS = \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
$(LIBCONFIG_CFLAGS)
$(GPROF_CFLAGS) $(GCOV_CFLAGS) \
$(LIBCONFIG_CFLAGS) \
$(LIBXML2_CFLAGS)
virt_ls_LDADD = \
$(LIBCONFIG_LIBS) \
$(top_builddir)/src/libutils.la \
$(top_builddir)/src/libguestfs.la \
$(LIBXML2_LIBS) \
$(LIBVIRT_LIBS) \
../gnulib/lib/libgnu.la
# Manual pages and HTML files for the website.

View File

@@ -1,6 +1,6 @@
#!/bin/bash -
# libguestfs
# Copyright (C) 2009-2012 Red Hat Inc.
# Copyright (C) 2009-2013 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

View File

@@ -1,6 +1,6 @@
#!/bin/bash -
# libguestfs
# Copyright (C) 2009-2012 Red Hat Inc.
# Copyright (C) 2009-2013 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

View File

@@ -24,11 +24,11 @@
#include <inttypes.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <locale.h>
#include <assert.h>
#include <libintl.h>
#include "progname.h"
#include "c-ctype.h"
#include "guestfs.h"
@@ -45,15 +45,10 @@ int echo_keys = 0;
const char *libvirt_uri = NULL;
int inspector = 1;
static int do_cat (int argc, char *argv[]);
static int is_windows (guestfs_h *g, const char *root);
static char *windows_path (guestfs_h *g, const char *root, const char *filename);
static inline char *
bad_cast (char const *s)
{
return (char *) s;
}
static void __attribute__((noreturn))
usage (int status)
{
@@ -88,9 +83,6 @@ usage (int status)
int
main (int argc, char *argv[])
{
/* Set global program name that is not polluted with libtool artifacts. */
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEBASEDIR);
textdomain (PACKAGE);
@@ -106,6 +98,7 @@ main (int argc, char *argv[])
{ "format", 2, 0, 0 },
{ "help", 0, 0, HELP_OPTION },
{ "keys-from-stdin", 0, 0, 0 },
{ "long-options", 0, 0, 0 },
{ "verbose", 0, 0, 'v' },
{ "version", 0, 0, 'V' },
{ 0, 0, 0, 0 }
@@ -114,6 +107,7 @@ main (int argc, char *argv[])
struct drv *drv;
const char *format = NULL;
int c;
int r;
int option_index;
g = guestfs_create ();
@@ -122,15 +116,15 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
argv[0] = bad_cast (program_name);
for (;;) {
c = getopt_long (argc, argv, options, long_options, &option_index);
if (c == -1) break;
switch (c) {
case 0: /* options which are long only */
if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
if (STREQ (long_options[option_index].name, "long-options"))
display_long_options (long_options);
else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
keys_from_stdin = 1;
} else if (STREQ (long_options[option_index].name, "echo-keys")) {
echo_keys = 1;
@@ -240,24 +234,34 @@ main (int argc, char *argv[])
/* Free up data structures, no longer needed after this point. */
free_drives (drvs);
r = do_cat (argc - optind, &argv[optind]);
guestfs_close (g);
exit (r == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
static int
do_cat (int argc, char *argv[])
{
unsigned errors = 0;
int windows;
char *root, **roots;
int windows, i;
char *root;
/* Get root mountpoint. See: fish/inspect.c:inspect_mount */
roots = guestfs_inspect_get_roots (g);
CLEANUP_FREE_STRING_LIST char **roots = guestfs_inspect_get_roots (g);
assert (roots);
assert (roots[0] != NULL);
assert (roots[1] == NULL);
root = roots[0];
free (roots);
/* Windows? Special handling is required. */
windows = is_windows (g, root);
for (; optind < argc; optind++) {
char *filename_to_free = NULL;
const char *filename = argv[optind];
for (i = 0; i < argc; ++i) {
CLEANUP_FREE char *filename_to_free = NULL;
const char *filename = argv[i];
if (windows) {
filename = filename_to_free = windows_path (g, root, filename);
@@ -269,15 +273,9 @@ main (int argc, char *argv[])
if (guestfs_download (g, filename, "/dev/stdout") == -1)
errors++;
free (filename_to_free);
}
free (root);
guestfs_close (g);
exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
return errors == 0 ? 0 : -1;
}
static int

View File

@@ -78,6 +78,12 @@ them with separate I<-a> options.
The format of the disk image is auto-detected. To override this and
force a particular format use the I<--format=..> option.
=item B<-a URI>
=item B<--add URI>
Add a remote disk. See L<guestfish(1)/ADDING REMOTE STORAGE>.
=item B<-c> URI
=item B<--connect> URI

View File

@@ -24,6 +24,7 @@
#include <inttypes.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <locale.h>
#include <assert.h>
#include <string.h>
@@ -31,7 +32,6 @@
#include "c-ctype.h"
#include "human.h"
#include "progname.h"
#include "guestfs.h"
#include "options.h"
@@ -80,12 +80,6 @@ static void do_output_end (void);
static struct guestfs_lvm_pv_list *get_pvs (void);
static void free_pvs (void);
static inline char *
bad_cast (char const *s)
{
return (char *) s;
}
static void __attribute__((noreturn))
usage (int status)
{
@@ -137,9 +131,6 @@ usage (int status)
int
main (int argc, char *argv[])
{
/* Set global program name that is not polluted with libtool artifacts. */
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEBASEDIR);
textdomain (PACKAGE);
@@ -162,9 +153,10 @@ main (int argc, char *argv[])
{ "help", 0, 0, HELP_OPTION },
{ "human-readable", 0, 0, 'h' },
{ "keys-from-stdin", 0, 0, 0 },
{ "long", 0, 0, 'l' },
{ "logical-volumes", 0, 0, 0 },
{ "logvols", 0, 0, 0 },
{ "long", 0, 0, 'l' },
{ "long-options", 0, 0, 0 },
{ "lvs", 0, 0, 0 },
{ "no-title", 0, 0, 0 },
{ "parts", 0, 0, 0 },
@@ -197,15 +189,15 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
argv[0] = bad_cast (program_name);
for (;;) {
c = getopt_long (argc, argv, options, long_options, &option_index);
if (c == -1) break;
switch (c) {
case 0: /* options which are long only */
if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
if (STREQ (long_options[option_index].name, "long-options"))
display_long_options (long_options);
else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
keys_from_stdin = 1;
} else if (STREQ (long_options[option_index].name, "echo-keys")) {
echo_keys = 1;
@@ -379,9 +371,6 @@ static int is_md (char *device);
static char **parents_of_md (char *device);
static char **parents_of_vg (char *vg);
static void free_strings (char **strings);
static size_t count_strings (char **strings);
static void
do_output_title (void)
{
@@ -438,22 +427,21 @@ do_output (void)
static void
do_output_filesystems (void)
{
char **fses;
size_t i;
fses = guestfs_list_filesystems (g);
CLEANUP_FREE_STRING_LIST char **fses = guestfs_list_filesystems (g);
if (fses == NULL)
exit (EXIT_FAILURE);
for (i = 0; fses[i] != NULL; i += 2) {
char *dev, *vfs_label = NULL, *vfs_uuid = NULL;
char **parents;
CLEANUP_FREE char *dev = NULL, *vfs_label = NULL, *vfs_uuid = NULL;
CLEANUP_FREE_STRING_LIST char **parents = NULL;
int64_t size = -1;
/* Skip swap and unknown, unless --extra flag was given. */
if (!(output & OUTPUT_FILESYSTEMS_EXTRA) &&
(STREQ (fses[i+1], "swap") || STREQ (fses[i+1], "unknown")))
goto next;
continue;
dev = guestfs_canonical_device_name (g, fses[i]);
if (dev == NULL)
@@ -499,32 +487,20 @@ do_output_filesystems (void)
write_row (dev, "filesystem",
fses[i+1], vfs_label, -1, size, parents, vfs_uuid);
free_strings (parents);
free (dev);
free (vfs_label);
free (vfs_uuid);
next:
free (fses[i]);
free (fses[i+1]);
}
free (fses);
}
static void
do_output_lvs (void)
{
char **lvs;
size_t i;
lvs = guestfs_lvs (g);
CLEANUP_FREE_STRING_LIST char **lvs = guestfs_lvs (g);
if (lvs == NULL)
exit (EXIT_FAILURE);
for (i = 0; lvs[i] != NULL; ++i) {
char *uuid = NULL, *parent_name = NULL;
CLEANUP_FREE char *uuid = NULL, *parent_name = NULL;
const char *parents[2];
int64_t size = -1;
@@ -553,29 +529,23 @@ do_output_lvs (void)
write_row (lvs[i], "lv",
NULL, NULL, -1, size, (char **) parents, uuid);
free (uuid);
free (parent_name);
free (lvs[i]);
}
free (lvs);
}
static void
do_output_vgs (void)
{
struct guestfs_lvm_vg_list *vgs;
size_t i;
vgs = guestfs_vgs_full (g);
CLEANUP_FREE_LVM_VG_LIST struct guestfs_lvm_vg_list *vgs =
guestfs_vgs_full (g);
if (vgs == NULL)
exit (EXIT_FAILURE);
for (i = 0; i < vgs->len; ++i) {
char *name;
CLEANUP_FREE char *name = NULL;
char uuid[33];
char **parents;
CLEANUP_FREE_STRING_LIST char **parents = NULL;
if (asprintf (&name, "/dev/%s", vgs->val[i].vg_name) == -1) {
perror ("asprintf");
@@ -589,12 +559,7 @@ do_output_vgs (void)
write_row (name, "vg",
NULL, NULL, -1, (int64_t) vgs->val[i].vg_size, parents, uuid);
free (name);
free_strings (parents);
}
guestfs_free_lvm_vg_list (vgs);
}
/* Cache the output of guestfs_pvs_full, since we use it in a few places. */
@@ -629,11 +594,11 @@ do_output_pvs (void)
struct guestfs_lvm_pv_list *pvs = get_pvs ();
for (i = 0; i < pvs->len; ++i) {
char *dev;
char uuid[33];
const char *parents[1] = { NULL };
dev = guestfs_canonical_device_name (g, pvs->val[i].pv_name);
CLEANUP_FREE char *dev =
guestfs_canonical_device_name (g, pvs->val[i].pv_name);
if (!dev)
exit (EXIT_FAILURE);
@@ -642,15 +607,13 @@ do_output_pvs (void)
write_row (dev, "pv",
NULL, NULL, -1, (int64_t) pvs->val[i].pv_size,
(char **) parents, uuid);
free (dev);
}
}
static int
get_mbr_id (const char *dev, const char *parent_name)
{
char *parttype = NULL;
CLEANUP_FREE char *parttype = NULL;
int mbr_id = -1, partnum;
guestfs_push_error_handler (g, NULL, NULL);
@@ -663,8 +626,6 @@ get_mbr_id (const char *dev, const char *parent_name)
mbr_id = guestfs_part_get_mbr_id (g, parent_name, partnum);
}
free (parttype);
guestfs_pop_error_handler (g);
return mbr_id;
@@ -673,15 +634,14 @@ get_mbr_id (const char *dev, const char *parent_name)
static void
do_output_partitions (void)
{
char **parts;
size_t i;
parts = guestfs_list_partitions (g);
CLEANUP_FREE_STRING_LIST char **parts = guestfs_list_partitions (g);
if (parts == NULL)
exit (EXIT_FAILURE);
for (i = 0; parts[i] != NULL; ++i) {
char *dev, *parent_name = NULL;
CLEANUP_FREE char *dev = NULL, *parent_name = NULL, *canonical_name = NULL;
const char *parents[2];
int64_t size = -1;
int mbr_id = -1;
@@ -703,41 +663,32 @@ do_output_partitions (void)
if ((columns & COLUMN_MBR))
mbr_id = get_mbr_id (parts[i], parent_name);
char *p = guestfs_canonical_device_name (g, parent_name);
if (!p)
canonical_name = guestfs_canonical_device_name (g, parent_name);
if (!canonical_name)
exit (EXIT_FAILURE);
free (parent_name);
parent_name = p;
parents[0] = parent_name;
parents[0] = canonical_name;
parents[1] = NULL;
}
write_row (dev, "partition",
NULL, NULL, mbr_id, size, (char **) parents, NULL);
free (dev);
free (parent_name);
free (parts[i]);
}
free (parts);
}
static void
do_output_blockdevs (void)
{
char **devices;
size_t i;
devices = guestfs_list_devices (g);
CLEANUP_FREE_STRING_LIST char **devices = guestfs_list_devices (g);
if (devices == NULL)
exit (EXIT_FAILURE);
for (i = 0; devices[i] != NULL; ++i) {
int64_t size = -1;
char *dev;
char **parents;
CLEANUP_FREE_STRING_LIST char **parents = NULL;
CLEANUP_FREE char *dev;
dev = guestfs_canonical_device_name (g, devices[i]);
if (!dev)
@@ -756,18 +707,10 @@ do_output_blockdevs (void)
write_row (dev, "device",
NULL, NULL, -1, size, parents, NULL);
free (dev);
free (devices[i]);
free_strings (parents);
}
free (devices);
}
/* Returns an empty list of parents. Note this must be freed using
* free_strings.
*/
/* Returns an empty list of parents. Note this must be freed. */
static char **
no_parents (void)
{
@@ -806,11 +749,11 @@ is_md (char *device)
static char **
parents_of_md (char *device)
{
struct guestfs_mdstat_list *stats;
char **ret;
size_t i;
stats = guestfs_md_stat (g, device);
CLEANUP_FREE_MDSTAT_LIST struct guestfs_mdstat_list *stats =
guestfs_md_stat (g, device);
if (!stats)
exit (EXIT_FAILURE);
@@ -828,8 +771,6 @@ parents_of_md (char *device)
ret[stats->len] = NULL;
guestfs_free_mdstat_list (stats);
return ret;
}
@@ -861,15 +802,14 @@ static char **
parents_of_vg (char *vg)
{
struct guestfs_lvm_pv_list *pvs = get_pvs ();
char **pvuuids;
char **ret;
size_t n, i, j;
pvuuids = guestfs_vgpvuuids (g, vg);
CLEANUP_FREE_STRING_LIST char **pvuuids = guestfs_vgpvuuids (g, vg);
if (!pvuuids)
exit (EXIT_FAILURE);
n = count_strings (pvuuids);
n = guestfs___count_strings (pvuuids);
ret = malloc ((n + 1) * sizeof (char *));
if (!ret) {
@@ -901,8 +841,6 @@ parents_of_vg (char *vg)
ret[i] = NULL;
free_strings (pvuuids);
return ret;
}
@@ -941,7 +879,7 @@ write_row (const char *name, const char *type,
int64_t size, char **parents, const char *uuid)
{
const char *strings[NR_COLUMNS];
char *parents_str = NULL;
CLEANUP_FREE char *parents_str = NULL;
size_t len = 0;
char hum[LONGEST_HUMAN_READABLE];
char num[256];
@@ -989,8 +927,6 @@ write_row (const char *name, const char *type,
assert (len <= NR_COLUMNS);
write_row_strings ((char **) strings, len);
free (parents_str);
}
static void add_row (char **strings, size_t len);
@@ -1159,23 +1095,3 @@ do_output_end (void)
}
free (rows);
}
static void
free_strings (char **strings)
{
size_t i;
for (i = 0; strings[i] != NULL; ++i)
free (strings[i]);
free (strings);
}
static size_t
count_strings (char **strings)
{
size_t i;
for (i = 0; strings[i] != NULL; ++i)
;
return i;
}

View File

@@ -107,6 +107,12 @@ them with separate I<-a> options.
The format of the disk image is auto-detected. To override this and
force a particular format use the I<--format=..> option.
=item B<-a URI>
=item B<--add URI>
Add a remote disk. See L<guestfish(1)/ADDING REMOTE STORAGE>.
=item B<--all>
Display everything. This is currently the same as specifying these

View File

@@ -25,13 +25,13 @@
#include <unistd.h>
#include <getopt.h>
#include <fcntl.h>
#include <errno.h>
#include <locale.h>
#include <assert.h>
#include <time.h>
#include <libintl.h>
#include "human.h"
#include "progname.h"
#include "guestfs.h"
#include "options.h"
@@ -82,14 +82,6 @@ static int is_fifo (int64_t mode);
static int is_lnk (int64_t mode);
static int is_sock (int64_t mode);
static void free_strings (char **);
static inline char *
bad_cast (char const *s)
{
return (char *) s;
}
static void __attribute__((noreturn))
usage (int status)
{
@@ -138,9 +130,6 @@ main (int argc, char *argv[])
/* Current time for --time-days, --time-relative output. */
time (&now);
/* Set global program name that is not polluted with libtool artifacts. */
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEBASEDIR);
textdomain (PACKAGE);
@@ -163,6 +152,7 @@ main (int argc, char *argv[])
{ "human-readable", 0, 0, 'h' },
{ "keys-from-stdin", 0, 0, 0 },
{ "long", 0, 0, 'l' },
{ "long-options", 0, 0, 0 },
{ "recursive", 0, 0, 'R' },
{ "time", 0, 0, 0 },
{ "times", 0, 0, 0 },
@@ -191,15 +181,15 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
argv[0] = bad_cast (program_name);
for (;;) {
c = getopt_long (argc, argv, options, long_options, &option_index);
if (c == -1) break;
switch (c) {
case 0: /* options which are long only */
if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
if (STREQ (long_options[option_index].name, "long-options"))
display_long_options (long_options);
else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
keys_from_stdin = 1;
} else if (STREQ (long_options[option_index].name, "echo-keys")) {
echo_keys = 1;
@@ -408,18 +398,14 @@ main (int argc, char *argv[])
static int
do_ls (const char *dir)
{
char **lines;
size_t i;
CLEANUP_FREE_STRING_LIST char **lines = guestfs_ls (g, dir);
if ((lines = guestfs_ls (g, dir)) == NULL) {
if (lines == NULL)
return -1;
}
for (i = 0; lines[i] != NULL; ++i) {
for (i = 0; lines[i] != NULL; ++i)
printf ("%s\n", lines[i]);
free (lines[i]);
}
free (lines);
return 0;
}
@@ -427,13 +413,12 @@ do_ls (const char *dir)
static int
do_ls_l (const char *dir)
{
char *out;
CLEANUP_FREE char *out = guestfs_ll (g, dir);
if ((out = guestfs_ll (g, dir)) == NULL)
if (out == NULL)
return -1;
printf ("%s", out);
free (out);
return 0;
}
@@ -441,18 +426,14 @@ do_ls_l (const char *dir)
static int
do_ls_R (const char *dir)
{
char **dirs;
size_t i;
CLEANUP_FREE_STRING_LIST char **dirs = guestfs_find (g, dir);
dirs = guestfs_find (g, dir);
if (dirs == NULL)
return -1;
for (i = 0; dirs[i] != NULL; ++i) {
for (i = 0; dirs[i] != NULL; ++i)
puts (dirs[i]);
free (dirs[i]);
}
free (dirs);
return 0;
}
@@ -473,8 +454,8 @@ visit (int depth, const char *dir, visitor_function f)
* case.
*/
if (depth == 0) {
struct guestfs_stat *stat;
struct guestfs_xattr_list *xattrs;
CLEANUP_FREE_STAT struct guestfs_stat *stat = NULL;
CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
int r;
stat = guestfs_lstat (g, dir);
@@ -482,40 +463,35 @@ visit (int depth, const char *dir, visitor_function f)
return -1;
xattrs = guestfs_lgetxattrs (g, dir);
if (xattrs == NULL) {
guestfs_free_stat (stat);
if (xattrs == NULL)
return -1;
}
r = f (dir, NULL, stat, xattrs);
guestfs_free_stat (stat);
guestfs_free_xattr_list (xattrs);
if (r == -1)
return -1;
}
int ret = -1;
char **names = NULL;
char *path = NULL;
size_t i, xattrp;
struct guestfs_stat_list *stats = NULL;
struct guestfs_xattr_list *xattrs = NULL;
CLEANUP_FREE_STRING_LIST char **names = NULL;
CLEANUP_FREE_STAT_LIST struct guestfs_stat_list *stats = NULL;
CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
names = guestfs_ls (g, dir);
if (names == NULL)
goto out;
return -1;
stats = guestfs_lstatlist (g, dir, names);
if (stats == NULL)
goto out;
return -1;
xattrs = guestfs_lxattrlist (g, dir, names);
if (xattrs == NULL)
goto out;
return -1;
/* Call function on everything in this directory. */
for (i = 0, xattrp = 0; names[i] != NULL; ++i, ++xattrp) {
CLEANUP_FREE char *path = NULL;
struct guestfs_xattr_list file_xattrs;
size_t nr_xattrs;
@@ -528,7 +504,7 @@ visit (int depth, const char *dir, visitor_function f)
if (xattrs->val[xattrp].attrval_len == 0) {
fprintf (stderr, _("%s: error getting extended attrs for %s %s\n"),
program_name, dir, names[i]);
goto out;
return -1;
}
/* attrval is not \0-terminated. */
char attrval[xattrs->val[xattrp].attrval_len+1];
@@ -538,7 +514,7 @@ visit (int depth, const char *dir, visitor_function f)
if (sscanf (attrval, "%zu", &nr_xattrs) != 1) {
fprintf (stderr, _("%s: error: cannot parse xattr count for %s %s\n"),
program_name, dir, names[i]);
goto out;
return -1;
}
file_xattrs.len = nr_xattrs;
@@ -547,28 +523,17 @@ visit (int depth, const char *dir, visitor_function f)
/* Call the function. */
if (f (dir, names[i], &stats->val[i], &file_xattrs) == -1)
goto out;
return -1;
/* Recursively call visit, but only on directories. */
if (is_dir (stats->val[i].mode)) {
path = full_path (dir, names[i]);
if (visit (depth + 1, path, f) == -1)
goto out;
free (path); path = NULL;
return -1;
}
}
ret = 0;
out:
free (path);
if (names)
free_strings (names);
if (stats)
guestfs_free_stat_list (stats);
if (xattrs)
guestfs_free_xattr_list (xattrs);
return ret;
return 0;
}
static char *
@@ -610,29 +575,28 @@ show_file (const char *dir, const char *name,
const struct guestfs_stat *stat,
const struct guestfs_xattr_list *xattrs)
{
char filetype[2];
char *path, *csum = NULL, *link = NULL;
const char *filetype;
CLEANUP_FREE char *path = NULL, *csum = NULL, *link = NULL;
/* Display the basic fields. */
output_start_line ();
if (is_reg (stat->mode))
filetype[0] = '-';
filetype = "-";
else if (is_dir (stat->mode))
filetype[0] = 'd';
filetype = "d";
else if (is_chr (stat->mode))
filetype[0] = 'c';
filetype = "c";
else if (is_blk (stat->mode))
filetype[0] = 'b';
filetype = "b";
else if (is_fifo (stat->mode))
filetype[0] = 'p';
filetype = "p";
else if (is_lnk (stat->mode))
filetype[0] = 'l';
filetype = "l";
else if (is_sock (stat->mode))
filetype[0] = 's';
filetype = "s";
else
filetype[0] = 'u';
filetype[1] = '\0';
filetype = "u";
output_string (filetype);
output_int64_perms (stat->mode & 07777);
@@ -683,10 +647,6 @@ show_file (const char *dir, const char *name,
output_end_line ();
free (path);
free (csum);
free (link);
return 0;
}
@@ -966,14 +926,3 @@ is_sock (int64_t mode)
{
return (mode & 0170000) == 0140000;
}
/* String functions. */
static void
free_strings (char **names)
{
size_t i;
for (i = 0; names[i] != NULL; ++i)
free (names[i]);
free (names);
}

View File

@@ -277,6 +277,12 @@ them with separate I<-a> options.
The format of the disk image is auto-detected. To override this and
force a particular format use the I<--format=..> option.
=item B<-a URI>
=item B<--add URI>
Add a remote disk. See L<guestfish(1)/ADDING REMOTE STORAGE>.
=item B<--checksum>
=item B<--checksum=crc|md5|sha1|sha224|sha256|sha384|sha512>
@@ -499,9 +505,6 @@ L<guestfish(1)>,
L<virt-cat(1)>,
L<virt-copy-out(1)>,
L<virt-tar-out(1)>,
L<Sys::Guestfs(3)>,
L<Sys::Guestfs::Lib(3)>,
L<Sys::Virt(3)>,
L<http://libguestfs.org/>.
=head1 AUTHOR
@@ -510,4 +513,4 @@ Richard W.M. Jones L<http://people.redhat.com/~rjones/>
=head1 COPYRIGHT
Copyright (C) 2009-2012 Red Hat Inc.
Copyright (C) 2009-2013 Red Hat Inc.

File diff suppressed because it is too large Load Diff

View File

@@ -22,6 +22,11 @@ make-check-on-installed.pl
we release them. Note that a checked out copy of the source
from git is required. Read the top of the file before using.
windows-icons.pl
This script lets you extract all the icons from a Windows
guest. We use this to locate the Windows logo in new releases
of Windows (see src/inspect-icon.c).
visualize-alignment/
Tests for visualizing block device reads and writes and
alignment using a patched qemu. See the README file in that

View File

@@ -1,6 +1,6 @@
#!/bin/bash -
# libguestfs autobuild script
# Copyright (C) 2009-2012 Red Hat Inc.
# Copyright (C) 2009-2013 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

View File

@@ -1,6 +1,6 @@
#!/usr/bin/perl -w
# libguestfs
# Copyright (C) 2009-2012 Red Hat Inc.
# Copyright (C) 2009-2013 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

View File

@@ -1,7 +1,7 @@
#!/usr/bin/ocamlrun /usr/bin/ocaml
(* Convert *.qtr (qemu block device trace) to Postscript.
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 Red Hat Inc.
* By Richard W.M. Jones <rjones@redhat.com>.
*
* This program is free software; you can redistribute it and/or modify

120
contrib/windows-icons.pl Executable file
View File

@@ -0,0 +1,120 @@
#!/usr/bin/perl -w
# libguestfs
# 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.
# This script lets you extract all the icons from a Windows guest. We
# use this to locate the Windows logo in new releases of Windows (see
# src/inspect-icon.c).
#
# Use it like this:
# ./run ./contrib/windows-icons.pl /path/to/windows-disk.img
use strict;
use Sys::Guestfs;
use File::Temp qw{tempdir};
# Check that the tools we need are installed.
system ("wrestool --help >/dev/null 2>&1") == 0 or
die "'wrestool' program is not installed\n";
#system ("icotool --help >/dev/null 2>&1") == 0 or
# die "'icotool' program is not installed\n";
# Check user provided disk image argument(s).
if (@ARGV == 0) {
print STDERR "usage: $0 /path/to/windows-disk.img\n";
exit 1
}
# Assume libguestfs >= 1.19.32, because that means we don't
# have to worry about protocol limits in various calls.
my $g = Sys::Guestfs->new;
my %version = $g->version ();
unless ($version{minor} >= 20 ||
$version{minor} >= 19 && $version{release} >= 32) {
die "$0: version of libguestfs is too old, use >= 1.19.32\n"
}
# Open the disk image(s).
$g->add_drive ($_, readonly => 1) foreach @ARGV;
$g->launch ();
# Check it's Windows.
my @roots = $g->inspect_os ();
if (@roots == 0) {
die "$0: no operating system found in disk image\n"
}
my $root = $roots[0];
if ($g->inspect_get_type ($root) ne "windows") {
die "$0: disk image is not Windows (type = ", $g->inspect_get_type ($root),
")\n"
}
# Mount it up.
my %mps = $g->inspect_get_mountpoints ($root);
my @mps = sort { length $a <=> length $b } (keys %mps);
for my $mp (@mps) {
eval { $g->mount_ro ($mps{$mp}, $mp) };
if ($@) {
print "$@ (ignored)\n"
}
}
# Create an output directory.
my $output = tempdir (CLEANUP => 0);
print "writing icons to $output\n";
chdir $output or die "chdir: $output: $!";
# Get a list of all files.
my @files = $g->find ("/");
@files = map { "/$_" } @files;
print "writing list of files to $output/files\n";
open FILES, ">files" or die "open: files: $!";
print FILES join("\n", @files) or die "write: files: $!";
close FILES or die "close: files: $!";
# Find all *.exe files. (XXX Can other file types contain resources?)
my @exe_files = grep { $_ =~ /\.exe$/i && $g->is_file ($_) } @files;
foreach (@exe_files) {
# Download each *.exe file.
my $basename = $_;
$basename =~ s{.*/}{};
$g->download ($_, $basename);
# Extract any icon (2) or group-icon (14) resources it may contain.
system ("wrestool", "-x", "--type=2", "-o", "./", $basename);
system ("wrestool", "-x", "--type=14", "-o", "./", $basename);
unlink $basename;
}
# Find and download all other image files.
foreach (@files) {
my $basename = $_;
$basename =~ s{.*/}{};
if ($g->is_file ($_) &&
$basename =~ /\.(png|git|jpeg|jpg|bmp|ico)$/i) {
$g->download ($_, $basename);
}
}
$g->close;

View File

@@ -48,8 +48,10 @@ do_list_9p (void)
dir = opendir (BUS_PATH);
if (!dir) {
perror ("opendir: " BUS_PATH);
if (errno != ENOENT)
if (errno != ENOENT) {
reply_with_perror ("opendir: " BUS_PATH);
return NULL;
}
/* If this directory doesn't exist, it probably means that
* the virtio driver isn't loaded. Don't return an error
@@ -75,17 +77,14 @@ do_list_9p (void)
* the mount tag length to be unlimited (or up to 65536 bytes).
* See: linux/include/linux/virtio_9p.h
*/
char *mount_tag = read_whole_file (mount_tag_path);
CLEANUP_FREE char *mount_tag = read_whole_file (mount_tag_path);
if (mount_tag == 0)
continue;
if (add_string (&r, mount_tag) == -1) {
free (mount_tag);
closedir (dir);
return NULL;
}
free (mount_tag);
}
}
@@ -148,7 +147,7 @@ read_whole_file (const char *filename)
*/
ssize_t n = read (fd, r + size, alloc - size - 1);
if (n == -1) {
perror (filename);
fprintf (stderr, "read: %s: %m\n", filename);
free (r);
close (fd);
return NULL;
@@ -159,7 +158,7 @@ read_whole_file (const char *filename)
}
if (close (fd) == -1) {
perror (filename);
fprintf (stderr, "close: %s: %m\n", filename);
free (r);
return NULL;
}
@@ -173,26 +172,26 @@ read_whole_file (const char *filename)
int
do_mount_9p (const char *mount_tag, const char *mountpoint, const char *options)
{
char *mp = NULL, *opts = NULL, *err = NULL;
CLEANUP_FREE char *mp = NULL, *opts = NULL, *err = NULL;
struct stat statbuf;
int r = -1;
int r;
ABS_PATH (mountpoint, , return -1);
mp = sysroot_path (mountpoint);
if (!mp) {
reply_with_perror ("malloc");
goto out;
return -1;
}
/* Check the mountpoint exists and is a directory. */
if (stat (mp, &statbuf) == -1) {
reply_with_perror ("%s", mountpoint);
goto out;
return -1;
}
if (!S_ISDIR (statbuf.st_mode)) {
reply_with_perror ("%s: mount point is not a directory", mountpoint);
goto out;
return -1;
}
/* Add trans=virtio to the options. */
@@ -200,14 +199,14 @@ do_mount_9p (const char *mount_tag, const char *mountpoint, const char *options)
STRNEQ (options, "")) {
if (asprintf (&opts, "trans=virtio,%s", options) == -1) {
reply_with_perror ("asprintf");
goto out;
return -1;
}
}
else {
opts = strdup ("trans=virtio");
if (opts == NULL) {
reply_with_perror ("strdup");
goto out;
return -1;
}
}
@@ -215,13 +214,8 @@ do_mount_9p (const char *mount_tag, const char *mountpoint, const char *options)
str_mount, "-o", opts, "-t", "9p", mount_tag, mp, NULL);
if (r == -1) {
reply_with_error ("%s on %s: %s", mount_tag, mountpoint, err);
goto out;
return -1;
}
r = 0;
out:
free (err);
free (opts);
free (mp);
return r;
return 0;
}

View File

@@ -19,26 +19,31 @@ include $(top_srcdir)/subdir-rules.mk
CLEANFILES = stamp-guestfsd.pod
libsrcdir = $(top_builddir)/src
generator_built = \
actions.h \
stubs.c \
names.c
BUILT_SOURCES = \
$(generator_built) \
shared_with_library = \
guestfs_protocol.c \
guestfs_protocol.h \
errnostring-gperf.c \
errnostring-gperf.gperf \
errnostring.c \
errnostring.h
BUILT_SOURCES = \
$(generator_built) \
$(shared_with_library) \
errnostring-gperf.c
EXTRA_DIST = \
$(BUILT_SOURCES) \
guestfsd.pod
$(shared_with_library): %: $(top_srcdir)/src/%
rm -f $@
ln $< $@
noinst_LIBRARIES = libprotocol.a
# This convenience library is solely to compile its generated sources with
@@ -46,16 +51,10 @@ noinst_LIBRARIES = libprotocol.a
libprotocol_a_SOURCES = guestfs_protocol.c guestfs_protocol.h
libprotocol_a_CFLAGS = -Wall -Wno-unused -fno-strict-aliasing
guestfs_protocol.c: $(libsrcdir)/guestfs_protocol.c
rm -f $@
ln $< $@
guestfs_protocol.h: $(libsrcdir)/guestfs_protocol.h
rm -f $@
ln $< $@
$(libsrcdir)/guestfs_protocol.c: force
$(MAKE) -C $(libsrcdir) guestfs_protocol.c
$(libsrcdir)/guestfs_protocol.h: force
$(MAKE) -C $(libsrcdir) guestfs_protocol.h
$(top_builddir)/src/guestfs_protocol.c: force
$(MAKE) -C $(top_builddir)/src guestfs_protocol.c
$(top_builddir)/src/guestfs_protocol.h: force
$(MAKE) -C $(top_builddir)/src guestfs_protocol.h
# Build the errnostring perfect hash code. The generated code has lots
# of warnings so we must compile it in a separate mini-library.
@@ -70,15 +69,6 @@ errnostring-gperf.c: errnostring-gperf.gperf
rm -f $@
$(GPERF) -t $< > $@-t
mv $@-t $@
errnostring-gperf.gperf: $(libsrcdir)/errnostring-gperf.gperf
rm -f $@
ln $< $@
errnostring.c: $(libsrcdir)/errnostring.c
rm -f $@
ln $< $@
errnostring.h: $(libsrcdir)/errnostring.h
rm -f $@
ln $< $@
if INSTALL_DAEMON
sbin_PROGRAMS = guestfsd
@@ -136,6 +126,7 @@ guestfsd_SOURCES = \
is.c \
isoinfo.c \
labels.c \
ldm.c \
link.c \
ls.c \
luks.c \
@@ -147,6 +138,7 @@ guestfsd_SOURCES = \
mktemp.c \
modprobe.c \
mount.c \
mountable.c \
names.c \
ntfs.c \
ntfsclone.c \
@@ -157,6 +149,7 @@ guestfsd_SOURCES = \
proto.c \
readdir.c \
realpath.c \
rename.c \
rsync.c \
scrub.c \
selinux.c \
@@ -168,6 +161,7 @@ guestfsd_SOURCES = \
stubs.c \
swap.c \
sync.c \
syslinux.c \
tar.c \
truncate.c \
umask.c \
@@ -185,6 +179,7 @@ guestfsd_LDADD = \
libprotocol.a \
$(ACL_LIBS) \
$(CAP_LIBS) \
$(YAJL_LIBS) \
$(SELINUX_LIB) \
$(AUGEAS_LIBS) \
$(HIVEX_LIBS) \
@@ -195,13 +190,20 @@ guestfsd_LDADD = \
$(LIBSOCKET) \
$(LIB_CLOCK_GETTIME) \
$(LIBINTL) \
$(SERVENT_LIB)
$(SERVENT_LIB) \
$(PCRE_LIBS)
guestfsd_CPPFLAGS = -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib
guestfsd_CPPFLAGS = \
-I$(top_srcdir)/gnulib/lib \
-I$(top_builddir)/gnulib/lib \
-I$(top_srcdir)/src \
-I$(top_builddir)/src
guestfsd_CFLAGS = \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
$(AUGEAS_CFLAGS) \
$(HIVEX_CFLAGS)
$(HIVEX_CFLAGS) \
$(YAJL_CFLAGS) \
$(PCRE_CFLAGS)
# Manual pages and HTML files for the website.
man_MANS = guestfsd.8

View File

@@ -144,32 +144,6 @@ do_acl_delete_def_file (const char *dir)
#else /* no acl library */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because
* optgroup_acl_available returns false.
*/
int
optgroup_acl_available (void)
{
return 0;
}
char *
do_acl_get_file (const char *path, const char *acltype)
{
abort ();
}
int
do_acl_set_file (const char *path, const char *acltype, const char *acl)
{
abort ();
}
int
do_acl_delete_def_file (const char *dir)
{
abort ();
}
OPTGROUP_ACL_NOT_AVAILABLE
#endif /* no acl library */

View File

@@ -68,7 +68,7 @@ optgroup_augeas_available (void)
int
do_aug_init (const char *root, int flags)
{
char *buf;
CLEANUP_FREE char *buf = NULL;
if (aug) {
aug_close (aug);
@@ -82,7 +82,6 @@ do_aug_init (const char *root, int flags)
}
aug = aug_init (buf, NULL, flags);
free (buf);
if (!aug) {
reply_with_error ("Augeas initialization failed");
@@ -338,7 +337,6 @@ char **
do_aug_ls (const char *path)
{
char **matches;
char *buf;
size_t len;
NEED_AUG (NULL);
@@ -358,6 +356,8 @@ do_aug_ls (const char *path)
if (STREQ (path, "/"))
matches = do_aug_match ("/*");
else {
CLEANUP_FREE char *buf;
len += 3; /* / * + terminating \0 */
buf = malloc (len);
if (buf == NULL) {
@@ -367,7 +367,6 @@ do_aug_ls (const char *path)
snprintf (buf, len, "%s/*", path);
matches = do_aug_match (buf);
free (buf);
}
if (matches == NULL)
@@ -379,98 +378,6 @@ do_aug_ls (const char *path)
#else /* !HAVE_AUGEAS */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because optgroup_augeas_available
* returns false.
*/
int
optgroup_augeas_available (void)
{
return 0;
}
int __attribute__((noreturn))
do_aug_init (const char *root, int flags)
{
abort ();
}
int __attribute__((noreturn))
do_aug_close (void)
{
abort ();
}
int __attribute__((noreturn))
do_aug_defvar (const char *name, const char *expr)
{
abort ();
}
guestfs_int_int_bool * __attribute__((noreturn))
do_aug_defnode (const char *name, const char *expr, const char *val)
{
abort ();
}
char * __attribute__((noreturn))
do_aug_get (const char *path)
{
abort ();
}
int __attribute__((noreturn))
do_aug_set (const char *path, const char *val)
{
abort ();
}
int __attribute__((noreturn))
do_aug_clear (const char *path)
{
abort ();
}
int __attribute__((noreturn))
do_aug_insert (const char *path, const char *label, int before)
{
abort ();
}
int __attribute__((noreturn))
do_aug_rm (const char *path)
{
abort ();
}
int __attribute__((noreturn))
do_aug_mv (const char *src, const char *dest)
{
abort ();
}
char ** __attribute__((noreturn))
do_aug_match (const char *path)
{
abort ();
}
int __attribute__((noreturn))
do_aug_save (void)
{
abort ();
}
int __attribute__((noreturn))
do_aug_load (void)
{
abort ();
}
char ** __attribute__((noreturn))
do_aug_ls (const char *path)
{
abort ();
}
OPTGROUP_AUGEAS_NOT_AVAILABLE
#endif

View File

@@ -23,6 +23,7 @@
#include <string.h>
#include "c-ctype.h"
#include "ignore-value.h"
#include "guestfs_protocol.h"
#include "daemon.h"
@@ -32,8 +33,8 @@
GUESTFSD_EXT_CMD(str_grep, grep);
GUESTFSD_EXT_CMD(str_modprobe, modprobe);
int
do_available (char *const *groups)
static int
available (char *const *groups, int error_on_unavailable)
{
int av;
size_t i, j;
@@ -43,8 +44,12 @@ do_available (char *const *groups)
if (STREQ (groups[i], optgroups[j].group)) {
av = optgroups[j].available ();
if (!av) {
reply_with_error ("%s: group not available", optgroups[j].group);
return -1;
if (error_on_unavailable) {
reply_with_error ("%s: group not available", optgroups[j].group);
return -1;
}
else
return 0;
}
break; /* out of for (j) loop */
}
@@ -57,6 +62,23 @@ do_available (char *const *groups)
}
}
/* All specified groups available. */
return 1;
}
int
do_feature_available (char *const *groups)
{
return available (groups, 0);
}
int
do_available (char *const *groups)
{
if (available (groups, 1) == -1)
return -1;
/* No error, so all groups available, just returns no error. */
return 0;
}
@@ -83,7 +105,7 @@ test_proc_filesystems (const char *filesystem)
{
size_t len = strlen (filesystem) + 32;
char regex[len];
char *err;
CLEANUP_FREE char *err = NULL;
int r;
snprintf (regex, len, "^[[:space:]]*%s$", filesystem);
@@ -91,10 +113,8 @@ test_proc_filesystems (const char *filesystem)
r = commandr (NULL, &err, str_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;
}
@@ -103,7 +123,7 @@ test_proc_filesystems (const char *filesystem)
static void
modprobe (const char *module)
{
command (NULL, NULL, str_modprobe, module, NULL);
ignore_value (command (NULL, NULL, str_modprobe, module, NULL));
}
/* Internal function for testing if a filesystem is available. Note

View File

@@ -22,6 +22,9 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "guestfs_protocol.h"
#include "daemon.h"
@@ -42,7 +45,7 @@ do_base64_in (const char *file)
{
int err, r;
FILE *fp;
char *cmd;
CLEANUP_FREE char *cmd = NULL;
if (asprintf_nowarn (&cmd, "%s -d -i > %R", str_base64, file) == -1) {
err = errno;
@@ -61,10 +64,8 @@ do_base64_in (const char *file)
cancel_receive ();
errno = err;
reply_with_perror ("%s", cmd);
free (cmd);
return -1;
}
free (cmd);
/* The semantics of fwrite are too undefined, so write to the
* file descriptor directly instead.
@@ -99,12 +100,32 @@ do_base64_in (const char *file)
int
do_base64_out (const char *file)
{
CLEANUP_FREE char *buf = NULL;
struct stat statbuf;
int r;
FILE *fp;
char *cmd;
char buf[GUESTFS_MAX_CHUNK_SIZE];
CLEANUP_FREE char *cmd = NULL;
char buffer[GUESTFS_MAX_CHUNK_SIZE];
if (asprintf_nowarn (&cmd, "%s %R", str_base64, file) == -1) {
/* Check the filename exists and is not a directory (RHBZ#908322). */
buf = sysroot_path (file);
if (buf == NULL) {
reply_with_perror ("malloc");
return -1;
}
if (stat (buf, &statbuf) == -1) {
reply_with_perror ("stat: %s", file);
return -1;
}
if (S_ISDIR (statbuf.st_mode)) {
reply_with_error ("%s: is a directory", file);
return -1;
}
/* Construct the command. */
if (asprintf_nowarn (&cmd, "%s %Q", str_base64, buf) == -1) {
reply_with_perror ("asprintf");
return -1;
}
@@ -115,10 +136,8 @@ do_base64_out (const char *file)
fp = popen (cmd, "r");
if (fp == NULL) {
reply_with_perror ("%s", cmd);
free (cmd);
return -1;
}
free (cmd);
/* Now we must send the reply message, before the file contents. After
* this there is no opportunity in the protocol to send any error
@@ -126,22 +145,22 @@ do_base64_out (const char *file)
*/
reply (NULL, NULL);
while ((r = fread (buf, 1, sizeof buf, fp)) > 0) {
if (send_file_write (buf, r) < 0) {
while ((r = fread (buffer, 1, sizeof buffer, fp)) > 0) {
if (send_file_write (buffer, r) < 0) {
pclose (fp);
return -1;
}
}
if (ferror (fp)) {
perror (file);
fprintf (stderr, "fread: %s: %m\n", file);
send_file_end (1); /* Cancel. */
pclose (fp);
return -1;
}
if (pclose (fp) != 0) {
perror (file);
fprintf (stderr, "pclose: %s: %m\n", file);
send_file_end (1); /* Cancel. */
return -1;
}

View File

@@ -32,7 +32,8 @@ GUESTFSD_EXT_CMD(str_blkid, blkid);
static char *
get_blkid_tag (const char *device, const char *tag)
{
char *out, *err;
char *out;
CLEANUP_FREE char *err = NULL;
int r;
r = commandr (&out, &err,
@@ -46,12 +47,9 @@ get_blkid_tag (const char *device, const char *tag)
else
reply_with_error ("%s: %s", device, err);
free (out);
free (err);
return NULL;
}
free (err);
if (r == 2) { /* means UUID etc not found */
free (out);
out = strdup ("");
@@ -69,21 +67,21 @@ get_blkid_tag (const char *device, const char *tag)
}
char *
do_vfs_type (const char *device)
do_vfs_type (const mountable_t *mountable)
{
return get_blkid_tag (device, "TYPE");
return get_blkid_tag (mountable->device, "TYPE");
}
char *
do_vfs_label (const char *device)
do_vfs_label (const mountable_t *mountable)
{
return get_blkid_tag (device, "LABEL");
return get_blkid_tag (mountable->device, "LABEL");
}
char *
do_vfs_uuid (const char *device)
do_vfs_uuid (const mountable_t *mountable)
{
return get_blkid_tag (device, "UUID");
return get_blkid_tag (mountable->device, "UUID");
}
/* RHEL5 blkid doesn't have the -p (low-level probing) option and the
@@ -96,32 +94,27 @@ static int
test_blkid_p_i_opt (void)
{
int r;
char *err;
CLEANUP_FREE char *err = NULL, *err2 = NULL;
r = commandr (NULL, &err, str_blkid, "-p", "/dev/null", NULL);
if (r == -1) {
/* This means we couldn't run the blkid command at all. */
command_failed:
reply_with_error ("could not run 'blkid' command: %s", err);
free (err);
return -1;
}
if (strstr (err, "invalid option --")) {
free (err);
return 0;
}
free (err);
r = commandr (NULL, &err, str_blkid, "-i", NULL);
r = commandr (NULL, &err2, str_blkid, "-i", NULL);
if (r == -1)
goto command_failed;
if (strstr (err, "invalid option --")) {
free (err);
if (strstr (err2, "invalid option --")) {
return 0;
}
free (err);
/* We have both options. */
return 1;
@@ -132,8 +125,8 @@ blkid_with_p_i_opt (const char *device)
{
size_t i;
int r;
char *out = NULL, *err = NULL;
char **lines = NULL;
CLEANUP_FREE char *out = NULL, *err = NULL;
CLEANUP_FREE_STRING_LIST char **lines = NULL;
DECLARE_STRINGSBUF (ret);
r = command (&out, &err, str_blkid, "-c", "/dev/null",
@@ -184,17 +177,9 @@ blkid_with_p_i_opt (const char *device)
if (end_stringsbuf (&ret) == -1) goto error;
free (out);
free (err);
free_strings (lines);
return ret.argv;
error:
free (out);
free (err);
if (lines)
free_strings (lines);
if (ret.argv)
free_strings (ret.argv);

View File

@@ -38,7 +38,7 @@ call_blockdev (const char *device, const char *switc, int extraarg, int prints)
{
int r;
int64_t rv;
char *out, *err;
CLEANUP_FREE char *out = NULL, *err = NULL;
const char *argv[] = {
str_blockdev,
switc,
@@ -73,8 +73,6 @@ call_blockdev (const char *device, const char *switc, int extraarg, int prints)
if (r == -1) {
reply_with_error ("%s: %s", argv[0], err);
free (err);
free (out);
return -1;
}
@@ -83,15 +81,10 @@ call_blockdev (const char *device, const char *switc, int extraarg, int prints)
if (prints) {
if (sscanf (out, "%" SCNi64, &rv) != 1) {
reply_with_error ("%s: expected output, but got nothing", argv[0]);
free (out);
free (err);
return -1;
}
}
free (out);
free (err);
return rv;
}

View File

@@ -21,17 +21,20 @@
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <pcre.h>
#include <string.h>
#include <unistd.h>
#include "daemon.h"
#include "actions.h"
#include "optgroups.h"
#include "xstrtol.h"
GUESTFSD_EXT_CMD(str_btrfs, btrfs);
GUESTFSD_EXT_CMD(str_btrfstune, btrfstune);
GUESTFSD_EXT_CMD(str_btrfsck, btrfsck);
GUESTFSD_EXT_CMD(str_mkfs_btrfs, mkfs.btrfs);
GUESTFSD_EXT_CMD(str_umount, umount);
int
optgroup_btrfs_available (void)
@@ -44,8 +47,7 @@ int
do_btrfs_filesystem_resize (const char *filesystem, int64_t size)
{
const size_t MAX_ARGS = 64;
char *buf;
char *err;
CLEANUP_FREE char *buf = NULL, *err = NULL;
int r;
const char *argv[MAX_ARGS];
size_t i = 0;
@@ -77,15 +79,12 @@ do_btrfs_filesystem_resize (const char *filesystem, int64_t size)
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (buf);
if (r == -1) {
reply_with_error ("%s: %s", filesystem, err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -107,7 +106,7 @@ do_mkfs_btrfs (char *const *devices,
const char *argv[MAX_ARGS];
size_t i = 0, j;
int r;
char *err;
CLEANUP_FREE char *err = NULL;
char allocstart_s[64];
char bytecount_s[64];
char leafsize_s[64];
@@ -197,14 +196,15 @@ do_mkfs_btrfs (char *const *devices,
ADD_ARG (argv, i, NULL);
for (j = 0; j < nr_devices; ++j)
wipe_device_before_mkfs (devices[j]);
r = commandv (NULL, &err, argv);
if (r == -1) {
reply_with_error ("%s: %s", devices[0], err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -214,8 +214,8 @@ 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;
CLEANUP_FREE char *source_buf = NULL, *dest_buf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
source_buf = sysroot_path (source);
@@ -226,7 +226,6 @@ do_btrfs_subvolume_snapshot (const char *source, const char *dest)
dest_buf = sysroot_path (dest);
if (dest_buf == NULL) {
reply_with_perror ("malloc");
free (source_buf);
return -1;
}
@@ -238,14 +237,10 @@ do_btrfs_subvolume_snapshot (const char *source, const char *dest)
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;
}
@@ -256,8 +251,8 @@ 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;
CLEANUP_FREE char *subvolume_buf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
subvolume_buf = sysroot_path (subvolume);
@@ -273,13 +268,10 @@ do_btrfs_subvolume_delete (const char *subvolume)
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;
}
@@ -290,8 +282,8 @@ 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;
CLEANUP_FREE char *dest_buf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
dest_buf = sysroot_path (dest);
@@ -307,111 +299,196 @@ do_btrfs_subvolume_create (const char *dest)
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)
do_btrfs_subvolume_list (const mountable_t *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;
char **lines;
fs_buf = sysroot_path (fs);
if (fs_buf == NULL) {
reply_with_perror ("malloc");
return NULL;
/* Execute 'btrfs subvolume list <fs>', and split the output into lines */
{
CLEANUP_FREE char *fs_buf = NULL;
if (fs->type == MOUNTABLE_PATH) {
fs_buf = sysroot_path (fs->device);
if (fs_buf == NULL) {
reply_with_perror ("malloc");
cmderror:
if (fs->type != MOUNTABLE_PATH && fs_buf) {
CLEANUP_FREE char *err = NULL;
if (command (NULL, &err, str_umount, fs_buf, NULL) == -1)
fprintf (stderr, "%s\n", err);
if (rmdir (fs_buf) == -1 && errno != ENOENT)
fprintf (stderr, "rmdir: %m\n");
}
return NULL;
}
}
else {
fs_buf = strdup ("/tmp/btrfs.XXXXXX");
if (fs_buf == NULL) {
reply_with_perror ("strdup");
goto cmderror;
}
if (mkdtemp (fs_buf) == NULL) {
reply_with_perror ("mkdtemp");
goto cmderror;
}
if (mount_vfs_nochroot ("", NULL, fs, fs_buf, "<internal>") == -1) {
goto cmderror;
}
}
size_t i = 0;
const size_t MAX_ARGS = 64;
const char *argv[MAX_ARGS];
ADD_ARG (argv, i, str_btrfs);
ADD_ARG (argv, i, "subvolume");
ADD_ARG (argv, i, "list");
ADD_ARG (argv, i, fs_buf);
ADD_ARG (argv, i, NULL);
CLEANUP_FREE char *out = NULL, *errout = NULL;
int r = commandv (&out, &errout, argv);
if (fs->type != MOUNTABLE_PATH) {
CLEANUP_FREE char *err = NULL;
if (command (NULL, &err, str_umount, fs_buf, NULL) == -1) {
reply_with_error ("%s", err ? err : "malloc");
goto cmderror;
}
if (rmdir (fs_buf) == -1 && errno != ENOENT) {
reply_with_error ("rmdir: %m\n");
goto cmderror;
}
}
if (r == -1) {
CLEANUP_FREE char *fs_desc = mountable_to_string (fs);
if (fs_desc == NULL) {
fprintf (stderr, "malloc: %m");
}
reply_with_error ("%s: %s", fs_desc ? fs_desc : "malloc", errout);
goto cmderror;
}
lines = split_lines (out);
if (!lines) return NULL;
}
ADD_ARG (argv, i, str_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 256 gen 30 top level 5 path test1
* ID 257 gen 30 top level 5 path dir/test2
* ID 258 gen 30 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.
* "ID <n>" is the subvolume ID.
* "gen <n>" is the generation when the root was created or last
* updated.
* "top level <n>" is the top level subvolume ID.
* "path <str>" is the subvolume path, relative to the top of the
* filesystem.
*
* Note that the order that each of the above is fixed, but
* different versions of btrfs may display different sets of data.
* Specifically, older versions of btrfs do not display gen.
*/
nr_subvolumes = count_strings (lines);
guestfs_int_btrfssubvolume_list *ret = NULL;
pcre *re = NULL;
size_t nr_subvolumes = count_strings (lines);
ret = malloc (sizeof *ret);
if (!ret) {
reply_with_perror ("malloc");
free_stringslen (lines, nr_subvolumes);
return NULL;
goto error;
}
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;
goto error;
}
for (i = 0; i < nr_subvolumes; ++i) {
const char *errptr;
int erroffset;
re = pcre_compile ("ID\\s+(\\d+).*\\s"
"top level\\s+(\\d+).*\\s"
"path\\s(.*)",
0, &errptr, &erroffset, NULL);
if (re == NULL) {
reply_with_error ("pcre_compile (%i): %s", erroffset, errptr);
goto error;
}
for (size_t 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];
#define N_MATCHES 4
int ovector[N_MATCHES * 3];
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) {
if (pcre_exec (re, NULL, line, strlen (line), 0, 0,
ovector, N_MATCHES * 3) < 0)
#undef N_MATCHES
{
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;
goto error;
}
pos = strstr (line, " path ");
if (pos == NULL)
goto unexpected_output;
pos += 6;
struct guestfs_int_btrfssubvolume *this =
&ret->guestfs_int_btrfssubvolume_list_val[i];
memmove (line, pos, strlen (pos) + 1);
ret->guestfs_int_btrfssubvolume_list_val[i].btrfssubvolume_path = line;
#if __WORDSIZE == 64
#define XSTRTOU64 xstrtoul
#else
#define XSTRTOU64 xstrtoull
#endif
if (XSTRTOU64 (line + ovector[2], NULL, 10,
&this->btrfssubvolume_id, NULL) != LONGINT_OK)
goto unexpected_output;
if (XSTRTOU64 (line + ovector[4], NULL, 10,
&this->btrfssubvolume_top_level_id, NULL) != LONGINT_OK)
goto unexpected_output;
#undef XSTRTOU64
memmove (line, line + ovector[6], ovector[7] + 1);
this->btrfssubvolume_path = line;
}
free (lines);
pcre_free (re);
return ret;
error:
free_stringslen (lines, nr_subvolumes);
if (ret) free (ret->guestfs_int_btrfssubvolume_list_val);
free (ret);
if (re) pcre_free (re);
return NULL;
}
int
@@ -420,9 +497,9 @@ 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;
CLEANUP_FREE char *fs_buf = NULL;
char buf[64];
char *err;
CLEANUP_FREE char *err = NULL;
int r;
snprintf (buf, sizeof buf, "%" PRIi64, id);
@@ -441,13 +518,10 @@ do_btrfs_subvolume_set_default (int64_t id, const char *fs)
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;
}
@@ -458,8 +532,8 @@ 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;
CLEANUP_FREE char *fs_buf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
fs_buf = sysroot_path (fs);
@@ -475,13 +549,10 @@ do_btrfs_filesystem_sync (const char *fs)
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;
}
@@ -492,8 +563,8 @@ 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;
CLEANUP_FREE char *fs_buf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
fs_buf = sysroot_path (fs);
@@ -509,13 +580,10 @@ do_btrfs_filesystem_balance (const char *fs)
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;
}
@@ -531,8 +599,8 @@ do_btrfs_device_add (char *const *devices, const char *fs)
size_t MAX_ARGS = nr_devices + 8;
const char *argv[MAX_ARGS];
size_t i = 0, j;
char *fs_buf;
char *err;
CLEANUP_FREE char *fs_buf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
fs_buf = sysroot_path (fs);
@@ -552,13 +620,10 @@ do_btrfs_device_add (char *const *devices, const char *fs)
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;
}
@@ -574,8 +639,8 @@ do_btrfs_device_delete (char *const *devices, const char *fs)
size_t MAX_ARGS = nr_devices + 8;
const char *argv[MAX_ARGS];
size_t i = 0, j;
char *fs_buf;
char *err;
CLEANUP_FREE char *fs_buf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
fs_buf = sysroot_path (fs);
@@ -595,13 +660,10 @@ do_btrfs_device_delete (char *const *devices, const char *fs)
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;
}
@@ -609,7 +671,7 @@ do_btrfs_device_delete (char *const *devices, const char *fs)
int
do_btrfs_set_seeding (const char *device, int svalue)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
const char *s_value = svalue ? "1" : "0";
@@ -617,11 +679,9 @@ do_btrfs_set_seeding (const char *device, int svalue)
r = commandr (NULL, &err, str_btrfstune, "-S", s_value, device, NULL);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -629,7 +689,7 @@ do_btrfs_set_seeding (const char *device, int svalue)
int
do_btrfs_fsck (const char *device, int64_t superblock, int repair)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
size_t i = 0;
const size_t MAX_ARGS = 64;
@@ -661,10 +721,8 @@ do_btrfs_fsck (const char *device, int64_t superblock, int repair)
r = commandv (NULL, &err, argv);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
free (err);
return -1;
}
free (err);
return 0;
}

View File

@@ -106,26 +106,6 @@ do_cap_set_file (const char *path, const char *capstr)
#else /* no libcap */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because
* optgroup_linuxcaps_available returns false.
*/
int
optgroup_linuxcaps_available (void)
{
return 0;
}
char *
do_cap_get_file (const char *path)
{
abort ();
}
int
do_cap_set_file (const char *path, const char *cap)
{
abort ();
}
OPTGROUP_LINUXCAPS_NOT_AVAILABLE
#endif /* no libcap */

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -66,7 +66,8 @@ static char *
checksum (const char *csumtype, int fd)
{
const char *program;
char *out, *err;
char *out;
CLEANUP_FREE char *err = NULL;
int flags, r;
size_t len;
@@ -84,12 +85,9 @@ checksum (const char *csumtype, int fd)
pulse_mode_cancel ();
reply_with_error ("%s: %s", program, err);
free (out);
free (err);
return NULL;
}
free (err);
/* Split it at the first whitespace. */
len = strcspn (out, " \t\n");
out[len] = '\0';
@@ -141,7 +139,7 @@ do_checksums_out (const char *csumtype, const char *dir)
if (program == NULL)
return -1;
char *sysrootdir = sysroot_path (dir);
CLEANUP_FREE char *sysrootdir = sysroot_path (dir);
if (!sysrootdir) {
reply_with_perror ("malloc");
return -1;
@@ -150,24 +148,19 @@ do_checksums_out (const char *csumtype, const char *dir)
r = stat (sysrootdir, &statbuf);
if (r == -1) {
reply_with_perror ("%s", dir);
free (sysrootdir);
return -1;
}
if (!S_ISDIR (statbuf.st_mode)) {
reply_with_error ("%s: not a directory", dir);
free (sysrootdir);
return -1;
}
char *cmd;
CLEANUP_FREE char *cmd = NULL;
if (asprintf_nowarn (&cmd, "cd %Q && %s -type f -print0 | %s -0 %s",
str_find, str_xargs,
sysrootdir, program) == -1) {
sysrootdir, str_find, str_xargs, program) == -1) {
reply_with_perror ("asprintf");
free (sysrootdir);
return -1;
}
free (sysrootdir);
if (verbose)
fprintf (stderr, "%s\n", cmd);
@@ -175,10 +168,8 @@ do_checksums_out (const char *csumtype, const char *dir)
FILE *fp = popen (cmd, "r");
if (fp == NULL) {
reply_with_perror ("%s", cmd);
free (cmd);
return -1;
}
free (cmd);
/* Now we must send the reply message, before the file contents. After
* this there is no opportunity in the protocol to send any error
@@ -196,14 +187,14 @@ do_checksums_out (const char *csumtype, const char *dir)
}
if (ferror (fp)) {
perror (dir);
fprintf (stderr, "fread: %s: %m\n", dir);
send_file_end (1); /* Cancel. */
pclose (fp);
return -1;
}
if (pclose (fp) != 0) {
perror (dir);
fprintf (stderr, "pclose: %s: %m\n", dir);
send_file_end (1); /* Cancel. */
return -1;
}

View File

@@ -32,8 +32,8 @@ GUESTFSD_EXT_CMD(str_cmp, cmp);
int
do_equal (const char *file1, const char *file2)
{
char *file1buf, *file2buf;
char *err;
CLEANUP_FREE char *file1buf = NULL, *file2buf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
file1buf = sysroot_path (file1);
@@ -45,22 +45,14 @@ do_equal (const char *file1, const char *file2)
file2buf = sysroot_path (file2);
if (file2buf == NULL) {
reply_with_perror ("malloc");
free (file1buf);
return -1;
}
r = commandr (NULL, &err, str_cmp, "-s", file1buf, file2buf, NULL);
free (file1buf);
free (file2buf);
if (r == -1 || r > 1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return r == 0;
}

View File

@@ -40,10 +40,11 @@ umount_ignore_fail (const char *path)
char *
do_command (char *const *argv)
{
char *out, *err;
char *out;
CLEANUP_FREE char *err;
int r;
char *sysroot_dev, *sysroot_dev_pts, *sysroot_proc,
*sysroot_selinux, *sysroot_sys;
CLEANUP_FREE char *sysroot_dev = NULL, *sysroot_dev_pts = NULL,
*sysroot_proc = NULL, *sysroot_selinux = NULL, *sysroot_sys = NULL;
int dev_ok, dev_pts_ok, proc_ok, selinux_ok, sys_ok;
/* We need a root filesystem mounted to do this. */
@@ -76,11 +77,6 @@ do_command (char *const *argv)
sysroot_proc == NULL || sysroot_selinux == NULL ||
sysroot_sys == NULL) {
reply_with_perror ("malloc");
free (sysroot_dev);
free (sysroot_dev_pts);
free (sysroot_proc);
free (sysroot_selinux);
free (sysroot_sys);
return NULL;
}
@@ -105,28 +101,19 @@ do_command (char *const *argv)
if (dev_pts_ok) umount_ignore_fail (sysroot_dev_pts);
if (dev_ok) umount_ignore_fail (sysroot_dev);
free (sysroot_dev);
free (sysroot_dev_pts);
free (sysroot_proc);
free (sysroot_selinux);
free (sysroot_sys);
if (r == -1) {
reply_with_error ("%s", err);
free (out);
free (err);
return NULL;
}
free (err);
return out; /* Caller frees. */
}
char **
do_command_lines (char *const *argv)
{
char *out;
CLEANUP_FREE char *out = NULL;
char **lines;
out = do_command (argv);
@@ -134,7 +121,6 @@ do_command_lines (char *const *argv)
return NULL;
lines = split_lines (out);
free (out);
if (lines == NULL)
return NULL;

View File

@@ -39,7 +39,7 @@ do_compressX_out (const char *file, const char *filter, int is_device)
{
int r;
FILE *fp;
char *cmd;
CLEANUP_FREE char *cmd = NULL;
char buf[GUESTFS_MAX_CHUNK_SIZE];
/* The command will look something like:
@@ -71,10 +71,8 @@ do_compressX_out (const char *file, const char *filter, int is_device)
fp = popen (cmd, "r");
if (fp == NULL) {
reply_with_perror ("%s", cmd);
free (cmd);
return -1;
}
free (cmd);
/* Now we must send the reply message, before the file contents. After
* this there is no opportunity in the protocol to send any error
@@ -90,14 +88,14 @@ do_compressX_out (const char *file, const char *filter, int is_device)
}
if (ferror (fp)) {
perror (file);
fprintf (stderr, "fread: %s: %m\n", file);
send_file_end (1); /* Cancel. */
pclose (fp);
return -1;
}
if (pclose (fp) != 0) {
perror (file);
fprintf (stderr, "pclose: %s: %m\n", file);
send_file_end (1); /* Cancel. */
return -1;
}
@@ -109,11 +107,9 @@ do_compressX_out (const char *file, const char *filter, int is_device)
}
#define CHECK_SUPPORTED(prog) \
if (!prog_exists (prog)) { \
if (!prog_exists (prog)) \
/* note: substring "not supported" must appear in this error */ \
reply_with_error ("compression type %s is not supported", prog); \
return -1; \
}
NOT_SUPPORTED (-1, "compression type %s is not supported, because external program '%s' is not available in the appliance", prog, prog);
static int
get_filter (const char *ctype, int level, char *ret, size_t n)

View File

@@ -42,13 +42,14 @@ static int
copy (const char *src, const char *src_display,
const char *dest, const char *dest_display,
int wrflags, int wrmode,
int64_t srcoffset, int64_t destoffset, int64_t size)
int64_t srcoffset, int64_t destoffset, int64_t size, int sparse)
{
int64_t saved_size = size;
int src_fd, dest_fd;
char buf[BUFSIZ];
size_t n;
ssize_t r;
int err;
if ((optargs_bitmask & GUESTFS_COPY_DEVICE_TO_DEVICE_SRCOFFSET_BITMASK)) {
if (srcoffset < 0) {
@@ -77,6 +78,9 @@ copy (const char *src, const char *src_display,
else
size = -1;
if (! (optargs_bitmask & GUESTFS_COPY_DEVICE_TO_DEVICE_SPARSE_BITMASK))
sparse = 0;
/* Open source and destination. */
src_fd = open (src, O_RDONLY|O_CLOEXEC);
if (src_fd == -1) {
@@ -116,8 +120,10 @@ copy (const char *src, const char *src_display,
r = read (src_fd, buf, n);
if (r == -1) {
err = errno;
if (size == -1)
pulse_mode_cancel ();
errno = err;
reply_with_perror ("read: %s", src_display);
close (src_fd);
close (dest_fd);
@@ -133,14 +139,31 @@ copy (const char *src, const char *src_display,
return -1;
}
if (sparse && is_zero (buf, r)) {
if (lseek (dest_fd, r, SEEK_CUR) == -1) {
err = errno;
if (size == -1)
pulse_mode_cancel ();
errno = err;
reply_with_perror ("%s: seek (because of sparse flag)", dest_display);
close (src_fd);
close (dest_fd);
return -1;
}
goto sparse_skip;
}
if (xwrite (dest_fd, buf, r) == -1) {
err = errno;
if (size == -1)
pulse_mode_cancel ();
errno = err;
reply_with_perror ("%s: write", dest_display);
close (src_fd);
close (dest_fd);
return -1;
}
sparse_skip:
if (size != -1) {
size -= r;
@@ -167,58 +190,51 @@ copy (const char *src, const char *src_display,
int
do_copy_device_to_device (const char *src, const char *dest,
int64_t srcoffset, int64_t destoffset, int64_t size)
int64_t srcoffset, int64_t destoffset, int64_t size,
int sparse)
{
return copy (src, src, dest, dest, DEST_DEVICE_FLAGS,
srcoffset, destoffset, size);
srcoffset, destoffset, size, sparse);
}
int
do_copy_device_to_file (const char *src, const char *dest,
int64_t srcoffset, int64_t destoffset, int64_t size)
int64_t srcoffset, int64_t destoffset, int64_t size,
int sparse)
{
char *dest_buf;
int r;
CLEANUP_FREE char *dest_buf = sysroot_path (dest);
dest_buf = sysroot_path (dest);
if (!dest_buf) {
reply_with_perror ("malloc");
return -1;
}
r = copy (src, src, dest_buf, dest, DEST_FILE_FLAGS,
srcoffset, destoffset, size);
free (dest_buf);
return r;
return copy (src, src, dest_buf, dest, DEST_FILE_FLAGS,
srcoffset, destoffset, size, sparse);
}
int
do_copy_file_to_device (const char *src, const char *dest,
int64_t srcoffset, int64_t destoffset, int64_t size)
int64_t srcoffset, int64_t destoffset, int64_t size,
int sparse)
{
char *src_buf;
int r;
CLEANUP_FREE char *src_buf = sysroot_path (src);
src_buf = sysroot_path (src);
if (!src_buf) {
reply_with_perror ("malloc");
return -1;
}
r = copy (src_buf, src, dest, dest, DEST_DEVICE_FLAGS,
srcoffset, destoffset, size);
free (src_buf);
return r;
return copy (src_buf, src, dest, dest, DEST_DEVICE_FLAGS,
srcoffset, destoffset, size, sparse);
}
int
do_copy_file_to_file (const char *src, const char *dest,
int64_t srcoffset, int64_t destoffset, int64_t size)
int64_t srcoffset, int64_t destoffset, int64_t size,
int sparse)
{
char *src_buf, *dest_buf;
int r;
CLEANUP_FREE char *src_buf = NULL, *dest_buf = NULL;
src_buf = sysroot_path (src);
if (!src_buf) {
@@ -229,14 +245,9 @@ do_copy_file_to_file (const char *src, const char *dest,
dest_buf = sysroot_path (dest);
if (!dest_buf) {
reply_with_perror ("malloc");
free (src_buf);
return -1;
}
r = copy (src_buf, src, dest_buf, dest, DEST_FILE_FLAGS,
srcoffset, destoffset, size);
free (src_buf);
free (dest_buf);
return r;
return copy (src_buf, src, dest_buf, dest, DEST_FILE_FLAGS,
srcoffset, destoffset, size, sparse);
}

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -51,8 +51,8 @@ do_mv (const char *src, const char *dest)
static int
cpmv_cmd (const char *cmd, const char *flags, const char *src, const char *dest)
{
char *srcbuf, *destbuf;
char *err;
CLEANUP_FREE char *srcbuf = NULL, *destbuf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
srcbuf = sysroot_path (src);
@@ -64,7 +64,6 @@ cpmv_cmd (const char *cmd, const char *flags, const char *src, const char *dest)
destbuf = sysroot_path (dest);
if (destbuf == NULL) {
reply_with_perror ("malloc");
free (srcbuf);
return -1;
}
@@ -75,16 +74,11 @@ cpmv_cmd (const char *cmd, const char *flags, const char *src, const char *dest)
else
r = command (NULL, &err, cmd, srcbuf, destbuf, NULL);
free (srcbuf);
free (destbuf);
if (r == -1) {
pulse_mode_cancel ();
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
pulse_mode_end ();

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -30,6 +30,16 @@
#include "guestfs_protocol.h"
#include "guestfs-internal-all.h"
/* Mountables */
typedef struct {
mountable_type_t type;
const char *device;
const char *volume;
} mountable_t;
/*-- in guestfsd.c --*/
extern int verbose;
@@ -47,6 +57,14 @@ extern int xwrite (int sock, const void *buf, size_t len)
extern int xread (int sock, void *buf, size_t len)
__attribute__((__warn_unused_result__));
extern char *mountable_to_string (const mountable_t *mountable);
/*-- in mount.c --*/
extern int mount_vfs_nochroot (const char *options, const char *vfstype,
const mountable_t *mountable,
const char *mp, const char *user_mp);
/* Growable strings buffer. */
struct stringsbuf {
char **argv;
@@ -100,9 +118,9 @@ extern char **split_lines (char *str);
#define COMMAND_FLAG_CHROOT_COPY_FILE_TO_STDIN 2048
extern int commandf (char **stdoutput, char **stderror, int flags,
const char *name, ...);
const char *name, ...) __attribute__((sentinel));
extern int commandrf (char **stdoutput, char **stderror, int flags,
const char *name, ...);
const char *name, ...) __attribute__((sentinel));
extern int commandvf (char **stdoutput, char **stderror, int flags,
char const *const *argv);
extern int commandrvf (char **stdoutput, char **stderror, int flags,
@@ -114,6 +132,8 @@ extern void trim (char *str);
extern int device_name_translation (char *device);
extern int parse_btrfsvol (char *desc, mountable_t *mountable);
extern int prog_exists (const char *prog);
extern void udev_settle (void);
@@ -122,8 +142,13 @@ 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.
* info about these. In GCC 4.8.0 the warning is even harder to
* 'trick', hence the need for the #pragma directives.
*/
#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
#endif
static inline int
asprintf_nowarn (char **strp, const char *fmt, ...)
{
@@ -135,6 +160,14 @@ asprintf_nowarn (char **strp, const char *fmt, ...)
va_end (args);
return r;
}
#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */
#pragma GCC diagnostic pop
#endif
/* Use by the CLEANUP_* macros. */
extern void cleanup_free (void *ptr);
extern void cleanup_free_string_list (void *ptr);
extern void cleanup_unlink_free (void *ptr);
/*-- in names.c (auto-generated) --*/
extern const char *function_names[];
@@ -179,6 +212,9 @@ extern int lv_canonical (const char *device, char **ret);
/*-- in lvm-filter.c --*/
extern void copy_lvm (void);
/*-- in zero.c --*/
extern void wipe_device_before_mkfs (const char *device);
/*-- in proto.c --*/
extern void main_loop (int sock) __attribute__((noreturn));
@@ -237,6 +273,11 @@ extern void pulse_mode_start (void);
extern void pulse_mode_end (void);
extern void pulse_mode_cancel (void);
/* Send a progress message without rate-limiting. This is just
* for debugging - DON'T use it in regular code!
*/
extern void notify_progress_no_ratelimit (uint64_t position, uint64_t total, const struct timeval *now);
/* Return true iff the buffer is all zero bytes.
*
* Note that gcc is smart enough to optimize this properly:
@@ -320,6 +361,33 @@ is_zero (const char *buffer, size_t size)
} \
} while (0)
/* All functions that take a mountable argument must call this macro.
* It parses the mountable into a mountable_t, ensures any
* underlying device exists, and does device name translation
* (described in the guestfs(3) manpage).
*
* Note that the "string" argument may be modified.
*/
#define RESOLVE_MOUNTABLE(string,mountable,cancel_stmt,fail_stmt) \
do { \
if (STRPREFIX ((string), "btrfsvol:")) { \
if (parse_btrfsvol ((string) + strlen ("btrfsvol:"), &(mountable)) == -1)\
{ \
cancel_stmt; \
reply_with_error ("%s: %s: expecting a btrfs volume", \
__func__, (string)); \
fail_stmt; \
} \
} \
\
else { \
(mountable).type = MOUNTABLE_DEVICE; \
(mountable).device = (string); \
(mountable).volume = NULL; \
RESOLVE_DEVICE((string), cancel_stmt, fail_stmt); \
} \
} while (0)
/* Helper for functions which need either an absolute path in the
* mounted filesystem, OR a /dev/ device which exists.
*
@@ -340,6 +408,24 @@ is_zero (const char *buffer, size_t size)
} \
} while (0)
/* Helper for functions which need either an absolute path in the
* mounted filesystem, OR a valid mountable description.
*/
#define REQUIRE_ROOT_OR_RESOLVE_MOUNTABLE(string, mountable, \
cancel_stmt, fail_stmt) \
do { \
if (STREQLEN ((string), "/dev/", strlen ("/dev/")) || (string)[0] != '/') {\
RESOLVE_MOUNTABLE (string, mountable, cancel_stmt, fail_stmt); \
} \
\
else { \
NEED_ROOT (cancel_stmt, fail_stmt); \
(mountable).type = MOUNTABLE_PATH; \
(mountable).device = (string); \
} \
} while (0) \
/* NB:
* (1) You must match CHROOT_IN and CHROOT_OUT even along error paths.
* (2) You must not change directory! cwd must always be "/", otherwise
@@ -376,24 +462,23 @@ is_zero (const char *buffer, size_t size)
} \
while (0)
#ifndef __attribute__
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
# define __attribute__(x) /* empty */
# endif
#endif
/* Marks functions which are not supported. */
#define NOT_SUPPORTED(errcode,...) \
do { \
reply_with_error_errno (ENOTSUP, __VA_ARGS__); \
return (errcode); \
} \
while (0)
#ifndef ATTRIBUTE_UNUSED
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#ifdef HAVE_ATTRIBUTE_CLEANUP
#define CLEANUP_FREE __attribute__((cleanup(cleanup_free)))
#define CLEANUP_FREE_STRING_LIST \
__attribute__((cleanup(cleanup_free_string_list)))
#define CLEANUP_UNLINK_FREE __attribute__((cleanup(cleanup_unlink_free)))
#else
#define CLEANUP_FREE
#define CLEANUP_FREE_STRING_LIST
#define CLEANUP_UNLINK_FREE
#endif
#define STREQ(a,b) (strcmp((a),(b)) == 0)
#define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
#define STRNEQ(a,b) (strcmp((a),(b)) != 0)
#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0)
#define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0)
#define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0)
#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0)
#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0)
#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
#endif /* GUESTFSD_DAEMON_H */

View File

@@ -33,8 +33,8 @@ int
do_dd (const char *src, const char *dest)
{
int src_is_dev, dest_is_dev;
char *if_arg, *of_arg;
char *err;
CLEANUP_FREE char *if_arg = NULL, *of_arg = NULL;
CLEANUP_FREE char *err = NULL;
int r;
src_is_dev = STRPREFIX (src, "/dev/");
@@ -56,20 +56,14 @@ do_dd (const char *src, const char *dest)
r = asprintf (&of_arg, "of=%s%s", sysroot, dest);
if (r == -1) {
reply_with_perror ("asprintf");
free (if_arg);
return -1;
}
r = command (NULL, &err, str_dd, "bs=1024K", if_arg, of_arg, NULL);
free (if_arg);
free (of_arg);
if (r == -1) {
reply_with_error ("%s: %s: %s", src, dest, err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -77,19 +71,17 @@ do_dd (const char *src, const char *dest)
int
do_copy_size (const char *src, const char *dest, int64_t ssize)
{
char *buf;
int src_fd, dest_fd;
if (STRPREFIX (src, "/dev/"))
src_fd = open (src, O_RDONLY | O_CLOEXEC);
else {
buf = sysroot_path (src);
CLEANUP_FREE char *buf = sysroot_path (src);
if (!buf) {
reply_with_perror ("malloc");
return -1;
}
src_fd = open (buf, O_RDONLY | O_CLOEXEC);
free (buf);
}
if (src_fd == -1) {
reply_with_perror ("%s", src);
@@ -99,14 +91,13 @@ do_copy_size (const char *src, const char *dest, int64_t ssize)
if (STRPREFIX (dest, "/dev/"))
dest_fd = open (dest, O_WRONLY | O_CLOEXEC);
else {
buf = sysroot_path (dest);
CLEANUP_FREE char *buf = sysroot_path (dest);
if (!buf) {
reply_with_perror ("malloc");
close (src_fd);
return -1;
}
dest_fd = open (buf, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_CLOEXEC, 0666);
free (buf);
}
if (dest_fd == -1) {
reply_with_perror ("%s", dest);

View File

@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -72,6 +73,8 @@ static char *debug_qtrace (const char *subcmd, size_t argc, char *const *const a
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 char *debug_spew (const char *subcmd, size_t argc, char *const *const argv);
static void deliberately_cause_a_segfault (void);
static struct cmd cmds[] = {
{ "help", debug_help },
@@ -87,6 +90,7 @@ static struct cmd cmds[] = {
{ "segv", debug_segv },
{ "setenv", debug_setenv },
{ "sh", debug_sh },
{ "spew", debug_spew },
{ NULL, NULL }
};
@@ -209,13 +213,7 @@ debug_fds (const char *subcmd, size_t argc, char *const *const argv)
static char *
debug_segv (const char *subcmd, size_t argc, char *const *const argv)
{
/* http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
* "Dereferencing a NULL Pointer: contrary to popular belief,
* dereferencing a null pointer in C is undefined. It is not defined
* to trap [...]"
*/
volatile int *ptr = NULL;
*ptr = 1;
deliberately_cause_a_segfault ();
return NULL;
}
@@ -227,7 +225,7 @@ debug_segv (const char *subcmd, size_t argc, char *const *const argv)
static char *
debug_sh (const char *subcmd, size_t argc, char *const *const argv)
{
char *cmd;
CLEANUP_FREE char *cmd = NULL;
size_t len, i, j;
if (argc < 1) {
@@ -266,8 +264,6 @@ debug_sh (const char *subcmd, size_t argc, char *const *const argv)
char *err;
int r = commandf (NULL, &err, COMMAND_FLAG_FOLD_STDOUT_ON_STDERR,
"/bin/sh", "-c", cmd, NULL);
free (cmd);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
@@ -282,18 +278,16 @@ static char *
debug_env (const char *subcmd, size_t argc, char *const *const argv)
{
int r;
char *out, *err;
char *out;
CLEANUP_FREE char *err = NULL;
r = command (&out, &err, str_printenv, NULL);
if (r == -1) {
reply_with_error ("printenv: %s", err);
free (out);
free (err);
return NULL;
}
free (err);
return out;
}
@@ -326,7 +320,8 @@ static char *
debug_binaries (const char *subcmd, size_t argc, char *const *const argv)
{
int r;
char *out, *err;
char *out;
CLEANUP_FREE char *err;
char cmd[256];
snprintf (cmd, sizeof (cmd),
@@ -340,12 +335,9 @@ debug_binaries (const char *subcmd, size_t argc, char *const *const argv)
if (r == -1) {
reply_with_error ("find: %s", err);
free (out);
free (err);
return NULL;
}
free (err);
return out;
}
@@ -356,7 +348,8 @@ static char *
debug_ldd (const char *subcmd, size_t argc, char *const *const argv)
{
int r;
char *out, *err, *ret;
char *out, *ret;
CLEANUP_FREE char *err = NULL;
if (argc != 1) {
reply_with_error ("ldd: no file argument");
@@ -373,7 +366,6 @@ debug_ldd (const char *subcmd, size_t argc, char *const *const argv)
if (r == -1) {
reply_with_error ("ldd: %s: %s", argv[0], err);
free (out);
free (err);
return NULL;
}
@@ -382,12 +374,10 @@ debug_ldd (const char *subcmd, size_t argc, char *const *const argv)
if (ret == NULL) {
reply_with_perror ("realloc");
free (out);
free (err);
return NULL;
}
strcat (ret, err);
free (err);
return ret;
}
@@ -399,6 +389,9 @@ debug_ls (const char *subcmd, size_t argc, char *const *const argv)
size_t len = count_strings (argv);
const char *cargv[len+3];
size_t i;
int r;
char *out;
CLEANUP_FREE char *err;
cargv[0] = str_ls;
cargv[1] = "-a";
@@ -406,19 +399,13 @@ debug_ls (const char *subcmd, size_t argc, char *const *const argv)
cargv[2+i] = argv[i];
cargv[2+len] = NULL;
int r;
char *out, *err;
r = commandv (&out, &err, (void *) cargv);
if (r == -1) {
reply_with_error ("ls: %s", err);
free (out);
free (err);
return NULL;
}
free (err);
return out;
}
@@ -429,6 +416,9 @@ debug_ll (const char *subcmd, size_t argc, char *const *const argv)
size_t len = count_strings (argv);
const char *cargv[len+3];
size_t i;
int r;
char *out;
CLEANUP_FREE char *err;
cargv[0] = str_ls;
cargv[1] = "-la";
@@ -436,19 +426,13 @@ debug_ll (const char *subcmd, size_t argc, char *const *const argv)
cargv[2+i] = argv[i];
cargv[2+len] = NULL;
int r;
char *out, *err;
r = commandv (&out, &err, (void *) cargv);
if (r == -1) {
reply_with_error ("ll: %s", err);
free (out);
free (err);
return NULL;
}
free (err);
return out;
}
@@ -456,29 +440,56 @@ 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)
{
uint64_t secs, rate = 0;
char *ret;
if (argc < 1) {
error:
reply_with_error ("progress: expecting arg (time in seconds as string)");
reply_with_error ("progress: expecting one or more args: time in seconds [, rate in microseconds]");
return NULL;
}
char *secs_str = argv[0];
unsigned secs;
if (sscanf (secs_str, "%u", &secs) != 1)
if (sscanf (argv[0], "%" SCNu64, &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 */
for (i = 1; i <= tsecs; ++i) {
usleep (100000);
notify_progress ((uint64_t) i, (uint64_t) tsecs);
if (argc >= 2) {
if (sscanf (argv[1], "%" SCNu64, &rate) != 1)
goto error;
if (rate == 0 || rate > 1000000) {
reply_with_error ("progress: rate is 0 or too large");
return NULL;
}
}
char *ret = strdup ("ok");
/* Note the inner loops go to '<= limit' because we want to ensure
* that the final 100% completed message is set.
*/
if (rate == 0) { /* Ordinary rate-limited progress messages. */
uint64_t tsecs = secs * 10; /* 1/10ths of seconds */
uint64_t i;
for (i = 1; i <= tsecs; ++i) {
usleep (100000);
notify_progress (i, tsecs);
}
}
else { /* Send messages at a given rate. */
uint64_t usecs = secs * 1000000; /* microseconds */
uint64_t i;
struct timeval now;
for (i = rate; i <= usecs; i += rate) {
usleep (rate);
gettimeofday (&now, NULL);
notify_progress_no_ratelimit (i, usecs, &now);
}
}
ret = strdup ("ok");
if (ret == NULL) {
reply_with_perror ("strdup");
return NULL;
@@ -538,6 +549,42 @@ debug_core_pattern (const char *subcmd, size_t argc, char *const *const argv)
return ret;
}
/* Generate lots of debug messages. Each line of output is 72
* characters long (plus '\n'), so the total size of the output in
* bytes is n*73.
*/
static char *
debug_spew (const char *subcmd, size_t argc, char *const *const argv)
{
size_t i, n;
char *ret;
if (argc != 1) {
reply_with_error ("spew: expecting number of lines <n>");
return NULL;
}
if (sscanf (argv[0], "%zu", &n) != 1) {
reply_with_error ("spew: could not parse number of lines '%s'", argv[0]);
return NULL;
}
for (i = 0; i < n; ++i)
fprintf (stderr,
"abcdefghijklmnopqrstuvwxyz" /* 26 */
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* 52 */
"01234567890123456789" /* 72 */
"\n");
ret = strdup ("ok");
if (!ret) {
reply_with_perror ("strdup");
return NULL;
}
return ret;
}
static int
write_cb (void *fd_ptr, const void *buf, size_t len)
{
@@ -589,12 +636,13 @@ debug_qtrace (const char *subcmd, size_t argc, char *const *const argv)
{ 2, 15, 21, 2, -1 }, /* disable trace */
{ 2, 21, 15, 2, -1 } /* enable trace */
};
void *buf;
CLEANUP_FREE void *buf = NULL;
size_t i;
/* For O_DIRECT, buffer must be aligned too (thanks Matt).
* Note posix_memalign has this strange errno behaviour.
*/
/* coverity[resource_leak] */
errno = posix_memalign (&buf, QTRACE_SIZE, QTRACE_SIZE);
if (errno != 0) {
reply_with_perror ("posix_memalign");
@@ -606,20 +654,17 @@ debug_qtrace (const char *subcmd, size_t argc, char *const *const argv)
if (lseek (fd, patterns[enable][i]*QTRACE_SIZE, SEEK_SET) == -1) {
reply_with_perror ("qtrace: %s: lseek", argv[0]);
close (fd);
free (buf);
return NULL;
}
if (read (fd, buf, QTRACE_SIZE) == -1) {
reply_with_perror ("qtrace: %s: read", argv[0]);
close (fd);
free (buf);
return NULL;
}
}
close (fd);
free (buf);
/* This does a sync and flushes all caches. */
if (do_drop_caches (3) == -1)
@@ -676,3 +721,64 @@ do_debug_upload (const char *filename, int mode)
return 0;
}
/* Internal function used only when testing
* https://bugzilla.redhat.com/show_bug.cgi?id=914931
*/
static int
crash_cb (void *countv, const void *buf, size_t len)
{
int *countp = countv;
(*countp)--;
sleep (1);
if (*countp == 0)
deliberately_cause_a_segfault ();
return 0;
}
/* Has one FileIn parameter. */
int
do_internal_rhbz914931 (int count)
{
int r;
if (count <= 0 || count > 1000) {
reply_with_error ("count out of range");
return -1;
}
r = receive_file (crash_cb, &count);
if (r == -1) { /* write error */
int err = errno;
cancel_receive ();
errno = err;
reply_with_error ("write error");
return -1;
}
if (r == -2) { /* cancellation from library */
/* This error is ignored by the library since it initiated the
* cancel. Nevertheless we must send an error reply here.
*/
reply_with_error ("file upload cancelled");
return -1;
}
return 0;
}
static void
deliberately_cause_a_segfault (void)
{
/* http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
* "Dereferencing a NULL Pointer: contrary to popular belief,
* dereferencing a null pointer in C is undefined. It is not defined
* to trap [...]"
*/
volatile int *ptr = NULL;
/* coverity[var_deref_op] */
*ptr = 1;
}

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -244,42 +244,62 @@ do_part_to_partnum (const char *part)
return r;
}
int
do_is_whole_device (const char *device)
{
/* A 'whole' block device will have a symlink to the device in its
* /sys/block directory */
CLEANUP_FREE char *devpath = NULL;
if (asprintf (&devpath, "/sys/block/%s/device",
device + strlen ("/dev/")) == -1)
{
reply_with_perror ("asprintf");
return -1;
}
struct stat statbuf;
if (stat (devpath, &statbuf) == -1) {
if (errno == ENOENT || errno == ENOTDIR) return 0;
reply_with_perror ("stat");
return -1;
}
return 1;
}
int
do_device_index (const char *device)
{
char **devices;
size_t i;
int ret = -1;
CLEANUP_FREE_STRING_LIST char **devices = do_list_devices ();
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;
CLEANUP_FREE_STRING_LIST char **devices = do_list_devices ();
devices = do_list_devices ();
if (devices == NULL)
return -1;
for (i = 0; devices[i] != NULL; ++i)
free (devices[i]);
free (devices);
;
return (int) i;
}
@@ -291,7 +311,7 @@ do_list_disk_labels (void)
{
DIR *dir = NULL;
struct dirent *d;
char *path = NULL, *rawdev = NULL;
char *rawdev = NULL;
DECLARE_STRINGSBUF (ret);
dir = opendir (GUESTFSDIR);
@@ -302,6 +322,8 @@ do_list_disk_labels (void)
errno = 0;
while ((d = readdir (dir)) != NULL) {
CLEANUP_FREE char *path = NULL;
if (d->d_name[0] == '.')
continue;
@@ -318,9 +340,6 @@ do_list_disk_labels (void)
goto error;
}
free (path);
path = NULL;
if (add_string (&ret, d->d_name) == -1)
goto error;
@@ -354,7 +373,6 @@ do_list_disk_labels (void)
error:
if (dir)
closedir (dir);
free (path);
free (rawdev);
return NULL;
}

View File

@@ -33,7 +33,8 @@ char *
do_df (void)
{
int r;
char *out, *err;
char *out;
CLEANUP_FREE char *err = NULL;
NEED_ROOT (, return NULL);
@@ -41,12 +42,9 @@ do_df (void)
if (r == -1) {
reply_with_error ("%s", err);
free (out);
free (err);
return NULL;
}
free (err);
return out; /* Caller frees. */
}
@@ -54,7 +52,8 @@ char *
do_df_h (void)
{
int r;
char *out, *err;
char *out;
CLEANUP_FREE char *err = NULL;
NEED_ROOT (, return NULL);
@@ -62,11 +61,8 @@ do_df_h (void)
if (r == -1) {
reply_with_error ("%s", err);
free (out);
free (err);
return NULL;
}
free (err);
return out; /* Caller frees. */
}

View File

@@ -56,7 +56,7 @@ int
do_rm_rf (const char *path)
{
int r;
char *buf, *err;
CLEANUP_FREE char *buf = NULL, *err = NULL;
if (STREQ (path, "/")) {
reply_with_error ("cannot remove root directory");
@@ -70,17 +70,12 @@ do_rm_rf (const char *path)
}
r = command (NULL, &err, str_rm, "-rf", buf, NULL);
free (buf);
/* rm -rf is never supposed to fail. I/O errors perhaps? */
if (r == -1) {
reply_with_error ("%s: %s", path, err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -133,7 +128,7 @@ recursive_mkdir (const char *path)
{
int loop = 0;
int r;
char *ppath, *p;
char *p;
struct stat buf;
again:
@@ -153,14 +148,13 @@ recursive_mkdir (const char *path)
if (path[0] == '/' && path[1] == '\0') return -1;
/* Try to make the parent directory first. */
ppath = strdup (path);
CLEANUP_FREE char *ppath = strdup (path);
if (ppath == NULL) return -1;
p = strrchr (ppath, '/');
if (p) *p = '\0';
r = recursive_mkdir (ppath);
free (ppath);
if (r != 0) return r;

View File

@@ -32,17 +32,16 @@ GUESTFSD_EXT_CMD(str_dmesg, dmesg);
char *
do_dmesg (void)
{
char *out, *err;
char *out;
CLEANUP_FREE char *err = NULL;
int r;
r = command (&out, &err, str_dmesg, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (out);
free (err);
return NULL;
}
free (err);
return out; /* caller frees */
}

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -35,8 +35,7 @@ do_du (const char *path)
{
int r;
int64_t rv;
char *out, *err;
char *buf;
CLEANUP_FREE char *out = NULL, *err = NULL, *buf = NULL;
/* Make the path relative to /sysroot. */
buf = sysroot_path (path);
@@ -48,26 +47,18 @@ do_du (const char *path)
pulse_mode_start ();
r = command (&out, &err, str_du, "-s", buf, NULL);
free (buf);
if (r == -1) {
pulse_mode_cancel ();
reply_with_error ("%s: %s", path, err);
free (out);
free (err);
return -1;
}
free (err);
if (sscanf (out, "%"SCNi64, &rv) != 1) {
pulse_mode_cancel ();
reply_with_error ("%s: could not read output: %s", path, out);
free (out);
return -1;
}
free (out);
pulse_mode_end ();
return rv;

View File

@@ -50,7 +50,7 @@ do_echo_daemon (char *const *argv)
char *out_new = realloc (out, out_len + 1);
if (NULL == out_new) {
reply_with_perror ("realloc");
free(out);
free (out);
return 0;
}
out = out_new;

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -42,18 +42,15 @@ char **
do_tune2fs_l (const char *device)
{
int r;
char *out, *err;
CLEANUP_FREE char *out = NULL, *err = NULL;
char *p, *pend, *colon;
DECLARE_STRINGSBUF (ret);
r = command (&out, &err, str_tune2fs, "-l", device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
free (out);
return NULL;
}
free (err);
p = out;
@@ -63,7 +60,6 @@ do_tune2fs_l (const char *device)
if (p) p++;
else {
reply_with_error ("truncated output");
free (out);
return NULL;
}
}
@@ -85,30 +81,25 @@ do_tune2fs_l (const char *device)
do { colon++; } while (*colon && c_isspace (*colon));
if (add_string (&ret, p) == -1) {
free (out);
return NULL;
}
if (STREQ (colon, "<none>") ||
STREQ (colon, "<not available>") ||
STREQ (colon, "(none)")) {
if (add_string (&ret, "") == -1) {
free (out);
return NULL;
}
} else {
if (add_string (&ret, colon) == -1) {
free (out);
return NULL;
}
}
}
else {
if (add_string (&ret, p) == -1) {
free (out);
return NULL;
}
if (add_string (&ret, "") == -1) {
free (out);
return NULL;
}
}
@@ -116,8 +107,6 @@ do_tune2fs_l (const char *device)
p = pend;
}
free (out);
if (end_stringsbuf (&ret) == -1)
return NULL;
@@ -127,43 +116,50 @@ do_tune2fs_l (const char *device)
int
do_set_e2label (const char *device, const char *label)
{
return do_set_label (device, label);
mountable_t mountable;
mountable.type = MOUNTABLE_DEVICE;
mountable.device = device;
return do_set_label (&mountable, label);
}
char *
do_get_e2label (const char *device)
{
return do_vfs_label (device);
mountable_t mountable;
mountable.type = MOUNTABLE_DEVICE;
mountable.device = device;
return do_vfs_label (&mountable);
}
int
do_set_e2uuid (const char *device, const char *uuid)
{
int r;
char *err;
CLEANUP_FREE char *err = NULL;
r = command (NULL, &err, str_tune2fs, "-U", uuid, device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
char *
do_get_e2uuid (const char *device)
{
return do_vfs_uuid (device);
mountable_t mountable;
mountable.type = MOUNTABLE_DEVICE;
mountable.device = device;
return do_vfs_uuid (&mountable);
}
/* If the filesystem is not mounted, run e2fsck -f on it unconditionally. */
static int
if_not_mounted_run_e2fsck (const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r, mounted;
mounted = is_device_mounted (device);
@@ -171,13 +167,13 @@ if_not_mounted_run_e2fsck (const char *device)
return -1;
if (!mounted) {
r = command (NULL, &err, str_e2fsck, "-fy", device, NULL);
r = commandf (NULL, &err,
COMMAND_FLAG_FOLD_STDOUT_ON_STDERR,
str_e2fsck, "-fy", device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
}
return 0;
@@ -186,7 +182,7 @@ if_not_mounted_run_e2fsck (const char *device)
int
do_resize2fs (const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
if (if_not_mounted_run_e2fsck (device) == -1)
@@ -195,18 +191,16 @@ do_resize2fs (const char *device)
r = command (NULL, &err, str_resize2fs, device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_resize2fs_size (const char *device, int64_t size)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
/* resize2fs itself may impose additional limits. Since we are
@@ -229,18 +223,16 @@ do_resize2fs_size (const char *device, int64_t size)
r = command (NULL, &err, str_resize2fs, device, buf, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_resize2fs_M (const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
if (if_not_mounted_run_e2fsck (device) == -1)
@@ -249,11 +241,9 @@ do_resize2fs_M (const char *device)
r = command (NULL, &err, str_resize2fs, "-M", device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -264,7 +254,7 @@ do_e2fsck (const char *device,
int forceall)
{
const char *argv[MAX_ARGS];
char *err;
CLEANUP_FREE char *err = NULL;
size_t i = 0;
int r;
@@ -291,7 +281,9 @@ do_e2fsck (const char *device,
ADD_ARG (argv, i, device);
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
r = commandvf (NULL, &err,
COMMAND_FLAG_FOLD_STDOUT_ON_STDERR,
argv);
/* 0 = no errors, 1 = errors corrected.
*
* >= 4 means uncorrected or other errors.
@@ -301,11 +293,9 @@ do_e2fsck (const char *device,
*/
if (r == -1 || r >= 2) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -319,29 +309,29 @@ do_e2fsck_f (const char *device)
int
do_mke2journal (int blocksize, const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
char blocksize_s[32];
snprintf (blocksize_s, sizeof blocksize_s, "%d", blocksize);
wipe_device_before_mkfs (device);
r = command (NULL, &err,
str_mke2fs, "-F", "-O", "journal_dev", "-b", blocksize_s,
device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_mke2journal_L (int blocksize, const char *label, const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
if (strlen (label) > EXT2_LABEL_MAX) {
@@ -353,40 +343,40 @@ do_mke2journal_L (int blocksize, const char *label, const char *device)
char blocksize_s[32];
snprintf (blocksize_s, sizeof blocksize_s, "%d", blocksize);
wipe_device_before_mkfs (device);
r = command (NULL, &err,
str_mke2fs, "-F", "-O", "journal_dev", "-b", blocksize_s,
"-L", label,
device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_mke2journal_U (int blocksize, const char *uuid, const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
char blocksize_s[32];
snprintf (blocksize_s, sizeof blocksize_s, "%d", blocksize);
wipe_device_before_mkfs (device);
r = command (NULL, &err,
str_mke2fs, "-F", "-O", "journal_dev", "-b", blocksize_s,
"-U", uuid,
device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -394,7 +384,7 @@ int
do_mke2fs_J (const char *fstype, int blocksize, const char *device,
const char *journal)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
char blocksize_s[32];
@@ -404,16 +394,16 @@ do_mke2fs_J (const char *fstype, int blocksize, const char *device,
char jdev[len+32];
snprintf (jdev, len+32, "device=%s", journal);
wipe_device_before_mkfs (device);
r = command (NULL, &err,
str_mke2fs, "-F", "-t", fstype, "-J", jdev, "-b", blocksize_s,
device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -421,7 +411,7 @@ int
do_mke2fs_JL (const char *fstype, int blocksize, const char *device,
const char *label)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
if (strlen (label) > EXT2_LABEL_MAX) {
@@ -437,16 +427,16 @@ do_mke2fs_JL (const char *fstype, int blocksize, const char *device,
char jdev[len+32];
snprintf (jdev, len+32, "device=LABEL=%s", label);
wipe_device_before_mkfs (device);
r = command (NULL, &err,
str_mke2fs, "-F", "-t", fstype, "-J", jdev, "-b", blocksize_s,
device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -454,7 +444,7 @@ int
do_mke2fs_JU (const char *fstype, int blocksize, const char *device,
const char *uuid)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
char blocksize_s[32];
@@ -464,16 +454,16 @@ do_mke2fs_JU (const char *fstype, int blocksize, const char *device,
char jdev[len+32];
snprintf (jdev, len+32, "device=UUID=%s", uuid);
wipe_device_before_mkfs (device);
r = command (NULL, &err,
str_mke2fs, "-F", "-t", fstype, "-J", jdev, "-b", blocksize_s,
device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -494,7 +484,7 @@ do_tune2fs (const char *device, /* only required parameter */
const char *argv[MAX_ARGS];
size_t i = 0;
int r;
char *err;
CLEANUP_FREE char *err = NULL;
char maxmountcount_s[64];
char mountcount_s[64];
char group_s[64];
@@ -612,11 +602,9 @@ do_tune2fs (const char *device, /* only required parameter */
r = commandv (NULL, &err, argv);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -632,8 +620,9 @@ char *
do_get_e2attrs (const char *filename)
{
int r;
char *buf;
char *out, *err;
CLEANUP_FREE char *buf;
char *out;
CLEANUP_FREE char *err;
size_t i, j;
buf = sysroot_path (filename);
@@ -643,14 +632,11 @@ do_get_e2attrs (const char *filename)
}
r = command (&out, &err, str_lsattr, "-d", "--", buf, NULL);
free (buf);
if (r == -1) {
reply_with_error ("%s: %s: %s", "lsattr", filename, err);
free (err);
free (out);
return NULL;
}
free (err);
/* Output looks like:
* -------------e- filename
@@ -674,8 +660,8 @@ int
do_set_e2attrs (const char *filename, const char *attrs, int clear)
{
int r;
char *buf;
char *err;
CLEANUP_FREE char *buf = NULL;
CLEANUP_FREE char *err = NULL;
size_t i, j;
int lowers[26], uppers[26];
char attr_arg[26*2+1+1]; /* '+'/'-' + attrs + trailing '\0' */
@@ -737,13 +723,10 @@ do_set_e2attrs (const char *filename, const char *attrs, int clear)
}
r = command (NULL, &err, str_chattr, attr_arg, "--", buf, NULL);
free (buf);
if (r == -1) {
reply_with_error ("%s: %s: %s", "chattr", filename, err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -752,8 +735,7 @@ int64_t
do_get_e2generation (const char *filename)
{
int r;
char *buf;
char *out, *err;
CLEANUP_FREE char *buf = NULL, *out = NULL, *err = NULL;
int64_t ret;
buf = sysroot_path (filename);
@@ -763,22 +745,16 @@ do_get_e2generation (const char *filename)
}
r = command (&out, &err, str_lsattr, "-dv", "--", buf, NULL);
free (buf);
if (r == -1) {
reply_with_error ("%s: %s: %s", "lsattr", filename, err);
free (err);
free (out);
return -1;
}
free (err);
if (sscanf (out, "%" SCNu64, &ret) != 1) {
reply_with_error ("cannot parse output from '%s' command: %s",
"lsattr", out);
free (out);
return -1;
}
free (out);
return ret;
}
@@ -787,8 +763,7 @@ int
do_set_e2generation (const char *filename, int64_t generation)
{
int r;
char *buf;
char *err;
CLEANUP_FREE char *buf = NULL, *err = NULL;
char generation_str[64];
buf = sysroot_path (filename);
@@ -801,13 +776,10 @@ do_set_e2generation (const char *filename, int64_t generation)
"%" PRIu64, (uint64_t) generation);
r = command (NULL, &err, str_chattr, "-v", generation_str, "--", buf, NULL);
free (buf);
if (r == -1) {
reply_with_error ("%s: %s: %s", "chattr", filename, err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -854,7 +826,7 @@ do_mke2fs (const char *device, /* 0 */
int uninitbg)
{
int r;
char *err = NULL;
CLEANUP_FREE char *err = NULL;
const char *argv[MAX_ARGS];
char blockscount_s[64];
char blocksize_s[64];
@@ -864,7 +836,7 @@ do_mke2fs (const char *device, /* 0 */
char bytesperinode_s[64];
char inodesize_s[64];
char journalsize_s[64];
char *journaldevice_s = NULL;
CLEANUP_FREE char *journaldevice_s = NULL;
char reservedblockspercentage_s[64];
char numberofinodes_s[64];
char mmpupdateinterval_s[84];
@@ -878,7 +850,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_BLOCKSIZE_BITMASK) {
if (blocksize < 0) {
reply_with_error ("blocksize must be >= 0");
goto error;
return -1;
}
snprintf (blocksize_s, sizeof blocksize_s, "%" PRIi64, blocksize);
ADD_ARG (argv, i, "-b");
@@ -887,7 +859,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_FRAGSIZE_BITMASK) {
if (fragsize < 0) {
reply_with_error ("fragsize must be >= 0");
goto error;
return -1;
}
snprintf (fragsize_s, sizeof fragsize_s, "%" PRIi64, fragsize);
ADD_ARG (argv, i, "-f");
@@ -900,7 +872,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_BLOCKSPERGROUP_BITMASK) {
if (blockspergroup < 0) {
reply_with_error ("blockspergroup must be >= 0");
goto error;
return -1;
}
snprintf (blockspergroup_s, sizeof blockspergroup_s,
"%" PRIi64, blockspergroup);
@@ -910,7 +882,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_NUMBEROFGROUPS_BITMASK) {
if (numberofgroups < 0) {
reply_with_error ("numberofgroups must be >= 0");
goto error;
return -1;
}
snprintf (numberofgroups_s, sizeof numberofgroups_s,
"%" PRIi64, numberofgroups);
@@ -920,7 +892,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_BYTESPERINODE_BITMASK) {
if (bytesperinode < 0) {
reply_with_error ("bytesperinode must be >= 0");
goto error;
return -1;
}
snprintf (bytesperinode_s, sizeof bytesperinode_s, "%" PRIi64, bytesperinode);
ADD_ARG (argv, i, "-i");
@@ -929,7 +901,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_INODESIZE_BITMASK) {
if (inodesize < 0) {
reply_with_error ("inodesize must be >= 0");
goto error;
return -1;
}
snprintf (inodesize_s, sizeof inodesize_s, "%" PRIi64, inodesize);
ADD_ARG (argv, i, "-I");
@@ -938,7 +910,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_JOURNALSIZE_BITMASK) {
if (journalsize < 0) {
reply_with_error ("journalsize must be >= 0");
goto error;
return -1;
}
snprintf (journalsize_s, sizeof journalsize_s,
"size=" "%" PRIi64, journalsize);
@@ -954,12 +926,12 @@ do_mke2fs (const char *device, /* 0 */
journaldevice_s = malloc (strlen (journaldevice) + 8);
if (!journaldevice_s) {
reply_with_perror ("malloc");
goto error;
return -1;
}
sprintf (journaldevice_s, "device=%s", journaldevice);
if (STRPREFIX (&journaldevice_s[7], "/dev/"))
RESOLVE_DEVICE (&journaldevice_s[7], , goto error);
RESOLVE_DEVICE (&journaldevice_s[7], , return -1);
ADD_ARG (argv, i, "-J");
ADD_ARG (argv, i, journaldevice_s);
@@ -974,7 +946,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_RESERVEDBLOCKSPERCENTAGE_BITMASK) {
if (reservedblockspercentage < 0) {
reply_with_error ("reservedblockspercentage must be >= 0");
goto error;
return -1;
}
snprintf (reservedblockspercentage_s, sizeof reservedblockspercentage_s,
"%" PRIi32, reservedblockspercentage);
@@ -990,7 +962,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_NUMBEROFINODES_BITMASK) {
if (numberofinodes < 0) {
reply_with_error ("numberofinodes must be >= 0");
goto error;
return -1;
}
snprintf (numberofinodes_s, sizeof numberofinodes_s,
"%" PRIi64, numberofinodes);
@@ -1028,7 +1000,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_MMPUPDATEINTERVAL_BITMASK) {
if (mmpupdateinterval < 0) {
reply_with_error ("mmpupdateinterval must be >= 0");
goto error;
return -1;
}
snprintf (mmpupdateinterval_s, sizeof mmpupdateinterval_s,
"mmp_update_interval=" "%" PRIi32, mmpupdateinterval);
@@ -1038,7 +1010,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_STRIDESIZE_BITMASK) {
if (stridesize < 0) {
reply_with_error ("stridesize must be >= 0");
goto error;
return -1;
}
snprintf (stridesize_s, sizeof stridesize_s,
"stride=" "%" PRIi64, stridesize);
@@ -1048,7 +1020,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_STRIPEWIDTH_BITMASK) {
if (stripewidth< 0) {
reply_with_error ("stripewidth must be >= 0");
goto error;
return -1;
}
snprintf (stripewidth_s, sizeof stripewidth_s,
"stripe_width=" "%" PRIi64, stripewidth);
@@ -1058,7 +1030,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_MAXONLINERESIZE_BITMASK) {
if (maxonlineresize < 0) {
reply_with_error ("maxonlineresize must be >= 0");
goto error;
return -1;
}
snprintf (maxonlineresize_s, sizeof maxonlineresize_s,
"resize=" "%" PRIi64, maxonlineresize);
@@ -1169,7 +1141,7 @@ do_mke2fs (const char *device, /* 0 */
if (optargs_bitmask & GUESTFS_MKE2FS_BLOCKSCOUNT_BITMASK) {
if (blockscount < 0) {
reply_with_error ("blockscount must be >= 0");
goto error;
return -1;
}
snprintf (blockscount_s, sizeof blockscount_s, "%" PRIi64, blockscount);
ADD_ARG (argv, i, blockscount_s);
@@ -1177,26 +1149,21 @@ do_mke2fs (const char *device, /* 0 */
ADD_ARG (argv, i, NULL);
wipe_device_before_mkfs (device);
r = commandv (NULL, &err, argv);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
goto error;
return -1;
}
free (journaldevice_s);
free (err);
return 0;
error:
free (journaldevice_s);
free (err);
return -1;
}
int
do_mklost_and_found (const char *mountpoint)
{
char *cmd;
CLEANUP_FREE char *cmd = NULL;
int r;
if (asprintf_nowarn (&cmd, "cd %R && mklost+found", mountpoint) == -1) {
@@ -1207,15 +1174,12 @@ do_mklost_and_found (const char *mountpoint)
r = system (cmd);
if (r == -1) {
reply_with_perror ("system");
free (cmd);
return -1;
}
if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) {
reply_with_error ("%s: command failed", cmd);
free (cmd);
return -1;
}
free (cmd);
return 0;
}

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -440,7 +440,7 @@ do_pwrite_device (const char *device, const char *content, size_t size,
char *
do_file (const char *path)
{
char *buf = NULL;
CLEANUP_FREE char *buf = NULL;
const char *display_path = path;
int is_dev = STRPREFIX (path, "/dev/");
@@ -459,15 +459,12 @@ do_file (const char *path)
struct stat statbuf;
if (lstat (path, &statbuf) == -1) {
reply_with_perror ("lstat: %s", display_path);
free (buf);
return NULL;
}
if (! S_ISREG (statbuf.st_mode)) {
char *ret;
free (buf);
if (S_ISDIR (statbuf.st_mode))
ret = strdup ("directory");
else if (S_ISCHR (statbuf.st_mode))
@@ -494,22 +491,27 @@ do_file (const char *path)
*/
const char *flags = is_dev ? "-zbsL" : "-zb";
char *out, *err;
char *out;
CLEANUP_FREE char *err;
int r = command (&out, &err, str_file, flags, path, NULL);
free (buf);
if (r == -1) {
free (out);
reply_with_error ("%s: %s", display_path, err);
free (err);
return NULL;
}
free (err);
/* We need to remove the trailing \n from output of file(1). */
size_t len = strlen (out);
if (len > 0 && out[len-1] == '\n')
out[len-1] = '\0';
out[--len] = '\0';
/* Some upstream versions of file add a space at the end of the
* output. This is fixed in the Fedora version, but we might as
* well fix it here too. (RHBZ#928995).
*/
if (len > 0 && out[len-1] == ' ')
out[--len] = '\0';
return out; /* caller frees */
}
@@ -520,7 +522,7 @@ do_zfile (const char *method, const char *path)
{
size_t len;
const char *zcat;
char *cmd;
CLEANUP_FREE char *cmd = NULL;
FILE *fp;
char line[256];
@@ -544,12 +546,9 @@ do_zfile (const char *method, const char *path)
fp = popen (cmd, "r");
if (fp == NULL) {
reply_with_perror ("%s", cmd);
free (cmd);
return NULL;
}
free (cmd);
if (fgets (line, sizeof line, fp) == NULL) {
reply_with_perror ("fgets");
fclose (fp);

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -51,14 +51,6 @@ input_to_nul (FILE *fp, char *buf, size_t maxlen)
return -1;
}
/* The code below assumes each path returned can fit into a protocol
* chunk. If this turns out not to be true at some point in the
* future then we'll need to modify the code a bit to handle it.
*/
#if PATH_MAX > GUESTFS_MAX_CHUNK_SIZE
#error "PATH_MAX > GUESTFS_MAX_CHUNK_SIZE"
#endif
/* Has one FileOut parameter. */
int
do_find0 (const char *dir)
@@ -66,9 +58,9 @@ do_find0 (const char *dir)
struct stat statbuf;
int r;
FILE *fp;
char *cmd;
char *sysrootdir;
size_t sysrootdirlen, len;
CLEANUP_FREE char *cmd = NULL;
CLEANUP_FREE char *sysrootdir = NULL;
size_t sysrootdirlen;
char str[GUESTFS_MAX_CHUNK_SIZE];
sysrootdir = sysroot_path (dir);
@@ -80,12 +72,10 @@ do_find0 (const char *dir)
r = stat (sysrootdir, &statbuf);
if (r == -1) {
reply_with_perror ("%s", dir);
free (sysrootdir);
return -1;
}
if (!S_ISDIR (statbuf.st_mode)) {
reply_with_error ("%s: not a directory", dir);
free (sysrootdir);
return -1;
}
@@ -93,10 +83,8 @@ do_find0 (const char *dir)
if (asprintf_nowarn (&cmd, "%s %Q -print0", str_find, sysrootdir) == -1) {
reply_with_perror ("asprintf");
free (sysrootdir);
return -1;
}
free (sysrootdir);
if (verbose)
fprintf (stderr, "%s\n", cmd);
@@ -104,10 +92,8 @@ do_find0 (const char *dir)
fp = popen (cmd, "r");
if (fp == NULL) {
reply_with_perror ("%s", cmd);
free (cmd);
return -1;
}
free (cmd);
/* Now we must send the reply message, before the file contents. After
* this there is no opportunity in the protocol to send any error
@@ -115,8 +101,13 @@ do_find0 (const char *dir)
*/
reply (NULL, NULL);
/* The code below assumes each path returned can fit into a protocol
* chunk (if not you'll get a runtime protocol error). If this
* turns out not to be a problem at some point in the future then
* we'll need to modify the code to handle it. XXX
*/
while ((r = input_to_nul (fp, str, GUESTFS_MAX_CHUNK_SIZE)) > 0) {
len = strlen (str);
size_t len = strlen (str);
if (len <= sysrootdirlen)
continue;
@@ -128,14 +119,14 @@ do_find0 (const char *dir)
}
if (ferror (fp)) {
perror (dir);
fprintf (stderr, "fgetc: %s: %m\n", dir);
send_file_end (1); /* Cancel. */
pclose (fp);
return -1;
}
if (pclose (fp) != 0) {
perror (dir);
fprintf (stderr, "pclose: %s: %m\n", dir);
send_file_end (1); /* Cancel. */
return -1;
}

View File

@@ -31,6 +31,10 @@ GUESTFSD_EXT_CMD(str_findfs, findfs);
static char *
findfs (const char *tag, const char *label_or_uuid)
{
char *out;
CLEANUP_FREE char *err = NULL;
int r;
/* Kill the cache file, forcing blkid to reread values from the
* original filesystems. In blkid there is a '-p' option which is
* supposed to do this, but (a) it doesn't work and (b) that option
@@ -43,17 +47,13 @@ findfs (const char *tag, const char *label_or_uuid)
char arg[len];
snprintf (arg, len, "%s=%s", tag, label_or_uuid);
char *out, *err;
int r = command (&out, &err, str_findfs, arg, NULL);
r = command (&out, &err, str_findfs, arg, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (out);
free (err);
return NULL;
}
free (err);
/* Trim trailing \n if present. */
len = strlen (out);
if (len > 0 && out[len-1] == '\n')

View File

@@ -31,16 +31,14 @@ GUESTFSD_EXT_CMD(str_fsck, fsck);
int
do_fsck (const char *fstype, const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = commandr (NULL, &err, str_fsck, "-a", "-t", fstype, device, NULL);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
free (err);
return -1;
}
free (err);
return r;
}

View File

@@ -46,7 +46,7 @@ do_fstrim (const char *path,
const char *argv[MAX_ARGS];
size_t i = 0;
char offset_s[64], length_s[64], mfe_s[64];
char *err;
CLEANUP_FREE char *err = NULL;
int r;
ADD_ARG (argv, i, str_fstrim);
@@ -90,10 +90,8 @@ do_fstrim (const char *path,
r = commandv (NULL, &err, argv);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}

View File

@@ -36,7 +36,7 @@ grep (const char *regex, const char *path,
{
const char *argv[MAX_ARGS];
size_t i = 0;
char *out, *err;
CLEANUP_FREE char *out = NULL, *err = NULL;
int fd, flags, r;
char **lines;
@@ -78,15 +78,10 @@ grep (const char *regex, const char *path,
r = commandrvf (&out, &err, flags, argv);
if (r == -1 || r > 1) {
reply_with_error ("%s: %s", regex, err);
free (out);
free (err);
return NULL;
}
free (err);
lines = split_lines (out);
free (out);
if (lines == NULL) return NULL;
return lines;

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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,8 +38,7 @@ int
do_grub_install (const char *root, const char *device)
{
int r;
char *err;
char *buf;
CLEANUP_FREE char *err = NULL, *buf = NULL;
if (asprintf_nowarn (&buf, "--root-directory=%R", root) == -1) {
reply_with_perror ("asprintf");
@@ -47,14 +46,11 @@ do_grub_install (const char *root, const char *device)
}
r = command (NULL, &err, str_grub_install, buf, device, NULL);
free (buf);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -66,6 +66,10 @@ static char *read_cmdline (void);
# define O_CLOEXEC 0
#endif
/* For improved readability dealing with pipe arrays */
#define PIPE_READ 0
#define PIPE_WRITE 1
/* If root device is an ext2 filesystem, this is the major and minor.
* This is so we can ignore this device from the point of view of the
* user, eg. in guestfs_list_devices and many other places.
@@ -354,6 +358,13 @@ read_cmdline (void)
/* Return true iff device is the root device (and therefore should be
* ignored from the point of view of user calls).
*/
static int
is_root_device_stat (struct stat *statbuf)
{
if (statbuf->st_rdev == root_device) return 1;
return 0;
}
int
is_root_device (const char *device)
{
@@ -362,9 +373,8 @@ is_root_device (const char *device)
perror (device);
return 0;
}
if (statbuf.st_rdev == root_device)
return 1;
return 0;
return is_root_device_stat (&statbuf);
}
/* Turn "/path" into "/sysroot/path".
@@ -513,6 +523,9 @@ free_strings (char **argv)
{
size_t argc;
if (!argv)
return;
for (argc = 0; argv[argc] != NULL; ++argc)
free (argv[argc]);
free (argv);
@@ -523,6 +536,9 @@ free_stringslen (char **argv, size_t len)
{
size_t i;
if (!argv)
return;
for (i = 0; i < len; ++i)
free (argv[i]);
free (argv);
@@ -647,7 +663,8 @@ int
commandf (char **stdoutput, char **stderror, int flags, const char *name, ...)
{
va_list args;
const char **argv;
/* NB: Mustn't free the strings which are on the stack. */
CLEANUP_FREE const char **argv;
char *s;
size_t i;
int r;
@@ -668,7 +685,6 @@ commandf (char **stdoutput, char **stderror, int flags, const char *name, ...)
const char **p = realloc (argv, sizeof (char *) * (++i));
if (p == NULL) {
perror ("realloc");
free (argv);
va_end (args);
return -1;
}
@@ -681,9 +697,6 @@ commandf (char **stdoutput, char **stderror, int flags, const char *name, ...)
r = commandvf (stdoutput, stderror, flags, (const char * const*) argv);
/* NB: Mustn't free the strings which are on the stack. */
free (argv);
return r;
}
@@ -695,7 +708,7 @@ int
commandrf (char **stdoutput, char **stderror, int flags, const char *name, ...)
{
va_list args;
const char **argv;
CLEANUP_FREE const char **argv;
char *s;
int i, r;
@@ -715,7 +728,6 @@ commandrf (char **stdoutput, char **stderror, int flags, const char *name, ...)
const char **p = realloc (argv, sizeof (char *) * (++i));
if (p == NULL) {
perror ("realloc");
free (argv);
va_end (args);
return -1;
}
@@ -728,9 +740,6 @@ commandrf (char **stdoutput, char **stderror, int flags, const char *name, ...)
r = commandrvf (stdoutput, stderror, flags, argv);
/* NB: Mustn't free the strings which are on the stack. */
free (argv);
return r;
}
@@ -785,8 +794,8 @@ commandrvf (char **stdoutput, char **stderror, int flags,
size_t so_size = 0, se_size = 0;
int so_fd[2], se_fd[2];
int flag_copy_stdin = flags & COMMAND_FLAG_CHROOT_COPY_FILE_TO_STDIN;
int stdin_fd[2] = { -1, -1 };
pid_t pid, stdin_pid = -1;
int flag_copy_fd = flags & COMMAND_FLAG_FD_MASK;
pid_t pid;
int r, quit, i;
fd_set rset, rset2;
char buf[256];
@@ -816,13 +825,6 @@ commandrvf (char **stdoutput, char **stderror, int flags,
abort ();
}
if (flag_copy_stdin) {
if (pipe (stdin_fd) == -1) {
error (0, errno, "pipe");
abort ();
}
}
pid = fork ();
if (pid == -1) {
error (0, errno, "fork");
@@ -834,95 +836,42 @@ commandrvf (char **stdoutput, char **stderror, int flags,
signal (SIGPIPE, SIG_DFL);
close (0);
if (flag_copy_stdin) {
dup2 (stdin_fd[0], 0);
close (stdin_fd[0]);
close (stdin_fd[1]);
dup2 (flag_copy_fd, STDIN_FILENO);
} else {
/* Set stdin to /dev/null (ignore failure) */
ignore_value (open ("/dev/null", O_RDONLY|O_CLOEXEC));
}
close (so_fd[0]);
close (se_fd[0]);
close (so_fd[PIPE_READ]);
close (se_fd[PIPE_READ]);
if (!(flags & COMMAND_FLAG_FOLD_STDOUT_ON_STDERR))
dup2 (so_fd[1], 1);
dup2 (so_fd[PIPE_WRITE], STDOUT_FILENO);
else
dup2 (se_fd[1], 1);
dup2 (se_fd[1], 2);
close (so_fd[1]);
close (se_fd[1]);
dup2 (se_fd[PIPE_WRITE], STDOUT_FILENO);
dup2 (se_fd[PIPE_WRITE], STDERR_FILENO);
close (so_fd[PIPE_WRITE]);
close (se_fd[PIPE_WRITE]);
ignore_value (chdir ("/"));
execvp (argv[0], (void *) argv);
perror (argv[0]);
_exit (EXIT_FAILURE);
}
if (flag_copy_stdin) {
int fd = flags & COMMAND_FLAG_FD_MASK;
stdin_pid = fork ();
if (stdin_pid == -1) {
error (0, errno, "fork");
abort ();
}
if (stdin_pid == 0) { /* Child process copying stdin. */
close (so_fd[0]);
close (so_fd[1]);
close (se_fd[0]);
close (se_fd[1]);
close (1);
dup2 (stdin_fd[1], 1);
close (stdin_fd[0]);
close (stdin_fd[1]);
if (chroot (sysroot) == -1) {
perror ("chroot");
_exit (EXIT_FAILURE);
}
ssize_t n;
char buffer[BUFSIZ];
while ((n = read (fd, buffer, sizeof buffer)) > 0) {
if (xwrite (1, buffer, n) == -1)
/* EPIPE error indicates the command process has exited
* early. If the command process fails that will be caught
* by the daemon, and if not, then it's not an error.
*/
_exit (errno == EPIPE ? EXIT_SUCCESS : EXIT_FAILURE);
}
if (n == -1) {
perror ("read");
_exit (EXIT_FAILURE);
}
if (close (fd) == -1) {
perror ("close");
_exit (EXIT_FAILURE);
}
_exit (EXIT_SUCCESS);
}
close (fd);
close (stdin_fd[0]);
close (stdin_fd[1]);
}
/* Parent process. */
close (so_fd[1]);
close (se_fd[1]);
close (so_fd[PIPE_WRITE]);
close (se_fd[PIPE_WRITE]);
FD_ZERO (&rset);
FD_SET (so_fd[0], &rset);
FD_SET (se_fd[0], &rset);
FD_SET (so_fd[PIPE_READ], &rset);
FD_SET (se_fd[PIPE_READ], &rset);
quit = 0;
while (quit < 2) {
again:
rset2 = rset;
r = select (MAX (so_fd[0], se_fd[0]) + 1, &rset2, NULL, NULL, NULL);
r = select (MAX (so_fd[PIPE_READ], se_fd[PIPE_READ]) + 1, &rset2,
NULL, NULL, NULL);
if (r == -1) {
if (errno == EINTR)
goto again;
@@ -943,20 +892,20 @@ commandrvf (char **stdoutput, char **stderror, int flags,
*stderror = strdup ("error running external command, "
"see debug output for details");
}
close (so_fd[0]);
close (se_fd[0]);
close (so_fd[PIPE_READ]);
close (se_fd[PIPE_READ]);
if (flag_copy_stdin) close (flag_copy_fd);
waitpid (pid, NULL, 0);
if (stdin_pid >= 0) waitpid (stdin_pid, NULL, 0);
return -1;
}
if (FD_ISSET (so_fd[0], &rset2)) { /* something on stdout */
r = read (so_fd[0], buf, sizeof buf);
if (FD_ISSET (so_fd[PIPE_READ], &rset2)) { /* something on stdout */
r = read (so_fd[PIPE_READ], buf, sizeof buf);
if (r == -1) {
perror ("read");
goto quit;
}
if (r == 0) { FD_CLR (so_fd[0], &rset); quit++; }
if (r == 0) { FD_CLR (so_fd[PIPE_READ], &rset); quit++; }
if (r > 0 && stdoutput) {
so_size += r;
@@ -970,17 +919,17 @@ commandrvf (char **stdoutput, char **stderror, int flags,
}
}
if (FD_ISSET (se_fd[0], &rset2)) { /* something on stderr */
r = read (se_fd[0], buf, sizeof buf);
if (FD_ISSET (se_fd[PIPE_READ], &rset2)) { /* something on stderr */
r = read (se_fd[PIPE_READ], buf, sizeof buf);
if (r == -1) {
perror ("read");
goto quit;
}
if (r == 0) { FD_CLR (se_fd[0], &rset); quit++; }
if (r == 0) { FD_CLR (se_fd[PIPE_READ], &rset); quit++; }
if (r > 0) {
if (verbose)
ignore_value (write (2, buf, r));
ignore_value (write (STDERR_FILENO, buf, r));
if (stderror) {
se_size += r;
@@ -996,8 +945,8 @@ commandrvf (char **stdoutput, char **stderror, int flags,
}
}
close (so_fd[0]);
close (se_fd[0]);
close (so_fd[PIPE_READ]);
close (se_fd[PIPE_READ]);
/* Make sure the output buffers are \0-terminated. Also remove any
* trailing \n characters from the error buffer (not from stdout).
@@ -1028,21 +977,9 @@ commandrvf (char **stdoutput, char **stderror, int flags,
}
}
if (flag_copy_stdin) {
/* Check copy process didn't fail. */
if (waitpid (stdin_pid, &r, 0) != stdin_pid) {
perror ("waitpid");
kill (pid, 9);
waitpid (pid, NULL, 0);
return -1;
}
if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) {
fprintf (stderr, "failed copying from input file, see earlier messages (r = %d)\n", r);
kill (pid, 9);
waitpid (pid, NULL, 0);
return -1;
}
if (flag_copy_stdin && close (flag_copy_fd) == -1) {
perror ("close");
return -1;
}
/* Get the exit status of the command. */
@@ -1233,6 +1170,88 @@ device_name_translation (char *device)
return -1;
}
/* Parse the mountable descriptor for a btrfs subvolume. Don't call this
* directly - use the RESOLVE_MOUNTABLE macro.
*
* A btrfs subvolume is given as:
*
* btrfsvol:/dev/sda3/root
*
* where /dev/sda3 is a block device containing a btrfs filesystem, and root is
* the name of a subvolume on it. This function is passed the string following
* 'btrfsvol:'.
*/
int
parse_btrfsvol (char *desc, mountable_t *mountable)
{
char *device, *volume = NULL, *slash;
struct stat statbuf;
mountable->type = MOUNTABLE_BTRFSVOL;
device = desc;
if (! STRPREFIX (device, "/dev/"))
return -1;
slash = device + strlen ("/dev/") - 1;
while ((slash = strchr (slash + 1, '/'))) {
*slash = '\0';
if (device_name_translation (device) == -1) {
perror (device);
continue;
}
if (stat (device, &statbuf) == -1) {
perror (device);
return -1;
}
if (!S_ISDIR (statbuf.st_mode) &&
!is_root_device_stat (&statbuf))
{
volume = slash + 1;
break;
}
*slash = '/';
}
if (!volume) return -1;
mountable->device = device;
mountable->volume = volume;
return 0;
}
/* Convert a mountable_t back to its string representation
*
* This function can be used in an error path, and must not call
* reply_with_error().
*/
char *
mountable_to_string (const mountable_t *mountable)
{
char *desc;
switch (mountable->type) {
case MOUNTABLE_DEVICE:
case MOUNTABLE_PATH:
return strdup (mountable->device);
case MOUNTABLE_BTRFSVOL:
if (asprintf(&desc, "btrfsvol:%s/%s",
mountable->device, mountable->volume) == -1)
return NULL;
return desc;
default:
return NULL;
}
}
/* Check program exists and is executable on $PATH. Actually, we
* just assume PATH contains the default entries (see main() above).
*/
@@ -1311,3 +1330,27 @@ udev_settle (void)
{
(void) command (NULL, NULL, str_udevadm, "settle", NULL);
}
/* Use by the CLEANUP_* macros. Do not call these directly. */
void
cleanup_free (void *ptr)
{
free (* (void **) ptr);
}
void
cleanup_free_string_list (void *ptr)
{
free_strings (* (char ***) ptr);
}
void
cleanup_unlink_free (void *ptr)
{
char *filename = * (char **) ptr;
if (filename) {
unlink (filename);
free (filename);
}
}

View File

@@ -100,4 +100,4 @@ Richard W.M. Jones L<http://people.redhat.com/~rjones/>
=head1 COPYRIGHT
Copyright (C) 2009-2012 Red Hat Inc.
Copyright (C) 2009-2013 Red Hat Inc.

View File

@@ -31,7 +31,7 @@
static char **
headtail (const char *prog, const char *flag, const char *n, const char *path)
{
char *out, *err;
CLEANUP_FREE char *out = NULL, *err = NULL;
int fd, flags, r;
char **lines;
@@ -48,13 +48,9 @@ headtail (const char *prog, const char *flag, const char *n, const char *path)
r = commandf (&out, &err, flags, prog, flag, n, NULL);
if (r == -1) {
reply_with_error ("%s %s %s: %s", prog, flag, n, err);
free (out);
free (err);
return NULL;
}
free (err);
#if 0
/* Split it at the first whitespace. */
len = strcspn (out, " \t\n");
@@ -62,7 +58,6 @@ headtail (const char *prog, const char *flag, const char *n, const char *path)
#endif
lines = split_lines (out);
free (out);
if (lines == NULL) return NULL;
return lines;

View File

@@ -31,7 +31,8 @@ char *
do_hexdump (const char *path)
{
int fd, flags, r;
char *out, *err;
char *out;
CLEANUP_FREE char *err = NULL;
CHROOT_IN;
fd = open (path, O_RDONLY|O_CLOEXEC);
@@ -46,12 +47,9 @@ do_hexdump (const char *path)
r = commandf (&out, &err, flags, "hexdump", "-C", NULL);
if (r == -1) {
reply_with_error ("%s: %s", path, err);
free (err);
free (out);
return NULL;
}
free (err);
return out; /* caller frees */
}

View File

@@ -70,7 +70,7 @@ hivex_finalize (void)
int
do_hivex_open (const char *filename, int verbose, int debug, int write)
{
char *buf;
CLEANUP_FREE char *buf = NULL;
int flags = 0;
if (h) {
@@ -100,11 +100,9 @@ do_hivex_open (const char *filename, int verbose, int debug, int write)
h = hivex_open (buf, flags);
if (!h) {
reply_with_perror ("hivex failed to open %s", filename);
free (buf);
return -1;
}
free (buf);
return 0;
}
@@ -155,7 +153,7 @@ guestfs_int_hivex_node_list *
do_hivex_node_children (int64_t nodeh)
{
guestfs_int_hivex_node_list *ret;
hive_node_h *r;
CLEANUP_FREE hive_node_h *r = NULL;
size_t i, len;
NEED_HANDLE (NULL);
@@ -173,7 +171,6 @@ do_hivex_node_children (int64_t nodeh)
ret = malloc (sizeof *ret);
if (!ret) {
reply_with_perror ("malloc");
free (r);
return NULL;
}
@@ -183,15 +180,12 @@ do_hivex_node_children (int64_t nodeh)
if (ret->guestfs_int_hivex_node_list_val == NULL) {
reply_with_perror ("malloc");
free (ret);
free (r);
return NULL;
}
for (i = 0; i < len; ++i)
ret->guestfs_int_hivex_node_list_val[i].hivex_node_h = r[i];
free (r);
return ret;
}
@@ -232,7 +226,7 @@ guestfs_int_hivex_value_list *
do_hivex_node_values (int64_t nodeh)
{
guestfs_int_hivex_value_list *ret;
hive_value_h *r;
CLEANUP_FREE hive_value_h *r = NULL;
size_t i, len;
NEED_HANDLE (NULL);
@@ -250,7 +244,6 @@ do_hivex_node_values (int64_t nodeh)
ret = malloc (sizeof *ret);
if (!ret) {
reply_with_perror ("malloc");
free (r);
return NULL;
}
@@ -260,15 +253,12 @@ do_hivex_node_values (int64_t nodeh)
if (ret->guestfs_int_hivex_value_list_val == NULL) {
reply_with_perror ("malloc");
free (ret);
free (r);
return NULL;
}
for (i = 0; i < len; ++i)
ret->guestfs_int_hivex_value_list_val[i].hivex_value_h = (int64_t) r[i];
free (r);
return ret;
}
@@ -341,11 +331,30 @@ do_hivex_value_value (int64_t valueh, size_t *size_r)
int
do_hivex_commit (const char *filename)
{
CLEANUP_FREE char *buf = NULL;
NEED_HANDLE (-1);
if (hivex_commit (h, filename, 0) == -1) {
reply_with_perror ("failed");
return -1;
/* The 'filename' parameter is an optional string, and in most
* cases will be NULL.
*/
if (filename) {
buf = sysroot_path (filename);
if (!buf) {
reply_with_perror ("malloc");
return -1;
}
if (hivex_commit (h, buf, 0) == -1) {
reply_with_perror ("%s: commit failed", filename);
return -1;
}
}
else {
if (hivex_commit (h, NULL, 0) == -1) {
reply_with_perror ("commit failed");
return -1;
}
}
return 0;
@@ -400,110 +409,6 @@ do_hivex_node_set_value (int64_t nodeh,
#else /* !HAVE_HIVEX */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because optgroup_hivex_available
* returns false.
*/
int
optgroup_hivex_available (void)
{
return 0;
}
int __attribute__((noreturn))
do_hivex_open (const char *filename, int verbose, int debug, int write)
{
abort ();
}
int __attribute__((noreturn))
do_hivex_close (void)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_root (void)
{
abort ();
}
char * __attribute__((noreturn))
do_hivex_node_name (int64_t nodeh)
{
abort ();
}
guestfs_int_hivex_node_list * __attribute__((noreturn))
do_hivex_node_children (int64_t nodeh)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_node_get_child (int64_t nodeh, const char *name)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_node_parent (int64_t nodeh)
{
abort ();
}
guestfs_int_hivex_value_list * __attribute__((noreturn))
do_hivex_node_values (int64_t nodeh)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_node_get_value (int64_t nodeh, const char *key)
{
abort ();
}
char * __attribute__((noreturn))
do_hivex_value_key (int64_t valueh)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_value_type (int64_t valueh)
{
abort ();
}
char * __attribute__((noreturn))
do_hivex_value_value (int64_t valueh, size_t *size_r)
{
abort ();
}
int __attribute__((noreturn))
do_hivex_commit (const char *filename)
{
abort ();
}
int64_t __attribute__((noreturn))
do_hivex_node_add_child (int64_t parent, const char *name)
{
abort ();
}
int __attribute__((noreturn))
do_hivex_node_delete_child (int64_t nodeh)
{
abort ();
}
int __attribute__((noreturn))
do_hivex_node_set_value (int64_t nodeh, const char *key, int64_t t, const char *val, size_t val_size)
{
abort ();
}
OPTGROUP_HIVEX_NOT_AVAILABLE
#endif /* !HAVE_HIVEX */

View File

@@ -83,7 +83,7 @@ do_internal_hot_remove_drive_precheck (const char *label)
size_t len = strlen (label);
char path[len+64];
int r;
char *out, *err;
CLEANUP_FREE char *out = NULL, *err = NULL;
/* Ensure there are no requests in flight (thanks Paolo Bonzini). */
udev_settle ();
@@ -94,11 +94,8 @@ do_internal_hot_remove_drive_precheck (const char *label)
r = commandr (&out, &err, str_fuser, "-v", "-m", path, NULL);
if (r == -1) {
reply_with_error ("fuser: %s: %s", path, err);
free (out);
free (err);
return -1;
}
free (err);
/* "fuser returns a non-zero return code if none of the specified
* files is accessed or in case of a fatal error. If at least one
@@ -112,13 +109,9 @@ do_internal_hot_remove_drive_precheck (const char *label)
if (verbose)
fprintf (stderr, "%s\n", out);
free (out);
return -1;
}
free (out);
return 0;
}

View File

@@ -37,10 +37,11 @@ char **
do_initrd_list (const char *path)
{
FILE *fp;
char *cmd;
char filename[PATH_MAX];
CLEANUP_FREE char *cmd = NULL;
DECLARE_STRINGSBUF (filenames);
size_t len;
CLEANUP_FREE char *filename = NULL;
size_t allocsize;
ssize_t len;
/* "zcat /sysroot/<path> | cpio --quiet -it", but path must be quoted. */
if (asprintf_nowarn (&cmd, "%s %R | %s --quiet -it", str_zcat, path, str_cpio) == -1) {
@@ -54,16 +55,13 @@ do_initrd_list (const char *path)
fp = popen (cmd, "r");
if (fp == NULL) {
reply_with_perror ("popen: %s", cmd);
free (cmd);
return NULL;
}
free (cmd);
while (fgets (filename, sizeof filename, fp) != NULL) {
len = strlen (filename);
allocsize = 0;
while ((len = getline (&filename, &allocsize, fp)) != -1) {
if (len > 0 && filename[len-1] == '\n')
filename[len-1] = '\0';
if (add_string (&filenames, filename) == -1) {
pclose (fp);
return NULL;
@@ -88,33 +86,36 @@ char *
do_initrd_cat (const char *path, const char *filename, size_t *size_r)
{
char tmpdir[] = "/tmp/initrd-cat-XXXXXX";
CLEANUP_FREE char *cmd;
struct stat statbuf;
int fd, r;
char *ret = NULL;
CLEANUP_FREE char *fullpath = NULL;
if (mkdtemp (tmpdir) == NULL) {
reply_with_perror ("mkdtemp");
return NULL;
}
/* "zcat /sysroot/<path> | cpio --quiet -id file", but paths must be quoted */
char *cmd;
if (asprintf_nowarn (&cmd, "cd %Q && zcat %R | cpio --quiet -id %Q",
tmpdir, path, filename) == -1) {
reply_with_perror ("asprintf");
rmdir (tmpdir);
return NULL;
}
/* Extract file into temporary directory. This may create subdirs.
* It's also possible that this doesn't create anything at all
* (eg. if the named file does not exist in the cpio archive) --
* cpio is silent in this case.
*/
int r = system (cmd);
if (r == -1) {
reply_with_perror ("command failed: %s", cmd);
free (cmd);
/* "zcat /sysroot/<path> | cpio --quiet -id file", but paths must be quoted */
if (asprintf_nowarn (&cmd, "cd %Q && zcat %R | cpio --quiet -id %Q",
tmpdir, path, filename) == -1) {
reply_with_perror ("asprintf");
rmdir (tmpdir);
return NULL;
}
r = system (cmd);
if (r == -1) {
reply_with_perror ("command failed: %s", cmd);
rmdir (tmpdir);
return NULL;
}
free (cmd);
if (WEXITSTATUS (r) != 0) {
reply_with_perror ("command failed with return code %d",
WEXITSTATUS (r));
@@ -122,13 +123,14 @@ do_initrd_cat (const char *path, const char *filename, size_t *size_r)
return NULL;
}
/* Construct the expected name of the extracted file. */
if (asprintf (&fullpath, "%s/%s", tmpdir, filename) == -1) {
reply_with_perror ("asprintf");
rmdir (tmpdir);
return NULL;
}
/* See if we got a file. */
char fullpath[PATH_MAX];
snprintf (fullpath, sizeof fullpath, "%s/%s", tmpdir, filename);
struct stat statbuf;
int fd;
fd = open (fullpath, O_RDONLY|O_CLOEXEC);
if (fd == -1) {
reply_with_perror ("open: %s:%s", path, filename);
@@ -139,8 +141,6 @@ do_initrd_cat (const char *path, const char *filename, size_t *size_r)
/* From this point, we know the file exists, so we require full
* cleanup.
*/
char *ret = NULL;
if (fstat (fd, &statbuf) == -1) {
reply_with_perror ("fstat: %s:%s", path, filename);
goto cleanup;
@@ -189,8 +189,7 @@ do_initrd_cat (const char *path, const char *filename, size_t *size_r)
/* Remove the file. */
if (unlink (fullpath) == -1) {
fprintf (stderr, "unlink: ");
perror (fullpath);
fprintf (stderr, "unlink: %s: %m\n", fullpath);
/* non-fatal */
}
@@ -200,8 +199,7 @@ do_initrd_cat (const char *path, const char *filename, size_t *size_r)
if (!p) break;
*p = '\0';
if (rmdir (fullpath) == -1) {
fprintf (stderr, "rmdir: ");
perror (fullpath);
fprintf (stderr, "rmdir: %s: %m\n", fullpath);
/* non-fatal */
}
} while (STRNEQ (fullpath, tmpdir));

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -43,6 +43,9 @@ static int inotify_fd = -1;
static char inotify_buf[64*1024*1024]; /* Event buffer, [0..posn-1] is valid */
static size_t inotify_posn = 0;
/* Because of use of arbitrary offsets within inotify_buf. */
#pragma GCC diagnostic ignored "-Wcast-align"
/* Clean up the inotify handle on daemon exit. */
static void inotify_finalize (void) __attribute__((destructor));
static void
@@ -151,7 +154,7 @@ int64_t
do_inotify_add_watch (const char *path, int mask)
{
int64_t r;
char *buf;
CLEANUP_FREE char *buf = NULL;
NEED_INOTIFY (-1);
@@ -162,7 +165,6 @@ do_inotify_add_watch (const char *path, int mask)
}
r = inotify_add_watch (inotify_fd, buf, mask);
free (buf);
if (r == -1) {
reply_with_perror ("%s", path);
return -1;
@@ -388,50 +390,6 @@ do_inotify_files (void)
#else /* !HAVE_SYS_INOTIFY_H */
/* Note that the wrapper code (daemon/stubs.c) ensures that the
* functions below are never called because optgroup_inotify_available
* returns false.
*/
int
optgroup_inotify_available (void)
{
return 0;
}
int
do_inotify_init (int max_events)
{
abort ();
}
int
do_inotify_close (void)
{
abort ();
}
int64_t
do_inotify_add_watch (const char *path, int mask)
{
abort ();
}
int
do_inotify_rm_watch (int wd)
{
abort ();
}
guestfs_int_inotify_event_list *
do_inotify_read (void)
{
abort ();
}
char **
do_inotify_files (void)
{
abort ();
}
OPTGROUP_INOTIFY_NOT_AVAILABLE
#endif

View File

@@ -57,7 +57,8 @@ parse_time_t (int64_t *ret, const char *str)
struct tm tm;
time_t r;
if (STREQ (str, "0000 00 00 00:00:00.00")) {
if (STREQ (str, "0000 00 00 00:00:00.00") ||
STREQ (str, " : : . ")) {
*ret = -1;
return 0;
}
@@ -238,10 +239,9 @@ parse_isoinfo (char **lines)
static guestfs_int_isoinfo *
isoinfo (const char *path)
{
char *out = NULL, *err = NULL;
int r;
char **lines = NULL;
guestfs_int_isoinfo *ret = NULL;
CLEANUP_FREE char *out = NULL, *err = NULL;
CLEANUP_FREE_STRING_LIST char **lines = NULL;
/* --debug is necessary to get additional fields, in particular
* the date & time fields.
@@ -249,24 +249,14 @@ isoinfo (const char *path)
r = command (&out, &err, str_isoinfo, "--debug", "-d", "-i", path, NULL);
if (r == -1) {
reply_with_error ("%s", err);
goto done;
return NULL;
}
lines = split_lines (out);
if (lines == NULL)
goto done;
return NULL;
ret = parse_isoinfo (lines);
if (ret == NULL)
goto done;
done:
free (out);
free (err);
if (lines)
free_strings (lines);
return ret;
return parse_isoinfo (lines);
}
guestfs_int_isoinfo *
@@ -278,17 +268,14 @@ do_isoinfo_device (const char *device)
guestfs_int_isoinfo *
do_isoinfo (const char *path)
{
char *buf;
guestfs_int_isoinfo *ret;
buf = sysroot_path (path);
CLEANUP_FREE char *buf = sysroot_path (path);
if (!buf) {
reply_with_perror ("malloc");
return NULL;
}
ret = isoinfo (buf);
free (buf);
return ret;
}

View File

@@ -34,7 +34,7 @@ static int
e2label (const char *device, const char *label)
{
int r;
char *err;
CLEANUP_FREE char *err = NULL;
if (strlen (label) > EXT2_LABEL_MAX) {
reply_with_error ("%s: ext2 labels are limited to %d bytes",
@@ -45,11 +45,9 @@ e2label (const char *device, const char *label)
r = command (NULL, &err, str_e2label, device, label, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -57,7 +55,7 @@ static int
ntfslabel (const char *device, const char *label)
{
int r;
char *err;
CLEANUP_FREE char *err = NULL;
/* XXX We should check if the label is longer than 128 unicode
* characters and return an error. This is not so easy since we
@@ -66,31 +64,28 @@ ntfslabel (const char *device, const char *label)
r = command (NULL, &err, str_ntfslabel, device, label, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_set_label (const char *device, const char *label)
do_set_label (const mountable_t *mountable, const char *label)
{
char *vfs_type;
int r;
/* How we set the label depends on the filesystem type. */
vfs_type = do_vfs_type (device);
CLEANUP_FREE char *vfs_type = do_vfs_type (mountable);
if (vfs_type == NULL)
return -1;
if (STREQ (vfs_type, "ext2") || STREQ (vfs_type, "ext3")
|| STREQ (vfs_type, "ext4"))
r = e2label (device, label);
r = e2label (mountable->device, label);
else if (STREQ (vfs_type, "ntfs"))
r = ntfslabel (device, label);
r = ntfslabel (mountable->device, label);
else {
reply_with_error ("don't know how to set the label for '%s' filesystems",
@@ -98,6 +93,5 @@ do_set_label (const char *device, const char *label)
r = -1;
}
free (vfs_type);
return r;
}

423
daemon/ldm.c Normal file
View File

@@ -0,0 +1,423 @@
/* 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 <glob.h>
#if HAVE_YAJL
#include <yajl/yajl_tree.h>
#endif
#include "daemon.h"
#include "actions.h"
#include "optgroups.h"
#if HAVE_YAJL
GUESTFSD_EXT_CMD(str_ldmtool, ldmtool);
int
optgroup_ldm_available (void)
{
return prog_exists (str_ldmtool);
}
static int
glob_errfunc (const char *epath, int eerrno)
{
fprintf (stderr, "glob: failure reading %s: %s\n", epath, strerror (eerrno));
return 1;
}
static char **
get_devices (const char *pattern)
{
DECLARE_STRINGSBUF (ret);
glob_t devs;
int err;
size_t i;
err = glob (pattern, GLOB_ERR, glob_errfunc, &devs);
if (err == GLOB_NOSPACE) {
reply_with_error ("glob: returned GLOB_NOSPACE: "
"rerun with LIBGUESTFS_DEBUG=1");
goto error;
} else if (err == GLOB_ABORTED) {
reply_with_error ("glob: returned GLOB_ABORTED: "
"rerun with LIBGUESTFS_DEBUG=1");
goto error;
}
for (i = 0; i < devs.gl_pathc; ++i) {
if (add_string (&ret, devs.gl_pathv[i]) == -1)
goto error;
}
if (end_stringsbuf (&ret) == -1) goto error;
globfree (&devs);
return ret.argv;
error:
globfree (&devs);
if (ret.argv != NULL)
free_stringslen (ret.argv, ret.size);
return NULL;
}
/* All device mapper devices called /dev/mapper/ldm_vol_*. XXX We
* could tighten this up in future if ldmtool had a way to read these
* names back after they have been created.
*/
char **
do_list_ldm_volumes (void)
{
return get_devices ("/dev/mapper/ldm_vol_*");
}
/* Same as above but /dev/mapper/ldm_part_*. See comment above. */
char **
do_list_ldm_partitions (void)
{
return get_devices ("/dev/mapper/ldm_part_*");
}
int
do_ldmtool_create_all (void)
{
int r;
CLEANUP_FREE char *err = NULL;
r = command (NULL, &err, "ldmtool", "create", "all", NULL);
if (r == -1) {
reply_with_error ("%s", err);
return -1;
}
return 0;
}
int
do_ldmtool_remove_all (void)
{
int r;
CLEANUP_FREE char *err = NULL;
r = command (NULL, &err, "ldmtool", "remove", "all", NULL);
if (r == -1) {
reply_with_error ("%s", err);
return -1;
}
return 0;
}
static yajl_val
parse_json (const char *json, const char *func)
{
yajl_val tree;
char parse_error[1024];
if (verbose)
fprintf (stderr, "%s: parsing json: %s\n", func, json);
tree = yajl_tree_parse (json, parse_error, sizeof parse_error);
if (tree == NULL) {
reply_with_error ("parse error: %s",
strlen (parse_error) ? parse_error : "unknown error");
return NULL;
}
/* Caller should free this by doing 'yajl_tree_free (tree);'. */
return tree;
}
#define TYPE_ERROR ((char **) -1)
static char **
json_value_to_string_list (yajl_val node)
{
DECLARE_STRINGSBUF (strs);
yajl_val n;
size_t i, len;
if (! YAJL_IS_ARRAY (node))
return TYPE_ERROR;
len = YAJL_GET_ARRAY(node)->len;
for (i = 0; i < len; ++i) {
n = YAJL_GET_ARRAY(node)->values[i];
if (! YAJL_IS_STRING (n))
return TYPE_ERROR;
if (add_string (&strs, YAJL_GET_STRING (n)) == -1)
return NULL;
}
if (end_stringsbuf (&strs) == -1)
return NULL;
return strs.argv;
}
static char **
parse_json_get_string_list (const char *json,
const char *func, const char *cmd)
{
char **ret;
yajl_val tree = NULL;
tree = parse_json (json, func);
if (tree == NULL)
return NULL;
ret = json_value_to_string_list (tree);
yajl_tree_free (tree);
if (ret == TYPE_ERROR) {
reply_with_error ("output of '%s' was not a JSON array of strings", cmd);
return NULL;
}
return ret;
}
#define GET_STRING_NULL_TO_EMPTY 1
static char *
parse_json_get_object_string (const char *json, const char *key, int flags,
const char *func, const char *cmd)
{
char *str, *ret;
yajl_val tree = NULL, node;
size_t i, len;
tree = parse_json (json, func);
if (tree == NULL)
return NULL;
if (! YAJL_IS_OBJECT (tree))
goto bad_type;
len = YAJL_GET_OBJECT(tree)->len;
for (i = 0; i < len; ++i) {
if (STREQ (YAJL_GET_OBJECT(tree)->keys[i], key)) {
node = YAJL_GET_OBJECT(tree)->values[i];
if ((flags & GET_STRING_NULL_TO_EMPTY) && YAJL_IS_NULL (node))
ret = strdup ("");
else {
str = YAJL_GET_STRING (node);
if (str == NULL)
goto bad_type;
ret = strdup (str);
}
if (ret == NULL)
reply_with_perror ("strdup");
yajl_tree_free (tree);
return ret;
}
}
bad_type:
reply_with_error ("output of '%s' was not a JSON object "
"containing a key '%s' of type string", cmd, key);
yajl_tree_free (tree);
return NULL;
}
static char **
parse_json_get_object_string_list (const char *json, const char *key,
const char *func, const char *cmd)
{
char **ret;
yajl_val tree, node;
size_t i, len;
tree = parse_json (json, func);
if (tree == NULL)
return NULL;
if (! YAJL_IS_OBJECT (tree))
goto bad_type;
len = YAJL_GET_OBJECT(tree)->len;
for (i = 0; i < len; ++i) {
if (STREQ (YAJL_GET_OBJECT(tree)->keys[i], key)) {
node = YAJL_GET_OBJECT(tree)->values[i];
ret = json_value_to_string_list (node);
if (ret == TYPE_ERROR)
goto bad_type;
yajl_tree_free (tree);
return ret;
}
}
bad_type:
reply_with_error ("output of '%s' was not a JSON object "
"containing a key '%s' of type array of strings",
cmd, key);
yajl_tree_free (tree);
return NULL;
}
char **
do_ldmtool_scan (void)
{
const char *empty_list[] = { NULL };
return do_ldmtool_scan_devices ((char * const *) empty_list);
}
char **
do_ldmtool_scan_devices (char * const * devices)
{
char **ret;
size_t i, nr_devices;
CLEANUP_FREE_STRING_LIST const char **argv = NULL;
int r;
CLEANUP_FREE char *out = NULL, *err = NULL;
nr_devices = count_strings (devices);
argv = malloc ((3 + nr_devices) * sizeof (char *));
if (argv == NULL) {
reply_with_perror ("malloc");
return NULL;
}
argv[0] = str_ldmtool;
argv[1] = "scan";
for (i = 0; i < nr_devices; ++i)
argv[2+i] = devices[i];
argv[2+i] = NULL;
r = commandv (&out, &err, argv);
if (r == -1) {
reply_with_error ("%s", err);
return NULL;
}
ret = parse_json_get_string_list (out, __func__, "ldmtool scan");
return ret;
}
char *
do_ldmtool_diskgroup_name (const char *diskgroup)
{
int r;
CLEANUP_FREE char *out = NULL, *err = NULL;
r = command (&out, &err, str_ldmtool, "show", "diskgroup", diskgroup, NULL);
if (r == -1) {
reply_with_error ("%s", err);
return NULL;
}
return parse_json_get_object_string (out, "name", 0,
__func__, "ldmtool show diskgroup");
}
char **
do_ldmtool_diskgroup_volumes (const char *diskgroup)
{
int r;
CLEANUP_FREE char *out = NULL, *err = NULL;
r = command (&out, &err, str_ldmtool, "show", "diskgroup", diskgroup, NULL);
if (r == -1) {
reply_with_error ("%s", err);
return NULL;
}
free (err);
return parse_json_get_object_string_list (out, "volumes",
__func__, "ldmtool show diskgroup");
}
char **
do_ldmtool_diskgroup_disks (const char *diskgroup)
{
int r;
CLEANUP_FREE char *out = NULL, *err = NULL;
r = command (&out, &err, str_ldmtool, "show", "diskgroup", diskgroup, NULL);
if (r == -1) {
reply_with_error ("%s", err);
return NULL;
}
return parse_json_get_object_string_list (out, "disks",
__func__, "ldmtool show diskgroup");
}
char *
do_ldmtool_volume_type (const char *diskgroup, const char *volume)
{
int r;
CLEANUP_FREE char *out = NULL, *err = NULL;
r = command (&out, &err,
str_ldmtool, "show", "volume", diskgroup, volume, NULL);
if (r == -1) {
reply_with_error ("%s", err);
return NULL;
}
return parse_json_get_object_string (out, "type", 0,
__func__, "ldmtool show volume");
}
char *
do_ldmtool_volume_hint (const char *diskgroup, const char *volume)
{
int r;
CLEANUP_FREE char *out = NULL, *err = NULL;
r = command (&out, &err,
str_ldmtool, "show", "volume", diskgroup, volume, NULL);
if (r == -1) {
reply_with_error ("%s", err);
return NULL;
}
return parse_json_get_object_string (out, "hint", GET_STRING_NULL_TO_EMPTY,
__func__, "ldmtool show volume");
}
char **
do_ldmtool_volume_partitions (const char *diskgroup, const char *volume)
{
int r;
CLEANUP_FREE char *out = NULL, *err = NULL;
r = command (&out, &err,
str_ldmtool, "show", "volume", diskgroup, volume, NULL);
if (r == -1) {
reply_with_error ("%s", err);
return NULL;
}
return parse_json_get_object_string_list (out, "partitions",
__func__, "ldmtool show volume");
}
#else /* !HAVE_YAJL */
OPTGROUP_LDM_NOT_AVAILABLE
#endif

View File

@@ -25,6 +25,8 @@
#include <unistd.h>
#include <limits.h>
#include "areadlink.h"
#include "daemon.h"
#include "actions.h"
@@ -33,25 +35,17 @@ GUESTFSD_EXT_CMD(str_ln, ln);
char *
do_readlink (const char *path)
{
ssize_t r;
char *ret;
char link[PATH_MAX];
char *link;
CHROOT_IN;
r = readlink (path, link, sizeof link);
link = areadlink (path);
CHROOT_OUT;
if (r == -1) {
if (link == NULL) {
reply_with_perror ("readlink");
return NULL;
}
ret = strndup (link, r);
if (ret == NULL) {
reply_with_perror ("strndup");
return NULL;
}
return ret; /* caller frees */
return link; /* caller frees */
}
char **
@@ -59,9 +53,6 @@ do_internal_readlinklist (const char *path, char *const *names)
{
int fd_cwd;
size_t i;
ssize_t r;
char link[PATH_MAX];
const char *str;
DECLARE_STRINGSBUF (ret);
CHROOT_IN;
@@ -74,23 +65,20 @@ do_internal_readlinklist (const char *path, char *const *names)
}
for (i = 0; names[i] != NULL; ++i) {
r = readlinkat (fd_cwd, names[i], link, sizeof link);
if (r >= PATH_MAX) {
reply_with_perror ("readlinkat: returned link is too long");
close (fd_cwd);
return NULL;
}
/* Because of the way this function is intended to be used,
* we actually expect to see errors here, and they are not fatal.
*/
if (r >= 0) {
link[r] = '\0';
str = link;
} else
str = "";
if (add_string (&ret, str) == -1) {
close (fd_cwd);
return NULL;
CLEANUP_FREE char *link = areadlinkat (fd_cwd, names[i]);
if (link != NULL) {
if (add_string (&ret, link) == -1) {
add_string_failed:
close (fd_cwd);
return NULL;
}
} else {
if (add_string (&ret, "") == -1)
goto add_string_failed;
}
}
@@ -102,13 +90,47 @@ do_internal_readlinklist (const char *path, char *const *names)
return ret.argv;
}
static int
_link (const char *flag, int symbolic, const char *target, const char *linkname)
int
do_ln (const char *target, const char *linkname)
{
int r;
char *err;
char *buf_linkname;
char *buf_target;
CHROOT_IN;
r = link (target, linkname);
CHROOT_OUT;
if (r == -1) {
reply_with_perror ("link: %s: %s", target, linkname);
return -1;
}
return 0;
}
int
do_ln_f (const char *target, const char *linkname)
{
int r;
CHROOT_IN;
unlink (linkname);
r = link (target, linkname);
CHROOT_OUT;
if (r == -1) {
reply_with_perror ("link: %s: %s", target, linkname);
return -1;
}
return 0;
}
static int
_symlink (const char *flag, const char *target, const char *linkname)
{
int r;
CLEANUP_FREE char *err = NULL;
CLEANUP_FREE char *buf_linkname = NULL;
/* Prefix linkname with sysroot. */
buf_linkname = sysroot_path (linkname);
@@ -117,65 +139,26 @@ _link (const char *flag, int symbolic, const char *target, const char *linkname)
return -1;
}
/* Only prefix target if it's _not_ a symbolic link, and if
* the target is absolute. Note that the resulting link will
* always be "broken" from the p.o.v. of the appliance, ie:
* /a -> /b but the path as seen here is /sysroot/b
*/
buf_target = NULL;
if (!symbolic && target[0] == '/') {
buf_target = sysroot_path (target);
if (!buf_target) {
reply_with_perror ("malloc");
free (buf_linkname);
return -1;
}
}
if (flag)
r = command (NULL, &err,
str_ln, flag, "--", /* target could begin with '-' */
buf_target ? : target, buf_linkname, NULL);
else
r = command (NULL, &err,
str_ln, "--",
buf_target ? : target, buf_linkname, NULL);
free (buf_linkname);
free (buf_target);
r = command (NULL, &err,
str_ln, flag, "--", /* target could begin with '-' */
target, buf_linkname, NULL);
if (r == -1) {
reply_with_error ("ln%s%s: %s: %s: %s",
flag ? " " : "",
flag ? : "",
target, linkname, err);
free (err);
reply_with_error ("ln %s: %s: %s: %s",
flag, target, linkname, err);
return -1;
}
free (err);
return 0;
}
int
do_ln (const char *target, const char *linkname)
{
return _link (NULL, 0, target, linkname);
}
int
do_ln_f (const char *target, const char *linkname)
{
return _link ("-f", 0, target, linkname);
}
int
do_ln_s (const char *target, const char *linkname)
{
return _link ("-s", 1, target, linkname);
return _symlink ("-s", target, linkname);
}
int
do_ln_sf (const char *target, const char *linkname)
{
return _link ("-sf", 1, target, linkname);
return _symlink ("-sf", target, linkname);
}

View File

@@ -77,14 +77,14 @@ do_ls0 (const char *path)
}
if (errno != 0) {
perror (path);
fprintf (stderr, "readdir: %s: %m\n", path);
send_file_end (1); /* Cancel. */
closedir (dir);
return -1;
}
if (closedir (dir) == -1) {
perror (path);
fprintf (stderr, "closedir: %s: %m\n", path);
send_file_end (1); /* Cancel. */
return -1;
}
@@ -105,8 +105,9 @@ char *
do_ll (const char *path)
{
int r;
char *out, *err;
char *spath;
char *out;
CLEANUP_FREE char *err = NULL;
CLEANUP_FREE char *spath = NULL;
spath = sysroot_path (path);
if (!spath) {
@@ -115,15 +116,12 @@ do_ll (const char *path)
}
r = command (&out, &err, str_ls, "-la", spath, NULL);
free (spath);
if (r == -1) {
reply_with_error ("%s", err);
free (out);
free (err);
return NULL;
}
free (err);
return out; /* caller frees */
}
@@ -131,8 +129,9 @@ char *
do_llz (const char *path)
{
int r;
char *out, *err;
char *spath;
char *out;
CLEANUP_FREE char *err = NULL;
CLEANUP_FREE char *spath;
spath = sysroot_path (path);
if (!spath) {
@@ -141,14 +140,11 @@ do_llz (const char *path)
}
r = command (&out, &err, str_ls, "-laZ", spath, NULL);
free (spath);
if (r == -1) {
reply_with_error ("%s", err);
free (out);
free (err);
return NULL;
}
free (err);
return out; /* caller frees */
}

View File

@@ -115,18 +115,15 @@ luks_open (const char *device, const char *key, const char *mapname,
ADD_ARG (argv, i, mapname);
ADD_ARG (argv, i, NULL);
char *err;
CLEANUP_FREE char *err = NULL;
int r = commandv (NULL, &err, (const char * const *) argv);
remove_temp (tempfile);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -155,16 +152,13 @@ do_luks_close (const char *device)
const char *mapname = &device[12];
char *err;
CLEANUP_FREE char *err = NULL;
int r = command (NULL, &err, str_cryptsetup, "luksClose", mapname, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -196,18 +190,15 @@ luks_format (const char *device, const char *key, int keyslot,
ADD_ARG (argv, i, tempfile);
ADD_ARG (argv, i, NULL);
char *err;
CLEANUP_FREE char *err = NULL;
int r = commandv (NULL, &err, (const char * const *) argv);
remove_temp (tempfile);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -256,19 +247,16 @@ do_luks_add_key (const char *device, const char *key, const char *newkey,
ADD_ARG (argv, i, newkeyfile);
ADD_ARG (argv, i, NULL);
char *err;
CLEANUP_FREE char *err = NULL;
int r = commandv (NULL, &err, (const char * const *) argv);
remove_temp (keyfile);
remove_temp (newkeyfile);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -293,17 +281,14 @@ do_luks_kill_slot (const char *device, const char *key, int keyslot)
ADD_ARG (argv, i, keyslot_s);
ADD_ARG (argv, i, NULL);
char *err;
CLEANUP_FREE char *err = NULL;
int r = commandv (NULL, &err, (const char * const *) argv);
remove_temp (tempfile);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}

View File

@@ -37,7 +37,13 @@ GUESTFSD_EXT_CMD(str_rm, rm);
/* This runs during daemon start up and creates a complete copy of
* /etc/lvm so that we can modify it as we desire. We set
* LVM_SYSTEM_DIR to point to the copy.
* LVM_SYSTEM_DIR to point to the copy. Note that the final directory
* layout is:
* /tmp/lvmXXXXXX (lvm_system_dir set to this)
* /tmp/lvmXXXXXX/lvm ($LVM_SYSTEM_DIR set to this)
* /tmp/lvmXXXXXX/lvm/lvm.conf (configuration file)
* /tmp/lvmXXXXXX/lvm/cache
* etc.
*/
static char lvm_system_dir[] = "/tmp/lvmXXXXXX";
@@ -47,7 +53,7 @@ void
copy_lvm (void)
{
struct stat statbuf;
char cmd[64];
char cmd[64], env[64];
int r;
/* If /etc/lvm directory doesn't exist (or isn't a directory) assume
@@ -64,12 +70,12 @@ copy_lvm (void)
}
if (mkdtemp (lvm_system_dir) == NULL) {
perror (lvm_system_dir);
fprintf (stderr, "mkdtemp: %s: %m\n", lvm_system_dir);
exit (EXIT_FAILURE);
}
/* Hopefully no dotfiles in there ... XXX */
snprintf (cmd, sizeof cmd, "%s -a /etc/lvm/* %s", str_cp, lvm_system_dir);
/* Copy the entire directory */
snprintf (cmd, sizeof cmd, "%s -a /etc/lvm/ %s", str_cp, lvm_system_dir);
r = system (cmd);
if (r == -1) {
perror (cmd);
@@ -85,7 +91,8 @@ copy_lvm (void)
}
/* Set environment variable so we use the copy. */
setenv ("LVM_SYSTEM_DIR", lvm_system_dir, 1);
snprintf (env, sizeof env, "%s/lvm", lvm_system_dir);
setenv ("LVM_SYSTEM_DIR", env, 1);
/* Set a handler to remove the temporary directory at exit. */
atexit (rm_lvm_system_dir);
@@ -129,10 +136,11 @@ static int
set_filter (const char *filter)
{
char lvm_conf[64];
snprintf (lvm_conf, sizeof lvm_conf, "%s/lvm.conf", lvm_system_dir);
snprintf (lvm_conf, sizeof lvm_conf, "%s/lvm/lvm.conf", lvm_system_dir);
char lvm_conf_new[64];
snprintf (lvm_conf_new, sizeof lvm_conf, "%s/lvm.conf.new", lvm_system_dir);
snprintf (lvm_conf_new, sizeof lvm_conf, "%s/lvm/lvm.conf.new",
lvm_system_dir);
FILE *ifp = fopen (lvm_conf, "r");
if (ifp == NULL) {
@@ -146,9 +154,9 @@ set_filter (const char *filter)
return -1;
}
char *line = NULL;
size_t len = 0;
while (getline (&line, &len, ifp) != -1) {
CLEANUP_FREE char *line = NULL;
size_t allocsize = 0;
while (getline (&line, &allocsize, ifp) != -1) {
int r;
if (is_filter_line (line)) {
r = fprintf (ofp, " filter = [ %s ]\n", filter);
@@ -160,14 +168,11 @@ set_filter (const char *filter)
reply_with_error ("%s: write failed", lvm_conf_new);
fclose (ifp);
fclose (ofp);
free (line);
unlink (lvm_conf_new);
return -1;
}
}
free (line);
if (fclose (ifp) == EOF) {
reply_with_perror ("close: %s", lvm_conf);
unlink (lvm_conf_new);
@@ -192,15 +197,13 @@ set_filter (const char *filter)
static int
vgchange (const char *vgchange_flag)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r = command (NULL, &err, str_lvm, "vgchange", vgchange_flag, NULL);
if (r == -1) {
reply_with_error ("vgchange: %s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -223,19 +226,17 @@ static int
rescan (void)
{
char lvm_cache[64];
snprintf (lvm_cache, sizeof lvm_cache, "%s/cache/.cache", lvm_system_dir);
snprintf (lvm_cache, sizeof lvm_cache, "%s/lvm/cache/.cache", lvm_system_dir);
unlink (lvm_cache);
char *err;
CLEANUP_FREE char *err = NULL;
int r = command (NULL, &err, str_lvm, "vgscan", NULL);
if (r == -1) {
reply_with_error ("vgscan: %s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -287,17 +288,14 @@ make_filter_string (char *const *devices)
int
do_lvm_set_filter (char *const *devices)
{
char *filter = make_filter_string (devices);
CLEANUP_FREE char *filter = make_filter_string (devices);
if (filter == NULL)
return -1;
if (deactivate () == -1) {
free (filter);
if (deactivate () == -1)
return -1;
}
int r = set_filter (filter);
free (filter);
if (r == -1)
return -1;

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -103,7 +103,8 @@ convert_lvm_output (char *out, const char *prefix)
char **
do_pvs (void)
{
char *out, *err;
char *out;
CLEANUP_FREE char *err = NULL;
int r;
r = command (&out, &err,
@@ -111,19 +112,17 @@ do_pvs (void)
if (r == -1) {
reply_with_error ("%s", err);
free (out);
free (err);
return NULL;
}
free (err);
return convert_lvm_output (out, NULL);
}
char **
do_vgs (void)
{
char *out, *err;
char *out;
CLEANUP_FREE char *err = NULL;
int r;
r = command (&out, &err,
@@ -131,19 +130,17 @@ do_vgs (void)
if (r == -1) {
reply_with_error ("%s", err);
free (out);
free (err);
return NULL;
}
free (err);
return convert_lvm_output (out, NULL);
}
char **
do_lvs (void)
{
char *out, *err;
char *out;
CLEANUP_FREE char *err = NULL;
int r;
r = command (&out, &err,
@@ -153,12 +150,9 @@ do_lvs (void)
if (r == -1) {
reply_with_error ("%s", err);
free (out);
free (err);
return NULL;
}
free (err);
return convert_lvm_output (out, "/dev/");
}
@@ -187,19 +181,16 @@ do_lvs_full (void)
int
do_pvcreate (const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
str_lvm, "pvcreate", device, NULL);
str_lvm, "pvcreate", "--force", device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -208,9 +199,9 @@ do_pvcreate (const char *device)
int
do_vgcreate (const char *volgroup, char *const *physvols)
{
char *err;
int r, argc, i;
const char **argv;
CLEANUP_FREE char *err = NULL;
CLEANUP_FREE const char **argv = NULL;
argc = count_strings (physvols) + 3;
argv = malloc (sizeof (char *) * (argc + 1));
@@ -227,14 +218,9 @@ do_vgcreate (const char *volgroup, char *const *physvols)
r = commandv (NULL, &err, (const char * const*) argv);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
free (argv);
return -1;
}
free (err);
free (argv);
udev_settle ();
return 0;
@@ -243,7 +229,7 @@ do_vgcreate (const char *volgroup, char *const *physvols)
int
do_lvcreate (const char *logvol, const char *volgroup, int mbytes)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
char size[64];
@@ -254,12 +240,9 @@ do_lvcreate (const char *logvol, const char *volgroup, int mbytes)
"-L", size, "-n", logvol, volgroup, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -268,7 +251,7 @@ do_lvcreate (const char *logvol, const char *volgroup, int mbytes)
int
do_lvcreate_free (const char *logvol, const char *volgroup, int percent)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
if (percent < 0 || percent > 100) {
@@ -284,12 +267,9 @@ do_lvcreate_free (const char *logvol, const char *volgroup, int percent)
"-l", size, "-n", logvol, volgroup, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -309,7 +289,7 @@ ignore_same_size_error (const char *err)
int
do_lvresize (const char *logvol, int mbytes)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
char size[64];
@@ -321,19 +301,17 @@ do_lvresize (const char *logvol, int mbytes)
if (r == -1) {
if (!ignore_same_size_error (err)) {
reply_with_error ("%s", err);
free (err);
return -1;
}
}
free (err);
return 0;
}
int
do_lvresize_free (const char *logvol, int percent)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
if (percent < 0 || percent > 100) {
@@ -349,12 +327,10 @@ do_lvresize_free (const char *logvol, int percent)
if (r == -1) {
if (!ignore_same_size_error (err)) {
reply_with_error ("%s", err);
free (err);
return -1;
}
}
free (err);
return 0;
}
@@ -364,71 +340,66 @@ do_lvresize_free (const char *logvol, int percent)
int
do_lvm_remove_all (void)
{
char **xs;
size_t i;
int r;
char *err;
/* Remove LVs. */
xs = do_lvs ();
if (xs == NULL)
return -1;
for (i = 0; xs[i] != NULL; ++i) {
/* Deactivate the LV first. On Ubuntu, lvremove '-f' option
* does not remove active LVs reliably.
*/
(void) command (NULL, NULL, str_lvm, "lvchange", "-an", xs[i], NULL);
udev_settle ();
r = command (NULL, &err, str_lvm, "lvremove", "-f", xs[i], NULL);
if (r == -1) {
reply_with_error ("lvremove: %s: %s", xs[i], err);
free (err);
free_strings (xs);
{
/* Remove LVs. */
CLEANUP_FREE char *err = NULL;
CLEANUP_FREE_STRING_LIST char **xs = do_lvs ();
if (xs == NULL)
return -1;
for (i = 0; xs[i] != NULL; ++i) {
/* Deactivate the LV first. On Ubuntu, lvremove '-f' option
* does not remove active LVs reliably.
*/
(void) command (NULL, NULL, str_lvm, "lvchange", "-an", xs[i], NULL);
udev_settle ();
r = command (NULL, &err, str_lvm, "lvremove", "-f", xs[i], NULL);
if (r == -1) {
reply_with_error ("lvremove: %s: %s", xs[i], err);
return -1;
}
}
free (err);
}
free_strings (xs);
/* Remove VGs. */
xs = do_vgs ();
if (xs == NULL)
return -1;
for (i = 0; xs[i] != NULL; ++i) {
/* Deactivate the VG first, see note above. */
(void) command (NULL, NULL, str_lvm, "vgchange", "-an", xs[i], NULL);
udev_settle ();
r = command (NULL, &err, str_lvm, "vgremove", "-f", xs[i], NULL);
if (r == -1) {
reply_with_error ("vgremove: %s: %s", xs[i], err);
free (err);
free_strings (xs);
{
/* Remove VGs. */
CLEANUP_FREE char *err = NULL;
CLEANUP_FREE_STRING_LIST char **xs = do_vgs ();
if (xs == NULL)
return -1;
}
free (err);
}
free_strings (xs);
for (i = 0; xs[i] != NULL; ++i) {
/* Deactivate the VG first, see note above. */
(void) command (NULL, NULL, str_lvm, "vgchange", "-an", xs[i], NULL);
udev_settle ();
r = command (NULL, &err, str_lvm, "vgremove", "-f", xs[i], NULL);
if (r == -1) {
reply_with_error ("vgremove: %s: %s", xs[i], err);
return -1;
}
}
}
{
/* Remove PVs. */
xs = do_pvs ();
if (xs == NULL)
return -1;
for (i = 0; xs[i] != NULL; ++i) {
r = command (NULL, &err, str_lvm, "pvremove", "-f", xs[i], NULL);
if (r == -1) {
reply_with_error ("pvremove: %s: %s", xs[i], err);
free (err);
free_strings (xs);
CLEANUP_FREE char *err = NULL;
CLEANUP_FREE_STRING_LIST char **xs = do_pvs ();
if (xs == NULL)
return -1;
for (i = 0; xs[i] != NULL; ++i) {
r = command (NULL, &err, str_lvm, "pvremove", "-f", xs[i], NULL);
if (r == -1) {
reply_with_error ("pvremove: %s: %s", xs[i], err);
return -1;
}
}
free (err);
}
free_strings (xs);
udev_settle ();
@@ -439,19 +410,16 @@ do_lvm_remove_all (void)
int
do_lvremove (const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
str_lvm, "lvremove", "-f", device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -460,19 +428,16 @@ do_lvremove (const char *device)
int
do_vgremove (const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
str_lvm, "vgremove", "-f", device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -481,19 +446,16 @@ do_vgremove (const char *device)
int
do_pvremove (const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
str_lvm, "pvremove", "-ff", device, NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -502,25 +464,23 @@ do_pvremove (const char *device)
int
do_pvresize (const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
str_lvm, "pvresize", device, NULL);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_pvresize_size (const char *device, int64_t size)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
char buf[32];
@@ -532,20 +492,18 @@ do_pvresize_size (const char *device, int64_t size)
device, NULL);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
free (err);
return -1;
}
free (err);
return 0;
}
int
do_vg_activate (int activate, char *const *volgroups)
{
char *err;
int r, i, argc;
const char **argv;
CLEANUP_FREE char *err = NULL;
CLEANUP_FREE const char **argv = NULL;
argc = count_strings (volgroups) + 4;
argv = malloc (sizeof (char *) * (argc+1));
@@ -564,14 +522,9 @@ do_vg_activate (int activate, char *const *volgroups)
r = commandv (NULL, &err, (const char * const*) argv);
if (r == -1) {
reply_with_error ("vgchange: %s", err);
free (err);
free (argv);
return -1;
}
free (err);
free (argv);
udev_settle ();
return 0;
@@ -587,7 +540,7 @@ do_vg_activate_all (int activate)
int
do_lvrename (const char *logvol, const char *newlogvol)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
@@ -595,12 +548,9 @@ do_lvrename (const char *logvol, const char *newlogvol)
logvol, newlogvol, NULL);
if (r == -1) {
reply_with_error ("%s -> %s: %s", logvol, newlogvol, err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -609,7 +559,7 @@ do_lvrename (const char *logvol, const char *newlogvol)
int
do_vgrename (const char *volgroup, const char *newvolgroup)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
@@ -617,12 +567,9 @@ do_vgrename (const char *volgroup, const char *newvolgroup)
volgroup, newvolgroup, NULL);
if (r == -1) {
reply_with_error ("%s -> %s: %s", volgroup, newvolgroup, err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -632,7 +579,7 @@ static char *
get_lvm_field (const char *cmd, const char *field, const char *device)
{
char *out;
char *err;
CLEANUP_FREE char *err = NULL;
int r = command (&out, &err,
str_lvm, cmd,
"--unbuffered", "--noheadings", "-o", field,
@@ -640,12 +587,9 @@ get_lvm_field (const char *cmd, const char *field, const char *device)
if (r == -1) {
reply_with_error ("%s: %s", device, err);
free (out);
free (err);
return NULL;
}
free (err);
trim (out);
return out; /* Caller frees. */
}
@@ -671,23 +615,18 @@ do_lvuuid (const char *device)
static char **
get_lvm_fields (const char *cmd, const char *field, const char *device)
{
char *out;
char *err;
CLEANUP_FREE char *out = NULL, *err = NULL;
int r = command (&out, &err,
str_lvm, cmd,
"--unbuffered", "--noheadings", "-o", field,
device, NULL);
if (r == -1) {
reply_with_error ("%s: %s", device, err);
free (out);
free (err);
return NULL;
}
free (err);
char **ret = split_lines (out);
free (out);
if (ret == NULL)
return NULL;
@@ -714,18 +653,16 @@ do_vglvuuids (const char *vgname)
int
do_vgscan (void)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
str_lvm, "vgscan", NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -760,7 +697,7 @@ lv_canonical (const char *device, char **ret)
return -1;
}
char **lvs = do_lvs ();
CLEANUP_FREE_STRING_LIST char **lvs = do_lvs ();
if (lvs == NULL)
return -1;
@@ -769,7 +706,6 @@ lv_canonical (const char *device, char **ret)
r = stat (lvs[i], &stat2);
if (r == -1) {
reply_with_perror ("stat: %s", lvs[i]);
free_strings (lvs);
return -1;
}
if (stat1.st_rdev == stat2.st_rdev) { /* found it */
@@ -777,17 +713,14 @@ lv_canonical (const char *device, char **ret)
*ret = strdup (lvs[i]);
if (*ret == NULL) {
reply_with_perror ("strdup");
free_strings (lvs);
return -1;
}
}
free_strings (lvs);
return 1;
}
}
/* not found */
free_strings (lvs);
return 0;
}
@@ -894,7 +827,7 @@ do_list_dm_devices (void)
char *
do_vgmeta (const char *vg, size_t *size_r)
{
char *err;
CLEANUP_FREE char *err = NULL;
int fd, r;
char tmp[] = "/tmp/vgmetaXXXXXX";
size_t alloc, size, max;
@@ -913,10 +846,8 @@ do_vgmeta (const char *vg, size_t *size_r)
r = command (NULL, &err, str_lvm, "vgcfgbackup", "-f", tmp, vg, NULL);
if (r == -1) {
reply_with_error ("vgcfgbackup: %s", err);
free (err);
return NULL;
}
free (err);
/* Now read back the temporary file. */
fd = open (tmp, O_RDONLY|O_CLOEXEC);
@@ -981,19 +912,16 @@ do_vgmeta (const char *vg, size_t *size_r)
int
do_pvchange_uuid (const char *device)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
str_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;
@@ -1002,19 +930,16 @@ do_pvchange_uuid (const char *device)
int
do_pvchange_uuid_all (void)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
str_lvm, "pvchange", "-u", "-a", NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -1023,19 +948,16 @@ do_pvchange_uuid_all (void)
int
do_vgchange_uuid (const char *vg)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
str_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;
@@ -1044,19 +966,16 @@ do_vgchange_uuid (const char *vg)
int
do_vgchange_uuid_all (void)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r;
r = command (NULL, &err,
str_lvm, "vgchange", "-u", NULL);
if (r == -1) {
reply_with_error ("%s", err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;

View File

@@ -61,7 +61,7 @@ do_md_create (const char *name, char *const *devices,
char chunk_s[32];
size_t j;
int r;
char *err;
CLEANUP_FREE char *err = NULL;
uint64_t umissingbitmap = (uint64_t) missingbitmap;
/* Check the optional parameters and set defaults where appropriate. */
@@ -161,12 +161,9 @@ do_md_create (const char *name, char *const *devices,
r = commandv (NULL, &err, argv);
if (r == -1) {
reply_with_error ("mdadm: %s: %s", name, err);
free (err);
return -1;
}
free (err);
udev_settle ();
return 0;
@@ -241,8 +238,8 @@ do_md_detail(const char *md)
size_t i;
int r;
char *out = NULL, *err = NULL;
char **lines = NULL;
CLEANUP_FREE char *out = NULL, *err = NULL;
CLEANUP_FREE_STRING_LIST char **lines = NULL;
DECLARE_STRINGSBUF (ret);
@@ -295,20 +292,12 @@ do_md_detail(const char *md)
}
}
free (out);
free (err);
free_strings (lines);
if (end_stringsbuf (&ret) == -1)
return NULL;
return ret.argv;
error:
free (out);
free (err);
if (lines)
free_strings (lines);
if (ret.argv != NULL)
free_stringslen (ret.argv, ret.size);
@@ -319,16 +308,14 @@ int
do_md_stop(const char *md)
{
int r;
char *err = NULL;
CLEANUP_FREE char *err = NULL;
const char *mdadm[] = { str_mdadm, "--stop", md, NULL};
r = commandv(NULL, &err, mdadm);
if (r == -1) {
reply_with_error("%s", err);
free(err);
return -1;
}
free (err);
return 0;
}
@@ -454,8 +441,8 @@ do_md_stat (const char *md)
{
size_t mdlen;
FILE *fp;
char *line = NULL;
size_t len = 0;
CLEANUP_FREE char *line = NULL;
size_t allocsize = 0;
ssize_t n;
guestfs_int_mdstat_list *ret = NULL;
@@ -470,13 +457,12 @@ do_md_stat (const char *md)
}
/* Search for a line which begins with "<md> : ". */
while ((n = getline (&line, &len, fp)) != -1) {
while ((n = getline (&line, &allocsize, fp)) != -1) {
if (STRPREFIX (line, md) &&
line[mdlen] == ' ' && line[mdlen+1] == ':' && line[mdlen+2] == ' ') {
/* Found it. */
ret = parse_md_stat_line (&line[mdlen+3]);
if (!ret) {
free (line);
fclose (fp);
return NULL;
}
@@ -488,10 +474,9 @@ do_md_stat (const char *md)
}
}
free (line);
if (fclose (fp) == EOF) {
reply_with_perror ("fclose: %s", "/proc/mdstat");
xdr_free ((xdrproc_t) xdr_guestfs_int_mdstat_list, (char *) ret);
return NULL;
}

View File

@@ -1,5 +1,5 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009-2012 Red Hat Inc.
* Copyright (C) 2009-2013 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
@@ -44,7 +44,7 @@ do_mkfs (const char *fstype, const char *device, int blocksize,
char inode_str[32];
char sectorsize_str[32];
int r;
char *err;
CLEANUP_FREE char *err = NULL;
int extfs = 0;
if (STREQ (fstype, "ext2") || STREQ (fstype, "ext3") ||
@@ -184,14 +184,14 @@ do_mkfs (const char *fstype, const char *device, int blocksize,
ADD_ARG (argv, i, device);
ADD_ARG (argv, i, NULL);
wipe_device_before_mkfs (device);
r = commandv (NULL, &err, argv);
if (r == -1) {
reply_with_error ("%s: %s: %s", fstype, device, err);
free (err);
return -1;
}
free (err);
return 0;
}

View File

@@ -80,34 +80,6 @@ do_mknod_c (int mode, int devmajor, int devminor, const char *path)
#else
int
optgroup_mknod_available (void)
{
return 0;
}
int
do_mknod (int mode, int devmajor, int devminor, const char *path)
{
abort ();
}
int
do_mkfifo (int mode, const char *path)
{
abort ();
}
int
do_mknod_b (int mode, int devmajor, int devminor, const char *path)
{
abort ();
}
int
do_mknod_c (int mode, int devmajor, int devminor, const char *path)
{
abort ();
}
OPTGROUP_MKNOD_NOT_AVAILABLE
#endif

View File

@@ -36,14 +36,13 @@ optgroup_linuxmodules_available (void)
int
do_modprobe (const char *module)
{
char *err;
CLEANUP_FREE char *err = NULL;
int r = command (NULL, &err, str_modprobe, module, NULL);
if (r == -1) {
reply_with_error ("%s", err);
return -1;
}
free (err);
return r;
}

View File

@@ -50,7 +50,7 @@ is_root_mounted (void)
*/
fp = setmntent ("/proc/mounts", "r");
if (fp == NULL) {
perror ("/proc/mounts");
fprintf (stderr, "setmntent: %s: %m\n", "/proc/mounts");
exit (EXIT_FAILURE);
}
@@ -92,7 +92,7 @@ is_device_mounted (const char *device)
*/
fp = setmntent ("/proc/mounts", "r");
if (fp == NULL) {
perror ("/proc/mounts");
fprintf (stderr, "setmntent: %s: %m\n", "/proc/mounts");
exit (EXIT_FAILURE);
}
@@ -124,11 +124,9 @@ is_device_mounted (const char *device)
int
do_mount_vfs (const char *options, const char *vfstype,
const char *device, const char *mountpoint)
const mountable_t *mountable, const char *mountpoint)
{
int r;
char *mp;
char *error;
CLEANUP_FREE char *mp = NULL;
struct stat statbuf;
ABS_PATH (mountpoint, , return -1);
@@ -142,50 +140,77 @@ do_mount_vfs (const char *options, const char *vfstype,
/* Check the mountpoint exists and is a directory. */
if (stat (mp, &statbuf) == -1) {
reply_with_perror ("mount: %s", mountpoint);
free (mp);
return -1;
}
if (!S_ISDIR (statbuf.st_mode)) {
reply_with_perror ("mount: %s: mount point is not a directory", mountpoint);
free (mp);
return -1;
}
return mount_vfs_nochroot (options, vfstype, mountable, mp, mountpoint);
}
int
mount_vfs_nochroot (const char *options, const char *vfstype,
const mountable_t *mountable,
const char *mp, const char *user_mp)
{
CLEANUP_FREE char *options_plus = NULL;
const char *device = mountable->device;
if (mountable->type == MOUNTABLE_BTRFSVOL) {
if (options && strlen (options) > 0) {
if (asprintf (&options_plus, "subvol=%s,%s",
mountable->volume, options) == -1)
{
reply_with_perror ("asprintf");
return -1;
}
}
else {
if (asprintf (&options_plus, "subvol=%s", mountable->volume) == -1) {
reply_with_perror ("asprintf");
return -1;
}
}
}
CLEANUP_FREE char *error = NULL;
int r;
if (vfstype)
r = command (NULL, &error,
str_mount, "-o", options, "-t", vfstype, device, mp, NULL);
str_mount, "-o", options_plus ? options_plus : options,
"-t", vfstype, device, mp, NULL);
else
r = command (NULL, &error,
str_mount, "-o", options, device, mp, NULL);
free (mp);
str_mount, "-o", options_plus ? options_plus : options,
device, mp, NULL);
if (r == -1) {
reply_with_error ("%s on %s (options: '%s'): %s",
device, mountpoint, options, error);
free (error);
device, user_mp, options, error);
return -1;
}
free (error);
return 0;
}
int
do_mount (const char *device, const char *mountpoint)
do_mount (const mountable_t *mountable, const char *mountpoint)
{
return do_mount_vfs ("", NULL, device, mountpoint);
return do_mount_vfs ("", NULL, mountable, mountpoint);
}
int
do_mount_ro (const char *device, const char *mountpoint)
do_mount_ro (const mountable_t *mountable, const char *mountpoint)
{
return do_mount_vfs ("ro", NULL, device, mountpoint);
return do_mount_vfs ("ro", NULL, mountable, mountpoint);
}
int
do_mount_options (const char *options, const char *device,
do_mount_options (const char *options, const mountable_t *mountable,
const char *mountpoint)
{
return do_mount_vfs (options, NULL, device, mountpoint);
return do_mount_vfs (options, NULL, mountable, mountpoint);
}
/* Takes optional arguments, consult optargs_bitmask. */
@@ -194,8 +219,8 @@ do_umount (const char *pathordevice,
int force, int lazyunmount)
{
int r;
char *err;
char *buf;
CLEANUP_FREE char *err = NULL;
CLEANUP_FREE char *buf = NULL;
int is_dev;
const char *argv[MAX_ARGS];
size_t i = 0;
@@ -227,16 +252,12 @@ do_umount (const char *pathordevice,
ADD_ARG (argv, i, NULL);
r = commandv (NULL, &err, argv);
free (buf);
if (r == -1) {
reply_with_error ("%s: %s", pathordevice, err);
free (err);
return -1;
}
free (err);
return 0;
}
@@ -255,7 +276,7 @@ mounts_or_mountpoints (int mp)
*/
fp = setmntent ("/proc/mounts", "r");
if (fp == NULL) {
perror ("/proc/mounts");
fprintf (stderr, "setmntent: %s: %m\n", "/proc/mounts");
exit (EXIT_FAILURE);
}
@@ -348,7 +369,7 @@ do_umount_all (void)
FILE *fp;
struct mntent *m;
DECLARE_STRINGSBUF (mounts);
char *err;
CLEANUP_FREE char *err = NULL;
size_t i;
int r;
@@ -357,7 +378,7 @@ do_umount_all (void)
*/
fp = setmntent ("/proc/mounts", "r");
if (fp == NULL) {
perror ("/proc/mounts");
fprintf (stderr, "setmntent: %s: %m\n", "/proc/mounts");
exit (EXIT_FAILURE);
}
@@ -388,11 +409,9 @@ do_umount_all (void)
r = command (NULL, &err, str_umount, mounts.argv[i], NULL);
if (r == -1) {
reply_with_error ("umount: %s: %s", mounts.argv[i], err);
free (err);
free_stringslen (mounts.argv, mounts.size);
return -1;
}
free (err);
}
free_stringslen (mounts.argv, mounts.size);
@@ -408,8 +427,7 @@ int
do_mount_loop (const char *file, const char *mountpoint)
{
int r;
char *buf, *mp;
char *error;
CLEANUP_FREE char *buf = NULL, *mp = NULL, *error = NULL;
/* We have to prefix /sysroot on both the filename and the mountpoint. */
mp = sysroot_path (mountpoint);
@@ -421,20 +439,15 @@ do_mount_loop (const char *file, const char *mountpoint)
buf = sysroot_path (file);
if (!buf) {
reply_with_perror ("malloc");
free (mp);
return -1;
}
r = command (NULL, &error, str_mount, "-o", "loop", buf, mp, NULL);
free (mp);
free (buf);
if (r == -1) {
reply_with_error ("%s on %s: %s", file, mountpoint, error);
free (error);
return -1;
}
free (error);
return 0;
}

64
daemon/mountable.c Normal file
View File

@@ -0,0 +1,64 @@
/* libguestfs - the guestfsd daemon
* Copyright (C) 2009 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 "daemon.h"
#include "actions.h"
#include "guestfs_protocol.h"
guestfs_int_internal_mountable *
do_internal_parse_mountable (const mountable_t *mountable)
{
guestfs_int_internal_mountable *ret = calloc (1, sizeof *ret);
if (ret == NULL) {
reply_with_perror ("calloc");
return NULL;
}
ret->im_type = mountable->type;
if (mountable->device)
ret->im_device = strdup (mountable->device);
else
ret->im_device = strdup ("");
if (!ret->im_device) {
reply_with_perror ("strdup");
free (ret);
return NULL;
}
if (mountable->volume)
ret->im_volume = strdup (mountable->volume);
else
ret->im_volume = strdup ("");
if (!ret->im_volume) {
reply_with_perror ("strdup");
free (ret->im_device);
free (ret);
return NULL;
}
return ret;
}

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