[GITLAB] - UPGRADE TO v12 on Wednesday the 18th of December at 11.30AM

Commit 358a3791 authored by Cedric Roux's avatar Cedric Roux

put local tracer in tracee

plus some cleanup here and there
parent 05afc953
......@@ -1488,7 +1488,8 @@ set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODU
add_boolean_option(T_TRACER True "Activate the T tracer" )
include_directories("${OPENAIR_DIR}/common/utils/T")
set(T_SOURCE
${OPENAIR_DIR}/common/utils/T/T.c)
${OPENAIR_DIR}/common/utils/T/T.c
${OPENAIR_DIR}/common/utils/T/local_tracer.c)
set (T_LIB "-lrt")
# Hack on a test of asn1c version (already dirty)
......
CC=gcc
CFLAGS=-Wall -g -pthread -DT_TRACER
LIBS += -lrt
PROG=t
OBJS=main.o T.o
CFLAGS=-Wall -g
GENIDS=genids
GENIDS_OBJS=genids.o
ALL=$(PROG) $(GENIDS)
all : $(ALL)
all : $(GENIDS) T_messages.txt.h T_IDs.h
$(GENIDS): $(GENIDS_OBJS)
$(CC) $(CFLAGS) -o $(GENIDS) $(GENIDS_OBJS)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
T.o: T_messages.txt.h
T_messages.txt.h: T_messages.txt
xxd -i T_messages.txt > T_messages.txt.h
T_IDs.h: $(GENIDS) T_messages.txt
./$(GENIDS) T_messages.txt T_IDs.h
main.o: T.h T_IDs.h T_defs.h
clean:
rm -f *.o $(PROG) $(GENIDS) core T_IDs.h T_messages.txt.h
rm -f *.o $(GENIDS) core T_IDs.h T_messages.txt.h
cd tracer && make clean
#include "T.h"
#include "T_messages.txt.h"
#include <string.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
......@@ -10,6 +8,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
/* array used to activate/disactivate a log */
static int T_IDs[T_NUMBER_OF_IDS];
......@@ -23,7 +22,6 @@ static int T_socket;
*/
volatile int _T_freelist_head;
volatile int *T_freelist_head = &_T_freelist_head;
int T_busylist_head;
T_cache_t *T_cache;
static void get_message(int s)
......@@ -83,36 +81,31 @@ static void new_thread(void *(*f)(void *), void *data)
{ fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
}
void T_connect_to_tracer(char *addr, int port)
/* defined in local_tracer.c */
void T_local_tracer_main(int remote_port, int wait_for_tracer,
int local_socket);
void T_init(int remote_port, int wait_for_tracer)
{
struct sockaddr_in a;
int socket_pair[2];
int s;
int T_shm_fd;
unsigned char *buf;
int len;
int f;
if (strcmp(addr, "127.0.0.1") != 0) {
printf("error: local tracer must be on same host\n");
abort();
}
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair))
{ perror("socketpair"); abort(); }
printf("connecting to local tracer on port %d\n", port);
again:
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) { perror("socket"); exit(1); }
a.sin_family = AF_INET;
a.sin_port = htons(port);
a.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1) {
perror("connect");
close(s);
printf("trying again in 1s\n");
sleep(1);
goto again;
f = fork(); if (f == -1) abort();
if (f == 0) {
close(socket_pair[1]);
T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0]);
exit(0);
}
close(socket_pair[0]);
s = socket_pair[1];
/* wait for first message - initial list of active T events */
get_message(s);
......
......@@ -562,7 +562,7 @@ extern T_cache_t *T_cache;
extern int *T_active;
void T_connect_to_tracer(char *addr, int port);
void T_init(int remote_port, int wait_for_tracer);
#else /* T_TRACER */
......
#include "defs.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
typedef struct {
char *name;
char *desc;
char **groups;
int size;
int id;
} id;
typedef struct {
char *name;
char **ids;
int size;
} group;
typedef struct {
char *name;
id *i;
int isize;
group *g;
int gsize;
} database;
typedef struct {
char *data;
int size;
int maxsize;
} buffer;
typedef struct {
buffer name;
buffer value;
} parser;
void put(buffer *b, int c)
{
if (b->size == b->maxsize) {
b->maxsize += 256;
b->data = realloc(b->data, b->maxsize);
if (b->data == NULL) { printf("memory allocation error\n"); exit(1); }
}
b->data[b->size] = c;
b->size++;
}
void smash_spaces(FILE *f)
{
int c;
while (1) {
c = fgetc(f);
if (isspace(c)) continue;
if (c == ' ') continue;
if (c == '\t') continue;
if (c == '\n') continue;
if (c == 10 || c == 13) continue;
if (c == '#') {
while (1) {
c = fgetc(f);
if (c == '\n' || c == EOF) break;
}
continue;
}
break;
}
if (c != EOF) ungetc(c, f);
}
void get_line(parser *p, FILE *f, char **name, char **value)
{
int c;
p->name.size = 0;
p->value.size = 0;
*name = NULL;
*value = NULL;
smash_spaces(f);
c = fgetc(f);
while (!(c == '=' || isspace(c) || c == EOF))
{ put(&p->name, c); c = fgetc(f); }
if (c == EOF) return;
put(&p->name, 0);
while (!(c == EOF || c == '=')) c = fgetc(f);
if (c == EOF) return;
smash_spaces(f);
c = fgetc(f);
while (!(c == 10 || c == 13 || c == EOF))
{ put(&p->value, c); c = fgetc(f); }
put(&p->value, 0);
if (p->name.size <= 1) return;
if (p->value.size <= 1) return;
*name = p->name.data;
*value = p->value.data;
}
int group_cmp(const void *_p1, const void *_p2)
{
const group *p1 = _p1;
const group *p2 = _p2;
return strcmp(p1->name, p2->name);
}
int id_cmp(const void *_p1, const void *_p2)
{
const id *p1 = _p1;
const id *p2 = _p2;
return strcmp(p1->name, p2->name);
}
int string_cmp(const void *_p1, const void *_p2)
{
char * const *p1 = _p1;
char * const *p2 = _p2;
return strcmp(*p1, *p2);
}
id *add_id(database *r, char *idname, int i)
{
if (bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp) != NULL)
{ printf("ERROR: ID '%s' declared more than once\n", idname); exit(1); }
if ((r->isize & 1023) == 0) {
r->i = realloc(r->i, (r->isize + 1024) * sizeof(id));
if (r->i == NULL) { printf("out of memory\n"); exit(1); }
}
r->i[r->isize].name = strdup(idname);
if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); }
r->i[r->isize].desc = NULL;
r->i[r->isize].groups = NULL;
r->i[r->isize].size = 0;
r->i[r->isize].id = i;
r->isize++;
qsort(r->i, r->isize, sizeof(id), id_cmp);
return (id*)bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp);
}
group *get_group(database *r, char *group_name)
{
group *ret;
ret = bsearch(&(group){name:group_name},
r->g, r->gsize, sizeof(group), group_cmp);
if (ret != NULL) return ret;
if ((r->gsize & 1023) == 0) {
r->g = realloc(r->g, (r->gsize + 1024) * sizeof(group));
if (r->g == NULL) abort();
}
r->g[r->gsize].name = strdup(group_name);
if (r->g[r->gsize].name == NULL) abort();
r->g[r->gsize].ids = NULL;
r->g[r->gsize].size = 0;
r->gsize++;
qsort(r->g, r->gsize, sizeof(group), group_cmp);
return bsearch(&(group){name:group_name},
r->g, r->gsize, sizeof(group), group_cmp);
}
void group_add_id(group *g, char *id)
{
if ((g->size & 1023) == 0) {
g->ids = realloc(g->ids, (g->size + 1024) * sizeof(char *));
if (g->ids == NULL) abort();
}
g->ids[g->size] = id;
g->size++;
}
void id_add_group(id *i, char *group)
{
char *g = bsearch(&group, i->groups, i->size, sizeof(char *), string_cmp);
if (g != NULL) return;
if ((i->size & 1023) == 0) {
i->groups = realloc(i->groups, (i->size+1024) * sizeof(char *));
if (i->groups == NULL) abort();
}
i->groups[i->size] = group;
i->size++;
qsort(i->groups, i->size, sizeof(char *), string_cmp);
}
void add_groups(database *r, id *i, char *groups)
{
group *g;
if (i == NULL) {printf("ERROR: GROUP line before ID line\n");exit(1);}
while (1) {
char *start = groups;
char *end = start;
while (!isspace(*end) && *end != ':' && *end != 0) end++;
if (end == start) {
printf("bad group line: groups are seperated by ':'\n");
abort();
}
if (*end == 0) end = NULL; else *end = 0;
g = get_group(r, start);
group_add_id(g, i->name);
id_add_group(i, g->name);
if (end == NULL) break;
end++;
while ((isspace(*end) || *end == ':') && *end != 0) end++;
if (*end == 0) break;
groups = end;
}
}
void add_desc(id *i, char *desc)
{
if (i == NULL) {printf("ERROR: DESC line before ID line\n");exit(1);}
i->desc = strdup(desc); if (i->desc == NULL) abort();
}
void *parse_database(char *filename)
{
FILE *in;
parser p;
database *r;
char *name, *value;
id *last_id = NULL;
int i;
r = calloc(1, sizeof(*r)); if (r == NULL) abort();
memset(&p, 0, sizeof(p));
r->name = strdup(filename); if (r->name == NULL) abort();
in = fopen(filename, "r"); if (in == NULL) { perror(filename); abort(); }
i = 0;
while (1) {
get_line(&p, in, &name, &value);
if (name == NULL) break;
//printf("%s %s\n", name, value);
if (!strcmp(name, "ID")) { last_id = add_id(r, value, i); i++; }
if (!strcmp(name, "GROUP")) add_groups(r, last_id, value);
if (!strcmp(name, "DESC")) add_desc(last_id, value);
}
fclose(in);
free(p.name.data);
free(p.value.data);
return r;
}
void dump_database(void *_d)
{
database *d = _d;
int i;
printf("database %s: %d IDs, %d GROUPs\n", d->name, d->isize, d->gsize);
for (i = 0; i < d->isize; i++) {
int j;
printf("ID %s [%s] [in %d group%s]\n",
d->i[i].name, d->i[i].desc ? d->i[i].desc : "",
d->i[i].size, d->i[i].size > 1 ? "s" : "");
for (j = 0; j < d->i[i].size; j++)
printf(" in GROUP: %s\n", d->i[i].groups[j]);
}
for (i = 0; i < d->gsize; i++) {
int j;
printf("GROUP %s [size %d]\n", d->g[i].name, d->g[i].size);
for (j = 0; j < d->g[i].size; j++)
printf(" contains ID: %s\n", d->g[i].ids[j]);
}
}
void list_ids(void *_d)
{
database *d = _d;
int i;
for (i = 0; i < d->isize; i++) printf("%s\n", d->i[i].name);
}
void list_groups(void *_d)
{
database *d = _d;
int i;
for (i = 0; i < d->gsize; i++) printf("%s\n", d->g[i].name);
}
static int onoff_id(database *d, char *name, int *a, int onoff)
{
id *i;
i = bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp);
if (i == NULL) return 0;
a[i->id] = onoff;
printf("turning %s %s\n", onoff ? "ON" : "OFF", name);
return 1;
}
static int onoff_group(database *d, char *name, int *a, int onoff)
{
group *g;
int i;
g = bsearch(&(group){name:name}, d->g, d->gsize, sizeof(group), group_cmp);
if (g == NULL) return 0;
for (i = 0; i < g->size; i++) onoff_id(d, g->ids[i], a, onoff);
return 1;
}
void on_off(void *_d, char *item, int *a, int onoff)
{
int done;
database *d = _d;
int i;
if (item == NULL) {
for (i = 0; i < d->isize; i++) a[i] = onoff;
printf("turning %s all traces\n", onoff ? "ON" : "OFF");
return;
}
done = onoff_group(d, item, a, onoff);
done += onoff_id(d, item, a, onoff);
if (done == 0) {
printf("ERROR: ID/group '%s' not found in database\n", item);
exit(1);
}
}
#include "defs.h"
#include <stdlib.h>
#include <stdio.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
typedef struct databuf {
char *d;
int l;
struct databuf *next;
} databuf;
typedef struct {
int s;
int sc;
pthread_mutex_t lock;
pthread_mutex_t datalock;
pthread_cond_t datacond;
databuf * volatile head, *tail;
} forward_data;
static void *data_sender(void *_f)
{
forward_data *f = _f;
databuf *cur;
char *buf, *b;
int size;
wait:
if (pthread_mutex_lock(&f->datalock)) abort();
while (f->head == NULL)
if (pthread_cond_wait(&f->datacond, &f->datalock)) abort();
cur = f->head;
buf = cur->d;
size = cur->l;
f->head = cur->next;
if (f->head == NULL) f->tail = NULL;
if (pthread_mutex_unlock(&f->datalock)) abort();
free(cur);
goto process;
process:
if (pthread_mutex_lock(&f->lock)) abort();
int *x = (int*)buf;
if (*x < 0 || *x >= 132) printf("bad id %d\n", *x);
printf("DATA_SENDER sends type %d\n", *x);
b = buf;
while (size) {
int l = write(f->s, b, size);
printf("DATA_SENDER write buffer %p len %d returns %d\n", b, size, l);
if (l <= 0) { printf("forward error\n"); exit(1); }
size -= l;
b += l;
}
if (pthread_mutex_unlock(&f->lock)) abort();
free(buf);
goto wait;
}
static void do_forward(forward_data *f, int from, int to, int lock)
{
int l, len;
char *b;
char buf[1024];
while (1) {
len = read(from, buf, 1024);
if (len <= 0) break;
b = buf;
if (lock) if (pthread_mutex_lock(&f->lock)) abort();
while (len) {
l = write(to, b, len);
printf("DO_FORWARD write buffer %p len %d returns %d\n", b, len, l);
if (l <= 0) break;
len -= l;
b += l;
}
if (lock) if (pthread_mutex_unlock(&f->lock)) abort();
}
}
static void *forward_s_to_sc(void *_f)
{
forward_data *f = _f;
do_forward(f, f->s, f->sc, 0);
return NULL;
}
static void *forward_sc_to_s(void *_f)
{
forward_data *f = _f;
do_forward(f, f->sc, f->s, 1);
printf("INFO: forwarder exits\n");
return NULL;
}
void forward_start_client(void *_f, int s)
{
forward_data *f = _f;
f->sc = s;
new_thread(forward_s_to_sc, f);
new_thread(forward_sc_to_s, f);
}
void *forwarder(char *ip, int port)
{
forward_data *f;
struct sockaddr_in a;
f = malloc(sizeof(*f)); if (f == NULL) abort();
pthread_mutex_init(&f->lock, NULL);
pthread_mutex_init(&f->datalock, NULL);
pthread_cond_init(&f->datacond, NULL);
f->sc = -1;
f->head = f->tail = NULL;
f->s = socket(AF_INET, SOCK_STREAM, 0);
if (f->s == -1) { perror("socket"); exit(1); }
a.sin_family = AF_INET;
a.sin_port = htons(port);
a.sin_addr.s_addr = inet_addr(ip);
if (connect(f->s, (struct sockaddr *)&a, sizeof(a)) == -1)
{ perror("connect"); exit(1); }
new_thread(data_sender, f);
return f;
}
void forward(void *_forwarder, char *buf, int size)
{
forward_data *f = _forwarder;
databuf *new;
new = malloc(sizeof(*new)); if (new == NULL) abort();
if (pthread_mutex_lock(&f->datalock)) abort();
new->d = malloc(size); if (new->d == NULL) abort();
memcpy(new->d, buf, size);
new->l = size;
new->next = NULL;
if (f->head == NULL) f->head = new;
f->tail = new;
if (pthread_cond_signal(&f->datacond)) abort();
if (pthread_mutex_unlock(&f->datalock)) abort();
}
......@@ -10,9 +10,7 @@
#include <pthread.h>
#include <inttypes.h>
#define DEFAULT_PORT 2021
#include "../T_defs.h"
#include "T_defs.h"
static T_cache_t *T_cache;
static int T_busylist_head;
......@@ -165,8 +163,6 @@ static void *forwarder(int port, int s)
f->socket_remote = get_connection("127.0.0.1", port);
printf("connected\n");
new_thread(data_sender, f);
new_thread(forward_remote_messages, f);
......@@ -239,38 +235,16 @@ static void init_shm(void)
for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0;
}
static void usage(void)
{
printf(
"tracer - local side\n"
"options:\n"
" -p <port> wait for remote tracer on port <port> (default %d)\n"
" -nowait don't wait for remote tracer, start tracee immediately\n",
DEFAULT_PORT
);
exit(1);
}
int main(int n, char **v)
void T_local_tracer_main(int remote_port, int wait_for_tracer,
int local_socket)
{
int s;
int i;
int port = DEFAULT_PORT;
int local_port = 2020;
int dont_wait = 0;
int port = remote_port;
int dont_wait = wait_for_tracer ? 0 : 1;
void *f;
for (i = 1; i < n; i++) {
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
if (!strcmp(v[i], "-p")) { if (i > n-2) usage();
port = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-nowait")) { dont_wait = 1; continue; }
printf("ERROR: unknown option %s\n", v[i]);
usage();
}
init_shm();
s = get_connection("127.0.0.1", local_port);
s = local_socket;
if (dont_wait) {
char t = 2;
......@@ -289,5 +263,4 @@ int main(int n, char **v)
T_busylist_head++;
T_busylist_head &= T_CACHE_SIZE - 1;
}
return 0;
}
#include "T.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
T_connect_to_tracer("127.0.0.1", 2020);
printf("after connect\n");
while (1) {
char *buf = "hello world %s!\n";
//T(T_first, T_PRINTF("hello world %s!\n", "yo"));
T(T_buf_test, T_BUFFER("hello world %s!\n", strlen(buf)+1));
usleep(1);
}
while (1) pause();
return 0;
}