From 1765330e07a48dc6f7bdef7007f69ebe606fa731 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Sat, 18 Apr 2009 13:17:12 +0100 Subject: [PATCH 1/1] Rewrite of main loop impl, start of FileIn/FileOut support. --- daemon/Makefile.am | 1 + daemon/daemon.h | 25 +- daemon/upload.c | 40 + fish/cmds.c | 2 +- guestfish-actions.pod | 2 +- guestfs-actions.pod | 2 +- guestfs.pod | 151 +-- perl/lib/Sys/Guestfs.pm | 2 +- python/guestfs-py.c | 1 - python/guestfs.py | 2 +- src/generator.ml | 360 ++++-- src/guestfs-actions.c | 3133 +++++++++++++++++++++++++++-------------------- src/guestfs.c | 432 +++++-- src/guestfs.h | 32 +- src/guestfs_protocol.c | 12 + src/guestfs_protocol.h | 14 +- src/guestfs_protocol.x | 40 +- 17 files changed, 2578 insertions(+), 1673 deletions(-) create mode 100644 daemon/upload.c diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 75de066..1c1609d 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -36,6 +36,7 @@ guestfsd_SOURCES = \ stubs.c \ sync.c \ tune2fs.c \ + upload.c \ ../src/guestfs_protocol.h \ ../src/guestfs_protocol.c diff --git a/daemon/daemon.h b/daemon/daemon.h index 27d86c9..ca71265 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -30,7 +30,7 @@ #include "../src/guestfs_protocol.h" -/* in guestfsd.c */ +/*-- in guestfsd.c --*/ extern int xwrite (int sock, const void *buf, size_t len); extern int xread (int sock, void *buf, size_t len); @@ -44,25 +44,37 @@ extern int command (char **stdoutput, char **stderror, const char *name, ...); extern int commandv (char **stdoutput, char **stderror, char * const* const argv); -/* in proto.c */ +/*-- in proto.c --*/ extern int proc_nr; extern int serial; -/* in mount.c */ +/*-- in mount.c --*/ extern int root_mounted; -/* in stubs.c (auto-generated) */ +/*-- in stubs.c (auto-generated) --*/ extern void dispatch_incoming_message (XDR *); extern guestfs_lvm_int_pv_list *parse_command_line_pvs (void); extern guestfs_lvm_int_vg_list *parse_command_line_vgs (void); extern guestfs_lvm_int_lv_list *parse_command_line_lvs (void); -/* in proto.c */ +/*-- in proto.c --*/ extern void main_loop (int sock); + +/* ordinary daemon functions use these to indicate errors */ extern void reply_with_error (const char *fs, ...); extern void reply_with_perror (const char *fs, ...); + +/* daemon functions that return files (FileOut) should call + * reply, then send_file for each FileOut parameter. + */ +#if 0 +extern void send_file (); +#endif + +/* only call this if there is a FileOut parameter */ extern void reply (xdrproc_t xdrp, char *ret); +/* Helper for functions that need a root filesystem mounted. */ #define NEED_ROOT(errcode) \ do { \ if (!root_mounted) { \ @@ -72,6 +84,7 @@ extern void reply (xdrproc_t xdrp, char *ret); } \ while (0) +/* Helper for functions that need an argument ("path") that is absolute. */ #define ABS_PATH(path,errcode) \ do { \ if ((path)[0] != '/') { \ @@ -80,6 +93,7 @@ extern void reply (xdrproc_t xdrp, char *ret); } \ } while (0) +/* Helper for functions that need an argument ("path") that is a device. */ #define IS_DEVICE(path,errcode) \ do { \ struct stat statbuf; \ @@ -104,6 +118,7 @@ extern void reply (xdrproc_t xdrp, char *ret); #define CHROOT_OUT \ do { int old_errno = errno; chroot ("."); errno = old_errno; } while (0) +/* Marks functions which are not implemented. */ #define XXX_NOT_IMPL(errcode) \ do { \ reply_with_error ("%s: function not implemented", __func__); \ diff --git a/daemon/upload.c b/daemon/upload.c new file mode 100644 index 0000000..d2feb02 --- /dev/null +++ b/daemon/upload.c @@ -0,0 +1,40 @@ +/* libguestfs - the guestfsd daemon + * Copyright (C) 2009 Red Hat Inc. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include +#include +#include +#include + +#include "../src/guestfs_protocol.h" +#include "daemon.h" +#include "actions.h" + +int +do_upload (const char *remote_filename) +{ + XXX_NOT_IMPL (-1); +} + +int +do_download (const char *remote_filename) +{ + XXX_NOT_IMPL (-1); +} diff --git a/fish/cmds.c b/fish/cmds.c index 8ee72d2..c197ece 100644 --- a/fish/cmds.c +++ b/fish/cmds.c @@ -155,7 +155,7 @@ void display_command (const char *cmd) pod2text ("touch - update file timestamps or create a new file", " touch \n\nTouch acts like the L command. It can be used to\nupdate the timestamps on a file, or, if the file does not exist,\nto create a new zero-length file."); else if (strcasecmp (cmd, "cat") == 0) - pod2text ("cat - list the contents of a file", " cat \n\nReturn the contents of the file named C.\n\nNote that this function cannot correctly handle binary files\n(specifically, files containing C<\\0> character which is treated\nas end of string). For those you need to use the C\nfunction which has a more complex interface.\n\nBecause of the message protocol, there is a transfer limit \nof somewhere between 2MB and 4MB. To transfer large files you should use\nFTP."); + pod2text ("cat - list the contents of a file", " cat \n\nReturn the contents of the file named C.\n\nNote that this function cannot correctly handle binary files\n(specifically, files containing C<\\0> character which is treated\nas end of string). For those you need to use the C\nfunction which has a more complex interface.\n\nBecause of the message protocol, there is a transfer limit \nof somewhere between 2MB and 4MB. To transfer large files you should use\nFTP."); else if (strcasecmp (cmd, "ll") == 0) pod2text ("ll - list the files in a directory (long format)", " ll \n\nList the files in C (relative to the root directory,\nthere is no cwd) in the format of 'ls -la'.\n\nThis command is mostly useful for interactive sessions. It\nis I intended that you try to parse the output string."); diff --git a/guestfish-actions.pod b/guestfish-actions.pod index d4c0401..116878d 100644 --- a/guestfish-actions.pod +++ b/guestfish-actions.pod @@ -289,7 +289,7 @@ Return the contents of the file named C. Note that this function cannot correctly handle binary files (specifically, files containing C<\0> character which is treated -as end of string). For those you need to use the C +as end of string). For those you need to use the C function which has a more complex interface. Because of the message protocol, there is a transfer limit diff --git a/guestfs-actions.pod b/guestfs-actions.pod index cb2415c..520425c 100644 --- a/guestfs-actions.pod +++ b/guestfs-actions.pod @@ -378,7 +378,7 @@ Return the contents of the file named C. Note that this function cannot correctly handle binary files (specifically, files containing C<\0> character which is treated -as end of string). For those you need to use the C +as end of string). For those you need to use the C function which has a more complex interface. This function returns a string, or NULL on error. diff --git a/guestfs.pod b/guestfs.pod index 6c01600..cce7b90 100644 --- a/guestfs.pod +++ b/guestfs.pod @@ -86,9 +86,8 @@ C is the opaque type representing a connection handle. Create a handle by calling C. Call C to free the handle and release all resources used. -Handles and operations on handles are not thread safe. However you -can use a separate handle for each thread (but not on the same disk -image). +For information on using multiple handles and threads, see the section +MULTIPLE HANDLES AND MULTIPLE THREADS below. =head2 guestfs_create @@ -312,34 +311,21 @@ this function with C set to C. =head2 NON-BLOCKING ACTIONS -XXX NOT IMPLEMENTED YET XXX +XXX This section was documented in previous versions but never +implemented in a way which matched the documentation. For now I have +removed the documentation, pending a working implementation. See also +C in the source. -C is the most interesting callback to -play with, since it allows you to perform actions without blocking. -For example: +=head2 guestfs_set_send_callback - do_it () - { - start_call (); - guestfs_main_loop_run (); /* --> blocks, then calls my_cb */ - } + typedef void (*guestfs_send_cb) (guestfs_h *g, void *opaque); + void guestfs_set_send_callback (guestfs_h *handle, + guestfs_send_cb cb, + void *opaque); - start_call () - { - guestfs_set_reply_callback (handle, my_cb, data); - guestfs_nb_[action] (handle, [other parameters ...]); - /* returns immediately */ - } - - my_cb (guestfs_h *handle, void *data, XDR *xdr) - { - retval = guestfs_nb_[action]_r (handle, xdr); - /* ... */ - } - -There are C and C functions -corresponding to every C action in the high-level API. +The callback function C will be called whenever a message +which is queued for sending, has been sent. =head2 guestfs_set_reply_callback @@ -400,9 +386,10 @@ non-blocking wait for the child process to finish booting up. =head2 EVENT MAIN LOOP -To use the low-level event API, you have to provide an event "main -loop". You can write your own, but if you don't want to write one, -two are provided for you: +To use the low-level event API and/or to use handles from multiple +threads, you have to provide an event "main loop". You can write your +own, but if you don't want to write one, two types are provided for +you: =over 4 @@ -410,8 +397,8 @@ two are provided for you: A simple main loop that is implemented using L. -This is the default main loop unless you call C -or C. +This is the default main loop for new guestfs handles, unless you +call C after a handle is created. =item libguestfs-glib @@ -421,67 +408,83 @@ without hanging during long or slow operations. =back -=head2 guestfs_set_main_loop +=head2 MULTIPLE HANDLES AND MULTIPLE THREADS + +The support for multiple handles and multiple threads is modelled +after glib (although doesn't require glib, if you use the select-based +main loop). + +L + +You will need to create one main loop for each thread that wants to +use libguestfs. Each guestfs handle should be confined to one thread. +If you try to pass guestfs handles between threads, you will get +undefined results. + +If you only want to use guestfs handles from one thread in your +program, but your program has other threads doing other things, then +you don't need to do anything special. - void guestfs_set_main_loop (guestfs_main_loop *); +=head2 SINGLE THREAD CASE -This call sets the current main loop to the list of callbacks -contained in the C structure. +In the single thread case, there is a single select-based main loop +created for you. All guestfs handles will use this main loop to +execute high level API actions. -Only one main loop implementation can be used by libguestfs, so -calling this replaces the previous one. (So this is something that -has to be done by the main program, but only the main program "knows" -that it is a GTK+ program or whatever). +=head2 MULTIPLE THREADS CASE + +In the multiple threads case, you will need to create a main loop for +each thread that wants to use libguestfs. + +To create main loops for other threads, use +C or C. + +Then you will need to attach each handle to the thread-specific main +loop by calling: + + handle = guestfs_create (); + guestfs_set_main_loop (handle, main_loop_of_current_thread); + +=head2 guestfs_set_main_loop -You should call this early in the main program, certainly before -calling C. + void guestfs_set_main_loop (guestfs_h *handle, + guestfs_main_loop *main_loop); -=head2 guestfs_glib_set_main_loop +Sets the main loop used by high level API actions for this handle. By +default, the select-based main loop is used (see +C). - void guestfs_glib_set_main_loop (GMainLoop *); +You only need to use this in multi-threaded programs, where multiple +threads want to use libguestfs. Create a main loop for each thread, +then call this function. -This helper calls C with the correct callbacks -for integrating with the GLib main loop. +You cannot pass guestfs handles between threads. -The libguestfs-glib main loop is contained in a separate library, so -that libguestfs doesn't depend on the whole of GLib: +=head2 guestfs_get_main_loop - #include - #include + guestfs_main_loop *guestfs_get_main_loop (guestfs_h *handle); - main () - { - GMainLoop *loop = - g_main_loop_new (g_main_context_default (), 1); - ... - guestfs_glib_set_main_loop (loop); - ... - g_main_loop_run (loop); - } +Return the main loop used by C. -To use this main loop you must link with C<-lguestfs-glib>. (See also -the GLib and GTK+ documentation). +=head2 guestfs_get_default_main_loop -=head2 guestfs_main_loop_run + guestfs_main_loop *guestfs_get_default_main_loop (void); - void guestfs_main_loop_run (void); +Return the default select-based main loop. -This calls the main loop. +=head2 guestfs_create_main_loop -For some types of main loop you may want or prefer to call another -function, eg. C, or the main loop may already be -invoked by another part of your program. In those cases, ignore this -call. + guestfs_main_loop *guestfs_create_main_loop (void); -=head2 guestfs_main_loop_quit +This creates a select-based main loop. You should create one main +loop for each additional thread that needs to use libguestfs. - void guestfs_main_loop_quit (void); +=head2 guestfs_free_main_loop -This instructs the main loop to quit. In other words, -C will return. + void guestfs_free_main_loop (guestfs_main_loop *); -For some types of main loop you may want or prefer to call another -function, eg. C. In those cases, ignore this call. +Free the select-based main loop which was previously allocated with +C. =head2 WRITING A CUSTOM MAIN LOOP diff --git a/perl/lib/Sys/Guestfs.pm b/perl/lib/Sys/Guestfs.pm index a351d57..28d2b0f 100644 --- a/perl/lib/Sys/Guestfs.pm +++ b/perl/lib/Sys/Guestfs.pm @@ -330,7 +330,7 @@ Return the contents of the file named C. Note that this function cannot correctly handle binary files (specifically, files containing C<\0> character which is treated -as end of string). For those you need to use the C<$h-Eread_file> +as end of string). For those you need to use the C<$h-Edownload> function which has a more complex interface. Because of the message protocol, there is a transfer limit diff --git a/python/guestfs-py.c b/python/guestfs-py.c index c8df178..09d4270 100644 --- a/python/guestfs-py.c +++ b/python/guestfs-py.c @@ -103,7 +103,6 @@ put_table (char * const * const argv) list = PyList_New (argc >> 1); for (i = 0; i < argc; i += 2) { - PyObject *item; item = PyTuple_New (2); PyTuple_SetItem (item, 0, PyString_FromString (argv[i])); PyTuple_SetItem (item, 1, PyString_FromString (argv[i+1])); diff --git a/python/guestfs.py b/python/guestfs.py index 9739fa5..0a4c396 100644 --- a/python/guestfs.py +++ b/python/guestfs.py @@ -236,7 +236,7 @@ class GuestFS: Note that this function cannot correctly handle binary files (specifically, files containing "\\0" character which is treated as end of string). For those you need - to use the "g.read_file" function which has a more + to use the "g.download" function which has a more complex interface. Because of the message protocol, there is a transfer diff --git a/src/generator.ml b/src/generator.ml index c0a4740..77bcc47 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -98,6 +98,16 @@ and argt = | StringList of string(* list of strings (each string cannot be NULL) *) | Bool of string (* boolean *) | Int of string (* int (smallish ints, signed, <= 31 bits) *) + (* These are treated as filenames (simple string parameters) in + * the C API and bindings. But in the RPC protocol, we transfer + * the actual file content up to or down from the daemon. + * FileIn: local machine -> daemon (in request) + * FileOut: daemon -> local machine (in reply) + * In guestfish (only), the special name "-" means read from + * stdin or write to stdout. + *) + | FileIn of string + | FileOut of string type flags = | ProtocolLimitWarning (* display warning about protocol size limits *) @@ -384,7 +394,7 @@ Return the contents of the file named C. Note that this function cannot correctly handle binary files (specifically, files containing C<\\0> character which is treated -as end of string). For those you need to use the C +as end of string). For those you need to use the C function which has a more complex interface."); ("ll", (RString "listing", [String "directory"]), 5, [], @@ -1198,6 +1208,30 @@ Reread the partition table on C. This uses the L command."); +(* + ("upload", (RErr, [FileIn "filename"; String "remotefilename"]), 66, [], + [], + "upload a file from the local machine", + "\ +Upload local file C to C on the +filesystem. + +C can also be a named pipe. + +See also C."); + + ("download", (RErr, [String "remotefilename"; FileOut "filename"]), 67, [], + [], + "download a file to the local machine", + "\ +Download file C and save it as C +on the local machine. + +C can also be a named pipe. + +See also C, C."); +*) + ] let all_functions = non_daemon_functions @ daemon_functions @@ -1410,7 +1444,8 @@ let mapi f xs = loop 0 xs let name_of_argt = function - | String n | OptString n | StringList n | Bool n | Int n -> n + | String n | OptString n | StringList n | Bool n | Int n + | FileIn n | FileOut n -> n let seq_of_test = function | TestRun s | TestOutput (s, _) | TestOutputList (s, _) @@ -1765,6 +1800,7 @@ and generate_xdr () = | StringList n -> pr " str %s<>;\n" n | Bool n -> pr " bool %s;\n" n | Int n -> pr " int %s;\n" n + | FileIn _ | FileOut _ -> () ) args; pr "};\n\n" ); @@ -1830,7 +1866,7 @@ and generate_xdr () = fun (shortname, _, proc_nr, _, _, _, _) -> pr " GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr ) daemon_functions; - pr " GUESTFS_PROC_dummy\n"; (* so we don't have a "hanging comma" *) + pr " GUESTFS_PROC_NR_PROCS\n"; pr "};\n"; pr "\n"; @@ -1864,6 +1900,19 @@ struct guestfs_message_error { string error; /* error message */ }; +/* For normal requests and replies (not involving any FileIn or + * FileOut parameters), the protocol is: + * + * For requests: + * total length (header + args, but not including length word itself) + * header + * guestfs_foo_args struct + * For replies: + * total length (as above) + * header + * guestfs_foo_ret struct + */ + struct guestfs_message_header { unsigned prog; /* GUESTFS_PROGRAM */ unsigned vers; /* GUESTFS_PROTOCOL_VERSION */ @@ -1872,6 +1921,31 @@ struct guestfs_message_header { unsigned serial; /* message serial number */ guestfs_message_status status; }; + +/* Chunked encoding used to transfer files, for FileIn and FileOut + * parameters. + * + * For requests which have >= 1 FileIn parameter: + * length of header + args (but not length word itself, and not chunks) + * header + * guestfs_foo_args struct + * sequence of chunks for FileIn param #0 + * sequence of chunks for FileIn param #1 etc + * + * For replies which have >= 1 FileOut parameter: + * length of header + ret (but not length word itself, and not chunks) + * header + * guestfs_foo_ret struct + * sequence of chunks for FileOut param #0 + * sequence of chunks for FileOut param #1 etc + */ +const GUESTFS_MAX_CHUNK_SIZE = 8192; + +struct guestfs_chunk { + int cancel; /* if non-zero, transfer is cancelled */ + /* data size is 0 bytes if the transfer has finished successfully */ + opaque data; +}; " (* Generate the guestfs-structs.h file. *) @@ -1953,9 +2027,14 @@ and generate_client_actions () = fun (shortname, style, _, _, _, _, _) -> let name = "guestfs_" ^ shortname in - (* Generate the return value struct. *) - pr "struct %s_rv {\n" shortname; - pr " int cb_done; /* flag to indicate callback was called */\n"; + (* Generate the state struct which stores the high-level + * state between callback functions. The callback(s) are: + * _cb_header_sent header was sent + * _cb_file_sent FileIn file was sent + * _cb_reply_received reply received + *) + pr "struct %s_state {\n" shortname; + pr " int cb_done;\n"; pr " struct guestfs_message_header hdr;\n"; pr " struct guestfs_message_error err;\n"; (match fst style with @@ -1970,19 +2049,20 @@ and generate_client_actions () = | RHashtable _ -> pr " struct %s_ret ret;\n" name ); - pr "};\n\n"; + pr "};\n"; + pr "\n"; (* Generate the callback function. *) pr "static void %s_cb (guestfs_h *g, void *data, XDR *xdr)\n" shortname; pr "{\n"; - pr " struct %s_rv *rv = (struct %s_rv *) data;\n" shortname shortname; + pr " struct %s_state *state = (struct %s_state *) data;\n" shortname shortname; pr "\n"; - pr " if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {\n"; + pr " if (!xdr_guestfs_message_header (xdr, &state->hdr)) {\n"; pr " error (g, \"%s: failed to parse reply header\");\n" name; pr " return;\n"; pr " }\n"; - pr " if (rv->hdr.status == GUESTFS_STATUS_ERROR) {\n"; - pr " if (!xdr_guestfs_message_error (xdr, &rv->err)) {\n"; + pr " if (state->hdr.status == GUESTFS_STATUS_ERROR) {\n"; + pr " if (!xdr_guestfs_message_error (xdr, &state->err)) {\n"; pr " error (g, \"%s: failed to parse reply error\");\n" name; pr " return;\n"; pr " }\n"; @@ -1999,15 +2079,15 @@ and generate_client_actions () = | RPVList _ | RVGList _ | RLVList _ | RStat _ | RStatVFS _ | RHashtable _ -> - pr " if (!xdr_%s_ret (xdr, &rv->ret)) {\n" name; + pr " if (!xdr_%s_ret (xdr, &state->ret)) {\n" name; pr " error (g, \"%s: failed to parse reply\");\n" name; pr " return;\n"; pr " }\n"; ); pr " done:\n"; - pr " rv->cb_done = 1;\n"; - pr " main_loop.main_loop_quit (g);\n"; + pr " state->cb_done = 1;\n"; + pr " g->main_loop->main_loop_quit (g->main_loop, g);\n"; pr "}\n\n"; (* Generate the action stub. *) @@ -2032,19 +2112,26 @@ and generate_client_actions () = | _ -> pr " struct %s_args args;\n" name ); - pr " struct %s_rv rv;\n" shortname; + pr " struct %s_state state;\n" shortname; pr " int serial;\n"; pr "\n"; pr " if (g->state != READY) {\n"; - pr " error (g, \"%s called from the wrong state, %%d != READY\",\n" - name; - pr " g->state);\n"; + pr " if (g->state == CONFIG)\n"; + pr " error (g, \"%%s: call launch() before using this function\",\n"; + pr " \"%s\");\n" name; + pr " else if (g->state == LAUNCHING)\n"; + pr " error (g, \"%%s: call wait_ready() before using this function\",\n"; + pr " \"%s\");\n" name; + pr " else\n"; + pr " error (g, \"%%s called from the wrong state, %%d != READY\",\n"; + pr " \"%s\", g->state);\n" name; pr " return %s;\n" error_code; pr " }\n"; pr "\n"; - pr " memset (&rv, 0, sizeof rv);\n"; + pr " memset (&state, 0, sizeof state);\n"; pr "\n"; + (* Dispatch the main header and arguments. *) (match snd style with | [] -> pr " serial = dispatch (g, GUESTFS_PROC_%s, NULL, NULL);\n" @@ -2063,6 +2150,7 @@ and generate_client_actions () = pr " args.%s = %s;\n" n n | Int n -> pr " args.%s = %s;\n" n n + | FileIn _ | FileOut _ -> () ) args; pr " serial = dispatch (g, GUESTFS_PROC_%s,\n" (String.uppercase shortname); @@ -2073,52 +2161,73 @@ and generate_client_actions () = pr " return %s;\n" error_code; pr "\n"; - pr " rv.cb_done = 0;\n"; + (* Send any additional files requested. *) + List.iter ( + function + | FileIn n -> + pr " if (send_file (g, %s) == -1)\n" n; + pr " return %s;\n" error_code; + pr "\n"; + | _ -> () + ) (snd style); + + (* Wait for the reply from the remote end. *) + pr " state.cb_done = 0;\n"; pr " g->reply_cb_internal = %s_cb;\n" shortname; - pr " g->reply_cb_internal_data = &rv;\n"; - pr " main_loop.main_loop_run (g);\n"; + pr " g->reply_cb_internal_data = &state;\n"; + pr " (void) g->main_loop->main_loop_run (g->main_loop, g);\n"; pr " g->reply_cb_internal = NULL;\n"; pr " g->reply_cb_internal_data = NULL;\n"; - pr " if (!rv.cb_done) {\n"; + pr " if (!state.cb_done) {\n"; pr " error (g, \"%s failed, see earlier error messages\");\n" name; pr " return %s;\n" error_code; pr " }\n"; pr "\n"; - pr " if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_%s, serial) == -1)\n" + pr " if (check_reply_header (g, &state.hdr, GUESTFS_PROC_%s, serial) == -1)\n" (String.uppercase shortname); pr " return %s;\n" error_code; pr "\n"; - pr " if (rv.hdr.status == GUESTFS_STATUS_ERROR) {\n"; - pr " error (g, \"%%s\", rv.err.error);\n"; + pr " if (state.hdr.status == GUESTFS_STATUS_ERROR) {\n"; + pr " error (g, \"%%s\", state.err.error);\n"; pr " return %s;\n" error_code; pr " }\n"; pr "\n"; + (* Expecting to receive further files (FileOut)? *) + List.iter ( + function + | FileOut n -> + pr " if (receive_file (g, %s) == -1)\n" n; + pr " return %s;\n" error_code; + pr "\n"; + | _ -> () + ) (snd style); + (match fst style with | RErr -> pr " return 0;\n" | RInt n | RInt64 n | RBool n -> - pr " return rv.ret.%s;\n" n + pr " return state.ret.%s;\n" n | RConstString _ -> failwithf "RConstString cannot be returned from a daemon function" | RString n -> - pr " return rv.ret.%s; /* caller will free */\n" n + pr " return state.ret.%s; /* caller will free */\n" n | RStringList n | RHashtable n -> pr " /* caller will free this, but we need to add a NULL entry */\n"; - pr " rv.ret.%s.%s_val =" n n; - pr " safe_realloc (g, rv.ret.%s.%s_val,\n" n n; - pr " sizeof (char *) * (rv.ret.%s.%s_len + 1));\n" + pr " state.ret.%s.%s_val =" n n; + pr " safe_realloc (g, state.ret.%s.%s_val,\n" n n; + pr " sizeof (char *) * (state.ret.%s.%s_len + 1));\n" n n; - pr " rv.ret.%s.%s_val[rv.ret.%s.%s_len] = NULL;\n" n n n n; - pr " return rv.ret.%s.%s_val;\n" n n + pr " state.ret.%s.%s_val[state.ret.%s.%s_len] = NULL;\n" n n n n; + pr " return state.ret.%s.%s_val;\n" n n | RIntBool _ -> pr " /* caller with free this */\n"; - pr " return safe_memdup (g, &rv.ret, sizeof (rv.ret));\n" + pr " return safe_memdup (g, &state.ret, sizeof (state.ret));\n" | RPVList n | RVGList n | RLVList n | RStat n | RStatVFS n -> pr " /* caller will free this */\n"; - pr " return safe_memdup (g, &rv.ret.%s, sizeof (rv.ret.%s));\n" n n + pr " return safe_memdup (g, &state.ret.%s, sizeof (state.ret.%s));\n" n n ); pr "}\n\n" @@ -2189,6 +2298,7 @@ and generate_daemon_actions () = | StringList n -> pr " char **%s;\n" n | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n + | FileIn _ | FileOut _ -> () ) args ); pr "\n"; @@ -2212,12 +2322,19 @@ and generate_daemon_actions () = pr " %s = args.%s.%s_val;\n" n n n | Bool n -> pr " %s = args.%s;\n" n n | Int n -> pr " %s = args.%s;\n" n n + | FileIn _ | FileOut _ -> () ) args; pr "\n" ); + (* Don't want to call the impl with any FileIn or FileOut + * parameters, since these go "outside" the RPC protocol. + *) + let argsnofile = + List.filter (function FileIn _ | FileOut _ -> false | _ -> true) + (snd style) in pr " r = do_%s " name; - generate_call_args style; + generate_call_args argsnofile; pr ";\n"; pr " if (r == %s)\n" error_code; @@ -2225,34 +2342,48 @@ and generate_daemon_actions () = pr " goto done;\n"; pr "\n"; - (match fst style with - | RErr -> pr " reply (NULL, NULL);\n" - | RInt n | RInt64 n | RBool n -> - 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 - | RConstString _ -> - failwithf "RConstString cannot be returned from a daemon function" - | RString n -> - 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 " free (r);\n" - | RStringList n | RHashtable n -> - pr " struct guestfs_%s_ret ret;\n" name; - pr " ret.%s.%s_len = count_strings (r);\n" n n; - pr " ret.%s.%s_val = r;\n" n n; - pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n" name; - pr " free_strings (r);\n" - | RIntBool _ -> - pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) r);\n" name; - pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) r);\n" name - | RPVList n | RVGList n | RLVList n - | RStat n | RStatVFS n -> - 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 + (* If there are any FileOut parameters, then the impl must + * send its own reply. + *) + let no_reply = + List.exists (function FileOut _ -> true | _ -> false) (snd style) in + if no_reply then + pr " /* do_%s has already sent a reply */\n" name + else ( + match fst style with + | RErr -> pr " reply (NULL, NULL);\n" + | RInt n | RInt64 n | RBool n -> + 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 + | RConstString _ -> + failwithf "RConstString cannot be returned from a daemon function" + | RString n -> + 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 " free (r);\n" + | RStringList n | RHashtable n -> + pr " struct guestfs_%s_ret ret;\n" name; + pr " ret.%s.%s_len = count_strings (r);\n" n n; + pr " ret.%s.%s_val = r;\n" n n; + pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n" + name; + pr " free_strings (r);\n" + | RIntBool _ -> + pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) r);\n" + name; + pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) r);\n" name + | RPVList n | RVGList n | RLVList n + | RStat n | RStatVFS n -> + 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 ); (* Free the args. *) @@ -2890,6 +3021,7 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd = | OptString _, _ | Int _, _ | Bool _, _ -> () + | FileIn _, _ | FileOut _, _ -> () | StringList n, arg -> pr " char *%s[] = {\n" n; let strs = string_split " " arg in @@ -2929,7 +3061,9 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd = (* Generate the parameters. *) List.iter ( function - | String _, arg -> pr ", \"%s\"" (c_quote arg) + | String _, arg + | FileIn _, arg | FileOut _, arg -> + pr ", \"%s\"" (c_quote arg) | OptString _, arg -> if arg = "NULL" then pr ", NULL" else pr ", \"%s\"" (c_quote arg) | StringList n, _ -> @@ -3151,7 +3285,9 @@ and generate_fish_cmds () = List.iter ( function | String n - | OptString n -> pr " const char *%s;\n" n + | OptString n + | FileIn n + | FileOut n -> pr " const char *%s;\n" n | StringList n -> pr " char **%s;\n" n | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n @@ -3172,6 +3308,12 @@ and generate_fish_cmds () = | OptString name -> pr " %s = strcmp (argv[%d], \"\") != 0 ? argv[%d] : NULL;\n" name i i + | FileIn name -> + pr " %s = strcmp (argv[%d], \"-\") != 0 ? argv[%d] : \"/dev/stdin\";\n" + name i i + | FileOut name -> + pr " %s = strcmp (argv[%d], \"-\") != 0 ? argv[%d] : \"/dev/stdout\";\n" + name i i | StringList name -> pr " %s = parse_string_list (argv[%d]);\n" name i | Bool name -> @@ -3185,7 +3327,7 @@ and generate_fish_cmds () = try find_map (function FishAction n -> Some n | _ -> None) flags with Not_found -> sprintf "guestfs_%s" name in pr " r = %s " fn; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; (* Check return value for errors and display command results. *) @@ -3394,11 +3536,16 @@ and generate_fish_actions_pod () = | StringList n -> pr " %s,..." n | Bool _ -> pr " true|false" | Int n -> pr " %s" n + | FileIn n | FileOut n -> pr " (%s|-)" n ) (snd style); pr "\n"; pr "\n"; pr "%s\n\n" longdesc; + if List.exists (function FileIn _ | FileOut _ -> true + | _ -> false) (snd style) then + pr "Use C<-> instead of a filename to read/write from stdin/stdout.\n\n"; + if List.mem ProtocolLimitWarning flags then pr "%s\n\n" protocol_limit_warning; @@ -3457,11 +3604,14 @@ and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true) in List.iter ( function - | String n -> next (); pr "const char *%s" n + | String n | OptString n -> next (); pr "const char *%s" n | StringList n -> next (); pr "char * const* const %s" n | Bool n -> next (); pr "int %s" n | Int n -> next (); pr "int %s" n + | FileIn n + | FileOut n -> + if not in_daemon then (next (); pr "const char *%s" n) ) (snd style); ); pr ")"; @@ -3469,7 +3619,7 @@ and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true) if newline then pr "\n" (* Generate C call arguments, eg "(handle, foo, bar)" *) -and generate_call_args ?handle style = +and generate_call_args ?handle args = pr "("; let comma = ref false in (match handle with @@ -3480,13 +3630,8 @@ and generate_call_args ?handle style = fun arg -> if !comma then pr ", "; comma := true; - match arg with - | String n - | OptString n - | StringList n - | Bool n - | Int n -> pr "%s" n - ) (snd style); + pr "%s" (name_of_argt arg) + ) args; pr ")" (* Generate the OCaml bindings interface. *) @@ -3715,7 +3860,9 @@ copy_table (char * const * argv) List.iter ( function - | String n -> + | String n + | FileIn n + | FileOut n -> pr " const char *%s = String_val (%sv);\n" n n | OptString n -> pr " const char *%s =\n" n; @@ -3760,7 +3907,7 @@ copy_table (char * const * argv) pr " caml_enter_blocking_section ();\n"; pr " r = guestfs_%s " name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; pr " caml_leave_blocking_section ();\n"; @@ -3768,7 +3915,7 @@ copy_table (char * const * argv) function | StringList n -> pr " ocaml_guestfs_free_strings (%s);\n" n; - | String _ | OptString _ | Bool _ | Int _ -> () + | String _ | OptString _ | Bool _ | Int _ | FileIn _ | FileOut _ -> () ) (snd style); pr " if (r == %s)\n" error_code; @@ -3864,7 +4011,7 @@ and generate_ocaml_prototype ?(is_external = false) name style = pr "%s : t -> " name; List.iter ( function - | String _ -> pr "string -> " + | String _ | FileIn _ | FileOut _ -> pr "string -> " | OptString _ -> pr "string option -> " | StringList _ -> pr "string array -> " | Bool _ -> pr "bool -> " @@ -4003,12 +4150,12 @@ DESTROY (g) ); (* Call and arguments. *) pr "%s " name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr "\n"; pr " guestfs_h *g;\n"; List.iter ( function - | String n -> pr " char *%s;\n" n + | String n | FileIn n | FileOut n -> pr " char *%s;\n" n | OptString n -> pr " char *%s;\n" n | StringList n -> pr " char **%s;\n" n | Bool n -> pr " int %s;\n" n @@ -4018,10 +4165,8 @@ DESTROY (g) let do_cleanups () = List.iter ( function - | String _ - | OptString _ - | Bool _ - | Int _ -> () + | String _ | OptString _ | Bool _ | Int _ + | FileIn _ | FileOut _ -> () | StringList n -> pr " free (%s);\n" n ) (snd style) in @@ -4033,7 +4178,7 @@ DESTROY (g) pr " int r;\n"; pr " PPCODE:\n"; pr " r = guestfs_%s " name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; do_cleanups (); pr " if (r == -1)\n"; @@ -4044,7 +4189,7 @@ DESTROY (g) pr " int %s;\n" n; pr " CODE:\n"; pr " %s = guestfs_%s " n name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; do_cleanups (); pr " if (%s == -1)\n" n; @@ -4057,7 +4202,7 @@ DESTROY (g) pr " int64_t %s;\n" n; pr " CODE:\n"; pr " %s = guestfs_%s " n name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; do_cleanups (); pr " if (%s == -1)\n" n; @@ -4070,7 +4215,7 @@ DESTROY (g) pr " const char *%s;\n" n; pr " CODE:\n"; pr " %s = guestfs_%s " n name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; do_cleanups (); pr " if (%s == NULL)\n" n; @@ -4083,7 +4228,7 @@ DESTROY (g) pr " char *%s;\n" n; pr " CODE:\n"; pr " %s = guestfs_%s " n name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; do_cleanups (); pr " if (%s == NULL)\n" n; @@ -4098,7 +4243,7 @@ DESTROY (g) pr " int i, n;\n"; pr " PPCODE:\n"; pr " %s = guestfs_%s " n name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; do_cleanups (); pr " if (%s == NULL)\n" n; @@ -4115,7 +4260,7 @@ DESTROY (g) pr " struct guestfs_int_bool *r;\n"; pr " PPCODE:\n"; pr " r = guestfs_%s " name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; do_cleanups (); pr " if (r == NULL)\n"; @@ -4147,7 +4292,7 @@ and generate_perl_lvm_code typ cols name style n do_cleanups = pr " HV *hv;\n"; pr " PPCODE:\n"; pr " %s = guestfs_%s " n name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; do_cleanups (); pr " if (%s == NULL)\n" n; @@ -4182,7 +4327,7 @@ and generate_perl_stat_code typ cols name style n do_cleanups = pr " struct guestfs_%s *%s;\n" typ n; pr " PPCODE:\n"; pr " %s = guestfs_%s " n name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; do_cleanups (); pr " if (%s == NULL)\n" n; @@ -4338,7 +4483,7 @@ and generate_perl_prototype name style = if !comma then pr ", "; comma := true; match arg with - | String n | OptString n | Bool n | Int n -> + | String n | OptString n | Bool n | Int n | FileIn n | FileOut n -> pr "$%s" n | StringList n -> pr "\\@%s" n @@ -4434,7 +4579,6 @@ put_table (char * const * const argv) list = PyList_New (argc >> 1); for (i = 0; i < argc; i += 2) { - PyObject *item; item = PyTuple_New (2); PyTuple_SetItem (item, 0, PyString_FromString (argv[i])); PyTuple_SetItem (item, 1, PyString_FromString (argv[i+1])); @@ -4590,7 +4734,7 @@ py_guestfs_close (PyObject *self, PyObject *args) List.iter ( function - | String n -> pr " const char *%s;\n" n + | String n | FileIn n | FileOut n -> pr " const char *%s;\n" n | OptString n -> pr " const char *%s;\n" n | StringList n -> pr " PyObject *py_%s;\n" n; @@ -4605,7 +4749,7 @@ py_guestfs_close (PyObject *self, PyObject *args) pr " if (!PyArg_ParseTuple (args, (char *) \"O"; List.iter ( function - | String _ -> pr "s" + | String _ | FileIn _ | FileOut _ -> pr "s" | OptString _ -> pr "z" | StringList _ -> pr "O" | Bool _ -> pr "i" (* XXX Python has booleans? *) @@ -4615,7 +4759,7 @@ py_guestfs_close (PyObject *self, PyObject *args) pr " &py_g"; List.iter ( function - | String n -> pr ", &%s" n + | String n | FileIn n | FileOut n -> pr ", &%s" n | OptString n -> pr ", &%s" n | StringList n -> pr ", &py_%s" n | Bool n -> pr ", &%s" n @@ -4628,7 +4772,7 @@ py_guestfs_close (PyObject *self, PyObject *args) pr " g = get_handle (py_g);\n"; List.iter ( function - | String _ | OptString _ | Bool _ | Int _ -> () + | String _ | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ -> () | StringList n -> pr " %s = get_string_list (py_%s);\n" n n; pr " if (!%s) return NULL;\n" n @@ -4637,12 +4781,12 @@ py_guestfs_close (PyObject *self, PyObject *args) pr "\n"; pr " r = guestfs_%s " name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; List.iter ( function - | String _ | OptString _ | Bool _ | Int _ -> () + | String _ | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ -> () | StringList n -> pr " free (%s);\n" n ) (snd style); @@ -4826,11 +4970,11 @@ class GuestFS: let doc = String.concat "\n " doc in pr " def %s " name; - generate_call_args ~handle:"self" style; + generate_call_args ~handle:"self" (snd style); pr ":\n"; pr " u\"\"\"%s\"\"\"\n" doc; pr " return libguestfsmod.%s " name; - generate_call_args ~handle:"self._o" style; + generate_call_args ~handle:"self._o" (snd style); pr "\n"; pr "\n"; ) all_functions @@ -4932,7 +5076,7 @@ static VALUE ruby_guestfs_close (VALUE gv) List.iter ( function - | String n -> + | String n | FileIn n | FileOut n -> pr " const char *%s = StringValueCStr (%sv);\n" n n; pr " if (!%s)\n" n; pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n"; @@ -4972,12 +5116,12 @@ static VALUE ruby_guestfs_close (VALUE gv) pr "\n"; pr " r = guestfs_%s " name; - generate_call_args ~handle:"g" style; + generate_call_args ~handle:"g" (snd style); pr ";\n"; List.iter ( function - | String _ | OptString _ | Bool _ | Int _ -> () + | String _ | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ -> () | StringList n -> pr " free (%s);\n" n ) (snd style); diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c index f516979..6f01f9f 100644 --- a/src/guestfs-actions.c +++ b/src/guestfs-actions.c @@ -19,30 +19,30 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -struct mount_rv { - int cb_done; /* flag to indicate callback was called */ +struct mount_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void mount_cb (guestfs_h *g, void *data, XDR *xdr) { - struct mount_rv *rv = (struct mount_rv *) data; + struct mount_state *state = (struct mount_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_mount: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_mount: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_mount (guestfs_h *g, @@ -50,16 +50,23 @@ int guestfs_mount (guestfs_h *g, const char *mountpoint) { struct guestfs_mount_args args; - struct mount_rv rv; + struct mount_state state; int serial; if (g->state != READY) { - error (g, "guestfs_mount called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_mount"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_mount"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_mount", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; args.mountpoint = (char *) mountpoint; @@ -68,133 +75,147 @@ int guestfs_mount (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = mount_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_mount failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_MOUNT, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_MOUNT, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct sync_rv { - int cb_done; /* flag to indicate callback was called */ +struct sync_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void sync_cb (guestfs_h *g, void *data, XDR *xdr) { - struct sync_rv *rv = (struct sync_rv *) data; + struct sync_state *state = (struct sync_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_sync: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_sync: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_sync (guestfs_h *g) { - struct sync_rv rv; + struct sync_state state; int serial; if (g->state != READY) { - error (g, "guestfs_sync called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_sync"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_sync"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_sync", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_SYNC, NULL, NULL); if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = sync_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_sync failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_SYNC, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_SYNC, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct touch_rv { - int cb_done; /* flag to indicate callback was called */ +struct touch_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void touch_cb (guestfs_h *g, void *data, XDR *xdr) { - struct touch_rv *rv = (struct touch_rv *) data; + struct touch_state *state = (struct touch_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_touch: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_touch: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_touch (guestfs_h *g, const char *path) { struct guestfs_touch_args args; - struct touch_rv rv; + struct touch_state state; int serial; if (g->state != READY) { - error (g, "guestfs_touch called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_touch"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_touch"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_touch", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_TOUCH, @@ -202,30 +223,30 @@ int guestfs_touch (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = touch_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_touch failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_TOUCH, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_TOUCH, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct cat_rv { - int cb_done; /* flag to indicate callback was called */ +struct cat_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_cat_ret ret; @@ -233,42 +254,49 @@ struct cat_rv { static void cat_cb (guestfs_h *g, void *data, XDR *xdr) { - struct cat_rv *rv = (struct cat_rv *) data; + struct cat_state *state = (struct cat_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_cat: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_cat: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_cat_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_cat_ret (xdr, &state->ret)) { error (g, "guestfs_cat: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char *guestfs_cat (guestfs_h *g, const char *path) { struct guestfs_cat_args args; - struct cat_rv rv; + struct cat_state state; int serial; if (g->state != READY) { - error (g, "guestfs_cat called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_cat"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_cat"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_cat", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_CAT, @@ -276,30 +304,30 @@ char *guestfs_cat (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = cat_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_cat failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_CAT, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_CAT, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } - return rv.ret.content; /* caller will free */ + return state.ret.content; /* caller will free */ } -struct ll_rv { - int cb_done; /* flag to indicate callback was called */ +struct ll_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_ll_ret ret; @@ -307,42 +335,49 @@ struct ll_rv { static void ll_cb (guestfs_h *g, void *data, XDR *xdr) { - struct ll_rv *rv = (struct ll_rv *) data; + struct ll_state *state = (struct ll_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_ll: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_ll: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_ll_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_ll_ret (xdr, &state->ret)) { error (g, "guestfs_ll: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char *guestfs_ll (guestfs_h *g, const char *directory) { struct guestfs_ll_args args; - struct ll_rv rv; + struct ll_state state; int serial; if (g->state != READY) { - error (g, "guestfs_ll called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_ll"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_ll"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_ll", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.directory = (char *) directory; serial = dispatch (g, GUESTFS_PROC_LL, @@ -350,30 +385,30 @@ char *guestfs_ll (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = ll_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_ll failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LL, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LL, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } - return rv.ret.listing; /* caller will free */ + return state.ret.listing; /* caller will free */ } -struct ls_rv { - int cb_done; /* flag to indicate callback was called */ +struct ls_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_ls_ret ret; @@ -381,42 +416,49 @@ struct ls_rv { static void ls_cb (guestfs_h *g, void *data, XDR *xdr) { - struct ls_rv *rv = (struct ls_rv *) data; + struct ls_state *state = (struct ls_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_ls: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_ls: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_ls_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_ls_ret (xdr, &state->ret)) { error (g, "guestfs_ls: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_ls (guestfs_h *g, const char *directory) { struct guestfs_ls_args args; - struct ls_rv rv; + struct ls_state state; int serial; if (g->state != READY) { - error (g, "guestfs_ls called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_ls"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_ls"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_ls", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.directory = (char *) directory; serial = dispatch (g, GUESTFS_PROC_LS, @@ -424,34 +466,34 @@ char **guestfs_ls (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = ls_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_ls failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LS, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.listing.listing_val = safe_realloc (g, rv.ret.listing.listing_val, - sizeof (char *) * (rv.ret.listing.listing_len + 1)); - rv.ret.listing.listing_val[rv.ret.listing.listing_len] = NULL; - return rv.ret.listing.listing_val; + state.ret.listing.listing_val = safe_realloc (g, state.ret.listing.listing_val, + sizeof (char *) * (state.ret.listing.listing_len + 1)); + state.ret.listing.listing_val[state.ret.listing.listing_len] = NULL; + return state.ret.listing.listing_val; } -struct list_devices_rv { - int cb_done; /* flag to indicate callback was called */ +struct list_devices_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_list_devices_ret ret; @@ -459,73 +501,80 @@ struct list_devices_rv { static void list_devices_cb (guestfs_h *g, void *data, XDR *xdr) { - struct list_devices_rv *rv = (struct list_devices_rv *) data; + struct list_devices_state *state = (struct list_devices_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_list_devices: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_list_devices: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_list_devices_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_list_devices_ret (xdr, &state->ret)) { error (g, "guestfs_list_devices: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_list_devices (guestfs_h *g) { - struct list_devices_rv rv; + struct list_devices_state state; int serial; if (g->state != READY) { - error (g, "guestfs_list_devices called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_list_devices"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_list_devices"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_list_devices", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_LIST_DEVICES, NULL, NULL); if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = list_devices_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_list_devices failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LIST_DEVICES, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LIST_DEVICES, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.devices.devices_val = safe_realloc (g, rv.ret.devices.devices_val, - sizeof (char *) * (rv.ret.devices.devices_len + 1)); - rv.ret.devices.devices_val[rv.ret.devices.devices_len] = NULL; - return rv.ret.devices.devices_val; + state.ret.devices.devices_val = safe_realloc (g, state.ret.devices.devices_val, + sizeof (char *) * (state.ret.devices.devices_len + 1)); + state.ret.devices.devices_val[state.ret.devices.devices_len] = NULL; + return state.ret.devices.devices_val; } -struct list_partitions_rv { - int cb_done; /* flag to indicate callback was called */ +struct list_partitions_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_list_partitions_ret ret; @@ -533,73 +582,80 @@ struct list_partitions_rv { static void list_partitions_cb (guestfs_h *g, void *data, XDR *xdr) { - struct list_partitions_rv *rv = (struct list_partitions_rv *) data; + struct list_partitions_state *state = (struct list_partitions_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_list_partitions: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_list_partitions: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_list_partitions_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_list_partitions_ret (xdr, &state->ret)) { error (g, "guestfs_list_partitions: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_list_partitions (guestfs_h *g) { - struct list_partitions_rv rv; + struct list_partitions_state state; int serial; if (g->state != READY) { - error (g, "guestfs_list_partitions called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_list_partitions"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_list_partitions"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_list_partitions", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_LIST_PARTITIONS, NULL, NULL); if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = list_partitions_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_list_partitions failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LIST_PARTITIONS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LIST_PARTITIONS, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.partitions.partitions_val = safe_realloc (g, rv.ret.partitions.partitions_val, - sizeof (char *) * (rv.ret.partitions.partitions_len + 1)); - rv.ret.partitions.partitions_val[rv.ret.partitions.partitions_len] = NULL; - return rv.ret.partitions.partitions_val; + state.ret.partitions.partitions_val = safe_realloc (g, state.ret.partitions.partitions_val, + sizeof (char *) * (state.ret.partitions.partitions_len + 1)); + state.ret.partitions.partitions_val[state.ret.partitions.partitions_len] = NULL; + return state.ret.partitions.partitions_val; } -struct pvs_rv { - int cb_done; /* flag to indicate callback was called */ +struct pvs_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_pvs_ret ret; @@ -607,73 +663,80 @@ struct pvs_rv { static void pvs_cb (guestfs_h *g, void *data, XDR *xdr) { - struct pvs_rv *rv = (struct pvs_rv *) data; + struct pvs_state *state = (struct pvs_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_pvs: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_pvs: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_pvs_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_pvs_ret (xdr, &state->ret)) { error (g, "guestfs_pvs: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_pvs (guestfs_h *g) { - struct pvs_rv rv; + struct pvs_state state; int serial; if (g->state != READY) { - error (g, "guestfs_pvs called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_pvs"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_pvs"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_pvs", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_PVS, NULL, NULL); if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = pvs_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_pvs failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_PVS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_PVS, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.physvols.physvols_val = safe_realloc (g, rv.ret.physvols.physvols_val, - sizeof (char *) * (rv.ret.physvols.physvols_len + 1)); - rv.ret.physvols.physvols_val[rv.ret.physvols.physvols_len] = NULL; - return rv.ret.physvols.physvols_val; + state.ret.physvols.physvols_val = safe_realloc (g, state.ret.physvols.physvols_val, + sizeof (char *) * (state.ret.physvols.physvols_len + 1)); + state.ret.physvols.physvols_val[state.ret.physvols.physvols_len] = NULL; + return state.ret.physvols.physvols_val; } -struct vgs_rv { - int cb_done; /* flag to indicate callback was called */ +struct vgs_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_vgs_ret ret; @@ -681,73 +744,80 @@ struct vgs_rv { static void vgs_cb (guestfs_h *g, void *data, XDR *xdr) { - struct vgs_rv *rv = (struct vgs_rv *) data; + struct vgs_state *state = (struct vgs_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_vgs: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_vgs: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_vgs_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_vgs_ret (xdr, &state->ret)) { error (g, "guestfs_vgs: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_vgs (guestfs_h *g) { - struct vgs_rv rv; + struct vgs_state state; int serial; if (g->state != READY) { - error (g, "guestfs_vgs called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_vgs"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_vgs"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_vgs", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_VGS, NULL, NULL); if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = vgs_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_vgs failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_VGS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_VGS, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.volgroups.volgroups_val = safe_realloc (g, rv.ret.volgroups.volgroups_val, - sizeof (char *) * (rv.ret.volgroups.volgroups_len + 1)); - rv.ret.volgroups.volgroups_val[rv.ret.volgroups.volgroups_len] = NULL; - return rv.ret.volgroups.volgroups_val; + state.ret.volgroups.volgroups_val = safe_realloc (g, state.ret.volgroups.volgroups_val, + sizeof (char *) * (state.ret.volgroups.volgroups_len + 1)); + state.ret.volgroups.volgroups_val[state.ret.volgroups.volgroups_len] = NULL; + return state.ret.volgroups.volgroups_val; } -struct lvs_rv { - int cb_done; /* flag to indicate callback was called */ +struct lvs_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_lvs_ret ret; @@ -755,73 +825,80 @@ struct lvs_rv { static void lvs_cb (guestfs_h *g, void *data, XDR *xdr) { - struct lvs_rv *rv = (struct lvs_rv *) data; + struct lvs_state *state = (struct lvs_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_lvs: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_lvs: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_lvs_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_lvs_ret (xdr, &state->ret)) { error (g, "guestfs_lvs: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_lvs (guestfs_h *g) { - struct lvs_rv rv; + struct lvs_state state; int serial; if (g->state != READY) { - error (g, "guestfs_lvs called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_lvs"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_lvs"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_lvs", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_LVS, NULL, NULL); if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = lvs_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_lvs failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LVS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LVS, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.logvols.logvols_val = safe_realloc (g, rv.ret.logvols.logvols_val, - sizeof (char *) * (rv.ret.logvols.logvols_len + 1)); - rv.ret.logvols.logvols_val[rv.ret.logvols.logvols_len] = NULL; - return rv.ret.logvols.logvols_val; + state.ret.logvols.logvols_val = safe_realloc (g, state.ret.logvols.logvols_val, + sizeof (char *) * (state.ret.logvols.logvols_len + 1)); + state.ret.logvols.logvols_val[state.ret.logvols.logvols_len] = NULL; + return state.ret.logvols.logvols_val; } -struct pvs_full_rv { - int cb_done; /* flag to indicate callback was called */ +struct pvs_full_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_pvs_full_ret ret; @@ -829,70 +906,77 @@ struct pvs_full_rv { static void pvs_full_cb (guestfs_h *g, void *data, XDR *xdr) { - struct pvs_full_rv *rv = (struct pvs_full_rv *) data; + struct pvs_full_state *state = (struct pvs_full_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_pvs_full: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_pvs_full: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_pvs_full_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_pvs_full_ret (xdr, &state->ret)) { error (g, "guestfs_pvs_full: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } struct guestfs_lvm_pv_list *guestfs_pvs_full (guestfs_h *g) { - struct pvs_full_rv rv; + struct pvs_full_state state; int serial; if (g->state != READY) { - error (g, "guestfs_pvs_full called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_pvs_full"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_pvs_full"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_pvs_full", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_PVS_FULL, NULL, NULL); if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = pvs_full_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_pvs_full failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_PVS_FULL, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_PVS_FULL, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this */ - return safe_memdup (g, &rv.ret.physvols, sizeof (rv.ret.physvols)); + return safe_memdup (g, &state.ret.physvols, sizeof (state.ret.physvols)); } -struct vgs_full_rv { - int cb_done; /* flag to indicate callback was called */ +struct vgs_full_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_vgs_full_ret ret; @@ -900,70 +984,77 @@ struct vgs_full_rv { static void vgs_full_cb (guestfs_h *g, void *data, XDR *xdr) { - struct vgs_full_rv *rv = (struct vgs_full_rv *) data; + struct vgs_full_state *state = (struct vgs_full_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_vgs_full: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_vgs_full: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_vgs_full_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_vgs_full_ret (xdr, &state->ret)) { error (g, "guestfs_vgs_full: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } struct guestfs_lvm_vg_list *guestfs_vgs_full (guestfs_h *g) { - struct vgs_full_rv rv; + struct vgs_full_state state; int serial; if (g->state != READY) { - error (g, "guestfs_vgs_full called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_vgs_full"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_vgs_full"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_vgs_full", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_VGS_FULL, NULL, NULL); if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = vgs_full_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_vgs_full failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_VGS_FULL, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_VGS_FULL, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this */ - return safe_memdup (g, &rv.ret.volgroups, sizeof (rv.ret.volgroups)); + return safe_memdup (g, &state.ret.volgroups, sizeof (state.ret.volgroups)); } -struct lvs_full_rv { - int cb_done; /* flag to indicate callback was called */ +struct lvs_full_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_lvs_full_ret ret; @@ -971,70 +1062,77 @@ struct lvs_full_rv { static void lvs_full_cb (guestfs_h *g, void *data, XDR *xdr) { - struct lvs_full_rv *rv = (struct lvs_full_rv *) data; + struct lvs_full_state *state = (struct lvs_full_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_lvs_full: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_lvs_full: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_lvs_full_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_lvs_full_ret (xdr, &state->ret)) { error (g, "guestfs_lvs_full: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } struct guestfs_lvm_lv_list *guestfs_lvs_full (guestfs_h *g) { - struct lvs_full_rv rv; + struct lvs_full_state state; int serial; if (g->state != READY) { - error (g, "guestfs_lvs_full called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_lvs_full"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_lvs_full"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_lvs_full", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_LVS_FULL, NULL, NULL); if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = lvs_full_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_lvs_full failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LVS_FULL, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LVS_FULL, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this */ - return safe_memdup (g, &rv.ret.logvols, sizeof (rv.ret.logvols)); + return safe_memdup (g, &state.ret.logvols, sizeof (state.ret.logvols)); } -struct read_lines_rv { - int cb_done; /* flag to indicate callback was called */ +struct read_lines_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_read_lines_ret ret; @@ -1042,42 +1140,49 @@ struct read_lines_rv { static void read_lines_cb (guestfs_h *g, void *data, XDR *xdr) { - struct read_lines_rv *rv = (struct read_lines_rv *) data; + struct read_lines_state *state = (struct read_lines_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_read_lines: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_read_lines: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_read_lines_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_read_lines_ret (xdr, &state->ret)) { error (g, "guestfs_read_lines: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_read_lines (guestfs_h *g, const char *path) { struct guestfs_read_lines_args args; - struct read_lines_rv rv; + struct read_lines_state state; int serial; if (g->state != READY) { - error (g, "guestfs_read_lines called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_read_lines"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_read_lines"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_read_lines", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_READ_LINES, @@ -1085,56 +1190,56 @@ char **guestfs_read_lines (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = read_lines_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_read_lines failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_READ_LINES, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_READ_LINES, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.lines.lines_val = safe_realloc (g, rv.ret.lines.lines_val, - sizeof (char *) * (rv.ret.lines.lines_len + 1)); - rv.ret.lines.lines_val[rv.ret.lines.lines_len] = NULL; - return rv.ret.lines.lines_val; + state.ret.lines.lines_val = safe_realloc (g, state.ret.lines.lines_val, + sizeof (char *) * (state.ret.lines.lines_len + 1)); + state.ret.lines.lines_val[state.ret.lines.lines_len] = NULL; + return state.ret.lines.lines_val; } -struct aug_init_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_init_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void aug_init_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_init_rv *rv = (struct aug_init_rv *) data; + struct aug_init_state *state = (struct aug_init_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_init: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_init: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_aug_init (guestfs_h *g, @@ -1142,16 +1247,23 @@ int guestfs_aug_init (guestfs_h *g, int flags) { struct guestfs_aug_init_args args; - struct aug_init_rv rv; + struct aug_init_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_init called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_init"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_init"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_init", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.root = (char *) root; args.flags = flags; @@ -1160,95 +1272,102 @@ int guestfs_aug_init (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_init_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_init failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_INIT, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_INIT, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct aug_close_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_close_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void aug_close_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_close_rv *rv = (struct aug_close_rv *) data; + struct aug_close_state *state = (struct aug_close_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_close: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_close: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_aug_close (guestfs_h *g) { - struct aug_close_rv rv; + struct aug_close_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_close called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_close"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_close"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_close", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_AUG_CLOSE, NULL, NULL); if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_close_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_close failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_CLOSE, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_CLOSE, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct aug_defvar_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_defvar_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_aug_defvar_ret ret; @@ -1256,26 +1375,26 @@ struct aug_defvar_rv { static void aug_defvar_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_defvar_rv *rv = (struct aug_defvar_rv *) data; + struct aug_defvar_state *state = (struct aug_defvar_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_defvar: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_defvar: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_aug_defvar_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_aug_defvar_ret (xdr, &state->ret)) { error (g, "guestfs_aug_defvar: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_aug_defvar (guestfs_h *g, @@ -1283,16 +1402,23 @@ int guestfs_aug_defvar (guestfs_h *g, const char *expr) { struct guestfs_aug_defvar_args args; - struct aug_defvar_rv rv; + struct aug_defvar_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_defvar called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_defvar"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_defvar"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_defvar", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.name = (char *) name; args.expr = expr ? (char **) &expr : NULL; @@ -1301,30 +1427,30 @@ int guestfs_aug_defvar (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_defvar_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_defvar failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_DEFVAR, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_DEFVAR, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } - return rv.ret.nrnodes; + return state.ret.nrnodes; } -struct aug_defnode_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_defnode_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_aug_defnode_ret ret; @@ -1332,26 +1458,26 @@ struct aug_defnode_rv { static void aug_defnode_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_defnode_rv *rv = (struct aug_defnode_rv *) data; + struct aug_defnode_state *state = (struct aug_defnode_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_defnode: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_defnode: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_aug_defnode_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_aug_defnode_ret (xdr, &state->ret)) { error (g, "guestfs_aug_defnode: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } struct guestfs_int_bool *guestfs_aug_defnode (guestfs_h *g, @@ -1360,16 +1486,23 @@ struct guestfs_int_bool *guestfs_aug_defnode (guestfs_h *g, const char *val) { struct guestfs_aug_defnode_args args; - struct aug_defnode_rv rv; + struct aug_defnode_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_defnode called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_defnode"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_defnode"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_defnode", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.name = (char *) name; args.expr = (char *) expr; @@ -1379,31 +1512,31 @@ struct guestfs_int_bool *guestfs_aug_defnode (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_defnode_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_defnode failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_DEFNODE, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_DEFNODE, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller with free this */ - return safe_memdup (g, &rv.ret, sizeof (rv.ret)); + return safe_memdup (g, &state.ret, sizeof (state.ret)); } -struct aug_get_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_get_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_aug_get_ret ret; @@ -1411,42 +1544,49 @@ struct aug_get_rv { static void aug_get_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_get_rv *rv = (struct aug_get_rv *) data; + struct aug_get_state *state = (struct aug_get_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_get: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_get: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_aug_get_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_aug_get_ret (xdr, &state->ret)) { error (g, "guestfs_aug_get: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char *guestfs_aug_get (guestfs_h *g, const char *path) { struct guestfs_aug_get_args args; - struct aug_get_rv rv; + struct aug_get_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_get called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_get"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_get"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_get", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_AUG_GET, @@ -1454,52 +1594,52 @@ char *guestfs_aug_get (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_get_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_get failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_GET, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_GET, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } - return rv.ret.val; /* caller will free */ + return state.ret.val; /* caller will free */ } -struct aug_set_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_set_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void aug_set_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_set_rv *rv = (struct aug_set_rv *) data; + struct aug_set_state *state = (struct aug_set_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_set: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_set: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_aug_set (guestfs_h *g, @@ -1507,16 +1647,23 @@ int guestfs_aug_set (guestfs_h *g, const char *val) { struct guestfs_aug_set_args args; - struct aug_set_rv rv; + struct aug_set_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_set called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_set"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_set"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_set", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; args.val = (char *) val; @@ -1525,52 +1672,52 @@ int guestfs_aug_set (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_set_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_set failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_SET, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_SET, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct aug_insert_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_insert_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void aug_insert_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_insert_rv *rv = (struct aug_insert_rv *) data; + struct aug_insert_state *state = (struct aug_insert_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_insert: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_insert: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_aug_insert (guestfs_h *g, @@ -1579,16 +1726,23 @@ int guestfs_aug_insert (guestfs_h *g, int before) { struct guestfs_aug_insert_args args; - struct aug_insert_rv rv; + struct aug_insert_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_insert called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_insert"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_insert"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_insert", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; args.label = (char *) label; @@ -1598,30 +1752,30 @@ int guestfs_aug_insert (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_insert_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_insert failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_INSERT, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_INSERT, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct aug_rm_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_rm_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_aug_rm_ret ret; @@ -1629,42 +1783,49 @@ struct aug_rm_rv { static void aug_rm_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_rm_rv *rv = (struct aug_rm_rv *) data; + struct aug_rm_state *state = (struct aug_rm_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_rm: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_rm: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_aug_rm_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_aug_rm_ret (xdr, &state->ret)) { error (g, "guestfs_aug_rm: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_aug_rm (guestfs_h *g, const char *path) { struct guestfs_aug_rm_args args; - struct aug_rm_rv rv; + struct aug_rm_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_rm called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_rm"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_rm"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_rm", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_AUG_RM, @@ -1672,52 +1833,52 @@ int guestfs_aug_rm (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_rm_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_rm failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_RM, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_RM, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } - return rv.ret.nrnodes; + return state.ret.nrnodes; } -struct aug_mv_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_mv_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void aug_mv_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_mv_rv *rv = (struct aug_mv_rv *) data; + struct aug_mv_state *state = (struct aug_mv_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_mv: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_mv: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_aug_mv (guestfs_h *g, @@ -1725,16 +1886,23 @@ int guestfs_aug_mv (guestfs_h *g, const char *dest) { struct guestfs_aug_mv_args args; - struct aug_mv_rv rv; + struct aug_mv_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_mv called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_mv"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_mv"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_mv", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.src = (char *) src; args.dest = (char *) dest; @@ -1743,30 +1911,30 @@ int guestfs_aug_mv (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_mv_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_mv failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_MV, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_MV, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct aug_match_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_match_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_aug_match_ret ret; @@ -1774,42 +1942,49 @@ struct aug_match_rv { static void aug_match_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_match_rv *rv = (struct aug_match_rv *) data; + struct aug_match_state *state = (struct aug_match_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_match: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_match: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_aug_match_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_aug_match_ret (xdr, &state->ret)) { error (g, "guestfs_aug_match: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_aug_match (guestfs_h *g, const char *path) { struct guestfs_aug_match_args args; - struct aug_match_rv rv; + struct aug_match_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_match called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_match"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_match"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_match", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_AUG_MATCH, @@ -1817,164 +1992,178 @@ char **guestfs_aug_match (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_match_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_match failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_MATCH, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_MATCH, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.matches.matches_val = safe_realloc (g, rv.ret.matches.matches_val, - sizeof (char *) * (rv.ret.matches.matches_len + 1)); - rv.ret.matches.matches_val[rv.ret.matches.matches_len] = NULL; - return rv.ret.matches.matches_val; + state.ret.matches.matches_val = safe_realloc (g, state.ret.matches.matches_val, + sizeof (char *) * (state.ret.matches.matches_len + 1)); + state.ret.matches.matches_val[state.ret.matches.matches_len] = NULL; + return state.ret.matches.matches_val; } -struct aug_save_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_save_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void aug_save_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_save_rv *rv = (struct aug_save_rv *) data; + struct aug_save_state *state = (struct aug_save_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_save: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_save: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_aug_save (guestfs_h *g) { - struct aug_save_rv rv; + struct aug_save_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_save called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_save"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_save"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_save", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_AUG_SAVE, NULL, NULL); if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_save_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_save failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_SAVE, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_SAVE, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct aug_load_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_load_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void aug_load_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_load_rv *rv = (struct aug_load_rv *) data; + struct aug_load_state *state = (struct aug_load_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_load: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_load: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_aug_load (guestfs_h *g) { - struct aug_load_rv rv; + struct aug_load_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_load called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_load"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_load"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_load", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_AUG_LOAD, NULL, NULL); if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_load_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_load failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_LOAD, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_LOAD, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct aug_ls_rv { - int cb_done; /* flag to indicate callback was called */ +struct aug_ls_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_aug_ls_ret ret; @@ -1982,42 +2171,49 @@ struct aug_ls_rv { static void aug_ls_cb (guestfs_h *g, void *data, XDR *xdr) { - struct aug_ls_rv *rv = (struct aug_ls_rv *) data; + struct aug_ls_state *state = (struct aug_ls_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_aug_ls: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_aug_ls: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_aug_ls_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_aug_ls_ret (xdr, &state->ret)) { error (g, "guestfs_aug_ls: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_aug_ls (guestfs_h *g, const char *path) { struct guestfs_aug_ls_args args; - struct aug_ls_rv rv; + struct aug_ls_state state; int serial; if (g->state != READY) { - error (g, "guestfs_aug_ls called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_aug_ls"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_aug_ls"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_aug_ls", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_AUG_LS, @@ -2025,72 +2221,79 @@ char **guestfs_aug_ls (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = aug_ls_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_aug_ls failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_AUG_LS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_AUG_LS, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.matches.matches_val = safe_realloc (g, rv.ret.matches.matches_val, - sizeof (char *) * (rv.ret.matches.matches_len + 1)); - rv.ret.matches.matches_val[rv.ret.matches.matches_len] = NULL; - return rv.ret.matches.matches_val; + state.ret.matches.matches_val = safe_realloc (g, state.ret.matches.matches_val, + sizeof (char *) * (state.ret.matches.matches_len + 1)); + state.ret.matches.matches_val[state.ret.matches.matches_len] = NULL; + return state.ret.matches.matches_val; } -struct rm_rv { - int cb_done; /* flag to indicate callback was called */ +struct rm_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void rm_cb (guestfs_h *g, void *data, XDR *xdr) { - struct rm_rv *rv = (struct rm_rv *) data; + struct rm_state *state = (struct rm_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_rm: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_rm: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_rm (guestfs_h *g, const char *path) { struct guestfs_rm_args args; - struct rm_rv rv; + struct rm_state state; int serial; if (g->state != READY) { - error (g, "guestfs_rm called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_rm"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_rm"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_rm", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_RM, @@ -2098,68 +2301,75 @@ int guestfs_rm (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = rm_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_rm failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_RM, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_RM, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct rmdir_rv { - int cb_done; /* flag to indicate callback was called */ +struct rmdir_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void rmdir_cb (guestfs_h *g, void *data, XDR *xdr) { - struct rmdir_rv *rv = (struct rmdir_rv *) data; + struct rmdir_state *state = (struct rmdir_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_rmdir: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_rmdir: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_rmdir (guestfs_h *g, const char *path) { struct guestfs_rmdir_args args; - struct rmdir_rv rv; + struct rmdir_state state; int serial; if (g->state != READY) { - error (g, "guestfs_rmdir called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_rmdir"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_rmdir"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_rmdir", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_RMDIR, @@ -2167,68 +2377,75 @@ int guestfs_rmdir (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = rmdir_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_rmdir failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_RMDIR, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_RMDIR, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct rm_rf_rv { - int cb_done; /* flag to indicate callback was called */ +struct rm_rf_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void rm_rf_cb (guestfs_h *g, void *data, XDR *xdr) { - struct rm_rf_rv *rv = (struct rm_rf_rv *) data; + struct rm_rf_state *state = (struct rm_rf_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_rm_rf: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_rm_rf: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_rm_rf (guestfs_h *g, const char *path) { struct guestfs_rm_rf_args args; - struct rm_rf_rv rv; + struct rm_rf_state state; int serial; if (g->state != READY) { - error (g, "guestfs_rm_rf called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_rm_rf"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_rm_rf"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_rm_rf", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_RM_RF, @@ -2236,68 +2453,75 @@ int guestfs_rm_rf (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = rm_rf_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_rm_rf failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_RM_RF, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_RM_RF, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct mkdir_rv { - int cb_done; /* flag to indicate callback was called */ +struct mkdir_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void mkdir_cb (guestfs_h *g, void *data, XDR *xdr) { - struct mkdir_rv *rv = (struct mkdir_rv *) data; + struct mkdir_state *state = (struct mkdir_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_mkdir: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_mkdir: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_mkdir (guestfs_h *g, const char *path) { struct guestfs_mkdir_args args; - struct mkdir_rv rv; + struct mkdir_state state; int serial; if (g->state != READY) { - error (g, "guestfs_mkdir called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_mkdir"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_mkdir"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_mkdir", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_MKDIR, @@ -2305,68 +2529,75 @@ int guestfs_mkdir (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = mkdir_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_mkdir failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_MKDIR, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_MKDIR, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct mkdir_p_rv { - int cb_done; /* flag to indicate callback was called */ +struct mkdir_p_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void mkdir_p_cb (guestfs_h *g, void *data, XDR *xdr) { - struct mkdir_p_rv *rv = (struct mkdir_p_rv *) data; + struct mkdir_p_state *state = (struct mkdir_p_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_mkdir_p: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_mkdir_p: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_mkdir_p (guestfs_h *g, const char *path) { struct guestfs_mkdir_p_args args; - struct mkdir_p_rv rv; + struct mkdir_p_state state; int serial; if (g->state != READY) { - error (g, "guestfs_mkdir_p called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_mkdir_p"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_mkdir_p"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_mkdir_p", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_MKDIR_P, @@ -2374,52 +2605,52 @@ int guestfs_mkdir_p (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = mkdir_p_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_mkdir_p failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_MKDIR_P, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_MKDIR_P, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct chmod_rv { - int cb_done; /* flag to indicate callback was called */ +struct chmod_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void chmod_cb (guestfs_h *g, void *data, XDR *xdr) { - struct chmod_rv *rv = (struct chmod_rv *) data; + struct chmod_state *state = (struct chmod_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_chmod: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_chmod: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_chmod (guestfs_h *g, @@ -2427,16 +2658,23 @@ int guestfs_chmod (guestfs_h *g, const char *path) { struct guestfs_chmod_args args; - struct chmod_rv rv; + struct chmod_state state; int serial; if (g->state != READY) { - error (g, "guestfs_chmod called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_chmod"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_chmod"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_chmod", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.mode = mode; args.path = (char *) path; @@ -2445,52 +2683,52 @@ int guestfs_chmod (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = chmod_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_chmod failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_CHMOD, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_CHMOD, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct chown_rv { - int cb_done; /* flag to indicate callback was called */ +struct chown_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void chown_cb (guestfs_h *g, void *data, XDR *xdr) { - struct chown_rv *rv = (struct chown_rv *) data; + struct chown_state *state = (struct chown_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_chown: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_chown: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_chown (guestfs_h *g, @@ -2499,16 +2737,23 @@ int guestfs_chown (guestfs_h *g, const char *path) { struct guestfs_chown_args args; - struct chown_rv rv; + struct chown_state state; int serial; if (g->state != READY) { - error (g, "guestfs_chown called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_chown"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_chown"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_chown", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.owner = owner; args.group = group; @@ -2518,30 +2763,30 @@ int guestfs_chown (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = chown_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_chown failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_CHOWN, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_CHOWN, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct exists_rv { - int cb_done; /* flag to indicate callback was called */ +struct exists_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_exists_ret ret; @@ -2549,42 +2794,49 @@ struct exists_rv { static void exists_cb (guestfs_h *g, void *data, XDR *xdr) { - struct exists_rv *rv = (struct exists_rv *) data; + struct exists_state *state = (struct exists_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_exists: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_exists: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_exists_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_exists_ret (xdr, &state->ret)) { error (g, "guestfs_exists: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_exists (guestfs_h *g, const char *path) { struct guestfs_exists_args args; - struct exists_rv rv; + struct exists_state state; int serial; if (g->state != READY) { - error (g, "guestfs_exists called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_exists"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_exists"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_exists", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_EXISTS, @@ -2592,30 +2844,30 @@ int guestfs_exists (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = exists_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_exists failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_EXISTS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_EXISTS, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } - return rv.ret.existsflag; + return state.ret.existsflag; } -struct is_file_rv { - int cb_done; /* flag to indicate callback was called */ +struct is_file_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_is_file_ret ret; @@ -2623,42 +2875,49 @@ struct is_file_rv { static void is_file_cb (guestfs_h *g, void *data, XDR *xdr) { - struct is_file_rv *rv = (struct is_file_rv *) data; + struct is_file_state *state = (struct is_file_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_is_file: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_is_file: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_is_file_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_is_file_ret (xdr, &state->ret)) { error (g, "guestfs_is_file: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_is_file (guestfs_h *g, const char *path) { struct guestfs_is_file_args args; - struct is_file_rv rv; + struct is_file_state state; int serial; if (g->state != READY) { - error (g, "guestfs_is_file called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_is_file"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_is_file"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_is_file", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_IS_FILE, @@ -2666,30 +2925,30 @@ int guestfs_is_file (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = is_file_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_is_file failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_IS_FILE, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_IS_FILE, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } - return rv.ret.fileflag; + return state.ret.fileflag; } -struct is_dir_rv { - int cb_done; /* flag to indicate callback was called */ +struct is_dir_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_is_dir_ret ret; @@ -2697,42 +2956,49 @@ struct is_dir_rv { static void is_dir_cb (guestfs_h *g, void *data, XDR *xdr) { - struct is_dir_rv *rv = (struct is_dir_rv *) data; + struct is_dir_state *state = (struct is_dir_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_is_dir: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_is_dir: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_is_dir_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_is_dir_ret (xdr, &state->ret)) { error (g, "guestfs_is_dir: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_is_dir (guestfs_h *g, const char *path) { struct guestfs_is_dir_args args; - struct is_dir_rv rv; + struct is_dir_state state; int serial; if (g->state != READY) { - error (g, "guestfs_is_dir called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_is_dir"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_is_dir"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_is_dir", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_IS_DIR, @@ -2740,68 +3006,75 @@ int guestfs_is_dir (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = is_dir_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_is_dir failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_IS_DIR, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_IS_DIR, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } - return rv.ret.dirflag; + return state.ret.dirflag; } -struct pvcreate_rv { - int cb_done; /* flag to indicate callback was called */ +struct pvcreate_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void pvcreate_cb (guestfs_h *g, void *data, XDR *xdr) { - struct pvcreate_rv *rv = (struct pvcreate_rv *) data; + struct pvcreate_state *state = (struct pvcreate_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_pvcreate: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_pvcreate: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_pvcreate (guestfs_h *g, const char *device) { struct guestfs_pvcreate_args args; - struct pvcreate_rv rv; + struct pvcreate_state state; int serial; if (g->state != READY) { - error (g, "guestfs_pvcreate called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_pvcreate"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_pvcreate"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_pvcreate", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_PVCREATE, @@ -2809,52 +3082,52 @@ int guestfs_pvcreate (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = pvcreate_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_pvcreate failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_PVCREATE, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_PVCREATE, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct vgcreate_rv { - int cb_done; /* flag to indicate callback was called */ +struct vgcreate_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void vgcreate_cb (guestfs_h *g, void *data, XDR *xdr) { - struct vgcreate_rv *rv = (struct vgcreate_rv *) data; + struct vgcreate_state *state = (struct vgcreate_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_vgcreate: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_vgcreate: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_vgcreate (guestfs_h *g, @@ -2862,16 +3135,23 @@ int guestfs_vgcreate (guestfs_h *g, char * const* const physvols) { struct guestfs_vgcreate_args args; - struct vgcreate_rv rv; + struct vgcreate_state state; int serial; if (g->state != READY) { - error (g, "guestfs_vgcreate called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_vgcreate"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_vgcreate"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_vgcreate", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.volgroup = (char *) volgroup; args.physvols.physvols_val = (char **) physvols; @@ -2881,52 +3161,52 @@ int guestfs_vgcreate (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = vgcreate_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_vgcreate failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_VGCREATE, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_VGCREATE, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct lvcreate_rv { - int cb_done; /* flag to indicate callback was called */ +struct lvcreate_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void lvcreate_cb (guestfs_h *g, void *data, XDR *xdr) { - struct lvcreate_rv *rv = (struct lvcreate_rv *) data; + struct lvcreate_state *state = (struct lvcreate_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_lvcreate: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_lvcreate: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_lvcreate (guestfs_h *g, @@ -2935,16 +3215,23 @@ int guestfs_lvcreate (guestfs_h *g, int mbytes) { struct guestfs_lvcreate_args args; - struct lvcreate_rv rv; + struct lvcreate_state state; int serial; if (g->state != READY) { - error (g, "guestfs_lvcreate called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_lvcreate"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_lvcreate"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_lvcreate", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.logvol = (char *) logvol; args.volgroup = (char *) volgroup; @@ -2954,52 +3241,52 @@ int guestfs_lvcreate (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = lvcreate_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_lvcreate failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LVCREATE, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LVCREATE, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct mkfs_rv { - int cb_done; /* flag to indicate callback was called */ +struct mkfs_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void mkfs_cb (guestfs_h *g, void *data, XDR *xdr) { - struct mkfs_rv *rv = (struct mkfs_rv *) data; + struct mkfs_state *state = (struct mkfs_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_mkfs: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_mkfs: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_mkfs (guestfs_h *g, @@ -3007,16 +3294,23 @@ int guestfs_mkfs (guestfs_h *g, const char *device) { struct guestfs_mkfs_args args; - struct mkfs_rv rv; + struct mkfs_state state; int serial; if (g->state != READY) { - error (g, "guestfs_mkfs called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_mkfs"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_mkfs"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_mkfs", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.fstype = (char *) fstype; args.device = (char *) device; @@ -3025,52 +3319,52 @@ int guestfs_mkfs (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = mkfs_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_mkfs failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_MKFS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_MKFS, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct sfdisk_rv { - int cb_done; /* flag to indicate callback was called */ +struct sfdisk_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void sfdisk_cb (guestfs_h *g, void *data, XDR *xdr) { - struct sfdisk_rv *rv = (struct sfdisk_rv *) data; + struct sfdisk_state *state = (struct sfdisk_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_sfdisk: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_sfdisk: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_sfdisk (guestfs_h *g, @@ -3081,16 +3375,23 @@ int guestfs_sfdisk (guestfs_h *g, char * const* const lines) { struct guestfs_sfdisk_args args; - struct sfdisk_rv rv; + struct sfdisk_state state; int serial; if (g->state != READY) { - error (g, "guestfs_sfdisk called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_sfdisk"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_sfdisk"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_sfdisk", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; args.cyls = cyls; @@ -3103,52 +3404,52 @@ int guestfs_sfdisk (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = sfdisk_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_sfdisk failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_SFDISK, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_SFDISK, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct write_file_rv { - int cb_done; /* flag to indicate callback was called */ +struct write_file_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void write_file_cb (guestfs_h *g, void *data, XDR *xdr) { - struct write_file_rv *rv = (struct write_file_rv *) data; + struct write_file_state *state = (struct write_file_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_write_file: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_write_file: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_write_file (guestfs_h *g, @@ -3157,16 +3458,23 @@ int guestfs_write_file (guestfs_h *g, int size) { struct guestfs_write_file_args args; - struct write_file_rv rv; + struct write_file_state state; int serial; if (g->state != READY) { - error (g, "guestfs_write_file called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_write_file"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_write_file"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_write_file", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; args.content = (char *) content; @@ -3176,68 +3484,75 @@ int guestfs_write_file (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = write_file_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_write_file failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_WRITE_FILE, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_WRITE_FILE, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct umount_rv { - int cb_done; /* flag to indicate callback was called */ +struct umount_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void umount_cb (guestfs_h *g, void *data, XDR *xdr) { - struct umount_rv *rv = (struct umount_rv *) data; + struct umount_state *state = (struct umount_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_umount: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_umount: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_umount (guestfs_h *g, const char *pathordevice) { struct guestfs_umount_args args; - struct umount_rv rv; + struct umount_state state; int serial; if (g->state != READY) { - error (g, "guestfs_umount called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_umount"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_umount"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_umount", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.pathordevice = (char *) pathordevice; serial = dispatch (g, GUESTFS_PROC_UMOUNT, @@ -3245,30 +3560,30 @@ int guestfs_umount (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = umount_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_umount failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_UMOUNT, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_UMOUNT, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct mounts_rv { - int cb_done; /* flag to indicate callback was called */ +struct mounts_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_mounts_ret ret; @@ -3276,203 +3591,224 @@ struct mounts_rv { static void mounts_cb (guestfs_h *g, void *data, XDR *xdr) { - struct mounts_rv *rv = (struct mounts_rv *) data; + struct mounts_state *state = (struct mounts_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_mounts: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_mounts: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_mounts_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_mounts_ret (xdr, &state->ret)) { error (g, "guestfs_mounts: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_mounts (guestfs_h *g) { - struct mounts_rv rv; + struct mounts_state state; int serial; if (g->state != READY) { - error (g, "guestfs_mounts called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_mounts"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_mounts"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_mounts", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_MOUNTS, NULL, NULL); if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = mounts_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_mounts failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_MOUNTS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_MOUNTS, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.devices.devices_val = safe_realloc (g, rv.ret.devices.devices_val, - sizeof (char *) * (rv.ret.devices.devices_len + 1)); - rv.ret.devices.devices_val[rv.ret.devices.devices_len] = NULL; - return rv.ret.devices.devices_val; + state.ret.devices.devices_val = safe_realloc (g, state.ret.devices.devices_val, + sizeof (char *) * (state.ret.devices.devices_len + 1)); + state.ret.devices.devices_val[state.ret.devices.devices_len] = NULL; + return state.ret.devices.devices_val; } -struct umount_all_rv { - int cb_done; /* flag to indicate callback was called */ +struct umount_all_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void umount_all_cb (guestfs_h *g, void *data, XDR *xdr) { - struct umount_all_rv *rv = (struct umount_all_rv *) data; + struct umount_all_state *state = (struct umount_all_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_umount_all: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_umount_all: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_umount_all (guestfs_h *g) { - struct umount_all_rv rv; + struct umount_all_state state; int serial; if (g->state != READY) { - error (g, "guestfs_umount_all called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_umount_all"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_umount_all"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_umount_all", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_UMOUNT_ALL, NULL, NULL); if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = umount_all_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_umount_all failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_UMOUNT_ALL, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_UMOUNT_ALL, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct lvm_remove_all_rv { - int cb_done; /* flag to indicate callback was called */ +struct lvm_remove_all_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void lvm_remove_all_cb (guestfs_h *g, void *data, XDR *xdr) { - struct lvm_remove_all_rv *rv = (struct lvm_remove_all_rv *) data; + struct lvm_remove_all_state *state = (struct lvm_remove_all_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_lvm_remove_all: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_lvm_remove_all: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_lvm_remove_all (guestfs_h *g) { - struct lvm_remove_all_rv rv; + struct lvm_remove_all_state state; int serial; if (g->state != READY) { - error (g, "guestfs_lvm_remove_all called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_lvm_remove_all"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_lvm_remove_all"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_lvm_remove_all", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); serial = dispatch (g, GUESTFS_PROC_LVM_REMOVE_ALL, NULL, NULL); if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = lvm_remove_all_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_lvm_remove_all failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LVM_REMOVE_ALL, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LVM_REMOVE_ALL, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct file_rv { - int cb_done; /* flag to indicate callback was called */ +struct file_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_file_ret ret; @@ -3480,42 +3816,49 @@ struct file_rv { static void file_cb (guestfs_h *g, void *data, XDR *xdr) { - struct file_rv *rv = (struct file_rv *) data; + struct file_state *state = (struct file_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_file: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_file: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_file_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_file_ret (xdr, &state->ret)) { error (g, "guestfs_file: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char *guestfs_file (guestfs_h *g, const char *path) { struct guestfs_file_args args; - struct file_rv rv; + struct file_state state; int serial; if (g->state != READY) { - error (g, "guestfs_file called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_file"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_file"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_file", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_FILE, @@ -3523,30 +3866,30 @@ char *guestfs_file (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = file_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_file failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_FILE, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_FILE, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } - return rv.ret.description; /* caller will free */ + return state.ret.description; /* caller will free */ } -struct command_rv { - int cb_done; /* flag to indicate callback was called */ +struct command_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_command_ret ret; @@ -3554,42 +3897,49 @@ struct command_rv { static void command_cb (guestfs_h *g, void *data, XDR *xdr) { - struct command_rv *rv = (struct command_rv *) data; + struct command_state *state = (struct command_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_command: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_command: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_command_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_command_ret (xdr, &state->ret)) { error (g, "guestfs_command: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char *guestfs_command (guestfs_h *g, char * const* const arguments) { struct guestfs_command_args args; - struct command_rv rv; + struct command_state state; int serial; if (g->state != READY) { - error (g, "guestfs_command called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_command"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_command"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_command", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.arguments.arguments_val = (char **) arguments; for (args.arguments.arguments_len = 0; arguments[args.arguments.arguments_len]; args.arguments.arguments_len++) ; @@ -3598,30 +3948,30 @@ char *guestfs_command (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = command_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_command failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_COMMAND, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_COMMAND, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } - return rv.ret.output; /* caller will free */ + return state.ret.output; /* caller will free */ } -struct command_lines_rv { - int cb_done; /* flag to indicate callback was called */ +struct command_lines_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_command_lines_ret ret; @@ -3629,42 +3979,49 @@ struct command_lines_rv { static void command_lines_cb (guestfs_h *g, void *data, XDR *xdr) { - struct command_lines_rv *rv = (struct command_lines_rv *) data; + struct command_lines_state *state = (struct command_lines_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_command_lines: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_command_lines: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_command_lines_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_command_lines_ret (xdr, &state->ret)) { error (g, "guestfs_command_lines: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_command_lines (guestfs_h *g, char * const* const arguments) { struct guestfs_command_lines_args args; - struct command_lines_rv rv; + struct command_lines_state state; int serial; if (g->state != READY) { - error (g, "guestfs_command_lines called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_command_lines"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_command_lines"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_command_lines", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.arguments.arguments_val = (char **) arguments; for (args.arguments.arguments_len = 0; arguments[args.arguments.arguments_len]; args.arguments.arguments_len++) ; @@ -3673,34 +4030,34 @@ char **guestfs_command_lines (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = command_lines_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_command_lines failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_COMMAND_LINES, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_COMMAND_LINES, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.lines.lines_val = safe_realloc (g, rv.ret.lines.lines_val, - sizeof (char *) * (rv.ret.lines.lines_len + 1)); - rv.ret.lines.lines_val[rv.ret.lines.lines_len] = NULL; - return rv.ret.lines.lines_val; + state.ret.lines.lines_val = safe_realloc (g, state.ret.lines.lines_val, + sizeof (char *) * (state.ret.lines.lines_len + 1)); + state.ret.lines.lines_val[state.ret.lines.lines_len] = NULL; + return state.ret.lines.lines_val; } -struct stat_rv { - int cb_done; /* flag to indicate callback was called */ +struct stat_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_stat_ret ret; @@ -3708,42 +4065,49 @@ struct stat_rv { static void stat_cb (guestfs_h *g, void *data, XDR *xdr) { - struct stat_rv *rv = (struct stat_rv *) data; + struct stat_state *state = (struct stat_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_stat: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_stat: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_stat_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_stat_ret (xdr, &state->ret)) { error (g, "guestfs_stat: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } struct guestfs_stat *guestfs_stat (guestfs_h *g, const char *path) { struct guestfs_stat_args args; - struct stat_rv rv; + struct stat_state state; int serial; if (g->state != READY) { - error (g, "guestfs_stat called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_stat"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_stat"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_stat", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_STAT, @@ -3751,31 +4115,31 @@ struct guestfs_stat *guestfs_stat (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = stat_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_stat failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_STAT, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_STAT, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this */ - return safe_memdup (g, &rv.ret.statbuf, sizeof (rv.ret.statbuf)); + return safe_memdup (g, &state.ret.statbuf, sizeof (state.ret.statbuf)); } -struct lstat_rv { - int cb_done; /* flag to indicate callback was called */ +struct lstat_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_lstat_ret ret; @@ -3783,42 +4147,49 @@ struct lstat_rv { static void lstat_cb (guestfs_h *g, void *data, XDR *xdr) { - struct lstat_rv *rv = (struct lstat_rv *) data; + struct lstat_state *state = (struct lstat_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_lstat: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_lstat: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_lstat_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_lstat_ret (xdr, &state->ret)) { error (g, "guestfs_lstat: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } struct guestfs_stat *guestfs_lstat (guestfs_h *g, const char *path) { struct guestfs_lstat_args args; - struct lstat_rv rv; + struct lstat_state state; int serial; if (g->state != READY) { - error (g, "guestfs_lstat called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_lstat"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_lstat"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_lstat", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_LSTAT, @@ -3826,31 +4197,31 @@ struct guestfs_stat *guestfs_lstat (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = lstat_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_lstat failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LSTAT, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_LSTAT, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this */ - return safe_memdup (g, &rv.ret.statbuf, sizeof (rv.ret.statbuf)); + return safe_memdup (g, &state.ret.statbuf, sizeof (state.ret.statbuf)); } -struct statvfs_rv { - int cb_done; /* flag to indicate callback was called */ +struct statvfs_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_statvfs_ret ret; @@ -3858,42 +4229,49 @@ struct statvfs_rv { static void statvfs_cb (guestfs_h *g, void *data, XDR *xdr) { - struct statvfs_rv *rv = (struct statvfs_rv *) data; + struct statvfs_state *state = (struct statvfs_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_statvfs: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_statvfs: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_statvfs_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_statvfs_ret (xdr, &state->ret)) { error (g, "guestfs_statvfs: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } struct guestfs_statvfs *guestfs_statvfs (guestfs_h *g, const char *path) { struct guestfs_statvfs_args args; - struct statvfs_rv rv; + struct statvfs_state state; int serial; if (g->state != READY) { - error (g, "guestfs_statvfs called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_statvfs"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_statvfs"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_statvfs", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.path = (char *) path; serial = dispatch (g, GUESTFS_PROC_STATVFS, @@ -3901,31 +4279,31 @@ struct guestfs_statvfs *guestfs_statvfs (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = statvfs_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_statvfs failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_STATVFS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_STATVFS, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this */ - return safe_memdup (g, &rv.ret.statbuf, sizeof (rv.ret.statbuf)); + return safe_memdup (g, &state.ret.statbuf, sizeof (state.ret.statbuf)); } -struct tune2fs_l_rv { - int cb_done; /* flag to indicate callback was called */ +struct tune2fs_l_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_tune2fs_l_ret ret; @@ -3933,42 +4311,49 @@ struct tune2fs_l_rv { static void tune2fs_l_cb (guestfs_h *g, void *data, XDR *xdr) { - struct tune2fs_l_rv *rv = (struct tune2fs_l_rv *) data; + struct tune2fs_l_state *state = (struct tune2fs_l_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_tune2fs_l: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_tune2fs_l: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_tune2fs_l_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_tune2fs_l_ret (xdr, &state->ret)) { error (g, "guestfs_tune2fs_l: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } char **guestfs_tune2fs_l (guestfs_h *g, const char *device) { struct guestfs_tune2fs_l_args args; - struct tune2fs_l_rv rv; + struct tune2fs_l_state state; int serial; if (g->state != READY) { - error (g, "guestfs_tune2fs_l called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_tune2fs_l"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_tune2fs_l"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_tune2fs_l", g->state); return NULL; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_TUNE2FS_L, @@ -3976,72 +4361,79 @@ char **guestfs_tune2fs_l (guestfs_h *g, if (serial == -1) return NULL; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = tune2fs_l_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_tune2fs_l failed, see earlier error messages"); return NULL; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_TUNE2FS_L, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_TUNE2FS_L, serial) == -1) return NULL; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return NULL; } /* caller will free this, but we need to add a NULL entry */ - rv.ret.superblock.superblock_val = safe_realloc (g, rv.ret.superblock.superblock_val, - sizeof (char *) * (rv.ret.superblock.superblock_len + 1)); - rv.ret.superblock.superblock_val[rv.ret.superblock.superblock_len] = NULL; - return rv.ret.superblock.superblock_val; + state.ret.superblock.superblock_val = safe_realloc (g, state.ret.superblock.superblock_val, + sizeof (char *) * (state.ret.superblock.superblock_len + 1)); + state.ret.superblock.superblock_val[state.ret.superblock.superblock_len] = NULL; + return state.ret.superblock.superblock_val; } -struct blockdev_setro_rv { - int cb_done; /* flag to indicate callback was called */ +struct blockdev_setro_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void blockdev_setro_cb (guestfs_h *g, void *data, XDR *xdr) { - struct blockdev_setro_rv *rv = (struct blockdev_setro_rv *) data; + struct blockdev_setro_state *state = (struct blockdev_setro_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_blockdev_setro: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_blockdev_setro: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_blockdev_setro (guestfs_h *g, const char *device) { struct guestfs_blockdev_setro_args args; - struct blockdev_setro_rv rv; + struct blockdev_setro_state state; int serial; if (g->state != READY) { - error (g, "guestfs_blockdev_setro called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_blockdev_setro"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_blockdev_setro"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_blockdev_setro", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_BLOCKDEV_SETRO, @@ -4049,68 +4441,75 @@ int guestfs_blockdev_setro (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = blockdev_setro_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_blockdev_setro failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_BLOCKDEV_SETRO, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_SETRO, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct blockdev_setrw_rv { - int cb_done; /* flag to indicate callback was called */ +struct blockdev_setrw_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void blockdev_setrw_cb (guestfs_h *g, void *data, XDR *xdr) { - struct blockdev_setrw_rv *rv = (struct blockdev_setrw_rv *) data; + struct blockdev_setrw_state *state = (struct blockdev_setrw_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_blockdev_setrw: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_blockdev_setrw: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_blockdev_setrw (guestfs_h *g, const char *device) { struct guestfs_blockdev_setrw_args args; - struct blockdev_setrw_rv rv; + struct blockdev_setrw_state state; int serial; if (g->state != READY) { - error (g, "guestfs_blockdev_setrw called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_blockdev_setrw"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_blockdev_setrw"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_blockdev_setrw", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_BLOCKDEV_SETRW, @@ -4118,30 +4517,30 @@ int guestfs_blockdev_setrw (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = blockdev_setrw_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_blockdev_setrw failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_BLOCKDEV_SETRW, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_SETRW, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct blockdev_getro_rv { - int cb_done; /* flag to indicate callback was called */ +struct blockdev_getro_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_blockdev_getro_ret ret; @@ -4149,42 +4548,49 @@ struct blockdev_getro_rv { static void blockdev_getro_cb (guestfs_h *g, void *data, XDR *xdr) { - struct blockdev_getro_rv *rv = (struct blockdev_getro_rv *) data; + struct blockdev_getro_state *state = (struct blockdev_getro_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_blockdev_getro: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_blockdev_getro: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_blockdev_getro_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_blockdev_getro_ret (xdr, &state->ret)) { error (g, "guestfs_blockdev_getro: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_blockdev_getro (guestfs_h *g, const char *device) { struct guestfs_blockdev_getro_args args; - struct blockdev_getro_rv rv; + struct blockdev_getro_state state; int serial; if (g->state != READY) { - error (g, "guestfs_blockdev_getro called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_blockdev_getro"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_blockdev_getro"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_blockdev_getro", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_BLOCKDEV_GETRO, @@ -4192,30 +4598,30 @@ int guestfs_blockdev_getro (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = blockdev_getro_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_blockdev_getro failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_BLOCKDEV_GETRO, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_GETRO, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } - return rv.ret.ro; + return state.ret.ro; } -struct blockdev_getss_rv { - int cb_done; /* flag to indicate callback was called */ +struct blockdev_getss_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_blockdev_getss_ret ret; @@ -4223,42 +4629,49 @@ struct blockdev_getss_rv { static void blockdev_getss_cb (guestfs_h *g, void *data, XDR *xdr) { - struct blockdev_getss_rv *rv = (struct blockdev_getss_rv *) data; + struct blockdev_getss_state *state = (struct blockdev_getss_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_blockdev_getss: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_blockdev_getss: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_blockdev_getss_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_blockdev_getss_ret (xdr, &state->ret)) { error (g, "guestfs_blockdev_getss: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_blockdev_getss (guestfs_h *g, const char *device) { struct guestfs_blockdev_getss_args args; - struct blockdev_getss_rv rv; + struct blockdev_getss_state state; int serial; if (g->state != READY) { - error (g, "guestfs_blockdev_getss called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_blockdev_getss"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_blockdev_getss"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_blockdev_getss", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_BLOCKDEV_GETSS, @@ -4266,30 +4679,30 @@ int guestfs_blockdev_getss (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = blockdev_getss_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_blockdev_getss failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_BLOCKDEV_GETSS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_GETSS, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } - return rv.ret.sectorsize; + return state.ret.sectorsize; } -struct blockdev_getbsz_rv { - int cb_done; /* flag to indicate callback was called */ +struct blockdev_getbsz_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_blockdev_getbsz_ret ret; @@ -4297,42 +4710,49 @@ struct blockdev_getbsz_rv { static void blockdev_getbsz_cb (guestfs_h *g, void *data, XDR *xdr) { - struct blockdev_getbsz_rv *rv = (struct blockdev_getbsz_rv *) data; + struct blockdev_getbsz_state *state = (struct blockdev_getbsz_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_blockdev_getbsz: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_blockdev_getbsz: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_blockdev_getbsz_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_blockdev_getbsz_ret (xdr, &state->ret)) { error (g, "guestfs_blockdev_getbsz: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_blockdev_getbsz (guestfs_h *g, const char *device) { struct guestfs_blockdev_getbsz_args args; - struct blockdev_getbsz_rv rv; + struct blockdev_getbsz_state state; int serial; if (g->state != READY) { - error (g, "guestfs_blockdev_getbsz called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_blockdev_getbsz"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_blockdev_getbsz"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_blockdev_getbsz", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_BLOCKDEV_GETBSZ, @@ -4340,52 +4760,52 @@ int guestfs_blockdev_getbsz (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = blockdev_getbsz_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_blockdev_getbsz failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_BLOCKDEV_GETBSZ, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_GETBSZ, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } - return rv.ret.blocksize; + return state.ret.blocksize; } -struct blockdev_setbsz_rv { - int cb_done; /* flag to indicate callback was called */ +struct blockdev_setbsz_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void blockdev_setbsz_cb (guestfs_h *g, void *data, XDR *xdr) { - struct blockdev_setbsz_rv *rv = (struct blockdev_setbsz_rv *) data; + struct blockdev_setbsz_state *state = (struct blockdev_setbsz_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_blockdev_setbsz: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_blockdev_setbsz: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_blockdev_setbsz (guestfs_h *g, @@ -4393,16 +4813,23 @@ int guestfs_blockdev_setbsz (guestfs_h *g, int blocksize) { struct guestfs_blockdev_setbsz_args args; - struct blockdev_setbsz_rv rv; + struct blockdev_setbsz_state state; int serial; if (g->state != READY) { - error (g, "guestfs_blockdev_setbsz called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_blockdev_setbsz"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_blockdev_setbsz"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_blockdev_setbsz", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; args.blocksize = blocksize; @@ -4411,30 +4838,30 @@ int guestfs_blockdev_setbsz (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = blockdev_setbsz_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_blockdev_setbsz failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_BLOCKDEV_SETBSZ, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_SETBSZ, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct blockdev_getsz_rv { - int cb_done; /* flag to indicate callback was called */ +struct blockdev_getsz_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_blockdev_getsz_ret ret; @@ -4442,42 +4869,49 @@ struct blockdev_getsz_rv { static void blockdev_getsz_cb (guestfs_h *g, void *data, XDR *xdr) { - struct blockdev_getsz_rv *rv = (struct blockdev_getsz_rv *) data; + struct blockdev_getsz_state *state = (struct blockdev_getsz_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_blockdev_getsz: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_blockdev_getsz: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_blockdev_getsz_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_blockdev_getsz_ret (xdr, &state->ret)) { error (g, "guestfs_blockdev_getsz: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int64_t guestfs_blockdev_getsz (guestfs_h *g, const char *device) { struct guestfs_blockdev_getsz_args args; - struct blockdev_getsz_rv rv; + struct blockdev_getsz_state state; int serial; if (g->state != READY) { - error (g, "guestfs_blockdev_getsz called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_blockdev_getsz"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_blockdev_getsz"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_blockdev_getsz", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_BLOCKDEV_GETSZ, @@ -4485,30 +4919,30 @@ int64_t guestfs_blockdev_getsz (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = blockdev_getsz_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_blockdev_getsz failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_BLOCKDEV_GETSZ, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_GETSZ, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } - return rv.ret.sizeinsectors; + return state.ret.sizeinsectors; } -struct blockdev_getsize64_rv { - int cb_done; /* flag to indicate callback was called */ +struct blockdev_getsize64_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; struct guestfs_blockdev_getsize64_ret ret; @@ -4516,42 +4950,49 @@ struct blockdev_getsize64_rv { static void blockdev_getsize64_cb (guestfs_h *g, void *data, XDR *xdr) { - struct blockdev_getsize64_rv *rv = (struct blockdev_getsize64_rv *) data; + struct blockdev_getsize64_state *state = (struct blockdev_getsize64_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_blockdev_getsize64: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_blockdev_getsize64: failed to parse reply error"); return; } goto done; } - if (!xdr_guestfs_blockdev_getsize64_ret (xdr, &rv->ret)) { + if (!xdr_guestfs_blockdev_getsize64_ret (xdr, &state->ret)) { error (g, "guestfs_blockdev_getsize64: failed to parse reply"); return; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int64_t guestfs_blockdev_getsize64 (guestfs_h *g, const char *device) { struct guestfs_blockdev_getsize64_args args; - struct blockdev_getsize64_rv rv; + struct blockdev_getsize64_state state; int serial; if (g->state != READY) { - error (g, "guestfs_blockdev_getsize64 called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_blockdev_getsize64"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_blockdev_getsize64"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_blockdev_getsize64", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_BLOCKDEV_GETSIZE64, @@ -4559,68 +5000,75 @@ int64_t guestfs_blockdev_getsize64 (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = blockdev_getsize64_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_blockdev_getsize64 failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_BLOCKDEV_GETSIZE64, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_GETSIZE64, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } - return rv.ret.sizeinbytes; + return state.ret.sizeinbytes; } -struct blockdev_flushbufs_rv { - int cb_done; /* flag to indicate callback was called */ +struct blockdev_flushbufs_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void blockdev_flushbufs_cb (guestfs_h *g, void *data, XDR *xdr) { - struct blockdev_flushbufs_rv *rv = (struct blockdev_flushbufs_rv *) data; + struct blockdev_flushbufs_state *state = (struct blockdev_flushbufs_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_blockdev_flushbufs: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_blockdev_flushbufs: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_blockdev_flushbufs (guestfs_h *g, const char *device) { struct guestfs_blockdev_flushbufs_args args; - struct blockdev_flushbufs_rv rv; + struct blockdev_flushbufs_state state; int serial; if (g->state != READY) { - error (g, "guestfs_blockdev_flushbufs called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_blockdev_flushbufs"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_blockdev_flushbufs"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_blockdev_flushbufs", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS, @@ -4628,68 +5076,75 @@ int guestfs_blockdev_flushbufs (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = blockdev_flushbufs_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_blockdev_flushbufs failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } return 0; } -struct blockdev_rereadpt_rv { - int cb_done; /* flag to indicate callback was called */ +struct blockdev_rereadpt_state { + int cb_done; struct guestfs_message_header hdr; struct guestfs_message_error err; }; static void blockdev_rereadpt_cb (guestfs_h *g, void *data, XDR *xdr) { - struct blockdev_rereadpt_rv *rv = (struct blockdev_rereadpt_rv *) data; + struct blockdev_rereadpt_state *state = (struct blockdev_rereadpt_state *) data; - if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + if (!xdr_guestfs_message_header (xdr, &state->hdr)) { error (g, "guestfs_blockdev_rereadpt: failed to parse reply header"); return; } - if (rv->hdr.status == GUESTFS_STATUS_ERROR) { - if (!xdr_guestfs_message_error (xdr, &rv->err)) { + if (state->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &state->err)) { error (g, "guestfs_blockdev_rereadpt: failed to parse reply error"); return; } goto done; } done: - rv->cb_done = 1; - main_loop.main_loop_quit (g); + state->cb_done = 1; + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_blockdev_rereadpt (guestfs_h *g, const char *device) { struct guestfs_blockdev_rereadpt_args args; - struct blockdev_rereadpt_rv rv; + struct blockdev_rereadpt_state state; int serial; if (g->state != READY) { - error (g, "guestfs_blockdev_rereadpt called from the wrong state, %d != READY", - g->state); + if (g->state == CONFIG) + error (g, "%s: call launch() before using this function", + "guestfs_blockdev_rereadpt"); + else if (g->state == LAUNCHING) + error (g, "%s: call wait_ready() before using this function", + "guestfs_blockdev_rereadpt"); + else + error (g, "%s called from the wrong state, %d != READY", + "guestfs_blockdev_rereadpt", g->state); return -1; } - memset (&rv, 0, sizeof rv); + memset (&state, 0, sizeof state); args.device = (char *) device; serial = dispatch (g, GUESTFS_PROC_BLOCKDEV_REREADPT, @@ -4697,22 +5152,22 @@ int guestfs_blockdev_rereadpt (guestfs_h *g, if (serial == -1) return -1; - rv.cb_done = 0; + state.cb_done = 0; g->reply_cb_internal = blockdev_rereadpt_cb; - g->reply_cb_internal_data = &rv; - main_loop.main_loop_run (g); + g->reply_cb_internal_data = &state; + (void) g->main_loop->main_loop_run (g->main_loop, g); g->reply_cb_internal = NULL; g->reply_cb_internal_data = NULL; - if (!rv.cb_done) { + if (!state.cb_done) { error (g, "guestfs_blockdev_rereadpt failed, see earlier error messages"); return -1; } - if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_BLOCKDEV_REREADPT, serial) == -1) + if (check_reply_header (g, &state.hdr, GUESTFS_PROC_BLOCKDEV_REREADPT, serial) == -1) return -1; - if (rv.hdr.status == GUESTFS_STATUS_ERROR) { - error (g, "%s", rv.err.error); + if (state.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", state.err.error); return -1; } diff --git a/src/guestfs.c b/src/guestfs.c index e104633..6c49e90 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -64,35 +64,71 @@ static char *safe_strdup (guestfs_h *g, const char *str); static void *safe_memdup (guestfs_h *g, void *ptr, size_t size); static void default_error_cb (guestfs_h *g, void *data, const char *msg); -static void stdout_event (void *data, int watch, int fd, int events); -static void sock_read_event (void *data, int watch, int fd, int events); -static void sock_write_event (void *data, int watch, int fd, int events); +static void stdout_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data, int watch, int fd, int events); +static void sock_read_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data, int watch, int fd, int events); +static void sock_write_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data, int watch, int fd, int events); static void close_handles (void); -static int select_add_handle (guestfs_h *g, int fd, int events, guestfs_handle_event_cb cb, void *data); -static int select_remove_handle (guestfs_h *g, int watch); -static int select_add_timeout (guestfs_h *g, int interval, guestfs_handle_timeout_cb cb, void *data); -static int select_remove_timeout (guestfs_h *g, int timer); -static void select_main_loop_run (guestfs_h *g); -static void select_main_loop_quit (guestfs_h *g); +static int select_add_handle (guestfs_main_loop *ml, guestfs_h *g, int fd, int events, guestfs_handle_event_cb cb, void *data); +static int select_remove_handle (guestfs_main_loop *ml, guestfs_h *g, int watch); +static int select_add_timeout (guestfs_main_loop *ml, guestfs_h *g, int interval, guestfs_handle_timeout_cb cb, void *data); +static int select_remove_timeout (guestfs_main_loop *ml, guestfs_h *g, int timer); +static int select_main_loop_run (guestfs_main_loop *ml, guestfs_h *g); +static int select_main_loop_quit (guestfs_main_loop *ml, guestfs_h *g); -#define UNIX_PATH_MAX 108 +/* Default select-based main loop. */ +struct select_handle_cb_data { + guestfs_handle_event_cb cb; + guestfs_h *g; + void *data; +}; -/* Also in guestfsd.c */ -#define VMCHANNEL_PORT 6666 -#define VMCHANNEL_ADDR "10.0.2.4" +struct select_main_loop { + /* NB. These fields must be the same as in struct guestfs_main_loop: */ + guestfs_add_handle_cb add_handle; + guestfs_remove_handle_cb remove_handle; + guestfs_add_timeout_cb add_timeout; + guestfs_remove_timeout_cb remove_timeout; + guestfs_main_loop_run_cb main_loop_run; + guestfs_main_loop_quit_cb main_loop_quit; + + /* Additional private data: */ + int is_running; + + fd_set rset; + fd_set wset; + fd_set xset; + + int max_fd; + int nr_fds; + struct select_handle_cb_data *handle_cb_data; +}; -/* Current main loop. */ -static guestfs_main_loop main_loop = { +/* Default main loop. */ +static struct select_main_loop default_main_loop = { .add_handle = select_add_handle, .remove_handle = select_remove_handle, .add_timeout = select_add_timeout, .remove_timeout = select_remove_timeout, .main_loop_run = select_main_loop_run, .main_loop_quit = select_main_loop_quit, + + /* XXX hopefully .rset, .wset, .xset are initialized to the empty + * set by the normal action of everything being initialized to zero. + */ + .is_running = 0, + .max_fd = -1, + .nr_fds = 0, + .handle_cb_data = NULL, }; +#define UNIX_PATH_MAX 108 + +/* Also in guestfsd.c */ +#define VMCHANNEL_PORT 6666 +#define VMCHANNEL_ADDR "10.0.2.4" + /* GuestFS handle and connection. */ enum state { CONFIG, LAUNCHING, READY, BUSY, NO_HANDLE }; @@ -127,6 +163,8 @@ struct guestfs_h guestfs_abort_cb abort_cb; guestfs_error_handler_cb error_cb; void * error_cb_data; + guestfs_send_cb send_cb; + void * send_cb_data; guestfs_reply_cb reply_cb; void * reply_cb_data; guestfs_log_message_cb log_message_cb; @@ -136,15 +174,21 @@ struct guestfs_h guestfs_launch_done_cb launch_done_cb; void * launch_done_cb_data; - /* These callbacks are called before reply_cb and launch_done_cb, - * and are used to implement the high-level API without needing to - * interfere with callbacks that the user might have set. + /* These callbacks are called before send_cb, reply_cb and + * launch_done_cb, and are used to implement the high-level + * API without needing to interfere with callbacks that the + * user might have set. */ + guestfs_send_cb send_cb_internal; + void * send_cb_internal_data; guestfs_reply_cb reply_cb_internal; void * reply_cb_internal_data; guestfs_launch_done_cb launch_done_cb_internal; void * launch_done_cb_internal_data; + /* Main loop used by this handle. */ + guestfs_main_loop *main_loop; + /* Messages sent and received from the daemon. */ char *msg_in; int msg_in_size, msg_in_allocated; @@ -187,6 +231,8 @@ guestfs_create (void) g->path = str != NULL ? str : GUESTFS_DEFAULT_PATH; /* XXX We should probably make QEMU configurable as well. */ + g->main_loop = (guestfs_main_loop *) &default_main_loop; + /* Start with large serial numbers so they are easy to spot * inside the protocol. */ @@ -780,18 +826,18 @@ guestfs_launch (guestfs_h *g) g->msg_out_pos = 0; g->stdout_watch = - main_loop.add_handle (g, g->fd[1], - GUESTFS_HANDLE_READABLE, - stdout_event, g); + g->main_loop->add_handle (g->main_loop, g, g->fd[1], + GUESTFS_HANDLE_READABLE, + stdout_event, NULL); if (g->stdout_watch == -1) { error (g, "could not watch qemu stdout"); goto cleanup3; } g->sock_watch = - main_loop.add_handle (g, g->sock, - GUESTFS_HANDLE_READABLE, - sock_read_event, g); + g->main_loop->add_handle (g->main_loop, g, g->sock, + GUESTFS_HANDLE_READABLE, + sock_read_event, NULL); if (g->sock_watch == -1) { error (g, "could not watch daemon communications socket"); goto cleanup3; @@ -802,9 +848,9 @@ guestfs_launch (guestfs_h *g) cleanup3: if (g->stdout_watch >= 0) - main_loop.remove_handle (g, g->stdout_watch); + g->main_loop->remove_handle (g->main_loop, g, g->stdout_watch); if (g->sock_watch >= 0) - main_loop.remove_handle (g, g->sock_watch); + g->main_loop->remove_handle (g->main_loop, g, g->sock_watch); cleanup2: close (g->sock); @@ -831,14 +877,17 @@ guestfs_launch (guestfs_h *g) static void finish_wait_ready (guestfs_h *g, void *vp) { + if (g->verbose) + fprintf (stderr, "finish_wait_ready called, %p, vp = %p\n", g, vp); + *((int *)vp) = 1; - main_loop.main_loop_quit (g); + g->main_loop->main_loop_quit (g->main_loop, g); } int guestfs_wait_ready (guestfs_h *g) { - int r = 0; + int finished = 0, r; if (g->state == READY) return 0; @@ -853,12 +902,14 @@ guestfs_wait_ready (guestfs_h *g) } g->launch_done_cb_internal = finish_wait_ready; - g->launch_done_cb_internal_data = &r; - main_loop.main_loop_run (g); + g->launch_done_cb_internal_data = &finished; + r = g->main_loop->main_loop_run (g->main_loop, g); g->launch_done_cb_internal = NULL; g->launch_done_cb_internal_data = NULL; - if (r != 1) { + if (r == -1) return -1; + + if (finished != 1) { error (g, "guestfs_wait_ready failed, see earlier error messages"); return -1; } @@ -897,9 +948,9 @@ guestfs_kill_subprocess (guestfs_h *g) * we see kernel messages here too. */ static void -stdout_event (void *data, int watch, int fd, int events) +stdout_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data, + int watch, int fd, int events) { - guestfs_h *g = (guestfs_h *) data; char buf[4096]; int n; @@ -923,9 +974,9 @@ stdout_event (void *data, int watch, int fd, int events) /*kill (g->pid, SIGTERM);*/ waitpid (g->pid, NULL, 0); if (g->stdout_watch >= 0) - main_loop.remove_handle (g, g->stdout_watch); + g->main_loop->remove_handle (g->main_loop, g, g->stdout_watch); if (g->sock_watch >= 0) - main_loop.remove_handle (g, g->sock_watch); + g->main_loop->remove_handle (g->main_loop, g, g->sock_watch); close (g->fd[0]); close (g->fd[1]); close (g->sock); @@ -961,9 +1012,9 @@ stdout_event (void *data, int watch, int fd, int events) * guestfsd (daemon inside the guest) communication socket. */ static void -sock_read_event (void *data, int watch, int fd, int events) +sock_read_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data, + int watch, int fd, int events) { - guestfs_h *g = (guestfs_h *) data; XDR xdr; unsigned len; int n; @@ -1098,9 +1149,9 @@ sock_read_event (void *data, int watch, int fd, int events) * guestfsd (daemon inside the guest) communication socket. */ static void -sock_write_event (void *data, int watch, int fd, int events) +sock_write_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data, + int watch, int fd, int events) { - guestfs_h *g = (guestfs_h *) data; int n; if (g->verbose) @@ -1145,14 +1196,14 @@ sock_write_event (void *data, int watch, int fd, int events) free (g->msg_out); g->msg_out_pos = g->msg_out_size = 0; - if (main_loop.remove_handle (g, g->sock_watch) == -1) { + if (g->main_loop->remove_handle (g->main_loop, g, g->sock_watch) == -1) { error (g, "remove_handle failed in sock_write_event"); return; } g->sock_watch = - main_loop.add_handle (g, g->sock, - GUESTFS_HANDLE_READABLE, - sock_read_event, g); + g->main_loop->add_handle (g->main_loop, g, g->sock, + GUESTFS_HANDLE_READABLE, + sock_read_event, NULL); if (g->sock_watch == -1) { error (g, "add_handle failed in sock_write_event"); return; @@ -1220,14 +1271,14 @@ dispatch (guestfs_h *g, int proc_nr, xdrproc_t xdrp, char *args) memcpy (g->msg_out + 4, buffer, len); /* Change the handle to sock_write_event. */ - if (main_loop.remove_handle (g, g->sock_watch) == -1) { + if (g->main_loop->remove_handle (g->main_loop, g, g->sock_watch) == -1) { error (g, "remove_handle failed in dispatch"); goto cleanup1; } g->sock_watch = - main_loop.add_handle (g, g->sock, - GUESTFS_HANDLE_WRITABLE, - sock_write_event, g); + g->main_loop->add_handle (g->main_loop, g, g->sock, + GUESTFS_HANDLE_WRITABLE, + sock_write_event, NULL); if (g->sock_watch == -1) { error (g, "add_handle failed in dispatch"); goto cleanup1; @@ -1243,6 +1294,139 @@ dispatch (guestfs_h *g, int proc_nr, xdrproc_t xdrp, char *args) return -1; } +#if 0 +static int cancel = 0; /* XXX Implement file cancellation. */ + +static int +send_file (guestfs_h *g, const char *filename) +{ + char buf[GUESTFS_MAX_CHUNK_SIZE]; + int fd, r; + + fd = open (filename, O_RDONLY); + if (fd == -1) { + perrorf (g, "open: %s", filename); + send_file_cancellation (g); + /* Daemon sees cancellation and won't reply, so caller can + * just return here. + */ + return -1; + } + + /* Send file in chunked encoding. */ + while (!cancel && (r = read (fd, buf, sizeof buf)) > 0) { + if (send_file_data (g, buf, r) == -1) + return -1; + } + + if (cancel) { + send_file_cancellation (g); + return -1; + } + + if (r == -1) { + perrorf (g, "read: %s", filename); + send_file_cancellation (g); + return -1; + } + + /* End of file, but before we send that, we need to close + * the file and check for errors. + */ + if (close (fd) == -1) { + perrorf (g, "close: %s", filename); + send_file_cancellation (g); + return -1; + } + + return send_file_complete (g); +} + +/* Send a chunk, cancellation or end of file, wait for it to go. */ +static int +send_file_chunk (guestfs_h *g, int cancel, const char *buf, size_t len) +{ + void *data; + guestfs_chunk chunk; + XDR xdr; + + if (g->state != BUSY) { + error (g, "send_file_chunk: state %d != READY", g->state); + return -1; + } + + /* Serialize the chunk. */ + chunk.cancel = cancel; + chunk.data.data_len = len; + chunk.data.data_val = (char *) buf; + + data = safe_malloc (g, GUESTFS_MAX_CHUNK_SIZE + 48); + xdrmem_create (&xdr, data, GUESTFS_MAX_CHUNK_SIZE + 48, XDR_ENCODE); + if (xdr_guestfs_chunk (&xdr, &chunk)) { + error (g, "xdr_guestfs_chunk failed"); + free (data); + return -1; + } + + chunkdatalen = xdr_getpos (&xdr); + xdr_destroy (&xdr); + + len = xdr_getpos (&xdr); + xdr_destroy (&xdr); + + data = safe_realloc (g, data, len); + g->msg_out = data; + g->msg_out_size = len; + g->msg_out_pos = 0; + + /* Change the handle to sock_write_event. */ + if (g->main_loop->remove_handle (g->main_loop, g, g->sock_watch) == -1) { + error (g, "remove_handle failed in dispatch"); + goto cleanup1; + } + g->sock_watch = + g->main_loop->add_handle (g->main_loop, g, g->sock, + GUESTFS_HANDLE_WRITABLE, + sock_write_event, NULL); + if (g->sock_watch == -1) { + error (g, "add_handle failed in dispatch"); + goto cleanup1; + } + + return 0; + + cleanup1: + free (g->msg_out); + g->msg_out = NULL; + g->msg_out_size = 0; + g->state = READY; + return -1; +} + +/* Send a chunk of file data. */ +static int +send_file_data (guestfs_h *g, const char *buf, size_t len) +{ + return send_file_chunk (g, 0, buf, len); +} + +/* Send a cancellation message. */ +static int +send_file_cancellation (guestfs_h *g) +{ + char buf[1]; + return send_file_chunk (g, 1, buf, 0); +} + +/* Send a file complete chunk. */ +static int +send_file_complete (guestfs_h *g) +{ + char buf[0]; + return send_file_chunk (g, 0, buf, 0); +} +#endif + /* Check the return message from a call for validity. */ static int check_reply_header (guestfs_h *g, @@ -1313,36 +1497,11 @@ guestfs_free_lvm_lv_list (struct guestfs_lvm_lv_list *x) /* This is the default main loop implementation, using select(2). */ -struct handle_cb_data { - guestfs_handle_event_cb cb; - void *data; -}; - -static fd_set rset; -static fd_set wset; -static fd_set xset; -static int select_init_done = 0; -static int max_fd = -1; -static int nr_fds = 0; -static struct handle_cb_data *handle_cb_data = NULL; - -static void -select_init (void) -{ - if (!select_init_done) { - FD_ZERO (&rset); - FD_ZERO (&wset); - FD_ZERO (&xset); - - select_init_done = 1; - } -} - static int -select_add_handle (guestfs_h *g, int fd, int events, +select_add_handle (guestfs_main_loop *mlv, guestfs_h *g, int fd, int events, guestfs_handle_event_cb cb, void *data) { - select_init (); + struct select_main_loop *ml = (struct select_main_loop *) mlv; if (fd < 0 || fd >= FD_SETSIZE) { error (g, "fd %d is out of range", fd); @@ -1362,7 +1521,9 @@ select_add_handle (guestfs_h *g, int fd, int events, return -1; } - if (FD_ISSET (fd, &rset) || FD_ISSET (fd, &wset) || FD_ISSET (fd, &xset)) { + if (FD_ISSET (fd, &ml->rset) || + FD_ISSET (fd, &ml->wset) || + FD_ISSET (fd, &ml->xset)) { error (g, "fd %d is already registered", fd); return -1; } @@ -1373,102 +1534,111 @@ select_add_handle (guestfs_h *g, int fd, int events, } if ((events & GUESTFS_HANDLE_READABLE)) - FD_SET (fd, &rset); + FD_SET (fd, &ml->rset); if ((events & GUESTFS_HANDLE_WRITABLE)) - FD_SET (fd, &wset); + FD_SET (fd, &ml->wset); if ((events & GUESTFS_HANDLE_HANGUP) || (events & GUESTFS_HANDLE_ERROR)) - FD_SET (fd, &xset); + FD_SET (fd, &ml->xset); - if (fd > max_fd) { - max_fd = fd; - handle_cb_data = safe_realloc (g, handle_cb_data, - sizeof (struct handle_cb_data) * (max_fd+1)); + if (fd > ml->max_fd) { + ml->max_fd = fd; + ml->handle_cb_data = + safe_realloc (g, ml->handle_cb_data, + sizeof (struct select_handle_cb_data) * (ml->max_fd+1)); } - handle_cb_data[fd].cb = cb; - handle_cb_data[fd].data = data; + ml->handle_cb_data[fd].cb = cb; + ml->handle_cb_data[fd].g = g; + ml->handle_cb_data[fd].data = data; - nr_fds++; + ml->nr_fds++; /* Any integer >= 0 can be the handle, and this is as good as any ... */ return fd; } static int -select_remove_handle (guestfs_h *g, int fd) +select_remove_handle (guestfs_main_loop *mlv, guestfs_h *g, int fd) { - select_init (); + struct select_main_loop *ml = (struct select_main_loop *) mlv; if (fd < 0 || fd >= FD_SETSIZE) { error (g, "fd %d is out of range", fd); return -1; } - if (!FD_ISSET (fd, &rset) && !FD_ISSET (fd, &wset) && !FD_ISSET (fd, &xset)) { + if (!FD_ISSET (fd, &ml->rset) && + !FD_ISSET (fd, &ml->wset) && + !FD_ISSET (fd, &ml->xset)) { error (g, "fd %d was not registered", fd); return -1; } - FD_CLR (fd, &rset); - FD_CLR (fd, &wset); - FD_CLR (fd, &xset); + FD_CLR (fd, &ml->rset); + FD_CLR (fd, &ml->wset); + FD_CLR (fd, &ml->xset); - if (fd == max_fd) { - max_fd--; - handle_cb_data = safe_realloc (g, handle_cb_data, - sizeof (struct handle_cb_data) * (max_fd+1)); + if (fd == ml->max_fd) { + ml->max_fd--; + ml->handle_cb_data = + safe_realloc (g, ml->handle_cb_data, + sizeof (struct select_handle_cb_data) * (ml->max_fd+1)); } - nr_fds--; + ml->nr_fds--; return 0; } static int -select_add_timeout (guestfs_h *g, int interval, +select_add_timeout (guestfs_main_loop *mlv, guestfs_h *g, int interval, guestfs_handle_timeout_cb cb, void *data) { - select_init (); + //struct select_main_loop *ml = (struct select_main_loop *) mlv; abort (); /* XXX not implemented yet */ } static int -select_remove_timeout (guestfs_h *g, int timer) +select_remove_timeout (guestfs_main_loop *mlv, guestfs_h *g, int timer) { - select_init (); + //struct select_main_loop *ml = (struct select_main_loop *) mlv; abort (); /* XXX not implemented yet */ } -/* Note that main loops can be nested. */ -static int level = 0; - -static void -select_main_loop_run (guestfs_h *g) +/* The 'g' parameter is just used for error reporting. Events + * for multiple handles can be dispatched by running the main + * loop. + */ +static int +select_main_loop_run (guestfs_main_loop *mlv, guestfs_h *g) { - int old_level, fd, r, events; + struct select_main_loop *ml = (struct select_main_loop *) mlv; + int fd, r, events; fd_set rset2, wset2, xset2; - select_init (); + if (ml->is_running) { + error (g, "select_main_loop_run: this cannot be called recursively"); + return -1; + } + + ml->is_running = 1; - old_level = level++; - while (level > old_level) { - if (nr_fds == 0) { - level = old_level; + while (ml->is_running) { + if (ml->nr_fds == 0) break; - } - rset2 = rset; - wset2 = wset; - xset2 = xset; - r = select (max_fd+1, &rset2, &wset2, &xset2, NULL); + rset2 = ml->rset; + wset2 = ml->wset; + xset2 = ml->xset; + r = select (ml->max_fd+1, &rset2, &wset2, &xset2, NULL); if (r == -1) { perrorf (g, "select"); - level = old_level; - break; + ml->is_running = 0; + return -1; } - for (fd = 0; r > 0 && fd <= max_fd; ++fd) { + for (fd = 0; r > 0 && fd <= ml->max_fd; ++fd) { events = 0; if (FD_ISSET (fd, &rset2)) events |= GUESTFS_HANDLE_READABLE; @@ -1478,22 +1648,28 @@ select_main_loop_run (guestfs_h *g) events |= GUESTFS_HANDLE_ERROR | GUESTFS_HANDLE_HANGUP; if (events) { r--; - handle_cb_data[fd].cb (handle_cb_data[fd].data, - fd, fd, events); + ml->handle_cb_data[fd].cb ((guestfs_main_loop *) ml, + ml->handle_cb_data[fd].g, + ml->handle_cb_data[fd].data, + fd, fd, events); } } } + + ml->is_running = 0; + return 0; } -static void -select_main_loop_quit (guestfs_h *g) +static int +select_main_loop_quit (guestfs_main_loop *mlv, guestfs_h *g) { - select_init (); + struct select_main_loop *ml = (struct select_main_loop *) mlv; - if (level == 0) { - error (g, "cannot quit, we are not in a main loop"); - return; + if (!ml->is_running) { + error (g, "cannot quit, we are not running in a main loop"); + return -1; } - level--; + ml->is_running = 0; + return 0; } diff --git a/src/guestfs.h b/src/guestfs.h index 3905554..bfa6b9c 100644 --- a/src/guestfs.h +++ b/src/guestfs.h @@ -53,11 +53,13 @@ extern void guestfs_free_lvm_vg_list (struct guestfs_lvm_vg_list *); extern void guestfs_free_lvm_lv_list (struct guestfs_lvm_lv_list *); /* Low-level event API. */ +typedef void (*guestfs_send_cb) (guestfs_h *g, void *data); typedef void (*guestfs_reply_cb) (guestfs_h *g, void *data, XDR *xdr); typedef void (*guestfs_log_message_cb) (guestfs_h *g, void *data, char *buf, int len); typedef void (*guestfs_subprocess_quit_cb) (guestfs_h *g, void *data); typedef void (*guestfs_launch_done_cb) (guestfs_h *g, void *data); +extern void guestfs_set_send_callback (guestfs_h *g, guestfs_send_cb cb, void *opaque); extern void guestfs_set_reply_callback (guestfs_h *g, guestfs_reply_cb cb, void *opaque); extern void guestfs_set_log_message_callback (guestfs_h *g, guestfs_log_message_cb cb, void *opaque); extern void guestfs_set_subprocess_quit_callback (guestfs_h *g, guestfs_subprocess_quit_cb cb, void *opaque); @@ -69,15 +71,20 @@ extern void guestfs_set_launch_done_callback (guestfs_h *g, guestfs_launch_done_ #define GUESTFS_HANDLE_HANGUP 0x4 #define GUESTFS_HANDLE_ERROR 0x8 -typedef void (*guestfs_handle_event_cb) (void *data, int watch, int fd, int events); -typedef int (*guestfs_add_handle_cb) (guestfs_h *g, int fd, int events, guestfs_handle_event_cb cb, void *data); -typedef int (*guestfs_remove_handle_cb) (guestfs_h *g, int watch); -typedef void (*guestfs_handle_timeout_cb) (void *data, int timer); -typedef int (*guestfs_add_timeout_cb) (guestfs_h *g, int interval, guestfs_handle_timeout_cb cb, void *data); -typedef int (*guestfs_remove_timeout_cb) (guestfs_h *g, int timer); -typedef void (*guestfs_main_loop_run_cb) (guestfs_h *g); -typedef void (*guestfs_main_loop_quit_cb) (guestfs_h *g); +struct guestfs_main_loop; +typedef void (*guestfs_handle_event_cb) (struct guestfs_main_loop *ml, guestfs_h *g, void *data, int watch, int fd, int events); +typedef int (*guestfs_add_handle_cb) (struct guestfs_main_loop *ml, guestfs_h *g, int fd, int events, guestfs_handle_event_cb cb, void *data); +typedef int (*guestfs_remove_handle_cb) (struct guestfs_main_loop *ml, guestfs_h *g, int watch); +typedef void (*guestfs_handle_timeout_cb) (struct guestfs_main_loop *ml, guestfs_h *g, void *data, int timer); +typedef int (*guestfs_add_timeout_cb) (struct guestfs_main_loop *ml, guestfs_h *g, int interval, guestfs_handle_timeout_cb cb, void *data); +typedef int (*guestfs_remove_timeout_cb) (struct guestfs_main_loop *ml, guestfs_h *g, int timer); +typedef int (*guestfs_main_loop_run_cb) (struct guestfs_main_loop *ml, guestfs_h *g); +typedef int (*guestfs_main_loop_quit_cb) (struct guestfs_main_loop *ml, guestfs_h *g); + +/* This is the head of the main loop structure. Concrete implementations + * use additional private data after this struct. + */ struct guestfs_main_loop { guestfs_add_handle_cb add_handle; guestfs_remove_handle_cb remove_handle; @@ -88,8 +95,11 @@ struct guestfs_main_loop { }; typedef struct guestfs_main_loop guestfs_main_loop; -extern void guestfs_set_main_loop (guestfs_main_loop *); -extern void guestfs_main_loop_run (void); -extern void guestfs_main_loop_quit (void); +extern void guestfs_set_main_loop (guestfs_h *handle, guestfs_main_loop *main_loop); +extern guestfs_main_loop *guestfs_get_main_loop (guestfs_h *handle); +extern guestfs_main_loop *guestfs_get_default_main_loop (void); + +extern guestfs_main_loop *guestfs_create_main_loop (void); +extern void guestfs_free_main_loop (guestfs_main_loop *); #endif /* GUESTFS_H_ */ diff --git a/src/guestfs_protocol.c b/src/guestfs_protocol.c index eb90d75..86a338f 100644 --- a/src/guestfs_protocol.c +++ b/src/guestfs_protocol.c @@ -1245,3 +1245,15 @@ xdr_guestfs_message_header (XDR *xdrs, guestfs_message_header *objp) return FALSE; return TRUE; } + +bool_t +xdr_guestfs_chunk (XDR *xdrs, guestfs_chunk *objp) +{ + register int32_t *buf; + + if (!xdr_int (xdrs, &objp->cancel)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, GUESTFS_MAX_CHUNK_SIZE)) + return FALSE; + return TRUE; +} diff --git a/src/guestfs_protocol.h b/src/guestfs_protocol.h index 822d960..c1837f8 100644 --- a/src/guestfs_protocol.h +++ b/src/guestfs_protocol.h @@ -682,7 +682,7 @@ enum guestfs_procedure { GUESTFS_PROC_BLOCKDEV_GETSIZE64 = 63, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS = 64, GUESTFS_PROC_BLOCKDEV_REREADPT = 65, - GUESTFS_PROC_dummy = 65 + 1, + GUESTFS_PROC_NR_PROCS = 65 + 1, }; typedef enum guestfs_procedure guestfs_procedure; #define GUESTFS_MESSAGE_MAX 4194304 @@ -716,6 +716,16 @@ struct guestfs_message_header { guestfs_message_status status; }; typedef struct guestfs_message_header guestfs_message_header; +#define GUESTFS_MAX_CHUNK_SIZE 8192 + +struct guestfs_chunk { + int cancel; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct guestfs_chunk guestfs_chunk; /* the xdr functions */ @@ -818,6 +828,7 @@ extern bool_t xdr_guestfs_message_direction (XDR *, guestfs_message_direction*) extern bool_t xdr_guestfs_message_status (XDR *, guestfs_message_status*); extern bool_t xdr_guestfs_message_error (XDR *, guestfs_message_error*); extern bool_t xdr_guestfs_message_header (XDR *, guestfs_message_header*); +extern bool_t xdr_guestfs_chunk (XDR *, guestfs_chunk*); #else /* K&R C */ extern bool_t xdr_str (); @@ -918,6 +929,7 @@ extern bool_t xdr_guestfs_message_direction (); extern bool_t xdr_guestfs_message_status (); extern bool_t xdr_guestfs_message_error (); extern bool_t xdr_guestfs_message_header (); +extern bool_t xdr_guestfs_chunk (); #endif /* K&R C */ diff --git a/src/guestfs_protocol.x b/src/guestfs_protocol.x index ba5d70c..d77bb5f 100644 --- a/src/guestfs_protocol.x +++ b/src/guestfs_protocol.x @@ -541,7 +541,7 @@ enum guestfs_procedure { GUESTFS_PROC_BLOCKDEV_GETSIZE64 = 63, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS = 64, GUESTFS_PROC_BLOCKDEV_REREADPT = 65, - GUESTFS_PROC_dummy + GUESTFS_PROC_NR_PROCS }; const GUESTFS_MESSAGE_MAX = 4194304; @@ -565,6 +565,19 @@ struct guestfs_message_error { string error; /* error message */ }; +/* For normal requests and replies (not involving any FileIn or + * FileOut parameters), the protocol is: + * + * For requests: + * total length (header + args, but not including length word itself) + * header + * guestfs_foo_args struct + * For replies: + * total length (as above) + * header + * guestfs_foo_ret struct + */ + struct guestfs_message_header { unsigned prog; /* GUESTFS_PROGRAM */ unsigned vers; /* GUESTFS_PROTOCOL_VERSION */ @@ -573,3 +586,28 @@ struct guestfs_message_header { unsigned serial; /* message serial number */ guestfs_message_status status; }; + +/* Chunked encoding used to transfer files, for FileIn and FileOut + * parameters. + * + * For requests which have >= 1 FileIn parameter: + * length of header + args (but not length word itself, and not chunks) + * header + * guestfs_foo_args struct + * sequence of chunks for FileIn param #0 + * sequence of chunks for FileIn param #1 etc + * + * For replies which have >= 1 FileOut parameter: + * length of header + ret (but not length word itself, and not chunks) + * header + * guestfs_foo_ret struct + * sequence of chunks for FileOut param #0 + * sequence of chunks for FileOut param #1 etc + */ +const GUESTFS_MAX_CHUNK_SIZE = 8192; + +struct guestfs_chunk { + int cancel; /* if non-zero, transfer is cancelled */ + /* data size is 0 bytes if the transfer has finished successfully */ + opaque data; +}; -- 1.8.3.1