Commit 322d17a8 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Overhaul the libvarnishapi:

- make struct VSL_data the uniform handle.
- eliminate global variables (this allows a program to have multiple
  shmlogs open at the same time).
- add a VSL_Delete() to clean up

This breaks libvarnishapi compatibility with the 2.x series.






git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@4775 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent c640e69a
......@@ -540,6 +540,7 @@ mgt_sigchld(const struct vev *e, int what)
child_state = CH_STOPPED;
} else if (child_state == CH_STOPPING)
child_state = CH_STOPPED;
return (0);
}
......@@ -615,6 +616,9 @@ MGT_Run(void)
REPORT(LOG_ERR, "vev_schedule() = %d", i);
REPORT0(LOG_ERR, "manager dies");
/* XXX: quench compiler warning about unused func */
vbit_destroy(NULL);
}
/*--------------------------------------------------------------------*/
......
......@@ -96,7 +96,7 @@ static int scales[] = {
};
static void
update(void)
update(struct VSL_data *vd)
{
int w = COLS / HIST_RANGE;
int n = w * HIST_RANGE;
......@@ -116,7 +116,7 @@ update(void)
mvprintw(LINES - 1, w * i, "|1e%d", j);
}
mvprintw(0, 0, "%*s", COLS - 1, VSL_Name());
mvprintw(0, 0, "%*s", COLS - 1, VSL_Name(vd));
/* count our flock */
for (i = 0; i < n; ++i)
......@@ -257,7 +257,7 @@ do_curses(struct VSL_data *vd)
erase();
for (;;) {
pthread_mutex_lock(&mtx);
update();
update(vd);
pthread_mutex_unlock(&mtx);
timeout(delay * 1000);
......@@ -323,7 +323,7 @@ main(int argc, char **argv)
vd = VSL_New();
while ((o = getopt(argc, argv, VSL_ARGS "Vw:")) != -1) {
while ((o = getopt(argc, argv, VSL_LOG_ARGS "Vw:")) != -1) {
switch (o) {
case 'V':
varnish_version("varnishhist");
......
......@@ -318,7 +318,7 @@ main(int argc, char **argv)
vd = VSL_New();
while ((c = getopt(argc, argv, VSL_ARGS "aDoP:uVw:")) != -1) {
while ((c = getopt(argc, argv, VSL_LOG_ARGS "aDoP:uVw:")) != -1) {
switch (c) {
case 'a':
a_flag = 1;
......
......@@ -529,7 +529,7 @@ main(int argc, char *argv[])
vd = VSL_New();
while ((c = getopt(argc, argv, VSL_ARGS "aDP:Vw:f")) != -1) {
while ((c = getopt(argc, argv, VSL_LOG_ARGS "aDP:Vw:f")) != -1) {
switch (c) {
case 'a':
a_flag = 1;
......
......@@ -96,7 +96,7 @@ static int scales[] = {
};
static void
update(void)
update(struct VSL_data *vd)
{
int w = COLS / HIST_RANGE;
int n = w * HIST_RANGE;
......@@ -116,7 +116,7 @@ update(void)
mvprintw(LINES - 1, w * i, "|1e%d", j);
}
mvprintw(0, 0, "%*s", COLS - 1, VSL_Name());
mvprintw(0, 0, "%*s", COLS - 1, VSL_Name(vd));
/* count our flock */
for (i = 0; i < n; ++i)
......@@ -258,7 +258,7 @@ do_curses(struct VSL_data *vd)
erase();
for (;;) {
pthread_mutex_lock(&mtx);
update();
update(vd);
pthread_mutex_unlock(&mtx);
timeout(delay * 1000);
......@@ -324,7 +324,7 @@ main(int argc, char **argv)
vd = VSL_New();
while ((o = getopt(argc, argv, VSL_ARGS "Vw:")) != -1) {
while ((o = getopt(argc, argv, VSL_LOG_ARGS "Vw:")) != -1) {
switch (o) {
case 'V':
varnish_version("varnishsizes");
......
......@@ -94,7 +94,7 @@ show_field(const char* field, const char *fields)
}
static void
do_curses(struct varnish_stats *VSL_stats, int delay, const char *fields)
do_curses(struct VSL_data *vd, struct varnish_stats *VSL_stats, int delay, const char *fields)
{
struct varnish_stats copy;
struct varnish_stats seen;
......@@ -129,7 +129,7 @@ do_curses(struct varnish_stats *VSL_stats, int delay, const char *fields)
rt = VSL_stats->uptime;
up = rt;
mvprintw(0, 0, "%*s", COLS - 1, VSL_Name());
mvprintw(0, 0, "%*s", COLS - 1, VSL_Name(vd));
mvprintw(0, 0, "%d+%02d:%02d:%02d", rt / 86400,
(rt % 86400) / 3600, (rt % 3600) / 60, rt % 60);
......@@ -347,12 +347,14 @@ int
main(int argc, char **argv)
{
int c;
struct VSL_data *vd;
struct varnish_stats *VSL_stats;
int delay = 1, once = 0, xml = 0;
const char *n_arg = NULL;
const char *fields = NULL;
while ((c = getopt(argc, argv, "1f:ln:Vw:x")) != -1) {
vd = VSL_New();
while ((c = getopt(argc, argv, VSL_STAT_ARGS "1f:lVw:x")) != -1) {
switch (c) {
case '1':
once = 1;
......@@ -363,9 +365,6 @@ main(int argc, char **argv)
case 'l':
list_fields();
exit(0);
case 'n':
n_arg = optarg;
break;
case 'V':
varnish_version("varnishstat");
exit(0);
......@@ -376,11 +375,13 @@ main(int argc, char **argv)
xml = 1;
break;
default:
if (VSL_Arg(vd, c, optarg) > 0)
break;
usage();
}
}
if ((VSL_stats = VSL_OpenStats(n_arg)) == NULL)
if ((VSL_stats = VSL_OpenStats(vd)) == NULL)
exit(1);
if (fields != NULL && !valid_fields(fields)) {
......@@ -393,7 +394,7 @@ main(int argc, char **argv)
else if (once)
do_once(VSL_stats, fields);
else
do_curses(VSL_stats, delay, fields);
do_curses(vd, VSL_stats, delay, fields);
exit(0);
}
......@@ -80,6 +80,8 @@ struct varnish {
int cli_fd;
int vcl_nbr;
char *workdir;
struct VSL_data *vd;
};
static VTAILQ_HEAD(, varnish) varnishes =
......@@ -198,7 +200,7 @@ varnish_delete(struct varnish *v)
vtc_logclose(v->vl);
free(v->name);
free(v->workdir);
VSL_Close();
VSL_Delete(v->vd);
/*
* We do not delete the workdir, it may contain stuff people
......@@ -259,6 +261,8 @@ varnish_launch(struct varnish *v)
enum cli_status_e u;
char *r;
v->vd = VSL_New();
/* Create listener socket */
nap = VSS_resolve("127.0.0.1", "0", &ap);
AN(nap);
......@@ -359,8 +363,9 @@ varnish_launch(struct varnish *v)
free(r);
if (v->stats != NULL)
VSL_Close();
v->stats = VSL_OpenStats(v->workdir);
VSL_Close(v->vd);
VSL_Arg(v->vd, 'n', v->workdir);
v->stats = VSL_OpenStats(v->vd);
}
/**********************************************************************
......
......@@ -137,7 +137,7 @@ accumulate(const unsigned char *p)
}
static void
update(void)
update(struct VSL_data *vd)
{
struct top *tp, *tp2;
int l, len;
......@@ -152,7 +152,7 @@ update(void)
erase();
l = 1;
mvprintw(0, 0, "%*s", COLS - 1, VSL_Name());
mvprintw(0, 0, "%*s", COLS - 1, VSL_Name(vd));
mvprintw(0, 0, "list length %u", ntop);
VTAILQ_FOREACH_SAFE(tp, &top_head, list, tp2) {
if (++l < LINES) {
......@@ -228,7 +228,7 @@ do_curses(struct VSL_data *vd)
erase();
for (;;) {
pthread_mutex_lock(&mtx);
update();
update(vd);
pthread_mutex_unlock(&mtx);
timeout(1000);
......@@ -306,7 +306,7 @@ main(int argc, char **argv)
vd = VSL_New();
while ((o = getopt(argc, argv, VSL_ARGS "1fV")) != -1) {
while ((o = getopt(argc, argv, VSL_LOG_ARGS "1fV")) != -1) {
switch (o) {
case '1':
VSL_Arg(vd, 'd', NULL);
......
......@@ -43,7 +43,8 @@ typedef int vsl_handler(void *priv, enum shmlogtag tag, unsigned fd,
unsigned len, unsigned spec, const char *ptr);
#define VSL_S_CLIENT (1 << 0)
#define VSL_S_BACKEND (1 << 1)
#define VSL_ARGS "bCcdI:i:k:n:r:s:X:x:"
#define VSL_LOG_ARGS "bCcdI:i:k:n:r:s:X:x:"
#define VSL_STAT_ARGS "n:"
#define VSL_USAGE "[-bCcd] [-i tag] [-I regexp] [-k keep]" \
" [-r file] [-s skip] [-X regexp] [-x tag]"
vsl_handler VSL_H_Print;
......@@ -55,9 +56,10 @@ void VSL_NonBlocking(struct VSL_data *vd, int nb);
int VSL_Dispatch(struct VSL_data *vd, vsl_handler *func, void *priv);
int VSL_NextLog(struct VSL_data *lh, unsigned char **pp);
int VSL_Arg(struct VSL_data *vd, int arg, const char *opt);
void VSL_Close(void);
struct varnish_stats *VSL_OpenStats(const char *varnish_name);
const char *VSL_Name(void);
void VSL_Close(struct VSL_data *vd);
void VSL_Delete(struct VSL_data *vd);
struct varnish_stats *VSL_OpenStats(struct VSL_data *vd);
const char *VSL_Name(struct VSL_data *vd);
extern const char *VSL_tags[256];
#endif
......@@ -75,6 +75,16 @@ vbit_init(unsigned initial)
return (vb);
}
static void
vbit_destroy(struct vbitmap *vb)
{
if (vb == NULL)
return;
free(vb->bits);
free(vb);
}
static inline void
vbit_set(struct vbitmap *vb, unsigned bit)
{
......
......@@ -65,7 +65,7 @@ struct VSL_data {
unsigned char *ptr;
/* for -r option */
int fd;
int r_fd;
unsigned rbuflen;
unsigned char *rbuf;
......@@ -101,16 +101,15 @@ struct VSL_data {
unsigned long skip;
unsigned long keep;
int vsl_fd;
struct shmloghead *vsl_lh;
};
#ifndef MAP_HASSEMAPHORE
#define MAP_HASSEMAPHORE 0 /* XXX Linux */
#endif
static int vsl_fd;
static struct shmloghead *vsl_lh;
static char vsl_name[PATH_MAX];
static int vsl_nextlog(struct VSL_data *vd, unsigned char **pp);
/*--------------------------------------------------------------------*/
......@@ -124,28 +123,28 @@ const char *VSL_tags[256] = {
/*--------------------------------------------------------------------*/
static int
vsl_shmem_map(const char *varnish_name)
vsl_shmem_map(struct VSL_data *vd)
{
int i;
struct shmloghead slh;
char *logname;
if (vsl_lh != NULL)
if (vd->vsl_lh != NULL)
return (0);
if (vin_n_arg(varnish_name, NULL, NULL, &logname)) {
if (vin_n_arg(vd->n_opt, NULL, NULL, &logname)) {
fprintf(stderr, "Invalid instance name: %s\n",
strerror(errno));
return (1);
}
vsl_fd = open(logname, O_RDONLY);
if (vsl_fd < 0) {
vd->vsl_fd = open(logname, O_RDONLY);
if (vd->vsl_fd < 0) {
fprintf(stderr, "Cannot open %s: %s\n",
logname, strerror(errno));
return (1);
}
i = read(vsl_fd, &slh, sizeof slh);
i = read(vd->vsl_fd, &slh, sizeof slh);
if (i != sizeof slh) {
fprintf(stderr, "Cannot read %s: %s\n",
logname, strerror(errno));
......@@ -157,9 +156,9 @@ vsl_shmem_map(const char *varnish_name)
return (1);
}
vsl_lh = (void *)mmap(NULL, slh.size + sizeof slh,
PROT_READ, MAP_SHARED|MAP_HASSEMAPHORE, vsl_fd, 0);
if (vsl_lh == MAP_FAILED) {
vd->vsl_lh = (void *)mmap(NULL, slh.size + sizeof slh,
PROT_READ, MAP_SHARED|MAP_HASSEMAPHORE, vd->vsl_fd, 0);
if (vd->vsl_lh == MAP_FAILED) {
fprintf(stderr, "Cannot mmap %s: %s\n",
logname, strerror(errno));
return (1);
......@@ -178,19 +177,42 @@ VSL_New(void)
assert(vd != NULL);
vd->regflags = 0;
vd->magic = VSL_MAGIC;
vd->fd = -1;
vd->vsl_fd = -1;
/* XXX: Allocate only if log access */
vd->vbm_client = vbit_init(4096);
vd->vbm_backend = vbit_init(4096);
vd->vbm_supress = vbit_init(256);
vd->vbm_select = vbit_init(256);
vd->r_fd = -1;
/* XXX: Allocate only if -r option given ? */
vd->rbuflen = SHMLOG_NEXTTAG + 256;
vd->rbuf = malloc(vd->rbuflen);
assert(vd->rbuf != NULL);
return (vd);
}
/*--------------------------------------------------------------------*/
void
VSL_Delete(struct VSL_data *vd)
{
VSL_Close(vd);
vbit_destroy(vd->vbm_client);
vbit_destroy(vd->vbm_backend);
vbit_destroy(vd->vbm_supress);
vbit_destroy(vd->vbm_select);
free(vd->n_opt);
free(vd->rbuf);
free(vd);
}
/*--------------------------------------------------------------------*/
void
VSL_Select(struct VSL_data *vd, unsigned tag)
{
......@@ -207,18 +229,18 @@ VSL_OpenLog(struct VSL_data *vd)
unsigned char *p;
CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
if (vd->fd != -1)
if (vd->r_fd != -1)
return (0);
if (vsl_shmem_map(vd->n_opt))
if (vsl_shmem_map(vd))
return (-1);
vd->head = vsl_lh;
vd->logstart = (unsigned char *)vsl_lh + vsl_lh->start;
vd->logend = vd->logstart + vsl_lh->size;
vd->head = vd->vsl_lh;
vd->logstart = (unsigned char *)vd->vsl_lh + vd->vsl_lh->start;
vd->logend = vd->logstart + vd->vsl_lh->size;
vd->ptr = vd->logstart;
if (!vd->d_opt && vd->fd == -1) {
if (!vd->d_opt && vd->r_fd == -1) {
for (p = vd->ptr; *p != SLT_ENDMARKER; )
p += SHMLOG_LEN(p) + SHMLOG_NEXTTAG;
vd->ptr = p;
......@@ -247,9 +269,9 @@ vsl_nextlog(struct VSL_data *vd, unsigned char **pp)
int i;
CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
if (vd->fd != -1) {
if (vd->r_fd != -1) {
assert(vd->rbuflen >= SHMLOG_DATA);
i = read(vd->fd, vd->rbuf, SHMLOG_DATA);
i = read(vd->r_fd, vd->rbuf, SHMLOG_DATA);
if (i != SHMLOG_DATA)
return (-1);
l = SHMLOG_LEN(vd->rbuf) + SHMLOG_NEXTTAG;
......@@ -260,7 +282,7 @@ vsl_nextlog(struct VSL_data *vd, unsigned char **pp)
vd->rbuflen = l;
}
l = SHMLOG_LEN(vd->rbuf) + 1;
i = read(vd->fd, vd->rbuf + SHMLOG_DATA, l);
i = read(vd->r_fd, vd->rbuf + SHMLOG_DATA, l);
if (i != l)
return (-1);
*pp = vd->rbuf;
......@@ -421,10 +443,10 @@ vsl_r_arg(struct VSL_data *vd, const char *opt)
CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
if (!strcmp(opt, "-"))
vd->fd = STDIN_FILENO;
vd->r_fd = STDIN_FILENO;
else
vd->fd = open(opt, O_RDONLY);
if (vd->fd < 0) {
vd->r_fd = open(opt, O_RDONLY);
if (vd->r_fd < 0) {
perror(opt);
return (-1);
}
......@@ -579,29 +601,30 @@ VSL_Arg(struct VSL_data *vd, int arg, const char *opt)
}
struct varnish_stats *
VSL_OpenStats(const char *varnish_name)
VSL_OpenStats(struct VSL_data *vd)
{
if (vsl_shmem_map(varnish_name))
if (vsl_shmem_map(vd))
return (NULL);
return (&vsl_lh->stats);
return (&vd->vsl_lh->stats);
}
void
VSL_Close(void)
VSL_Close(struct VSL_data *vd)
{
if (vsl_lh == NULL)
if (vd->vsl_lh == NULL)
return;
assert(0 == munmap((void*)vsl_lh, vsl_lh->size + sizeof *vsl_lh));
vsl_lh = NULL;
assert(vsl_fd >= 0);
assert(0 == close(vsl_fd));
vsl_fd = -1;
assert(0 == munmap((void*)vd->vsl_lh,
vd->vsl_lh->size + sizeof *vd->vsl_lh));
vd->vsl_lh = NULL;
assert(vd->vsl_fd >= 0);
assert(0 == close(vd->vsl_fd));
vd->vsl_fd = -1;
}
const char *
VSL_Name(void)
VSL_Name(struct VSL_data *vd)
{
return (vsl_name);
return (vd->n_opt);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment