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
15 +static virCgroupPtr domain_cgroup = NULL;
18 * lxcSetContainerResources
20 _("Unable to add task %d to cgroup for domain %s"),
23 + domain_cgroup = cgroup;
27 - virCgroupFree(&driver);
28 virCgroupFree(&cgroup);
30 + virCgroupFree(&driver);
35 static bool quit = false;
37 static int sigpipe[2];
38 +static pid_t initpid = -1;
40 +static void lxcSignalALRMHandler(int signum ATTRIBUTE_UNUSED)
43 + char *keypath = NULL;
49 + if (domain_cgroup == NULL)
52 + rc = virCgroupPathOfController(domain_cgroup, -1, "tasks", &keypath);
54 + VIR_DEBUG("No path of cgroup tasks");
58 + if (!(fp = fopen(keypath, "r"))) {
59 + VIR_DEBUG("Failed to read %s: %m\n", keypath);
63 + unsigned long pid_value;
64 + if (fscanf(fp, "%lu", &pid_value) != 1) {
68 + VIR_DEBUG("Failed to read %s: %m\n", keypath);
75 + VIR_DEBUG("Tasks left: %d", tasks);
76 + /* Kill init if it's the only process left beside container controller process */
78 + kill(initpid, SIGKILL);
81 +static void lxcSignalINTHandler(int signum ATTRIBUTE_UNUSED)
83 + struct itimerval timer;
87 + kill(initpid, SIGINT);
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);
96 static void lxcSignalChildHandler(int signum ATTRIBUTE_UNUSED)
98 @@ -1134,6 +1196,18 @@
102 + if (signal(SIGINT, lxcSignalINTHandler) == SIG_ERR) {
103 + virReportSystemError(errno, "%s",
104 + _("Cannot install signal handler"));
108 + if (signal(SIGALRM, lxcSignalALRMHandler) == SIG_ERR) {
109 + virReportSystemError(errno, "%s",
110 + _("Cannot install signal handler"));
114 VIR_DEBUG("serverFd=%d clientFd=%d",
117 @@ -1539,6 +1613,7 @@
119 VIR_FORCE_CLOSE(control[1]);
120 VIR_FORCE_CLOSE(containerhandshake[1]);
121 + initpid = container;
123 if (lxcControllerMoveInterfaces(nveths, veths, container) < 0)
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 @@
132 +lxcDomainShutdown (virDomainPtr dom)
134 + lxc_driver_t *driver = dom->conn->privateData;
135 + virDomainObjPtr vm;
136 + virDomainEventPtr event = NULL;
139 + lxcDriverLock(driver);
140 + vm = virDomainFindByUUID(&driver->domains, dom->uuid);
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);
149 + if (!virDomainObjIsActive(vm)) {
150 + lxcError(VIR_ERR_OPERATION_INVALID,
151 + "%s", _("Domain is not running"));
155 + if (vm->pid <= 0) {
156 + lxcError(VIR_ERR_INTERNAL_ERROR,
157 + _("Invalid PID %d for container"), vm->pid);
161 + if (kill(vm->pid, SIGINT) < -1)
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);
176 + virDomainObjUnlock(vm);
178 + lxcDomainEventQueue(driver, event);
179 + lxcDriverUnlock(driver);
184 lxcDomainOpenConsole(virDomainPtr dom,
185 const char *dev_name,
187 @@ -3866,6 +3918,7 @@
188 .domainLookupByName = lxcDomainLookupByName, /* 0.4.2 */
189 .domainSuspend = lxcDomainSuspend, /* 0.7.2 */
190 .domainResume = lxcDomainResume, /* 0.7.2 */
191 + .domainShutdown = lxcDomainShutdown, /* PLD */
192 .domainDestroy = lxcDomainDestroy, /* 0.4.4 */
193 .domainDestroyFlags = lxcDomainDestroyFlags, /* 0.9.4 */
194 .domainGetOSType = lxcGetOSType, /* 0.4.2 */