2 * Copyright (C) 2009-2011 Red Hat Inc.
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.
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.
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
19 (* Please read generator/README first. *)
26 open Generator_docstrings
27 open Generator_optgroups
28 open Generator_actions
29 open Generator_structs
31 (* Generate the protocol (XDR) file, 'guestfs_protocol.x' and
32 * indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'.
34 * We have to use an underscore instead of a dash because otherwise
35 * rpcgen generates incorrect code.
37 * This header is NOT exported to clients, but see also generate_structs_h.
40 generate_header CStyle LGPLv2plus;
42 (* This has to be defined to get around a limitation in Sun's rpcgen. *)
43 pr "typedef string guestfs_str<>;\n";
46 (* Internal structures. *)
50 pr "struct guestfs_int_%s {\n" typ;
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
62 pr "typedef struct guestfs_int_%s guestfs_int_%s_list<>;\n" typ typ;
67 fun (shortname, (ret, args, optargs), _, _, _, _, _) ->
68 let name = "guestfs_" ^ shortname in
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
75 (match args @ optargs with
78 pr "struct %s_args {\n" name;
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
89 pr " opaque %s<>;\n" n
90 | FileIn _ | FileOut _ -> ()
91 | Pointer _ -> assert false
98 pr "struct %s_ret {\n" name;
102 pr "struct %s_ret {\n" name;
106 pr "struct %s_ret {\n" name;
109 | RConstString _ | RConstOptString _ ->
110 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
112 pr "struct %s_ret {\n" name;
113 pr " string %s<>;\n" n;
116 pr "struct %s_ret {\n" name;
117 pr " guestfs_str %s<>;\n" n;
119 | RStruct (n, typ) ->
120 pr "struct %s_ret {\n" name;
121 pr " guestfs_int_%s %s;\n" typ n;
123 | RStructList (n, typ) ->
124 pr "struct %s_ret {\n" name;
125 pr " guestfs_int_%s_list %s;\n" typ n;
128 pr "struct %s_ret {\n" name;
129 pr " guestfs_str %s<>;\n" n;
132 pr "struct %s_ret {\n" name;
133 pr " opaque %s<>;\n" n;
138 (* Table of procedure numbers. *)
139 pr "enum guestfs_procedure {\n";
141 fun (shortname, _, proc_nr, _, _, _, _) ->
142 pr " GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr
144 pr " GUESTFS_PROC_NR_PROCS\n";
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.
153 pr "const GUESTFS_MESSAGE_MAX = %d;\n" (4 * 1024 * 1024);
156 (* Message header, etc. *)
158 /* The communication protocol is now documented in the guestfs(3)
162 const GUESTFS_PROGRAM = 0x2000F5F5;
163 const GUESTFS_PROTOCOL_VERSION = 4;
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;
170 enum guestfs_message_direction {
171 GUESTFS_DIRECTION_CALL = 0, /* client -> daemon */
172 GUESTFS_DIRECTION_REPLY = 1 /* daemon -> client */
175 enum guestfs_message_status {
176 GUESTFS_STATUS_OK = 0,
177 GUESTFS_STATUS_ERROR = 1
182 pr "const GUESTFS_ERROR_LEN = %d;\n" (64 * 1024);
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>;
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;
203 const GUESTFS_MAX_CHUNK_SIZE = 8192;
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>;
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.
219 * (1) guestfs___recv_from_daemon assumes the XDR-encoded
220 * structure is 24 bytes long.
222 * (2) daemon/proto.c:async_safe_send_pulse assumes the progress
223 * message is laid out precisely in this way. So if you change
224 * this then you'd better change that function as well.
226 struct guestfs_progress {
227 guestfs_procedure proc; /* @0: GUESTFS_PROC_x */
228 unsigned serial; /* @4: message serial number */
229 unsigned hyper position; /* @8: 0 <= position <= total */
230 unsigned hyper total; /* @16: total size of operation */
231 /* @24: size of structure */