[master] 612b641 Align the lifetime of the PID file to the VUT process

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Wed May 2 09:32:09 UTC 2018


commit 612b641954a3714cb34a665bbf56db99bed49899
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 0000000..a5c3c43
--- /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 e268326..a793e44 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