ia64/xen-unstable

view tools/debugger/pdb/pdb_caml_xcs.c @ 6435:b4b3f6be5226

merge?
author cl349@firebug.cl.cam.ac.uk
date Thu Aug 25 17:27:49 2005 +0000 (2005-08-25)
parents 0610add7c3fe 6e899a3840b2
children 8799d14bef77 9312a3e8a6f8 112d44270733
line source
1 /*
2 * xcs stuff
3 *
4 * http://www.cl.cam.ac.uk/netos/pdb
5 *
6 * this is responsible for establishing the initial connection
7 * between a backend domain and the pdb server.
8 *
9 * liberated from xu.c
10 *
11 */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <sys/un.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <errno.h>
20 #include <xenctrl.h>
22 #include <xen/xen.h>
23 #include <xen/io/domain_controller.h>
24 #include <xen/linux/privcmd.h>
26 #include <arpa/inet.h>
27 #include <xcs_proto.h>
29 #include <caml/alloc.h>
30 #include <caml/fail.h>
31 #include <caml/memory.h>
32 #include <caml/mlvalues.h>
34 static int control_fd = -1;
36 #include "pdb_module.h"
37 #include "pdb_caml_xen.h"
39 void *map_ring(u32 dom, unsigned long mfn );
41 /*
42 * xcs_initialize_ring : int -> int32 -> int32
43 *
44 * initialize a communications ring
45 * (probably belongs in a different file :)
46 */
48 value
49 xcs_initialize_ring (value domain, value ring)
50 {
51 CAMLparam2(domain, ring);
52 int my_domain = Int_val(domain);
53 unsigned long my_ring = Int32_val(ring);
55 pdb_front_ring_t *front_ring;
56 pdb_sring_t *sring;
58 front_ring = (pdb_front_ring_t *)malloc(sizeof(pdb_front_ring_t));
59 if ( front_ring == NULL )
60 {
61 printf("(pdb) xcs initialize ring: malloc failed.\n"); fflush(stdout);
62 failwith("xcs initialize ring: malloc");
63 }
65 sring = map_ring(my_domain, my_ring);
66 if ( sring == NULL )
67 {
68 printf("(pdb) xcs initialize ring: map ring failed.\n");fflush(stdout);
69 failwith("xcs initialize ring: map ring");
70 }
71 FRONT_RING_INIT(front_ring, sring, PAGE_SIZE);
73 CAMLreturn(caml_copy_int32((unsigned long)front_ring));
74 }
77 /*
78 * xcs_write_message : Unix.file_descr -> xcs_message -> unit
79 *
80 * ack a packet
81 */
82 value
83 xcs_write_message (value data_fd, value msg)
84 {
85 CAMLparam2(data_fd, msg);
86 int my_data_fd = Int_val(data_fd);
87 xcs_msg_t my_msg;
88 pdb_connection_p conn;
90 my_msg.type = XCS_REQUEST;
91 my_msg.u.control.remote_dom = Int_val(Field(msg,0));
92 my_msg.u.control.msg.type = CMSG_DEBUG;
93 my_msg.u.control.msg.subtype = CMSG_DEBUG_CONNECTION_STATUS;
94 my_msg.u.control.msg.id = 0;
95 my_msg.u.control.msg.length = sizeof(pdb_connection_t);
97 conn = (pdb_connection_p)my_msg.u.control.msg.msg;
99 conn->status = Int_val(Field(msg,1));
100 conn->ring = Int32_val(Field(msg,2));
101 conn->evtchn = Int_val(Field(msg,3));
103 send(my_data_fd, &my_msg, sizeof(xcs_msg_t), 0); /* ack */
105 CAMLreturn(Val_unit);
106 }
108 /*
109 * xcs_read_message : Unix.file_descr -> xcs_message
110 *
111 * read pending data on xcs socket.
112 */
114 value
115 xcs_read_message (value data_fd)
116 {
117 CAMLparam1(data_fd);
118 CAMLlocal1(result);
119 int my_data_fd = Int_val(data_fd);
120 xcs_msg_t msg;
122 if ( read(my_data_fd, &msg, sizeof(xcs_msg_t)) < 0 )
123 {
124 perror("read");
125 failwith("xcs message: read");
126 }
128 switch (msg.type)
129 {
130 case XCS_REQUEST :
131 {
132 pdb_connection_p conn;
134 if ( msg.u.control.msg.type != CMSG_DEBUG ||
135 msg.u.control.msg.subtype != CMSG_DEBUG_CONNECTION_STATUS )
136 {
137 printf("bogus message type: %d %d\n",
138 msg.u.control.msg.type, msg.u.control.msg.subtype);
139 failwith("xcs message: invalid message type");
140 }
142 conn = (pdb_connection_p) msg.u.control.msg.msg;
144 result = caml_alloc_tuple(4); /* FIXME */
145 Store_field(result, 0, Val_int(msg.u.control.remote_dom)); /* domain */
146 Store_field(result, 1, Val_int(conn->status)); /* status */
147 Store_field(result, 2, caml_copy_int32(conn->ring)); /* ring */
148 Store_field(result, 3, Val_int(0)); /* OUT: evtchn */
150 break;
151 }
152 case XCS_RESPONSE :
153 {
154 printf("[XCS RESPONSE] type: %d, remote_dom: %d\n",
155 msg.type, msg.u.control.remote_dom);
156 printf("strange. we never initiate messages, so what is the ");
157 printf("domain responding to?\n");
158 failwith ("xcs message: resonse");
159 break;
160 }
161 default:
162 {
163 printf("[XCS IGNORE] type: %d\n", msg.type);
164 failwith ("xcs message: unknown");
165 break;
166 }
167 }
169 CAMLreturn(result);
170 }
172 /*
173 * xcs_connect : string -> int -> Unix.file_descr
174 */
176 value
177 xcs_connect (value path, value msg_type)
178 {
179 CAMLparam2(path, msg_type);
180 char *my_path = String_val(path);
181 int my_msg_type = Int_val(msg_type);
182 struct sockaddr_un addr;
183 u32 session_id = 0;
184 int data_fd;
185 int ret, len;
186 xcs_msg_t msg;
188 /* setup control channel connection to xcs */
190 control_fd = socket(AF_UNIX, SOCK_STREAM, 0);
191 if ( control_fd < 0 )
192 {
193 printf("error creating xcs socket!\n");
194 goto fail;
195 }
197 addr.sun_family = AF_UNIX;
198 strcpy(addr.sun_path, my_path);
199 len = sizeof(addr.sun_family) + strlen(addr.sun_path) + 1;
201 ret = connect(control_fd, (struct sockaddr *)&addr, len);
202 if (ret < 0)
203 {
204 printf("error connecting to xcs (ctrl)! (%d)\n", errno);
205 goto ctrl_fd_fail;
206 }
208 msg.type = XCS_CONNECT_CTRL;
209 msg.u.connect.session_id = session_id;
210 send(control_fd, &msg, sizeof(xcs_msg_t), 0);
211 /* bug: this should have a timeout & error! */
212 read(control_fd, &msg, sizeof(xcs_msg_t));
214 if (msg.result != XCS_RSLT_OK)
215 {
216 printf("error connecting xcs control channel!\n");
217 goto ctrl_fd_fail;
218 }
219 session_id = msg.u.connect.session_id;
222 /* setup data channel connection to xcs */
224 data_fd = socket(AF_UNIX, SOCK_STREAM, 0);
225 if ( data_fd < 0 )
226 {
227 printf("error creating xcs data socket!\n");
228 goto ctrl_fd_fail;
229 }
231 addr.sun_family = AF_UNIX;
232 strcpy(addr.sun_path, my_path);
233 len = sizeof(addr.sun_family) + strlen(addr.sun_path) + 1;
235 ret = connect(data_fd, (struct sockaddr *)&addr, len);
236 if (ret < 0)
237 {
238 printf("error connecting to xcs (data)! (%d)\n", errno);
239 goto data_fd_fail;
240 }
242 msg.type = XCS_CONNECT_DATA;
243 msg.u.connect.session_id = session_id;
244 send(data_fd, &msg, sizeof(xcs_msg_t), 0);
245 read(data_fd, &msg, sizeof(xcs_msg_t)); /* same bug */
247 if ( msg.result != XCS_RSLT_OK )
248 {
249 printf("error connecting xcs control channel!\n");
250 goto ctrl_fd_fail;
251 }
255 /* now request all messages of a particular type */
257 msg.type = XCS_MSG_BIND;
258 msg.u.bind.port = PORT_WILDCARD;
259 msg.u.bind.type = my_msg_type;
260 send(control_fd, &msg, sizeof(xcs_msg_t), 0);
261 read(control_fd, &msg, sizeof(xcs_msg_t)); /* still buggy */
263 if (msg.result != XCS_RSLT_OK) {
264 printf ("error: MSG BIND\n");
265 goto bind_fail;
266 }
268 CAMLreturn(Val_int(data_fd));
270 bind_fail:
271 data_fd_fail:
272 close(data_fd);
274 ctrl_fd_fail:
275 close(control_fd);
277 fail:
278 failwith("xcs connection error"); /* should be more explicit */
279 }
282 /* xcs_disconnect: Unix.file_descr -> unit */
284 value
285 xcs_disconnect (value data_fd)
286 {
287 CAMLparam1(data_fd);
289 int my_data_fd = Int_val(data_fd);
291 close(my_data_fd);
292 close(control_fd);
293 control_fd = -1;
295 CAMLreturn(Val_unit);
296 }
299 /*
300 * Local variables:
301 * mode: C
302 * c-set-style: "BSD"
303 * c-basic-offset: 4
304 * tab-width: 4
305 * indent-tabs-mode: nil
306 * End:
307 */