示例#1
0
int
main(int argc, char **argv)
{
	struct VSM_data *vd;
	int o, once = 0;
	float period = 60; /* seconds */

	vd = VSM_New();

	while ((o = getopt(argc, argv, VSL_ARGS "1fVp:")) != -1) {
		switch (o) {
		case '1':
			AN(VSL_Arg(vd, 'd', NULL));
			once = 1;
			break;
		case 'f':
			f_flag = 1;
			break;
		case 'p':
			errno = 0;
			period = strtol(optarg, NULL, 0);
			if (errno != 0)  {
				fprintf(stderr,
				    "Syntax error, %s is not a number", optarg);
				exit(1);
			}
			break;
		case 'V':
			VCS_Message("varnishtop");
			exit(0);
		case 'm':
			fprintf(stderr, "-m is not supported\n");
			exit(1);
		default:
			if (VSL_Arg(vd, o, optarg) > 0)
				break;
			usage();
		}
	}

	if (VSM_Open(vd)) {
		fprintf(stderr, "%s\n", VSM_Error(vd));
		exit (1);
	}

	if (once) {
		do_once(vd);
	} else {
		do_curses(vd, period);
	}
	exit(0);
}
示例#2
0
int
main(int argc, char *argv[])
{
	int c;
	struct VSM_data *vd;
	const char *address = NULL;

	vd = VSM_New();
	debug = 0;

	VSL_Arg(vd, 'c', NULL);
	while ((c = getopt(argc, argv, "a:Dr:n:")) != -1) {
		switch (c) {
		case 'a':
			address = optarg;
			break;
		case 'D':
			++debug;
			break;
		default:
			if (VSL_Arg(vd, c, optarg) > 0)
				break;
			usage();
		}
	}

	if (address == NULL) {
		usage();
	}

	if (VSM_Open(vd)) {
		fprintf(stderr, "%s\n", VSM_Error(vd));
		exit(1);
	}

	addr_info = init_connection(address);

	signal(SIGPIPE, SIG_IGN);

	pthread_attr_init(&thread_attr);

	/*
	 * XXX: seting the stack size manually reduces the memory usage
	 * XXX: (allowing more threads) and increases speed (?)
	 */
	pthread_attr_setstacksize(&thread_attr, 32768);

	while (VSL_Dispatch(vd, gen_traffic, NULL) == 0)
		/* nothing */ ;
	thread_close(-1);
	exit(0);
}
static void *
varnishlog_thread(void *priv)
{
	struct varnish *v;
	struct VSM_data	*vsl;

	CAST_OBJ_NOTNULL(v, priv, VARNISH_MAGIC);
	vsl = VSM_New();
	VSL_Setup(vsl);
	(void)VSL_Arg(vsl, 'n', v->workdir);
	VSL_NonBlocking(vsl, 1);
	while (v->pid  && VSL_Open(vsl, 0) != 0) {
		assert(usleep(VSL_SLEEP_USEC) == 0 || errno == EINTR);
	}
	while (v->pid) {
		if (VSL_Dispatch(vsl, h_addlog, v) < 0) {
			assert(usleep(v->vsl_sleep) == 0 || errno == EINTR);
			v->vsl_sleep += v->vsl_sleep;
			if (v->vsl_sleep > VSL_SLEEP_USEC)
				v->vsl_sleep = VSL_SLEEP_USEC;
		}
	}
	VSM_Delete(vsl);
	return (NULL);
}
示例#4
0
int
main(int argc, char **argv)
{
	int o;
	struct VSM_data *vd;

	vd = VSM_New();
	VSL_Setup(vd);

	while ((o = getopt(argc, argv, VSL_ARGS "Vw:")) != -1) {
		switch (o) {
		case 'V':
			VCS_Message("varnishhist");
			exit(0);
		case 'w':
			delay = atoi(optarg);
			break;
		default:
			if (VSL_Arg(vd, o, optarg) > 0)
				break;
			usage();
		}
	}

	if (VSL_Open(vd, 1))
		exit(1);

	log_ten = log(10.0);

	do_curses(vd);
	exit(0);
}
示例#5
0
文件: vadmin.c 项目: simonvik/vagent2
/*
 * Parse the -n argument and populate -T if necessary.
 *
 * Run on every connect, must do some cleanup.
 *
 * XXX: It writes to stdout in addition to the logger because the logger
 * may not be operational yet. Not sure if this makes sense... At any rate,
 * the required bit is to write to the logger.
 */
