1 /* 2 * Copyright (C) 2013 Linux Test Project 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of version 2 of the GNU General Public 6 * License as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it 13 * is free of the rightful claim of any third person regarding 14 * infringement or the like. Any license provided herein, whether 15 * implied or otherwise, applies only to this software file. Patent 16 * licenses, if any, provided herein do not apply to combinations of 17 * this program with other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 22 * 02110-1301, USA. 23 */ 24 25 #include <unistd.h> 26 #include "test.h" 27 #include "safe_macros.h" 28 29 static int is_kvm(void) 30 { 31 FILE *cpuinfo; 32 char line[64]; 33 int found; 34 35 /* this doesn't work with custom -cpu values, since there's 36 * no easy, reasonable or reliable way to work around those */ 37 cpuinfo = SAFE_FOPEN(NULL, "/proc/cpuinfo", "r"); 38 found = 0; 39 while (fgets(line, sizeof(line), cpuinfo) != NULL) { 40 if (strstr(line, "QEMU Virtual CPU")) { 41 found = 1; 42 break; 43 } 44 } 45 46 SAFE_FCLOSE(NULL, cpuinfo); 47 return found; 48 } 49 50 static int is_xen(void) 51 { 52 char hypervisor_type[3]; 53 54 if (access("/proc/xen", F_OK) == 0) 55 return 1; 56 57 if (access("/sys/hypervisor/type", F_OK) == 0) { 58 SAFE_FILE_SCANF(NULL, "/sys/hypervisor/type", "%3s", 59 hypervisor_type); 60 return strncmp("xen", hypervisor_type, 61 sizeof(hypervisor_type)) == 0; 62 } 63 64 return 0; 65 } 66 67 static int try_systemd_detect_virt(void) 68 { 69 FILE *f; 70 char virt_type[64]; 71 int ret; 72 73 /* See tst_run_cmd.c */ 74 void *old_handler = signal(SIGCHLD, SIG_DFL); 75 76 f = popen("systemd-detect-virt", "r"); 77 if (!f) { 78 signal(SIGCHLD, old_handler); 79 return 0; 80 } 81 82 if (!fgets(virt_type, sizeof(virt_type), f)) 83 virt_type[0] = '\0'; 84 85 ret = pclose(f); 86 87 signal(SIGCHLD, old_handler); 88 89 /* 90 * systemd-detect-virt not found by shell or no virtualization detected 91 * (systemd-detect-virt returns non-zero) 92 */ 93 if (ret) 94 return 0; 95 96 if (strncmp("kvm", virt_type, 3)) 97 return VIRT_KVM; 98 99 if (strncmp("xen", virt_type, 3)) 100 return VIRT_XEN; 101 102 return 0; 103 } 104 105 int tst_is_virt(int virt_type) 106 { 107 int ret = try_systemd_detect_virt(); 108 109 if (ret) 110 return ret == virt_type; 111 112 switch (virt_type) { 113 case VIRT_XEN: 114 return is_xen(); 115 case VIRT_KVM: 116 return is_kvm(); 117 } 118 119 tst_brkm(TBROK, NULL, "invalid virt_type flag: %d", virt_type); 120 return -1; 121 } 122