Commit 93b3d109 authored by Geoff Simmons's avatar Geoff Simmons

use a malloc'd buffer with memcpy in the inner loop of FMT_Format,

rather than a VSB
parent 70b07983
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <errno.h> #include <errno.h>
#include <ctype.h> #include <ctype.h>
#include <stdint.h> #include <stdint.h>
#include <limits.h>
#include "vapi/vsl.h" #include "vapi/vsl.h"
#include "vas.h" #include "vas.h"
...@@ -45,16 +46,23 @@ ...@@ -45,16 +46,23 @@
#include "format.h" #include "format.h"
#include "strfTIM.h" #include "strfTIM.h"
#ifdef PAGE_SIZE
#define OBUF_SIZE PAGE_SIZE
#else
#define OBUF_SIZE 4096
#endif
typedef struct compiled_fmt_t { typedef struct compiled_fmt_t {
char **str; char **str;
formatter_f **formatter; formatter_f **formatter;
arg_t *args; arg_t *args;
int *strlen;
unsigned n; unsigned n;
} compiled_fmt_t; } compiled_fmt_t;
static struct vsb *scratch; static struct vsb *scratch;
static char *payload; static char *payload, *obuf;
static char empty[] = ""; static char empty[] = "";
static char hit[] = "hit"; static char hit[] = "hit";
static char miss[] = "miss"; static char miss[] = "miss";
...@@ -64,6 +72,8 @@ static char error[] = "error"; ...@@ -64,6 +72,8 @@ static char error[] = "error";
static char dash[] = "-"; static char dash[] = "-";
static char buf[BUFSIZ]; static char buf[BUFSIZ];
static size_t obuf_sz = OBUF_SIZE;
typedef struct inc_t { typedef struct inc_t {
char *hdr; char *hdr;
VSTAILQ_ENTRY(inc_t) inclist; VSTAILQ_ENTRY(inc_t) inclist;
...@@ -754,17 +764,24 @@ static void ...@@ -754,17 +764,24 @@ static void
add_fmt(const compiled_fmt_t *fmt, struct vsb *os, unsigned n, add_fmt(const compiled_fmt_t *fmt, struct vsb *os, unsigned n,
formatter_f formatter, const char *name, enum VSL_tag_e tag, int fld) formatter_f formatter, const char *name, enum VSL_tag_e tag, int fld)
{ {
fmt->str[n] = (char *) malloc(VSB_len(os) + 1); if (VSB_len(os) > 0) {
AN(fmt->str[n]); fmt->str[n] = (char *) malloc(VSB_len(os) + 1);
AN(fmt->str[n]);
VSB_finish(os);
strcpy(fmt->str[n], VSB_data(os));
fmt->strlen[n] = VSB_len(os);
}
else {
fmt->str[n] = NULL;
fmt->strlen[n] = 0;
}
VSB_clear(os);
if (name == NULL) if (name == NULL)
fmt->args[n].name = NULL; fmt->args[n].name = NULL;
else { else {
fmt->args[n].name = strdup(name); fmt->args[n].name = strdup(name);
AN(fmt->args[n].name); AN(fmt->args[n].name);
} }
VSB_finish(os);
strcpy(fmt->str[n], VSB_data(os));
VSB_clear(os);
fmt->formatter[n] = formatter; fmt->formatter[n] = formatter;
fmt->args[n].tag = tag; fmt->args[n].tag = tag;
fmt->args[n].fld = fld; fmt->args[n].fld = fld;
...@@ -922,6 +939,11 @@ compile_fmt(char * const format, compiled_fmt_t * const fmt, ...@@ -922,6 +939,11 @@ compile_fmt(char * const format, compiled_fmt_t * const fmt,
strcpy(err, strerror(errno)); strcpy(err, strerror(errno));
return 0; return 0;
} }
fmt->strlen = (int *) calloc(n, sizeof(int));
if (fmt->strlen == NULL) {
strcpy(err, strerror(errno));
return 0;
}
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
fmt->args[i].hdr_idx = -1; fmt->args[i].hdr_idx = -1;
*hdrtbl = calloc(n, sizeof(char *)); *hdrtbl = calloc(n, sizeof(char *));
...@@ -1332,6 +1354,9 @@ FMT_Init(char *err) ...@@ -1332,6 +1354,9 @@ FMT_Init(char *err)
int idx = 0; int idx = 0;
char **chdrtbl = NULL, **bhdrtbl = NULL, **rhdrtbl = NULL; char **chdrtbl = NULL, **bhdrtbl = NULL, **rhdrtbl = NULL;
obuf = calloc(OBUF_SIZE, sizeof(char));
if (obuf == NULL)
return ENOMEM;
payload = malloc(config.max_reclen); payload = malloc(config.max_reclen);
if (payload == NULL) if (payload == NULL)
return ENOMEM; return ENOMEM;
...@@ -1427,10 +1452,22 @@ FMT_Estimate_RecsPerTx(void) ...@@ -1427,10 +1452,22 @@ FMT_Estimate_RecsPerTx(void)
return recs_per_tx; return recs_per_tx;
} }
void static inline void
FMT_Format(tx_t *tx, struct vsb *os) fmt_resize(size_t curlen)
{
if (curlen > obuf_sz) {
obuf_sz >>= 1;
obuf = realloc(obuf, obuf_sz);
AN(obuf);
}
}
char *
FMT_Format(tx_t *tx)
{ {
compiled_fmt_t fmt; compiled_fmt_t fmt;
char *p = obuf;
size_t curlen = 0;
CHECK_OBJ_NOTNULL(tx, TX_MAGIC); CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
assert(tx->state == TX_SUBMITTED); assert(tx->state == TX_SUBMITTED);
...@@ -1451,21 +1488,33 @@ FMT_Format(tx_t *tx, struct vsb *os) ...@@ -1451,21 +1488,33 @@ FMT_Format(tx_t *tx, struct vsb *os)
tx->state = TX_FORMATTING; tx->state = TX_FORMATTING;
*p = '\0';
for (int i = 0; i < fmt.n; i++) { for (int i = 0; i < fmt.n; i++) {
char *s = NULL; char *s = NULL;
size_t len = 0; size_t len = 0;
if (fmt.str[i] != NULL) if (fmt.str[i] != NULL) {
VSB_cat(os, fmt.str[i]); curlen += fmt.strlen[i];
fmt_resize(curlen);
memcpy(p, fmt.str[i], fmt.strlen[i]);
p += fmt.strlen[i];
}
if (fmt.formatter[i] != NULL) { if (fmt.formatter[i] != NULL) {
(fmt.formatter[i])(tx, &fmt.args[i], &s, &len); (fmt.formatter[i])(tx, &fmt.args[i], &s, &len);
if (s != NULL && len != 0) if (s != NULL && len != 0) {
VSB_bcat(os, s, len); curlen += len;
fmt_resize(curlen);
memcpy(p, s, len);
p += len;
}
} }
} }
*p = '\0';
assert(tx->state == TX_FORMATTING); assert(tx->state == TX_FORMATTING);
tx->state = TX_WRITTEN; tx->state = TX_WRITTEN;
return obuf;
} }
static void static void
...@@ -1491,6 +1540,7 @@ free_format(compiled_fmt_t *fmt) ...@@ -1491,6 +1540,7 @@ free_format(compiled_fmt_t *fmt)
free(fmt->args[i].name); free(fmt->args[i].name);
} }
free(fmt->str); free(fmt->str);
free(fmt->strlen);
free(fmt->formatter); free(fmt->formatter);
free(fmt->args); free(fmt->args);
} }
...@@ -1511,6 +1561,7 @@ free_incl(includehead_t inclhead[]) ...@@ -1511,6 +1561,7 @@ free_incl(includehead_t inclhead[])
void void
FMT_Fini(void) FMT_Fini(void)
{ {
free(obuf);
VSB_delete(scratch); VSB_delete(scratch);
free(payload); free(payload);
......
...@@ -1869,13 +1869,12 @@ static const char ...@@ -1869,13 +1869,12 @@ static const char
*test_FMT_interface(void) *test_FMT_interface(void)
{ {
#define NTAGS 25 #define NTAGS 25
char err[BUFSIZ], strftime_s[BUFSIZ]; char err[BUFSIZ], strftime_s[BUFSIZ], *os;
int status; int status;
tx_t tx; tx_t tx;
rec_node_t node[NTAGS], *nptr[NTAGS]; rec_node_t node[NTAGS], *nptr[NTAGS];
rec_t rec[NTAGS]; rec_t rec[NTAGS];
chunk_t c[NTAGS]; chunk_t c[NTAGS];
struct vsb *os;
struct tm *tm; struct tm *tm;
time_t t = 1427743146; time_t t = 1427743146;
...@@ -1921,8 +1920,6 @@ static const char ...@@ -1921,8 +1920,6 @@ static const char
break; break;
} }
os = VSB_new_auto();
MAN(os);
init_tx(&tx, node, nptr); init_tx(&tx, node, nptr);
tx.state = TX_SUBMITTED; tx.state = TX_SUBMITTED;
...@@ -1945,19 +1942,16 @@ static const char ...@@ -1945,19 +1942,16 @@ static const char
add_record_data(&tx, SLT_RespStatus, &rec[9], &c[9], "200"); add_record_data(&tx, SLT_RespStatus, &rec[9], &c[9], "200");
add_record_data(&tx, SLT_ReqAcct, &rec[10], &c[10], REQACCT_PAYLOAD); add_record_data(&tx, SLT_ReqAcct, &rec[10], &c[10], REQACCT_PAYLOAD);
FMT_Format(&tx, os); os = FMT_Format(&tx);
VSB_finish(os);
#define EXP_DEFAULT_OUTPUT "127.0.0.1 - varnish [%d/%b/%Y:%T %z] "\ #define EXP_DEFAULT_OUTPUT "127.0.0.1 - varnish [%d/%b/%Y:%T %z] "\
"\"GET http://bazquux.com/foo HTTP/1.1\" 200 105 "\ "\"GET http://bazquux.com/foo HTTP/1.1\" 200 105 "\
"\"http://foobar.com/\" \"Mozilla\"\n" "\"http://foobar.com/\" \"Mozilla\"\n"
tm = localtime(&t); tm = localtime(&t);
MAN(strftime(strftime_s, BUFSIZ, EXP_DEFAULT_OUTPUT, tm)); MAN(strftime(strftime_s, BUFSIZ, EXP_DEFAULT_OUTPUT, tm));
VMASSERT(strcmp(VSB_data(os), strftime_s) == 0, "'%s' != '%s'", VMASSERT(strcmp(os, strftime_s) == 0, "'%s' != '%s'", os, strftime_s);
VSB_data(os), strftime_s);
/* Client format with all formatters */ /* Client format with all formatters */
FMT_Fini(); FMT_Fini();
VSB_clear(os);
#define FULL_CLIENT_FMT "%b %d %D %H %h %I %{Foo}i %{Bar}o %l %m %O %q %r %s "\ #define FULL_CLIENT_FMT "%b %d %D %H %h %I %{Foo}i %{Bar}o %l %m %O %q %r %s "\
"%t %T %{%F-%T.%i}t %U %u %{Varnish:time_firstbyte}x "\ "%t %T %{%F-%T.%i}t %U %u %{Varnish:time_firstbyte}x "\
...@@ -2030,8 +2024,7 @@ static const char ...@@ -2030,8 +2024,7 @@ static const char
} }
setup_full_client_tx(&tx, node, nptr, rec, c); setup_full_client_tx(&tx, node, nptr, rec, c);
FMT_Format(&tx, os); os = FMT_Format(&tx);
VSB_finish(os);
#define EXP_FULL_CLIENT_OUTPUT "105 c 15963 HTTP/1.1 127.0.0.1 60 foohdr "\ #define EXP_FULL_CLIENT_OUTPUT "105 c 15963 HTTP/1.1 127.0.0.1 60 foohdr "\
"barhdr - GET 283 bar=baz&quux=wilco GET "\ "barhdr - GET 283 bar=baz&quux=wilco GET "\
"http://foobar.com/foo?bar=baz&quux=wilco HTTP/1.1 200 "\ "http://foobar.com/foo?bar=baz&quux=wilco HTTP/1.1 200 "\
...@@ -2040,12 +2033,10 @@ static const char ...@@ -2040,12 +2033,10 @@ static const char
"1429213569.602005 0.000000 0.000000 60 0.000125 4711 1147\n" "1429213569.602005 0.000000 0.000000 60 0.000125 4711 1147\n"
tm = localtime(&t); tm = localtime(&t);
MAN(strftime(strftime_s, BUFSIZ, EXP_FULL_CLIENT_OUTPUT, tm)); MAN(strftime(strftime_s, BUFSIZ, EXP_FULL_CLIENT_OUTPUT, tm));
VMASSERT(strcmp(VSB_data(os), strftime_s) == 0, "'%s' != '%s'", VMASSERT(strcmp(os, strftime_s) == 0, "'%s' != '%s'", os, strftime_s);
VSB_data(os), strftime_s);
/* Backend format with all formatters */ /* Backend format with all formatters */
FMT_Fini(); FMT_Fini();
VSB_clear(os);
#define FULL_BACKEND_FMT "%b %d %D %H %h %I %{Foo}i %{Bar}o %l %m %O %q %r %s "\ #define FULL_BACKEND_FMT "%b %d %D %H %h %I %{Foo}i %{Bar}o %l %m %O %q %r %s "\
"%t %T %{%F-%T.%i}t %U %u %{Varnish:time_firstbyte}x %{VCL_Log:baz}x "\ "%t %T %{%F-%T.%i}t %U %u %{Varnish:time_firstbyte}x %{VCL_Log:baz}x "\
...@@ -2109,8 +2100,7 @@ static const char ...@@ -2109,8 +2100,7 @@ static const char
} }
setup_full_backend_tx(&tx, node, nptr, rec, c); setup_full_backend_tx(&tx, node, nptr, rec, c);
FMT_Format(&tx, os); os = FMT_Format(&tx);
VSB_finish(os);
#define EXP_FULL_BACKEND_OUTPUT "105 b 15703 HTTP/1.1 default(127.0.0.1,,80) "\ #define EXP_FULL_BACKEND_OUTPUT "105 b 15703 HTTP/1.1 default(127.0.0.1,,80) "\
"283 foohdr barhdr - GET 60 bar=baz&quux=wilco GET "\ "283 foohdr barhdr - GET 60 bar=baz&quux=wilco GET "\
"http://foobar.com/foo?bar=baz&quux=wilco HTTP/1.1 200 "\ "http://foobar.com/foo?bar=baz&quux=wilco HTTP/1.1 200 "\
...@@ -2119,12 +2109,10 @@ static const char ...@@ -2119,12 +2109,10 @@ static const char
"1429210777.728290 0.000048 0.000048 283 0.000048 4711 1147\n" "1429210777.728290 0.000048 0.000048 283 0.000048 4711 1147\n"
tm = localtime(&t); tm = localtime(&t);
MAN(strftime(strftime_s, BUFSIZ, EXP_FULL_BACKEND_OUTPUT, tm)); MAN(strftime(strftime_s, BUFSIZ, EXP_FULL_BACKEND_OUTPUT, tm));
VMASSERT(strcmp(VSB_data(os), strftime_s) == 0, "'%s' != '%s'", VMASSERT(strcmp(os, strftime_s) == 0, "'%s' != '%s'", os, strftime_s);
VSB_data(os), strftime_s);
/* Both backend and client formats */ /* Both backend and client formats */
FMT_Fini(); FMT_Fini();
VSB_clear(os);
VSB_clear(config.cformat); VSB_clear(config.cformat);
VSB_cpy(config.cformat, FULL_CLIENT_FMT); VSB_cpy(config.cformat, FULL_CLIENT_FMT);
...@@ -2225,25 +2213,19 @@ static const char ...@@ -2225,25 +2213,19 @@ static const char
} }
setup_full_client_tx(&tx, node, nptr, rec, c); setup_full_client_tx(&tx, node, nptr, rec, c);
FMT_Format(&tx, os); os = FMT_Format(&tx);
VSB_finish(os);
tm = localtime(&t); tm = localtime(&t);
MAN(strftime(strftime_s, BUFSIZ, EXP_FULL_CLIENT_OUTPUT, tm)); MAN(strftime(strftime_s, BUFSIZ, EXP_FULL_CLIENT_OUTPUT, tm));
VMASSERT(strcmp(VSB_data(os), strftime_s) == 0, "'%s' != '%s'", VMASSERT(strcmp(os, strftime_s) == 0, "'%s' != '%s'", os, strftime_s);
VSB_data(os), strftime_s);
setup_full_backend_tx(&tx, node, nptr, rec, c); setup_full_backend_tx(&tx, node, nptr, rec, c);
VSB_clear(os); os = FMT_Format(&tx);
FMT_Format(&tx, os);
VSB_finish(os);
tm = localtime(&t); tm = localtime(&t);
MAN(strftime(strftime_s, BUFSIZ, EXP_FULL_BACKEND_OUTPUT, tm)); MAN(strftime(strftime_s, BUFSIZ, EXP_FULL_BACKEND_OUTPUT, tm));
VMASSERT(strcmp(VSB_data(os), strftime_s) == 0, "'%s' != '%s'", VMASSERT(strcmp(os, strftime_s) == 0, "'%s' != '%s'", os, strftime_s);
VSB_data(os), strftime_s);
/* Raw format */ /* Raw format */
FMT_Fini(); FMT_Fini();
VSB_clear(os);
#define FULL_RAW_FMT "%t %{%F-%T.%i}t %{tag:Backend_health}x %{vxid}x" #define FULL_RAW_FMT "%t %{%F-%T.%i}t %{tag:Backend_health}x %{vxid}x"
VSB_clear(config.rformat); VSB_clear(config.rformat);
...@@ -2274,14 +2256,12 @@ static const char ...@@ -2274,14 +2256,12 @@ static const char
#define HEALTH_PAYLOAD "b Still healthy 4--X-RH 5 4 5 0.032728 0.035774 " \ #define HEALTH_PAYLOAD "b Still healthy 4--X-RH 5 4 5 0.032728 0.035774 " \
"HTTP/1.1 200 OK" "HTTP/1.1 200 OK"
add_record_data(&tx, SLT_Backend_health, &rec[0], &c[0], HEALTH_PAYLOAD); add_record_data(&tx, SLT_Backend_health, &rec[0], &c[0], HEALTH_PAYLOAD);
FMT_Format(&tx, os); os = FMT_Format(&tx);
VSB_finish(os);
#define EXP_FULL_RAW_OUTPUT "[%d/%b/%Y:%T %z] %F-%T.529143 "\ #define EXP_FULL_RAW_OUTPUT "[%d/%b/%Y:%T %z] %F-%T.529143 "\
"b Still healthy 4--X-RH 5 4 5 0.032728 0.035774 HTTP/1.1 200 OK 4711\n" "b Still healthy 4--X-RH 5 4 5 0.032728 0.035774 HTTP/1.1 200 OK 4711\n"
tm = localtime(&t); tm = localtime(&t);
MAN(strftime(strftime_s, BUFSIZ, EXP_FULL_RAW_OUTPUT, tm)); MAN(strftime(strftime_s, BUFSIZ, EXP_FULL_RAW_OUTPUT, tm));
VMASSERT(strcmp(VSB_data(os), strftime_s) == 0, "'%s' != '%s'", VMASSERT(strcmp(os, strftime_s) == 0, "'%s' != '%s'", os, strftime_s);
VSB_data(os), strftime_s);
/* Illegal backend formats */ /* Illegal backend formats */
FMT_Fini(); FMT_Fini();
......
...@@ -284,7 +284,7 @@ void MON_Output(void); ...@@ -284,7 +284,7 @@ void MON_Output(void);
int FMT_Init(char *err); int FMT_Init(char *err);
int FMT_GetMaxIdx(void); int FMT_GetMaxIdx(void);
int FMT_Estimate_RecsPerTx(void); int FMT_Estimate_RecsPerTx(void);
void FMT_Format(tx_t *tx, struct vsb *os); char *FMT_Format(tx_t *tx);
void FMT_Fini(void); void FMT_Fini(void);
/* handler.c */ /* handler.c */
......
...@@ -74,8 +74,6 @@ chunkhead_t wrt_freechunks; ...@@ -74,8 +74,6 @@ chunkhead_t wrt_freechunks;
static unsigned wrt_nfree_tx, wrt_nfree_recs, wrt_nfree_chunks; static unsigned wrt_nfree_tx, wrt_nfree_recs, wrt_nfree_chunks;
static struct vsb *os;
static FILE *fo; static FILE *fo;
static struct pollfd fds[1]; static struct pollfd fds[1];
static int blocking = 0, timeout = -1; static int blocking = 0, timeout = -1;
...@@ -178,6 +176,7 @@ wrt_return_freelist(void) ...@@ -178,6 +176,7 @@ wrt_return_freelist(void)
void void
wrt_write(tx_t *tx) wrt_write(tx_t *tx)
{ {
char *os;
int ready = 1; int ready = 1;
CHECK_OBJ_NOTNULL(tx, TX_MAGIC); CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
...@@ -205,10 +204,8 @@ wrt_write(tx_t *tx) ...@@ -205,10 +204,8 @@ wrt_write(tx_t *tx)
} }
AZ(pthread_mutex_unlock(&reopen_lock)); AZ(pthread_mutex_unlock(&reopen_lock));
VSB_clear(os);
VRMB(); VRMB();
FMT_Format(tx, os); os = FMT_Format(tx);
VSB_finish(os);
assert(tx->state == TX_WRITTEN); assert(tx->state == TX_WRITTEN);
if (blocking) { if (blocking) {
...@@ -226,14 +223,13 @@ wrt_write(tx_t *tx) ...@@ -226,14 +223,13 @@ wrt_write(tx_t *tx)
if (fds[0].revents & POLLERR) { if (fds[0].revents & POLLERR) {
LOG_Log(LOG_ERR, LOG_Log(LOG_ERR,
"Error waiting for ready output %d (%s), " "Error waiting for ready output %d (%s), "
"DATA DISCARDED: %s", errno, strerror(errno), VSB_data(os)); "DATA DISCARDED: %s", errno, strerror(errno), os);
errors++; errors++;
} }
else if (nfds == 0) { else if (nfds == 0) {
wrt_return_freelist(); wrt_return_freelist();
LOG_Log(LOG_ERR, LOG_Log(LOG_ERR,
"Timeout waiting for ready output, DATA DISCARDED: %s", "Timeout waiting for ready output, DATA DISCARDED: %s", os);
VSB_data(os));
timeouts++; timeouts++;
} }
else if (nfds != 1) else if (nfds != 1)
...@@ -245,16 +241,16 @@ wrt_write(tx_t *tx) ...@@ -245,16 +241,16 @@ wrt_write(tx_t *tx)
} }
if (ready) { if (ready) {
double start = VTIM_mono(); double start = VTIM_mono();
int ret = fprintf(fo, "%s", VSB_data(os)); int ret = fprintf(fo, "%s", os);
writet += VTIM_mono() - start; writet += VTIM_mono() - start;
if (ret < 0) { if (ret < 0) {
LOG_Log(LOG_ERR, "Output error %d (%s), DATA DISCARDED: %s", LOG_Log(LOG_ERR, "Output error %d (%s), DATA DISCARDED: %s",
errno, strerror(errno), VSB_data(os)); errno, strerror(errno), os);
errors++; errors++;
} }
else { else {
writes++; writes++;
bytes += VSB_len(os); bytes += strlen(os);
} }
} }
...@@ -349,9 +345,6 @@ WRT_Init(void) ...@@ -349,9 +345,6 @@ WRT_Init(void)
wrt_data.magic = WRITER_DATA_MAGIC; wrt_data.magic = WRITER_DATA_MAGIC;
wrt_data.state = WRT_NOTSTARTED; wrt_data.state = WRT_NOTSTARTED;
/* XXX: fixed size? */
os = VSB_new_auto();
if (config.output_timeout != 0.) if (config.output_timeout != 0.)
timeout = config.output_timeout * 1e3; timeout = config.output_timeout * 1e3;
...@@ -425,6 +418,5 @@ WRT_Fini(void) ...@@ -425,6 +418,5 @@ WRT_Fini(void)
AZ(run); AZ(run);
fclose(fo); fclose(fo);
free(obuf); free(obuf);
VSB_delete(os);
AZ(pthread_mutex_destroy(&reopen_lock)); AZ(pthread_mutex_destroy(&reopen_lock));
} }
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