From: phk Date: Wed, 12 Mar 2008 14:07:08 +0000 (+0000) Subject: Further revamp the CLI handling in the cacher process, making it X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d6d53be724bb85650827ad76129606e91a5ea6b5;p=varnish Further revamp the CLI handling in the cacher process, making it possible for various modules to add cli functions so they can be manipulated on the fly. CLI_AddFuncs() registers a set of CLI functions. We operate with three lists: the ones not shown in "help" because the manager already showed them, the normal ones and the debug commands which are also not shown in a plain "help". Move the registration of cli functions out to the code they belong in: VCL, BAN and VCA. Give VCA a real Init function, and have the cli function ("start") initiate the acceptor thread which listens for incoming connections. Split CLI_Init() into CLI_Init() and CLI_Run() git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2598 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 536fb69f..467ad37a 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -79,6 +79,7 @@ struct workreq; struct addrinfo; struct esi_bit; struct vrt_backend; +struct cli_proto; /*--------------------------------------------------------------------*/ @@ -415,8 +416,6 @@ void VBE_SelectBackend(struct sess *sp); /* cache_ban.c */ void AddBan(const char *, int hash); void BAN_Init(void); -void ccf_url_purge(struct cli *cli, const char * const *av, void *priv); -void ccf_hash_purge(struct cli *cli, const char * const *av, void *priv); void BAN_NewObj(struct object *o); int BAN_CheckObject(struct object *o, const char *url, const char *hash); @@ -426,6 +425,9 @@ void CNT_Init(void); /* cache_cli.c [CLI] */ void CLI_Init(void); +void CLI_Run(void); +enum cli_set_e {MASTER_CLI, PUBLIC_CLI, DEBUG_CLI}; +void CLI_AddFuncs(enum cli_set_e which, struct cli_proto *p); extern pthread_t cli_thread; #define ASSERT_CLI() do {assert(pthread_self() == cli_thread);} while (0) @@ -558,13 +560,6 @@ void VCL_Idle(void); #undef VCL_MET_MAC #undef VCL_RET_MAC -#ifdef CLI_PRIV_H -cli_func_t ccf_config_list; -cli_func_t ccf_config_load; -cli_func_t ccf_config_discard; -cli_func_t ccf_config_use; -#endif - /* cache_vrt_esi.c */ void ESI_Deliver(struct sess *); diff --git a/varnish-cache/bin/varnishd/cache_acceptor.c b/varnish-cache/bin/varnishd/cache_acceptor.c index 09dffdba..12a77a93 100644 --- a/varnish-cache/bin/varnishd/cache_acceptor.c +++ b/varnish-cache/bin/varnishd/cache_acceptor.c @@ -50,6 +50,8 @@ #include "compat/srandomdev.h" #endif +#include "cli.h" +#include "cli_priv.h" #include "shmlog.h" #include "cache.h" #include "cache_acceptor.h" @@ -274,11 +276,13 @@ vca_return_session(struct sess *sp) /*--------------------------------------------------------------------*/ -void -VCA_Init(void) +static void +ccf_start(struct cli *cli, const char * const *av, void *priv) { - + (void)cli; + (void)av; + (void)priv; /* XXX: Add selector mechanism at some point */ vca_act = vca_acceptors[0]; @@ -291,3 +295,15 @@ VCA_Init(void) AZ(pthread_create(&vca_thread_acct, NULL, vca_acct, NULL)); VSL(SLT_Debug, 0, "Acceptor is %s", vca_act->name); } + +static struct cli_proto vca_cmds[] = { + { CLI_SERVER_START, ccf_start }, + { NULL } +}; + +void +VCA_Init(void) +{ + + CLI_AddFuncs(MASTER_CLI, vca_cmds); +} diff --git a/varnish-cache/bin/varnishd/cache_ban.c b/varnish-cache/bin/varnishd/cache_ban.c index d6e924ae..5dcbccd3 100644 --- a/varnish-cache/bin/varnishd/cache_ban.c +++ b/varnish-cache/bin/varnishd/cache_ban.c @@ -40,6 +40,7 @@ #include #include "shmlog.h" +#include "cli.h" #include "cli_priv.h" #include "cache.h" @@ -103,7 +104,7 @@ BAN_CheckObject(struct object *o, const char *url, const char *hash) return (0); } -void +static void ccf_url_purge(struct cli *cli, const char * const *av, void *priv) { @@ -112,7 +113,7 @@ ccf_url_purge(struct cli *cli, const char * const *av, void *priv) cli_out(cli, "PURGE %s\n", av[2]); } -void +static void ccf_hash_purge(struct cli *cli, const char * const *av, void *priv) { @@ -121,9 +122,16 @@ ccf_hash_purge(struct cli *cli, const char * const *av, void *priv) cli_out(cli, "PURGE %s\n", av[2]); } +static struct cli_proto ban_cmds[] = { + { CLI_URL_PURGE, ccf_url_purge }, + { CLI_HASH_PURGE, ccf_hash_purge }, + { NULL } +}; + void BAN_Init(void) { + CLI_AddFuncs(PUBLIC_CLI, ban_cmds); AddBan("\001", 0); } diff --git a/varnish-cache/bin/varnishd/cache_cli.c b/varnish-cache/bin/varnishd/cache_cli.c index 5bdf0cb7..63b05639 100644 --- a/varnish-cache/bin/varnishd/cache_cli.c +++ b/varnish-cache/bin/varnishd/cache_cli.c @@ -27,6 +27,13 @@ * SUCH DAMAGE. * * $Id$ + * + * Caching process CLI handling. + * + * We only have one CLI source, the stdin/stdout pipes from the manager + * process, but we complicate things by having undocumented commands that + * we do not want to show in a plain help, and by having commands that the + * manager has already shown in help before asking us. */ #include "config.h" @@ -47,106 +54,45 @@ #include "vsb.h" pthread_t cli_thread; +static MTX cli_mtx; -/*--------------------------------------------------------------------*/ - -static void -cli_debug_sizeof(struct cli *cli, const char * const *av, void *priv) -{ - (void)av; - (void)priv; - -#define SZOF(foo) cli_out(cli, \ - "sizeof(%s) = %zd = 0x%zx\n", #foo, sizeof(foo), sizeof(foo)); - SZOF(struct ws); - SZOF(struct http); - SZOF(struct http_conn); - SZOF(struct acct); - SZOF(struct worker); - SZOF(struct workreq); - SZOF(struct bereq); - SZOF(struct storage); - SZOF(struct object); - SZOF(struct objhead); - SZOF(struct sess); - SZOF(struct vbe_conn); -} - -/*--------------------------------------------------------------------*/ - -static void -ccf_start(struct cli *cli, const char * const *av, void *priv) -{ - - (void)cli; - (void)av; - (void)priv; - VCA_Init(); - return; -} - -/*--------------------------------------------------------------------*/ - -static void ccf_help(struct cli *cli, const char * const *av, void *priv); - -/*-------------------------------------------------------------------- +/* * The CLI commandlist is split in three: - * Commands we get from/share with the manager - * Cache process commands - * Undocumented commands + * - Commands we get from/share with the manager, we don't show these + * in help, as the manager already did that. + * - Cache process commands, show in help + * - Undocumented debug commands, show in undocumented "help -d" */ -static struct cli_proto master_cmds[] = { - { CLI_PING, cli_func_ping }, - { CLI_SERVER_START, ccf_start }, - { CLI_VCL_LOAD, ccf_config_load }, - { CLI_VCL_LIST, ccf_config_list }, - { CLI_VCL_DISCARD, ccf_config_discard }, - { CLI_VCL_USE, ccf_config_use }, - { NULL } -}; - -static struct cli_proto cacher_cmds[] = { - { CLI_HELP, ccf_help, NULL }, - { CLI_URL_PURGE, ccf_url_purge }, - { CLI_HASH_PURGE, ccf_hash_purge }, -#if 0 - { CLI_URL_QUERY, ccf_url_query }, -#endif - { NULL } -}; - -static struct cli_proto undoc_cmds[] = { - { "debug.sizeof", "debug.sizeof", - "\tDump sizeof various data structures\n", - 0, 0, cli_debug_sizeof }, - { NULL } -}; +static struct cli_proto *ccf_master_cli, *ccf_public_cli, *ccf_debug_cli; +/*-------------------------------------------------------------------- + * Add CLI functions to the appropriate command set + */ -/*--------------------------------------------------------------------*/ - -static void -ccf_help(struct cli *cli, const char * const *av, void *priv) +void +CLI_AddFuncs(enum cli_set_e which, struct cli_proto *p) { + struct cli_proto *c, **cp; - (void)priv; - /* "+1" to skip "help" entry, manager already did that. */ - cli_func_help(cli, av, cacher_cmds + 1); - - if (av[2] != NULL && !strcmp(av[2], "-d")) { - /* Also list undocumented commands */ - cli_out(cli, "\nDebugging commands:\n"); - cli_func_help(cli, av, undoc_cmds); - } else if (cli->result == CLIS_UNKNOWN) { - /* Otherwise, try the undocumented list */ - vsb_clear(cli->sb); - cli->result = CLIS_OK; - cli_func_help(cli, av, undoc_cmds); + switch (which) { + case MASTER_CLI: cp = &ccf_master_cli; break; + case PUBLIC_CLI: cp = &ccf_public_cli; break; + case DEBUG_CLI: cp = &ccf_debug_cli; break; + default: INCOMPL(); } + LOCK(&cli_mtx); + c = cli_concat(*cp, p); + AN(c); + free(*cp); + *cp = c; + UNLOCK(&cli_mtx); } -/*--------------------------------------------------------------------*/ +/*-------------------------------------------------------------------- + * Called when we have a full line, look through all three command + * lists to find it. + */ static int cli_vlu(void *priv, const char *p) @@ -157,17 +103,19 @@ cli_vlu(void *priv, const char *p) cli = priv; VSL(SLT_CLI, 0, "Rd %s", p); vsb_clear(cli->sb); - cli_dispatch(cli, master_cmds, p); + LOCK(&cli_mtx); + cli_dispatch(cli, ccf_master_cli, p); if (cli->result == CLIS_UNKNOWN) { vsb_clear(cli->sb); cli->result = CLIS_OK; - cli_dispatch(cli, cacher_cmds, p); + cli_dispatch(cli, ccf_public_cli, p); } if (cli->result == CLIS_UNKNOWN) { vsb_clear(cli->sb); cli->result = CLIS_OK; - cli_dispatch(cli, undoc_cmds, p); + cli_dispatch(cli, ccf_debug_cli, p); } + UNLOCK(&cli_mtx); vsb_finish(cli->sb); AZ(vsb_overflowed(cli->sb)); i = cli_writeres(heritage.fds[1], cli); @@ -179,8 +127,12 @@ cli_vlu(void *priv, const char *p) return (0); } +/*-------------------------------------------------------------------- + * Run CLI on stdin/stdout pipe from manager + */ + void -CLI_Init(void) +CLI_Run(void) { struct pollfd pfd[1]; struct cli *cli, clis; @@ -190,7 +142,6 @@ CLI_Init(void) cli = &clis; memset(cli, 0, sizeof *cli); - cli_thread = pthread_self(); cli->sb = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND); XXXAN(cli->sb); vlu = VLU_New(cli, cli_vlu, params->cli_buffer); @@ -219,3 +170,80 @@ CLI_Init(void) } } } + +/*--------------------------------------------------------------------*/ + +static void +cli_debug_sizeof(struct cli *cli, const char * const *av, void *priv) +{ + (void)av; + (void)priv; + +#define SZOF(foo) cli_out(cli, \ + "sizeof(%s) = %zd = 0x%zx\n", #foo, sizeof(foo), sizeof(foo)); + SZOF(struct ws); + SZOF(struct http); + SZOF(struct http_conn); + SZOF(struct acct); + SZOF(struct worker); + SZOF(struct workreq); + SZOF(struct bereq); + SZOF(struct storage); + SZOF(struct object); + SZOF(struct objhead); + SZOF(struct sess); + SZOF(struct vbe_conn); +} + +/*--------------------------------------------------------------------*/ + +static void +ccf_help(struct cli *cli, const char * const *av, void *priv) +{ + + (void)priv; + cli_func_help(cli, av, ccf_public_cli); + + if (av[2] != NULL && !strcmp(av[2], "-d")) { + /* Also list undocumented commands */ + cli_out(cli, "\nDebugging commands:\n"); + cli_func_help(cli, av, ccf_debug_cli); + } else if (cli->result == CLIS_UNKNOWN) { + /* Otherwise, try the undocumented list */ + vsb_clear(cli->sb); + cli->result = CLIS_OK; + cli_func_help(cli, av, ccf_debug_cli); + } +} + +/*--------------------------------------------------------------------*/ + +static struct cli_proto master_cmds[] = { + { CLI_PING, cli_func_ping }, + { CLI_HELP, ccf_help, NULL }, + { NULL } +}; + +static struct cli_proto debug_cmds[] = { + { "debug.sizeof", "debug.sizeof", + "\tDump sizeof various data structures\n", + 0, 0, cli_debug_sizeof }, + { NULL } +}; + + +/*-------------------------------------------------------------------- + * Initialize the CLI subsystem + */ + +void +CLI_Init(void) +{ + + MTX_INIT(&cli_mtx); + cli_thread = pthread_self(); + + CLI_AddFuncs(MASTER_CLI, master_cmds); + CLI_AddFuncs(DEBUG_CLI, debug_cmds); +} + diff --git a/varnish-cache/bin/varnishd/cache_main.c b/varnish-cache/bin/varnishd/cache_main.c index 58cee809..e0fa3dd3 100644 --- a/varnish-cache/bin/varnishd/cache_main.c +++ b/varnish-cache/bin/varnishd/cache_main.c @@ -71,6 +71,8 @@ child_main(void) THR_Name("cache-main"); + CLI_Init(); + CNT_Init(); VCL_Init(); @@ -85,11 +87,13 @@ child_main(void) HSH_Init(); BAN_Init(); + VCA_Init(); + STV_open(); VSL_stats->start_time = (time_t)TIM_real(); - CLI_Init(); + CLI_Run(); printf("Child dies\n"); } diff --git a/varnish-cache/bin/varnishd/cache_vcl.c b/varnish-cache/bin/varnishd/cache_vcl.c index 0e2c8437..d224c6dd 100644 --- a/varnish-cache/bin/varnishd/cache_vcl.c +++ b/varnish-cache/bin/varnishd/cache_vcl.c @@ -208,7 +208,7 @@ VCL_Idle(void) /*--------------------------------------------------------------------*/ -void +static void ccf_config_list(struct cli *cli, const char * const *av, void *priv) { struct vcls *vcl; @@ -224,7 +224,7 @@ ccf_config_list(struct cli *cli, const char * const *av, void *priv) } } -void +static void ccf_config_load(struct cli *cli, const char * const *av, void *priv) { @@ -236,7 +236,7 @@ ccf_config_load(struct cli *cli, const char * const *av, void *priv) return; } -void +static void ccf_config_discard(struct cli *cli, const char * const *av, void *priv) { struct vcls *vcl; @@ -263,7 +263,7 @@ ccf_config_discard(struct cli *cli, const char * const *av, void *priv) VCL_Nuke(vcl); } -void +static void ccf_config_use(struct cli *cli, const char * const *av, void *priv) { struct vcls *vcl; @@ -321,9 +321,18 @@ VCL_##func##_method(struct sess *sp) \ /*--------------------------------------------------------------------*/ +static struct cli_proto vcl_cmds[] = { + { CLI_VCL_LOAD, ccf_config_load }, + { CLI_VCL_LIST, ccf_config_list }, + { CLI_VCL_DISCARD, ccf_config_discard }, + { CLI_VCL_USE, ccf_config_use }, + { NULL } +}; + void VCL_Init() { + CLI_AddFuncs(MASTER_CLI, vcl_cmds); MTX_INIT(&vcl_mtx); } diff --git a/varnish-cache/bin/varnishd/mgt.h b/varnish-cache/bin/varnishd/mgt.h index caddc537..7922f152 100644 --- a/varnish-cache/bin/varnishd/mgt.h +++ b/varnish-cache/bin/varnishd/mgt.h @@ -44,7 +44,6 @@ extern pid_t mgt_pid, child_pid; /* mgt_cli.c */ -void mgt_cli_init(void); void mgt_cli_setup(int fdi, int fdo, int verbose, const char *ident); int mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...); void mgt_cli_start_child(int fdi, int fdo);