// File: /workspace/github_c_makefile_star2_O1/zhou-yuxin[P]redis-aof-no-cow/src/replication.c
// Function: syncWithMaster
void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
    char tmpfile[256], *err = NULL;
    int dfd, maxtries = 5;
    int sockerr = 0, psync_result;
    socklen_t errlen = sizeof(sockerr);
    UNUSED(el);
    UNUSED(privdata);
    UNUSED(mask);

    /* If this event fired after the user turned the instance into a master
     * with SLAVEOF NO ONE we must just return ASAP. */
    if (server.repl_state == REPL_STATE_NONE) {
        close(fd);
        return;
    }

    /* Check for errors in the socket. */
    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &errlen) == -1)
        sockerr = errno;
    if (sockerr) {
        serverLog(LL_WARNING,"Error condition on socket for SYNC: %s",
            strerror(sockerr));
        goto error;
    }

    /* Send a PING to check the master is able to reply without errors. */
    if (server.repl_state == REPL_STATE_CONNECTING) {
        serverLog(LL_NOTICE,"Non blocking connect for SYNC fired the event.");
        /* Delete the writable event so that the readable event remains
         * registered and we can wait for the PONG reply. */
        aeDeleteFileEvent(server.el,fd,AE_WRITABLE);
        server.repl_state = REPL_STATE_RECEIVE_PONG;
        /* Send the PING, don't check for errors at all, we have the timeout
         * that will take care about this. */
        err = sendSynchronousCommand(SYNC_CMD_WRITE,fd,"PING",NULL);
        if (err) goto write_error;
        return;
    }

    /* Receive the PONG command. */
    if (server.repl_state == REPL_STATE_RECEIVE_PONG) {
        err = sendSynchronousCommand(SYNC_CMD_READ,fd,NULL);

        /* We accept only two replies as valid, a positive +PONG reply
         * (we just check for "+") or an authentication error.
         * Note that older versions of Redis replied with "operation not
         * permitted" instead of using a proper error code, so we test
         * both. */
        if (err[0] != '+' &&
            strncmp(err,"-NOAUTH",7) != 0 &&
            strncmp(err,"-ERR operation not permitted",28) != 0)
        {
            serverLog(LL_WARNING,"Error reply to PING from master: '%s'",err);
            sdsfree(err);
            goto error;
        } else {
            serverLog(LL_NOTICE,
                "Master replied to PING, replication can continue...");
        }
        sdsfree(err);
        server.repl_state = REPL_STATE_SEND_AUTH;
    }

    /* AUTH with the master if required. */
    if (server.repl_state == REPL_STATE_SEND_AUTH) {
        if (server.masterauth) {
            err = sendSynchronousCommand(SYNC_CMD_WRITE,fd,"AUTH",server.masterauth,NULL);
            if (err) goto write_error;
            server.repl_state = REPL_STATE_RECEIVE_AUTH;
            return;
        } else {
            server.repl_state = REPL_STATE_SEND_PORT;
        }
    }

    /* Receive AUTH reply. */
    if (server.repl_state == REPL_STATE_RECEIVE_AUTH) {
        err = sendSynchronousCommand(SYNC_CMD_READ,fd,NULL);
        if (err[0] == '-') {
            serverLog(LL_WARNING,"Unable to AUTH to MASTER: %s",err);
            sdsfree(err);
            goto error;
        }
        sdsfree(err);
        server.repl_state = REPL_STATE_SEND_PORT;
    }

    /* Set the slave port, so that Master's INFO command can list the
     * slave listening port correctly. */
    if (server.repl_state == REPL_STATE_SEND_PORT) {
        sds port = sdsfromlonglong(server.slave_announce_port ?
            server.slave_announce_port : server.port);
        err = sendSynchronousCommand(SYNC_CMD_WRITE,fd,"REPLCONF",
                "listening-port",port, NULL);
        sdsfree(port);
        if (err) goto write_error;
        sdsfree(err);
        server.repl_state = REPL_STATE_RECEIVE_PORT;
        return;
    }

    /* Receive REPLCONF listening-port reply. */
    if (server.repl_state == REPL_STATE_RECEIVE_PORT) {
        err = sendSynchronousCommand(SYNC_CMD_READ,fd,NULL);
        /* Ignore the error if any, not all the Redis versions support
         * REPLCONF listening-port. */
        if (err[0] == '-') {
            serverLog(LL_NOTICE,"(Non critical) Master does not understand "
                                "REPLCONF listening-port: %s", err);
        }
        sdsfree(err);
        server.repl_state = REPL_STATE_SEND_IP;
    }

    /* Skip REPLCONF ip-address if there is no slave-announce-ip option set. */
    if (server.repl_state == REPL_STATE_SEND_IP &&
        server.slave_announce_ip == NULL)
    {
            server.repl_state = REPL_STATE_SEND_CAPA;
    }

    /* Set the slave ip, so that Master's INFO command can list the
     * slave IP address port correctly in case of port forwarding or NAT. */
    if (server.repl_state == REPL_STATE_SEND_IP) {
        err = sendSynchronousCommand(SYNC_CMD_WRITE,fd,"REPLCONF",
                "ip-address",server.slave_announce_ip, NULL);
        if (err) goto write_error;
        sdsfree(err);
        server.repl_state = REPL_STATE_RECEIVE_IP;
        return;
    }

    /* Receive REPLCONF ip-address reply. */
    if (server.repl_state == REPL_STATE_RECEIVE_IP) {
        err = sendSynchronousCommand(SYNC_CMD_READ,fd,NULL);
        /* Ignore the error if any, not all the Redis versions support
         * REPLCONF listening-port. */
        if (err[0] == '-') {
            serverLog(LL_NOTICE,"(Non critical) Master does not understand "
                                "REPLCONF ip-address: %s", err);
        }
        sdsfree(err);
        server.repl_state = REPL_STATE_SEND_CAPA;
    }

    /* Inform the master of our capabilities. While we currently send
     * just one capability, it is possible to chain new capabilities here
     * in the form of REPLCONF capa X capa Y capa Z ...
     * The master will ignore capabilities it does not understand. */
    if (server.repl_state == REPL_STATE_SEND_CAPA) {
        err = sendSynchronousCommand(SYNC_CMD_WRITE,fd,"REPLCONF",
                "capa","eof",NULL);
        if (err) goto write_error;
        sdsfree(err);
        server.repl_state = REPL_STATE_RECEIVE_CAPA;
        return;
    }

    /* Receive CAPA reply. */
    if (server.repl_state == REPL_STATE_RECEIVE_CAPA) {
        err = sendSynchronousCommand(SYNC_CMD_READ,fd,NULL);
        /* Ignore the error if any, not all the Redis versions support
         * REPLCONF capa. */
        if (err[0] == '-') {
            serverLog(LL_NOTICE,"(Non critical) Master does not understand "
                                  "REPLCONF capa: %s", err);
        }
        sdsfree(err);
        server.repl_state = REPL_STATE_SEND_PSYNC;
    }

    /* Try a partial resynchonization. If we don't have a cached master
     * slaveTryPartialResynchronization() will at least try to use PSYNC
     * to start a full resynchronization so that we get the master run id
     * and the global offset, to try a partial resync at the next
     * reconnection attempt. */
    if (server.repl_state == REPL_STATE_SEND_PSYNC) {
        if (slaveTryPartialResynchronization(fd,0) == PSYNC_WRITE_ERROR) {
            err = sdsnew("Write error sending the PSYNC command.");
            goto write_error;
        }
        server.repl_state = REPL_STATE_RECEIVE_PSYNC;
        return;
    }

    /* If reached this point, we should be in REPL_STATE_RECEIVE_PSYNC. */
    if (server.repl_state != REPL_STATE_RECEIVE_PSYNC) {
        serverLog(LL_WARNING,"syncWithMaster(): state machine error, "
                             "state should be RECEIVE_PSYNC but is %d",
                             server.repl_state);
        goto error;
    }

    psync_result = slaveTryPartialResynchronization(fd,1);
    if (psync_result == PSYNC_WAIT_REPLY) return; /* Try again later... */

    /* Note: if PSYNC does not return WAIT_REPLY, it will take care of
     * uninstalling the read handler from the file descriptor. */

    if (psync_result == PSYNC_CONTINUE) {
        serverLog(LL_NOTICE, "MASTER <-> SLAVE sync: Master accepted a Partial Resynchronization.");
        return;
    }

    /* PSYNC failed or is not supported: we want our slaves to resync with us
     * as well, if we have any (chained replication case). The mater may
     * transfer us an entirely different data set and we have no way to
     * incrementally feed our slaves after that. */
    disconnectSlaves(); /* Force our slaves to resync with us as well. */
    freeReplicationBacklog(); /* Don't allow our chained slaves to PSYNC. */

    /* Fall back to SYNC if needed. Otherwise psync_result == PSYNC_FULLRESYNC
     * and the server.repl_master_runid and repl_master_initial_offset are
     * already populated. */
    if (psync_result == PSYNC_NOT_SUPPORTED) {
        serverLog(LL_NOTICE,"Retrying with SYNC...");
        if (syncWrite(fd,"SYNC\r\n",6,server.repl_syncio_timeout*1000) == -1) {
            serverLog(LL_WARNING,"I/O error writing to MASTER: %s",
                strerror(errno));
            goto error;
        }
    }

    /* Prepare a suitable temp file for bulk transfer */
    while(maxtries--) {
        snprintf(tmpfile,256,
            "temp-%d.%ld.rdb",(int)server.unixtime,(long int)getpid());
        dfd = open(tmpfile,O_CREAT|O_WRONLY|O_EXCL,0644);
        if (dfd != -1) break;
        sleep(1);
    }
    if (dfd == -1) {
        serverLog(LL_WARNING,"Opening the temp file needed for MASTER <-> SLAVE synchronization: %s",strerror(errno));
        goto error;
    }

    /* Setup the non blocking download of the bulk file. */
    if (aeCreateFileEvent(server.el,fd, AE_READABLE,readSyncBulkPayload,NULL)
            == AE_ERR)
    {
        serverLog(LL_WARNING,
            "Can't create readable event for SYNC: %s (fd=%d)",
            strerror(errno),fd);
        goto error;
    }

    server.repl_state = REPL_STATE_TRANSFER;
    server.repl_transfer_size = -1;
    server.repl_transfer_read = 0;
    server.repl_transfer_last_fsync_off = 0;
    server.repl_transfer_fd = dfd;
    server.repl_transfer_lastio = server.unixtime;
    server.repl_transfer_tmpfile = zstrdup(tmpfile);
    return;

