-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdaemon.c
More file actions
101 lines (85 loc) · 2.71 KB
/
daemon.c
File metadata and controls
101 lines (85 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <libvirt/libvirt.h>
#include <syslog.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
int main(void)
{
const char *VFIO_VM_NAME = getenv("VFIO_VM_NAME");
const char *IDLE_VM_NAME = getenv("IDLE_VM_NAME");
const char *CONNECTION_URI = getenv("CONNECTION_URI");
if (!CONNECTION_URI)
{
CONNECTION_URI = "qemu:///system";
}
if (!VFIO_VM_NAME && !IDLE_VM_NAME)
{
syslog(LOG_ERR, "Exiting because the following variable(s) are not set:%s%s\n", VFIO_VM_NAME ? "" : " VFIO_VM_NAME", IDLE_VM_NAME ? "" : " IDLE_VM_NAME");
return EXIT_FAILURE;
}
virConnectPtr conn = NULL;
if (!(conn = virConnectOpen(CONNECTION_URI)))
{
syslog(LOG_ERR, "Failed to connect to the hypervisor.");
return EXIT_FAILURE;
}
virDomainPtr vfio_vm = NULL;
if (!(vfio_vm = virDomainLookupByName(conn, VFIO_VM_NAME)))
{
syslog(LOG_ERR, "Unable to find VFIO VM '%s'", VFIO_VM_NAME);
return EXIT_FAILURE;
}
virDomainPtr idle_vm = NULL;
if (!(idle_vm = virDomainLookupByName(conn, IDLE_VM_NAME)))
{
syslog(LOG_ERR, "Unable to find idle VM '%s'", IDLE_VM_NAME);
return EXIT_FAILURE;
}
syslog(LOG_INFO, "Service started.");
bool boot_vfio_next = false;
int vfio_vm_state;
int idle_vm_state;
int reason;
for (;;)
{
/*
* See https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainState
* for the meaning of state values
*/
// virDomainGetState() produces `state` and `reason`, only the former is useful to us
virDomainGetState(vfio_vm, &vfio_vm_state, &reason, 0);
virDomainGetState(idle_vm, &idle_vm_state, &reason, 0);
if (vfio_vm_state == 5 && idle_vm_state == 5)
{
// If both VMs are shut off, boot the next VM in the rotation
sleep(1);
if (boot_vfio_next)
{
syslog(LOG_INFO, "Booting VFIO VM!");
if (virDomainCreate(vfio_vm) != 0)
{
syslog(LOG_ERR, "Failed to boot the VFIO VM.");
}
}
else
{
syslog(LOG_INFO, "Booting idle VM!");
if (virDomainCreate(idle_vm) != 0)
{
syslog(LOG_ERR, "Failed to boot the idle VM.");
}
}
boot_vfio_next = !boot_vfio_next;
}
// Assume that both VMs cannot be up at the same time
else if (vfio_vm_state == 1)
{
boot_vfio_next = false;
}
else if (idle_vm_state == 1)
{
boot_vfio_next = true;
}
sleep(1);
}
}