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
16 +static virCgroupPtr domain_cgroup = NULL;
19 * lxcSetContainerResources
21 _("Unable to add task %d to cgroup for domain %s"),
24 + domain_cgroup = cgroup;
28 - virCgroupFree(&driver);
29 virCgroupFree(&cgroup);
31 + virCgroupFree(&driver);
36 static bool quit = false;
38 static int sigpipe[2];
39 +static pid_t initpid = -1;
41 +static void lxcSignalALRMHandler(int signum ATTRIBUTE_UNUSED)
44 + char *keypath = NULL;
50 + if (domain_cgroup == NULL)
53 + rc = virCgroupPathOfController(domain_cgroup, -1, "tasks", &keypath);
55 + VIR_DEBUG("No path of cgroup tasks");
59 + if (!(fp = fopen(keypath, "r"))) {
60 + VIR_DEBUG("Failed to read %s: %m\n", keypath);
64 + unsigned long pid_value;
65 + if (fscanf(fp, "%lu", &pid_value) != 1) {
69 + VIR_DEBUG("Failed to read %s: %m\n", keypath);
76 + VIR_DEBUG("Tasks left: %d", tasks);
77 + /* Kill init if it's the only process left beside container controller process */
79 + kill(initpid, SIGKILL);
82 +static void lxcSignalINTHandler(int signum ATTRIBUTE_UNUSED)
84 + struct itimerval timer;
88 + kill(initpid, SIGINT);
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);
97 static void lxcSignalChildHandler(int signum ATTRIBUTE_UNUSED)
99 @@ -1135,6 +1196,18 @@
103 + if (signal(SIGINT, lxcSignalINTHandler) == SIG_ERR) {
104 + virReportSystemError(errno, "%s",
105 + _("Cannot install signal handler"));
109 + if (signal(SIGALRM, lxcSignalALRMHandler) == SIG_ERR) {
110 + virReportSystemError(errno, "%s",
111 + _("Cannot install signal handler"));
115 VIR_DEBUG("serverFd=%d clientFd=%d",
118 @@ -1554,6 +1627,7 @@
120 VIR_FORCE_CLOSE(control[1]);
121 VIR_FORCE_CLOSE(containerhandshake[1]);
122 + initpid = container;
124 if (lxcControllerMoveInterfaces(nveths, veths, container) < 0)
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 @@
133 +lxcDomainShutdown (virDomainPtr dom)
135 + lxc_driver_t *driver = dom->conn->privateData;
136 + virDomainObjPtr vm;
137 + virDomainEventPtr event = NULL;
140 + lxcDriverLock(driver);
141 + vm = virDomainFindByUUID(&driver->domains, dom->uuid);
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);
150 + if (!virDomainObjIsActive(vm)) {
151 + lxcError(VIR_ERR_OPERATION_INVALID,
152 + "%s", _("Domain is not running"));
156 + if (vm->pid <= 0) {
157 + lxcError(VIR_ERR_INTERNAL_ERROR,
158 + _("Invalid PID %d for container"), vm->pid);
162 + if (kill(vm->pid, SIGINT) < -1)
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);
177 + virDomainObjUnlock(vm);
179 + lxcDomainEventQueue(driver, event);
180 + lxcDriverUnlock(driver);
185 lxcDomainOpenConsole(virDomainPtr dom,
186 const char *dev_name,
188 @@ -3866,6 +3918,7 @@
189 .domainLookupByName = lxcDomainLookupByName, /* 0.4.2 */
190 .domainSuspend = lxcDomainSuspend, /* 0.7.2 */
191 .domainResume = lxcDomainResume, /* 0.7.2 */
192 + .domainShutdown = lxcDomainShutdown, /* PLD */
193 .domainDestroy = lxcDomainDestroy, /* 0.4.4 */
194 .domainDestroyFlags = lxcDomainDestroyFlags, /* 0.9.4 */
195 .domainGetOSType = lxcGetOSType, /* 0.4.2 */