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