These 3 patches implement support for APIs which must accept a mountable, but don't update apis which must return mountables. Matt
Matthew Booth
2013-Jan-24 10:19 UTC
[Libguestfs] [PATCH 1/3] generator: Add new Mountable argument type
This type is initially identical to Device. --- generator/bindtests.ml | 2 +- generator/c.ml | 7 +++++-- generator/csharp.ml | 6 ++++-- generator/daemon.ml | 4 ++-- generator/erlang.ml | 6 +++--- generator/fish.ml | 8 ++++---- generator/gobject.ml | 11 ++++++----- generator/haskell.ml | 11 +++++++---- generator/java.ml | 10 +++++----- generator/lua.ml | 6 +++--- generator/ocaml.ml | 10 +++++----- generator/perl.ml | 9 +++++---- generator/php.ml | 10 +++++----- generator/python.ml | 12 ++++++------ generator/ruby.ml | 4 ++-- generator/tests_c_api.ml | 3 ++- generator/types.ml | 1 + generator/utils.ml | 2 +- generator/xdr.ml | 3 ++- 19 files changed, 69 insertions(+), 56 deletions(-) diff --git a/generator/bindtests.ml b/generator/bindtests.ml index b707427..774a3f3 100644 --- a/generator/bindtests.ml +++ b/generator/bindtests.ml @@ -127,7 +127,7 @@ print_strings (guestfs_h *g, char *const *argv) List.iter ( function | Pathname n - | Device n | Dev_or_Path n + | Device n | Mountable n | Dev_or_Path n | String n | FileIn n | FileOut n diff --git a/generator/c.ml b/generator/c.ml index b9d4b35..c20f502 100644 --- a/generator/c.ml +++ b/generator/c.ml @@ -109,7 +109,7 @@ let rec generate_prototype ?(extern = true) ?(static = false) List.iter ( function | Pathname n - | Device n | Dev_or_Path n + | Device n | Mountable n | Dev_or_Path n | String n | OptString n | Key n -> @@ -793,6 +793,7 @@ and generate_client_actions hash () (* parameters which should not be NULL *) | String n | Device n + | Mountable n | Pathname n | Dev_or_Path n | FileIn n @@ -910,6 +911,7 @@ and generate_client_actions hash () function | String n (* strings *) | Device n + | Mountable n | Pathname n | Dev_or_Path n | FileIn n @@ -1225,7 +1227,8 @@ and generate_client_actions hash () ) else ( List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n | Key n -> + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n + | Key n -> pr " args.%s = (char *) %s;\n" n n | OptString n -> pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n diff --git a/generator/csharp.ml b/generator/csharp.ml index 803a4a5..9d4ea68 100644 --- a/generator/csharp.ml +++ b/generator/csharp.ml @@ -187,7 +187,8 @@ namespace Guestfs (c_return_type ()) c_function; List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n | OptString n + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n + | OptString n | FileIn n | FileOut n | Key n | BufferIn n -> @@ -213,7 +214,8 @@ namespace Guestfs in List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n | OptString n + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n + | OptString n | FileIn n | FileOut n | Key n | BufferIn n -> diff --git a/generator/daemon.ml b/generator/daemon.ml index 3c2f949..a7096a1 100644 --- a/generator/daemon.ml +++ b/generator/daemon.ml @@ -111,7 +111,7 @@ and generate_daemon_actions () pr " struct guestfs_%s_args args;\n" name; List.iter ( function - | Device n | Dev_or_Path n + | Device n | Mountable n | Dev_or_Path n | Pathname n | String n | Key n @@ -205,7 +205,7 @@ and generate_daemon_actions () pr_args n; pr " ABS_PATH (%s, %s, goto done);\n" n (if is_filein then "cancel_receive ()" else ""); - | Device n -> + | Device n | Mountable n -> pr_args n; pr " RESOLVE_DEVICE (%s, %s, goto done);\n" n (if is_filein then "cancel_receive ()" else ""); diff --git a/generator/erlang.ml b/generator/erlang.ml index 6c7eb70..ef1f01f 100644 --- a/generator/erlang.ml +++ b/generator/erlang.ml @@ -293,7 +293,7 @@ extern void free_strings (char **r); fun i -> function | Pathname n - | Device n | Dev_or_Path n + | Device n | Mountable n | Dev_or_Path n | String n | FileIn n | FileOut n @@ -386,8 +386,8 @@ extern void free_strings (char **r); (* Free strings if we copied them above. *) List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n | OptString n - | FileIn n | FileOut n | Key n -> + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n + | OptString n | FileIn n | FileOut n | Key n -> pr " free (%s);\n" n | StringList n | DeviceList n -> pr " free_strings (%s);\n" n; diff --git a/generator/fish.ml b/generator/fish.ml index 59c1114..c1686cf 100644 --- a/generator/fish.ml +++ b/generator/fish.ml @@ -328,7 +328,7 @@ Guestfish will prompt for these separately." ); List.iter ( function - | Device n + | Device n | Mountable n | String n | OptString n -> pr " const char *%s;\n" n | Pathname n @@ -411,7 +411,7 @@ Guestfish will prompt for these separately." List.iter ( function - | Device name + | Device name | Mountable name | String name -> pr " %s = argv[i++];\n" name | Pathname name @@ -616,7 +616,7 @@ Guestfish will prompt for these separately." ) (List.rev optargs); List.iter ( function - | Device _ | String _ + | Device _ | Mountable _ | String _ | OptString _ | Bool _ | BufferIn _ -> () | Int name | Int64 name -> @@ -858,7 +858,7 @@ and generate_fish_actions_pod () pr " %s" name; List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n -> + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n -> pr " %s" n | OptString n -> pr " %s" n | StringList n | DeviceList n -> pr " '%s ...'" n diff --git a/generator/gobject.ml b/generator/gobject.ml index 6c35e02..ea3fecc 100644 --- a/generator/gobject.ml +++ b/generator/gobject.ml @@ -75,7 +75,7 @@ let generate_gobject_proto name ?(single_line = true) | Int64 n-> pr "gint64 %s" n | String n - | Device n + | Device n | Mountable n | Pathname n | Dev_or_Path n | OptString n @@ -1033,7 +1033,8 @@ guestfs_session_close(GuestfsSession *session, GError **err) pr " (transfer none) (type utf8):" | OptString _ -> pr " (transfer none) (type utf8) (allow-none):" - | Device _ | Pathname _ | Dev_or_Path _ | FileIn _ | FileOut _ -> + | Device _ | Mountable _ | Pathname _ | Dev_or_Path _ + | FileIn _ | FileOut _ -> pr " (transfer none) (type filename):" | StringList _ -> pr " (transfer none) (array zero-terminated=1) (element-type utf8): an array of strings" @@ -1183,9 +1184,9 @@ guestfs_session_close(GuestfsSession *session, GError **err) match argt with | BufferIn n -> pr "%s, %s_size" n n - | Bool n | Int n | Int64 n | String n | Device n | Pathname n - | Dev_or_Path n | OptString n | StringList n | DeviceList n - | Key n | FileIn n | FileOut n -> + | Bool n | Int n | Int64 n | String n | Device n | Mountable n + | Pathname n | Dev_or_Path n | OptString n | StringList n + | DeviceList n | Key n | FileIn n | FileOut n -> pr "%s" n | Pointer _ -> failwith "gobject bindings do not support Pointer arguments" diff --git a/generator/haskell.ml b/generator/haskell.ml index abd0478..66628bd 100644 --- a/generator/haskell.ml +++ b/generator/haskell.ml @@ -140,7 +140,8 @@ assocListOfHashtable (a:b:rest) = (a,b) : assocListOfHashtable rest function | FileIn n | FileOut n - | Pathname n | Device n | Dev_or_Path n | String n | Key n -> + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n + | Key n -> pr "withCString %s $ \\%s -> " n n | BufferIn n -> pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n @@ -156,7 +157,7 @@ assocListOfHashtable (a:b:rest) = (a,b) : assocListOfHashtable rest | Int n -> sprintf "(fromIntegral %s)" n | Int64 n | Pointer (_, n) -> sprintf "(fromIntegral %s)" n | FileIn n | FileOut n - | Pathname n | Device n | Dev_or_Path n + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n | OptString n | StringList n | DeviceList n | Key n -> n @@ -213,7 +214,8 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) List.iter ( fun arg -> (match arg with - | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _ -> + | Pathname _ | Device _ | Mountable _ | Dev_or_Path _ | String _ + | Key _ -> pr "CString" | BufferIn _ -> pr "CString -> CInt" @@ -254,7 +256,8 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) List.iter ( fun arg -> (match arg with - | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _ -> + | Pathname _ | Device _ | Mountable _ | Dev_or_Path _ | String _ + | Key _ -> pr "String" | BufferIn _ -> pr "String" diff --git a/generator/java.ml b/generator/java.ml index 9ef09ad..9bb4739 100644 --- a/generator/java.ml +++ b/generator/java.ml @@ -463,7 +463,7 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false) match arg with | Pathname n - | Device n | Dev_or_Path n + | Device n | Mountable n | Dev_or_Path n | String n | OptString n | FileIn n @@ -797,7 +797,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn) List.iter ( function | Pathname n - | Device n | Dev_or_Path n + | Device n | Mountable n | Dev_or_Path n | String n | OptString n | FileIn n @@ -866,7 +866,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn) List.iter ( function | Pathname n - | Device n | Dev_or_Path n + | Device n | Mountable n | Dev_or_Path n | String n | OptString n | FileIn n @@ -923,7 +923,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn) List.iter ( function | Pathname n - | Device n | Dev_or_Path n + | Device n | Mountable n | Dev_or_Path n | String n | FileIn n | FileOut n @@ -990,7 +990,7 @@ get_all_event_callbacks (guestfs_h *g, size_t *len_rtn) List.iter ( function | Pathname n - | Device n | Dev_or_Path n + | Device n | Mountable n | Dev_or_Path n | String n | FileIn n | FileOut n diff --git a/generator/lua.ml b/generator/lua.ml index c4e3463..6c4b45d 100644 --- a/generator/lua.ml +++ b/generator/lua.ml @@ -470,7 +470,7 @@ guestfs_lua_delete_event_callback (lua_State *L) List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n | FileIn n | FileOut n | Key n -> pr " const char *%s;\n" n | BufferIn n -> @@ -500,7 +500,7 @@ guestfs_lua_delete_event_callback (lua_State *L) fun i -> let i = i+2 in (* Lua indexes from 1(!), plus the handle. *) function - | Pathname n | Device n | Dev_or_Path n | String n + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n | FileIn n | FileOut n | Key n -> pr " %s = luaL_checkstring (L, %d);\n" n i | BufferIn n -> @@ -560,7 +560,7 @@ guestfs_lua_delete_event_callback (lua_State *L) (* Free temporary data. *) List.iter ( function - | Pathname _ | Device _ | Dev_or_Path _ | String _ + | Pathname _ | Device _ | Mountable _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _ | Key _ | BufferIn _ | OptString _ | Bool _ | Int _ | Int64 _ diff --git a/generator/ocaml.ml b/generator/ocaml.ml index 1ecdea8..f4a6832 100644 --- a/generator/ocaml.ml +++ b/generator/ocaml.ml @@ -497,7 +497,7 @@ copy_table (char * const * argv) List.iter ( function | Pathname n - | Device n | Dev_or_Path n + | Device n | Mountable n | Dev_or_Path n | String n | FileIn n | FileOut n @@ -583,8 +583,8 @@ copy_table (char * const * argv) (* Free strings if we copied them above. *) List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n | OptString n - | FileIn n | FileOut n | BufferIn n | Key n -> + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n + | OptString n | FileIn n | FileOut n | BufferIn n | Key n -> pr " free (%s);\n" n | StringList n | DeviceList n -> pr " ocaml_guestfs_free_strings (%s);\n" n; @@ -712,8 +712,8 @@ and generate_ocaml_function_type ?(extra_unit = false) (ret, args, optargs) ) optargs; List.iter ( function - | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _ - | BufferIn _ | Key _ -> pr "string -> " + | Pathname _ | Device _ | Mountable _ | Dev_or_Path _ | String _ + | FileIn _ | FileOut _ | BufferIn _ | Key _ -> pr "string -> " | OptString _ -> pr "string option -> " | StringList _ | DeviceList _ -> pr "string array -> " | Bool _ -> pr "bool -> " diff --git a/generator/perl.ml b/generator/perl.ml index aa5ca26..9533105 100644 --- a/generator/perl.ml +++ b/generator/perl.ml @@ -338,7 +338,7 @@ user_cancel (g) iteri ( fun i -> function - | Pathname n | Device n | Dev_or_Path n | String n + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n | FileIn n | FileOut n | Key n -> pr " char *%s;\n" n | BufferIn n -> @@ -487,8 +487,8 @@ user_cancel (g) (* Cleanup any arguments. *) List.iter ( function - | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _ - | Bool _ | Int _ | Int64 _ + | Pathname _ | Device _ | Mountable _ | Dev_or_Path _ | String _ + | OptString _ | Bool _ | Int _ | Int64 _ | FileIn _ | FileOut _ | BufferIn _ | Key _ | Pointer _ -> () | StringList n | DeviceList n -> pr " free (%s);\n" n @@ -909,6 +909,7 @@ handlers and threads. let pr_type i = function | Pathname n -> pr "[ '%s', 'string(path)', %d ]" n i | Device n -> pr "[ '%s', 'string(device)', %d ]" n i + | Mountable n -> pr "[ '%s', 'string(mountable)', %d ]" n i | Dev_or_Path n -> pr "[ '%s', 'string(dev_or_path)', %d ]" n i | String n -> pr "[ '%s', 'string', %d ]" n i | FileIn n -> pr "[ '%s', 'string(filename)', %d ]" n i @@ -1081,7 +1082,7 @@ and generate_perl_prototype name (ret, args, optargs) if !comma then pr ", "; comma := true; match arg with - | Pathname n | Device n | Dev_or_Path n | String n + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n | BufferIn n | Key n | Pointer (_, n) -> pr "$%s" n diff --git a/generator/php.ml b/generator/php.ml index 368248e..e777de9 100644 --- a/generator/php.ml +++ b/generator/php.ml @@ -188,7 +188,7 @@ PHP_FUNCTION (guestfs_last_error) List.iter ( function - | String n | Device n | Pathname n | Dev_or_Path n + | String n | Device n | Mountable n | Pathname n | Dev_or_Path n | FileIn n | FileOut n | Key n | OptString n | BufferIn n -> @@ -232,7 +232,7 @@ PHP_FUNCTION (guestfs_last_error) let param_string = String.concat "" ( List.map ( function - | String n | Device n | Pathname n | Dev_or_Path n + | String n | Device n | Mountable n | Pathname n | Dev_or_Path n | FileIn n | FileOut n | BufferIn n | Key n -> "s" | OptString n -> "s!" | StringList n | DeviceList n -> "a" @@ -260,7 +260,7 @@ PHP_FUNCTION (guestfs_last_error) pr " &z_g"; List.iter ( function - | String n | Device n | Pathname n | Dev_or_Path n + | String n | Device n | Mountable n | Pathname n | Dev_or_Path n | FileIn n | FileOut n | BufferIn n | Key n | OptString n -> pr ", &%s, &%s_size" n n @@ -293,7 +293,7 @@ PHP_FUNCTION (guestfs_last_error) List.iter ( function - | String n | Device n | Pathname n | Dev_or_Path n + | String n | Device n | Mountable n | Pathname n | Dev_or_Path n | FileIn n | FileOut n | Key n | OptString n -> (* Just need to check the string doesn't contain any ASCII @@ -420,7 +420,7 @@ PHP_FUNCTION (guestfs_last_error) (* Free up parameters. *) List.iter ( function - | String n | Device n | Pathname n | Dev_or_Path n + | String n | Device n | Mountable n | Pathname n | Dev_or_Path n | FileIn n | FileOut n | Key n | OptString n -> () | BufferIn n -> () diff --git a/generator/python.ml b/generator/python.ml index 8752fd3..2d6e72f 100644 --- a/generator/python.ml +++ b/generator/python.ml @@ -289,7 +289,7 @@ free_strings (char **argv) List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n | Key n + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n | Key n | FileIn n | FileOut n -> pr " const char *%s;\n" n | OptString n -> pr " const char *%s;\n" n @@ -326,7 +326,7 @@ free_strings (char **argv) pr " if (!PyArg_ParseTuple (args, (char *) \"O"; List.iter ( function - | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _ + | Pathname _ | Device _ | Mountable _ | Dev_or_Path _ | String _ | Key _ | FileIn _ | FileOut _ -> pr "s" | OptString _ -> pr "z" | StringList _ | DeviceList _ -> pr "O" @@ -347,7 +347,7 @@ free_strings (char **argv) pr " &py_g"; List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n | Key n + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n | Key n | FileIn n | FileOut n -> pr ", &%s" n | OptString n -> pr ", &%s" n | StringList n | DeviceList n -> pr ", &py_%s" n @@ -369,7 +369,7 @@ free_strings (char **argv) pr " g = get_handle (py_g);\n"; List.iter ( function - | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _ + | Pathname _ | Device _ | Mountable _ | Dev_or_Path _ | String _ | Key _ | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ | BufferIn _ -> () | StringList n | DeviceList n -> @@ -505,7 +505,7 @@ free_strings (char **argv) List.iter ( function - | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _ + | Pathname _ | Device _ | Mountable _ | Dev_or_Path _ | String _ | Key _ | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ | BufferIn _ | Pointer _ -> () | StringList n | DeviceList n -> @@ -772,7 +772,7 @@ class GuestFS: *) List.iter ( function - | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _ + | Pathname _ | Device _ | Mountable _ | Dev_or_Path _ | String _ | Key _ | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ | BufferIn _ | Pointer _ -> () | StringList n | DeviceList n -> diff --git a/generator/ruby.ml b/generator/ruby.ml index 06f7d58..5ff6a2e 100644 --- a/generator/ruby.ml +++ b/generator/ruby.ml @@ -500,7 +500,7 @@ ruby_user_cancel (VALUE gv) List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n | Key n + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n | Key n | FileIn n | FileOut n -> pr " const char *%s = StringValueCStr (%sv);\n" n n; | BufferIn n -> @@ -602,7 +602,7 @@ ruby_user_cancel (VALUE gv) List.iter ( function - | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _ + | Pathname _ | Device _ | Mountable _ | Dev_or_Path _ | String _ | Key _ | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ | BufferIn _ | Pointer _ -> () | StringList n | DeviceList n -> diff --git a/generator/tests_c_api.ml b/generator/tests_c_api.ml index 2aa78df..75b59a2 100644 --- a/generator/tests_c_api.ml +++ b/generator/tests_c_api.ml @@ -793,6 +793,7 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd | OptString n, "NULL" -> () | Pathname n, arg | Device n, arg + | Mountable n, arg | Dev_or_Path n, arg | String n, arg | OptString n, arg @@ -902,7 +903,7 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd function | OptString _, "NULL" -> pr ", NULL" | Pathname n, _ - | Device n, _ | Dev_or_Path n, _ + | Device n, _ | Mountable n, _ | Dev_or_Path n, _ | String n, _ | OptString n, _ | Key n, _ -> diff --git a/generator/types.ml b/generator/types.ml index e6f56ec..7660c3d 100644 --- a/generator/types.ml +++ b/generator/types.ml @@ -132,6 +132,7 @@ and argt | Int64 of string (* any 64 bit int *) | String of string (* const char *name, cannot be NULL *) | Device of string (* /dev device name, cannot be NULL *) + | Mountable of string (* location of mountable filesystem, cannot be NULL *) | Pathname of string (* file name, cannot be NULL *) | Dev_or_Path of string (* /dev device name or Pathname, cannot be NULL *) | OptString of string (* const char *name, may be NULL *) diff --git a/generator/utils.ml b/generator/utils.ml index 2d84bcd..ef1d028 100644 --- a/generator/utils.ml +++ b/generator/utils.ml @@ -250,7 +250,7 @@ let map_chars f str List.map f (explode str) let name_of_argt = function - | Pathname n | Device n | Dev_or_Path n | String n | OptString n + | Pathname n | Device n | Mountable n | Dev_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) -> n diff --git a/generator/xdr.ml b/generator/xdr.ml index 46b1c90..7073a1d 100644 --- a/generator/xdr.ml +++ b/generator/xdr.ml @@ -106,7 +106,8 @@ let generate_xdr () pr "struct %s_args {\n" name; List.iter ( function - | Pathname n | Device n | Dev_or_Path n | String n | Key n -> + | Pathname n | Device n | Mountable n | Dev_or_Path n | String n + | Key n -> pr " string %s<>;\n" n | OptString n -> pr " guestfs_str *%s;\n" n | StringList n | DeviceList n -> pr " guestfs_str %s<>;\n" n -- 1.8.1
Matthew Booth
2013-Jan-24 10:19 UTC
[Libguestfs] [PATCH 2/3] generator: Convert relevant arguments from Device to Mountable
This change updates the api style of all apis which should take Mountable descriptions rather than block devices. It also updates the documentation accordingly, but doesn't implement any functional changes. --- generator/actions.ml | 86 ++++++++++++++++++++++++++-------------------------- src/guestfs.pod | 31 +++++++++++++++++++ 2 files changed, 74 insertions(+), 43 deletions(-) diff --git a/generator/actions.ml b/generator/actions.ml index d75de8d..40a9dce 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -904,7 +904,7 @@ See also C<guestfs_list_filesystems>." }; { defaults with name = "inspect_get_type"; - style = RString "name", [Device "root"], []; + style = RString "name", [Mountable "root"], []; shortdesc = "get type of inspected operating system"; longdesc = "\ This returns the type of the inspected operating system. @@ -953,7 +953,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_get_arch"; - style = RString "arch", [Device "root"], []; + style = RString "arch", [Mountable "root"], []; shortdesc = "get architecture of inspected operating system"; longdesc = "\ This returns the architecture of the inspected operating system. @@ -967,7 +967,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_get_distro"; - style = RString "distro", [Device "root"], []; + style = RString "distro", [Mountable "root"], []; shortdesc = "get distro of inspected operating system"; longdesc = "\ This returns the distro (distribution) of the inspected operating @@ -1087,7 +1087,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_get_major_version"; - style = RInt "major", [Device "root"], []; + style = RInt "major", [Mountable "root"], []; shortdesc = "get major version of inspected operating system"; longdesc = "\ This returns the major version number of the inspected operating @@ -1106,7 +1106,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_get_minor_version"; - style = RInt "minor", [Device "root"], []; + style = RInt "minor", [Mountable "root"], []; shortdesc = "get minor version of inspected operating system"; longdesc = "\ This returns the minor version number of the inspected operating @@ -1119,7 +1119,7 @@ See also C<guestfs_inspect_get_major_version>." }; { defaults with name = "inspect_get_product_name"; - style = RString "product", [Device "root"], []; + style = RString "product", [Mountable "root"], []; shortdesc = "get product name of inspected operating system"; longdesc = "\ This returns the product name of the inspected operating @@ -1134,7 +1134,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_get_mountpoints"; - style = RHashtable "mountpoints", [Device "root"], []; + style = RHashtable "mountpoints", [Mountable "root"], []; shortdesc = "get mountpoints of inspected operating system"; longdesc = "\ This returns a hash of where we think the filesystems @@ -1165,7 +1165,7 @@ See also C<guestfs_inspect_get_filesystems>." }; { defaults with name = "inspect_get_filesystems"; - style = RStringList "filesystems", [Device "root"], []; + style = RStringList "filesystems", [Mountable "root"], []; shortdesc = "get filesystems associated with inspected operating system"; longdesc = "\ This returns a list of all the filesystems that we think @@ -1209,7 +1209,7 @@ This returns the enable network flag." }; shortdesc = "list filesystems"; longdesc = "\ This inspection command looks for filesystems on partitions, -block devices and logical volumes, returning a list of devices +block devices and logical volumes, returning a list of C<mountables> containing filesystems and their type. The return value is a hash, where the keys are the devices @@ -1220,6 +1220,7 @@ For example: \"/dev/sda2\" => \"ext2\" \"/dev/vg_guest/lv_root\" => \"ext4\" \"/dev/vg_guest/lv_swap\" => \"swap\" + \"btrfsvol:/dev/sda3/root\" => \"btrfs\" The value can have the special value \"unknown\", meaning the content of the device is undetermined or empty. @@ -1315,7 +1316,7 @@ See L<guestfs(3)/DISK LABELS>. { defaults with name = "inspect_get_windows_systemroot"; - style = RString "systemroot", [Device "root"], []; + style = RString "systemroot", [Mountable "root"], []; shortdesc = "get Windows systemroot of inspected operating system"; longdesc = "\ This returns the Windows systemroot of the inspected guest. @@ -1485,7 +1486,7 @@ C<guestfs_add_drive_opts>." }; { defaults with name = "inspect_get_package_format"; - style = RString "packageformat", [Device "root"], []; + style = RString "packageformat", [Mountable "root"], []; shortdesc = "get package format used by the operating system"; longdesc = "\ This function and C<guestfs_inspect_get_package_management> return @@ -1506,7 +1507,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_get_package_management"; - style = RString "packagemanagement", [Device "root"], []; + style = RString "packagemanagement", [Mountable "root"], []; shortdesc = "get package management tool used by the operating system"; longdesc = "\ C<guestfs_inspect_get_package_format> and this function return @@ -1528,7 +1529,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_list_applications"; - style = RStructList ("applications", "application"), [Device "root"], []; + style = RStructList ("applications", "application"), [Mountable "root"], []; deprecated_by = Some "inspect_list_applications2"; shortdesc = "get list of applications installed in the operating system"; longdesc = "\ @@ -1626,7 +1627,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_list_applications2"; - style = RStructList ("applications2", "application2"), [Device "root"], []; + style = RStructList ("applications2", "application2"), [Mountable "root"], []; shortdesc = "get list of applications installed in the operating system"; longdesc = "\ Return the list of applications installed in the operating system. @@ -1729,7 +1730,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_get_hostname"; - style = RString "hostname", [Device "root"], []; + style = RString "hostname", [Mountable "root"], []; shortdesc = "get hostname of the operating system"; longdesc = "\ This function returns the hostname of the operating system @@ -1742,7 +1743,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_get_format"; - style = RString "format", [Device "root"], []; + style = RString "format", [Mountable "root"], []; shortdesc = "get format of inspected operating system"; longdesc = "\ This returns the format of the inspected operating system. You @@ -1774,7 +1775,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_is_live"; - style = RBool "live", [Device "root"], []; + style = RBool "live", [Mountable "root"], []; shortdesc = "get live flag for install disk"; longdesc = "\ If C<guestfs_inspect_get_format> returns C<installer> (this @@ -1785,7 +1786,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_is_netinst"; - style = RBool "netinst", [Device "root"], []; + style = RBool "netinst", [Mountable "root"], []; shortdesc = "get netinst (network installer) flag for install disk"; longdesc = "\ If C<guestfs_inspect_get_format> returns C<installer> (this @@ -1798,7 +1799,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_is_multipart"; - style = RBool "multipart", [Device "root"], []; + style = RBool "multipart", [Mountable "root"], []; shortdesc = "get multipart flag for install disk"; longdesc = "\ If C<guestfs_inspect_get_format> returns C<installer> (this @@ -1835,7 +1836,7 @@ See C<guestfs_set_attach_method> and L<guestfs(3)/ATTACH METHOD>." }; { defaults with name = "inspect_get_product_variant"; - style = RString "variant", [Device "root"], []; + style = RString "variant", [Mountable "root"], []; shortdesc = "get product variant of inspected operating system"; longdesc = "\ This returns the product variant of the inspected operating @@ -1863,7 +1864,7 @@ C<guestfs_inspect_get_major_version>." }; { defaults with name = "inspect_get_windows_current_control_set"; - style = RString "controlset", [Device "root"], []; + style = RString "controlset", [Mountable "root"], []; shortdesc = "get Windows CurrentControlSet of inspected operating system"; longdesc = "\ This returns the Windows CurrentControlSet of the inspected guest. @@ -1877,7 +1878,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." }; { defaults with name = "inspect_get_drive_mappings"; - style = RHashtable "drives", [Device "root"], []; + style = RHashtable "drives", [Mountable "root"], []; shortdesc = "get drive letter mappings"; longdesc = "\ This call is useful for Windows which uses a primitive system @@ -1911,7 +1912,7 @@ C<guestfs_inspect_get_filesystems>." }; { defaults with name = "inspect_get_icon"; - style = RBufferOut "icon", [Device "root"], [OBool "favicon"; OBool "highquality"]; + style = RBufferOut "icon", [Mountable "root"], [OBool "favicon"; OBool "highquality"]; shortdesc = "get the icon corresponding to this operating system"; longdesc = "\ This function returns an icon corresponding to the inspected @@ -2695,7 +2696,7 @@ Get the directory used by the handle to store the appliance cache." }; let daemon_functions = [ { defaults with name = "mount"; - style = RErr, [Device "device"; String "mountpoint"], []; + style = RErr, [Mountable "mountable"; String "mountpoint"], []; proc_nr = Some 1; tests = [ InitEmpty, Always, TestOutput ( @@ -2707,11 +2708,8 @@ let daemon_functions = [ ]; shortdesc = "mount a guest disk at a position in the filesystem"; longdesc = "\ -Mount a guest disk at a position in the filesystem. Block devices -are named C</dev/sda>, C</dev/sdb> and so on, as they were added to -the guest. If those block devices contain partitions, they will have -the usual names (eg. C</dev/sda1>). Also LVM C</dev/VG/LV>-style -names can be used. +Mount C<mountable> at a position in the filesystem. See L</MOUNTABLES> for a +description of the format of C<mountable>. The rules are the same as for L<mount(2)>: A filesystem must first be mounted on C</> before others can be mounted. Other @@ -3492,7 +3490,8 @@ contains the filesystem." }; shortdesc = "show mounted filesystems"; longdesc = "\ This returns the list of currently mounted filesystems. It returns -the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>). +the list of C<mountables> (eg. C</dev/sda1>, C</dev/VG/LV>, +C<btrfsvol:/dev/sda3/root>). Some internal mounts are not shown. @@ -4186,7 +4185,7 @@ it to local file C<tarball>." }; { defaults with name = "mount_ro"; - style = RErr, [Device "device"; String "mountpoint"], []; + style = RErr, [Mountable "mountable"; String "mountpoint"], []; proc_nr = Some 73; tests = [ InitBasicFS, Always, TestLastFail ( @@ -4206,7 +4205,7 @@ mounts the filesystem with the read-only (I<-o ro>) flag." }; { defaults with name = "mount_options"; - style = RErr, [String "options"; Device "device"; String "mountpoint"], []; + style = RErr, [String "options"; Mountable "mountable"; String "mountpoint"], []; proc_nr = Some 74; shortdesc = "mount a guest disk with mount options"; longdesc = "\ @@ -4220,7 +4219,7 @@ the filesystem uses)." }; { defaults with name = "mount_vfs"; - style = RErr, [String "options"; String "vfstype"; Device "device"; String "mountpoint"], []; + style = RErr, [String "options"; String "vfstype"; Mountable "mountable"; String "mountpoint"], []; proc_nr = Some 75; shortdesc = "mount a guest disk with mount options and vfstype"; longdesc = "\ @@ -6684,7 +6683,7 @@ See also C<guestfs_realpath>." }; { defaults with name = "vfs_type"; - style = RString "fstype", [Device "device"], []; + style = RString "fstype", [Mountable "mountable"], []; proc_nr = Some 198; tests = [ InitScratchFS, Always, TestOutput ( @@ -6693,7 +6692,7 @@ See also C<guestfs_realpath>." }; shortdesc = "get the Linux VFS type corresponding to a mounted device"; longdesc = "\ This command gets the filesystem type corresponding to -the filesystem on C<device>. +the filesystem on C<mountable>. For most filesystems, the result is the name of the Linux VFS module which would be used to mount this filesystem @@ -7814,7 +7813,7 @@ a file in the host and attach it as a device." }; { defaults with name = "vfs_label"; - style = RString "label", [Device "device"], []; + style = RString "label", [Mountable "mountable"], []; proc_nr = Some 253; tests = [ InitBasicFS, Always, TestOutput ( @@ -7823,8 +7822,7 @@ a file in the host and attach it as a device." }; ]; shortdesc = "get the filesystem label"; longdesc = "\ -This returns the filesystem label of the filesystem on -C<device>. +This returns the label of the filesystem on C<mountable>. If the filesystem is unlabeled, this returns the empty string. @@ -7832,7 +7830,7 @@ To find a filesystem from the label, use C<guestfs_findfs_label>." }; { defaults with name = "vfs_uuid"; - style = RString "uuid", [Device "device"], []; + style = RString "uuid", [Mountable "mountable"], []; proc_nr = Some 254; tests (let uuid = uuidgen () in [ @@ -7842,8 +7840,7 @@ To find a filesystem from the label, use C<guestfs_findfs_label>." }; ]); shortdesc = "get the filesystem UUID"; longdesc = "\ -This returns the filesystem UUID of the filesystem on -C<device>. +This returns the filesystem UUID of the filesystem on C<mountable>. If the filesystem does not have a UUID, this returns the empty string. @@ -9054,7 +9051,7 @@ any existing contents of this device." }; { defaults with name = "set_label"; - style = RErr, [Device "device"; String "label"], []; + style = RErr, [Mountable "mountable"; String "label"], []; proc_nr = Some 310; tests = [ InitBasicFS, Always, TestOutput ( @@ -9070,7 +9067,7 @@ any existing contents of this device." }; ]; shortdesc = "set filesystem label"; longdesc = "\ -Set the filesystem label on C<device> to C<label>. +Set the filesystem label on C<mountable> to C<label>. Only some filesystem types support labels, and libguestfs supports setting labels on only a subset of these. @@ -9079,6 +9076,9 @@ On ext2/3/4 filesystems, labels are limited to 16 bytes. On NTFS filesystems, labels are limited to 128 unicode characters. +Setting the label on a btrfs subvolume will set the label on its parent +filesystem. + To read the label on a filesystem, call C<guestfs_vfs_label>." }; { defaults with diff --git a/src/guestfs.pod b/src/guestfs.pod index 283f7ac..60cbab4 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -182,6 +182,37 @@ particular L<virt-inspector(1)>. To mount a filesystem read-only, use L</guestfs_mount_ro>. There are several other variations of the C<guestfs_mount_*> call. +=head2 MOUNTABLES + +A mountable describes the location of a mountable filesystem. Two types of +mountable are currently supported: + +=over + +=item Device name + +This is the name of a block device in the current session. Block devices are +named C</dev/sda>, C</dev/sdb> and so on, as they were added to the guest. If +those block devices contain partitions, they will have the usual names (eg. +C</dev/sda1>). Also LVM C</dev/VG/LV>-style names can be used. + +=item Btrfs Subvolume + +A btrfs subvolume comprises a block device containing a btrfs +filesystem, and the name of a subvolume on that filesystem. It is written as: + + btrfsvol:<block device>/<subvolume> + +where C<block device> is the same format as for L</Device name>. For example, to +specify the subvolume 'root' on the btrfs filesystem on /dev/sda3 would be: + + btrfsvol:/dev/sda3/root + +Note that a btrfs filesystem which spans several block devices is mountable by +specifying any single component block device. + +=back + =head2 FILESYSTEM ACCESS AND MODIFICATION The majority of the libguestfs API consists of fairly low-level calls -- 1.8.1
Matthew Booth
2013-Jan-24 10:19 UTC
[Libguestfs] [PATCH 3/3] mountable: Implement Mountable support for all apis which take it
A Mountable is passed from the library to the daemon as a string. The daemon stub parses it into a mountable_t, which it passes to the implementation. Update all implementations which now take a mountable_t. --- daemon/blkid.c | 36 ++++++++++++++++++++++++++++++------ daemon/daemon.h | 39 +++++++++++++++++++++++++++++++++++++++ daemon/ext2.c | 15 ++++++++++++--- daemon/guestfsd.c | 42 ++++++++++++++++++++++++++++++++++++++++++ daemon/labels.c | 19 +++++++++++++++++-- daemon/mount.c | 52 +++++++++++++++++++++++++++++++++++++++++++--------- generator/c.ml | 12 +++++++++++- generator/daemon.ml | 11 ++++++++--- 8 files changed, 202 insertions(+), 24 deletions(-) diff --git a/daemon/blkid.c b/daemon/blkid.c index b6bc22d..429a005 100644 --- a/daemon/blkid.c +++ b/daemon/blkid.c @@ -69,21 +69,45 @@ get_blkid_tag (const char *device, const char *tag) } char * -do_vfs_type (const char *device) +do_vfs_type (const mountable_t *mountable) { - return get_blkid_tag (device, "TYPE"); + switch (mountable->type) { + case MOUNTABLE_DEVICE: + return get_blkid_tag (mountable->desc.device, "TYPE"); + case MOUNTABLE_BTRFSVOL: + return strdup("btrfs"); + default: + reply_with_error ("Unknown mountable type: %i", mountable->type); + return NULL; + } } char * -do_vfs_label (const char *device) +do_vfs_label (const mountable_t *mountable) { - return get_blkid_tag (device, "LABEL"); + switch (mountable->type) { + case MOUNTABLE_DEVICE: + return get_blkid_tag (mountable->desc.device, "LABEL"); + case MOUNTABLE_BTRFSVOL: + return get_blkid_tag (mountable->desc.btrfsvol.device, "LABEL"); + default: + reply_with_error ("Unknown mountable type: %i", mountable->type); + return NULL; + } } char * -do_vfs_uuid (const char *device) +do_vfs_uuid (const mountable_t *mountable) { - return get_blkid_tag (device, "UUID"); + switch (mountable->type) { + case MOUNTABLE_DEVICE: + return get_blkid_tag (mountable->desc.device, "UUID"); + case MOUNTABLE_BTRFSVOL: + return get_blkid_tag (mountable->desc.btrfsvol.device, "UUID"); + default: + reply_with_error ("Unknown mountable type: %i", mountable->type); + return NULL; + } } /* RHEL5 blkid doesn't have the -p (low-level probing) option and the diff --git a/daemon/daemon.h b/daemon/daemon.h index df1ba3a..8f5015a 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -47,6 +47,24 @@ extern int xwrite (int sock, const void *buf, size_t len) extern int xread (int sock, void *buf, size_t len) __attribute__((__warn_unused_result__)); +/* Mountables */ + +typedef enum { + MOUNTABLE_DEVICE, + MOUNTABLE_BTRFSVOL +} mountable_type_t; + +typedef struct { + mountable_type_t type; + union { + const char *device; + struct { + const char *device; + const char *volume; + } btrfsvol; + } desc; +} mountable_t; + /* Growable strings buffer. */ struct stringsbuf { char **argv; @@ -114,6 +132,8 @@ extern void trim (char *str); extern int device_name_translation (char *device); +extern int parse_btrfsvol (char *desc, mountable_t *mountable); + extern int prog_exists (const char *prog); extern void udev_settle (void); @@ -320,6 +340,25 @@ is_zero (const char *buffer, size_t size) } \ } while (0) +#define RESOLVE_MOUNTABLE(string,mountable,cancel_stmt,fail_stmt) \ + do { \ + if (strncmp ((string), "btrfsvol:", strlen ("btrfsvol:")) == 0) { \ + if (parse_btrfsvol ((string) + strlen ("btrfsvol:"), &(mountable)) == -1)\ + { \ + cancel_stmt; \ + reply_with_error ("%s: %s: expecting a btrfs volume", \ + __func__, (string)); \ + fail_stmt; \ + } \ + } \ + \ + else { \ + mountable.type = MOUNTABLE_DEVICE; \ + mountable.desc.device = (string); \ + RESOLVE_DEVICE((string), cancel_stmt, fail_stmt); \ + } \ + } while (0) + /* Helper for functions which need either an absolute path in the * mounted filesystem, OR a /dev/ device which exists. * diff --git a/daemon/ext2.c b/daemon/ext2.c index ab879db..94e85f0 100644 --- a/daemon/ext2.c +++ b/daemon/ext2.c @@ -127,13 +127,19 @@ do_tune2fs_l (const char *device) int do_set_e2label (const char *device, const char *label) { - return do_set_label (device, label); + mountable_t mountable; + mountable.type = MOUNTABLE_DEVICE; + mountable.desc.device = device; + return do_set_label (&mountable, label); } char * do_get_e2label (const char *device) { - return do_vfs_label (device); + mountable_t mountable; + mountable.type = MOUNTABLE_DEVICE; + mountable.desc.device = device; + return do_vfs_label (&mountable); } int @@ -156,7 +162,10 @@ do_set_e2uuid (const char *device, const char *uuid) char * do_get_e2uuid (const char *device) { - return do_vfs_uuid (device); + mountable_t mountable; + mountable.type = MOUNTABLE_DEVICE; + mountable.desc.device = device; + return do_vfs_uuid (&mountable); } /* If the filesystem is not mounted, run e2fsck -f on it unconditionally. */ diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index 9c1c028..5016780 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -1165,6 +1165,48 @@ device_name_translation (char *device) return -1; } +/* Parse the mountable descriptor for a btrfs subvolume. Don't call this + * directly - use the RESOLVE_MOUNTABLE macro. + * + * A btrfs subvolume is given as: + * + * btrfsvol:/dev/sda3/root + * + * where /dev/sda3 is a block device containing a btrfs filesystem, and root is + * the name of a subvolume on it. This function is passed the string following + * 'btrfsvol:'. + */ +int +parse_btrfsvol (char *desc, mountable_t *mountable) +{ + mountable->type = MOUNTABLE_BTRFSVOL; + + char *device = desc; + + if (strncmp (device, "/dev/", strlen("/dev/")) == -1) + return -1; + + char *volume = NULL; + char *slash = device + strlen("/dev/") - 1; + while ((slash = strchr (slash + 1, '/'))) { + *slash = '\0'; + + if (!is_root_device(device) && device_name_translation (device) == 0) { + volume = slash + 1; + break; + } + + *slash = '/'; + } + + if (!volume) return -1; + + mountable->desc.btrfsvol.device = device; + mountable->desc.btrfsvol.volume = volume; + + return 0; +} + /* Check program exists and is executable on $PATH. Actually, we * just assume PATH contains the default entries (see main() above). */ diff --git a/daemon/labels.c b/daemon/labels.c index ead6b46..e2f045a 100644 --- a/daemon/labels.c +++ b/daemon/labels.c @@ -75,16 +75,31 @@ ntfslabel (const char *device, const char *label) } int -do_set_label (const char *device, const char *label) +do_set_label (const mountable_t *mountable, const char *label) { char *vfs_type; int r; /* How we set the label depends on the filesystem type. */ - vfs_type = do_vfs_type (device); + vfs_type = do_vfs_type (mountable); if (vfs_type == NULL) return -1; + const char *device; + switch (mountable->type) { + case MOUNTABLE_DEVICE: + device = mountable->desc.device; + break; + + case MOUNTABLE_BTRFSVOL: + device = mountable->desc.btrfsvol.device; + break; + + default: + reply_with_error ("Invalid mountable type %i", mountable->type); + return -1; + } + if (STREQ (vfs_type, "ext2") || STREQ (vfs_type, "ext3") || STREQ (vfs_type, "ext4")) r = e2label (device, label); diff --git a/daemon/mount.c b/daemon/mount.c index c84faaf..d0c321a 100644 --- a/daemon/mount.c +++ b/daemon/mount.c @@ -124,7 +124,7 @@ is_device_mounted (const char *device) int do_mount_vfs (const char *options, const char *vfstype, - const char *device, const char *mountpoint) + const mountable_t *mountable, const char *mountpoint) { int r; char *mp; @@ -151,13 +151,47 @@ do_mount_vfs (const char *options, const char *vfstype, return -1; } + char *options_plus = NULL; + const char *device = NULL; + switch (mountable->type) { + case MOUNTABLE_DEVICE: + device = mountable->desc.device; + break; + + case MOUNTABLE_BTRFSVOL: + device = mountable->desc.btrfsvol.device; + if (options && strlen(options) > 1) { + if (asprintf (&options_plus, "subvol=%s,%s", + mountable->desc.btrfsvol.volume, options) == -1) + { + reply_with_perror ("asprintf"); + return -1; + } + } else { + if (asprintf (&options_plus, "subvol=%s", + mountable->desc.btrfsvol.volume) == -1) + { + reply_with_perror ("asprintf"); + return -1; + } + } + break; + + default: + reply_with_error ("Invalid mountable type %i", mountable->type); + return -1; + } + if (vfstype) r = command (NULL, &error, - str_mount, "-o", options, "-t", vfstype, device, mp, NULL); + str_mount, "-o", options_plus ? options_plus : options, + "-t", vfstype, device, mp, NULL); else r = command (NULL, &error, - str_mount, "-o", options, device, mp, NULL); + str_mount, "-o", options_plus ? options_plus : options, + device, mp, NULL); free (mp); + free (options_plus); if (r == -1) { reply_with_error ("%s on %s (options: '%s'): %s", device, mountpoint, options, error); @@ -170,22 +204,22 @@ do_mount_vfs (const char *options, const char *vfstype, } int -do_mount (const char *device, const char *mountpoint) +do_mount (const mountable_t *mountable, const char *mountpoint) { - return do_mount_vfs ("", NULL, device, mountpoint); + return do_mount_vfs ("", NULL, mountable, mountpoint); } int -do_mount_ro (const char *device, const char *mountpoint) +do_mount_ro (const mountable_t *mountable, const char *mountpoint) { - return do_mount_vfs ("ro", NULL, device, mountpoint); + return do_mount_vfs ("ro", NULL, mountable, mountpoint); } int -do_mount_options (const char *options, const char *device, +do_mount_options (const char *options, const mountable_t *mountable, const char *mountpoint) { - return do_mount_vfs (options, NULL, device, mountpoint); + return do_mount_vfs (options, NULL, mountable, mountpoint); } /* Takes optional arguments, consult optargs_bitmask. */ diff --git a/generator/c.ml b/generator/c.ml index c20f502..e0fc852 100644 --- a/generator/c.ml +++ b/generator/c.ml @@ -109,12 +109,18 @@ let rec generate_prototype ?(extern = true) ?(static = false) List.iter ( function | Pathname n - | Device n | Mountable n | Dev_or_Path n + | Device n | Dev_or_Path n | String n | OptString n | Key n -> next (); pr "const char *%s" n + | Mountable n -> + next(); + if in_daemon then + pr "const mountable_t *%s" n + else + pr "const char *%s" n | StringList n | DeviceList n -> next (); pr "char *const *%s" n @@ -148,6 +154,7 @@ let rec generate_prototype ?(extern = true) ?(static = false) (* Generate C call arguments, eg "(handle, foo, bar)" *) and generate_c_call_args ?handle ?(implicit_size_ptr = "&size") + ?(in_daemon = false) (ret, args, optargs) pr "("; let comma = ref false in @@ -164,6 +171,9 @@ and generate_c_call_args ?handle ?(implicit_size_ptr = "&size") | BufferIn n -> next (); pr "%s, %s_size" n n + | Mountable n -> + next (); + pr (if in_daemon then "&%s" else "%s") n | arg -> next (); pr "%s" (name_of_argt arg) diff --git a/generator/daemon.ml b/generator/daemon.ml index a7096a1..094fe6d 100644 --- a/generator/daemon.ml +++ b/generator/daemon.ml @@ -38,6 +38,7 @@ let generate_daemon_actions_h () pr "\n"; pr "#include \"guestfs_protocol.h\"\n"; + pr "#include \"daemon.h\"\n"; pr "\n"; List.iter ( @@ -111,11 +112,12 @@ and generate_daemon_actions () pr " struct guestfs_%s_args args;\n" name; List.iter ( function - | Device n | Mountable n | Dev_or_Path n + | Device n | Dev_or_Path n | Pathname n | String n | Key n | OptString n -> pr " char *%s;\n" n + | Mountable n -> pr " mountable_t %s;\n" n | StringList n | DeviceList n -> pr " char **%s;\n" n | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n @@ -205,10 +207,13 @@ and generate_daemon_actions () pr_args n; pr " ABS_PATH (%s, %s, goto done);\n" n (if is_filein then "cancel_receive ()" else ""); - | Device n | Mountable n -> + | Device n -> pr_args n; pr " RESOLVE_DEVICE (%s, %s, goto done);\n" n (if is_filein then "cancel_receive ()" else ""); + | Mountable n -> + pr " RESOLVE_MOUNTABLE(args.%s, %s, %s, goto done);\n" + n n (if is_filein then "cancel_receive ()" else ""); | Dev_or_Path n -> pr_args n; pr " REQUIRE_ROOT_OR_RESOLVE_DEVICE (%s, %s, goto done);\n" @@ -257,7 +262,7 @@ and generate_daemon_actions () (function FileIn _ | FileOut _ -> false | _ -> true) args in let style = ret, args' @ args_of_optargs optargs, [] in pr " r = do_%s " name; - generate_c_call_args style; + generate_c_call_args ~in_daemon:true style; pr ";\n" in (match ret with -- 1.8.1