| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef __MESOS_CONTAINERIZER_PATHS_HPP__ |
| #define __MESOS_CONTAINERIZER_PATHS_HPP__ |
| |
| #include <sys/types.h> |
| |
| #include <string> |
| #include <vector> |
| |
| #include <process/address.hpp> |
| |
| #include <stout/result.hpp> |
| #include <stout/try.hpp> |
| |
| #include <mesos/mesos.hpp> |
| |
| #include <mesos/slave/containerizer.hpp> |
| |
| namespace mesos { |
| namespace internal { |
| namespace slave { |
| namespace containerizer { |
| namespace paths { |
| |
| |
| // The containerizer uses the runtime directory to checkpoint things |
| // for each container, like the PID of the first process executed |
| // within a container (i.e., the "PID 1") or the LaunchInfo associated |
| // with the given container. |
| // |
| // The file system layout is as follows: |
| // |
| // root ('--runtime_dir' flag) |
| // |-- containers |
| // |-- <container_id> |
| // |-- config |
| // |-- containers |
| // | |-- <container_id> |
| // | | |-- <more nesting of containers> |
| // | |-- pid |
| // | |-- ... |
| // |-- devices |
| // |-- force_destroy_on_recovery |
| // |-- io_switchboard |
| // | |-- pid |
| // | |-- socket |
| // |-- launch_info |
| // |-- mnt |
| // | |-- host_proc |
| // |-- pid |
| // |-- shm |
| // |-- standalone.marker |
| // |-- status |
| // |-- termination |
| |
| |
| constexpr char PID_FILE[] = "pid"; |
| constexpr char CONTAINER_CONFIG_FILE[] = "config"; |
| constexpr char STATUS_FILE[] = "status"; |
| constexpr char TERMINATION_FILE[] = "termination"; |
| constexpr char SOCKET_FILE[] = "socket"; |
| constexpr char FORCE_DESTROY_ON_RECOVERY_FILE[] = "force_destroy_on_recovery"; |
| constexpr char IO_SWITCHBOARD_DIRECTORY[] = "io_switchboard"; |
| constexpr char MNT_DIRECTORY[] = "mnt"; |
| constexpr char MNT_HOST_PROC[] = "host_proc"; |
| constexpr char CONTAINER_DIRECTORY[] = "containers"; |
| constexpr char CONTAINER_DEVICES_DIRECTORY[] = "devices"; |
| constexpr char CONTAINER_LAUNCH_INFO_FILE[] = "launch_info"; |
| constexpr char STANDALONE_MARKER_FILE[] = "standalone.marker"; |
| constexpr char CONTAINER_SHM_DIRECTORY[] = "shm"; |
| constexpr char AGENT_SHM_DIRECTORY[] = "/dev/shm"; |
| constexpr char SECRET_DIRECTORY[] = ".secret"; |
| |
| |
| enum Mode |
| { |
| PREFIX, |
| SUFFIX, |
| JOIN, |
| }; |
| |
| // Returns a path representation of a ContainerID that can be used for |
| // creating cgroups or writing to the filesystem. A ContainerID can |
| // represent a nested container (i.e, it has a parent ContainerID) and |
| // the path representation includes all of the parents as directories |
| // in the path. Depending on the 'mode', the result can be the |
| // following for a nested container 'xxx.yyy': |
| // 1) mode == PREFIX: '<separator>/xxx/<separator>/yyy' |
| // 2) mode == SUFFIX: 'xxx/<separator>/yyy/<separator>' |
| // 3) mode == JOIN: 'xxx/<separator>/yyy' |
| std::string buildPath( |
| const ContainerID& containerId, |
| const std::string& separator, |
| const Mode& mode); |
| |
| |
| // The following helper function constructs the path |
| // for a container given the 'runtimeDir' that was |
| // used as well as the container `containerId`. |
| std::string getRuntimePath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // Given a `runtimeDir`, construct a unique directory to stage |
| // per-container device nodes. This directory is initially created |
| // and populated by the `filesystem/linux` isolator. Any subsequent |
| // isolators may add devices to this directory and bind mount them |
| // into the container. |
| std::string getContainerDevicesPath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to read the pid file. |
| Result<pid_t> getContainerPid( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to read the status file. |
| Result<int> getContainerStatus( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| #ifndef __WINDOWS__ |
| // The helper method to get the io switchboard directory path. |
| std::string getContainerIOSwitchboardPath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to get the io switchboard pid file path. |
| std::string getContainerIOSwitchboardPidPath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to get the io switchboard pid. |
| Result<pid_t> getContainerIOSwitchboardPid( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to get the socket file path. |
| std::string getContainerIOSwitchboardSocketPath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to get the io switchboard provisional socket path, |
| // see comment in IOSwitchboardServer::create(). |
| std::string getContainerIOSwitchboardSocketProvisionalPath( |
| const std::string& socketPath); |
| |
| |
| // The helper method to get the io switchboard provisional socket path, |
| // see comment in IOSwitchboardServer::create(). |
| std::string getContainerIOSwitchboardSocketProvisionalPath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to read the io switchboard socket file. |
| Result<process::network::unix::Address> getContainerIOSwitchboardAddress( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| // The helper method to get the host proc mount point path. |
| std::string getHostProcMountPointPath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| #endif |
| |
| |
| // The helper method to get the destroy on recovery file path. |
| std::string getContainerForceDestroyOnRecoveryPath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to check if we should |
| // destroy a container on recovery or not. |
| bool getContainerForceDestroyOnRecovery( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to read the container termination state. |
| Result<mesos::slave::ContainerTermination> getContainerTermination( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to get the standalone container marker path. |
| std::string getStandaloneContainerMarkerPath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to check if the given container is a standalone |
| // container or not. This is determined by the existence (or not) of |
| // a marker file in the container's runtime metadata directory. |
| bool isStandaloneContainer( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to read the launch config of the contaienr. |
| Result<mesos::slave::ContainerConfig> getContainerConfig( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to list all container IDs (including nested |
| // containers) from the container runtime directory. The order of |
| // returned vector is a result of pre-ordering walk (i.e., parent |
| // is inserted before its children). |
| Try<std::vector<ContainerID>> getContainerIds( |
| const std::string& runtimeDir); |
| |
| |
| // The helper method to get the container launch information path. |
| std::string getContainerLaunchInfoPath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to get the container launch information |
| // at the moment it was launched. |
| Result<mesos::slave::ContainerLaunchInfo> getContainerLaunchInfo( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // The helper method to get the sandbox path. |
| std::string getSandboxPath( |
| const std::string& rootSandboxPath, |
| const ContainerID& containerId); |
| |
| |
| // The helper method parses a given 'path' and returns the container |
| // ID of the container whose sandbox contains 'path'. |
| Try<ContainerID> parseSandboxPath( |
| const ContainerID& rootContainerId, |
| const std::string& rootSandboxPath, |
| const std::string& path); |
| |
| |
| std::string getContainerShmPath( |
| const std::string& runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| Try<std::string> getParentShmPath( |
| const std::string runtimeDir, |
| const ContainerID& containerId); |
| |
| |
| // Helper for determining the cgroup for a container (i.e., the path |
| // in a cgroup subsystem). |
| std::string getCgroupPath( |
| const std::string& cgroupsRoot, |
| const ContainerID& containerId); |
| |
| |
| // Helper for parsing the cgroup path to determine the container ID |
| // it belongs to. |
| Option<ContainerID> parseCgroupPath( |
| const std::string& cgroupsRoot, |
| const std::string& cgroup); |
| |
| // All cgroups v2 paths are either leaf or non-leaf paths. Leaf paths end |
| // in `/leaf`, contain processes, and may impose resource constraints. Non-leaf |
| // paths do not contain processes and may impose resource constraints. |
| // This is done to avoid the restrictions of the "Internal Process Contraint". |
| // More information: https://docs.kernel.org/admin-guide/cgroup-v2.html#no-internal-process-constraint |
| // |
| // The cgroup2 file system has the structure: |
| // <MOUNT>/<root>/agent Mesos Agent constraints |
| // <MOUNT>/<root>/agent/leaf Mesos Agent process |
| // |
| // <MOUNT>/<root>/<id> Container constraints |
| // <MOUNT>/<root>/<id>/leaf Container process |
| // |
| // <MOUNT>/<root>/<id>/mesos/<id2> Nested container constraints |
| // <MOUNT>/<root>/<id>/mesos/<id2>/leaf Nested container process |
| // |
| // For every new level of nesting, `/mesos/<idN>` is added to the path. |
| // |
| // <root> Value of the `cgroups_root` flag. |
| // <MOUNT> /sys/fs/cgroup, where the cgroup2 hierarchy is mounted. |
| namespace cgroups2 { |
| |
| // Path to the Mesos Agent's cgroup. |
| // `root` is the value of the `cgroups_root` flag. |
| std::string agent(const std::string& root, bool leaf = false); |
| |
| |
| // Path to a container's cgroup. |
| // `root` is the value of the `cgroups_root` flag. |
| std::string container( |
| const std::string& root, |
| const ContainerID& containerId, |
| bool leaf = false); |
| |
| |
| // Get a containerId from a container's cgroup. |
| // Inverse of `cgroups2::container(root, id)`. |
| // |
| // Leaf paths (which end in `/leaf`) and non-leaf paths will resolve to the |
| // same container id. |
| Option<ContainerID> containerId( |
| const std::string& root, |
| const std::string& cgroup); |
| |
| } // namespace cgroups2 { |
| } // namespace paths { |
| } // namespace containerizer { |
| } // namespace slave { |
| } // namespace internal { |
| } // namespace mesos { |
| |
| #endif // __MESOS_CONTAINERIZER_PATHS_HPP__ |