Set replication to the specified master address and port. */
| 3920 | |
| 3921 | /* Set replication to the specified master address and port. */ |
| 3922 | struct redisMaster *replicationAddMaster(char *ip, int port) { |
| 3923 | // pre-reqs: We must not already have a replica in the list with the same tuple |
| 3924 | listIter li; |
| 3925 | listNode *ln; |
| 3926 | listRewind(g_pserver->masters, &li); |
| 3927 | while ((ln = listNext(&li))) |
| 3928 | { |
| 3929 | redisMaster *miCheck = (redisMaster*)listNodeValue(ln); |
| 3930 | if (strcasecmp(miCheck->masterhost, ip)==0 && miCheck->masterport == port) |
| 3931 | return nullptr; |
| 3932 | } |
| 3933 | |
| 3934 | // Pre-req satisfied, lets continue |
| 3935 | int was_master = listLength(g_pserver->masters) == 0; |
| 3936 | redisMaster *mi = nullptr; |
| 3937 | if (!g_pserver->enable_multimaster && listLength(g_pserver->masters)) { |
| 3938 | serverAssert(listLength(g_pserver->masters) == 1); |
| 3939 | mi = (redisMaster*)listNodeValue(listFirst(g_pserver->masters)); |
| 3940 | } |
| 3941 | else |
| 3942 | { |
| 3943 | mi = (redisMaster*)zcalloc(sizeof(redisMaster), MALLOC_LOCAL); |
| 3944 | initMasterInfo(mi); |
| 3945 | listAddNodeTail(g_pserver->masters, mi); |
| 3946 | } |
| 3947 | |
| 3948 | sdsfree(mi->masterhost); |
| 3949 | mi->masterhost = nullptr; |
| 3950 | disconnectMaster(mi); |
| 3951 | serverAssert(mi->master == nullptr); |
| 3952 | if (!g_pserver->fActiveReplica) |
| 3953 | disconnectAllBlockedClients(); /* Clients blocked in master, now replica. */ |
| 3954 | |
| 3955 | /* Setting masterhost only after the call to freeClient since it calls |
| 3956 | * replicationHandleMasterDisconnection which can trigger a re-connect |
| 3957 | * directly from within that call. */ |
| 3958 | mi->masterhost = sdsnew(ip); |
| 3959 | mi->masterport = port; |
| 3960 | |
| 3961 | /* Update oom_score_adj */ |
| 3962 | setOOMScoreAdj(-1); |
| 3963 | |
| 3964 | /* Force our slaves to resync with us as well. They may hopefully be able |
| 3965 | * to partially resync with us, but we can notify the replid change. */ |
| 3966 | if (!g_pserver->fActiveReplica) |
| 3967 | disconnectSlaves(); |
| 3968 | cancelReplicationHandshake(mi,false); |
| 3969 | /* Before destroying our master state, create a cached master using |
| 3970 | * our own parameters, to later PSYNC with the new master. */ |
| 3971 | if (was_master) { |
| 3972 | replicationDiscardCachedMaster(mi); |
| 3973 | replicationCacheMasterUsingMyself(mi); |
| 3974 | } |
| 3975 | |
| 3976 | /* Fire the role change modules event. */ |
| 3977 | moduleFireServerEvent(REDISMODULE_EVENT_REPLICATION_ROLE_CHANGED, |
| 3978 | REDISMODULE_EVENT_REPLROLECHANGED_NOW_REPLICA, |
| 3979 | NULL); |
no test coverage detected