| 459 | |
| 460 | |
| 461 | Try<Nothing> DockerContainerizerProcess::updatePersistentVolumes( |
| 462 | const ContainerID& containerId, |
| 463 | const string& directory, |
| 464 | const Resources& current, |
| 465 | const Resources& updated) |
| 466 | { |
| 467 | // Docker Containerizer currently is only expected to run on Linux. |
| 468 | #ifdef __linux__ |
| 469 | // Unmount all persistent volumes that are no longer present. |
| 470 | foreach (const Resource& resource, current.persistentVolumes()) { |
| 471 | // This is enforced by the master. |
| 472 | CHECK(resource.disk().has_volume()); |
| 473 | |
| 474 | // Ignore absolute and nested paths. |
| 475 | const string& containerPath = resource.disk().volume().container_path(); |
| 476 | if (strings::contains(containerPath, "/")) { |
| 477 | LOG(WARNING) << "Skipping updating mount for persistent volume " |
| 478 | << resource << " of container " << containerId |
| 479 | << " because the container path '" << containerPath |
| 480 | << "' contains slash"; |
| 481 | continue; |
| 482 | } |
| 483 | |
| 484 | if (updated.contains(resource)) { |
| 485 | continue; |
| 486 | } |
| 487 | |
| 488 | const string target = path::join( |
| 489 | directory, resource.disk().volume().container_path()); |
| 490 | |
| 491 | Try<Nothing> unmount = fs::unmount(target); |
| 492 | if (unmount.isError()) { |
| 493 | return Error("Failed to unmount persistent volume at '" + target + |
| 494 | "': " + unmount.error()); |
| 495 | } |
| 496 | |
| 497 | // TODO(tnachen): Remove mount point after unmounting. This requires |
| 498 | // making sure the work directory is marked as a shared mount. For |
| 499 | // more details please refer to MESOS-3483. |
| 500 | } |
| 501 | |
| 502 | // Get user and group info for this task based on the sandbox directory. |
| 503 | struct stat s; |
| 504 | if (::stat(directory.c_str(), &s) < 0) { |
| 505 | return Error("Failed to get ownership for '" + directory + "': " + |
| 506 | os::strerror(errno)); |
| 507 | } |
| 508 | |
| 509 | const uid_t uid = s.st_uid; |
| 510 | const gid_t gid = s.st_gid; |
| 511 | |
| 512 | // Mount all new persistent volumes added. |
| 513 | foreach (const Resource& resource, updated.persistentVolumes()) { |
| 514 | // This is enforced by the master. |
| 515 | CHECK(resource.disk().has_volume()); |
| 516 | |
| 517 | if (current.contains(resource)) { |
| 518 | continue; |