+ return open_ret;
+}
+
+
+int read_subbuffer(struct fd_pair *pair)
+{
+ unsigned int consumed_old;
+ int err, ret=0;
+
+
+ err = ioctl(pair->channel, RELAYFS_GET_SUBBUF,
+ &consumed_old);
+ printf("cookie : %u\n", consumed_old);
+ if(err != 0) {
+ ret = errno;
+ perror("Reserving sub buffer failed (everything is normal)");
+ goto get_error;
+ }
+
+ err = TEMP_FAILURE_RETRY(write(pair->trace,
+ pair->mmap
+ + (consumed_old & ((pair->n_subbufs * pair->subbuf_size)-1)),
+ pair->subbuf_size));
+
+ if(err < 0) {
+ ret = errno;
+ perror("Error in writing to file");
+ goto write_error;
+ }
+#if 0
+ err = fsync(pair->trace);
+ if(err < 0) {
+ ret = errno;
+ perror("Error in writing to file");
+ goto write_error;
+ }
+#endif //0
+write_error:
+ err = ioctl(pair->channel, RELAYFS_PUT_SUBBUF, &consumed_old);
+ if(err != 0) {
+ ret = errno;
+ if(errno == -EFAULT) {
+ perror("Error in unreserving sub buffer\n");
+ } else if(errno == -EIO) {
+ perror("Reader has been pushed by the writer, last subbuffer corrupted.");
+ /* FIXME : we may delete the last written buffer if we wish. */
+ }
+ goto get_error;
+ }
+
+get_error:
+ return ret;
+}
+
+
+
+int map_channels(struct channel_trace_fd *fd_pairs)
+{
+ int i,j;
+ int ret=0;
+
+ 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++) {
+ struct fd_pair *pair = &fd_pairs->pair[i];
+
+ ret = ioctl(pair->channel, RELAYFS_GET_N_SUBBUFS,
+ &pair->n_subbufs);
+ if(ret != 0) {
+ perror("Error in getting the number of subbuffers");
+ goto end;
+ }
+ ret = ioctl(pair->channel, RELAYFS_GET_SUBBUF_SIZE,
+ &pair->subbuf_size);
+ if(ret != 0) {
+ perror("Error in getting the size of the subbuffers");
+ goto end;
+ }
+ ret = pthread_mutex_init(&pair->mutex, NULL); /* Fast mutex */
+ if(ret != 0) {
+ perror("Error in mutex init");
+ goto end;
+ }
+ }
+
+ /* Mmap each FD */
+ for(i=0;i<fd_pairs->num_pairs;i++) {
+ struct fd_pair *pair = &fd_pairs->pair[i];
+
+ pair->mmap = mmap(0, pair->subbuf_size * pair->n_subbufs, PROT_READ,
+ MAP_SHARED, pair->channel, 0);
+ if(pair->mmap == MAP_FAILED) {
+ perror("Mmap error");
+ goto munmap;
+ }
+ }
+
+ goto end; /* success */
+
+ /* Error handling */
+ /* munmap only the successfully mmapped indexes */
+munmap:
+ /* Munmap each FD */
+ for(j=0;j<i;j++) {
+ struct fd_pair *pair = &fd_pairs->pair[j];
+ int err_ret;
+
+ err_ret = munmap(pair->mmap, pair->subbuf_size * pair->n_subbufs);
+ if(err_ret != 0) {
+ perror("Error in munmap");
+ }
+ ret |= err_ret;
+ }
+
+end:
+ return ret;
+
+
+}
+
+
+int unmap_channels(struct channel_trace_fd *fd_pairs)
+{
+ int j;
+ int ret=0;
+
+ /* Munmap each FD */
+ for(j=0;j<fd_pairs->num_pairs;j++) {
+ struct fd_pair *pair = &fd_pairs->pair[j];
+ int err_ret;
+
+ err_ret = munmap(pair->mmap, pair->subbuf_size * pair->n_subbufs);
+ if(err_ret != 0) {
+ perror("Error in munmap");
+ }
+ ret |= err_ret;
+ err_ret = pthread_mutex_destroy(&pair->mutex);
+ if(err_ret != 0) {
+ perror("Error in mutex destroy");
+ }
+ ret |= err_ret;
+ }
+
+ return ret;