[master] 916473552 debug stoage: Add support for maxsize=<BYTES>
Nils Goroll
nils.goroll at uplex.de
Fri Apr 11 10:52:09 UTC 2025
commit 9164735521989e54d8a8599828498797bc271107
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Fri Apr 11 12:45:21 2025 +0200
debug stoage: Add support for maxsize=<BYTES>
If the maximum is reached, allocations fail.
diff --git a/bin/varnishd/storage/storage_debug.c b/bin/varnishd/storage/storage_debug.c
index bf4a01a43..e144f9648 100644
--- a/bin/varnishd/storage/storage_debug.c
+++ b/bin/varnishd/storage/storage_debug.c
@@ -52,6 +52,7 @@
*/
static vtim_dur dopen = 0.0;
static unsigned count = 0;
+static ssize_t max_size = 0;
/* returns one byte less than requested */
static int v_matchproto_(objgetspace_f)
@@ -64,10 +65,61 @@ smd_lsp_getspace(struct worker *wrk, struct objcore *oc, ssize_t *sz,
return (SML_methods.objgetspace(wrk, oc, sz, ptr));
}
+/*
+ * returns max_size at most, then fails
+ *
+ * relies on the actual storage implementation to not use priv2
+ */
+static int v_matchproto_(objgetspace_f)
+smd_max_getspace(struct worker *wrk, struct objcore *oc, ssize_t *sz,
+ uint8_t **ptr)
+{
+ ssize_t used;
+ int r;
+
+ AN(sz);
+ used = (ssize_t)oc->stobj->priv2;
+
+ VSLb(wrk->vsl, SLT_Debug, "-sdebug: %zd/%zd", used, max_size);
+
+ if (used >= max_size) {
+ VSLb(wrk->vsl, SLT_Storage, "-sdebug: max_size=%zd reached", max_size);
+ return (0);
+ }
+
+ assert(used < max_size);
+ *sz = vmin_t(ssize_t, *sz, max_size - used);
+
+ r = SML_methods.objgetspace(wrk, oc, sz, ptr);
+ if (r != 0)
+ oc->stobj->priv2 = (uint64_t)(used + *sz);
+ return (r);
+}
+
#define dur_arg(a, s, d) \
(! strncmp((a), (s), strlen(s)) \
&& (d = VNUM_duration(a + strlen(s))) != nan(""))
+static int
+bytes_arg(char *a, const char *s, ssize_t *sz)
+{
+ const char *err;
+ uintmax_t bytes;
+
+ AN(sz);
+ if (strncmp(a, s, strlen(s)))
+ return (0);
+ a += strlen(s);
+ err = VNUM_2bytes(a, &bytes, 0);
+ if (err != NULL)
+ ARGV_ERR("%s\n", err);
+ assert(bytes <= SSIZE_MAX);
+ *sz = (ssize_t)bytes;
+
+ return (1);
+}
+
+
static void smd_open(struct stevedore *stv)
{
sma_stevedore.open(stv);
@@ -80,6 +132,7 @@ static void v_matchproto_(storage_init_f)
smd_init(struct stevedore *parent, int aac, char * const *aav)
{
struct obj_methods *methods;
+ objgetspace_f *getspace = NULL;
const char *ident;
int i, ac = 0;
size_t nac;
@@ -109,7 +162,19 @@ smd_init(struct stevedore *parent, int aac, char * const *aav)
a = aav[i];
if (a != NULL) {
if (! strcmp(a, "lessspace")) {
- methods->objgetspace = smd_lsp_getspace;
+ if (getspace != NULL) {
+ ARGV_ERR("-s%s conflicting options\n",
+ smd_stevedore.name);
+ }
+ getspace = smd_lsp_getspace;
+ continue;
+ }
+ if (bytes_arg(a, "maxspace=", &max_size)) {
+ if (getspace != NULL) {
+ ARGV_ERR("-s%s conflicting options\n",
+ smd_stevedore.name);
+ }
+ getspace = smd_max_getspace;
continue;
}
if (dur_arg(a, "dinit=", d)) {
@@ -128,6 +193,9 @@ smd_init(struct stevedore *parent, int aac, char * const *aav)
assert(ac < (int)nac);
AZ(av[ac]);
+ if (getspace != NULL)
+ methods->objgetspace = getspace;
+
sma_stevedore.init(parent, ac, av);
free(av);
fprintf(stderr, "-sdebug init delay %fs\n", dinit);
diff --git a/bin/varnishtest/tests/c00030.vtc b/bin/varnishtest/tests/c00030.vtc
index 912337dbf..b0eb4945a 100644
--- a/bin/varnishtest/tests/c00030.vtc
+++ b/bin/varnishtest/tests/c00030.vtc
@@ -2,3 +2,50 @@ varnishtest "debug storage"
shell -err -expect {Error: Only one -sdebug instance supported} \
"varnishd -b none -a ${tmpdir}/vtc.sock -sdebug -sdebug"
+
+shell -err -expect {Error: -sdebug conflicting options} \
+ "varnishd -b none -a ${tmpdir}/vtc.sock -sdebug,lessspace,maxspace=1KB"
+
+shell -err -expect {Error: Unknown BYTES} \
+ "varnishd -b none -a ${tmpdir}/vtc.sock -sdebug,maxspace=1DJT"
+
+# lessspace is implicitly tested in b00017.vtc
+
+server s1 {
+ rxreq
+ txresp -bodylen 1024
+
+ rxreq
+ txresp -bodylen 1025
+} -start
+
+
+varnish v1 -arg "-sTransient=debug,maxspace=1KB" -vcl+backend {
+ sub vcl_recv {
+ return(pass);
+ }
+} -start
+
+logexpect l1 -v v1 -q "BerespHeader:Content-Length eq 1025" {
+ fail add * End
+ expect * * Storage {^-sdebug: max_size=1024 reached}
+ expect 0 = FetchError {^Could not get storage}
+ expect 0 = BackendClose {close RX_BODY}
+ fail clear
+} -start
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.bodylen == 1024
+
+ txreq
+ rxresphdrs
+ expect resp.status == 200
+ expect resp.http.Content-Length == 1025
+ rxrespbody -max 1024
+ expect_close
+ expect resp.bodylen == 1024
+} -run
+
+logexpect l1 -wait
More information about the varnish-commit
mailing list