summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSalvatore Sanfilippo <antirez@gmail.com>2017-11-24 09:37:06 +0100
committerGitHub <noreply@github.com>2017-11-24 09:37:06 +0100
commitf739c27229b4b20d809e5453864748f2bd2c4d5e (patch)
treed3b7889623c0b3deff36464f82836555ef564c7d
parent58ac57f6651c1b3c8223cf04fe86a2c51aef1bc7 (diff)
parent6dffc1b7a33f1fd4fa1ff0368933ed575bca5606 (diff)
downloadredis-f739c27229b4b20d809e5453864748f2bd2c4d5e.tar.gz
Merge pull request #4344 from soloestoy/fix-module-name-conflict
Fix module name conflict
-rw-r--r--src/module.c65
-rw-r--r--src/redismodule.h5
2 files changed, 47 insertions, 23 deletions
diff --git a/src/module.c b/src/module.c
index 83249554e..7f9402ecf 100644
--- a/src/module.c
+++ b/src/module.c
@@ -613,7 +613,7 @@ int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc c
sds cmdname = sdsnew(name);
/* Check if the command name is busy. */
- if (lookupCommand((char*)name) != NULL) {
+ if (lookupCommand(cmdname) != NULL) {
sdsfree(cmdname);
return REDISMODULE_ERR;
}
@@ -648,7 +648,7 @@ int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc c
*
* This is an internal function, Redis modules developers don't need
* to use it. */
-void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int apiver){
+void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int apiver) {
RedisModule *module;
if (ctx->module != NULL) return;
@@ -660,6 +660,19 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api
ctx->module = module;
}
+/* Return non-zero if the module name is busy.
+ * Otherwise zero is returned. */
+int RM_IsModuleNameBusy(const char *name) {
+ sds modulename = sdsnew(name);
+
+ /* Check if the module name is busy. */
+ if (dictFind(modules,modulename) != NULL) {
+ sdsfree(modulename);
+ return 1;
+ }
+ return 0;
+}
+
/* Return the current UNIX time in milliseconds. */
long long RM_Milliseconds(void) {
return mstime();
@@ -3736,6 +3749,28 @@ void moduleFreeModuleStructure(struct RedisModule *module) {
zfree(module);
}
+void moduleUnregisterCommands(struct RedisModule *module) {
+ /* Unregister all the commands registered by this module. */
+ dictIterator *di = dictGetSafeIterator(server.commands);
+ dictEntry *de;
+ while ((de = dictNext(di)) != NULL) {
+ struct redisCommand *cmd = dictGetVal(de);
+ if (cmd->proc == RedisModuleCommandDispatcher) {
+ RedisModuleCommandProxy *cp =
+ (void*)(unsigned long)cmd->getkeys_proc;
+ sds cmdname = cp->rediscmd->name;
+ if (cp->module == module) {
+ dictDelete(server.commands,cmdname);
+ dictDelete(server.orig_commands,cmdname);
+ sdsfree(cmdname);
+ zfree(cp->rediscmd);
+ zfree(cp);
+ }
+ }
+ }
+ dictReleaseIterator(di);
+}
+
/* Load a module and initialize it. On success C_OK is returned, otherwise
* C_ERR is returned. */
int moduleLoad(const char *path, void **module_argv, int module_argc) {
@@ -3756,7 +3791,10 @@ int moduleLoad(const char *path, void **module_argv, int module_argc) {
return C_ERR;
}
if (onload((void*)&ctx,module_argv,module_argc) == REDISMODULE_ERR) {
- if (ctx.module) moduleFreeModuleStructure(ctx.module);
+ if (ctx.module) {
+ moduleUnregisterCommands(ctx.module);
+ moduleFreeModuleStructure(ctx.module);
+ }
dlclose(handle);
serverLog(LL_WARNING,
"Module %s initialization failed. Module not loaded",path);
@@ -3790,25 +3828,7 @@ int moduleUnload(sds name) {
return REDISMODULE_ERR;
}
- /* Unregister all the commands registered by this module. */
- dictIterator *di = dictGetSafeIterator(server.commands);
- dictEntry *de;
- while ((de = dictNext(di)) != NULL) {
- struct redisCommand *cmd = dictGetVal(de);
- if (cmd->proc == RedisModuleCommandDispatcher) {
- RedisModuleCommandProxy *cp =
- (void*)(unsigned long)cmd->getkeys_proc;
- sds cmdname = cp->rediscmd->name;
- if (cp->module == module) {
- dictDelete(server.commands,cmdname);
- dictDelete(server.orig_commands,cmdname);
- sdsfree(cmdname);
- zfree(cp->rediscmd);
- zfree(cp);
- }
- }
- }
- dictReleaseIterator(di);
+ moduleUnregisterCommands(module);
/* Unregister all the hooks. TODO: Yet no hooks support here. */
@@ -3903,6 +3923,7 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API(Strdup);
REGISTER_API(CreateCommand);
REGISTER_API(SetModuleAttribs);
+ REGISTER_API(IsModuleNameBusy);
REGISTER_API(WrongArity);
REGISTER_API(ReplyWithLongLong);
REGISTER_API(ReplyWithError);
diff --git a/src/redismodule.h b/src/redismodule.h
index 8df203aba..672951f78 100644
--- a/src/redismodule.h
+++ b/src/redismodule.h
@@ -143,7 +143,8 @@ void *REDISMODULE_API_FUNC(RedisModule_Calloc)(size_t nmemb, size_t size);
char *REDISMODULE_API_FUNC(RedisModule_Strdup)(const char *str);
int REDISMODULE_API_FUNC(RedisModule_GetApi)(const char *, void *);
int REDISMODULE_API_FUNC(RedisModule_CreateCommand)(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep);
-int REDISMODULE_API_FUNC(RedisModule_SetModuleAttribs)(RedisModuleCtx *ctx, const char *name, int ver, int apiver);
+void REDISMODULE_API_FUNC(RedisModule_SetModuleAttribs)(RedisModuleCtx *ctx, const char *name, int ver, int apiver);
+int REDISMODULE_API_FUNC(RedisModule_IsModuleNameBusy)(const char *name);
int REDISMODULE_API_FUNC(RedisModule_WrongArity)(RedisModuleCtx *ctx);
int REDISMODULE_API_FUNC(RedisModule_ReplyWithLongLong)(RedisModuleCtx *ctx, long long ll);
int REDISMODULE_API_FUNC(RedisModule_GetSelectedDb)(RedisModuleCtx *ctx);
@@ -263,6 +264,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
REDISMODULE_GET_API(Strdup);
REDISMODULE_GET_API(CreateCommand);
REDISMODULE_GET_API(SetModuleAttribs);
+ REDISMODULE_GET_API(IsModuleNameBusy);
REDISMODULE_GET_API(WrongArity);
REDISMODULE_GET_API(ReplyWithLongLong);
REDISMODULE_GET_API(ReplyWithError);
@@ -370,6 +372,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
REDISMODULE_GET_API(AbortBlock);
#endif
+ if (RedisModule_IsModuleNameBusy(name)) return REDISMODULE_ERR;
RedisModule_SetModuleAttribs(ctx,name,ver,apiver);
return REDISMODULE_OK;
}