[PATCH] v2v: Use Std_utils.qemu_input_filename instead of prefixing "file:" to filename (RHBZ#1580292).
by Richard W.M. Jones
This also allows us to use virt-v2v with the old version of qemu in
RHEL 7.
Fixes commit e29296cfa20dd691995832940a30fe2e6b98149a.
Thanks: Pino Toscano for suggesting the fix.
---
v2v/v2v.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 54a2b3998..363699701 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -744,7 +744,7 @@ and copy_targets cmdline targets input output =
let cmd =
let filename =
match t.target_file with
- | TargetFile filename -> "file:" ^ filename
+ | TargetFile filename -> qemu_input_filename filename
| TargetURI uri -> uri in
[ Guestfs_config.qemu_img; "convert" ] @
(if not (quiet ()) then [ "-p" ] else []) @
--
2.16.2
6 years, 5 months
[PATCH for discussion only] lib: libvirt: If root, run qemu subprocess as root.root.
by Richard W.M. Jones
libvirt doesn't have a concept of "session qemu" for root:
https://bugzilla.redhat.com/show_bug.cgi?id=890291
When a libguestfs-using process runs as root, and libvirt runs a qemu
subprocess, the qemu subprocess is run as a non-root user (typically
qemu.qemu). This causes various problems, for example if we try to
open a file which is readable by root but unreadable by qemu.qemu then
the operation will fail.
This can be changed globally via a configuration file, but it can also
be changed by using a <seclabel/> clause in the XML (although I think
that's not the only effect):
<seclabel type="static" model="dac" relabel="no">
<label>0:0</label>
</seclabel>
This patch makes that change.
I notice that after this change, qemu is indeed running as root.
However the file being examined still gets relabelled by SELinux (to
virt_content_t IIRC). Maybe this relabelling is in fact desirable.
Also as you can see from the patch there are cases where we use
another <seclabel model='selinux'/> element to set labels to a known
value. It's not clear if we can include both <seclabel/> elements.
The patch as shown overrides the selinux seclabel if running as root.
Rich.
6 years, 5 months
[PATCH] v2v: linux: fix kernel detection when split in different packages
by Pino Toscano
The current detection code for Linux kernels assumes that a kernel
package contains everything in it, i.e. the kernel itself, its modules,
and its configuration. However, since recent Ubuntu versions (e.g.
starting from 18.04) modules & config (with few more files) are split in
an own package, thus not detecting the modpath from installed vmlinuz
files.
To overcome this situation, rework this detection a bit:
1) find the vmlinuz file as before, but then immediately make sure it
exists by stat'ing it
2) get the kernel version from the vmlinuz filename, which should be a
good assumption to do
3) use the calculated version to detect the modules path, checking that
it exists
As additional change, do not assume the config file is in the same
package as vmlinuz, but directly look into the filesystem using the
version we already have.
---
v2v/linux_kernels.ml | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/v2v/linux_kernels.ml b/v2v/linux_kernels.ml
index c047d6deb..6a355b880 100644
--- a/v2v/linux_kernels.ml
+++ b/v2v/linux_kernels.ml
@@ -103,27 +103,27 @@ let detect_kernels (g : G.guestfs) inspect family bootloader =
None
)
else (
- (* Which of these is the kernel itself? *)
+ (* Which of these is the kernel itself? Also, make sure to check
+ * it exists by stat'ing it.
+ *)
let vmlinuz = List.find (
fun filename -> String.is_prefix filename "/boot/vmlinuz-"
) files in
- (* Which of these is the modpath? *)
- let modpath = List.find (
- fun filename ->
- String.length filename >= 14 &&
- String.is_prefix filename "/lib/modules/"
- ) files in
-
- (* Check vmlinuz & modpath exist. *)
- if not (g#is_dir ~followsymlinks:true modpath) then
- raise Not_found;
let vmlinuz_stat =
try g#statns vmlinuz with G.Error _ -> raise Not_found in
- (* Get/construct the version. XXX Read this from kernel file. *)
+ (* Get/construct the version from the vmlinuz file.
+ * XXX Read this from kernel file.
+ *)
let version =
- let prefix_len = String.length "/lib/modules/" in
- String.sub modpath prefix_len (String.length modpath - prefix_len) in
+ String.sub vmlinuz 14 (String.length vmlinuz - 14) in
+
+ (* Determine the modpath from the vmlinuz version, and check it
+ * exists.
+ *)
+ let modpath = "/lib/modules/" ^ version in
+ if not (g#is_dir ~followsymlinks:true modpath) then
+ raise Not_found;
(* Find the initramfs which corresponds to the kernel.
* Since the initramfs is built at runtime, and doesn't have
@@ -188,7 +188,7 @@ let detect_kernels (g : G.guestfs) inspect family bootloader =
let config_file =
let cfg = "/boot/config-" ^ version in
- if List.mem cfg files then Some cfg
+ if g#is_file ~followsymlinks:true cfg then Some cfg
else None in
let kernel_supports what kconf =
--
2.17.0
6 years, 5 months
[PATCH] v2v: -o null: support older qemu-img (RHBZ#1580309)
by Pino Toscano
Commit 4699c7b6e126e07c95b67fb95df58aed87a680dd converted the null
output to use the null-co qemu driver with a JSON URL syntax --
especially the latter is only available in newer versions of qemu.
Even if this output mode is mostly for testing, check at runtime whether
the null-co + JSON way is possible, falling back to the creation of
thrown-away temporary files as before.
---
v2v/output_null.ml | 60 +++++++++++++++++++++++++++++++++++++---------
1 file changed, 49 insertions(+), 11 deletions(-)
diff --git a/v2v/output_null.ml b/v2v/output_null.ml
index b93d53dc5..5a5473c0d 100644
--- a/v2v/output_null.ml
+++ b/v2v/output_null.ml
@@ -42,7 +42,37 @@ open Utils
* size instead.
*)
+let qemu_supports_null_co_device () =
+ (* We actually attempt to convert a raw file to the null-co device. *)
+ let tmp = Filename.temp_file "v2vqemunullcotst" ".img" in
+ Unix.truncate tmp 1024;
+
+ let json = [
+ "file.driver", JSON.String "null-co";
+ "file.size", JSON.String "1E";
+ ] in
+
+ let cmd =
+ sprintf "qemu-img convert -n -f raw -O raw %s json:%s >/dev/null%s"
+ (quote tmp)
+ (quote (JSON.string_of_doc ~fmt:JSON.Compact json))
+ (if verbose () then "" else " 2>&1") in
+ debug "%s" cmd;
+ let r = 0 = Sys.command cmd in
+ Unix.unlink tmp;
+ debug "qemu-img supports the null-co device: %b" r;
+ r
+
class output_null =
+ (* Create a temporary directory which is always deleted at exit,
+ * so we can put the drives there in case qemu does not support
+ * the null-co device.
+ *)
+ let tmpdir =
+ let base_dir = (open_guestfs ())#get_cachedir () in
+ let t = Mkdtemp.temp_dir ~base_dir "null." in
+ rmdir_on_exit t;
+ t in
object
inherit output
@@ -51,19 +81,27 @@ object
method supported_firmware = [ TargetBIOS; TargetUEFI ]
method prepare_targets source targets =
- let json_params = [
- "file.driver", JSON.String "null-co";
- "file.size", JSON.String "1E";
- ] in
- let target_file = TargetURI ("json:" ^ JSON.string_of_doc json_params) in
+ if qemu_supports_null_co_device () then (
+ let json_params = [
+ "file.driver", JSON.String "null-co";
+ "file.size", JSON.String "1E";
+ ] in
+ let target_file = TargetURI ("json:" ^ JSON.string_of_doc json_params) in
- (* While it's not intended that output drivers can set the
- * target_format field (thus overriding the -of option), in
- * this special case of -o null it is reasonable.
- *)
- let target_format = "raw" in
+ (* While it's not intended that output drivers can set the
+ * target_format field (thus overriding the -of option), in
+ * this special case of -o null it is reasonable.
+ *)
+ let target_format = "raw" in
- List.map (fun t -> { t with target_file; target_format }) targets
+ List.map (fun t -> { t with target_file; target_format }) targets
+ ) else (
+ List.map (
+ fun t ->
+ let target_file = tmpdir // t.target_overlay.ov_sd in
+ { t with target_file = TargetFile target_file }
+ ) targets
+ )
method create_metadata _ _ _ _ _ _ = ()
end
--
2.17.0
6 years, 5 months
[PATCH] daemon: inspect: better handling windows drive mapping.
by Mykola Ivanets
I have several Windows disk images which contains strange registry entry
for mapped drives:
"\\DosDevices\\Y:"=hex(3):00,00,00,00,00,00,00,00,00,00,00,00
Which is decoded something like diskID = 0x0, partition starts at
0 bytes from the start of the disk. In addition of Windows disk image
I have attached dummy disk and made xfs file system on a whole device
without partitioning it. I mount xfs file system to a "/" and then
mount other found file systems inside (/fs1, /fs2 etc.). When we decode
drive mappings we are looking for a disk with ID 0x0 (it is 4 bytes
somewhere LBA0). It is appeared that dummy non-partitioned disk with
xfs file system has zeros by offset where diskID is expected to be).
So the disk is considered as a candidate to search for partition at
offset 0. part-list command (and "parted" which is used under the hood)
reports there is 1 partition on "dummy" disk which starts exactly at
offset 0. And thus dummy device name and partition number are simply
concatenated together and corresponding drive mapping is returned:
Y => /dev/sdX1. But /dev/sdX1 is not existing block device.
No matter either it is a bug in "parted" (or it works a such by-design),
let's protect ourself from this situation: in addition we look for msdos
partition table on a disk before making any further assumptions.
---
daemon/inspect_fs_windows.ml | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/daemon/inspect_fs_windows.ml b/daemon/inspect_fs_windows.ml
index 8b2aad8d3..af52dee2d 100644
--- a/daemon/inspect_fs_windows.ml
+++ b/daemon/inspect_fs_windows.ml
@@ -329,7 +329,7 @@ and get_drive_mappings h root data =
String.is_prefix blob "DMIO:ID:" (* GPT *) then
map_registry_disk_blob_gpt (Lazy.force partitions) blob
else if String.length blob = 12 then
- map_registry_disk_blob (Lazy.force devices) blob
+ map_registry_disk_blob_mbr (Lazy.force devices) blob
else
None
)
@@ -356,13 +356,18 @@ and get_drive_mappings h root data =
* The following function maps this blob to a libguestfs partition
* name, if possible.
*)
-and map_registry_disk_blob devices blob =
+and map_registry_disk_blob_mbr devices blob =
try
(* First 4 bytes are the disk ID. Search all devices to find the
* disk with this disk ID.
*)
let diskid = String.sub blob 0 4 in
- let device = List.find (fun dev -> pread dev 4 0x01b8 = diskid) devices in
+ let device =
+ List.find (
+ fun dev ->
+ Parted.part_get_parttype dev = "msdos" &&
+ pread dev 4 0x01b8 = diskid
+ ) devices in
(* Next 8 bytes are the offset of the partition in bytes(!) given as
* a 64 bit little endian number. Luckily it's easy to get the
--
2.17.0
6 years, 5 months
[PATCH] tests: Increase appliance memory when testing 256+ disks.
by Richard W.M. Jones
Currently the tests fail on x86 with recent kernels:
FAIL: test-255-disks.sh
This confused me for a while because our other test program
(utils/max-disks/max-disks.pl) reports that it should be possible to
add 255 disks.
Well it turns out that the default amount of appliance memory is
sufficient if you're just adding disks, but if you try to add _and_
partition those disks there's insufficient memory and the daemon falls
over with an out of memory error.
I considered increasing the default appliance memory, and this is
certainly one way to fix the problem. However this penalises every
user for what is a fairly niche use case. This takes an alternative
approach of increasing the appliance memory for the affected tests.
Related links:
https://bugzilla.redhat.com/show_bug.cgi?id=1478201
https://rwmj.wordpress.com/2017/04/28/how-many-disks-can-you-add-to-a-vir...
Rich.
6 years, 5 months
[PATCH libldm 00/12] New API: an ability to retrieve created device-mapper devices back after they have been created.
by Mykola Ivanets
The main goal of these patch series is to implement a new API that allows to retrieve created device-mapper devices for volumes and partitions back after they have been created.
As part of this patch:
- required libdevmapper version was bumped to 1.02. I think it is safe because it was released more then 10 years ago;
- newer version of libdevmapper allowed to simplify code base a little bit;
- libdevmapper (and a good practice) suggest using UUID for device-mapper devices. It is get implemented as well. Presence of device UUID allows to use libevmapper API function to find device node easier;
- misc fixes and improvements.
IMPORTANT: These patch series depends on this one: https://www.redhat.com/archives/libguestfs/2018-May/msg00059.html.
NOTE: I tried to look around and follow project code style but it seems inconsistent or I simply was unable to recognize used code style. Any comments re welcomed.
--
Mykola Ivanets
Mykola Ivanets (12):
Requires libdevmapper v1.02.
Change the way we sanitise LDM partition name.
Clarify ldm_volume_dm_get_name function documentation.
Set UUID for device mapper devices (partitions and volumes).
Fix potential memory leak.
Use device mapper device UUID instead of name to find device in a
tree.
refactoring: search for device-mapper node in tree.
Don't use hard-coded path to a device mapper directory.
Move devmapper logging functionality into a single place.
misc: don't make unnecessary functions calls, return correct result.
New API: ldm_volume_dm_get_device
New API: ldm_partition_dm_get_device
configure.ac | 2 +-
docs/reference/ldmtool/ldmtool.xml | 20 ++
ldm-1.0.pc.in | 2 +-
libldm.spec.in | 2 +-
src/ldm.c | 379 ++++++++++++++++++++---------
src/ldm.h | 31 ++-
src/ldmtool.c | 74 ++++--
test/ldmread.c | 34 ++-
8 files changed, 392 insertions(+), 152 deletions(-)
--
2.17.0
6 years, 5 months
[PATCH libldm v4 0/3] Make libldm to parse and return volume GUID.
by Mykola Ivanets
v2: wrap commit message, "PATCH libldm" prefix.
v3: correctly initialize and free GLib resources.
v4: gtk-doc is updated to reflect presence of new volume GUID field.
The result of this patch might be used by libguestfs to return drive
mappings for LDM volumes.
Note, that "show volume" ldmtool command already returns hint which
is a drive letter assigned by Windows to corresponding volume. But
it is not reliable source of information. More over, in multiboot
environment it will be unclear which drive letter belongs to which
operating system. Volume GUID allows to overcome this shortcoming.
Mykola Ivanets (3):
Make libldm to parse and return volume GUID.
gtk-doc: update documentation.
Make git to ignore all test output files.
docs/reference/ldmtool/ldmtool.xml | 7 ++++++
src/ldm.c | 29 ++++++++++++++++++++--
src/ldm.h | 10 ++++++++
src/ldmtool.c | 4 +++
test/.gitignore | 39 +++++++++++++++---------------
test/ldmread.c | 9 ++++---
6 files changed, 74 insertions(+), 24 deletions(-)
--
2.17.0
6 years, 5 months