| 2646 | /* Asynchronously read the SYNC payload we receive from a master */ |
| 2647 | #define REPL_MAX_WRITTEN_BEFORE_FSYNC (1024*1024*8) /* 8 MB */ |
| 2648 | bool readSyncBulkPayloadRdb(connection *conn, redisMaster *mi, rdbSaveInfo &rsi, int &usemark) { |
| 2649 | char buf[PROTO_IOBUF_LEN]; |
| 2650 | ssize_t nread, readlen, nwritten; |
| 2651 | int use_diskless_load = useDisklessLoad(); |
| 2652 | const dbBackup *diskless_load_backup = NULL; |
| 2653 | rsi.fForceSetKey = !!g_pserver->fActiveReplica; |
| 2654 | int empty_db_flags = g_pserver->repl_slave_lazy_flush ? EMPTYDB_ASYNC : |
| 2655 | EMPTYDB_NO_FLAGS; |
| 2656 | off_t left; |
| 2657 | // Should we update our database, or create from scratch? |
| 2658 | int fUpdate = g_pserver->fActiveReplica || g_pserver->enable_multimaster; |
| 2659 | |
| 2660 | serverAssert(GlobalLocksAcquired()); |
| 2661 | serverAssert(mi->master == nullptr); |
| 2662 | |
| 2663 | /* Static vars used to hold the EOF mark, and the last bytes received |
| 2664 | * from the server: when they match, we reached the end of the transfer. */ |
| 2665 | static char eofmark[CONFIG_RUN_ID_SIZE]; |
| 2666 | static char lastbytes[CONFIG_RUN_ID_SIZE]; |
| 2667 | |
| 2668 | /* If repl_transfer_size == -1 we still have to read the bulk length |
| 2669 | * from the master reply. */ |
| 2670 | if (mi->repl_transfer_size == -1) { |
| 2671 | if (connSyncReadLine(conn,buf,1024,g_pserver->repl_syncio_timeout*1000) == -1) { |
| 2672 | serverLog(LL_WARNING, |
| 2673 | "I/O error reading bulk count from MASTER: %s", |
| 2674 | strerror(errno)); |
| 2675 | goto error; |
| 2676 | } |
| 2677 | |
| 2678 | if (buf[0] == '-') { |
| 2679 | serverLog(LL_WARNING, |
| 2680 | "MASTER aborted replication with an error: %s", |
| 2681 | buf+1); |
| 2682 | goto error; |
| 2683 | } else if (buf[0] == '\0') { |
| 2684 | /* At this stage just a newline works as a PING in order to take |
| 2685 | * the connection live. So we refresh our last interaction |
| 2686 | * timestamp. */ |
| 2687 | mi->repl_transfer_lastio = g_pserver->unixtime; |
| 2688 | return false; |
| 2689 | } else if (buf[0] != '$') { |
| 2690 | serverLog(LL_WARNING,"Bad protocol from MASTER, the first byte is not '$' (we received '%s'), are you sure the host and port are right?", buf); |
| 2691 | goto error; |
| 2692 | } |
| 2693 | |
| 2694 | /* There are two possible forms for the bulk payload. One is the |
| 2695 | * usual $<count> bulk format. The other is used for diskless transfers |
| 2696 | * when the master does not know beforehand the size of the file to |
| 2697 | * transfer. In the latter case, the following format is used: |
| 2698 | * |
| 2699 | * $EOF:<40 bytes delimiter> |
| 2700 | * |
| 2701 | * At the end of the file the announced delimiter is transmitted. The |
| 2702 | * delimiter is long and random enough that the probability of a |
| 2703 | * collision with the actual file content can be ignored. */ |
| 2704 | if (strncmp(buf+1,"EOF:",4) == 0 && strlen(buf+5) >= CONFIG_RUN_ID_SIZE) { |
| 2705 | usemark = 1; |
no test coverage detected