libltt ok
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Mon, 18 Jul 2005 22:28:58 +0000 (22:28 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Mon, 18 Jul 2005 22:28:58 +0000 (22:28 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@968 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/libltt/Makefile.am
ltt/branches/poly/libltt/libltt.c
ltt/branches/poly/libltt/libltt.h

index 1777a493467eedfafc918b09ae34ac602f00050b..22d81b88f581f8cb648238c4034aa88ef475ffe7 100644 (file)
@@ -1,6 +1,6 @@
 
 lib_LTLIBRARIES = libltt.la
-libtextDump_la_SOURCES = libltt.c
+libltt_la_SOURCES = libltt.c
 
 lttinclude_HEADERS = \
-       ltt-control.h
+       libltt.h
index d8fa3ca18777faba7bd1f1da23a9b69989ce19a5..4fca391ad16aac257662c8acb879d6b5df4e1d66 100644 (file)
  *     
  */
 
-#include <ltt/libltt.h>
-
+#include <libltt/libltt.h>
+#include <linux/netlink.h>
+#include <errno.h>
+#include <stdio.h>
 
 /* Private interface */
 
@@ -54,23 +56,23 @@ struct lttctl_errmap_t {
        int errcode;
        char *message;
 } lttctl_errmap[] = {
-       { IPQ_ERR_NONE, "Unknown error" },
-       { IPQ_ERR_IMPL, "Implementation error" },
-       { IPQ_ERR_HANDLE, "Unable to create netlink handle" },
-       { IPQ_ERR_SOCKET, "Unable to create netlink socket" },
-       { IPQ_ERR_BIND, "Unable to bind netlink socket" },
-       { IPQ_ERR_BUFFER, "Unable to allocate buffer" },
-       { IPQ_ERR_RECV, "Failed to receive netlink message" },
-       { IPQ_ERR_NLEOF, "Received EOF on netlink socket" },
-       { IPQ_ERR_ADDRLEN, "Invalid peer address length" },
-       { IPQ_ERR_STRUNC, "Sent message truncated" },
-       { IPQ_ERR_RTRUNC, "Received message truncated" },
-       { IPQ_ERR_NLRECV, "Received error from netlink" },
-       { IPQ_ERR_SEND, "Failed to send netlink message" },
-       { IPQ_ERR_SUPP, "Operation not supported" },
-       { IPQ_ERR_RECVBUF, "Receive buffer size invalid" },
-       { IPQ_ERR_TIMEOUT, "Timeout"},
-       { IPQ_ERR_PROTOCOL, "Invalid protocol specified" }
+       { LTTCTL_ERR_NONE, "Unknown error" },
+       { LTTCTL_ERR_IMPL, "Implementation error" },
+       { LTTCTL_ERR_HANDLE, "Unable to create netlink handle" },
+       { LTTCTL_ERR_SOCKET, "Unable to create netlink socket" },
+       { LTTCTL_ERR_BIND, "Unable to bind netlink socket" },
+       { LTTCTL_ERR_BUFFER, "Unable to allocate buffer" },
+       { LTTCTL_ERR_RECV, "Failed to receive netlink message" },
+       { LTTCTL_ERR_NLEOF, "Received EOF on netlink socket" },
+       { LTTCTL_ERR_ADDRLEN, "Invalid peer address length" },
+       { LTTCTL_ERR_STRUNC, "Sent message truncated" },
+       { LTTCTL_ERR_RTRUNC, "Received message truncated" },
+       { LTTCTL_ERR_NLRECV, "Received error from netlink" },
+       { LTTCTL_ERR_SEND, "Failed to send netlink message" },
+       { LTTCTL_ERR_SUPP, "Operation not supported" },
+       { LTTCTL_ERR_RECVBUF, "Receive buffer size invalid" },
+       { LTTCTL_ERR_TIMEOUT, "Timeout"},
+       { LTTCTL_ERR_PROTOCOL, "Invalid protocol specified" }
 };
 
 static int lttctl_errno = LTTCTL_ERR_NONE;
@@ -89,6 +91,8 @@ static ssize_t lttctl_netlink_sendmsg(const struct lttctl_handle *h,
 
 static char *lttctl_strerror(int errcode);
 
+void lttctl_perror(const char *s);
+
 static ssize_t lttctl_netlink_sendto(const struct lttctl_handle *h,
                                   const void *msg, size_t len)
 {
@@ -96,6 +100,7 @@ static ssize_t lttctl_netlink_sendto(const struct lttctl_handle *h,
                            (struct sockaddr *)&h->peer, sizeof(h->peer));
        if (status < 0)
                lttctl_errno = LTTCTL_ERR_SEND;
+       
        return status;
 }
 
@@ -116,8 +121,9 @@ static ssize_t lttctl_netlink_recvfrom(const struct lttctl_handle *h,
        int addrlen, status;
        struct nlmsghdr *nlh;
 
-       if (len < sizeof(struct nlmsgerr)) {
+       if (len < sizeof(struct nlmsghdr)) {
                lttctl_errno = LTTCTL_ERR_RECVBUF;
+               lttctl_perror("Netlink recvfrom");
                return -1;
        }
        addrlen = sizeof(h->peer);
@@ -141,40 +147,51 @@ static ssize_t lttctl_netlink_recvfrom(const struct lttctl_handle *h,
                ret = select(h->fd+1, &read_fds, NULL, NULL, &tv);
                if (ret < 0) {
                        if (errno == EINTR) {
+                               printf("eintr\n");
                                return 0;
                        } else {
-                               lttctl_errno = lttctl_ERR_RECV;
+                               lttctl_errno = LTTCTL_ERR_RECV;
+                               lttctl_perror("Netlink recvfrom");
                                return -1;
                        }
                }
                if (!FD_ISSET(h->fd, &read_fds)) {
-                       lttctl_errno = lttctl_ERR_TIMEOUT;
+                       lttctl_errno = LTTCTL_ERR_TIMEOUT;
+                       printf("timeout\n");
                        return 0;
                }
        }
        status = recvfrom(h->fd, buf, len, 0,
                              (struct sockaddr *)&h->peer, &addrlen);
+       
        if (status < 0) {
                lttctl_errno = LTTCTL_ERR_RECV;
+               lttctl_perror("Netlink recvfrom");
                return status;
        }
        if (addrlen != sizeof(h->peer)) {
                lttctl_errno = LTTCTL_ERR_RECV;
+               lttctl_perror("Netlink recvfrom");
                return -1;
        }
        if (h->peer.nl_pid != 0) {
                lttctl_errno = LTTCTL_ERR_RECV;
+               lttctl_perror("Netlink recvfrom");
                return -1;
        }
        if (status == 0) {
                lttctl_errno = LTTCTL_ERR_NLEOF;
+               lttctl_perror("Netlink recvfrom");
                return -1;
        }
        nlh = (struct nlmsghdr *)buf;
        if (nlh->nlmsg_flags & MSG_TRUNC || nlh->nlmsg_len > status) {
                lttctl_errno = LTTCTL_ERR_RTRUNC;
+               lttctl_perror("Netlink recvfrom");
                return -1;
        }
+       
+
        return status;
 }
 
@@ -187,6 +204,23 @@ static char *lttctl_strerror(int errcode)
 }
 
 
+char *lttctl_errstr(void)
+{
+       return lttctl_strerror(lttctl_errno);
+}
+
+void lttctl_perror(const char *s)
+{
+       if (s)
+               fputs(s, stderr);
+       else
+               fputs("ERROR", stderr);
+       if (lttctl_errno)
+               fprintf(stderr, ": %s", lttctl_errstr());
+       if (errno)
+               fprintf(stderr, ": %s", strerror(errno));
+       fputc('\n', stderr);
+}
 
 /* public interface */
 
@@ -200,8 +234,9 @@ struct lttctl_handle *lttctl_create_handle(void)
 
        h = (struct lttctl_handle *)malloc(sizeof(struct lttctl_handle));
        if (h == NULL) {
-               lttctl_errno = lttctl_ERR_HANDLE;
-               return NULL;
+               lttctl_errno = LTTCTL_ERR_HANDLE;
+               lttctl_perror("Create handle");
+               goto alloc_error;
        }
        
        memset(h, 0, sizeof(struct lttctl_handle));
@@ -210,9 +245,8 @@ struct lttctl_handle *lttctl_create_handle(void)
         
        if (h->fd == -1) {
                lttctl_errno = LTTCTL_ERR_SOCKET;
-               close(h->fd);
-               free(h);
-               return NULL;
+               lttctl_perror("Create handle");
+               goto socket_error;
        }
        memset(&h->local, 0, sizeof(struct sockaddr_nl));
        h->local.nl_family = AF_NETLINK;
@@ -221,15 +255,22 @@ struct lttctl_handle *lttctl_create_handle(void)
        status = bind(h->fd, (struct sockaddr *)&h->local, sizeof(h->local));
        if (status == -1) {
                lttctl_errno = LTTCTL_ERR_BIND;
-               close(h->fd);
-               free(h);
-               return NULL;
+               lttctl_perror("Create handle");
+               goto bind_error;
        }
        memset(&h->peer, 0, sizeof(struct sockaddr_nl));
        h->peer.nl_family = AF_NETLINK;
        h->peer.nl_pid = 0;
        h->peer.nl_groups = 0;
        return h;
+       
+       /* Error condition */
+bind_error:
+socket_error:
+               close(h->fd);
+alloc_error:
+               free(h);
+       return NULL;
 }
 
 /*
@@ -246,37 +287,68 @@ int lttctl_destroy_handle(struct lttctl_handle *h)
 }
 
 
-int lttctl_create_trace(const struct ipq_handle *h,
+int lttctl_create_trace(const struct lttctl_handle *h,
                char *name, enum trace_mode mode)
 {
+       int err;
+       
        struct {
                struct nlmsghdr nlh;
                lttctl_peer_msg_t       msg;
        } req;
+       struct {
+               struct nlmsghdr nlh;
+               struct nlmsgerr nlerr;
+               lttctl_peer_msg_t       msg;
+       } ack;
 
        memset(&req, 0, sizeof(req));
-       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(req));
-       req.nlh.nlmsg_flags = NLM_F_REQUEST;
+       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(lttctl_peer_msg_t));
+       req.nlh.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
        req.nlh.nlmsg_type = LTTCTLM_CONTROL;
        req.nlh.nlmsg_pid = h->local.nl_pid;
+       req.nlh.nlmsg_seq = 0;
 
        strncpy(req.msg.trace_name, name, NAME_MAX);
        req.msg.op = OP_CREATE;
        req.msg.args.mode = mode;
 
-       return lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       err = lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       if(err < 0) goto senderr;
+
+       err = lttctl_netlink_recvfrom(h, (void*)&ack, sizeof(ack), 0);
+       if(err < 0) goto senderr;
+
+       err = ack.nlerr.error;
+       if(err != 0) {
+               errno = err;
+               lttctl_perror("Create Trace Error");
+               return -1;
+       }
+
+       return 0;
+
+senderr:
+       lttctl_perror("Create Trace Error");
+       return err;
 }
 
-int lttctl_destroy_trace(const struct ipq_handle *h,
+int lttctl_destroy_trace(const struct lttctl_handle *h,
                char *name)
 {
        struct {
                struct nlmsghdr nlh;
                lttctl_peer_msg_t       msg;
        } req;
+       struct {
+               struct nlmsghdr nlh;
+               struct nlmsgerr nlerr;
+               lttctl_peer_msg_t       msg;
+       } ack;
+       int err;
 
        memset(&req, 0, sizeof(req));
-       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(req));
+       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(lttctl_peer_msg_t));
        req.nlh.nlmsg_flags = NLM_F_REQUEST;
        req.nlh.nlmsg_type = LTTCTLM_CONTROL;
        req.nlh.nlmsg_pid = h->local.nl_pid;
@@ -284,19 +356,44 @@ int lttctl_destroy_trace(const struct ipq_handle *h,
        strncpy(req.msg.trace_name, name, NAME_MAX);
        req.msg.op = OP_DESTROY;
 
-       return lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       err = lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       if(err < 0) goto senderr;
+
+       err = lttctl_netlink_recvfrom(h, (void*)&ack, sizeof(ack), 0);
+       if(err < 0) goto senderr;
+
+       err = ack.nlerr.error;
+       if(err != 0) {
+               errno = err;
+               lttctl_perror("Destroy Trace Channels Error");
+               return -1;
+       }
+
+       return 0;
+
+senderr:
+       lttctl_perror("Destroy Trace Channels Error");
+       return err;
+
 }
 
-int lttctl_start(const struct ipq_handle *h,
+int lttctl_start(const struct lttctl_handle *h,
                char *name)
 {
        struct {
                struct nlmsghdr nlh;
                lttctl_peer_msg_t       msg;
        } req;
+       struct {
+               struct nlmsghdr nlh;
+               struct nlmsgerr nlerr;
+               lttctl_peer_msg_t       msg;
+       } ack;
+
+       int err;
 
        memset(&req, 0, sizeof(req));
-       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(req));
+       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(lttctl_peer_msg_t));
        req.nlh.nlmsg_flags = NLM_F_REQUEST;
        req.nlh.nlmsg_type = LTTCTLM_CONTROL;
        req.nlh.nlmsg_pid = h->local.nl_pid;
@@ -304,19 +401,43 @@ int lttctl_start(const struct ipq_handle *h,
        strncpy(req.msg.trace_name, name, NAME_MAX);
        req.msg.op = OP_START;
 
-       return lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       err = lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       if(err < 0) goto senderr;
+
+       err = lttctl_netlink_recvfrom(h, (void*)&ack, sizeof(ack), 0);
+       if(err < 0) goto senderr;
+
+       err = ack.nlerr.error;
+       if(err != 0) {
+               errno = err;
+               lttctl_perror("Start Trace Error");
+               return -1;
+       }
+
+       return 0;
+
+senderr:
+       lttctl_perror("Start Trace Error");
+       return err;
+
 }
 
-int lttctl_stop(const struct ipq_handle *h,
+int lttctl_stop(const struct lttctl_handle *h,
                char *name)
 {
        struct {
                struct nlmsghdr nlh;
                lttctl_peer_msg_t       msg;
        } req;
+       struct {
+               struct nlmsghdr nlh;
+               struct nlmsgerr nlerr;
+               lttctl_peer_msg_t       msg;
+       } ack;
+       int err;
 
        memset(&req, 0, sizeof(req));
-       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(req));
+       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(lttctl_peer_msg_t));
        req.nlh.nlmsg_flags = NLM_F_REQUEST;
        req.nlh.nlmsg_type = LTTCTLM_CONTROL;
        req.nlh.nlmsg_pid = h->local.nl_pid;
@@ -324,5 +445,22 @@ int lttctl_stop(const struct ipq_handle *h,
        strncpy(req.msg.trace_name, name, NAME_MAX);
        req.msg.op = OP_STOP;
 
-       return lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       err = lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       if(err < 0) goto senderr;
+
+       err = lttctl_netlink_recvfrom(h, (void*)&ack, sizeof(ack), 0);
+       if(err < 0) goto senderr;
+
+       err = ack.nlerr.error;
+       if(err != 0) {
+               errno = err;
+               lttctl_perror("Stop Trace Error");
+               return -1;
+       }
+
+       return 0;
+
+senderr:
+       lttctl_perror("Stop Trace Error");
+       return err;
 }
index b9224bb5a5acc2b58ab7e3aea99db208611f934a..274ee0f7af6bdea2bff0e13b081735458e8fcfca 100644 (file)
 #define _LIBLTT_H
 
 #include <linux/limits.h>
+#include <linux/netlink.h>
+
+#ifndef NETLINK_LTT
+#define NETLINK_LTT 12
+#endif
+
 
 enum trace_op {
        OP_CREATE,
        OP_DESTROY,
        OP_START,
-       OP_STOP
+       OP_STOP,
+       OP_NONE
 };
 
 enum trace_mode {
-       TRACE_NORMAL,
-       TRACE_FLIGHT
+       LTT_TRACE_NORMAL,
+       LTT_TRACE_FLIGHT
 };
 
 
 struct lttctl_handle
 {
   int fd;
-  u_int8_t blocking;
+  //u_int8_t blocking;
   struct sockaddr_nl local;
   struct sockaddr_nl peer;
 };
@@ -53,19 +60,23 @@ typedef struct lttctl_peer_msg {
        } args;
 } lttctl_peer_msg_t;
 
+typedef struct lttctl_resp_msg {
+       int err;
+} lttctl_resp_msg_t;
 
-struct lttctl_handle *lttctl_create_handle(u_int32_t flags);
+struct lttctl_handle *lttctl_create_handle(void);
 
 int lttctl_destroy_handle(struct lttctl_handle *h);
 
 
-int lttctl_create_trace(char *name, enum trace_mode mode);
+int lttctl_create_trace(const struct lttctl_handle * handle,
+               char *name, enum trace_mode mode);
 
-int lttctl_destroy_trace(char *name);
+int lttctl_destroy_trace(const struct lttctl_handle *handle, char *name);
 
-int lttctl_start(char *name);
+int lttctl_start(const struct lttctl_handle *handle, char *name);
 
-int lttctl_stop(char *name);
+int lttctl_stop(const struct lttctl_handle *handle, char *name);
 
 #define LTTCTLM_BASE   0x10
 #define LTTCTLM_CONTROL        (LTTCTLM_BASE + 1)      /* LTT control message */
This page took 0.030371 seconds and 4 git commands to generate.