Commit 6225c0af authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add the foundation of the "VEXT" mechanism

parent 1157dfdc
......@@ -57,6 +57,7 @@ varnishd_SOURCES = \
cache/cache_ws_common.c \
common/common_vsc.c \
common/common_vsmw.c \
common/common_vext.c \
hash/hash_classic.c \
hash/hash_critbit.c \
hash/hash_simple_list.c \
......
/*-
* Copyright (c) 2022 Varnish Software AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Loadable extensions
*/
#include "config.h"
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "vdef.h"
#include "vas.h"
#include "miniobj.h"
#include "vav.h"
#include "vqueue.h"
#include "vrnd.h"
#include "vsb.h"
#include "heritage.h"
struct vext {
unsigned magic;
#define VEXT_MAGIC 0xd5063ef6
VTAILQ_ENTRY(vext) list;
char **argv;
int fd;
struct vsb *vsb;
void *dlptr;
};
static VTAILQ_HEAD(,vext) vext_list =
VTAILQ_HEAD_INITIALIZER(vext_list);
void
vext_argument(const char *arg)
{
struct vext *vp;
fprintf(stderr, "EEE <%s>\n", arg);
ALLOC_OBJ(vp, VEXT_MAGIC);
AN(vp);
vp->argv = VAV_Parse(arg, NULL, ARGV_COMMA);
AN(vp->argv);
if (vp->argv[0] != NULL)
ARGV_ERR("\tParse failure in argument: %s\n\t%s\n",
arg, vp->argv[0]);
VTAILQ_INSERT_TAIL(&vext_list, vp, list);
fprintf(stderr, "eee <%s>\n", vp->argv[1]);
vp->fd = open(vp->argv[1], O_RDONLY);
if (vp->fd < 0)
ARGV_ERR("\tCannot open %s\n\t%s\n",
vp->argv[1], strerror(errno));
}
void
vext_copyin(struct vsb *vident)
{
struct vext *vp;
const char *p;
int i, fdo;
unsigned u;
char buf[BUFSIZ];
ssize_t sz, szw;
VTAILQ_FOREACH(vp, &vext_list, list) {
if (vp->vsb == NULL) {
vp->vsb = VSB_new_auto();
AN(vp->vsb);
}
VSB_clear(vp->vsb);
p = strrchr(vp->argv[1], '/');
if (p != NULL)
p++;
else
p = vp->argv[0];
VSB_printf(vident, ",-E%s", p);
VSB_printf(vp->vsb, "vext_cache/%s,", p);
for (i = 0; i < 8; i++) {
AZ(VRND_RandomCrypto(&u, sizeof u));
u %= 26;
VSB_printf(vp->vsb, "%c", 'a' + (char)u);
}
VSB_printf(vp->vsb, ".so");
AZ(VSB_finish(vp->vsb));
fprintf(stderr, "ee2 %s\n", VSB_data(vp->vsb));
fdo = open(VSB_data(vp->vsb), O_WRONLY|O_CREAT|O_EXCL, 0700);
xxxassert(fdo >= 0);
AZ(lseek(vp->fd, 0, SEEK_SET));
do {
sz = read(vp->fd, buf, sizeof buf);
if (sz > 0) {
szw = write(fdo, buf, sz);
xxxassert(szw == sz);
}
} while (sz > 0);
closefd(&fdo);
closefd(&vp->fd);
}
}
void
vext_load(void)
{
struct vext *vp;
VTAILQ_FOREACH(vp, &vext_list, list) {
vp->dlptr = dlopen(
VSB_data(vp->vsb),
RTLD_NOW | RTLD_GLOBAL
);
if (vp->dlptr == NULL) {
XXXAN(vp->dlptr);
}
fprintf(stderr, "Loaded -E %s\n", VSB_data(vp->vsb));
}
}
void
vext_cleanup(void)
{
struct vext *vp;
VTAILQ_FOREACH(vp, &vext_list, list) {
fprintf(stderr, "ee3 %s\n", VSB_data(vp->vsb));
if (vp->vsb != NULL && VSB_len(vp->vsb) > 0) {
XXXAZ(unlink(VSB_data(vp->vsb)));
VSB_clear(vp->vsb);
}
}
}
......@@ -129,3 +129,9 @@ extern vsm_lock_f *vsc_unlock;
extern vsm_lock_f *vsmw_lock;
extern vsm_lock_f *vsmw_unlock;
/* common/common_vext.c */
void vext_argument(const char *);
void vext_copyin(struct vsb *);
void vext_load(void);
void vext_cleanup(void);
......@@ -378,6 +378,8 @@ mgt_launch_child(struct cli *cli)
heritage.cls = mgt_cls;
heritage.ident = VSB_data(vident) + 1;
vext_load();
VJ_subproc(JAIL_SUBPROC_WORKER);
heritage.proc_vsmw = VSMW_New(heritage.vsm_fd, 0640, "_.index");
......@@ -385,7 +387,7 @@ mgt_launch_child(struct cli *cli)
/*
* We pass these two params because child_main needs them
* Well before it has found its own param struct.
* well before it has found its own param struct.
*/
child_main(mgt_param.sigsegv_handler,
mgt_param.wthread_stacksize);
......
......@@ -74,7 +74,7 @@ static char *workdir;
static struct vfil_path *vcl_path = NULL;
static const char opt_spec[] = "?a:b:Cdf:Fh:i:I:j:l:M:n:P:p:r:S:s:T:t:VW:x:";
static const char opt_spec[] = "?a:b:CdE:f:Fh:i:I:j:l:M:n:P:p:r:S:s:T:t:VW:x:";
/*--------------------------------------------------------------------*/
......@@ -123,6 +123,7 @@ usage(void)
printf(FMT, "-P file", "PID file");
printf(FMT, "-i identity", "Identity of varnish instance");
printf(FMT, "-I clifile", "Initialization CLI commands");
printf(FMT, "-E extension", "Load extension");
printf("\nTuning options:\n");
......@@ -284,7 +285,9 @@ mgt_Cflag_atexit(void)
/* Only master process */
if (getpid() != heritage.mgt_pid)
return;
vext_cleanup();
VJ_rmdir("vmod_cache");
VJ_rmdir("vext_cache");
(void)chdir("/");
VJ_rmdir(workdir);
}
......@@ -660,6 +663,7 @@ main(int argc, char * const *argv)
W_arg = optarg;
break;
case 'a':
case 'E':
case 'f':
case 'I':
case 'p':
......@@ -752,6 +756,9 @@ main(int argc, char * const *argv)
if (*alp->val != '\0')
alp->priv = mgt_f_read(alp->val);
break;
case 'E':
vext_argument(alp->val);
break;
case 'I':
VJ_master(JAIL_MASTER_FILE);
I_fd = open(alp->val, O_RDONLY);
......@@ -821,6 +828,7 @@ main(int argc, char * const *argv)
VJ_master(JAIL_MASTER_SYSTEM);
AZ(system("rm -rf vmod_cache"));
AZ(system("rm -rf vext_cache"));
VJ_master(JAIL_MASTER_LOW);
if (VJ_make_subdir("vmod_cache", "VMOD cache", NULL)) {
......@@ -829,6 +837,13 @@ main(int argc, char * const *argv)
workdir, VAS_errtxt(errno));
}
if (arg_list_count("E") &&
VJ_make_subdir("vext_cache", "VMOD cache", NULL)) {
ARGV_ERR(
"Cannot create vmod directory (%s/vext_cache): %s\n",
workdir, VAS_errtxt(errno));
}
if (C_flag)
AZ(atexit(mgt_Cflag_atexit));
......@@ -881,6 +896,8 @@ main(int argc, char * const *argv)
VPF_Write(alp->priv);
}
vext_copyin(vident);
AZ(VSB_finish(vident));
if (S_arg == NULL)
......@@ -968,6 +985,10 @@ main(int argc, char * const *argv)
MGT_Complain(C_INFO, "manager dies");
mgt_cli_close_all();
VEV_Destroy(&mgt_evb);
VJ_master(JAIL_MASTER_SYSTEM);
vext_cleanup();
(void)rmdir("vext_cache");
VJ_master(JAIL_MASTER_LOW);
VTAILQ_FOREACH(alp, &arglist, list) {
if (!strcmp(alp->arg, "P"))
VPF_Remove(alp->priv);
......
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