[master] d9f7cd5 Keep an age counter in VSM_Head that will show the age of this SHM segment.
Martin Blix Grydeland
martin at varnish-cache.org
Wed May 15 14:46:13 CEST 2013
commit d9f7cd52dcce9bdb20ec5fe00b23f75f7b7f416e
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date: Wed Jan 9 11:17:21 2013 +0100
Keep an age counter in VSM_Head that will show the age of this SHM
segment.
The API will use this counter to check for abandonment.
Make use of the SHM age attribute in VSM_Abandoned.
This gives a less expensive way (without doing stat syscall) to check
for abandonment. If there's been more than 2 seconds between calls to
VSM_Abandoned and the age attribute hasn't changed in between, the
stat on the file will be performed to see if the SHM file has changed.
VSM_Abandoned will be the standard way to check for SHM changes in API
utilities, and when it returns true, the application is supposed to
call VSM_Close and then VSM_Open to reopen the SHM file.
Update Makefile.am in various places for build
diff --git a/bin/varnishadm/Makefile.am b/bin/varnishadm/Makefile.am
index 7941eb2..22825cd 100644
--- a/bin/varnishadm/Makefile.am
+++ b/bin/varnishadm/Makefile.am
@@ -17,7 +17,7 @@ varnishadm_CFLAGS = @LIBEDIT_CFLAGS@
varnishadm_LDADD = \
$(top_builddir)/lib/libvarnishapi/libvarnishapi.la \
$(top_builddir)/lib/libvarnishcompat/libvarnishcompat.la \
- ${PTHREAD_LIBS} ${NET_LIBS} @LIBEDIT_LIBS@ ${LIBM}
+ ${PTHREAD_LIBS} ${RT_LIBS} ${NET_LIBS} @LIBEDIT_LIBS@ ${LIBM}
varnishadm.1: $(top_srcdir)/doc/sphinx/reference/varnishadm.rst
if HAVE_RST2MAN
diff --git a/bin/varnishd/common/common.h b/bin/varnishd/common/common.h
index 8140734..978b54d 100644
--- a/bin/varnishd/common/common.h
+++ b/bin/varnishd/common/common.h
@@ -115,6 +115,7 @@ void VSM_common_free(struct vsm_sc *sc, void *ptr);
void VSM_common_delete(struct vsm_sc **sc);
void VSM_common_copy(struct vsm_sc *to, const struct vsm_sc *from);
void VSM_common_cleaner(struct vsm_sc *sc, struct VSC_C_main *stats);
+void VSM_common_ageupdate(struct vsm_sc *sc);
/*---------------------------------------------------------------------
* Generic power-2 rounding macros
diff --git a/bin/varnishd/common/common_vsm.c b/bin/varnishd/common/common_vsm.c
index e53972c..6f7f5a3 100644
--- a/bin/varnishd/common/common_vsm.c
+++ b/bin/varnishd/common/common_vsm.c
@@ -66,6 +66,7 @@ struct vsm_sc {
char *b;
ssize_t len;
struct VSM_head *head;
+ double t0;
VTAILQ_HEAD(,vsm_range) r_used;
VTAILQ_HEAD(,vsm_range) r_cooling;
VTAILQ_HEAD(,vsm_range) r_free;
@@ -139,6 +140,7 @@ VSM_common_new(void *p, ssize_t l)
VTAILQ_INIT(&sc->r_bogus);
sc->b = p;
sc->len = l;
+ sc->t0 = VTIM_mono();
sc->head = (void *)sc->b;
/* This should not be necessary, but just in case...*/
@@ -377,3 +379,15 @@ VSM_common_copy(struct vsm_sc *to, const struct vsm_sc *from)
memcpy(p, vr->chunk + 1, vr->chunk->len);
}
}
+
+/*--------------------------------------------------------------------
+ * Update age
+ */
+
+void
+VSM_common_ageupdate(struct vsm_sc *sc)
+{
+
+ CHECK_OBJ_NOTNULL(sc, VSM_SC_MAGIC);
+ sc->head->age = VTIM_mono() - sc->t0;
+}
diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c
index 1ae4599..9397891 100644
--- a/bin/varnishd/mgt/mgt_child.c
+++ b/bin/varnishd/mgt/mgt_child.c
@@ -669,6 +669,8 @@ mgt_uptime(const struct vev *e, int what)
AN(VSC_C_mgt);
VSC_C_mgt->uptime = static_VSC_C_mgt.uptime =
VTIM_mono() - mgt_uptime_t0;
+ if (heritage.vsm != NULL)
+ VSM_common_ageupdate(heritage.vsm);
return (0);
}
diff --git a/bin/varnishhist/Makefile.am b/bin/varnishhist/Makefile.am
index 3d849f6..91719e8 100644
--- a/bin/varnishhist/Makefile.am
+++ b/bin/varnishhist/Makefile.am
@@ -14,7 +14,7 @@ varnishhist_LDADD = \
$(top_builddir)/lib/libvarnishcompat/libvarnishcompat.la \
$(top_builddir)/lib/libvarnishapi/libvarnishapi.la \
-lm \
- ${CURSES_LIBS} ${PTHREAD_LIBS}
+ ${CURSES_LIBS} ${RT_LIBS} ${PTHREAD_LIBS}
varnishhist.1: $(top_srcdir)/doc/sphinx/reference/varnishhist.rst
if HAVE_RST2MAN
diff --git a/bin/varnishlog/Makefile.am b/bin/varnishlog/Makefile.am
index 23e1fe4..f6416f7 100644
--- a/bin/varnishlog/Makefile.am
+++ b/bin/varnishlog/Makefile.am
@@ -17,7 +17,7 @@ varnishlog_SOURCES = \
varnishlog_LDADD = \
$(top_builddir)/lib/libvarnishcompat/libvarnishcompat.la \
$(top_builddir)/lib/libvarnishapi/libvarnishapi.la \
- ${PTHREAD_LIBS}
+ ${RT_LIBS} ${LIBM} ${PTHREAD_LIBS}
varnishlog.1: $(top_srcdir)/doc/sphinx/reference/varnishlog.rst
if HAVE_RST2MAN
diff --git a/bin/varnishncsa/Makefile.am b/bin/varnishncsa/Makefile.am
index e9c30fa..7db8e89 100644
--- a/bin/varnishncsa/Makefile.am
+++ b/bin/varnishncsa/Makefile.am
@@ -19,7 +19,7 @@ varnishncsa_SOURCES = \
varnishncsa_LDADD = \
$(top_builddir)/lib/libvarnishcompat/libvarnishcompat.la \
$(top_builddir)/lib/libvarnishapi/libvarnishapi.la \
- ${PTHREAD_LIBS}
+ ${RT_LIBS} ${LIBM} ${PTHREAD_LIBS}
varnishncsa.1: $(top_srcdir)/doc/sphinx/reference/varnishncsa.rst
if HAVE_RST2MAN
diff --git a/bin/varnishreplay/Makefile.am b/bin/varnishreplay/Makefile.am
index df7b2b8..59c6a0d 100644
--- a/bin/varnishreplay/Makefile.am
+++ b/bin/varnishreplay/Makefile.am
@@ -15,7 +15,7 @@ varnishreplay_SOURCES = \
varnishreplay_LDADD = \
$(top_builddir)/lib/libvarnishcompat/libvarnishcompat.la \
$(top_builddir)/lib/libvarnishapi/libvarnishapi.la \
- ${PTHREAD_LIBS} ${NET_LIBS} ${LIBM}
+ ${RT_LIBS} ${PTHREAD_LIBS} ${NET_LIBS} ${LIBM}
varnishreplay.1: $(top_srcdir)/doc/sphinx/reference/varnishreplay.rst
if HAVE_RST2MAN
diff --git a/bin/varnishstat/Makefile.am b/bin/varnishstat/Makefile.am
index 98ea717..1a38329 100644
--- a/bin/varnishstat/Makefile.am
+++ b/bin/varnishstat/Makefile.am
@@ -17,7 +17,7 @@ varnishstat_SOURCES = \
varnishstat_LDADD = \
$(top_builddir)/lib/libvarnishcompat/libvarnishcompat.la \
$(top_builddir)/lib/libvarnishapi/libvarnishapi.la \
- ${CURSES_LIBS} ${RT_LIBS} ${PTHREAD_LIBS}
+ ${CURSES_LIBS} ${RT_LIBS} ${LIBM} ${PTHREAD_LIBS}
varnishstat.1: $(top_srcdir)/doc/sphinx/reference/varnishstat.rst
if HAVE_RST2MAN
diff --git a/bin/varnishtop/Makefile.am b/bin/varnishtop/Makefile.am
index 362acf5..1a6ecc4 100644
--- a/bin/varnishtop/Makefile.am
+++ b/bin/varnishtop/Makefile.am
@@ -14,7 +14,7 @@ varnishtop_SOURCES = varnishtop.c \
varnishtop_LDADD = \
$(top_builddir)/lib/libvarnishcompat/libvarnishcompat.la \
$(top_builddir)/lib/libvarnishapi/libvarnishapi.la \
- ${CURSES_LIBS} ${PTHREAD_LIBS}
+ ${CURSES_LIBS} ${RT_LIBS} ${LIBM} ${PTHREAD_LIBS}
varnishtop.1: $(top_srcdir)/doc/sphinx/reference/varnishtop.rst
if HAVE_RST2MAN
diff --git a/include/vapi/vsm.h b/include/vapi/vsm.h
index 800cb76..9d9ef5e 100644
--- a/include/vapi/vsm.h
+++ b/include/vapi/vsm.h
@@ -100,7 +100,7 @@ int VSM_Open(struct VSM_data *vd);
* <0 on failure, VSM_Error() returns diagnostic string
*/
-int VSM_Abandoned(const struct VSM_data *vd);
+int VSM_Abandoned(struct VSM_data *vd);
/*
* Find out if the VSM file has been abandoned or closed and should
* be reopened. This function calls stat(2) and should only be
diff --git a/include/vapi/vsm_int.h b/include/vapi/vsm_int.h
index 7e44604..a615ffd 100644
--- a/include/vapi/vsm_int.h
+++ b/include/vapi/vsm_int.h
@@ -53,11 +53,12 @@
* If a manager is started and finds and old abandoned VSM segment
* it will zero the alloc_seq in it, before replacing the file.
*
- * Subscribers will have to monitor two things to make sure they have
- * the current VSM instance: The alloc_seq field and the dev+inode
- * of the path-name. The former check is by far the cheaper and the
- * latter check should only be employed when lack of activity in the
- * VSM segment raises suspicion that something has happened.
+ * Subscribers will have to monitor three things to make sure they look at
+ * the right thing: The alloc_seq field, the age counter and the dev+inode
+ * of the path-name. The former check is by far the cheaper, the second
+ * can be used to check that Varnishd is still alive and the last check
+ * should only be employed when lack of activity in the VSM segment raises
+ * suspicion that something has happened.
*
* The allocations ("chunks") in the VSM forms a linked list, starting with
* VSM_head->first, with the first/next fields being byte offsets relative
@@ -114,6 +115,7 @@ struct VSM_head {
ssize_t shm_size;
ssize_t first; /* Offset, first chunk */
unsigned alloc_seq;
+ uint64_t age;
};
#endif /* VSM_INT_H_INCLUDED */
diff --git a/lib/libvarnishapi/Makefile.am b/lib/libvarnishapi/Makefile.am
index 181d1c1..2e5de91 100644
--- a/lib/libvarnishapi/Makefile.am
+++ b/lib/libvarnishapi/Makefile.am
@@ -22,6 +22,7 @@ libvarnishapi_la_SOURCES = \
../libvarnish/vmb.c \
../libvarnish/vre.c \
../libvarnish/vsb.c \
+ ../libvarnish/vtim.c \
../libvarnish/vsha256.c \
vsm.c \
vsl_arg.c \
diff --git a/lib/libvarnishapi/libvarnishapi.map b/lib/libvarnishapi/libvarnishapi.map
index 5640868..272cbd6 100644
--- a/lib/libvarnishapi/libvarnishapi.map
+++ b/lib/libvarnishapi/libvarnishapi.map
@@ -84,3 +84,10 @@ LIBVARNISHAPI_1.2 {
VSM_Get;
# Variables:
} LIBVARNISHAPI_1.0;
+
+LIBVARNISHAPI_1.3 {
+ global:
+ # Functions:
+ VSM_Abandoned;
+ # Variables:
+} LIBVARNISHAPI_1.0;
diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c
index 08d8eb6..ff42be5 100644
--- a/lib/libvarnishapi/vsm.c
+++ b/lib/libvarnishapi/vsm.c
@@ -48,6 +48,7 @@
#include "vapi/vsm.h"
#include "vapi/vsm_int.h"
+#include "vtim.h"
#include "vin.h"
#include "vsb.h"
#include "vsm_api.h"
@@ -219,6 +220,8 @@ VSM_Open(struct VSM_data *vd)
vd->head = v;
vd->b = v;
vd->e = vd->b + slh.shm_size;
+ vd->age_ok = vd->head->age;
+ vd->t_ok = VTIM_mono();
return (0);
}
@@ -246,23 +249,37 @@ VSM_Close(struct VSM_data *vd)
/*--------------------------------------------------------------------*/
int
-VSM_Abandoned(const struct VSM_data *vd)
+VSM_Abandoned(struct VSM_data *vd)
{
struct stat st;
+ double now;
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
if (vd->head == NULL)
+ /* Not open */
return (1);
-
if (!vd->head->alloc_seq)
+ /* Flag of abandonment set by mgt */
return (1);
- if (!stat(vd->fname, &st))
- return (1);
- if (st.st_dev != vd->fstat.st_dev)
- return (1);
- if (st.st_ino != vd->fstat.st_ino)
+ if (vd->head->age < vd->age_ok)
+ /* Age going backwards */
return (1);
+ now = VTIM_mono();
+ if (vd->head->age == vd->age_ok && now - vd->t_ok > 2.) {
+ /* No age change for 2 seconds, stat the file */
+ if (!stat(vd->fname, &st))
+ return (1);
+ if (st.st_dev != vd->fstat.st_dev)
+ return (1);
+ if (st.st_ino != vd->fstat.st_ino)
+ return (1);
+ vd->t_ok = now;
+ } else if (vd->head->age > vd->age_ok) {
+ /* It is aging, update timestamps */
+ vd->t_ok = now;
+ vd->age_ok = vd->head->age;
+ }
return (0);
}
diff --git a/lib/libvarnishapi/vsm_api.h b/lib/libvarnishapi/vsm_api.h
index af99798..2942494 100644
--- a/lib/libvarnishapi/vsm_api.h
+++ b/lib/libvarnishapi/vsm_api.h
@@ -47,6 +47,9 @@ struct VSM_data {
char *b;
char *e;
+ uint64_t age_ok;
+ double t_ok;
+
struct vsc *vsc;
struct vsl *vsl;
};
More information about the varnish-commit
mailing list