[master] 97537cb17 Create a directory owned by the worker process for use as a TMPDIR
Nils Goroll
nils.goroll at uplex.de
Mon May 27 15:46:02 UTC 2024
commit 97537cb1784f69a5862acf6d4e78713a2cb1e033
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Mon May 27 17:43:22 2024 +0200
Create a directory owned by the worker process for use as a TMPDIR
Processes created by the worker might require a TMPDIR for temporary
files (think: filters). Create a dedicated directory for this purpose,
which is otherwise hard to achieve in a universal manner.
diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c
index 192ae202a..1b2ddbc2f 100644
--- a/bin/varnishd/mgt/mgt_main.c
+++ b/bin/varnishd/mgt/mgt_main.c
@@ -319,6 +319,7 @@ mgt_Cflag_atexit(void)
VJ_rmdir("vext_cache");
}
VJ_rmdir("vmod_cache");
+ VJ_rmdir("worker_tmpdir");
(void)chdir("/");
VJ_rmdir(workdir);
}
@@ -865,7 +866,7 @@ main(int argc, char * const *argv)
workdir, VAS_errtxt(errno));
VJ_master(JAIL_MASTER_SYSTEM);
- AZ(system("rm -rf vmod_cache vext_cache"));
+ AZ(system("rm -rf vmod_cache vext_cache worker_tmpdir"));
VJ_master(JAIL_MASTER_LOW);
if (VJ_make_subdir("vmod_cache", "VMOD cache", NULL)) {
@@ -881,6 +882,13 @@ main(int argc, char * const *argv)
workdir, VAS_errtxt(errno));
}
+ if (VJ_make_subdir("worker_tmpdir",
+ "TMPDIR for the worker process", NULL)) {
+ ARGV_ERR(
+ "Cannot create vmod directory (%s/worker_tmpdir): %s\n",
+ workdir, VAS_errtxt(errno));
+ }
+
if (C_flag)
AZ(atexit(mgt_Cflag_atexit));
diff --git a/doc/changes.rst b/doc/changes.rst
index dbe31e3ab..ba74f7c13 100644
--- a/doc/changes.rst
+++ b/doc/changes.rst
@@ -41,11 +41,17 @@ Varnish Cache NEXT (2024-09-15)
.. PLEASE keep this roughly in commit order as shown by git-log / tig
(new to old)
+* ``varnishd`` now creates a ``worker_tmpdir`` which can be used by
+ VMODs for temporary files. The `VMOD deleveloper documentation`_ has
+ details.
+
* The environment variable ``VARNISH_DEFAULT_N`` now provides the
default "varnish name" / "workdir" as otherwise specified by he
``-n`` argument to ``varnishd`` and ``varnish*`` utilities except
``varnishtest``.
+.. _VMOD deleveloper documentation: doc/sphinx/reference/vmod.rst
+
================================
Varnish Cache 7.5.0 (2024-03-18)
================================
diff --git a/doc/sphinx/reference/vmod.rst b/doc/sphinx/reference/vmod.rst
index b8a524ce6..193b9060d 100644
--- a/doc/sphinx/reference/vmod.rst
+++ b/doc/sphinx/reference/vmod.rst
@@ -858,3 +858,47 @@ You should call ``VSC_*_New()`` when your VMOD is loaded and
``VSC_*_Destroy()`` when it is unloaded. See the generated
``VSC_*.h`` file for the full details about the structure that contains
your counters.
+
+Temporary Files
+===============
+
+``varnishd`` creates a directroy named ``worker_tmpdir`` under the
+varnish working directory (see ``varnishd -n`` argument) for
+read/write access by the worker process.
+
+From the perspective of VMODs, the relative path is always
+``worker_tmpdir``.
+
+This directory is intended (though not limited) to provide a place for
+VMODs to create temporary files using ``mkstemp()`` and related libc
+functions. VMODs are responsible for cleaning up files which are no
+longer required, and they will ultimately be removed when the
+``varnishd`` worker process restarts. There is no isolation between
+VMODs (as is the case anyway).
+
+A simple example for how to use it::
+
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ #include "vdef.h"
+ #include "vas.h"
+
+ static void
+ tmpfile_example(void) {
+ int fd;
+ char name[] = "worker_tmpdir/myvmod.XXXXXX";
+
+ fd = mkstemp(name);
+ if (fd < 0) {
+ // handle error
+ return;
+ }
+
+ // hide file
+ AZ(unlink(name));
+
+ // use fd
+
+ AZ(close(fd));
+ }
diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c
index 8f3f5636e..e2e42ee51 100644
--- a/vmod/vmod_debug.c
+++ b/vmod/vmod_debug.c
@@ -55,6 +55,7 @@ struct priv_vcl {
VCL_BACKEND be;
unsigned cold_be;
unsigned cooling_be;
+ int tmpf;
};
@@ -401,12 +402,18 @@ VCL_VOID v_matchproto_(td_debug_test_priv_vcl)
xyzzy_test_priv_vcl(VRT_CTX, struct vmod_priv *priv)
{
struct priv_vcl *priv_vcl;
+ char t[PATH_MAX];
+ ssize_t l;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(priv);
CAST_OBJ_NOTNULL(priv_vcl, priv->priv, PRIV_VCL_MAGIC);
+
+ l = pread(priv_vcl->tmpf, t, sizeof t, 0);
+ assert(l > 0);
+
AN(priv_vcl->foo);
- assert(!strcmp(priv_vcl->foo, "FOO"));
+ assert(!strncmp(priv_vcl->foo, t, l));
}
VCL_VOID v_matchproto_(td_debug_rot104)
@@ -501,7 +508,9 @@ priv_vcl_fini(VRT_CTX, void *priv)
struct priv_vcl *priv_vcl;
CAST_OBJ_NOTNULL(priv_vcl, priv, PRIV_VCL_MAGIC);
+ AZ(close(priv_vcl->tmpf));
AN(priv_vcl->foo);
+ AZ(unlink(priv_vcl->foo));
free(priv_vcl->foo);
if (priv_vcl->obj_cb != 0) {
ObjUnsubscribeEvents(&priv_vcl->obj_cb);
@@ -534,8 +543,11 @@ event_load(VRT_CTX, struct vmod_priv *priv)
ALLOC_OBJ(priv_vcl, PRIV_VCL_MAGIC);
AN(priv_vcl);
- priv_vcl->foo = strdup("FOO");
+ priv_vcl->foo = strdup("worker_tmpdir/vmod_debug.XXXXXX");
AN(priv_vcl->foo);
+ priv_vcl->tmpf = mkstemp(priv_vcl->foo);
+ assert(priv_vcl->tmpf >= 0);
+ AN(write(priv_vcl->tmpf, priv_vcl->foo, strlen(priv_vcl->foo)));
priv->priv = priv_vcl;
priv->methods = priv_vcl_methods;
More information about the varnish-commit
mailing list