X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Fgenerator.ml;h=5868e170a6ae50e0edfce0c0c7c176b7bcc0aeb1;hb=b72ec21d24824720385c9cd024b7f1eae734f4a4;hp=8588cf3146f9c015dcd5e2f79d088d5b2937ec74;hpb=40ca9a57829f2e82362e391d7d998bf33c8bd671;p=libguestfs.git diff --git a/src/generator.ml b/src/generator.ml index 8588cf3..5868e17 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -53,7 +53,13 @@ names can be used. The rules are the same as for L: A filesystem must first be mounted on C before others can be mounted. Other filesystems can only be mounted on directories which already -exist."); +exist. + +The mounted filesystem is writable, if we have sufficient permissions +on the underlying device. + +The filesystem options C and C are set with this +call, in order to improve reliability."); ("sync", (Err, P0), 2, "Sync disks, writes are flushed through to the disk image", @@ -208,6 +214,12 @@ enum guestfs_message_status { GUESTFS_STATUS_ERROR = 1 }; +const GUESTFS_ERROR_LEN = 256; + +struct guestfs_message_error { + string error; /* error message */ +}; + struct guestfs_message_header { unsigned prog; /* GUESTFS_PROGRAM */ unsigned vers; /* GUESTFS_PROTOCOL_VERSION */ @@ -237,9 +249,9 @@ and generate_client_actions () = (* Generate the return value struct. *) pr "struct %s_rv {\n" shortname; - pr " int err_code; /* 0 OK or -1 error */\n"; - pr " int serial; /* serial number of reply */\n"; - pr " char err_str[256]; /* error from daemon */\n"; + pr " int cb_done; /* flag to indicate callback was called */\n"; + pr " struct guestfs_message_header hdr;\n"; + pr " struct guestfs_message_error err;\n"; (match style with | (Err, _) -> () (* | _ -> pr " struct %s_ret ret;\n" name; *) @@ -251,8 +263,25 @@ and generate_client_actions () = pr "{\n"; pr " struct %s_rv *rv = (struct %s_rv *) data;\n" shortname shortname; pr "\n"; - pr " /* XXX */ rv->err_code = 0;\n"; - pr " /* XXX rv->serial = ?; */\n"; + pr " if (!xdr_guestfs_message_header (xdr, &rv->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 " error (g, \"%s: failed to parse reply error\");\n" name; + pr " return;\n"; + pr " }\n"; + pr " goto done;\n"; + pr " }\n"; + + (match style with + | (Err, _) -> () + (* | _ -> pr " if (!xdr_%s_ret (&xdr, &rv->ret)) ..." *) + ); + + pr " done:\n"; + pr " rv->cb_done = 1;\n"; pr " main_loop.main_loop_quit (g);\n"; pr "}\n\n"; @@ -280,13 +309,15 @@ and generate_client_actions () = pr " g->state);\n"; pr " return %s;\n" error_code; pr " }\n"; + pr "\n"; + pr " memset (&rv, 0, sizeof rv);\n"; + pr "\n"; (match style with | (_, P0) -> pr " serial = dispatch (g, GUESTFS_PROC_%s, NULL, NULL);\n" (String.uppercase shortname) | (_, args) -> - pr "\n"; iter_args ( function | String name -> pr " args.%s = (char *) %s;\n" name name @@ -300,23 +331,28 @@ and generate_client_actions () = pr " return %s;\n" error_code; pr "\n"; - pr " rv.err_code = 42;\n"; + pr " rv.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 = NULL;\n"; pr " g->reply_cb_internal_data = NULL;\n"; - pr " if (rv.err_code == 42) { /* callback wasn't called */\n"; + pr " if (!rv.cb_done) {\n"; pr " error (g, \"%s failed, see earlier error messages\");\n" name; pr " return %s;\n" error_code; pr " }\n"; - pr " else if (rv.err_code == -1) { /* error from remote end */\n"; - pr " error (g, \"%%s\", rv.err_str);\n"; + pr "\n"; + + pr " if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_%s, serial) == -1)\n" + (String.uppercase shortname); pr " return %s;\n" error_code; - pr " }\n"; pr "\n"; - pr " /* XXX check serial number agrees */\n\n"; + pr " if (rv.hdr.status == GUESTFS_STATUS_ERROR) {\n"; + pr " error (g, \"%%s\", rv.err.error);\n"; + pr " return %s;\n" error_code; + pr " }\n"; + pr "\n"; (match style with | (Err, _) -> pr " return 0;\n" @@ -366,6 +402,8 @@ and generate_daemon_actions () = (match style with | (_, P0) -> () | (_, args) -> + pr " memset (&args, 0, sizeof args);\n"; + pr "\n"; pr " if (!xdr_guestfs_%s_args (xdr_in, &args)) {\n" name; pr " reply_with_error (\"%s: daemon failed to decode procedure arguments\");\n" name; pr " return;\n";