Commit e033127e authored by Julius Plenz's avatar Julius Plenz

Intercept dup2()

Thus, also shell redirection -- which makes heavy use of dup2() -- is handled correctly: $ cachestats /tmp/foo open: No such file or directory $ nocache sh -c 'echo foo > /tmp/foo' $ cachestats /tmp/foo pages in cache: 0/1 (0.0%) [filesize=0.0K, pagesize=4K]
parent d355dafd
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
/* Since open() and close() are re-defined in nocache.c, it's not /* Since open() and close() are re-defined in nocache.c, it's not
* possible to include <fcntl.h> there. So we do it here. */ * possible to include <fcntl.h> there. So we do it here. */
...@@ -14,6 +15,12 @@ int fadv_noreuse(int fd, off_t offset, off_t len) ...@@ -14,6 +15,12 @@ int fadv_noreuse(int fd, off_t offset, off_t len)
return posix_fadvise(fd, offset, len, POSIX_FADV_NOREUSE); return posix_fadvise(fd, offset, len, POSIX_FADV_NOREUSE);
} }
int valid_fd(int fd)
{
/* will return 1 if fd is opened */
return fcntl(fd, F_GETFL) != -1 || errno != EBADF;
}
void sync_if_writable(int fd) void sync_if_writable(int fd)
{ {
int r; int r;
......
...@@ -13,6 +13,7 @@ int (*_original_open)(const char *pathname, int flags, mode_t mode); ...@@ -13,6 +13,7 @@ int (*_original_open)(const char *pathname, int flags, mode_t mode);
int (*_original_creat)(const char *pathname, int flags, mode_t mode); int (*_original_creat)(const char *pathname, int flags, mode_t mode);
int (*_original_openat)(int dirfd, const char *pathname, int flags, mode_t mode); int (*_original_openat)(int dirfd, const char *pathname, int flags, mode_t mode);
int (*_original_dup)(int fd); int (*_original_dup)(int fd);
int (*_original_dup2)(int newfd, int oldfd);
int (*_original_close)(int fd); int (*_original_close)(int fd);
static void init(void) __attribute__((constructor)); static void init(void) __attribute__((constructor));
...@@ -31,6 +32,7 @@ int openat64(int dirfd, const char *pathname, int flags, mode_t mode) ...@@ -31,6 +32,7 @@ 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) int __openat_2(int dirfd, const char *pathname, int flags, mode_t mode)
__attribute__ ((alias ("openat"))); __attribute__ ((alias ("openat")));
int dup(int oldfd); int dup(int oldfd);
int dup2(int oldfd, int newfd);
int close(int fd); int close(int fd);
static void store_pageinfo(int fd); static void store_pageinfo(int fd);
...@@ -38,6 +40,7 @@ static void free_unclaimed_pages(int fd); ...@@ -38,6 +40,7 @@ static void free_unclaimed_pages(int fd);
extern int fadv_dontneed(int fd, off_t offset, off_t len); extern int fadv_dontneed(int fd, off_t offset, off_t len);
extern int fadv_noreuse(int fd, off_t offset, off_t len); extern int fadv_noreuse(int fd, off_t offset, off_t len);
extern int valid_fd(int fd);
extern void sync_if_writable(int fd); extern void sync_if_writable(int fd);
#define _MAX_FDS 1024 #define _MAX_FDS 1024
...@@ -62,6 +65,7 @@ static void init(void) ...@@ -62,6 +65,7 @@ static void init(void)
_original_openat = (int (*)(int, const char *, int, mode_t)) _original_openat = (int (*)(int, const char *, int, mode_t))
dlsym(RTLD_NEXT, "openat"); dlsym(RTLD_NEXT, "openat");
_original_dup = (int (*)(int)) dlsym(RTLD_NEXT, "dup"); _original_dup = (int (*)(int)) dlsym(RTLD_NEXT, "dup");
_original_dup2 = (int (*)(int, int)) dlsym(RTLD_NEXT, "dup2");
_original_close = (int (*)(int)) dlsym(RTLD_NEXT, "close"); _original_close = (int (*)(int)) dlsym(RTLD_NEXT, "close");
PAGESIZE = getpagesize(); PAGESIZE = getpagesize();
for(i = 0; i < _MAX_FDS; i++) for(i = 0; i < _MAX_FDS; i++)
...@@ -127,6 +131,22 @@ int dup(int oldfd) ...@@ -127,6 +131,22 @@ int dup(int oldfd)
return 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);
if((ret = _original_dup2(oldfd, newfd)) != -1) {
store_pageinfo(newfd);
}
return ret;
}
int close(int fd) int close(int fd)
{ {
free_unclaimed_pages(fd); free_unclaimed_pages(fd);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment