]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/utils.c
fix container find the previously created configuration
[mirror_lxc.git] / src / lxc / utils.c
CommitLineData
e3642c43
DL
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <dlezcano at fr.ibm.com>
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
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
d983b93c 24#define _GNU_SOURCE
e3642c43
DL
25#include <errno.h>
26#include <unistd.h>
d983b93c
MN
27#include <stdlib.h>
28#include <stddef.h>
e3642c43
DL
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/mman.h>
d983b93c
MN
32#include <sys/param.h>
33#include <dirent.h>
34#include <fcntl.h>
e3642c43 35
af795875 36#include "list.h"
e3642c43
DL
37#include "log.h"
38
39lxc_log_define(lxc_utils, lxc);
40
41int lxc_copy_file(const char *srcfile, const char *dstfile)
42{
43 void *srcaddr = NULL, *dstaddr;
44 struct stat stat;
45 int srcfd, dstfd, ret = -1;
46 char c = '\0';
47
48 dstfd = open(dstfile, O_CREAT | O_EXCL | O_RDWR, 0600);
49 if (dstfd < 0) {
50 SYSERROR("failed to creat '%s'", dstfile);
51 goto out;
52 }
53
54 srcfd = open(srcfile, O_RDONLY);
55 if (srcfd < 0) {
56 SYSERROR("failed to open '%s'", srcfile);
57 goto err;
58 }
59
60 if (fstat(srcfd, &stat)) {
61 SYSERROR("failed to stat '%s'", srcfile);
62 goto err;
63 }
64
65 if (!stat.st_size) {
66 INFO("copy '%s' which is an empty file", srcfile);
67 ret = 0;
68 goto out_close;
69 }
70
71 if (lseek(dstfd, stat.st_size - 1, SEEK_SET) < 0) {
72 SYSERROR("failed to seek dest file '%s'", dstfile);
73 goto err;
74 }
75
76 /* fixup length */
77 if (write(dstfd, &c, 1) < 0) {
78 SYSERROR("failed to write to '%s'", dstfile);
79 goto err;
80 }
81
82 srcaddr = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, srcfd, 0L);
83 if (srcaddr == MAP_FAILED) {
84 SYSERROR("failed to mmap '%s'", srcfile);
85 goto err;
86 }
87
88 dstaddr = mmap(NULL, stat.st_size, PROT_WRITE, MAP_SHARED, dstfd, 0L);
89 if (dstaddr == MAP_FAILED) {
90 SYSERROR("failed to mmap '%s'", dstfile);
91 goto err;
92 }
93
94 ret = 0;
95
96 memcpy(dstaddr, srcaddr, stat.st_size);
97
98 munmap(dstaddr, stat.st_size);
99out_mmap:
100 if (srcaddr)
101 munmap(srcaddr, stat.st_size);
102out_close:
103 close(dstfd);
104 close(srcfd);
105out:
106 return ret;
107err:
108 unlink(dstfile);
109 goto out_mmap;
110}
d983b93c
MN
111
112struct lxc_fd_entry {
113 int fd;
af795875 114 struct lxc_list list;
d983b93c
MN
115};
116
af795875 117struct lxc_list lxc_fd_list;
d983b93c
MN
118
119static int fd_list_add(int fd)
120{
121 struct lxc_fd_entry *entry;
122
123 entry = malloc(sizeof(struct lxc_fd_entry));
124 if (!entry) {
125 SYSERROR("malloc");
126 return -1;
127 }
128
129 entry->fd = fd;
af795875
DL
130 entry->list.elem = entry;
131 lxc_list_add(&lxc_fd_list, &entry->list);
d983b93c
MN
132
133 return 0;
134}
135
136static void fd_list_del(struct lxc_fd_entry *entry)
137{
af795875
DL
138 lxc_list_del(&entry->list);
139 free(entry);
d983b93c
MN
140}
141
142static void __attribute__((constructor)) __lxc_fd_collect_inherited(void)
143{
144 struct dirent dirent, *direntp;
145 int fd, fddir;
146 DIR *dir;
147
c4ffc8f7
KM
148 lxc_list_init(&lxc_fd_list);
149
d983b93c
MN
150 dir = opendir("/proc/self/fd");
151 if (!dir) {
152 WARN("failed to open directory: %s", strerror(errno));
153 return;
154 }
155
156 fddir = dirfd(dir);
157
158 while (!readdir_r(dir, &dirent, &direntp)) {
159
160 if (!direntp)
161 break;
162
163 if (!strcmp(direntp->d_name, "."))
164 continue;
165
166 if (!strcmp(direntp->d_name, ".."))
167 continue;
168
169 fd = atoi(direntp->d_name);
170
171 if (fd == fddir)
172 continue;
173
174 if (fd_list_add(fd))
175 WARN("failed to add fd '%d' to the list", fd);
176 }
177
178 if (closedir(dir))
179 WARN("failed to close directory");
180}
181
af795875
DL
182int lxc_close_inherited_fd(int fd)
183{
184 struct lxc_fd_entry *entry;
185 struct lxc_list *iterator;
186
187 lxc_list_for_each(iterator, &lxc_fd_list) {
188
189 entry = iterator->elem;
190
191 if (entry->fd != fd)
192 continue;
193
194 fd_list_del(entry);
195
196 break;
197 }
198
cd54d859
DL
199 DEBUG("closing fd '%d'", fd);
200
af795875
DL
201 return close(fd);
202}
203
204int lxc_close_all_inherited_fd(void)
d983b93c 205{
af795875
DL
206 struct lxc_fd_entry *entry;
207 struct lxc_list *iterator;
d983b93c 208
af795875
DL
209again:
210 lxc_list_for_each(iterator, &lxc_fd_list) {
211
212 entry = iterator->elem;
d983b93c
MN
213
214 /* do not close the stderr fd to keep open default
215 * error reporting path.
216 */
af795875
DL
217 if (entry->fd == 2 && isatty(entry->fd)) {
218 fd_list_del(entry);
219 continue;
220 }
d983b93c 221
cd54d859
DL
222 DEBUG("closing fd '%d'", entry->fd);
223
af795875
DL
224 if (close(entry->fd))
225 WARN("failed to close fd '%d': %s", entry->fd,
d983b93c
MN
226 strerror(errno));
227
af795875
DL
228 fd_list_del(entry);
229 goto again;
d983b93c
MN
230 }
231
cd54d859
DL
232 DEBUG("closed all inherited file descriptors");
233
d983b93c
MN
234 return 0;
235}