libguestfs/0005-generator-Implement-struct-FDevice-type.patch
Richard W.M. Jones 96b6a35bd4 Rebase to libguestfs 1.55.8
resolves: RHEL-81733
Fix virt-v2v conversion of split /usr Ubuntu 22+
resolves: RHEL-87622

Remove dependencies on oUnit, flex, bison
2025-04-16 22:05:30 +01:00

492 lines
20 KiB
Diff

From 0ff73a42c7f4f309fbab11ea2e89ee6f0501367d Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 16 Apr 2025 11:35:13 +0100
Subject: [PATCH] generator: Implement struct FDevice type
This acts just like FString except that we do reverse device name
translation on it. The only use is in the 'pvs-full' API where we
will use it (in a subsequent commit) to reverse translate the pv_name
field (a device name) before returning it from the daemon.
Compare this to the 'pvs' API which also returns a list of device
names, but using the generator's 'RStructList (RDevice,...)' return
type, where RDevice is similarly reverse translated.
Note in the library-side bindings, because the name has already been
translated in the daemon, we just treat it exactly the same as
FString. The vast majority of this patch is this mechanical change.
---
generator/GObject.ml | 6 +++---
generator/OCaml.ml | 6 ++----
generator/XDR.ml | 2 +-
generator/c.ml | 20 +++++++++-----------
generator/csharp.ml | 2 +-
generator/daemon.ml | 30 ++++++++++++++++++++++++++----
generator/erlang.ml | 2 +-
generator/golang.ml | 4 ++--
generator/java.ml | 7 ++++---
generator/lua.ml | 2 +-
generator/perl.ml | 4 ++--
generator/php.ml | 4 ++--
generator/python.ml | 2 +-
generator/ruby.ml | 4 ++--
generator/rust.ml | 6 +++---
generator/types.ml | 1 +
generator/types.mli | 1 +
17 files changed, 62 insertions(+), 41 deletions(-)
diff --git a/generator/GObject.ml b/generator/GObject.ml
index b89db690f..87c5b33bf 100644
--- a/generator/GObject.ml
+++ b/generator/GObject.ml
@@ -206,7 +206,7 @@ let generate_gobject_struct_header filename typ cols () =
pr " * @%s: An unsigned 64-bit integer\n" n
| n, FInt64 ->
pr " * @%s: A signed 64-bit integer\n" n
- | n, FString ->
+ | n, (FString|FDevice) ->
pr " * @%s: A NULL-terminated string\n" n
| n, FBuffer ->
pr " * @%s: A GByteArray\n" n
@@ -231,7 +231,7 @@ let generate_gobject_struct_header filename typ cols () =
pr " guint64 %s;\n" n
| n, FInt64 ->
pr " gint64 %s;\n" n
- | n, FString ->
+ | n, (FString|FDevice) ->
pr " gchar *%s;\n" n
| n, FBuffer ->
pr " GByteArray *%s;\n" n
@@ -1228,7 +1228,7 @@ guestfs_session_close (GuestfsSession *session, GError **err)
| n, FUUID ->
pr "%smemcpy (%s%s, %s%s, sizeof (%s%s));\n"
indent dst n src n dst n
- | n, FString ->
+ | n, (FString|FDevice) ->
pr "%sif (%s%s) %s%s = g_strdup (%s%s);\n"
indent src n dst n src n
| n, FBuffer ->
diff --git a/generator/OCaml.ml b/generator/OCaml.ml
index 66ed5e1ae..d4dfe9ed0 100644
--- a/generator/OCaml.ml
+++ b/generator/OCaml.ml
@@ -512,7 +512,7 @@ copy_table (char * const * argv)
List.iteri (
fun i col ->
(match col with
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " v = caml_copy_string (%s->%s);\n" typ name
| name, FBuffer ->
pr " v = caml_alloc_initialized_string (%s->%s_len, %s->%s);\n"
@@ -839,9 +839,7 @@ and generate_ocaml_structure_decls () =
pr "type %s = {\n" typ;
List.iter (
function
- | name, FString -> pr " %s : string;\n" name
- | name, FBuffer -> pr " %s : string;\n" name
- | name, FUUID -> pr " %s : string;\n" name
+ | name, (FString|FDevice|FBuffer|FUUID) -> pr " %s : string;\n" name
| name, (FBytes|FInt64|FUInt64) -> pr " %s : int64;\n" name
| name, (FInt32|FUInt32) -> pr " %s : int32;\n" name
| name, FChar -> pr " %s : char;\n" name
diff --git a/generator/XDR.ml b/generator/XDR.ml
index c5444b501..431959819 100644
--- a/generator/XDR.ml
+++ b/generator/XDR.ml
@@ -66,7 +66,7 @@ let generate_xdr () =
pr "struct guestfs_int_%s {\n" typ;
List.iter (function
| name, FChar -> pr " char %s;\n" name
- | name, FString -> pr " string %s<>;\n" name
+ | name, (FString|FDevice) -> pr " string %s<>;\n" name
| name, FBuffer -> pr " opaque %s<>;\n" name
| name, FUUID -> pr " opaque %s[32];\n" name
| name, FInt32 -> pr " int %s;\n" name
diff --git a/generator/c.ml b/generator/c.ml
index a51031eff..c6e5dd994 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -352,7 +352,7 @@ and generate_structs_pod () =
| name, FInt32 -> pr " int32_t %s;\n" name
| name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
| name, FInt64 -> pr " int64_t %s;\n" name
- | name, FString -> pr " char *%s;\n" name
+ | name, (FString|FDevice) -> pr " char *%s;\n" name
| name, FBuffer ->
pr " /* The next two fields describe a byte array. */\n";
pr " uint32_t %s_len;\n" name;
@@ -609,7 +609,7 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char *
List.iter (
function
| name, FChar -> pr " char %s;\n" name
- | name, FString -> pr " char *%s;\n" name
+ | name, (FString|FDevice) -> pr " char *%s;\n" name
| name, FBuffer ->
pr " uint32_t %s_len;\n" name;
pr " char *%s;\n" name
@@ -916,7 +916,7 @@ and generate_client_structs_compare () =
fun { s_name = typ; s_cols = cols } ->
let has_nonnumeric_cols =
let nonnumeric = function
- | _,(FString|FUUID|FBuffer) -> true
+ | _,(FString|FDevice|FUUID|FBuffer) -> true
| _,(FChar|FUInt32|FInt32|FUInt64|FBytes|FInt64|FOptPercent) -> false
in
List.exists nonnumeric cols in
@@ -932,7 +932,7 @@ and generate_client_structs_compare () =
);
List.iter (
function
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " r = strcmp (s1->%s, s2->%s);\n" name name;
pr " if (r != 0) return r;\n"
| name, FBuffer ->
@@ -1001,7 +1001,7 @@ and generate_client_structs_copy () =
fun { s_name = typ; s_cols = cols } ->
let has_boxed_cols =
let boxed = function
- | _,(FString|FBuffer) -> true
+ | _,(FString|FDevice|FBuffer) -> true
| _,(FChar|FUUID|FUInt32|FInt32|FUInt64|FBytes|FInt64|FOptPercent) ->
false
in
@@ -1014,8 +1014,7 @@ and generate_client_structs_copy () =
pr "{\n";
List.iter (
function
- | name, FString
- | name, FBuffer -> pr " free (s->%s);\n" name
+ | name, (FString|FDevice|FBuffer) -> pr " free (s->%s);\n" name
| _, FChar
| _, FUUID
| _, FUInt32
@@ -1038,8 +1037,7 @@ and generate_client_structs_copy () =
pr "\n";
List.iter (
function
- | name, FString
- | name, FBuffer -> pr " out->%s = NULL;\n" name
+ | name, (FString|FDevice|FBuffer) -> pr " out->%s = NULL;\n" name
| _, FChar
| _, FUUID
| _, FUInt32
@@ -1051,7 +1049,7 @@ and generate_client_structs_copy () =
) cols;
List.iter (
function
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " out->%s = strdup (inp->%s);\n" name name;
pr " if (out->%s == NULL) goto error;\n" name
| name, FBuffer ->
@@ -1234,7 +1232,7 @@ and generate_client_structs_print_c () =
);
List.iter (
function
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " fprintf (dest, \"%%s%s: %%s%%s\", indent, %s->%s, linesep);\n"
name typ name
| name, FUUID ->
diff --git a/generator/csharp.ml b/generator/csharp.ml
index d1999bcff..5c77a46b4 100644
--- a/generator/csharp.ml
+++ b/generator/csharp.ml
@@ -119,7 +119,7 @@ namespace Guestfs
List.iter (
function
| name, FChar -> pr " char %s;\n" name
- | name, FString -> pr " string %s;\n" name
+ | name, (FString | FDevice) -> pr " string %s;\n" name
| name, FBuffer ->
pr " uint %s_len;\n" name;
pr " string %s;\n" name
diff --git a/generator/daemon.ml b/generator/daemon.ml
index 9f75f385a..e19fa07d2 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -442,15 +442,37 @@ let generate_daemon_stubs actions () =
pr " ret.%s.%s_val = r;\n" n n;
pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
name
- | RStruct (n, _) ->
+ | RStruct (n, typ) ->
+ (* XXX RStruct containing an FDevice field would require
+ * reverse device name translation. That is not implemented.
+ * See also RStructList immediately below this.
+ *)
+ let cols = (Structs.lookup_struct typ).s_cols in
+ assert (not (List.exists
+ (function (_, FDevice) -> true | _ -> false) cols));
pr " struct guestfs_%s_ret ret;\n" name;
pr " ret.%s = *r;\n" n;
pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
name;
pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
name
- | RStructList (n, _) ->
+ | RStructList (n, typ) ->
pr " struct guestfs_%s_ret ret;\n" name;
+ let cols = (Structs.lookup_struct typ).s_cols in
+ List.iter (
+ function
+ | (fname, FDevice) ->
+ pr " for (size_t i = 0; i < r->guestfs_int_%s_list_len; ++i) {\n"
+ typ;
+ pr " char *field = r->guestfs_int_%s_list_val[i].%s;\n"
+ typ fname;
+ pr " char *rr = reverse_device_name_translation (field);\n";
+ pr " if (!rr) abort ();\n";
+ pr " free (field);\n";
+ pr " r->guestfs_int_%s_list_val[i].%s = rr;\n" typ fname;
+ pr " }\n";
+ | _ -> ()
+ ) cols;
pr " ret.%s = *r;\n" n;
pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
name;
@@ -619,7 +641,7 @@ let generate_daemon_caml_stubs () =
fun i ->
pr " v = Field (retv, %d);\n" i;
function
- | n, (FString|FUUID) ->
+ | n, (FString|FDevice|FUUID) ->
pr " ret->%s = strdup (String_val (v));\n" n;
pr " if (ret->%s == NULL) return NULL;\n" n
| n, FBuffer ->
@@ -986,7 +1008,7 @@ let generate_daemon_lvm_tokenization () =
pr " if (*p) next = p+1; else next = NULL;\n";
pr " *p = '\\0';\n";
(match coltype with
- | FString ->
+ | FString | FDevice ->
pr " r->%s = strdup (tok);\n" name;
pr " if (r->%s == NULL) {\n" name;
pr " perror (\"strdup\");\n";
diff --git a/generator/erlang.ml b/generator/erlang.ml
index 65af75aaf..864b3ff04 100644
--- a/generator/erlang.ml
+++ b/generator/erlang.ml
@@ -286,7 +286,7 @@ and generate_erlang_structs () =
List.iteri (
fun i col ->
(match col with
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " if (ei_x_encode_string (buff, %s->%s) != 0) return -1;\n" typ name
| name, FBuffer ->
pr " if (ei_x_encode_string_len (buff, %s->%s, %s->%s_len) != 0) return -1;\n"
diff --git a/generator/golang.ml b/generator/golang.ml
index 0d6a92367..a5b39f5df 100644
--- a/generator/golang.ml
+++ b/generator/golang.ml
@@ -248,7 +248,7 @@ func return_hashtable (argv **C.char) map[string]string {
let n = String.capitalize_ascii n in
match field with
| FChar -> pr " %s byte\n" n
- | FString -> pr " %s string\n" n
+ | FString | FDevice -> pr " %s string\n" n
| FBuffer -> pr " %s []byte\n" n
| FUInt32 -> pr " %s uint32\n" n
| FInt32 -> pr " %s int32\n" n
@@ -267,7 +267,7 @@ func return_hashtable (argv **C.char) map[string]string {
let gon = String.capitalize_ascii n in
match field with
| FChar -> pr " r.%s = byte (c.%s)\n" gon n
- | FString -> pr " r.%s = C.GoString (c.%s)\n" gon n
+ | FString | FDevice -> pr " r.%s = C.GoString (c.%s)\n" gon n
| FBuffer ->
pr " r.%s = C.GoBytes (unsafe.Pointer (c.%s), C.int (c.%s_len))\n"
gon n n
diff --git a/generator/java.ml b/generator/java.ml
index 7a8c0016c..909db4530 100644
--- a/generator/java.ml
+++ b/generator/java.ml
@@ -560,6 +560,7 @@ public class %s {
List.iter (
function
| name, FString
+ | name, FDevice
| name, FUUID
| name, FBuffer -> pr " public String %s;\n" name
| name, (FBytes|FUInt64|FInt64) -> pr " public long %s;\n" name
@@ -947,7 +948,7 @@ and generate_java_struct_return typ jtyp cols =
pr " jr = (*env)->AllocObject (env, cl);\n";
List.iter (
function
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, r->%s));\n" name;
| name, FUUID ->
@@ -997,7 +998,7 @@ and generate_java_struct_list_return typ jtyp cols =
fun (name, ftyp) ->
(* Get the field ID in 'fl'. *)
let java_field_type = match ftyp with
- | FString | FUUID | FBuffer -> "Ljava/lang/String;"
+ | FString | FDevice | FUUID | FBuffer -> "Ljava/lang/String;"
| FBytes | FUInt64 | FInt64 -> "J"
| FUInt32 | FInt32 -> "I"
| FOptPercent -> "F"
@@ -1007,7 +1008,7 @@ and generate_java_struct_list_return typ jtyp cols =
(* Assign the value to this field. *)
match ftyp with
- | FString ->
+ | FString | FDevice ->
pr " (*env)->SetObjectField (env, jfl, fl,\n";
pr " (*env)->NewStringUTF (env, r->val[i].%s));\n" name;
| FUUID ->
diff --git a/generator/lua.ml b/generator/lua.ml
index 0d7e63be0..685645abf 100644
--- a/generator/lua.ml
+++ b/generator/lua.ml
@@ -824,7 +824,7 @@ push_event (lua_State *L, uint64_t event)
(match field with
| FChar ->
pr " lua_pushlstring (L, &v->%s, 1);\n" n
- | FString ->
+ | FString | FDevice ->
pr " lua_pushstring (L, v->%s);\n" n
| FBuffer ->
pr " lua_pushlstring (L, v->%s, v->%s_len);\n" n n
diff --git a/generator/perl.ml b/generator/perl.ml
index 0059d4c1d..17ed64d29 100644
--- a/generator/perl.ml
+++ b/generator/perl.ml
@@ -607,7 +607,7 @@ and generate_perl_struct_list_code typ cols name style =
pr " hv = newHV ();\n";
List.iter (
function
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " (void) hv_store (hv, \"%s\", %d, newSVpv (r->val[i].%s, 0), 0);\n"
name (String.length name) name
| name, FUUID ->
@@ -645,7 +645,7 @@ and generate_perl_struct_code typ cols name style =
pr " PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name;
match col with
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " PUSHs (sv_2mortal (newSVpv (r->%s, 0)));\n"
name
| name, FBuffer ->
diff --git a/generator/php.ml b/generator/php.ml
index df8470461..2b336f96f 100644
--- a/generator/php.ml
+++ b/generator/php.ml
@@ -616,7 +616,7 @@ and generate_php_struct_code typ cols =
pr " array_init (return_value);\n";
List.iter (
function
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " guestfs_add_assoc_string (return_value, \"%s\", r->%s, 1);\n" name name
| name, FBuffer ->
pr " guestfs_add_assoc_stringl (return_value, \"%s\", r->%s, r->%s_len, 1);\n"
@@ -650,7 +650,7 @@ and generate_php_struct_list_code typ cols =
pr " array_init (z_elem);\n";
List.iter (
function
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " guestfs_add_assoc_string (z_elem, \"%s\", r->val[c].%s, 1);\n"
name name
| name, FBuffer ->
diff --git a/generator/python.ml b/generator/python.ml
index 242721f33..86b70b2de 100644
--- a/generator/python.ml
+++ b/generator/python.ml
@@ -168,7 +168,7 @@ and generate_python_structs () =
pr " return NULL;\n";
List.iter (
function
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " value = guestfs_int_py_fromstring (%s->%s);\n" typ name;
pr " if (value == NULL)\n";
pr " goto err;\n";
diff --git a/generator/ruby.ml b/generator/ruby.ml
index 0f63b82ed..f9787af69 100644
--- a/generator/ruby.ml
+++ b/generator/ruby.ml
@@ -526,7 +526,7 @@ and generate_ruby_struct_code typ cols =
pr " volatile VALUE rv = rb_hash_new ();\n";
List.iter (
function
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name
| name, FBuffer ->
pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, r->%s_len));\n" name name name
@@ -556,7 +556,7 @@ and generate_ruby_struct_list_code typ cols =
pr " volatile VALUE hv = rb_hash_new ();\n";
List.iter (
function
- | name, FString ->
+ | name, (FString|FDevice) ->
pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name
| name, FBuffer ->
pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, r->val[i].%s_len));\n" name name name
diff --git a/generator/rust.ml b/generator/rust.ml
index 1f5cefa62..f4dcfd723 100644
--- a/generator/rust.ml
+++ b/generator/rust.ml
@@ -115,7 +115,7 @@ extern \"C\" {
List.iter (
function
| n, FChar -> pr " pub %s: i8,\n" n
- | n, FString -> pr " pub %s: String,\n" n
+ | n, (FString|FDevice) -> pr " pub %s: String,\n" n
| n, FBuffer -> pr " pub %s: Vec<u8>,\n" n
| n, FUInt32 -> pr " pub %s: u32,\n" n
| n, FInt32 -> pr " pub %s: i32,\n" n
@@ -130,7 +130,7 @@ extern \"C\" {
List.iter (
function
| n, FChar -> pr " %s: c_char,\n" n
- | n, FString -> pr " %s: *const c_char,\n" n
+ | n, (FString|FDevice) -> pr " %s: *const c_char,\n" n
| n, FBuffer ->
pr " %s_len: usize,\n" n;
pr " %s: *const c_char,\n" n;
@@ -154,7 +154,7 @@ extern \"C\" {
match x with
| n, FChar ->
pr "%s: (*raw).%s as i8,\n" n n;
- | n, FString ->
+ | n, (FString|FDevice) ->
pr "%s: char_ptr_to_string((*raw).%s)?,\n" n n;
| n, FBuffer ->
pr "%s: slice::from_raw_parts((*raw).%s as *const u8, (*raw).%s_len).to_vec(),\n" n n n
diff --git a/generator/types.ml b/generator/types.ml
index 76b699e78..7163da8d2 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -215,6 +215,7 @@ let defaults = { name = "";
type field =
| FChar (* C 'char' (really, a 7 bit byte). *)
| FString (* nul-terminated ASCII string, NOT NULL. *)
+ | FDevice (* device name, needs reverse transl. *)
| FBuffer (* opaque buffer of bytes, (char *, int) pair *)
| FUInt32
| FInt32
diff --git a/generator/types.mli b/generator/types.mli
index 7c549a35e..e8939370e 100644
--- a/generator/types.mli
+++ b/generator/types.mli
@@ -413,6 +413,7 @@ val defaults : action
type field =
| FChar (** C 'char' (really, a 7 bit byte). *)
| FString (** nul-terminated ASCII string, NOT NULL. *)
+ | FDevice (** device name, needs reverse transl. *)
| FBuffer (** opaque buffer of bytes, (char *, int) pair*)
| FUInt32
| FInt32
--
2.47.1