X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Fproto.c;h=490dcfd7a6135d5b37d2593ec50dfac26f8e87ca;hb=913d5cd3a950a35f19581262250f58a871689d8c;hp=a5d9d2b84bf67e3a3eb3579ad1119d5bb05758c6;hpb=11be64049ba3ce36e1be297d2d6f54abca079742;p=libguestfs.git diff --git a/src/proto.c b/src/proto.c index a5d9d2b..490dcfd 100644 --- a/src/proto.c +++ b/src/proto.c @@ -404,8 +404,19 @@ guestfs___send_to_daemon (guestfs_h *g, const void *v_buf, size_t n) } if (FD_ISSET (g->sock, &rset2)) { r = check_for_daemon_cancellation_or_eof (g, g->sock); - if (r < 0) - return r; + if (r == -1) + return r; + if (r == -2) { + /* Daemon sent cancel message. But to maintain + * synchronization we must write out the remainder of the + * write buffer before we return (RHBZ#576879). + */ + if (xwrite (g->sock, buf, n) == -1) { + perrorf (g, "write"); + return -1; + } + return -2; /* cancelled */ + } } if (FD_ISSET (g->sock, &wset2)) { r = write (g->sock, buf, n); @@ -448,6 +459,25 @@ guestfs___send_to_daemon (guestfs_h *g, const void *v_buf, size_t n) * will not see GUESTFS_PROGRESS_FLAG. */ +static inline void +unexpected_end_of_file_from_daemon_error (guestfs_h *g) +{ +#define UNEXPEOF_ERROR "unexpected end of file when reading from daemon.\n" +#define UNEXPEOF_TEST_TOOL \ + "Or you can run 'libguestfs-test-tool' and post the complete output into\n" \ + "a bug report or message to the libguestfs mailing list." + if (!g->verbose) + error (g, _(UNEXPEOF_ERROR +"This usually means the libguestfs appliance failed to start up. Please\n" +"enable debugging (LIBGUESTFS_DEBUG=1) and rerun the command, then look at\n" +"the debug messages output prior to this error.\n" +UNEXPEOF_TEST_TOOL)); + else + error (g, _(UNEXPEOF_ERROR +"See earlier debug messages.\n" +UNEXPEOF_TEST_TOOL)); +} + int guestfs___recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void **buf_rtn) { @@ -516,7 +546,7 @@ guestfs___recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void **buf_rtn) return -1; } if (r == 0) { - error (g, _("unexpected end of file when reading from daemon")); + unexpected_end_of_file_from_daemon_error (g); child_cleanup (g); return -1; } @@ -577,7 +607,7 @@ guestfs___recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void **buf_rtn) return -1; } if (r == 0) { - error (g, _("unexpected end of file when reading from daemon")); + unexpected_end_of_file_from_daemon_error (g); child_cleanup (g); free (*buf_rtn); *buf_rtn = NULL; @@ -693,7 +723,8 @@ guestfs___accept_from_daemon (guestfs_h *g) } int -guestfs___send (guestfs_h *g, int proc_nr, uint64_t progress_hint, +guestfs___send (guestfs_h *g, int proc_nr, + uint64_t progress_hint, uint64_t optargs_bitmask, xdrproc_t xdrp, char *args) { struct guestfs_message_header hdr; @@ -726,7 +757,7 @@ guestfs___send (guestfs_h *g, int proc_nr, uint64_t progress_hint, hdr.serial = serial; hdr.status = GUESTFS_STATUS_OK; hdr.progress_hint = progress_hint; - hdr.optargs_bitmask = 0; + hdr.optargs_bitmask = optargs_bitmask; if (!xdr_guestfs_message_header (&xdr, &hdr)) { error (g, _("xdr_guestfs_message_header failed")); @@ -792,9 +823,6 @@ guestfs___send_file (guestfs_h *g, const char *filename) 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; } @@ -979,6 +1007,34 @@ guestfs___recv (guestfs_h *g, const char *fn, return 0; } +/* Same as guestfs___recv, but it discards the reply message. */ +int +guestfs___recv_discard (guestfs_h *g, const char *fn) +{ + void *buf; + uint32_t size; + int r; + + again: + r = guestfs___recv_from_daemon (g, &size, &buf); + if (r == -1) + return -1; + + /* This can happen if a cancellation happens right at the end + * of us sending a FileIn parameter to the daemon. Discard. The + * daemon should send us an error message next. + */ + if (size == GUESTFS_CANCEL_FLAG) + goto again; + + if (size == GUESTFS_LAUNCH_FLAG) { + error (g, "%s: received unexpected launch flag from daemon when expecting reply", fn); + return -1; + } + + return 0; +} + /* Receive a file. */ /* Returns -1 = error, 0 = EOF, > 0 = more data */