libguestfs and exporting to OVA/OVF
by Emmanuel Kasper
Hi
I've been looking for a standalone tool to create OVA/OVF VM files based
on a disk image and found none. So I was thinking to write my own.
Would you be interested in having such a tool in the libguestfs umbrella ?
My aim is too have a free toolchain to build VirtualBox images for
Debian (for Vagrant to be more exact, see
https://wiki.debian.org/Teams/Cloud/VagrantBaseBoxes)
Interface for such a tool would be something like
disk2ova --memory 2G --controller sata --network E1000
myDiskImage.{raw,qcow2}
based on the command line switches, a XML ovf would be created and
packed with the disk image in a OVA file.
There is some python code around which does that, for example the ganeti
export code and imagefactory
https://github.com/redhat-imaging/imagefactory/blob/master/imagefactory_p...
but nothing available as a standalone tool.
I am afraid I can only contribute Perl code.
Emmanuel
7 years, 9 months
[PATCH] appliance: move virt-rescue welcome to /etc/issue
by Cédric Bosdonnat
To allow easier downstream tweaks to the virt-rescue welcome message,
just output the content of the /etc/issue file in the appliance.
Thus, a new extras.tar.gz file appeared in supermin.d containing
the etc/issue file and future tweaks like this one.
---
appliance/Makefile.am | 11 +++++++++++
appliance/init | 11 ++---------
appliance/issue | 9 +++++++++
3 files changed, 22 insertions(+), 9 deletions(-)
create mode 100644 appliance/issue
diff --git a/appliance/Makefile.am b/appliance/Makefile.am
index e23778e..f26c4d4 100644
--- a/appliance/Makefile.am
+++ b/appliance/Makefile.am
@@ -36,6 +36,7 @@ EXTRA_DIST = \
guestfs_shadow.aug \
hostfiles.in \
init \
+ issue \
libguestfs-make-fixed-appliance.in \
libguestfs-make-fixed-appliance.pod \
make.sh.in \
@@ -49,6 +50,7 @@ superminfs_DATA = \
supermin.d/base.tar.gz \
supermin.d/daemon.tar.gz \
supermin.d/excludefiles \
+ supermin.d/extras.tar.gz \
supermin.d/hostfiles \
supermin.d/init.tar.gz \
supermin.d/packages \
@@ -107,6 +109,15 @@ supermin.d/excludefiles: excludefiles.in Makefile
cmp -s $@ excludefiles-t || mv excludefiles-t $@
rm -f excludefiles-t
+supermin.d/extras.tar.gz: issue
+ rm -f $@ $@-t
+ rm -rf tmp-d
+ mkdir -p tmp-d/etc
+ cp issue tmp-d/etc
+ ( cd tmp-d && tar zcf - * ) > $@-t
+ rm -r tmp-d
+ mv $@-t $@
+
supermin.d/hostfiles: hostfiles.in Makefile
m4 $(PACKAGELIST_CPP_FLAGS) $< | \
grep -v '^[[:space:]]*$$' | grep -v '^#' > hostfiles-t
diff --git a/appliance/init b/appliance/init
index 3816dfd..e549df0 100755
--- a/appliance/init
+++ b/appliance/init
@@ -184,15 +184,8 @@ else
echo "PS1='><rescue> '" >> $HOME/.bashrc
echo "export TERM PS1" >> $HOME/.bashrc
- echo
- echo "------------------------------------------------------------"
- echo
- echo "Welcome to virt-rescue, the libguestfs rescue shell."
- echo
- echo "Note: The contents of / are the rescue appliance."
- echo "You have to mount the guest's partitions under /sysroot"
- echo "before you can examine them."
- echo
+ cat /etc/issue
+
bash -i
echo
echo "virt-rescue: Syncing the disk now before exiting ..."
diff --git a/appliance/issue b/appliance/issue
new file mode 100644
index 0000000..40b8e17
--- /dev/null
+++ b/appliance/issue
@@ -0,0 +1,9 @@
+
+------------------------------------------------------------
+
+Welcome to virt-rescue, the libguestfs rescue shell.
+
+Note: The contents of / are the rescue appliance.
+You have to mount the guest's partitions under /sysroot
+before you can examine them.
+
--
2.6.6
7 years, 9 months
[PATCH] v2v: bootloaders: search grub config for all distributions
by Pavel Butsykin
This patch improves the search of grub config on EFI partition. This means that
the config will be found not only for rhel but also for many other distributions.
Tests were performed on the following distributions: centos, fedora, ubuntu,
suse. In all cases, the config path was /boot/efi/EFI/*distname*/grub.cfg
The main purpose of the patch is to improve support for converting of vm with
UEFI for most distributions. Unfortunately this patch does not solve the problem
for all distributions, for example Debian does not store grub config on the EFI
partition, therefore for such distributions another solution is necessary.
Signed-off-by: Pavel Butsykin <pbutsykin(a)virtuozzo.com>
---
v2v/linux_bootloaders.ml | 56 +++++++++++++++++++++++++++++-------------------
1 file changed, 34 insertions(+), 22 deletions(-)
diff --git a/v2v/linux_bootloaders.ml b/v2v/linux_bootloaders.ml
index e03d22b..210c273 100644
--- a/v2v/linux_bootloaders.ml
+++ b/v2v/linux_bootloaders.ml
@@ -335,32 +335,44 @@ end
let detect_bootloader (g : G.guestfs) inspect =
let config_file, typ =
- let locations = [
- "/boot/grub2/grub.cfg", Grub2;
- "/boot/grub/grub.cfg", Grub2;
- "/boot/grub/menu.lst", Grub1;
- "/boot/grub/grub.conf", Grub1;
+ let grub_configs = [
+ "grub.cfg", Grub2;
+ "grub.conf", Grub1;
+ "menu.lst", Grub1;
] in
- let locations =
+
+ let boot_location =
match inspect.i_firmware with
- | I_UEFI _ ->
- [
- "/boot/efi/EFI/redhat/grub.cfg", Grub2;
- "/boot/efi/EFI/redhat/grub.conf", Grub1;
- ] @ locations
- | I_BIOS -> locations in
- try
- List.find (
- fun (config_file, _) -> g#is_file ~followsymlinks:true config_file
- ) locations
- with
- Not_found ->
- error (f_"no bootloader detected") in
+ | I_BIOS -> "/boot/"
+ | I_UEFI _ -> "/boot/efi/EFI/"
+ in
+
+ let rec find_grub dirs configs =
+ let rec config_check dir configs =
+ match configs with
+ | [] -> None
+ | (config, typ) :: configs ->
+ let cfg_path = boot_location ^ dir ^ "/" ^ config in
+ if g#is_file ~followsymlinks:true cfg_path then (
+ Some (cfg_path, typ)
+ ) else config_check dir configs;
+ in
+ match dirs with
+ | [] -> error (f_"no bootloader detected")
+ | dir :: dirs ->
+ let res = config_check dir configs in
+ match res with
+ | None -> find_grub dirs configs
+ | Some (cfg_path, typ) -> cfg_path, typ
+ in
+
+ find_grub (Array.to_list (g#ls boot_location)) grub_configs in
match typ with
| Grub1 ->
- if config_file = "/boot/efi/EFI/redhat/grub.conf" then
- g#aug_transform "grub" "/boot/efi/EFI/redhat/grub.conf";
-
+ (match inspect.i_firmware with
+ | I_BIOS -> ()
+ | I_UEFI _ -> g#aug_transform "grub" config_file
+ );
new bootloader_grub1 g inspect config_file
| Grub2 -> new bootloader_grub2 g config_file
--
2.8.3
7 years, 10 months
[PATCH 0/4] supermin: use dnf on Mageia
by Pino Toscano
Hi,
as pointed out by Neal Gompa, Mageia recently introduced dnf in the
distribution (currently only in Cauldron, which is the future Mageia 6),
and most probably it will replace urpmi in the future.
As such, on Mageia make supermin prefer dnf over urpmi when found,
using the same code already used for Fedora.
Related change: make test-harder.sh work explicitly also on Mageia
("broken" since the recent switch to /etc/os-release).
Thanks,
Pino Toscano (4):
tests: add Mageia checks in test-harder
rpm: move fedora_download_all_packages_with_dnf around
rpm: isolate actual mageia download in own function
rpm: mageia: prefer dnf over urpmi
README | 3 +--
src/rpm.ml | 49 +++++++++++++++++++++++++++----------------------
tests/test-harder.sh | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 62 insertions(+), 24 deletions(-)
--
2.7.4
7 years, 10 months
Memory corruption when testing nbdkit python plugin with nbd-tester-client?
by Carl-Daniel Hailfinger
Hi,
has anyone ever run "make check" from nbd against nbdkit with a python
plugin? I usually get segfaults during such a run, and sometimes various
other errors happen before the segfault, suggesting that some memory
corruption is underway.
AFAICS a pure python plugin should not be able to cause memory corruption.
Examples of nbdkit logs for running "make check" or subsets of it from
nbd against nbdkit:
nbdkit -n -f python script=ssd-ftl-wearleveling.py disksize=52428800
nbdkit: python[6]: error: ssd-ftl-wearleveling.py: callback failed: close
nbdkit: python[7]: error: invalid flush request: expecting offset and
length == 0
nbdkit: python[7]: error: write reply: Connection reset by peer
Segmentation fault
nbdkit -n -f python script=ssd-ftl-wearleveling.py disksize=52428800
Fatal Python error: GC object already tracked
Segmentation fault
nbdkit -n -f python script=ssd-ftl-wearleveling.py disksize=52428800
Segmentation fault
nbdkit -n -f python script=ssd-ftl-wearleveling.py disksize=52428800
nbdkit: python[1]: error: invalid flush request: expecting offset and
length == 0
nbdkit: python[1]: error: write reply: Broken pipe
nbdkit: python[3]: error: client sent NBD_OPT_ABORT to abort the connection
nbdkit: python[6]: error: ssd-ftl-wearleveling.py: callback failed: close
Traceback (most recent call last):
File "ssd-ftl-wearleveling.py", line 221, in close
pickle.dump(lbahist, f)
File "/usr/lib/python2.7/pickle.py", line 1370, in dump
Segmentation fault (core dumped)
My close function just dumps the disk image and write access history
with python pickle. It does not have any return statement, and because
of that I seriously doubt that said close function can fail.
I'm now trying to replicate this with example.py. Will report back.
Regards,
Carl-Daniel
7 years, 10 months
[PATCH] handle: Improve error messaging if XDG_RUNTIME_DIR path does not exist.
by Richard W.M. Jones
If an environment variable such as XDG_RUNTIME_DIR or one of the
tmpdirs or cachedir is set to a non-existent directory, improve the
error message that the user will see so that (where possible) it
includes the environment variable or API call.
This is still not bullet-proof because it's hard to display the
environment variable if it is LIBGUESTFS_TMPDIR or
LIBGUESTFS_CACHEDIR, but the main problem is with XDG_RUNTIME_DIR
(because of systemd bugs).
Thanks: Hilko Bengen for identifying the bug.
---
src/guestfs-internal.h | 4 ++--
src/handle.c | 4 ++--
src/tmpdirs.c | 30 ++++++++++++++++++++----------
3 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 2261f49..f2f2a97 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -803,8 +803,8 @@ extern void guestfs_int_call_callbacks_message (guestfs_h *g, uint64_t event, co
extern void guestfs_int_call_callbacks_array (guestfs_h *g, uint64_t event, const uint64_t *array, size_t array_len);
/* tmpdirs.c */
-extern int guestfs_int_set_env_tmpdir (guestfs_h *g, const char *tmpdir);
-extern int guestfs_int_set_env_runtimedir (guestfs_h *g, const char *runtimedir);
+extern int guestfs_int_set_env_tmpdir (guestfs_h *g, const char *envname, const char *tmpdir);
+extern int guestfs_int_set_env_runtimedir (guestfs_h *g, const char *envname, const char *runtimedir);
extern int guestfs_int_lazy_make_tmpdir (guestfs_h *g);
extern int guestfs_int_lazy_make_sockdir (guestfs_h *g);
extern char *guestfs_int_lazy_make_supermin_appliance_dir (guestfs_h *g);
diff --git a/src/handle.c b/src/handle.c
index b28a1e0..0796015 100644
--- a/src/handle.c
+++ b/src/handle.c
@@ -218,7 +218,7 @@ parse_environment (guestfs_h *g,
}
str = do_getenv (data, "TMPDIR");
- if (guestfs_int_set_env_tmpdir (g, str) == -1)
+ if (guestfs_int_set_env_tmpdir (g, "TMPDIR", str) == -1)
return -1;
str = do_getenv (data, "LIBGUESTFS_PATH");
@@ -277,7 +277,7 @@ parse_environment (guestfs_h *g,
}
str = do_getenv (data, "XDG_RUNTIME_DIR");
- if (guestfs_int_set_env_runtimedir (g, str) == -1)
+ if (guestfs_int_set_env_runtimedir (g, "XDG_RUNTIME_DIR", str) == -1)
return -1;
return 0;
diff --git a/src/tmpdirs.c b/src/tmpdirs.c
index 6c8fe0d..725f683 100644
--- a/src/tmpdirs.c
+++ b/src/tmpdirs.c
@@ -39,9 +39,14 @@
* We need to make all tmpdir paths absolute because lots of places in
* the code assume this. Do it at the time we set the path or read
* the environment variable (L<https://bugzilla.redhat.com/882417>).
+ *
+ * The C<ctxstr> parameter is a string displayed in error messages
+ * giving the context of the operation (eg. name of environment
+ * variable being used, or API function being called).
*/
static int
-set_abs_path (guestfs_h *g, const char *tmpdir, char **tmpdir_ret)
+set_abs_path (guestfs_h *g, const char *ctxstr,
+ const char *tmpdir, char **tmpdir_ret)
{
char *ret;
struct stat statbuf;
@@ -57,17 +62,20 @@ set_abs_path (guestfs_h *g, const char *tmpdir, char **tmpdir_ret)
ret = realpath (tmpdir, NULL);
if (ret == NULL) {
- perrorf (g, _("failed to set temporary directory: %s"), tmpdir);
+ perrorf (g, _("converting path to absolute path: %s: %s: realpath"),
+ ctxstr, tmpdir);
return -1;
}
if (stat (ret, &statbuf) == -1) {
- perrorf (g, _("failed to set temporary directory: %s"), tmpdir);
+ perrorf (g, "%s: %s: %s: stat",
+ _("setting temporary directory"), ctxstr, tmpdir);
return -1;
}
if (!S_ISDIR (statbuf.st_mode)) {
- error (g, _("temporary directory '%s' is not a directory"), tmpdir);
+ error (g, _("%s: %s: '%s' is not a directory"),
+ _("setting temporary directory"), ctxstr, tmpdir);
return -1;
}
@@ -76,21 +84,23 @@ set_abs_path (guestfs_h *g, const char *tmpdir, char **tmpdir_ret)
}
int
-guestfs_int_set_env_tmpdir (guestfs_h *g, const char *tmpdir)
+guestfs_int_set_env_tmpdir (guestfs_h *g, const char *envname,
+ const char *tmpdir)
{
- return set_abs_path (g, tmpdir, &g->env_tmpdir);
+ return set_abs_path (g, envname, tmpdir, &g->env_tmpdir);
}
int
-guestfs_int_set_env_runtimedir (guestfs_h *g, const char *runtimedir)
+guestfs_int_set_env_runtimedir (guestfs_h *g, const char *envname,
+ const char *runtimedir)
{
- return set_abs_path (g, runtimedir, &g->env_runtimedir);
+ return set_abs_path (g, envname, runtimedir, &g->env_runtimedir);
}
int
guestfs_impl_set_tmpdir (guestfs_h *g, const char *tmpdir)
{
- return set_abs_path (g, tmpdir, &g->int_tmpdir);
+ return set_abs_path (g, "set_tmpdir", tmpdir, &g->int_tmpdir);
}
/**
@@ -117,7 +127,7 @@ guestfs_impl_get_tmpdir (guestfs_h *g)
int
guestfs_impl_set_cachedir (guestfs_h *g, const char *cachedir)
{
- return set_abs_path (g, cachedir, &g->int_cachedir);
+ return set_abs_path (g, "set_cachedir", cachedir, &g->int_cachedir);
}
/**
--
2.9.3
7 years, 10 months
[PATCH] run.in: Quote contents of @VAR@ substitutions
by Hilko Bengen
---
run.in | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/run.in b/run.in
index 8fdf454..438a68c 100755
--- a/run.in
+++ b/run.in
@@ -140,15 +140,15 @@ export PERL_VALGRIND=1
export PERL_DESTRUCT_LEVEL=2
# For Python.
-export PYTHON=@PYTHON@
+export PYTHON="@PYTHON@"
prepend PYTHONPATH "$b/python/.libs"
prepend PYTHONPATH "$b/python"
prepend PYTHONPATH "$s/python"
export PYTHONPATH
# For Ruby.
-export RUBY=@RUBY@
-export RAKE=@RAKE@
+export RUBY="@RUBY@"
+export RAKE="@RAKE@"
prepend RUBYLIB "$b/ruby/ext/guestfs"
prepend RUBYLIB "$b/ruby/lib"
export RUBYLIB
@@ -160,7 +160,7 @@ prepend CAML_LD_LIBRARY_PATH "$b/ocaml"
export CAML_LD_LIBRARY_PATH
# For Java.
-export JAVA_EXE=@JAVA_EXE@
+export JAVA_EXE="@JAVA_EXE@"
prepend CLASSPATH "$b/java/libguestfs-@VERSION@.jar"
prepend CLASSPATH "$b/java/t"
prepend CLASSPATH "$b/java"
@@ -171,7 +171,7 @@ prepend ERL_LIBS "$b/erlang"
export ERL_LIBS
# For Lua.
-export LUA=@LUA@
+export LUA="@LUA@"
# Can't use 'prepend' here because Lua paths use semicolons.
if [ -z "$LUA_CPATH" ]; then
LUA_CPATH="$b/lua/?.so"
@@ -181,7 +181,7 @@ fi
export LUA_CPATH
# For golang.
-export GOLANG=@GOLANG@
+export GOLANG="@GOLANG@"
prepend GOPATH "$b/golang"
export GOPATH
if [ -z "$CGO_CFLAGS" ]; then
@@ -198,7 +198,7 @@ fi
export CGO_LDFLAGS
# For GObject, Javascript and friends.
-export GJS=@GJS@
+export GJS="@GJS@"
prepend GI_TYPELIB_PATH "$b/gobject"
export GI_TYPELIB_PATH
# Be friendly to valgrind (https://live.gnome.org/Valgrind)
--
2.10.1
7 years, 10 months
[PATCH] p2v: Inhibit power saving during the conversion.
by Richard W.M. Jones
We do this by sending an Inhibit() message to logind and receiving a
file descriptor back, which we hold open until the conversion
completes (or fails). This is described here:
https://www.freedesktop.org/wiki/Software/systemd/inhibit/
This adds an additional optional dependency on DBus since we use DBus
to call the Inhibit() method.
Reported-by: Chris Cowley.
---
docs/guestfs-building.pod | 8 +++
m4/guestfs_misc_libraries.m4 | 9 +++
p2v/Makefile.am | 5 +-
p2v/conversion.c | 10 +++
p2v/inhibit.c | 153 +++++++++++++++++++++++++++++++++++++++++++
p2v/p2v.h | 3 +
6 files changed, 187 insertions(+), 1 deletion(-)
create mode 100644 p2v/inhibit.c
diff --git a/docs/guestfs-building.pod b/docs/guestfs-building.pod
index 5c1806d..1e4a574 100644
--- a/docs/guestfs-building.pod
+++ b/docs/guestfs-building.pod
@@ -282,6 +282,14 @@ Either Gtk 2 or Gtk 3 can be used. If you want to select a specific
version of Gtk, use S<C<./configure --with-gtk=2>> or
S<C<./configure --with-gtk=3>>.
+=item DBus
+
+Optional.
+
+If the DBus C API is available, virt-p2v can send a DBus message to
+logind to inhibit power saving (sleep, suspend, etc) during P2V
+conversions.
+
=item zip
=item unzip
diff --git a/m4/guestfs_misc_libraries.m4 b/m4/guestfs_misc_libraries.m4
index fee265b..82864f9 100644
--- a/m4/guestfs_misc_libraries.m4
+++ b/m4/guestfs_misc_libraries.m4
@@ -103,6 +103,15 @@ elif test "x$with_gtk" = "xcheck"; then
])
fi
+dnl DBus is an optional dependency of virt-p2v.
+PKG_CHECK_MODULES([DBUS], [dbus-1], [
+ AC_SUBST([DBUS_CFLAGS])
+ AC_SUBST([DBUS_LIBS])
+ AC_DEFINE([HAVE_DBUS],[1],[DBus found at compile time.])
+],[
+ AC_MSG_WARN([DBus not found, virt-p2v will not be able to inhibit power saving during P2V conversions])
+])
+
dnl Can we build virt-p2v?
AC_MSG_CHECKING([if we can build virt-p2v])
if test "x$GTK_LIBS" != "x"; then
diff --git a/p2v/Makefile.am b/p2v/Makefile.am
index 1f6e601..216ab30 100644
--- a/p2v/Makefile.am
+++ b/p2v/Makefile.am
@@ -77,6 +77,7 @@ virt_p2v_SOURCES = \
config.c \
conversion.c \
gui.c \
+ inhibit.c \
kernel.c \
kernel-cmdline.c \
main.c \
@@ -97,13 +98,15 @@ virt_p2v_CFLAGS = \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
$(PCRE_CFLAGS) \
$(LIBXML2_CFLAGS) \
- $(GTK_CFLAGS)
+ $(GTK_CFLAGS) \
+ $(DBUS_CFLAGS)
virt_p2v_LDADD = \
$(top_builddir)/src/libutils.la \
$(PCRE_LIBS) \
$(LIBXML2_LIBS) \
$(GTK_LIBS) \
+ $(DBUS_LIBS) \
../gnulib/lib/libgnu.la
# Scripts to build the disk image, USB key, or kickstart.
diff --git a/p2v/conversion.c b/p2v/conversion.c
index 3be9a45..a5b6769 100644
--- a/p2v/conversion.c
+++ b/p2v/conversion.c
@@ -208,6 +208,7 @@ start_conversion (struct config *config,
char libvirt_xml_file[] = "/tmp/p2v.XXXXXX/physical.xml";
char wrapper_script[] = "/tmp/p2v.XXXXXX/virt-v2v-wrapper.sh";
char dmesg_file[] = "/tmp/p2v.XXXXXX/dmesg";
+ int inhibit_fd = -1;
#if DEBUG_STDERR
print_config (config, stderr);
@@ -218,6 +219,12 @@ start_conversion (struct config *config,
set_running (1);
set_cancel_requested (0);
+ inhibit_fd = inhibit_sleep ();
+#ifdef DEBUG_STDERR
+ if (inhibit_fd == -1)
+ fprintf (stderr, "warning: virt-p2v cannot inhibit power saving during conversion.\n");
+#endif
+
data_conns = malloc (sizeof (struct data_conn) * nr_disks);
if (data_conns == NULL)
error (EXIT_FAILURE, errno, "malloc");
@@ -426,6 +433,9 @@ start_conversion (struct config *config,
}
cleanup_data_conns (data_conns, nr_disks);
+ if (inhibit_fd >= 0)
+ close (inhibit_fd);
+
set_running (0);
return ret;
diff --git a/p2v/inhibit.c b/p2v/inhibit.c
new file mode 100644
index 0000000..b5acfd4
--- /dev/null
+++ b/p2v/inhibit.c
@@ -0,0 +1,153 @@
+/* virt-p2v
+ * Copyright (C) 2016 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 file is used to inhibit power saving, sleep, suspend etc during
+ * the conversion.
+ *
+ * The method it uses is to send a dbus message to logind, as
+ * described here:
+ *
+ * https://www.freedesktop.org/wiki/Software/systemd/inhibit/
+ *
+ * If virt-p2v is compiled with DBus support then this does nothing.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_DBUS
+#include <dbus/dbus.h>
+#endif
+
+#include "p2v.h"
+
+/**
+ * Inhibit all forms of power saving. A file descriptor is returned,
+ * and when the file descriptor is closed the inhibit is stopped.
+ *
+ * If the function returns C<-1> then C<Inhibit> operation could not
+ * be performed (eg. if we are compiled with DBus support, or there is
+ * some error contacting logind). This is not usually fatal from the
+ * point of view of the caller, conversion can continue.
+ */
+int
+inhibit_sleep (void)
+{
+#ifdef HAVE_DBUS
+ DBusError err;
+ DBusConnection *conn = NULL;
+ DBusMessage *msg = NULL;
+ DBusMessageIter args;
+ DBusPendingCall *pending = NULL;
+ const char *what = "shutdown:sleep:idle";
+ const char *who = "virt-p2v";
+ const char *why = "virt-p2v conversion is running";
+ const char *mode = "block";
+ int fd = -1;
+
+ dbus_error_init (&err);
+
+ conn = dbus_bus_get (DBUS_BUS_SYSTEM, &err);
+ if (dbus_error_is_set (&err)) {
+ fprintf (stderr, "dbus: cannot connect to system bus: %s\n", err.message);
+ goto out;
+ }
+ if (conn == NULL)
+ goto out;
+
+ msg = dbus_message_new_method_call ("org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "Inhibit");
+ if (msg == NULL) {
+ fprintf (stderr, "dbus: cannot create message\n");
+ goto out;
+ }
+
+ dbus_message_iter_init_append (msg, &args);
+ if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &what) ||
+ !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &who) ||
+ !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &why) ||
+ !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &mode)) {
+ fprintf (stderr, "dbus: cannot add message arguments\n");
+ goto out;
+ }
+
+ if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) {
+ fprintf (stderr, "dbus: cannot send Inhibit message to logind\n");
+ goto out;
+ }
+ if (pending == NULL)
+ goto out;
+ dbus_connection_flush (conn);
+ dbus_message_unref (msg);
+ msg = NULL;
+
+ dbus_pending_call_block (pending);
+ msg = dbus_pending_call_steal_reply (pending);
+ if (msg == NULL) {
+ fprintf (stderr, "dbus: could not read message reply\n");
+ goto out;
+ }
+
+ dbus_pending_call_unref (pending);
+ pending = NULL;
+
+ if (!dbus_message_iter_init (msg, &args)) {
+ fprintf (stderr, "dbus: message reply has no return value\n");
+ goto out;
+ }
+
+ if (dbus_message_iter_get_arg_type (&args) != DBUS_TYPE_UNIX_FD) {
+ fprintf (stderr, "dbus: message reply is not a file descriptor\n");
+ goto out;
+ }
+
+ dbus_message_iter_get_basic (&args, &fd);
+
+#ifdef DEBUG_STDERR
+ fprintf (stderr, "dbus: Inhibit() call returned file descriptor %d\n", fd);
+#endif
+
+out:
+ if (pending != NULL)
+ dbus_pending_call_unref (pending);
+ if (msg != NULL)
+ dbus_message_unref (msg);
+
+ /* This is the system bus connection, so unref-ing it does not
+ * actually close it.
+ */
+ if (conn != NULL)
+ dbus_connection_unref (conn);
+
+ dbus_error_free (&err);
+
+ return fd;
+
+#else /* !HAVE_DBUS */
+#ifdef DEBUG_STDERR
+ fprintf (stderr, "warning: virt-p2v compiled without DBus support.\n");
+#endif
+ return -1;
+#endif
+}
diff --git a/p2v/p2v.h b/p2v/p2v.h
index 1282a17..86e2c50 100644
--- a/p2v/p2v.h
+++ b/p2v/p2v.h
@@ -120,6 +120,9 @@ extern const char *get_conversion_error (void);
extern void cancel_conversion (void);
extern int conversion_is_running (void);
+/* inhibit.c */
+extern int inhibit_sleep (void);
+
/* ssh.c */
extern int test_connection (struct config *);
extern mexp_h *open_data_connection (struct config *, int *local_port, int *remote_port);
--
2.9.3
7 years, 10 months
[PATCH v2 1/2] mllib: curl: add optional tmpdir parameter
by Pino Toscano
Add a new optional parameter for the Curl ADT, so temporary files can be
created in a specified directory (which is supposed to be temporary, and
disposed only when the application quits).
---
mllib/curl.ml | 10 ++++++----
mllib/curl.mli | 2 +-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/mllib/curl.ml b/mllib/curl.ml
index 376406e..baa75ec 100644
--- a/mllib/curl.ml
+++ b/mllib/curl.ml
@@ -25,6 +25,7 @@ let quote = Filename.quote
type t = {
curl : string;
args : args;
+ tmpdir : string option;
}
and args = (string * string option) list
@@ -40,12 +41,13 @@ let args_of_proxy = function
| SystemProxy -> []
| ForcedProxy url -> [ "proxy", Some url; "noproxy", Some "" ]
-let create ?(curl = "curl") ?(proxy = SystemProxy) args =
+let create ?(curl = "curl") ?(proxy = SystemProxy) ?tmpdir args =
let args = safe_args @ args_of_proxy proxy @ args in
- { curl = curl; args = args }
+ { curl = curl; args = args; tmpdir = tmpdir }
-let run { curl = curl; args = args } =
- let config_file, chan = Filename.open_temp_file "guestfscurl" ".conf" in
+let run { curl = curl; args = args; tmpdir = tmpdir } =
+ let config_file, chan = Filename.open_temp_file ?temp_dir:tmpdir
+ "guestfscurl" ".conf" in
List.iter (
function
| name, None -> fprintf chan "%s\n" name
diff --git a/mllib/curl.mli b/mllib/curl.mli
index f045572..c0c2fb0 100644
--- a/mllib/curl.mli
+++ b/mllib/curl.mli
@@ -27,7 +27,7 @@ type proxy =
| SystemProxy (** Use the system settings. *)
| ForcedProxy of string (** The proxy is forced to the specified URL. *)
-val create : ?curl:string -> ?proxy:proxy -> args -> t
+val create : ?curl:string -> ?proxy:proxy -> ?tmpdir:string -> args -> t
(** Create a curl command handle.
The curl arguments are a list of key, value pairs corresponding
--
2.7.4
7 years, 10 months