diff options
Diffstat (limited to 'src/hypervisor_check.adb')
-rw-r--r-- | src/hypervisor_check.adb | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/hypervisor_check.adb b/src/hypervisor_check.adb index 340d4a5..bbc83f1 100644 --- a/src/hypervisor_check.adb +++ b/src/hypervisor_check.adb @@ -61,6 +61,8 @@ package body Hypervisor_Check is else return False; end if; + elsif Config.FreeBSD then + return Command_Succeeds(Interfaces.C.To_C(FreeBSD_Xen_Present_Command)); else raise OS_Not_Supported; end if; @@ -78,6 +80,23 @@ package body Hypervisor_Check is end if; end Hypervisor_Present; + -- Execute a system command and return true if it succeeded + -- (i.e. returned 0) + function Command_Succeeds (Command : Interfaces.C.Char_Array) return Boolean is + use Interfaces.C; + function Sys (Arg : Char_Array) return Integer; + pragma Import(C, Sys, "system"); + + Ret_Val : Integer; + begin + Ret_Val := Sys(Command); + if Ret_Val > 0 then + return False; + else + return True; + end if; + end Command_Succeeds; + -- Calling CPUID instruction with hypervisor leaf in %eax -- puts the vendor string in %ebx, %ecx, and %edx function Get_Vendor_String return US.Unbounded_String is @@ -111,16 +130,22 @@ package body Hypervisor_Check is return Vendor_Name; end Get_Vendor_Name; + -- There are two cases: 1. DMI is not available on a _system_ + -- (paravirtualized guests are notable examples) + -- 2. the OS doesn't have a DMI API available to unprivileged users function DMI_Available return Boolean is begin if Config.Linux then + -- Linux provides DMI info via sysfs, but on systems + -- without SMBIOS it's not available if Ada.Directories.Exists("/sys/class/dmi") then return True; else return False; end if; else - raise OS_Not_Supported; + -- Other OSes don't have DMI API we can use + return False; end if; end DMI_Available; |