static void mcache_sess_reinit_ev(const void *event_data, void *user_data) { int res; config_rec *c; /* A HOST command changed the main_server pointer, reinitialize ourselves. */ pr_event_unregister(&memcache_module, "core.exit", mcache_exit_ev); pr_event_unregister(&memcache_module, "core.session-reinit", mcache_sess_reinit_ev); (void) close(memcache_logfd); memcache_logfd = -1; c = find_config(session.prev_server->conf, CONF_PARAM, "MemcacheServers", FALSE); if (c != NULL) { memcached_server_st *memcache_servers; memcache_servers = c->argv[0]; memcache_set_servers(memcache_servers); } /* XXX Restore other memcache settings? */ /* reset MemcacheOptions */ /* reset MemcacheReplicas */ /* reset MemcacheTimeout */ res = mcache_sess_init(); if (res < 0) { pr_session_disconnect(&memcache_module, PR_SESS_DISCONNECT_SESSION_INIT_FAILED, NULL); } }
MODRET memcache_post_host(cmd_rec *cmd) { /* If the HOST command changed the main_server pointer, reinitialize * ourselves. */ if (session.prev_server != NULL) { int res; config_rec *c; pr_event_unregister(&memcache_module, "core.exit", mcache_exit_ev); (void) close(memcache_logfd); c = find_config(session.prev_server->conf, CONF_PARAM, "MemcacheServers", FALSE); if (c != NULL) { memcached_server_st *memcache_servers; memcache_servers = c->argv[0]; memcache_set_servers(memcache_servers); } /* XXX Restore other memcache settings? */ res = mcache_sess_init(); if (res < 0) { pr_session_disconnect(&memcache_module, PR_SESS_DISCONNECT_SESSION_INIT_FAILED, NULL); } } return PR_DECLINED(cmd); }
/* usage: MemcacheServers host1[:port1] ... */ MODRET set_memcacheservers(cmd_rec *cmd) { register unsigned int i; config_rec *c; char *str = ""; int ctxt; memcached_server_st *memcache_servers = NULL; if (cmd->argc-1 < 1) { CONF_ERROR(cmd, "wrong number of parameters"); } CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL); c = add_config_param(cmd->argv[0], 1, NULL); for (i = 1; i < cmd->argc; i++) { str = pstrcat(cmd->pool, str, *str ? ", " : "", cmd->argv[i], NULL); } memcache_servers = memcached_servers_parse(str); if (memcache_servers == NULL) { CONF_ERROR(cmd, "unable to parse server parameters"); } ctxt = (cmd->config && cmd->config->config_type != CONF_PARAM ? cmd->config->config_type : cmd->server->config_type ? cmd->server->config_type : CONF_ROOT); if (ctxt == CONF_ROOT) { /* If we're the "server config" context, set the server list now. This * would let mod_memcache talk to those servers for e.g. ftpdctl actions. */ memcache_set_servers(memcache_servers); } c->argv[0] = memcache_servers; /* Add the libmemcached-allocated pointer to a list, for later freeing. */ *((memcached_server_st **) push_array(memcache_server_lists)) = memcache_servers; return PR_HANDLED(cmd); }
static void mcache_restart_ev(const void *event_data, void *user_data) { register unsigned int i; memcached_server_st **mcache_servers = NULL; mcache_servers = memcache_server_lists->elts; for (i = 0; i < memcache_server_lists->nelts; i++) { memcached_server_list_free(mcache_servers[i]); } /* Make sure to clear the pointer in the Memcache API as well, to prevent * a dangling pointer situation. */ memcache_set_servers(NULL); /* Now we can recycle the mod_memcache pool and its associated resources. */ destroy_pool(memcache_pool); memcache_pool = make_sub_pool(permanent_pool); pr_pool_tag(memcache_pool, MOD_MEMCACHE_VERSION); memcache_server_lists = make_array(memcache_pool, 2, sizeof(memcached_server_st **)); }
static int mcache_sess_init(void) { config_rec *c; pr_event_register(&memcache_module, "core.session-reinit", mcache_sess_reinit_ev, NULL); c = find_config(main_server->conf, CONF_PARAM, "MemcacheEngine", FALSE); if (c) { int engine; engine = *((int *) c->argv[0]); if (engine == FALSE) { /* Explicitly disable memcache support for this session */ memcache_set_servers(NULL); return 0; } } pr_event_register(&memcache_module, "core.exit", mcache_exit_ev, NULL); c = find_config(main_server->conf, CONF_PARAM, "MemcacheLog", FALSE); if (c) { const char *path; path = c->argv[0]; if (strcasecmp(path, "none") != 0) { int res, xerrno; pr_signals_block(); PRIVS_ROOT res = pr_log_openfile(path, &memcache_logfd, PR_LOG_SYSTEM_MODE); xerrno = errno; PRIVS_RELINQUISH pr_signals_unblock(); switch (res) { case 0: break; case -1: pr_log_pri(PR_LOG_NOTICE, MOD_MEMCACHE_VERSION ": notice: unable to open MemcacheLog '%s': %s", path, strerror(xerrno)); break; case PR_LOG_WRITABLE_DIR: pr_log_pri(PR_LOG_WARNING, MOD_MEMCACHE_VERSION ": notice: unable to use MemcacheLog '%s': parent directory is " "world-writable", path); break; case PR_LOG_SYMLINK: pr_log_pri(PR_LOG_WARNING, MOD_MEMCACHE_VERSION ": notice: unable to use MemcacheLog '%s': cannot log to a symlink", path); break; } } } c = find_config(main_server->conf, CONF_PARAM, "MemcacheServers", FALSE); if (c) { memcached_server_st *memcache_servers; memcache_servers = c->argv[0]; memcache_set_servers(memcache_servers); } c = find_config(main_server->conf, CONF_PARAM, "MemcacheOptions", FALSE); if (c) { unsigned long flags; flags = *((unsigned long *) c->argv[0]); if (memcache_set_sess_flags(flags) < 0) { (void) pr_log_writefile(memcache_logfd, MOD_MEMCACHE_VERSION, "error setting memcache flags: %s", strerror(errno)); } } c = find_config(main_server->conf, CONF_PARAM, "MemcacheReplicas", FALSE); if (c) { uint64_t count; count = *((uint64_t *) c->argv[0]); if (memcache_set_sess_replicas(count) < 0) { (void) pr_log_writefile(memcache_logfd, MOD_MEMCACHE_VERSION, "error setting memcache replicas: %s", strerror(errno)); } } c = find_config(main_server->conf, CONF_PARAM, "MemcacheTimeouts", FALSE); if (c) { unsigned long conn_millis, read_millis, write_millis, retry_sec; conn_millis = *((unsigned long *) c->argv[0]); read_millis = *((unsigned long *) c->argv[1]); write_millis = *((unsigned long *) c->argv[2]); retry_sec = *((unsigned long *) c->argv[3]); if (memcache_set_timeouts(conn_millis, read_millis, write_millis, retry_sec) < 0) { (void) pr_log_writefile(memcache_logfd, MOD_MEMCACHE_VERSION, "error setting memcache timeouts: %s", strerror(errno)); } } return 0; }