| 196 | |
| 197 | |
| 198 | bool exists() |
| 199 | { |
| 200 | // This is static as the init system should not change while we are running. |
| 201 | static const bool exists = []() -> bool { |
| 202 | // (1) Test whether `/sbin/init` links to systemd. |
| 203 | const Result<string> realpath = os::realpath("/sbin/init"); |
| 204 | if (realpath.isError() || realpath.isNone()) { |
| 205 | LOG(WARNING) << "Failed to test /sbin/init for systemd environment: " |
| 206 | << (realpath.isError() ? realpath.error() |
| 207 | : "does not exist"); |
| 208 | |
| 209 | return false; |
| 210 | } |
| 211 | |
| 212 | CHECK_SOME(realpath); |
| 213 | |
| 214 | // (2) Testing whether we have a systemd version. |
| 215 | const string command = realpath.get() + " --version"; |
| 216 | Try<string> versionCommand = os::shell(command); |
| 217 | |
| 218 | if (versionCommand.isError()) { |
| 219 | LOG(WARNING) << "Failed to test command '" << command << "': " |
| 220 | << versionCommand.error(); |
| 221 | |
| 222 | return false; |
| 223 | } |
| 224 | |
| 225 | vector<string> tokens = strings::tokenize(versionCommand.get(), " \n"); |
| 226 | |
| 227 | // We need at least a name and a version number to match systemd. |
| 228 | if (tokens.size() < 2) { |
| 229 | return false; |
| 230 | } |
| 231 | |
| 232 | if (tokens[0] != "systemd") { |
| 233 | return false; |
| 234 | } |
| 235 | |
| 236 | Try<int> version = numify<int>(tokens[1]); |
| 237 | if (version.isError()) { |
| 238 | LOG(WARNING) << "Failed to parse systemd version '" << tokens[1] << "'"; |
| 239 | return false; |
| 240 | } |
| 241 | |
| 242 | LOG(INFO) << "systemd version `" << version.get() << "` detected"; |
| 243 | |
| 244 | // We log a warning if the version is below 218. This is because the |
| 245 | // `Delegate` flag was introduced in version 218. Some systems, like RHEL 7, |
| 246 | // have patched versions that are below 218 but still have the `Delegate` |
| 247 | // flag. This is why we warn / inform users rather than failing. See |
| 248 | // MESOS-3352. |
| 249 | if (version.get() < DELEGATE_MINIMUM_VERSION) { |
| 250 | LOG(WARNING) |
| 251 | << "Required functionality `Delegate` was introduced in Version `" |
| 252 | << DELEGATE_MINIMUM_VERSION << "`. Your system may not function" |
| 253 | << " properly; however since some distributions have patched systemd" |
| 254 | << " packages, your system may still be functional. This is why we keep" |
| 255 | << " running. See MESOS-3352 for more information"; |