/* * Copyright (C) 2018 The Android Open Source Project * * Licensed 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. */ #include "host/libs/vm_manager/host_configuration.h" #include #include #include #include #include #include "common/libs/utils/users.h" namespace cuttlefish { namespace vm_manager { namespace { __attribute__((unused)) bool UserInGroup( const std::string& group, std::vector* config_commands) { if (!InGroup(group)) { LOG(ERROR) << "User must be a member of " << group; config_commands->push_back("# Add your user to the " + group + " group:"); config_commands->push_back("sudo usermod -aG " + group + " $USER"); return false; } return true; } constexpr std::pair invalid_linux_version = std::pair(); __attribute__((unused)) std::pair GetLinuxVersion() { struct utsname info; if (!uname(&info)) { char* digit = strtok(info.release, "+.-"); int major = atoi(digit); if (digit) { digit = strtok(NULL, "+.-"); int minor = atoi(digit); return std::pair{major, minor}; } } LOG(ERROR) << "Failed to detect Linux kernel version"; return invalid_linux_version; } __attribute__((unused)) bool LinuxVersionAtLeast( std::vector* config_commands, const std::pair& version, int major, int minor) { if (version.first > major || (version.first == major && version.second >= minor)) { return true; } LOG(ERROR) << "Kernel version must be >=" << major << "." << minor << ", have " << version.first << "." << version.second; config_commands->push_back("# Please upgrade your kernel to >=" + std::to_string(major) + "." + std::to_string(minor)); return false; } } // namespace bool ValidateHostConfiguration(std::vector* config_commands) { #ifdef __APPLE__ (void)config_commands; return true; #else // if we can't detect the kernel version, just fail auto version = GetLinuxVersion(); if (version == invalid_linux_version) { return false; } // the check for cvdnetwork needs to happen even if the user is not in kvm, so // we can't just say UserInGroup("kvm") && UserInGroup("cvdnetwork") auto in_cvdnetwork = UserInGroup("cvdnetwork", config_commands); // if we're in the virtaccess group this is likely to be a CrOS environment. auto is_cros = InGroup("virtaccess"); if (is_cros) { // relax the minimum kernel requirement slightly, as chromeos-4.4 has the // needed backports to enable vhost_vsock auto linux_ver_4_4 = LinuxVersionAtLeast(config_commands, version, 4, 4); return in_cvdnetwork && linux_ver_4_4; } else { // this is regular Linux, so use the Debian group name and be more // conservative with the kernel version check. auto in_kvm = UserInGroup("kvm", config_commands); auto linux_ver_4_8 = LinuxVersionAtLeast(config_commands, version, 4, 8); return in_cvdnetwork && in_kvm && linux_ver_4_8; } #endif } } // namespace vm_manager } // namespace cuttlefish