static int
n_arg_sock(struct agent_core_t *core)
{
	struct VSM_data *vsd;
	struct vadmin_config_t *vadmin;
	char *p;
	GET_PRIV(core, vadmin);

	vsd = VSM_New();
	assert(VSL_Arg(vsd, 'n', core->config->n_arg));
	if (VSM_Open(vsd, 1)) {
		logger(vadmin->logger,"Couldn't open VSM");
		fprintf(stderr, "Couldn't open VSM\n");
		VSM_Delete(vsd);
		vsd = NULL;
	}

	if (core->config->T_arg_orig) {
		if (core->config->T_arg)
			free(core->config->T_arg);
		core->config->T_arg = strdup(core->config->T_arg_orig);
	} else {		
		if (vsd == NULL) {
			logger(vadmin->logger,"No -T arg and no shmlog readable.");
			return -1;
		}
		p = VSM_Find_Chunk(vsd, "Arg", "-T", "", NULL);
		if (p == NULL)  {
			fprintf(stderr, "No -T arg in shared memory\n");
			logger(vadmin->logger, "No -T arg in shared memory.");
			return (-1);
		}
		core->config->T_arg = strdup(p);
	}

	if (core->config->S_arg == NULL && !vsd) {
		logger(vadmin->logger, "No shmlog and no -S arg. Unknown if authentication will work.");
	}
	if (vsd && core->config->S_arg == NULL) {
		p = VSM_Find_Chunk(vsd, "Arg", "-S", "", NULL);
		if (p != NULL)
			core->config->S_arg = strdup(p);
	}

	p = strchr(core->config->T_arg, '\n');
	if (p) {
		assert(p);
		*p = '\0';
	}
	if (vsd)
		VSM_Delete(vsd);
	logger(vadmin->logger, "-T argument computed to: %s", core->config->T_arg ? core->config->T_arg : "(null)");
	return (1);
}
示例#6
0
static void *
varnishlog_thread(void *priv)
{
	struct varnish *v;
	struct VSM_data	*vsl;

	CAST_OBJ_NOTNULL(v, priv, VARNISH_MAGIC);
	vsl = VSM_New();
	(void)VSL_Arg(vsl, 'n', v->workdir);
	while (v->pid) {
		if (VSL_Dispatch(vsl, h_addlog, v) <= 0)
			usleep(100000);
	}
	VSM_Delete(vsl);
	return (NULL);
}
示例#7
0
static int
n_arg_sock(const char *n_arg)
{
	char *T_arg = NULL, *T_start = NULL;
	char *S_arg = NULL;
	struct VSM_data *vsd;
	char *p;
	int sock;
	struct VSM_fantom vt;

	vsd = VSM_New();
	assert(VSL_Arg(vsd, 'n', n_arg));
	if (VSM_Open(vsd)) {
		fprintf(stderr, "%s\n", VSM_Error(vsd));
		return (-1);
	}

	if (!VSM_Get(vsd, &vt, "Arg", "-T", "")) {
		fprintf(stderr, "No -T arg in shared memory\n");
		return (-1);
	}
	AN(vt.b);
	T_start = T_arg = strdup(vt.b);

	if (VSM_Get(vsd, &vt, "Arg", "-S", "")) {
		AN(vt.b);
		S_arg = strdup(vt.b);
	}

	sock = -1;
	while (*T_arg) {
		p = strchr(T_arg, '\n');
		AN(p);
		*p = '\0';
		sock = cli_sock(T_arg, S_arg);
		if (sock >= 0)
			break;
		T_arg = p + 1;
	}
	free(T_start);
	free(S_arg);
	return (sock);
}
示例#8
0
static int
n_arg_sock(const char *n_arg)
{
	char *T_arg = NULL, *T_start = NULL;
	char *S_arg = NULL;
	struct VSM_data *vsd;
	char *p;
	int sock;

	vsd = VSM_New();
	assert(VSL_Arg(vsd, 'n', n_arg));
	if (VSM_Open(vsd, 1)) {
		fprintf(stderr, "Could not open shared memory\n");
		return (-1);
	}
	if (T_arg == NULL) {
		p = VSM_Find_Chunk(vsd, "Arg", "-T", "", NULL);
		if (p == NULL)  {
			fprintf(stderr, "No -T arg in shared memory\n");
			return (-1);
		}
		T_start = T_arg = strdup(p);
	}
	if (S_arg == NULL) {
		p = VSM_Find_Chunk(vsd, "Arg", "-S", "", NULL);
		if (p != NULL)
			S_arg = strdup(p);
	}
	sock = -1;
	while (*T_arg) {
		p = strchr(T_arg, '\n');
		AN(p);
		*p = '\0';
		sock = cli_sock(T_arg, S_arg);
		if (sock >= 0)
			break;
		T_arg = p + 1;
	}
	free(T_start);
	free(S_arg);
	return (sock);
}
static void
varnish_launch(struct varnish *v)
{
	struct vsb *vsb, *vsb1;
	int i, nfd, nap;
	struct vss_addr **ap;
	char abuf[128], pbuf[128];
	struct pollfd fd[2];
	enum VCLI_status_e u;
	char *r;

	v->vd = VSM_New();
	VSC_Setup(v->vd);

	/* Create listener socket */
	nap = VSS_resolve("127.0.0.1", "0", &ap);
	AN(nap);
	v->cli_fd = VSS_listen(ap[0], 1);
	VTCP_myname(v->cli_fd, abuf, sizeof abuf, pbuf, sizeof pbuf);

	AZ(VSB_finish(v->args));
	vtc_log(v->vl, 2, "Launch");
	vsb = VSB_new_auto();
	AN(vsb);
	VSB_printf(vsb, "cd ${pwd} &&");
	VSB_printf(vsb, " ${varnishd} -d -d -n %s", v->workdir);
	VSB_printf(vsb, " -l 10m,1m,-");
	VSB_printf(vsb, " -p auto_restart=off");
	VSB_printf(vsb, " -p syslog_cli_traffic=off");
	VSB_printf(vsb, " -a '%s'", "127.0.0.1:0");
	VSB_printf(vsb, " -S %s/_S", v->workdir);
	VSB_printf(vsb, " -M '%s %s'", abuf, pbuf);
	VSB_printf(vsb, " -P %s/varnishd.pid", v->workdir);
	VSB_printf(vsb, " %s", VSB_data(v->storage));
	VSB_printf(vsb, " %s", VSB_data(v->args));
	AZ(VSB_finish(vsb));
	vtc_log(v->vl, 3, "CMD: %s", VSB_data(vsb));
	vsb1 = macro_expand(v->vl, VSB_data(vsb));
	AN(vsb1);
	VSB_delete(vsb);
	vsb = vsb1;
	vtc_log(v->vl, 3, "CMD: %s", VSB_data(vsb));
	AZ(pipe(&v->fds[0]));
	AZ(pipe(&v->fds[2]));
	v->pid = fork();
	assert(v->pid >= 0);
	if (v->pid == 0) {
		assert(dup2(v->fds[0], 0) == 0);
		assert(dup2(v->fds[3], 1) == 1);
		assert(dup2(1, 2) == 2);
		AZ(close(v->fds[0]));
		AZ(close(v->fds[1]));
		AZ(close(v->fds[2]));
		AZ(close(v->fds[3]));
		for (i = 3; i <getdtablesize(); i++)
			(void)close(i);
		AZ(execl("/bin/sh", "/bin/sh", "-c", VSB_data(vsb), (char*)0));
		exit(1);
	} else {
		vtc_log(v->vl, 3, "PID: %ld", (long)v->pid);
	}
	AZ(close(v->fds[0]));
	AZ(close(v->fds[3]));
	v->fds[0] = v->fds[2];
	v->fds[2] = v->fds[3] = -1;
	VSB_delete(vsb);
	AZ(pthread_create(&v->tp, NULL, varnish_thread, v));
	AZ(pthread_create(&v->tp_vsl, NULL, varnishlog_thread, v));

	/* Wait for the varnish to call home */
	memset(fd, 0, sizeof fd);
	fd[0].fd = v->cli_fd;
	fd[0].events = POLLIN;
	fd[1].fd = v->fds[0];
	fd[1].events = 0; /* Only care about POLLHUP, which is output-only */
	i = poll(fd, 2, 10000);
	vtc_log(v->vl, 4, "CLIPOLL %d 0x%x 0x%x",
	    i, fd[0].revents, fd[1].revents);
	if (i == 0) {
		vtc_log(v->vl, 0, "FAIL timeout waiting for CLI connection");
		return;
	}
	if (fd[1].revents & POLLHUP) {
		vtc_log(v->vl, 0, "FAIL debug pipe closed");
		return;
	}
	if (!(fd[0].revents & POLLIN)) {
		vtc_log(v->vl, 0, "FAIL CLI connection wait failure");
		return;
	}
	nfd = accept(v->cli_fd, NULL, NULL);
	if (nfd < 0) {
		vtc_log(v->vl, 0, "FAIL no CLI connection accepted");
		return;
	}

	AZ(close(v->cli_fd));
	v->cli_fd = nfd;

	vtc_log(v->vl, 3, "CLI connection fd = %d", v->cli_fd);
	assert(v->cli_fd >= 0);


	/* Receive the banner or auth response */
	u = varnish_ask_cli(v, NULL, &r);
	if (vtc_error)
		return;
	if (u != CLIS_AUTH)
		vtc_log(v->vl, 0, "CLI auth demand expected: %u %s", u, r);

	bprintf(abuf, "%s/_S", v->workdir);
	nfd = open(abuf, O_RDONLY);
	assert(nfd >= 0);

	assert(sizeof abuf >= CLI_AUTH_RESPONSE_LEN + 7);
	strcpy(abuf, "auth ");
	VCLI_AuthResponse(nfd, r, abuf + 5);
	AZ(close(nfd));
	free(r);
	strcat(abuf, "\n");

	u = varnish_ask_cli(v, abuf, &r);
	if (vtc_error)
		return;
	if (u != CLIS_OK)
		vtc_log(v->vl, 0, "CLI auth command failed: %u %s", u, r);
	free(r);

	(void)VSL_Arg(v->vd, 'n', v->workdir);
	AZ(VSC_Open(v->vd, 1));
}
示例#10
0
static unsigned int vlog_reply(struct http_request *request, void *data)
{
	struct vlog_req_priv vrp = { .limit = 10 };
	int disp_status;
	char *p;
	char *tag = NULL;
	char *tag_re = NULL;
	struct VSL_data *vsl = NULL;
	struct VSLQ *vslq = NULL;
	struct VSL_cursor *c = NULL;
	enum VSL_grouping_e grouping = VSL_g_request;
	struct agent_core_t *core = data;

	p = next_slash(request->url + 1);
	if (p) {
		char *lim = strdup(p);
		assert(lim);
		char *tmp2 = strchr(lim, '/');
		if (tmp2 && *tmp2) *tmp2 = '\0';

		int j = sscanf(lim, "%u", &vrp.limit);
		if(j != 1) {
			free(lim);
			http_reply(request->connection, 500, "Not a number");
			return 0;
		}

		free(lim);
		p = next_slash(p);
	}

	if (p) {
		tag = strdup(p);
		char *tmp2 = strchr(tag,'/');
		if (tmp2 && *tmp2) *tmp2 = '\0';
		p = next_slash(p);
	}

	if (p) {
		tag_re = strdup(p);
		char *tmp2 = strchr(tag_re, '/');
		if (tmp2 && *tmp2) *tmp2 = '\0';
		p = next_slash(p);
	}
	
	vrp.answer = VSB_new_auto();
	assert(vrp.answer != NULL);

	vrp.vsm = VSM_New();
	assert(vrp.vsm);
	if (!VSM_n_Arg(vrp.vsm, core->config->n_arg)) {
		VSB_printf(vrp.answer, "Error in creating shmlog: %s",
		    VSM_Error(vrp.vsm));
		VSB_finish(vrp.answer);
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}

	if (VSM_Open(vrp.vsm) != 0) {
		VSB_printf(vrp.answer, "Error in opening shmlog: %s",
		    VSM_Error(vrp.vsm));
		VSB_finish(vrp.answer);
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}
	
	vsl = VSL_New();
	assert(vsl);

	if (tag) {
		grouping = VSL_g_raw;
		
		if (VSL_Arg(vsl, 'i', tag) < 0) {
			VSB_printf(vrp.answer, "Unable to specify tag '%s': %s",
			    tag, VSL_Error(vsl));
			VSB_finish(vrp.answer);
			http_reply(request->connection, 500, VSB_data(vrp.answer));
			goto cleanup;
		}
		if (tag_re) {
			VSL_Arg(vsl,'I', tag_re);
		}
	}

	c = VSL_CursorVSM(vsl, vrp.vsm,
	    VSL_COPT_BATCH | VSL_COPT_TAILSTOP);
	if (c == NULL) {
		VSB_printf(vrp.answer, "Can't open log (%s)",
		    VSL_Error(vsl));
		VSB_finish(vrp.answer);
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}

	
	vslq = VSLQ_New(vsl, &c, grouping, NULL);
	if (vslq == NULL) {
		VSB_clear(vrp.answer);
		VSB_printf(vrp.answer, "Error in creating query: %s",
		    VSL_Error(vsl));
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}

	VSB_printf(vrp.answer, "{ \"log\": [");

	do {
		disp_status = VSLQ_Dispatch(vslq, vlog_cb_func, &vrp);
	} while (disp_status == 1 && vrp.entries < vrp.limit);

	VSB_printf(vrp.answer, "\n] }\n");

	assert(VSB_finish(vrp.answer) == 0);
	if (VSB_len(vrp.answer) > 1) {
		struct http_response *resp = http_mkresp(request->connection, 200, NULL);
		resp->data = VSB_data(vrp.answer);
		resp->ndata = VSB_len(vrp.answer);
		http_add_header(resp,"Content-Type","application/json");
		send_response(resp);
		http_free_resp(resp);
	} else {
		http_reply(request->connection, 500, "FAIL");
	}

 cleanup:
	free(tag);
	free(tag_re);
	VSB_delete(vrp.answer);
	if (vslq)
		VSLQ_Delete(&vslq);
	if (vsl)
		VSL_Delete(vsl);
	if (vrp.vsm)
		VSM_Delete(vrp.vsm);
	vrp.answer = NULL;
	return 0;
}

