regressions: Enable both tests for bug 576879 (not fixed).
[libguestfs.git] / generator / generator_xdr.ml
1 (* libguestfs
2  * Copyright (C) 2009-2010 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  *)
18
19 (* Please read generator/README first. *)
20
21 open Printf
22
23 open Generator_types
24 open Generator_utils
25 open Generator_pr
26 open Generator_docstrings
27 open Generator_optgroups
28 open Generator_actions
29 open Generator_structs
30
31 (* Generate the protocol (XDR) file, 'guestfs_protocol.x' and
32  * indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'.
33  *
34  * We have to use an underscore instead of a dash because otherwise
35  * rpcgen generates incorrect code.
36  *
37  * This header is NOT exported to clients, but see also generate_structs_h.
38  *)
39 let generate_xdr () =
40   generate_header CStyle LGPLv2plus;
41
42   (* This has to be defined to get around a limitation in Sun's rpcgen. *)
43   pr "typedef string guestfs_str<>;\n";
44   pr "\n";
45
46   (* Internal structures. *)
47   List.iter (
48     function
49     | typ, cols ->
50         pr "struct guestfs_int_%s {\n" typ;
51         List.iter (function
52                    | name, FChar -> pr "  char %s;\n" name
53                    | name, FString -> pr "  string %s<>;\n" name
54                    | name, FBuffer -> pr "  opaque %s<>;\n" name
55                    | name, FUUID -> pr "  opaque %s[32];\n" name
56                    | name, (FInt32|FUInt32) -> pr "  int %s;\n" name
57                    | name, (FInt64|FUInt64|FBytes) -> pr "  hyper %s;\n" name
58                    | name, FOptPercent -> pr "  float %s;\n" name
59                   ) cols;
60         pr "};\n";
61         pr "\n";
62         pr "typedef struct guestfs_int_%s guestfs_int_%s_list<>;\n" typ typ;
63         pr "\n";
64   ) structs;
65
66   List.iter (
67     fun (shortname, (ret, args, optargs), _, _, _, _, _) ->
68       let name = "guestfs_" ^ shortname in
69
70       (* Ordinary arguments and optional arguments are concatenated
71        * together in the XDR args struct.  The optargs_bitmask field
72        * in the header controls which optional arguments are
73        * meaningful.
74        *)
75       (match args @ optargs with
76        | [] -> ()
77        | args ->
78            pr "struct %s_args {\n" name;
79            List.iter (
80              function
81              | Pathname n | Device n | Dev_or_Path n | String n | Key n ->
82                  pr "  string %s<>;\n" n
83              | OptString n -> pr "  guestfs_str *%s;\n" n
84              | StringList n | DeviceList n -> pr "  guestfs_str %s<>;\n" n
85              | Bool n -> pr "  bool %s;\n" n
86              | Int n -> pr "  int %s;\n" n
87              | Int64 n -> pr "  hyper %s;\n" n
88              | BufferIn n ->
89                  pr "  opaque %s<>;\n" n
90              | FileIn _ | FileOut _ -> ()
91              | Pointer _ -> assert false
92            ) args;
93            pr "};\n\n"
94       );
95       (match ret with
96        | RErr -> ()
97        | RInt n ->
98            pr "struct %s_ret {\n" name;
99            pr "  int %s;\n" n;
100            pr "};\n\n"
101        | RInt64 n ->
102            pr "struct %s_ret {\n" name;
103            pr "  hyper %s;\n" n;
104            pr "};\n\n"
105        | RBool n ->
106            pr "struct %s_ret {\n" name;
107            pr "  bool %s;\n" n;
108            pr "};\n\n"
109        | RConstString _ | RConstOptString _ ->
110            failwithf "RConstString|RConstOptString cannot be used by daemon functions"
111        | RString n ->
112            pr "struct %s_ret {\n" name;
113            pr "  string %s<>;\n" n;
114            pr "};\n\n"
115        | RStringList n ->
116            pr "struct %s_ret {\n" name;
117            pr "  guestfs_str %s<>;\n" n;
118            pr "};\n\n"
119        | RStruct (n, typ) ->
120            pr "struct %s_ret {\n" name;
121            pr "  guestfs_int_%s %s;\n" typ n;
122            pr "};\n\n"
123        | RStructList (n, typ) ->
124            pr "struct %s_ret {\n" name;
125            pr "  guestfs_int_%s_list %s;\n" typ n;
126            pr "};\n\n"
127        | RHashtable n ->
128            pr "struct %s_ret {\n" name;
129            pr "  guestfs_str %s<>;\n" n;
130            pr "};\n\n"
131        | RBufferOut n ->
132            pr "struct %s_ret {\n" name;
133            pr "  opaque %s<>;\n" n;
134            pr "};\n\n"
135       );
136   ) daemon_functions;
137
138   (* Table of procedure numbers. *)
139   pr "enum guestfs_procedure {\n";
140   List.iter (
141     fun (shortname, _, proc_nr, _, _, _, _) ->
142       pr "  GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr
143   ) daemon_functions;
144   pr "  GUESTFS_PROC_NR_PROCS\n";
145   pr "};\n";
146   pr "\n";
147
148   (* Having to choose a maximum message size is annoying for several
149    * reasons (it limits what we can do in the API), but it (a) makes
150    * the protocol a lot simpler, and (b) provides a bound on the size
151    * of the daemon which operates in limited memory space.
152    *)
153   pr "const GUESTFS_MESSAGE_MAX = %d;\n" (4 * 1024 * 1024);
154   pr "\n";
155
156   (* Message header, etc. *)
157   pr "\
158 /* The communication protocol is now documented in the guestfs(3)
159  * manpage.
160  */
161
162 const GUESTFS_PROGRAM = 0x2000F5F5;
163 const GUESTFS_PROTOCOL_VERSION = 4;
164
165 /* These constants must be larger than any possible message length. */
166 const GUESTFS_LAUNCH_FLAG = 0xf5f55ff5;
167 const GUESTFS_CANCEL_FLAG = 0xffffeeee;
168 const GUESTFS_PROGRESS_FLAG = 0xffff5555;
169
170 enum guestfs_message_direction {
171   GUESTFS_DIRECTION_CALL = 0,        /* client -> daemon */
172   GUESTFS_DIRECTION_REPLY = 1        /* daemon -> client */
173 };
174
175 enum guestfs_message_status {
176   GUESTFS_STATUS_OK = 0,
177   GUESTFS_STATUS_ERROR = 1
178 };
179
180 ";
181
182   pr "const GUESTFS_ERROR_LEN = %d;\n" (64 * 1024);
183   pr "\n";
184
185   pr "\
186 struct guestfs_message_error {
187   string errno_string<32>;           /* errno eg. \"EINVAL\", empty string
188                                         if errno not available */
189   string error_message<GUESTFS_ERROR_LEN>;
190 };
191
192 struct guestfs_message_header {
193   unsigned prog;                     /* GUESTFS_PROGRAM */
194   unsigned vers;                     /* GUESTFS_PROTOCOL_VERSION */
195   guestfs_procedure proc;            /* GUESTFS_PROC_x */
196   guestfs_message_direction direction;
197   unsigned serial;                   /* message serial number */
198   unsigned hyper progress_hint;      /* upload hint for progress bar */
199   unsigned hyper optargs_bitmask;    /* bitmask for optional args */
200   guestfs_message_status status;
201 };
202
203 const GUESTFS_MAX_CHUNK_SIZE = 8192;
204
205 struct guestfs_chunk {
206   int cancel;                        /* if non-zero, transfer is cancelled */
207   /* data size is 0 bytes if the transfer has finished successfully */
208   opaque data<GUESTFS_MAX_CHUNK_SIZE>;
209 };
210
211 /* Progress notifications.  Daemon self-limits these messages to
212  * at most one per second.  The daemon can send these messages
213  * at any time, and the caller should discard unexpected messages.
214  * 'position' and 'total' have undefined units; however they may
215  * have meaning for some calls.
216  *
217  * NB. guestfs___recv_from_daemon assumes the XDR-encoded
218  * structure is 24 bytes long.
219  */
220 struct guestfs_progress {
221   guestfs_procedure proc;            /* @0:  GUESTFS_PROC_x */
222   unsigned serial;                   /* @4:  message serial number */
223   unsigned hyper position;           /* @8:  0 <= position <= total */
224   unsigned hyper total;              /* @16: total size of operation */
225                                      /* @24: size of structure */
226 };
227 "