[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