From: Richard W.M. Jones Date: Fri, 1 May 2009 10:47:31 +0000 (+0100) Subject: Generated code for ping-daemon command. X-Git-Tag: 1.0.18~3 X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=commitdiff_plain;h=8c3b820c2b687345448e3d74a7101b07ff32688e Generated code for ping-daemon command. --- diff --git a/daemon/actions.h b/daemon/actions.h index dbc2bbd..2dc8537 100644 --- a/daemon/actions.h +++ b/daemon/actions.h @@ -112,3 +112,4 @@ extern int do_cp_a (const char *src, const char *dest); extern int do_mv (const char *src, const char *dest); extern int do_drop_caches (int whattodrop); extern char *do_dmesg (void); +extern int do_ping_daemon (void); diff --git a/daemon/stubs.c b/daemon/stubs.c index c21eecf..f992bdf 100644 --- a/daemon/stubs.c +++ b/daemon/stubs.c @@ -2271,6 +2271,19 @@ static void dmesg_stub (XDR *xdr_in) done: ; } +static void ping_daemon_stub (XDR *xdr_in) +{ + int r; + + r = do_ping_daemon (); + if (r == -1) + /* do_ping_daemon has already called reply_with_error */ + goto done; + + reply (NULL, NULL); +done: ; +} + void dispatch_incoming_message (XDR *xdr_in) { switch (proc_nr) { @@ -2547,6 +2560,9 @@ void dispatch_incoming_message (XDR *xdr_in) case GUESTFS_PROC_DMESG: dmesg_stub (xdr_in); break; + case GUESTFS_PROC_PING_DAEMON: + ping_daemon_stub (xdr_in); + break; default: reply_with_error ("dispatch_incoming_message: unknown procedure number %d", proc_nr); } diff --git a/fish/cmds.c b/fish/cmds.c index 561018a..7264e7d 100644 --- a/fish/cmds.c +++ b/fish/cmds.c @@ -107,6 +107,7 @@ void list_commands (void) printf ("%-20s %s\n", "mount-vfs", "mount a guest disk with mount options and vfstype"); printf ("%-20s %s\n", "mounts", "show mounted filesystems"); printf ("%-20s %s\n", "mv", "move a file"); + printf ("%-20s %s\n", "ping-daemon", "ping the guest daemon"); printf ("%-20s %s\n", "pvcreate", "create an LVM physical volume"); printf ("%-20s %s\n", "pvremove", "remove an LVM physical volume"); printf ("%-20s %s\n", "pvs", "list the LVM physical volumes (PVs)"); @@ -472,6 +473,9 @@ void display_command (const char *cmd) if (strcasecmp (cmd, "dmesg") == 0) pod2text ("dmesg - return kernel messages", " dmesg\n\nThis returns the kernel messages (C output) from\nthe guest kernel. This is sometimes useful for extended\ndebugging of problems.\n\nAnother way to get the same information is to enable\nverbose messages with C or by setting\nthe environment variable C before\nrunning the program."); else + if (strcasecmp (cmd, "ping_daemon") == 0 || strcasecmp (cmd, "ping-daemon") == 0) + pod2text ("ping-daemon - ping the guest daemon", " ping-daemon\n\nThis is a test probe into the guestfs daemon running inside\nthe qemu subprocess. Calling this function checks that the\ndaemon responds to the ping message, without affecting the daemon\nor attached block device(s) in any other way."); + else display_builtin_command (cmd); } @@ -2299,6 +2303,18 @@ static int run_dmesg (const char *cmd, int argc, char *argv[]) return 0; } +static int run_ping_daemon (const char *cmd, int argc, char *argv[]) +{ + int r; + if (argc != 0) { + fprintf (stderr, "%s should have 0 parameter(s)\n", cmd); + fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd); + return -1; + } + r = guestfs_ping_daemon (g); + return r; +} + int run_action (const char *cmd, int argc, char *argv[]) { if (strcasecmp (cmd, "launch") == 0 || strcasecmp (cmd, "run") == 0) @@ -2628,6 +2644,9 @@ int run_action (const char *cmd, int argc, char *argv[]) if (strcasecmp (cmd, "dmesg") == 0) return run_dmesg (cmd, argc, argv); else + if (strcasecmp (cmd, "ping_daemon") == 0 || strcasecmp (cmd, "ping-daemon") == 0) + return run_ping_daemon (cmd, argc, argv); + else { fprintf (stderr, "%s: unknown command\n", cmd); return -1; diff --git a/fish/completion.c b/fish/completion.c index f1abc0b..095a335 100644 --- a/fish/completion.c +++ b/fish/completion.c @@ -114,6 +114,7 @@ static const char *const commands[] = { "mounts", "mv", "path", + "ping-daemon", "pvcreate", "pvremove", "pvs", diff --git a/guestfish-actions.pod b/guestfish-actions.pod index d04a663..2d9c5e8 100644 --- a/guestfish-actions.pod +++ b/guestfish-actions.pod @@ -833,6 +833,15 @@ Some internal mounts are not shown. This moves a file from C to C where C is either a destination filename or destination directory. +=head2 ping-daemon + + ping-daemon + +This is a test probe into the guestfs daemon running inside +the qemu subprocess. Calling this function checks that the +daemon responds to the ping message, without affecting the daemon +or attached block device(s) in any other way. + =head2 pvcreate pvcreate device diff --git a/guestfs-actions.pod b/guestfs-actions.pod index f1b5964..9d094c9 100644 --- a/guestfs-actions.pod +++ b/guestfs-actions.pod @@ -1105,6 +1105,17 @@ either a destination filename or destination directory. This function returns 0 on success or -1 on error. +=head2 guestfs_ping_daemon + + int guestfs_ping_daemon (guestfs_h *handle); + +This is a test probe into the guestfs daemon running inside +the qemu subprocess. Calling this function checks that the +daemon responds to the ping message, without affecting the daemon +or attached block device(s) in any other way. + +This function returns 0 on success or -1 on error. + =head2 guestfs_pvcreate int guestfs_pvcreate (guestfs_h *handle, diff --git a/java/com/redhat/et/libguestfs/GuestFS.java b/java/com/redhat/et/libguestfs/GuestFS.java index f56ae41..5ae2b10 100644 --- a/java/com/redhat/et/libguestfs/GuestFS.java +++ b/java/com/redhat/et/libguestfs/GuestFS.java @@ -2536,4 +2536,25 @@ public class GuestFS { private native String _dmesg (long g) throws LibGuestFSException; + /** + * ping the guest daemon + * + * This is a test probe into the guestfs daemon running + * inside the qemu subprocess. Calling this function checks + * that the daemon responds to the ping message, without + * affecting the daemon or attached block device(s) in any + * other way. + * + * @throws LibGuestFSException + */ + public void ping_daemon () + throws LibGuestFSException + { + if (g == 0) + throw new LibGuestFSException ("ping_daemon: handle is closed"); + _ping_daemon (g); + } + private native void _ping_daemon (long g) + throws LibGuestFSException; + } diff --git a/java/com_redhat_et_libguestfs_GuestFS.c b/java/com_redhat_et_libguestfs_GuestFS.c index 323402d..b689a6c 100644 --- a/java/com_redhat_et_libguestfs_GuestFS.c +++ b/java/com_redhat_et_libguestfs_GuestFS.c @@ -2551,3 +2551,17 @@ Java_com_redhat_et_libguestfs_GuestFS__1dmesg return jr; } +JNIEXPORT void JNICALL +Java_com_redhat_et_libguestfs_GuestFS__1ping_1daemon + (JNIEnv *env, jobject obj, jlong jg) +{ + guestfs_h *g = (guestfs_h *) (long) jg; + int r; + + r = guestfs_ping_daemon (g); + if (r == -1) { + throw_exception (env, guestfs_last_error (g)); + return ; + } +} + diff --git a/ocaml/guestfs.ml b/ocaml/guestfs.ml index 80e1d39..e4916b0 100644 --- a/ocaml/guestfs.ml +++ b/ocaml/guestfs.ml @@ -227,3 +227,4 @@ external cp_a : t -> string -> string -> unit = "ocaml_guestfs_cp_a" external mv : t -> string -> string -> unit = "ocaml_guestfs_mv" external drop_caches : t -> int -> unit = "ocaml_guestfs_drop_caches" external dmesg : t -> string = "ocaml_guestfs_dmesg" +external ping_daemon : t -> unit = "ocaml_guestfs_ping_daemon" diff --git a/ocaml/guestfs.mli b/ocaml/guestfs.mli index 810c49a..125fa97 100644 --- a/ocaml/guestfs.mli +++ b/ocaml/guestfs.mli @@ -460,3 +460,6 @@ val drop_caches : t -> int -> unit val dmesg : t -> string (** return kernel messages *) +val ping_daemon : t -> unit +(** ping the guest daemon *) + diff --git a/ocaml/guestfs_c_actions.c b/ocaml/guestfs_c_actions.c index 20cb327..a640e0f 100644 --- a/ocaml/guestfs_c_actions.c +++ b/ocaml/guestfs_c_actions.c @@ -2988,3 +2988,25 @@ ocaml_guestfs_dmesg (value gv) CAMLreturn (rv); } +CAMLprim value +ocaml_guestfs_ping_daemon (value gv) +{ + CAMLparam1 (gv); + CAMLlocal1 (rv); + + guestfs_h *g = Guestfs_val (gv); + if (g == NULL) + caml_failwith ("ping_daemon: used handle after closing it"); + + int r; + + caml_enter_blocking_section (); + r = guestfs_ping_daemon (g); + caml_leave_blocking_section (); + if (r == -1) + ocaml_guestfs_raise_error (g, "ping_daemon"); + + rv = Val_unit; + CAMLreturn (rv); +} + diff --git a/perl/Guestfs.xs b/perl/Guestfs.xs index ed8e670..af543ec 100644 --- a/perl/Guestfs.xs +++ b/perl/Guestfs.xs @@ -1672,3 +1672,13 @@ PREINIT: OUTPUT: RETVAL +void +ping_daemon (g) + guestfs_h *g; +PREINIT: + int r; + PPCODE: + r = guestfs_ping_daemon (g); + if (r == -1) + croak ("ping_daemon: %s", guestfs_last_error (g)); + diff --git a/perl/lib/Sys/Guestfs.pm b/perl/lib/Sys/Guestfs.pm index 01d81a6..a13c441 100644 --- a/perl/lib/Sys/Guestfs.pm +++ b/perl/lib/Sys/Guestfs.pm @@ -772,6 +772,13 @@ Some internal mounts are not shown. This moves a file from C to C where C is either a destination filename or destination directory. +=item $h->ping_daemon (); + +This is a test probe into the guestfs daemon running inside +the qemu subprocess. Calling this function checks that the +daemon responds to the ping message, without affecting the daemon +or attached block device(s) in any other way. + =item $h->pvcreate ($device); This creates an LVM physical volume on the named C, diff --git a/python/guestfs-py.c b/python/guestfs-py.c index dd9f4ca..6a807e3 100644 --- a/python/guestfs-py.c +++ b/python/guestfs-py.c @@ -3205,6 +3205,30 @@ py_guestfs_dmesg (PyObject *self, PyObject *args) return py_r; } +static PyObject * +py_guestfs_ping_daemon (PyObject *self, PyObject *args) +{ + PyObject *py_g; + guestfs_h *g; + PyObject *py_r; + int r; + + if (!PyArg_ParseTuple (args, (char *) "O:guestfs_ping_daemon", + &py_g)) + return NULL; + g = get_handle (py_g); + + r = guestfs_ping_daemon (g); + if (r == -1) { + PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g)); + return NULL; + } + + Py_INCREF (Py_None); + py_r = Py_None; + return py_r; +} + static PyMethodDef methods[] = { { (char *) "create", py_guestfs_create, METH_VARARGS, NULL }, { (char *) "close", py_guestfs_close, METH_VARARGS, NULL }, @@ -3320,6 +3344,7 @@ static PyMethodDef methods[] = { { (char *) "mv", py_guestfs_mv, METH_VARARGS, NULL }, { (char *) "drop_caches", py_guestfs_drop_caches, METH_VARARGS, NULL }, { (char *) "dmesg", py_guestfs_dmesg, METH_VARARGS, NULL }, + { (char *) "ping_daemon", py_guestfs_ping_daemon, METH_VARARGS, NULL }, { NULL, NULL, 0, NULL } }; diff --git a/python/guestfs.py b/python/guestfs.py index e298922..1596bcd 100644 --- a/python/guestfs.py +++ b/python/guestfs.py @@ -1233,3 +1233,12 @@ class GuestFS: """ return libguestfsmod.dmesg (self._o) + def ping_daemon (self): + u"""This is a test probe into the guestfs daemon running + inside the qemu subprocess. Calling this function checks + that the daemon responds to the ping message, without + affecting the daemon or attached block device(s) in any + other way. + """ + return libguestfsmod.ping_daemon (self._o) + diff --git a/ruby/ext/guestfs/_guestfs.c b/ruby/ext/guestfs/_guestfs.c index c0fc180..eed0b80 100644 --- a/ruby/ext/guestfs/_guestfs.c +++ b/ruby/ext/guestfs/_guestfs.c @@ -2698,6 +2698,23 @@ static VALUE ruby_guestfs_dmesg (VALUE gv) return rv; } +static VALUE ruby_guestfs_ping_daemon (VALUE gv) +{ + guestfs_h *g; + Data_Get_Struct (gv, guestfs_h, g); + if (!g) + rb_raise (rb_eArgError, "%s: used handle after closing it", "ping_daemon"); + + + int r; + + r = guestfs_ping_daemon (g); + if (r == -1) + rb_raise (e_Error, "%s", guestfs_last_error (g)); + + return Qnil; +} + /* Initialize the module. */ void Init__guestfs () { @@ -2932,4 +2949,6 @@ void Init__guestfs () ruby_guestfs_drop_caches, 1); rb_define_method (c_guestfs, "dmesg", ruby_guestfs_dmesg, 0); + rb_define_method (c_guestfs, "ping_daemon", + ruby_guestfs_ping_daemon, 0); } diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c index 94963ff..c0762df 100644 --- a/src/guestfs-actions.c +++ b/src/guestfs-actions.c @@ -8253,3 +8253,85 @@ char *guestfs_dmesg (guestfs_h *g) return ctx.ret.kmsgs; /* caller will free */ } +struct ping_daemon_ctx { + /* This flag is set by the callbacks, so we know we've done + * the callbacks as expected, and in the right sequence. + * 0 = not called, 1 = reply_cb called. + */ + int cb_sequence; + struct guestfs_message_header hdr; + struct guestfs_message_error err; +}; + +static void ping_daemon_reply_cb (guestfs_h *g, void *data, XDR *xdr) +{ + guestfs_main_loop *ml = guestfs_get_main_loop (g); + struct ping_daemon_ctx *ctx = (struct ping_daemon_ctx *) data; + + /* This should definitely not happen. */ + if (ctx->cb_sequence != 0) { + ctx->cb_sequence = 9999; + error (g, "%s: internal error: reply callback called twice", "guestfs_ping_daemon"); + return; + } + + ml->main_loop_quit (ml, g); + + if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) { + error (g, "%s: failed to parse reply header", "guestfs_ping_daemon"); + return; + } + if (ctx->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &ctx->err)) { + error (g, "%s: failed to parse reply error", "guestfs_ping_daemon"); + return; + } + goto done; + } + done: + ctx->cb_sequence = 1; +} + +int guestfs_ping_daemon (guestfs_h *g) +{ + struct ping_daemon_ctx ctx; + guestfs_main_loop *ml = guestfs_get_main_loop (g); + int serial; + + if (check_state (g, "guestfs_ping_daemon") == -1) return -1; + guestfs_set_busy (g); + + memset (&ctx, 0, sizeof ctx); + + serial = guestfs__send_sync (g, GUESTFS_PROC_PING_DAEMON, NULL, NULL); + if (serial == -1) { + guestfs_set_ready (g); + return -1; + } + + guestfs__switch_to_receiving (g); + ctx.cb_sequence = 0; + guestfs_set_reply_callback (g, ping_daemon_reply_cb, &ctx); + (void) ml->main_loop_run (ml, g); + guestfs_set_reply_callback (g, NULL, NULL); + if (ctx.cb_sequence != 1) { + error (g, "%s reply failed, see earlier error messages", "guestfs_ping_daemon"); + guestfs_set_ready (g); + return -1; + } + + if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PING_DAEMON, serial) == -1) { + guestfs_set_ready (g); + return -1; + } + + if (ctx.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", ctx.err.error_message); + guestfs_set_ready (g); + return -1; + } + + guestfs_set_ready (g); + return 0; +} + diff --git a/src/guestfs-actions.h b/src/guestfs-actions.h index b14840c..f2218f4 100644 --- a/src/guestfs-actions.h +++ b/src/guestfs-actions.h @@ -131,3 +131,4 @@ extern int guestfs_cp_a (guestfs_h *handle, const char *src, const char *dest); extern int guestfs_mv (guestfs_h *handle, const char *src, const char *dest); extern int guestfs_drop_caches (guestfs_h *handle, int whattodrop); extern char *guestfs_dmesg (guestfs_h *handle); +extern int guestfs_ping_daemon (guestfs_h *handle); diff --git a/src/guestfs_protocol.h b/src/guestfs_protocol.h index 40c84ee..e472524 100644 --- a/src/guestfs_protocol.h +++ b/src/guestfs_protocol.h @@ -881,7 +881,8 @@ enum guestfs_procedure { GUESTFS_PROC_MV = 89, GUESTFS_PROC_DROP_CACHES = 90, GUESTFS_PROC_DMESG = 91, - GUESTFS_PROC_NR_PROCS = 91 + 1, + GUESTFS_PROC_PING_DAEMON = 92, + GUESTFS_PROC_NR_PROCS = 92 + 1, }; typedef enum guestfs_procedure guestfs_procedure; #define GUESTFS_MESSAGE_MAX 4194304 diff --git a/src/guestfs_protocol.x b/src/guestfs_protocol.x index 4bf42be..e61d3fb 100644 --- a/src/guestfs_protocol.x +++ b/src/guestfs_protocol.x @@ -706,6 +706,7 @@ enum guestfs_procedure { GUESTFS_PROC_MV = 89, GUESTFS_PROC_DROP_CACHES = 90, GUESTFS_PROC_DMESG = 91, + GUESTFS_PROC_PING_DAEMON = 92, GUESTFS_PROC_NR_PROCS }; diff --git a/tests.c b/tests.c index e494d9c..3adf389 100644 --- a/tests.c +++ b/tests.c @@ -112,6 +112,34 @@ static void no_test_warnings (void) fprintf (stderr, "warning: \"guestfs_get_e2uuid\" has no tests\n"); } +static int test_ping_daemon_0 (void) +{ + /* InitEmpty for ping_daemon (0) */ + { + int r; + suppress_error = 0; + r = guestfs_umount_all (g); + if (r == -1) + return -1; + } + { + int r; + suppress_error = 0; + r = guestfs_lvm_remove_all (g); + if (r == -1) + return -1; + } + /* TestRun for ping_daemon (0) */ + { + int r; + suppress_error = 0; + r = guestfs_ping_daemon (g); + if (r == -1) + return -1; + } + return 0; +} + static int test_dmesg_0 (void) { /* InitEmpty for dmesg (0) */ @@ -7292,9 +7320,15 @@ int main (int argc, char *argv[]) exit (1); } - nr_tests = 103; + nr_tests = 104; test_num++; + printf ("%3d/%3d test_ping_daemon_0\n", test_num, nr_tests); + if (test_ping_daemon_0 () == -1) { + printf ("test_ping_daemon_0 FAILED\n"); + failed++; + } + test_num++; printf ("%3d/%3d test_dmesg_0\n", test_num, nr_tests); if (test_dmesg_0 () == -1) { printf ("test_dmesg_0 FAILED\n");