Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.o
*.so
cachedel
cachestats
nocache
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ bindir = $(DESTDIR)$(PREFIX)$(BINDIR)
libdir = $(DESTDIR)$(PREFIX)$(LIBDIR)

CACHE_BINS=cachedel cachestats
NOCACHE_BINS=nocache.o fcntl_helpers.o pageinfo.o
NOCACHE_BINS=nocache.o fcntl_helpers.o pageinfo.o wrappers.o
MANPAGES=$(wildcard man/*.1)

CC ?= gcc
CFLAGS+= -Wall
CFLAGS+= -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
COMPILE = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)

.PHONY: all
Expand Down
258 changes: 25 additions & 233 deletions nocache.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
Expand All @@ -15,47 +16,17 @@
#include <assert.h>
#include <signal.h>

#include "wrappers.h"
#include "pageinfo.h"
#include "fcntl_helpers.h"
#include "nocache.h"

static void init(void) __attribute__((constructor));
static void destroy(void) __attribute__((destructor));
static void init_mutexes(void);
static void init_debugging(void);
static void handle_stdout(void);

static void store_pageinfo(int fd);
static void free_unclaimed_pages(int fd, bool block_signals);

int open(const char *pathname, int flags, mode_t mode);
int open64(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, int flags, mode_t mode);
int creat64(const char *pathname, int flags, mode_t mode);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);
int openat64(int dirfd, const char *pathname, int flags, mode_t mode);
int __openat_2(int dirfd, const char *pathname, int flags, mode_t mode)
__attribute__ ((alias ("openat")));
int dup(int oldfd);
int dup2(int oldfd, int newfd);
int close(int fd);
FILE *fopen(const char *path, const char *mode);
FILE *fopen64(const char *path, const char *mode);
int fclose(FILE *fp);

int (*_original_open)(const char *pathname, int flags, mode_t mode);
int (*_original_open64)(const char *pathname, int flags, mode_t mode);
int (*_original_creat)(const char *pathname, int flags, mode_t mode);
int (*_original_creat64)(const char *pathname, int flags, mode_t mode);
int (*_original_openat)(int dirfd, const char *pathname, int flags, mode_t mode);
int (*_original_openat64)(int dirfd, const char *pathname, int flags, mode_t mode);
int (*_original_dup)(int fd);
int (*_original_dup2)(int newfd, int oldfd);
int (*_original_close)(int fd);
FILE *(*_original_fopen)(const char *path, const char *mode);
FILE *(*_original_fopen64)(const char *path, const char *mode);
int (*_original_fclose)(FILE *fp);


/* Info about a file descriptor 'fd' is stored in fds[fd]. Before accessing an
* element, callers MUST both check fds_lock != NULL and then acquire
* fds_lock[fd] while holding the fds_iter_lock. While any mutex in fds_lock is
Expand All @@ -70,22 +41,33 @@ static size_t PAGESIZE;
static char *env_nr_fadvise = "NOCACHE_NR_FADVISE";
static int nr_fadvise;

int nocache_EOF;

static char *env_debugfd = "NOCACHE_DEBUGFD";
int debugfd = -1;
FILE *debugfp;
static int debugfd = -1;
static FILE *debugfp;

static char *env_flushall = "NOCACHE_FLUSHALL";
static char flushall;

static char *env_max_fds = "NOCACHE_MAX_FDS";
static rlim_t max_fd_limit = 1 << 20;

#define DEBUG(...) \
do { \
if(debugfp != NULL) { \
fprintf(debugfp, "[nocache] DEBUG: " __VA_ARGS__); \
} \
} while(0)
int nocache_fileno(FILE *fp)
{
return fileno(fp);
}

void debug(const char *fmt, ...)
{
if(debugfp != NULL) {
va_list args;

va_start(args, fmt);
vfprintf(debugfp, fmt, args);
va_end(args);
}
}

static void init(void)
{
Expand Down Expand Up @@ -141,6 +123,7 @@ static void init(void)
}

PAGESIZE = getpagesize();
nocache_EOF = EOF;
pthread_mutex_lock(&fds_iter_lock);
for(i = 0; i < max_fds; i++) {
pthread_mutex_lock(&fds_lock[i]);
Expand Down Expand Up @@ -232,198 +215,7 @@ static void destroy(void)
pthread_mutex_unlock(&fds_iter_lock);
}

int open(const char *pathname, int flags, mode_t mode)
{
int fd;

if(!_original_open)
_original_open = (int (*)(const char *, int, mode_t)) dlsym(RTLD_NEXT, "open");
assert(_original_open != NULL);

if((fd = _original_open(pathname, flags, mode)) != -1) {
DEBUG("open(pathname=%s, flags=0x%x, mode=0%o) = %d\n",
pathname, flags, mode, fd);
store_pageinfo(fd);
}
return fd;
}

int open64(const char *pathname, int flags, mode_t mode)
{
int fd;

if(!_original_open64)
_original_open64 = (int (*)(const char *, int, mode_t)) dlsym(RTLD_NEXT, "open64");
assert(_original_open64 != NULL);

DEBUG("open64(pathname=%s, flags=0x%x, mode=0%o)\n", pathname, flags, mode);

if((fd = _original_open64(pathname, flags, mode)) != -1)
store_pageinfo(fd);
return fd;
}

int creat(const char *pathname, int flags, mode_t mode)
{
int fd;

if(!_original_creat)
_original_creat = (int (*)(const char *, int, mode_t)) dlsym(RTLD_NEXT, "creat");
assert(_original_creat != NULL);

DEBUG("creat(pathname=%s, flags=0x%x, mode=0%o)\n", pathname, flags, mode);

if((fd = _original_creat(pathname, flags, mode)) != -1)
store_pageinfo(fd);
return fd;
}

int creat64(const char *pathname, int flags, mode_t mode)
{
int fd;

if(!_original_creat64)
_original_creat64 = (int (*)(const char *, int, mode_t)) dlsym(RTLD_NEXT, "creat64");
assert(_original_creat64 != NULL);

DEBUG("creat64(pathname=%s, flags=0x%x, mode=0%o)\n", pathname, flags, mode);

if((fd = _original_creat64(pathname, flags, mode)) != -1)
store_pageinfo(fd);
return fd;
}

int openat(int dirfd, const char *pathname, int flags, mode_t mode)
{
int fd;

if(!_original_openat)
_original_openat = (int (*)(int, const char *, int, mode_t)) dlsym(RTLD_NEXT, "openat");
assert(_original_openat != NULL);

DEBUG("openat(dirfd=%d, pathname=%s, flags=0x%x, mode=0%o)\n", dirfd, pathname, flags, mode);

if((fd = _original_openat(dirfd, pathname, flags, mode)) != -1)
store_pageinfo(fd);
return fd;
}

int openat64(int dirfd, const char *pathname, int flags, mode_t mode)
{
int fd;

if(!_original_openat64)
_original_openat64 = (int (*)(int, const char *, int, mode_t)) dlsym(RTLD_NEXT, "openat64");
assert(_original_openat64 != NULL);

DEBUG("openat64(dirfd=%d, pathname=%s, flags=0x%x, mode=0%o)\n", dirfd, pathname, flags, mode);

if((fd = _original_openat64(dirfd, pathname, flags, mode)) != -1)
store_pageinfo(fd);
return fd;
}

int dup(int oldfd)
{
int fd;

if(!_original_dup)
_original_dup = (int (*)(int)) dlsym(RTLD_NEXT, "dup");
assert(_original_dup != NULL);

DEBUG("dup(oldfd=%d)\n", oldfd);

if((fd = _original_dup(oldfd)) != -1)
store_pageinfo(fd);
return fd;
}

int dup2(int oldfd, int newfd)
{
int ret;

/* if newfd is already opened, the kernel will close it directly
* once dup2 is invoked. So now is the last chance to mark the
* pages as "DONTNEED" */
if(valid_fd(newfd))
free_unclaimed_pages(newfd, true);

if(!_original_dup2)
_original_dup2 = (int (*)(int, int)) dlsym(RTLD_NEXT, "dup2");
assert(_original_dup2 != NULL);

DEBUG("dup2(oldfd=%d, newfd=%d)\n", oldfd, newfd);

if((ret = _original_dup2(oldfd, newfd)) != -1)
store_pageinfo(newfd);
return ret;
}

