]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/mainloop.c
lxccontainer: properly cleanup on mount injection failure
[mirror_lxc.git] / src / lxc / mainloop.c
CommitLineData
b0a33c1e 1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
9afe19d6 7 * Daniel Lezcano <daniel.lezcano at free.fr>
b0a33c1e 8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
250b1eec 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
b0a33c1e 22 */
3c319edb 23
d38dd64a
CB
24#ifndef _GNU_SOURCE
25#define _GNU_SOURCE 1
26#endif
b0a33c1e 27#include <errno.h>
91480a0f 28#include <fcntl.h>
3c319edb
CB
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
b0a33c1e 32#include <sys/epoll.h>
d38dd64a 33#include <unistd.h>
b0a33c1e 34
d38dd64a 35#include "config.h"
b0a33c1e 36#include "mainloop.h"
37
9227a12a 38struct mainloop_handler {
b0a33c1e 39 lxc_mainloop_callback_t callback;
40 int fd;
41 void *data;
42};
43
5df6b18f
CC
44#define MAX_EVENTS 10
45
e51d4895 46int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms)
b0a33c1e 47{
a529bc25 48 int i, nfds, ret;
9227a12a 49 struct mainloop_handler *handler;
5df6b18f 50 struct epoll_event events[MAX_EVENTS];
b0a33c1e 51
52 for (;;) {
e51d4895 53 nfds = epoll_wait(descr->epfd, events, MAX_EVENTS, timeout_ms);
b0a33c1e 54 if (nfds < 0) {
55 if (errno == EINTR)
56 continue;
3c319edb 57
b0a33c1e 58 return -1;
59 }
60
5df6b18f 61 for (i = 0; i < nfds; i++) {
a529bc25 62 handler = events[i].data.ptr;
b0a33c1e 63
a529bc25 64 /* If the handler returns a positive value, exit the
3c319edb
CB
65 * mainloop.
66 */
a529bc25
CB
67 ret = handler->callback(handler->fd, events[i].events,
68 handler->data, descr);
69 if (ret == LXC_MAINLOOP_CLOSE)
b0a33c1e 70 return 0;
b0a33c1e 71 }
72
3c319edb 73 if (nfds == 0)
e51d4895
DE
74 return 0;
75
d066f3b8 76 if (lxc_list_empty(&descr->handlers))
b0a33c1e 77 return 0;
78 }
79}
80
f79d43bb 81int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
b0a33c1e 82 lxc_mainloop_callback_t callback, void *data)
83{
d066f3b8 84 struct epoll_event ev;
9227a12a 85 struct mainloop_handler *handler;
d066f3b8 86 struct lxc_list *item;
b0a33c1e 87
88 handler = malloc(sizeof(*handler));
89 if (!handler)
90 return -1;
91
92 handler->callback = callback;
93 handler->fd = fd;
94 handler->data = data;
95
d066f3b8
CC
96 ev.events = EPOLLIN;
97 ev.data.ptr = handler;
b0a33c1e 98
d066f3b8
CC
99 if (epoll_ctl(descr->epfd, EPOLL_CTL_ADD, fd, &ev) < 0)
100 goto out_free_handler;
b0a33c1e 101
d066f3b8
CC
102 item = malloc(sizeof(*item));
103 if (!item)
104 goto out_free_handler;
b0a33c1e 105
d066f3b8
CC
106 item->elem = handler;
107 lxc_list_add(&descr->handlers, item);
3ce45e64 108 return 0;
b0a33c1e 109
d066f3b8 110out_free_handler:
b0a33c1e 111 free(handler);
3ce45e64 112 return -1;
b0a33c1e 113}
114
115int lxc_mainloop_del_handler(struct lxc_epoll_descr *descr, int fd)
116{
9227a12a 117 struct mainloop_handler *handler;
d066f3b8 118 struct lxc_list *iterator;
b0a33c1e 119
d066f3b8
CC
120 lxc_list_for_each(iterator, &descr->handlers) {
121 handler = iterator->elem;
b0a33c1e 122
d066f3b8
CC
123 if (handler->fd == fd) {
124 /* found */
125 if (epoll_ctl(descr->epfd, EPOLL_CTL_DEL, fd, NULL))
126 return -1;
b0a33c1e 127
d066f3b8
CC
128 lxc_list_del(iterator);
129 free(iterator->elem);
130 free(iterator);
131 return 0;
b0a33c1e 132 }
b0a33c1e 133 }
134
135 return -1;
136}
137
a9e61274 138int lxc_mainloop_open(struct lxc_epoll_descr *descr)
b0a33c1e 139{
a9e61274 140 /* hint value passed to epoll create */
12c2798e 141 descr->epfd = epoll_create1(EPOLL_CLOEXEC);
b0a33c1e 142 if (descr->epfd < 0)
143 return -1;
144
d066f3b8 145 lxc_list_init(&descr->handlers);
b0a33c1e 146 return 0;
147}
148
149int lxc_mainloop_close(struct lxc_epoll_descr *descr)
150{
d066f3b8
CC
151 struct lxc_list *iterator, *next;
152
153 iterator = descr->handlers.next;
154 while (iterator != &descr->handlers) {
155 next = iterator->next;
b0a33c1e 156
d066f3b8
CC
157 lxc_list_del(iterator);
158 free(iterator->elem);
159 free(iterator);
160 iterator = next;
161 }
b0a33c1e 162
1cc8bd4b
CB
163 if (descr->epfd >= 0)
164 return close(descr->epfd);
165
166 return 0;
b0a33c1e 167}