* Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
/* Get the next sub buffer that can be read. */
#define RELAYFS_GET_SUBBUF _IOR(0xF4, 0x00,__u32)
/* Release the oldest reserved (by "get") sub buffer. */
-#define RELAYFS_PUT_SUBBUF _IO(0xF4, 0x01)
+#define RELAYFS_PUT_SUBBUF _IOW(0xF4, 0x01,__u32)
/* returns the number of sub buffers in the per cpu channel. */
#define RELAYFS_GET_N_SUBBUFS _IOR(0xF4, 0x02,__u32)
/* returns the size of the sub buffers. */
* -c directory Root directory of the relayfs trace channels.
* -d Run in background (daemon).
* -a Trace append mode.
+ * -s Send SIGUSR1 to parent when ready for IO.
*/
void show_arguments(void)
{
char path_trace[PATH_MAX];
int path_trace_len;
char *path_trace_ptr;
+ int open_ret = 0;
if(channel_dir == NULL) {
perror(subchannel_name);
- return ENOENT;
+ open_ret = ENOENT;
+ goto end;
}
printf("Creating trace subdirectory %s\n", subtrace_name);
ret = mkdir(subtrace_name, S_IRWXU|S_IRWXG|S_IRWXO);
if(ret == -1) {
- if(errno == EEXIST && append_mode) {
- printf("Appending to directory %s as resquested\n", subtrace_name);
- } else {
+ if(errno != EEXIST) {
perror(subtrace_name);
- return -1;
+ open_ret = -1;
+ goto end;
}
}
open(path_channel, O_RDONLY | O_NONBLOCK);
if(fd_pairs->pair[fd_pairs->num_pairs-1].channel == -1) {
perror(path_channel);
+ fd_pairs->num_pairs--;
+ continue;
}
/* Open the trace in write mode, only append if append_mode */
ret = stat(path_trace, &stat_buf);
}
} else {
printf("File %s exists, cannot open. Try append mode.\n", path_trace);
- return -1;
+ open_ret = -1;
+ goto end;
}
} else {
if(errno == ENOENT) {
}
}
+end:
closedir(channel_dir);
- return 0;
+ return open_ret;
}
int read_subbuffer(struct fd_pair *pair)
{
- unsigned int subbuf_index;
- int ret;
+ unsigned int consumed_old;
+ int err, ret;
- ret = ioctl(pair->channel, RELAYFS_GET_SUBBUF,
- &subbuf_index);
- if(ret != 0) {
+ err = ioctl(pair->channel, RELAYFS_GET_SUBBUF,
+ &consumed_old);
+ printf("cookie : %u\n", consumed_old);
+ if(err != 0) {
perror("Error in reserving sub buffer");
- goto error;
+ ret = -EPERM;
+ goto get_error;
}
-
- ret = TEMP_FAILURE_RETRY(write(pair->trace,
- pair->mmap + (subbuf_index * pair->subbuf_size),
- pair->subbuf_size));
- if(ret < 0) {
+ err = TEMP_FAILURE_RETRY(write(pair->trace,
+ pair->mmap + (consumed_old & (~(pair->subbuf_size-1))),
+ pair->subbuf_size));
+
+ if(err < 0) {
perror("Error in writing to file");
- goto error;
+ ret = err;
+ goto write_error;
}
- ret = ioctl(pair->channel, RELAYFS_PUT_SUBBUF);
- if(ret != 0) {
- perror("Error in unreserving sub buffer");
- goto error;
+write_error:
+ err = ioctl(pair->channel, RELAYFS_PUT_SUBBUF, &consumed_old);
+ if(err != 0) {
+ if(errno == -EFAULT) {
+ perror("Error in unreserving sub buffer");
+ ret = -EFAULT;
+ } else if(errno == -EIO) {
+ perror("Reader has been pushed by the writer, last subbuffer corrupted.");
+ ret = -EIO;
+ }
+ goto get_error;
}
- return 0;
-error:
- return -1;
+get_error:
+ return ret;
}
int high_prio;
int ret;
+ if(fd_pairs->num_pairs <= 0) {
+ printf("No channel to read\n");
+ goto end;
+ }
+
/* Get the subbuf sizes and number */
for(i=0;i<fd_pairs->num_pairs;i++) {
printf("Press a key for next poll...\n");
char buf[1];
read(STDIN_FILENO, &buf, 1);
- printf("Next poll :\n");
+ printf("Next poll (polling %d fd) :\n", fd_pairs->num_pairs);
#endif //DEBUG
/* Have we received a signal ? */
int main(int argc, char ** argv)
{
int ret;
- pid_t pid;
struct channel_trace_fd fd_pairs = { NULL, 0 };
struct sigaction act;
show_info();
if(daemon_mode) {
- pid = fork();
-
- if(pid > 0) {
- /* parent */
- return 0;
- } else if(pid < 0) {
- /* error */
- printf("An error occured while forking.\n");
- return -1;
- }
- /* else, we are the child, continue... */
- }
+ ret = daemon(0, 0);
+
+ if(ret == -1) {
+ perror("An error occured while daemonizing.");
+ exit(-1);
+ }
+ }
/* Connect the signal handlers */
act.sa_handler = handler;