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