nsssrv_mmap_cache.c revision a3c8390d19593b1e5277d95bfb4ab206d4785150
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/*
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen SSSD
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen NSS Responder - Mmap Cache
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen Copyright (C) Simo Sorce <ssorce@redhat.com> 2011
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
e8434aad92ea6ff1c915b708294dbd0c7ff5908dMichael M Slusarz This program is free software; you can redistribute it and/or modify
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen it under the terms of the GNU General Public License as published by
de5f478d9e7ae7b8e58082e0b30b6ce1f034236aTimo Sirainen the Free Software Foundation; either version 3 of the License, or
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen (at your option) any later version.
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen This program is distributed in the hope that it will be useful,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen GNU General Public License for more details.
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen You should have received a copy of the GNU General Public License
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen*/
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "util/util.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "confdb/confdb.h"
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen#include <sys/mman.h>
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen#include <fcntl.h>
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen#include "util/mmap_cache.h"
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen#include "responder/nss/nsssrv.h"
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen#include "responder/nss/nsssrv_mmap_cache.h"
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen/* arbitrary (avg of my /etc/passwd) */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#define SSS_AVG_PASSWD_PAYLOAD (MC_SLOT_SIZE * 4)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen/* short group name and no gids (private user group */
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen#define SSS_AVG_GROUP_PAYLOAD (MC_SLOT_SIZE * 3)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen#define MC_NEXT_BARRIER(val) ((((val) + 1) & 0x00ffffff) | 0xf0000000)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen#define MC_RAISE_BARRIER(m) do { \
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen m->b2 = MC_NEXT_BARRIER(m->b1); \
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen __sync_synchronize(); \
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen} while (0)
01aca4a521410be85e1f39e37c662435d052f48aAki Tuomi
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen#define MC_LOWER_BARRIER(m) do { \
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen __sync_synchronize(); \
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen m->b1 = m->b2; \
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen} while (0)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen#define MC_RAISE_INVALID_BARRIER(m) do { \
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen m->b2 = MC_INVALID_VAL; \
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen __sync_synchronize(); \
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen} while (0)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainenstruct sss_mc_ctx {
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen char *name; /* mmap cache name */
01aca4a521410be85e1f39e37c662435d052f48aAki Tuomi enum sss_mc_type type; /* mmap cache type */
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen char *file; /* mmap cache file name */
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen int fd; /* file descriptor */
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen uint32_t seed; /* pseudo-random seed to avoid collision attacks */
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen time_t valid_time_slot; /* maximum time the entry is valid in seconds */
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen
8a6afcd8a6d9ed69626add85a7b75105ee3cb6a1Timo Sirainen void *mmap_base; /* base address of mmap */
8a6afcd8a6d9ed69626add85a7b75105ee3cb6a1Timo Sirainen size_t mmap_size; /* total size of mmap */
8a6afcd8a6d9ed69626add85a7b75105ee3cb6a1Timo Sirainen
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen uint32_t *hash_table; /* hash table address (in mmap) */
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen uint32_t ht_size; /* size of hash table */
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
8a6afcd8a6d9ed69626add85a7b75105ee3cb6a1Timo Sirainen uint8_t *free_table; /* free list bitmaps */
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen uint32_t ft_size; /* size of free table */
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen uint32_t next_slot; /* the next slot after last allocation */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint8_t *data_table; /* data table address (in mmap) */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t dt_size; /* size of data table */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen};
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#define MC_FIND_BIT(base, num) \
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t n = (num); \
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint8_t *b = (base) + n / 8; \
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint8_t c = 0x80 >> (n % 8);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#define MC_SET_BIT(base, num) do { \
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen MC_FIND_BIT(base, num) \
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen *b |= c; \
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen} while (0)
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
14189e0d0af45ddcb888d026bd8d7e4609912ec5Timo Sirainen#define MC_CLEAR_BIT(base, num) do { \
e564ff0581fc44b78badf8da36e68f9f7a27807eTimo Sirainen MC_FIND_BIT(base, num) \
f9eee365367f37b1692c07db6c23d30243844aaaTimo Sirainen *b &= ~c; \
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen} while (0)
7cd055a212d44067e2d94452c05691d696c9f699Timo Sirainen
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen#define MC_PROBE_BIT(base, num, used) do { \
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen MC_FIND_BIT(base, num) \
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi if (*b & c) used = true; \
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen else used = false; \
e8434aad92ea6ff1c915b708294dbd0c7ff5908dMichael M Slusarz} while (0)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic inline
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenuint32_t sss_mc_next_slot_with_hash(struct sss_mc_rec *rec,
f0e416aa42058e7ccc0dc6deec0d4f4a19ee6ebeTimo Sirainen uint32_t hash)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (rec->hash1 == hash) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return rec->next1;
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen } else if (rec->hash2 == hash) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return rec->next2;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen } else {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* it should never happen. */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return MC_INVALID_VAL;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen }
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen}
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainenstatic inline
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainenvoid sss_mc_chain_slot_to_record_with_hash(struct sss_mc_rec *rec,
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen uint32_t hash,
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen uint32_t slot)
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen{
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen /* changing a single uint32_t is atomic, so there is no
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * need to use barriers in this case */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (rec->hash1 == hash) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rec->next1 = slot;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else if (rec->hash2 == hash) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rec->next2 = slot;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen/* This function will store corrupted memcache to disk for later
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * analysis. */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void sss_mc_save_corrupted(struct sss_mc_ctx *mc_ctx)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int err;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen int fd = -1;
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen ssize_t written = -1;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen char *file = NULL;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen TALLOC_CTX *tmp_ctx;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (mc_ctx == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(SSSDBG_TRACE_FUNC,
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen "Cannot store uninitialized cache. Nothing to do.\n");
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tmp_ctx = talloc_new(NULL);
b6c9cc2bf7517adcc0b9f98696c61bde321900f6Timo Sirainen if (tmp_ctx == NULL) {
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n");
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen return;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen file = talloc_asprintf(tmp_ctx, "%s_%s",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->file, "corrupted");
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (file == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n");
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* We will always store only the last problematic cache state */
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen fd = creat(file, 0600);
92a7f5f9bf20c0bd1b1ac309d100f9c144e2b127Timo Sirainen if (fd == -1) {
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen err = errno;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen "Failed to open file '%s' [%d]: %s\n",
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen file, err, strerror(err));
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen written = sss_atomic_write_s(fd, mc_ctx->mmap_base, mc_ctx->mmap_size);
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen if (written != mc_ctx->mmap_size) {
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen if (written == -1) {
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen err = errno;
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen "write() failed [%d]: %s\n", err, strerror(err));
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen } else {
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen "write() returned %zd (expected (%zd))\n",
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen written, mc_ctx->mmap_size);
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen }
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen goto done;
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen }
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen sss_log(SSS_LOG_NOTICE,
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen "Stored copy of corrupted mmap cache in file '%s\n'", file);
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainendone:
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen if (fd != -1) {
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen close(fd);
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen if (written == -1) {
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen err = unlink(file);
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen if (err != 0) {
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen err = errno;
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen "Failed to remove file '%s': %s.\n", file,
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen strerror(err));
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen }
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen }
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen }
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen talloc_free(tmp_ctx);
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen}
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainenstatic uint32_t sss_mc_hash(struct sss_mc_ctx *mcc,
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen const char *key, size_t len)
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen{
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen return murmurhash3(key, len, mcc->seed) % MC_HT_ELEMS(mcc->ht_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void sss_mc_add_rec_to_chain(struct sss_mc_ctx *mcc,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_mc_rec *rec,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t hash)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_mc_rec *cur;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t slot;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (hash > MC_HT_ELEMS(mcc->ht_size)) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* Invalid hash. This should never happen, but better
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * return than trying to access out of bounds memory */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen slot = mcc->hash_table[hash];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (slot == MC_INVALID_VAL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* no previous record/collision, just add to hash table */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mcc->hash_table[hash] = MC_PTR_TO_SLOT(mcc->data_table, rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen do {
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen if (cur == rec) {
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen /* rec already stored in hash chain */
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen return;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen slot = sss_mc_next_slot_with_hash(cur, hash);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen } while (slot != MC_INVALID_VAL);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen /* end of chain, append our record here */
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen slot = MC_PTR_TO_SLOT(mcc->data_table, rec);
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen sss_mc_chain_slot_to_record_with_hash(cur, hash, slot);
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen}
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainenstatic void sss_mc_rm_rec_from_chain(struct sss_mc_ctx *mcc,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_mc_rec *rec,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t hash)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_mc_rec *prev = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_mc_rec *cur = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t slot;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (hash > MC_HT_ELEMS(mcc->ht_size)) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* It can happen if rec->hash1 and rec->hash2 was the same.
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * or it is invalid hash. It is better to return
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * than trying to access out of bounds memory
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen slot = mcc->hash_table[hash];
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen if (slot == MC_INVALID_VAL) {
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen /* record has already been removed. It may happen if rec->hash1 and
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen * rec->has2 are the same. (It is not very likely).
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen */
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen return;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen if (cur == rec) {
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen mcc->hash_table[hash] = sss_mc_next_slot_with_hash(rec, hash);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen } else {
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen slot = sss_mc_next_slot_with_hash(cur, hash);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen while (slot != MC_INVALID_VAL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen prev = cur;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (cur == rec) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen slot = sss_mc_next_slot_with_hash(cur, hash);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mc_chain_slot_to_record_with_hash(prev, hash, slot);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen slot = MC_INVALID_VAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen slot = sss_mc_next_slot_with_hash(cur, hash);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainenstatic void sss_mc_free_slots(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec)
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen{
5f1d689131a75c39f064cbd4202373e7edf78f18Josef 'Jeff' Sipek uint32_t slot;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t num;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t i;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen slot = MC_PTR_TO_SLOT(mcc->data_table, rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen num = MC_SIZE_TO_SLOTS(rec->len);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen for (i = 0; i < num; i++) {
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen MC_CLEAR_BIT(mcc->free_table, slot + i);
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen }
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen}
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainenstatic void sss_mc_invalidate_rec(struct sss_mc_ctx *mcc,
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen struct sss_mc_rec *rec)
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen{
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen if (rec->b1 == MC_INVALID_VAL) {
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen /* record already invalid */
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen return;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen }
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen /* Remove from hash chains */
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen /* hash chain 1 */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mc_rm_rec_from_chain(mcc, rec, rec->hash1);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* hash chain 2 */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mc_rm_rec_from_chain(mcc, rec, rec->hash2);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* Clear from free_table */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mc_free_slots(mcc, rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* Invalidate record fields */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_RAISE_INVALID_BARRIER(rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(rec->data, MC_INVALID_VAL8, ((MC_SLOT_SIZE * MC_SIZE_TO_SLOTS(rec->len))
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen - sizeof(struct sss_mc_rec)));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rec->len = MC_INVALID_VAL32;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rec->expire = MC_INVALID_VAL64;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rec->next1 = MC_INVALID_VAL32;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rec->next2 = MC_INVALID_VAL32;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rec->hash1 = MC_INVALID_VAL32;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rec->hash2 = MC_INVALID_VAL32;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_LOWER_BARRIER(rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic bool sss_mc_is_valid_rec(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec)
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen{
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen struct sss_mc_rec *self;
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen uint32_t slot;
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen if (((uint8_t *)rec < mcc->data_table) ||
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen ((uint8_t *)rec > (mcc->data_table + mcc->dt_size - MC_SLOT_SIZE))) {
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen return false;
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen }
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen if ((rec->b1 == MC_INVALID_VAL) ||
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen (rec->b1 != rec->b2)) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return false;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!MC_CHECK_RECORD_LENGTH(mcc, rec)) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return false;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (rec->expire == MC_INVALID_VAL64) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return false;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* next record can be invalid if there are no next records */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (rec->hash1 == MC_INVALID_VAL32) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return false;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen self = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen slot = mcc->hash_table[rec->hash1];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen while (slot != MC_INVALID_VAL32 && self != rec) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen self = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen slot = sss_mc_next_slot_with_hash(self, rec->hash1);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (self != rec) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return false;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (rec->hash2 != MC_INVALID_VAL32) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen self = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen slot = mcc->hash_table[rec->hash2];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen while (slot != MC_INVALID_VAL32 && self != rec) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen self = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen slot = sss_mc_next_slot_with_hash(self, rec->hash2);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (self != rec) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return false;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* all tests passed */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return true;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen/* FIXME: This is a very simplistic, inefficient, memory allocator,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * it will just free the oldest entries regardless of expiration if it
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * cycled the whole freebits map and found no empty slot */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic errno_t sss_mc_find_free_slots(struct sss_mc_ctx *mcc,
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen int num_slots, uint32_t *free_slot)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_mc_rec *rec;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t tot_slots;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t cur;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t i;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t t;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen bool used;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tot_slots = mcc->ft_size * 8;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* Try to find a free slot w/o removing anything first */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* FIXME: is it really worth it ? May be it is easier to
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * just recycle the next set of slots ? */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if ((mcc->next_slot + num_slots) > tot_slots) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen cur = 0;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen cur = mcc->next_slot;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* search for enough (num_slots) consecutive zero bits, indicating
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * consecutive empty slots */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen for (i = 0; i < mcc->ft_size; i++) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen t = cur / 8;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* if all full in this byte skip directly to the next */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (mcc->free_table[t] == 0xff) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen cur = ((cur + 8) & ~7);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (cur >= tot_slots) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen cur = 0;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen continue;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* at least one bit in this byte is marked as empty */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen for (t = ((cur + 8) & ~7) ; cur < t; cur++) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_PROBE_BIT(mcc->free_table, cur, used);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!used) break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen /* check if we have enough slots before hitting the table end */
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen if ((cur + num_slots) > tot_slots) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen cur = 0;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen continue;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* check if we have at least num_slots empty starting from the first
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * we found in the previous steps */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen for (t = cur + num_slots; cur < t; cur++) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_PROBE_BIT(mcc->free_table, cur, used);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (used) break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (cur == t) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* ok found num_slots consecutive free bits */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *free_slot = cur - num_slots;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* no free slots found, free occupied slots after next_slot */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if ((mcc->next_slot + num_slots) > tot_slots) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen cur = 0;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen cur = mcc->next_slot;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen for (i = 0; i < num_slots; i++) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_PROBE_BIT(mcc->free_table, cur + i, used);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (used) {
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen /* the first used slot should be a record header, however we
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * carefully check it is a valid header and hardfail if not */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rec = MC_SLOT_TO_PTR(mcc->data_table, cur + i, struct sss_mc_rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!sss_mc_is_valid_rec(mcc, rec)) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* this is a fatal error, the caller should probaly just
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * invalidate the whole cache */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EFAULT;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* next loop skip the whole record */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen i += MC_SIZE_TO_SLOTS(rec->len) - 1;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* finally invalidate record completely */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mc_invalidate_rec(mcc, rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mcc->next_slot = cur + num_slots;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *free_slot = cur;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic errno_t sss_mc_get_strs_offset(struct sss_mc_ctx *mcc,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen size_t *_offset)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen switch (mcc->type) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_MC_PASSWD:
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen *_offset = offsetof(struct sss_mc_pwd_data, strs);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen case SSS_MC_GROUP:
6ea145a99eeee923602f04d3c9183bbdba6cd190Timo Sirainen *_offset = offsetof(struct sss_mc_grp_data, strs);
6ea145a99eeee923602f04d3c9183bbdba6cd190Timo Sirainen return EOK;
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen default:
7cd055a212d44067e2d94452c05691d696c9f699Timo Sirainen DEBUG(SSSDBG_FATAL_FAILURE, "Unknown memory cache type.\n");
7cd055a212d44067e2d94452c05691d696c9f699Timo Sirainen return EINVAL;
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic errno_t sss_mc_get_strs_len(struct sss_mc_ctx *mcc,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_mc_rec *rec,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen size_t *_len)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen switch (mcc->type) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_MC_PASSWD:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *_len = ((struct sss_mc_pwd_data *)&rec->data)->strs_len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_MC_GROUP:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *_len = ((struct sss_mc_grp_data *)&rec->data)->strs_len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen default:
e8434aad92ea6ff1c915b708294dbd0c7ff5908dMichael M Slusarz DEBUG(SSSDBG_FATAL_FAILURE, "Unknown memory cache type.\n");
e8434aad92ea6ff1c915b708294dbd0c7ff5908dMichael M Slusarz return EINVAL;
e8434aad92ea6ff1c915b708294dbd0c7ff5908dMichael M Slusarz }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic struct sss_mc_rec *sss_mc_find_record(struct sss_mc_ctx *mcc,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sized_string *key)
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen{
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen struct sss_mc_rec *rec;
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen uint32_t hash;
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen uint32_t slot;
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen rel_ptr_t name_ptr;
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen char *t_key;
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen size_t strs_offset;
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen size_t strs_len;
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen uint8_t *max_addr;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen errno_t ret;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen hash = sss_mc_hash(mcc, key->str, key->len);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen slot = mcc->hash_table[hash];
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) {
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen return NULL;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen }
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen /* Get max address of data table. */
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen max_addr = mcc->data_table + mcc->dt_size;
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen ret = sss_mc_get_strs_offset(mcc, &strs_offset);
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen if (ret != EOK) {
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen return NULL;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen }
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen while (slot != MC_INVALID_VAL) {
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) {
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen DEBUG(SSSDBG_FATAL_FAILURE,
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen "Corrupted fastcache. Slot number too big.\n");
14189e0d0af45ddcb888d026bd8d7e4609912ec5Timo Sirainen sss_mc_save_corrupted(mcc);
14189e0d0af45ddcb888d026bd8d7e4609912ec5Timo Sirainen sss_mmap_cache_reset(mcc);
e564ff0581fc44b78badf8da36e68f9f7a27807eTimo Sirainen return NULL;
e564ff0581fc44b78badf8da36e68f9f7a27807eTimo Sirainen }
f9eee365367f37b1692c07db6c23d30243844aaaTimo Sirainen
f9eee365367f37b1692c07db6c23d30243844aaaTimo Sirainen rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
f9eee365367f37b1692c07db6c23d30243844aaaTimo Sirainen ret = sss_mc_get_strs_len(mcc, rec, &strs_len);
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen if (ret != EOK) {
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen return NULL;
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen }
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen safealign_memcpy(&name_ptr, rec->data, sizeof(rel_ptr_t), NULL);
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen if (key->len > strs_len
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen || (name_ptr + key->len) > (strs_offset + strs_len)
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen || (uint8_t *)rec->data + strs_offset + strs_len > max_addr) {
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen DEBUG(SSSDBG_FATAL_FAILURE,
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen "Corrupted fastcache. name_ptr value is %u.\n", name_ptr);
7cd055a212d44067e2d94452c05691d696c9f699Timo Sirainen sss_mc_save_corrupted(mcc);
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen sss_mmap_cache_reset(mcc);
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen return NULL;
7cd055a212d44067e2d94452c05691d696c9f699Timo Sirainen }
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen t_key = (char *)rec->data + name_ptr;
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen if (strcmp(key->str, t_key) == 0) {
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen break;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen }
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen slot = sss_mc_next_slot_with_hash(rec, hash);
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi }
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi if (slot == MC_INVALID_VAL) {
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi return NULL;
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi }
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi return rec;
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi}
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomistatic errno_t sss_mc_get_record(struct sss_mc_ctx **_mcc,
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi size_t rec_len,
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi struct sized_string *key,
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen struct sss_mc_rec **_rec)
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen{
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen struct sss_mc_ctx *mcc = *_mcc;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_mc_rec *old_rec = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_mc_rec *rec;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int old_slots;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int num_slots;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t base_slot;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen errno_t ret;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen int i;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen num_slots = MC_SIZE_TO_SLOTS(rec_len);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen old_rec = sss_mc_find_record(mcc, key);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen if (old_rec) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen old_slots = MC_SIZE_TO_SLOTS(old_rec->len);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (old_slots == num_slots) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *_rec = old_rec;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen /* slot size changed, invalidate record and fall through to get a
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen * fully new record */
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen sss_mc_invalidate_rec(mcc, old_rec);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen }
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen /* we are going to use more space, find enough free slots */
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen ret = sss_mc_find_free_slots(mcc, num_slots, &base_slot);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen if (ret != EOK) {
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen if (ret == EFAULT) {
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen "Fatal internal mmap cache error, invalidating cache!\n");
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen (void)sss_mmap_cache_reinit(talloc_parent(mcc), -1, -1, _mcc);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen }
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen return ret;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen }
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen rec = MC_SLOT_TO_PTR(mcc->data_table, base_slot, struct sss_mc_rec);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen /* mark as not valid yet */
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen MC_RAISE_INVALID_BARRIER(rec);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen rec->len = rec_len;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen rec->next1 = MC_INVALID_VAL;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen rec->next2 = MC_INVALID_VAL;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen rec->padding = MC_INVALID_VAL;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen MC_LOWER_BARRIER(rec);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen /* and now mark slots as used */
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen for (i = 0; i < num_slots; i++) {
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen MC_SET_BIT(mcc->free_table, base_slot + i);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen }
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen *_rec = rec;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen return EOK;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen}
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainenstatic inline void sss_mmap_set_rec_header(struct sss_mc_ctx *mcc,
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen struct sss_mc_rec *rec,
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen size_t len, int ttl,
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen const char *key1, size_t key1_len,
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen const char *key2, size_t key2_len)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen{
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen rec->len = len;
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi rec->expire = time(NULL) + ttl;
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi rec->hash1 = sss_mc_hash(mcc, key1, key1_len);
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen rec->hash2 = sss_mc_hash(mcc, key2, key2_len);
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen}
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainenstatic inline void sss_mmap_chain_in_rec(struct sss_mc_ctx *mcc,
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen struct sss_mc_rec *rec)
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen{
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen /* name first */
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen sss_mc_add_rec_to_chain(mcc, rec, rec->hash1);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen /* then uid/gid */
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen sss_mc_add_rec_to_chain(mcc, rec, rec->hash2);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen}
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen/***************************************************************************
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen * generic invalidation
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen ***************************************************************************/
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainenstatic errno_t sss_mmap_cache_invalidate(struct sss_mc_ctx *mcc,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen struct sized_string *key)
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen{
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen struct sss_mc_rec *rec;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen if (mcc == NULL) {
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen /* cache not initialized ? */
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen return EINVAL;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen }
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen rec = sss_mc_find_record(mcc, key);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen if (rec == NULL) {
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen /* nothing to invalidate */
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen return ENOENT;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen }
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen sss_mc_invalidate_rec(mcc, rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen/***************************************************************************
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * passwd map
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ***************************************************************************/
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenerrno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sized_string *name,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sized_string *pw,
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen uid_t uid, gid_t gid,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sized_string *gecos,
4d8f538565145fd90eae48df5c4f2ed76e51ca78Timo Sirainen struct sized_string *homedir,
4d8f538565145fd90eae48df5c4f2ed76e51ca78Timo Sirainen struct sized_string *shell)
4d8f538565145fd90eae48df5c4f2ed76e51ca78Timo Sirainen{
4d8f538565145fd90eae48df5c4f2ed76e51ca78Timo Sirainen struct sss_mc_ctx *mcc = *_mcc;
4d8f538565145fd90eae48df5c4f2ed76e51ca78Timo Sirainen struct sss_mc_rec *rec;
4d8f538565145fd90eae48df5c4f2ed76e51ca78Timo Sirainen struct sss_mc_pwd_data *data;
4d8f538565145fd90eae48df5c4f2ed76e51ca78Timo Sirainen struct sized_string uidkey;
be59f9ae981dbe4bdd264053e9febd4ea5dad75bTimo Sirainen char uidstr[11];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen size_t data_len;
f0e416aa42058e7ccc0dc6deec0d4f4a19ee6ebeTimo Sirainen size_t rec_len;
7cd055a212d44067e2d94452c05691d696c9f699Timo Sirainen size_t pos;
7cd055a212d44067e2d94452c05691d696c9f699Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen if (mcc == NULL) {
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen /* cache not initialized ? */
e8434aad92ea6ff1c915b708294dbd0c7ff5908dMichael M Slusarz return EINVAL;
e8434aad92ea6ff1c915b708294dbd0c7ff5908dMichael M Slusarz }
f9eee365367f37b1692c07db6c23d30243844aaaTimo Sirainen
f9eee365367f37b1692c07db6c23d30243844aaaTimo Sirainen ret = snprintf(uidstr, 11, "%ld", (long)uid);
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen if (ret > 10) {
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen return EINVAL;
e564ff0581fc44b78badf8da36e68f9f7a27807eTimo Sirainen }
00bcc83b18793b9ec5e5d264480a88bf78b10b33Timo Sirainen to_sized_string(&uidkey, uidstr);
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen data_len = name->len + pw->len + gecos->len + homedir->len + shell->len;
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen rec_len = sizeof(struct sss_mc_rec) +
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen sizeof(struct sss_mc_pwd_data) +
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi data_len;
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi if (rec_len > mcc->dt_size) {
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi return ENOMEM;
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen ret = sss_mc_get_record(_mcc, rec_len, name, &rec);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen if (ret != EOK) {
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen return ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen data = (struct sss_mc_pwd_data *)rec->data;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pos = 0;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_RAISE_BARRIER(rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* header */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mmap_set_rec_header(mcc, rec, rec_len, mcc->valid_time_slot,
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen name->str, name->len, uidkey.str, uidkey.len);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* passwd struct */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen data->name = MC_PTR_DIFF(data->strs, data);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen data->uid = uid;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen data->gid = gid;
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen data->strs_len = data_len;
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen memcpy(&data->strs[pos], name->str, name->len);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pos += name->len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memcpy(&data->strs[pos], pw->str, pw->len);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pos += pw->len;
f0e416aa42058e7ccc0dc6deec0d4f4a19ee6ebeTimo Sirainen memcpy(&data->strs[pos], gecos->str, gecos->len);
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek pos += gecos->len;
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen memcpy(&data->strs[pos], homedir->str, homedir->len);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pos += homedir->len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memcpy(&data->strs[pos], shell->str, shell->len);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pos += shell->len;
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen MC_LOWER_BARRIER(rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* finally chain the rec in the hash table */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mmap_chain_in_rec(mcc, rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen return EOK;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainenerrno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx *mcc,
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen struct sized_string *name)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen return sss_mmap_cache_invalidate(mcc, name);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen}
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainenerrno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid)
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen{
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen struct sss_mc_rec *rec;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen struct sss_mc_pwd_data *data;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen uint32_t hash;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint32_t slot;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen char *uidstr;
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen errno_t ret;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen if (mcc == NULL) {
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen /* cache not initialized ? */
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen return EINVAL;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen }
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen uidstr = talloc_asprintf(NULL, "%ld", (long)uid);
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen if (!uidstr) {
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen return ENOMEM;
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen }
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen hash = sss_mc_hash(mcc, uidstr, strlen(uidstr) + 1);
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen slot = mcc->hash_table[hash];
b6c9cc2bf7517adcc0b9f98696c61bde321900f6Timo Sirainen if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) {
b6c9cc2bf7517adcc0b9f98696c61bde321900f6Timo Sirainen ret = ENOENT;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen goto done;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen }
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen while (slot != MC_INVALID_VAL) {
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) {
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen DEBUG(SSSDBG_FATAL_FAILURE, "Corrupted fastcache.\n");
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen sss_mc_save_corrupted(mcc);
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen sss_mmap_cache_reset(mcc);
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen ret = ENOENT;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen goto done;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen }
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen data = (struct sss_mc_pwd_data *)(&rec->data);
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen if (uid == data->uid) {
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen break;
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen }
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen slot = sss_mc_next_slot_with_hash(rec, hash);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (slot == MC_INVALID_VAL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = ENOENT;
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b457d2ecf97fb52064f9dd563fd4e8065af39dfbTimo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mc_invalidate_rec(mcc, rec);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainendone:
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen talloc_zfree(uidstr);
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen return ret;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen}
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen/***************************************************************************
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen * group map
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen ***************************************************************************/
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainenint sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc,
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen struct sized_string *name,
2ccb478c35972517721ce415d81fcbd11a73fad3Timo Sirainen struct sized_string *pw,
f0e811f0e306bb20d3da9c26353bdd5669132f29Timo Sirainen gid_t gid, size_t memnum,
f0e811f0e306bb20d3da9c26353bdd5669132f29Timo Sirainen char *membuf, size_t memsize)
f0e811f0e306bb20d3da9c26353bdd5669132f29Timo Sirainen{
f0e811f0e306bb20d3da9c26353bdd5669132f29Timo Sirainen struct sss_mc_ctx *mcc = *_mcc;
3e8842470a4a17017529d43b39c40a7549c2ecf2Timo Sirainen struct sss_mc_rec *rec;
3e8842470a4a17017529d43b39c40a7549c2ecf2Timo Sirainen struct sss_mc_grp_data *data;
c69a177207ed18d0f0210347430a60957136bd6cJosef 'Jeff' Sipek struct sized_string gidkey;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen char gidstr[11];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen size_t data_len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen size_t rec_len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen size_t pos;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (mcc == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* cache not initialized ? */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EINVAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
2ccb478c35972517721ce415d81fcbd11a73fad3Timo Sirainen ret = snprintf(gidstr, 11, "%ld", (long)gid);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen if (ret > 10) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EINVAL;
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen }
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen to_sized_string(&gidkey, gidstr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen data_len = name->len + pw->len + memsize;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rec_len = sizeof(struct sss_mc_rec) +
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sizeof(struct sss_mc_grp_data) +
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen data_len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (rec_len > mcc->dt_size) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = sss_mc_get_record(_mcc, rec_len, name, &rec);
1856c361aad526948d56d8aafd576bca94516b92Timo Sirainen if (ret != EOK) {
1856c361aad526948d56d8aafd576bca94516b92Timo Sirainen return ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen data = (struct sss_mc_grp_data *)rec->data;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pos = 0;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen MC_RAISE_BARRIER(rec);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen /* header */
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen sss_mmap_set_rec_header(mcc, rec, rec_len, mcc->valid_time_slot,
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen name->str, name->len, gidkey.str, gidkey.len);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen /* group struct */
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen data->name = MC_PTR_DIFF(data->strs, data);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen data->gid = gid;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen data->members = memnum;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen data->strs_len = data_len;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen memcpy(&data->strs[pos], name->str, name->len);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen pos += name->len;
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen memcpy(&data->strs[pos], pw->str, pw->len);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen pos += pw->len;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen memcpy(&data->strs[pos], membuf, memsize);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen pos += memsize;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen MC_LOWER_BARRIER(rec);
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen /* finally chain the rec in the hash table */
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen sss_mmap_chain_in_rec(mcc, rec);
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen return EOK;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen}
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainenerrno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx *mcc,
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen struct sized_string *name)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen{
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen return sss_mmap_cache_invalidate(mcc, name);
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen}
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainenerrno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen{
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen struct sss_mc_rec *rec;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen struct sss_mc_grp_data *data;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen uint32_t hash;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen uint32_t slot;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen char *gidstr;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen errno_t ret;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen if (mcc == NULL) {
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen /* cache not initialized ? */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EINVAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen gidstr = talloc_asprintf(NULL, "%ld", (long)gid);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen if (!gidstr) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return ENOMEM;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen hash = sss_mc_hash(mcc, gidstr, strlen(gidstr) + 1);
e401fa68eb1e7761ffd0b747919d44568555efeeTimo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen slot = mcc->hash_table[hash];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = ENOENT;
e401fa68eb1e7761ffd0b747919d44568555efeeTimo Sirainen goto done;
e401fa68eb1e7761ffd0b747919d44568555efeeTimo Sirainen }
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
0098ac3b6dcd8ef6ac20f87a8285da201db75a01Timo Sirainen while (slot != MC_INVALID_VAL) {
0098ac3b6dcd8ef6ac20f87a8285da201db75a01Timo Sirainen if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) {
0098ac3b6dcd8ef6ac20f87a8285da201db75a01Timo Sirainen DEBUG(SSSDBG_FATAL_FAILURE, "Corrupted fastcache.\n");
b8eb3211af2987d6e8f0d416156171fbd74f0737Timo Sirainen sss_mc_save_corrupted(mcc);
0098ac3b6dcd8ef6ac20f87a8285da201db75a01Timo Sirainen sss_mmap_cache_reset(mcc);
b8eb3211af2987d6e8f0d416156171fbd74f0737Timo Sirainen ret = ENOENT;
5d9ecbcec051b570d29b8f433d6b26d8435236fdTimo Sirainen goto done;
5d9ecbcec051b570d29b8f433d6b26d8435236fdTimo Sirainen }
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen data = (struct sss_mc_grp_data *)(&rec->data);
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
2522acb523343dd37bf788747d86d9470fc08025Timo Sirainen if (gid == data->gid) {
0098ac3b6dcd8ef6ac20f87a8285da201db75a01Timo Sirainen break;
0098ac3b6dcd8ef6ac20f87a8285da201db75a01Timo Sirainen }
2522acb523343dd37bf788747d86d9470fc08025Timo Sirainen
b394d41ad4da0e2e7b8bfafccf3b4f3e9ac26ad1Timo Sirainen slot = sss_mc_next_slot_with_hash(rec, hash);
b394d41ad4da0e2e7b8bfafccf3b4f3e9ac26ad1Timo Sirainen }
b394d41ad4da0e2e7b8bfafccf3b4f3e9ac26ad1Timo Sirainen
b394d41ad4da0e2e7b8bfafccf3b4f3e9ac26ad1Timo Sirainen if (slot == MC_INVALID_VAL) {
2522acb523343dd37bf788747d86d9470fc08025Timo Sirainen ret = ENOENT;
2522acb523343dd37bf788747d86d9470fc08025Timo Sirainen goto done;
2522acb523343dd37bf788747d86d9470fc08025Timo Sirainen }
2522acb523343dd37bf788747d86d9470fc08025Timo Sirainen
2522acb523343dd37bf788747d86d9470fc08025Timo Sirainen sss_mc_invalidate_rec(mcc, rec);
2522acb523343dd37bf788747d86d9470fc08025Timo Sirainen
b394d41ad4da0e2e7b8bfafccf3b4f3e9ac26ad1Timo Sirainen ret = EOK;
2522acb523343dd37bf788747d86d9470fc08025Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainendone:
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen talloc_zfree(gidstr);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen return ret;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen}
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen/***************************************************************************
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * initialization
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen ***************************************************************************/
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen/* Copy of sss_mc_set_recycled is present in the src/tools/tools_mc_util.c.
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen * If you modify this function, you should modify the duplicated function
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen * too. */
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainenstatic errno_t sss_mc_set_recycled(int fd)
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen{
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen uint32_t w = SSS_MC_HEADER_RECYCLED;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_mc_header h;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen off_t offset;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen off_t pos;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen offset = MC_PTR_DIFF(&h.status, &h);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen pos = lseek(fd, offset, SEEK_SET);
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen if (pos == -1) {
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen /* What do we do now ? */
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen return errno;
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi }
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi errno = 0;
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen ret = sss_atomic_write_s(fd, (uint8_t *)&w, sizeof(h.status));
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen if (ret == -1) {
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen return errno;
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen }
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen if (ret != sizeof(h.status)) {
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen /* Write error */
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen return EIO;
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen }
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen return EOK;
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen}
214aff73cd9809446bef169b216d6eb5a81079d8Timo Sirainen
214aff73cd9809446bef169b216d6eb5a81079d8Timo Sirainen/*
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen * When we (re)create a new file we must mark the current file as recycled
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen * so active clients will abandon its use asap.
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen * We unlink the current file and make a new one
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen */
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainenstatic errno_t sss_mc_create_file(struct sss_mc_ctx *mc_ctx)
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen{
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen mode_t old_mask;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen int ofd;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen int ret, uret;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen useconds_t t = 50000;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen int retries = 3;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen ofd = open(mc_ctx->file, O_RDWR);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen if (ofd != -1) {
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen ret = sss_br_lock_file(ofd, 0, 1, retries, t);
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen if (ret != EOK) {
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen DEBUG(SSSDBG_FATAL_FAILURE,
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen "Failed to lock file %s.\n", mc_ctx->file);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen }
a8a5f2f8ccc134dcc7b61ea48664c3381db4a1aaTimo Sirainen ret = sss_mc_set_recycled(ofd);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen if (ret) {
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen DEBUG(SSSDBG_FATAL_FAILURE, "Failed to mark mmap file %s as"
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen " recycled: %d(%s)\n",
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen mc_ctx->file, ret, strerror(ret));
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen }
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen close(ofd);
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen } else if (errno != ENOENT) {
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen ret = errno;
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen "Failed to open old memory cache file %s: %d(%s).\n",
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen mc_ctx->file, ret, strerror(ret));
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen }
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen errno = 0;
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen ret = unlink(mc_ctx->file);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen if (ret == -1 && errno != ENOENT) {
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen ret = errno;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen DEBUG(SSSDBG_TRACE_FUNC, "Failed to rm mmap file %s: %d(%s)\n",
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen mc_ctx->file, ret, strerror(ret));
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* temporarily relax umask as we need the file to be readable
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen * by everyone for now */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen old_mask = umask(0022);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen errno = 0;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen mc_ctx->fd = open(mc_ctx->file, O_CREAT | O_EXCL | O_RDWR, 0644);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen umask(old_mask);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen if (mc_ctx->fd == -1) {
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen ret = errno;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Failed to open mmap file %s: %d(%s)\n",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->file, ret, strerror(ret));
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen return ret;
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen }
de5f478d9e7ae7b8e58082e0b30b6ce1f034236aTimo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = sss_br_lock_file(mc_ctx->fd, 0, 1, retries, t);
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen if (ret != EOK) {
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen DEBUG(SSSDBG_FATAL_FAILURE,
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen "Failed to lock file %s.\n", mc_ctx->file);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen close(mc_ctx->fd);
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen mc_ctx->fd = -1;
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen /* Report on unlink failures but don't overwrite the errno
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen * from sss_br_lock_file
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen */
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen errno = 0;
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen uret = unlink(mc_ctx->file);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen if (uret == -1) {
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen uret = errno;
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen DEBUG(SSSDBG_TRACE_FUNC, "Failed to rm mmap file %s: %d(%s)\n",
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen mc_ctx->file, uret, strerror(uret));
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen }
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen return ret;
8a6afcd8a6d9ed69626add85a7b75105ee3cb6a1Timo Sirainen }
8a6afcd8a6d9ed69626add85a7b75105ee3cb6a1Timo Sirainen
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen return ret;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen}
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainenstatic void sss_mc_header_update(struct sss_mc_ctx *mc_ctx, int status)
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen{
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen struct sss_mc_header *h;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen /* update header using barriers */
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen h = (struct sss_mc_header *)mc_ctx->mmap_base;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen MC_RAISE_BARRIER(h);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen if (status == SSS_MC_HEADER_ALIVE) {
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen /* no reason to update anything else if the file is recycled or
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen * right before reset */
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen h->hash_table = MC_PTR_DIFF(mc_ctx->hash_table, mc_ctx->mmap_base);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen h->free_table = MC_PTR_DIFF(mc_ctx->free_table, mc_ctx->mmap_base);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen h->data_table = MC_PTR_DIFF(mc_ctx->data_table, mc_ctx->mmap_base);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen h->ht_size = mc_ctx->ht_size;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen h->ft_size = mc_ctx->ft_size;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen h->dt_size = mc_ctx->dt_size;
709ee5a909d482f31611f9e6cc10d893a272e061Timo Sirainen h->major_vno = SSS_MC_MAJOR_VNO;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen h->minor_vno = SSS_MC_MINOR_VNO;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen h->seed = mc_ctx->seed;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen h->reserved = 0;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen h->status = status;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_LOWER_BARRIER(h);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic int mc_ctx_destructor(struct sss_mc_ctx *mc_ctx)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen /* Print debug message to logs if munmap() or close()
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen * fail but always return 0 */
b6c9cc2bf7517adcc0b9f98696c61bde321900f6Timo Sirainen
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen if (mc_ctx->mmap_base != NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = munmap(mc_ctx->mmap_base, mc_ctx->mmap_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret == -1) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = errno;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen "Failed to unmap old memory cache file."
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen "[%d]: %s\n", ret, strerror(ret));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen }
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen if (mc_ctx->fd != -1) {
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen ret = close(mc_ctx->fd);
b6c9cc2bf7517adcc0b9f98696c61bde321900f6Timo Sirainen if (ret == -1) {
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen ret = errno;
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen "Failed to close old memory cache file."
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen "[%d]: %s\n", ret, strerror(ret));
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen }
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen }
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen return 0;
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen}
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainenerrno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen enum sss_mc_type type, size_t n_elem,
b6c9cc2bf7517adcc0b9f98696c61bde321900f6Timo Sirainen time_t timeout, struct sss_mc_ctx **mcc)
a5f2707224b10f26e3d478a2b11e8d01f1b8f609Timo Sirainen{
a2c4998f6e1fe5ea9a2c9bafd678cd4b6b064a0bTimo Sirainen struct sss_mc_ctx *mc_ctx = NULL;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen unsigned int rseed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int payload;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret, dret;
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen switch (type) {
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen case SSS_MC_PASSWD:
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen payload = SSS_AVG_PASSWD_PAYLOAD;
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_MC_GROUP:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen payload = SSS_AVG_GROUP_PAYLOAD;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen break;
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen default:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EINVAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx = talloc_zero(mem_ctx, struct sss_mc_ctx);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!mc_ctx) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->fd = -1;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_set_destructor(mc_ctx, mc_ctx_destructor);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->name = talloc_strdup(mc_ctx, name);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!mc_ctx->name) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->type = type;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->valid_time_slot = timeout;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->file = talloc_asprintf(mc_ctx, "%s/%s",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen SSS_NSS_MCACHE_DIR, name);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!mc_ctx->file) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* elements must always be multiple of 8 to make things easier to handle,
e07677bb15404a3c18ad205efae86d6db31c3150Timo Sirainen * so we increase by the necessary amount if they are not a multiple */
e07677bb15404a3c18ad205efae86d6db31c3150Timo Sirainen /* We can use MC_ALIGN64 for this */
e07677bb15404a3c18ad205efae86d6db31c3150Timo Sirainen n_elem = MC_ALIGN64(n_elem);
e07677bb15404a3c18ad205efae86d6db31c3150Timo Sirainen
e07677bb15404a3c18ad205efae86d6db31c3150Timo Sirainen /* hash table is double the size because it will store both forward and
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * reverse keys (name/uid, name/gid, ..) */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->ht_size = MC_HT_SIZE(n_elem * 2);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->dt_size = MC_DT_SIZE(n_elem, payload);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->ft_size = MC_FT_SIZE(n_elem);
8759c5d294e762fe9c5b7b19f3842b23aaaaf4ebTimo Sirainen mc_ctx->mmap_size = MC_HEADER_SIZE +
8759c5d294e762fe9c5b7b19f3842b23aaaaf4ebTimo Sirainen MC_ALIGN64(mc_ctx->dt_size) +
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_ALIGN64(mc_ctx->ft_size) +
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_ALIGN64(mc_ctx->ht_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* for now ALWAYS create a new file on restart */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = sss_mc_create_file(mc_ctx);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = ftruncate(mc_ctx->fd, mc_ctx->mmap_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret == -1) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = errno;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Failed to resize file %s: %d(%s)\n",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->file, ret, strerror(ret));
8759c5d294e762fe9c5b7b19f3842b23aaaaf4ebTimo Sirainen goto done;
8759c5d294e762fe9c5b7b19f3842b23aaaaf4ebTimo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->mmap_base = mmap(NULL, mc_ctx->mmap_size,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen PROT_READ | PROT_WRITE,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MAP_SHARED, mc_ctx->fd, 0);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (mc_ctx->mmap_base == MAP_FAILED) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = errno;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Failed to mmap file %s(%zu): %d(%s)\n",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->file, mc_ctx->mmap_size,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret, strerror(ret));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->data_table = MC_PTR_ADD(mc_ctx->mmap_base, MC_HEADER_SIZE);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->free_table = MC_PTR_ADD(mc_ctx->data_table,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_ALIGN64(mc_ctx->dt_size));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mc_ctx->hash_table = MC_PTR_ADD(mc_ctx->free_table,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MC_ALIGN64(mc_ctx->ft_size));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(mc_ctx->data_table, 0xff, mc_ctx->dt_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(mc_ctx->free_table, 0x00, mc_ctx->ft_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(mc_ctx->hash_table, 0xff, mc_ctx->ht_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* generate a pseudo-random seed.
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * Needed to fend off dictionary based collision attacks */
8759c5d294e762fe9c5b7b19f3842b23aaaaf4ebTimo Sirainen rseed = time(NULL) * getpid();
8759c5d294e762fe9c5b7b19f3842b23aaaaf4ebTimo Sirainen mc_ctx->seed = rand_r(&rseed);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mc_header_update(mc_ctx, SSS_MC_HEADER_ALIVE);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainendone:
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen if (ret) {
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen /* Closing the file descriptor and ummaping the file
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * from memory is done in the mc_ctx_destructor. */
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen if (mc_ctx && mc_ctx->file && mc_ctx->fd != -1) {
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen dret = unlink(mc_ctx->file);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (dret == -1) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen "Failed to rm mmap file %s: %d(%s)\n", mc_ctx->file,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen dret, strerror(dret));
23bdbb7b1831785c6ba6df190f6369da882d2b9dTimo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
0cb80fbd739a9a9b3618a5595b34458a0a994d9bTimo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_free(mc_ctx);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *mcc = mc_ctx;
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen }
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen return ret;
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen}
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainenerrno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen time_t timeout, struct sss_mc_ctx **mc_ctx)
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen{
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen errno_t ret;
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen TALLOC_CTX* tmp_ctx = NULL;
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen char *name;
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen enum sss_mc_type type;
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen if (mc_ctx == NULL || (*mc_ctx) == NULL) {
344c4411571e25dcf2f974c07c116a6160c77338Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen "Unable to re-init unitialized memory cache.\n");
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen return EINVAL;
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen }
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen tmp_ctx = talloc_new(NULL);
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen if (tmp_ctx == NULL) {
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n");
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen return ENOMEM;
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen }
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen name = talloc_strdup(tmp_ctx, (*mc_ctx)->name);
769cbb608e9ed620063708aff49fc1b6e924394aTimo Sirainen if (name == NULL) {
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n");
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen ret = ENOMEM;
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen goto done;
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen }
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen type = (*mc_ctx)->type;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen if (n_elem == (size_t)-1) {
b096ecf3188cdb9162460ed7ae885c03f3161462Timo Sirainen n_elem = (*mc_ctx)->ft_size * 8;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen if (timeout == (time_t)-1) {
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen timeout = (*mc_ctx)->valid_time_slot;
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen }
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_free(*mc_ctx);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* make sure we do not leave a potentially freed pointer around */
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen *mc_ctx = NULL;
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen ret = sss_mmap_cache_init(mem_ctx, name, type, n_elem, timeout, mc_ctx);
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen if (ret != EOK) {
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "Failed to re-initialize mmap cache.\n");
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen goto done;
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen }
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainendone:
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen talloc_free(tmp_ctx);
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen return ret;
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen}
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen/* Erase all contents of the mmap cache. This will bring the cache
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen * to the same state as if it was just initialized. */
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainenvoid sss_mmap_cache_reset(struct sss_mc_ctx *mc_ctx)
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen{
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen if (mc_ctx == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(SSSDBG_TRACE_FUNC,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen "Fastcache not initialized. Nothing to do.\n");
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mc_header_update(mc_ctx, SSS_MC_HEADER_UNINIT);
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* Reset the mmaped area */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(mc_ctx->data_table, 0xff, mc_ctx->dt_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(mc_ctx->free_table, 0x00, mc_ctx->ft_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(mc_ctx->hash_table, 0xff, mc_ctx->ht_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen sss_mc_header_update(mc_ctx, SSS_MC_HEADER_ALIVE);
23bdbb7b1831785c6ba6df190f6369da882d2b9dTimo Sirainen}
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen