X-Git-Url: https://git.liburcu.org/?p=ltt-control.git;a=blobdiff_plain;f=liblttd%2Fliblttd.c;h=2b187c85860996f7304352453a649b0502967e24;hp=0f703f57b32f1f351df95a1be7f91833ac63914b;hb=HEAD;hpb=d6d516b717dfb30a882178494203bf4ceb4810fe diff --git a/liblttd/liblttd.c b/liblttd/liblttd.c index 0f703f5..2b187c8 100644 --- a/liblttd/liblttd.c +++ b/liblttd/liblttd.c @@ -1,4 +1,4 @@ -/* lttd +/* liblttd * * Linux Trace Toolkit Daemon * @@ -9,6 +9,23 @@ * * Copyright 2005 - * Mathieu Desnoyers + * Copyright 2010 - + * Michael Sills-Lavoie + * Oumarou Dicko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H @@ -75,40 +92,6 @@ static inline int inotify_rm_watch (int fd, __u32 wd) #undef HAS_INOTIFY #endif -struct channel_trace_fd { - struct fd_pair *pair; - int num_pairs; -}; - -struct inotify_watch { - int wd; - char path_channel[PATH_MAX]; - char *base_path_channel; -}; - -struct inotify_watch_array { - struct inotify_watch *elem; - int num; -}; - -struct liblttd_instance { - struct liblttd_callbacks *callbacks; - - int inotify_fd; - struct channel_trace_fd fd_pairs; - struct inotify_watch_array inotify_watch_array; - - /* protects fd_pairs and inotify_watch_array */ - pthread_rwlock_t fd_pairs_lock; - - char channel_name[PATH_MAX]; - unsigned long num_threads; - int quit_program; /* For signal handler */ - int dump_flight_only; - int dump_normal_only; - int verbose_mode; -}; - struct liblttd_thread_data { int thread_num; struct liblttd_instance *instance; @@ -126,15 +109,16 @@ int open_buffer_file(struct liblttd_instance *instance, char *filename, { int open_ret = 0; int ret = 0; + int fd; - if(strncmp(filename, "flight-", sizeof("flight-")-1) != 0) { - if(instance->dump_flight_only) { + if (strncmp(filename, "flight-", sizeof("flight-")-1) != 0) { + if (instance->dump_flight_only) { printf_verbose("Skipping normal channel %s\n", path_channel); return 0; } } else { - if(instance->dump_normal_only) { + if (instance->dump_normal_only) { printf_verbose("Skipping flight channel %s\n", path_channel); return 0; @@ -146,19 +130,20 @@ int open_buffer_file(struct liblttd_instance *instance, char *filename, ++instance->fd_pairs.num_pairs * sizeof(struct fd_pair)); /* Open the channel in read mode */ - instance->fd_pairs.pair[instance->fd_pairs.num_pairs-1].channel = - open(path_channel, O_RDONLY | O_NONBLOCK); - if(instance->fd_pairs.pair[instance->fd_pairs.num_pairs-1].channel == -1) { + fd = open(path_channel, O_RDONLY | O_NONBLOCK); + instance->fd_pairs.pair[instance->fd_pairs.num_pairs-1].channel = fd; + + if (instance->fd_pairs.pair[instance->fd_pairs.num_pairs-1].channel == -1) { perror(path_channel); instance->fd_pairs.num_pairs--; return 0; /* continue */ } - if(instance->callbacks->on_open_channel) ret = instance->callbacks->on_open_channel( + if (instance->callbacks->on_open_channel) ret = instance->callbacks->on_open_channel( instance->callbacks, &instance->fd_pairs.pair[instance->fd_pairs.num_pairs-1], base_path_channel); - if(ret != 0) { + if (ret != 0) { open_ret = -1; close(instance->fd_pairs.pair[instance->fd_pairs.num_pairs-1].channel); instance->fd_pairs.num_pairs--; @@ -183,17 +168,17 @@ int open_channel_trace_pairs(struct liblttd_instance *instance, int open_ret = 0; - if(channel_dir == NULL) { + if (channel_dir == NULL) { perror(subchannel_name); open_ret = ENOENT; goto end; } - printf_verbose("Calling on new channels folder\n"); - if(instance->callbacks->on_new_channels_folder) ret = instance->callbacks-> + printf_verbose("Calling : on new channels folder\n"); + if (instance->callbacks->on_new_channels_folder) ret = instance->callbacks-> on_new_channels_folder(instance->callbacks, base_subchannel_name); - if(ret == -1) { + if (ret == -1) { open_ret = -1; goto end; } @@ -223,27 +208,27 @@ int open_channel_trace_pairs(struct liblttd_instance *instance, while((entry = readdir(channel_dir)) != NULL) { - if(entry->d_name[0] == '.') continue; + if (entry->d_name[0] == '.') continue; strncpy(path_channel_ptr, entry->d_name, PATH_MAX - path_channel_len); ret = stat(path_channel, &stat_buf); - if(ret == -1) { + if (ret == -1) { perror(path_channel); continue; } printf_verbose("Channel file : %s\n", path_channel); - if(S_ISDIR(stat_buf.st_mode)) { + if (S_ISDIR(stat_buf.st_mode)) { printf_verbose("Entering channel subdirectory...\n"); ret = open_channel_trace_pairs(instance, path_channel, base_subchannel_ptr); - if(ret < 0) continue; - } else if(S_ISREG(stat_buf.st_mode)) { + if (ret < 0) continue; + } else if (S_ISREG(stat_buf.st_mode)) { open_ret = open_buffer_file(instance, entry->d_name, path_channel, base_subchannel_ptr); - if(open_ret) + if (open_ret) goto end; } } @@ -262,33 +247,33 @@ int read_subbuffer(struct liblttd_instance *instance, struct fd_pair *pair) long ret; off_t offset; - err = ioctl(pair->channel, RELAY_GET_SB, &consumed_old); printf_verbose("cookie : %u\n", consumed_old); - if(err != 0) { + if (err != 0) { ret = errno; perror("Reserving sub buffer failed (everything is normal, it is due to concurrency)"); goto get_error; } err = ioctl(pair->channel, RELAY_GET_SB_SIZE, &len); - if(err != 0) { + if (err != 0) { ret = errno; perror("Getting sub-buffer len failed."); goto get_error; } - if(instance->callbacks->on_read_subbuffer) ret = instance->callbacks->on_read_subbuffer( - instance->callbacks, pair, len); + if (instance->callbacks->on_read_subbuffer) + ret = instance->callbacks->on_read_subbuffer( + instance->callbacks, pair, len); write_error: ret = 0; err = ioctl(pair->channel, RELAY_PUT_SB, &consumed_old); - if(err != 0) { + if (err != 0) { ret = errno; - if(errno == EFAULT) { + if (errno == EFAULT) { perror("Error in unreserving sub buffer\n"); - } else if(errno == EIO) { + } else if (errno == EIO) { /* Should never happen with newer LTTng versions */ perror("Reader has been pushed by the writer, last sub-buffer corrupted."); } @@ -305,7 +290,7 @@ int map_channels(struct liblttd_instance *instance, int idx_begin, int idx_end) int i,j; int ret=0; - if(instance->fd_pairs.num_pairs <= 0) { + if (instance->fd_pairs.num_pairs <= 0) { printf("No channel to read\n"); goto end; } @@ -316,18 +301,18 @@ int map_channels(struct liblttd_instance *instance, int idx_begin, int idx_end) struct fd_pair *pair = &instance->fd_pairs.pair[i]; ret = ioctl(pair->channel, RELAY_GET_N_SB, &pair->n_sb); - if(ret != 0) { + if (ret != 0) { perror("Error in getting the number of sub-buffers"); goto end; } ret = ioctl(pair->channel, RELAY_GET_MAX_SB_SIZE, &pair->max_sb_size); - if(ret != 0) { + if (ret != 0) { perror("Error in getting the max sub-buffer size"); goto end; } ret = pthread_mutex_init(&pair->mutex, NULL); /* Fast mutex */ - if(ret != 0) { + if (ret != 0) { perror("Error in mutex init"); goto end; } @@ -348,7 +333,7 @@ int unmap_channels(struct liblttd_instance *instance) int err_ret; err_ret = pthread_mutex_destroy(&pair->mutex); - if(err_ret != 0) { + if (err_ret != 0) { perror("Error in mutex destroy"); } ret |= err_ret; @@ -375,9 +360,9 @@ int read_inotify(struct liblttd_instance *instance) offset = 0; len = read(instance->inotify_fd, buf, sizeof(struct inotify_event) + PATH_MAX); - if(len < 0) { + if (len < 0) { - if(errno == EAGAIN) + if (errno == EAGAIN) return 0; /* another thread got the data before us */ printf("Error in read from inotify FD %s.\n", strerror(len)); @@ -386,7 +371,7 @@ int read_inotify(struct liblttd_instance *instance) while(offset < len) { ievent = (struct inotify_event *)&(buf[offset]); for(i=0; iinotify_watch_array.num; i++) { - if(instance->inotify_watch_array.elem[i].wd == ievent->wd && + if (instance->inotify_watch_array.elem[i].wd == ievent->wd && ievent->mask == IN_CREATE) { printf_verbose( "inotify wd %u event mask : %u for %s%s\n", @@ -396,13 +381,13 @@ int read_inotify(struct liblttd_instance *instance) old_num = instance->fd_pairs.num_pairs; strcpy(path_channel, instance->inotify_watch_array.elem[i].path_channel); strcat(path_channel, ievent->name); - if(ret = open_buffer_file(instance, ievent->name, path_channel, + if (ret = open_buffer_file(instance, ievent->name, path_channel, path_channel + (instance->inotify_watch_array.elem[i].base_path_channel - instance->inotify_watch_array.elem[i].path_channel))) { printf("Error opening buffer file\n"); return -1; } - if(ret = map_channels(instance, old_num, instance->fd_pairs.num_pairs)) { + if (ret = map_channels(instance, old_num, instance->fd_pairs.num_pairs)) { printf("Error mapping channel\n"); return -1; } @@ -414,7 +399,8 @@ int read_inotify(struct liblttd_instance *instance) } #endif //HAS_INOTIFY -/* read_channels +/* + * read_channels * * Thread worker. * @@ -479,11 +465,11 @@ int read_channels(struct liblttd_instance *instance, unsigned long thread_num) #endif //DEBUG /* Have we received a signal ? */ - if(instance->quit_program) break; + if (instance->quit_program) break; num_rdy = poll(pollfd, num_pollfd, -1); - if(num_rdy == -1) { + if (num_rdy == -1) { perror("Poll error"); goto free_fd; } @@ -542,7 +528,7 @@ int read_channels(struct liblttd_instance *instance, unsigned long thread_num) break; case POLLPRI: pthread_rwlock_rdlock(&instance->fd_pairs_lock); - if(pthread_mutex_trylock(&instance->fd_pairs.pair[i-inotify_fds].mutex) == 0) { + if (pthread_mutex_trylock(&instance->fd_pairs.pair[i-inotify_fds].mutex) == 0) { printf_verbose( "Urgent read on fd %d\n", pollfd[i].fd); @@ -550,10 +536,10 @@ int read_channels(struct liblttd_instance *instance, unsigned long thread_num) high_prio = 1; /* it's ok to have an unavailable sub-buffer */ ret = read_subbuffer(instance, &instance->fd_pairs.pair[i-inotify_fds]); - if(ret == EAGAIN) ret = 0; + if (ret == EAGAIN) ret = 0; ret = pthread_mutex_unlock(&instance->fd_pairs.pair[i-inotify_fds].mutex); - if(ret) + if (ret) printf("Error in mutex unlock : %s\n", strerror(ret)); } pthread_rwlock_unlock(&instance->fd_pairs_lock); @@ -561,24 +547,24 @@ int read_channels(struct liblttd_instance *instance, unsigned long thread_num) } } /* If every buffer FD has hung up, we end the read loop here */ - if(num_hup == num_pollfd - inotify_fds) break; + if (num_hup == num_pollfd - inotify_fds) break; - if(!high_prio) { + if (!high_prio) { for(i=inotify_fds;ifd_pairs_lock); - if(pthread_mutex_trylock(&instance->fd_pairs.pair[i-inotify_fds].mutex) == 0) { + if (pthread_mutex_trylock(&instance->fd_pairs.pair[i-inotify_fds].mutex) == 0) { /* Take care of low priority channels. */ printf_verbose( "Normal read on fd %d\n", pollfd[i].fd); /* it's ok to have an unavailable subbuffer */ ret = read_subbuffer(instance, &instance->fd_pairs.pair[i-inotify_fds]); - if(ret == EAGAIN) ret = 0; + if (ret == EAGAIN) ret = 0; ret = pthread_mutex_unlock(&instance->fd_pairs.pair[i-inotify_fds].mutex); - if(ret) + if (ret) printf("Error in mutex unlock : %s\n", strerror(ret)); } pthread_rwlock_unlock(&instance->fd_pairs_lock); @@ -589,7 +575,7 @@ int read_channels(struct liblttd_instance *instance, unsigned long thread_num) /* Update pollfd array if an entry was added to fd_pairs */ pthread_rwlock_rdlock(&instance->fd_pairs_lock); - if((inotify_fds + instance->fd_pairs.num_pairs) != num_pollfd) { + if ((inotify_fds + instance->fd_pairs.num_pairs) != num_pollfd) { pollfd = realloc(pollfd, (inotify_fds + instance->fd_pairs.num_pairs) * sizeof(struct pollfd)); for(i=num_pollfd-inotify_fds;ifd_pairs.num_pairs;i++) { @@ -626,11 +612,11 @@ void close_channel_trace_pairs(struct liblttd_instance *instance) for(i=0;ifd_pairs.num_pairs;i++) { ret = close(instance->fd_pairs.pair[i].channel); - if(ret == -1) perror("Close error on channel"); - if(instance->callbacks->on_close_channel) { + if (ret == -1) perror("Close error on channel"); + if (instance->callbacks->on_close_channel) { ret = instance->callbacks->on_close_channel( instance->callbacks, &instance->fd_pairs.pair[i]); - if(ret != 0) perror("Error on close channel callback"); + if (ret != 0) perror("Error on close channel callback"); } } free(instance->fd_pairs.pair); @@ -643,7 +629,7 @@ void * thread_main(void *arg) long ret = 0; struct liblttd_thread_data *thread_data = (struct liblttd_thread_data*) arg; - if(thread_data->instance->callbacks->on_new_thread) + if (thread_data->instance->callbacks->on_new_thread) ret = thread_data->instance->callbacks->on_new_thread( thread_data->instance->callbacks, thread_data->thread_num); @@ -652,7 +638,7 @@ void * thread_main(void *arg) } ret = read_channels(thread_data->instance, thread_data->thread_num); - if(thread_data->instance->callbacks->on_close_thread) + if (thread_data->instance->callbacks->on_close_thread) thread_data->instance->callbacks->on_close_thread( thread_data->instance->callbacks, thread_data->thread_num); @@ -668,7 +654,7 @@ int channels_init(struct liblttd_instance *instance) instance->inotify_fd = inotify_init(); fcntl(instance->inotify_fd, F_SETFL, O_NONBLOCK); - if(ret = open_channel_trace_pairs(instance, instance->channel_name, + if (ret = open_channel_trace_pairs(instance, instance->channel_name, instance->channel_name + strlen(instance->channel_name))) goto close_channel; @@ -678,13 +664,13 @@ int channels_init(struct liblttd_instance *instance) goto close_channel; } - if(ret = map_channels(instance, 0, instance->fd_pairs.num_pairs)) + if (ret = map_channels(instance, 0, instance->fd_pairs.num_pairs)) goto close_channel; return 0; close_channel: close_channel_trace_pairs(instance); - if(instance->inotify_fd >= 0) + if (instance->inotify_fd >= 0) close(instance->inotify_fd); return ret; } @@ -703,10 +689,10 @@ int liblttd_start_instance(struct liblttd_instance *instance) unsigned long i; void *tret; - if(!instance) + if (!instance) return -EINVAL; - if(ret = channels_init(instance)) + if (ret = channels_init(instance)) return ret; tids = malloc(sizeof(pthread_t) * instance->num_threads); @@ -717,7 +703,7 @@ int liblttd_start_instance(struct liblttd_instance *instance) thread_data->instance = instance; ret = pthread_create(&tids[i], NULL, thread_main, thread_data); - if(ret) { + if (ret) { perror("Error creating thread"); break; } @@ -725,11 +711,11 @@ int liblttd_start_instance(struct liblttd_instance *instance) for(i=0; inum_threads; i++) { ret = pthread_join(tids[i], &tret); - if(ret) { + if (ret) { perror("Error joining thread"); break; } - if((long)tret != 0) { + if ((long)tret != 0) { printf("Error %s occured in thread %ld\n", strerror((long)tret), i); } @@ -738,11 +724,11 @@ int liblttd_start_instance(struct liblttd_instance *instance) free(tids); ret = unmap_channels(instance); close_channel_trace_pairs(instance); - if(instance->inotify_fd >= 0) + if (instance->inotify_fd >= 0) close(instance->inotify_fd); - if(instance->callbacks->on_trace_end) - instance->callbacks->on_trace_end(instance->callbacks); + if (instance->callbacks->on_trace_end) + instance->callbacks->on_trace_end(instance); delete_instance(instance); @@ -754,12 +740,17 @@ struct liblttd_instance * liblttd_new_instance( unsigned long n_threads, int flight_only, int normal_only, int verbose) { struct liblttd_instance * instance; - if(!channel_path || !callbacks) return NULL; - if(n_threads == 0) n_threads = 1; - if(flight_only && normal_only) return NULL; + + if (!channel_path || !callbacks) + return NULL; + if (n_threads == 0) + n_threads = 1; + if (flight_only && normal_only) + return NULL; instance = malloc(sizeof(struct liblttd_instance)); - if(!instance) return NULL; + if (!instance) + return NULL; instance->callbacks = callbacks; @@ -778,6 +769,7 @@ struct liblttd_instance * liblttd_new_instance( instance->dump_flight_only = flight_only; instance->dump_normal_only = normal_only; instance->verbose_mode = verbose; + instance->quit_program = 0; return instance; }