]>
Commit | Line | Data |
---|---|---|
2e1a6c43 JR |
1 | diff -ur libvirt-0.9.12/src/lxc/lxc_controller.c libvirt-0.9.12-lxc/src/lxc/lxc_controller.c |
2 | --- libvirt-0.9.12/src/lxc/lxc_controller.c 2012-05-17 11:55:25.719689270 +0200 | |
3 | +++ libvirt-0.9.12-lxc/src/lxc/lxc_controller.c 2012-05-17 11:54:54.623023703 +0200 | |
4 | @@ -43,6 +43,7 @@ | |
5 | #include <dirent.h> | |
6 | #include <grp.h> | |
7 | #include <sys/stat.h> | |
8 | +#include <sys/time.h> | |
9 | ||
10 | #if HAVE_CAPNG | |
11 | # include <cap-ng.h> | |
12 | @@ -559,6 +560,7 @@ | |
13 | return ret; | |
14 | } | |
15 | ||
16 | +static virCgroupPtr domain_cgroup = NULL; | |
17 | ||
18 | /** | |
19 | * lxcSetContainerResources | |
20 | @@ -618,10 +620,13 @@ | |
21 | _("Unable to add task %d to cgroup for domain %s"), | |
22 | getpid(), def->name); | |
23 | } | |
24 | + domain_cgroup = cgroup; | |
25 | + goto out; | |
26 | ||
27 | cleanup: | |
28 | - virCgroupFree(&driver); | |
29 | virCgroupFree(&cgroup); | |
30 | +out: | |
31 | + virCgroupFree(&driver); | |
32 | ||
33 | return rc; | |
34 | } | |
35 | @@ -710,6 +715,63 @@ | |
918baaba JR |
36 | static bool quit = false; |
37 | static virMutex lock; | |
38 | static int sigpipe[2]; | |
39 | +static pid_t initpid = -1; | |
40 | + | |
2e1a6c43 JR |
41 | +static void lxcSignalALRMHandler(int signum ATTRIBUTE_UNUSED) |
42 | +{ | |
43 | + int tasks = 0; | |
44 | + char *keypath = NULL; | |
45 | + int rc = -1; | |
46 | + FILE *fp; | |
47 | + | |
48 | + if (initpid <= 0) | |
49 | + return; | |
50 | + if (domain_cgroup == NULL) | |
51 | + return; | |
52 | + | |
53 | + rc = virCgroupPathOfController(domain_cgroup, -1, "tasks", &keypath); | |
54 | + if (rc != 0) { | |
55 | + VIR_DEBUG("No path of cgroup tasks"); | |
56 | + return; | |
57 | + } | |
58 | + | |
59 | + if (!(fp = fopen(keypath, "r"))) { | |
60 | + VIR_DEBUG("Failed to read %s: %m\n", keypath); | |
61 | + return; | |
62 | + } | |
63 | + while (!feof(fp)) { | |
64 | + unsigned long pid_value; | |
65 | + if (fscanf(fp, "%lu", &pid_value) != 1) { | |
66 | + if (feof(fp)) | |
67 | + break; | |
68 | + rc = -errno; | |
69 | + VIR_DEBUG("Failed to read %s: %m\n", keypath); | |
70 | + fclose(fp); | |
71 | + return; | |
72 | + } | |
73 | + tasks++; | |
74 | + } | |
75 | + fclose(fp); | |
76 | + VIR_DEBUG("Tasks left: %d", tasks); | |
fded075e | 77 | + /* Kill init if it's the only process left beside container controller process */ |
2e1a6c43 JR |
78 | + if (tasks == 2) |
79 | + kill(initpid, SIGKILL); | |
80 | +} | |
81 | + | |
918baaba JR |
82 | +static void lxcSignalINTHandler(int signum ATTRIBUTE_UNUSED) |
83 | +{ | |
2e1a6c43 JR |
84 | + struct itimerval timer; |
85 | + | |
918baaba | 86 | + if (initpid <= 0) |
2e1a6c43 | 87 | + return; |
918baaba | 88 | + kill(initpid, SIGINT); |
2e1a6c43 JR |
89 | + |
90 | + timer.it_interval.tv_sec = 1; | |
91 | + timer.it_interval.tv_usec = 0; | |
92 | + timer.it_value.tv_sec = 1; | |
93 | + timer.it_value.tv_usec = 0; | |
94 | + setitimer(ITIMER_REAL, &timer, NULL); | |
918baaba JR |
95 | +} |
96 | ||
97 | static void lxcSignalChildHandler(int signum ATTRIBUTE_UNUSED) | |
98 | { | |
2e1a6c43 | 99 | @@ -1135,6 +1196,18 @@ |
918baaba JR |
100 | goto cleanup; |
101 | } | |
102 | ||
103 | + if (signal(SIGINT, lxcSignalINTHandler) == SIG_ERR) { | |
104 | + virReportSystemError(errno, "%s", | |
105 | + _("Cannot install signal handler")); | |
106 | + goto cleanup; | |
107 | + } | |
2e1a6c43 JR |
108 | + |
109 | + if (signal(SIGALRM, lxcSignalALRMHandler) == SIG_ERR) { | |
110 | + virReportSystemError(errno, "%s", | |
111 | + _("Cannot install signal handler")); | |
112 | + goto cleanup; | |
113 | + } | |
918baaba JR |
114 | + |
115 | VIR_DEBUG("serverFd=%d clientFd=%d", | |
116 | serverFd, clientFd); | |
117 | virResetLastError(); | |
2e1a6c43 | 118 | @@ -1554,6 +1627,7 @@ |
918baaba JR |
119 | goto cleanup; |
120 | VIR_FORCE_CLOSE(control[1]); | |
121 | VIR_FORCE_CLOSE(containerhandshake[1]); | |
122 | + initpid = container; | |
123 | ||
124 | if (lxcControllerMoveInterfaces(nveths, veths, container) < 0) | |
125 | goto cleanup; | |
2e1a6c43 JR |
126 | diff -ur libvirt-0.9.12/src/lxc/lxc_driver.c libvirt-0.9.12-lxc/src/lxc/lxc_driver.c |
127 | --- libvirt-0.9.12/src/lxc/lxc_driver.c 2012-05-02 05:08:53.000000000 +0200 | |
128 | +++ libvirt-0.9.12-lxc/src/lxc/lxc_driver.c 2012-05-16 19:54:48.946901077 +0200 | |
129 | @@ -3751,6 +3751,58 @@ | |
918baaba JR |
130 | } |
131 | ||
132 | static int | |
133 | +lxcDomainShutdown (virDomainPtr dom) | |
134 | +{ | |
135 | + lxc_driver_t *driver = dom->conn->privateData; | |
136 | + virDomainObjPtr vm; | |
2e1a6c43 | 137 | + virDomainEventPtr event = NULL; |
918baaba JR |
138 | + int ret = -1; |
139 | + | |
140 | + lxcDriverLock(driver); | |
141 | + vm = virDomainFindByUUID(&driver->domains, dom->uuid); | |
2e1a6c43 JR |
142 | + if (!vm) { |
143 | + char uuidstr[VIR_UUID_STRING_BUFLEN]; | |
144 | + virUUIDFormat(dom->uuid, uuidstr); | |
145 | + lxcError(VIR_ERR_NO_DOMAIN, | |
146 | + _("No domain with matching uuid '%s'"), uuidstr); | |
147 | + goto cleanup; | |
148 | + } | |
149 | + | |
150 | + if (!virDomainObjIsActive(vm)) { | |
151 | + lxcError(VIR_ERR_OPERATION_INVALID, | |
152 | + "%s", _("Domain is not running")); | |
153 | + goto cleanup; | |
154 | + } | |
918baaba JR |
155 | + |
156 | + if (vm->pid <= 0) { | |
157 | + lxcError(VIR_ERR_INTERNAL_ERROR, | |
158 | + _("Invalid PID %d for container"), vm->pid); | |
159 | + goto cleanup; | |
160 | + } | |
161 | + | |
162 | + if (kill(vm->pid, SIGINT) < -1) | |
2e1a6c43 | 163 | + goto cleanup; |
918baaba JR |
164 | + ret = 0; |
165 | + | |
2e1a6c43 JR |
166 | + event = virDomainEventNewFromObj(vm, |
167 | + VIR_DOMAIN_EVENT_STOPPED, | |
168 | + VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN); | |
169 | + virDomainAuditStop(vm, "shutdown"); | |
170 | + if (!vm->persistent) { | |
171 | + virDomainRemoveInactive(&driver->domains, vm); | |
172 | + vm = NULL; | |
173 | + } | |
174 | + | |
918baaba JR |
175 | +cleanup: |
176 | + if (vm) | |
177 | + virDomainObjUnlock(vm); | |
2e1a6c43 JR |
178 | + if (event) |
179 | + lxcDomainEventQueue(driver, event); | |
918baaba JR |
180 | + lxcDriverUnlock(driver); |
181 | + return ret; | |
182 | +} | |
183 | + | |
184 | +static int | |
185 | lxcDomainOpenConsole(virDomainPtr dom, | |
186 | const char *dev_name, | |
187 | virStreamPtr st, | |
2e1a6c43 | 188 | @@ -3866,6 +3918,7 @@ |
918baaba JR |
189 | .domainLookupByName = lxcDomainLookupByName, /* 0.4.2 */ |
190 | .domainSuspend = lxcDomainSuspend, /* 0.7.2 */ | |
191 | .domainResume = lxcDomainResume, /* 0.7.2 */ | |
edf86aab | 192 | + .domainShutdown = lxcDomainShutdown, /* PLD */ |
918baaba JR |
193 | .domainDestroy = lxcDomainDestroy, /* 0.4.4 */ |
194 | .domainDestroyFlags = lxcDomainDestroyFlags, /* 0.9.4 */ | |
195 | .domainGetOSType = lxcGetOSType, /* 0.4.2 */ |