[PATCH supermin] ext2: fix printf formatters
by Pino Toscano
Use the right formatting placeholders, so it gives no warnings also on
32bit platforms.
---
src/ext2fs-c.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/ext2fs-c.c b/src/ext2fs-c.c
index e45980a..cb9282b 100644
--- a/src/ext2fs-c.c
+++ b/src/ext2fs-c.c
@@ -31,6 +31,7 @@
#include <limits.h>
#include <errno.h>
#include <assert.h>
+#include <inttypes.h>
/* Inlining is broken in the ext2fs header file. Disable it by
* defining the following:
@@ -659,9 +660,9 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest)
*/
blocks = ROUND_UP (statbuf.st_size, data->fs->blocksize);
if (blocks > ext2fs_free_blocks_count (data->fs->super)) {
- fprintf (stderr, "supermin: %s: needed %lu blocks (%d each) for "
- "%lu bytes, available only %llu\n",
- src, blocks, data->fs->blocksize, statbuf.st_size,
+ fprintf (stderr, "supermin: %s: needed %zu blocks (%d each) for "
+ "%" PRIu64 " bytes, available only %llu\n",
+ src, blocks, data->fs->blocksize, (uint64_t) statbuf.st_size,
ext2fs_free_blocks_count (data->fs->super));
unix_error (ENOSPC, (char *) "block size",
data->fs->device_name ? caml_copy_string (data->fs->device_name) : Val_none);
--
2.5.5
8 years, 8 months
[PATCH v2] customize/perl_edit-c.c: Don't use internal APIs.
by Richard W.M. Jones
In v1 of this patch, there was the (small) possibility that 'g' might
have been garbage collected while we were in the C function.
Avoid this by passing 'g' to the function as well as the C pointer, so
that 'g' is pinned as a garbage collector root [by CAMLparam5] so it
cannot be collected while we're in the function.
Rich.
8 years, 8 months
[PATCH v4] v2v: add support for virtio-scsi
by Roman Kagan
Virtio-SCSI offers a number of advantages over virtio-blk, in
particular, it supports SCSI UNMAP (aka trim) which is crucial for
keeping the virtual drive from wasting host disk space.
This patch adds support for virtio-scsi as the virtual disk connection
type both on input and on output of v2v.
Virtio-blk remains the default, so for now virtio-scsi-based guests can
only be produced in --in-place mode.
Signed-off-by: Roman Kagan <rkagan(a)virtuozzo.com>
---
v4:
- used 'assert false' to indicate impossible case
- replaced wildcard with explicit match
- dropped 'passthrough' when referring to virtio SCSI
v3:
- resend off a proper branch
v2:
- corrected OVF and glance output
- stopped abusing debug stringifier to obtain linux module name
- droped unneeded braces
v2v/OVF.ml | 4 +++-
v2v/convert_linux.ml | 20 ++++++++++++++------
v2v/input_libvirtxml.ml | 32 ++++++++++++++++++++------------
v2v/output_glance.ml | 5 +++++
v2v/test-v2v-print-source.sh | 2 +-
v2v/types.ml | 9 ++++++---
v2v/types.mli | 11 ++++-------
v2v/v2v.ml | 13 ++++++++-----
v2v/windows_virtio.ml | 30 ++++++++++++++++++++++++------
9 files changed, 85 insertions(+), 41 deletions(-)
diff --git a/v2v/OVF.ml b/v2v/OVF.ml
index f8afc8c..87ce561 100644
--- a/v2v/OVF.ml
+++ b/v2v/OVF.ml
@@ -454,7 +454,9 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
"ovf:format", "http://en.wikipedia.org/wiki/Byte"; (* wtf? *)
"ovf:disk-interface",
(match guestcaps.gcaps_block_bus with
- | Virtio_blk -> "VirtIO" | IDE -> "IDE");
+ | Virtio_blk -> "VirtIO"
+ | Virtio_SCSI -> "VirtIO_SCSI"
+ | IDE -> "IDE");
"ovf:disk-type", "System"; (* RHBZ#744538 *)
"ovf:boot", if is_boot_drive then "True" else "False";
] in
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index 0a2e439..951aa32 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -803,8 +803,9 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
* major number of vdX block devices. If we change it, RHEL 3
* KVM guests won't boot.
*)
- [ "virtio"; "virtio_ring"; "virtio_blk"; "virtio_net";
- "virtio_pci" ]
+ List.filter (fun m -> List.mem m kernel.ki_modules)
+ [ "virtio"; "virtio_ring"; "virtio_blk";
+ "virtio_scsi"; "virtio_net"; "virtio_pci" ]
else
[ "sym53c8xx" (* XXX why not "ide"? *) ] in
@@ -1134,7 +1135,13 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
(* Update 'alias scsi_hostadapter ...' *)
let paths = augeas_modprobe ". =~ regexp('scsi_hostadapter.*')" in
match block_type with
- | Virtio_blk ->
+ | Virtio_blk | Virtio_SCSI ->
+ let block_module =
+ match block_type with
+ | Virtio_blk -> "virtio_blk"
+ | Virtio_SCSI -> "virtio_scsi"
+ | _ -> assert false in
+
if paths <> [] then (
(* There's only 1 scsi controller in the converted guest.
* Convert only the first scsi_hostadapter entry to virtio
@@ -1148,14 +1155,14 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
List.iter (fun path -> ignore (g#aug_rm path))
(List.rev paths_to_delete);
- g#aug_set (path ^ "/modulename") "virtio_blk"
+ g#aug_set (path ^ "/modulename") block_module
) else (
(* We have to add a scsi_hostadapter. *)
let modpath = discover_modpath () in
g#aug_set (sprintf "/files%s/alias[last()+1]" modpath)
"scsi_hostadapter";
g#aug_set (sprintf "/files%s/alias[last()]/modulename" modpath)
- "virtio_blk"
+ block_module
)
| IDE ->
(* There is no scsi controller in an IDE guest. *)
@@ -1247,6 +1254,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let block_prefix_after_conversion =
match block_type with
| Virtio_blk -> "vd"
+ | Virtio_SCSI -> "sd"
| IDE -> ide_block_prefix in
let map =
@@ -1255,7 +1263,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let block_prefix_before_conversion =
match disk.s_controller with
| Some Source_IDE -> ide_block_prefix
- | Some Source_SCSI -> "sd"
+ | Some Source_virtio_SCSI | Some Source_SCSI -> "sd"
| Some Source_virtio_blk -> "vd"
| None ->
(* This is basically a guess. It assumes the source used IDE. *)
diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml
index 9d8963d..231931f 100644
--- a/v2v/input_libvirtxml.ml
+++ b/v2v/input_libvirtxml.ml
@@ -181,6 +181,12 @@ let parse_libvirt_xml ?conn xml =
None
) in
+ (* Presence of virtio-scsi controller. *)
+ let has_virtio_scsi =
+ let obj = Xml.xpath_eval_expression xpathctx
+ "/domain/devices/controller[@model='virtio-scsi']" in
+ Xml.xpathobj_nr_nodes obj > 0 in
+
(* Non-removable disk devices. *)
let disks =
let get_disks, add_disk =
@@ -208,12 +214,13 @@ let parse_libvirt_xml ?conn xml =
let controller =
let target_bus = xpath_string "target/@bus" in
- match target_bus with
- | None -> None
- | Some "ide" -> Some Source_IDE
- | Some "scsi" -> Some Source_SCSI
- | Some "virtio" -> Some Source_virtio_blk
- | Some _ -> None in
+ match target_bus, has_virtio_scsi with
+ | None, _ -> None
+ | Some "ide", _ -> Some Source_IDE
+ | Some "scsi", true -> Some Source_virtio_SCSI
+ | Some "scsi", false -> Some Source_SCSI
+ | Some "virtio", _ -> Some Source_virtio_blk
+ | Some _, _ -> None in
let format =
match xpath_string "driver/@type" with
@@ -297,12 +304,13 @@ let parse_libvirt_xml ?conn xml =
let controller =
let target_bus = xpath_string "target/@bus" in
- match target_bus with
- | None -> None
- | Some "ide" -> Some Source_IDE
- | Some "scsi" -> Some Source_SCSI
- | Some "virtio" -> Some Source_virtio_blk
- | Some _ -> None in
+ match target_bus, has_virtio_scsi with
+ | None, _ -> None
+ | Some "ide", _ -> Some Source_IDE
+ | Some "scsi", true -> Some Source_virtio_SCSI
+ | Some "scsi", false -> Some Source_SCSI
+ | Some "virtio", _ -> Some Source_virtio_blk
+ | Some _, _ -> None in
let slot =
let target_dev = xpath_string "target/@dev" in
diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml
index 9487f0b..8562749 100644
--- a/v2v/output_glance.ml
+++ b/v2v/output_glance.ml
@@ -86,6 +86,7 @@ object
"hw_disk_bus",
(match guestcaps.gcaps_block_bus with
| Virtio_blk -> "virtio"
+ | Virtio_SCSI -> "scsi"
| IDE -> "ide");
"hw_vif_model",
(match guestcaps.gcaps_net_bus with
@@ -105,6 +106,10 @@ object
)
] in
let properties =
+ match guestcaps.gcaps_block_bus with
+ | Virtio_SCSI -> ("hw_scsi_model", "virtio-scsi") :: properties
+ | Virtio_blk | IDE -> properties in
+ let properties =
match inspect.i_major_version, inspect.i_minor_version with
| 0, 0 -> properties
| x, 0 -> ("os_version", string_of_int x) :: properties
diff --git a/v2v/test-v2v-print-source.sh b/v2v/test-v2v-print-source.sh
index 8af6104..789555d 100755
--- a/v2v/test-v2v-print-source.sh
+++ b/v2v/test-v2v-print-source.sh
@@ -63,7 +63,7 @@ hypervisor type: test
video: qxl
sound:
disks:
- /windows.img (raw) [virtio]
+ /windows.img (raw) [virtio-blk]
removable media:
NICs:
Network \"default\" mac: 00:11:22:33:44:55 [virtio]" ]; then
diff --git a/v2v/types.ml b/v2v/types.ml
index 821b7ec..9a23b4a 100644
--- a/v2v/types.ml
+++ b/v2v/types.ml
@@ -55,7 +55,8 @@ and source_disk = {
s_format : string option;
s_controller : s_controller option;
}
-and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk
+and s_controller = Source_IDE | Source_SCSI |
+ Source_virtio_blk | Source_virtio_SCSI
and source_removable = {
s_removable_type : s_removable_type;
s_removable_controller : s_controller option;
@@ -187,7 +188,8 @@ and string_of_source_disk { s_qemu_uri = qemu_uri; s_format = format;
and string_of_controller = function
| Source_IDE -> "ide"
| Source_SCSI -> "scsi"
- | Source_virtio_blk -> "virtio"
+ | Source_virtio_blk -> "virtio-blk"
+ | Source_virtio_SCSI -> "virtio-scsi"
and string_of_source_removable { s_removable_type = typ;
s_removable_controller = controller;
@@ -366,13 +368,14 @@ and requested_guestcaps = {
rcaps_net_bus : guestcaps_net_type option;
rcaps_video : guestcaps_video_type option;
}
-and guestcaps_block_type = Virtio_blk | IDE
+and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
and guestcaps_video_type = QXL | Cirrus
let string_of_block_type block_type =
(match block_type with
| Virtio_blk -> "virtio-blk"
+ | Virtio_SCSI -> "virtio-scsi"
| IDE -> "ide")
let string_of_net_type net_type =
(match net_type with
diff --git a/v2v/types.mli b/v2v/types.mli
index 4595a1f..dde0d29 100644
--- a/v2v/types.mli
+++ b/v2v/types.mli
@@ -65,12 +65,9 @@ and source_disk = {
}
(** A source disk. *)
-and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk
-(** Source disk controller.
-
- For the purposes of this field, we can treat virtio-scsi as
- [SCSI]. However we don't support conversions from virtio in any
- case so virtio is here only to make it work for testing. *)
+and s_controller = Source_IDE | Source_SCSI |
+ Source_virtio_blk | Source_virtio_SCSI
+(** Source disk controller. *)
and source_removable = {
s_removable_type : s_removable_type; (** Type. *)
@@ -218,7 +215,7 @@ and requested_guestcaps = {
}
(** Guest capabilities after conversion. eg. Was virtio found or installed? *)
-and guestcaps_block_type = Virtio_blk | IDE
+and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
and guestcaps_video_type = QXL | Cirrus
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 4d0d525..46c97ca 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -731,10 +731,11 @@ and do_convert g inspect source keep_serial_console rcaps =
(* Did we manage to install virtio drivers? *)
if not (quiet ()) then (
- if guestcaps.gcaps_block_bus = Virtio_blk then
- info (f_"This guest has virtio drivers installed.")
- else
- info (f_"This guest does not have virtio drivers installed.");
+ match guestcaps.gcaps_block_bus with
+ | Virtio_blk | Virtio_SCSI ->
+ info (f_"This guest has virtio drivers installed.")
+ | IDE ->
+ info (f_"This guest does not have virtio drivers installed.")
);
guestcaps
@@ -939,6 +940,7 @@ and target_bus_assignment source targets guestcaps =
let t = BusSlotTarget t in
match guestcaps.gcaps_block_bus with
| Virtio_blk -> insert virtio_blk_bus i t
+ | Virtio_SCSI -> insert scsi_bus i t
| IDE -> insert ide_bus i t
) targets;
@@ -952,7 +954,7 @@ and target_bus_assignment source targets guestcaps =
| None -> ide_bus (* Wild guess, but should be safe. *)
| Some Source_virtio_blk -> virtio_blk_bus
| Some Source_IDE -> ide_bus
- | Some Source_SCSI -> scsi_bus in
+ | Some Source_virtio_SCSI | Some Source_SCSI -> scsi_bus in
match r.s_removable_slot with
| None -> ignore (insert_after bus 0 (BusSlotRemovable r))
| Some desired_slot_nr ->
@@ -992,6 +994,7 @@ and rcaps_from_source source =
let block_type =
match source_block_type with
| Some Source_virtio_blk -> Some Virtio_blk
+ | Some Source_virtio_SCSI -> Some Virtio_SCSI
| Some Source_IDE -> Some IDE
| Some t -> error (f_"source has unsupported hard disk type '%s'")
(string_of_controller t)
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
index 7ca4068..be50107 100644
--- a/v2v/windows_virtio.ml
+++ b/v2v/windows_virtio.ml
@@ -35,6 +35,7 @@ let virtio_win =
let scsi_class_guid = "{4D36E97B-E325-11CE-BFC1-08002BE10318}"
let viostor_pciid = "VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00"
+let vioscsi_pciid = "VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00"
let rec install_drivers g inspect systemroot root current_cs rcaps =
(* Copy the virtio drivers to the guest. *)
@@ -43,7 +44,7 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
if not (copy_drivers g inspect driverdir) then (
match rcaps with
- | { rcaps_block_bus = Some Virtio_blk }
+ | { rcaps_block_bus = Some Virtio_blk | Some Virtio_SCSI }
| { rcaps_net_bus = Some Virtio_net }
| { rcaps_video = Some QXL } ->
error (f_"there are no virtio drivers available for this version of Windows (%d.%d %s %s). virt-v2v looks for drivers in %s")
@@ -66,19 +67,25 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
(* Can we install the block driver? *)
let block : guestcaps_block_type =
let has_viostor = g#exists (driverdir // "viostor.inf") in
- match rcaps.rcaps_block_bus, has_viostor with
- | Some Virtio_blk, false ->
+ let has_vioscsi = g#exists (driverdir // "vioscsi.inf") in
+ match rcaps.rcaps_block_bus, has_viostor, has_vioscsi with
+ | Some Virtio_blk, false, _ ->
error (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
inspect.i_major_version inspect.i_minor_version
inspect.i_arch virtio_win
- | None, false ->
+ | Some Virtio_SCSI, _, false ->
+ error (f_"there is no vioscsi (virtio SCSI) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
+ inspect.i_major_version inspect.i_minor_version
+ inspect.i_arch virtio_win
+
+ | None, false, _ ->
warning (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
inspect.i_major_version inspect.i_minor_version
inspect.i_arch virtio_win;
IDE
- | (Some Virtio_blk | None), true ->
+ | (Some Virtio_blk | None), true, _ ->
(* Block driver needs tweaks to allow booting; the rest is set up by PnP
* manager *)
let source = driverdir // "viostor.sys" in
@@ -89,7 +96,18 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
viostor_pciid;
Virtio_blk
- | Some IDE, _ ->
+ | Some Virtio_SCSI, _, true ->
+ (* Block driver needs tweaks to allow booting; the rest is set up by PnP
+ * manager *)
+ let source = driverdir // "vioscsi.sys" in
+ let target = sprintf "%s/system32/drivers/vioscsi.sys" systemroot in
+ let target = g#case_sensitive_path target in
+ g#cp source target;
+ add_guestor_to_registry g root current_cs "vioscsi"
+ vioscsi_pciid;
+ Virtio_SCSI
+
+ | Some IDE, _, _ ->
IDE in
(* Can we install the virtio-net driver? *)
--
2.5.5
8 years, 8 months
[PATCH v3] v2v: add support for virtio-scsi
by Roman Kagan
Virtio-SCSI offers a number of advantages over virtio-blk, in
particular, it supports SCSI UNMAP (aka trim) which is crucial for
keeping the virtual drive from wasting host disk space.
This patch adds support for virtio-scsi as the virtual disk connection
type both on input and on output of v2v.
Virtio-blk remains the default, so for now virtio-scsi-based guests can
only be produced in --in-place mode.
Signed-off-by: Roman Kagan <rkagan(a)virtuozzo.com>
---
v3:
- resend off a proper branch
v2:
- corrected OVF and glance output
- stopped abusing debug stringifier to obtain linux module name
- droped unneeded braces
v2v/OVF.ml | 4 +++-
v2v/convert_linux.ml | 20 ++++++++++++++------
v2v/input_libvirtxml.ml | 32 ++++++++++++++++++++------------
v2v/output_glance.ml | 5 +++++
v2v/test-v2v-print-source.sh | 2 +-
v2v/types.ml | 9 ++++++---
v2v/types.mli | 11 ++++-------
v2v/v2v.ml | 13 ++++++++-----
v2v/windows_virtio.ml | 30 ++++++++++++++++++++++++------
9 files changed, 85 insertions(+), 41 deletions(-)
diff --git a/v2v/OVF.ml b/v2v/OVF.ml
index f8afc8c..87ce561 100644
--- a/v2v/OVF.ml
+++ b/v2v/OVF.ml
@@ -454,7 +454,9 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
"ovf:format", "http://en.wikipedia.org/wiki/Byte"; (* wtf? *)
"ovf:disk-interface",
(match guestcaps.gcaps_block_bus with
- | Virtio_blk -> "VirtIO" | IDE -> "IDE");
+ | Virtio_blk -> "VirtIO"
+ | Virtio_SCSI -> "VirtIO_SCSI"
+ | IDE -> "IDE");
"ovf:disk-type", "System"; (* RHBZ#744538 *)
"ovf:boot", if is_boot_drive then "True" else "False";
] in
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index 0a2e439..04b7739 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -803,8 +803,9 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
* major number of vdX block devices. If we change it, RHEL 3
* KVM guests won't boot.
*)
- [ "virtio"; "virtio_ring"; "virtio_blk"; "virtio_net";
- "virtio_pci" ]
+ List.filter (fun m -> List.mem m kernel.ki_modules)
+ [ "virtio"; "virtio_ring"; "virtio_blk";
+ "virtio_scsi"; "virtio_net"; "virtio_pci" ]
else
[ "sym53c8xx" (* XXX why not "ide"? *) ] in
@@ -1134,7 +1135,13 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
(* Update 'alias scsi_hostadapter ...' *)
let paths = augeas_modprobe ". =~ regexp('scsi_hostadapter.*')" in
match block_type with
- | Virtio_blk ->
+ | Virtio_blk | Virtio_SCSI ->
+ let block_module =
+ match block_type with
+ | Virtio_blk -> "virtio_blk"
+ | Virtio_SCSI -> "virtio_scsi"
+ | _ -> raise Not_found in
+
if paths <> [] then (
(* There's only 1 scsi controller in the converted guest.
* Convert only the first scsi_hostadapter entry to virtio
@@ -1148,14 +1155,14 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
List.iter (fun path -> ignore (g#aug_rm path))
(List.rev paths_to_delete);
- g#aug_set (path ^ "/modulename") "virtio_blk"
+ g#aug_set (path ^ "/modulename") block_module
) else (
(* We have to add a scsi_hostadapter. *)
let modpath = discover_modpath () in
g#aug_set (sprintf "/files%s/alias[last()+1]" modpath)
"scsi_hostadapter";
g#aug_set (sprintf "/files%s/alias[last()]/modulename" modpath)
- "virtio_blk"
+ block_module
)
| IDE ->
(* There is no scsi controller in an IDE guest. *)
@@ -1247,6 +1254,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let block_prefix_after_conversion =
match block_type with
| Virtio_blk -> "vd"
+ | Virtio_SCSI -> "sd"
| IDE -> ide_block_prefix in
let map =
@@ -1255,7 +1263,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let block_prefix_before_conversion =
match disk.s_controller with
| Some Source_IDE -> ide_block_prefix
- | Some Source_SCSI -> "sd"
+ | Some Source_virtio_SCSI | Some Source_SCSI -> "sd"
| Some Source_virtio_blk -> "vd"
| None ->
(* This is basically a guess. It assumes the source used IDE. *)
diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml
index 9d8963d..231931f 100644
--- a/v2v/input_libvirtxml.ml
+++ b/v2v/input_libvirtxml.ml
@@ -181,6 +181,12 @@ let parse_libvirt_xml ?conn xml =
None
) in
+ (* Presence of virtio-scsi controller. *)
+ let has_virtio_scsi =
+ let obj = Xml.xpath_eval_expression xpathctx
+ "/domain/devices/controller[@model='virtio-scsi']" in
+ Xml.xpathobj_nr_nodes obj > 0 in
+
(* Non-removable disk devices. *)
let disks =
let get_disks, add_disk =
@@ -208,12 +214,13 @@ let parse_libvirt_xml ?conn xml =
let controller =
let target_bus = xpath_string "target/@bus" in
- match target_bus with
- | None -> None
- | Some "ide" -> Some Source_IDE
- | Some "scsi" -> Some Source_SCSI
- | Some "virtio" -> Some Source_virtio_blk
- | Some _ -> None in
+ match target_bus, has_virtio_scsi with
+ | None, _ -> None
+ | Some "ide", _ -> Some Source_IDE
+ | Some "scsi", true -> Some Source_virtio_SCSI
+ | Some "scsi", false -> Some Source_SCSI
+ | Some "virtio", _ -> Some Source_virtio_blk
+ | Some _, _ -> None in
let format =
match xpath_string "driver/@type" with
@@ -297,12 +304,13 @@ let parse_libvirt_xml ?conn xml =
let controller =
let target_bus = xpath_string "target/@bus" in
- match target_bus with
- | None -> None
- | Some "ide" -> Some Source_IDE
- | Some "scsi" -> Some Source_SCSI
- | Some "virtio" -> Some Source_virtio_blk
- | Some _ -> None in
+ match target_bus, has_virtio_scsi with
+ | None, _ -> None
+ | Some "ide", _ -> Some Source_IDE
+ | Some "scsi", true -> Some Source_virtio_SCSI
+ | Some "scsi", false -> Some Source_SCSI
+ | Some "virtio", _ -> Some Source_virtio_blk
+ | Some _, _ -> None in
let slot =
let target_dev = xpath_string "target/@dev" in
diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml
index 9487f0b..106c99a 100644
--- a/v2v/output_glance.ml
+++ b/v2v/output_glance.ml
@@ -86,6 +86,7 @@ object
"hw_disk_bus",
(match guestcaps.gcaps_block_bus with
| Virtio_blk -> "virtio"
+ | Virtio_SCSI -> "scsi"
| IDE -> "ide");
"hw_vif_model",
(match guestcaps.gcaps_net_bus with
@@ -105,6 +106,10 @@ object
)
] in
let properties =
+ match guestcaps.gcaps_block_bus with
+ | Virtio_SCSI -> ("hw_scsi_model", "virtio-scsi") :: properties
+ | _ -> properties in
+ let properties =
match inspect.i_major_version, inspect.i_minor_version with
| 0, 0 -> properties
| x, 0 -> ("os_version", string_of_int x) :: properties
diff --git a/v2v/test-v2v-print-source.sh b/v2v/test-v2v-print-source.sh
index 8af6104..789555d 100755
--- a/v2v/test-v2v-print-source.sh
+++ b/v2v/test-v2v-print-source.sh
@@ -63,7 +63,7 @@ hypervisor type: test
video: qxl
sound:
disks:
- /windows.img (raw) [virtio]
+ /windows.img (raw) [virtio-blk]
removable media:
NICs:
Network \"default\" mac: 00:11:22:33:44:55 [virtio]" ]; then
diff --git a/v2v/types.ml b/v2v/types.ml
index 821b7ec..9a23b4a 100644
--- a/v2v/types.ml
+++ b/v2v/types.ml
@@ -55,7 +55,8 @@ and source_disk = {
s_format : string option;
s_controller : s_controller option;
}
-and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk
+and s_controller = Source_IDE | Source_SCSI |
+ Source_virtio_blk | Source_virtio_SCSI
and source_removable = {
s_removable_type : s_removable_type;
s_removable_controller : s_controller option;
@@ -187,7 +188,8 @@ and string_of_source_disk { s_qemu_uri = qemu_uri; s_format = format;
and string_of_controller = function
| Source_IDE -> "ide"
| Source_SCSI -> "scsi"
- | Source_virtio_blk -> "virtio"
+ | Source_virtio_blk -> "virtio-blk"
+ | Source_virtio_SCSI -> "virtio-scsi"
and string_of_source_removable { s_removable_type = typ;
s_removable_controller = controller;
@@ -366,13 +368,14 @@ and requested_guestcaps = {
rcaps_net_bus : guestcaps_net_type option;
rcaps_video : guestcaps_video_type option;
}
-and guestcaps_block_type = Virtio_blk | IDE
+and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
and guestcaps_video_type = QXL | Cirrus
let string_of_block_type block_type =
(match block_type with
| Virtio_blk -> "virtio-blk"
+ | Virtio_SCSI -> "virtio-scsi"
| IDE -> "ide")
let string_of_net_type net_type =
(match net_type with
diff --git a/v2v/types.mli b/v2v/types.mli
index 4595a1f..dde0d29 100644
--- a/v2v/types.mli
+++ b/v2v/types.mli
@@ -65,12 +65,9 @@ and source_disk = {
}
(** A source disk. *)
-and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk
-(** Source disk controller.
-
- For the purposes of this field, we can treat virtio-scsi as
- [SCSI]. However we don't support conversions from virtio in any
- case so virtio is here only to make it work for testing. *)
+and s_controller = Source_IDE | Source_SCSI |
+ Source_virtio_blk | Source_virtio_SCSI
+(** Source disk controller. *)
and source_removable = {
s_removable_type : s_removable_type; (** Type. *)
@@ -218,7 +215,7 @@ and requested_guestcaps = {
}
(** Guest capabilities after conversion. eg. Was virtio found or installed? *)
-and guestcaps_block_type = Virtio_blk | IDE
+and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
and guestcaps_video_type = QXL | Cirrus
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 4d0d525..647ae11 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -731,10 +731,11 @@ and do_convert g inspect source keep_serial_console rcaps =
(* Did we manage to install virtio drivers? *)
if not (quiet ()) then (
- if guestcaps.gcaps_block_bus = Virtio_blk then
- info (f_"This guest has virtio drivers installed.")
- else
- info (f_"This guest does not have virtio drivers installed.");
+ match guestcaps.gcaps_block_bus with
+ | Virtio_blk | Virtio_SCSI ->
+ info (f_"This guest has virtio drivers installed.")
+ | _ ->
+ info (f_"This guest does not have virtio drivers installed.")
);
guestcaps
@@ -939,6 +940,7 @@ and target_bus_assignment source targets guestcaps =
let t = BusSlotTarget t in
match guestcaps.gcaps_block_bus with
| Virtio_blk -> insert virtio_blk_bus i t
+ | Virtio_SCSI -> insert scsi_bus i t
| IDE -> insert ide_bus i t
) targets;
@@ -952,7 +954,7 @@ and target_bus_assignment source targets guestcaps =
| None -> ide_bus (* Wild guess, but should be safe. *)
| Some Source_virtio_blk -> virtio_blk_bus
| Some Source_IDE -> ide_bus
- | Some Source_SCSI -> scsi_bus in
+ | Some Source_virtio_SCSI | Some Source_SCSI -> scsi_bus in
match r.s_removable_slot with
| None -> ignore (insert_after bus 0 (BusSlotRemovable r))
| Some desired_slot_nr ->
@@ -992,6 +994,7 @@ and rcaps_from_source source =
let block_type =
match source_block_type with
| Some Source_virtio_blk -> Some Virtio_blk
+ | Some Source_virtio_SCSI -> Some Virtio_SCSI
| Some Source_IDE -> Some IDE
| Some t -> error (f_"source has unsupported hard disk type '%s'")
(string_of_controller t)
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
index 7ca4068..6b78420 100644
--- a/v2v/windows_virtio.ml
+++ b/v2v/windows_virtio.ml
@@ -35,6 +35,7 @@ let virtio_win =
let scsi_class_guid = "{4D36E97B-E325-11CE-BFC1-08002BE10318}"
let viostor_pciid = "VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00"
+let vioscsi_pciid = "VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00"
let rec install_drivers g inspect systemroot root current_cs rcaps =
(* Copy the virtio drivers to the guest. *)
@@ -43,7 +44,7 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
if not (copy_drivers g inspect driverdir) then (
match rcaps with
- | { rcaps_block_bus = Some Virtio_blk }
+ | { rcaps_block_bus = Some Virtio_blk | Some Virtio_SCSI }
| { rcaps_net_bus = Some Virtio_net }
| { rcaps_video = Some QXL } ->
error (f_"there are no virtio drivers available for this version of Windows (%d.%d %s %s). virt-v2v looks for drivers in %s")
@@ -66,19 +67,25 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
(* Can we install the block driver? *)
let block : guestcaps_block_type =
let has_viostor = g#exists (driverdir // "viostor.inf") in
- match rcaps.rcaps_block_bus, has_viostor with
- | Some Virtio_blk, false ->
+ let has_vioscsi = g#exists (driverdir // "vioscsi.inf") in
+ match rcaps.rcaps_block_bus, has_viostor, has_vioscsi with
+ | Some Virtio_blk, false, _ ->
error (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
inspect.i_major_version inspect.i_minor_version
inspect.i_arch virtio_win
- | None, false ->
+ | Some Virtio_SCSI, _, false ->
+ error (f_"there is no vioscsi (virtio SCSI passthrough) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
+ inspect.i_major_version inspect.i_minor_version
+ inspect.i_arch virtio_win
+
+ | None, false, _ ->
warning (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
inspect.i_major_version inspect.i_minor_version
inspect.i_arch virtio_win;
IDE
- | (Some Virtio_blk | None), true ->
+ | (Some Virtio_blk | None), true, _ ->
(* Block driver needs tweaks to allow booting; the rest is set up by PnP
* manager *)
let source = driverdir // "viostor.sys" in
@@ -89,7 +96,18 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
viostor_pciid;
Virtio_blk
- | Some IDE, _ ->
+ | Some Virtio_SCSI, _, true ->
+ (* Block driver needs tweaks to allow booting; the rest is set up by PnP
+ * manager *)
+ let source = driverdir // "vioscsi.sys" in
+ let target = sprintf "%s/system32/drivers/vioscsi.sys" systemroot in
+ let target = g#case_sensitive_path target in
+ g#cp source target;
+ add_guestor_to_registry g root current_cs "vioscsi"
+ vioscsi_pciid;
+ Virtio_SCSI
+
+ | Some IDE, _, _ ->
IDE in
(* Can we install the virtio-net driver? *)
--
2.5.5
8 years, 8 months
[PATCH v2] v2v: add support for virtio-scsi
by Roman Kagan
Virtio-SCSI offers a number of advantages over virtio-blk, in
particular, it supports SCSI UNMAP (aka trim) which is crucial for
keeping the virtual drive from wasting host disk space.
This patch adds support for virtio-scsi as the virtual disk connection
type both on input and on output of v2v.
Virtio-blk remains the default, so for now virtio-scsi-based guests can
only be produced in --in-place mode.
Signed-off-by: Roman Kagan <rkagan(a)virtuozzo.com>
---
v2:
- corrected OVF and glance output
- stopped abusing debug stringifier to obtain linux module name
- droped unneeded braces
v2v/OVF.ml | 4 +++-
v2v/convert_linux.ml | 20 ++++++++++++++------
v2v/input_libvirtxml.ml | 32 ++++++++++++++++++++------------
v2v/output_glance.ml | 5 +++++
v2v/test-v2v-print-source.sh | 2 +-
v2v/types.ml | 9 ++++++---
v2v/types.mli | 11 ++++-------
v2v/v2v.ml | 13 ++++++++-----
v2v/windows_virtio.ml | 30 ++++++++++++++++++++++++------
9 files changed, 85 insertions(+), 41 deletions(-)
diff --git a/v2v/OVF.ml b/v2v/OVF.ml
index f8afc8c..87ce561 100644
--- a/v2v/OVF.ml
+++ b/v2v/OVF.ml
@@ -454,7 +454,9 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
"ovf:format", "http://en.wikipedia.org/wiki/Byte"; (* wtf? *)
"ovf:disk-interface",
(match guestcaps.gcaps_block_bus with
- | Virtio_blk -> "VirtIO" | IDE -> "IDE");
+ | Virtio_blk -> "VirtIO"
+ | Virtio_SCSI -> "VirtIO_SCSI"
+ | IDE -> "IDE");
"ovf:disk-type", "System"; (* RHBZ#744538 *)
"ovf:boot", if is_boot_drive then "True" else "False";
] in
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index c9a5f69..b64d6fb 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -805,8 +805,9 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
* major number of vdX block devices. If we change it, RHEL 3
* KVM guests won't boot.
*)
- [ "virtio"; "virtio_ring"; "virtio_blk"; "virtio_net";
- "virtio_pci" ]
+ List.filter (fun m -> List.mem m kernel.ki_modules)
+ [ "virtio"; "virtio_ring"; "virtio_blk";
+ "virtio_scsi"; "virtio_net"; "virtio_pci" ]
else
[ "sym53c8xx" (* XXX why not "ide"? *) ] in
@@ -1136,7 +1137,13 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
(* Update 'alias scsi_hostadapter ...' *)
let paths = augeas_modprobe ". =~ regexp('scsi_hostadapter.*')" in
match block_type with
- | Virtio_blk ->
+ | Virtio_blk | Virtio_SCSI ->
+ let block_module =
+ match block_type with
+ | Virtio_blk -> "virtio_blk"
+ | Virtio_SCSI -> "virtio_scsi"
+ | _ -> raise Not_found in
+
if paths <> [] then (
(* There's only 1 scsi controller in the converted guest.
* Convert only the first scsi_hostadapter entry to virtio
@@ -1150,14 +1157,14 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
List.iter (fun path -> ignore (g#aug_rm path))
(List.rev paths_to_delete);
- g#aug_set (path ^ "/modulename") "virtio_blk"
+ g#aug_set (path ^ "/modulename") block_module
) else (
(* We have to add a scsi_hostadapter. *)
let modpath = discover_modpath () in
g#aug_set (sprintf "/files%s/alias[last()+1]" modpath)
"scsi_hostadapter";
g#aug_set (sprintf "/files%s/alias[last()]/modulename" modpath)
- "virtio_blk"
+ block_module
)
| IDE ->
(* There is no scsi controller in an IDE guest. *)
@@ -1249,6 +1256,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let block_prefix_after_conversion =
match block_type with
| Virtio_blk -> "vd"
+ | Virtio_SCSI -> "sd"
| IDE -> ide_block_prefix in
let map =
@@ -1257,7 +1265,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let block_prefix_before_conversion =
match disk.s_controller with
| Some Source_IDE -> ide_block_prefix
- | Some Source_SCSI -> "sd"
+ | Some Source_virtio_SCSI | Some Source_SCSI -> "sd"
| Some Source_virtio_blk -> "vd"
| None ->
(* This is basically a guess. It assumes the source used IDE. *)
diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml
index 9d8963d..231931f 100644
--- a/v2v/input_libvirtxml.ml
+++ b/v2v/input_libvirtxml.ml
@@ -181,6 +181,12 @@ let parse_libvirt_xml ?conn xml =
None
) in
+ (* Presence of virtio-scsi controller. *)
+ let has_virtio_scsi =
+ let obj = Xml.xpath_eval_expression xpathctx
+ "/domain/devices/controller[@model='virtio-scsi']" in
+ Xml.xpathobj_nr_nodes obj > 0 in
+
(* Non-removable disk devices. *)
let disks =
let get_disks, add_disk =
@@ -208,12 +214,13 @@ let parse_libvirt_xml ?conn xml =
let controller =
let target_bus = xpath_string "target/@bus" in
- match target_bus with
- | None -> None
- | Some "ide" -> Some Source_IDE
- | Some "scsi" -> Some Source_SCSI
- | Some "virtio" -> Some Source_virtio_blk
- | Some _ -> None in
+ match target_bus, has_virtio_scsi with
+ | None, _ -> None
+ | Some "ide", _ -> Some Source_IDE
+ | Some "scsi", true -> Some Source_virtio_SCSI
+ | Some "scsi", false -> Some Source_SCSI
+ | Some "virtio", _ -> Some Source_virtio_blk
+ | Some _, _ -> None in
let format =
match xpath_string "driver/@type" with
@@ -297,12 +304,13 @@ let parse_libvirt_xml ?conn xml =
let controller =
let target_bus = xpath_string "target/@bus" in
- match target_bus with
- | None -> None
- | Some "ide" -> Some Source_IDE
- | Some "scsi" -> Some Source_SCSI
- | Some "virtio" -> Some Source_virtio_blk
- | Some _ -> None in
+ match target_bus, has_virtio_scsi with
+ | None, _ -> None
+ | Some "ide", _ -> Some Source_IDE
+ | Some "scsi", true -> Some Source_virtio_SCSI
+ | Some "scsi", false -> Some Source_SCSI
+ | Some "virtio", _ -> Some Source_virtio_blk
+ | Some _, _ -> None in
let slot =
let target_dev = xpath_string "target/@dev" in
diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml
index 9487f0b..106c99a 100644
--- a/v2v/output_glance.ml
+++ b/v2v/output_glance.ml
@@ -86,6 +86,7 @@ object
"hw_disk_bus",
(match guestcaps.gcaps_block_bus with
| Virtio_blk -> "virtio"
+ | Virtio_SCSI -> "scsi"
| IDE -> "ide");
"hw_vif_model",
(match guestcaps.gcaps_net_bus with
@@ -105,6 +106,10 @@ object
)
] in
let properties =
+ match guestcaps.gcaps_block_bus with
+ | Virtio_SCSI -> ("hw_scsi_model", "virtio-scsi") :: properties
+ | _ -> properties in
+ let properties =
match inspect.i_major_version, inspect.i_minor_version with
| 0, 0 -> properties
| x, 0 -> ("os_version", string_of_int x) :: properties
diff --git a/v2v/test-v2v-print-source.sh b/v2v/test-v2v-print-source.sh
index 8af6104..789555d 100755
--- a/v2v/test-v2v-print-source.sh
+++ b/v2v/test-v2v-print-source.sh
@@ -63,7 +63,7 @@ hypervisor type: test
video: qxl
sound:
disks:
- /windows.img (raw) [virtio]
+ /windows.img (raw) [virtio-blk]
removable media:
NICs:
Network \"default\" mac: 00:11:22:33:44:55 [virtio]" ]; then
diff --git a/v2v/types.ml b/v2v/types.ml
index 821b7ec..9a23b4a 100644
--- a/v2v/types.ml
+++ b/v2v/types.ml
@@ -55,7 +55,8 @@ and source_disk = {
s_format : string option;
s_controller : s_controller option;
}
-and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk
+and s_controller = Source_IDE | Source_SCSI |
+ Source_virtio_blk | Source_virtio_SCSI
and source_removable = {
s_removable_type : s_removable_type;
s_removable_controller : s_controller option;
@@ -187,7 +188,8 @@ and string_of_source_disk { s_qemu_uri = qemu_uri; s_format = format;
and string_of_controller = function
| Source_IDE -> "ide"
| Source_SCSI -> "scsi"
- | Source_virtio_blk -> "virtio"
+ | Source_virtio_blk -> "virtio-blk"
+ | Source_virtio_SCSI -> "virtio-scsi"
and string_of_source_removable { s_removable_type = typ;
s_removable_controller = controller;
@@ -366,13 +368,14 @@ and requested_guestcaps = {
rcaps_net_bus : guestcaps_net_type option;
rcaps_video : guestcaps_video_type option;
}
-and guestcaps_block_type = Virtio_blk | IDE
+and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
and guestcaps_video_type = QXL | Cirrus
let string_of_block_type block_type =
(match block_type with
| Virtio_blk -> "virtio-blk"
+ | Virtio_SCSI -> "virtio-scsi"
| IDE -> "ide")
let string_of_net_type net_type =
(match net_type with
diff --git a/v2v/types.mli b/v2v/types.mli
index 4595a1f..dde0d29 100644
--- a/v2v/types.mli
+++ b/v2v/types.mli
@@ -65,12 +65,9 @@ and source_disk = {
}
(** A source disk. *)
-and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk
-(** Source disk controller.
-
- For the purposes of this field, we can treat virtio-scsi as
- [SCSI]. However we don't support conversions from virtio in any
- case so virtio is here only to make it work for testing. *)
+and s_controller = Source_IDE | Source_SCSI |
+ Source_virtio_blk | Source_virtio_SCSI
+(** Source disk controller. *)
and source_removable = {
s_removable_type : s_removable_type; (** Type. *)
@@ -218,7 +215,7 @@ and requested_guestcaps = {
}
(** Guest capabilities after conversion. eg. Was virtio found or installed? *)
-and guestcaps_block_type = Virtio_blk | IDE
+and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
and guestcaps_video_type = QXL | Cirrus
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 9bf0afe..48ab6e5 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -731,10 +731,11 @@ and do_convert g inspect source keep_serial_console rcaps =
(* Did we manage to install virtio drivers? *)
if not (quiet ()) then (
- if guestcaps.gcaps_block_bus = Virtio_blk then
- info (f_"This guest has virtio drivers installed.")
- else
- info (f_"This guest does not have virtio drivers installed.");
+ match guestcaps.gcaps_block_bus with
+ | Virtio_blk | Virtio_SCSI ->
+ info (f_"This guest has virtio drivers installed.")
+ | _ ->
+ info (f_"This guest does not have virtio drivers installed.")
);
guestcaps
@@ -939,6 +940,7 @@ and target_bus_assignment source targets guestcaps =
let t = BusSlotTarget t in
match guestcaps.gcaps_block_bus with
| Virtio_blk -> insert virtio_blk_bus i t
+ | Virtio_SCSI -> insert scsi_bus i t
| IDE -> insert ide_bus i t
) targets;
@@ -952,7 +954,7 @@ and target_bus_assignment source targets guestcaps =
| None -> ide_bus (* Wild guess, but should be safe. *)
| Some Source_virtio_blk -> virtio_blk_bus
| Some Source_IDE -> ide_bus
- | Some Source_SCSI -> scsi_bus in
+ | Some Source_virtio_SCSI | Some Source_SCSI -> scsi_bus in
match r.s_removable_slot with
| None -> ignore (insert_after bus 0 (BusSlotRemovable r))
| Some desired_slot_nr ->
@@ -992,6 +994,7 @@ and rcaps_from_source source =
let block_type =
match source_block_type with
| Some Source_virtio_blk -> Some Virtio_blk
+ | Some Source_virtio_SCSI -> Some Virtio_SCSI
| Some Source_IDE -> Some IDE
| Some t -> error (f_"source has unsupported hard disk type '%s'")
(string_of_controller t)
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
index 1b63aef..7def882 100644
--- a/v2v/windows_virtio.ml
+++ b/v2v/windows_virtio.ml
@@ -35,6 +35,7 @@ let virtio_win =
let scsi_class_guid = "{4D36E97B-E325-11CE-BFC1-08002BE10318}"
let viostor_pciid = "VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00"
+let vioscsi_pciid = "VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00"
let rec install_drivers g inspect systemroot root current_cs rcaps =
(* Copy the virtio drivers to the guest. *)
@@ -43,7 +44,7 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
if not (copy_drivers g inspect driverdir) then (
match rcaps with
- | { rcaps_block_bus = Some Virtio_blk }
+ | { rcaps_block_bus = Some Virtio_blk | Some Virtio_SCSI }
| { rcaps_net_bus = Some Virtio_net }
| { rcaps_video = Some QXL } ->
error (f_"there are no virtio drivers available for this version of Windows (%d.%d %s %s). virt-v2v looks for drivers in %s")
@@ -66,19 +67,25 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
(* Can we install the block driver? *)
let block : guestcaps_block_type =
let has_viostor = g#exists (driverdir // "viostor.inf") in
- match rcaps.rcaps_block_bus, has_viostor with
- | Some Virtio_blk, false ->
+ let has_vioscsi = g#exists (driverdir // "vioscsi.inf") in
+ match rcaps.rcaps_block_bus, has_viostor, has_vioscsi with
+ | Some Virtio_blk, false, _ ->
error (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
inspect.i_major_version inspect.i_minor_version
inspect.i_arch virtio_win
- | None, false ->
+ | Some Virtio_SCSI, _, false ->
+ error (f_"there is no vioscsi (virtio SCSI passthrough) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
+ inspect.i_major_version inspect.i_minor_version
+ inspect.i_arch virtio_win
+
+ | None, false, _ ->
warning (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
inspect.i_major_version inspect.i_minor_version
inspect.i_arch virtio_win;
IDE
- | (Some Virtio_blk | None), true ->
+ | (Some Virtio_blk | None), true, _ ->
(* Block driver needs tweaks to allow booting; the rest is set up by PnP
* manager *)
let source = driverdir // "viostor.sys" in
@@ -89,7 +96,18 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
viostor_pciid;
Virtio_blk
- | Some IDE, _ ->
+ | Some Virtio_SCSI, _, true ->
+ (* Block driver needs tweaks to allow booting; the rest is set up by PnP
+ * manager *)
+ let source = driverdir // "vioscsi.sys" in
+ let target = sprintf "%s/system32/drivers/vioscsi.sys" systemroot in
+ let target = g#case_sensitive_path target in
+ g#cp source target;
+ add_guestor_to_registry g root current_cs "vioscsi"
+ vioscsi_pciid;
+ Virtio_SCSI
+
+ | Some IDE, _, _ ->
IDE in
(* Can we install the virtio-net driver? *)
--
2.5.5
8 years, 8 months
[PATCH v2 libguestfs] launch: Implement a safer getumask.
by Richard W.M. Jones
The current implementation of getumask involves writing a file with
mode 0777 and then testing what mode was created by the kernel. This
doesn't work properly if the user set a per-mount umask (or fmask/
dmask).
This alternative method was suggested by Josh Stone. By forking, we
can use the thread-unsafe method (calling umask) and pass the result
back over a pipe.
This change also fixes another problem: mode_t is unsigned, so cannot
be used to return an error indication (ie. -1). Return a plain int
instead.
Thanks: Josh Stone, Jiri Jaburek, Eric Blake.
---
src/Makefile.am | 1 +
src/guestfs-internal.h | 3 ++
src/launch.c | 41 ++--------------
src/umask.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 136 insertions(+), 37 deletions(-)
create mode 100644 src/umask.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 3b4cd10..34c4fa6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -130,6 +130,7 @@ libguestfs_la_SOURCES = \
structs-copy.c \
structs-free.c \
tmpdirs.c \
+ umask.c \
whole-file.c \
libguestfs.syms
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 61f384c..bf107d0 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -915,4 +915,7 @@ void guestfs_int_init_unix_backend (void) __attribute__((constructor));
/* guid.c */
extern int guestfs_int_validate_guid (const char *);
+/* umask.c */
+extern int guestfs_int_getumask (guestfs_h *g);
+
#endif /* GUESTFS_INTERNAL_H_ */
diff --git a/src/launch.c b/src/launch.c
index a4326fe..460ed29 100644
--- a/src/launch.c
+++ b/src/launch.c
@@ -50,8 +50,6 @@ static struct backend {
const struct backend_ops *ops;
} *backends = NULL;
-static mode_t get_umask (guestfs_h *g);
-
int
guestfs_impl_launch (guestfs_h *g)
{
@@ -75,6 +73,7 @@ guestfs_impl_launch (guestfs_h *g)
guestfs_version (g);
struct backend *b;
CLEANUP_FREE char *backend = guestfs_get_backend (g);
+ int mask;
debug (g, "launch: program=%s", g->program);
if (STRNEQ (g->identifier, ""))
@@ -87,7 +86,9 @@ guestfs_impl_launch (guestfs_h *g)
debug (g, "launch: backend=%s", backend);
debug (g, "launch: tmpdir=%s", g->tmpdir);
- debug (g, "launch: umask=0%03o", get_umask (g));
+ mask = guestfs_int_getumask (g);
+ if (mask >= 0)
+ debug (g, "launch: umask=0%03o", (unsigned) mask);
debug (g, "launch: euid=%ju", (uintmax_t) geteuid ());
}
@@ -475,40 +476,6 @@ guestfs_int_create_socketname (guestfs_h *g, const char *filename,
}
/**
- * glibc documents, but does not actually implement, a L<getumask(3)>
- * call.
- *
- * This function implements a thread-safe way to get the umask. Note
- * this is only called when C<g-E<gt>verbose> is true and after
- * C<g-E<gt>tmpdir> has been created.
- */
-static mode_t
-get_umask (guestfs_h *g)
-{
- mode_t ret;
- int fd;
- struct stat statbuf;
- CLEANUP_FREE char *filename = safe_asprintf (g, "%s/umask-check", g->tmpdir);
-
- fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_CLOEXEC, 0777);
- if (fd == -1)
- return -1;
-
- if (fstat (fd, &statbuf) == -1) {
- close (fd);
- return -1;
- }
-
- close (fd);
-
- ret = statbuf.st_mode;
- ret &= 0777;
- ret = ret ^ 0777;
-
- return ret;
-}
-
-/**
* When the library is loaded, each backend calls this function to
* register itself in a global list.
*/
diff --git a/src/umask.c b/src/umask.c
new file mode 100644
index 0000000..49c5a4b
--- /dev/null
+++ b/src/umask.c
@@ -0,0 +1,128 @@
+/* libguestfs
+ * Copyright (C) 2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * Return current umask in a thread-safe way.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "ignore-value.h"
+
+#include "guestfs.h"
+#include "guestfs-internal.h"
+
+/**
+ * glibc documents, but does not actually implement, a L<getumask(3)>
+ * call.
+ *
+ * This function implements an expensive, but thread-safe way to get
+ * the current process's umask.
+ *
+ * Returns the current process's umask. On failure, returns C<-1> and
+ * sets the error in the guestfs handle.
+ *
+ * Thanks to: Josh Stone, Jiri Jaburek, Eric Blake.
+ */
+int
+guestfs_int_getumask (guestfs_h *g)
+{
+ pid_t pid;
+ int fd[2], r;
+ int mask;
+ int status;
+ const char *str, *err;
+
+ r = pipe2 (fd, O_CLOEXEC);
+ if (r == -1) {
+ perrorf (g, "pipe2");
+ return -1;
+ }
+
+ pid = fork ();
+ if (pid == -1) {
+ perrorf (g, "fork");
+ close (fd[0]);
+ close (fd[1]);
+ return -1;
+ }
+ if (pid == 0) {
+ /* The child process must ONLY call async-safe functions. */
+ close (fd[0]);
+
+ mask = umask (0);
+ if (mask == -1) {
+ str = "umask: ";
+ err = strerror (errno);
+ ignore_value (write (2, str, strlen (str)));
+ ignore_value (write (2, err, strlen (err)));
+ _exit (EXIT_FAILURE);
+ }
+
+ if (write (fd[1], &mask, sizeof mask) != sizeof mask) {
+ str = "write: ";
+ err = strerror (errno);
+ ignore_value (write (2, str, strlen (str)));
+ ignore_value (write (2, err, strlen (err)));
+ _exit (EXIT_FAILURE);
+ }
+ if (close (fd[1]) == -1) {
+ str = "close: ";
+ err = strerror (errno);
+ ignore_value (write (2, str, strlen (str)));
+ ignore_value (write (2, err, strlen (err)));
+ _exit (EXIT_FAILURE);
+ }
+
+ _exit (EXIT_SUCCESS);
+ }
+
+ /* Parent. */
+ close (fd[1]);
+
+ /* Read the umask. */
+ if (read (fd[0], &mask, sizeof mask) != sizeof mask) {
+ perrorf (g, "read");
+ close (fd[0]);
+ return -1;
+ }
+ close (fd[0]);
+
+ again:
+ if (waitpid (pid, &status, 0) == -1) {
+ if (errno == EINTR) goto again;
+ perrorf (g, "waitpid");
+ return -1;
+ }
+ else if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) {
+ guestfs_int_external_command_failed (g, status, "umask", NULL);
+ return -1;
+ }
+
+ return mask;
+}
--
2.7.4
8 years, 8 months
[PATCH libguestfs] launch: Implement a safer getumask.
by Richard W.M. Jones
The current implementation of getumask involves writing a file with
mode 0777 and then testing what mode was created by the kernel. This
doesn't work properly if the user set a per-mount umask (or fmask/
dmask).
This alternative method was suggested by Josh Stone. By forking, we
can use the thread-unsafe method (calling umask) and pass the result
back over a pipe.
This change also fixes another problem: mode_t is unsigned, so cannot
be used to return an error indication (ie. -1). Return a plain int
instead.
Thanks: Josh Stone, Jiri Jaburek, Eric Blake.
---
src/Makefile.am | 1 +
src/guestfs-internal.h | 3 ++
src/launch.c | 41 ++----------------
src/umask.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 120 insertions(+), 37 deletions(-)
create mode 100644 src/umask.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 3b4cd10..34c4fa6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -130,6 +130,7 @@ libguestfs_la_SOURCES = \
structs-copy.c \
structs-free.c \
tmpdirs.c \
+ umask.c \
whole-file.c \
libguestfs.syms
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 61f384c..bf107d0 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -915,4 +915,7 @@ void guestfs_int_init_unix_backend (void) __attribute__((constructor));
/* guid.c */
extern int guestfs_int_validate_guid (const char *);
+/* umask.c */
+extern int guestfs_int_getumask (guestfs_h *g);
+
#endif /* GUESTFS_INTERNAL_H_ */
diff --git a/src/launch.c b/src/launch.c
index a4326fe..460ed29 100644
--- a/src/launch.c
+++ b/src/launch.c
@@ -50,8 +50,6 @@ static struct backend {
const struct backend_ops *ops;
} *backends = NULL;
-static mode_t get_umask (guestfs_h *g);
-
int
guestfs_impl_launch (guestfs_h *g)
{
@@ -75,6 +73,7 @@ guestfs_impl_launch (guestfs_h *g)
guestfs_version (g);
struct backend *b;
CLEANUP_FREE char *backend = guestfs_get_backend (g);
+ int mask;
debug (g, "launch: program=%s", g->program);
if (STRNEQ (g->identifier, ""))
@@ -87,7 +86,9 @@ guestfs_impl_launch (guestfs_h *g)
debug (g, "launch: backend=%s", backend);
debug (g, "launch: tmpdir=%s", g->tmpdir);
- debug (g, "launch: umask=0%03o", get_umask (g));
+ mask = guestfs_int_getumask (g);
+ if (mask >= 0)
+ debug (g, "launch: umask=0%03o", (unsigned) mask);
debug (g, "launch: euid=%ju", (uintmax_t) geteuid ());
}
@@ -475,40 +476,6 @@ guestfs_int_create_socketname (guestfs_h *g, const char *filename,
}
/**
- * glibc documents, but does not actually implement, a L<getumask(3)>
- * call.
- *
- * This function implements a thread-safe way to get the umask. Note
- * this is only called when C<g-E<gt>verbose> is true and after
- * C<g-E<gt>tmpdir> has been created.
- */
-static mode_t
-get_umask (guestfs_h *g)
-{
- mode_t ret;
- int fd;
- struct stat statbuf;
- CLEANUP_FREE char *filename = safe_asprintf (g, "%s/umask-check", g->tmpdir);
-
- fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_CLOEXEC, 0777);
- if (fd == -1)
- return -1;
-
- if (fstat (fd, &statbuf) == -1) {
- close (fd);
- return -1;
- }
-
- close (fd);
-
- ret = statbuf.st_mode;
- ret &= 0777;
- ret = ret ^ 0777;
-
- return ret;
-}
-
-/**
* When the library is loaded, each backend calls this function to
* register itself in a global list.
*/
diff --git a/src/umask.c b/src/umask.c
new file mode 100644
index 0000000..e01ebbe
--- /dev/null
+++ b/src/umask.c
@@ -0,0 +1,112 @@
+/* libguestfs
+ * Copyright (C) 2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * Return current umask in a thread-safe way.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "guestfs.h"
+#include "guestfs-internal.h"
+
+/**
+ * glibc documents, but does not actually implement, a L<getumask(3)>
+ * call.
+ *
+ * This function implements an expensive, but thread-safe way to get
+ * the current process's umask.
+ *
+ * Returns the current process's umask. On failure, returns C<-1> and
+ * sets the error in the guestfs handle.
+ *
+ * Thanks to: Josh Stone, Jiri Jaburek, Eric Blake.
+ */
+int
+guestfs_int_getumask (guestfs_h *g)
+{
+ pid_t pid;
+ int fd[2], r;
+ int mask;
+ int status;
+
+ r = pipe2 (fd, O_CLOEXEC);
+ if (r == -1) {
+ perrorf (g, "pipe2");
+ return -1;
+ }
+
+ pid = fork ();
+ if (pid == -1) {
+ perrorf (g, "fork");
+ close (fd[0]);
+ close (fd[1]);
+ return -1;
+ }
+ if (pid == 0) {
+ /* The child process must ONLY call async-safe functions. */
+ close (fd[0]);
+
+ mask = umask (0);
+ if (mask == -1) {
+ perror ("umask");
+ _exit (EXIT_FAILURE);
+ }
+
+ if (write (fd[1], &mask, sizeof mask) != sizeof mask) {
+ perror ("write");
+ _exit (EXIT_FAILURE);
+ }
+ if (close (fd[1]) == -1) {
+ perror ("close");
+ _exit (EXIT_FAILURE);
+ }
+
+ _exit (EXIT_SUCCESS);
+ }
+
+ /* Parent. */
+ close (fd[1]);
+
+ /* Read the umask. */
+ if (read (fd[0], &mask, sizeof mask) != sizeof mask) {
+ perrorf (g, "read");
+ close (fd[0]);
+ return -1;
+ }
+ close (fd[0]);
+
+ if (waitpid (pid, &status, 0) == -1) {
+ perrorf (g, "waitpid");
+ return -1;
+ }
+ else if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) {
+ guestfs_int_external_command_failed (g, status, "umask", NULL);
+ return -1;
+ }
+
+ return mask;
+}
--
2.7.4
8 years, 8 months
[PATCH] v2v: add support for virtio-scsi
by Roman Kagan
Virtio-SCSI offers a number of advantages over virtio-blk, in
particular, it supports SCSI UNMAP (aka trim) which is crucial for
keeping the virtual drive from wasting host disk space.
This patch adds support for virtio-scsi as the virtual disk connection
type both on input and on output of v2v.
Virtio-blk remains the default, so for now virtio-scsi-based guests can
only be produced in --in-place mode.
Signed-off-by: Roman Kagan <rkagan(a)virtuozzo.com>
---
v2v/OVF.ml | 4 +++-
v2v/convert_linux.ml | 15 +++++++++------
v2v/input_libvirtxml.ml | 32 ++++++++++++++++++++------------
v2v/output_glance.ml | 1 +
v2v/test-v2v-print-source.sh | 2 +-
v2v/types.ml | 9 ++++++---
v2v/types.mli | 14 +++++++-------
v2v/v2v.ml | 13 ++++++++-----
v2v/windows_virtio.ml | 30 ++++++++++++++++++++++++------
9 files changed, 79 insertions(+), 41 deletions(-)
diff --git a/v2v/OVF.ml b/v2v/OVF.ml
index f8afc8c..dc1e971 100644
--- a/v2v/OVF.ml
+++ b/v2v/OVF.ml
@@ -454,7 +454,9 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
"ovf:format", "http://en.wikipedia.org/wiki/Byte"; (* wtf? *)
"ovf:disk-interface",
(match guestcaps.gcaps_block_bus with
- | Virtio_blk -> "VirtIO" | IDE -> "IDE");
+ | Virtio_blk -> "VirtIO"
+ | Virtio_SCSI -> "SCSI"
+ | IDE -> "IDE");
"ovf:disk-type", "System"; (* RHBZ#744538 *)
"ovf:boot", if is_boot_drive then "True" else "False";
] in
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index 0a2e439..90355fb 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -803,8 +803,9 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
* major number of vdX block devices. If we change it, RHEL 3
* KVM guests won't boot.
*)
- [ "virtio"; "virtio_ring"; "virtio_blk"; "virtio_net";
- "virtio_pci" ]
+ List.filter (fun m -> List.mem m kernel.ki_modules)
+ [ "virtio"; "virtio_ring"; "virtio_blk";
+ "virtio_scsi"; "virtio_net"; "virtio_pci" ]
else
[ "sym53c8xx" (* XXX why not "ide"? *) ] in
@@ -1134,7 +1135,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
(* Update 'alias scsi_hostadapter ...' *)
let paths = augeas_modprobe ". =~ regexp('scsi_hostadapter.*')" in
match block_type with
- | Virtio_blk ->
+ | Virtio_blk | Virtio_SCSI ->
if paths <> [] then (
(* There's only 1 scsi controller in the converted guest.
* Convert only the first scsi_hostadapter entry to virtio
@@ -1148,14 +1149,15 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
List.iter (fun path -> ignore (g#aug_rm path))
(List.rev paths_to_delete);
- g#aug_set (path ^ "/modulename") "virtio_blk"
+ g#aug_set (path ^ "/modulename")
+ (string_of_block_type block_type)
) else (
(* We have to add a scsi_hostadapter. *)
let modpath = discover_modpath () in
g#aug_set (sprintf "/files%s/alias[last()+1]" modpath)
"scsi_hostadapter";
g#aug_set (sprintf "/files%s/alias[last()]/modulename" modpath)
- "virtio_blk"
+ (string_of_block_type block_type)
)
| IDE ->
(* There is no scsi controller in an IDE guest. *)
@@ -1247,6 +1249,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let block_prefix_after_conversion =
match block_type with
| Virtio_blk -> "vd"
+ | Virtio_SCSI -> "sd"
| IDE -> ide_block_prefix in
let map =
@@ -1255,7 +1258,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let block_prefix_before_conversion =
match disk.s_controller with
| Some Source_IDE -> ide_block_prefix
- | Some Source_SCSI -> "sd"
+ | Some Source_virtio_SCSI | Some Source_SCSI -> "sd"
| Some Source_virtio_blk -> "vd"
| None ->
(* This is basically a guess. It assumes the source used IDE. *)
diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml
index 9d8963d..6f325e6 100644
--- a/v2v/input_libvirtxml.ml
+++ b/v2v/input_libvirtxml.ml
@@ -181,6 +181,12 @@ let parse_libvirt_xml ?conn xml =
None
) in
+ (* Presence of virtio-scsi controller. *)
+ let has_virtio_scsi =
+ let obj = Xml.xpath_eval_expression xpathctx
+ "/domain/devices/controller[@model='virtio-scsi']" in
+ (Xml.xpathobj_nr_nodes obj) > 0 in
+
(* Non-removable disk devices. *)
let disks =
let get_disks, add_disk =
@@ -208,12 +214,13 @@ let parse_libvirt_xml ?conn xml =
let controller =
let target_bus = xpath_string "target/@bus" in
- match target_bus with
- | None -> None
- | Some "ide" -> Some Source_IDE
- | Some "scsi" -> Some Source_SCSI
- | Some "virtio" -> Some Source_virtio_blk
- | Some _ -> None in
+ match target_bus, has_virtio_scsi with
+ | None, _ -> None
+ | Some "ide", _ -> Some Source_IDE
+ | Some "scsi", true -> Some Source_virtio_SCSI
+ | Some "scsi", false -> Some Source_SCSI
+ | Some "virtio", _ -> Some Source_virtio_blk
+ | Some _, _ -> None in
let format =
match xpath_string "driver/@type" with
@@ -297,12 +304,13 @@ let parse_libvirt_xml ?conn xml =
let controller =
let target_bus = xpath_string "target/@bus" in
- match target_bus with
- | None -> None
- | Some "ide" -> Some Source_IDE
- | Some "scsi" -> Some Source_SCSI
- | Some "virtio" -> Some Source_virtio_blk
- | Some _ -> None in
+ match target_bus, has_virtio_scsi with
+ | None, _ -> None
+ | Some "ide", _ -> Some Source_IDE
+ | Some "scsi", true -> Some Source_virtio_SCSI
+ | Some "scsi", false -> Some Source_SCSI
+ | Some "virtio", _ -> Some Source_virtio_blk
+ | Some _, _ -> None in
let slot =
let target_dev = xpath_string "target/@dev" in
diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml
index 9487f0b..2572de6 100644
--- a/v2v/output_glance.ml
+++ b/v2v/output_glance.ml
@@ -86,6 +86,7 @@ object
"hw_disk_bus",
(match guestcaps.gcaps_block_bus with
| Virtio_blk -> "virtio"
+ | Virtio_SCSI -> "scsi"
| IDE -> "ide");
"hw_vif_model",
(match guestcaps.gcaps_net_bus with
diff --git a/v2v/test-v2v-print-source.sh b/v2v/test-v2v-print-source.sh
index 8af6104..789555d 100755
--- a/v2v/test-v2v-print-source.sh
+++ b/v2v/test-v2v-print-source.sh
@@ -63,7 +63,7 @@ hypervisor type: test
video: qxl
sound:
disks:
- /windows.img (raw) [virtio]
+ /windows.img (raw) [virtio-blk]
removable media:
NICs:
Network \"default\" mac: 00:11:22:33:44:55 [virtio]" ]; then
diff --git a/v2v/types.ml b/v2v/types.ml
index 821b7ec..9a23b4a 100644
--- a/v2v/types.ml
+++ b/v2v/types.ml
@@ -55,7 +55,8 @@ and source_disk = {
s_format : string option;
s_controller : s_controller option;
}
-and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk
+and s_controller = Source_IDE | Source_SCSI |
+ Source_virtio_blk | Source_virtio_SCSI
and source_removable = {
s_removable_type : s_removable_type;
s_removable_controller : s_controller option;
@@ -187,7 +188,8 @@ and string_of_source_disk { s_qemu_uri = qemu_uri; s_format = format;
and string_of_controller = function
| Source_IDE -> "ide"
| Source_SCSI -> "scsi"
- | Source_virtio_blk -> "virtio"
+ | Source_virtio_blk -> "virtio-blk"
+ | Source_virtio_SCSI -> "virtio-scsi"
and string_of_source_removable { s_removable_type = typ;
s_removable_controller = controller;
@@ -366,13 +368,14 @@ and requested_guestcaps = {
rcaps_net_bus : guestcaps_net_type option;
rcaps_video : guestcaps_video_type option;
}
-and guestcaps_block_type = Virtio_blk | IDE
+and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
and guestcaps_video_type = QXL | Cirrus
let string_of_block_type block_type =
(match block_type with
| Virtio_blk -> "virtio-blk"
+ | Virtio_SCSI -> "virtio-scsi"
| IDE -> "ide")
let string_of_net_type net_type =
(match net_type with
diff --git a/v2v/types.mli b/v2v/types.mli
index 4595a1f..71cfa31 100644
--- a/v2v/types.mli
+++ b/v2v/types.mli
@@ -65,12 +65,9 @@ and source_disk = {
}
(** A source disk. *)
-and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk
-(** Source disk controller.
-
- For the purposes of this field, we can treat virtio-scsi as
- [SCSI]. However we don't support conversions from virtio in any
- case so virtio is here only to make it work for testing. *)
+and s_controller = Source_IDE | Source_SCSI |
+ Source_virtio_blk | Source_virtio_SCSI
+(** Source disk controller. *)
and source_removable = {
s_removable_type : s_removable_type; (** Type. *)
@@ -218,10 +215,13 @@ and requested_guestcaps = {
}
(** Guest capabilities after conversion. eg. Was virtio found or installed? *)
-and guestcaps_block_type = Virtio_blk | IDE
+and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
and guestcaps_video_type = QXL | Cirrus
+val string_of_block_type : guestcaps_block_type -> string
+val string_of_net_type : guestcaps_net_type -> string
+val string_of_video : guestcaps_video_type -> string
val string_of_guestcaps : guestcaps -> string
val string_of_requested_guestcaps : requested_guestcaps -> string
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 4d0d525..647ae11 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -731,10 +731,11 @@ and do_convert g inspect source keep_serial_console rcaps =
(* Did we manage to install virtio drivers? *)
if not (quiet ()) then (
- if guestcaps.gcaps_block_bus = Virtio_blk then
- info (f_"This guest has virtio drivers installed.")
- else
- info (f_"This guest does not have virtio drivers installed.");
+ match guestcaps.gcaps_block_bus with
+ | Virtio_blk | Virtio_SCSI ->
+ info (f_"This guest has virtio drivers installed.")
+ | _ ->
+ info (f_"This guest does not have virtio drivers installed.")
);
guestcaps
@@ -939,6 +940,7 @@ and target_bus_assignment source targets guestcaps =
let t = BusSlotTarget t in
match guestcaps.gcaps_block_bus with
| Virtio_blk -> insert virtio_blk_bus i t
+ | Virtio_SCSI -> insert scsi_bus i t
| IDE -> insert ide_bus i t
) targets;
@@ -952,7 +954,7 @@ and target_bus_assignment source targets guestcaps =
| None -> ide_bus (* Wild guess, but should be safe. *)
| Some Source_virtio_blk -> virtio_blk_bus
| Some Source_IDE -> ide_bus
- | Some Source_SCSI -> scsi_bus in
+ | Some Source_virtio_SCSI | Some Source_SCSI -> scsi_bus in
match r.s_removable_slot with
| None -> ignore (insert_after bus 0 (BusSlotRemovable r))
| Some desired_slot_nr ->
@@ -992,6 +994,7 @@ and rcaps_from_source source =
let block_type =
match source_block_type with
| Some Source_virtio_blk -> Some Virtio_blk
+ | Some Source_virtio_SCSI -> Some Virtio_SCSI
| Some Source_IDE -> Some IDE
| Some t -> error (f_"source has unsupported hard disk type '%s'")
(string_of_controller t)
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
index 7ca4068..a54dbca 100644
--- a/v2v/windows_virtio.ml
+++ b/v2v/windows_virtio.ml
@@ -35,6 +35,7 @@ let virtio_win =
let scsi_class_guid = "{4D36E97B-E325-11CE-BFC1-08002BE10318}"
let viostor_pciid = "VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00"
+let vioscsi_pciid = "VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00"
let rec install_drivers g inspect systemroot root current_cs rcaps =
(* Copy the virtio drivers to the guest. *)
@@ -43,7 +44,7 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
if not (copy_drivers g inspect driverdir) then (
match rcaps with
- | { rcaps_block_bus = Some Virtio_blk }
+ | { rcaps_block_bus = (Some Virtio_blk | Some Virtio_SCSI) }
| { rcaps_net_bus = Some Virtio_net }
| { rcaps_video = Some QXL } ->
error (f_"there are no virtio drivers available for this version of Windows (%d.%d %s %s). virt-v2v looks for drivers in %s")
@@ -66,19 +67,25 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
(* Can we install the block driver? *)
let block : guestcaps_block_type =
let has_viostor = g#exists (driverdir // "viostor.inf") in
- match rcaps.rcaps_block_bus, has_viostor with
- | Some Virtio_blk, false ->
+ let has_vioscsi = g#exists (driverdir // "vioscsi.inf") in
+ match rcaps.rcaps_block_bus, has_viostor, has_vioscsi with
+ | Some Virtio_blk, false, _ ->
error (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
inspect.i_major_version inspect.i_minor_version
inspect.i_arch virtio_win
- | None, false ->
+ | Some Virtio_SCSI, _, false ->
+ error (f_"there is no vioscsi (virtio SCSI passthrough) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
+ inspect.i_major_version inspect.i_minor_version
+ inspect.i_arch virtio_win
+
+ | None, false, _ ->
warning (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
inspect.i_major_version inspect.i_minor_version
inspect.i_arch virtio_win;
IDE
- | (Some Virtio_blk | None), true ->
+ | (Some Virtio_blk | None), true, _ ->
(* Block driver needs tweaks to allow booting; the rest is set up by PnP
* manager *)
let source = driverdir // "viostor.sys" in
@@ -89,7 +96,18 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
viostor_pciid;
Virtio_blk
- | Some IDE, _ ->
+ | Some Virtio_SCSI, _, true ->
+ (* Block driver needs tweaks to allow booting; the rest is set up by PnP
+ * manager *)
+ let source = driverdir // "vioscsi.sys" in
+ let target = sprintf "%s/system32/drivers/vioscsi.sys" systemroot in
+ let target = g#case_sensitive_path target in
+ g#cp source target;
+ add_guestor_to_registry g root current_cs "vioscsi"
+ vioscsi_pciid;
+ Virtio_SCSI
+
+ | Some IDE, _, _ ->
IDE in
(* Can we install the virtio-net driver? *)
--
2.5.5
8 years, 8 months
[PATCH 0/4] v2v: simplify Windows registry patching
by Roman Kagan
The way we patch the Windows registry in order to allow it to boot off a
virtio-blk drive was initially conceived by comparing the state with
virtio-blk driver properly installed, to that without.
However, we don't want to replicate the Windows PnP system; rather we
need to apply just enough edits to make the system boot, and then let
the Windows PnP manager figure out the rest.
This series makes a dramatic reduction to the amount of edits we apply.
Besides it refactors the code somewhat, to make it generic enough to
allow later on to accomodate other SCSI drivers (specifically, vioscsi).
Tested on
Win XP SP3 x32
Win XP SP2 x64
Win 2003R2 SP2 x32
Win 2003R2 SP2 x63
Win Vista SP2 x32
Win Vista SP2 x64
Win 2008 SP2 x32
Win 2008R2 SP1 x64
Win 7 SP1 x32
Win 7 SP1 x64
Win 8 x32
Win 8 x64
Win 8.1 x32
Win 8.1 x64
Win 2012R2 x64
Win 10 x64
Roman Kagan (4):
v2v: win <= 7: reduce registry patch
v2v: win >= 8: reduce registry patch
v2v: win >= 8: simplify registry patching
v2v: win: factor out common bits in registry patching
v2v/windows_virtio.ml | 306 +++++++++-----------------------------------------
1 file changed, 52 insertions(+), 254 deletions(-)
--
2.5.5
8 years, 8 months