[PATCH] lib: libvirt: If root, run qemu as root.root.
by Richard W.M. Jones
Previously we had assumed that when running as root, libvirt would
always run qemu as a non-root user (eg. qemu.qemu), unless you modify
a global configuration file (/etc/libvirt/qemu.conf).
It turns out there is a little-known feature to make libvirt run qemu
as root without modifying any configuration files. We have to add a
<seclabel/> element to the appliance XML:
<seclabel type='static' model='dac' relabel='no'>
<label>root:root</label>
</seclabel>
For further information see:
https://libvirt.org/formatdomain.html#seclabel
This change adds the required <seclabel/> element when running as
root, and also removes the code which changed the owner of the console
and daemon sockets, as that is no longer required.
Thanks: Peter Krempa, Pino Toscano, Dan Berrange.
---
lib/launch-libvirt.c | 60 +++++++++++-----------------------------------------
1 file changed, 12 insertions(+), 48 deletions(-)
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
index 168bba6..81cdead 100644
--- a/lib/launch-libvirt.c
+++ b/lib/launch-libvirt.c
@@ -523,53 +523,6 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri)
clear_socket_create_context (g);
- /* libvirt, if running as root, will run the qemu process as
- * qemu.qemu, which means it won't be able to access the socket.
- * There are roughly three things that get in the way:
- *
- * (1) Permissions of the socket.
- *
- * (2) Permissions of the parent directory(-ies). Remember this if
- * $TMPDIR is located in your home directory.
- *
- * (3) SELinux/sVirt will prevent access. libvirt ought to label
- * the socket.
- *
- * Note that the 'current_proc_is_root' flag here just means that we
- * are root. It's also possible for non-root user to try to use the
- * system libvirtd by specifying a qemu:///system URI (RHBZ#913774)
- * but there's no sane way to test for that.
- */
- if (params.current_proc_is_root) {
- /* Current process is root, so try to create sockets that are
- * owned by root.qemu with mode 0660 and hence accessible to qemu.
- */
- struct group *grp;
-
- if (chmod (data->guestfsd_path, 0660) == -1) {
- perrorf (g, "chmod: %s", data->guestfsd_path);
- goto cleanup;
- }
-
- if (chmod (data->console_path, 0660) == -1) {
- perrorf (g, "chmod: %s", data->console_path);
- goto cleanup;
- }
-
- grp = getgrnam ("qemu");
- if (grp != NULL) {
- if (chown (data->guestfsd_path, 0, grp->gr_gid) == -1) {
- perrorf (g, "chown: %s", data->guestfsd_path);
- goto cleanup;
- }
- if (chown (data->console_path, 0, grp->gr_gid) == -1) {
- perrorf (g, "chown: %s", data->console_path);
- goto cleanup;
- }
- } else
- debug (g, "cannot find group 'qemu'");
- }
-
/* Store any secrets in libvirtd, keeping a mapping from the secret
* to its UUID.
*/
@@ -1256,7 +1209,18 @@ construct_libvirt_xml_seclabel (guestfs_h *g,
const struct libvirt_xml_params *params,
xmlTextWriterPtr xo)
{
- if (!params->enable_svirt) {
+ if (params->current_proc_is_root) {
+ /* Force libvirt to run qemu as root.root. */
+ start_element ("seclabel") {
+ attribute ("type", "static");
+ attribute ("model", "dac");
+ attribute ("relabel", "no");
+ start_element ("label") {
+ string ("root:root");
+ } end_element ();
+ } end_element ();
+ }
+ else if (!params->enable_svirt) {
/* This disables SELinux/sVirt confinement. */
start_element ("seclabel") {
attribute ("type", "none");
--
2.10.2
7 years, 7 months
[PATCH 0/4] v2v: -i -ova: Various fixes.
by Richard W.M. Jones
This has to be applied on top of this series:
https://www.redhat.com/archives/libguestfs/2017-March/msg00144.html
This is a fix for:
https://bugzilla.redhat.com/show_bug.cgi?id=1430680
Kun Wei noticed that virt-v2v -i ova has a problem if we are running
as root and the OVA is not located on a path which is fully readable
by non-root. The reason for this is that libvirt runs qemu as a
non-root user in this case (because there is no qemu:///session for
root, which is a libvirt bug). qemu cannot access the path, and so
the conversion fails.
Now previously we'd seen this bug and worked around it by chmodding
the exploded directory, ie. the product of untarring the OVA file
(https://bugzilla.redhat.com/show_bug.cgi?id=1375157#c6).
However this workaround stopped working when we added support for
accessing the OVA file directly instead of unpacking it, since now the
unreadable OVA file is the backing file.
Fixing this is simple enough -- at least in the trivial csae where the
OVA file is not in an unreadable containing directory, there's no good
way to work around that. But the fix revealed another bug in libvirt
to do with relative paths in backing files
(https://bugzilla.redhat.com/show_bug.cgi?id=1431652) so I had to work
around that as well.
This series also includes a regression test for this. That's not
very simple either, since the regression test has to run as root,
requiring me to add infrastructure for running tests as root
('sudo make check-root').
Rich.
7 years, 7 months
guestfsd: error while loading shared libraries in SUSE12
by Wang, Phoenix
Hi guys,
I've struggled in this error for 1 week and your help is really appreciated. As one EMC software engineer, I need to setup the libguestfs tool in SUSE12 ( SUSE11SP4 is also OK, while SUSE12 is preferred ) to mount some qcow2 image from openstack environment. Then we can read its file system architecture and restore some files.
1. The first thing is we build one SUSE appliance from susestudio.com. For libguestfs/libguestfs0/guestfstools , SUSE studio only provide 1.26.9 version. After download SUSE12 appliance and try to start our task by "guestmount" , we get this error:
According to this page (http://libguestfs.org/guestfs-faq.1.html#libguestfs:-error:-cannot-find-a... ), on SUSE we can only upgrade to higher version of libguestfs to resolve this issue, right ?
Do we have any method to bypass this error on libguestfs 1.26.9 version ? "sudo update-guestfs-appliance" is not used by SUSE.
2. To install libguestfs 1.32 version on SUSE is painful process :) I have searched many websites and try to install below RPM packages :
rpm -qa --last
guestfs-tools-1.32.4-230.6.x86_64 Wed Mar 8 01:23:15 2017
e2fsprogs-1.42.9-63.1.x86_64 Tue Mar 7 10:18:14 2017
python-evtx-0.3.1-2.5.noarch Tue Mar 7 09:51:37 2017
python-libguestfs-1.32.4-230.6.x86_64 Tue Mar 7 09:26:41 2017
perl-Sys-Guestfs-1.32.4-230.6.x86_64 Tue Mar 7 09:26:17 2017
libguestfs0-1.32.4-230.6.x86_64 Tue Mar 7 09:25:24 2017
supermin-5.1.13-14.3.x86_64 Tue Mar 7 09:24:56 2017
xmlstarlet-1.6.1-2.11.x86_64 Tue Mar 7 09:24:10 2017
libxslt1-1.1.29-2.14.x86_64 Tue Mar 7 09:23:39 2017
guestfs-data-1.32.4-230.6.x86_64 Tue Mar 7 09:13:57 2017
fuse-2.9.5-74.1.x86_64 Tue Mar 7 08:38:08 2017
And I get below strange error ( detail error information is in attachment) : guestfsd: error while loading shared libraries: libaugeas.so.0: cannot open shared object file: No such file or directory
1) The rpm package is installed : a
rpm -qa |grep augeas
libaugeas0-1.2.0-3.1.x86_64
And the file is there:
rpm -ql libaugeas0-1.2.0-3.1.x86_64
/usr/lib64/libaugeas.so.0
/usr/lib64/libaugeas.so.0.18.0
/usr/lib64/libfa.so.1
/usr/lib64/libfa.so.1.4.0
2) And I also run ldconfig -p command and we can see libaugeas.so.0 is registered.
3) Is there any impact for the account to run this program ? I use root and also update the /etc/libvirt/qemu.conf to uncomment "user = root".
I really have no idea why this issue comes. Do you have idea or suggestion ?
Thanks a lot !
To be or not to be, that's the question.
Phoenix Wang
EMC China COE Chengdu Center
T: +86 (28) 8296 6862
7 years, 7 months
[PATCH 0/2] v2v: -i ova: A couple of cleanup patches.
by Richard W.M. Jones
A couple of patches cleaning up the -i ova code. These are
both just refactoring (or should be at any rate).
The second patch is best viewed with 'git show -w' to exclude
whitespace changes.
Rich.
7 years, 7 months
[PATCH] v2v: support no socket for <listen type='socket'>
by Pino Toscano
Support also a "socket" listen type with no explicitly specified socket
(which will be generated by libvirt).
Updates commit a4adf48915c0e3e7f4e8b7bbdbb5ac622da1ac58.
Related to: RHBZ#1378022
---
v2v/create_libvirt_xml.ml | 4 +++-
v2v/parse_libvirt_xml.ml | 4 ++--
v2v/types.ml | 5 +++--
v2v/types.mli | 2 +-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml
index 19e0a52..c276109 100644
--- a/v2v/create_libvirt_xml.ml
+++ b/v2v/create_libvirt_xml.ml
@@ -249,7 +249,9 @@ let create_libvirt_xml ?pool source target_buses guestcaps
let sub = e "listen" [ "type", "network"; "network", n ] [] in
append_child sub graphics
| LSocket s ->
- let sub = e "listen" [ "type", "socket"; "socket", s ] [] in
+ let attrs = [ "type", "socket" ] @
+ (match s with None -> [] | Some s -> [ "socket", s ]) in
+ let sub = e "listen" attrs [] in
append_child sub graphics
| LNone ->
let sub = e "listen" [ "type", "none" ] [] in
diff --git a/v2v/parse_libvirt_xml.ml b/v2v/parse_libvirt_xml.ml
index 50bdf1c..edffd20 100644
--- a/v2v/parse_libvirt_xml.ml
+++ b/v2v/parse_libvirt_xml.ml
@@ -109,8 +109,8 @@ let parse_libvirt_xml ?conn xml =
)
| Some "socket" ->
(match xpath_string "listen[1]/@socket" with
- | None -> LNoListen
- | Some n -> LSocket n
+ | None -> LSocket None
+ | Some n -> LSocket (Some n)
)
| Some "none" ->
LNone
diff --git a/v2v/types.ml b/v2v/types.ml
index 3c92357..d802e19 100644
--- a/v2v/types.ml
+++ b/v2v/types.ml
@@ -85,7 +85,7 @@ and s_display_listen =
| LNoListen
| LAddress of string
| LNetwork of string
- | LSocket of string
+ | LSocket of string option
| LNone
and source_video = Source_other_video of string |
@@ -232,7 +232,8 @@ and string_of_source_display { s_display_type = typ;
| LNoListen -> ""
| LAddress a -> sprintf " listening on address %s" a
| LNetwork n -> sprintf " listening on network %s" n
- | LSocket s -> sprintf " listening on Unix domain socket %s" s
+ | LSocket (Some s) -> sprintf " listening on Unix domain socket %s" s
+ | LSocket None -> sprintf " listening on automatically created Unix domain socket"
| LNone -> " listening on private fd"
)
diff --git a/v2v/types.mli b/v2v/types.mli
index 6cd6190..31a974a 100644
--- a/v2v/types.mli
+++ b/v2v/types.mli
@@ -142,7 +142,7 @@ and s_display_listen =
| LNoListen (** No parseable <listen/> element. *)
| LAddress of string (** Listen address. *)
| LNetwork of string (** Listen network. *)
- | LSocket of string (** Listen Unix domain socket. *)
+ | LSocket of string option (** Listen Unix domain socket. *)
| LNone (** <listen type='none'> *)
(** Video adapter model. *)
--
2.9.3
7 years, 7 months
[PATCH] mllib: Add a binding for realpath(3).
by Richard W.M. Jones
I was planning to use this function to harden the code in
v2v/input_ova.ml against malicious OVA files. However I didn't
complete that work. Hate to see a good commit go to waste ...
Rich.
7 years, 7 months
virt-inspector command hung up
by power off
Hi,
I met a problem when using libguestfs-1.28.1 (centos 7.1) on a virtual machine.
Execute virt-inspector command to get OS information and the command hangs .
.......................
Launching appliance, timeout set to 600 seconds
libguestfs: launch: program=virt-inspcetor
libguestfs: launch: version=1.28.1rhel=7,release=1.18.el7,libvirt
libguestfs: launch: backend registered: unix
libguestfs: launch: backend registered: uml
libguestfs: launch: backend registered: libvirt
libguestfs: launch: backend registered: direct
libguestfs: launch: backend=libvirt
libguestfs: launch: tmpdir=/tmp/libguestfsQp28Qo
libguestfs: launch: umask=0027
libguestfs: launch: euid=2016
libguestfs: libvirt version = 1002008 (1.2.8)
libguestfs: guest random name = guestfs-w8hcve9rhu0dve4a
libguestfs: [00000ms] connect to libvirt
libguestfs: opening libvirt handle: URI = qemu://session, auth = default+wrapper, flags = 0
command hung on here.We review the libguestfs soure code
It seems that libguestfs call libvirt API virConnetOpenAuth failed but no returns.
And I set LIBVIRT_DEBUG=debug,and execute virt-inspect command again.
I find the command hung after function virFileFindResourceFull from libvirt debug log.
.........
2017-03-11 07:19:09.246+000: 114046: debug: doRemoteOpen:882 : Peoceeding with sockname /run/user/2016/libvirt/libvirt-sock
2017-03-11 07:19:09.246+000: 114046: debug: virFileFindResourceFull:1608 : Resolved 'libvirtd' to ‘/usr/sbin/libvirtd’
there is no more debug log.
System run well about half of a year before this problem happened.
Any ideas?
PS: can I reboot virtual machine to resume it?
Thanks
Gao Lin
7 years, 7 months
[PATCH] appliance: run systemd-tmpfiles also for /var/run
by Pino Toscano
Commit a6330e9d3af0f5286f1d53d909fd868387b67f69 enabled /run for
systemd-tmpfiles: while this works fine in most of the cases, there are
few tmpfiles configurations that still references /var/run instead of
/run. As result, include also /var/run in the systemd-tmpfiles
execution.
---
appliance/init | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/appliance/init b/appliance/init
index b951857..968429c 100755
--- a/appliance/init
+++ b/appliance/init
@@ -90,7 +90,7 @@ machine_id=$(dd if=/dev/urandom bs=16 count=1 status=none | od -x -A n)
echo "${machine_id// /}" > /etc/machine-id
# Set up tmpfiles (must run after kmod.conf is created above).
-systemd-tmpfiles --prefix=/dev --prefix=/run --create --boot
+systemd-tmpfiles --prefix=/dev --prefix=/run --prefix=/var/run --create --boot
# Find udevd and run it directly.
for f in /lib/systemd/systemd-udevd /usr/lib/systemd/systemd-udevd \
--
2.9.3
7 years, 7 months
[PATCH 1/2] daemon: generate cleanup handlers for structs
by Pino Toscano
This way it is possible to cleanup properly structs in the daemon, when
using them within other daemon functions.
---
.gitignore | 2 +
daemon/Makefile.am | 4 ++
daemon/daemon.h | 1 +
generator/daemon.ml | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++
generator/daemon.mli | 2 +
generator/main.ml | 4 ++
6 files changed, 114 insertions(+)
diff --git a/.gitignore b/.gitignore
index 7dd49e2..c82745e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -163,6 +163,8 @@ Makefile.in
/daemon/optgroups.h
/daemon/lvm-tokenization.c
/daemon/stamp-guestfsd.pod
+/daemon/structs-cleanups.c
+/daemon/structs-cleanups.h
/daemon/stubs-?.c
/daemon/stubs.h
/depcomp
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index e3ad053..8632c37 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -22,6 +22,8 @@ generator_built = \
dispatch.c \
names.c \
lvm-tokenization.c \
+ structs-cleanups.c \
+ structs-cleanups.h \
stubs-0.c \
stubs-1.c \
stubs-2.c \
@@ -142,6 +144,8 @@ guestfsd_SOURCES = \
stat.c \
statvfs.c \
strings.c \
+ structs-cleanups.c \
+ structs-cleanups.h \
stubs-0.c \
stubs-1.c \
stubs-2.c \
diff --git a/daemon/daemon.h b/daemon/daemon.h
index 793074d..abec087 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -33,6 +33,7 @@
#include "guestfs-internal-all.h"
#include "cleanups.h"
+#include "structs-cleanups.h"
#include "command.h"
/* Mountables */
diff --git a/generator/daemon.ml b/generator/daemon.ml
index 3941d97..9453d12 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -840,3 +840,104 @@ let generate_daemon_optgroups_h () =
) optgroups;
pr "#endif /* GUESTFSD_OPTGROUPS_H */\n"
+
+(* Generate structs-cleanups.c file. *)
+and generate_daemon_structs_cleanups_c () =
+ generate_header CStyle GPLv2plus;
+
+ pr "\
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include \"daemon.h\"
+#include \"guestfs_protocol.h\"
+
+";
+
+ pr "/* Cleanup functions used by CLEANUP_* macros. Do not call\n";
+ pr " * these functions directly.\n";
+ pr " */\n";
+ pr "\n";
+
+ List.iter (
+ fun { s_name = typ; s_cols = cols } ->
+ pr "void\n";
+ pr "cleanup_free_int_%s (void *ptr)\n" typ;
+ pr "{\n";
+ pr " struct guestfs_int_%s *x = (* (struct guestfs_int_%s **) ptr);\n" typ typ;
+ pr "\n";
+ pr " if (x) {\n";
+ pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s, (char *) x);\n" typ;
+ pr " free (x);\n";
+ pr " }\n";
+ pr "}\n";
+ pr "\n";
+
+ pr "void\n";
+ pr "cleanup_free_int_%s_list (void *ptr)\n" typ;
+ pr "{\n";
+ pr " struct guestfs_int_%s_list *x = (* (struct guestfs_int_%s_list **) ptr);\n"
+ typ typ;
+ pr "\n";
+ pr " if (x) {\n";
+ pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s_list, (char *) x);\n"
+ typ;
+ pr " free (x);\n";
+ pr " }\n";
+ pr "}\n";
+ pr "\n";
+
+ ) structs
+
+(* Generate structs-cleanups.h file. *)
+and generate_daemon_structs_cleanups_h () =
+ generate_header CStyle GPLv2plus;
+
+ pr "\
+/* These CLEANUP_* macros automatically free the struct or struct list
+ * pointed to by the local variable at the end of the current scope.
+ */
+
+#ifndef GUESTFS_DAEMON_STRUCTS_CLEANUPS_H_
+#define GUESTFS_DAEMON_STRUCTS_CLEANUPS_H_
+
+#ifdef HAVE_ATTRIBUTE_CLEANUP
+";
+
+ List.iter (
+ fun { s_name = name } ->
+ pr "#define CLEANUP_FREE_%s \\\n" (String.uppercase_ascii name);
+ pr " __attribute__((cleanup(cleanup_free_int_%s)))\n" name;
+ pr "#define CLEANUP_FREE_%s_LIST \\\n" (String.uppercase_ascii name);
+ pr " __attribute__((cleanup(cleanup_free_int_%s_list)))\n" name
+ ) structs;
+
+ pr "#else /* !HAVE_ATTRIBUTE_CLEANUP */\n";
+
+ List.iter (
+ fun { s_name = name } ->
+ pr "#define CLEANUP_FREE_%s\n" (String.uppercase_ascii name);
+ pr "#define CLEANUP_FREE_%s_LIST\n" (String.uppercase_ascii name)
+ ) structs;
+
+ pr "\
+#endif /* !HAVE_ATTRIBUTE_CLEANUP */
+
+/* These functions are used internally by the CLEANUP_* macros.
+ * Don't call them directly.
+ */
+
+";
+
+ List.iter (
+ fun { s_name = name } ->
+ pr "extern void cleanup_free_int_%s (void *ptr);\n"
+ name;
+ pr "extern void cleanup_free_int_%s_list (void *ptr);\n"
+ name
+ ) structs;
+
+ pr "\n";
+ pr "#endif /* GUESTFS_INTERNAL_FRONTEND_CLEANUPS_H_ */\n"
diff --git a/generator/daemon.mli b/generator/daemon.mli
index b7966c9..ff008bf 100644
--- a/generator/daemon.mli
+++ b/generator/daemon.mli
@@ -24,3 +24,5 @@ val generate_daemon_lvm_tokenization : unit -> unit
val generate_daemon_names : unit -> unit
val generate_daemon_optgroups_c : unit -> unit
val generate_daemon_optgroups_h : unit -> unit
+val generate_daemon_structs_cleanups_c : unit -> unit
+val generate_daemon_structs_cleanups_h : unit -> unit
diff --git a/generator/main.ml b/generator/main.ml
index febede5..fe5da5a 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -137,6 +137,10 @@ Run it from the top source directory using the command
Daemon.generate_daemon_optgroups_h;
output_to "daemon/lvm-tokenization.c"
Daemon.generate_daemon_lvm_tokenization;
+ output_to "daemon/structs-cleanups.c"
+ Daemon.generate_daemon_structs_cleanups_c;
+ output_to "daemon/structs-cleanups.h"
+ Daemon.generate_daemon_structs_cleanups_h;
output_to "fish/cmds-gperf.gperf"
Fish.generate_fish_cmds_gperf;
--
2.9.3
7 years, 7 months