mmap_cache.h revision 9028706a00da1bc48547e74aa872c825ac15adb2
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce/*
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce SSSD
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce Mmap Cache Common header
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce Copyright (C) Simo Sorce <ssorce@redhat.com> 2011
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce This program is free software; you can redistribute it and/or modify
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce it under the terms of the GNU General Public License as published by
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce the Free Software Foundation; either version 3 of the License, or
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce (at your option) any later version.
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce This program is distributed in the hope that it will be useful,
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce but WITHOUT ANY WARRANTY; without even the implied warranty of
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce GNU General Public License for more details.
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce You should have received a copy of the GNU General Public License
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce along with this program. If not, see <http://www.gnu.org/licenses/>.
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce*/
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#ifndef _MMAP_CACHE_H_
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define _MMAP_CACHE_H_
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#include "util/murmurhash3.h"
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce/* NOTE: all the code here assumes that writing a uint32_t nto mmapped
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce * memory is an atomic operation and can't be split in multiple
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce * non-atomic operations */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorcetypedef uint32_t rel_ptr_t;
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce/* align macros */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_8 sizeof(uint8_t)
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_32 sizeof(uint32_t)
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_64 sizeof(uint64_t)
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_ALIGN32(size) ( ((size) + MC_32 -1) & (~(MC_32 -1)) )
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_ALIGN64(size) ( ((size) + MC_64 -1) & (~(MC_64 -1)) )
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_HEADER_SIZE MC_ALIGN64(sizeof(struct sss_mc_header))
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_HT_SIZE(elems) ( (elems) * MC_32 )
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_HT_ELEMS(size) ( (size) / MC_32 )
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_DT_SIZE(elems, payload) ( (elems) * (payload) )
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_FT_SIZE(elems) ( (elems) / 8 )
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce/* ^^ 8 bits per byte so we need just elems/8 bytes to represent all blocks */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_PTR_ADD(ptr, bytes) (void *)((uint8_t *)(ptr) + (bytes))
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_PTR_DIFF(ptr, base) ((uint8_t *)(ptr) - (uint8_t *)(base))
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
6acf7c92ab38ad388295b2d57cc97c4598aa95ccSimo Sorce#define MC_INVALID_VAL64 ((uint64_t)-1)
6acf7c92ab38ad388295b2d57cc97c4598aa95ccSimo Sorce#define MC_INVALID_VAL32 ((uint32_t)-1)
6acf7c92ab38ad388295b2d57cc97c4598aa95ccSimo Sorce#define MC_INVALID_VAL8 ((uint8_t)-1)
6acf7c92ab38ad388295b2d57cc97c4598aa95ccSimo Sorce#define MC_INVALID_VAL MC_INVALID_VAL32
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce/*
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce * 32 seem a good compromise for slot size
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce * 4 blocks are enough for the average passwd entry of 42 bytes
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce * passwd records have 84 bytes of overhead, 128 - 82 = 46 bytes
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce * 3 blocks can contain a very minimal entry, 96 - 82 = 14 bytes
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce *
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce * 3 blocks are enough for groups w/o users (private user groups)
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce * group records have 68 bytes of overhead, 96 - 66 = 30 bytes
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_SLOT_SIZE 32
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_SIZE_TO_SLOTS(len) (((len) + (MC_SLOT_SIZE - 1)) / MC_SLOT_SIZE)
4869633dc87dadb2b9a114444d375c39703ac863Pavel Březina#define MC_PTR_TO_SLOT(base, ptr) (MC_PTR_DIFF(ptr, base) / MC_SLOT_SIZE)
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_SLOT_TO_PTR(base, slot, type) \
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce (type *)((base) + ((slot) * MC_SLOT_SIZE))
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define MC_VALID_BARRIER(val) (((val) & 0xff000000) == 0xf0000000)
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
31c47cacc7f9453153e57319474909d23122883fPavel Březina#define MC_CHECK_RECORD_LENGTH(mc_ctx, rec) \
31c47cacc7f9453153e57319474909d23122883fPavel Březina ((rec)->len >= MC_HEADER_SIZE && (rec)->len != MC_INVALID_VAL32 \
31c47cacc7f9453153e57319474909d23122883fPavel Březina && ((rec)->len <= ((mc_ctx)->dt_size \
31c47cacc7f9453153e57319474909d23122883fPavel Březina - MC_PTR_DIFF(rec, (mc_ctx)->data_table))))
31c47cacc7f9453153e57319474909d23122883fPavel Březina
31c47cacc7f9453153e57319474909d23122883fPavel Březina
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define SSS_MC_MAJOR_VNO 0
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define SSS_MC_MINOR_VNO 4
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
9028706a00da1bc48547e74aa872c825ac15adb2Michal Zidek#define SSS_MC_HEADER_UNINIT 0 /* after ftruncate or before reset */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define SSS_MC_HEADER_ALIVE 1 /* current and in use */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#define SSS_MC_HEADER_RECYCLED 2 /* file was recycled, reopen asap */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#pragma pack(1)
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorcestruct sss_mc_header {
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t b1; /* barrier 1 */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t major_vno; /* major version number */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t minor_vno; /* minor version number */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t status; /* database status */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t seed; /* random seed used to avoid collision attacks */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t dt_size; /* data table size */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t ft_size; /* free table size */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t ht_size; /* hash table size */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce rel_ptr_t data_table; /* data table pointer relative to mmap base */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce rel_ptr_t free_table; /* free table pointer relative to mmap base */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce rel_ptr_t hash_table; /* hash table pointer relative to mmap base */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce rel_ptr_t reserved; /* reserved for future changes */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t b2; /* barrier 2 */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce};
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorcestruct sss_mc_rec {
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t b1; /* barrier 1 */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t len; /* total record length including record data */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint64_t expire; /* record expiration time (cast to time_t) */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce rel_ptr_t next; /* ptr of next record rel to data_table */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t hash1; /* val of first hash (usually name of record) */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t hash2; /* val of second hash (usually id of record) */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t b2; /* barrier 2 - 32 bytes mark, fits a slot */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce char data[0];
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce};
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
9028706a00da1bc48547e74aa872c825ac15adb2Michal Zidek/* FIXME: Function sss_mc_find_record currently relies on fact that
9028706a00da1bc48547e74aa872c825ac15adb2Michal Zidek * offset of strs is the same in both sss_mc_pwd_data and sss_mc_grp_data. */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorcestruct sss_mc_pwd_data {
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce rel_ptr_t name; /* ptr to name string, rel. to struct base addr */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t uid;
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t gid;
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce uint32_t strs_len; /* length of strs */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce char strs[0]; /* concatenation of all passwd strings, each
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce * string is zero terminated ordered as follows:
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce * name, passwd, gecos, dir, shell */
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce};
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorcestruct sss_mc_grp_data {
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce rel_ptr_t name; /* ptr to name string, rel. to struct base addr */
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce uint32_t gid;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce uint32_t members; /* number of members in strs */
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce uint32_t strs_len; /* length of strs */
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce char strs[0]; /* concatenation of all group strings, each
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce * string is zero terminated ordered as follows:
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce * name, passwd, member1, member2, ... */
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce};
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#pragma pack()
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce
5f90993426fa2bdc3b3d994c9e85e0805bb92bbcSimo Sorce#endif /* _MMAP_CACHE_H_ */