| 63 | |
| 64 | if (flags.allowed_devices.isSome()) { |
| 65 | foreach (const DeviceAccess& deviceAccess, |
| 66 | flags.allowed_devices->allowed_devices()) { |
| 67 | if (!deviceAccess.device().has_path()) { |
| 68 | return Error("Whitelisted device has no device path provided"); |
| 69 | } |
| 70 | |
| 71 | const string& path = deviceAccess.device().path(); |
| 72 | |
| 73 | Try<dev_t> rdev = os::stat::rdev(path); |
| 74 | if (rdev.isError()) { |
| 75 | return Error("Failed to obtain device ID for '" + path + |
| 76 | "': " + rdev.error()); |
| 77 | } |
| 78 | |
| 79 | Try<mode_t> mode = os::stat::mode(path); |
| 80 | if (mode.isError()) { |
| 81 | return Error("Failed to obtain device mode for '" + path + |
| 82 | "': " + mode.error()); |
| 83 | } |
| 84 | |
| 85 | Device dev = {rdev.get(), S_IRUSR | S_IWUSR }; |
| 86 | |
| 87 | if (S_ISBLK(mode.get())) { |
| 88 | dev.mode |= S_IFBLK; |
| 89 | } else if (S_ISCHR(mode.get())) { |
| 90 | dev.mode |= S_IFCHR; |
| 91 | } else { |
| 92 | return Error("'" + path + "' is not a block or character device"); |
| 93 | } |
| 94 | |
| 95 | // Set the desired access for the device. Access is controlled at |
| 96 | // container granularity, which is consistent with the devices cgroup |
| 97 | // policy. This means that if we populate a read-write device into a |
| 98 | // container, then every process in that container should have access, |
| 99 | // regardless of the credential of that process. |
| 100 | |
| 101 | if (deviceAccess.access().read()) { |
| 102 | dev.mode |= (S_IRGRP | S_IROTH); |
| 103 | } |
| 104 | |
| 105 | if (deviceAccess.access().write()) { |
| 106 | dev.mode |= (S_IWGRP | S_IWOTH); |
| 107 | } |
| 108 | |
| 109 | whitelistedDevices.put( |
| 110 | strings::remove(path, "/dev/", strings::PREFIX), dev); |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return new MesosIsolator(Owned<MesosIsolatorProcess>( |
nothing calls this directly
no test coverage detected