From ace0e68d0f2f9b977e2bbbc2228ff60f6de903ba Mon Sep 17 00:00:00 2001 From: compudj Date: Mon, 18 Jul 2005 22:28:58 +0000 Subject: [PATCH] libltt ok git-svn-id: http://ltt.polymtl.ca/svn@968 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/libltt/Makefile.am | 4 +- ltt/branches/poly/libltt/libltt.c | 224 ++++++++++++++++++++++----- ltt/branches/poly/libltt/libltt.h | 29 ++-- 3 files changed, 203 insertions(+), 54 deletions(-) diff --git a/ltt/branches/poly/libltt/Makefile.am b/ltt/branches/poly/libltt/Makefile.am index 1777a493..22d81b88 100644 --- a/ltt/branches/poly/libltt/Makefile.am +++ b/ltt/branches/poly/libltt/Makefile.am @@ -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 diff --git a/ltt/branches/poly/libltt/libltt.c b/ltt/branches/poly/libltt/libltt.c index d8fa3ca1..4fca391a 100644 --- a/ltt/branches/poly/libltt/libltt.c +++ b/ltt/branches/poly/libltt/libltt.c @@ -23,8 +23,10 @@ * */ -#include - +#include +#include +#include +#include /* 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; } diff --git a/ltt/branches/poly/libltt/libltt.h b/ltt/branches/poly/libltt/libltt.h index b9224bb5..274ee0f7 100644 --- a/ltt/branches/poly/libltt/libltt.h +++ b/ltt/branches/poly/libltt/libltt.h @@ -23,24 +23,31 @@ #define _LIBLTT_H #include +#include + +#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 */ -- 2.34.1