summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/monitor/monitor.c12
-rw-r--r--src/monitor/monitor_interfaces.h1
-rw-r--r--src/responder/nss/nsssrv.c77
-rw-r--r--src/responder/nss/nsssrv_mmap_cache.c46
-rw-r--r--src/responder/nss/nsssrv_mmap_cache.h5
-rw-r--r--src/tools/sss_cache.c26
-rw-r--r--src/util/util.h2
7 files changed, 166 insertions, 3 deletions
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 50b2e9523..a94227878 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -51,6 +51,7 @@
#include "dbus/dbus.h"
#include "sbus/sssd_dbus.h"
#include "monitor/monitor_interfaces.h"
+#include "responder/nss/nsssrv.h"
#ifdef USE_KEYRING
#include <keyutils.h>
@@ -701,6 +702,10 @@ static int service_signal_rotate(struct mt_svc *svc)
{
return service_signal(svc, MON_CLI_METHOD_ROTATE);
}
+static int service_signal_clear_memcache(struct mt_svc *svc)
+{
+ return service_signal(svc, MON_CLI_METHOD_CLEAR_MEMCACHE);
+}
static int check_domain_ranges(struct sss_domain_info *domains)
{
@@ -1177,10 +1182,15 @@ static void monitor_hup(struct tevent_context *ev,
DEBUG(1, ("Received SIGHUP.\n"));
- /* Signal all services to rotate debug files */
+ /* Send D-Bus message to other services to rotate their logs.
+ * NSS service receives also message to clear memory caches. */
for(cur_svc = ctx->svc_list; cur_svc; cur_svc = cur_svc->next) {
service_signal_rotate(cur_svc);
+ if (!strcmp(NSS_SBUS_SERVICE_NAME, cur_svc->name)) {
+ service_signal_clear_memcache(cur_svc);
+ }
}
+
}
static int monitor_cleanup(void)
diff --git a/src/monitor/monitor_interfaces.h b/src/monitor/monitor_interfaces.h
index 51ac254cd..abe905035 100644
--- a/src/monitor/monitor_interfaces.h
+++ b/src/monitor/monitor_interfaces.h
@@ -45,6 +45,7 @@
#define MON_CLI_METHOD_OFFLINE "goOffline" /* Applicable only to providers */
#define MON_CLI_METHOD_RESET_OFFLINE "resetOffline" /* Applicable only to providers */
#define MON_CLI_METHOD_ROTATE "rotateLogs"
+#define MON_CLI_METHOD_CLEAR_MEMCACHE "clearMemcache"
#define SSSD_SERVICE_PIPE "private/sbus-monitor"
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 64267e868..5fa72494e 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -51,10 +51,14 @@
#define SHELL_REALLOC_INCREMENT 5
#define SHELL_REALLOC_MAX 50
+static int nss_clear_memcache(DBusMessage *message,
+ struct sbus_connection *conn);
+
struct sbus_method monitor_nss_methods[] = {
{ MON_CLI_METHOD_PING, monitor_common_pong },
{ MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
{ MON_CLI_METHOD_ROTATE, responder_logrotate },
+ { MON_CLI_METHOD_CLEAR_MEMCACHE, nss_clear_memcache},
{ NULL, NULL }
};
@@ -66,6 +70,65 @@ struct sbus_interface monitor_nss_interface = {
NULL
};
+static int nss_clear_memcache(DBusMessage *message,
+ struct sbus_connection *conn)
+{
+ errno_t ret;
+ int memcache_timeout;
+ struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(conn),
+ struct resp_ctx);
+ struct nss_ctx *nctx = (struct nss_ctx*) rctx->pvt_ctx;
+
+ ret = unlink(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG);
+ if (ret != 0) {
+ ret = errno;
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_FUNC,
+ ("CLEAR_MC_FLAG not found. Nothing to do.\n"));
+ goto done;
+ } else {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to unlink file: %s.\n",
+ strerror(ret)));
+ return ret;
+ }
+ }
+
+ /* CLEAR_MC_FLAG removed successfully. Clearing memory caches. */
+
+ ret = confdb_get_int(rctx->cdb,
+ CONFDB_NSS_CONF_ENTRY,
+ CONFDB_MEMCACHE_TIMEOUT,
+ 300, &memcache_timeout);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Unable to get memory cache entry timeout.\n"));
+ return ret;
+ }
+
+ /* TODO: read cache sizes from configuration */
+ DEBUG(SSSDBG_TRACE_FUNC, ("Clearing memory caches.\n"));
+ ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS,
+ (time_t) memcache_timeout,
+ &nctx->pwd_mc_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("passwd mmap cache invalidation failed\n"));
+ return ret;
+ }
+
+ ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS,
+ (time_t) memcache_timeout,
+ &nctx->grp_mc_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("group mmap cache invalidation failed\n"));
+ return ret;
+ }
+
+done:
+ return monitor_common_pong(message, conn);
+}
+
static errno_t nss_get_etc_shells(TALLOC_CTX *mem_ctx, char ***_shells)
{
int i = 0;
@@ -328,6 +391,16 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
}
/* create mmap caches */
+ /* Remove the CLEAR_MC_FLAG file if exists. */
+ ret = unlink(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG);
+ if (ret != 0 && errno != ENOENT) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to unlink file [%s]. This can cause memory cache to "
+ "be purged when next log rotation is requested. %d: %s\n",
+ SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG, ret, strerror(ret)));
+ }
+
ret = confdb_get_int(nctx->rctx->cdb,
CONFDB_NSS_CONF_ENTRY,
CONFDB_MEMCACHE_TIMEOUT,
@@ -339,14 +412,14 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
/* TODO: read cache sizes from configuration */
ret = sss_mmap_cache_init(nctx, "passwd", SSS_MC_PASSWD,
- 50000, (time_t)memcache_timeout,
+ SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
&nctx->pwd_mc_ctx);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE, ("passwd mmap cache is DISABLED\n"));
}
ret = sss_mmap_cache_init(nctx, "group", SSS_MC_GROUP,
- 50000, (time_t)memcache_timeout,
+ SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
&nctx->grp_mc_ctx);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE, ("group mmap cache is DISABLED\n"));
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 07498a9b7..f40256472 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -725,3 +725,49 @@ done:
return ret;
}
+errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
+ time_t timeout, struct sss_mc_ctx **mc_ctx)
+{
+ errno_t ret;
+ TALLOC_CTX* tmp_ctx = NULL;
+ char *name;
+ enum sss_mc_type type;
+
+ if (mc_ctx == NULL || (*mc_ctx) == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Unable to re-init unitialized memory cache.\n"));
+ return EINVAL;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory.\n"));
+ return ENOMEM;
+ }
+
+ name = talloc_strdup(tmp_ctx, (*mc_ctx)->name);
+ if (name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ type = (*mc_ctx)->type;
+ ret = talloc_free(*mc_ctx);
+ if (ret != 0) {
+ /* This can happen only if destructor is associated with this
+ * context */
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Destructor asociated with memory"
+ " context failed.\n"));
+ }
+
+ ret = sss_mmap_cache_init(mem_ctx, name, type, n_elem, timeout, mc_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to re-initialize mmap cache.\n"));
+ goto done;
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/src/responder/nss/nsssrv_mmap_cache.h b/src/responder/nss/nsssrv_mmap_cache.h
index 81241b24d..2a0712c88 100644
--- a/src/responder/nss/nsssrv_mmap_cache.h
+++ b/src/responder/nss/nsssrv_mmap_cache.h
@@ -22,6 +22,8 @@
#ifndef _NSSSRV_MMAP_CACHE_H_
#define _NSSSRV_MMAP_CACHE_H_
+#define SSS_MC_CACHE_ELEMENTS 50000
+
struct sss_mc_ctx;
enum sss_mc_type {
@@ -48,4 +50,7 @@ errno_t sss_mmap_cache_gr_store(struct sss_mc_ctx *mcc,
gid_t gid, size_t memnum,
char *membuf, size_t memsize);
+errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
+ time_t timeout, struct sss_mc_ctx **mc_ctx);
+
#endif /* _NSSSRV_MMAP_CACHE_H_ */
diff --git a/src/tools/sss_cache.c b/src/tools/sss_cache.c
index 950ff1c16..73d99651b 100644
--- a/src/tools/sss_cache.c
+++ b/src/tools/sss_cache.c
@@ -100,6 +100,7 @@ int main(int argc, const char *argv[])
struct sysdb_ctx *sysdb;
int i;
bool skipped;
+ FILE *clear_mc_flag;
ret = init_context(argc, argv, &tctx);
if (ret != EOK) {
@@ -141,6 +142,31 @@ int main(int argc, const char *argv[])
ERROR("No cache object matched the specified search\n");
ret = ENOENT;
goto done;
+ } else {
+ /*Local cache changed -> signal monitor to invalidate fastcache */
+ clear_mc_flag = fopen(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG, "w");
+ if (clear_mc_flag == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to create clear_mc_flag file. "
+ "Memory cache will not be cleared.\n"));
+ goto done;
+ }
+ ret = fclose(clear_mc_flag);
+ if (ret != 0) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Unable to close file descriptor: %s\n",
+ strerror(ret)));
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, ("Sending SIGHUP to monitor.\n"));
+ ret = signal_sssd(SIGHUP);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to send SIGHUP to monitor.\n"));
+ goto done;
+ }
}
}
diff --git a/src/util/util.h b/src/util/util.h
index 685702fc9..df739ab6c 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -54,6 +54,8 @@ typedef int errno_t;
#define ENUM_INDICATOR "*"
+#define CLEAR_MC_FLAG "clear_mc_flag"
+
extern const char *debug_prg_name;
extern int debug_level;
extern int debug_timestamps;