Support configurable file backed scratch
This commit is contained in:
parent
5e6b9b9c54
commit
a476fdfd8c
@ -166,9 +166,9 @@ REDIS_SERVER_NAME=redis-server
|
||||
REDIS_SENTINEL_NAME=redis-sentinel
|
||||
REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o acl.o storage.o
|
||||
REDIS_CLI_NAME=redis-cli
|
||||
REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o storage.o
|
||||
REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o storage-lite.o
|
||||
REDIS_BENCHMARK_NAME=redis-benchmark
|
||||
REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o zmalloc.o redis-benchmark.o storage.o
|
||||
REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o zmalloc.o redis-benchmark.o storage-lite.o
|
||||
REDIS_CHECK_RDB_NAME=redis-check-rdb
|
||||
REDIS_CHECK_AOF_NAME=redis-check-aof
|
||||
|
||||
|
@ -804,6 +804,8 @@ void loadServerConfigFromString(char *config) {
|
||||
err = sentinelHandleConfiguration(argv+1,argc-1);
|
||||
if (err) goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"scratch-file-path")) {
|
||||
storage_init(argv[1]);
|
||||
} else {
|
||||
err = "Bad directive or wrong number of arguments"; goto loaderr;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
/* ===================== Creation and parsing of objects ==================== */
|
||||
|
||||
robj *createObject(int type, void *ptr) {
|
||||
robj *o = salloc_obj(); //zmalloc(sizeof(*o), MALLOC_SHARED);
|
||||
robj *o = zmalloc(sizeof(*o), MALLOC_SHARED);
|
||||
o->type = type;
|
||||
o->encoding = OBJ_ENCODING_RAW;
|
||||
o->ptr = ptr;
|
||||
@ -362,10 +362,7 @@ void decrRefCount(robj *o) {
|
||||
case OBJ_STREAM: freeStreamObject(o); break;
|
||||
default: serverPanic("Unknown object type"); break;
|
||||
}
|
||||
if (o->type == OBJ_STRING && o->encoding == OBJ_ENCODING_EMBSTR)
|
||||
zfree(o);
|
||||
else
|
||||
sfree_obj(o);
|
||||
zfree(o);
|
||||
} else {
|
||||
if (o->refcount <= 0) serverPanic("decrRefCount against refcount <= 0");
|
||||
if (o->refcount != OBJ_SHARED_REFCOUNT) o->refcount--;
|
||||
|
@ -653,7 +653,7 @@ int main(int argc, const char **argv) {
|
||||
|
||||
client c;
|
||||
|
||||
storage_init();
|
||||
storage_init(NULL);
|
||||
|
||||
srandom(time(NULL));
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
|
@ -7176,7 +7176,7 @@ static void intrinsicLatencyMode(void) {
|
||||
int main(int argc, char **argv) {
|
||||
int firstarg;
|
||||
|
||||
storage_init();
|
||||
storage_init(NULL);
|
||||
config.hostip = sdsnew("127.0.0.1");
|
||||
config.hostport = 6379;
|
||||
config.hostsocket = NULL;
|
||||
|
@ -4740,7 +4740,7 @@ int main(int argc, char **argv) {
|
||||
struct timeval tv;
|
||||
int j;
|
||||
|
||||
storage_init();
|
||||
storage_init(NULL);
|
||||
|
||||
#ifdef REDIS_TEST
|
||||
if (argc == 3 && !strcasecmp(argv[1], "test")) {
|
||||
|
41
src/storage-lite.c
Normal file
41
src/storage-lite.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memkind.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include "storage.h"
|
||||
#include <assert.h>
|
||||
|
||||
// initialize the memory subsystem.
|
||||
// NOTE: This may be called twice, first with NULL specifying we should use ram
|
||||
// later, after the configuration file is loaded with a path to where we should
|
||||
// place our temporary file.
|
||||
void storage_init(const char *tmpfilePath)
|
||||
{
|
||||
assert(tmpfilePath == NULL);
|
||||
(void)tmpfilePath;
|
||||
}
|
||||
|
||||
void *salloc(size_t cb, enum MALLOC_CLASS class)
|
||||
{
|
||||
(void)class;
|
||||
return malloc(cb);
|
||||
}
|
||||
|
||||
void *scalloc(size_t cb, size_t c, enum MALLOC_CLASS class)
|
||||
{
|
||||
(void)class;
|
||||
return calloc(cb, c);
|
||||
}
|
||||
|
||||
void sfree(void *pv)
|
||||
{
|
||||
free(pv);
|
||||
}
|
||||
|
||||
void *srealloc(void *pv, size_t cb)
|
||||
{
|
||||
return realloc(pv, cb);
|
||||
}
|
@ -10,7 +10,7 @@
|
||||
#include "storage.h"
|
||||
|
||||
struct memkind *mkdisk = NULL;
|
||||
static char *PMEM_DIR = "/mnt/btrfs_scratch/";
|
||||
static const char *PMEM_DIR = NULL;
|
||||
|
||||
void handle_prefork();
|
||||
void handle_postfork_parent();
|
||||
@ -85,9 +85,6 @@ void *pool_alloc(struct alloc_pool *ppool)
|
||||
}
|
||||
}
|
||||
|
||||
#pragma weak serverLog
|
||||
void serverLog(int level, const char*fmt, ...){}
|
||||
|
||||
void pool_free(struct alloc_pool *ppool, void *pv)
|
||||
{
|
||||
struct object_page *cur = ppool->pobjpageHead;
|
||||
@ -113,18 +110,62 @@ void pool_free(struct alloc_pool *ppool, void *pv)
|
||||
struct alloc_pool poolobj;
|
||||
struct alloc_pool poolembstrobj;
|
||||
|
||||
void storage_init()
|
||||
int forkFile()
|
||||
{
|
||||
int errv = memkind_create_pmem(PMEM_DIR, 0, &mkdisk);
|
||||
if (errv)
|
||||
int fdT;
|
||||
memkind_tmpfile(PMEM_DIR, &fdT);
|
||||
if (ioctl(fdT, FICLONE, memkind_fd(mkdisk)) == -1)
|
||||
{
|
||||
fprintf(stderr, "Memory pool creation failed: %d\n", errv);
|
||||
exit(EXIT_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
pool_initialize(&poolobj, sizeof(robj));
|
||||
pool_initialize(&poolembstrobj, EMBSTR_ROBJ_SIZE);
|
||||
return fdT;
|
||||
}
|
||||
|
||||
pthread_atfork(handle_prefork, handle_postfork_parent, handle_postfork_child);
|
||||
// initialize the memory subsystem.
|
||||
// NOTE: This may be called twice, first with NULL specifying we should use ram
|
||||
// later, after the configuration file is loaded with a path to where we should
|
||||
// place our temporary file.
|
||||
void storage_init(const char *tmpfilePath)
|
||||
{
|
||||
if (tmpfilePath == NULL)
|
||||
{
|
||||
serverAssert(mkdisk == NULL);
|
||||
mkdisk = MEMKIND_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// First create the file
|
||||
serverAssert(mkdisk == MEMKIND_DEFAULT);
|
||||
PMEM_DIR = memkind_malloc(MEMKIND_DEFAULT, strlen(tmpfilePath));
|
||||
strcpy((char*)PMEM_DIR, tmpfilePath);
|
||||
int errv = memkind_create_pmem(PMEM_DIR, 0, &mkdisk);
|
||||
if (errv == MEMKIND_ERROR_INVALID)
|
||||
{
|
||||
serverLog(LOG_CRIT, "Memory pool creation failed: %s", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if (errv)
|
||||
{
|
||||
char msgbuf[1024];
|
||||
memkind_error_message(errv, msgbuf, 1024);
|
||||
serverLog(LOG_CRIT, "Memory pool creation failed: %s", msgbuf);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Next test if COW is working
|
||||
int fdTest = forkFile();
|
||||
if (fdTest < 0)
|
||||
{
|
||||
serverLog(LOG_ERR, "Scratch file system does not support Copy on Write. To fix this scratch-file-path must point to a path on a filesystem which supports copy on write, such as btrfs.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
close(fdTest);
|
||||
|
||||
pool_initialize(&poolobj, sizeof(robj));
|
||||
pool_initialize(&poolembstrobj, EMBSTR_ROBJ_SIZE);
|
||||
|
||||
pthread_atfork(handle_prefork, handle_postfork_parent, handle_postfork_child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -184,12 +225,9 @@ void *srealloc(void *pv, size_t cb)
|
||||
int fdNew = -1;
|
||||
void handle_prefork()
|
||||
{
|
||||
memkind_tmpfile(PMEM_DIR, &fdNew);
|
||||
if (ioctl(fdNew, FICLONE, memkind_fd(mkdisk)) == -1)
|
||||
{
|
||||
perror("failed to fork file");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fdNew = forkFile();
|
||||
if (fdNew < 0)
|
||||
serverLog(LOG_ERR, "Failed to clone scratch file");
|
||||
}
|
||||
|
||||
void handle_postfork_parent()
|
||||
|
@ -9,12 +9,7 @@ enum MALLOC_CLASS
|
||||
MALLOC_SHARED,
|
||||
};
|
||||
|
||||
void storage_init(void);
|
||||
|
||||
struct redisObject *salloc_obj();
|
||||
void sfree_obj(struct redisObject *obj);
|
||||
struct redisObject *salloc_objembstr();
|
||||
void sfree_objembstr(struct redisObject *obj);
|
||||
void storage_init(const char *tmpfilePath);
|
||||
|
||||
void *salloc(size_t cb, enum MALLOC_CLASS class);
|
||||
void *scalloc(size_t cb, size_t c, enum MALLOC_CLASS class);
|
||||
|
Loading…
x
Reference in New Issue
Block a user