[6.0] 239bca372 Align the lifetime of the PID file to the VUT process

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Thu Aug 16 08:52:53 UTC 2018


commit 239bca372c94c18880fcc8d4162f97db0815dc64
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Wed May 2 11:25:10 2018 +0200

    Align the lifetime of the PID file to the VUT process
    
    For out-of-tree code that may set up multiple VUTs in a single process,
    we don't want the VUT that initialized a PID file to remove it if it
    finishes before other VUTs.
    
    A global pseudo-VUT is introduced to keep track of the PID file and
    the error callback in order to use them in the atexit(3) callback.
    
    Original test case by Geoff, slightly modified.
    
    Closes #2651

diff --git a/bin/varnishtest/tests/r02646.vtc b/bin/varnishtest/tests/r02646.vtc
new file mode 100644
index 000000000..a5c3c432c
--- /dev/null
+++ b/bin/varnishtest/tests/r02646.vtc
@@ -0,0 +1,21 @@
+varnishtest "#2646: VUT should fail gracefully when removing a pid file fails"
+
+varnish v1 -vcl {
+	backend be {
+		.host = "${bad_backend}";
+	}
+} -start
+
+process p1 {
+	exec varnishncsa -n ${v1_name} -P ${tmpdir}/ncsa.pid -w ${tmpdir}/ncsa.log
+} -start
+
+delay 1
+
+shell "rm -f ${tmpdir}/ncsa.pid"
+
+process p1 -expect-exit 1 -stop -wait
+
+shell -expect "Cannot remove pid file ${tmpdir}/ncsa.pid" {
+	cat ${tmpdir}/p1/stderr
+}
diff --git a/lib/libvarnishapi/vut.c b/lib/libvarnishapi/vut.c
index e268326c1..a793e44a6 100644
--- a/lib/libvarnishapi/vut.c
+++ b/lib/libvarnishapi/vut.c
@@ -62,6 +62,8 @@ static int vut_options(const struct vopt_spec *);
 static struct vpf_fh	*pfh;
 static unsigned		daemonized;
 
+static struct VUT pfh_vut;
+
 static int
 vut_daemon(struct VUT *vut)
 {
@@ -74,10 +76,18 @@ vut_daemon(struct VUT *vut)
 static void
 vut_vpf_remove(void)
 {
-	if (pfh != NULL) {
-		AZ(VPF_Remove(pfh));
-		pfh = NULL;
-	}
+
+	assert(VALID_OBJ(&pfh_vut, VUT_MAGIC));
+	AN(pfh);
+	AN(pfh_vut.P_arg);
+
+	if (VPF_Remove(pfh) != 0)
+		VUT_Error(&pfh_vut, 1, "Cannot remove pid file %s: %s",
+		    pfh_vut.P_arg, strerror(errno));
+
+	free(pfh_vut.P_arg);
+	ZERO_OBJ(&pfh_vut, sizeof pfh_vut);
+	pfh = NULL;
 }
 
 static int v_matchproto_(VSLQ_dispatch_f)
@@ -306,6 +316,13 @@ VUT_Setup(struct VUT *vut)
 	if (vut->P_arg) {
 		AN(pfh);
 		AZ(VPF_Write(pfh));
+
+		/* NB: move ownership to a global pseudo-VUT. */
+		INIT_OBJ(&pfh_vut, VUT_MAGIC);
+		pfh_vut.P_arg = vut->P_arg;
+		pfh_vut.error_f = vut->error_f;
+		vut->P_arg = NULL;
+
 		AZ(atexit(vut_vpf_remove));
 	}
 }
@@ -319,13 +336,10 @@ VUT_Fini(struct VUT **vutp)
 	AN(vut->progname);
 
 	free(vut->n_arg);
-	free(vut->P_arg);
 	free(vut->q_arg);
 	free(vut->r_arg);
 	free(vut->t_arg);
-
-	vut_vpf_remove();
-	AZ(pfh);
+	AZ(vut->P_arg);
 
 	if (vut->vslq)
 		VSLQ_Delete(&vut->vslq);


More information about the varnish-commit mailing list