Replay the append log file. On success C_OK is returned. On non fatal * error (the append only file is zero-length) C_ERR is returned. On * fatal error an error message is logged and the program exists. */
| 751 | * error (the append only file is zero-length) C_ERR is returned. On |
| 752 | * fatal error an error message is logged and the program exists. */ |
| 753 | int loadAppendOnlyFile(char *filename) { |
| 754 | struct client *fakeClient; |
| 755 | FILE *fp = fopen(filename,"r"); |
| 756 | struct redis_stat sb; |
| 757 | int old_aof_state = server.aof_state; |
| 758 | long loops = 0; |
| 759 | off_t valid_up_to = 0; /* Offset of latest well-formed command loaded. */ |
| 760 | off_t valid_before_multi = 0; /* Offset before MULTI command loaded. */ |
| 761 | |
| 762 | if (fp == NULL) { |
| 763 | serverLog(LL_WARNING,"Fatal error: can't open the append log file for reading: %s",strerror(errno)); |
| 764 | exit(1); |
| 765 | } |
| 766 | |
| 767 | /* Handle a zero-length AOF file as a special case. An empty AOF file |
| 768 | * is a valid AOF because an empty server with AOF enabled will create |
| 769 | * a zero length file at startup, that will remain like that if no write |
| 770 | * operation is received. */ |
| 771 | if (fp && redis_fstat(fileno(fp),&sb) != -1 && sb.st_size == 0) { |
| 772 | server.aof_current_size = 0; |
| 773 | server.aof_fsync_offset = server.aof_current_size; |
| 774 | fclose(fp); |
| 775 | return C_ERR; |
| 776 | } |
| 777 | |
| 778 | /* Temporarily disable AOF, to prevent EXEC from feeding a MULTI |
| 779 | * to the same file we're about to read. */ |
| 780 | server.aof_state = AOF_OFF; |
| 781 | |
| 782 | fakeClient = createAOFClient(); |
| 783 | startLoadingFile(fp, filename, RDBFLAGS_AOF_PREAMBLE); |
| 784 | |
| 785 | /* Check if this AOF file has an RDB preamble. In that case we need to |
| 786 | * load the RDB file and later continue loading the AOF tail. */ |
| 787 | char sig[5]; /* "REDIS" */ |
| 788 | if (fread(sig,1,5,fp) != 5 || memcmp(sig,"REDIS",5) != 0) { |
| 789 | /* No RDB preamble, seek back at 0 offset. */ |
| 790 | if (fseek(fp,0,SEEK_SET) == -1) goto readerr; |
| 791 | } else { |
| 792 | /* RDB preamble. Pass loading the RDB functions. */ |
| 793 | rio rdb; |
| 794 | |
| 795 | serverLog(LL_NOTICE,"Reading RDB preamble from AOF file..."); |
| 796 | if (fseek(fp,0,SEEK_SET) == -1) goto readerr; |
| 797 | rioInitWithFile(&rdb,fp); |
| 798 | if (rdbLoadRio(&rdb,RDBFLAGS_AOF_PREAMBLE,NULL) != C_OK) { |
| 799 | serverLog(LL_WARNING,"Error reading the RDB preamble of the AOF file, AOF loading aborted"); |
| 800 | goto readerr; |
| 801 | } else { |
| 802 | serverLog(LL_NOTICE,"Reading the remaining AOF tail..."); |
| 803 | } |
| 804 | } |
| 805 | |
| 806 | /* Read the actual AOF file, in REPL format, command by command. */ |
| 807 | while(1) { |
| 808 | int argc, j; |
| 809 | unsigned long len; |
| 810 | robj **argv; |
no test coverage detected