NOTE: We provide atomic (all-or-nothing) semantics here by always writing to a temporary file to the staging directory first then using `os::rename` to atomically move it to the desired path.
| 429 | // writing to a temporary file to the staging directory first then using |
| 430 | // `os::rename` to atomically move it to the desired path. |
| 431 | Try<Nothing> LocalResourceProviderDaemonProcess::save( |
| 432 | const string& path, |
| 433 | const ResourceProviderInfo& info) |
| 434 | { |
| 435 | CHECK_SOME(configDir); |
| 436 | |
| 437 | // NOTE: We create the staging directory in the resource provider |
| 438 | // config directory to make sure that the renaming below does not |
| 439 | // cross devices (MESOS-2319). |
| 440 | // TODO(chhsiao): Consider adding a way to garbage collect the staging |
| 441 | // directory. |
| 442 | const string stagingDir = path::join(configDir.get(), STAGING_DIR); |
| 443 | Try<Nothing> mkdir = os::mkdir(stagingDir); |
| 444 | if (mkdir.isError()) { |
| 445 | return Error( |
| 446 | "Failed to create directory '" + stagingDir + "': " + mkdir.error()); |
| 447 | } |
| 448 | |
| 449 | const string stagingPath = path::join(stagingDir, Path(path).basename()); |
| 450 | |
| 451 | Try<Nothing> write = os::write(stagingPath, stringify(JSON::protobuf(info))); |
| 452 | if (write.isError()) { |
| 453 | // Try to remove the temporary file on error. |
| 454 | os::rm(stagingPath); |
| 455 | |
| 456 | return Error( |
| 457 | "Failed to write temporary file '" + stagingPath + "': " + |
| 458 | write.error()); |
| 459 | } |
| 460 | |
| 461 | Try<Nothing> rename = os::rename(stagingPath, path); |
| 462 | if (rename.isError()) { |
| 463 | // Try to remove the temporary file on error. |
| 464 | os::rm(stagingPath); |
| 465 | |
| 466 | return Error( |
| 467 | "Failed to rename '" + stagingPath + "' to '" + path + "': " + |
| 468 | rename.error()); |
| 469 | } |
| 470 | |
| 471 | return Nothing(); |
| 472 | } |
| 473 | |
| 474 | |
| 475 | Future<Nothing> LocalResourceProviderDaemonProcess::launch( |
nothing calls this directly
no test coverage detected