void vlog_init(struct agent_core_t *core)
{
	struct agent_plugin_t *plug;
	struct vlog_priv_t *priv;

	ALLOC_OBJ(priv);
	plug = plugin_find(core,"vlog");
	plug->data = priv;

	http_register_url(core, "/log", M_GET, vlog_reply, core);
}
示例#11
0
static unsigned int vlog_reply(struct httpd_request *request, void *data)
{
	struct vlog_priv_t *vlog;
	int ret;
	char *limit = NULL;
	char *p;
	char *tag = NULL;
	char *itag = NULL;
	struct agent_core_t *core = data;
	GET_PRIV(data,vlog);
	p = next_slash(request->url + 1);

	assert(vlog->tag==NULL);
	assert(vlog->answer == NULL);

	if (p) {
		limit = strdup(p);
		assert(limit);
		char *tmp2 = index(limit,'/');
		if (tmp2 && *tmp2) *tmp2 = '\0';

		if(!(atoi(limit) > 0)) {
			free(limit);
			send_response_fail(request->connection,"Not a number");
			return 0;
		}
		p = next_slash(p);
	}
	if (p) {
		tag = strdup(p);
		char *tmp2 = index(tag,'/');
		if (tmp2 && *tmp2) *tmp2 = '\0';
		p = next_slash(p);
	}
	if (p) {
		itag = strdup(p);
		char *tmp2 = index(itag,'/');
		if (tmp2 && *tmp2) *tmp2 = '\0';
		p = next_slash(p);
	}
	vlog->answer = VSB_new_auto();
	assert(vlog->answer != NULL);
	vlog->vd = VSM_New();
	assert(VSL_Arg(vlog->vd, 'n', core->config->n_arg));
	VSL_Setup(vlog->vd);
	VSL_Arg(vlog->vd, 'd', "");
	if (tag) {
		VSL_Arg(vlog->vd, 'i', tag);
		if (itag)
			VSL_Arg(vlog->vd,'I',itag);
	} else {
		VSL_Arg(vlog->vd, 'k', limit ? limit : "10");
	}

	if (limit)
		free(limit);
	VSB_printf(vlog->answer, "{ \"log\": [");
	ret = VSL_Open(vlog->vd, 1);
	assert(!ret);

	if (tag == NULL) {
		do_order(vlog);
	} else {
		do_unorder(vlog);
	}
	if (tag)
		free(tag);
	if (itag)
		free(itag);

	VSB_printf(vlog->answer, "\n] }\n");
	assert(VSB_finish(vlog->answer) == 0);
	if (VSB_len(vlog->answer) > 1) {
		send_response(request->connection, 200, VSB_data(vlog->answer), VSB_len(vlog->answer));
	} else {
		send_response_fail(request->connection, "FAIL");
	}
	VSB_clear(vlog->answer);
	VSM_Close(vlog->vd);
	vlog->answer = NULL;
	vlog->entries = 0;
	return 0;
}
示例#12
0
int
VUT_Arg(int opt, const char *arg)
{
	int i;
	char *p;

	switch (opt) {
	case 'd':
		/* Head */
		VUT.d_opt = 1;
		return (1);
	case 'D':
		/* Daemon mode */
		VUT.D_opt = 1;
		return (1);
	case 'g':
		/* Grouping */
		return (VUT_g_Arg(arg));
	case 'k':
		/* Log transaction limit */
		VUT.k_arg = (int)strtol(arg, &p, 10);
		if (*p != '\0' || VUT.k_arg <= 0)
			VUT_Error(1, "-k: Invalid number '%s'", arg);
		return (1);
	case 'n':
		/* Varnish instance name */
		REPLACE(VUT.n_arg, arg);
		return (1);
	case 'N':
		/* Varnish stale VSM file */
		REPLACE(VUT.N_arg, arg);
		return (1);
	case 'P':
		/* PID file */
		REPLACE(VUT.P_arg, arg);
		return (1);
	case 'q':
		/* Query to use */
		REPLACE(VUT.q_arg, arg);
		return (1);
	case 'r':
		/* Binary file input */
		REPLACE(VUT.r_arg, arg);
		return (1);
	case 't':
		/* VSM connect timeout */
		if (!strcasecmp("off", arg))
			VUT.t_arg = -1.;
		else {
			VUT.t_arg = VNUM(arg);
			if (isnan(VUT.t_arg))
				VUT_Error(1, "-t: Syntax error");
			if (VUT.t_arg < 0.)
				VUT_Error(1, "-t: Range error");
		}
		return (1);
	case 'V':
		/* Print version number and exit */
		VCS_Message(VUT.progname);
		exit(0);
	default:
		AN(VUT.vsl);
		i = VSL_Arg(VUT.vsl, opt, arg);
		if (i < 0)
			VUT_Error(1, "%s", VSL_Error(VUT.vsl));
		return (i);
	}
}