Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
babe3c7b
Commit
babe3c7b
authored
Apr 20, 2018
by
zhaozhao.zz
Committed by
Oran Agra
Jun 01, 2021
Browse files
Modules: rewrite config loadmodule option
parent
09e435c8
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/config.c
View file @
babe3c7b
...
@@ -315,7 +315,7 @@ void queueLoadModule(sds path, sds *argv, int argc) {
...
@@ -315,7 +315,7 @@ void queueLoadModule(sds path, sds *argv, int argc) {
struct
moduleLoadQueueEntry
*
loadmod
;
struct
moduleLoadQueueEntry
*
loadmod
;
loadmod
=
zmalloc
(
sizeof
(
struct
moduleLoadQueueEntry
));
loadmod
=
zmalloc
(
sizeof
(
struct
moduleLoadQueueEntry
));
loadmod
->
argv
=
zmalloc
(
sizeof
(
robj
*
)
*
argc
);
loadmod
->
argv
=
argc
?
zmalloc
(
sizeof
(
robj
*
)
*
argc
)
:
NULL
;
loadmod
->
path
=
sdsnew
(
path
);
loadmod
->
path
=
sdsnew
(
path
);
loadmod
->
argc
=
argc
;
loadmod
->
argc
=
argc
;
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
...
@@ -1542,6 +1542,27 @@ void rewriteConfigBindOption(struct rewriteConfigState *state) {
...
@@ -1542,6 +1542,27 @@ void rewriteConfigBindOption(struct rewriteConfigState *state) {
rewriteConfigRewriteLine
(
state
,
option
,
line
,
force
);
rewriteConfigRewriteLine
(
state
,
option
,
line
,
force
);
}
}
/* Rewrite the loadmodule option. */
void
rewriteConfigLoadmoduleOption
(
struct
rewriteConfigState
*
state
)
{
sds
line
;
dictIterator
*
di
=
dictGetIterator
(
modules
);
dictEntry
*
de
;
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
struct
RedisModule
*
module
=
dictGetVal
(
de
);
line
=
sdsnew
(
"loadmodule "
);
line
=
sdscatsds
(
line
,
module
->
loadmod
->
path
);
for
(
int
i
=
0
;
i
<
module
->
loadmod
->
argc
;
i
++
)
{
line
=
sdscatlen
(
line
,
" "
,
1
);
line
=
sdscatsds
(
line
,
module
->
loadmod
->
argv
[
i
]
->
ptr
);
}
rewriteConfigRewriteLine
(
state
,
"loadmodule"
,
line
,
1
);
}
dictReleaseIterator
(
di
);
/* Mark "loadmodule" as processed in case modules is empty. */
rewriteConfigMarkAsProcessed
(
state
,
"loadmodule"
);
}
/* Glue together the configuration lines in the current configuration
/* Glue together the configuration lines in the current configuration
* rewrite state into a single string, stripping multiple empty lines. */
* rewrite state into a single string, stripping multiple empty lines. */
sds
rewriteConfigGetContentFromState
(
struct
rewriteConfigState
*
state
)
{
sds
rewriteConfigGetContentFromState
(
struct
rewriteConfigState
*
state
)
{
...
@@ -1702,6 +1723,7 @@ int rewriteConfig(char *path, int force_all) {
...
@@ -1702,6 +1723,7 @@ int rewriteConfig(char *path, int force_all) {
rewriteConfigNotifykeyspaceeventsOption
(
state
);
rewriteConfigNotifykeyspaceeventsOption
(
state
);
rewriteConfigClientoutputbufferlimitOption
(
state
);
rewriteConfigClientoutputbufferlimitOption
(
state
);
rewriteConfigOOMScoreAdjValuesOption
(
state
);
rewriteConfigOOMScoreAdjValuesOption
(
state
);
rewriteConfigLoadmoduleOption
(
state
);
/* Rewrite Sentinel config if in Sentinel mode. */
/* Rewrite Sentinel config if in Sentinel mode. */
if
(
server
.
sentinel_mode
)
rewriteConfigSentinelOption
(
state
);
if
(
server
.
sentinel_mode
)
rewriteConfigSentinelOption
(
state
);
...
...
src/module.c
View file @
babe3c7b
...
@@ -75,28 +75,6 @@ typedef struct RedisModuleInfoCtx {
...
@@ -75,28 +75,6 @@ typedef struct RedisModuleInfoCtx {
int
in_dict_field
;
/* indication that we're currently appending to a dict */
int
in_dict_field
;
/* indication that we're currently appending to a dict */
}
RedisModuleInfoCtx
;
}
RedisModuleInfoCtx
;
typedef
void
(
*
RedisModuleInfoFunc
)(
RedisModuleInfoCtx
*
ctx
,
int
for_crash_report
);
typedef
void
(
*
RedisModuleDefragFunc
)(
struct
RedisModuleDefragCtx
*
ctx
);
/* This structure represents a module inside the system. */
struct
RedisModule
{
void
*
handle
;
/* Module dlopen() handle. */
char
*
name
;
/* Module name. */
int
ver
;
/* Module version. We use just progressive integers. */
int
apiver
;
/* Module API version as requested during initialization.*/
list
*
types
;
/* Module data types. */
list
*
usedby
;
/* List of modules using APIs from this one. */
list
*
using
;
/* List of modules we use some APIs of. */
list
*
filters
;
/* List of filters the module has registered. */
int
in_call
;
/* RM_Call() nesting level */
int
in_hook
;
/* Hooks callback nesting level for this module (0 or 1). */
int
options
;
/* Module options and capabilities. */
int
blocked_clients
;
/* Count of RedisModuleBlockedClient in this module. */
RedisModuleInfoFunc
info_cb
;
/* Callback for module to add INFO fields. */
RedisModuleDefragFunc
defrag_cb
;
/* Callback for global data defrag. */
};
typedef
struct
RedisModule
RedisModule
;
/* This represents a shared API. Shared APIs will be used to populate
/* This represents a shared API. Shared APIs will be used to populate
* the server.sharedapi dictionary, mapping names of APIs exported by
* the server.sharedapi dictionary, mapping names of APIs exported by
* modules for other modules to use, to their structure specifying the
* modules for other modules to use, to their structure specifying the
...
@@ -107,7 +85,7 @@ struct RedisModuleSharedAPI {
...
@@ -107,7 +85,7 @@ struct RedisModuleSharedAPI {
};
};
typedef
struct
RedisModuleSharedAPI
RedisModuleSharedAPI
;
typedef
struct
RedisModuleSharedAPI
RedisModuleSharedAPI
;
static
dict
*
modules
;
/* Hash table of modules. SDS -> RedisModule ptr.*/
dict
*
modules
;
/* Hash table of modules. SDS -> RedisModule ptr.*/
/* Entries in the context->amqueue array, representing objects to free
/* Entries in the context->amqueue array, representing objects to free
* when the callback returns. */
* when the callback returns. */
...
@@ -950,7 +928,7 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api
...
@@ -950,7 +928,7 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api
if
(
ctx
->
module
!=
NULL
)
return
;
if
(
ctx
->
module
!=
NULL
)
return
;
module
=
zmalloc
(
sizeof
(
*
module
));
module
=
zmalloc
(
sizeof
(
*
module
));
module
->
name
=
sdsnew
(
(
char
*
)
name
);
module
->
name
=
sdsnew
(
name
);
module
->
ver
=
ver
;
module
->
ver
=
ver
;
module
->
apiver
=
apiver
;
module
->
apiver
=
apiver
;
module
->
types
=
listCreate
();
module
->
types
=
listCreate
();
...
@@ -962,6 +940,7 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api
...
@@ -962,6 +940,7 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api
module
->
options
=
0
;
module
->
options
=
0
;
module
->
info_cb
=
0
;
module
->
info_cb
=
0
;
module
->
defrag_cb
=
0
;
module
->
defrag_cb
=
0
;
module
->
loadmod
=
NULL
;
ctx
->
module
=
module
;
ctx
->
module
=
module
;
}
}
...
@@ -8467,6 +8446,16 @@ void moduleInitModulesSystem(void) {
...
@@ -8467,6 +8446,16 @@ void moduleInitModulesSystem(void) {
pthread_mutex_lock
(
&
moduleGIL
);
pthread_mutex_lock
(
&
moduleGIL
);
}
}
void
moduleLoadQueueEntryFree
(
struct
moduleLoadQueueEntry
*
loadmod
)
{
if
(
!
loadmod
)
return
;
sdsfree
(
loadmod
->
path
);
for
(
int
i
=
0
;
i
<
loadmod
->
argc
;
i
++
)
{
decrRefCount
(
loadmod
->
argv
[
i
]);
}
zfree
(
loadmod
->
argv
);
zfree
(
loadmod
);
}
/* Load all the modules in the server.loadmodule_queue list, which is
/* Load all the modules in the server.loadmodule_queue list, which is
* populated by `loadmodule` directives in the configuration file.
* populated by `loadmodule` directives in the configuration file.
* We can't load modules directly when processing the configuration file
* We can't load modules directly when processing the configuration file
...
@@ -8491,12 +8480,7 @@ void moduleLoadFromQueue(void) {
...
@@ -8491,12 +8480,7 @@ void moduleLoadFromQueue(void) {
loadmod
->
path
);
loadmod
->
path
);
exit
(
1
);
exit
(
1
);
}
}
sdsfree
(
loadmod
->
path
);
moduleLoadQueueEntryFree
(
loadmod
);
for
(
int
i
=
0
;
i
<
loadmod
->
argc
;
i
++
)
{
decrRefCount
(
loadmod
->
argv
[
i
]);
}
zfree
(
loadmod
->
argv
);
zfree
(
loadmod
);
listDelNode
(
server
.
loadmodule_queue
,
ln
);
listDelNode
(
server
.
loadmodule_queue
,
ln
);
}
}
}
}
...
@@ -8507,6 +8491,7 @@ void moduleFreeModuleStructure(struct RedisModule *module) {
...
@@ -8507,6 +8491,7 @@ void moduleFreeModuleStructure(struct RedisModule *module) {
listRelease
(
module
->
usedby
);
listRelease
(
module
->
usedby
);
listRelease
(
module
->
using
);
listRelease
(
module
->
using
);
sdsfree
(
module
->
name
);
sdsfree
(
module
->
name
);
moduleLoadQueueEntryFree
(
module
->
loadmod
);
zfree
(
module
);
zfree
(
module
);
}
}
...
@@ -8580,6 +8565,15 @@ int moduleLoad(const char *path, void **module_argv, int module_argc) {
...
@@ -8580,6 +8565,15 @@ int moduleLoad(const char *path, void **module_argv, int module_argc) {
dictAdd
(
modules
,
ctx
.
module
->
name
,
ctx
.
module
);
dictAdd
(
modules
,
ctx
.
module
->
name
,
ctx
.
module
);
ctx
.
module
->
blocked_clients
=
0
;
ctx
.
module
->
blocked_clients
=
0
;
ctx
.
module
->
handle
=
handle
;
ctx
.
module
->
handle
=
handle
;
ctx
.
module
->
loadmod
=
zmalloc
(
sizeof
(
struct
moduleLoadQueueEntry
));
ctx
.
module
->
loadmod
->
path
=
sdsnew
(
path
);
ctx
.
module
->
loadmod
->
argv
=
module_argc
?
zmalloc
(
sizeof
(
robj
*
)
*
module_argc
)
:
NULL
;
ctx
.
module
->
loadmod
->
argc
=
module_argc
;
for
(
int
i
=
0
;
i
<
module_argc
;
i
++
)
{
ctx
.
module
->
loadmod
->
argv
[
i
]
=
module_argv
[
i
];
incrRefCount
(
ctx
.
module
->
loadmod
->
argv
[
i
]);
}
serverLog
(
LL_NOTICE
,
"Module '%s' loaded from %s"
,
ctx
.
module
->
name
,
path
);
serverLog
(
LL_NOTICE
,
"Module '%s' loaded from %s"
,
ctx
.
module
->
name
,
path
);
/* Fire the loaded modules event. */
/* Fire the loaded modules event. */
moduleFireServerEvent
(
REDISMODULE_EVENT_MODULE_CHANGE
,
moduleFireServerEvent
(
REDISMODULE_EVENT_MODULE_CHANGE
,
...
...
src/server.h
View file @
babe3c7b
...
@@ -538,8 +538,10 @@ struct RedisModule;
...
@@ -538,8 +538,10 @@ struct RedisModule;
struct
RedisModuleIO
;
struct
RedisModuleIO
;
struct
RedisModuleDigest
;
struct
RedisModuleDigest
;
struct
RedisModuleCtx
;
struct
RedisModuleCtx
;
struct
moduleLoadQueueEntry
;
struct
redisObject
;
struct
redisObject
;
struct
RedisModuleDefragCtx
;
struct
RedisModuleDefragCtx
;
struct
RedisModuleInfoCtx
;
/* Each module type implementation should export a set of methods in order
/* Each module type implementation should export a set of methods in order
* to serialize and deserialize the value in the RDB file, rewrite the AOF
* to serialize and deserialize the value in the RDB file, rewrite the AOF
...
@@ -557,6 +559,8 @@ typedef size_t (*moduleTypeFreeEffortFunc)(struct redisObject *key, const void *
...
@@ -557,6 +559,8 @@ typedef size_t (*moduleTypeFreeEffortFunc)(struct redisObject *key, const void *
typedef
void
(
*
moduleTypeUnlinkFunc
)(
struct
redisObject
*
key
,
void
*
value
);
typedef
void
(
*
moduleTypeUnlinkFunc
)(
struct
redisObject
*
key
,
void
*
value
);
typedef
void
*
(
*
moduleTypeCopyFunc
)(
struct
redisObject
*
fromkey
,
struct
redisObject
*
tokey
,
const
void
*
value
);
typedef
void
*
(
*
moduleTypeCopyFunc
)(
struct
redisObject
*
fromkey
,
struct
redisObject
*
tokey
,
const
void
*
value
);
typedef
int
(
*
moduleTypeDefragFunc
)(
struct
RedisModuleDefragCtx
*
ctx
,
struct
redisObject
*
key
,
void
**
value
);
typedef
int
(
*
moduleTypeDefragFunc
)(
struct
RedisModuleDefragCtx
*
ctx
,
struct
redisObject
*
key
,
void
**
value
);
typedef
void
(
*
RedisModuleInfoFunc
)(
struct
RedisModuleInfoCtx
*
ctx
,
int
for_crash_report
);
typedef
void
(
*
RedisModuleDefragFunc
)(
struct
RedisModuleDefragCtx
*
ctx
);
/* This callback type is called by moduleNotifyUserChanged() every time
/* This callback type is called by moduleNotifyUserChanged() every time
* a user authenticated via the module API is associated with a different
* a user authenticated via the module API is associated with a different
...
@@ -606,6 +610,26 @@ typedef struct moduleValue {
...
@@ -606,6 +610,26 @@ typedef struct moduleValue {
void
*
value
;
void
*
value
;
}
moduleValue
;
}
moduleValue
;
/* This structure represents a module inside the system. */
struct
RedisModule
{
void
*
handle
;
/* Module dlopen() handle. */
char
*
name
;
/* Module name. */
int
ver
;
/* Module version. We use just progressive integers. */
int
apiver
;
/* Module API version as requested during initialization.*/
list
*
types
;
/* Module data types. */
list
*
usedby
;
/* List of modules using APIs from this one. */
list
*
using
;
/* List of modules we use some APIs of. */
list
*
filters
;
/* List of filters the module has registered. */
int
in_call
;
/* RM_Call() nesting level */
int
in_hook
;
/* Hooks callback nesting level for this module (0 or 1). */
int
options
;
/* Module options and capabilities. */
int
blocked_clients
;
/* Count of RedisModuleBlockedClient in this module. */
RedisModuleInfoFunc
info_cb
;
/* Callback for module to add INFO fields. */
RedisModuleDefragFunc
defrag_cb
;
/* Callback for global data defrag. */
struct
moduleLoadQueueEntry
*
loadmod
;
/* Module load arguments for config rewrite. */
};
typedef
struct
RedisModule
RedisModule
;
/* This is a wrapper for the 'rio' streams used inside rdb.c in Redis, so that
/* This is a wrapper for the 'rio' streams used inside rdb.c in Redis, so that
* the user does not have to take the total count of the written bytes nor
* the user does not have to take the total count of the written bytes nor
* to care about error conditions. */
* to care about error conditions. */
...
@@ -1746,6 +1770,7 @@ extern dictType replScriptCacheDictType;
...
@@ -1746,6 +1770,7 @@ extern dictType replScriptCacheDictType;
extern
dictType
dbExpiresDictType
;
extern
dictType
dbExpiresDictType
;
extern
dictType
modulesDictType
;
extern
dictType
modulesDictType
;
extern
dictType
sdsReplyDictType
;
extern
dictType
sdsReplyDictType
;
extern
dict
*
modules
;
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
* Functions prototypes
* Functions prototypes
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment