1#define _GNU_SOURCE
2#include <dlfcn.h>         // dlsym(), dlopen() [OS X]
3#include <stdio.h>
4#include <stdlib.h>
5#include <assert.h>
6#include <stdint.h>
7#include <string.h>
8#include <arpa/inet.h>
9#include <pci/devids.h>
10#include <errors/errno.h>
11#include <sys/mman.h>
12#include <unistd.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15/* #include <fcntl.h> */
16#include "linux_defs.h"
17#include <storage/vsic.h>
18#include <storage/vsa.h>
19
20static int myfd = -1;
21static off_t mypos = 0;
22static FILE *myfile = NULL;
23static struct storage_vsic vsic;
24static struct storage_vsa vsa;
25
26int open64(const char *pathname, int flags, mode_t mode)
27{
28  typedef int (*func_t)(const char *pathname, int flags, mode_t mode);
29  static func_t original = NULL;
30
31  if(original == NULL) {
32    original = (func_t)dlsym(RTLD_NEXT, __func__);
33    assert(original != NULL);
34  }
35
36  if(!strcmp(pathname, "appendonly.aof")) {
37    printf("open64('%s', %d) called\n", pathname, flags);
38    /* int result = original(pathname, flags, mode); */
39    /* myfd = result; */
40    /* return result; */
41    static const char *argv[2] = { "megaraid", "0x37c000" };
42    errval_t err = storage_vsic_driver_init(2, argv, &vsic);
43    assert(err_is_ok(err));
44    err = storage_vsa_acquire(&vsa, "0", 1 * 1024 * 1024);
45    assert(err_is_ok(err));
46    myfd = 100;
47    return myfd;
48  } else {
49    int result = original(pathname, flags, mode);
50    return result;
51  }
52}
53
54FILE *fopen64(const char *path, const char *mode)
55{
56  typedef FILE *(*func_t)(const char *path, const char *mode);
57  static func_t original = NULL;
58
59  if(original == NULL) {
60    original = (func_t)dlsym(RTLD_NEXT, __func__);
61    assert(original != NULL);
62  }
63
64  if(!strcmp(path, "appendonly.aof")) {
65    printf("fopen64('%s', '%s') called from %p\n", path, mode,
66	   __builtin_return_address(0));
67    FILE *result = original(path, mode);
68    myfile = result;
69    return result;
70  } else {
71    FILE *result = original(path, mode);
72    return result;
73  }
74}
75
76#define BUF_SIZE	65536
77
78void *user_alloc(size_t size, uintptr_t *paddr);
79
80ssize_t write(int fd, const void *buf, size_t count)
81{
82  if(fd == myfd) {
83    static uint8_t *mybuf = NULL;
84
85    if(mybuf == NULL) {
86      lpaddr_t paddr;
87      mybuf = user_alloc(BUF_SIZE, &paddr);
88      assert(mybuf != NULL);
89      memset(mybuf, 0, BUF_SIZE);
90    }
91
92    memcpy(mybuf, buf, count);
93
94    size_t mycount = STORAGE_VSIC_ROUND(&vsic, count);
95    /* printf("write on my fd called, count = %zu, mycount = %zu\n", count, mycount); */
96    errval_t err = vsic.ops.write(&vsic, &vsa, mypos, mycount, (void *)mybuf);
97    assert(err_is_ok(err));
98    mypos += mycount;
99    return count;
100  } else {
101    typedef ssize_t (*func_t)(int fd, const void *buf, size_t count);
102    static func_t original = NULL;
103
104    if(original == NULL) {
105      original = (func_t)dlsym(RTLD_NEXT, __func__);
106      assert(original != NULL);
107    }
108
109    return original(fd, buf, count);
110  }
111}
112
113int fdatasync(int fd)
114{
115  if(fd == myfd) {
116    /* printf("fdatasync on my fd called\n"); */
117    errval_t err = vsic.ops.flush(&vsic, &vsa);
118    assert(err_is_ok(err));
119    err = vsic.ops.wait(&vsic);
120    assert(err_is_ok(err));
121    return 0;
122  } else {
123    typedef ssize_t (*func_t)(int fd);
124    static func_t original = NULL;
125
126    if(original == NULL) {
127      original = (func_t)dlsym(RTLD_NEXT, __func__);
128      assert(original != NULL);
129    }
130
131    return original(fd);
132  }
133}
134