Called when the user switches from "appendonly no" to "appendonly yes" * at runtime using the CONFIG command. */
| 256 | /* Called when the user switches from "appendonly no" to "appendonly yes" |
| 257 | * at runtime using the CONFIG command. */ |
| 258 | int startAppendOnly(void) { |
| 259 | char cwd[MAXPATHLEN]; /* Current working dir path for error messages. */ |
| 260 | int newfd; |
| 261 | |
| 262 | newfd = open(server.aof_filename,O_WRONLY|O_APPEND|O_CREAT,0644); |
| 263 | serverAssert(server.aof_state == AOF_OFF); |
| 264 | if (newfd == -1) { |
| 265 | char *cwdp = getcwd(cwd,MAXPATHLEN); |
| 266 | |
| 267 | serverLog(LL_WARNING, |
| 268 | "Redis needs to enable the AOF but can't open the " |
| 269 | "append only file %s (in server root dir %s): %s", |
| 270 | server.aof_filename, |
| 271 | cwdp ? cwdp : "unknown", |
| 272 | strerror(errno)); |
| 273 | return C_ERR; |
| 274 | } |
| 275 | if (hasActiveChildProcess() && server.child_type != CHILD_TYPE_AOF) { |
| 276 | server.aof_rewrite_scheduled = 1; |
| 277 | serverLog(LL_WARNING,"AOF was enabled but there is already another background operation. An AOF background was scheduled to start when possible."); |
| 278 | } else { |
| 279 | /* If there is a pending AOF rewrite, we need to switch it off and |
| 280 | * start a new one: the old one cannot be reused because it is not |
| 281 | * accumulating the AOF buffer. */ |
| 282 | if (server.child_type == CHILD_TYPE_AOF) { |
| 283 | serverLog(LL_WARNING,"AOF was enabled but there is already an AOF rewriting in background. Stopping background AOF and starting a rewrite now."); |
| 284 | killAppendOnlyChild(); |
| 285 | } |
| 286 | if (rewriteAppendOnlyFileBackground() == C_ERR) { |
| 287 | close(newfd); |
| 288 | serverLog(LL_WARNING,"Redis needs to enable the AOF but can't trigger a background AOF rewrite operation. Check the above logs for more info about the error."); |
| 289 | return C_ERR; |
| 290 | } |
| 291 | } |
| 292 | /* We correctly switched on AOF, now wait for the rewrite to be complete |
| 293 | * in order to append data on disk. */ |
| 294 | server.aof_state = AOF_WAIT_REWRITE; |
| 295 | server.aof_last_fsync = server.unixtime; |
| 296 | server.aof_fd = newfd; |
| 297 | |
| 298 | /* If AOF fsync error in bio job, we just ignore it and log the event. */ |
| 299 | int aof_bio_fsync_status; |
| 300 | atomicGet(server.aof_bio_fsync_status, aof_bio_fsync_status); |
| 301 | if (aof_bio_fsync_status == C_ERR) { |
| 302 | serverLog(LL_WARNING, |
| 303 | "AOF reopen, just ignore the AOF fsync error in bio job"); |
| 304 | atomicSet(server.aof_bio_fsync_status,C_OK); |
| 305 | } |
| 306 | |
| 307 | /* If AOF was in error state, we just ignore it and log the event. */ |
| 308 | if (server.aof_last_write_status == C_ERR) { |
| 309 | serverLog(LL_WARNING,"AOF reopen, just ignore the last error."); |
| 310 | server.aof_last_write_status = C_OK; |
| 311 | } |
| 312 | return C_OK; |
| 313 | } |
| 314 | |
| 315 | /* This is a wrapper to the write syscall in order to retry on short writes |
no test coverage detected