| 327 | } |
| 328 | |
| 329 | static void *save_snapshot(void* arg) { |
| 330 | SnapshotArg* sa = (SnapshotArg*) arg; |
| 331 | std::unique_ptr<SnapshotArg> arg_guard(sa); |
| 332 | // Serialize StateMachine to the snapshot |
| 333 | brpc::ClosureGuard done_guard(sa->done); |
| 334 | std::string snapshot_path = sa->writer->get_path() + "/data"; |
| 335 | // Sync buffered data before |
| 336 | int rc = 0; |
| 337 | LOG(INFO) << "Saving snapshot to " << snapshot_path; |
| 338 | for (; (rc = ::fdatasync(sa->fd->fd())) < 0 && errno == EINTR;) {} |
| 339 | if (rc < 0) { |
| 340 | sa->done->status().set_error(EIO, "Fail to sync fd=%d : %m", |
| 341 | sa->fd->fd()); |
| 342 | return NULL; |
| 343 | } |
| 344 | std::string data_path = FLAGS_data_path + "/data"; |
| 345 | if (link_overwrite(data_path.c_str(), snapshot_path.c_str()) != 0) { |
| 346 | sa->done->status().set_error(EIO, "Fail to link data : %m"); |
| 347 | return NULL; |
| 348 | } |
| 349 | |
| 350 | // Snapshot is a set of files in raft. Add the only file into the |
| 351 | // writer here. |
| 352 | if (sa->writer->add_file("data") != 0) { |
| 353 | sa->done->status().set_error(EIO, "Fail to add file to writer"); |
| 354 | return NULL; |
| 355 | } |
| 356 | return NULL; |
| 357 | } |
| 358 | |
| 359 | void on_snapshot_save(braft::SnapshotWriter* writer, braft::Closure* done) { |
| 360 | // Save current StateMachine in memory and starts a new bthread to avoid |