[master] cf3f0b3 Add a VUT_Main implementation that all the VSL utilities should be able to use.

Martin Blix Grydeland martin at varnish-cache.org
Thu Jun 13 12:41:24 CEST 2013


commit cf3f0b3cf782415a9dc6dedf792b42739751cfae
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Thu May 23 10:08:54 2013 +0200

    Add a VUT_Main implementation that all the VSL utilities should be
    able to use.
    
    Moved most functionality from varnishlog to VUT.

diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c
index db9bcef..a3199f7 100644
--- a/bin/varnishlog/varnishlog.c
+++ b/bin/varnishlog/varnishlog.c
@@ -61,121 +61,22 @@ main(int argc, char * const *argv)
 {
 	char opt;
 
-	struct VUT *vut;
-	struct VSL_data *vsl;
-	struct VSM_data *vsm;
-	struct VSL_cursor *c;
-	struct VSLQ *q;
-	int i;
-	int a_opt = 0;
-	const char *w_arg = NULL;
-	FILE *fo = stdout;
-	VSLQ_dispatch_f *func;
+	VUT_Init();
 
-	vut = VUT_New();
-	AN(vut);
-	vsl = VSL_New();
-	AN(vsl);
-	vsm = VSM_New();
-	AN(vsm);
-
-	while ((opt = getopt(argc, argv, "adg:n:r:vw:")) != -1) {
+	while ((opt = getopt(argc, argv, "adg:n:r:uvw:")) != -1) {
 		switch (opt) {
-		case 'a':
-			a_opt = 1;
-			break;
-		case 'n':
-			/* Instance name */
-			if (VSM_n_Arg(vsm, optarg) > 0)
-				break;
-		case 'w':
-			w_arg = optarg;
-			break;
 		default:
-			if (!VSL_Arg(vsl, opt, optarg) &&
-			    !VUT_Arg(vut, opt, optarg))
+			if (!VUT_Arg(opt, optarg))
 				usage();
 		}
 	}
 
-	func = VSL_PrintTransactions;
-	if (w_arg) {
-		fo = VSL_WriteOpen(vsl, w_arg, a_opt);
-		if (fo == NULL)
-			VUT_Error(1, "-w: %s", VSL_Error(vsl));
-		AZ(setvbuf(fo, NULL, _IONBF, 0));
-		func = VSL_WriteTransactions;
-	}
-	AN(fo);
-
-	/* Create cursor */
-	if (vut->r_arg)
-		c = VSL_CursorFile(vsl, vut->r_arg);
-	else {
-		if (VSM_Open(vsm))
-			VUT_Error(1, "VSM_Open: %s", VSM_Error(vsm));
-		c = VSL_CursorVSM(vsl, vsm, !vut->d_opt);
-	}
-	if (c == NULL)
-		VUT_Error(1, "Can't open log: %s", VSL_Error(vsl));
-
-	/* Create query */
-	q = VSLQ_New(vsl, &c, vut->g_arg, argv[optind]);
-	if (q == NULL)
-		VUT_Error(1, "Query error: %s", VSL_Error(vsl));
-	AZ(c);
+	if (optind < argc)
+		VUT.query = argv[optind];
 
-	while (1) {
-		while (q == NULL) {
-			AZ(vut->r_arg);
-			VTIM_sleep(0.1);
-			if (VSM_Open(vsm)) {
-				VSM_ResetError(vsm);
-				continue;
-			}
-			c = VSL_CursorVSM(vsl, vsm, 1);
-			if (c == NULL) {
-				VSL_ResetError(vsl);
-				continue;
-			}
-			q = VSLQ_New(vsl, &c, vut->g_arg, argv[optind]);
-			AN(q);
-			AZ(c);
-		}
-
-		i = VSLQ_Dispatch(q, func, fo);
-		if (i == 0) {
-			/* Nothing to do but wait */
-			VTIM_sleep(0.01);
-		} else if (i == -1) {
-			/* EOF */
-			break;
-		} else if (i <= -2) {
-			/* XXX: Make continuation optional */
-			VSLQ_Flush(q, func, fo);
-			VSLQ_Delete(&q);
-			AZ(q);
-			if (i == -2) {
-				/* Abandoned */
-				VUT_Error(0, "Log abandoned - reopening");
-				VSM_Close(vsm);
-			} else if (i < -2) {
-				/* Overrun */
-				VUT_Error(0, "Log overrun");
-			}
-		} else {
-			VUT_Error(1, "Unexpected: %d", i);
-		}
-	}
-
-	if (q != NULL) {
-		VSLQ_Flush(q, func, fo);
-		VSLQ_Delete(&q);
-		AZ(q);
-	}
-	VSL_Delete(vsl);
-	VSM_Delete(vsm);
-	VUT_Delete(&vut);
+	VUT_Setup();
+	VUT_Main(NULL, NULL);
+	VUT_Fini();
 
 	exit(0);
 }
diff --git a/bin/varnishlog/vut.c b/bin/varnishlog/vut.c
index b6711ec..29ff56b 100644
--- a/bin/varnishlog/vut.c
+++ b/bin/varnishlog/vut.c
@@ -41,11 +41,14 @@
 #include "vapi/vsm.h"
 #include "vapi/vsc.h"
 #include "vapi/vsl.h"
+#include "vtim.h"
 #include "vas.h"
 #include "miniobj.h"
 
 #include "vut.h"
 
+struct VUT VUT;
+
 void
 VUT_Error(int status, const char *fmt, ...)
 {
@@ -61,52 +64,210 @@ VUT_Error(int status, const char *fmt, ...)
 		exit(status);
 }
 
-struct VUT*
-VUT_New(void)
+int
+VUT_g_Arg(const char *arg)
 {
-	struct VUT *vut;
 
-	vut = calloc(1, sizeof *vut);
-	AN(vut);
-	vut->g_arg = VSL_g_vxid;
+	VUT.g_arg = VSLQ_Name2Grouping(arg, -1);
+	if (VUT.g_arg == -2)
+		VUT_Error(1, "Ambigous grouping type: %s", arg);
+	else if (VUT.g_arg < 0)
+		VUT_Error(1, "Unknown grouping type: %s", arg);
+	return (1);
+}
+
+int
+VUT_Arg(int opt, const char *arg)
+{
+	switch (opt) {
+	case 'a':
+		/* Binary file append */
+		VUT.a_opt = 1;
+		return (1);
+	case 'n':
+		/* Varnish instance */
+		if (VUT.vsm == NULL)
+			VUT.vsm = VSM_New();
+		AN(VUT.vsm);
+		if (VSM_n_Arg(VUT.vsm, arg) <= 0)
+			VUT_Error(1, "%s", VSM_Error(VUT.vsm));
+		return (1);
+	case 'd':
+		/* Head */
+		VUT.d_opt = 1;
+		return (1);
+	case 'g':
+		/* Grouping */
+		return (VUT_g_Arg(arg));
+	case 'r':
+		/* Binary file input */
+		REPLACE(VUT.r_arg, arg);
+		return (1);
+	case 'u':
+		/* Unbuffered binary output */
+		VUT.u_opt = 1;
+		return (1);
+	case 'w':
+		/* Binary file output */
+		REPLACE(VUT.w_arg, arg);
+		return (1);
+	default:
+		AN(VUT.vsl);
+		return (VSL_Arg(VUT.vsl, opt, arg));
+	}
+}
 
-	return (vut);
+void
+VUT_Init(void)
+{
+	VUT.g_arg = VSL_g_vxid;
+	AZ(VUT.vsl);
+	VUT.vsl = VSL_New();
+	AN(VUT.vsl);
 }
 
 void
-VUT_Delete(struct VUT **pvut)
+VUT_Setup(void)
 {
-	struct VUT *vut;
+	struct VSL_cursor *c;
 
-	AN(pvut);
-	vut = *pvut;
-	*pvut = NULL;
-	AN(vut);
+	AN(VUT.vsl);
 
-	free(vut->r_arg);
+	/* Input */
+	if (VUT.r_arg && VUT.vsm)
+		VUT_Error(1, "Can't have both -n and -r options");
+	if (VUT.r_arg)
+		c = VSL_CursorFile(VUT.vsl, VUT.r_arg);
+	else {
+		if (VUT.vsm == NULL)
+			/* Default uses VSM with n=hostname */
+			VUT.vsm = VSM_New();
+		AN(VUT.vsm);
+		if (VSM_Open(VUT.vsm))
+			VUT_Error(1, "Can't open VSM file (%s)",
+			    VSM_Error(VUT.vsm));
+		c = VSL_CursorVSM(VUT.vsl, VUT.vsm, !VUT.d_opt);
+	}
+	if (c == NULL)
+		VUT_Error(1, "Can't open log (%s)", VSL_Error(VUT.vsl));
+
+	/* Output */
+	if (VUT.w_arg) {
+		VUT.fo = VSL_WriteOpen(VUT.vsl, VUT.w_arg, VUT.a_opt,
+		    VUT.u_opt);
+		if (VUT.fo == NULL)
+			VUT_Error(1, "Can't open output file (%s)",
+			    VSL_Error(VUT.vsl));
+	}
 
-	free(vut);
+	/* Create query */
+	VUT.vslq = VSLQ_New(VUT.vsl, &c, VUT.g_arg, VUT.query);
+	if (VUT.vslq == NULL)
+		VUT_Error(1, "Query parse error (%s)", VSL_Error(VUT.vsl));
+	AZ(c);
 }
 
-int
-VUT_g_Arg(struct VUT *vut, const char *arg)
+void
+VUT_Fini(void)
 {
+	free(VUT.r_arg);
 
-	vut->g_arg = VSLQ_Name2Grouping(arg, -1);
-	if (vut->g_arg == -2)
-		VUT_Error(1, "Ambigous grouping type: %s", arg);
-	else if (vut->g_arg < 0)
-		VUT_Error(1, "Unknown grouping type: %s", arg);
-	return (1);
+	if (VUT.vslq)
+		VSLQ_Delete(&VUT.vslq);
+	if (VUT.vsl)
+		VSL_Delete(VUT.vsl);
+	if (VUT.vsm)
+		VSM_Delete(VUT.vsm);
+
+	memset(&VUT, 0, sizeof VUT);
 }
 
 int
-VUT_Arg(struct VUT *vut, int opt, const char *arg)
+VUT_Main(VSLQ_dispatch_f *func, void *priv)
 {
-	switch (opt) {
-	case 'd': vut->d_opt = 1; return (1);
-	case 'g': return (VUT_g_Arg(vut, arg));
-	case 'r': REPLACE(vut->r_arg, arg); return (1);
-	default: return (0);
+	struct VSL_cursor *c;
+	int i;
+
+	if (func == NULL) {
+		if (VUT.w_arg)
+			func = VSL_WriteTransactions;
+		else
+			func = VSL_PrintTransactions;
+		priv = VUT.fo;
 	}
+
+	while (1) {
+		while (VUT.vslq == NULL) {
+			AZ(VUT.r_arg);
+			AN(VUT.vsm);
+			VTIM_sleep(0.1);
+			if (VSM_Open(VUT.vsm)) {
+				VSM_ResetError(VUT.vsm);
+				continue;
+			}
+			c = VSL_CursorVSM(VUT.vsl, VUT.vsm, 1);
+			if (c == NULL) {
+				VSL_ResetError(VUT.vsl);
+				continue;
+			}
+			VUT.vslq = VSLQ_New(VUT.vsl, &c, VUT.g_arg, VUT.query);
+			AN(VUT.vslq);
+			AZ(c);
+		}
+
+		i = VSLQ_Dispatch(VUT.vslq, func, priv);
+		if (i == 0) {
+			/* Nothing to do but wait */
+			if (VUT.fo)
+				fflush(VUT.fo);
+			VTIM_sleep(0.01);
+			continue;
+		}
+		if (i == -1) {
+			/* EOF */
+			break;
+		}
+
+		if (VUT.vsm == NULL)
+			break;
+
+		/* XXX: Make continuation optional */
+
+		VSLQ_Flush(VUT.vslq, func, priv);
+		VSLQ_Delete(&VUT.vslq);
+		AZ(VUT.vslq);
+
+		if (i == -2) {
+			/* Abandoned */
+			VUT_Error(0, "Log abandoned - reopening");
+			VSM_Close(VUT.vsm);
+		} else if (i < -2) {
+			/* Overrun */
+			VUT_Error(0, "Log overrun");
+		}
+
+		/* Reconnect VSM */
+		while (VUT.vslq == NULL) {
+			AZ(VUT.r_arg);
+			AN(VUT.vsm);
+			VTIM_sleep(0.1);
+			if (VSM_Open(VUT.vsm)) {
+				VSM_ResetError(VUT.vsm);
+				continue;
+			}
+			c = VSL_CursorVSM(VUT.vsl, VUT.vsm, 1);
+			if (c == NULL) {
+				VSL_ResetError(VUT.vsl);
+				continue;
+			}
+			VUT.vslq = VSLQ_New(VUT.vsl, &c, VUT.g_arg, VUT.query);
+			AN(VUT.vslq);
+			AZ(c);
+		}
+	}
+
+	if (VUT.vslq != NULL)
+		VSLQ_Flush(VUT.vslq, func, priv);
+
+	return (i);
 }
diff --git a/bin/varnishlog/vut.h b/bin/varnishlog/vut.h
index 6d72755..dcb5a77 100644
--- a/bin/varnishlog/vut.h
+++ b/bin/varnishlog/vut.h
@@ -32,18 +32,35 @@
 #include "vdef.h"
 
 struct VUT {
-	int d_opt;
-	int g_arg;
-	char *r_arg;
+	/* Options */
+	int		a_opt;
+	int		d_opt;
+	int		g_arg;
+	char		*r_arg;
+	int		u_opt;
+	char		*w_arg;
+	const char	*query;
+
+	/* State */
+	struct VSL_data	*vsl;
+	struct VSM_data	*vsm;
+	struct VSLQ	*vslq;
+	FILE		*fo;
 };
 
+extern struct VUT VUT;
+
 void VUT_Error(int status, const char *fmt, ...)
 	__printflike(2, 3);
 
-struct VUT *VUT_New(void);
+int VUT_g_Arg(const char *arg);
+
+int VUT_Arg(int opt, const char *arg);
+
+void VUT_Setup(void);
 
-void VUT_Delete(struct VUT **pvut);
+void VUT_Init(void);
 
-int VUT_g_Arg(struct VUT *vut, const char *arg);
+void VUT_Fini(void);
 
-int VUT_Arg(struct VUT *vut, int opt, const char *arg);
+int VUT_Main(VSLQ_dispatch_f *func, void *priv);



More information about the varnish-commit mailing list