aboutsummaryrefslogtreecommitdiffstats
path: root/tools/debugger/pdb/pdb_caml_xcs.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/debugger/pdb/pdb_caml_xcs.c')
-rw-r--r--tools/debugger/pdb/pdb_caml_xcs.c305
1 files changed, 305 insertions, 0 deletions
diff --git a/tools/debugger/pdb/pdb_caml_xcs.c b/tools/debugger/pdb/pdb_caml_xcs.c
new file mode 100644
index 0000000000..61944420b2
--- /dev/null
+++ b/tools/debugger/pdb/pdb_caml_xcs.c
@@ -0,0 +1,305 @@
+/*
+ * xcs stuff
+ *
+ * this is responsible for establishing the initial connection
+ * between a backend domain and the pdb server.
+ *
+ * liberated from xu.c
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <xc.h>
+
+#include <xen/xen.h>
+#include <xen/io/domain_controller.h>
+#include <xen/linux/privcmd.h>
+
+#include <arpa/inet.h>
+#include <xcs_proto.h>
+
+#include <caml/alloc.h>
+#include <caml/fail.h>
+#include <caml/memory.h>
+#include <caml/mlvalues.h>
+
+static int control_fd = -1;
+
+#include "pdb_module.h"
+#include "pdb_caml_xen.h"
+
+void *map_ring(u32 dom, unsigned long mfn );
+
+/*
+ * xcs_initialize_ring : int -> int32 -> int32
+ *
+ * initialize a communications ring
+ * (probably belongs in a different file :)
+ */
+
+value
+xcs_initialize_ring (value domain, value ring)
+{
+ CAMLparam2(domain, ring);
+ int my_domain = Int_val(domain);
+ memory_t my_ring = Int32_val(ring);
+
+ pdb_front_ring_t *front_ring;
+ pdb_sring_t *sring;
+
+ front_ring = (pdb_front_ring_t *)malloc(sizeof(pdb_front_ring_t));
+ if ( front_ring == NULL )
+ {
+ printf("(pdb) xcs initialize ring: malloc failed.\n"); fflush(stdout);
+ failwith("xcs initialize ring: malloc");
+ }
+
+ sring = map_ring(my_domain, my_ring);
+ if ( sring == NULL )
+ {
+ printf("(pdb) xcs initialize ring: map ring failed.\n");fflush(stdout);
+ failwith("xcs initialize ring: map ring");
+ }
+ FRONT_RING_INIT(front_ring, sring, PAGE_SIZE);
+
+ CAMLreturn(caml_copy_int32((unsigned long)front_ring));
+}
+
+
+/*
+ * xcs_write_message : Unix.file_descr -> xcs_message -> unit
+ *
+ * ack a packet
+ */
+value
+xcs_write_message (value data_fd, value msg)
+{
+ CAMLparam2(data_fd, msg);
+ int my_data_fd = Int_val(data_fd);
+ xcs_msg_t my_msg;
+ pdb_connection_p conn;
+
+ my_msg.type = XCS_REQUEST;
+ my_msg.u.control.remote_dom = Int_val(Field(msg,0));
+ my_msg.u.control.msg.type = CMSG_DEBUG;
+ my_msg.u.control.msg.subtype = CMSG_DEBUG_CONNECTION_STATUS;
+ my_msg.u.control.msg.id = 0;
+ my_msg.u.control.msg.length = sizeof(pdb_connection_t);
+
+ conn = (pdb_connection_p)my_msg.u.control.msg.msg;
+
+ conn->status = Int_val(Field(msg,1));
+ conn->ring = Int32_val(Field(msg,2));
+ conn->evtchn = Int_val(Field(msg,3));
+
+ send(my_data_fd, &my_msg, sizeof(xcs_msg_t), 0); /* ack */
+
+ CAMLreturn(Val_unit);
+}
+
+/*
+ * xcs_read_message : Unix.file_descr -> xcs_message
+ *
+ * read pending data on xcs socket.
+ */
+
+value
+xcs_read_message (value data_fd)
+{
+ CAMLparam1(data_fd);
+ CAMLlocal1(result);
+ int my_data_fd = Int_val(data_fd);
+ xcs_msg_t msg;
+
+ if ( read(my_data_fd, &msg, sizeof(xcs_msg_t)) < 0 )
+ {
+ perror("read");
+ failwith("xcs message: read");
+ }
+
+ switch (msg.type)
+ {
+ case XCS_REQUEST :
+ {
+ pdb_connection_p conn;
+
+ if ( msg.u.control.msg.type != CMSG_DEBUG ||
+ msg.u.control.msg.subtype != CMSG_DEBUG_CONNECTION_STATUS )
+ {
+ printf("bogus message type: %d %d\n",
+ msg.u.control.msg.type, msg.u.control.msg.subtype);
+ failwith("xcs message: invalid message type");
+ }
+
+ conn = (pdb_connection_p) msg.u.control.msg.msg;
+
+ result = caml_alloc_tuple(4); /* FIXME */
+ Store_field(result, 0, Val_int(msg.u.control.remote_dom)); /* domain */
+ Store_field(result, 1, Val_int(conn->status)); /* status */
+ Store_field(result, 2, caml_copy_int32(conn->ring)); /* ring */
+ Store_field(result, 3, Val_int(0)); /* OUT: evtchn */
+
+ break;
+ }
+ case XCS_RESPONSE :
+ {
+ printf("[XCS RESPONSE] type: %d, remote_dom: %d\n",
+ msg.type, msg.u.control.remote_dom);
+ printf("strange. we never initiate messages, so what is the ");
+ printf("domain responding to?\n");
+ failwith ("xcs message: resonse");
+ break;
+ }
+ default:
+ {
+ printf("[XCS IGNORE] type: %d\n", msg.type);
+ failwith ("xcs message: unknown");
+ break;
+ }
+ }
+
+ CAMLreturn(result);
+}
+
+/*
+ * xcs_connect : string -> int -> Unix.file_descr
+ */
+
+value
+xcs_connect (value path, value msg_type)
+{
+ CAMLparam2(path, msg_type);
+ char *my_path = String_val(path);
+ int my_msg_type = Int_val(msg_type);
+ struct sockaddr_un addr;
+ u32 session_id = 0;
+ int data_fd;
+ int ret, len;
+ xcs_msg_t msg;
+
+ /* setup control channel connection to xcs */
+
+ control_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if ( control_fd < 0 )
+ {
+ printf("error creating xcs socket!\n");
+ goto fail;
+ }
+
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, my_path);
+ len = sizeof(addr.sun_family) + strlen(addr.sun_path) + 1;
+
+ ret = connect(control_fd, (struct sockaddr *)&addr, len);
+ if (ret < 0)
+ {
+ printf("error connecting to xcs(ctrl)! (%d)\n", errno);
+ goto ctrl_fd_fail;
+ }
+
+ msg.type = XCS_CONNECT_CTRL;
+ msg.u.connect.session_id = session_id;
+ send(control_fd, &msg, sizeof(xcs_msg_t), 0);
+ /* bug: this should have a timeout & error! */
+ read(control_fd, &msg, sizeof(xcs_msg_t));
+
+ if (msg.result != XCS_RSLT_OK)
+ {
+ printf("error connecting xcs control channel!\n");
+ goto ctrl_fd_fail;
+ }
+ session_id = msg.u.connect.session_id;
+
+
+ /* setup data channel connection to xcs */
+
+ data_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if ( data_fd < 0 )
+ {
+ printf("error creating xcs data socket!\n");
+ goto ctrl_fd_fail;
+ }
+
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, my_path);
+ len = sizeof(addr.sun_family) + strlen(addr.sun_path) + 1;
+
+ ret = connect(data_fd, (struct sockaddr *)&addr, len);
+ if (ret < 0)
+ {
+ printf("error connecting to xcs(data)! (%d)\n", errno);
+ goto data_fd_fail;
+ }
+
+ msg.type = XCS_CONNECT_DATA;
+ msg.u.connect.session_id = session_id;
+ send(data_fd, &msg, sizeof(xcs_msg_t), 0);
+ read(data_fd, &msg, sizeof(xcs_msg_t)); /* same bug */
+
+ if ( msg.result != XCS_RSLT_OK )
+ {
+ printf("error connecting xcs control channel!\n");
+ goto ctrl_fd_fail;
+ }
+
+
+
+ /* now request all messages of a particular type */
+
+ msg.type = XCS_MSG_BIND;
+ msg.u.bind.port = PORT_WILDCARD;
+ msg.u.bind.type = my_msg_type;
+ send(control_fd, &msg, sizeof(xcs_msg_t), 0);
+ read(control_fd, &msg, sizeof(xcs_msg_t)); /* still buggy */
+
+ if (msg.result != XCS_RSLT_OK) {
+ printf ("error: MSG BIND\n");
+ goto bind_fail;
+ }
+
+ CAMLreturn(Val_int(data_fd));
+
+bind_fail:
+data_fd_fail:
+ close(data_fd);
+
+ctrl_fd_fail:
+ close(control_fd);
+
+fail:
+ failwith("xcs connection error"); /* should be more explicit */
+}
+
+
+/* xcs_disconnect: Unix.file_descr -> unit */
+
+value
+xcs_disconnect (value data_fd)
+{
+ CAMLparam1(data_fd);
+
+ int my_data_fd = Int_val(data_fd);
+
+ close(my_data_fd);
+ close(control_fd);
+ control_fd = -1;
+
+ CAMLreturn(Val_unit);
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+