| 136 | |
| 137 | |
| 138 | Future<Option<ContainerLaunchInfo>> LinuxDevicesIsolatorProcess::prepare( |
| 139 | const ContainerID& containerId, |
| 140 | const ContainerConfig& containerConfig) |
| 141 | { |
| 142 | // If there's no rootfs, we won't be building a private `/dev` |
| 143 | // so there's nothing to do. |
| 144 | if (!containerConfig.has_rootfs()) { |
| 145 | return None(); |
| 146 | } |
| 147 | |
| 148 | if (whitelistedDevices.empty()) { |
| 149 | return None(); |
| 150 | } |
| 151 | |
| 152 | ContainerLaunchInfo launchInfo; |
| 153 | |
| 154 | const string devicesDir = containerizer::paths::getContainerDevicesPath( |
| 155 | runtimeDirectory, containerId); |
| 156 | |
| 157 | // The `filesystem/linux` isolator is responsible for creating the |
| 158 | // devices directory and ordered to run before we do. Here, we can |
| 159 | // just assert that the devices directory is still present. |
| 160 | if (!os::exists(devicesDir)) { |
| 161 | return Failure("Missing container devices directory '" + devicesDir + "'"); |
| 162 | } |
| 163 | |
| 164 | // Import the whitelisted devices to all containers. |
| 165 | foreachpair (const string& path, const Device& dev, whitelistedDevices) { |
| 166 | const string devicePath = path::join(devicesDir, path); |
| 167 | |
| 168 | Try<Nothing> mkdir = os::mkdir(Path(devicePath).dirname()); |
| 169 | if (mkdir.isError()) { |
| 170 | return Failure( |
| 171 | "Failed to create parent directory for device '" + |
| 172 | devicePath + "': " + mkdir.error()); |
| 173 | } |
| 174 | |
| 175 | Try<Nothing> mknod = os::mknod(devicePath, dev.mode, dev.dev); |
| 176 | if (mknod.isError()) { |
| 177 | return Failure( |
| 178 | "Failed to create device '" + devicePath + "': " + mknod.error()); |
| 179 | } |
| 180 | |
| 181 | // We have to chmod the device to make sure that the umask doesn't filter |
| 182 | // the permissions defined by the whitelist. |
| 183 | Try<Nothing> chmod = os::chmod(devicePath, dev.mode & ~S_IFMT); |
| 184 | if (chmod.isError()) { |
| 185 | return Failure( |
| 186 | "Failed to chmod device '" + devicePath + "': " + chmod.error()); |
| 187 | } |
| 188 | |
| 189 | *launchInfo.add_mounts() = protobuf::slave::createContainerMount( |
| 190 | devicePath, |
| 191 | path::join(containerConfig.rootfs(), "dev", path), |
| 192 | MS_BIND); |
| 193 | } |
| 194 | |
| 195 | // TODO(jpeach) Define Task API to let schedulers specify the container |
nothing calls this directly
no test coverage detected