summaryrefslogtreecommitdiff
path: root/src/defrag.c
diff options
context:
space:
mode:
authoryoav-steinberg <yoav@monfort.co.il>2022-02-11 21:58:05 +0200
committerGitHub <noreply@github.com>2022-02-11 21:58:05 +0200
commit2eb9b19612db39b1bb91902c9669e28883bbbee7 (patch)
tree354a5a6dbd9ec5caf4c9bde658799864bc1ca9c8 /src/defrag.c
parent5f0119ca91ad37d8b656d51bcfc46c600d177e8f (diff)
downloadredis-2eb9b19612db39b1bb91902c9669e28883bbbee7.tar.gz
Fix Eval scripts defrag (broken 7.0 in RC1) (#10271)
Remove scripts defragger since it was broken since #10126 (released in 7.0 RC1). would crash the server if defragger starts in a server that contains eval scripts. In #10126 the global `lua_script` dict became a dict to a custom `luaScript` struct with an internal `robj` in it instead of a generic `sds` -> `robj` dict. This means we need custom code to defrag it and since scripts should never really cause much fragmentation it makes more sense to simply remove the defrag code for scripts.
Diffstat (limited to 'src/defrag.c')
-rw-r--r--src/defrag.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/defrag.c b/src/defrag.c
index 16b1a4d2d..b0ae487f3 100644
--- a/src/defrag.c
+++ b/src/defrag.c
@@ -128,6 +128,27 @@ robj *activeDefragStringOb(robj* ob, long *defragged) {
return ret;
}
+/* Defrag helper for lua scripts
+ *
+ * returns NULL in case the allocation wasn't moved.
+ * when it returns a non-null value, the old pointer was already released
+ * and should NOT be accessed. */
+luaScript *activeDefragLuaScript(luaScript *script, long *defragged) {
+ luaScript *ret = NULL;
+
+ /* try to defrag script struct */
+ if ((ret = activeDefragAlloc(script))) {
+ script = ret;
+ (*defragged)++;
+ }
+
+ /* try to defrag actual script object */
+ robj *ob = activeDefragStringOb(script->body, defragged);
+ if (ob) script->body = ob;
+
+ return ret;
+}
+
/* Defrag helper for dictEntries to be used during dict iteration (called on
* each step). Returns a stat of how many pointers were moved. */
long dictIterDefragEntry(dictIterator *iter) {
@@ -256,6 +277,7 @@ long activeDefragZsetEntry(zset *zs, dictEntry *de) {
#define DEFRAG_SDS_DICT_VAL_IS_SDS 1
#define DEFRAG_SDS_DICT_VAL_IS_STROB 2
#define DEFRAG_SDS_DICT_VAL_VOID_PTR 3
+#define DEFRAG_SDS_DICT_VAL_LUA_SCRIPT 4
/* Defrag a dict with sds key and optional value (either ptr, sds or robj string) */
long activeDefragSdsDict(dict* d, int val_type) {
@@ -280,6 +302,10 @@ long activeDefragSdsDict(dict* d, int val_type) {
void *newptr, *ptr = dictGetVal(de);
if ((newptr = activeDefragAlloc(ptr)))
de->v.val = newptr, defragged++;
+ } else if (val_type == DEFRAG_SDS_DICT_VAL_LUA_SCRIPT) {
+ void *newptr, *ptr = dictGetVal(de);
+ if ((newptr = activeDefragLuaScript(ptr, &defragged)))
+ de->v.val = newptr;
}
defragged += dictIterDefragEntry(di);
}
@@ -939,7 +965,7 @@ long defragOtherGlobals() {
/* there are many more pointers to defrag (e.g. client argv, output / aof buffers, etc.
* but we assume most of these are short lived, we only need to defrag allocations
* that remain static for a long time */
- defragged += activeDefragSdsDict(evalScriptsDict(), DEFRAG_SDS_DICT_VAL_IS_STROB);
+ defragged += activeDefragSdsDict(evalScriptsDict(), DEFRAG_SDS_DICT_VAL_LUA_SCRIPT);
defragged += moduleDefragGlobals();
return defragged;
}