error:
    aeDeleteFileEvent(server.el,fd,AE_READABLE|AE_WRITABLE);
    close(fd);
    server.repl_transfer_s = -1;
    server.repl_state = REPL_STATE_CONNECT;
    return;

write_error: /* Handle sendSynchronousCommand(SYNC_CMD_WRITE) errors. */
    serverLog(LL_WARNING,"Sending command to master in replication handshake: %s", err);
    sdsfree(err);
    goto error;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movl %esi, %ebx
movl $0x0, 0x8(%rsp)
movl $0x4, 0xc(%rsp)
leaq 0xbd188(%rip), %r12     # 0x106858
cmpl $0x0, 0x83c(%r12)
je 0x4972e
leaq 0x8(%rsp), %rcx
leaq 0xc(%rsp), %r8
movl %ebx, %edi
movl $0x1, %esi
movl $0x4, %edx
callq 0x26710
cmpl $-0x1, %eax
jne 0x49706
callq 0x26890
movl (%rax), %eax
movl %eax, 0x8(%rsp)
movl 0x8(%rsp), %edi
testl %edi, %edi
je 0x49746
callq 0x26690
leaq 0x7b86d(%rip), %rsi     # 0xc4f87
movl $0x3, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0x32ea6
jmp 0x49b95
movl %ebx, %edi
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x26180
movl 0x83c(%r12), %eax
cmpl $0x3, %eax
je 0x497b1
cmpl $0x2, %eax
jne 0x4982c
leaq 0x7b84b(%rip), %rsi     # 0xc4fae
movl $0x2, %edi
xorl %eax, %eax
callq 0x32ea6
movq 0x40(%r12), %rdi
movl %ebx, %esi
movl $0x2, %edx
callq 0x2ffb6
movl $0x3, 0x83c(%r12)
leaq 0x7b84a(%rip), %rdx     # 0xc4fdd
movl $0x2, %edi
movl %ebx, %esi
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x48f8d
testq %rax, %rax
jne 0x49b74
jmp 0x49bc5
movl $0x1, %edi
movl %ebx, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x48f8d
movq %rax, %r14
cmpb $0x2b, (%rax)
je 0x49805
leaq 0x7b812(%rip), %rsi     # 0xc4fe2
movl $0x7, %edx
movq %r14, %rdi
callq 0x26360
testl %eax, %eax
je 0x49805
leaq 0x7b802(%rip), %rsi     # 0xc4fea
movl $0x1c, %edx
movq %r14, %rdi
callq 0x26360
testl %eax, %eax
je 0x49805
leaq 0x7b807(%rip), %rsi     # 0xc5007
jmp 0x49b7e
leaq 0x7b821(%rip), %rsi     # 0xc502d
movl $0x2, %edi
xorl %eax, %eax
callq 0x32ea6
movq %r14, %rdi
callq 0x392b6
movl $0x4, 0x83c(%r12)
cmpl $0x4, 0x83c(%r12)
jne 0x49882
movq 0x810(%r12), %rcx
testq %rcx, %rcx
je 0x49876
leaq 0x7b79a(%rip), %rdx     # 0xc4fe5
movl $0x2, %edi
movl %ebx, %esi
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x48f8d
testq %rax, %rax
jne 0x49b74
movl $0x5, 0x83c(%r12)
jmp 0x49bc5
movl $0x6, 0x83c(%r12)
cmpl $0x5, 0x83c(%r12)
jne 0x498c5
movl $0x1, %edi
movl %ebx, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x48f8d
movq %rax, %r14
cmpb $0x2d, (%rax)
jne 0x498b1
leaq 0x7b7b5(%rip), %rsi     # 0xc5061
jmp 0x49b7e
movq %r14, %rdi
callq 0x392b6
movl $0x6, 0x83c(%r12)
movl 0x83c(%r12), %eax
cmpl $0x7, %eax
je 0x49948
cmpl $0x6, %eax
jne 0x4998a
movl 0x888(%r12), %eax
testl %eax, %eax
jne 0x498ef
movl 0xa0(%r12), %eax
movslq %eax, %rdi
callq 0x39da4
movq %rax, %r15
leaq 0x76278(%rip), %rdx     # 0xbfb79
leaq 0x7ae56(%rip), %rcx     # 0xc475e
movl $0x2, %edi
movl %ebx, %esi
movq %rax, %r8
xorl %r9d, %r9d
xorl %eax, %eax
callq 0x48f8d
movq %rax, %r14
movq %r15, %rdi
callq 0x392b6
testq %r14, %r14
jne 0x49b77
xorl %edi, %edi
callq 0x392b6
movl $0x7, 0x83c(%r12)
jmp 0x49bc5
movl $0x1, %edi
movl %ebx, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x48f8d
movq %rax, %r14
cmpb $0x2d, (%rax)
jne 0x49976
leaq 0x7b717(%rip), %rsi     # 0xc507e
movl $0x2, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x32ea6
movq %r14, %rdi
callq 0x392b6
movl $0x8, 0x83c(%r12)
cmpl $0x8, 0x83c(%r12)
sete %al
movq 0x890(%r12), %r8
testq %r8, %r8
sete %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x499b7
movl $0xa, 0x83c(%r12)
movl 0x83c(%r12), %eax
cmpl $0x9, %eax
je 0x49a0d
cmpl $0x8, %eax
jne 0x49a4f
leaq 0x761a5(%rip), %rdx     # 0xbfb79
leaq 0x7ad92(%rip), %rcx     # 0xc476d
movl $0x2, %edi
movl %ebx, %esi
xorl %r9d, %r9d
xorl %eax, %eax
callq 0x48f8d
testq %rax, %rax
jne 0x49b74
xorl %edi, %edi
callq 0x392b6
movl $0x9, 0x83c(%r12)
jmp 0x49bc5
movl $0x1, %edi
movl %ebx, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x48f8d
movq %rax, %r14
cmpb $0x2d, (%rax)
jne 0x49a3b
leaq 0x7b698(%rip), %rsi     # 0xc50c4
movl $0x2, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x32ea6
movq %r14, %rdi
callq 0x392b6
movl $0xa, 0x83c(%r12)
movl 0x83c(%r12), %eax
cmpl $0xb, %eax
je 0x49aac
cmpl $0xa, %eax
jne 0x49aee
leaq 0x7610d(%rip), %rdx     # 0xbfb79
leaq 0x7ad4b(%rip), %rcx     # 0xc47be
leaq 0x75ddb(%rip), %r8      # 0xbf855
movl $0x2, %edi
movl %ebx, %esi
xorl %r9d, %r9d
xorl %eax, %eax
callq 0x48f8d
testq %rax, %rax
jne 0x49b74
xorl %edi, %edi
callq 0x392b6
movl $0xb, 0x83c(%r12)
jmp 0x49bc5
movl $0x1, %edi
movl %ebx, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x48f8d
movq %rax, %r14
cmpb $0x2d, (%rax)
jne 0x49ada
leaq 0x7b63b(%rip), %rsi     # 0xc5106
movl $0x2, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x32ea6
movq %r14, %rdi
callq 0x392b6
movl $0xc, 0x83c(%r12)
movl 0x83c(%r12), %edx
cmpl $0xd, %edx
je 0x49b1e
cmpl $0xc, %edx
jne 0x49b53
movl %ebx, %edi
xorl %esi, %esi
callq 0x4920c
testl %eax, %eax
je 0x49b68
movl $0xd, 0x83c(%r12)
jmp 0x49bc5
movl %ebx, %edi
movl $0x1, %esi
callq 0x4920c
cmpl $0x1, %eax
je 0x49bc5
movl %eax, %ebp
cmpl $0x2, %eax
jne 0x49bd7
leaq 0x7b673(%rip), %rsi     # 0xc51b8
movl $0x2, %edi
xorl %eax, %eax
callq 0x32ea6
jmp 0x49bc5
leaq 0x7b60f(%rip), %rsi     # 0xc5169
movl $0x3, %edi
xorl %eax, %eax
callq 0x32ea6
jmp 0x49b95
leaq 0x7b5d3(%rip), %rdi     # 0xc5142
callq 0x39245
movq %rax, %r14
leaq 0x7b742(%rip), %rsi     # 0xc52c0
movl $0x3, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x32ea6
movq %r14, %rdi
callq 0x392b6
movq 0x40(%r12), %rdi
movl %ebx, %esi
movl $0x3, %edx
callq 0x2ffb6
movl %ebx, %edi
callq 0x26180
movl $0xffffffff, 0x858(%r12) # imm = 0xFFFFFFFF
movl $0x1, 0x83c(%r12)
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x40ade
callq 0x4720a
cmpl $0x4, %ebp
jne 0x49c25
leaq 0x7b60f(%rip), %rsi     # 0xc51fc
movl $0x2, %edi
xorl %eax, %eax
callq 0x32ea6
movslq 0x838(%r12), %rax
imulq $0x3e8, %rax, %rcx      # imm = 0x3E8
leaq 0x7b603(%rip), %rsi     # 0xc5212
movl $0x6, %edx
movl %ebx, %edi
callq 0x68a80
cmpq $-0x1, %rax
je 0x49d45
movl $0xfffffffb, %r13d      # imm = 0xFFFFFFFB
leaq 0x7b607(%rip), %r14     # 0xc5239
leaq 0x10(%rsp), %r15
movl 0x968(%r12), %ebp
callq 0x26430
movslq %eax, %r8
movl $0x100, %esi            # imm = 0x100
movq %r15, %rdi
movq %r14, %rdx
movl %ebp, %ecx
xorl %eax, %eax
callq 0x26120
movq %r15, %rdi
movl $0xc1, %esi
movl $0x1a4, %edx            # imm = 0x1A4
xorl %eax, %eax
callq 0x266a0
cmpl $-0x1, %eax
jne 0x49c8a
movl $0x1, %edi
callq 0x26600
incl %r13d
jne 0x49c37
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
jmp 0x49c8c
movl %eax, %ebp
cmpl $-0x1, %ebp
je 0x49d04
movq 0x40(%r12), %rdi
leaq -0x129d(%rip), %rcx     # 0x48a00
movl %ebx, %esi
movl $0x1, %edx
xorl %r8d, %r8d
callq 0x2fee7
cmpl $-0x1, %eax
je 0x49d1c
movl $0xe, 0x83c(%r12)
movq $-0x1, 0x840(%r12)
xorps %xmm0, %xmm0
movups %xmm0, 0x848(%r12)
movl %ebp, 0x85c(%r12)
movq 0x968(%r12), %rax
movq %rax, 0x868(%r12)
leaq 0x10(%rsp), %rdi
callq 0x3b419
movq %rax, 0x860(%r12)
jmp 0x49bc5
callq 0x26890
movl (%rax), %edi
callq 0x26690
leaq 0x7b532(%rip), %rsi     # 0xc5249
jmp 0x4971a
callq 0x26890
movl (%rax), %edi
callq 0x26690
leaq 0x7b560(%rip), %rsi     # 0xc528f
movl $0x3, %edi
movq %rax, %rdx
movl %ebx, %ecx
xorl %eax, %eax
callq 0x32ea6
jmp 0x49b95
callq 0x26890
movl (%rax), %edi
callq 0x26690
leaq 0x7b4c1(%rip), %rsi     # 0xc5219
jmp 0x4971a