[PATCH] v2v: use open_guestfs everywhere
by Pino Toscano
Use the common open_guestfs to open Guestfs handles, so we get
debugging, tracing, and other common options set.
---
v2v/convert_windows.ml | 4 +---
v2v/input_disk.ml | 2 +-
v2v/input_libvirt_other.ml | 2 +-
v2v/input_ova.ml | 2 +-
v2v/output_glance.ml | 2 +-
v2v/output_null.ml | 2 +-
v2v/output_rhev.ml | 2 +-
v2v/output_vdsm.ml | 2 +-
v2v/types.ml | 2 +-
v2v/v2v.ml | 4 ++--
10 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
index 6402a63..099ced2 100644
--- a/v2v/convert_windows.ml
+++ b/v2v/convert_windows.ml
@@ -295,10 +295,8 @@ echo uninstalling Xen PV driver
)
else if is_regular_file virtio_win then (
try
- let g2 = new Guestfs.guestfs () in
+ let g2 = open_guestfs () in
g#set_identifier "virtio_win";
- if trace () then g2#set_trace true;
- if verbose () then g2#set_verbose true;
g2#add_drive_opts virtio_win ~readonly:true;
g2#launch ();
let vio_root = "/" in
diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml
index 970f552..4b75262 100644
--- a/v2v/input_disk.ml
+++ b/v2v/input_disk.ml
@@ -60,7 +60,7 @@ class input_disk input_format disk = object
match input_format with
| Some format -> format
| None ->
- match (new Guestfs.guestfs ())#disk_format disk with
+ match (open_guestfs ())#disk_format disk with
| "unknown" ->
error (f_"cannot detect the input disk format; use the -if parameter")
| format -> format in
diff --git a/v2v/input_libvirt_other.ml b/v2v/input_libvirt_other.ml
index 0a137c1..bb97bc6 100644
--- a/v2v/input_libvirt_other.ml
+++ b/v2v/input_libvirt_other.ml
@@ -28,7 +28,7 @@ open Utils
* (RHBZ#1134592). This can be removed once the libvirt bug is fixed.
*)
let error_if_libvirt_backend () =
- let libguestfs_backend = (new Guestfs.guestfs ())#get_backend () in
+ let libguestfs_backend = (open_guestfs ())#get_backend () in
if libguestfs_backend = "libvirt" then (
error (f_"because of libvirt bug https://bugzilla.redhat.com/show_bug.cgi?id=1134592 you must set this environment variable:\n\nexport LIBGUESTFS_BACKEND=direct\n\nand then rerun the virt-v2v command.")
)
diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml
index cd26160..f2dc28b 100644
--- a/v2v/input_ova.ml
+++ b/v2v/input_ova.ml
@@ -26,7 +26,7 @@ open Utils
class input_ova ova =
let tmpdir =
- let base_dir = (new Guestfs.guestfs ())#get_cachedir () in
+ let base_dir = (open_guestfs ())#get_cachedir () in
let t = Mkdtemp.temp_dir ~base_dir "ova." "" in
rmdir_on_exit t;
t in
diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml
index e775229..ddcd771 100644
--- a/v2v/output_glance.ml
+++ b/v2v/output_glance.ml
@@ -31,7 +31,7 @@ class output_glance () =
* to write to a temporary file. XXX
*)
let tmpdir =
- let base_dir = (new Guestfs.guestfs ())#get_cachedir () in
+ let base_dir = (open_guestfs ())#get_cachedir () in
let t = Mkdtemp.temp_dir ~base_dir "glance." "" in
rmdir_on_exit t;
t in
diff --git a/v2v/output_null.ml b/v2v/output_null.ml
index 2cada46..b201baa 100644
--- a/v2v/output_null.ml
+++ b/v2v/output_null.ml
@@ -30,7 +30,7 @@ class output_null =
* temporary directory which is always deleted at exit.
*)
let tmpdir =
- let base_dir = (new Guestfs.guestfs ())#get_cachedir () in
+ let base_dir = (open_guestfs ())#get_cachedir () in
let t = Mkdtemp.temp_dir ~base_dir "null." "" in
rmdir_on_exit t;
t in
diff --git a/v2v/output_rhev.ml b/v2v/output_rhev.ml
index 4b46f83..2878e13 100644
--- a/v2v/output_rhev.ml
+++ b/v2v/output_rhev.ml
@@ -262,7 +262,7 @@ object
?clustersize path format size =
Changeuid.func changeuid_t (
fun () ->
- let g = new Guestfs.guestfs () in
+ let g = open_guestfs () in
g#set_identifier "rhev_disk_create";
(* For qcow2, override v2v-supplied compat option, because RHEL 6
* nodes cannot handle qcow2 v3 (RHBZ#1145582).
diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml
index 1134e5b..079b47f 100644
--- a/v2v/output_vdsm.ml
+++ b/v2v/output_vdsm.ml
@@ -156,7 +156,7 @@ object
method disk_create ?backingfile ?backingformat ?preallocation ?compat
?clustersize path format size =
- let g = new Guestfs.guestfs () in
+ let g = open_guestfs () in
g#set_identifier "vdsm_disk_create";
(* For qcow2, override v2v-supplied compat option, because RHEL 6
* nodes cannot handle qcow2 v3 (RHBZ#1145582).
diff --git a/v2v/types.ml b/v2v/types.ml
index a295172..038d259 100644
--- a/v2v/types.ml
+++ b/v2v/types.ml
@@ -401,7 +401,7 @@ class virtual output = object
method virtual supported_firmware : target_firmware list
method check_target_firmware (_ : guestcaps) (_ : target_firmware) = ()
method check_target_free_space (_ : source) (_ : target list) = ()
- method disk_create = (new Guestfs.guestfs ())#disk_create
+ method disk_create = (open_guestfs ())#disk_create
method virtual create_metadata : source -> target list -> target_buses -> guestcaps -> inspect -> target_firmware -> unit
method keep_serial_console = true
end
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 88ae409..2f473eb 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -217,7 +217,7 @@ and create_overlays src_disks =
* data over the wire.
*)
message (f_"Creating an overlay to protect the source from being modified");
- let overlay_dir = (new Guestfs.guestfs ())#get_cachedir () in
+ let overlay_dir = (open_guestfs ())#get_cachedir () in
List.mapi (
fun i ({ s_qemu_uri = qemu_uri; s_format = format } as source) ->
let overlay_file =
@@ -944,7 +944,7 @@ and target_bus_assignment source targets guestcaps =
and preserve_overlays overlays src_name =
(* Save overlays if --debug-overlays option was used. *)
- let overlay_dir = (new Guestfs.guestfs ())#get_cachedir () in
+ let overlay_dir = (open_guestfs ())#get_cachedir () in
List.iter (
fun ov ->
let saved_filename =
--
2.1.0
9 years, 2 months
[PATCH hivex] build: pass $(MAKE) to run-perl-tests
by Pino Toscano
Instead of hardcoding "make" in run-perl-tests, pass the actual name of
make from the Makefile; the default is still "make", mostly to use the
script without having to set $MAKE.
---
perl/Makefile.am | 4 +++-
perl/run-perl-tests | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/perl/Makefile.am b/perl/Makefile.am
index a0ae863..4632719 100644
--- a/perl/Makefile.am
+++ b/perl/Makefile.am
@@ -41,7 +41,9 @@ TESTS = run-perl-tests
$(TESTS): src_deps all
-TESTS_ENVIRONMENT = ../run
+TESTS_ENVIRONMENT = \
+ MAKE=$(MAKE) \
+ ../run
INSTALLDIRS = site
diff --git a/perl/run-perl-tests b/perl/run-perl-tests
index 770df94..e36c066 100755
--- a/perl/run-perl-tests
+++ b/perl/run-perl-tests
@@ -18,4 +18,4 @@
set -e
-make -f Makefile-pl test "$@"
+${MAKE:-make} -f Makefile-pl test "$@"
--
2.1.0
9 years, 2 months
[PATCH] v2v: move open_guestfs to Types
by Pino Toscano
Move most of open_guestfs to Types, so a common function to open a
Guestfs handle is available. Since it does not do all the things the
old open_guestfs did, the two operations have been moved to the only
place requiring them.
This function has been placed in Types and not Utils, as will be needed
by other functions in Types; Utils uses Types, so this avoids a circular
dependency.
---
v2v/types.ml | 10 ++++++++++
v2v/types.mli | 5 +++++
v2v/v2v.ml | 11 ++---------
3 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/v2v/types.ml b/v2v/types.ml
index cc417bc..a295172 100644
--- a/v2v/types.ml
+++ b/v2v/types.ml
@@ -18,6 +18,9 @@
open Printf
+open Common_gettext.Gettext
+open Common_utils
+
(* Types. See types.mli for documentation. *)
type source = {
@@ -379,6 +382,13 @@ let string_of_target_buses buses =
string_of_target_bus_slots "ide" buses.target_ide_bus ^
string_of_target_bus_slots "scsi" buses.target_scsi_bus
+let open_guestfs () =
+ (* Open the guestfs handle. *)
+ let g = new Guestfs.guestfs () in
+ if trace () then g#set_trace true;
+ if verbose () then g#set_verbose true;
+ g
+
class virtual input = object
method virtual as_options : string
method virtual source : unit -> source
diff --git a/v2v/types.mli b/v2v/types.mli
index 55fb09a..9e8932e 100644
--- a/v2v/types.mli
+++ b/v2v/types.mli
@@ -253,3 +253,8 @@ type output_allocation = Sparse | Preallocated
type vmtype = Desktop | Server
(** Type of [--vmtype] option. *)
+
+val open_guestfs : unit -> Guestfs.guestfs
+(* Create a new Guestfs handle, with common options (e.g. debug, tracing)
+ * already set.
+ *)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 333ece0..88ae409 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -76,6 +76,8 @@ let rec main () =
);
let g = open_guestfs () in
+ g#set_identifier "v2v";
+ g#set_network true;
(match conversion_mode with
| Copying (overlays, _) -> populate_overlays g overlays
| In_place -> populate_disks g source.s_disks
@@ -284,15 +286,6 @@ and init_targets overlays source output output_format =
output#prepare_targets source targets
-and open_guestfs () =
- (* Open the guestfs handle. *)
- let g = new G.guestfs () in
- g#set_identifier "v2v";
- if trace () then g#set_trace true;
- if verbose () then g#set_verbose true;
- g#set_network true;
- g
-
and populate_overlays g overlays =
(* Populate guestfs handle with qcow2 overlays. *)
List.iter (
--
2.1.0
9 years, 2 months
[PATCH] v2v: fix identifier
by Pino Toscano
Set the "virtio_win" identifier to the right Guestfs handle.
Fixes commit f7249a0bccc43d5b5e11703ff432b0361b03292b.
---
v2v/convert_windows.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
index 099ced2..fbd3ce1 100644
--- a/v2v/convert_windows.ml
+++ b/v2v/convert_windows.ml
@@ -296,7 +296,7 @@ echo uninstalling Xen PV driver
else if is_regular_file virtio_win then (
try
let g2 = open_guestfs () in
- g#set_identifier "virtio_win";
+ g2#set_identifier "virtio_win";
g2#add_drive_opts virtio_win ~readonly:true;
g2#launch ();
let vio_root = "/" in
--
2.1.0
9 years, 2 months
[PATCHv4 0/2] Introduce vfs_minimum_size API to get minimum filesystem size.
by Maxim Perevedentsev
Tried to make it in accordance with your comments.
Difference to v1:
Added reply_with_error where necessary.
Changed name get_min_size -> vfs_min_size.
Difference to v2:
Changed name to vfs_minimum_size.
Changed parsing to xstrtol + STR* macros where possible.
Difference to v3:
Decapitalize error messages.
Maxim Perevedentsev (2):
New API: vfs_minimum_size
Include resize2fs_P into vfs_minimum_size.
daemon/Makefile.am | 1 +
daemon/daemon.h | 2 ++
daemon/ext2.c | 62 ++++++++++++++++++++++++++++++++-----
daemon/fs-min-size.c | 49 +++++++++++++++++++++++++++++
daemon/ntfs.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++
generator/actions.ml | 19 ++++++++----
po/POTFILES | 1 +
7 files changed, 207 insertions(+), 14 deletions(-)
create mode 100644 daemon/fs-min-size.c
--
1.8.3.1
9 years, 2 months
[PATCH 1/2] generator: add a FilenameList parameter type
by Pino Toscano
Mostly like StringList (so it can used in current StringList
parameters), but checking client- and daemon-side that the elements are
file names.
---
generator/bindtests.ml | 3 ++-
generator/c.ml | 29 ++++++++++++++++++++++++-----
generator/csharp.ml | 4 ++--
generator/daemon.ml | 20 ++++++++++++++++++--
generator/erlang.ml | 2 +-
generator/fish.ml | 10 ++++++----
generator/gobject.ml | 7 ++++---
generator/golang.ml | 9 ++++++---
generator/haskell.ml | 9 +++++----
generator/java.ml | 10 +++++-----
generator/lua.ml | 6 +++---
generator/ocaml.ml | 7 ++++---
generator/perl.ml | 9 ++++++---
generator/php.ml | 13 ++++++++-----
generator/python.ml | 13 +++++++------
generator/ruby.ml | 4 ++--
generator/tests_c_api.ml | 7 +++++--
generator/types.ml | 5 +++++
generator/utils.ml | 2 +-
generator/xdr.ml | 3 ++-
20 files changed, 116 insertions(+), 56 deletions(-)
diff --git a/generator/bindtests.ml b/generator/bindtests.ml
index 0959704..020d059 100644
--- a/generator/bindtests.ml
+++ b/generator/bindtests.ml
@@ -163,7 +163,8 @@ fill_lvm_pv (guestfs_h *g, struct guestfs_lvm_pv *pv, size_t i)
pr " fprintf (fp, \"\\n\");\n";
pr " }\n";
| OptString n -> pr " fprintf (fp, \"%%s\\n\", %s ? %s : \"null\");\n" n n
- | StringList n | DeviceList n -> pr " print_strings (g, %s);\n" n
+ | StringList n | DeviceList n | FilenameList n ->
+ pr " print_strings (g, %s);\n" n
| Bool n -> pr " fprintf (fp, \"%%s\\n\", %s ? \"true\" : \"false\");\n" n
| Int n -> pr " fprintf (fp, \"%%d\\n\", %s);\n" n
| Int64 n -> pr " fprintf (fp, \"%%\" PRIi64 \"\\n\", %s);\n" n
diff --git a/generator/c.ml b/generator/c.ml
index 055b683..f05da03 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -131,7 +131,7 @@ let rec generate_prototype ?(extern = true) ?(static = false)
pr "const mountable_t *%s" n
else
pr "const char *%s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
next ();
pr "char *const *%s" n
| Bool n -> next (); pr "int %s" n
@@ -1252,7 +1252,8 @@ and generate_client_actions hash () =
| DeviceList n
| Key n
| Pointer (_, n)
- | GUID n ->
+ | GUID n
+ | FilenameList n ->
pr " if (%s == NULL) {\n" n;
pr " error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
pr " \"%s\", \"%s\");\n" c_name n;
@@ -1355,6 +1356,23 @@ and generate_client_actions hash () =
pr " }\n";
pr_newline := true
+ | FilenameList n ->
+ pr " {\n";
+ pr " size_t i;\n";
+ pr " for (i = 0; %s[i] != NULL; ++i) {\n" n;
+ pr " if (strchr (%s[i], '/') != NULL) {\n" n;
+ pr " error (g, \"%%s: %%s: '%%s' is not a file name\",\n";
+ pr " \"%s\", \"%s\", %s[i]);\n" c_name n n;
+ let errcode =
+ match errcode_of_ret ret with
+ | `CannotReturnError -> assert false
+ | (`ErrorIsMinusOne |`ErrorIsNULL) as e -> e in
+ pr " return %s;\n" (string_of_errcode errcode);
+ pr " }\n";
+ pr " }\n";
+ pr " }\n";
+ pr_newline := true
+
(* not applicable *)
| String _
| Device _
@@ -1383,7 +1401,7 @@ and generate_client_actions hash () =
let needs_i =
List.exists (function
- | StringList _ | DeviceList _ -> true
+ | StringList _ | DeviceList _ | FilenameList _ -> true
| _ -> false) args ||
List.exists (function
| OStringList _ -> true
@@ -1419,7 +1437,8 @@ and generate_client_actions hash () =
pr " else\n";
pr " fprintf (trace_buffer.fp, \" null\");\n"
| StringList n
- | DeviceList n -> (* string list *)
+ | DeviceList n
+ | FilenameList n -> (* string list *)
pr " fputc (' ', trace_buffer.fp);\n";
pr " fputc ('\"', trace_buffer.fp);\n";
pr " for (i = 0; %s[i]; ++i) {\n" n;
@@ -1735,7 +1754,7 @@ and generate_client_actions hash () =
pr " args.%s = (char *) %s;\n" n n
| OptString n ->
pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " args.%s.%s_val = (char **) %s;\n" n n n;
pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
| Bool n ->
diff --git a/generator/csharp.ml b/generator/csharp.ml
index e2bd25b..6022af1 100644
--- a/generator/csharp.ml
+++ b/generator/csharp.ml
@@ -195,7 +195,7 @@ namespace Guestfs
| BufferIn n
| GUID n ->
pr ", [In] string %s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr ", [In] string[] %s" n
| Bool n ->
pr ", bool %s" n
@@ -224,7 +224,7 @@ namespace Guestfs
| BufferIn n
| GUID n ->
next (); pr "string %s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
next (); pr "string[] %s" n
| Bool n ->
next (); pr "bool %s" n
diff --git a/generator/daemon.ml b/generator/daemon.ml
index 1825de4..a950c17 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -255,7 +255,7 @@ cleanup_free_mountable (mountable_t *mountable)
| Mountable n | Mountable_or_Path n ->
pr " CLEANUP_FREE_MOUNTABLE mountable_t %s\n" n;
pr " = { .device = NULL, .volume = NULL };\n"
- | StringList n ->
+ | StringList n | FilenameList n ->
pr " char **%s;\n" n
| DeviceList n ->
pr " CLEANUP_FREE_STRING_LIST char **%s = NULL;\n" n
@@ -344,7 +344,23 @@ cleanup_free_mountable (mountable_t *mountable)
n n (if is_filein then "cancel_receive ()" else "");
| String n | Key n | GUID n -> pr_args n
| OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
- | StringList n ->
+ | StringList n | FilenameList n as arg ->
+ (match arg with
+ | FilenameList n ->
+ pr " {\n";
+ pr " size_t i;\n";
+ pr " for (i = 0; i < args.%s.%s_len; ++i) {\n" n n;
+ pr " if (strchr (args.%s.%s_val[i], '/') != NULL) {\n" n n;
+ if is_filein then
+ pr " cancel_receive ();\n";
+ pr " reply_with_error (\"%%s: '%%s' is not a file name\", __func__, args.%s.%s_val[i]);\n"
+ n n;
+ pr " goto done;\n";
+ pr " }\n";
+ pr " }\n";
+ pr " }\n"
+ | _ -> ()
+ );
pr " /* Ugly, but safe and avoids copying the strings. */\n";
pr " %s = realloc (args.%s.%s_val,\n" n n n;
pr " sizeof (char *) * (args.%s.%s_len+1));\n" n n;
diff --git a/generator/erlang.ml b/generator/erlang.ml
index 5d4faaf..d5d30b4 100644
--- a/generator/erlang.ml
+++ b/generator/erlang.ml
@@ -310,7 +310,7 @@ extern int64_t get_int64 (ETERM *term);
pr " ETERM *%s_bin = erl_iolist_to_binary (ARG (%d));\n" n i;
pr " const void *%s = ERL_BIN_PTR (%s_bin);\n" n n;
pr " size_t %s_size = ERL_BIN_SIZE (%s_bin);\n" n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " CLEANUP_FREE_STRING_LIST char **%s = get_string_list (ARG (%d));\n" n i
| Bool n ->
pr " int %s = get_bool (ARG (%d));\n" n i
diff --git a/generator/fish.ml b/generator/fish.ml
index 6f68e65..40b97d3 100644
--- a/generator/fish.ml
+++ b/generator/fish.ml
@@ -376,7 +376,8 @@ Guestfish will prompt for these separately."
| BufferIn n ->
pr " const char *%s;\n" n;
pr " size_t %s_size;\n" n
- | StringList n | DeviceList n -> pr " char **%s;\n" n
+ | StringList n | DeviceList n | FilenameList n ->
+ pr " char **%s;\n" n
| Bool n -> pr " int %s;\n" n
| Int n -> pr " int %s;\n" n
| Int64 n -> pr " int64_t %s;\n" n
@@ -464,7 +465,7 @@ Guestfish will prompt for these separately."
| FileOut name ->
pr " %s = file_out (argv[i++]);\n" name;
pr " if (%s == NULL) goto out_%s;\n" name name
- | StringList name | DeviceList name ->
+ | StringList name | DeviceList name | FilenameList name ->
pr " %s = parse_string_list (argv[i++]);\n" name;
pr " if (%s == NULL) goto out_%s;\n" name name
| Key name ->
@@ -678,7 +679,7 @@ Guestfish will prompt for these separately."
| FileIn name ->
pr " free_file_in (%s);\n" name;
pr " out_%s:\n" name
- | StringList name | DeviceList name ->
+ | StringList name | DeviceList name | FilenameList name ->
pr " guestfs_int_free_string_list (%s);\n" name;
pr " out_%s:\n" name
| Pointer _ -> assert false
@@ -917,7 +918,8 @@ and generate_fish_actions_pod () =
| GUID n ->
pr " %s" n
| OptString n -> pr " %s" n
- | StringList n | DeviceList n -> pr " '%s ...'" n
+ | StringList n | DeviceList n | FilenameList n ->
+ pr " '%s ...'" n
| Bool _ -> pr " true|false"
| Int n -> pr " %s" n
| Int64 n -> pr " %s" n
diff --git a/generator/gobject.ml b/generator/gobject.ml
index 8d5ac06..2c8b64e 100644
--- a/generator/gobject.ml
+++ b/generator/gobject.ml
@@ -85,7 +85,8 @@ let generate_gobject_proto name ?(single_line = true)
| GUID n ->
pr "const gchar *%s" n
| StringList n
- | DeviceList n ->
+ | DeviceList n
+ | FilenameList n ->
pr "gchar *const *%s" n
| BufferIn n ->
pr "const guint8 *%s, gsize %s_size" n n
@@ -1052,7 +1053,7 @@ guestfs_session_close (GuestfsSession *session, GError **err)
pr " (transfer none) (type filename):"
| StringList _ ->
pr " (transfer none) (array zero-terminated=1) (element-type utf8): an array of strings"
- | DeviceList _ ->
+ | DeviceList _ | FilenameList _ ->
pr " (transfer none) (array zero-terminated=1) (element-type filename): an array of strings"
| BufferIn n ->
pr " (transfer none) (array length=%s_size) (element-type guint8): an array of binary data\n" n;
@@ -1211,7 +1212,7 @@ guestfs_session_close (GuestfsSession *session, GError **err)
| Pathname n | Dev_or_Path n | Mountable_or_Path n
| OptString n | StringList n
| DeviceList n | Key n | FileIn n | FileOut n
- | GUID n ->
+ | GUID n | FilenameList n ->
pr "%s" n
| Pointer (_, n) ->
pr "%s" n
diff --git a/generator/golang.ml b/generator/golang.ml
index b4b2482..faaf19e 100644
--- a/generator/golang.ml
+++ b/generator/golang.ml
@@ -315,7 +315,8 @@ func return_hashtable (argv **C.char) map[string]string {
| GUID n -> pr "%s string" n
| OptString n -> pr "%s *string" n
| StringList n
- | DeviceList n -> pr "%s []string" n
+ | DeviceList n
+ | FilenameList n -> pr "%s []string" n
| BufferIn n -> pr "%s []byte" n
| Pointer (_, n) -> pr "%s int64" n
) args;
@@ -380,7 +381,8 @@ func return_hashtable (argv **C.char) map[string]string {
pr " defer C.free (unsafe.Pointer (c_%s))\n" n;
pr " }\n"
| StringList n
- | DeviceList n ->
+ | DeviceList n
+ | FilenameList n ->
pr "\n";
pr " c_%s := arg_string_list (%s)\n" n n;
pr " defer free_string_list (c_%s)\n" n
@@ -455,7 +457,8 @@ func return_hashtable (argv **C.char) map[string]string {
| FileIn n | FileOut n
| GUID n -> pr "c_%s" n
| StringList n
- | DeviceList n -> pr "c_%s" n
+ | DeviceList n
+ | FilenameList n -> pr "c_%s" n
| BufferIn n -> pr "c_%s, C.size_t (len (%s))" n n
| Pointer _ -> pr "nil"
) args;
diff --git a/generator/haskell.ml b/generator/haskell.ml
index 96682e6..59c5859 100644
--- a/generator/haskell.ml
+++ b/generator/haskell.ml
@@ -147,7 +147,8 @@ assocListOfHashtable (a:b:rest) = (a,b) : assocListOfHashtable rest
| BufferIn n ->
pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
| OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
- | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
+ | StringList n | DeviceList n | FilenameList n ->
+ pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
| Bool _ | Int _ | Int64 _ | Pointer _ -> ()
) args;
(* Convert integer arguments. *)
@@ -161,7 +162,7 @@ assocListOfHashtable (a:b:rest) = (a,b) : assocListOfHashtable rest
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n
| String n | OptString n
- | StringList n | DeviceList n
+ | StringList n | DeviceList n | FilenameList n
| Key n | GUID n -> n
| BufferIn n -> sprintf "%s (fromIntegral %s_size)" n n
) args in
@@ -224,7 +225,7 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) =
pr "CString -> CInt"
| OptString _ ->
pr "CString"
- | StringList _ | DeviceList _ ->
+ | StringList _ | DeviceList _ | FilenameList _ ->
pr "Ptr CString"
| Bool _ -> pr "CInt"
| Int _ -> pr "CInt"
@@ -267,7 +268,7 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) =
pr "String"
| OptString _ ->
pr "Maybe String"
- | StringList _ | DeviceList _ ->
+ | StringList _ | DeviceList _ | FilenameList _ ->
pr "[String]"
| Bool _ -> pr "Bool"
| Int _ -> pr "Int"
diff --git a/generator/java.ml b/generator/java.ml
index 4c89197..93266cb 100644
--- a/generator/java.ml
+++ b/generator/java.ml
@@ -485,7 +485,7 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
pr "String %s" n
| BufferIn n ->
pr "byte[] %s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr "String[] %s" n
| Bool n ->
pr "boolean %s" n
@@ -846,7 +846,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
pr ", jstring j%s" n
| BufferIn n ->
pr ", jbyteArray j%s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr ", jobjectArray j%s" n
| Bool n ->
pr ", jboolean j%s" n
@@ -917,7 +917,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| BufferIn n ->
pr " char *%s;\n" n;
pr " size_t %s_size;\n" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " size_t %s_len;\n" n;
pr " char **%s;\n" n
| Bool n
@@ -979,7 +979,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| BufferIn n ->
pr " %s = (char *) (*env)->GetByteArrayElements (env, j%s, NULL);\n" n n;
pr " %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
pr " %s = guestfs_int_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n;
pr " for (i = 0; i < %s_len; ++i) {\n" n;
@@ -1044,7 +1044,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
| BufferIn n ->
pr " (*env)->ReleaseByteArrayElements (env, j%s, (jbyte *) %s, 0);\n" n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " for (i = 0; i < %s_len; ++i) {\n" n;
pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
n;
diff --git a/generator/lua.ml b/generator/lua.ml
index 630d805..7c0e93f 100644
--- a/generator/lua.ml
+++ b/generator/lua.ml
@@ -474,7 +474,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
pr " size_t %s_size;\n" n;
| OptString n ->
pr " const char *%s;\n" n;
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " char **%s;\n" n
| Bool n -> pr " int %s;\n" n
| Int n -> pr " int %s;\n" n
@@ -504,7 +504,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
pr " %s = luaL_checklstring (L, %d, &%s_size);\n" n i n
| OptString n ->
pr " %s = luaL_optstring (L, %d, NULL);\n" n i
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " %s = get_string_list (L, %d);\n" n i
| Bool n ->
pr " %s = lua_toboolean (L, %d);\n" n i
@@ -564,7 +564,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
| BufferIn _ | OptString _
| Bool _ | Int _ | Int64 _
| Pointer _ | GUID _ -> ()
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " free (%s);\n" n
) args;
List.iter (
diff --git a/generator/ocaml.ml b/generator/ocaml.ml
index 5d92fcb..4bbe5bc 100644
--- a/generator/ocaml.ml
+++ b/generator/ocaml.ml
@@ -600,7 +600,7 @@ copy_table (char * const * argv)
| BufferIn n ->
pr " size_t %s_size = caml_string_length (%sv);\n" n n;
pr " char *%s = guestfs_int_safe_memdup (g, String_val (%sv), %s_size);\n" n n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n
| Bool n ->
pr " int %s = Bool_val (%sv);\n" n n
@@ -677,7 +677,7 @@ copy_table (char * const * argv)
| OptString n | FileIn n | FileOut n | BufferIn n
| Key n | GUID n ->
pr " free (%s);\n" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " guestfs_int_free_string_list (%s);\n" n;
| Bool _ | Int _ | Int64 _ | Pointer _ -> ()
) args;
@@ -850,7 +850,8 @@ and generate_ocaml_function_type ?(extra_unit = false) (ret, args, optargs) =
| FileIn _ | FileOut _ | BufferIn _ | Key _
| GUID _ -> pr "string -> "
| OptString _ -> pr "string option -> "
- | StringList _ | DeviceList _ -> pr "string array -> "
+ | StringList _ | DeviceList _ | FilenameList _ ->
+ pr "string array -> "
| Bool _ -> pr "bool -> "
| Int _ -> pr "int -> "
| Int64 _ | Pointer _ -> pr "int64 -> "
diff --git a/generator/perl.ml b/generator/perl.ml
index dcd180f..81973e4 100644
--- a/generator/perl.ml
+++ b/generator/perl.ml
@@ -365,7 +365,8 @@ PREINIT:
* to add 1 to the ST(x) operator.
*)
pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
- | StringList n | DeviceList n -> pr " char **%s;\n" n
+ | StringList n | DeviceList n | FilenameList n ->
+ pr " char **%s;\n" n
| Bool n -> pr " int %s;\n" n
| Int n -> pr " int %s;\n" n
| Int64 n -> pr " int64_t %s;\n" n
@@ -510,7 +511,8 @@ PREINIT:
| OptString _ | Bool _ | Int _ | Int64 _
| FileIn _ | FileOut _
| BufferIn _ | Key _ | Pointer _ | GUID _ -> ()
- | StringList n | DeviceList n -> pr " free (%s);\n" n
+ | StringList n | DeviceList n | FilenameList n ->
+ pr " free (%s);\n" n
) args;
(* Check return value for errors and return it if necessary. *)
@@ -955,6 +957,7 @@ errnos:
| Int n -> pr "[ '%s', 'int', %d ]" n i
| Int64 n -> pr "[ '%s', 'int64', %d ]" n i
| Pointer (t, n) -> pr "[ '%s', 'pointer(%s)', %d ]" n t i
+ | FilenameList n -> pr "[ '%s', 'string(path) list', %d ]" n i
in
pr " args => [\n";
iteri (fun i arg ->
@@ -1113,7 +1116,7 @@ and generate_perl_prototype name (ret, args, optargs) =
| OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
| BufferIn n | Key n | Pointer (_, n) | GUID n ->
pr "$%s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr "\\@%s" n
) args;
List.iter (
diff --git a/generator/php.ml b/generator/php.ml
index b49bf60..cb0543a 100644
--- a/generator/php.ml
+++ b/generator/php.ml
@@ -240,7 +240,8 @@ PHP_FUNCTION (guestfs_last_error)
pr " char *%s = NULL;\n" n;
pr " int %s_size;\n" n
| StringList n
- | DeviceList n ->
+ | DeviceList n
+ | FilenameList n ->
pr " zval *z_%s;\n" n;
pr " char **%s;\n" n;
| Bool n ->
@@ -284,7 +285,7 @@ PHP_FUNCTION (guestfs_last_error)
| FileIn n | FileOut n | BufferIn n | Key n
| GUID n -> "s"
| OptString n -> "s!"
- | StringList n | DeviceList n -> "a"
+ | StringList n | DeviceList n | FilenameList n -> "a"
| Bool n -> "b"
| Int n | Int64 n -> "l"
| Pointer _ -> ""
@@ -319,7 +320,7 @@ PHP_FUNCTION (guestfs_last_error)
| FileIn n | FileOut n | BufferIn n | Key n
| OptString n | GUID n ->
pr ", &%s, &%s_size" n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr ", &z_%s" n
| Bool n ->
pr ", &%s" n
@@ -372,7 +373,8 @@ PHP_FUNCTION (guestfs_last_error)
pr "\n"
| BufferIn n -> ()
| StringList n
- | DeviceList n ->
+ | DeviceList n
+ | FilenameList n ->
pr " %s = get_stringlist (z_%s);\n" n n;
pr "\n"
| Bool _ | Int _ | Int64 _ -> ()
@@ -453,7 +455,8 @@ PHP_FUNCTION (guestfs_last_error)
| OptString n | GUID n -> ()
| BufferIn n -> ()
| StringList n
- | DeviceList n ->
+ | DeviceList n
+ | FilenameList n ->
pr " guestfs_efree_stringlist (%s);\n" n;
pr "\n"
| Bool _ | Int _ | Int64 _ | Pointer _ -> ()
diff --git a/generator/python.ml b/generator/python.ml
index 1e043fc..9b3037c 100644
--- a/generator/python.ml
+++ b/generator/python.ml
@@ -292,7 +292,7 @@ put_table (char * const * const argv)
| BufferIn n ->
pr " const char *%s;\n" n;
pr " Py_ssize_t %s_size;\n" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " PyObject *py_%s;\n" n;
pr " char **%s = NULL;\n" n
| Bool n -> pr " int %s;\n" n
@@ -326,7 +326,7 @@ put_table (char * const * const argv)
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | GUID _ -> pr "s"
| OptString _ -> pr "z"
- | StringList _ | DeviceList _ -> pr "O"
+ | StringList _ | DeviceList _ | FilenameList _ -> pr "O"
| Bool _ -> pr "i" (* XXX Python has booleans? *)
| Int _ -> pr "i"
| Int64 _ ->
@@ -349,7 +349,8 @@ put_table (char * const * const argv)
| Dev_or_Path n | Mountable_or_Path n | String n | Key n
| FileIn n | FileOut n | GUID n -> pr ", &%s" n
| OptString n -> pr ", &%s" n
- | StringList n | DeviceList n -> pr ", &py_%s" n
+ | StringList n | DeviceList n | FilenameList n ->
+ pr ", &py_%s" n
| Bool n -> pr ", &%s" n
| Int n -> pr ", &%s" n
| Int64 n -> pr ", &%s" n
@@ -372,7 +373,7 @@ put_table (char * const * const argv)
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
| BufferIn _ | GUID _ -> ()
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " %s = get_string_list (py_%s);\n" n n;
pr " if (!%s) goto out;\n" n
| Pointer (_, n) ->
@@ -522,7 +523,7 @@ put_table (char * const * const argv)
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
| BufferIn _ | Pointer _ | GUID _ -> ()
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " free (%s);\n" n
) args;
@@ -829,7 +830,7 @@ class GuestFS(object):
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
| BufferIn _ | GUID _ -> ()
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " %s = list (%s)\n" n n
| Pointer (_, n) ->
pr " %s = %s.c_pointer()\n" n n
diff --git a/generator/ruby.ml b/generator/ruby.ml
index cb187b0..e2761c7 100644
--- a/generator/ruby.ml
+++ b/generator/ruby.ml
@@ -582,7 +582,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
pr " size_t %s_size = RSTRING_LEN (%sv);\n" n n
| OptString n ->
pr " const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " char **%s;\n" n;
pr " Check_Type (%sv, T_ARRAY);\n" n;
pr " {\n";
@@ -677,7 +677,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
| BufferIn _ | Pointer _ | GUID _ -> ()
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | FilenameList n ->
pr " free (%s);\n" n
) args;
diff --git a/generator/tests_c_api.ml b/generator/tests_c_api.ml
index 1522eff..6be753f 100644
--- a/generator/tests_c_api.ml
+++ b/generator/tests_c_api.ml
@@ -419,7 +419,8 @@ and generate_test_command_call ?(expect_error = false) ?test ?ret test_name cmd=
| DeviceList _, "", sym ->
pr " const char *const %s[1] = { NULL };\n" sym
| StringList _, arg, sym
- | DeviceList _, arg, sym ->
+ | DeviceList _, arg, sym
+ | FilenameList _, arg, sym ->
let strs = string_split " " arg in
iteri (
fun i str ->
@@ -527,7 +528,9 @@ and generate_test_command_call ?(expect_error = false) ?test ?ret test_name cmd=
| GUID _, _, sym -> pr ", %s" sym
| BufferIn _, _, sym -> pr ", %s, %s_size" sym sym
| FileOut _, arg, _ -> pr ", \"%s\"" (c_quote arg)
- | StringList _, _, sym | DeviceList _, _, sym -> pr ", (char **) %s" sym
+ | StringList _, _, sym | DeviceList _, _, sym
+ | FilenameList _, _, sym ->
+ pr ", (char **) %s" sym
| Int _, arg, _ ->
let i =
try int_of_string arg
diff --git a/generator/types.ml b/generator/types.ml
index 83a6a98..0d22e0c 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -190,6 +190,11 @@ and argt =
* guestfs_int_validate_guid.
*)
| GUID of string
+ (* List of file names only, where the list cannot be NULL,
+ * and each element cannot be NULL, empty, or anything different than
+ * a simple file name (i.e. neither absolute nor relative paths).
+ *)
+ | FilenameList of string
and optargs = optargt list
diff --git a/generator/utils.ml b/generator/utils.ml
index 1b00ce5..7d47430 100644
--- a/generator/utils.ml
+++ b/generator/utils.ml
@@ -254,7 +254,7 @@ let name_of_argt = function
| Mountable_or_Path n | String n | OptString n
| StringList n | DeviceList n | Bool n | Int n | Int64 n
| FileIn n | FileOut n | BufferIn n | Key n | Pointer (_, n)
- | GUID n -> n
+ | GUID n | FilenameList n -> n
let name_of_optargt = function
| OBool n | OInt n | OInt64 n | OString n | OStringList n -> n
diff --git a/generator/xdr.ml b/generator/xdr.ml
index 37a52b7..037be1e 100644
--- a/generator/xdr.ml
+++ b/generator/xdr.ml
@@ -115,7 +115,8 @@ let generate_xdr () =
| Key n | GUID n ->
pr " string %s<>;\n" n
| OptString n -> pr " guestfs_str *%s;\n" n
- | StringList n | DeviceList n -> pr " guestfs_str %s<>;\n" n
+ | StringList n | DeviceList n | FilenameList n ->
+ pr " guestfs_str %s<>;\n" n
| Bool n -> pr " bool %s;\n" n
| Int n -> pr " int %s;\n" n
| Int64 n -> pr " int64_t %s;\n" n
--
2.1.0
9 years, 2 months
[PATCH] tests: use fake-virt-tools also in tests outside v2v
by Pino Toscano
We have phony tools for v2v tests, introduced with
commit c1af1ba32f126b7be275bcc8cd4ea4e5af27a88e; make use of it also in
tests related to v2v outside the v2v directory.
---
p2v/test-virt-p2v.sh | 6 +-----
tests/regressions/rhbz1232192.sh | 6 +-----
2 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/p2v/test-virt-p2v.sh b/p2v/test-virt-p2v.sh
index 8c3731c..540d2fd 100755
--- a/p2v/test-virt-p2v.sh
+++ b/p2v/test-virt-p2v.sh
@@ -44,11 +44,7 @@ if ! test -f $f2 || ! test -s $f2; then
exit 77
fi
-virt_tools_data_dir=${VIRT_TOOLS_DATA_DIR:-/usr/share/virt-tools}
-if ! test -r $virt_tools_data_dir/rhsrvany.exe; then
- echo "$0: test skipped because rhsrvany.exe is not installed"
- exit 77
-fi
+export VIRT_TOOLS_DATA_DIR="../v2v/fake-virt-tools"
d=test-virt-p2v.d
rm -rf $d
diff --git a/tests/regressions/rhbz1232192.sh b/tests/regressions/rhbz1232192.sh
index 5b4b31e..8cd6453 100755
--- a/tests/regressions/rhbz1232192.sh
+++ b/tests/regressions/rhbz1232192.sh
@@ -47,10 +47,6 @@ if [ ! -f ../guests/blank-disk.img ]; then
exit 77
fi
-virt_tools_data_dir=${VIRT_TOOLS_DATA_DIR:-/usr/share/virt-tools}
-if ! test -r $virt_tools_data_dir/rhsrvany.exe; then
- echo "$0: test skipped because rhsrvany.exe is not installed"
- exit 77
-fi
+export VIRT_TOOLS_DATA_DIR="../../v2v/fake-virt-tools"
../../v2v/virt-v2v -i libvirtxml rhbz1232192.xml -o null --no-copy
--
2.1.0
9 years, 2 months
[PATCH 1/2] generator: add a RelativePathnameList parameter type
by Pino Toscano
Mostly like StringList (so it can used in current StringList
parameters), but checking client- and daemon-side that the elements are
relative paths.
---
generator/bindtests.ml | 3 ++-
generator/c.ml | 29 ++++++++++++++++++++++++-----
generator/csharp.ml | 4 ++--
generator/daemon.ml | 20 ++++++++++++++++++--
generator/erlang.ml | 2 +-
generator/fish.ml | 10 ++++++----
generator/gobject.ml | 7 ++++---
generator/golang.ml | 9 ++++++---
generator/haskell.ml | 9 +++++----
generator/java.ml | 10 +++++-----
generator/lua.ml | 6 +++---
generator/ocaml.ml | 7 ++++---
generator/perl.ml | 9 ++++++---
generator/php.ml | 13 ++++++++-----
generator/python.ml | 13 +++++++------
generator/ruby.ml | 4 ++--
generator/tests_c_api.ml | 7 +++++--
generator/types.ml | 4 ++++
generator/utils.ml | 2 +-
generator/xdr.ml | 3 ++-
20 files changed, 115 insertions(+), 56 deletions(-)
diff --git a/generator/bindtests.ml b/generator/bindtests.ml
index 0959704..1d9ea3e 100644
--- a/generator/bindtests.ml
+++ b/generator/bindtests.ml
@@ -163,7 +163,8 @@ fill_lvm_pv (guestfs_h *g, struct guestfs_lvm_pv *pv, size_t i)
pr " fprintf (fp, \"\\n\");\n";
pr " }\n";
| OptString n -> pr " fprintf (fp, \"%%s\\n\", %s ? %s : \"null\");\n" n n
- | StringList n | DeviceList n -> pr " print_strings (g, %s);\n" n
+ | StringList n | DeviceList n | RelativePathnameList n ->
+ pr " print_strings (g, %s);\n" n
| Bool n -> pr " fprintf (fp, \"%%s\\n\", %s ? \"true\" : \"false\");\n" n
| Int n -> pr " fprintf (fp, \"%%d\\n\", %s);\n" n
| Int64 n -> pr " fprintf (fp, \"%%\" PRIi64 \"\\n\", %s);\n" n
diff --git a/generator/c.ml b/generator/c.ml
index 055b683..183bf94 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -131,7 +131,7 @@ let rec generate_prototype ?(extern = true) ?(static = false)
pr "const mountable_t *%s" n
else
pr "const char *%s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
next ();
pr "char *const *%s" n
| Bool n -> next (); pr "int %s" n
@@ -1252,7 +1252,8 @@ and generate_client_actions hash () =
| DeviceList n
| Key n
| Pointer (_, n)
- | GUID n ->
+ | GUID n
+ | RelativePathnameList n ->
pr " if (%s == NULL) {\n" n;
pr " error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
pr " \"%s\", \"%s\");\n" c_name n;
@@ -1355,6 +1356,23 @@ and generate_client_actions hash () =
pr " }\n";
pr_newline := true
+ | RelativePathnameList n ->
+ pr " {\n";
+ pr " size_t i;\n";
+ pr " for (i = 0; %s[i] != NULL; ++i) {\n" n;
+ pr " if (%s[i][0] == '/') {\n" n;
+ pr " error (g, \"%%s: %%s: path '%%s' must be relative\",\n";
+ pr " \"%s\", \"%s\", %s[i]);\n" c_name n n;
+ let errcode =
+ match errcode_of_ret ret with
+ | `CannotReturnError -> assert false
+ | (`ErrorIsMinusOne |`ErrorIsNULL) as e -> e in
+ pr " return %s;\n" (string_of_errcode errcode);
+ pr " }\n";
+ pr " }\n";
+ pr " }\n";
+ pr_newline := true
+
(* not applicable *)
| String _
| Device _
@@ -1383,7 +1401,7 @@ and generate_client_actions hash () =
let needs_i =
List.exists (function
- | StringList _ | DeviceList _ -> true
+ | StringList _ | DeviceList _ | RelativePathnameList _ -> true
| _ -> false) args ||
List.exists (function
| OStringList _ -> true
@@ -1419,7 +1437,8 @@ and generate_client_actions hash () =
pr " else\n";
pr " fprintf (trace_buffer.fp, \" null\");\n"
| StringList n
- | DeviceList n -> (* string list *)
+ | DeviceList n
+ | RelativePathnameList n -> (* string list *)
pr " fputc (' ', trace_buffer.fp);\n";
pr " fputc ('\"', trace_buffer.fp);\n";
pr " for (i = 0; %s[i]; ++i) {\n" n;
@@ -1735,7 +1754,7 @@ and generate_client_actions hash () =
pr " args.%s = (char *) %s;\n" n n
| OptString n ->
pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " args.%s.%s_val = (char **) %s;\n" n n n;
pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
| Bool n ->
diff --git a/generator/csharp.ml b/generator/csharp.ml
index e2bd25b..59f7be9 100644
--- a/generator/csharp.ml
+++ b/generator/csharp.ml
@@ -195,7 +195,7 @@ namespace Guestfs
| BufferIn n
| GUID n ->
pr ", [In] string %s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr ", [In] string[] %s" n
| Bool n ->
pr ", bool %s" n
@@ -224,7 +224,7 @@ namespace Guestfs
| BufferIn n
| GUID n ->
next (); pr "string %s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
next (); pr "string[] %s" n
| Bool n ->
next (); pr "bool %s" n
diff --git a/generator/daemon.ml b/generator/daemon.ml
index 1825de4..e6093a3 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -255,7 +255,7 @@ cleanup_free_mountable (mountable_t *mountable)
| Mountable n | Mountable_or_Path n ->
pr " CLEANUP_FREE_MOUNTABLE mountable_t %s\n" n;
pr " = { .device = NULL, .volume = NULL };\n"
- | StringList n ->
+ | StringList n | RelativePathnameList n ->
pr " char **%s;\n" n
| DeviceList n ->
pr " CLEANUP_FREE_STRING_LIST char **%s = NULL;\n" n
@@ -344,7 +344,23 @@ cleanup_free_mountable (mountable_t *mountable)
n n (if is_filein then "cancel_receive ()" else "");
| String n | Key n | GUID n -> pr_args n
| OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
- | StringList n ->
+ | StringList n | RelativePathnameList n as arg ->
+ (match arg with
+ | RelativePathnameList n ->
+ pr " {\n";
+ pr " size_t i;\n";
+ pr " for (i = 0; i < args.%s.%s_len; ++i) {\n" n n;
+ pr " if (args.%s.%s_val[i][0] == '/') {\n" n n;
+ if is_filein then
+ pr " cancel_receive ();\n";
+ pr " reply_with_error (\"%%s: path '%%s' must be relative\", __func__, args.%s.%s_val[i]);\n"
+ n n;
+ pr " goto done;\n";
+ pr " }\n";
+ pr " }\n";
+ pr " }\n"
+ | _ -> ()
+ );
pr " /* Ugly, but safe and avoids copying the strings. */\n";
pr " %s = realloc (args.%s.%s_val,\n" n n n;
pr " sizeof (char *) * (args.%s.%s_len+1));\n" n n;
diff --git a/generator/erlang.ml b/generator/erlang.ml
index 5d4faaf..c09d97c 100644
--- a/generator/erlang.ml
+++ b/generator/erlang.ml
@@ -310,7 +310,7 @@ extern int64_t get_int64 (ETERM *term);
pr " ETERM *%s_bin = erl_iolist_to_binary (ARG (%d));\n" n i;
pr " const void *%s = ERL_BIN_PTR (%s_bin);\n" n n;
pr " size_t %s_size = ERL_BIN_SIZE (%s_bin);\n" n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " CLEANUP_FREE_STRING_LIST char **%s = get_string_list (ARG (%d));\n" n i
| Bool n ->
pr " int %s = get_bool (ARG (%d));\n" n i
diff --git a/generator/fish.ml b/generator/fish.ml
index 6f68e65..cfbec2a 100644
--- a/generator/fish.ml
+++ b/generator/fish.ml
@@ -376,7 +376,8 @@ Guestfish will prompt for these separately."
| BufferIn n ->
pr " const char *%s;\n" n;
pr " size_t %s_size;\n" n
- | StringList n | DeviceList n -> pr " char **%s;\n" n
+ | StringList n | DeviceList n | RelativePathnameList n ->
+ pr " char **%s;\n" n
| Bool n -> pr " int %s;\n" n
| Int n -> pr " int %s;\n" n
| Int64 n -> pr " int64_t %s;\n" n
@@ -464,7 +465,7 @@ Guestfish will prompt for these separately."
| FileOut name ->
pr " %s = file_out (argv[i++]);\n" name;
pr " if (%s == NULL) goto out_%s;\n" name name
- | StringList name | DeviceList name ->
+ | StringList name | DeviceList name | RelativePathnameList name ->
pr " %s = parse_string_list (argv[i++]);\n" name;
pr " if (%s == NULL) goto out_%s;\n" name name
| Key name ->
@@ -678,7 +679,7 @@ Guestfish will prompt for these separately."
| FileIn name ->
pr " free_file_in (%s);\n" name;
pr " out_%s:\n" name
- | StringList name | DeviceList name ->
+ | StringList name | DeviceList name | RelativePathnameList name ->
pr " guestfs_int_free_string_list (%s);\n" name;
pr " out_%s:\n" name
| Pointer _ -> assert false
@@ -917,7 +918,8 @@ and generate_fish_actions_pod () =
| GUID n ->
pr " %s" n
| OptString n -> pr " %s" n
- | StringList n | DeviceList n -> pr " '%s ...'" n
+ | StringList n | DeviceList n | RelativePathnameList n ->
+ pr " '%s ...'" n
| Bool _ -> pr " true|false"
| Int n -> pr " %s" n
| Int64 n -> pr " %s" n
diff --git a/generator/gobject.ml b/generator/gobject.ml
index 8d5ac06..15f214b 100644
--- a/generator/gobject.ml
+++ b/generator/gobject.ml
@@ -85,7 +85,8 @@ let generate_gobject_proto name ?(single_line = true)
| GUID n ->
pr "const gchar *%s" n
| StringList n
- | DeviceList n ->
+ | DeviceList n
+ | RelativePathnameList n ->
pr "gchar *const *%s" n
| BufferIn n ->
pr "const guint8 *%s, gsize %s_size" n n
@@ -1052,7 +1053,7 @@ guestfs_session_close (GuestfsSession *session, GError **err)
pr " (transfer none) (type filename):"
| StringList _ ->
pr " (transfer none) (array zero-terminated=1) (element-type utf8): an array of strings"
- | DeviceList _ ->
+ | DeviceList _ | RelativePathnameList _ ->
pr " (transfer none) (array zero-terminated=1) (element-type filename): an array of strings"
| BufferIn n ->
pr " (transfer none) (array length=%s_size) (element-type guint8): an array of binary data\n" n;
@@ -1211,7 +1212,7 @@ guestfs_session_close (GuestfsSession *session, GError **err)
| Pathname n | Dev_or_Path n | Mountable_or_Path n
| OptString n | StringList n
| DeviceList n | Key n | FileIn n | FileOut n
- | GUID n ->
+ | GUID n | RelativePathnameList n ->
pr "%s" n
| Pointer (_, n) ->
pr "%s" n
diff --git a/generator/golang.ml b/generator/golang.ml
index b4b2482..cfc5b5b 100644
--- a/generator/golang.ml
+++ b/generator/golang.ml
@@ -315,7 +315,8 @@ func return_hashtable (argv **C.char) map[string]string {
| GUID n -> pr "%s string" n
| OptString n -> pr "%s *string" n
| StringList n
- | DeviceList n -> pr "%s []string" n
+ | DeviceList n
+ | RelativePathnameList n -> pr "%s []string" n
| BufferIn n -> pr "%s []byte" n
| Pointer (_, n) -> pr "%s int64" n
) args;
@@ -380,7 +381,8 @@ func return_hashtable (argv **C.char) map[string]string {
pr " defer C.free (unsafe.Pointer (c_%s))\n" n;
pr " }\n"
| StringList n
- | DeviceList n ->
+ | DeviceList n
+ | RelativePathnameList n ->
pr "\n";
pr " c_%s := arg_string_list (%s)\n" n n;
pr " defer free_string_list (c_%s)\n" n
@@ -455,7 +457,8 @@ func return_hashtable (argv **C.char) map[string]string {
| FileIn n | FileOut n
| GUID n -> pr "c_%s" n
| StringList n
- | DeviceList n -> pr "c_%s" n
+ | DeviceList n
+ | RelativePathnameList n -> pr "c_%s" n
| BufferIn n -> pr "c_%s, C.size_t (len (%s))" n n
| Pointer _ -> pr "nil"
) args;
diff --git a/generator/haskell.ml b/generator/haskell.ml
index 96682e6..7e3e0c2 100644
--- a/generator/haskell.ml
+++ b/generator/haskell.ml
@@ -147,7 +147,8 @@ assocListOfHashtable (a:b:rest) = (a,b) : assocListOfHashtable rest
| BufferIn n ->
pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
| OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
- | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
+ | StringList n | DeviceList n | RelativePathnameList n ->
+ pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
| Bool _ | Int _ | Int64 _ | Pointer _ -> ()
) args;
(* Convert integer arguments. *)
@@ -161,7 +162,7 @@ assocListOfHashtable (a:b:rest) = (a,b) : assocListOfHashtable rest
| Pathname n | Device n | Mountable n
| Dev_or_Path n | Mountable_or_Path n
| String n | OptString n
- | StringList n | DeviceList n
+ | StringList n | DeviceList n | RelativePathnameList n
| Key n | GUID n -> n
| BufferIn n -> sprintf "%s (fromIntegral %s_size)" n n
) args in
@@ -224,7 +225,7 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) =
pr "CString -> CInt"
| OptString _ ->
pr "CString"
- | StringList _ | DeviceList _ ->
+ | StringList _ | DeviceList _ | RelativePathnameList _ ->
pr "Ptr CString"
| Bool _ -> pr "CInt"
| Int _ -> pr "CInt"
@@ -267,7 +268,7 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) =
pr "String"
| OptString _ ->
pr "Maybe String"
- | StringList _ | DeviceList _ ->
+ | StringList _ | DeviceList _ | RelativePathnameList _ ->
pr "[String]"
| Bool _ -> pr "Bool"
| Int _ -> pr "Int"
diff --git a/generator/java.ml b/generator/java.ml
index 4c89197..81fbf9b 100644
--- a/generator/java.ml
+++ b/generator/java.ml
@@ -485,7 +485,7 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
pr "String %s" n
| BufferIn n ->
pr "byte[] %s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr "String[] %s" n
| Bool n ->
pr "boolean %s" n
@@ -846,7 +846,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
pr ", jstring j%s" n
| BufferIn n ->
pr ", jbyteArray j%s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr ", jobjectArray j%s" n
| Bool n ->
pr ", jboolean j%s" n
@@ -917,7 +917,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| BufferIn n ->
pr " char *%s;\n" n;
pr " size_t %s_size;\n" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " size_t %s_len;\n" n;
pr " char **%s;\n" n
| Bool n
@@ -979,7 +979,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| BufferIn n ->
pr " %s = (char *) (*env)->GetByteArrayElements (env, j%s, NULL);\n" n n;
pr " %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
pr " %s = guestfs_int_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n;
pr " for (i = 0; i < %s_len; ++i) {\n" n;
@@ -1044,7 +1044,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
| BufferIn n ->
pr " (*env)->ReleaseByteArrayElements (env, j%s, (jbyte *) %s, 0);\n" n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " for (i = 0; i < %s_len; ++i) {\n" n;
pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
n;
diff --git a/generator/lua.ml b/generator/lua.ml
index 630d805..ea47739 100644
--- a/generator/lua.ml
+++ b/generator/lua.ml
@@ -474,7 +474,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
pr " size_t %s_size;\n" n;
| OptString n ->
pr " const char *%s;\n" n;
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " char **%s;\n" n
| Bool n -> pr " int %s;\n" n
| Int n -> pr " int %s;\n" n
@@ -504,7 +504,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
pr " %s = luaL_checklstring (L, %d, &%s_size);\n" n i n
| OptString n ->
pr " %s = luaL_optstring (L, %d, NULL);\n" n i
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " %s = get_string_list (L, %d);\n" n i
| Bool n ->
pr " %s = lua_toboolean (L, %d);\n" n i
@@ -564,7 +564,7 @@ guestfs_lua_delete_event_callback (lua_State *L)
| BufferIn _ | OptString _
| Bool _ | Int _ | Int64 _
| Pointer _ | GUID _ -> ()
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " free (%s);\n" n
) args;
List.iter (
diff --git a/generator/ocaml.ml b/generator/ocaml.ml
index 5d92fcb..d8ab3b1 100644
--- a/generator/ocaml.ml
+++ b/generator/ocaml.ml
@@ -600,7 +600,7 @@ copy_table (char * const * argv)
| BufferIn n ->
pr " size_t %s_size = caml_string_length (%sv);\n" n n;
pr " char *%s = guestfs_int_safe_memdup (g, String_val (%sv), %s_size);\n" n n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n
| Bool n ->
pr " int %s = Bool_val (%sv);\n" n n
@@ -677,7 +677,7 @@ copy_table (char * const * argv)
| OptString n | FileIn n | FileOut n | BufferIn n
| Key n | GUID n ->
pr " free (%s);\n" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " guestfs_int_free_string_list (%s);\n" n;
| Bool _ | Int _ | Int64 _ | Pointer _ -> ()
) args;
@@ -850,7 +850,8 @@ and generate_ocaml_function_type ?(extra_unit = false) (ret, args, optargs) =
| FileIn _ | FileOut _ | BufferIn _ | Key _
| GUID _ -> pr "string -> "
| OptString _ -> pr "string option -> "
- | StringList _ | DeviceList _ -> pr "string array -> "
+ | StringList _ | DeviceList _ | RelativePathnameList _ ->
+ pr "string array -> "
| Bool _ -> pr "bool -> "
| Int _ -> pr "int -> "
| Int64 _ | Pointer _ -> pr "int64 -> "
diff --git a/generator/perl.ml b/generator/perl.ml
index dcd180f..f1d5d6d 100644
--- a/generator/perl.ml
+++ b/generator/perl.ml
@@ -365,7 +365,8 @@ PREINIT:
* to add 1 to the ST(x) operator.
*)
pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
- | StringList n | DeviceList n -> pr " char **%s;\n" n
+ | StringList n | DeviceList n | RelativePathnameList n ->
+ pr " char **%s;\n" n
| Bool n -> pr " int %s;\n" n
| Int n -> pr " int %s;\n" n
| Int64 n -> pr " int64_t %s;\n" n
@@ -510,7 +511,8 @@ PREINIT:
| OptString _ | Bool _ | Int _ | Int64 _
| FileIn _ | FileOut _
| BufferIn _ | Key _ | Pointer _ | GUID _ -> ()
- | StringList n | DeviceList n -> pr " free (%s);\n" n
+ | StringList n | DeviceList n | RelativePathnameList n ->
+ pr " free (%s);\n" n
) args;
(* Check return value for errors and return it if necessary. *)
@@ -955,6 +957,7 @@ errnos:
| Int n -> pr "[ '%s', 'int', %d ]" n i
| Int64 n -> pr "[ '%s', 'int64', %d ]" n i
| Pointer (t, n) -> pr "[ '%s', 'pointer(%s)', %d ]" n t i
+ | RelativePathnameList n -> pr "[ '%s', 'string(path) list', %d ]" n i
in
pr " args => [\n";
iteri (fun i arg ->
@@ -1113,7 +1116,7 @@ and generate_perl_prototype name (ret, args, optargs) =
| OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
| BufferIn n | Key n | Pointer (_, n) | GUID n ->
pr "$%s" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr "\\@%s" n
) args;
List.iter (
diff --git a/generator/php.ml b/generator/php.ml
index b49bf60..82e0cd4 100644
--- a/generator/php.ml
+++ b/generator/php.ml
@@ -240,7 +240,8 @@ PHP_FUNCTION (guestfs_last_error)
pr " char *%s = NULL;\n" n;
pr " int %s_size;\n" n
| StringList n
- | DeviceList n ->
+ | DeviceList n
+ | RelativePathnameList n ->
pr " zval *z_%s;\n" n;
pr " char **%s;\n" n;
| Bool n ->
@@ -284,7 +285,7 @@ PHP_FUNCTION (guestfs_last_error)
| FileIn n | FileOut n | BufferIn n | Key n
| GUID n -> "s"
| OptString n -> "s!"
- | StringList n | DeviceList n -> "a"
+ | StringList n | DeviceList n | RelativePathnameList n -> "a"
| Bool n -> "b"
| Int n | Int64 n -> "l"
| Pointer _ -> ""
@@ -319,7 +320,7 @@ PHP_FUNCTION (guestfs_last_error)
| FileIn n | FileOut n | BufferIn n | Key n
| OptString n | GUID n ->
pr ", &%s, &%s_size" n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr ", &z_%s" n
| Bool n ->
pr ", &%s" n
@@ -372,7 +373,8 @@ PHP_FUNCTION (guestfs_last_error)
pr "\n"
| BufferIn n -> ()
| StringList n
- | DeviceList n ->
+ | DeviceList n
+ | RelativePathnameList n ->
pr " %s = get_stringlist (z_%s);\n" n n;
pr "\n"
| Bool _ | Int _ | Int64 _ -> ()
@@ -453,7 +455,8 @@ PHP_FUNCTION (guestfs_last_error)
| OptString n | GUID n -> ()
| BufferIn n -> ()
| StringList n
- | DeviceList n ->
+ | DeviceList n
+ | RelativePathnameList n ->
pr " guestfs_efree_stringlist (%s);\n" n;
pr "\n"
| Bool _ | Int _ | Int64 _ | Pointer _ -> ()
diff --git a/generator/python.ml b/generator/python.ml
index 1e043fc..b8329a5 100644
--- a/generator/python.ml
+++ b/generator/python.ml
@@ -292,7 +292,7 @@ put_table (char * const * const argv)
| BufferIn n ->
pr " const char *%s;\n" n;
pr " Py_ssize_t %s_size;\n" n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " PyObject *py_%s;\n" n;
pr " char **%s = NULL;\n" n
| Bool n -> pr " int %s;\n" n
@@ -326,7 +326,7 @@ put_table (char * const * const argv)
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | GUID _ -> pr "s"
| OptString _ -> pr "z"
- | StringList _ | DeviceList _ -> pr "O"
+ | StringList _ | DeviceList _ | RelativePathnameList _ -> pr "O"
| Bool _ -> pr "i" (* XXX Python has booleans? *)
| Int _ -> pr "i"
| Int64 _ ->
@@ -349,7 +349,8 @@ put_table (char * const * const argv)
| Dev_or_Path n | Mountable_or_Path n | String n | Key n
| FileIn n | FileOut n | GUID n -> pr ", &%s" n
| OptString n -> pr ", &%s" n
- | StringList n | DeviceList n -> pr ", &py_%s" n
+ | StringList n | DeviceList n | RelativePathnameList n ->
+ pr ", &py_%s" n
| Bool n -> pr ", &%s" n
| Int n -> pr ", &%s" n
| Int64 n -> pr ", &%s" n
@@ -372,7 +373,7 @@ put_table (char * const * const argv)
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
| BufferIn _ | GUID _ -> ()
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " %s = get_string_list (py_%s);\n" n n;
pr " if (!%s) goto out;\n" n
| Pointer (_, n) ->
@@ -522,7 +523,7 @@ put_table (char * const * const argv)
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
| BufferIn _ | Pointer _ | GUID _ -> ()
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " free (%s);\n" n
) args;
@@ -829,7 +830,7 @@ class GuestFS(object):
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
| BufferIn _ | GUID _ -> ()
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " %s = list (%s)\n" n n
| Pointer (_, n) ->
pr " %s = %s.c_pointer()\n" n n
diff --git a/generator/ruby.ml b/generator/ruby.ml
index cb187b0..5e22ed0 100644
--- a/generator/ruby.ml
+++ b/generator/ruby.ml
@@ -582,7 +582,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
pr " size_t %s_size = RSTRING_LEN (%sv);\n" n n
| OptString n ->
pr " const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " char **%s;\n" n;
pr " Check_Type (%sv, T_ARRAY);\n" n;
pr " {\n";
@@ -677,7 +677,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn)
| Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
| BufferIn _ | Pointer _ | GUID _ -> ()
- | StringList n | DeviceList n ->
+ | StringList n | DeviceList n | RelativePathnameList n ->
pr " free (%s);\n" n
) args;
diff --git a/generator/tests_c_api.ml b/generator/tests_c_api.ml
index 1522eff..c5af42f 100644
--- a/generator/tests_c_api.ml
+++ b/generator/tests_c_api.ml
@@ -419,7 +419,8 @@ and generate_test_command_call ?(expect_error = false) ?test ?ret test_name cmd=
| DeviceList _, "", sym ->
pr " const char *const %s[1] = { NULL };\n" sym
| StringList _, arg, sym
- | DeviceList _, arg, sym ->
+ | DeviceList _, arg, sym
+ | RelativePathnameList _, arg, sym ->
let strs = string_split " " arg in
iteri (
fun i str ->
@@ -527,7 +528,9 @@ and generate_test_command_call ?(expect_error = false) ?test ?ret test_name cmd=
| GUID _, _, sym -> pr ", %s" sym
| BufferIn _, _, sym -> pr ", %s, %s_size" sym sym
| FileOut _, arg, _ -> pr ", \"%s\"" (c_quote arg)
- | StringList _, _, sym | DeviceList _, _, sym -> pr ", (char **) %s" sym
+ | StringList _, _, sym | DeviceList _, _, sym
+ | RelativePathnameList _, _, sym ->
+ pr ", (char **) %s" sym
| Int _, arg, _ ->
let i =
try int_of_string arg
diff --git a/generator/types.ml b/generator/types.ml
index 83a6a98..156df3b 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -190,6 +190,10 @@ and argt =
* guestfs_int_validate_guid.
*)
| GUID of string
+ (* List of file names, where the list cannot be NULL, and each
+ * filename cannot be NULL, empty, or an absolute path.
+ *)
+ | RelativePathnameList of string
and optargs = optargt list
diff --git a/generator/utils.ml b/generator/utils.ml
index 1b00ce5..5b97b2b 100644
--- a/generator/utils.ml
+++ b/generator/utils.ml
@@ -254,7 +254,7 @@ let name_of_argt = function
| Mountable_or_Path n | String n | OptString n
| StringList n | DeviceList n | Bool n | Int n | Int64 n
| FileIn n | FileOut n | BufferIn n | Key n | Pointer (_, n)
- | GUID n -> n
+ | GUID n | RelativePathnameList n -> n
let name_of_optargt = function
| OBool n | OInt n | OInt64 n | OString n | OStringList n -> n
diff --git a/generator/xdr.ml b/generator/xdr.ml
index 37a52b7..aef5c1e 100644
--- a/generator/xdr.ml
+++ b/generator/xdr.ml
@@ -115,7 +115,8 @@ let generate_xdr () =
| Key n | GUID n ->
pr " string %s<>;\n" n
| OptString n -> pr " guestfs_str *%s;\n" n
- | StringList n | DeviceList n -> pr " guestfs_str %s<>;\n" n
+ | StringList n | DeviceList n | RelativePathnameList n ->
+ pr " guestfs_str %s<>;\n" n
| Bool n -> pr " bool %s;\n" n
| Int n -> pr " int %s;\n" n
| Int64 n -> pr " int64_t %s;\n" n
--
2.1.0
9 years, 2 months
Extlinux with guestfish
by slim tabka
Hi everyone,
I'm working with libguestfs 1.30.3 on Centos 7 host.
I encountered a problem when I wanted to install extlinux with guestfish as
a bootloader for my guests and I always get this error:
SYSLINUX 4.05 EDD 0x54f93f16 Copyright (C) 1994-2010 H. Peter Anvin et al
ERROR: No configuration file found
No default or UI configuration directive found!
boot: _
*This is how I create the virtual machines:*
lvcreate -n vm_name -L 9G vm_volumes
parted /dev/vm_volumes/vm_name mklabel msdos
parted -a optimal /dev/vm_volumes/vm_name mkpart primary ext4 0% 100%
parted /dev/vm_volumes/vm_name set 1 boot on
kpartx -av /dev/vm_volumes/vm_name
mkfs.ext4 /dev/mapper/loop0p1
mount /dev/mapper/loop0p1 /mnt/clone
tar -zxf /root/centos7_template.tar.gz -C /mnt/clone/
umount /mnt/clone
kpartx -dv /dev/vm_volumes/vm_name
/root/libguestfs-1.30.3/run guestfish -i -a /dev/vm_volumes/{vm_name}
<< _EOF_ \n\
#####mbr.bin and syslinux already existant in centos7_template.tar.gz####
copy-file-to-device /boot/mbr.bin /dev/sda size:440 \n\
extlinux /boot \n\
part-set-bootable /dev/sda 1 true \n\
_EOF_
*And this is the syslinux.cfg file:*
DEFAULT linux
LABEL linux
SAY Booting the kernel
KERNEL /boot/vmlinuz-3.10.0-229.el7.x86_64
INITRD /boot/initramfs-3.10.0-229.el7.x86_64.img
APPEND ro root=UUID={{ UUID }}
The strange thing is that before I was using a ubuntu 14.04 host with
libguestfs 1.24.5 and everything was working fine all my guests worked
with extlinux as a bootloader and it's a better solution than grub but
when I changed to a Centos7 host the same vm creation script didn't
work.
I don't know where is the problem, is it from guestfish?? or
extlinux?? is there an additional package that I need to install??
Thank you for your time.
Best regards, Slim TABKA
9 years, 2 months
[PATCH] v2v: add --in-place mode
by Roman Kagan
In this mode, converting of the VM configuration, setting up the
rollback path for error cases, transforming the VM storage and so on is
taken care of by a third-party toolset, and virt-v2v is only supposed to
tune up the guest OS directly inside the source VM, to enable it to boot
and run under the input hypervisor.
Signed-off-by: Roman Kagan <rkagan(a)virtuozzo.com>
---
tests/guests/guests.xml.in | 16 +++++++
v2v/Makefile.am | 1 +
v2v/cmdline.ml | 7 +++-
v2v/test-v2v-in-place.sh | 81 +++++++++++++++++++++++++++++++++++
v2v/v2v.ml | 102 +++++++++++++++++++++++++++------------------
v2v/virt-v2v.pod | 17 ++++++++
6 files changed, 183 insertions(+), 41 deletions(-)
create mode 100755 v2v/test-v2v-in-place.sh
diff --git a/tests/guests/guests.xml.in b/tests/guests/guests.xml.in
index 8f7ac81..6f08b80 100644
--- a/tests/guests/guests.xml.in
+++ b/tests/guests/guests.xml.in
@@ -279,4 +279,20 @@
</devices>
</domain>
+ <domain type='test'>
+ <name>windows-overlay</name>
+ <memory>1048576</memory>
+ <os>
+ <type>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2'/>
+ <source file='@abs_builddir(a)/windows-overlay.qcow2'/>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ </devices>
+ </domain>
+
</node>
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index 06da002..dae063c 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -232,6 +232,7 @@ TESTS += \
test-v2v-cdrom.sh \
test-v2v-i-ova.sh \
test-v2v-i-disk.sh \
+ test-v2v-in-place.sh \
test-v2v-machine-readable.sh \
test-v2v-networks-and-bridges.sh \
test-v2v-no-copy.sh \
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index eaf57dc..2a3224a 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -37,6 +37,7 @@ let parse_cmdline () =
let output_format = ref "" in
let output_name = ref "" in
let output_storage = ref "" in
+ let in_place = ref false in
let password_file = ref "" in
let print_source = ref false in
let qemu_boot = ref false in
@@ -160,6 +161,7 @@ let parse_cmdline () =
"-of", Arg.Set_string output_format, "raw|qcow2 " ^ s_"Set output format";
"-on", Arg.Set_string output_name, "name " ^ s_"Rename guest when converting";
"-os", Arg.Set_string output_storage, "storage " ^ s_"Set output storage location";
+ "--in-place", Arg.Set in_place, " " ^ s_"Only tune the guest in the input VM";
"--password-file", Arg.Set_string password_file, "file " ^ s_"Use password from file";
"--print-source", Arg.Set print_source, " " ^ s_"Print source and stop";
"--qemu-boot", Arg.Set qemu_boot, " " ^ s_"Boot in qemu (-o qemu only)";
@@ -226,6 +228,7 @@ read the man page virt-v2v(1).
let output_mode = !output_mode in
let output_name = match !output_name with "" -> None | s -> Some s in
let output_storage = !output_storage in
+ let in_place = !in_place in
let password_file = match !password_file with "" -> None | s -> Some s in
let print_source = !print_source in
let qemu_boot = !qemu_boot in
@@ -305,6 +308,8 @@ read the man page virt-v2v(1).
Input_ova.input_ova filename in
(* Parse the output mode. *)
+ if output_mode <> `Not_set && in_place then
+ error (f_"-o and --in-place cannot be used at the same time");
let output =
match output_mode with
| `Glance ->
@@ -386,5 +391,5 @@ read the man page virt-v2v(1).
input, output,
debug_gc, debug_overlays, do_copy, network_map, no_trim,
- output_alloc, output_format, output_name,
+ output_alloc, output_format, output_name, in_place,
print_source, root_choice
diff --git a/v2v/test-v2v-in-place.sh b/v2v/test-v2v-in-place.sh
new file mode 100755
index 0000000..c19707e
--- /dev/null
+++ b/v2v/test-v2v-in-place.sh
@@ -0,0 +1,81 @@
+#!/bin/bash -
+# libguestfs virt-v2v test script
+# Copyright (C) 2014 Red Hat Inc.
+# Copyright (C) 2015 Parallels IP Holdings GmbH.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Test --in-place.
+
+unset CDPATH
+export LANG=C
+set -e
+
+if [ -n "$SKIP_TEST_V2V_IN_PLACE_SH" ]; then
+ echo "$0: test skipped because environment variable is set"
+ exit 77
+fi
+
+if [ "$(guestfish get-backend)" = "uml" ]; then
+ echo "$0: test skipped because UML backend does not support network"
+ exit 77
+fi
+
+# You shouldn't be running the tests as root anyway, but in this case
+# it's especially bad because we don't want to start creating guests
+# or storage pools in the system namespace.
+if [ "$(id -u)" -eq 0 ]; then
+ echo "$0: test skipped because you're running tests as root. Don't do that!"
+ exit 77
+fi
+
+guests_dir="$(cd $(dirname $0)/../tests/guests && pwd)"
+libvirt_uri="test://$guests_dir/guests.xml"
+
+f="$guests_dir/windows.img"
+if ! test -f $f || ! test -s $f; then
+ echo "$0: test skipped because phony Windows image was not created"
+ exit 77
+fi
+
+virt_tools_data_dir=${VIRT_TOOLS_DATA_DIR:-/usr/share/virt-tools}
+if ! test -r $virt_tools_data_dir/rhsrvany.exe; then
+ echo "$0: test skipped because rhsrvany.exe is not installed"
+ exit 77
+fi
+
+fo="$guests_dir/windows-overlay.qcow2"
+rm -f $fo
+qemu-img create -f qcow2 -b $f -o compat=1.1,backing_fmt=raw $fo
+md5="$(md5sum $f)"
+
+$VG virt-v2v --debug-gc \
+ -i libvirt -ic "$libvirt_uri" windows-overlay \
+ --in-place
+
+# Test some aspects of the target disk image.
+guestfish --ro -a $fo -i <<EOF
+ is-dir "/Program Files/Red Hat/Firstboot"
+ is-file "/Program Files/Red Hat/Firstboot/firstboot.bat"
+ is-dir "/Program Files/Red Hat/Firstboot/scripts"
+ is-dir "/Windows/Drivers/VirtIO"
+EOF
+
+
+# Test the base image remained untouched
+test "$md5" = "$(md5sum $f)"
+
+# Clean up.
+rm -r $fo
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 242f129..b744056 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -47,7 +47,8 @@ let rec main () =
(* Handle the command line. *)
let input, output,
debug_gc, debug_overlays, do_copy, network_map, no_trim,
- output_alloc, output_format, output_name, print_source, root_choice =
+ output_alloc, output_format, output_name, in_place, print_source,
+ root_choice =
Cmdline.parse_cmdline () in
(* Print the version, easier than asking users to tell us. *)
@@ -117,52 +118,70 @@ let rec main () =
) nics in
{ source with s_nics = nics } in
- (* Create a qcow2 v3 overlay to protect the source image(s). There
- * is a specific reason to use the newer qcow2 variant: Because the
- * L2 table can store zero clusters efficiently, and because
- * discarded blocks are stored as zero clusters, this should allow us
- * to fstrim/blkdiscard and avoid copying significant parts of the
- * data over the wire.
- *)
- message (f_"Creating an overlay to protect the source from being modified");
let overlay_dir = (new Guestfs.guestfs ())#get_cachedir () in
- let overlays =
- List.map (
- fun ({ s_qemu_uri = qemu_uri; s_format = format } as source) ->
- let overlay_file =
- Filename.temp_file ~temp_dir:overlay_dir "v2vovl" ".qcow2" in
- unlink_on_exit overlay_file;
-
- let options =
- "compat=1.1" ^
- (match format with None -> ""
- | Some fmt -> ",backing_fmt=" ^ fmt) in
- let cmd =
- sprintf "qemu-img create -q -f qcow2 -b %s -o %s %s"
- (quote qemu_uri) (quote options) overlay_file in
- if verbose () then printf "%s\n%!" cmd;
- if Sys.command cmd <> 0 then
- error (f_"qemu-img command failed, see earlier errors");
-
- (* Sanity check created overlay (see below). *)
- if not ((new G.guestfs ())#disk_has_backing_file overlay_file) then
- error (f_"internal error: qemu-img did not create overlay with backing file");
-
- overlay_file, source
- ) source.s_disks in
+ let overlays = (
+ if not in_place then (
+ (* Create a qcow2 v3 overlay to protect the source image(s). There
+ * is a specific reason to use the newer qcow2 variant: Because the
+ * L2 table can store zero clusters efficiently, and because
+ * discarded blocks are stored as zero clusters, this should allow us
+ * to fstrim/blkdiscard and avoid copying significant parts of the
+ * data over the wire.
+ *)
+ message (f_"Creating an overlay to protect the source from being modified");
+ List.map (
+ fun ({ s_qemu_uri = qemu_uri; s_format = format } as source) ->
+ let overlay_file =
+ Filename.temp_file ~temp_dir:overlay_dir "v2vovl" ".qcow2" in
+ unlink_on_exit overlay_file;
+
+ let options =
+ "compat=1.1" ^
+ (match format with None -> ""
+ | Some fmt -> ",backing_fmt=" ^ fmt) in
+ let cmd =
+ sprintf "qemu-img create -q -f qcow2 -b %s -o %s %s"
+ (quote qemu_uri) (quote options) overlay_file in
+ if verbose () then printf "%s\n%!" cmd;
+ if Sys.command cmd <> 0 then
+ error (f_"qemu-img command failed, see earlier errors");
+
+ (* Sanity check created overlay (see below). *)
+ if not ((new G.guestfs ())#disk_has_backing_file overlay_file) then
+ error (f_"internal error: qemu-img did not create overlay with backing file");
+
+ overlay_file, source
+ ) source.s_disks
+ ) else []
+ ) in
(* Open the guestfs handle. *)
- message (f_"Opening the overlay");
+ if in_place then
+ message (f_"Opening the guest disks")
+ else
+ message (f_"Opening the overlay");
let g = new G.guestfs () in
if trace () then g#set_trace true;
if verbose () then g#set_verbose true;
g#set_network true;
- List.iter (
- fun (overlay_file, _) ->
- g#add_drive_opts overlay_file
- ~format:"qcow2" ~cachemode:"unsafe" ~discard:"besteffort"
- ~copyonread:true
- ) overlays;
+ if in_place then (
+ List.iter (
+ fun ({s_qemu_uri = qemu_uri; s_format = format}) ->
+ match format with
+ | None ->
+ g#add_drive_opts qemu_uri ~cachemode:"unsafe" ~discard:"besteffort"
+ | Some fmt ->
+ g#add_drive_opts qemu_uri ~format:fmt ~cachemode:"unsafe"
+ ~discard:"besteffort"
+ ) source.s_disks
+ ) else (
+ List.iter (
+ fun (overlay_file, _) ->
+ g#add_drive_opts overlay_file
+ ~format:"qcow2" ~cachemode:"unsafe" ~discard:"besteffort"
+ ~copyonread:true
+ ) overlays
+ );
g#launch ();
@@ -294,6 +313,9 @@ let rec main () =
g#shutdown ();
g#close ();
+ if in_place then
+ exit 0;
+
(* Does the guest require UEFI on the target? *)
message (f_"Checking if the guest needs BIOS or UEFI to boot");
let target_firmware =
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
index ef2dee1..eda1cf7 100644
--- a/v2v/virt-v2v.pod
+++ b/v2v/virt-v2v.pod
@@ -9,6 +9,8 @@ virt-v2v - Convert a guest to use KVM
virt-v2v -ic vpx://vcenter.example.com/Datacenter/esxi vmware_guest \
-o rhev -os rhev.nfs:/export_domain --network rhevm
+ virt-v2v -ic qemu:///system qemu_guest --in-place
+
virt-v2v -i libvirtxml guest-domain.xml -o local -os /var/tmp
virt-v2v -i disk disk.img -o local -os /var/tmp
@@ -75,6 +77,9 @@ booting the guest directly in qemu (mainly for testing).
I<-o rhev> is used to write to a RHEV-M / oVirt target. I<-o vdsm>
is only used when virt-v2v runs under VDSM control.
+I<--in-place> instructs virt-v2v to customize the guest OS in the input
+virtual machine, instead of creating a new VM in the target hypervisor.
+
=head1 EXAMPLES
=head2 Convert from VMware vCenter server to local libvirt
@@ -518,6 +523,18 @@ C<root>.
You will get an error if virt-v2v is unable to mount/write to the
Export Storage Domain.
+=item B<--in-place>
+
+Do not create an output virtual machine in the target hypervisor.
+Instead, adjust the guest OS in the source VM to run in the input
+hypervisor.
+
+This mode is meant for integration with other toolsets, which take the
+responsibility of converting the VM configuration, providing for
+rollback in case of errors, transforming the storage, etc.
+
+Conflicts with all I<-o *> options.
+
=item B<--password-file> file
Instead of asking for password(s) interactively, pass the password
--
2.4.3
9 years, 2 months