Commit d355dafd authored by Julius Plenz's avatar Julius Plenz

Add destructor

parent a1fae007
...@@ -22,7 +22,7 @@ Just type `make`. Then, prepend `./nocache` to your command: ...@@ -22,7 +22,7 @@ Just type `make`. Then, prepend `./nocache` to your command:
./nocache cp -a ~/ /mnt/backup/home-$(hostname) ./nocache cp -a ~/ /mnt/backup/home-$(hostname)
You can also put the `nocache.so` file to a location like You can also put the `nocache.so` file to a location like
`/usr/local/lib` and do `LD_PRELOAD=nocache.so`. `/usr/local/lib` and do `LD_PRELOAD=/usr/local/lib/nocache.so`.
Testing Testing
...@@ -63,6 +63,22 @@ With `nocache`, the original caching state will be preserved. ...@@ -63,6 +63,22 @@ With `nocache`, the original caching state will be preserved.
pages in cache: 154/1945 (7.9%) [filesize=7776.2K, pagesize=4K] pages in cache: 154/1945 (7.9%) [filesize=7776.2K, pagesize=4K]
Limitations
-----------
The pre-loaded library tries really hard to catch all system calls
that open or close a file. This happens by "hijacking" the libc
functions that wrap the actual system calls. In some cases, this may
fail, for example because the application does some clever wrapping.
(That is the reason why `__openat_2` is defined: GNU `tar` uses this
instead of a regular `openat`.)
However, since the actual `fadvise` calls are performed right before
the file descriptor is closed, this may not happen if they are left
open when the application exits, although the destructor tries to do
that.
Acknowledgements Acknowledgements
---------------- ----------------
......
...@@ -15,8 +15,9 @@ int (*_original_openat)(int dirfd, const char *pathname, int flags, mode_t mode) ...@@ -15,8 +15,9 @@ 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_close)(int fd); int (*_original_close)(int fd);
void init(void) __attribute__((constructor)); static void init(void) __attribute__((constructor));
void init_mutex(void); static void destroy(void) __attribute__((destructor));
static void init_mutex(void);
int open(const char *pathname, int flags, mode_t mode); int open(const char *pathname, int flags, mode_t mode);
int open64(const char *pathname, int flags, mode_t mode) int open64(const char *pathname, int flags, mode_t mode)
...@@ -51,7 +52,7 @@ static struct fadv_info fds[_MAX_FDS]; ...@@ -51,7 +52,7 @@ static struct fadv_info fds[_MAX_FDS];
static size_t PAGESIZE; static size_t PAGESIZE;
static pthread_mutex_t lock; /* protects access to fds[] */ static pthread_mutex_t lock; /* protects access to fds[] */
void init(void) static void init(void)
{ {
int i; int i;
_original_open = (int (*)(const char *, int, mode_t)) _original_open = (int (*)(const char *, int, mode_t))
...@@ -68,13 +69,28 @@ void init(void) ...@@ -68,13 +69,28 @@ void init(void)
init_mutex(); init_mutex();
} }
void init_mutex(void) static void init_mutex(void)
{ {
pthread_mutex_init(&lock, NULL); pthread_mutex_init(&lock, NULL);
/* make sure to re-initialize mutex if forked */ /* make sure to re-initialize mutex if forked */
pthread_atfork(NULL, NULL, init_mutex); pthread_atfork(NULL, NULL, init_mutex);
} }
/* try to advise fds that were not manually closed */
static void destroy(void)
{
int i;
pthread_mutex_lock(&lock);
for(i = 0; i < _MAX_FDS; i++) {
if(fds[i].fd == -1)
continue; /* slot is empty */
pthread_mutex_unlock(&lock);
free_unclaimed_pages(fds[i].fd);
pthread_mutex_lock(&lock);
}
pthread_mutex_unlock(&lock);
}
int open(const char *pathname, int flags, mode_t mode) int open(const char *pathname, int flags, mode_t mode)
{ {
int fd; int fd;
...@@ -106,7 +122,6 @@ int dup(int oldfd) ...@@ -106,7 +122,6 @@ int dup(int oldfd)
{ {
int fd; int fd;
if((fd = _original_dup(oldfd)) != -1) { if((fd = _original_dup(oldfd)) != -1) {
fprintf(stderr, "dup()! old=%d, new=%d\n", oldfd, fd);
store_pageinfo(fd); store_pageinfo(fd);
} }
return fd; return 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