[master] 36123ef Do a stat(2) check of inode/dev to detect changed vmod files.
Poul-Henning Kamp
phk at FreeBSD.org
Mon Aug 25 10:20:40 CEST 2014
commit 36123ef1db0a007fb4dfe5edb485e427a7030da5
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Aug 25 08:20:05 2014 +0000
Do a stat(2) check of inode/dev to detect changed vmod files.
diff --git a/bin/varnishd/cache/cache_vrt_vmod.c b/bin/varnishd/cache/cache_vrt_vmod.c
index a2dc7c0..b5b76fe 100644
--- a/bin/varnishd/cache/cache_vrt_vmod.c
+++ b/bin/varnishd/cache/cache_vrt_vmod.c
@@ -31,10 +31,14 @@
#include "config.h"
+#include <fcntl.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
#include "cache.h"
#include "vcli_priv.h"
@@ -54,6 +58,8 @@ struct vmod {
char *nm;
char *path;
+ intmax_t st_dev;
+ intmax_t st_ino;
void *hdl;
const void *funcs;
int funclen;
@@ -69,28 +75,41 @@ VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
const struct vmod_data *d;
char buf[256];
void *dlhdl;
+ int fd;
+ struct stat st;
ASSERT_CLI();
- dlhdl = dlopen(path, RTLD_NOW | RTLD_LOCAL);
- if (dlhdl == NULL) {
+ fd = open(path, O_RDONLY, 0);
+ if (fd < 0) {
VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
- VCLI_Out(cli, "dlopen() failed: %s\n", dlerror());
+ VCLI_Out(cli, "open() failed: %s\n", strerror(errno));
VCLI_Out(cli, "Check child process permissions.\n");
return (1);
}
+ AZ(fstat(fd, &st));
VTAILQ_FOREACH(v, &vmods, list)
- if (v->hdl == dlhdl)
+ if (st.st_dev == v->st_dev && st.st_ino == v->st_ino)
break;
- if (v == NULL) {
- ALLOC_OBJ(v, VMOD_MAGIC);
- AN(v);
- v->hdl = dlhdl;
+ if (v != NULL) {
+ AZ(close(fd));
+ } else {
+ dlhdl = fdlopen(fd, RTLD_NOW | RTLD_LOCAL);
+
+ AZ(close(fd));
+
+ if (dlhdl == NULL) {
+ VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
+ VCLI_Out(cli, "fdlopen() failed: %s\n", dlerror());
+ VCLI_Out(cli, "Check child process permissions.\n");
+ return (1);
+ }
bprintf(buf, "Vmod_%s_Data", nm);
- d = dlsym(v->hdl, buf);
+
+ d = dlsym(dlhdl, buf);
if (d == NULL ||
d->file_id == NULL ||
strcmp(d->file_id, file_id)) {
@@ -98,10 +117,10 @@ VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
VCLI_Out(cli,
"This is no longer the same file seen by"
" the VCL-compiler.\n");
- (void)dlclose(v->hdl);
- FREE_OBJ(v);
+ (void)dlclose(dlhdl);
return (1);
}
+
if (d->vrt_major != VRT_MAJOR_VERSION ||
d->vrt_minor > VRT_MINOR_VERSION ||
d->name == NULL ||
@@ -113,11 +132,17 @@ VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
d->abi == NULL) {
VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
VCLI_Out(cli, "VMOD data is mangled.\n");
- (void)dlclose(v->hdl);
- FREE_OBJ(v);
+ (void)dlclose(dlhdl);
return (1);
}
+ ALLOC_OBJ(v, VMOD_MAGIC);
+ AN(v);
+
+ v->st_dev = st.st_dev;
+ v->st_ino = st.st_ino;
+ v->hdl = dlhdl;
+
v->funclen = d->func_len;
v->funcs = d->func;
@@ -143,10 +168,14 @@ VRT_Vmod_Fini(void **hdl)
ASSERT_CLI();
+
AN(*hdl);
CAST_OBJ_NOTNULL(v, *hdl, VMOD_MAGIC);
*hdl = NULL;
+ if (--v->ref != 0)
+ return;
+
#ifndef DONT_DLCLOSE_VMODS
/*
* atexit(3) handlers are not called during dlclose(3). We don't
@@ -155,8 +184,6 @@ VRT_Vmod_Fini(void **hdl)
*/
AZ(dlclose(v->hdl));
#endif
- if (--v->ref != 0)
- return;
free(v->nm);
free(v->path);
VTAILQ_REMOVE(&vmods, v, list);
More information about the varnish-commit
mailing list