int close(int fd)
{
if(!_original_close)
_original_close = (int (*)(int)) dlsym(RTLD_NEXT, "close");
assert(_original_close != NULL);

free_unclaimed_pages(fd, true);

DEBUG("close(%d)\n", fd);
return _original_close(fd);
}

FILE *fopen(const char *path, const char *mode)
{
int fd;
FILE *fp = NULL;

if(!_original_fopen)
_original_fopen = (FILE *(*)(const char *, const char *)) dlsym(RTLD_NEXT, "fopen");
assert(_original_fopen != NULL);

DEBUG("fopen(path=%s, mode=%s)\n", path, mode);

if((fp = _original_fopen(path, mode)) != NULL)
if((fd = fileno(fp)) != -1)
store_pageinfo(fd);

return fp;
}

FILE *fopen64(const char *path, const char *mode)
{
int fd;
FILE *fp;
fp = NULL;

if(!_original_fopen64)
_original_fopen64 = (FILE *(*)(const char *, const char *)) dlsym(RTLD_NEXT, "fopen64");
assert(_original_fopen64 != NULL);

DEBUG("fopen64(path=%s, mode=%s)\n", path, mode);

if((fp = _original_fopen64(path, mode)) != NULL)
if((fd = fileno(fp)) != -1)
store_pageinfo(fd);

return fp;
}

int fclose(FILE *fp)
{
if(!_original_fclose)
_original_fclose = (int (*)(FILE *)) dlsym(RTLD_NEXT, "fclose");
assert(_original_fclose != NULL);

if(_original_fclose) {
free_unclaimed_pages(fileno(fp), true);
return _original_fclose(fp);
}

errno = EFAULT;
return EOF;
}

static void store_pageinfo(int fd)
void store_pageinfo(int fd)
{
sigset_t mask, old_mask;

Expand Down Expand Up @@ -472,7 +264,7 @@ static void store_pageinfo(int fd)
return;
}

static void free_unclaimed_pages(int fd, bool block_signals)
void free_unclaimed_pages(int fd, bool block_signals)
{
struct stat st;
sigset_t mask, old_mask;
Expand Down
17 changes: 17 additions & 0 deletions nocache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef NOCACHE_H
#define NOCACHE_H

#include <stdbool.h>

#define DEBUG(...) \
debug("[nocache] DEBUG: " __VA_ARGS__)

void debug(const char *fmt, ...);

extern int nocache_EOF;
int nocache_fileno(FILE *fp);

void store_pageinfo(int fd);
void free_unclaimed_pages(int fd, bool block_signals);

#endif
9 changes: 1 addition & 8 deletions pageinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,7 @@
#include <string.h>

#include "pageinfo.h"

extern FILE *debugfp;
#define DEBUG(...) \
do { \
if(debugfp != NULL) { \
fprintf(debugfp, "[nocache] DEBUG: " __VA_ARGS__); \
} \
} while(0)
#include "nocache.h"

static int insert_into_br_list(struct file_pageinfo *pi,
struct byterange **brtail, size_t pos, size_t len);
Expand Down
Loading