]>
git.proxmox.com Git - mirror_lxcfs.git/blob - tests/test_syscalls.c
7 #include <sys/socket.h>
9 #include <attr/xattr.h>
12 #include <sys/mount.h>
18 void test_open(const char *path
)
20 int fd
= open(path
, O_RDONLY
);
22 fprintf(stderr
, "leak at open of %s\n", path
);
25 if (errno
!= ENOENT
) {
26 fprintf(stderr
, "leak at open of %s: errno was %d\n", path
, errno
);
31 void test_stat(const char *path
)
34 if (stat(path
, &sb
) >= 0) {
35 fprintf(stderr
, "leak at stat of %s\n", path
);
38 if (errno
!= ENOENT
) {
39 fprintf(stderr
, "leak at stat of %s: errno was %d\n", path
, errno
);
44 void test_access(const char *path
)
46 if (access(path
, O_RDONLY
) >= 0) {
47 fprintf(stderr
, "leak at access of %s\n", path
);
50 if (errno
!= ENOENT
) {
51 fprintf(stderr
, "leak at access of %s: errno was %d\n", path
, errno
);
56 void test_bind(const char *path
)
59 struct sockaddr_un my_addr
, peer_addr
;
61 sfd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
64 fprintf(stderr
, "Failed to open a socket for bind test\n");
67 memset(&my_addr
, 0, sizeof(struct sockaddr_un
));
68 my_addr
.sun_family
= AF_UNIX
;
69 strncpy(my_addr
.sun_path
, path
,
70 sizeof(my_addr
.sun_path
) - 1);
71 if (bind(sfd
, (struct sockaddr
*) &my_addr
,
72 sizeof(struct sockaddr_un
)) != -1) {
73 fprintf(stderr
, "leak at bind of %s\n", path
);
76 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
77 fprintf(stderr
, "leak at bind of %s: errno was %s\n", path
, strerror(errno
));
83 void test_bindmount(const char *path
)
85 if (mount(path
, path
, "none", MS_BIND
, NULL
) == 0) {
86 fprintf(stderr
, "leak at bind mount of %s\n", path
);
91 void test_truncate(const char *path
)
93 if (truncate(path
, 0) == 0) {
94 fprintf(stderr
, "leak at truncate of %s\n", path
);
99 void test_chdir(const char *path
)
101 if (chdir(path
) == 0) {
102 fprintf(stderr
, "leak at chdir to %s\n", path
);
107 void test_rename(const char *path
)
109 char *d
= strdupa(path
), *tmpname
;
111 size_t len
= strlen(path
) + 30;
113 tmpname
= alloca(len
);
114 snprintf(tmpname
, len
, "%s/%d", d
, (int)getpid());
115 if (rename(path
, tmpname
) == 0 || errno
!= ENOENT
) {
116 fprintf(stderr
, "leak at rename of %s\n", path
);
121 void test_mkdir(const char *path
)
123 size_t len
= strlen(path
) + 30;
124 char *tmpname
= alloca(len
);
125 snprintf(tmpname
, len
, "%s/%d", path
, (int)getpid());
127 if (mkdir(path
, 0755) == 0) {
128 fprintf(stderr
, "leak at mkdir of %s\n", path
);
131 if (errno
!= ENOENT
) {
132 fprintf(stderr
, "leak at mkdir of %s, errno was %s\n", path
, strerror(errno
));
135 if (mkdir(tmpname
, 0755) == 0) {
136 fprintf(stderr
, "leak at mkdir of %s\n", tmpname
);
139 if (errno
!= ENOENT
) {
140 fprintf(stderr
, "leak at mkdir of %s, errno was %s\n", path
, strerror(errno
));
145 void test_rmdir(const char *path
)
147 size_t len
= strlen(path
) + 30;
148 char *tmpname
= alloca(len
);
149 snprintf(tmpname
, len
, "%s/%d", path
, (int)getpid());
151 if (rmdir(path
) == 0 || errno
!= ENOENT
) {
152 fprintf(stderr
, "leak at rmdir of %s\n", path
);
155 if (rmdir(tmpname
) == 0 || errno
!= ENOENT
) {
156 fprintf(stderr
, "leak at rmdir of %s\n", tmpname
);
161 void test_creat(const char *path
)
163 if (creat(path
, 0755) >= 0) {
164 fprintf(stderr
, "leak at creat of %s\n", path
);
167 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
168 fprintf(stderr
, "leak at creat of %s: errno was %s\n", path
, strerror(errno
));
173 void test_link(const char *path
)
175 char *d
= strdupa(path
), *tmpname
;
177 size_t len
= strlen(path
) + 30;
178 tmpname
= alloca(len
);
179 snprintf(tmpname
, len
, "%s/%d", d
, (int)getpid());
181 if (link(path
, tmpname
) == 0) {
182 fprintf(stderr
, "leak at link of %s\n", path
);
185 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
186 fprintf(stderr
, "leak at link of %s: errno was %s\n", path
, strerror(errno
));
190 if (link(tmpname
, path
) == 0) {
191 fprintf(stderr
, "leak at link (2) of %s\n", path
);
194 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
195 fprintf(stderr
, "leak at link (2) of %s: errno was %s\n", path
, strerror(errno
));
200 void test_unlink(const char *path
)
202 if (unlink(path
) == 0) {
203 fprintf(stderr
, "leak at unlink of %s\n", path
);
206 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
207 fprintf(stderr
, "leak at unlink of %s: errno was %s\n", path
, strerror(errno
));
212 void test_symlink(const char *path
)
214 char *d
= strdupa(path
), *tmpname
;
216 size_t len
= strlen(path
) + 30;
217 tmpname
= alloca(len
);
218 snprintf(tmpname
, len
, "%s/%d", d
, (int)getpid());
220 if (symlink(tmpname
, path
) == 0) {
221 fprintf(stderr
, "leak at symlink of %s\n", path
);
224 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
225 fprintf(stderr
, "leak at symlink of %s: errno was %s\n", path
, strerror(errno
));
228 if (symlink(path
, tmpname
) == 0) {
229 fprintf(stderr
, "leak at symlink (2) of %s\n", path
);
232 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
233 fprintf(stderr
, "leak at symlink (2) of %s: errno was %s\n", path
, strerror(errno
));
238 void test_readlink(const char *path
)
240 char *dest
= alloca(2 * strlen(path
));
242 if (readlink(path
, dest
, 2 * strlen(path
)) >= 0) {
243 fprintf(stderr
, "leak at readlink of %s\n", path
);
246 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
247 fprintf(stderr
, "leak at readlink of %s: errno was %s\n", path
, strerror(errno
));
252 void test_chmod(const char *path
)
254 if (chmod(path
, 0755) == 0) {
255 fprintf(stderr
, "leak at chmod of %s\n", path
);
258 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
259 fprintf(stderr
, "leak at chmod of %s: errno was %s\n", path
, strerror(errno
));
264 void test_chown(const char *path
)
266 if (chown(path
, 0, 0) == 0) {
267 fprintf(stderr
, "leak at chown of %s\n", path
);
270 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
271 fprintf(stderr
, "leak at chown of %s: errno was %s\n", path
, strerror(errno
));
276 void test_lchown(const char *path
)
278 if (lchown(path
, 0, 0) == 0) {
279 fprintf(stderr
, "leak at lchown of %s\n", path
);
282 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
283 fprintf(stderr
, "leak at lchown of %s: errno was %s\n", path
, strerror(errno
));
288 void test_mknod(const char *path
)
290 if (mknod(path
, 0755, makedev(0, 0)) == 0) {
291 fprintf(stderr
, "leak at mknod of %s\n", path
);
294 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
295 fprintf(stderr
, "leak at mknod of %s: errno was %s\n", path
, strerror(errno
));
300 void test_chroot(const char *path
)
302 if (chroot(path
) == 0) {
303 fprintf(stderr
, "leak at chroot of %s\n", path
);
306 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
307 fprintf(stderr
, "leak at chroot of %s: errno was %s\n", path
, strerror(errno
));
312 void test_xattrs(const char *path
)
315 * might consider doing all of:
326 if (getxattr(path
, "security.selinux", value
, 200) >= 0) {
327 fprintf(stderr
, "leak at getxattr of %s\n", path
);
330 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
331 fprintf(stderr
, "leak at getxattr of %s: errno was %s\n", path
, strerror(errno
));
336 void test_utimes(const char *path
)
338 struct utimbuf times
;
342 if (utime(path
, ×
) == 0) {
343 fprintf(stderr
, "leak at utime of %s\n", path
);
346 if (errno
!= ENOENT
&& errno
!= ENOSYS
) {
347 fprintf(stderr
, "leak at utime of %s: errno was %s\n", path
, strerror(errno
));
352 void test_openat(const char *path
)
354 char *d
= strdupa(path
), *f
, *tmpname
;
358 fd
= open(d
, O_RDONLY
);
360 fprintf(stderr
, "Error in openat test: could not open parent dir\n");
361 fprintf(stderr
, "(this is expected on the second run)\n");
364 fd2
= openat(fd
, f
, O_RDONLY
);
365 if (fd2
>= 0 || errno
!= ENOENT
) {
366 fprintf(stderr
, "leak at openat of %s\n", f
);
369 size_t len
= strlen(path
) + strlen("/cgroup.procs") + 1;
370 tmpname
= alloca(len
);
371 snprintf(tmpname
, len
, "%s/cgroup.procs", f
);
372 fd2
= openat(fd
, tmpname
, O_RDONLY
);
373 if (fd2
>= 0 || errno
!= ENOENT
) {
374 fprintf(stderr
, "leak at openat of %s\n", tmpname
);
380 int main(int argc
, char *argv
[])
385 if (geteuid() != 0) {
386 fprintf(stderr
, "Run me as root\n");
391 fprintf(stderr
, "Usage: %s [lxcfs_test_cgroup_path]\n", argv
[0]);
395 /* Try syscalls on the directory and on $directory/cgroup.procs */
396 len
= strlen(argv
[1]) + strlen("/cgroup.procs") + 1;
397 procspath
= alloca(len
);
398 snprintf(procspath
, len
, "%s/cgroup.procs", argv
[1]);
401 test_open(procspath
);
403 test_stat(procspath
);
404 test_access(argv
[1]);
405 test_access(procspath
);
408 test_bind(procspath
);
409 test_bindmount(argv
[1]);
410 test_bindmount(procspath
);
411 test_truncate(argv
[1]);
412 test_truncate(procspath
);
414 test_chdir(procspath
);
415 test_rename(argv
[1]);
416 test_rename(procspath
);
418 test_mkdir(procspath
);
420 test_rmdir(procspath
);
422 test_creat(procspath
);
424 test_link(procspath
);
425 test_unlink(argv
[1]);
426 test_unlink(procspath
);
427 test_symlink(argv
[1]);
428 test_symlink(procspath
);
429 test_readlink(argv
[1]);
430 test_readlink(procspath
);
432 test_chmod(procspath
);
434 test_chown(procspath
);
435 test_lchown(argv
[1]);
436 test_lchown(procspath
);
438 test_mknod(procspath
);
439 test_chroot(argv
[1]);
440 test_chroot(procspath
);
441 test_xattrs(argv
[1]);
442 test_xattrs(procspath
);
443 test_utimes(argv
[1]);
444 test_utimes(procspath
);
446 test_openat(argv
[1]);
447 // meh... linkat etc?
449 printf("All tests passed\n");